Many designs create a slower clock from a faster one, for example with a flip-flop that toggles on every clock edge. STA does not follow a clock through a flip-flop, so it does not know that the new signal is a clock. You have to tell it with create_generated_clock. This article shows what happens without the command, how to write it, and how STA chooses the launch and capture edges between a master clock and the clock generated from it.
9 min read | Intermediate
What You'll Learn
- Explain why a clock divider needs a generated clock definition
- Write
create_generated_clockfor a divider and a multiplier - Read the clock summary and the warnings that show a missing clock
- Find the launch and capture edges of a path between a master and a generated clock
A Clock Divider
A divide-by-2 clock is made with a flip-flop that inverts its own output at every clock edge. Its output changes once per clock period, so it goes through a full cycle in two periods. Here is a small design with such a divider and two other flip-flops:
module sta_div (input clk, input d, output q);
reg div, r, s;
initial div = 1'b0;
always @(posedge clk) div <= ~div; // divide-by-2 flip-flop
always @(posedge div) r <= d; // clocked by the slow clock
always @(posedge clk) s <= r; // back in the fast clock domain
assign q = s;
endmodule
The flip-flop r is clocked by div, which is an output of a flip-flop and not a port. In the synthesized netlist of our run, the divider is the cell _4_, r is _3_ and s is _2_.
What Happens Without a Definition
Define only the clock on the port and run the setup check command check_setup -verbose, which lists missing constraints:
create_clock -name clk -period 2.0 [get_ports clk]
set_input_delay 0.4 -clock clk [get_ports d]
set_output_delay 0.4 -clock clk [get_ports q]
Warning: There is 1 unclocked register/latch pin. _3_/CLK Warning: There are 2 unconstrained endpoints. _2_/D _3_/D
STA sees that the clock pin of _3_ has no clock, and so it does not check anything that starts or ends at it. The paths to _3_/D and _2_/D are unconstrained. The worst part is that no violation is reported. Missing checks look like a clean design.
Defining the Generated Clock
Tell STA that the output of the divider is a new clock that is made from clk:
create_generated_clock -name clk_div -source [get_ports clk] -divide_by 2 [get_pins _4_/Q]
-name clk_divnames the new clock.-source [get_ports clk]says which point of the master clock it comes from.-divide_by 2says that the new period is twice the master period. The option-multiply_bydoes the opposite, for a clock multiplier such as a PLL output.[get_pins _4_/Q]is the point where the generated clock appears, the output of the divider.
Print the clock summary to check:
Clock Period Waveform ---------------------------------------------------- clk 2.00 0.00 1.00 clk_div 4.00 0.00 2.00 (generated)
The generated clock has a period of 4.0 ns and a waveform of {0 2.0}. It is half as fast as clk. Now the flip-flop _3_ has a clock, and the warning is gone.
Paths Between the Two Clocks
The generated clock is related to its master clock, because it comes from it. STA therefore checks the paths from clk_div to clk. The question is which edges to use. The rule is the same as in the earlier articles: for setup, STA takes a launch edge and the closest capture edge after it.
The flip-flop _3_ launches data at the rising edge of clk_div at time 0. The flip-flop _2_ is clocked by clk, which rises at 0, 2.0 and 4.0 ns. The first rising edge after the launch is at 2.0 ns, so the data has only one fast period, not the 4.0 ns of the slow clock:
Startpoint: _3_ (rising edge-triggered flip-flop clocked by clk_div)
Endpoint: _2_ (rising edge-triggered flip-flop clocked by clk)
0.0000 0.0000 clock clk_div (rise edge)
0.0000 0.0000 ^ _3_/CLK (sky130_fd_sc_hd__dfxtp_1)
0.2688 0.2688 v _3_/Q (sky130_fd_sc_hd__dfxtp_1)
0.2688 data arrival time
2.0000 2.0000 clock clk (rise edge)
-0.1112 1.8888 library setup time
1.8888 data required time
1.6200 slack (MET)
For hold, the launch edge at 0 and the capture edge at 0 are used, and the hold slack is 0.3096 ns. Paths in the other direction, from clk to clk_div, are also checked. The input d in the example is constrained to clk_div with set_input_delay 0.4 -clock clk_div, so its capture edge is at 4.0 ns, and the setup slack is 3.4988 ns.
The clock divider itself is in the clock path in this example. With ideal clocks, STA treats clk_div as arriving at time 0, as if the divider flip-flop had no delay. After you switch to propagated clocks, the delay from the clock pin of the divider to its output is added to the clock latency. The article about clock latency shows how.
Multiplied and Inverted Clocks
The same command describes other clocks that are made from a master clock. A clock that is twice as fast, as it comes out of a PLL, uses -multiply_by 2, and the new period is half of the master period. A clock that is the master clock inverted, which means its rising edge is the falling edge of the master, uses -invert. If there is more than one master clock at the source pin, -master_clock names the one to use. In every case, the generated clock is tied to its master, so STA knows the relationship between their edges and can pick the launch and capture edges for the paths between them.
Common Mistakes
Mistake #1: Leaving a divided clock undefined
STA does not report an error when a clock is missing. It only reports a warning with check_setup. Always run that command and look for unclocked pins and unconstrained endpoints.
Mistake #2: Using a wrong divide factor
If you write -divide_by 4 for a divide-by-2 flip-flop, STA assumes a period of 8.0 ns and checks paths with the wrong edges. The factor must match the real circuit.
Quick Check: A master clock has a period of 1.0 ns. What period does -divide_by 4 create?
The generated clock has a period of 4 x 1.0 = 4.0 ns.
Practice Exercise
Challenge: Add Uncertainty to the Clock Crossing
Paste the sta_div design into the lab, run STA with only the port clock, and look at the warnings. Then add the generated clock and the constraints for d and q as above, using the name of your divider flip-flop. Finally add an uncertainty of 0.1 ns for setup between the two clocks:
set_clock_uncertainty 0.1 -from [get_clocks clk_div] -to [get_clocks clk] -setup
Predict the new setup slack of the path from the slow flip-flop to the fast flip-flop. The slack before was 1.6200 ns.
Open the ready-made example in the lab, run synthesis, and then run STA. Editing constraints.sdc and re-running only STA, and choosing another library or corner, are PRO features.
Hint
The uncertainty lowers the required time of the setup check by the same amount.
Solution
The report shows an inter-clock uncertainty row of -0.1000, and the required time becomes 1.7888 ns. The slack is 1.7888 - 0.2688 = 1.5200 ns. The hold slack stays at 0.3096 ns, because the uncertainty was applied to setup only.
Summary
- STA does not follow clocks through flip-flops, so a divided or generated clock needs
create_generated_clock. - Without it, the flip-flops of the generated domain are unclocked, and their paths are not checked.
-divide_byand-multiply_byset the period relative to the master clock.check_setup -verboselists unclocked pins and unconstrained endpoints.- Between a master clock and a generated clock, STA uses the closest capture edge after the launch edge for setup and the same edge for hold.
- Check the clock summary after defining a generated clock.