A real chip has several clocks, and data often goes from the domain of one clock to the domain of another. STA has to decide two things for every such path: which clock edges to compare, and whether to check the path at all. This article shows how STA picks the edges for two clocks of different periods, and how set_clock_groups tells it which clocks are related, which are unrelated, and which never run at the same time.
9 min read | Intermediate
What You'll Learn
- Explain how STA chooses launch and capture edges between two clocks with different periods
- Say when a clock crossing is not checked and what that means for the design
- Use
set_clock_groupswith-asynchronousand-logically_exclusive - Read the effect of a clock group in a report
The Default: Clocks Are Related
If you define two clocks and do nothing else, STA assumes that they are synchronous. This means it assumes the edges of the two clocks have a fixed, known relationship, as if both came from the same source. STA then checks every path between them.
Take a design with a flip-flop ra on a clock clka of 2.0 ns period, whose output goes to the flip-flop rb on a clock clkb of 3.0 ns period:
module sta_cdc (input clka, clkb, d, output q);
reg ra, rb;
always @(posedge clka) ra <= d;
always @(posedge clkb) rb <= ra;
assign q = rb;
endmodule
create_clock -name clka -period 2.0 [get_ports clka]
create_clock -name clkb -period 3.0 [get_ports clkb]
set_input_delay 0.4 -clock clka [get_ports d]
set_output_delay 0.4 -clock clkb [get_ports q]
How STA Picks the Edges
The edges of clka are at 0, 2.0, 4.0, 6.0 ns. The edges of clkb are at 0, 3.0, 6.0 ns. For the setup check, STA looks at all launch edges and, for each one, at the closest capture edge after it. Then it uses the pair that leaves the least time:
- Launch at 0, capture at 3.0: a window of 3.0 ns.
- Launch at 2.0, capture at 3.0: a window of 1.0 ns.
- Launch at 4.0, capture at 6.0: a window of 2.0 ns.
The worst pair is the second, with only 1.0 ns. The pattern repeats every 6.0 ns, the smallest time in which both clocks are back at their starting point. The report shows it:
Startpoint: _1_ (rising edge-triggered flip-flop clocked by clka)
Endpoint: _0_ (rising edge-triggered flip-flop clocked by clkb)
2.0000 2.0000 clock clka (rise edge)
0.0000 2.0000 ^ _1_/CLK (sky130_fd_sc_hd__dfxtp_1)
0.2688 2.2688 v _1_/Q (sky130_fd_sc_hd__dfxtp_1)
2.2688 data arrival time
3.0000 3.0000 clock clkb (rise edge)
-0.1112 2.8888 library setup time
2.8888 data required time
0.6200 slack (MET)
The launch clock row is at 2.0 ns, not at 0. The setup slack is 3.0 - 0.1112 - 2.2688 = 0.6200 ns. For hold, the check uses the launch edge at 0 and the capture edge at 0, with a slack of 0.3096 ns. For clocks like these, STA tests the case that is really the worst, which is correct if the clocks are truly related, for example both made from the same PLL.
Unrelated Clocks
If the two clocks come from different sources, such as two oscillators, their edges have no fixed relationship. The edge pairs that STA picks do not mean anything, because the real phase of the two clocks drifts all the time. A check on these paths is not useful. You tell STA with an asynchronous clock group:
set_clock_groups -asynchronous -group clka -group clkb
Clocks in the same group are related, clocks in different groups are not. STA does not check the paths between the groups. In the example, the path from ra to rb disappears from the reports. Only the paths inside each clock remain:
max_delay/setup group clka _1_/D (sky130_fd_sc_hd__dfxtp_1) 1.8988 0.4000 1.4988 (MET) max_delay/setup group clkb q (output) 2.6000 0.2615 2.3385 (MET)
This removes the check, not the problem. Data that crosses between unrelated clocks can be captured at the wrong moment, and the flip-flop can become unstable. STA has no way to see this. The crossing needs a synchronizer, and a separate check for clock domain crossings, as the article about synchronizers explains. An asynchronous group only says that STA should not time the path.
Exclusive Clocks
There is a third case. Two clocks can be related to the design but never active at the same time, for example the two clocks that go through a multiplexer. The options -logically_exclusive and -physically_exclusive say this. Clock Muxes and Multiple Clocks on One Register shows where it is used. For the paths between the two clocks the effect is the same as the asynchronous group: they are not checked.
Common Mistakes
Mistake #1: Declaring clocks asynchronous to make violations go away
A path that fails between two clocks may be a real problem. Use an asynchronous group only if the clocks really have no relationship, and make sure that the crossing is protected by a synchronizer.
Mistake #2: Forgetting a clock in the group command
A clock that is not listed in any group still has a relationship with all the others. A clock that was forgotten will be checked against clocks that it should be ignored by.
Quick Check: Clock A has a period of 4.0 ns and clock B has a period of 6.0 ns. After how many nanoseconds does the pattern of their edges repeat?
After 12.0 ns, the smallest time that is a multiple of both periods.
Practice Exercise
Challenge: Cross Two Clocks
Paste the sta_cdc design and the four constraint lines above into the lab and run STA. Find the setup slack of the path from ra to rb and the launch edge time in the report. Then add the asynchronous group and run again:
set_clock_groups -asynchronous -group clka -group clkb
Predict what happens to the path, and what the report shows.
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 path starts at a flip-flop of one group and ends at a flip-flop of the other group.
Solution
Without the group, the launch edge is at 2.0 ns, the capture edge at 3.0 ns and the setup slack is 0.6200 ns. With the group, the report for this pair of clocks says No paths found, and the endpoint rb/D no longer appears in the summary. The slack was not improved: the path was removed from the checks.
Summary
- By default, STA assumes that clocks are related and checks every path between them.
- For setup, STA uses the launch edge and the closest capture edge after it, and keeps the pair with the smallest window. For two clocks of 2.0 and 3.0 ns this is a window of 1.0 ns.
- The edge pattern repeats at the smallest common multiple of the periods.
set_clock_groups -asynchronousremoves the paths between groups of unrelated clocks from the checks.- An asynchronous group does not make the crossing safe. It needs a synchronizer and a separate check.
- Exclusive groups are for clocks that can never be active together.