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

True Dual Port RAM Collision Resolution

HardVerilog / SystemVerilogBuild

Multi-core processors and hardware accelerators frequently share memory spaces using True Dual-Port RAM. When independent agents access the same memory element simultaneously, write collisions can corrupt data or cause metastable states. Arbitration logic is required to ensure deterministic behaviour and preserve data integrity across the system.

This module implements a 256-word by 8-bit True Dual-Port RAM with integrated collision resolution. Both Port A and Port B can independently read and write to the shared memory array. When both ports attempt to write to the identical address in the same clock cycle, a collision occurs. Port A has strict priority; its data must be written to the memory array, and Port B's write is discarded. Reads are synchronous and operate in a write-first (read-through) mode. If a port reads an address that is being written to in the same cycle by either port, the read output must immediately reflect the newly written data.

Timing and Reset Rules: • Clock edge: posedge clk • Reset: There is no reset signal; the memory array contents are uninitialized at power-up. • Write-first forwarding: If Port X writes to address N, dout_x updates with the new data on the exact same clock edge. • Cross-port forwarding: If Port X writes to address N and Port Y reads address N simultaneously, dout_y updates with Port X's new data. • Collision forwarding: If Port A and Port B both write to address N simultaneously, Port A wins. Both dout_a and dout_b must output Port A's data.

Worked Trace: • Cycle 1: we_a=1, addr_a=8'h10, din_a=8'hAA, we_b=0, addr_b=8'h20. Port A writes 8'hAA to 8'h10. dout_a becomes 8'hAA. • Cycle 2: we_a=0, addr_a=8'h10, we_b=1, addr_b=8'h10, din_b=8'hBB. Port B writes 8'hBB to 8'h10, Port A reads 8'h10. dout_b becomes 8'hBB (write-first), dout_a becomes 8'hBB (cross-port forward). • Cycle 3: we_a=1, addr_a=8'h30, din_a=8'hCC, we_b=1, addr_b=8'h30, din_b=8'hDD. Collision at 8'h30. Port A wins. dout_a becomes 8'hCC, dout_b becomes 8'hCC (collision forward). Memory at 8'h30 is 8'hCC. • Cycle 4: we_a=0, addr_a=8'h30, we_b=0, addr_b=8'h30. Both ports read 8'h30. Both output 8'hCC.

{ "signal": [
  { "name": "clk", "wave": "p......" },
  { "name": "we_a", "wave": "01010.." },
  { "name": "addr_a", "wave": "x=x=x..", "data": ["0x10", "0x30"] },
  { "name": "din_a", "wave": "x=x=x..", "data": ["0xAA", "0xCC"] },
  { "name": "dout_a", "wave": "x.=x.=.", "data": ["0xAA", "0xBB", "0xCC"] },
  {},
  { "name": "we_b", "wave": "00110.." },
  { "name": "addr_b", "wave": "x=x=x..", "data": ["0x20", "0x10", "0x30"] },
  { "name": "din_b", "wave": "x.x=x..", "data": ["0xBB", "0xDD"] },
  { "name": "dout_b", "wave": "x...=..", "data": ["0xBB", "0xCC"] }
], "head": { "text": "Cycle 1: Port A writes. Cycle 2: Port B writes. Cycle 3: Collision at 0x30, Port A wins." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | we_a | input | 1 | Port A write enable | | addr_a | input | 8 | Port A memory address | | din_a | input | 8 | Port A write data | | dout_a | output | 8 | Port A read data; registered output | | we_b | input | 1 | Port B write enable | | addr_b | input | 8 | Port B memory address | | din_b | input | 8 | Port B write data | | dout_b | output | 8 | Port B read data; registered output |

Constraints

  • Memory capacity must be exactly 256 words of 8 bits each.
  • Outputs dout_a and dout_b must be registered and update exactly on posedge clk.
  • Port A strictly overrides Port B when we_a=1, we_b=1, and addr_a == addr_b.
  • Read-through (write-first) behaviour is required for both intra-port and cross-port read/write combinations.

Topics

MemorySynchronous LogicArbitration

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