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: 
12,551 Views
Registered: ‎01-22-2015

Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

As I understand, the key lines of a VHDL component that describes a two-flip-flop (2FF) synchronizer could be the following (where siga is being crossed from the clka-domain into the clkb-domain as sigb):

 

  1. signal sig_meta: std_logic;
  2. attribute ASYNC_REG : string;
  3. attribute DONT_TOUCH : string;
  4. attribute ASYNC_REG of sig_meta: signal is "TRUE";
  5. attribute DONT_TOUCH of sig_meta: signal is "TRUE";
  6.  
  7. 2FF: process (clkb)
  8. begin
  9.    if rising_edge(clkb) then
  10.        sig_meta <= siga;        --sig_meta may be metastable
  11.        sigb <= sig_meta;        --but sigb will be stable (probably)
  12.    end if;        
  13. end process 2FF;

 

Does the code look correct?  

More specifically are the attribute lines correct?

Are the attribute lines sufficient to place the ASYNC_REG=TRUE property on all registers of the 2FF where it is needed?

 

I am asking because in Vivado v2014.2, the resulting implementation shows that registers for siga, sig_meta, and sigb are all spaced many slices apart.

24 Replies
Teacher muzaffer
Teacher
12,540 Views
Registered: ‎03-31-2012

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

You should place async_reg attribute on both sig_meta and sigb registers (in general on all registers in the sync chain). Also I am pretty sure async_reg generates an implicit dont_touch so it's not necessary but can't hurt.

 

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
Historian
Historian
12,526 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

@muzaffer is correct in both his points:

  - the ASYNC_REG should be on both flip-flops

  - the ASYNC_REG implies a DONT_TOUCH

 

The ASYNC_REG does a number of things:

  - sets DONT_TOUCH on the registers

  - for any pair of FFs that are connected directly Q to D that both have the ASYNC_REG property on them, the placer must keep these two FFs "close" together. If possible (as in not illegal due to control sets) they will be placed in the same slice

  - helps the tool identify clock crossing paths for analysis (like the report_synchronizer_mtbf command)

  - instructs gate level simulation not to set the FF to X when the setup/hold of the flip-flop is violated (which is the normal behavior for FFs without the ASYNC_REG property).

 

So since you only have the ASYNC_REG on one FF, the tools do not identify a pair of FFs to keep together.

 

None of these constraints affect the placement of the sig_meta FF wrt. to the siga FF. If you want to constrain this path's length (and, for many synchronizers you do want to do so), then you do it with a set_max_delay -datapath_only constraint.

 

Avrum

12,485 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Thanks muzaffer and avrum for quick and thorough answers.

 

For the record, I added the following line to the code and found that registers for sig_meta and sigb are now implemented within the same slice.

                   attribute ASYNC_REG of sigb: signal is "TRUE";

 

However, in Vivado v2014.2, I found it necessary to remove the DONT_TOUCH lines.  If I left these lines of code in, then the sig_meta and sigb registers were implemented to be many slices apart.  This is unexpected, both because of your comments and because AR#61018 says that the DONT_TOUCH lines are a necessary work-around for this version of Vivado.  No worries, probably time for me to upgrade my Vivado anyway.

 

One more question please.  AR#64019 shows a problem with applying the ASYNC_REG property using HDL.  In AR# 64019 it is stated:

 

 The ASYNC_REG property can only be applied on cells.  In the example above it is applied on net signals that are connecting between register instances and so is ignored.

 

I don't fully understand this statement.  When using HDL commands to set the ASYNC_REG property, the distinction between cells(registers?) and signals is a little blurry (in my mind).  That is, in my VHDL example code, both sig_meta and sigb are called VHDL "signals", and my "attribute" lines of VHDL code seem to be applying the ASYNC_REG property to these signals - and not to cells.  Please further explain AR#64019 and comment on my confusion.

0 Kudos
Scholar drjohnsmith
Scholar
12,457 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

