Blog
The clocks course teaches clock trees, reset strategy and crossing clock domains in 27 lessons, and every lesson opens a widget no other lesson uses, three of them minted for this course. The post body has sat unregistered in the tree since the course PR; this entry wires it up.

There is a third t27 course. Course 3, "Clocking, resets and clock-domain crossings", is 27 lessons in 9 modules of 3, chained after the AI numbers course the way that one is chained after the FPGA course: the last lesson of the course before links forward, and lesson 1 links back. Every lesson opens one widget and one t27 spec in the browser player, and where the browser runner cannot execute the spec yet, the lesson says so plainly and the widget is a recording of the native t27c on a real machine.
| Module | What it teaches |
|---|---|
| 1, What a clock is | A clock domain as every flop that shares one edge; period, jitter, and where a board clock enters the chip. |
| 2, Clock trees | Skew and insertion delay, the global buffer network, and why gating a clock with logic quietly mints a new domain. |
| 3, PLL and MMCM | Multiply and divide one clock into another, phase in 1/56 steps of the VCO period, and which clocks a timer calls related. |
| 4, Resets | Assert asynchronous, release synchronous: the three reset kinds, the release pipe, and the reset tree. |
| 5, Metastability | The setup-hold window, MTBF in integer log2 arithmetic, and the two-flop synchronizer. |
| 6, Crossing many bits | Why a binary bus tears when sampled in another domain, why Gray code does not, and handshakes for pulses. |
| 7, The asynchronous FIFO | Pointers, flags and depth: the buffer that carries a stream between two clocks. |
| 8, Constraints | create_clock, false path and max delay, and I/O timing against a clock another chip drives. |
| 9, On the board | A CDC report, one crossing captured on the RX flops of a routed E3 design, and a bitstream diff to close. |
The course needed models the tree did not have, so it adds three specs. specs/fpga/mmcm.t27 models an MMCME2: 16 tests and 4 invariants cover the VCO window, M/D/O ranges, fractional multiply in eighths, the 1/56 phase step and the lock model. specs/fpga/reset_sync.t27 names the three reset kinds: 16 tests and 3 invariants. specs/fpga/mtbf.t27 computes MTBF in integer log2 with 10 fractional bits, because the honest answer overflows any integer seconds count: 15 tests and 4 invariants. Every constant that is not from a document is labelled in the spec header as an assumption, with the document it is not.
| Spec | Tests | Invariants | What the header labels |
|---|---|---|---|
| mmcm.t27 | 16 | 4 | DIVCLK, MULT, CLKOUT ranges and the 1/56 phase step from UG472; the VCO window and lock window are labelled assumptions, UG472 and DS181 hold the per-speed-grade numbers. |
| reset_sync.t27 | 16 | 3 | The recommended form (async assert, sync release) and the stage counts it accepts. |
| mtbf.t27 | 15 | 4 | The WP323 form of the equation; tau 50 ps and W 10 ps are labelled assumptions, vendors publish flop parameters only partially. |
Sixteen new cast widgets join the gallery, one recording per recorded lesson, made with native t27c 0.4.0 on a laptop. A recording shows the run that matters and reads its verdict from the text. The MTBF lesson shows one flop leaving -200 ps of slack and a log2-MTBF of -19513 in Q10, and two flops leaving 9800 ps and 275887. The MMCM mutation recording widens the VCO window floor from 800000 to 400000 kHz with one sed line, and the one test that fails is the one that names the number it rejects. The FIFO mutation recording changes the head pointer increment from + 1 to + 3 and every test still passes, because the suite asserts fill counts and flags, never pointer values: the exact hole a torn multi-bit pointer would slip through.
The board numbers are real runs, each named in the widget that shows it. The board-spec lesson runs the Wukong board spec natively: 15 tests, 11 invariants, and the CFGMCLK ring oscillator measured at 70770, 68490 and 67200 kHz on three attached dice over JTAG, against the 65 MHz nominal that UG470 states as a 50-80 MHz envelope. The I/O timing lesson reads the two recorded runs of the routed E3 design for the AX7203 board: smallest TX hold 3445 ps on eth_txd[1], smallest mid-nibble margin 10900 ps on rxctl_n, and both are a model over the SDF nextpnr writes for the routed design, not a board measurement, and say so. The capture lesson runs tri fpga-rxcap on the same SDF: hold 10900 ps on rxctl_n with RXC 2.4 ns behind its data through a BUFG.
Work with me
I work contract and part-time on hardware-AI, FPGA/RTL and ML systems — from specification and open toolchains to reproducible measurements.