Write Pointer Generation and Gray Conversion
Asynchronous FIFOs rely on independent read and write pointers to manage data flow between different clock domains. The write domain must track the current write address in binary for memory access, while simultaneously providing a glitch-free Gray-coded version to the read domain for empty-flag evaluation. Passing a binary counter directly across a clock domain can cause catastrophic multi-bit errors; converting it to Gray code ensures that only a single bit toggles per increment, making it safe for synchronization.
The module maintains a 4-bit write pointer. When the write enable signal is asserted, the binary pointer increments by one. The module simultaneously converts the incremented binary value into Gray code. Both the binary pointer and the Gray-coded pointer are registered on the clock edge to ensure clean, glitch-free outputs.
Timing and reset rules: • Clock edge: w_clk posedge • Reset type: w_rst_n asynchronous • Reset polarity: active-low • Output values on reset: Both w_ptr_bin and w_ptr_gray reset to 4'b0000 • Priority rules: Reset has highest priority. If w_rst_n is 0, outputs remain 0 regardless of w_en. • Registered outputs: Both w_ptr_bin and w_ptr_gray must be updated exactly on the clock edge.
Cycle 1: w_rst_n=0 → w_ptr_bin=0, w_ptr_gray=0 Cycle 2: w_rst_n=1, w_en=1 → w_ptr_bin=1, w_ptr_gray=1 Cycle 3: w_en=1 → w_ptr_bin=2, w_ptr_gray=3 Cycle 4: w_en=0 → w_ptr_bin=2, w_ptr_gray=3 (hold) Cycle 5: w_en=1 → w_ptr_bin=3, w_ptr_gray=2 Cycle 6: w_en=1 → w_ptr_bin=4, w_ptr_gray=6
{ "signal": [
{ "name": "w_clk", "wave": "p......" },
{ "name": "w_rst_n", "wave": "01....." },
{ "name": "w_en", "wave": "x11011." },
{},
{ "name": "w_ptr_bin", "wave": "=.=====", "data": ["0", "1", "2", "2", "3", "4"] },
{ "name": "w_ptr_gray", "wave": "=.=====", "data": ["0", "1", "3", "3", "2", "6"] }
], "head": { "text": "Pointer increments when w_en is high and holds when low." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | w_clk | input | 1 | Positive-edge triggered write clock | | w_rst_n | input | 1 | Asynchronous active-low reset; drives outputs to 0 | | w_en | input | 1 | Write enable; increments pointer when 1 | | w_ptr_bin | output | 4 | Registered binary write pointer | | w_ptr_gray | output | 4 | Registered Gray-coded write pointer |
Constraints
- Clock edge and reset polarity:
w_clkposedge,w_rst_nactive-low asynchronous. - Output values on reset: Both outputs must be exactly 4'b0000.
- Priority: Reset takes precedence over enable.
- Bit widths: All pointers are exactly 4-bit.
- Overflow: The counter must naturally wrap from 15 (4'b1111) back to 0 (4'b0000).
- Registered outputs: Both
w_ptr_binandw_ptr_graymust be flip-flop outputs, not combinational logic.
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.