马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
1.首先明白输入信号为什么要寄存
如果信号来自同一时钟域,各模块的输入不需要寄存。只要满足建立时间,保持时间的约束,可以保证在时钟上升沿到来时,输入信号已经稳定,可以采样得到正确的值。
如果这个输入信号来自异步时钟域(比如FPGA芯片外部的输入),必须寄存两拍。第一拍将输入信号同步化,同步化后的输出可能带来建立/保持时间的冲突,产生亚稳态。需要再寄存一拍,减少亚稳态带来的影响。
如果这个输入信号来自于同一时钟域且需要用到跳变沿,需要寄存一拍。否则时序报告多半会报clock skew > data delay,造成建立/保持时间的冲突。
2.简单的脉冲同步器设计
如下实现脉冲从慢时钟域同步到快时钟域:
1)将src_clk时钟域的输入脉冲转换为src_clk时钟域的电平信号src_state
2) 对src_data电平信号进行打拍(一般打两拍)同步到dst_clk时钟域
3)对dst_clk时钟域的电平信号进行边沿检测,产生dst_clk时钟域的脉冲
3.这里以简单的代码设计题目进行理解
从A时钟域提取一个单时钟周期宽度脉冲,然后在新的时钟域B建立另一个单时钟宽度的脉冲。 A时钟域的频率是B时钟域的10倍;A时钟域脉冲之间的间隔很大,无需考虑脉冲间隔太小的问题。data_in是脉冲输入信号,data_out是新的脉冲信号;clk_fast是A时钟域时钟信号,clk_slow是B时钟域时钟信号;rst_n是异步复位信号。
`timescale 1ns/1ns
//实现从快时钟域到慢时钟域的脉冲信号同步
module pulse_detect(
input clk_fast ,
input clk_slow ,
input rst_n ,
input data_in ,
output dataout
);
//Toggle电路实现在输入信号为高电平时输出信号翻转
reg Toggle;
always @ (posedge clk_fast or negedge rst_n)
begin
if(!rst_n)
Toggle <= 0;
else if(data_in)
Toggle <= ~Toggle;
else
Toggle <= Toggle;
end
//对输出的Toggle信号打两拍(防止出现亚稳态 ),同步到另一个时钟域。
reg Toggle_r1,Toggle_r2;
always @ (posedge clk_slow or negedge rst_n)
begin
if(!rst_n)
begin
Toggle_r1 <= 0;
Toggle_r2 <= 0;
end
else
begin
Toggle_r1 <= Toggle;
Toggle_r2 <= Toggle_r1;
end
end
//最后一级寄存器+异或门 组成边沿检测电路
reg Toggle_r3;
always @ (posedge clk_slow or negedge rst_n)
begin
if(!rst_n)
begin
Toggle_r3 <= 0;
end
else
begin
Toggle_r3 <= Toggle_r2;
end
end
assign dataout = Toggle_r3 ^ Toggle_r2;
endmodule
|