文章****:
1. 概述
訊號同步的目的是防止新時鐘域中第一級觸發器
的亞穩態訊號對下一級邏輯造成影響。
簡單的同步器由兩個觸發器串聯而成,中間沒有其它組合電路。
這種設計可以保證後面的觸發器獲得前乙個觸發器輸出時
前乙個觸發器已退出了亞穩態,並且輸出已穩定。
2.訊號同步的要求
為了使同步工作能正常進行
從某個時鐘域傳來的訊號應先通過原時鐘域上的乙個觸發器
然後不經過兩個時鐘域間的任何組合邏輯
直接進入同步器的第乙個觸發器中。
這一要求非常重要,
因為同步器的第一級觸發器對組合邏輯所產生的毛刺非常敏感。
如果乙個足夠長的毛刺正好滿足建立-保持時間的要求
則同步器的第一級觸發器會將其放行,
給新時鐘域的後續邏輯送出乙個虛假的訊號。
3.同步造成的延時
乙個經同步後的訊號在兩個時鐘延以後就成為新時鐘域中的有效訊號。
訊號的延遲是新時鐘域中的一到兩個時鐘週期。
一種粗略的估算方法是同步器電路在新時鐘域中造成兩個時鐘週期的延遲,
設計者需要考慮同步延遲對跨時鐘域的訊號時序造成的影響。
4.三種常用的同步器
同步器由許多種設計方法,
因為同一種同步器不能滿足所有應用的需求。
同步器的型別基本上有三種:電平、邊沿檢測和脈衝。
雖然還存在其它型別的同步器,
但這三種型別的同步器可以解決設計者遇到的多數應用問題。
a. 電平(level signal)同步器
在電平同步器中,
跨時鐘域的訊號在新時鐘域中要保持高電平或低電平兩個時鐘週期以上。
同步之後的訊號是電平的形式,
而該電平所維持的時鐘週期個數是其在跨時鐘域期間被上公升沿檢測到的次數。
這種同步器是所有同步器電路的核心。
下面是用verilog描述的電平同步器
module synzer_ls(
data_out,
clk1,
clk2,
data_in
); //level signal synchronizer
output data_out; // signal that after synchronized
input clk1; // old clk signal
input clk2; // new clk signal
input data_in; // signal that before synchronized
reg a; // dff in the old clk domain
reg b; // the first dff in the new clk domain
reg c; // the second dff in the new clk domain
always @(posedge clk1) //a
a<=data_in;
always @(posedge clk2) //b
b<=a;
always @(posedge clk2) //c
c<=b;
assign data_out=c;
endmodule
b. 邊沿檢測(edge detecting)同步器
邊沿檢測同步器在電平同步器的輸出端增加了乙個觸發器。
新增觸發器的輸出經反相後和電平同步器的輸出進行與操作。
這一電路會檢測同步器輸入的上公升沿,
產生乙個與時鐘週期等寬、高電平有效的脈衝。
如果將與門的兩個輸入端交換使用,
就可以構成乙個檢測輸入訊號下降沿的同步器。
將與門改為非門可以構建乙個產生低電平有效脈衝的電路。
當乙個脈衝進入更快的時鐘域中時,
邊沿檢測同步器可以工作的很好。
這一電路會產生乙個脈衝,用來指示輸入訊號上公升或下降沿。
這種同步器有乙個限制,
即輸入脈衝的寬度必須大於同步時鐘週期與第乙個同步觸發器所需保持時間之和。
最保險的脈衝寬度是同步器時鐘週期的兩倍。
如果輸入是乙個單時鐘寬度脈衝進入乙個較慢的時鐘域,
則這種同步器沒有作用,
在這種情況下就要採用脈衝同步器。
下面是用verilog描述的邊沿(上公升沿)檢測同步器
module synzer_ed(
data_out,
clk1,
clk2,
data_in
); // edge detecting synchronizer
output data_out; // signal that after synchronized
input clk1; // old clk signal
input clk2; // new clk signal
input data_in; // signal that before synchronized
reg a; // dff in the old clk domain
reg b; // the first dff in the new clk domain
reg c; // the second dff in the new clk domain
reg d; // the third dff in the new clk domain
always @(posedge clk1) //a
a<=data_in;
always @(posedge clk2) //b
b<=a;
always @(posedge clk2) //c
c<=b;
always @(posedge clk2) //d
d<=c;
assign data_out=c&&(~d);
endmodule
c. 脈衝(pulse)同步器
脈衝同步器的輸入訊號是乙個單時鐘寬度脈衝,
它觸發原時鐘域中的乙個翻轉電路。
每當翻轉電路接收到乙個脈衝時,它就會在高低電平間進行轉換,
然後通過電平同步器到達異或門的乙個輸入端,
而另乙個訊號經過乙個時鐘週期的延遲進入異或門的另一端,
翻轉電路每轉換一次狀態,
這個同步器的輸出端就產生乙個單時鐘寬度的脈衝。
脈衝同步器的基本功能是從某個時鐘域取出乙個單時鐘寬度脈衝,
然後在新時鐘域中建立另乙個單時鐘寬度的脈衝。
脈衝同步器也有乙個限制,
及輸入脈衝之間的最小間隔必須等於兩個同步器時鐘週期。
如果輸入脈衝相互過近,
則新時鐘域中的輸出脈衝也緊密相鄰,
結果是輸出脈衝寬度比乙個時鐘週期寬。
當輸入脈衝時鐘週期大於兩個同步器時鐘週期時,這個問題更加嚴重。
這種情況下,如果輸入脈衝相鄰太近,則同步器就不能檢測到每個脈衝。
下面是用verilog描述的脈衝同步器
module synzer_pl(
data_out,
clk1,
clk2,
data_in,
rst_n
); // pulse synchronizer
output data_out; // signal that after synchronized
input clk1; // old clk signal
input clk2; // new clk signal
input data_in; // signal that before synchronized
input rst_n; // signal indicating reset
reg a; // dff in the old clk domain
reg b; // the first dff in the new clk domain
reg c; // the second dff in the new clk domain
reg d; // the third dff in the new clk domain
wire q;
wire q1;
wire di;
assign di=data_in?q1:q;
assign q=a;
assign q1=~a;
assign data_out=(c==d)?0:1;
always @(posedge clk1) //a
begin
if(!rst_n)
a<=1'b0;
else
a<=di;
endalways @(posedge clk2) //b
b<=a;
always @(posedge clk2) //c
c<=b;
always @(posedge clk2) //d
d<=c;
endmodule
跨時鐘域分析 單位元訊號同步
處理跨時鐘域的資料有單bit和多bit之分,而打兩拍的方式常見於處理單bit資料的跨時鐘域問題。打兩拍本質就是定義兩級暫存器對資料進行延拍。流程如下圖所示 兩級暫存器的原理 兩級寄存是一級寄存的平方,兩級並不能完全消除亞穩態危害,但是提高了可靠性減少其發生概率。總的來講,就是一級概率很大,改善不大。...
FPGA單位元訊號跨時鐘域處理
詳細的原理解釋 單位元訊號跨時鐘域問題詳解 輸入 singal in,來自10mhz慢速時鐘域的單位元訊號 輸出 singal out,輸出100mhz快速時鐘域的單位元訊號 10mhz 100ns 100mhz 10ns 因為慢速時鐘域的最簡訊號長度為1個時鐘時鐘週期即 100ns,大於快速時鐘域...
跨時鐘域訊號處理
一 場景描述 某訊號signal需要在不同的時鐘域進行處理,需要同步到的不同的時鐘域繼續使用。舉例說明 某定時器timer包含兩個時鐘域bus clk和tmr clk。狀態暫存器sts和控制暫存器ctrl定義如下。暫存器讀寫訪問採用bus clk時鐘,timer功能採用tmr clk時鐘,當發生溢位...