UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor gstorto
Visitor
3,807 Views
Registered: ‎08-11-2017

Should I set ASYNC_REG attribute to data FF in mux synchronizer?

I have implemented the following design:

synctechf9.png

With the following remarks:

 

  • A1 -> B1 is defined as a false path
  • B1 and B2 are ASYNC_REGs
  • A2 -> B3 is defined as a multicycle of 2 (setup) and 1 (hold) CLKB
  • data does not change until the control signal is properly ack by CLKB -> CLKA domain.

I have the following questions:

 

  1. Should B3 be defined as an ASYNC_REG, or is it a useless constraint?
  2. I have seem some implementations where the multicycle -start/-end parameter depends on F_CLKA and F_CLKB, but I think it should be always defined in F_CLKB units in this design. Am I right?

 

0 Kudos
6 Replies
Voyager
Voyager
3,746 Views
Registered: ‎06-24-2013

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

Hey @gstorto,

 

Should B3 be defined as an ASYNC_REG, or is it a useless constraint?

The ASYNC_REG attribute basically tells the tools to minimize the path time between two flip-flops and to make sure that they are not removed or reordered. The purpose here is to ensure there is enough time for a metastable event to resolve. Note that it has to go on both FFs to be effective.

 

If your recirculation mux synchronizer is done properly, then there is no metastability between A2 and B3, but even if there was, the mux would still separate the two FFs, so no purpose here to use ASYNC_REG. You might still want to put a DONT_TOUCH on it so that it doesn't get optimized away (if that is a problem).

 

I have seem some implementations where the multicycle -start/-end parameter depends on F_CLKA and F_CLKB, but I think it should be always defined in F_CLKB units in this design. Am I right?

Given that A1 and A2 will latch at the same CLKA cycle, the synchronization delay is between B1 and B2 so the reference clock here is CLKB.

 

Hope this helps,

Herbert

-------------- Yes, I do this for fun!
Historian
Historian
3,721 Views
Registered: ‎01-23-2009

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

As @hpoetzl said, the only flip-flops that can have the ASYNC_REG are B1 and B2.

 

But I worry about your constraints.

 

A1 to B1 isn't truly a false path - it does have requirements. For example if the routing is so long between A1 and B1, then that delay, in conjunction with the 1-2 clock periods of CLK_B may be long enough so that the next change on A2 happens before the B3 flip-flop properly samples the "stable" old signal at A2. With a false path from A1 to B1, the placement and routing is completely unconstrained - theoretically allowing any routing delay on this path.

 

To prevent all of this, you should really be using set_max_delay -datapath_only constraints - both between A1 and B1 as well as between A2 and B3. The latter is not a multicycle path, and any true "path" analysis it does between these two unrelated clocks is meaningless.

 

Avrum

Visitor gstorto
Visitor
3,701 Views
Registered: ‎08-11-2017

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

Hello @avrumw,

 

About A1 -> B1 being defined as a false path, I think it is safe, because A2 will change only when the ctrl signal is properly ack by CLKB domain. That will take A1 -> B1 -> B2 -> (Comb -> Resync to CLKA). Note that the group between parenthesis is not depicted in the diagram, but it is indeed implemented.

 

Concerning the multicycle, I think you are correct. This design is used for both related clocks, coming from the same PLL, as well as completely unrelated (no phase relation). Would you think I should set two different types of constraints: one for async clocks and another for related clocks?

 

In the first case (related clocks), I would maintain the multicycle of 2 CLKB (setup) and 1 (hold). On the other hand, I am not sure what to define as set_max_delay -datapath_only for A2 -> B3, I would think it should be no be longer than CLKB period (B1 -> B2) propagation. Am I right?

0 Kudos
Voyager
Voyager
3,685 Views
Registered: ‎06-24-2013

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

Hey @gstorto,

 

... defined as a false path, I think it is safe, because A2 will change only when the ctrl signal is properly ack by CLKB domain ...

The problem here is that in theory a false path can have arbitrary length and if you have two or more of them (data and control signals for example) they might differ dramatically in the timing path. So for example, the control signals might have a routing path of slightly less than one clock cycle while the data path might end up with a routing path of several clock cycles or vice versa, so if you want to do it properly, the set_max_delay is the way to go.

 

Note that in reality the path lengths will not be that different and the corner cases are rare, but there is no guarantee that it won't happen without you ever noticing.

 

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!
Visitor gstorto
Visitor
3,670 Views
Registered: ‎08-11-2017

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

Hello @hpoetzl,

 

I don't think a set_max_delay should be applied to A1 -> B1 path, should src_send/dst_req latency not be a problem to the design. And that is exactly what xpm_cdc_handshake constraints do:

 

