Every design has signals that "never change during operation": mode straps, configuration registers, calibration values. They cross clock domains, and because they supposedly never change, they are the crossings most often left unsynchronised. Then firmware, test, or a product variant changes one, and the "static" signal takes down the chip.
A signal that changes once a month fails differently from a data bus: it passes every test, survives years in the field, and then corrupts state exactly once, in a way no log captures. Three examples show the shape: a mode bit sampled mid-change puts a control FSM into an illegal combination of modes; a clock-mux select changed while both clocks run produces the runt pulse from the previous lesson; a multi-bit calibration value updated in two register writes is sampled between the writes and mixes halves of two settings. None of these is a metastability problem; all are ordering problems.
Enforcement | How it works | What can still go wrong |
|---|---|---|
Synchronised apply pulse | The value settles, then a two-flop-synchronised pulse tells the destination to capture it | The source changing the value while the pulse is in flight |
Double buffering | New settings go to a shadow register and transfer to the active one on a safe event (frame boundary, idle) | The transfer event itself crossing domains unsynchronised |
Reset-held update | The receiving domain is held in reset while the value changes | Forgetting a domain, or a partial reset that misses some capture flops |
Constraint plus waiver | The signal is formally constrained stable during operation, with a reviewed waiver recording the justification | Firmware or a later product variant breaking the constraint without revisiting the waiver |
Notice what the mechanisms share: each names the exact moment the destination is allowed to look, and each makes "do not look yet" structural rather than advisory. A comment saying "stable during operation" is not enforcement; any of the four rows is.
A structural analysis cannot see intent, so it reports a quasi-static crossing like any other: unsynchronised, or multi-bit without a protocol. The review then asks for the enforcement evidence: which row of the table, where the apply pulse or shadow transfer is, and what stops the source changing mid-transfer. "It only changes at boot" is accepted only with the boot sequence written down and the waiver carrying an expiry or a re-review trigger for firmware changes.
Any two of: a firmware update changes it later or rewrites it on every boot at a different time; a test or debug mode toggles it; a product variant drives it differently; a partial reset re-runs the configuration sequence while the destination runs. The fix is an enforcement mechanism, not a stronger promise.
Because the pulse takes several destination cycles to arrive and be acted on. If the source changes the value during that window, the destination may capture a mixture. Stable-until-applied-completes is part of the contract.