Area | What to test | How |
|---|---|---|
Functional | Order, data integrity, no loss or duplication | Scoreboard queue; random enables on both sides |
Full and empty | Reaches both; no overflow or underflow | Biased traffic (writer fast, then reader fast); coverage of full and empty |
Clock ratios | Faster, slower, equal, nearly equal, large ratio | Parametrised periods (at least 5 combinations, as in the previous lesson) |
Metastability | Multi-bit pointer changes landing in the window | Metastability-aware synchroniser model; run both Gray and a binary mutant to prove the test has teeth |
Flags | Almost flags never late | Compare with the scoreboard occupancy |
Reset | Both sides, various release orders | Reset in the middle of traffic and after |
Corner cases | Write when full, read when empty (must be ignored); simultaneous reads and writes at the boundaries | Directed tests plus random |
Throughput | One word per cycle of the slower clock when both sides are ready | Count transfers over long runs |
Only the Gray pointers pass through synchronisers. Data still crosses, through the memory, as a qualified held-data path: the CDC tool must classify mem → rdata as qualified by the synchronised write pointer, and implementation must bound the write-to-read-data delay below the pointer-visibility latency (Gray register, 2FF, registered rempty), or use a registered RAM output. No flags cross.
Each crossing uses a two-flop (or more) synchroniser with nothing between the flops.
Gray pointers come directly from flops, not from combinational conversion at the crossing.
The memory supports independent concurrent write and read access on their respective clocks, normally a dual-port memory; no combinational path from read data into the write domain. Two single-port banks alone are not an equivalent replacement: same-bank read/write conflicts need a separately verified ownership/arbitration architecture, CDC-safe control and backpressure, with its throughput limits specified.
wfull and rempty are registered and computed from next-state pointers.
Crossing constraints on the pointer paths bound the bit-to-bit skew to less than the minimum interval between successive pointer changes (the source clock period for a pointer that can step every source cycle), using set_max_delay -datapath_only and, where the flow offers one, a bus-skew constraint (see below).
A CDC tool reports the pointer crossings as synchronised, with Gray-coded single-bit-change classification.
Reset ordering and the RDC analysis include the FIFO.
A critical constraint is bit-skew between the Gray pointer bits. The Gray argument is not about the destination clock. It needs all bits of one pointer value to settle before the next pointer value can appear, so that at any instant the wires hold the old value, the new value or a single-bit mixture of the two, which are adjacent Gray codes.
The requirement is therefore: bit-to-bit skew < the minimum interval between successive pointer changes. For a pointer that can increment every source cycle, that interval is one source clock period (less any margin). The destination period does not set this bound. The destination only samples the wires, and the synchroniser handles a bit caught mid-change, because a one-bit difference resolves to the old or the new value, both valid.
Read each strip as three wires of one pointer. The top row numbers the values 1 to 5 in the order the source sends them; the dashed line is the moment the destination samples the wires.
With 4 ns of skew, g2 already shows value 4 while g0 still shows value 2. The sample mixes three different values and reads 111, a value that does not exist on the source until 10 ns.
With 1.2 ns of skew, every bit has settled to value 3 or value 4, which differ only in g2. Any sample is the old value or the new one.
Only the source spacing (2 ns) matters here; the destination period never appears in the picture.
Case (illustrative numbers) | Skew vs pointer spacing | What the destination can sample |
|---|---|---|
Source 2 ns, destination 10 ns, bit skew 4 ns | 4 ns skew is above the 2 ns spacing. It is below the 10 ns destination period, which does not help | Up to five increments happen during one destination period, and the bits of value n are still arriving while value n+1 has started. A sample can mix bits from different values: a multi-bit difference, not a one-bit one. Unsafe |
Source 2 ns, destination 10 ns, bit skew 1.2 ns | 1.2 ns skew is below the 2 ns spacing | Old value, new value or a one-bit mixture. Safe, even though the destination is five times slower |
Source 10 ns, destination 2 ns, bit skew 4 ns | 4 ns skew is below the 10 ns spacing. It is above the 2 ns destination period, which does not matter | At most one increment is in flight; a sample sees the old value, the new value or a one-bit mixture. Safe |
The constraint form is generic. Choose the value from the source period (here 2 ns, with 20% margin), and constrain each pointer from its Gray register to the first synchroniser flop. For nonnegative path delays, max(delay) − min(delay) ≤ max(delay): bounding every path by 1.6 ns is sufficient to bound their relative skew by 1.6 ns. A relative-skew constraint can instead permit larger common latency (for example 4.0 to 5.2 ns arrivals have 1.2 ns skew), provided coherent ordering, pointer latency and protocol assumptions are reviewed.
Compare like arrival quantities from the same source launch: include source clock insertion differences, clock-to-Q and routing to first-stage D, across the required corners. A datapath-only report may not include every contribution in that arrival definition; reserve margin or constrain/report the omitted terms explicitly. Check the source minimum step interval, pin collections, effective exceptions and achieved per-bit arrival spread. Clock groups or false paths must not silently override the intended bounds. These SDC sketches are unverified until the implementation flow reports effective constraints and timing.
# not-run: SDC is not executable here
# illustrative only: each limit comes from the period of the clock that LAUNCHES that pointer (2 ns here), never from the capturing clock
set_max_delay 1.6 -datapath_only -from [get_cells wptr_gray_reg*] -to [get_cells wptr_sync_ff1*]
set_max_delay 1.6 -datapath_only -from [get_cells rptr_gray_reg*] -to [get_cells rptr_sync_ff1*] ;# the read pointer's limit comes from the READ clock period (taken as 2 ns here too)
# a bus-skew style constraint, if the flow offers one (name and syntax differ between flows):
# bound (latest bit arrival - earliest bit arrival) across wptr_gray_reg* to below 1.6 nsTools differ in which constraint they offer and how they treat it. Confirm the constraint in the CDC and timing reports (achieved skew against the limit on each pointer), and do not assume a clean run means the bound is met.
No. The pointer can step every 2 ns, so the bits of one value are still arriving when the next value starts, and a destination sample can mix bits from two different values (a multi-bit change). The skew must be below the minimum spacing of pointer changes (the source period, with margin), not the destination period.
A mutation test: change the design to use binary pointers across the crossing and show that the testbench fails. A test that cannot fail on a known-bad design is not a CDC test.