对于脉冲,我们使用脉冲同步器,对于电平信号,我们使用2-flop同步器,但如果信号可以是脉冲或电平行为呢?有办法同步吗?
是的,你可以,但解决方案需要基于输入脉冲相对于输出时钟的宽度。
当输出时钟非常慢,并且您有脉冲时,您需要添加一个在输入时钟域中工作的内联脉冲拉伸器。拉伸由下面stretch_out的位宽定义,并且"必须"大于输出clk域中的一个时钟。
reg [3:0] stretch_out;
always @ (posedge inclk)
begin
stretch_out <= in_signal ? 4'b1111 : {stretch_out[2:0],1'b0};
end
现在你可以使用你的双触发器同步器了。
reg [1:0] out_sync;
always @ (posedge outclk)
begin
out_sync <= {out_sync[0],stretch_out[3]};
end
这将同步电平和脉冲从一个快域到一个慢域。
唯一的问题是,您将添加比通常的两次翻牌延迟更多的延迟。
您可以使用目标域中的信号异步设置,使用双触发器同步,然后检测上升沿。短脉冲和长脉冲都能工作。
// Prevent DRC violations if using scan
wire in_signal_n = scan_mode ? 1'b1 : !signal_in;
// Following code creates a flop with both async setb and resetb
reg sig_n_async;
always @ ( posedge outclk or negedge reset_n or negedge in_signal_n)
if (!reset_n)
sig_n_async <= 0;
else if (!in_signal_n)
sig_n_async <= 1;
else
sig_n_async <= 0;
// Synchronizer
reg [1:0] out_sync;
always @ (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync <= 0;
else
out_sync <= {out_sync[0],sig_n_async};
// Rising edge
reg out_sync_del;
always @ (posedge outclk or negedge reset_n)
if (!reset_n)
out_sync_del <= 0;
else
out_sync_del <= out_sync[1];
wire signal_out = out_sync[1] & !out_sync_del;