Skip to content

Commit b27e4b2

Browse files
committed
[chip,dv] Fix RegFileDataWidth in lockstep_glitch_vseq
Depending on whether we are faulting the main or the shadow core, use the correct data width size for the register file ports. The main core operates on the plain data (RegFileDataWidth = 32 bit) and the shadow core on the data + ECC (RegFileDataEccWidth = 39 bit). The write data that is forwarded to the shadow core RF only uses the upper bits of the write data. Signed-off-by: Pascal Nasahl <[email protected]>
1 parent cbadd9c commit b27e4b2

File tree

1 file changed

+69
-54
lines changed

1 file changed

+69
-54
lines changed

hw/top_earlgrey/dv/env/seq_lib/chip_sw_rv_core_ibex_lockstep_glitch_vseq.sv

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class chip_sw_rv_core_ibex_lockstep_glitch_vseq extends chip_sw_base_vseq;
1414
int unsigned width; // >0: take this as width; 0: use width from parameter
1515
string width_parameter_name;
1616
int unsigned unpacked_dim_width;
17+
int unsigned offset;
1718
} port_t;
1819

1920
typedef logic [255:0] val_t;
@@ -205,70 +206,85 @@ class chip_sw_rv_core_ibex_lockstep_glitch_vseq extends chip_sw_base_vseq;
205206
"Could not read LockstepOffset parameter.");
206207

