CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Memory Design

Standard Synchronous FIFO

MediumVerilog / SystemVerilogBuild

Data producers and consumers rarely operate at the exact same sustained throughput in digital systems. A synchronous First-In-First-Out (FIFO) buffer acts as an elastic storage element between two subsystems in the same clock domain; it safely absorbs bursts of data from the producer and prevents data loss while the consumer processes it.

The module manages an internal memory array of 16 bytes. It maintains internal write and read pointers to track the current insertion and extraction indices. When a valid write operation is requested, data is written to the memory array and the write pointer advances. When a valid read operation is requested, the module reads the memory at the current read pointer into the output register and then advances the read pointer. The module generates empty and full status flags based on the pointer positions to back-pressure the producer and stall the consumer.

  • Clock edge: posedge clk
  • Reset type: Asynchronous, active-low rst_n
  • Reset behavior: empty goes to 1, full goes to 0, rd_data goes to 8'h00. Internal pointers reset to 0. The memory array contents do not need to be reset.
  • Write priority: If full is 1, write requests (wr_en) are ignored.
  • Read priority: If empty is 1, read requests (rd_en) are ignored.
  • Simultaneous requests: If wr_en and rd_en are asserted concurrently and the FIFO is neither full nor empty, both operations execute in the same cycle.
  • Read output behavior: On posedge clk, if a valid read is requested (rd_en=1 and empty=0), rd_data is updated with the value from the memory array at the current read pointer. If no valid read is requested, rd_data holds its previous value.

Worked Trace: Cycle 1: rst_n=0 → empty=1, full=0, rd_data=8'h00 Cycle 2: rst_n=1, wr_en=1, wr_data=8'hAA, rd_en=0 → empty=0, full=0, rd_data=8'h00 (Write occurs) Cycle 3: rst_n=1, wr_en=1, wr_data=8'hBB, rd_en=0 → empty=0, full=0, rd_data=8'h00 (Write occurs) Cycle 4: rst_n=1, wr_en=0, wr_data=8'h00, rd_en=1 → empty=0, full=0, rd_data=8'hAA (Read occurs, data updates) Cycle 5: rst_n=1, wr_en=0, wr_data=8'h00, rd_en=1 → empty=1, full=0, rd_data=8'hBB (Read occurs, FIFO now empty) Cycle 6: rst_n=1, wr_en=1, wr_data=8'hCC, rd_en=1 → empty=0, full=0, rd_data=8'hBB (Read ignored because empty=1; Write occurs)

{ "signal": [
  { "name": "clk", "wave": "p........." },
  { "name": "rst_n", "wave": "01........" },
  { "name": "wr_en", "wave": "011001...." },
  { "name": "wr_data", "wave": "x44xx4....", "data": ["AA", "BB", "CC"] },
  { "name": "rd_en", "wave": "000111...." },
  { "name": "rd_data", "wave": "=.=..=.=..", "data": ["00", "AA", "BB"] },
  { "name": "empty", "wave": "1.0..10..." },
  { "name": "full", "wave": "0........." }
], "head": { "text": "Basic write, read, and simultaneous request on empty." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | wr_en | input | 1 | Write enable; ignored if full is 1 | | wr_data | input | 8 | Data to be written into the FIFO | | rd_en | input | 1 | Read enable; ignored if empty is 1 | | rd_data | output | 8 | Read data output; updates on valid read | | full | output | 1 | High when the FIFO contains 16 words | | empty | output | 1 | High when the FIFO contains 0 words |

Constraints

  • The FIFO depth must be exactly 16 words.
  • Internal write and read pointers must be 5 bits wide to distinguish between full and empty conditions.
  • The memory array should be modeled as an array of 8-bit registers or standard Verilog memory; it does not require an explicit reset.
  • rd_data must be a registered output that updates strictly on posedge clk during a valid read.
  • Write requests on a full FIFO must not modify the memory or pointers.
  • Read requests on an empty FIFO must not modify the pointers or rd_data.

Topics

FIFOMemorySequential LogicPointers

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

  • Shift Register Based FIFOMedium
  • Asymmetric Data Width FIFOHard
  • True Dual Port RAM 2RWHard
  • Circular Buffer with OverwriteMedium
  • Synchronous Single Port RAMEasy
  • Stack Overflow and Underflow ProtectionMedium
  • Circular Buffer Pointer MathMedium
  • Read First Single Port RAMMedium

Browse all problems · Learning tracks