The write pointer must be visible in the read domain (for empty) and the read pointer in the write domain (for full), but a multi-bit counter cannot cross bit-by-bit: skew between bits lets the destination sample a mixture of old and new values. Gray coding restricts every legal pointer step to a single-bit change, so a sample taken mid-change is at worst one step stale, never a torn value.
Gray-coded pointers cross the boundary; each increment flips exactly one bit, including the wrap-around step.
Registered Gray values feed the synchronisers: the Gray code comes from source-domain flops, never from combinational conversion at the crossing, so the synchroniser input cannot glitch.
A two-flop (or more) synchroniser per pointer bit in the receiving clock carries the Gray value across, exactly like a set of single-bit level crossings that change one at a time.
Single-step discipline: the pointer advances by one per operation only. Jumps (reloads, skips) break the one-bit rule and with it the whole argument.
Check | What passes | Typical finding when it fails |
|---|---|---|
Crossing classification | Pointer crossings reported as synchronised Gray crossings, not plain multi-bit crossings | Multi-bit crossing without protocol |
Synchroniser presence | One synchroniser chain per pointer bit, no logic between the flops | Missing or shared synchroniser, logic before the synchroniser |
Gray discipline | Encoding recognised as Gray with single-step updates | Counter that can jump, or binary pointer across the boundary |
Source hygiene | Gray value driven by flops in the source domain | Combinational conversion feeding the crossing |
One bit each time (bit 0, then bit 3). The sequence respects the single-bit rule, so a sample mid-change is at most one step stale.