# Phase 2.1 - Register File Module ## Context This subphase turns the architectural register model into clocked hardware with two combinational reads and one synchronous write. ## Goals - Implement 32 registers of 32 bits. - Enforce `x0` semantics. - Verify read, write, and collision behavior. ## New Concepts - Synchronous write: state changes only at the active clock edge. - Combinational read: output changes when the address changes. - Read-after-write: reading an address in the same cycle it is written. - Bypass/forwarding: returning newly written data without waiting for storage update. ## How To Think About It Choose behavior deliberately. A simple non-pipelined core can tolerate many choices, but tests and later pipeline work become easier if the behavior is documented. ## Learning Tasks - Write a truth table for `write_enable`, `rd`, `rs1`, and `rs2` interactions. - Decide how reset affects registers, if at all. - Confirm whether the register file should initialize to zero for simulation clarity. ## Pitfalls - Resetting a large register file unnecessarily in hardware. - Making simulation behavior differ from synthesis behavior. - Forgetting that reads from `x0` must ignore any stored value. ## Tooling And Testing - Use assertions for `x0` if your simulator supports them. - Run repeated randomized write/read sequences. - Inspect synthesis resource use; this may infer LUT RAM or flip-flops. ## References - RISC-V ABI register names: https://riscv.org/technical/specifications/ - SystemVerilog always_ff guidance: https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md - Vivado synthesis guide: https://docs.xilinx.com/