隨著各種應用場景的限制,芯片在運行時往往需要在不同的應用下切換不同的時鐘源,例如低功耗和高性能模式就分別需要低頻率和高頻率的時鐘。兩個時鐘源有可能是同源且頻率比呈倍數(shù)關系,也有可能是不相關的。直接使用選擇邏輯進行時鐘切換大概率會導致分頻時鐘信號出現(xiàn)毛刺現(xiàn)象,所以時鐘切換邏輯也需要進行特殊的處理。
時鐘切換問題
直接采用選擇邏輯對時鐘進行切換的電路圖如下所示。
假如時鐘選擇信號 sel_clk1 與兩個時鐘都是異步的,那么時鐘切換時刻就是任意的。假如時鐘由 clk1 切換到 clk2,且切換時刻為 clk1 輸出電平為高的時候,此時立即切換時鐘就會導致輸出時鐘出現(xiàn)毛刺(glitch)。波形示意圖如下:
時鐘切換方案
在電平相反的時候切換時鐘,肯定有毛刺;電平相同的時候,即使不產生毛刺,時鐘切換后的第一個時鐘的周期或占空比也不是理想的。所以,為避免毛刺的產生,需要在兩個時鐘都為低電平的時候進行時鐘切換。
一種典型的時鐘切換電路如下所示。
該電路利用時鐘下降沿對時鐘選擇信號 sel_clk1 進行緩存。同時一個時鐘選擇信號對另一個時鐘進行反饋控制,保證同一時刻只能有一路時鐘有效。最后采用“或操作”將兩路時鐘合并,完成時鐘切換的過程。
采用上述電路完成時鐘切換(clk1->clk2)的波形示意圖入戲所示。
由圖可知,clk1 向 clk2 切換時,先回關閉 clk1, 然后打開 clk2。由于時鐘選擇信號被同步到時鐘下降沿,所以切換過程中不會出現(xiàn)毛刺。
clk2 向 clk1 切換的波形示意圖如下所示。
考慮到選擇信號有可能是異步信號,需要在時鐘選擇信號的緩存觸發(fā)器之前加兩級觸發(fā)器進行同步處理,來減少亞穩(wěn)態(tài)的傳播,結構圖如下。該時鐘切換電路更具有應用場景的普遍性。
時鐘切換設計
普遍且安全的時鐘切換邏輯描述如下。
module clk_switch(
input rstn ,
input clk1,
input clk2,
input sel_clk1 , // 1 clk1, 0 clk2
output clk_out
);
reg [2:0] sel_clk1_r ;
reg [1:0] sel_clk1_neg_r ;
reg [2:0] sel_clk2_r ;
reg [1:0] sel_clk2_neg_r ;
//使用3拍緩存,同步另一個時鐘控制信號與本時鐘控制信號的"與"邏輯操作
always @(posedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_r <= 3'b111 ; //注意默認值
end
else begin
//sel clk1, and not sel clk2
sel_clk1_r <= {sel_clk1_r[1:0], sel_clk1 & (!sel_clk2_neg_r[1])} ;
end
end
//在下降沿,使用2拍緩存時鐘選擇信號
always @(negedge clk1 or negedge rstn) begin
if (!rstn) begin
sel_clk1_neg_r <= 2'b11 ; //注意默認值
end
else begin
sel_clk1_neg_r <= {sel_clk1_neg_r[0], sel_clk1_r[2]} ;
end
end
//使用3拍緩存,同步另一個時鐘控制信號與本時鐘控制信號的"與"邏輯操作
always @(posedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_r <= 3'b0 ; //注意默認值
end
else begin
//sel clk2, and not sel clk1
sel_clk2_r <= {sel_clk2_r[1:0], !sel_clk1 & (!sel_clk1_neg_r[1])} ;
end
end
//在下降沿,使用2拍緩存時鐘選擇信號
always @(negedge clk2 or negedge rstn) begin
if (!rstn) begin
sel_clk2_neg_r <= 2'b0 ; //注意默認值
end
else begin
sel_clk2_neg_r <= {sel_clk2_neg_r[0], sel_clk2_r[2]} ;
end
end
//時鐘邏輯運算時,一般使用特定的工藝單元庫。
//這里用 Verilog 自帶的邏輯門單元代替
wire clk1_gate, clk2_gate ;
and (clk1_gate, clk1, sel_clk1_neg_r[1]) ;
and (clk2_gate, clk2, sel_clk2_neg_r[1]) ;
or (clk_out, clk1_gate, clk2_gate) ;
endmodule
testbench 描述如下,主要產生異步的時鐘選擇信號。
`timescale 1ns/1ps
module test ;
reg clk_100mhz, clk_200mhz ;
reg rstn ;
reg sel ;
wire clk_out ;
always #(2.5) clk_200mhz = ~clk_200mhz ;
always @(posedge clk_200mhz)
clk_100mhz = #1 ~clk_100mhz ;
initial begin
clk_100mhz = 0 ;
clk_200mhz = 0 ;
rstn = 0 ;
sel = 1 ;
#11 rstn = 1 ;
#36.2 sel = ~sel ;
#119.7 sel = ~sel ;
end
clk_switch u_clk_switch(
.rstn (rstn),
.clk1 (clk_100mhz),
.clk2 (clk_200mhz),
.sel_clk1 (sel),
.clk_out (clk_out));
initial begin
forever begin
#100;
if ($time >= 10000) $finish ;
end
end
endmodule
仿真結果如下,可見時鐘相互切換時沒有產生毛刺,但是存在延遲。
-
電路設計
+關注
關注
6675文章
2453瀏覽量
204393 -
仿真
+關注
關注
50文章
4083瀏覽量
133614 -
信號
+關注
關注
11文章
2791瀏覽量
76778 -
時鐘
+關注
關注
11文章
1734瀏覽量
131490 -
切換電路
+關注
關注
0文章
29瀏覽量
9412
發(fā)布評論請先 登錄
相關推薦
評論