問題:
在多時鍾設計中可能需要進行時鍾的切換。由於時鍾之間可能存在相位、頻率等差異,直接切換時鍾可能導致產生glitch。
組合邏輯實現時鍾切換:
HDL代碼:
module clock_mux( input clk0, clk1, input select, output out_clock ); assign out_clock = selsect ? clk1: clk0; endmodule
電路圖:
波形圖:
問題:
使用上述電路進行時鍾切換會導致在控制信號sel附近出現glitch。其原因在於控制信號可以在任意時刻進行時鍾切換,切換信號相對於兩個時鍾都是異步信號。
解決方法:
使用寄存器使得控制信號僅在時鍾邊沿作用,避免在任何時鍾都為高電平是進行時鍾切換。
適用於倍頻時鍾切換的時序邏輯電路
HDL代碼:
module clock_mux( input clk0, clk1, input select, output out_clock ); reg q1; reg q0; always @(negedge clk1) q1 <= !q0 && selected always @(negedge clk0) q0 <= !q1 && ~select; assign out_clock = (clk1 && q1) || (clk0 && q0); endmodule
電路圖:
波形圖:
功能:
當切換的時鍾存在倍頻關系時,分別插入一個下降沿觸發的觸發器以確保控制信號僅在時鍾低電平時起作用。
問題:
當DFF1輸入的變化非常接近CLK1的下降沿時,可能會導致DFF1的亞穩態問題;DFF0同理。
為什么可以用於倍頻時鍾之間的切換?
異步時鍾切換的時序電路
HDL代碼:
module clock_mux( input clk0, clk1, input rst_n, input select, output out_clock ); reg inter0_p, inter0_n; reg inter1_p, inter1_n; always @(posedge clk0 or negedge rst_n) if(!rst_n) inter0_p <= 0; else inter0_p <= (select && !inter1_n); always @(negedge clk0 or negedge rst_n) if(!rst_n) inter0_n <= 0; else inter0_n <= inter0_p; always @(posedge clk1 or negedge rst_n) if(!rst_n) inter1_p <= 0; else inter1_p <= (select && !inter0_n); always @(negedge clk1 or negedge rst_n) if(!rst_n) inter1_n <= 0; else inter1_n <= inter1_p; assign out_clock = (clk0 && inter0_n) || (clk1 && inter1_n); endmodule
電路圖:
波形圖:
功能:
通過為每個時鍾源添加一個額外級的正邊沿觸發觸發器來提供針對亞穩態性的保護,CLK0的上升沿采樣到信號到下降沿傳遞至CLK1的正邊沿觸發器,並在CLK0下降沿后CLK1第一個上升沿之后的下降沿輸出。(不是很理解)