The one-bit promise has to hold on every step, including the step from the last value back to zero. That wrap step is where non-power-of-two depths fail, and the reason is parity, not tooling.
Each step flips one bit, which flips the parity of the popcount. Returning to the starting value needs the starting parity back, so any single-bit-change cycle has an even number of steps. An odd depth can never visit each entry exactly once with single-bit steps and a single-bit wrap. The n-bit binary-reflected Gray code gives the full 2^n cycle, wrap included: 3-bit Gray ends ...011, 010, 110, 100 and returns to 000 with one bit.
Take a 4-bit counter truncated to depth 10, values 0 to 9. The wrap step goes from 9 to 0:
illustrative check of the wrap step for a depth-10 truncation
Gray(9): binary 1001, Gray = 1001 ^ 0100 = 1101
Gray(0): 0000
bits differing between 1101 and 0000: 3
result: the wrap step flips three bits, so the ring is not GrayDepths 12 and 14 fail the same way with their own wrap steps. There is no standard combinational formula that produces a cyclic Gray order for an arbitrary depth, so do not invent one.
Situation | Standard approach |
|---|---|
Free choice of depth | Use a power of two. This is the normal answer for Gray-pointer FIFOs (see async FIFO design). |
Depth fixed at a non-power of two | Keep a power-of-two Gray ring at or above the depth and size full and empty from occupancy against the real depth, or move the transfer to a handshake. |
Odd depth | A single-bit-change cycle visiting each entry once is impossible by the parity argument above; use a handshake or FIFO of a neighbouring depth. |
Custom even-length sequence | Allowed only with an exhaustive adjacency proof covering the wrap, exactly like the Gray counter check. State plainly that the sequence is custom and keep the proof with the design. |
An even depth does not rescue truncation either. Depth 12 fails on its own wrap step (Gray of 11 against Gray of 0), and only a constructed even-length cycle with a proven wrap, checked exactly like the counter in the previous lesson, is acceptable. When a design claims one, ask for the proof first and the depth justification second.
The wrap step from 11 to 0 flips more than one bit, so pointer samples near the wrap can tear. Fix one: run a 16-deep Gray ring and assert full at occupancy 12. Fix two: carry the data by handshake instead of Gray pointers.
Each Gray step flips parity, so returning to the starting value needs an even number of steps. Nine entries can never form a single-bit-change cycle that visits each entry once and wraps cleanly.