async_reg nether worked up to 2015.4,

   or should I say results were variable , some time got registers together, some times not.

 

which as far as I am concerned menas async_reg does not work.

 

if we find a way that does work where one can put the attribute in the code, I'd make a component with the attribute in so it could just be instantiated.

 

as it is, had to tcl down to the register with constraints, not very re usable.

 

please say this is fixed, and the constraint int he code can work, and I'll be hapy.

 

0 Kudos
12,285 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

drjohnsmith: 

Thanks for sharing your experience with setting the ASYNC_REG property in Vivado.

 

I confirm that using VHDL attribute commands to set ASYNC_REG=TRUE  in Vivado v2014.2 gives variable results.  As you say, sometimes it places the 2FF synchronizer registers in the same slice and sometimes it does not.  I also observe (in v2014.2) that these VHDL attribute commands *sometimes* cause constraints to be placed in the XDC file.  These constraints looks like the following:

 

set_property ASYNC_REG false [get_cells cmr/rx/sdi_s/sig_meta_reg]

 

Note that this automatically generated constraint is setting ASYNC_REG to FALSE, while my VHDL attribute command is setting it to TRUE.  -very strange and getting kinda scary!!

 

When you say "tcl down" (I like that phrase), I assume that you mean placing Tcl-like constraints (similar to set_property constraint shown above) into the XDC file? 

 

Have you found that XDC file constraints are a reliable method of setting the ASYNC_REG property in the older versions of Vivado?

0 Kudos
Scholar drjohnsmith
Scholar
12,263 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

HI

 

yes had good results with the tcl commands for setting registers,

   

but

 

just way too much faffle,   as names of registers keep changing depoending on where the block of re usable code is used.

   

My 'answer' was to instantiate the iserdes block....  as my input signals were way slower than the clock I had, ..

 

crude, but worked and client was happy with the answer....

 

     

0 Kudos
12,215 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Synchronizers are extremely important to FPGA work – and keeping the registers of the synchronizer close together using "ASYNC_REG=TRUE" is absolutely necessary for making synchronizers work properly.

 

I don’t think that I’m overstating these facts.

 

If the ASYNC_REG property is not being implemented reliably by Vivado Implementation, then I think this is a big deal.

 

I’m kinda disappointed that mentors/teachers/moderators aren’t saying more in this post.

0 Kudos
Scholar drjohnsmith
Scholar
12,205 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

dont worry too much about these forums

 

the suport team is back on the paid product support, 

    we all help ourselfs now...

 

async_reg 'works' as far as I see, but not in the way you or I want , i.e. in the vhdl, 

    the admins would answer, yes it works with tcl...

 

tcl fixes everything ..

 

 

0 Kudos
Scholar drjohnsmith
Scholar
12,199 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

tye official answer from xilinx

 

http://www.xilinx.com/support/answers/64019.html

 

basicaly , its expcted to be broken, but heres a work around with tcl...

 

Scholar markcurry
Scholar
10,448 Views
Registered: ‎09-16-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

 

That AR is a rather awful excuse for why the attribute doesn't work. The attribute "can only be applied on cells"?  What is this 1990?  We're designing RTL here, folks.  Not schematic capture, instatiating primitives.

 

The XDC workaround is klunky - to difficult to manage and insure the attribute gets applied everywhere.  I suppose with a scoped XDC I might be able to get things to work, but the attribute was the best solution.    Xilinx should fix this.

 

Regards,

 

Mark

 

0 Kudos
10,412 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

drjohnsmith:

 

Based on your last posts, I put together the following method for setting the ASYNC_REG property of registers used in the 2FF synchronizer:

 

1) Created a VHDL component to implement the 2FF synchronizer and called it SYNC_2FF.vhd. 

2) Inside SYNC_2FF.vhd, I used the "2FF:" process shown in my original post.

3) Inside SYNC_2FF.vhd, I removed all the attribute lines (ie. the lines that I was previously using to set ASYNC_REG).

