Repository navigation
Course: Clocks, resets and clock-domain crossing (9x3, hardware track) #1482
Copy link
Copy link
Closed
Labels
Description
Parent epic: #1476
Course id: clocks-and-cdc
Audience: hardware engineers (RTL / FPGA / ASIC).
Prerequisites: Course 1 (FPGA) modules timing and board.
Why this course
Most field failures in FPGA designs are not logic bugs but clocking bugs: a missing synchronizer, a reset released on the wrong edge, a FIFO pointer crossing domains in binary. The repo already has clock_domain, cts, fifo (gray pointers), timing and XDC emission, yet no course explains them. This is the course a hardware hiring manager asks about first.
What already exists in the repo (grounding)
fpga/clock_domain.t27+testbench/clock_domain_tb.t27(12 tests, currently fail in the browser runner)fpga/cts.t27,fpga/fifo.t27+fifo_tb(18 tests),fpga/timing.t27pins/emitter_xdc.t27,pins/ir.t27,boards/arty_a7.t27,boards/wukong_v1.t27tools/trios/tri/clocks.t27,fpga-rxcap.t27(real captured traffic)fpga/vcd_trace.t27for waveforms
Decomposition: 9 modules x 3 lessons
Module 1 -- what-a-clock-is: the clock as a contract
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 1 | one-edge-one-world |
why synchronous design works: one edge, one state update | fpga/clock_domain.t27 |
edge stepper: click an edge, watch every flop update at once |
| 2 | period-and-jitter |
period, frequency, duty cycle, jitter budget | tools/trios/tri/clocks.t27 |
jitter eye drawn from a real capture |
| 3 | where-the-clock-enters |
clock-capable pins, the board oscillator, IBUF to BUFG | boards/wukong_v1.t27 |
pin-map highlighting the clock-capable balls |
Module 2 -- clock-trees: distributing one edge to every flop
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 4 | skew-and-insertion |
skew vs insertion delay, why a tree and not a wire | fpga/cts.t27 |
tree builder with per-leaf delay |
| 5 | global-buffers |
BUFG / BUFR / BUFH and clock regions on 7-series | fpga/cts.t27 |
clock-region map of the XC7A200T |
| 6 | gated-clock-trap |
why gating a clock in fabric breaks timing; use a clock enable | fpga/clock_domain.t27 |
side-by-side: gated clock vs CE, glitch shown |
Module 3 -- pll-and-mmcm: making new clocks
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 7 | multiply-and-divide |
VCO range, M/D/O dividers, legal settings | NEW fpga/mmcm.t27 |
MMCM calculator with legality checks as spec tests |
| 8 | phase-and-lock |
phase shift, LOCKED, holding logic in reset until lock | NEW fpga/mmcm.t27 |
lock timeline |
| 9 | related-or-not |
when two clocks are related (same MMCM) vs asynchronous | fpga/timing.t27 |
relation table derived from the spec |
Module 4 -- resets: starting from a known state
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 10 | sync-or-async |
synchronous vs asynchronous reset, cost on 7-series flops | NEW fpga/reset_sync.t27 |
LUT/FF count from a yosys run, both styles |
| 11 | reset-release |
async assert, sync deassert; the reset synchronizer | NEW fpga/reset_sync.t27 |
wave: release near the edge, with and without sync |
| 12 | reset-fanout |
reset trees, why fewer resets is often better | fpga/cts.t27 |
fanout histogram from a real netlist |
Module 5 -- metastability: what happens between 0 and 1
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 13 | setup-hold-window |
the forbidden window and what a flop does inside it | fpga/clock_domain.t27 |
window slider: data edge vs clock edge |
| 14 | mtbf |
MTBF formula, why two flops buy centuries | NEW fpga/mtbf.t27 (numbers as spec tests) |
MTBF calculator, log scale |
| 15 | two-flop-sync |
the standard synchronizer and the ASYNC_REG attribute | fpga/clock_domain.t27 |
netlist view with ASYNC_REG placement |
Module 6 -- crossing-many-bits: when one synchronizer is not enough
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 16 | why-binary-fails |
multi-bit skew: binary counter read mid-change | fpga/fifo.t27 |
glitch sampler showing impossible values |
| 17 | gray-code |
one bit changes at a time; bin2gray / gray2bin | fpga/fifo.t27 |
gray counter next to binary counter |
| 18 | handshakes-and-pulses |
req/ack handshake, pulse synchronizer, toggle sync | fpga/clock_domain.t27 |
two-domain timeline |
Module 7 -- async-fifo: the workhorse of CDC
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 19 | pointers-and-flags |
write/read pointers, full and empty in gray | fpga/fifo.t27 |
FIFO animation with both pointers |
| 20 | depth-sizing |
how deep: burst length, rate ratio, latency | fpga/fifo.t27 |
depth calculator, spec tests as sizing rules |
| 21 | fifo-testbench |
what fifo_tb checks and what it does not |
fpga/testbench/fifo_tb.t27 |
test-waves of the tb run |
Module 8 -- constraints: telling the tool what you meant
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 22 | create-clock |
create_clock, generated clocks, from spec to XDC | pins/emitter_xdc.t27 |
spec -> XDC diff |
| 23 | false-path-and-max-delay |
set_false_path vs set_max_delay -datapath_only, clock groups | fpga/timing.t27 |
constraint picker explaining what each hides |
| 24 | io-timing |
input/output delays, the RGMII-style source-synchronous case | pins/emitter_xdc.t27 |
IO timing diagram |
Module 9 -- on-the-board: proof on hardware
| # | Lesson id | What the reader learns | Spec | Widget idea |
|---|---|---|---|---|
| 25 | cdc-report |
reading a CDC / timing report from the open flow | fpga/timing.t27 |
slack-waterfall per clock domain |
| 26 | capture-a-crossing |
capturing a real crossing on the board | tools/trios/tri/fpga-rxcap.t27 |
captured trace replay |
| 27 | capstone |
build a two-clock design with an async FIFO, prove it on the board | fpga/fifo.t27 + fpga/clock_domain.t27 |
build receipt with both clocks |
Specs that do not exist yet (write in gHashTag/t27 first)
-
fpga/mmcm.t27-- MMCM/PLL parameter legality (VCO range, dividers) as tests -
fpga/reset_sync.t27-- reset synchronizer -
fpga/mtbf.t27-- MTBF model with documented constants
Honesty notes and traps
- MTBF numbers depend on flop parameters that Xilinx publishes only partially; label any constant as an assumption with its source.
- Course 1 already touches timing slack and
cts.t27(lessontiming-slackpoints atcts.t27); this course goes deeper and Course 1 should link here instead of duplicating.
Acceptance criteria
-
specs/course/<id>.t27+<id>-ru.t27exist, registered inspecs/course/courses.t27, built bycourse-from-spec.mjs(recipe:specs/course_recipe/course-27.t27). - Exactly 9 modules x 3 lessons = 27 lessons; every lesson names one widget and one spec.
- Every lesson spec compiles AND its
testblocks pass in the reader's browser (blocked by the browser-runner issue), or the lesson says plainly that it is a recordedtricast and links the recording. - Every number on a page comes from real tool output named in the widget's
DATA_SOURCES(yosys / nextpnr / board run / spec test). No invented figures. - Board named on every hardware page (Wukong
xc7a200tfgg676vs AX7203xc7a200tfbg484vs Arty A7 / XC7A100T). - Black-and-white share cards and SEO pages generated for all 27 lessons (EN + RU).
- The course PR carries a blog post: EN
body+ RUruBody. - Lessons that need a spec that does not exist yet are listed as sub-tasks (spec first in
gHashTag/t27, then copied here).
Blocked by: #1477 (browser test runner) for every lesson whose spec uses calls, locals or struct fields in tests.
Reactions are currently unavailable
Activity
cdc: merge verification world into clocks-and-cdc; 160-widget gallery…
cdc: mint the first missing cast -- tri fpga-txhold lands in slot 22;…
cdc: close the last two uniqueness gaps -- rxcap and rxer casts; all …
Merge feat/course-verification-1483 into feat/course-cdc-1482 (posts.…
fix(tools): tri-fpga-rxer carries its cast, rxcap and txhold point at…
Merge origin/main (course 5 verify-hardware landed as #1497) into fea…
fix(course): keep the harness mutations honest for the sixth course (…
Merge pull request #1498 from gHashTag/feat/course-cdc-1482
Deploy f1f1f73
course: buses-and-peripherals -- 27 lessons, 33 casts, 392 pages (Closes
Deploy 6518d5c