目录
一、基本原理
在数字芯片设计中常常涉及到不同的时钟域,而在实际应用场景下,对于某一时钟域的脉冲信号需要同步到另一时钟域中,主要有以下两种脉冲同步情景:
(1)慢时钟域到快时钟域
这里的快慢指的是频率大小,频率小的时钟下的脉冲同步到频率大的时钟下,原理如图:
(2)快时钟域到慢时钟域
示意图如下:
二、脉冲同步电路例题
1、题目:
从A时钟域提取一个单时钟周期宽度脉冲,然后在新的时钟域B建立另一个单时钟宽度的脉冲。A时钟域的频率是B时钟域的10倍;A时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。电路的接口如下图所示。data_in是脉冲输入信号,data_out是新的脉冲信号;clk_fast是A时钟域时钟信号,clk_slow是B时钟域时钟信号;rst_n是异步复位信号。
详解如下:
主要思路:(题中未说明)用寄存器实现打拍,利用判断输入是否是高电平(脉冲态)来推导是否需要翻转,然后用一个异或来判断脉冲何时结束。
2、原理示意图:
这里没有按照题中严格的10:1的频率比例,大致示意了从快时钟到慢时钟的变化,打两拍之后翻转。一个周期的脉冲信号,pulse翻转一次,即data_a=001,产生一个clk_slow时钟周期的脉冲。
3、题解:
module pulse_detect(
input clk_fast ,
input clk_slow ,
input rst_n ,
input data_in ,
output dataout
);
reg [2:0] data_a; //打两拍
reg pulse;
always @(posedge clk_slow or negedge rst_n) begin
if(!rst_n) data_a <= 0 ;
else
data_a <= {data_a[1:0],pulse}; //移位两次,当data_a[1] = 1时,输出一个脉冲
end
always @(posedge clk_fast or negedge rst_n ) begin
if(!rst_n) pulse <=0;
else begin
pulse <=data_in? ~pulse:pulse;
//当data_in为1时,pulse翻转为1,一个脉冲在两拍之后输出
//随后一个周期(连续两个周期),若in=0,则不变化,只输入也只输出一个脉冲,若in=1,会再次翻转,
//此时data_a为010,将会有连续两个周期的脉冲高电平,同理若输出in一直为1,则持续性输出高电平
end
end
assign dataout = data_a[2]^data_a[1];
//采用异或进行脉冲判断,相异时为脉冲输出,因为此时pulse发生了翻转,知道pulse停止翻转,即in=0,脉冲结束。
//要记录in的所有边沿
endmodule
4、一些问题和思考:
a、在这一题中,如果两个脉冲相隔很近,可能出现脉冲丢失。比如,输入两个周期为1,间隔为1的脉冲,此时可能无法识别到第二个脉冲,当脉冲移位两拍后,输出的一个脉冲还没有结束。
b、而类似的,如果在脉冲出现的三个周期内,慢时钟上升沿并没有出现,则无法同步脉冲信号,并且如果输入周期脉冲为2个周期,可能也无法产生输出脉冲。如图:
总而言之,我觉得在脉冲同步时,时钟域频率相差越大越容易产生信号丢失,而脉冲间隔越小也越容易产生信号缺失。这一部分应该会有相应的解决方法,之后如果学习到了再来补充。
结束