4) Instantiated SYNC_2FF in my project as needed

5) Ensured that signal names, sig_meta and sigb, used in SYNC_2FF are not used elsewhere in the project <<important

6) Added the following constraints to the XDC file:

    set_property ASYNC_REG TRUE [get_cells -hierarchical *sigb_reg]

    set_property ASYNC_REG TRUE [get_cells -hierarchical *sig_meta_reg]

 

After running synthesis and implementation, I opened the implemented design and inspected all my instances (24ea) of SYNC_2FF.  I found that the sigb and sig_meta registers were always located in the same slice - just what is needed!

 

Note the use of wildcards in the set_property constraints.  These wildcards [ together with step-5) ] allow the two set_property constraints to do everything we were trying to do with the two attribute lines in VHDL - and make it unnecessary to "Tcl-down (as you say)" to each separate instance of SYNC_2FF.

 

I will continue testing this method and let you know (via this post) if problems arise.

 

....many safe and happy journeys to you and your tardis

 

 

PS. thanks markcurry for your comments

0 Kudos
Historian
Historian
10,400 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

I looked at the AR. I think we need to make sure we are keeping this in context.

 

The AR says that the ASYNC_REG property doesn't work in this case - this is a specific case where the code is instantiating FDRE cells directly in a generate loop. Apparently (and I am not a VHDL expert) you cannot set a property on a primitive that is instantiated in a generate loop.

 

When using inference of registers, you use a VHDL signal as the signal that will become the register (the signal george when used in a proper clocked process will create the flip-flop george_reg). My understanding is that you can set the ASYNC_REG property on george, and that will propagate to the cell george_reg.

 

In the AR's case, they were setting the ASYNC_REG attribute on the signals that will become the nets connecting these instantiated primitive cells together, which doesn't do anything since the attribute needs to be applied to cells. The attribute was not being applied to the instantiated cells themselves (which can't be done in a generate loop). It is clearly also not being applied to a signal that infers the flip-flops, since they aren't inferring flip-flops, they are directly instantiating the FDRE).

 

So, the AR is saying that for this particular coding style, the only option is to do it in Tcl.

 

But if you are inferring flip-flops (which is probably the more common case), this AR doesn't apply.

 

