cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
591 Views
Registered: ‎06-07-2019

register bit(s) CDC

I've learned a lot from @avrumw 's posts on CDC related topics. Recently I came across this post on multi-bit register CDC and I'd like to share my thoughts on it, see if it makes sense or not.

While I have no problem with using handshake to handle it, I think depending on specific situation it can be much simpler.

The scenario I have in my mind is:

The driver/cpu sets up a bunch of (multi-bit or single-bit) registers, then at the end it sets up a register bit, say "valid", which tells the other clock domains which need to use the registers can now take and use the registers. In this situation  only the register bit "valid" needs to be synchronized with 2FF synchronizer and "set_false_path"  is used on all of the registers involved.

So, in this case the multi-bit registers don't need a CDC circuit at all and it is safe to consume the registers in other clock domains because they are stable when "valid" is synchronized to the destination clock domains.

Another scenario I can think of is:

There are interrupts (sof, start of frame) generated regularly, say 16.67ms like in P60 video system. Whenever there is an interrupt, the driver/cpu will set up some registers and they will be used around 8us (one video line) before the next interrupt (new sof). Also let's assume the register clock is 24Mhz.

In this situation, between the register setup and the register being used, there is a big gap, the registers are safe to use in the clock domain that generates the interrupt. So no need for any CDC circuits between these 2 clock domains.

I think this is of the same principle with the handshake mechanism just that my suggested scheme does not have the ack part, which is not needed. In handshake, the multi-bit data is static, it relies on some "data_en" and a small FSM to safely pass the data between clock domains. 

In short, CDCC is not necessary for multi-bits/single-bit register when their timing can be guaranteed in the design.

Any thoughts on this are welcome.

0 Kudos
9 Replies
Highlighted
479 Views
Registered: ‎01-22-2015

Re: register bit(s) CDC

jiangzhk@126.com 

I'd like to share my thoughts on it, see if it makes sense or not.
You know “how” but want to know more about “why” – I like these kind of questions!

I too learned lots about CDCs from Avrum and from “Fourteen Ways to Fool Your Synchronizer by Ran Ginosar”. 

Your thoughts describe tinkering with the handshake synchronizer.  In short, you seem to be saying:

  • The sending-clock-domain (sender) places data on the clock-crossing (crossing)
  • The sender waits “many-clock-cycles
  • The sender sends a valid flag through the crossing (using a 1-bit synchronizer w/proper timing exceptions)
  • The receiving-clock-domain (receiver) reads the data
  • The data paths through the crossing have set_false_path timing exceptions

In principle, your method will work if you correctly define many-clock-cycles.

One thing to consider is the frequency of the clock in each clock domain.  Suppose the sender is using a 100MHz clock and the receiver is using a 10MHz.  Then, you might think that a safe definition of many-clock-cycles is 2 cycles of the 10MHz clock, which is 20 cycles(!) of the 100MHz clock. 

…but,

when defining many-clock-cycles, we must also wait until every data bit has propagated through the routing paths associated with the crossing.   How long can these routing paths be?  Well, because you have placed a set_false_path on these data paths then they could be very long and all different (because set_false_path tells Vivado it can do whatever it wants when routing these paths).

We want to avoid guessing how many clock-cycles it takes for data to travel through the routing paths of the crossing.  So, instead of using set_false_path, it is better to use “set_max_delay -datapath_only” because the latter allows us to constrain length of the data routing paths to some maximum value.

So, your thoughts about clock crossings are basically correct.  However, you should replace the set_false_path timing exceptions with “set_max_delay -datapath_only” – and carefully define the many-clock-cycles that you must wait before raising your “valid” flag.

Cheers,
Mark

Highlighted
460 Views
Registered: ‎06-07-2019

Re: register bit(s) CDC

Mark, thanks very much for commenting and sharing the pdf document. I read a lot of your posts too!

Your summary covers/goes beyond of register bits synchronization and can be applied more widely in general-purpose situation. 

If we limit the situation to register bits synchronization, as usually register configuring clock is quite slow compare to the main clock(s) used in FPGA. Let's assume clock_reg = 24Mhz, clk_main = 100Mhz. 

Register write from driver/cpu is quite slow as it is controlled by software, there are naturally some cycles of clock_reg gap between two consecutive writes. Assuming the gap is only one reg cycle, the final "valid" bit write takes another one reg cycle, plus 2 main clock cycle before all the registers can be used. That's a total of at lease (41.67*2+20)=103 ns, that's a lot of time!

Based on above register and main clock setting, summary point 2) The sender waits “many-clock-cycles”  can be bypassed.

I have absolutely with no problem with using “set_max_delay -datapath_only” to constrain the skew which is very safe, but I still think we can get away with "set_false_path" in this case as 103 ns is a lot of time that bus skew would not be a problem. 

0 Kudos
Highlighted
436 Views
Registered: ‎01-22-2015

Re: register bit(s) CDC

jiangzhk@126.com 

..but I still think we can get away with "set_false_path"…
No.  I know your goal is to reduce latency of the clock crossing.   However, “set_false_path” will result is larger latency for the crossing than “set_max_delay -datapath_only”.  The example below will explain.

