简体   繁体   English

脉冲和电平信号的时钟域交叉

[英]Clock Domain Crossing for Pulse and Level Signal

For pulse we use Pulse-Synchronizer and for Level Signal we use 2-flop synchronizer but what if the signal can be of Pulse or Level behaviour. 对于脉冲,我们使用脉冲同步器,对于电平信号,我们使用2-flop同步器但是如果信号可以是脉冲或电平行为怎么办。 Is there any way to synchronize that? 有没有办法同步?

Yes, you can but the solution needs to be based on the width of the input pulse relative to the output clock. 是的,您可以,但解决方案需要基于输入脉冲相对于输出时钟的宽度。

When the output clock is very slow, and you have a pulse, you need to add an inline pulse stretcher that operates in the input clock domain. 当输出时钟非常慢并且您有脉冲时,您需要添加一个在输入时钟域中运行的内联脉冲展宽器。 The stretch is defined by the bit width of stretch_out below and "MUST" be greater than one clock on the output clk domain. 拉伸由下面的stretch_out的位宽定义,并且“MUST”大于输出clk域上的一个时钟。

reg [3:0] stretch_out;
always @ (posedge inclk)
begin 
   stretch_out <= in_signal ? 4'b1111 : {stretch_out[2:0],1'b0}; 
end

Now you can just use your double flop synchronizer. 现在您可以使用双翻转同步器。

reg [1:0] out_sync;
always @ (posedge outclk)
begin 
    out_sync <= {out_sync[0],stretch_out[3]};
end

This should synchronize a level and pulse from a fast domain into a slow domain. 这应该将来自快域的电平和脉冲同步到慢域。

The only issue, is that you will be adding more than just your usual two flop latency. 唯一的问题是,你将增加的不只是通常的两个翻牌延迟。

You could asynchronously set using the signal in the destination domain, synchronize using dual flops, and then detect the rising edge. 您可以使用目标域中的信号进行异步设置,使用双触发器进行同步,然后检测上升沿。 Should work for both short pulses and long levels. 应该适用于短脉冲和长脉冲。

// 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM