要将快时钟域的脉冲信号同步到慢时钟域的信号常采用握手的机制实现,所以该电路又常被称为握手电路,其设计思路为:首先在慢时钟域下将快时钟域的脉冲转换为电平信号,然后把电平信号同步到快时钟域,同步完成后的信号要反馈回快时钟域,快时钟域接收到该信号后给控制信号,原来的电平信号被拉低。
![](https://img.kancloud.cn/fe/3d/fe3d6d451b461949d7d37353dd1cd582_720x252.png)
图 :快时钟域到慢时钟域准换电路
如图所示,pls\_fast为输入的快时钟域的脉冲信号,红框部分是脉冲转电平结构,exp寄存器输出的电平信号被exp\_d1和exp\_d2同步到慢时钟域(蓝框部分),exp\_d2再打一拍造出慢时钟域的脉冲信号。exp\_d2信号需要反馈回快时钟域,根据数字设计的基本原则,再采用两级同步器lev1和lev2(紫框部分)将信号抓取回来作为控制信号将原来高电平信号拉低,握手完成。
~~~verilog
module pls_sync_f2s(
rst_n ,
clka ,
clkb ,
pls_a ,
pls_b
);
//parametr
parameter DLY = 1 ;
//input output
input rst_n ;
input clka ;
input clkb ;
input pls_a ;//pluse in
output pls_b ;//pluse out
//-----------------------------
//--signal
//-----------------------------
reg exp ;
reg exp_d1 ;
reg exp_d2 ;
reg exp_d3 ;
reg lev1 ;
reg lev2 ;
//-----------------------------
//--main circuit
//-----------------------------
//pluse 2 level
always@(posedge clka or negedge rst_n)
begin
if(!rst_n)
exp <= 1'b0 ;
else if(lev2)
exp <= #DLY 1'b0 ;
else if(pls_a)
exp <= #DLY 1'b1 ;
end
always@(posedge clka or negedge rst_n)
begin
if(!rst_n) begin
lev1 <= 1'b0 ;
lev2 <= 1'b0 ;
end
else begin
lev1 <= #DLY exp_d2 ;
lev2 <= #DLY lev1 ;
end
end
always@(posedge clkb or negedge rst_n)
begin
if(!rst_n) begin
exp_d1 <= 1'b0 ;
exp_d2 <= 1'b0 ;
exp_d3 <= 1'b0 ;
end
else begin
exp_d1 <= #DLY exp ;
exp_d2 <= #DLY exp_d1 ;
exp_d3 <= #DLY exp_d2 ;
end
end
assign pls_b = exp_d2 & (~exp_d3) ; //posedge pluse detect
endmodule
~~~
仿真波形如图6所示。
![](https://img.kancloud.cn/37/1c/371c1ab73398c0622c7941bd4505a632_720x160.png)
## **快时钟域到慢时钟域转换电路的局限性**
握手电路的局限性在于快时钟域产生的脉冲信号的间隔不能太短,否则会造成慢时钟域同步的脉冲丢失,如图6所示,红色方框内快时钟域的脉冲没有被同步到慢时钟域。