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

Synchronizing Read Pointer to Write Domain

MediumVerilog / SystemVerilogBuild

Asynchronous FIFOs must evaluate their full condition within the write clock domain to prevent data overwrite. This requires comparing the current write pointer against the read pointer. Because the read pointer originates in an independent read clock domain, it must be safely synchronized into the write domain before any comparison occurs to avoid metastability.

This module synchronizes a Gray-coded read pointer into the write clock domain using a standard two stage flip-flop synchronizer. The input pointer is captured on the positive edge of the write clock and passed through two sequential registers. Because Gray code guarantees that only one bit changes at a time during normal counting, passing it through a multi-bit synchronizer is safe and prevents the write domain from seeing corrupted intermediate pointer values.

Timing and Reset Rules: • Clock edge: posedge wclk • Reset type: Asynchronous • Reset polarity: Active low (wrst_n) • Reset behavior: All internal synchronizer stages and the output wq_rptr_gray must reset to 0 immediately when wrst_n is 0.

Worked Trace: Cycle 1: wrst_n=0 → internal_stage=0, wq_rptr_gray=0 Cycle 2: wrst_n=1, rptr_gray=5 → internal_stage=5, wq_rptr_gray=0 Cycle 3: rptr_gray=5 → internal_stage=5, wq_rptr_gray=5 Cycle 4: rptr_gray=12 → internal_stage=12, wq_rptr_gray=5 Cycle 5: rptr_gray=12 → internal_stage=12, wq_rptr_gray=12

{ "signal": [
  { "name": "wclk",         "wave": "p....." },
  { "name": "wrst_n",       "wave": "01...." },
  { "name": "rptr_gray",    "wave": "x4..5.", "data": ["5", "12"] },
  {},
  { "name": "internal",     "wave": "0.4..5", "data": ["5", "12"] },
  { "name": "wq_rptr_gray", "wave": "0..4..", "data": ["5", "12"] }
], "head": { "text": "Two cycle propagation of the Gray pointer into the write domain." } }

Module Parameters: | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | PTR_WIDTH | integer | 5 | Bit width of the read pointer |

Port Table: | Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | wclk | input | 1 | Write domain positive-edge triggered clock | | wrst_n | input | 1 | Write domain asynchronous active-low reset | | rptr_gray | input | PTR_WIDTH | Gray-coded read pointer from the read clock domain | | wq_rptr_gray | output | PTR_WIDTH | Synchronized Gray-coded read pointer in the write clock domain |

Constraints

  • The module must be parameterized with PTR_WIDTH defaulting to 5.
  • The synchronizer must consist of exactly two flip-flop stages in series.
  • No combinational logic may be placed between the first and second synchronizer stages.
  • All stages must be cleared asynchronously when wrst_n is low.

Topics

FIFOGray CodeCDCSynchronizer

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