原理如下圖(為了方便簡(jiǎn)潔,去掉了rst_n)
波形是這樣的
代碼就是根據(jù)電路圖寫的
1 /////////////////////////////////////////////////////////////////////////////////////////// 2 // DATE : Wed Jun 6 23:31:57 CST 2012 3 /////////////////////////////////////////////////////////////////////////////////////////// 4 module clk_sw( 5 input wire clk_a 6 , input wire clk_b 7 , input wire rst_n 8 , input wire sel 9 , output wire clk_o 10 ); 11 /////////////////////////////////////////////////////////////////////////////////////////// 12 // variable declaration 13 reg clk_a_en ; 14 reg clk_b_en ; 15 /////////////////////////////////////////////////////////////////////////////////////////// 16 // logic 17 always @(posedge clk_a or negedge rst_n) begin 18 if(~rst_n) clk_a_en <= 1'b0 ; 19 else clk_a_en <= ~sel & ~clk_b_en ; 20 end 21 always @(posedge clk_b or negedge rst_n) begin 22 if(~rst_n) clk_b_en <= 1'b0 ; 23 else clk_b_en <= sel & ~clk_a_en ; 24 end 25 assign clk_o = (clk_a & clk_a_en) | (clk_b & clk_b_en) ; 26 /////////////////////////////////////////////////////////////////////////////////////////// 27 28 endmodule // CREATED by poiu_elab@1207 29 30 ///////////////////////////////////////////////////////////////////////////////////////////
testbench是這樣的
1 /////////////////////////////////////////////////////////////////////////////////////////// 2 // DATE : Wed Jun 6 23:42:58 CST 2012 3 /////////////////////////////////////////////////////////////////////////////////////////// 4 `define CLK_A_CYCLE 23 5 `define CLK_B_CYCLE 47 6 module tb(); 7 /////////////////////////////////////////////////////////////////////////////////////////// 8 // variable declaration 9 reg clk_a ; 10 reg clk_b ; 11 reg rst_n ; 12 reg sel ; 13 wire clk_o ; 14 /////////////////////////////////////////////////////////////////////////////////////////// 15 // stimulation generation 16 initial forever #(`CLK_A_CYCLE/2) clk_a = ~clk_a; 17 initial forever #(`CLK_B_CYCLE/2) clk_b = ~clk_b; 18 initial begin 19 rst_n = 1'b0 ; 20 clk_a = 1'b1 ; 21 clk_b = 1'b1 ; 22 sel = 1'b0 ; 23 #500; 24 rst_n = 1'b1 ; 25 #500; 26 #({$random}%13+500); 27 sel = ~sel ; 28 #({$random}%23+500); 29 sel = ~sel ; 30 #({$random}%33+500); 31 sel = ~sel ; 32 #({$random}%43+500); 33 sel = ~sel ; 34 #({$random}%53+500); 35 sel = ~sel ; 36 #({$random}%63+500); 37 sel = ~sel ; 38 #({$random}%73+500); 39 sel = ~sel ; 40 #({$random}%83+500); 41 sel = ~sel ; 42 #({$random}%93+500); 43 sel = ~sel ; 44 #({$random}%13+500); 45 sel = ~sel ; 46 #({$random}%23+500); 47 sel = ~sel ; 48 #({$random}%33+500); 49 sel = ~sel ; 50 #({$random}%43+500); 51 sel = ~sel ; 52 #({$random}%53+500); 53 sel = ~sel ; 54 #({$random}%63+500); 55 sel = ~sel ; 56 #({$random}%73+500); 57 sel = ~sel ; 58 #({$random}%83+500); 59 sel = ~sel ; 60 #({$random}%93+500); 61 sel = ~sel ; 62 #5000; 63 $stop; 64 end 65 /////////////////////////////////////////////////////////////////////////////////////////// 66 // module instaniation 67 clk_sw u_clk_sw( 68 .clk_a ( clk_a ) 69 , .clk_b ( clk_b ) 70 , .rst_n ( rst_n ) 71 , .sel ( sel ) 72 , .clk_o ( clk_o ) 73 ); 74 /////////////////////////////////////////////////////////////////////////////////////////// 75 76 endmodule // CREATED by poiu_elab@1207 77 78 ///////////////////////////////////////////////////////////////////////////////////////////
這里的核心就是你的sel發(fā)生翻轉(zhuǎn)的時(shí)候,首先肯定是在本時(shí)鐘域內(nèi)的clk_en會(huì)先變低(invalid),之后才會(huì)使得另外時(shí)鐘域內(nèi)的clk_en變高(valid),這時(shí)另外一個(gè)時(shí)鐘域內(nèi)的時(shí)鐘才能和clk_en相與輸出。
簡(jiǎn)而言之,比如一開始是clk_a有效,clk_out為clk_a,sel翻轉(zhuǎn)后,clk_a_en在clk_a的時(shí)鐘域內(nèi)先關(guān)斷(拉低),使得clk_out持續(xù)拉低,clk_a_en變低后,clk_b_en在clk_b的時(shí)鐘域內(nèi)才能被拉高有效,這時(shí)同步的clk_b_en信號(hào)與clk_b相與就能使得clk_out成功切換到clk_b了。
原理就是這樣,其中clk_a_en和clk_b_en不會(huì)同時(shí)有效就避免了時(shí)鐘切換的時(shí)候窄脈沖及毛刺的生成,但是我覺(jué)得由于是組合邏輯輸出的時(shí)鐘總歸還是會(huì)有一些缺點(diǎn)和不足的。不知道有沒(méi)有什么更好的辦法。
編輯:hfy
-
時(shí)鐘
+關(guān)注
關(guān)注
10文章
1714瀏覽量
131277 -
波形
+關(guān)注
關(guān)注
3文章
377瀏覽量
31473
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論