synchronization of state machine between clocks

Discussion in 'VHDL' started by richard.melikson@gmail.com, Nov 25, 2007.

  1. Guest

    Hi,

    There are two clocks in my design. On the main clock, a state machine
    runs. It is encoded as a type (leaving the decision on the exact
    encoding to the synthesizer). I want to set a signal on "enable" when
    the machine is in a certain state, so I do:

    if reset
    ...
    elsif rising_edge(clk1) then
    if machine_state = active then
    my_enable <= '1';
    else
    my_enable <= '0';
    end if;
    end if;

    This works fine, of course. But suppose I have another enable signal,
    which should depend on the same event but works with a different
    clock. How do I synchronize the state of the machine between the two
    clocks ? At the moment I do a process:

    if reset
    ...
    elsif rising_edge(clk2) then
    my_enable_sync <= my_enable;
    my_enable2 <= my_enable_sync;
    end if;

    This works, because I know that the "Active" state is very long and
    I'm not sensitive to exact timing. This double FF ensures no
    metastability and correct syncing of my_enable to the clk2 domain.

    Questions:

    1) Is this a valid way to accomplish my goal ?
    2) What is a faster / tighter way to do this synchronization, if I
    care about every clock cycle ?

    10x
    R
    , Nov 25, 2007
    #1
    1. Advertising

  2. Guest

    On Nov 25, 6:09 am, wrote:

    > 1) Is this a valid way to accomplish my goal ?
    > 2) What is a faster / tighter way to do this synchronization, if I
    > care about every clock cycle ?
    >
    > 10x
    > R


    It's very common. This makes it mostly valid :) Read the literature
    on metastability, it's all probabilities. One flop gets you the
    biggest bang for th buck. I tend to be paranoid and flop more than
    once, but this costs you delay.

    It also depends on the relative clock rates. One gotcha is that if you
    assume that the pulse in the sending domain is a certain number of
    clocks wide, it may not be so on the other side. In particular, single
    pulse "events" may get deleted or stretched.

    Also, make sure you use the flopped output in *exactly* one place, and
    make sure you decorate it with do-not-replicate and do-not-retime
    attributes. Otherwise the synthesizer may introduce all kinds of
    problems when signals reconverge after undergoing a statistically
    distributed and unequal number of clock delays at each crossing.

    Another fairly common approach is to build a hand-shake (an SR-flop
    idea), possibly with intervening metastability flops, which guarantees
    to hold the signal until seen properly at the other side. You can
    couple this with edge-detctors to get single clock wide pulse ouputs.
    This lets you cross from slow to fast clocks safely but again, can
    cost delays.

    If you need absolute speed (like in a CPU pipeline), and are willing
    to do some serious work to achieve it, look at some of the neat ideas
    in the paper "Efficient Self-Timed Interfaces for Crossing Clock
    Domains" by Chakraborty and Greenstreet:

    http://www.cs.utah.edu/classes/cs6943/papers/async2003.pdf

    These techniques may be easier to implement in ASIC than FPGA, though.
    I'm sure there are a thousand other neat ideas out there, too.

    Best regards,

    - Kenn
    , Nov 25, 2007
    #2
    1. Advertising

  3. schrieb:

    > if reset
    > ...
    > elsif rising_edge(clk2) then
    > my_enable_sync <= my_enable;
    > my_enable2 <= my_enable_sync;
    > end if;
    >
    > This works, because I know that the "Active" state is very long and
    > I'm not sensitive to exact timing. This double FF ensures no
    > metastability and correct syncing of my_enable to the clk2 domain.
    >
    > Questions:
    >
    > 1) Is this a valid way to accomplish my goal ?
    > 2) What is a faster / tighter way to do this synchronization, if I
    > care about every clock cycle ?


    Synchronisation of asynchronous processes can be done by detecting a one
    bit signal change. With this method you can avoid in many situations
    that the duration of the synchronisation signal could become too short.
    I would never use a pulse to synchronise between two clock domains.

    -- trigger process 2 from process 1, clock domain #1:
    if have_to_trigger_proc2 then
    trigger_proc2 <= not trigger_proc2;
    end if;

    -- detect trigger from process 1 in process 2, clock domain #2:
    trigger_proc2_sync <= trigger_proc2; -- synchronise signal from proc1
    trigger_proc2_sync_old <= trigger_proc2_sync;

    if trigger_proc2_sync /= trigger_proc2_sync_old then
    ...
    end if;

    You have to care about that the trigger signals in both processes have
    the same reset value.

    Best regards

    Wolfgang Grafen
    Wolfgang Grafen, Nov 26, 2007
    #3
    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. David Lamb
    Replies:
    1
    Views:
    659
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,082
    Mike Treseler
    Nov 25, 2003
  3. Weng Tianxiang
    Replies:
    3
    Views:
    1,372
    Weng Tianxiang
    Jul 25, 2006
  4. Grumps
    Replies:
    2
    Views:
    669
    Grumps
    Feb 13, 2008
  5. fenster
    Replies:
    3
    Views:
    1,151
    jeppe
    Dec 23, 2011
Loading...

Share This Page