Skip to content

Commit 7f7f613

Browse files
committed
[rtl] Add common security features of regfiles to separate module
1 parent 594ea97 commit 7f7f613

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

rtl/ibex_register_file_common.sv

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright lowRISC contributors.
2+
// Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
3+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
/**
7+
* RISC-V register file
8+
*
9+
* Register file common security functionality across multiple implementations
10+
*/
11+
module ibex_register_file_common #(
12+
parameter bit FPGA = 0,
13+
parameter int unsigned AddrWidth = 5,
14+
parameter int unsigned NumWords = 5,
15+
parameter int unsigned DataWidth = 32,
16+
parameter bit WrenCheck = 0,
17+
parameter bit RdataMuxCheck = 0
18+
) (
19+
// Clock and Reset
20+
input logic clk_i,
21+
input logic rst_ni,
22+
23+
//Read port R1
24+
input logic [4:0] raddr_a_i,
25+
output logic oh_raddr_a_err,
26+
27+
//Read port R2
28+
input logic [4:0] raddr_b_i,
29+
output logic oh_raddr_b_err,
30+
31+
// Write port W1
32+
input logic [ 4:0] waddr_a_i,
33+
input logic we_a_i,
34+
output logic [NumWords-1:0] oh_we_a_o,
35+
output logic oh_we_err,
36+
37+
// This indicates whether spurious WE or non-one-hot encoded raddr are detected.
38+
output logic err_o
39+
);
40+
41+
if (FPGA) begin : gen_fpga_oh_we_a_o_decoder
42+
always_comb begin : oh_we_a_o_decoder
43+
for (int unsigned i = 0; i < NumWords; i++) begin
44+
oh_we_a_o[i] = (i == 0) ? ((waddr_a_i == '0) ? 1'b0 : we_a_i) : 1'b0;
45+
end
46+
end
47+
end else begin : gen_other_oh_we_a_o_decoder
48+
always_comb begin : oh_we_a_o_decoder
49+
for (int unsigned i = 0; i < NumWords; i++) begin
50+
oh_we_a_o[i] = (waddr_a_i == 5'(i)) ? we_a_i : 1'b0;
51+
end
52+
end
53+
end
54+
55+
// SEC_CM: DATA_REG_SW.GLITCH_DETECT
56+
// This checks for spurious WE strobes on the regfile.
57+
if (WrenCheck) begin : gen_wren_check
58+
// Buffer the decoded write enable bits so that the checker
59+
// is not optimized into the address decoding logic.
60+
logic [NumWords-1:0] oh_we_a_o_buf;
61+
prim_buf #(
62+
.Width(NumWords)
63+
) u_prim_buf (
64+
.in_i (oh_we_a_o),
65+
.out_o(oh_we_a_o_buf)
66+
);
67+
68+
prim_onehot_check #(
69+
.AddrWidth (AddrWidth),
70+
.OneHotWidth(NumWords),
71+
.AddrCheck (FPGA ? 0 : 1), // disable in case of FPGA impl, as we use [0] only
72+
.EnableCheck(1),
73+
) u_prim_onehot_check (
74+
.clk_i,
75+
.rst_ni,
76+
.oh_i (oh_we_a_o_buf),
77+
.addr_i(waddr_a_i),
78+
.en_i (we_a_i),
79+
.err_o (oh_we_err)
80+
);
81+
end else begin : gen_no_wren_check
82+
assign oh_we_err = 1'b0;
83+
end
84+
85+
if (RdataMuxCheck) begin : gen_rdata_mux_check
86+
// Encode raddr_a/b into one-hot encoded signals.
87+
logic [NumWords-1:0] raddr_onehot_a, raddr_onehot_b;
88+
logic [NumWords-1:0] raddr_onehot_a_buf, raddr_onehot_b_buf;
89+
prim_onehot_enc #(
90+
.OneHotWidth(NumWords)
91+
) u_prim_onehot_enc_raddr_a (
92+
.in_i (raddr_a_i),
93+
.en_i (1'b1),
94+
.out_o(raddr_onehot_a)
95+
);
96+
97+
prim_onehot_enc #(
98+
.OneHotWidth(NumWords)
99+
) u_prim_onehot_enc_raddr_b (
100+
.in_i (raddr_b_i),
101+
.en_i (1'b1),
102+
.out_o(raddr_onehot_b)
103+
);
104+
105+
// Buffer the one-hot encoded signals so that the checkers
106+
// are not optimized.
107+
prim_buf #(
108+
.Width(NumWords)
109+
) u_prim_buf_raddr_a (
110+
.in_i (raddr_onehot_a),
111+
.out_o(raddr_onehot_a_buf)
112+
);
113+
114+
prim_buf #(
115+
.Width(NumWords)
116+
) u_prim_buf_raddr_b (
117+
.in_i (raddr_onehot_b),
118+
.out_o(raddr_onehot_b_buf)
119+
);
120+
121+
// SEC_CM: DATA_REG_SW.GLITCH_DETECT
122+
// Check the one-hot encoded signals for glitches.
123+
prim_onehot_check #(
124+
.AddrWidth (AddrWidth),
125+
.OneHotWidth(NumWords),
126+
.AddrCheck (1),
127+
// When AddrCheck=1 also EnableCheck needs to be 1.
128+
.EnableCheck(1)
129+
) u_prim_onehot_check_raddr_a (
130+
.clk_i,
131+
.rst_ni,
132+
.oh_i (raddr_onehot_a_buf),
133+
.addr_i(raddr_a_i),
134+
// Set enable=1 as address is always valid.
135+
.en_i (1'b1),
136+
.err_o (oh_raddr_a_err)
137+
);
138+
139+
prim_onehot_check #(
140+
.AddrWidth (AddrWidth),
141+
.OneHotWidth(NumWords),
142+
.AddrCheck (1),
143+
// When AddrCheck=1 also EnableCheck needs to be 1.
144+
.EnableCheck(1)
145+
) u_prim_onehot_check_raddr_b (
146+
.clk_i,
147+
.rst_ni,
148+
.oh_i (raddr_onehot_b_buf),
149+
.addr_i(raddr_b_i),
150+
// Set enable=1 as address is always valid.
151+
.en_i (1'b1),
152+
.err_o (oh_raddr_b_err)
153+
);
154+
end else begin : gen_no_rdata_mux_check
155+
assign oh_raddr_a_err = 1'b0;
156+
assign oh_raddr_b_err = 1'b0;
157+
end
158+
159+
assign err_o = oh_raddr_a_err || oh_raddr_b_err || oh_we_err;
160+
161+
endmodule

0 commit comments

Comments
 (0)