Skip to question
asic.fyi
DesignVerificationSystemVerilogFirmwareArchitectureInterviews
asic.fyi/Interview questions/Implement a deterministic true dual-port RAM

Hardware interview practice

Implement a deterministic true dual-port RAM

MediumClock and Reset DomainsSystemVerilog

Build a same-clock 16x8 true dual-port RAM with registered outputs and globally write-first behavior. Both ports sample on the same rising edge. Reset initializes only observable output/control registers, not the memory array. Implement the RAM and its defined collision behavior.

Try it in the question bankReason first. Then compare.

Keep this exact question selected while you check your answer and review the full solution.

Practice this question →
Starting point

Question code

module tdp16x8(input logic clk,rst_n,
 input logic a_en,a_we, input logic[3:0] a_addr, input logic[7:0] a_din, output logic[7:0] a_dout,
 input logic b_en,b_we, input logic[3:0] b_addr, input logic[7:0] b_din, output logic[7:0] b_dout,
 output logic write_conflict);
Reviewed example

Work through one case

Input
Case 1: A writes address 3 with 8'hA5 while B reads address 3
Case 2: A writes address 2 with 8'h11 while B writes address 7 with 8'h22
Case 3: A and B both write address 4 with different data
Expected output
Case 1: memory[3],a_dout,b_dout all become 8'hA5 and conflict=0.
Case 2: both bytes update and conflict=0.
Case 3: memory[4] keeps its old value, both outputs become 8'h00, and conflict=1 for that cycle.

The shown result follows by applying this rule: Resolve the same-address dual-write case before ordinary reads/writes so no process-order race chooses a winner. The cases also demonstrate this requirement: If both enabled ports write the same address on one edge, assert write_conflict for one cycle, leave that byte unchanged, and set both outputs to 8'h00. Tests must not read an address before it has been written after reset.

What to cover

Requirements

  1. Active-low synchronous reset clears both data outputs and write_conflict but does not initialize memory. On every nonreset edge without a dual-write conflict, drive write_conflict low.
  2. On one enabled write, update memory and make that port's registered output equal its input data; a disabled port holds its output.
  3. On an enabled read, register the addressed byte; when either port writes that address on the same edge, the read returns the new written byte. Two writes to different addresses and two reads may occur together.
  4. If both enabled ports write the same address on one edge, assert write_conflict for one cycle, leave that byte unchanged, and set both outputs to 8'h00. Tests must not read an address before it has been written after reset.
Continue practicing

Related questions

Clock and Reset DomainsIdentify an asynchronous-reset recovery violation→Clock and Reset DomainsImplement a coordinated-reset depth-16 asynchronous FIFO→Reset DesignSynchronize reset release in each clock domain→
asic.fyi · Learn silicon end to end.info@asic.fyi