有毛刺的時鍾切換電路
這個時鍾切換電路是一個純組合邏輯,輸出時鍾(OUT CLOCK)由選擇信號(SELECT)控制,當SELECT為1時輸出CLK1,反之,輸出CLK0.
看似很簡單,實現了時鍾的切換,實則存在着很大的隱患,如下圖所示:
對上圖的Verilog描述:
assign outclk = (clk1 & select) | (~select & clk0);
相關時鍾源的毛刺保護
下圖顯示了防止源時鍾相互倍數的時鍾開關輸出出現毛刺的解決方案。在每個時鍾源的選擇路徑中插入一個負邊沿觸發的D觸發器。 在時鍾的下降沿采樣選擇控制(SELECT),以及僅在首先使其他時鍾無效后使能選擇(SELECT),可以提供出色的輸出保護 :
下面簡單的解釋下這個電路:
當SELECT為0時,明顯CLK1的那部分通路到輸出無效,僅僅看下半部分電路即可,在CLK0的下降沿采樣SELECT(取反后)信號,與CLK0相與之后輸出;當SELECT為1時,同理上半部分電路有效;
需要重點分析的是當SELECT在任意時刻切換的時候,輸出會不會出現毛刺?
首先SELECT為0,也就是在CLK0的下降沿采樣寄存SELECT(取反后)信號與CLK0相與,輸出時鍾為CLK0;
當在圖中時刻SELECT由低電平變為高電平,此時未到CLK0的下降沿,寄存器的輸出還將一直是高電平(SELECT之前為0,取反為1),當到達CLK0的下降沿時刻,采樣到SELECT為高電平,那么!SELECT為0,也就是下半部分電路從此無效,上半部分電路有效,此時需要等到CLK1的下降沿采樣SELECT值,在此之前,輸出仍未CLK0,到達CLK1的下降沿后,輸出變成了CLK1和SELECT的與,也就是CLK1。由圖可見,輸出時鍾完美切換,並沒有出現斬波信號以及毛刺。
在時鍾的下降沿寄存選擇信號(SELECT)可確保在任一時鍾處於高電平時輸出端不會發生變化,從而防止斬波輸出時鍾(意思是下降沿寄存,可以保證下降沿到來之前輸出端保持不變,這樣就不會斬斷當前時鍾了)。 從一個時鍾的選擇到另一個時鍾的反饋使開關能夠在開始傳播下一個時鍾之前等待取消選擇當前時鍾,從而避免任何毛刺(意思是即使當前SELECT突然變化了,也必須等待到當前時鍾的下降沿到來才能去使當前時鍾無效,這一段時間就避免了毛刺(glitch));
該電路中有三個時序路徑需要特別考慮 - SELECT控制信號到兩個負邊沿觸發觸發器中的任何一個,DFF0輸出到DFF1的輸入,DFF1的輸出到DFF0的輸入。 如果這三條路徑中的任何一條路徑上的信號與目標觸發器時鍾的捕獲邊緣同時發生變化,則該寄存器的輸出很可能變為亞穩態,這意味着它可能會進入理想的0和1兩者之間的狀態。
對上圖的Verilog描述為:
reg out1; reg out0; always @(negedge clk1 or negedge rst_n)begin if(rst_n == 1'b0)begin out1 <= 0; end else begin out1 <= ~out0 & select; end end always @(negedge clk0 or negedge rst_n)begin if(rst_n == 1'b0)begin out0 <= 0; end else begin out0 <= ~select & ~out1; end end assign outclk = (out1 & clk1) | (out0 & clk0);
針對無關時鍾源的毛刺保護
先前避免時鍾開關輸出處的毛刺的方法需要兩個時鍾源彼此的倍數,使得用戶可以避免信號與任一時鍾域異步。在該實現中沒有處理異步信號的機制。
這導致實現具有同步器電路的時鍾開關的第二種方法,以避免由異步信號引起的潛在的亞穩態。當兩個時鍾源彼此完全無關時,異步行為的源可以是SELECT信號或從一個時鍾域到另一個時鍾域的反饋。
如圖3所示,通過為每個時鍾源添加一個額外級的正邊沿觸發觸發器來提供針對亞穩態性的保護。每個選擇路徑中的正邊沿觸發觸發器以及現有的負邊沿觸發觸發器防止潛在的亞穩態性,這可能是由異步SELECT信號或從一個時鍾域到另一個時鍾域的異步反饋引起的。
同步器只是兩級觸發器,其中第一級通過鎖定數據來幫助穩定數據,然后將數據傳遞到下一級;
再看上圖時序圖,在CLK0的第二個時鍾上升沿,采樣數據為SELECT為1,但是要等到時鍾的下降沿才被輸出,這時CLK0的傳播到此結束;
對上圖的Verilog描述為:
reg out_r1; reg out1; reg out_r0; reg out0; always @(posedge clk1 or negedge rst_n)begin if(rst_n == 1'b0)begin out_r1 <= 0; end else begin out_r1 <= ~out0 & select; end end always @(negedge clk1 or negedge rst_n)begin if(rst_n == 1'b0)begin out1 <= 0; end else begin out1 <= out_r1; end end always @(posedge clk0 or negedge rst_n)begin if(rst_n == 1'b0)begin out_r0 <= 0; end else begin out_r0 <= ~select & ~out1; end end always @(negedge clk0 or negedge rst_n)begin if(rst_n == 1'b0)begin out0 <= 0; end else begin out0 <= out_r0; end end assign outclk = (out1 & clk1) | (out0 & clk0);
總結:
通過使用本文中介紹的設計技術,可以通過非常小的開銷避免在時鍾源之間切換時在時鍾線上產生毛刺的危險。 這些技術完全可擴展,可以擴展到時鍾切換兩個以上的時鍾。 對於多個時鍾源,每個時鍾源的選擇信號將通過所有其他源的反饋啟用;