Synthesis · lesson 4

Clocks and the timing model

Define a clock, understand period and waveform, and add uncertainty and latency so that an ideal clock behaves like a real one.

8 min read · Free, no login

Every timing check in a synchronous design is measured against a clock. If the clock is not defined, the tool has nothing to measure against, and the registers are not timed at all. This lesson shows how to define a clock and how to describe, before the clock tree exists, what the clock tree will do to it.

Reading time: about 8 minutes.

4.1 A clock is a waveform

A clock waveform is a periodic signal with one rising and one falling edge per period. Let us consider a clock of period 10 ns with a 50 percent duty cycle. The rising edge is at 0, the falling edge at 5, and the next rising edge at 10. Two numbers describe this: the period (10) and the waveform (the list of edge times, 0 and 5).

A register launches data at one edge and captures it at the next. If the combinational logic between two registers takes longer than one period minus the clock-to-Q delay and the setup time of the capturing register, the path fails. The clock period is therefore the budget every path must live within.

rise at 0 fall at 5 next rise at 10 Period = 10 ns, waveform {0 5} Budget = period โˆ’ uncertainty โˆ’ clock-to-Q โˆ’ setup
A clock waveform with period 10 ns and a 50 percent duty cycle: the rising edge at 0, the falling edge at 5, and the next rising edge at 10. A register launches at one rising edge and must capture at the next, inside the budget the period sets.

4.2 create_clock

The SDC command that defines a clock is create_clock.

create_clock [-name clock_name]
             [-period period_value]
             [-waveform {rise_time fall_time}]
             [-add]
             [source_objects]

For our accumulator:

create_clock -name clk -period 2.0 [get_ports clk]

This defines a 2 ns clock (500 MHz) on the port named clk. Since -waveform is omitted, the tool assumes the rising edge is at 0 and the falling edge at half the period. If a different duty cycle is needed:

create_clock -name clk_30 -period 10 -waveform {0 3} [get_ports clk_in]

Here the clock is high from 0 to 3 and low from 3 to 10, a 30 percent duty cycle.

Typically, the clock is attached to a port. It can also be attached to an internal pin, for example the output of a clock divider. When -name is omitted, the tool might name the clock after the object it is attached to, but behaviour varies, so naming the clock explicitly is better.

4.3 Clock domains in Genus

Genus allows clocks that are synchronous to each other to be grouped in a clock domain. Timing is analysed between clocks in the same domain. If no domain is given, all clocks are assumed to be in one domain.

create_clock -domain core_dom -name clk_core -period 1.0 [get_ports clk_core]
create_clock -domain io_dom   -name clk_io   -period 2.5 [get_ports clk_io]

A path from a flop on clk_core to a flop on clk_io is not timed here, because the domains are separate. Whether that is correct depends on the design. If the two clocks are really unrelated, it is. If they are related and the path is real, the domains must be merged or the relationship stated. We return to this in Lesson 6.

4.4 Clock uncertainty

An ideal clock reaches every register at the same instant. A real one does not. Skew between branches and jitter on the source both shrink the time available to a path. Before the clock tree exists, a designer models this loss with uncertainty.

set_clock_uncertainty 0.10 [get_clocks clk]

With a period of 2.0 and an uncertainty of 0.10, the tool behaves as if the period were 1.9 for setup checks. Uncertainty can be given separately for setup and hold:

set_clock_uncertainty -setup 0.12 [get_clocks clk]
set_clock_uncertainty -hold  0.03 [get_clocks clk]

The value is usually chosen from experience with the technology, often 5 to 10 percent of the period at synthesis, and is reduced as the design progresses and real skew becomes known. A value that is too small hides problems that appear later. One that is too large makes the tool upsize cells for no reason, costing area and power. In case of doubt, err slightly on the larger side early on, and tighten later.

4.5 Clock latency

Latency is the delay from the clock source to the register clock pins. At synthesis the network is ideal, so the latency is zero unless the designer says otherwise.

set_clock_latency 0.8 [get_clocks clk]

This tells the tool that the clock arrives 0.8 ns late at every register. Because it applies equally to launching and capturing registers inside the block, it cancels in register-to-register paths. When the port delays are referenced to the same real clock, as in our accumulator, the latency is applied to the external launch or capture edge as well, so it cancels at the boundary too. It changes the budget at the boundary only when the port delays refer to a virtual clock (Lesson 5) that does not carry the latency. The syntax and defaults of latency options differ between tools, so use the tool's built-in help, for example help set_clock_latency, to confirm what is accepted in your version.

4.6 The ideal network

The tool will not buffer an ideal clock network to fix design rule violations. Genus idealizes clock nets automatically, along with asynchronous set and reset nets. A net can also be marked by hand, and queried:

# Example for a buffered net in a larger design; acc8 needs neither
set_db pin:<design>/<buf_inst>/Z .ideal_network true
puts [get_db net:<design>/<net> .is_ideal]

Thus, the clock is ideal at synthesis not because of an oversight but because the tool leaves the network for clock tree synthesis to build. The designer's only job at this stage is to describe its effect through uncertainty and latency.

4.7 Completing the clock constraints

The minimum clock constraint is a create_clock with a period on every clock source in the design. Without it, the registers behind that source are not timed. In practice, add uncertainty as well, and check afterward that the tool saw every clock:

report_timing -lint

The lint report lists problems such as registers with no clock, which are easy to miss otherwise.

4.8 Why an interviewer asks about this

Clock questions are always asked, because every other constraint refers to a clock. Expect "what is uncertainty and why do we add it", "what is the difference between uncertainty and latency", and "why is the clock ideal at synthesis". A good answer links the three: ideal now, real later, and uncertainty reserving the margin until then.

Key takeaways

  • A clock is a period plus a waveform, and create_clock with a name, period and source is the minimum constraint.
  • Registers on an undefined clock are not timed, so check the lint report to confirm every clock was seen.
  • Uncertainty reserves margin for skew and jitter before the clock tree exists, and is usually reduced as the flow progresses.
  • Latency delays the clock arrival at registers. Against port delays on the same real clock it cancels, and only against a virtual clock does it change the boundary budget.