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

Circular Buffer with Overwrite

MediumVerilog / SystemVerilogBuild

Telemetry logging systems and audio streaming pipelines often require a history buffer that retains only the most recent N samples. Unlike a strict FIFO that stalls the upstream producer when full, an overwriting circular buffer continuously accepts new data by silently discarding the oldest unread samples. This ensures the system always has access to the latest data without requiring complex software management.

The module manages a 4-deep, 8-bit wide ring buffer. It maintains internal write and read pointers to track data. When a write occurs, data is stored and the write pointer advances. If the buffer is full during a write, the oldest data is overwritten, and the read pointer is pushed forward to point to the new oldest entry. When a valid read occurs, the data at the read pointer is fetched, and the read pointer advances.

Timing and reset rules: • Clock edge: Positive-edge triggered clk. • Reset: Asynchronous active-low rst_n. • On reset, empty is 1, full is 0, r_valid is 0, r_data is 0, and all internal pointers are 0. • empty is 1 when the buffer contains 0 valid elements. • full is 1 when the buffer contains exactly 4 valid elements. • empty and full are combinational outputs reflecting the immediate state of the internal pointers. • r_data and r_valid are registered outputs updated on the clock edge. • When r_en is 1 and empty is 0, r_data updates with the read value and r_valid becomes 1 on the next clock cycle. • If r_en is 1 and empty is 1, the read is ignored; r_valid becomes 0 and r_data holds its previous value. • If w_en and r_en are asserted simultaneously when the buffer is full, the read operation fetches the current oldest data, and the write operation overwrites that same slot with new data. Both pointers increment by 1.

Worked trace: • Cycle 1: rst_n=0 → empty=1, full=0, r_valid=0, r_data=0 • Cycle 2: rst_n=1, w_en=1, w_data=10 → empty=0, full=0 • Cycle 3: w_en=1, w_data=20 → empty=0, full=0 • Cycle 4: w_en=1, w_data=30 → empty=0, full=0 • Cycle 5: w_en=1, w_data=40 → empty=0, full=1 (Buffer is now full) • Cycle 6: w_en=1, w_data=50, r_en=0 → empty=0, full=1 (Overwrites 10; read pointer is pushed forward) • Cycle 7: w_en=0, r_en=1 → empty=0, full=0, r_valid=1, r_data=20 (Reads 20, the new oldest data) • Cycle 8: w_en=0, r_en=1 → empty=0, full=0, r_valid=1, r_data=30

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | w_en | input | 1 | Write enable | | w_data | input | 8 | Data to be written to the buffer | | r_en | input | 1 | Read enable | | r_data | output | 8 | Registered read data output | | r_valid | output | 1 | Registered valid flag for read data | | empty | output | 1 | Combinational flag; 1 when buffer is empty | | full | output | 1 | Combinational flag; 1 when buffer is full |

Constraints

  • The buffer depth is exactly 4 elements.
  • empty and full must be combinational logic driven by the current pointer states.
  • r_data and r_valid must be registered logic updated on the positive clock edge.
  • When full, a write without a simultaneous read forces the read pointer to increment by 1.
  • When a read is ignored due to an empty buffer, r_valid must be set to 0 on the next clock cycle, and r_data must hold its previous value.

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
  • Synchronous Single Port RAMEasy
  • Stack Overflow and Underflow ProtectionMedium
  • Circular Buffer Pointer MathMedium
  • Combinational ROM InitializationEasy
  • Read First Single Port RAMMedium

Browse all problems · Learning tracks