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

Write First Single Port RAM

MediumVerilog / SystemVerilogBuild

High performance packet buffers and forwarding pipelines often require that data written to a memory address be immediately available for reading on the exact same clock cycle. Standard block RAM primitives typically exhibit read first behavior, returning the old data during a simultaneous read and write. To resolve this, memory controllers must implement bypass logic.

This module implements a single port synchronous RAM named solution with write first behavior, also known as read through bypass. The memory array contains 16 words, each 8 bits wide. On every clock cycle, the module processes the provided addr. If we is asserted, the input din is written into the memory array and simultaneously forwarded directly to the output dout. If we is deasserted, the output dout updates with the existing data stored at the requested memory address.

  • Clock edge: posedge clk
  • Reset type: Asynchronous, active low rst_n
  • Reset behavior: When rst_n is 0, the output register dout is cleared to 0. The internal memory array contents remain uninitialized and are not cleared by reset.
  • Write first logic: The output dout must reflect the newly written data on the same clock edge that we is asserted.

Cycle 1: rst_n=0, we=0 → dout=0 Cycle 2: rst_n=1, we=1, addr=5, din=8'hAA → dout=8'hAA (writes 0xAA to mem[5], bypasses to output) Cycle 3: we=0, addr=5 → dout=8'hAA (reads mem[5]) Cycle 4: we=1, addr=2, din=8'hBB → dout=8'hBB (writes 0xBB to mem[2], bypasses to output) Cycle 5: we=0, addr=2 → dout=8'hBB (reads mem[2]) Cycle 6: we=0, addr=5 → dout=8'hAA (reads mem[5])

{ "signal": [
  { "name": "clk",   "wave": "p......" },
  { "name": "rst_n", "wave": "01....." },
  { "name": "we",    "wave": "010100." },
  { "name": "addr",  "wave": "x======", "data": ["5", "5", "2", "2", "5"] },
  { "name": "din",   "wave": "x=x=xx.", "data": ["AA", "BB"] },
  { "name": "dout",  "wave": "=.=.=.=", "data": ["00", "AA", "AA", "BB", "BB", "AA"] }
], "head": { "text": "Write first RAM operation showing immediate bypass and subsequent reads." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive edge triggered clock | | rst_n| input | 1 | Asynchronous active low reset; clears dout to 0 | | we | input | 1 | Write enable; when 1, writes din to addr and bypasses to dout | | addr | input | 4 | Memory address for read and write operations | | din | input | 8 | Data input to be written into the memory | | dout | output | 8 | Data output; updates synchronously on clk |

Constraints

  • The memory array must be exactly 16 words deep by 8 bits wide.
  • The output dout must be a registered output that updates strictly on posedge clk or asynchronous rst_n.
  • The bypass logic must ensure dout receives din in the same cycle we is high, without requiring a combinational path from din to dout that bypasses the output register.
  • Do not attempt to reset the entire memory array; only reset the output register dout.

Topics

MemorySynchronous LogicBypass Logic

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