module xpm_cdc_handshake #(
  // Module parameters
  parameter integer DEST_EXT_HSK   = 1,
  parameter integer DEST_SYNC_FF   = 4,
  parameter integer SIM_ASSERT_CHK = 0,
  parameter integer SRC_SYNC_FF    = 4,
  parameter integer VERSION        = 0,
  parameter integer WIDTH          = 1
) (
  // Module ports
  input  wire             src_clk,
  input  wire [WIDTH-1:0] src_in,
  input  wire             src_send,
  output wire             src_rcv,

  input  wire             dest_clk,
  output wire [WIDTH-1:0] dest_out,
  output wire             dest_req,
  input  wire             dest_ack
);

 

set src_clk  [get_clocks -quiet -of [get_ports src_clk]]
set dest_clk [get_clocks -quiet -of [get_ports dest_clk]]

set src_clk_period  [get_property -quiet -min PERIOD $src_clk]
set dest_clk_period [get_property -quiet -min PERIOD $dest_clk]

set xpm_cdc_hs_width [llength [get_cells dest_hsdata_ff_reg[*]]]

if {$src_clk != $dest_clk} {
    if {$xpm_cdc_hs_width <= 100} {
        set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}] -datapath_only
        set_bus_skew  -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr {$dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff}]
    } else {
        set_max_delay -from [get_cells src_hsdata_ff_reg*] -to [get_cells dest_hsdata_ff_reg*] [expr min ($src_clk_period, $dest_clk_period)] -datapath_only
    }
}

The set_max_delay and set_bus_skew are applied to the module data path only, (A2 -> B3) in my case. Internally, to resynchronize the src_send/dst_req signals, it calls a xpm_cdc_single:

 

  xpm_cdc_single #  (
    .DEST_SYNC_FF   (DEST_SYNC_FF  ),
    .SRC_INPUT_REG  (0             ),
    .VERSION        (VERSION       )
  ) xpm_cdc_single_src2dest_inst (

    .src_clk        (src_clk       ),
    .dest_clk       (dest_clk      ),
    .src_in         (src_sendd_ff  ),
    .dest_out       (dest_req_sync )
  );

And when checking xpm_cdc_single constraints, we find that:

 

set src_clk  [get_clocks -quiet -of [get_ports src_clk]]
set dest_clk [get_clocks -quiet -of [get_ports dest_clk]]

if {$src_clk != $dest_clk} {
    set_false_path -to [get_cells syncstages_ff_reg[0]]
}

Which corresponds to the false path I want to apply between A1 -> B1. I confess though that my thread title is misleading when I say I have a multiplexer synchronizer, when it is in fact a handshake CDC.

 

All files are in Xilinx/Vivado/<version>/data/ip/xpm/xpm_cdc/ if you want to take a look.

 

I have one question though:

 

  1. I don't quite understand how the set_bus_skew to "dest_clk_period * xpm_cdc_hs_num_s2d_dsync_ff" cannot be satisfied with a set_max_delay -datapath_only to the same value. I though that the set_bus_skew limits the maximum delta of datapath propagation delay between any pairs of wires. Mathematically speaking:

 

max( abs(t_p(bus[i]) - t_p(bus[j])) ) <= dest_clk_period * xpm_cdc_hs_num_s2d_dsync_ff; any i, j 
t_p -> datapath propagation delay
bus -> nets between -to and -from

As max(t_p) = (dest_clk_period * $xpm_cdc_hs_num_s2d_dsync_ff) by set_max_delay and min(t_p) = 0 (ideal case), the bus_skew will always be satisfied. Is my definition of set_bus_skew wrong?

 

 

0 Kudos
Voyager
Voyager
3,666 Views
Registered: ‎06-24-2013

Re: Should I set ASYNC_REG attribute to data FF in mux synchronizer?

Hey @gstorto,

 

I don't think a set_max_delay should be applied to A1 -> B1 path, should src_send/dst_req latency not be a problem to the design.

I didn't say that you should or must apply a set_max_delay, all I said was that instead of a set_false_path you should use set_max_delay instead unless you are lazy and adventurous.

 

Is my definition of set_bus_skew wrong?

UG835 explains:

 

Set the bus skew requirement on bus signals that cross clock domains. The bus skew constraint defines the maximum spread between the fastest and slowest signals of the bus.

 

In order to not over constrain the skew requirement, the bus skew value should be about the smallest period of the two clock domains. This will prevent multiple data captures by the destination clock domain.

 

Best,

Herbert

-------------- Yes, I do this for fun!
0 Kudos