cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Observer
Observer
6,482 Views
Registered: ‎05-31-2014

Data transfer between async clock domains using an "update" signal

Jump to solution

Hello - 

I have a question on defining a timing constraint betwwen clocks domains.   The goal is drive a wide data bus from one asynchronous clock domain to another within the FPGA.    This is a general IP block, so the periods of the clock domains are not known until they are synthesized.  

 

There are two fairly easy solutions to this problem:

  1. Use a metastable hardener on the data lines – Effective but also requires a lot of registers in my case.
  2. Define a false_path constraint to avoid giving the timing closure fits – This has the obvious problem that I’m not constraining anything and just hoping for the best.

I’d like to avoid using these methods for the reasons mentioned.  However, I can (by design) ensure the data rate is low.   There will be a minimum of 30 clock cycles on the either clock between transactions. 

 

My proposed solution is to generate an ‘update’ signal that has a rising edge when new data is generated.  The update signal is generated with the data.  Both data and update signals are held constant for many cycles of either clock.   I would send the ‘update’ signal (alone) to the ‘end’ domain using a metastable hardener with 3 stages of registers.   When the receive clock domain detects a rising edge on the update signal, the data has been stable (by design) for at least 2 cycles of the ‘end’ clock (assuming no delay).   We lose one cycle because the asynchronous clocks could occur at any point, so we can’t be sure about the phasing during 1 cycle.  Since the data is now stable, I should be able to just clock it into the ‘end’ domain directly.   (Unless the path routing introduces a long delay!)

 

I’m confident this will work, but to be safe, I’d like to constrain the routing of the data lines to preclude a long path delay, which eats into my setup margin.   A simple :"set_max_delay" constraint won’t work, because I don’t know the period of the clocks until the module is synthesized.   It seems like a multi-path exception might work, if I use it to constrain the end clock for 2 cycles.  Something like this:

set_multicycle_path 2 -setup -end –from …
set_multicycle_path 1 -hold -end –from …

 

But, I never seen the multicycle exception used in this way, so I’d appreciate some advice. 

0 Kudos
Reply
1 Solution

Accepted Solutions
Guide
Guide
12,290 Views
Registered: ‎01-23-2009

The synchronizer you describe is valid and appropriate for busses. You need some kind of event synchronizer for your "update" signal (and I generally use a toggle event synchronizer). For the synchronizer itself, you will need the ASYNC_REG property on the metastability flip-flops...

 

For the databus crossing, the correct constraint is a set_max_delay -datapath_only. Your issue is the magnitude of the delay...

 

First, if you are really providing 30 clocks of stability, then the value isn't critical; choose 10ns; it will be fine for pretty much any combination of frequencies.

 

But, if you want to be precise, then you can get the clock frequency from the clocks. If the constraint is in a scoped xdc file, then you can do

 

set src_per [get_property PERIOD [get_clocks -of_objects [get_ports <clk_port>]]]

 

You can do the same for the dst_per and you can even use max and min functions to do the constraints. If you want to see an example, look at the generated constraint file for a BRAM based FIFO (not built-it FIFO) generated from the IP catalog; that does exactly what you want for your module.

 

If you aren't putting it in a scoped constraint file, then you need to do the same thing using any known net or pin that carries the clocks.

 

Of course, you need to make sure that these constraints get executed after the constraints that create the clocks - you may need to play with constraint file ordering to ensure that this happens.

 

Avrum

View solution in original post

2 Replies
Guide
Guide
12,291 Views
Registered: ‎01-23-2009

The synchronizer you describe is valid and appropriate for busses. You need some kind of event synchronizer for your "update" signal (and I generally use a toggle event synchronizer). For the synchronizer itself, you will need the ASYNC_REG property on the metastability flip-flops...

 

For the databus crossing, the correct constraint is a set_max_delay -datapath_only. Your issue is the magnitude of the delay...

 

First, if you are really providing 30 clocks of stability, then the value isn't critical; choose 10ns; it will be fine for pretty much any combination of frequencies.

 

But, if you want to be precise, then you can get the clock frequency from the clocks. If the constraint is in a scoped xdc file, then you can do

 

set src_per [get_property PERIOD [get_clocks -of_objects [get_ports <clk_port>]]]

 

You can do the same for the dst_per and you can even use max and min functions to do the constraints. If you want to see an example, look at the generated constraint file for a BRAM based FIFO (not built-it FIFO) generated from the IP catalog; that does exactly what you want for your module.

 

If you aren't putting it in a scoped constraint file, then you need to do the same thing using any known net or pin that carries the clocks.

 

Of course, you need to make sure that these constraints get executed after the constraints that create the clocks - you may need to play with constraint file ordering to ensure that this happens.

 

Avrum

View solution in original post

Observer
Observer
6,425 Views
Registered: ‎05-31-2014

Thanks Avum, that's just what I was looking for.

As I wrote my message, I wondered if it were possible to deterimine the clock period and apply this to set_max_path.   Your response confirmed this is possible and now I see that it's a better option than the one I proposed.  Thanks for the help.

 

To answer your question, I'd like to constrain this path to ensure a clean capture, but there are several tight timing requirements in other parts of the design.  So I wanted to give the timing closure some breathing room on this section of the design so it's not strugging with too many difficult constraints.  

 

- Andy 

0 Kudos
Reply