スリーステートドアの紹介:
スリーステートゲートには、入力状態、出力状態、高インピーダンス状態があります。スリーステート信号の定義:入力
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
したがって、スリーステートゲートのテストファイルを作成する場合は、次の条件を満たす必要があります。
- スリーステート信号はワイヤータイプです。
- トライステート信号に割り当てるregタイプの中間信号を定義します。
- 入力端子としてスリーステート信号が必要な場合は、中間信号を使用して割り当てます。
最後に、要約すると:
- プロジェクトにスリーステート信号のVerilogコードを記述して、スリーステート信号をワイヤタイプとして定義します。
- テストファイルのスリーステート信号もワイヤタイプとして定義され、中間信号は割り当て入力のスリーステート信号を置き換えるために使用されます。
最後に、この記事の執筆は非常に面倒で、とても不快だと思いますが、その意味を理解し、主に要約を見るのは良いことです。SDRAMインターフェースの書き込みプロセスは後で共有されます。