3

Let me simplify a common clock network structure used in my company:

Firstly, there're multiple true clock sources (PLLs, external input, or RC OSCs).

Right at the beginning when these sources are "born", they are MUXed, and we call this generated clock "system clock".

Then this system clock travels through a lot of clock divider modules. All these DIVs have the same internal structure: the output clock is selected between the input clock and a divided input clock (using D-FFs). Each DIV outputs a clock which clocks certain digital logic, and can drive the next DIV.

                                  DIV(1)
             +-----+    +----------------------+
clk src 1 -->|     |    |                      |
clk src 2 -->| MUX |--------+--------->+---+   |
clk src N -->|     |    |   |  +--+    |MUX|-------+--------------------------> block 1
             +-----+    |   +--|FF|--->+---+   |   |  +------+
                        |      +--+            |   +->|DIV(2)|---+------------> block 2
                        +----------------------+      +------+   |  +------+
                                                                 +->|DIV(N)|--> block N
                                                                    +------+

Then, how can I constrain this clock structure correctly and neatly?

Can I create a "system clock" at the first MUX output? Or should I let all the sources pass?

And how am I supposed to handle all these DIVs? The number of SDC CLOCKs will grow rapidly if I write SDC like this:

(suppose there's only one SDC CLOCK at the entry of DIV(1))


generate a clock after DIV(1)'s FF ----> so, block 1 get 2 SDC CLOCKs


generate a clock after DIV(2)'s FF from DIV(1)'s bypass path

generate a clock after DIV(2)'s FF from DIV(1)'s FF path ----> so, block 2 get 4 SDC CLOCKs


so on.

Or, how can I improve this structure?

Mitu Raj
  • 10,843
  • 6
  • 23
  • 46
Light
  • 323
  • 1
  • 2
  • 12
  • What is its function? – Tony Stewart EE75 Aug 13 '21 at 03:04
  • @TonyStewartEE75 different part of our system needs different clock frequency. But basically they have a relation of divide-by-2/divide-by-4/etc. The whole system is still synchronous. – Light Aug 13 '21 at 03:12
  • 1
    Is that an ASIC design, an FPGA, or a CPLD (i.e. can you even derive a clock in logic without penalty, or would you fare better with generating enables)? – Simon Richter Aug 13 '21 at 09:02
  • @SimonRichter It's ASIC. I have to define too many generated clocks at each FF's Q (for each possible master clock, define a generated clock). – Light Aug 14 '21 at 04:28

1 Answers1

1

Quite tricky and a bit complex. What I would have done is (SDC Contraints):

  1. Constraint clocks src_1 to src_N using:

    create_clock -name clk_1 -period <> [get_ports src_1]

    Note: I assumed clock sources as top-level ports.

  2. The above clocks automatically propagate through Mux to different end points in the design, so you may not need another clock constaint at the Mux output. But there will be clock paths which are contradictory and will not actually exist on design physically (Eg: src_1 to src_2 path can't exist because Mux will forward only one of the clocks) and yet gets evaluated by the timing analyser. To avoid that, use:

    set_clock_groups -exclusive -group {get_clocks clk_1} -group {get_clocks clk_2} .... -group {get_clocks clk_N}

  3. For DIV_1 clock divider, you should create a generated clock at the output of the last flip-flop in the chain or at the input to the Mux1 inside it. The source clock for this generated clock will be the Mux output:

    create_generated_clock -divide_by X -source [get_clocks[get_pins Mux/Mux_output]] -name clk_DIV1 [get_registers/get_cells clk_DIV1_flop]

  4. Repeats steps 2-3 for the rest.


Note:

If this is on FPGA, you have to use dedicated clock-multiplexers, and not an RTL one, and avoid RTL clock dividers. This is to avoid routing of clock through FPGA fabric (poor skew, slew, jitter, latencies ...)

Mitu Raj
  • 10,843
  • 6
  • 23
  • 46
  • It's ASIC. May I ask how do I specify the master clock in step 3 if the `-source` is the mux output? Actually the problem I'm facing is that if I define each clock exactly obeying the SDC rules (for each possible source clocks, generate a clock at the FF output), it will result in too many clocks. – Light Aug 14 '21 at 04:22
  • You have to find the name of that instance and it's pin/port from netlist/RTL and derive clock using [get_clocks[get_pins[Mux/output]]. 'Mux' is the instance. If there are too many, you should find a way like script or something to auto generate or maybe there are specific looping constructs you can use within SDC. – Mitu Raj Aug 14 '21 at 05:04
  • Still confused. If generating and propagating many clocks is the only correct way to constrain this structure, then I'll either use script or redesign clkgen module. – Light Aug 18 '21 at 00:47
  • That's right. You have no other choice. Because each one of these are different clocks. So you have to define them yourself to convey the information to the simulator. I have seen people using scripts in situations like these. @Light – Mitu Raj Aug 18 '21 at 02:40
  • 1
    This is because the timing analyser is not aware that your blocks are clock dividers, and neither it's aware of what factor you will divide it, and neither it's aware of how to handle the muxed clock. So you have to convey this information. – Mitu Raj Aug 18 '21 at 06:24