207208
// List of all ports and their bit widths (or the name of the parameter that defines the width
208-
// and/or the unpacked dimension).
209+
// and/or the unpacked dimension). The fourth field allows enabling an offset from where the
210+
// fault will be injected.
209211
ports = new[45];
210212
ports = '{
211213
// `hart_id_i` and `boot_addr_i` are not glitch-protected by the lockstep core.
212-
// '{"hart_id_i", 1, "", 0},
213-
// '{"boot_addr_i", 1, "", 0},
214-
'{"instr_req_o", 1, "", 0},
215-
'{"instr_gnt_i", 1, "", 0},
216-
'{"instr_rvalid_i", 1, "", 0},
217-
'{"instr_addr_o", 32, "", 0},
218-
'{"instr_rdata_i", 0, "MemDataWidth", 0},
219-
'{"instr_err_i", 1, "", 0},
220-
'{"data_req_o", 1, "", 0},
221-
'{"data_gnt_i", 1, "", 0},
222-
'{"data_rvalid_i", 1, "", 0},
223-
'{"data_we_o", 1, "", 0},
224-
'{"data_be_o", 1, "", 0},
225-
'{"data_addr_o", 32, "", 0},
226-
'{"data_wdata_o", 0, "MemDataWidth", 0},
227-
'{"data_rdata_i", 0, "MemDataWidth", 0},
228-
'{"data_err_i", 1, "", 0},
229-
'{"dummy_instr_id_o", 1, "", 0},
230-
'{"rf_raddr_a_o", 5, "", 0},
231-
'{"rf_raddr_b_o", 5, "", 0},
232-
'{"rf_waddr_wb_o", 5, "", 0},
233-
'{"rf_we_wb_o", 1, "", 0},
234-
'{"rf_wdata_wb_ecc_o", 0, "RegFileDataWidth", 0},
235-
'{"rf_rdata_a_ecc_i", 0, "RegFileDataWidth", 0},
236-
'{"rf_rdata_b_ecc_i", 0, "RegFileDataWidth", 0},
237-
'{"ic_tag_req_o", ibex_pkg::IC_NUM_WAYS, "", 0},
238-
'{"ic_tag_write_o", 1, "", 0},
239-
'{"ic_tag_addr_o", ibex_pkg::IC_INDEX_W, "", 0},
240-
'{"ic_tag_wdata_o", 0, "TagSizeECC", 0},
241-
'{"ic_tag_rdata_i", 0, "TagSizeECC", ibex_pkg::IC_NUM_WAYS},
242-
'{"ic_data_req_o", ibex_pkg::IC_NUM_WAYS, "", 0},
243-
'{"ic_data_write_o", 1, "", 0},
244-
'{"ic_data_addr_o", ibex_pkg::IC_INDEX_W, "", 0},
245-
'{"ic_data_wdata_o", 0, "LineSizeECC", 0},
246-
'{"ic_data_rdata_i", 0, "LineSizeECC", ibex_pkg::IC_NUM_WAYS},
247-
'{"ic_scr_key_valid_i", 1, "", 0},
248-
'{"ic_scr_key_req_o", 1, "", 0},
249-
'{"irq_software_i", 1, "", 0},
250-
'{"irq_timer_i", 1, "", 0},
251-
'{"irq_external_i", 1, "", 0},
252-
'{"irq_fast_i", 15, "", 0},
253-
'{"irq_nm_i", 1, "", 0},
254-
'{"irq_pending_o", 1, "", 0},
255-
'{"debug_req_i", 1, "", 0},
256-
'{"crash_dump_o", $bits(ibex_pkg::crash_dump_t), "", 0},
257-
'{"double_fault_seen_o", 1, "", 0},
214+
// '{"hart_id_i", 1, "", 0, 0},
215+
// '{"boot_addr_i", 1, "", 0, 0},
216+
'{"instr_req_o", 1, "", 0, 0},
217+
'{"instr_gnt_i", 1, "", 0, 0},
218+
'{"instr_rvalid_i", 1, "", 0, 0},
219+
'{"instr_addr_o", 32, "", 0, 0},
220+
'{"instr_rdata_i", 0, "MemDataWidth", 0, 0},
221+
'{"instr_err_i", 1, "", 0, 0},
222+
'{"data_req_o", 1, "", 0, 0},
223+
'{"data_gnt_i", 1, "", 0, 0},
224+
'{"data_rvalid_i", 1, "", 0, 0},
225+
'{"data_we_o", 1, "", 0, 0},
226+
'{"data_be_o", 1, "", 0, 0},
227+
'{"data_addr_o", 32, "", 0, 0},
228+
'{"data_wdata_o", 0, "MemDataWidth", 0, 0},
229+
'{"data_rdata_i", 0, "MemDataWidth", 0, 0},
230+
'{"data_err_i", 1, "", 0, 0},
231+
'{"dummy_instr_id_o", 1, "", 0, 0},
232+
'{"rf_raddr_a_o", 5, "", 0, 0},
233+
'{"rf_raddr_b_o", 5, "", 0, 0},
234+
'{"rf_waddr_wb_o", 5, "", 0, 0},
235+
'{"rf_we_wb_o", 1, "", 0, 0},
236+
'{"ic_tag_req_o", ibex_pkg::IC_NUM_WAYS, "", 0, 0},
237+
'{"ic_tag_write_o", 1, "", 0, 0},
238+
'{"ic_tag_addr_o", ibex_pkg::IC_INDEX_W, "", 0, 0},
239+
'{"ic_tag_wdata_o", 0, "TagSizeECC", 0, 0},
240+
'{"ic_tag_rdata_i", 0, "TagSizeECC", ibex_pkg::IC_NUM_WAYS, 0},
241+
'{"ic_data_req_o", ibex_pkg::IC_NUM_WAYS, "", 0, 0},
242+
'{"ic_data_write_o", 1, "", 0, 0},
243+
'{"ic_data_addr_o", ibex_pkg::IC_INDEX_W, "", 0, 0},
244+
'{"ic_data_wdata_o", 0, "LineSizeECC", 0, 0},
245+
'{"ic_data_rdata_i", 0, "LineSizeECC", ibex_pkg::IC_NUM_WAYS, 0},
246+
'{"ic_scr_key_valid_i", 1, "", 0, 0},
247+
'{"ic_scr_key_req_o", 1, "", 0, 0},
248+
'{"irq_software_i", 1, "", 0, 0},
249+
'{"irq_timer_i", 1, "", 0, 0},
250+
'{"irq_external_i", 1, "", 0, 0},
251+
'{"irq_fast_i", 15, "", 0, 0},
252+
'{"irq_nm_i", 1, "", 0, 0},
253+
'{"irq_pending_o", 1, "", 0, 0},
254+
'{"debug_req_i", 1, "", 0, 0},
255+
'{"crash_dump_o", $bits(ibex_pkg::crash_dump_t), "", 0, 0},
256+
'{"double_fault_seen_o", 1, "", 0, 0},
258257
// `fetch_enable_i` is a multi-bit signal, and multi-bit FI is outside the threat model.
259-
// '{"fetch_enable_i", 1, "", 0},
258+
// '{"fetch_enable_i", 1, "", 0, 0},
260259
// The `alert_*` output signals are not compared between the regular core and the lockstep
261260
// core. Thus, those outputs are not protected against glitches. This is intentional because
262261
// an alert is raised in reaction to a glitch (potentially an injected fault) inside the core.
263262
// To then also glitch the `alert_*` outputs, the attacker would need to be able to glitch two
264263
// signals at the same time, which is outside the threat model. Thus, these signals are
265264
// excluded from the list of outputs in order to prevent false negative test results.
266-
// '{"alert_minor_o", 1, "", 0},
267-
// '{"alert_major_internal_o", 1, "", 0},
268-
// '{"alert_major_bus_o", 1, "", 0},
269-
'{"core_busy_o", 1, "", 0}
265+
// '{"alert_minor_o", 1, "", 0, 0},
266+
// '{"alert_major_internal_o", 1, "", 0, 0},
267+
// '{"alert_major_bus_o", 1, "", 0, 0},
268+
'{"core_busy_o", 1, "", 0, 0}
270269
};
271270

