@@ -48,46 +48,34 @@ module ibex_register_file_ff #(
48
48
localparam int unsigned NUM_WORDS = 2 ** ADDR_WIDTH ;
49
49
50
50
logic [DataWidth- 1 : 0 ] rf_reg [NUM_WORDS ];
51
- logic [NUM_WORDS - 1 : 0 ] we_a_dec;
52
51
52
+ // Encode we_a/raddr_a/raddr_b into one-hot encoded signals
53
+ logic [NUM_WORDS - 1 : 0 ] raddr_onehot_a, raddr_onehot_b, we_onehot_a;
54
+
55
+ // One-hot encoding error signals
53
56
logic oh_raddr_a_err, oh_raddr_b_err, oh_we_err;
54
57
55
- always_comb begin : we_a_decoder
56
- for (int unsigned i = 0 ; i < NUM_WORDS ; i++ ) begin
57
- we_a_dec[i] = (waddr_a_i == 5 '(i)) ? we_a_i : 1'b0 ;
58
- end
59
- end
60
-
61
- // SEC_CM: DATA_REG_SW.GLITCH_DETECT
62
- // This checks for spurious WE strobes on the regfile.
63
- if (WrenCheck) begin : gen_wren_check
64
- // Buffer the decoded write enable bits so that the checker
65
- // is not optimized into the address decoding logic.
66
- logic [NUM_WORDS - 1 : 0 ] we_a_dec_buf;
67
- prim_buf # (
68
- .Width (NUM_WORDS )
69
- ) u_prim_buf (
70
- .in_i (we_a_dec),
71
- .out_o (we_a_dec_buf)
72
- );
73
-
74
- prim_onehot_check # (
75
- .AddrWidth (ADDR_WIDTH ),
76
- .AddrCheck (1 ),
77
- .EnableCheck (1 )
78
- ) u_prim_onehot_check (
79
- .clk_i,
80
- .rst_ni,
81
- .oh_i (we_a_dec_buf),
82
- .addr_i (waddr_a_i),
83
- .en_i (we_a_i),
84
- .err_o (oh_we_err)
85
- );
86
- end else begin : gen_no_wren_check
87
- logic unused_strobe;
88
- assign unused_strobe = we_a_dec[0 ]; // this is never read from in this case
89
- assign oh_we_err = 1'b0 ;
90
- end
58
+ // Common security functionality
59
+ ibex_register_file_common # (
60
+ .AddrWidth (ADDR_WIDTH ),
61
+ .NumWords (NUM_WORDS ),
62
+ .WrenCheck (WrenCheck),
63
+ .RdataMuxCheck (RdataMuxCheck)
64
+ ) security_module (
65
+ .clk_i,
66
+ .rst_ni,
67
+ .raddr_a_i,
68
+ .raddr_onehot_a,
69
+ .oh_raddr_a_err,
70
+ .raddr_b_i,
71
+ .raddr_onehot_b,
72
+ .oh_raddr_b_err,
73
+ .waddr_a_i,
74
+ .we_a_i,
75
+ .we_onehot_a,
76
+ .oh_we_err,
77
+ .err_o
78
+ );
91
79
92
80
// No flops for R0 as it's hard-wired to 0
93
81
for (genvar i = 1 ; i < NUM_WORDS ; i++ ) begin : g_rf_flops
@@ -96,7 +84,7 @@ module ibex_register_file_ff #(
96
84
always_ff @ (posedge clk_i or negedge rst_ni) begin
97
85
if (! rst_ni) begin
98
86
rf_reg_q <= WordZeroVal;
99
- end else if (we_a_dec [i]) begin
87
+ end else if (we_onehot_a [i]) begin
100
88
rf_reg_q <= wdata_a_i;
101
89
end
102
90
end
@@ -134,75 +122,6 @@ module ibex_register_file_ff #(
134
122
end
135
123
136
124
if (RdataMuxCheck) begin : gen_rdata_mux_check
137
- // Encode raddr_a/b into one-hot encoded signals.
138
- logic [NUM_WORDS - 1 : 0 ] raddr_onehot_a, raddr_onehot_b;
139
- logic [NUM_WORDS - 1 : 0 ] raddr_onehot_a_buf, raddr_onehot_b_buf;
140
- prim_onehot_enc # (
141
- .OneHotWidth (NUM_WORDS )
142
- ) u_prim_onehot_enc_raddr_a (
143
- .in_i (raddr_a_i),
144
- .en_i (1'b1 ),
145
- .out_o (raddr_onehot_a)
146
- );
147
-
148
- prim_onehot_enc # (
149
- .OneHotWidth (NUM_WORDS )
150
- ) u_prim_onehot_enc_raddr_b (
151
- .in_i (raddr_b_i),
152
- .en_i (1'b1 ),
153
- .out_o (raddr_onehot_b)
154
- );
155
-
156
- // Buffer the one-hot encoded signals so that the checkers
157
- // are not optimized.
158
- prim_buf # (
159
- .Width (NUM_WORDS )
160
- ) u_prim_buf_raddr_a (
161
- .in_i (raddr_onehot_a),
162
- .out_o (raddr_onehot_a_buf)
163
- );
164
-
165
- prim_buf # (
166
- .Width (NUM_WORDS )
167
- ) u_prim_buf_raddr_b (
168
- .in_i (raddr_onehot_b),
169
- .out_o (raddr_onehot_b_buf)
170
- );
171
-
172
- // SEC_CM: DATA_REG_SW.GLITCH_DETECT
173
- // Check the one-hot encoded signals for glitches.
174
- prim_onehot_check # (
175
- .AddrWidth (ADDR_WIDTH ),
176
- .OneHotWidth (NUM_WORDS ),
177
- .AddrCheck (1 ),
178
- // When AddrCheck=1 also EnableCheck needs to be 1.
179
- .EnableCheck (1 )
180
- ) u_prim_onehot_check_raddr_a (
181
- .clk_i,
182
- .rst_ni,
183
- .oh_i (raddr_onehot_a_buf),
184
- .addr_i (raddr_a_i),
185
- // Set enable=1 as address is always valid.
186
- .en_i (1'b1 ),
187
- .err_o (oh_raddr_a_err)
188
- );
189
-
190
- prim_onehot_check # (
191
- .AddrWidth (ADDR_WIDTH ),
192
- .OneHotWidth (NUM_WORDS ),
193
- .AddrCheck (1 ),
194
- // When AddrCheck=1 also EnableCheck needs to be 1.
195
- .EnableCheck (1 )
196
- ) u_prim_onehot_check_raddr_b (
197
- .clk_i,
198
- .rst_ni,
199
- .oh_i (raddr_onehot_b_buf),
200
- .addr_i (raddr_b_i),
201
- // Set enable=1 as address is always valid.
202
- .en_i (1'b1 ),
203
- .err_o (oh_raddr_b_err)
204
- );
205
-
206
125
// MUX register to rdata_a/b_o according to raddr_a/b_onehot.
207
126
prim_onehot_mux # (
208
127
.Width (DataWidth),
@@ -228,14 +147,21 @@ module ibex_register_file_ff #(
228
147
end else begin : gen_no_rdata_mux_check
229
148
assign rdata_a_o = rf_reg[raddr_a_i];
230
149
assign rdata_b_o = rf_reg[raddr_b_i];
231
- assign oh_raddr_a_err = 1'b0 ;
232
- assign oh_raddr_b_err = 1'b0 ;
233
- end
234
150
235
- assign err_o = oh_raddr_a_err || oh_raddr_b_err || oh_we_err;
151
+ logic unused_raddr_onehot, unused_oh_raddr_err;
152
+ assign unused_raddr_onehot = ^{ raddr_onehot_a, raddr_onehot_b} ;
153
+ assign unused_oh_raddr_err = ^{ oh_raddr_a_err, oh_raddr_b_err} ;
154
+ end
236
155
237
156
// Signal not used in FF register file
238
157
logic unused_test_en;
239
158
assign unused_test_en = test_en_i;
240
159
160
+ if (WrenCheck) begin : gen_wren_check
161
+ end else begin : gen_no_wren_check
162
+ logic unused_strobe, unused_oh_we_err;
163
+ assign unused_strobe = we_onehot_a[0 ]; // this is never read from in this case
164
+ assign unused_oh_we_err = oh_we_err; // this is never read from in this case
165
+ end
166
+
241
167
endmodule
0 commit comments