clock synchronization and flip flops

Discussion in 'VHDL' started by john, Apr 16, 2009.

  1. john

    john Guest

    Hello All,

    I am need for some serious advice. I am trying to synchronize the
    passing of the control signal "Reset_counter" between two clocks
    namely "clk1x" and clk_b = clk_synch. The clk_b is equal to
    "clk_divider (6) and generated by dividing the "clk1x" as you can see
    in the following code.

    The sequential machine is running on "clk1x" and it generates the
    signal called "Reset_counter" to reset the 49 bit counter
    "p2s_counter". This counter outputs 49 bit of serial data at the
    rising edge of the slower clock "clk_synch". Because "clk_synch" is
    slower than the "clk1x", so I tired to pass the signal "Reset_counter"
    through atleast three flip flops as you can see in the code clocking
    with the slower clock " clk_synch".

    Then I used the resultant output signal " synch_reset_2" to Reset the
    49 bit counter. The sequential state machine " ser_out_state" checks
    running on "clk1x" for p2s counter to get equal to count 49. after the
    counter reaches its count the state machine gets into a new state.
    Since, "clk1x " is way faster than "clk_synch" thats why it will not
    miss the p2s_counter signal.

    I am using xess board and foundation code and have all sorts of
    problems simulating the code. SO thats why i am testing the code using
    Logic Analyzer.

    My questions is

    Am I synchronizing the clocks in the right way?

    I will appreciate any advice!

    John


    combinatorial : process(err_r, addr_r, dIn, rand, begun, done,
    rdPending, doAgain )
    begin
    case state_r is
    when INIT =>
    Reset_counter <= '1';
    state_x <= Ser_buff_LOAD_1;

    when Ser_buff_LOAD_1 =>
    Reset_counter <= '1';
    state_x <= Ser_buff_LOAD_2;

    When Ser_buff_LOAD_2 =>
    Reset_counter <='1';
    state_x <= Ser_buff_LOAD_3;

    When Ser_buff_LOAD_3 =>
    Reset_counter <='1';
    state_x <= Reset_state;

    when Reset_state =>
    Reset_counter <='1';
    state_x<= Tag_state;

    when Tag_state =>

    Reset_counter <='1';
    state_x <= ser_out_state;
    ----------------------------------------
    when ser_out_state =>

    Reset_counter <='1';

    if ( p2s_counter /= "110001") then
    Reset_counter <='0';
    state_x <= ser_out_state;
    else
    Reset_counter <='1';
    state_x <= Ser_buff_LOAD_1;
    end if;
    ---------------------------------------
    When EMPTY_PIPE =>

    Reset_counter <='1';
    if done = YES then
    cke <= YES;
    end if;

    if rdPending = NO then
    state_x <= STOP;
    end if;
    When others =>
    end process;

    ------------------------------------
    -- clk1x is the main clock generated by xess's program
    update: process (clk1x)
    begin
    if clk1x'event and clk1x = '1' then
    if rst = YES then -- main reset from xess's program
    state_r <= INIT;
    else
    addr_r <= addr_x;
    state_r <= state_x;
    end if;
    end if;
    end process;
    ------------------------------------
    clk_synch <= clk_b;
    -------------------------------------
    -- 49 bits, parallel to serial port conversion--
    serial_count : process ( clk_synch)
    begin
    if rising_edge (clk_synch) then
    if ( synch_reset_2 = '0') Then
    p2s_counter <= p2s_counter + 1;
    ser_out<=ser_buff ( to_integer ( p2s_counter ) );
    else
    p2s_counter <= ( others =>'0');
    end if;
    end if;
    end process;

    ------------------------------------

    Two_flip_flop_synch: process(clk_synch, Reset_counter)
    variable synch_reset_a : std_logic;
    variable synch_reset_b: std_logic;
    begin
    If (Reset_counter = '1') Then
    synch_reset_a := '1';
    synch_reset_b := '1';
    elsif rising_edge (clk_synch) then
    synch_reset_a :=synch_reset_b;
    synch_reset_b:= '0';
    end if;
    synch_reset <= synch_reset_a ;
    end process;
    -----------------------------------
    -- Third Synchronizing Flip Flop to sycnhronize the Reset_counter --

    third_flip_flop_synch : process (clk_synch,Reset_counter )
    variable synch_reset_c: std_logic;
    variable synch_reset_d:std_logic;
    Begin
    if ( Reset_counter ='1') then
    synch_reset_c:= '1';
    synch_reset_d:='1';
    elsif rising_edge (clk_synch) then
    synch_reset_c:= synch_reset;
    synch_reset_d:='0';
    end if;
    done_1 <= synch_reset_c;
    synch_reset_2<= synch_reset_c;
    end process;
    ----------------------------------
    -- Dividing the 100MHz clk1x to 1MHz clk_synch--
    div : process ( rst,clk1x)
    begin
    If ( rst = '1') Then
    clk_divider <= "00000000000";
    elsIf rising_edge (clk1x) then
    clk_divider <= clk_divider + 1;
    end if;
    end process;
    ---------------------------------
    End arch;
    -- End of the VHDL Program --
     
    john, Apr 16, 2009
    #1
    1. Advertising

  2. john

    surpriya.7

    Joined:
    Mar 24, 2009
    Messages:
    5
    Hi John,
    I think the 1st debugging step here is with the patch of code below:
    I think the patch should prodice clk_synch as the output. You are using 'clk_divider' but apparently not using it to generate teh actual clock 'clk_synch'.

    Since you mentioned you are using a logic analyzer, you should assign 'clk_synch' to a pin and check it on LA.

    ----------------------------------
    -- Dividing the 100MHz clk1x to 1MHz clk_synch--
    div : process ( rst,clk1x)
    begin
    If ( rst = '1') Then
    clk_divider <= "00000000000";
    elsIf rising_edge (clk1x) then
    clk_divider <= clk_divider + 1;
    end if;
    end process;
    ---------------------------------
     
    surpriya.7, Apr 17, 2009
    #2
    1. Advertising

  3. john

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    It sounds like you might have some size optimization turned on. That may be deleting your redundant registers and putting you back into a metastable condition. If you don't understand this search for "metastability" on the web.

    What compiler are you using?

    Also, clk_b is used but never defined in the logic. Where is the rest of the code?

    John
     
    JohnDuq, Apr 17, 2009
    #3
  4. john

    KJ Guest

    On Apr 16, 3:06 pm, john <> wrote:

    > I am using xess board and foundation code and have all sorts of
    > problems simulating the code. SO thats why i am testing the code using
    > Logic Analyzer.
    >


    You're attacking the problem backwards then. It is far easier and
    more productive to debug in a simulator then with a logic analyzer.
    With the simulator you have immediate access to every signal in the
    design at any time...with the analyzer you do not.

    > My questions is
    >
    > Am I synchronizing the clocks in the right way?
    >


    No. Unless you're doing a custom ASIC design, don't generate clocks
    at all, timing between clock domains will be your doom. Have
    everything run off of one clock signal. Rather than creating a
    divided down clock from a high speed clock consider this approach

    1. Create a counter that counts from 0 to some maximum count and then
    goes back to 0. For example, if you want to create a lower speed
    clock that is 1/50th of the original clock signal what you would do
    instead is have a counter that runs from 0 to 49 and then resets back
    to 0. You're not using this counter as a clock, it's just a counter.

    2. Create a clock enable signal from the counter by decoding one of
    the counter states like this "clock_enable <= '1' when (counter = 7)
    else '0'; Here I've arbitrarily picked a count value of 7, unless you
    have some specific phase relationship to maintain between the clocks
    for some reason the exact count value can be anything. This clock
    enable signal will fire for exactly one clock cycle and then sit
    inactive for the other values of the counter (in the above example, it
    would sit inactive for 49 clock cycles).

    3. Wherever you would have liked to do this...
    process(Generated_Clock)
    if rising_edge(Generated_Clock) then
    ...Your logic here
    end if;
    end process;

    Do this instead...
    process(Clock)
    if rising_edge(Clock) then
    if (Clock_Enable = '1') then
    ...Your logic here
    end if;
    end if;
    end process;


    > I will appreciate any advice!
    >


    The best advice is to try to avoid multiple clocks until you really
    have an understanding of how to do it correctly. I haven't gone into
    how to do that here simply because it doesn't appear that you've fully
    mastered good synchronous design practice.

    >
    >  combinatorial : process(err_r, addr_r, dIn, rand, begun, done,
    > rdPending, doAgain )


    Don't use combinatorial process. They are sources of the following
    types of design errors that are difficult to debug to but are
    completely avoidable if you simply use only clocked processes and
    concurrent signal assignments.

    - Synthesis differs from simulation because synthesis tools do not
    properly handle sensitivity lists per the LRM. If your sensitivity
    list is missing a signal, you'll get burned.
    - Latches are easy to create and if you do create one...again, you'll
    get burned.

    Kevin Jennings
     
    KJ, Apr 18, 2009
    #4
  5. john

    john Guest

    john, Apr 20, 2009
    #5
  6. john

    john Guest

    Hi,

    So , I will use the counter output as clock. I need a 1MHz clock to
    serial output the data. Where will I get that clock?

    Regards,
    John
     
    john, Apr 20, 2009
    #6
  7. john

    KJ Guest

    On Apr 20, 12:16 pm, john <> wrote:

    > So , I will use the counter output as clock.


    As the clock to what? An external device? Internal to the design?

    If it is internal to the design, then you didn't get my post at all so
    go back and re-read. If it is a signal to an external device, then it
    is not a 'clock' from the perspective of your design since it is not
    used *by your design* to sample anything.

    > I need a 1MHz clock to
    > serial output the data. Where will I get that clock?
    >

    This suggests to me that the '1MHz clock' is some output of your
    design and that there is some other serial output data as well...those
    are two separate outputs. But the '1 MHz clock' is not a clock to
    your design at all, it is a clock input to *the external device*.

    If that is what you're trying to do (I'm not sure, it's not at all
    clear to me) then to generate this 1 MHz output signal from say a 50
    MHz clock input you would construct the counter like I mentioned
    previously to count from 0 to 49 (or 49 downto 0 if you'd like). Keep
    in mind that any particular value of the count then essentially
    defines something that happens at a 1 MHz rate. So....

    process(Clock)
    begin
    if rising_edge(Clock) then
    if (Count = 3) then
    My_1MHz_Output <= '1';
    elsif (Count = 28) then
    My_1MHz_Output <= '0';
    end if;
    end if;
    end process;

    The signal 'My_1MHz_Output' then will be a 1 MHz output signal, you
    wouldn't use it internally within your design, it is simply the output
    signal that you're generating in order to interface to whatever device
    is using this signal.

    The value of '3' that I picked for switching the output to a '1' is
    arbitrary, any value would work. The value of '28' was chosen because
    people like to see 50% duty cycle clocks. If you want a different
    duty cycle then change the 28 to something else.

    Presumably your serial output data must have some specific timing
    relationship to the 'clock' to meet some setup or hold time
    requirement. Perhaps the external device samples on the data on the
    rising edge so you would need to make sure that the data is stable
    around that point (which from the above example would be around the
    time when Count=3). Based on whatever your requirement is, you might
    then decide that 70 ns is more than enough hold time and decide to
    only allow the data to change when the count = 10 (7 ticks of the 100
    MHz clock = 70 ns).

    process(Clock)
    begin
    if rising_edge(Clock) then
    if (Count = 10) then
    Serial_Out_Data <= ...
    end if;
    end if;
    end process;

    That's the basic idea. You would probably want to define some
    constants so that the numbers '3', '10' and '28' (or whatever) have
    real definitions instead of appearing to be magic constants.

    Kevin Jennings
     
    KJ, Apr 20, 2009
    #7
  8. john

    KJ Guest

    KJ, Apr 20, 2009
    #8
  9. john

    KJ Guest

    On Apr 20, 1:38 pm, KJ <> wrote:

    > then decide that 70 ns is more than enough hold time and decide to
    > only allow the data to change when the count = 10 (7 ticks of the 100
    > MHz clock = 70 ns).


    Should've said 7 ticks of the 50 MHz clock...and said that maybe 140
    ns is plenty of hold time

    KJ
     
    KJ, Apr 20, 2009
    #9
  10. john

    john Guest

    Hi,

    I am not doing ASIC. I think , I got the idea. I will try your adviced
    solution and we will see. I am trying to generate clock, data and tag
    signals for a DAC. The DAC needs 49 bit of data at the clock of 1MHz.
    The internal clock frequency is 100MHz. I think that the counter
    solution might work.

    Thanks
    John
     
    john, Apr 20, 2009
    #10
  11. john

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    John,

    That is a very good paper that you are referencing. I suggest you make sure you are strong in synchronous design before tackling the asynchronous design aspects. His technique of making synchronous modules is a good one. Make sure you can get one module through the entire process (design -> simulation -> synthesis -> programming) before you tackle multiple asynchronous modules.

    John D
     
    JohnDuq, Apr 21, 2009
    #11
    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. crazyrdx

    Latches and flip flops

    crazyrdx, Apr 1, 2006, in forum: VHDL
    Replies:
    6
    Views:
    6,706
    Mike Treseler
    Apr 10, 2006
  2. t flip flops

    , May 17, 2006, in forum: VHDL
    Replies:
    18
    Views:
    9,463
  3. t flip flops

    , May 17, 2006, in forum: VHDL
    Replies:
    0
    Views:
    631
  4. mav1101
    Replies:
    1
    Views:
    741
    Dave Dean
    Sep 22, 2006
  5. Weng Tianxiang
    Replies:
    13
    Views:
    2,596
    Weng Tianxiang
    Feb 15, 2010
Loading...

Share This Page