Difficulty: Medium · Puzzle 2 of 6 · Topic: Verifying CDC & Reset Puzzles
A testbench drives a 10 ns source clock and a destination clock, both starting at t=0. How many different positions of the destination edge relative to the source period does the bench exercise (edges taken over 1,000 ns) for destination periods of 20 ns, 13 ns and 15 ns? What do you change to cover more?
Look at the destination edge times modulo 10.
1) 20 ns: edges at 0, 20, 40, ...; modulo 10 every edge falls at 0. One phase only: the destination edge is always exactly aligned with a source edge.
2) 13 ns: edges at 0, 13, 26, 39, 52, ...; modulo 10 gives 0, 3, 6, 9, 2, 5, 8, 1, 4, 7: all ten phases.
3) 15 ns: edges at 0, 15, 30, ...; modulo 10 gives 0, 5, 0, 5: two phases.
4) A bench with a 2:1 ratio and aligned starts exercises one fixed alignment for the entire run, so a bug that appears only at some other phase is never hit.
5) Fixes: random start offset and random ratio or period per test, jitter on the clock edges, and a sweep that is long enough to cover the phases; each run still covers a limited set of phases, so repeat across seeds.Answer: 20 ns: 1 phase; 13 ns: 10 phases; 15 ns: 2 phases. Randomise the start offset and the period (or add jitter) per seed and run many seeds; an integer-ratio aligned clock pair never exercises most phases.
Checked by running a model of the rule in a Python model. A Python model counts distinct edge positions of the destination clock modulo the source period.
Using a neat 2:1 or 1:1 clock ratio because it is 'easier to debug'. The relation between the clocks is part of the stimulus: a fixed alignment is a single test point, and the bugs live in the phases you did not run.
If you add random jitter to the 20 ns clock, does one run now cover all ten phases? Model answer: only if the jitter spans the 10 ns range or is accumulated over time; small jitter covers a small neighbourhood of one phase, so use a randomised start offset and ratio per run in addition.