Parameterized Gray Code Counter
Every asynchronous FIFO needs a pointer to track read and write addresses across clock domains. A Gray code counter ensures only one bit toggles per increment, eliminating multi-bit skew hazards when passing the pointer to the opposite clock domain.
This module implements a parameterizable counter that natively outputs Gray code. It increments when enabled. To achieve this safely, it maintains an internal binary count, converts the next binary value to Gray code, and registers the Gray code output to guarantee glitch-free transitions on the crossing paths.
The circuit operates on the positive edge of clk. It uses an asynchronous, active-low reset rst_n. On reset, both the internal binary state and the gray_out register must be cleared to 0. When en is high, the counter increments. When en is low, the output holds its current value.
Cycle 1: rst_n=0 → internal_bin=0, gray_out=0 Cycle 2: rst_n=1, en=1 → internal_bin=1, gray_out=1 Cycle 3: en=1 → internal_bin=2, gray_out=3 Cycle 4: en=0 → internal_bin=2, gray_out=3 (hold) Cycle 5: en=1 → internal_bin=3, gray_out=2 Cycle 6: en=1 → internal_bin=4, gray_out=6
{ "signal": [
{ "name": "clk", "wave": "p......." },
{ "name": "rst_n", "wave": "01......" },
{ "name": "en", "wave": "01101111" },
{},
{ "name": "gray_out", "wave": "========", "data": ["0","0","1","3","3","2","6","7"] }
], "head": { "text": "Gray counter operation showing increment and hold." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; clears internal state and output to 0 | | en | input | 1 | Enable signal; increments counter on posedge clk when high | | gray_out | output | WIDTH | Registered Gray code output; resets to 0 |
Constraints
- Module must be parameterized with
WIDTHdefaulting to 4. - The
gray_outoutput must be registered directly (driven by a flip-flop, not combinational logic) to prevent glitches from propagating across clock domains. - Internal binary counter wraps around naturally when it reaches its maximum value.
- Clock edge is
posedge clkand reset is asynchronousnegedge rst_n. - Reset takes priority over enable when both are asserted simultaneously.
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.