cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
8,149 Views
Registered: ‎05-29-2015

Using Synchronizers

Hi Guys,


Currently I am working on a project with Vivado 2014.3.1 & came across a cdc issue as shown in figure below.

i.e. timing violation between "up_xfer_toggle_reg" and "d_xfer_toggle_m1_reg" .

CDC_0.jpg

 

So used " xfer_vio " block as a synchronizer, as shown below.

 

CDC.jpg

(Is the usage correct ? Or should I use 2FF synchronizer : Because, had read online that usually 2FF design is used )


Due to the design which I used, as showed in the 2nd figure(above); timing violations got reduced reduced / number of failing points reduced.

 

My doubt:
Is the implementation of synchronizer proper ?
(Or should I use 2FF synchronizer)
If the implementation is right, can I assign the clock as asynchronous using constraint for removing the timing violations ?

If the implementation is NOT right, can you please specify any other way of doing it.

 

Thanks in advance,

Regards,

ananya

 

0 Kudos
4 Replies
Highlighted
Moderator
Moderator
8,094 Views
Registered: ‎02-16-2010

Re: Using Synchronizers

yes. Please try 2FF (or) 3FF synchronization. If you check some of the Xilinx IPs like GT wizard, you can find some synchronization modules in the example design. You can use them for your design.
------------------------------------------------------------------------------
Don't forget to reply, give kudo and accept as solution
------------------------------------------------------------------------------
7,900 Views
Registered: ‎05-29-2015

Re: Using Synchronizers

 

 

ananya

Tags (1)
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
7,894 Views
Registered: ‎07-21-2014

Re: Using Synchronizers

Hi,

"How can I proceed when the data path is between multi-bit regs?"

I assume here you are asking question specific to timing constraints and analysis of this path.
If you have taken care about crossing clock domain, you can use path exception for this.
Please following forum thread for more information about this.
https://forums.xilinx.com/t5/Timing-Analysis/Timing-Exception-for-Synchronous-Clock-Domain-Crossing/td-p/671037

-Shreyas
----------------------------------------------------------------------------------------------
Try to search answer for your issue in forums or xilinx user guides before you post a new thread.

Kindly note- Please mark the Answer as "Accept as solution" if information provided solves your query.
Give Kudos (star provided in right) to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
Highlighted
7,882 Views
Registered: ‎05-29-2015

Re: Using Synchronizers

Thanks for pointing me to those threads Shreyas.

 

By multi-bit I was referring to 'bus'.

Have used fifo for this purpose earlier(for other path). 

Am not sure which one(fifo / FF for each bit in the reg)  should be used [between regs 'd_data_cntrl' & 'up_xfer_data'] .

 

Can you please suggest ? 

 

module d2l_l2d_up_xfer_cntrl (
  up_rstn,
  up_clk,
  up_data_cntrl,
  up_xfer_done,

  d_rst,
  d_clk,
  d_data_cntrl);

  parameter     DATA_WIDTH = 8;
  localparam    DW = DATA_WIDTH - 1;

  input           up_rstn;
  input           up_clk;
  input   [DW:0]  up_data_cntrl;
  output          up_xfer_done;

  input           d_rst;
  input           d_clk;
  output  [DW:0]  d_data_cntrl;

  // internal registers
  reg     [ 5:0]  up_xfer_count = 'd0;
  reg             up_xfer_done = 'd0;
  reg             up_xfer_toggle = 'd0;
  reg     [DW:0]  up_xfer_data = 'd0;
  reg             d_xfer_toggle_m1 = 'd0;
  reg             d_xfer_toggle_m2 = 'd0;
  reg             d_xfer_toggle_m3 = 'd0;
  reg     [DW:0]  d_data_cntrl = 'd0;

  // internal signals
  wire            d_xfer_toggle_s;

  always @(negedge up_rstn or posedge up_clk) begin
    if (up_rstn == 1'b0) begin
      up_xfer_count <= 'd0;
      up_xfer_done <= 'd0;
      up_xfer_toggle <= 'd0;
      up_xfer_data <= 'd0;
    end else begin
      up_xfer_count <= up_xfer_count + 1'd1;
      up_xfer_done <= (up_xfer_count == 6'd1) ? 1'b1 : 1'b0;
      if (up_xfer_count == 6'd1) begin
        up_xfer_toggle <= ~up_xfer_toggle;
        up_xfer_data <= up_data_cntrl;
      end
    end
  end

  assign d_xfer_toggle_s = d_xfer_toggle_m3 ^ d_xfer_toggle_m2;

 sync_block 2FF_sync 
        (
           .clk             (d_clk),
           .data_in         (up_xfer_toggle),
           .data_out        (d_q)
        );

  always @(posedge d_clk) begin
    if (d_rst == 1'b1) begin
      d_xfer_toggle_m1 <= 'd0;
      d_xfer_toggle_m2 <= 'd0;
      d_xfer_toggle_m3 <= 'd0;
      d_data_cntrl <= 'd0;
    end else begin
//      d_xfer_toggle_m1 <= up_xfer_toggle;

      d_xfer_toggle_m1 <= d_q;
      d_xfer_toggle_m2 <= d_xfer_toggle_m1;
      d_xfer_toggle_m3 <= d_xfer_toggle_m2;
      if (d_xfer_toggle_s == 1'b1) begin
        d_data_cntrl <= up_xfer_data;
      end
    end
  end
endmodule

Regards,

ananya

 

 

 

0 Kudos