CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

Parameterized Gray Code Counter

MediumVerilog / SystemVerilogBuild

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 WIDTH defaulting to 4.
  • The gray_out output 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 clk and reset is asynchronous negedge rst_n.
  • Reset takes priority over enable when both are asserted simultaneously.

Topics

gray-codecounterscdcparameterizable

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.

Sign in to solveSee what Pro unlocks

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.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks