Skip to content
VLSI Mentor

Tcl · Module 20

Creating Clocks

Everything else in timing is measured against a clock. Declare it wrong and nothing complains; declare it on a port that does not exist and the report comes back clean and empty.

Intermediate17 min readtcledapart-iisdcclocksconstraints

Part II · Module 20 · Chapter 20.2 · Creating Clocks

A clock declaration says: this signal is a clock, it has this period, and it enters the design here. Every setup check, every hold check and every slack number in the flow is measured against it.

It is the first constraint written and the one with the worst failure mode, because getting it wrong does not produce an error.

1. A primary clock

A primary clock is one that arrives from outside — it is generated elsewhere and enters through a port.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
create_clock -name core_clk -period 2.0 [get_ports clk]

Three pieces:

  • -name core_clk — what the clock is called in everything downstream. Reports, exceptions and clock groups all refer to it by this name, not by the port.
  • -period 2.0 — the cycle time. The unit comes from the library, commonly nanoseconds; a period of 2.0 ns is 500 MHz.
  • [get_ports clk] — where it enters. A collection, so everything from Module 18 applies, including the way it fails.

2. More than one

Most designs have several, and they are simply several declarations:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
create_clock -name core_clk -period 2.0  [get_ports clk]
create_clock -name ref_clk  -period 10.0 [get_ports ref_clk]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  clocks:
    core_clk   2.0            on clk              (primary)
    ref_clk    10.0           on ref_clk          (primary)

Two independent clocks at different frequencies. Whether paths between them should be analysed is a separate decision, and it is Chapter 20.7.

3. Generated clocks

A clock produced inside the design — by a divider, a gate, or a PLL output — is a generated clock. It is declared differently, and the difference matters:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
create_generated_clock -name div2_clk -source ref_clk -divide_by 2 [get_pins -hierarchical u_div/Q]
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    div2_clk   div2 of ref_clk on u_div/Q          (generated)

The essential part is -source. It tells the tool that div2_clk is derived from ref_clk — so the two are phase-related, and the tool can analyse paths between them correctly because it knows how they line up.

Note also that the source is a pin, not a port — the divider's output — which is why the query needs -hierarchical. That is Chapter 18.4 §2's rule, and forgetting it produces an empty collection, which is §5.

4. What the period actually commits you to

The period is not a wish. It is the budget every path in that domain is checked against, and it propagates:

  • A path from a flop to a flop in the same domain gets one period to complete.
  • The I/O budgets in 20.3 and 20.4 are usually expressed as a fraction of it.
  • Multicycle exceptions (20.6) are stated in multiples of it.

Which is why Chapter 20.1 §4 put it in a variable:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
set PERIOD 2.0
create_clock -name core_clk -period $PERIOD [get_ports clk]
set_input_delay [expr {$PERIOD * 0.20}] -clock core_clk [get_ports {d_in[*]}]

Change $PERIOD and the I/O budgets follow. Write 2.0 and 0.4 separately and one day they disagree.

5. The failure that makes everything else meaningless

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
puts "  create_clock on a typo'd port:"
puts "    [catch {create_clock -name core_clk -period 2.0 [get_ports clock]} e] / $e"
puts "  and the port that does exist:"
create_clock -name core_clk -period 2.0 [get_ports clk]
puts "    defined: [llength $::sdc::clocks] clock(s)"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  create_clock on a typo'd port:
    1 / create_clock -name core_clk source matched nothing
  and the port that does exist:
    defined: 1 clock(s)

6. Checking what you declared

After the clocks are defined, print them. Chapter 19.2 is the full version — comparing clocks defined against clocks arriving — and even the short form is worth having at the top of every run:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
foreach c $::sdc::clocks {
    lassign $c name period source kind
    puts [format "  %-10s %-8s on %-14s (%s)" $name $period $source $kind]
}

Three things to check by eye the first time, and by script thereafter:

  • The count. Fewer clocks than you expected means one failed to apply.
  • The periods. Against the specification, not against memory.
  • Primary versus generated. A divider output listed as primary is §3's mistake.

7. Exercises

Exercise 1. What three pieces does a primary clock declaration need?

Exercise 2. Why give the clock a different name from the port it arrives on?

Exercise 3. What makes a clock generated rather than primary?

Exercise 4. What does -source tell the tool, and what goes wrong without it?

Exercise 5. Why does a generated clock's source query usually need -hierarchical?

Exercise 6. A real create_clock on a pattern that matches nothing — what happens?

Exercise 7. Why put the period in a variable?

Where this fits

Part of the Tcl curriculum.