Multi-Clock Domains & Phase Relationships
Multi-Clock Domains and Phase Relationships
A real chip rarely runs on one clock. It has many. One clock might run a processor core, another a memory bus, another an external interface. Each clock has its own period and its own edges. When data crosses from one clock to another, the timing tool must figure out which launch edge pairs with which capture edge. This chapter explains how the tool does that, and how period and phase relationships set the timing budget. A clock domain is the set of registers driven by one clock. A register is a small storage cell, usually a flip-flop, that captures a value on a clock edge. When two registers in the same domain talk, the analysis is simple: same period, same edges. The trouble starts when registers in different domains talk. That is a multi-clock, or cross-domain, path. The tool must align two different waveforms in time before it can measure the path. The key idea is the common base period. The tool lines up both clocks on a shared timeline and looks for the tightest pair of edges. The phase relationship is how the edges of one clock sit relative to the edges of the other. If the relationship is fixed and known, the path is synchronous and the tool can time it. If the relationship drifts, the path is asynchronous and needs special handling, covered in other chapters.
The Common Base Period and the LCM Idea
To pair edges from two clocks, the tool needs a window of time where both waveforms repeat together. That window is the least common multiple (LCM) of the two periods. The LCM is the smallest length of time that contains a whole number of cycles of both clocks. After one LCM, the edge pattern repeats exactly, so the tool only needs to study that one window. Suppose clock A has a period of 2.50 ns and clock B has a period of 3.75 ns. The LCM of 2.50 and 3.75 is 7.50 ns. In that 7.50 ns window, clock A has three cycles and clock B has two cycles. The tool lists every rising edge of both clocks inside that window, then checks every launch-to-capture pair.

Within that window, the tool does not check every pair equally. It looks for the worst case. For a setup check, the worst case is the launch edge and the very next capture edge that are closest together. The smaller that gap, the tighter the path. The tool finds the minimum gap across the whole LCM window and uses it as the required time.
# standard SDC — portable across compliant tools
# Two related clocks; the tool computes the common base.
create_clock -name clk_a -period 2.50 [get_ports clk_a_in]
create_clock -name clk_b -period 3.75 [get_ports clk_b_in]
The table below shows the LCM for several period pairs.
| Clock A (ns) | Clock B (ns) | Common base / LCM (ns) | A cycles in window | B cycles in window |
|---|---|---|---|---|
| 2.50 | 3.75 | 7.50 | 3 | 2 |
| 2.00 | 5.00 | 10.00 | 5 | 2 |
| 1.60 | 2.40 | 4.80 | 3 | 2 |
| 3.20 | 4.00 | 16.00 | 5 | 4 |
| 2.10 | 6.30 | 6.30 | 3 | 1 |
Notice the last row. When one period divides evenly into the other, the LCM is just the larger period. Those clocks are integer-related and easy to time. When the periods share no nice ratio, the LCM grows large, and the tightest edge pair can be very close, making the path hard to meet.
Which Edge Pairs Are Checked
The tool checks two things on every path: setup and hold. Setup asks whether data arrives early enough before the capture edge. Hold asks whether data stays stable long enough after the capture edge. Each check uses a different edge pair. For setup, the launch edge is some rising edge of the source clock. The capture edge is the next rising edge of the destination clock that comes after it. The tool scans all launch edges in the LCM window, finds the next capture edge for each, and keeps the pair with the smallest positive gap. That smallest gap is the setup window. For hold, the tool uses the same launch edge but checks the capture edge from the previous cycle, the one just before or at the launch. Hold makes sure new data does not arrive so fast that it overwrites the value the capture register was supposed to hold from the last cycle.