Now, there may be additional problems associated with the ASYNC_REG property in certain versions of the tool (I haven't personally seen any), but we need to be careful not to extrapolate the case shown in this AR to the statement that "ASYNC_REG cannot be applied in the RTL code".

 

Avrum

0 Kudos
10,384 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

avrumw:

 

Thanks for clarifying the AR.  After rereading it, I see that it is for a rather special case of VHDL coding.

 

I believe that the major complaint in this post is that for the common case of "inference of registers", the VHDL method (an attribute statement) for setting the ASYNC_REG property is not working reliably.  Specifically, I have observed it fail many times in Vivado v2014.2.  drjohnsmith says it works unreliably up thru Vivado v2015.4.

 

For these older versions of Vivado, the consensus of this post seems to be that XDC(Tcl) constraints are a reliable method of setting the ASYNC_REG property.   Do you see anything wrong with the XDC(Tcl) constraints described in my last post for setting the ASYNC_REG property?

0 Kudos
Historian
Historian
10,287 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Do you see anything wrong with the XDC(Tcl) constraints described in my last post for setting the ASYNC_REG property?

 

With all the restrictions you mentioned, it should be OK, but I am generally uncomfortable with that "open" a wildcard. So here is an alternative (which should be pretty foolproof).

 

# Get all the instances of the entity "SYNC_2FF" wherever they are in the hierarchy

 

set sync_inst [get_cells -hier -filter {(ORIG_REF_NAME == SYNC_2FF) || (REF_NAME == SYNC_2FF)}]

 

# Set the ASYNC_REG property on all the cells named "sig_meta_reg" and "sigb_reg" in the instances identified above

set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/sig_meta_reg "]]

set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/sigb_reg "]]

 

# Note: the spaces after sig_meta and sigb inside the quotes are important...

 

[edited to add the slash in front of the flip-flop names and add the _reg]

Avrum

Scholar drjohnsmith
Scholar
10,240 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Just catching up.

  yes the ar is a special case, but it came about from the general problem thats still shown, 

      despite whats said, you can not use the async reg attribute n the vhdl code, you have to use the tcl approach.

 

the tcl is 'great' / 'powerful' tool 

 

BUT 

 

and its a big but, 

 

the general case is mentioned.

 

VHDL modules are meant to be re usable,

 

If I have a re usable module that needs re synchronisers in it, 

    

If I could use the VHDL approach, then the module is re usable.

   If I have to use the TCL approach, 

        I have to what, put documentation into prompt the user how to use the module and write the TCL code,

            and if there are more than one instance , do I have to put the path to each block into the tcl ?

                  and I have to also set the TCL such that the registers are not absorbed.

 

we just need the async_reg  attribute statement to work in vivado please 

 

I have not made it work so far, would love an example in vhdl that did work

 

10,218 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Avrum:  Thanks for the “more focused” XDC(Tcl) constraints used to set the ASYNC_REG property.

 

For other readers of this post:   You can use commands similar to “join [get_cells -hier *sig_meta_reg] \n” in the Vivado Tcl Console to generate reports. These reports are a good check (I think) that the “set_property ASYNC_REG TRUE… ” constraints are catching all (and only) the instances of SYNC_2FF.

 

If the “VHDL attribute” method were working, I would prefer to use it instead of the XDC(Tcl) method for setting the ASYNC_REG property - for all the reasons giving by drjohnsmith.

 

For Vivado, does Xilinx have plans to test/fix the “VHDL attribute” method of setting the ASYNC_REG property?

0 Kudos
Highlighted
Historian
Historian
10,213 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

You can use commands similar to “join [get_cells -hier *sig_meta_reg] \n” in the Vivado Tcl Console to generate reports.

 

(slightly off the main topic, but useful none-the-less)

 

Agreed.

 

However, if you are in the Tcl console in the Vivado GUI, I prefer

 

show_objects [get_cells -hier *signal_meta_reg]

 

(keeping with the same example)

 

This generates an interactive "Find Results" window which shows all the objects found by the command. Within this window, you can click on each object to select it - when an object is selected, you can see its properties in the property window.

 

You can also select objects in a similar fashion using the select_objects command. When selected, objects are highlighted in all the graphics views (the schematic viewer, the die viewer, the hierarchy viewer, etc...). So,

 

select_objects [get_cells -hier *signal_meta_reg]

 

would select all the cells that match the name.

 

Its inverse is "get_selected_objects", which returns the list of objects that are selected. This can be very useful if you want to execute the same command on different things in the schematic window. For example, I often use

 

get_clocks -of_objects [get_selected_objects]

 

You can then re-run this command after clicking on different clock nets or pins in your design schematic to easily find which clocks propagate to that net or pin (very useful for visualizing and debugging clock crossing circuits).

 

Another good use of these commands is

 

select_objects [get_nets -segments [get_selected_objects]]

 

When you click on a net in the schematic viewer, it only selects the net segment. If you want to see where the whole net goes (passing in and out of levels of hierarchy), then you can use the above command.

 

(These are a few of the commands in my list of favorite Tcl commands)

 

Avrum

10,200 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

Avrum:  Thanks for the list of cool Tcl commands.  -simple and very useful.  I think they go hand-in-hand with the XDC(Tcl) constraints we are talking about (giving us confidence that the constraints are doing what we want).

 

-back the "VHDL attribute" method of setting ASYNC_REG.   I see VHDL attribute statements all the time in the instantiation templates for Xilinx/Vivado IP HDL code.  Hence, the use of VHDL attribute statements is not specific to setting the ASYNC_REG property. 

 

Is there anything further I can do to encourage Xilinx to look into this apparent problem of using VHDL attribute statements to set the ASYNC_REG property?

0 Kudos
9,750 Views
Registered: ‎01-22-2015

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

I have migrated my project from Vivado v2014.2 to Vivado v2016.1.  

 

In each of several implemention runs, I find that the VHDL attribute statments are now setting the ASYNC_REG property correctly (ie. keeping registers of the 2FF synchronizer together in the same slice).  

 

If future problems occur then I will update this post.

Scholar drjohnsmith
Scholar
7,554 Views
Registered: ‎07-09-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

thanks for coming back on this with the update.

 

0 Kudos
Observer caryan
Observer
5,232 Views
Registered: ‎04-17-2014

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

@avrumw the tcl join trick is clever but it doesn't append the register name to the last module instance because

 

% join {module1 module2 module3} "/sync_reg "
 module1/sync_reg module2/sync_reg module3 
0 Kudos
Historian
Historian
5,187 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

but it doesn't append the register name to the last module instance

 

You're right... There are probably many ways of fixing it - for example:

 

set sync_inst [get_cells -hier -filter {(ORIG_REF_NAME == SYNC_2FF) || (REF_NAME == SYNC_2FF)}]

 

# Set the ASYNC_REG property on all the cells named "sig_meta_reg" and "sigb_reg" in the instances identified above

set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/sig_meta_reg "]/sig_meta_reg]

set_property ASYNC_REG TRUE [get_cells [join $sync_inst "/sigb_reg "]/sigb_reg]

 

Avrum

0 Kudos
Visitor aspenlogic
Visitor
1,958 Views
Registered: ‎08-01-2014

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

The Q->D net must be as short as possible to minimize the capacitative load on the driver transistors in the Q output. That maximizes the MTBF of the synchronizer. The other often overlooked requirement is that there be no other logic tapped into that Q->D path (which loads it). So, making an edge detector around the second flip flop is a no-no. My solution is to instantiate a synchronizer block consisting of two library primitive flip flops. It is easier to apply the ASYNC_REG to those instances. The use of a clocked process (VHDL) or always block (Verilog) to create the synchronizer is a rookie mistake -- IMHO. To guarantee that the two flops are placed next to each other you can apply an HLUTNM (Vivado) or HBLKNM (ISE) attribute on the instances and give them the same value. The value is arbitrary but the pair must share a **unique** name versus all other synchronizer pairs.
ASPEN LOGIC, INC.
By: Timothy R Davis, President
0 Kudos
Historian
Historian
1,935 Views
Registered: ‎01-23-2009

Re: Setting ASYNC_REG in VHDL for Two-Flop Synchronizer

My solution is to instantiate a synchronizer block consisting of two library primitive flip flops. It is easier to apply the ASYNC_REG to those instances.

 

There is no question that this is a viable (and pretty foolproof) solution.

 

The use of a clocked process (VHDL) or always block (Verilog) to create the synchronizer is a rookie mistake -- IMHO.

 

However, this is a bit strong. Many (most?) people do use inferred flip-flops with the ASYNC_REG property set, either directly in the RTL or in an XDC file. This is the "supported" mechanism in Xilinx, and is also pretty foolproof. It also improves code portability, since it doesn't directly instantiate any Xilinx primitives (although the ASYNC_REG property is specific to Xilinx, so portability with this mechanism isn't 100% either).

 

To guarantee that the two flops are placed next to each other you can apply an HLUTNM (Vivado) or HBLKNM (ISE) attribute on the instances and give them the same value.

 

This is probably overkill. One of the important roles of the ASYNC_REG property is to ensure that the flip-flops in the chain get placed "as close as possible" - which means in the same slice or the adjacent slice (if they can't share the same slice due to control set mismatches). So the ASYNC_REG property is sufficient - you don't need to force the placement in any other way.

 

Avrum

 

0 Kudos