CPU-style register files often require 2 read + 1 write ports in one cycle. True multi-port SRAM is expensive, so many designs use flop arrays or replicated RAM banks.
The contract below fixes the same-cycle semantics per the architectural spec. Every implementation in this topic follows it.
Read the picture with the table below beside it. The write commits at the edge, while both reads are combinational. That is why a read of the register being written needs a rule: without one it returns the old word in that cycle.
Two read muxes: the two reads never compete, because each port has its own mux on the shared array.
One write port: a single word changes per cycle, so the only same-cycle conflict is a read of that word.
x0: the read side forces zero and the write side drops the write, so register 0 never holds anything else.
Case | Result |
|---|---|
Read address differs from write address | The stored word |
Read address equals write address, write enabled | The NEW write data (write-through) |
Write disabled | The stored word on every read |
Read address is x0 | Zero, always, regardless of writes |
Write address is x0 | Dropped: the write changes nothing |
One more rule sets up the next lesson. A bypass is added when the decode stage needs a just-written value immediately.
A 32-entry by 32-bit flop array holds 1024 storage flops plus two 32-to-1 read muxes. It resets with a loop, reads combinationally, and grows a mux per read port.
Style | How 2R1W is built | Cost | Use when |
|---|---|---|---|
Flop array | One array, two read muxes, one write enable | Flops plus muxes; area grows with ports and words | Tens of words, for example a 32-entry integer file |
Replicated banks | One SRAM bank per read port; writes broadcast to all banks | One bank per read port plus broadcast logic | Hundreds of words with few read ports |
True multi-port RAM | One macro with two read and one write port | Dense storage; port combinations are process-limited | Large files where the macro ports match 2R1W |
The reset loop in the next lesson targets flops. Conventional FPGA block RAM and selected synchronous SRAM macros cannot clear every word at once and require clocked reads, so this combinational-read, array-reset code does not match them. Other SRAM resources can support asynchronous reads; inspect the chosen macro's interface. Replacing this file with synchronous banks changes read latency and requires a matching pipeline contract.
The new write data. Same-cycle read of the written register is write-through by contract.
Both return zero. The write is dropped, so the array is unchanged.
Area and timing. The flop count grows 32x and each read mux grows from 32-to-1 to 1024-to-1. A replicated-bank or multi-port SRAM structure fits large files better.