QuartusコンパイルおよびModelsimでのFPGA Verilog 3ステートゲートの設計およびシミュレーションの問題

スリーステートドアの紹介:

スリーステートゲートには、入力状態、出力状態、高インピーダンス状態があります。スリーステート信号の定義:入力

FPGAデザインでは、データの入力と出力がよく使用されます。外部チップでデータを送信するときは、スリーステートゲートがよく使用されます。たとえば、現在学習しているSDRAMです。ポートリソースを節約するために、いくつかのデータポートが通常使用されます。入力および出力として、このようなポートはスリーステートゲートと呼ばれます。

SDRAMチップのデータポートdqは、一般的なスリーステートゲートです。書き込み操作を実行する場合、dqは入力ポートとして使用されます。読み取り操作を実行する場合、dqは出力ポートとして使用されます。それ以外の場合は、高インピーダンス状態です。FPGAおよびSDRAMインターフェイスを書き込む場合、SDRAMに接続される信号としてスリーステート信号dqを使用する必要があります。

例を使用して直感的に説明します。
以下はVerilogプログラムです。

module tri_state(
		input				clk     ,
		input				rst_n   ,
		input				data	,
		input 				dout_en	,
		output reg			odata	,
		inout     			dout
		);
				
	assign dout = (dout_en==1)? data : 1'bz;
		
	always@(posedge clk or negedge rst_n)begin
		if(rst_n == 0)
			odata <= 0;
		else if(dout_en!=1)
			odata <= dout;
	end	
		
endmodule

スリーステート信号はドートで、RTLビューは次のとおりです。

dout_enが1の場合、doutはデータデータを出力し、dout_enが0の場合、doutはハイインピーダンスになります。このとき、doutは入力ポートとして使用できます。入力ポートとして使用すると、バッファは入力データバッファとしてFPGA内で自動的に生成されます。 。

3ステートゲートのクォータスコンパイルとModelsimシミュレーションの問題:

1. quartusはスリーステートゲートをコンパイルします

例として書き込まれているSDRAMインターフェイスを見てください。Verilogコードのスリーステート信号dqのコードセグメントは次のとおりです(エラー)。

     inout  reg [ 15: 0]   dq        ; //数据线
     output reg [ 15: 0]   rdate     ;

//dq信号输出,数据线
	 always@(posedge clk or negedge rst_n)begin
		  if(rst_n == 0)begin
				dq <= 16'hzzzz;
		  end
		  else if(wr_write_start || state_c==wr_write)
				dq <= wdata;
		  else 
				dq <= 16'hzzzz;
	 end  

     always@(posedge clk or negedge rst_n)begin
		  if(rst_n == 0)
				rdate <= 0;
			else if(state_c==rd_read || state_c==rd_pre)
				rdate <= dq;
	 end

現時点では、quartusでコンパイルするとエラーは報告されませんが、Modelsimでコンパイルすると報告されます。これは、トライステート信号をワイヤータイプの信号として定義する必要があるため、Modelsimでコンパイルするとエラーが報告されないためです。私の理解から:実際には、dqスリース​​テート信号はワイヤータイプまたはregタイプとして定義できます。regタイプはModelsimでコンパイルできませんが、ボードにダウンロードしたときの結果は同じです。興味がある場合は、自分で試すことができます。ただし、デフォルトではスリーステート信号をワイヤータイプに設定します。変更されたコードは次のとおりです。


     inout         [  15: 0]    dq       ;
     reg           [  15: 0]	dq_t     ;

//dq信号输出,数据线
	 assign dq = dq_t;
	 always@(posedge clk or negedge rst_n)begin
		  if(rst_n == 0)begin
				dq_t <= 16'hzzzz;
		  end
		  else if(wr_write_start || state_c==wr_write)
				dq_t <= wdata;
		  else 
				dq_t <= 16'hzzzz;
	 end  

     always@(posedge clk or negedge rst_n)begin
		  if(rst_n == 0)
				rdate <= 0;
			else if(state_c==rd_read || state_c==rd_pre)
				rdate <= dq;
	 end

主なことは、dqをワイヤータイプとして定義し、次にregタイプの中間信号dq_tを定義することです。これは、dqに割り当てられます。
2. Modelsimがスリーステートゲートをコンパイルする

inoutタイプのシグナルの場合、テストファイルを書き込むときに、次のように記述します。

wire [15:0]  dq;
initial begin
	for(i=1 ;i<260;i=i+1)begin
			dq = (i==1)? 1:(dq+1'b1);
			#(clk_period);
	end	
end

Modelsimがエラーを報告します:ネット "dq"への不正な参照
dqは、ワイヤータイプを定義する3ステートゲートですが、データにregタイプが指定されている場合は、間違いなくエラーが報告されます。次のようにregタイプとして定義されている場合:

reg [15:0]  dq;
initial begin
	for(i=1 ;i<260;i=i+1)begin
			dq = (i==1)? 1:(dq+1'b1);
			#(clk_period);
	end	
end

コンパイルではエラーは報告されませんが、ホームエラーが発生します。

スリーステート信号は次のように処理されます(他のコードが使用され、非常に乱雑に見え、意味を理解しています):(regタイプの中間信号を追加し、assignを使用してdqに割り当て、この信号を以下の割り当てに使用します)

parameter	WIDTH = 16;

wire	[WIDTH-1 : 0]	dq;

reg		            	tri_en;
reg		[WIDTH-1 : 0]	data_w;

assign  dq = (tri_en) ? data_w : 16'hzzzz;

module_1 u_module_1(
		
		);		
initial begin
	tri_en = 0;
	#(clk_period);
	tri_en = 1;
	data_w = 16'h1111;
	#(clk_period);
	tri_en = 0;
	
	data_w = ......
end

 

したがって、スリーステートゲートのテストファイルを作成する場合は、次の条件を満たす必要があります。

  1. スリーステート信号はワイヤータイプです。
  2. トライステート信号に割り当てるregタイプの中間信号を定義します。
  3. 入力端子としてスリーステート信号が必要な場合は、中間信号を使用して割り当てます。

最後に、要約すると:

  • プロジェクトにスリーステート信号のVerilogコードを記述して、スリーステート信号をワイヤタイプとして定義します。
  • テストファイルのスリーステート信号もワイヤタイプとして定義され、中間信号は割り当て入力のスリーステート信号を置き換えるために使用されます。

最後に、この記事の執筆は非常に面倒で、とても不快だと思いますが、その意味を理解し、主に要約を見るのは良いことです。SDRAMインターフェースの書き込みプロセスは後で共有されます。

おすすめ

転載: blog.csdn.net/qq_33231534/article/details/105129252