Here is a worked setup example. Clock A is 2.50 ns, clock B is 3.75 ns, both rising at time 0. The launch edges of A fall at 0, 2.50, 5.00, 7.50 ns. The capture edges of B fall at 0, 3.75, 7.50 ns. Take the A launch at 2.50 ns. The next B capture is at 3.75 ns. The gap is 1.25 ns. Scan all launches and 1.25 ns turns out to be the smallest. So the setup budget for this cross-domain path is just 1.25 ns, far less than either clock period.
| A launch (ns) | Next B capture (ns) | Setup gap (ns) |
|---|---|---|
| 0.00 | 3.75 | 3.75 |
| 2.50 | 3.75 | 1.25 |
| 5.00 | 7.50 | 2.50 |
| 7.50 | 7.50 | 0.00 (same edge, special) |
The 1.25 ns gap is what the data must beat. This is why cross-domain paths between unrelated clocks are so tight: the worst edge pair can leave very little time. It helps to see why the gap shrinks. As the two clocks march through the LCM window, their edges slide past each other. At some alignment, a launch edge lands just before a capture edge, leaving a sliver of time. The tool always finds that worst sliver, because timing must guarantee the path works in every cycle, not just the easy ones. So even two clocks with generous periods can produce a brutal cross-domain budget. The remedy is usually to avoid the crossing in design, or to add a synchronizing circuit that breaks the timing dependency.
Slow-to-Fast and Fast-to-Slow
The direction of the crossing changes the picture. A slow-to-fast path launches from a slow clock and captures on a fast clock. A fast-to-slow path does the reverse. The two behave differently because the capture clock sets how often a deadline arrives. In a slow-to-fast path, the capture clock ticks often. So after the slow launch edge, a fast capture edge comes soon. The setup window is short, set by the fast clock's spacing. These paths are usually setup-critical. The data must hurry to beat the next quick capture edge. In a fast-to-slow path, the launch clock ticks often but the capture clock is slow. Many launch edges happen before the next capture. The tool must pick the launch edge that lands closest before the capture edge, which gives the tightest setup window. Hold can also be tricky here because fast launches can crowd the capture edge.
# illustrative — names vary by tool
# Inspect the worst cross-domain setup path.
report_timing -from [get_clocks clk_slow] \
-to [get_clocks clk_fast] -delay_type max -max_paths 5
Consider a slow-to-fast case. The slow clock is 6.00 ns, the fast clock is 2.25 ns, both starting at 0. The slow launch at 0 looks for the next fast capture. Fast captures land at 2.25, 4.50, 6.75 ns. The nearest after a launch can be as small as the spacing between a slow edge and the fast edge just after it. In one alignment that gap shrinks to about 0.75 ns. That tiny window is the real budget, and meeting it may require careful path design or a planned exception.
| Direction | Launch clock (ns) | Capture clock (ns) | Tends to be limited by |
|---|---|---|---|
| Slow-to-fast | 6.00 | 2.25 | Setup (close fast capture) |
| Fast-to-slow | 2.25 | 6.00 | Hold and tight setup pick |
| Same period | 4.00 | 4.00 | One full period |
| Integer 2:1 | 4.00 | 2.00 | Half-period setup |
Managing Multi-Clock Paths
Once you understand the edge pairing, you control it with constraints. If two clocks are truly synchronous and you want the tool to time them with the LCM method, define them both and leave them in the same group. If they are unrelated and should never be timed together, tell the tool to skip those paths. That is done with clock grouping, which marks two clocks as belonging to different, noninteracting families.
# standard SDC — portable across compliant tools
# Mark two clocks as asynchronous so the tool skips crossings.
set_clock_groups -asynchronous \
-group {clk_core} -group {clk_io}
The most common mistake is letting the tool time a crossing that should have been declared asynchronous. The tool then reports an impossible setup window, like 0.40 ns, and you chase a violation that does not exist on real silicon. The fix is to decide, for every clock pair, whether the crossing is synchronous, asynchronous, or simply never used. The second mistake is the opposite: declaring a real synchronous crossing as asynchronous to make a violation disappear. That hides a true timing problem. The path still exists in hardware, and skipping it in analysis means it ships unchecked. A good habit is to build a clock relationship table early. For every pair of clocks that exchange data, write down their periods, their LCM, and whether the crossing is synchronous. Then encode that table into constraints. This makes the analysis match the design intent instead of guessing. There is a third category beyond synchronous and asynchronous: clocks that are physically exclusive. Two clocks may drive the same logic but never be active at the same time, such as a fast functional clock and a slow test clock that share wires through a multiplexer. These should be marked as exclusive, not asynchronous, because the distinction affects how the tool treats their shared paths. An exclusive pair never coexists, so no crossing between them can ever happen. Sorting each pair into synchronous, asynchronous, or exclusive is the foundation of clean multi-clock constraints. One more detail rewards attention: clocks that look unrelated may share a common origin. If both a 2.00 ns clock and a 4.00 ns clock come from the same oscillator through different dividers, they are actually synchronous with a clean 4.00 ns LCM, even though their frequencies differ. Treating such a pair as asynchronous would skip real, timeable paths. Always trace clocks back to their source before
deciding the relationship; the frequency alone does not tell you whether two clocks are related.
Interview Q&A
periods, the smallest time window where both waveforms repeat together. For 2.50 ns and 3.75 ns
clocks, the LCM is 7.50 ns, holding three A cycles and two B cycles. The tool studies edge pairs only within that window.
the source clock and the next capture edge from the destination clock. The tool scans the whole LCM window and keeps the pair with the smallest positive gap. That smallest gap is the setup budget the data must beat.
edge pair can land very close together. For a 2.50 ns and 3.75 ns pair, the tightest setup gap is only 1.25 ns, far less than either period. Data has very little time to travel.
ticks often, so a capture edge arrives soon after the slow launch. With a 6.00 ns launch and 2.25 ns capture, the budget can shrink to about 0.75 ns.
asynchronous and never exchange synchronous data. Marking them as separate groups tells the tool to skip those crossings, so it stops reporting impossible windows. Never use it to hide a real synchronous violation.
stops checking that path, so a genuine timing problem ships unverified. The path still exists in silicon and can fail in the field. Only declare crossings asynchronous when the hardware truly is.
Key Takeaways
- The common base period is the LCM of two clock periods; the tool only needs to study one such window.
- For setup, the tool pairs each launch edge with the next capture edge and keeps the smallest gap as the budget.
- Cross-domain budgets can be far smaller than either period; a 2.50/3.75 ns pair gives just 1.25 ns.
- Slow-to-fast paths are usually setup-limited; fast-to-slow paths often stress hold.
- Build a clock relationship table and encode it, so analysis matches intent instead of guessing.
ChipBuddy
← Home
Comments
Leave a Reply