forked from lowRISC/ibex
-
Notifications
You must be signed in to change notification settings - Fork 2
/
zeroriscy_register_file_ff.sv
103 lines (82 loc) · 3.49 KB
/
zeroriscy_register_file_ff.sv
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Francesco Conti - [email protected] //
// //
// Additional contributions by: //
// Markus Wegmann - [email protected] //
// //
// Design Name: RISC-V register file //
// Project Name: zero-riscy //
// Language: SystemVerilog //
// //
// Description: Register file with 31 or 15x 32 bit wide registers. //
// Register 0 is fixed to 0. This register file is based on //
// flip flops. //
// //
////////////////////////////////////////////////////////////////////////////////
`include "zeroriscy_config.sv"
module zeroriscy_register_file
#(
parameter RV32E = 0,
parameter DATA_WIDTH = 32
)
(
// Clock and Reset
input logic clk,
input logic rst_n,
input logic test_en_i,
//Read port R1
input logic [4:0] raddr_a_i,
output logic [DATA_WIDTH-1:0] rdata_a_o,
//Read port R2
input logic [4:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// Write port W1
input logic [4:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i
);
localparam ADDR_WIDTH = RV32E ? 4 : 5;
localparam NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg_tmp;
logic [NUM_WORDS-1:0] we_a_dec;
always_comb
begin : we_a_decoder
for (int i = 0; i < NUM_WORDS; i++) begin
if (waddr_a_i == i)
we_a_dec[i] = we_a_i;
else
we_a_dec[i] = 1'b0;
end
end
genvar i;
generate
// loop from 1 to NUM_WORDS-1 as R0 is nil
for (i = 1; i < NUM_WORDS; i++)
begin : rf_gen
always_ff @(posedge clk, negedge rst_n)
begin : register_write_behavioral
if (rst_n==1'b0) begin
rf_reg_tmp[i] <= 'b0;
end else begin
if (we_a_dec[i])
rf_reg_tmp[i] <= wdata_a_i;
end
end
end
// R0 is nil
assign rf_reg[0] = '0;
assign rf_reg[NUM_WORDS-1:1] = rf_reg_tmp[NUM_WORDS-1:1];
endgenerate
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
endmodule