Forum Discussion

jch4416's avatar
jch4416
Icon for Occasional Contributor rankOccasional Contributor
5 years ago

Timing Closure for domain crossing between source and divided clocks

This post is an offshoot of an earlier post entitled

"Are divided clocks synchronous with the source clock?"

I have a cpld design with 5 different clock domains. There is a slow master clock (1.432MHz, T = 542ns), and 4 (integer) divided clocks generated from the master by separate synchronous counters. The positive edge of each divided clock should then be one Tco behind a positive edge of the source clock, and data in the divided clock domains should be another Tco delayed behind the positive edge of the divided clock. I assumed this was a fixed phase relationship that meant all these domains were synchronous. But Quartus doesn't agree.

I had warnings on every domain crossing: Critical Warning (308060): (High) Rule D101: Data bits are not synchronized when transferred between asynchronous clock domains

There were also hold time violations on signals transferred to the master clock domain. I got rid of these by clocking data out of the master clock domain on the negative edge of the master clock and into the slower domains on the positive edges of the divided clocks. That way there is always at least 270ns of setup and hold time in the divided clock domains.

The result of the above was a new warning: Warning (308022): (Medium) Rule C106: Clock signal source should not drive registers triggered by different clock edges. Is this something I need to be concerned about?

I do have generated clock constraints in my SDC file stating that the divided clocks are integer divisions of the master, but still have "Data bits not synchronized" warnings. Do I need to add synchronizers to every bit? I have synch'ed data ready flags and latched data when they are asserted, but Quartus is still unhappy.

Any help is greatly appreciated

12 Replies

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    Can you show your .sdc and maybe a drawing of your clock network at this point? It's a little hard to visualize.

    You're using such low clock speeds that it's surprising that you'd run into any timing issues, though I guess the hold timing issues may be more of a trampling of the next clock cycle by a previous one.

    • jch4416's avatar
      jch4416
      Icon for Occasional Contributor rankOccasional Contributor

      Hello,

      Happy New Year and thanks for your help. I am attaching the sdc file and a pdf showing the clock tree structure. The clock definitions from the sdc are pasted below the dotted line

      Jim

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

      #**************************************************************
      # Create Clock
      #**************************************************************

      create_clock -name {clock_in_3p6864mhz} -period 271.000 -waveform { 0.000 135.000 } [get_ports {clock_in_3p6864mhz}]
      create_clock -name {cpld_master_clock} -period 542.000 -waveform { 0.000 271.000 } [get_nets {cpld_master_clock}]


      #**************************************************************
      # Create Generated Clock
      #**************************************************************

      create_generated_clock -name {uart_rx_clock} -source [get_nets {cpld_master_clock}] -divide_by 2 -master_clock {cpld_master_clock} [get_registers {clock_divider:CDIV2|clk_out}]
      create_generated_clock -name {uart_tx_clock} -source [get_nets {cpld_master_clock}] -divide_by 32 -master_clock {cpld_master_clock} [get_registers {clock_divider:CDIV3|clk_out}]
      create_generated_clock -name {millisec_clock} -source [get_nets {cpld_master_clock}] -divide_by 1920 -master_clock {cpld_master_clock} [get_registers {clock_divider:CDIV4|clk_out}]
      create_generated_clock -name {heartbeat_clock} -source [get_nets {cpld_master_clock}] -divide_by 3840 -master_clock {cpld_master_clock} [get_registers {clock_divider:CDIV5|clk_out}]

      • sstrell's avatar
        sstrell
        Icon for Super Contributor rankSuper Contributor

        Your second create_clock should be a create_generated_clock since it's sourced from the input clock. And you should always try to use get_pins for your targets instead of get_nets. You can use the Name Finder through the Quartus Text Editor SDC GUI dialog boxes to find the correct targets.

  • SyafieqS's avatar
    SyafieqS
    Icon for Super Contributor rankSuper Contributor

    Hi Jim,


    Any update from the previous reply? Probably share your .sdc file.


    • jch4416's avatar
      jch4416
      Icon for Occasional Contributor rankOccasional Contributor

      Hello SyafieqS,

      No updates on my end, I am still waiting for someone to answer the original question. I restated the question in my previous post

      Jim