Synchronizer theory and question

Discussion in 'VHDL' started by moogyd@yahoo.co.uk, Nov 27, 2006.

  1. Guest

    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
    , Nov 27, 2006
    #1
    1. Advertising

  2. gabor Guest

    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.

    wrote:
    > 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
    gabor, Nov 27, 2006
    #2
    1. Advertising

  3. wrote:

    > 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
    Mike Treseler, Nov 27, 2006
    #3
  4. Andy Guest

    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


    Mike Treseler wrote:
    > wrote:
    >
    > > 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
    Andy, Nov 27, 2006
    #4
  5. Guest

    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
    , Dec 3, 2006
    #5
  6. john Guest

    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
    Mike Treseler wrote:
    > wrote:
    >
    > > 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
    john, Dec 7, 2006
    #6
  7. john wrote:

    > 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
    Mike Treseler, Dec 7, 2006
    #7
  8. john Guest

    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
    john, Dec 7, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Synchronizer doubts

    , Jul 20, 2005, in forum: VHDL
    Replies:
    2
    Views:
    1,688
  2. Synchronizer doubts

    , Jul 20, 2005, in forum: VHDL
    Replies:
    0
    Views:
    446
  3. GerritM
    Replies:
    1
    Views:
    314
    Christos TZOTZIOY Georgiou
    Nov 4, 2003
  4. Kyler Laird
    Replies:
    3
    Views:
    423
    Mark Carter
    Jan 20, 2004
  5. Replies:
    2
    Views:
    122
    Dio Gratia
    Apr 20, 2014
Loading...

Share This Page