aboutsummaryrefslogtreecommitdiff
path: root/rv64cpu/rtl/core/registers/regfile.sv
blob: dbc3c04807046d4e5b48ba2f267afe1b5d8a77d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//     Richard CPU
//     Copyright (C) 2026  Richard Qin

//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.

//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.

//     You should have received a copy of the GNU General Public License
//     along with this program.  If not, see <https://www.gnu.org/licenses/>.

// File path: rtl/core/regfile.sv
// Description: 64-bit Register File

module regfile
    import rv64_pkg::*;
(
    input  logic                      clk,  // Clock signal
    input  logic                      rst,  // Reset signal active high

    // Read port 1
    input  logic [4:0]                rs1_addr, // Read address 1
    output logic [XLEN-1:0]           rs1_rdata,  // Read data 1

    // Read port 2
    input  logic [4:0]                rs2_addr, // Read address 2
    output logic [XLEN-1:0]           rs2_rdata,  // Read data 2

    // Write port
    input  logic [4:0]                rd_addr,  // Write address
    input  logic [XLEN-1:0]           rd_wdata,   // Write data
    input  logic                      reg_write_en // Write enable signal
);

    // Register file storage
    logic [XLEN-1:0] regs [0:31];

    // Read Logic (combinational logic)
    // Internal bypass: If reading the same register as currently being written, 
    // forward the write data immediately.
    assign rs1_rdata = (rs1_addr == 5'b0) ? '0 : 
                       ((rs1_addr == rd_addr) && reg_write_en) ? rd_wdata : 
                       regs[rs1_addr];
                       
    assign rs2_rdata = (rs2_addr == 5'b0) ? '0 : 
                       ((rs2_addr == rd_addr) && reg_write_en) ? rd_wdata : 
                       regs[rs2_addr];

    // Write Logic (sequential logic)
    always_ff @(posedge clk) begin
        if (rst) begin
            for (int i = 0; i < 32; i++) begin
                regs[i] <= '0;
            end
        end else begin
            if (reg_write_en && rd_addr != 5'b0) begin
                regs[rd_addr] <= rd_wdata;
            end
        end
    end

endmodule