aboutsummaryrefslogtreecommitdiff
path: root/rtl/regfile.sv
blob: 8ca992cd65f3c80751adc601d342c1206bd5e7bf (plain) (blame)
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
/* SPDX-License-Identifier: CERN-OHL-P-2.0 */

/*
 * Copyright 2026 UBC ASIC contributors (Montreal project).
 *
 * Author: Warrick Lo <wlo@warricklo.net>
 *
 * Register file
 *
 * This module contains the register file for the RISC-V core. Each word is
 * partitioned into slices (default 8 bits). A global slice selector determines
 * which slice of each word is accessed for both read and write operations.
 *
 * The register file has one synchronous write port and a configurable number of
 * read ports (default 2). Register 0 is fixed to 0 for all reads.
 */

module regfile #(
  parameter int unsigned WORD_WIDTH     = 32,
  parameter int unsigned ADDR_WIDTH     = 4,
  parameter int unsigned SLICE_WIDTH    = 8,
  parameter int unsigned NUM_READ_PORTS = 2,

  localparam int unsigned NUM_WORDS  = 2 ** ADDR_WIDTH,
  localparam int unsigned NUM_SLICES = WORD_WIDTH / SLICE_WIDTH
) (
  input logic clk_i,
  input logic rst_ni,
  input logic [$clog2(NUM_SLICES)-1:0] slice_sel_i,

  input  logic [NUM_READ_PORTS-1:0][ADDR_WIDTH-1:0]  raddr_i,
  output logic [NUM_READ_PORTS-1:0][SLICE_WIDTH-1:0] rdata_o,

  input logic wen_i,
  input logic [ADDR_WIDTH-1:0]  waddr_i,
  input logic [SLICE_WIDTH-1:0] wdata_i
);

  logic [NUM_WORDS-1:0][WORD_WIDTH-1:0] register;

  always_comb begin
    for (int i = 0; i < NUM_READ_PORTS; i++) begin : gen_read_block
      rdata_o[i] = (raddr_i[i] == '0)
          ? '0 : register[raddr_i[i]][slice_sel_i*SLICE_WIDTH +: SLICE_WIDTH];
    end : gen_read_block
  end

  always_ff @(posedge clk_i) begin
    if (!rst_ni) begin
      register <= '0;
    end else if (wen_i && (waddr_i != '0)) begin
      /* verilog_lint: waive dff-name-style */
      register[waddr_i][slice_sel_i*SLICE_WIDTH +: SLICE_WIDTH] <= wdata_i;
    end
  end

endmodule : regfile