時鍾無縫切換


轉載自:https://blog.csdn.net/u010668547/article/details/80250997

本文討論了時鍾切換的兩種基本情況以及兩種基本電路結構,討論了一些問題:

下圖是一個時鍾選擇的簡單實現以及時序圖,使用AND-OR多路復用邏輯,其中SELECT信號為時鍾選擇信號,如圖中所示,直接切換會產生毛刺(glitch)

 

時鍾切換分為兩種情況:(1)CLK0與CLK1為相關時鍾源,即CLK0與CLK1成整數倍關系;(2)CLK0與CLK1之間沒有關系;

(1)CLK0與CLK1為相關時鍾源

(2)CLK0與CLK1為無關時鍾源

時鍾切換源代碼:

`timescale 1ns/1ns module clk_syn_tst ( rst_n, clka,  clkb,  sel_clkb,  clk_o ); input rst_n; input clka; input clkb; input sel_clkb; output clk_o; reg sel_clka_d0; reg sel_clka_d1; reg sel_clka_dly1; reg sel_clka_dly2 ; reg sel_clka_dly3; reg sel_clkb_d0; reg sel_clkb_d1; reg sel_clkb_dly1; reg sel_clkb_dly2; reg sel_clkb_dly3; always @ (posedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_d0 <= 1'b0; sel_clka_d1 <= 1'b0; end else  begin sel_clka_d0 <= (~sel_clkb) & (~sel_clkb_dly3) ; sel_clka_d1 <= sel_clka_d0 ; end end // part2 
//always @ (posedge clka_n or negedge rst_n) always @ (negedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_dly1 <= 1'b0; sel_clka_dly2 <= 1'b0; sel_clka_dly3 <= 1'b0; end else  begin sel_clka_dly1 <= sel_clka_d1; sel_clka_dly2 <= sel_clka_dly1 ; sel_clka_dly3 <= sel_clka_dly2 ; end end
// part3 //always @ (posedge clkb_n or negedge rst_n) always @ (posedge clkb or negedge rst_n) begin if (!rst_n) begin sel_clkb_d0 <= 1'b1; sel_clkb_d1 <= 1'b1; end else  begin sel_clkb_d0 <= sel_clkb & (~sel_clka_dly3) ; sel_clkb_d1 <= sel_clkb_d0 ; end end // part4 //always @ (posedge clkb_n or negedge rst_n) always @ (negedge clkb or negedge rst_n) begin if (!rst_n) begin sel_clkb_dly1 <= 1'b1; sel_clkb_dly2 <= 1'b1; sel_clkb_dly3 <= 1'b1; end else  begin sel_clkb_dly1 <= sel_clkb_d1; sel_clkb_dly2 <= sel_clkb_dly1 ; sel_clkb_dly3 <= sel_clkb_dly2 ; end end // part5 //clk_gate_xxx clk_gate_a ( .CP(clka), .EN(sel_clka_dly3), .Q(clka_g), .TE(1'b0) ); //clk_gate_xxx clk_gate_b ( .CP(clkb), .EN(sel_clkb_dly3), .Q(clkb_g), .TE(1'b0) ); assign clka_g = clka & sel_clka_dly3 ; assign clkb_g = clkb & sel_clkb_dly3 ; assign clk_o = clka_g | clkb_g ; endmodule

時鍾切換測試代碼:

`timescale 1ns/1ns module clk_syn_tb; parameter DLY=1; reg rst_n; reg clka; reg clkb; reg sel_clkb; wire clk_o; clk_syn_tst test1( //input .rst_n (rst_n), //system reset .clka (clka), //clock A .clkb (clkb), //clock B .sel_clkb (sel_clkb),//pulse input from clka // output .clk_o (clk_o)//pulse output in clkb ); initial begin rst_n=0; clka=0; clkb=0; sel_clkb=0; #20 rst_n =1; #500 sel_clkb=1; #500 sel_clkb=0; end always #5 clka<=~clka; always #20 clkb<=~clkb; //always @(posedge clka or negedge rst_n) //begin //if(rst_n==1'b0) //puls_a_in<=0; //else //puls_a_in<=# DLY $random %2; //end endmodule

本文代碼部分中clka即為CLK0,clkb即為CLK1,sel_clkb即為SELECT,時鍾切換的結構有些不同,

   begin sel_clkb_d0 <= sel_clkb & (~sel_clka_dly3) ; sel_clkb_d1 <= sel_clkb_d0 ; end

代碼相當於將(sel_clkb)&(~sel_clka_dly3)之后,再打兩拍在反饋回路上增加兩個DFF,結合sel_clkb_d1之后經過了三拍延遲,

begin sel_clkb_dly1 <= sel_clkb_d1; sel_clkb_dly2 <= sel_clkb_dly1 ; sel_clkb_dly3 <= sel_clkb_dly2 ; end

故由sel_clkb由0變為1時,clk_o在經過5個clkb下降沿之后,才由clka切換至clkb。同時在這里需要考慮兩個問題:

(1)為什么part4中,需要在下降沿(negedge)對sel_clkb_d1進行采樣,假設采用上升沿(posedge)對sel_clkb_d1進行采樣,結果又會怎樣:

//always @ (posedge clka_n or negedge rst_n) always @ (negedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_dly1 <= 1'b0; sel_clka_dly2 <= 1'b0; sel_clka_dly3 <= 1'b0; end else  begin sel_clka_dly1 <= sel_clka_d1; sel_clka_dly2 <= sel_clka_dly1 ; sel_clka_dly3 <= sel_clka_dly2 ; end end

采用下降沿對sel_clkb_d1進行采樣:

采用上升沿對sel_clkb_d1進行采樣:

圓圈中的毛刺是由於在sel_clkb由0變為1時,需要5個clka時鍾輸出clk_o才關閉,但是由於是在clka上升沿進行采樣,之后與clka進行&操作,&操作在clk上升沿之后,故進行與操作會產生毛刺。

 

(2)在對寄存器進行賦值時,為什么復位初始值都設置為0,這里面出於什么考慮:

// part2 //always @ (posedge clka_n or negedge rst_n) always @ (negedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_dly1 <= 1'b0; sel_clka_dly2 <= 1'b0; sel_clka_dly3 <= 1'b0; end

復位初始值設置為0:

此時sel_clka_dly3與sel_clkb_dly3都為0,即在復位時將clk_o鎖住,輸出為0,在rst_n被拉起后,經過5個clka,clka的使能信號sel_clkb(0)才被采到。

假設與clkb相關的寄存器復位狀態都設置為1,與clka相關的寄存器復位狀態都設置為0,則時序圖為:

此時相當於clk_o由時鍾clkb向clka進行了切換,因此在復位的時候進行了依次切換。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM