When are two clock domains actually considered asynchronous?

Discussion in 'VHDL' started by Beppe, Dec 10, 2010.

  1. Beppe

    Beppe Guest

    Consider the following system:

    inp_clk -- Input clock to FPGA (Xilinx Spartan 3A DSP)
    -- directly routed to DCM
    -- PERIOD constraint attached to it
    -- Frequency: 125 MHz

    clk_25 -- CLKDV_OUT from DCM
    -- Frequency: 25 MHz

    clk_28 -- CLKFX_OUT from DCM
    -- Frequency: inp_clk*7/31 MHz

    clk_250k -- Output from a VHDL-module that divides the clk_25 with
    100
    -- Frequency: 250 kHz

    CTRL_PROC : process (clk_250k)
    begin
    if rising_edge(clk_250k) then
    if reset = '1' then
    reg1 <= '0';
    else
    if byte_received = '1' then
    if data_in = “10101010” then
    reg1 <= '1';
    else
    reg1 <= '0';
    end if;
    end if;
    end if;
    end if;
    end process;

    CNT_PROC : process (clk_28)
    begin
    if rising_edge(clk_28) then
    if reset = '1' then
    cnt <= (others => ‘0’);
    else
    if reg1 = '1' then
    cnt <= cnt + 1;
    else
    cnt <= cnt - 1;
    end if;
    end if;
    end if;
    end process;

    reg1 is assigned a value in CTRL_PROC and read in CNT_PROC and thus it
    is crossing clock domains. Do I need to worry about that in the above
    situation and apply some asynchronous clock domain techniques? I’m
    asking since the two clocks actually are related to each other. So,
    main question:

    When are two clock domains actually considered asynchronous?

    Some related questions. How does ISE/XST handle the situation? As I
    understand the Xilinx software automatically derives a new PERIOD for
    each of the DCM output clocks and determines the clock relationships
    between the output clock domains. There will probably be moments where
    the edges of the two clocks are so close that the timing won’t be met.
    Do I need to insert a FALSE PATH constraint in this case?

    And, last question, should I put the clk_250k on a global clock path?

    Regards
    Beppe
    Beppe, Dec 10, 2010
    #1
    1. Advertising

  2. Beppe

    KJ Guest

    On Dec 10, 4:13 pm, Beppe <> wrote:
    > Consider the following system:
    >
    > inp_clk   -- Input clock to FPGA (Xilinx Spartan 3A DSP)
    >           -- directly routed to DCM
    >           -- PERIOD constraint attached to it
    >           -- Frequency: 125 MHz
    >
    > clk_25    -- CLKDV_OUT from DCM
    >           -- Frequency: 25 MHz
    >
    > clk_28    -- CLKFX_OUT from DCM
    >           -- Frequency: inp_clk*7/31 MHz
    >
    > clk_250k   -- Output from a VHDL-module that divides the clk_25 with
    > 100


    clk_250k will be a problem in an FPGA. In an FPGA environment, you
    basically almos never want to generate a clock with logic. Even when
    it comes out of a flip flop you're most likely doomed.

    >           -- Frequency: 250 kHz
    >
    > CTRL_PROC : process (clk_250k)
    > begin
    >  if rising_edge(clk_250k) then


    Yep...doomed

    <snip>
    >   end if;
    >  end if;
    > end process;
    >
    > CNT_PROC : process (clk_28)
    > begin
    >  if rising_edge(clk_28) then
    >   if reset = '1' then
    >    cnt <= (others => ‘0’);
    >   else
    >    if reg1 = '1' then
    >     cnt <= cnt + 1;
    >    else
    >     cnt <= cnt - 1;
    >    end if;
    >   end if;
    >  end if;
    > end process;
    >
    > reg1 is assigned a value in CTRL_PROC and read in CNT_PROC and thus it
    > is crossing clock domains. Do I need to worry about that in the above
    > situation and apply some asynchronous clock domain techniques?


    Yes and no.
    - Since you created two clocks, then yes you should treat them as if
    they are unrelated.
    - What you should do is generate a clock enable for rather than a
    clock for the 250k. Then both processes are running in the same clock
    domain...no clock crossings at all.

    Instead of this...
    process(clk_250k)
    begin
    if rising_edge(clk_250k) then
    ...
    end if;
    end process;

    Do this...
    process(clk)
    begin
    if rising_edge(clk) then
    if (clkenable_250k) then
    ...
    end if;
    end if;
    end process;

    Where clkenable_250k is generated by your VHDL code to be exactly one
    clock cycle in your 0 to 99 counter.


    >
    > And, last question, should I put the clk_250k on a global clock path?
    >

    No...because you should be getting rid of it as a clock and using it
    as a clock enable instead.

    Kevin Jennings
    KJ, Dec 10, 2010
    #2
    1. Advertising

  3. Beppe

    rickman Guest

    I can't say I totally agree with the doom and gloom predictions of
    KJ...


    On Dec 10, 5:28 pm, KJ <> wrote:
    > On Dec 10, 4:13 pm, Beppe <> wrote:
    >
    > > Consider the following system:

    >
    > > inp_clk -- Input clock to FPGA (Xilinx Spartan 3A DSP)
    > > -- directly routed to DCM
    > > -- PERIOD constraint attached to it
    > > -- Frequency: 125 MHz

    >
    > > clk_25 -- CLKDV_OUT from DCM
    > > -- Frequency: 25 MHz

    >
    > > clk_28 -- CLKFX_OUT from DCM
    > > -- Frequency: inp_clk*7/31 MHz

    >
    > > clk_250k -- Output from a VHDL-module that divides the clk_25 with
    > > 100

    >
    > clk_250k will be a problem in an FPGA. In an FPGA environment, you
    > basically almos never want to generate a clock with logic. Even when
    > it comes out of a flip flop you're most likely doomed.


    I agree that generating a clock from a counter is not a good idea.
    But it is not a fatal flaw if handled correctly. But you are better
    off using a clock enable unless there is a reason.


    > > -- Frequency: 250 kHz

    >
    > > CTRL_PROC : process (clk_250k)
    > > begin
    > > if rising_edge(clk_250k) then

    >
    > Yep...doomed


    Isn't that a bit dramatic? If the tools properly recognize this
    signal as a clock and routes it on a clock spline, and you treat it as
    a separate clock with no clear timing relation to the clock it is
    generated from, then there shouldn't be any problem. Actually, I have
    seen the tools not use a clock spline and they seem to handle it
    correctly, recognizing it as a clock but routing it on the local
    interconnect.


    > > end if;
    > > end if;
    > > end process;

    >
    > > CNT_PROC : process (clk_28)
    > > begin
    > > if rising_edge(clk_28) then
    > > if reset = '1' then
    > > cnt <= (others => ‘0’);
    > > else
    > > if reg1 = '1' then
    > > cnt <= cnt + 1;
    > > else
    > > cnt <= cnt - 1;
    > > end if;
    > > end if;
    > > end if;
    > > end process;

    >
    > > reg1 is assigned a value in CTRL_PROC and read in CNT_PROC and thus it
    > > is crossing clock domains. Do I need to worry about that in the above
    > > situation and apply some asynchronous clock domain techniques?

    >
    > Yes and no.
    > - Since you created two clocks, then yes you should treat them as if
    > they are unrelated.
    > - What you should do is generate a clock enable for rather than a
    > clock for the 250k. Then both processes are running in the same clock
    > domain...no clock crossings at all.
    >
    > Instead of this...
    > process(clk_250k)
    > begin
    > if rising_edge(clk_250k) then
    > ...
    > end if;
    > end process;
    >
    > Do this...
    > process(clk)
    > begin
    > if rising_edge(clk) then
    > if (clkenable_250k) then
    > ...
    > end if;
    > end if;
    > end process;
    >
    > Where clkenable_250k is generated by your VHDL code to be exactly one
    > clock cycle in your 0 to 99 counter.
    >
    >
    >
    > > And, last question, should I put the clk_250k on a global clock path?

    >
    > No...because you should be getting rid of it as a clock and using it
    > as a clock enable instead.


    I don't think you can easily put a signal on a global clock line. If
    the tools recognize it as a clock, because it drives the clock input
    of a FF, it will consider if it needs to use a global clock line to
    control skew. If so it will use one. If not it won't.

    There are times when you don't want to use an enable. A design I did
    generates a clock enable to control some circuitry. But the input and
    output of the data signals need to be done on the actual clock edges
    to optimize the setup and hold times of the external signals. So the
    data input and output are run through a FF clocked by the clock I am
    generating and then I deal with the data timing as required.

    Rick
    rickman, Dec 11, 2010
    #3
  4. Beppe

    KJ Guest

    On Dec 10, 11:44 pm, rickman <> wrote:
    > I can't say I totally agree with the doom and gloom predictions of
    > KJ...
    > > clk_250k will be a problem in an FPGA.  In an FPGA environment, you
    > > basically almos never want to generate a clock with logic.  Even when
    > > it comes out of a flip flop you're most likely doomed.

    >
    > I agree that generating a clock from a counter is not a good idea.
    > But it is not a fatal flaw if handled correctly.  


    The only way to 'handle it correctly' will be to treat it as an
    independent clock domain and design in clock domain crossing logic.
    Without that, you'll be running into hold time issues with any signal
    originating from the high speed clock domain that enters the generated
    clock domain. You can't do anything about those issues except re-
    route, cross your fingers and hope. Yes you can hand hold a design
    and get it to work, but before you do so there should be a compelling
    reason to do so. No such reason was posted.

    > > > CTRL_PROC : process (clk_250k)
    > > > begin
    > > >  if rising_edge(clk_250k) then

    >
    > > Yep...doomed

    >
    > Isn't that a bit dramatic?  


    No. I would characterize the OP's odds of success as 'low'. At best,
    he would find that he is never able to get the design working right
    out of the shoot, abandon the approach and will end up with more
    knowledge. That would be a good outcome. At worst, the design would
    be going into production when there starts to become a growing pile of
    boards that seem to have a 'temperature sensitivity' or 'date code
    issue'.

    What is your definition of 'doomed'?

    >If the tools properly recognize this
    > signal as a clock and routes it on a clock spline, and you treat it as
    > a separate clock with no clear timing relation to the clock it is
    > generated from,


    But the OP clearly doesn't know this if you read the post.

    >
    > There are times when you don't want to use an enable.  A design I did
    > generates a clock enable to control some circuitry.  But the input and
    > output of the data signals need to be done on the actual clock edges
    > to optimize the setup and hold times of the external signals.  So the
    > data input and output are run through a FF clocked by the clock I am
    > generating and then I deal with the data timing as required.
    >


    But in those situations, you don't have any logic being implemented in
    the clock domain crossing as was in the OP. In the posted code, the
    signals reset, byte_received and data_in probably originate in some
    other domain and are crossing; reg1, as noted by the OP definitely
    does come from a foreign clock domain and is not treated properly.

    The clock domain crossing looks like this...

    Synced_To_Clock_Signal <= Synced_To_Other_Clock_Signal when
    rising_edge(Clock);

    Kevin Jennings
    KJ, Dec 11, 2010
    #4
  5. Beppe

    Beppe Guest

    Thanks for the answers.

    An enable won’t solve the problem of crossing clock domains. With an
    enable the CTRL_PROC would be clocked by clk_25, but the CNT_PROC
    would still be clocked by clk_28. clk_28 = 35/31*clk_25.

    I’m aware of the problem with logic generated clocks, but I hope that
    Rick is right here. Putting the clock on a low skew global clock net
    should be enough to ensure that hold and setup times are met.
    Actually, when synthesizing the design, XST infers a BUFG on the
    clk_250k, as you predicted Rick, and the design seems to be working
    fine in hardware although I haven’t made any extensive tests yet.

    I was first thinking that it would be okay to put the clk_250k on a
    non-dedicated clock net because of its low frequency, but the
    frequency doesn’t matter here if I’m right when rethinking it. The
    output of a flip-flop (as a result of the flip-flop being clocked by a
    clock edge) could be propagating to the next flip-flop before the same
    clock edge clocks the next flip-flop and thus leading to a hold time
    violation no matter the frequency. Right?

    On a side note, a solution for clocks with excessive skew (on non-
    global clock nets) should be to alternate between positive and
    negative clock edges on every other register. That would cut the
    performance by half, but if it’s applied on low frequency clocks it
    doesn’t really matter. Is this a no, no technique or would I be fine
    using it?

    As for the original question I guess I could simply find the minimum
    distance between a clk_28 edge and a clk_25 edge (Hm, exactly this is
    what ISE/XST should do if I understand the documentation correctly).
    That time would be the “new” timing constraint. If it’s impossible to
    meet this new timing I need to use asynchronous clock domain
    techniques, otherwise it would be just fine.

    > In the posted code, the
    > signals reset, byte_received and data_in probably originate in some
    > other domain and are crossing; reg1, as noted by the OP definitely
    > does come from a foreign clock domain and is not treated properly.


    data_in and byte_received are registers clocked by clk_250k and
    originate from a MIDI UART. The clk_250k frequency is eight times the
    31.25 kbaud rate of the MIDI interface and used to retrieve the
    asynchronous serial MIDI data.

    Beppe
    Beppe, Dec 11, 2010
    #5
  6. Beppe

    Beppe Guest

    > (Hm, exactly this is
    > what ISE/XST should do if I understand the documentation correctly).


    And it does. Another good reason for using clock enables in this
    particular case (and probably in other cases as well) and not the
    derived clock is that XST sees the relationship between clk_25 and
    clk_28 when a source register is clocked by the first and the
    destination register is clocked by the second.

    A test (not with the exact processes above) reveals this. Timing
    report:

    Slack: -5.319ns (requirement –
    (data path - clock path skew + uncertainty))
    Source: test_cnt_1 (FF)
    Destination: led_2 (FF)
    Requirement: 1.140ns
    Data Path Delay: 6.059ns (Levels of Logic = 10)
    (Component delays alone exceeds constraint)
    Clock Path Skew: -0.400ns (1.832 - 2.232)
    Source Clock: clk_25 rising at 1169000.000ns
    Destination Clock: clk_28 rising at 1169001.140ns
    Clock Uncertainty: 0.000ns

    So, the minimum distance is 1.140 ns and that’s the new requirement,
    which of course is not met.

    /B
    Beppe, Dec 11, 2010
    #6
  7. Beppe

    rickman Guest

    On Dec 11, 11:29 am, KJ <> wrote:
    > On Dec 10, 11:44 pm, rickman <> wrote:
    >
    > > I can't say I totally agree with the doom and gloom predictions of
    > > KJ...
    > > > clk_250k will be a problem in an FPGA.  In an FPGA environment, you
    > > > basically almos never want to generate a clock with logic.  Even when
    > > > it comes out of a flip flop you're most likely doomed.

    >
    > > I agree that generating a clock from a counter is not a good idea.
    > > But it is not a fatal flaw if handled correctly.  

    >
    > The only way to 'handle it correctly' will be to treat it as an
    > independent clock domain and design in clock domain crossing logic.
    > Without that, you'll be running into hold time issues with any signal
    > originating from the high speed clock domain that enters the generated
    > clock domain.  You can't do anything about those issues except re-
    > route, cross your fingers and hope.  Yes you can hand hold a design
    > and get it to work, but before you do so there should be a compelling
    > reason to do so.  No such reason was posted.


    I expect there are tons of facts involve that he didn't post. Why not
    assume the guy has a brain in his head and discuss the issue without
    being extreme about it?


    > > > > CTRL_PROC : process (clk_250k)
    > > > > begin
    > > > >  if rising_edge(clk_250k) then

    >
    > > > Yep...doomed

    >
    > > Isn't that a bit dramatic?  

    >
    > No.  I would characterize the OP's odds of success as 'low'.  At best,
    > he would find that he is never able to get the design working right
    > out of the shoot, abandon the approach and will end up with more
    > knowledge.  That would be a good outcome.  At worst, the design would
    > be going into production when there starts to become a growing pile of
    > boards that seem to have a 'temperature sensitivity' or 'date code
    > issue'.
    >
    > What is your definition of 'doomed'?
    >
    > >If the tools properly recognize this
    > > signal as a clock and routes it on a clock spline, and you treat it as
    > > a separate clock with no clear timing relation to the clock it is
    > > generated from,

    >
    > But the OP clearly doesn't know this if you read the post.


    I think you are missing the point. The OP is asking the question. Of
    course he doesn't "know" for sure that he has to treat the new clock
    as an independent clock, otherwise he wouldn't be asking the
    question. But clearly he is aware of the issues involved. So yes,
    "doomed" is being overly dramatic.


    > > There are times when you don't want to use an enable.  A design I did
    > > generates a clock enable to control some circuitry.  But the input and
    > > output of the data signals need to be done on the actual clock edges
    > > to optimize the setup and hold times of the external signals.  So the
    > > data input and output are run through a FF clocked by the clock I am
    > > generating and then I deal with the data timing as required.

    >
    > But in those situations, you don't have any logic being implemented in
    > the clock domain crossing as was in the OP.  In the posted code, the
    > signals reset, byte_received and data_in probably originate in some
    > other domain and are crossing; reg1, as noted by the OP definitely
    > does come from a foreign clock domain and is not treated properly.
    >
    > The clock domain crossing looks like this...
    >
    > Synced_To_Clock_Signal <= Synced_To_Other_Clock_Signal when
    > rising_edge(Clock);
    >
    > Kevin Jennings


    Yes, the OP is asking if he needs to add that sort of code. The
    answer is "yes". No need to say his design is "doomed" or otherwise
    be dramatic about it. If the guy didn't have a clue, he wouldn't have
    asked the question.

    Rick
    rickman, Dec 12, 2010
    #7
  8. Beppe

    rickman Guest

    On Dec 11, 3:43 pm, Beppe <> wrote:
    > Thanks for the answers.
    >
    > An enable won’t solve the problem of crossing clock domains. With an
    > enable the CTRL_PROC would be clocked by clk_25, but the CNT_PROC
    > would still be clocked by clk_28. clk_28 = 35/31*clk_25.
    >
    > I’m aware of the problem with logic generated clocks, but I hope that
    > Rick is right here. Putting the clock on a low skew global clock net
    > should be enough to ensure that hold and setup times are met.
    > Actually, when synthesizing the design, XST infers a BUFG on the
    > clk_250k, as you predicted Rick, and the design seems to be working
    > fine in hardware although I haven’t made any extensive tests yet.


    Don't count on the fact that the design works on your lab bench as
    proof that it works in any real sense! You can never prove a design
    works by testing it!!! You can only use test to prove that a design
    doesn't work. To prove that it works requires that you test all
    possible conditions and that's not really possible much less
    practical.


    > I was first thinking that it would be okay to put the clk_250k on a
    > non-dedicated clock net because of its low frequency, but the
    > frequency doesn’t matter here if I’m right when rethinking it. The
    > output of a flip-flop (as a result of the flip-flop being clocked by a
    > clock edge) could be propagating to the next flip-flop before the same
    > clock edge clocks the next flip-flop and thus leading to a hold time
    > violation no matter the frequency. Right?
    >
    > On a side note, a solution for clocks with excessive skew (on non-
    > global clock nets) should be to alternate between positive and
    > negative clock edges on every other register. That would cut the
    > performance by half, but if it’s applied on low frequency clocks it
    > doesn’t really matter. Is this a no, no technique or would I be fine
    > using it?


    Yes, I think you understand the issue here. I've never considered
    using a low speed clock in this manner, but I expect it would work ok
    as long as you account for ***ALL*** possible logic paths. For
    example, if you have any sort of counter, you would need to use two
    sets of FFs in the feedback loop, one positive edge triggered and one
    negative edge triggered. Otherwise clock skew can cause one output to
    change before another bit that depends on the first is clocked. As
    you say, clock skew causes hold time problems.


    > As for the original question I guess I could simply find the minimum
    > distance between a clk_28 edge and a clk_25 edge (Hm, exactly this is
    > what ISE/XST should do if I understand the documentation correctly).
    > That time would be the “new” timing constraint. If it’s impossible to
    > meet this new timing I need to use asynchronous clock domain
    > techniques, otherwise it would be just fine.


    I'm not sure what you are getting at. If the clocks are not simply
    related, I'm not sure you can assume there is any useful relationship
    between their timing. To generate the 28 MHz clock the 125 MHz input
    clock is multiplied up to 825 before being divided down to 28.xxx.
    How would you expect the tools to consider the timing relationship
    between two clocks divided down from an 825 MHz (~1.2 ns period)
    clock?


    > > In the posted code, the
    > > signals reset, byte_received and data_in probably originate in some
    > > other domain and are crossing; reg1, as noted by the OP definitely
    > > does come from a foreign clock domain and is not treated properly.

    >
    > data_in and byte_received are registers clocked by clk_250k and
    > originate from a MIDI UART. The clk_250k frequency is eight times the
    > 31.25 kbaud rate of the MIDI interface and used to retrieve the
    > asynchronous serial MIDI data.


    I recently discussed a multiple clock design with my customer. He
    said he had more than 50 clocks in this design and wanted details on
    how I deal with syncing multiple clock domains. I explained that I do
    all my work in one clock domain and use a particular logic circuit to
    transport clocks, enables and data into that one domain. I solve the
    synchronization problem once at the interface and never have to worry
    about it again.

    That logic uses two processes, one in each clock domain. If the FROM
    domain uses a clock enable, the data is registered in the FROM
    domain. Data is normally also registered in the TO domain but it
    depends on the rates. Clocks and/or clock enables run through a
    simple circuit that deals with metastability and provides a clock
    enable in the new domain that suits the situation. The circuit is
    just three FFs, one in the FROM clock domain and two in the TO clock
    domain. The FROM domain FF and one of the TO domain FFs have the data
    inputs and outputs connected in a feedback loop with one inverter in
    the loop. If syncing a clock the FROM domain FF has no enable. If
    syncing a clock enable, that enable is used on the FROM domain FF.
    The TO domain FF in the feedback loop feeds the second FF for
    metastability minimization. Every FROM domain clock edge or clock
    enable causes the feedback loop to toggle state. An XOR gate on the
    output of the two TO FFs gives you a clock enable in the TO domain.
    The FROM domain clock can be faster than the TO domain clock as long
    as the FROM clock enable is less frequent than half the TO domain
    clock rate. It may even be possible to have an enable rate up to the
    TO domain clock rate, but I won't swear to that unless I analyzed this
    carefully.

    This is a lot simpler to think about looking at a diagram. Maybe I
    need to write this up. I didn't think of this circuit myself. A co-
    worker told me about it and it was given to him by his brother I
    think. It is very versatile and is the only circuit I use for clock
    domain crossing with varying data registers depending on the
    particulars.

    My customer found this to work for him with his 50+ clocks.

    Rick
    rickman, Dec 12, 2010
    #8
  9. On 12/12/2010 11:01 AM, rickman wrote:
    > On Dec 11, 3:43 pm, Beppe<> wrote:
    >> Thanks for the answers.

    [snip]
    >
    > Don't count on the fact that the design works on your lab bench as
    > proof that it works in any real sense! You can never prove a design
    > works by testing it!!! You can only use test to prove that a design
    > doesn't work. To prove that it works requires that you test all
    > possible conditions and that's not really possible much less
    > practical.
    >


    I am sorry but I disagree with you on this point. There are "good
    practices" that help a lot in guaranteeing the quality of your project.
    I believe that coding is just part of the story. Having the possibility
    to test the design by a different team from the designers one will make
    a huge difference. To do that a very precise (not necessarily detailed)
    documentation is of course mandatory, since the verification team should
    not go in the rtl details, or even the timing constraints and place &
    route details of the project (the concept behind the design will also
    benefit of a well structured documentation).

    This is why there are standardized procedures, for avionics, space
    applications, military applications (to mention some of them), which go
    beyond the vhdl and define a work flow that should be as much
    independent as possible from the individual skills of the designers team.

    And also limiting the focus only on the coding side, there are a lot of
    dos and don'ts that should be followed thoroughly.
    Here for instance a good article on common hdl mistakes (and IMHO
    misconceptions):

    http://www.designabstraction.co.uk/Articles/Common HDL Errors.PDF

    >
    >> I was first thinking that it would be okay to put the clk_250k on a
    >> non-dedicated clock net because of its low frequency, but the
    >> frequency doesn’t matter here if I’m right when rethinking it. The
    >> output of a flip-flop (as a result of the flip-flop being clocked by a
    >> clock edge) could be propagating to the next flip-flop before the same
    >> clock edge clocks the next flip-flop and thus leading to a hold time
    >> violation no matter the frequency. Right?
    >>
    >> On a side note, a solution for clocks with excessive skew (on non-
    >> global clock nets) should be to alternate between positive and
    >> negative clock edges on every other register. That would cut the
    >> performance by half, but if it’s applied on low frequency clocks it
    >> doesn’t really matter. Is this a no, no technique or would I be fine
    >> using it?


    Why do you need to go in such a complicated pathway when you don't need
    to? It has been already suggested a very easy and robust solution that
    will avoid any of the problems you mentioned:

    On 12/10/2010 11:28 PM, KJ wrote:
    > - What you should do is generate a clock enable for rather than a
    > clock for the 250k. Then both processes are running in the same clock
    > domain...no clock crossings at all.
    >


    In my opinion the use of both rising and falling edges should have a
    stronger motivation (like to minimize the peak current during clock
    transitions in large SoC).

    >
    >> As for the original question I guess I could simply find the minimum
    >> distance between a clk_28 edge and a clk_25 edge (Hm, exactly this is
    >> what ISE/XST should do if I understand the documentation correctly).
    >> That time would be the “new” timing constraint. If it’s impossible to
    >> meet this new timing I need to use asynchronous clock domain
    >> techniques, otherwise it would be just fine.

    >


    Even though your solution may work, that doesn't mean it is the right
    one. I would recommend going through a clock domain crossing technique
    as already suggested.
    Again, following "good practices" not only help us having better chances
    our systems work, it also (and more important) helps spreading the use
    of them with invaluable returns to the whole community.

    > I'm not sure what you are getting at. If the clocks are not simply
    > related, I'm not sure you can assume there is any useful relationship
    > between their timing. To generate the 28 MHz clock the 125 MHz input
    > clock is multiplied up to 825 before being divided down to 28.xxx.
    > How would you expect the tools to consider the timing relationship
    > between two clocks divided down from an 825 MHz (~1.2 ns period)
    > clock?
    >
    >
    >>> In the posted code, the
    >>> signals reset, byte_received and data_in probably originate in some
    >>> other domain and are crossing; reg1, as noted by the OP definitely
    >>> does come from a foreign clock domain and is not treated properly.

    >>
    >> data_in and byte_received are registers clocked by clk_250k and
    >> originate from a MIDI UART. The clk_250k frequency is eight times the
    >> 31.25 kbaud rate of the MIDI interface and used to retrieve the
    >> asynchronous serial MIDI data.


    That is data_in and byte_received are from a different clock domain and
    they should by resync'ed to be used in the clk_25 domain.

    >
    > I recently discussed a multiple clock design with my customer. He
    > said he had more than 50 clocks in this design and wanted details on
    > how I deal with syncing multiple clock domains. I explained that I do
    > all my work in one clock domain and use a particular logic circuit to
    > transport clocks, enables and data into that one domain. I solve the
    > synchronization problem once at the interface and never have to worry
    > about it again.
    >


    I would recommend an alternative to the 50 clocks domains, instead.

    Al
    Alessandro Basili, Dec 12, 2010
    #9
  10. Beppe

    Beppe Guest

    > Don't count on the fact that the design works on your lab bench as
    > proof that it works in any real sense! You can never prove a design
    > works by testing it!!! You can only use test to prove that a design
    > doesn't work. To prove that it works requires that you test all
    > possible conditions and that's not really possible much less
    > practical.


    Of course you’re right. “It’s working in hardware” was more of a hint
    that it might not be totally doomed.

    > How would you expect the tools to consider the timing relationship
    > between two clocks divided down from an 825 MHz (~1.2 ns period)
    > clock?


    Maybe I wasn’t clear enough, but the two clocks are related by a known
    fraction. They are both derived from the 125 MHz input clock. clk_28 =
    125*7/31 and clk_25 = 125/5 and hence clk_28 = 35/31*clk_25. And I
    expect the tools to consider the timing relationship because the ISE/
    XST/DCM documentation states that the software derives a new PERIOD
    for each of the DCM output clocks and determines the clock
    relationships between the output clock domains. And that is also what
    the timing report in my previous post reflects.

    > I solve the synchronization problem once at the interface
    > and never have to worry about it again.

    Seems like a good idea.

    > This is a lot simpler to think about looking at a diagram. Maybe I
    > need to write this up.

    Please do that! I lost you somewhere in between the domains..., but I
    would very much like to see how you solve the clock domain crossing.

    /B
    Beppe, Dec 12, 2010
    #10
  11. Beppe

    Beppe Guest

    > Why do you need to go in such a complicated pathway when you don't need
    > to? It has been already suggested a very easy and robust solution that
    > will avoid any of the problems you mentioned:
    > On 12/10/2010 11:28 PM, KJ wrote:
    > > - What you should do is generate a clock enable for rather than a
    > > clock for the 250k. Then both processes are running in the same clock
    > > domain...no clock crossings at all.


    I don’t intend to. As I said it was just a side note. And as I also
    have said, that solution doesn’t help since I still need to cross
    domains. With an enable the CTRL_PROC would be clocked by clk_25, but
    the CNT_PROC would still be clocked by clk_28.

    > That is data_in and byte_received are from a different clock domain and
    > they should by resync'ed to be used in the clk_25 domain.


    If you read the original post you will notice that the clk_25 domain
    isn’t used in either of the two processes. data_in and byte_received
    are read in the CTRL_PROC, which is clocked by clk_250k and thus they
    don't cross domains and they don’t need to be resynchronized. At least
    not in the given example.

    /B
    Beppe, Dec 12, 2010
    #11
  12. On 12/12/2010 10:45 PM, Beppe wrote:
    >> Why do you need to go in such a complicated pathway when you don't need
    >> to? It has been already suggested a very easy and robust solution that
    >> will avoid any of the problems you mentioned:
    >> On 12/10/2010 11:28 PM, KJ wrote:
    >> > - What you should do is generate a clock enable for rather than a
    >> > clock for the 250k. Then both processes are running in the same clock
    >> > domain...no clock crossings at all.

    >
    > I don’t intend to. As I said it was just a side note. And as I also
    > have said, that solution doesn’t help since I still need to cross
    > domains. With an enable the CTRL_PROC would be clocked by clk_25, but
    > the CNT_PROC would still be clocked by clk_28.
    >


    That is the reason why you need to resync.

    >> That is data_in and byte_received are from a different clock domain and
    >> they should by resync'ed to be used in the clk_25 domain.

    >
    > If you read the original post you will notice that the clk_25 domain
    > isn’t used in either of the two processes. data_in and byte_received
    > are read in the CTRL_PROC, which is clocked by clk_250k and thus they
    > don't cross domains and they don’t need to be resynchronized. At least
    > not in the given example.
    >


    My fault, indeed it seems to me you do not need the clk_250k at all and
    can have data_in and byte_received directly in clk_25 domain (800 pulses
    per bit).

    > /B
    Alessandro Basili, Dec 12, 2010
    #12
  13. Beppe

    Beppe Guest


    > > I don t intend to. As I said it was just a side note. And as I also
    > > have said, that solution doesn t help since I still need to cross
    > > domains. With an enable the CTRL_PROC would be clocked by clk_25, but
    > > the CNT_PROC would still be clocked by clk_28.

    >
    > That is the reason why you need to resync.


    Exactly. And the reason why an enable doesn't help. However, an enable
    will get rid of the logic generated clk_250k although I haven't been
    convinced why it's so bad with a logic generated clock even when it is
    put on the low skew global clock line.


    > >> That is data_in and byte_received are from a different clock domain and
    > >> they should by resync'ed to be used in the clk_25 domain.

    >
    > > If you read the original post you will notice that the clk_25 domain
    > > isn t used in either of the two processes. data_in and byte_received
    > > are read in the CTRL_PROC, which is clocked by clk_250k and thus they
    > > don't cross domains and they don t need to be resynchronized. At least
    > > not in the given example.

    >
    > My fault, indeed it seems to me you do not need the clk_250k at all and
    > can have data_in and byte_received directly in clk_25 domain (800 pulses
    > per bit).


    That's right. So in any case I need to use a clock domain crossing
    technique unless I rewrite the MIDI UART and clock it with the clk_28.

    /B
    Beppe, Dec 13, 2010
    #13
  14. Beppe

    KJ Guest

    On Dec 13, 5:05 am, Beppe <> wrote:
    >
    > > That is the reason why you need to resync.

    >
    > Exactly. And the reason why an enable doesn't help. However, an enable
    > will get rid of the logic generated clk_250k although I haven't been
    > convinced why it's so bad with a logic generated clock even when it is
    > put on the low skew global clock line.
    >


    Because of the potential for hold time problems on a signal coming
    from the high speed clock domain into the generated clock domain. The
    low skew that you are talking about is between different flops clocked
    by that same clock. It does not address the skew between the two
    clock domains. The timing analysis will report it...but it won't fix
    it. While this is true of all timing problems, the solution to this
    particular timing problem is to add delays into the data path so that
    the minimum data delay is still faster than the clock (plus setup).
    Then ask yourself, how do you insert delays into an FPGA design? Do
    you want to be adding this delay potentially every time you re-route
    the design for some reason?

    Plus, when you get right down to it, it will likely take exactly the
    same amount of logic to generate the lower speed clock as it would to
    generate the clock enable...so ask yourself, other than more work and
    potential headaches what do you expect to get by using a generated
    clock?

    Kevin Jennings
    KJ, Dec 13, 2010
    #14
  15. Beppe

    Beppe Guest

    > Because of the potential for hold time problems on a signal coming
    > from the high speed clock domain into the generated clock domain.


    But if there’s no data coming from the high speed clock domain into
    the generated clock domain I don’t see the problem. That is actually
    the case in the given example. The clock domain crossing is between
    clk_250k and clk_28 not between clk_250k and clk_25.

    > Then ask yourself, how do you insert delays into an FPGA design?


    Clocking on both positive and negative clock edge...! Ok, I won’t do
    that I will use enables.

    > what do you expect to get by using a generated clock?


    Lower power consumption?

    /B
    Beppe, Dec 13, 2010
    #15
  16. Beppe

    rickman Guest

    On Dec 12, 3:37 pm, Alessandro Basili <>
    wrote:
    > On 12/12/2010 11:01 AM, rickman wrote:
    >
    > > On Dec 11, 3:43 pm, Beppe<> wrote:
    > >> Thanks for the answers.

    > [snip]
    >
    > > Don't count on the fact that the design works on your lab bench as
    > > proof that it works in any real sense! You can never prove a design
    > > works by testing it!!! You can only use test to prove that a design
    > > doesn't work. To prove that it works requires that you test all
    > > possible conditions and that's not really possible much less
    > > practical.

    >
    > I am sorry but I disagree with you on this point. There are "good
    > practices" that help a lot in guaranteeing the quality of your project.


    I never said testing isn't useful. I said that testing can't assure
    that something works unless you test every possible condition and that
    is not possible in an absolute sense.

    Besides, you snipped the OP's comment I was responding to...

    "the design seems to be working fine in hardware although I haven’t
    made any extensive tests yet."

    The problem we are discussing is ***exactly*** the sort of thing you
    may not find in testing. The way the OP has constructed the circuit
    it may work in 99.99% of the systems he builds. Or it may work 99.99%
    of the time in all of the systems. But testing can't validate timing
    since you can't control all of the variables.

    The only thing testing can really do is to verify that your design
    meets your requirements... if your requirements are testable! I've
    been trained in quality process development and after seeing it in
    action, I realize that much of it is not a better than intelligent
    thinking. Just like many of the tools provided in engineering, this
    is one that seems to provide benefit when used by the "masses" rather
    than by the skilled.


    > I believe that coding is just part of the story. Having the possibility
    > to test the design by a different team from the designers one will make
    > a huge difference.


    "a huge difference"... I understand there are lots of ways to improve
    testing, but that doesn't change the fundamental limitation of
    testing.


    > To do that a very precise (not necessarily detailed)
    > documentation is of course mandatory, since the verification team should
    > not go in the rtl details, or even the timing constraints and place &
    > route details of the project (the concept behind the design will also
    > benefit of a well structured documentation).
    >
    > This is why there are standardized procedures, for avionics, space
    > applications, military applications (to mention some of them), which go
    > beyond the vhdl and define a work flow that should be as much
    > independent as possible from the individual skills of the designers team.
    >
    > And also limiting the focus only on the coding side, there are a lot of
    > dos and don'ts that should be followed thoroughly.
    > Here for instance a good article on common hdl mistakes (and IMHO
    > misconceptions):
    >
    > http://www.designabstraction.co.uk/Articles/Common HDL Errors.PDF


    I'm not sure what to say about this article. It is actually a bit
    shallow in my opinion. But it also contains errors! Much of it is
    really just the opinion of the author.


    > Even though your solution may work, that doesn't mean it is the right
    > one. I would recommend going through a clock domain crossing technique
    > as already suggested.
    > Again, following "good practices" not only help us having better chances
    > our systems work, it also (and more important) helps spreading the use
    > of them with invaluable returns to the whole community.


    I think that terms like "good practices" are some of the least useful
    concepts I've ever seen. First, where are "good practices" defined?
    Without a clear, detailed definition of the term, it doesn't
    communicate anything. Usually it is used to mean "what I do". It may
    be defined within a company, in some limited ways it may be defined
    within a sector. But in general this is a term that has little
    meaning as used by most people. This is much like recommending to
    design "carefully". I can't say how many times I have seen that word
    used in engineering without actually saying anything.


    > > I recently discussed a multiple clock design with my customer. He
    > > said he had more than 50 clocks in this design and wanted details on
    > > how I deal with syncing multiple clock domains. I explained that I do
    > > all my work in one clock domain and use a particular logic circuit to
    > > transport clocks, enables and data into that one domain. I solve the
    > > synchronization problem once at the interface and never have to worry
    > > about it again.

    >
    > I would recommend an alternative to the 50 clocks domains, instead.


    What alternative would that be??? Is that different than the solution
    I recommended?

    Rick
    rickman, Dec 14, 2010
    #16
  17. Beppe

    rickman Guest

    On Dec 12, 4:17 pm, Beppe <> wrote:
    > > Don't count on the fact that the design works on your lab bench as
    > > proof that it works in any real sense!  You can never prove a design
    > > works by testing it!!!  You can only use test to prove that a design
    > > doesn't work.  To prove that it works requires that you test all
    > > possible conditions and that's not really possible much less
    > > practical.

    >
    > Of course you’re right. “It’s working in hardware” was more of a hint
    > that it might not be totally doomed.
    >
    > > How would you expect the tools to consider the timing relationship
    > > between two clocks divided down from an 825 MHz (~1.2 ns period)
    > > clock?

    >
    > Maybe I wasn’t clear enough, but the two clocks are related by a known
    > fraction. They are both derived from the 125 MHz input clock. clk_28 =
    > 125*7/31 and clk_25 = 125/5 and hence clk_28 = 35/31*clk_25. And I
    > expect the tools to consider the timing relationship because the ISE/
    > XST/DCM documentation states that the software derives a new PERIOD
    > for each of the DCM output clocks and determines the clock
    > relationships between the output clock domains. And that is also what
    > the timing report in my previous post reflects.
    >
    > > I solve the synchronization problem once at the interface
    > > and never have to worry about it again.

    >
    > Seems like a good idea.
    >
    > > This is a lot simpler to think about looking at a diagram.  Maybe I
    > > need to write this up.

    >
    > Please do that! I lost you somewhere in between the domains..., but I
    > would very much like to see how you solve the clock domain crossing.



    I don't have time to draw a diagram, but here is some code. I've had
    to edit out a lot of support circuitry which is not related, I hope I
    didn't screw this up.

    Scfg_Sync : process (SysClk, SysRst) begin
    if (SysRst = '1') then
    Scfg_SysClk <= '0';
    elsif (falling_edge(SysClk)) then
    if (Clk_en = '1') then
    Scfg_SysClk <= not Scfg_StbLatch; -- Sync across clock domains
    end if;
    end if;
    end process Scfg_Sync;

    -- Control register interface
    -- Clock interface and synchronize to system clock
    CntrlReg : process (Scfg_Str, IF_EN) begin
    if (IF_EN = '1') then
    Scfg_StbLatch <= '0';
    Scfg_StbLatch_D <= '0';
    elsif (rising_edge(Scfg_Str)) then
    Scfg_StbLatch <= Scfg_SysClk; -- Sync across clock domains
    Scfg_StbLatch_D <= Scfg_StbLatch;
    end if;
    end process CntrlReg;

    Scfg_clk_en <= Scfg_StbLatch xor Scfg_StbLatch_D;

    Every time the clock enable in the SysClk domain is asserted, the loop
    signal Scfg_SysClk toggles generating an edge which is detected by the
    concurrent statement at the end. That logic can also be registered to
    help with metastability issues since Scfg_StbLatch will go
    metastable.

    To convey the clock SysClk to the other domain, just remove the if
    (Clk_en = '1') and let every rising edge send an transition to the
    other domain. The Scfg_Str domain has to be clocked at least as fast
    as the edge rate of Scfg_SysClk for an enable or twice as fast for a
    clock.

    Getting data across just requires that the data be held stable until
    it is clocked into the receiving domain. Sometimes this does not
    require an interface register at all depending on the particulars of
    the interface timing, etc.

    Rick
    rickman, Dec 14, 2010
    #17
  18. Beppe

    Beppe Guest

    > I don't have time to draw a diagram, but here is some code.

    That makes it easier. Here’s the XST RTL schematic of the circuit:

    http://www.mypicx.com/uploadimg/1078299247_12152010_1.jpg

    And a wave diagram:

    http://www.mypicx.com/uploadimg/694346392_12152010_2.jpg

    Any particular reason for using the negative edge in the Scfg_Sync
    process? I used the positive edge. data_in is clocked on the positive
    sysclk edge without enable. data_out is clocked on the positive
    scfg_str edge when scfg_clk_en is high.

    Am I using this in a way you recognize?

    /B
    Beppe, Dec 15, 2010
    #18
  19. Beppe

    rickman Guest

    On Dec 15, 4:55 am, Beppe <> wrote:
    > > I don't have time to draw a diagram, but here is some code.

    >
    > That makes it easier. Here’s the XST RTL schematic of the circuit:
    >
    > http://www.mypicx.com/uploadimg/1078299247_12152010_1.jpg
    >
    > And a wave diagram:
    >
    > http://www.mypicx.com/uploadimg/694346392_12152010_2.jpg


    This is why I hate these machine drawn schematics. The machine has no
    clue about the logical flow. Scfg_StbLatch should be in the same line
    with the other blocks clearly showing the flow with the feedback loop
    back to the other clock domain. The feedback loop is what makes it
    work (each side is not armed until the other acknowledges) and the
    following logic is just to reconstruct the enable or clock.


    > Any particular reason for using the negative edge in the Scfg_Sync
    > process? I used the positive edge. data_in is clocked on the positive
    > sysclk edge without enable. data_out is clocked on the positive
    > scfg_str edge when scfg_clk_en is high.
    >
    > Am I using this in a way you recognize?


    Yes, Scfg_Sync was required to use the falling edge in my design as it
    is an external interface. This looks exactly as it should look for a
    clock enable circuit. Metastability precautions are required for the
    signal Scfg_StbLatch. The only other note is to make sure the data is
    held stable long enough for it to be registered in the destination
    domain. This may require a register in the data path driven by
    SysClk. There are a lot of details dependent on the relative clock
    speeds.

    If you need to convey a clock enable just add that to the Scfg_SysClk
    register.

    Rick
    rickman, Dec 15, 2010
    #19
  20. On 12/14/2010 4:56 AM, rickman wrote:
    [snip]
    >> I am sorry but I disagree with you on this point. There are "good
    >> practices" that help a lot in guaranteeing the quality of your project.

    >
    > I never said testing isn't useful. I said that testing can't assure
    > that something works unless you test every possible condition and that
    > is not possible in an absolute sense.
    >


    I don't get that. What you call as "every possible condition" is
    intended as every possible state of a particular set of logic. If your
    logic cannot be described as a well defined number of states then I
    agree that testing will never be enough (but in this case I suggest a
    rework of the design).
    If your states are not controllable (i.e. by an external control signal)
    then there's little you can do in testing. If your states are even not
    observable then I believe you are "doomed" (as somebody said earlier...).

    > Besides, you snipped the OP's comment I was responding to...
    >
    > "the design seems to be working fine in hardware although I haven’t
    > made any extensive tests yet."
    >


    I snipped the OP's comment because didn't add anything that wasn't
    already said in your sentence.

    > The problem we are discussing is ***exactly*** the sort of thing you
    > may not find in testing. The way the OP has constructed the circuit
    > it may work in 99.99% of the systems he builds. Or it may work 99.99%
    > of the time in all of the systems. But testing can't validate timing
    > since you can't control all of the variables.
    >


    This is why the way OP constructed the circuit was suboptimal and that
    is why it was suggested not to use a generated clock, but an enable
    signal (or even clock the UART with the original 25MHz clock).

    > The only thing testing can really do is to verify that your design
    > meets your requirements... if your requirements are testable!


    If something cannot be testable, how would you accept those
    requirements? And how can than be said the system doesn't work?
    according to which requirement violation?

    >
    >> I believe that coding is just part of the story. Having the possibility
    >> to test the design by a different team from the designers one will make
    >> a huge difference.

    >
    > "a huge difference"... I understand there are lots of ways to improve
    > testing, but that doesn't change the fundamental limitation of
    > testing.
    >


    The fundamental limitation of testing are most probably due to a very
    poor description of the device under test. That is why documentation
    should be the first step in a work flow, rather then the last one where
    the designer tend to leave out all the "unnecessary" details which
    eventually lead to misunderstanding. How hard is to test one single
    flip-flop? Not much, only because if fully described.

    >>
    >> http://www.designabstraction.co.uk/Articles/Common HDL Errors.PDF

    >
    > I'm not sure what to say about this article. It is actually a bit
    > shallow in my opinion. But it also contains errors! Much of it is
    > really just the opinion of the author.
    >

    Could you please post the errors? Since I haven't found them, most
    probably your reading was deeper than mine and it would be very helpful
    to me.
    The author not only gives an opinion, it lays down an approach which is
    at a higher level of abstraction than the flops and gates.

    >
    > I think that terms like "good practices" are some of the least useful
    > concepts I've ever seen. First, where are "good practices" defined?


    In many books, standards, proceedings, articles and you may be lucky
    that your company has already defined a set of them.

    > Without a clear, detailed definition of the term, it doesn't
    > communicate anything. Usually it is used to mean "what I do". It may
    > be defined within a company, in some limited ways it may be defined
    > within a sector. But in general this is a term that has little
    > meaning as used by most people. This is much like recommending to
    > design "carefully". I can't say how many times I have seen that word
    > used in engineering without actually saying anything.
    >


    Usually it means "what most of the people do" as opposed of what you
    suggested. Of course circumstances and requirements maybe some how very
    demanding but an alternative architectural approach will surely have an
    higher impact.

    >
    >>> I recently discussed a multiple clock design with my customer. He
    >>> said he had more than 50 clocks in this design and wanted details on
    >>> how I deal with syncing multiple clock domains. I explained that I do
    >>> all my work in one clock domain and use a particular logic circuit to
    >>> transport clocks, enables and data into that one domain. I solve the
    >>> synchronization problem once at the interface and never have to worry
    >>> about it again.

    >>
    >> I would recommend an alternative to the 50 clocks domains, instead.

    >
    > What alternative would that be??? Is that different than the solution
    > I recommended?
    >


    As in the OP example, instead of suggesting how to control the timing of
    the clk_250k I would recommend not to use it at all (that means one
    clock less).

    > Rick
    Alessandro Basili, Dec 15, 2010
    #20
    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. Weng Tianxiang

    Signals across two clock domains

    Weng Tianxiang, Dec 17, 2003, in forum: VHDL
    Replies:
    9
    Views:
    4,927
    Mike Treseler
    Dec 22, 2003
  2. nfirtaps
    Replies:
    13
    Views:
    1,194
    nfirtaps
    Dec 1, 2006
  3. JK
    Replies:
    1
    Views:
    807
    Mike Treseler
    Mar 24, 2007
  4. himassk
    Replies:
    1
    Views:
    1,220
    Paul Uiterlinden
    May 16, 2007
  5. Prashanth Rao
    Replies:
    0
    Views:
    462
    Prashanth Rao
    Sep 19, 2007
Loading...

Share This Page