做個(gè)假設(shè):需要將100M時(shí)鐘下的脈沖同步到1M的時(shí)鐘域下,如果按照打拍的方式,需要延展100拍后再進(jìn)行跨時(shí)鐘域才能保證信號能在1M時(shí)鐘域正確采到,這種設(shè)計(jì)方法未免太愚蠢而又浪費(fèi)資源。
本篇介紹兩種可以同時(shí)處理快到慢、慢到快所有時(shí)鐘頻率的脈沖同步設(shè)計(jì)電路情況。
- 脈沖同步
- 電平同步
脈沖同步

sync_pluse.jpg
注:
* 藍(lán)色為 A 時(shí)鐘域的寄存器;
* 紅色為 B 時(shí)鐘域的寄存器;
實(shí)現(xiàn)說明
- 該模塊關(guān)鍵寄存器是signal_a,在A時(shí)鐘域下,捕獲到i_plus_a的脈沖,轉(zhuǎn)化為電平反轉(zhuǎn)傳輸?shù)紹時(shí)鐘域,等待B時(shí)鐘域捕獲到有電平變化,signal_a再清0,等待下一個(gè)脈沖輸入。
HDL代碼
module sync_pulse
(
//A clock domain
input clk_A ,
input rst_n_A ,
//B clock domain
input clk_B ,
input rst_n_B ,
//input plus(A)
input i_puls_a ,
//output plus(B)
output reg o_puls_b
);
//------------------------------ Reg & Wire --------------------------
reg signal_a ; // A clock domain
reg signal_b1_a1 ; // A clock domain
reg signal_b1_a2 ; // A clock domain
reg signal_b ; // B clock domain
reg signal_b_b1 ; // B clock domain
reg signal_b_b2 ; // B clock domain
//-------------------------------- logic -----------------------------
always @(posedge clk_A or negedge rst_n_A)
begin
if(!rst_n_A)
signal_a <= 1'b0;
else if(i_puls_a == 1'b1)
signal_a <= 1'b1;
else if(signal_b1_a2 == 1'b1)
signal_a <= 1'b0;
end
always @(posedge clk_B)
begin
signal_b <= signal_a ;
signal_b_b1 <= signal_b ;
signal_b_b2 <= signal_b_b1 ;
end
always @(posedge clk_A)
begin
signal_b1_a1 <= signal_b_b1 ;
signal_b1_a2 <= signal_b1_a1;
end
always @(posedge clk_B or negedge rst_n_B)
begin
if(!rst_n_B)
o_puls_b <= 1'b0;
else if(signal_b_b1 && !signal_b_b2)
o_puls_b <= 1'b1;
else
o_puls_b <= 1'b0;
end
endmodule
電平同步
以上的思想是脈沖跨時(shí)鐘域,其實(shí)也可以通過電平跳轉(zhuǎn)的方法跨時(shí)鐘域:

sync_pluse.png
- 在A時(shí)鐘域檢測脈沖上升沿,然后通過改變電平Z狀態(tài)的方式傳送給B時(shí)鐘域,然后通過檢測電平Z狀態(tài)是否發(fā)生變化來判斷A時(shí)鐘域是否有脈沖。
- 電平同步比脈沖同步更節(jié)省資源,電路更加簡單,效果也不比脈沖同步差。
來源:馬哥 - Marin
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。