Skip to content

Commit 8466e42

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

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

rtl/ibex_register_file_common.sv

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

0 commit comments

Comments
 (0)