271+
glitch_lockstep_core = $urandom_range(1);
272+
// The main core uses a register file data width of RegFileDataWidth and the
273+
// shadow core uses RegFileDataEccWidth. Assemble the ports array
274+
// accordingly.
275+
if (glitch_lockstep_core) begin
276+
// Although the shadow core drives all RegFileDataEccWidth bits of rf_wdata_wb_ecc_o, only
277+
// bits RegFileDataEccWidth-1:RegFileDataWidth are forwarded to the shadow register file.
278+
// As a fault in the lower bits have no effect, use an offset of RegFileDataWidth.
279+
ports[42] = '{"rf_wdata_wb_ecc_o", 0, "RegFileDataEccWidth", 0, "RegFileDataWidth"};
280+
ports[43] = '{"rf_rdata_a_ecc_i", 0, "RegFileDataEccWidth", 0, 0};
281+
ports[44] = '{"rf_rdata_b_ecc_i", 0, "RegFileDataEccWidth", 0, 0};
282+
end else begin
283+
ports[42] = '{"rf_wdata_wb_ecc_o", 0, "RegFileDataWidth", 0, 0};
284+
ports[43] = '{"rf_rdata_a_ecc_i", 0, "RegFileDataWidth", 0, 0};
285+
ports[44] = '{"rf_rdata_b_ecc_i", 0, "RegFileDataWidth", 0, 0};
286+
end
287+
272288
// Randomly pick a port (of either the lockstep core or the regular core) to glitch.
273289
port_idx = $urandom_range(ports.size() - 1);
274290
if (ports[port_idx].width > 0) begin
@@ -280,7 +296,6 @@ class chip_sw_rv_core_ibex_lockstep_glitch_vseq extends chip_sw_base_vseq;
280296
"Could not obtain port width from parameter value.");
281297
`DV_CHECK_FATAL(port_width > 0, "Read zero port width from parameter value.")
282298
end
283-
glitch_lockstep_core = $urandom_range(1);
284299
glitch_core_path = glitch_lockstep_core ? lockstep_core_path : core_path;
285300
port_name = ports[port_idx].name;
286301
glitch_path = $sformatf("%s.%s", glitch_core_path, port_name);
@@ -296,7 +311,7 @@ class chip_sw_rv_core_ibex_lockstep_glitch_vseq extends chip_sw_base_vseq;
296311
end
297312

298313
// Pick one bit to glitch in the port.
299-
bit_idx = $urandom_range(port_width - 1);
314+
bit_idx = $urandom_range(port_width - 1 - ports[port_idx].offset) + ports[port_idx].offset;
300315

301316
// Wait until the CPU is executing code, except if glitching the I$ scramble key valid port.
302317
// The reason is that the scramble key is provided shortly after reset and then not again until

0 commit comments

Comments
 (0)