デジタルIC設計研究ノート
クロスクロックドメイン同期の問題
1 单比特信号跨时钟域问题
1.1 慢时钟域--> 快时钟域
1.2 快时钟域-->慢时钟域
1シングルビット信号のクロスクロックドメインの問題
1.1低速クロックドメイン->高速クロックドメイン
- 方法:2レベルのトリガーを使用した2つのショット。
- 注:
- 第1レベルのレジスタが準安定状態を生成し、それ自体を通過した後に出力を安定させることができる確率は約70%〜80%であり、第2レベルのレジスタが出力を安定させることができる確率は約99%であり、その後の改善はっきりしないので、データが入ります。その後、通常は2枚のショットを選択します。
- データは2ビート後に0または1に安定化できますが、0と1の安定値はランダムであり、入力との必然的な関係はありません。
- 準安定状態の衝撃時間に影響を与える要因:デバイスの製造プロセス、温度、環境、レジスタが準安定状態で安定状態を収集する時間、干渉、放射など。
- Verilogコード
input syn_clk;
input rst_n;
input asyn_sig;
reg syn_reg1;
reg syn_reg2;
always@(posedge syn_clk or negedge rst_n)
if(!rst_n)begin
syn_reg1 <= 0;
syn_reg2 <= 0;
end else
begin
syn_reg1 <= asyn_sig;
syn_reg2 <= syn_reg1;
end
1.2高速クロックドメイン->低速クロックドメイン
- 方法1:
- パルス信号を元のクロックドメイン(clka)のレベル信号に変換します
- レベル信号をスロークロックドメインに渡し、スロークロックドメイン(clb)でダブルビート処理を行います。
- 最後に、同期された信号がパルス信号に復元されます(エッジ検出方法)
-
短所:高速クロックドメインで生成されるパルス信号の周期は、低速クロックドメインのクロック周期よりも長くする必要があります。そうしないと、低速クロックドメインで信号が収集されない場合があります。
-
タイミング図
- Verilogコード
//----top module---------------------------------
module fast_to_slow
(
input clka, rsta, clkb,signala,rstb,
output signalb
);
reg sstate,state1, state2, state3;
//----脉冲信号转换沿信号-----------------------
always@(posedge clka or negedge rsta)begin
if(!rsta) state <= 0
else if(signala) state <=~state;
else state <=0;
end
//----沿信号打三拍-----------------------------
always@(posedge clkb or negedge rstb)begin
If(!rst) begin
state1 <= 0;
state2<=0;
state3<=0;
end
else begin
state1<=state;
state2<=state1;
state3<=state2;
end
//----上升沿,下降沿同时检测-------------------
assign signalb = state2 ^ state3;
endmodule
- 方法2:ハンドシェイク信号
信号が低速クロックドメインで収集された後、信号は高速クロックドメインにフィードバックされ、高速クロックドメインはデータの送信を停止します。
- Verilogコード
// Company:
// Engineer: GloriaHuo
//
// Create Date: 15:26:46 10/20/2020
// Design Name:
// Module Name: shack_hand
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module shack_hand
(
input clk1,
input clk2,
input rst1,
input rst2,
input din,
output dout
);
reg din_reg;
reg din_reg_asyn;
reg din_reg_sync1;
reg din_reg_sync2;
reg d_ask_asyn;
reg d_ask;
//----extend din--------------------//
always@(posedge clk1 or negedge rst1)begin
if(~rst1)
din_reg <= 0;
else if(din==1)
din_reg <= 1;
else if(d_ask == 1)
din_reg <= 0;
end
//----asyn din_reg from clk1 to clk2---//
always@(posedge clk2 or negedge rst2)begin
if(~rst2)
din_reg_asyn <= 0;
else
din_reg_asyn <= din_reg;
end
//----clk2: synchronos process by two DFF-----//
always@(posedge clk2 or negedge rst2)begin
if(~rst2)begin
din_reg_sync1 <= 0;
din_reg_sync2 <= 0;
end else
begin
din_reg_sync1 <= din_reg_asyn;
din_reg_sync2 <= din_reg_sync1;
end
end
//----clk1: d_ask --------------------//
always@(posedge clk1 or negedge rst1)begin
if(~rst1)begin
d_ask_asyn <= 0;
d_ask <= 0;
end else
begin
d_ask_asyn <= din_reg_sync2;
d_ask <= d_ask_asyn;
end
end
//----dout---------------------//
assign dout = din_reg_sync1 & ~din_reg_sync2;
endmodule
—コンテンツの一部はダーウィンからのもので、公式アカウントに感謝します^^
【注意】:個人学習メモ、間違いがありましたら、お気軽に教えてください、丁寧です~~~