Let's assume clock_reg = 24Mhz, clk_main = 100Mhz.
Latency of the crossing can be small when the Sender is a slow-clock domain and the Receiver is a fast-clock domain.  Let PS equal the period of the Sender’s 24MHz clock and let PR equal the period of the Receiver’s 100MHz clock.   For this slow-to-fast clock domain crossing, the following protocol can be used.

  1. Idle state is described as:  Sender sets “valid=0” and Receiver waits for “valid=1”
  2. Sender simultaneously places data and the “valid=1” signal on the crossing
  3. The “valid=1” signal goes through a 2-flip-flop synchronizer, taking either 1*PR or 2*PR seconds (we can’t be sure which) to travel through the crossing
  4. Receiver sees the “valid=1” signal and assumes (worse case) that “valid=1” arrived 1*PR after it was sent
  5. Receiver now waits for data to safely make the crossing.  Since sender sent “valid=1” and data at the same time, then data has already been traveling for (worse case) 1*PR seconds.  Sender should now wait for data to “finish travelling” through the crossing *and* wait another 2*PR to avoid metastability of the data.
  6. After waiting enough cycles of PR (as described in step-5), then data is read/received by the Receiver.
  7. Both the Sender and Receiver return to Idle state.


As you can see, latency of the crossing depends on what is done in step-5.  When you use set_false_path, the “finish travellingpart is unknown and could be very long.  However, if you use “set_max_delay -datapath_only” with a value of 1*PR, then total latency of the crossing becomes either 3*PR or 4*PR (we can’t be sure which).  Since, PR=10ns, then this means that total latency of the crossing is either 30ns or 40ns (and not the 103ns that you thought).

0 Kudos
Highlighted
410 Views
Registered: ‎06-07-2019

Re: register bit(s) CDC

Mark, I think we are not on the same page. "valid" is the last register bit I set, before which N registers have been set. I only synchronize this "valid" bit and when clk_main sees the synchronized "valid", it knows it's safe to use reg1 to regN in clk_main domain.

Because clk_reg is slow and sequential reg writes are slow with gaps between them. if clk_reg is 24Mhz, clk_main is 100Mhz, from regN being written to "valid" being synced to clk_main it will be a long time that bus skew is not a problem. That's why I think I can get away with "set_false_path" on all the registers involved without having to worry about bus skew.

reg_sync.png

0 Kudos
Highlighted
Scholar
Scholar
393 Views
Registered: ‎05-21-2015

Re: register bit(s) CDC

jiangzhk@126.com,

If I understand the conversation correctly, the technique is similar to Fig. 5 from this article, with the exception that you aren't using the acknowledgment path.

My general thought is that this would work for some clock rate crossings but not others dependent upon the relative clock rates.  I'd want to formally verify it to be sure--since I've been surprised in the past by what the formal tools have discovered.  (The SPI design was particularly unexpected ...)

Dan

0 Kudos
Highlighted
375 Views
Registered: ‎06-07-2019

Re: register bit(s) CDC

If I understand the conversation correctly, the technique is similar to Fig. 5 from this article, with the exception that you aren't using the acknowledgment path.

That's right. The "valid" or REQ is guaranteed to be seen in the clk_main domain, ACK part is only needed when there are new data to send through these regs so the sender knows when to start writing new data to these registers.

Or I can say the ACK part is there but in a different form: the clk_main domain processes data based on the latched registers, generates an interrupt, driver gets the interrupt and fills out the registers with new value, all the registers are synchronized to clk_main domain,......

Of course this only works in particular scenario, I'm presenting a possible case that instead of using handshake to synchronize a bunch of (multi-bit) registers, we can just use a simple 2FF synchronizer to do the job and it is still safe.

0 Kudos
Highlighted
Explorer
Explorer
373 Views
Registered: ‎03-31-2016

Re: register bit(s) CDC

If you use set_false_path the tools are free to draw literally the longest possible path through the part.  If your register writes are coming over a very slow interface, a user typing in commands to a keyboard for example, then yes it is very likely to work.  If its a processor running well optimized C code in the same FPGA it becomes very iffy.  Do NOT assume the router will take a "reasonable" path if you have a false_path constraint, other timed routing may be going between those two points and getting all the "reasonable" routing resources.

You still have to write some constraint either way so why not do the safe thing and use a set_max_delay with the value of whatever you have calculated the fastest possible time from the write of the last data register to the write of valid register, minus one receive clock for skew.

All that does is ensure that tools meet your assumptions, and a very tiny bit of run time as that path is checked.  If the design fails to meet timing with a good value for that constraint then you need to redesign your CDC logic to give you more time to cross.

There is basically no downside to setting the constraint to a reasonable value and a very hard to track down potential problem if you do not.  If you set it to a very low value, yes you will make the tools work harder than they need to and potentially fail timing.  Setting it to value your CDC circuit needs just ensures the router doesn't do "something stupid" and give you a report to check to make sure it didn't

Is one second more in P&R time worth a random failure in a shipping design?

 

Highlighted
325 Views
Registered: ‎06-07-2019

Re: register bit(s) CDC

Thanks @necare81 @dgisselq markg@prosensing.com  for joining the discussion. 

Even though "set_false_path" seems OK in my particular case, it may cause problem if the implementation is gone crazy. You are right it's not worth a random failure in a shipping design even if the chance of it happening is slim.

It makes more sense to use "set_max_delay -datapath only"/"set_bus_skew" when it is guaranteed to be working and safe.  

0 Kudos
Highlighted
225 Views
Registered: ‎06-07-2019

Re: register bit(s) CDC

@avrumw has already answered a similar question in a post HERE

0 Kudos