Synchronizer theory and question

M

moogyd

Hi experts,

Sorry for the cross posting, but I wanted to ensure a complete
readership. It's more a design question than language specific.

When I pass a signal between clock domains (clkfrom to clkto), I use
two FF's in the clkto domain prior to using the signal in this domain.
If there is a timing violation (setup or hold) at the first FF, then
the O/P will become metastable. i.e. Unknown, and it will stay in this
state for a time determind by a probability distribution.
We therefore use a second FF before we use the signal. Hopefully, the
O/P of the fist FF will be stable by the next clock edge. This is not
guarenteed, and depends on the clock frequency, target technology etc.
All we can say is that there is a probabilty of X% that it will always
work.

Therefore, first question : Is my understanding correct?

If so, I have another question.

If I am passing a signal from a fast clock domain (16MHz) to a slow
clock domain (100Hz) at 0.18us, do I need to synchronize?

e.g. As a simple example, I have a timer on a system bus. The cycle
time register is in the fast domain.

Ignoring reset's, (and assuming I gray code the counter) my code looks
like

p_fast : process(fastclk)
if fastclk'event and fastclk='1' then
if write_cycle='1' then
r_cycle <= wr_data ;
end if;
end if ;
end process ;

p_slow : process(slowclk)
if slowclk'event and slowclk='1' then
r_cycle_eq_count <=cycle_eq_count ; // This is an interrupt which
will be sync'ed into fast clock domain
if r_cycle_eq_count='1' then
r_count <= (others => '0') ;
else
r_count <= r_count + 1 ;
endif ;
end if ;
end process ;

assign cycle_eq_count = '1' when r_cycle=r_count else '0' ;

Is there a problem with this code?
If r_cycle changes around slowclk, there may be metastabity in
r_cycle_count, but this should have settled within a 100Hz cycle?

Any further suggestions/insights welcomed.

Steven
 
G

gabor

There are two issues when changing clock domains with
multibit data. The first is data coherency and this would
be addressed using Gray code. There are other methods
when the destination clock is much slower than the source
clock. My favourite is to create a sampling signal in the
source clock domain just after the edge in the destination
clock. Use this as a clock enable in the source clock
domain to latch the data, which is then used directly
at the next destination clock edge.

The second issue is metastability, and at 100 Hz I would
say this is not likely to become an issue. In the Gray code
case only one bit at a time is changing and therefore unless
your metastability window spans the source clock period
the sampled data will be usable at the next edge of 100 Hz.
The important issue here is not so much the two-stage
synchronizer, but the single point of sampling. i.e. at the
sampling clock edge only one flip-flop in the 100 Hz clock
domain can sample each bit. This seems to be addressed
in your slowclk process below. Of course this delays
your interrupt by 10 milliseconds.
 
M

Mike Treseler

When I pass a signal between clock domains (clkfrom to clkto), I use
two FF's in the clkto domain prior to using the signal in this domain.
If there is a timing violation (setup or hold) at the first FF, then
the O/P will become metastable. i.e. Unknown, and it will stay in this
state for a time determind by a probability distribution.

The most likely result of a timing violation in FF1 is proper
synchronization either on that edge or the next. The primary
job of the flop is to eliminate races to the subsequent flops
in the design by retiming the edges. The most common symptom of a logic
race is an "impossible" state transition.

The second flop is there to reduce the odds
of synchronization failure from say once a year to maybe
once every hundred years. That's cheap insurance.
Without any synchronization, I would expect a race problem
in much less than a year -- more likely in less than a millisecond.

For a synchronizer example, search for "retime"
in the reference design here:
http://home.comcast.net/~mike_treseler/
If I am passing a signal from a fast clock domain (16MHz) to a slow
clock domain (100Hz) at 0.18us, do I need to synchronize?

Yes.

The easiest way is to run the "slow" counter at 16MHz
using clock enables. See the "clock enabled counters"
source for an example. Or you could handshake the
transaction with ready and ack signals, properly
synchronized, of course.
e.g. As a simple example, I have a timer on a system bus. The cycle
time register is in the fast domain.
Is there a problem with this code?

Yes.

If you travel down this road you will
eventually reinvent the uart or the fifo.

-- Mike Treseler
 
A

Andy

The second flop is assumed to have more timing margin on its input than
other flop inputs driven through combinatorial logic. If adequate
timing margin can be guaranteed to produce a desired probability of
failure, it does not matter whether it is one flop with no preceding
logic, or one or more flops, each with preceding logic.

As an example, say an asynchronous input is registered only once, and
then used to drive a load signal on a counter. Generally speaking, the
timing margin from clock to setup, going through the load muxes to all
the bits of the counter will be less than the timing margin to a
single additional flop immediately downstream from the synchronizing
flop. But, depending on routing, placement, and logic involved, there
can actually be less margin on the single flop than on the multiple
flops with preceding mux logic. Unless the timing is additionally
constrained to give you that extra margin (in either case), there is no
guaranteed improvement in probability of failure from inserting a
second flop after the synchronizing flop (we call the second flop the
meta[stable]-rejecting flop).

The above only holds true for non-causal (i.e. clocked) inputs. It is
not true for causal (clock or asyncrhonous) inputs. Never drive causal
inputs from output of the first synchronizing flop.

You should also constrain the synchronizing input register (the first
one) so as not to be replicated due to high fanout (or any other
reason). Such replication is almost never a problem if you have a
single, second flop before fanning out into the rest of your logic
(although in rare cases, the second flop gets replicated enough times
to where it creates enough fanout on the first register to trigger
replication!). Such replication is more common when the synchronizing
flop drives your logic directly. Either way, the no-replicate
constraint is highly recommended. You also don't want the synchronizing
flop to be re-timed either.

Andy
 
M

moogyd

Thanks for all the responses and clarifications.

The reason for the initial question is that I require very low power
(both static and dynamic).

Therefore:
- Sampling the slow clock using the fast clock is not possible. I only
want the fast clock to be running when a bus operation is required. I
am using AMBPA APB, so this may be 2 clock cycles (when the PSEL is
active)
- I am trying to reduce gate-count (i.e. I'll try to avoid having the
compare register in both clock domains)

I am hoping that this problem has a solution. When I think about it too
hard, my head hurts :-(

Thanks,

Steven
 
J

john

Hello Mike,

Are you advicing that synchronizing the signal between two clock
domains via two flip flops is OK? I have one clock which is running at
24MHz and the second clock running at 1MHz.

John
 
M

Mike Treseler

john said:
Are you advicing that synchronizing the signal between two clock
domains via two flip flops is OK? I have one clock which is running at
24MHz and the second clock running at 1MHz.

I would advise running the module at 24 MHz
and using the second clock as a plain input to
be synchronized and and converted
to a single cycle strobe.

-- Mike Treseler
 
J

john

Hi Mike,
I am trying to write a 48 bit buffer in the FPGA at the rising edge of
the USB clock and then trying to use the 1MHz clock to read the 48bit
bit buffer and then serially outputing them. What I understood from ur
advise that FPGA will run at 24MHz and the 1MHz clock will be input and
pass through flip flops and at the output of the second flip flop will
be used to read the 48bit buffer and serially output the data. Am I
right? Please adivse some sample code >

Regards
John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top