Skip to content

Mem intg testing #1907

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 7, 2022
Merged

Mem intg testing #1907

merged 11 commits into from
Nov 7, 2022

Conversation

GregAC
Copy link
Contributor

@GregAC GregAC commented Nov 4, 2022

This is a mix @ctopal's work in #1811 and work I've done. It supersedes #1811

ctopal and others added 6 commits November 4, 2022 20:35
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This will prevent seeing mismatches right at the end of our test.
Before this change, mem_error_test could inject error at the store
instruction in which we finish up the test, resulting with mismatches
with Spike and Ibex on the instructions after finishing.

Also do the same prevention for signature_addr as well, since we also
don't want to corrupt that memory transaction too.

Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
This enables the sequence to corrupt the integrity on write responses
should it choose to.  Previously the driver would always produce correct
integrity.
This enables tests to implement custom test completion handling
rtl/ibex_core.sv Outdated
captured_debug_req <= 1'b0;
end else begin
// Capture when ID stage has emptied out and something occurs that will cause a trap and we
// haven't yet captured
if (~instr_valid_id & (new_debug_req | new_irq | new_nmi) & ~captured_valid) begin
if (~instr_valid_id & (new_debug_req | new_irq | new_nmi | new_nmi_int) & ~captured_valid) begin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 102 [Style: line-length] [line-length]

rtl/ibex_core.sv Outdated
rvfi_ext_stage_debug_req[0] <= '0;
end else if (if_stage_i.instr_valid_id_d & if_stage_i.instr_new_id_d) begin
rvfi_ext_stage_mip[0] <= instr_valid_id | ~captured_valid ? cs_registers_i.mip :
captured_mip;
rvfi_ext_stage_nmi[0] <= instr_valid_id | ~captured_valid ? irq_nm_i :
captured_nmi;
rvfi_ext_stage_nmi_int[0] <= instr_valid_id | ~captured_valid ? id_stage_i.controller_i.irq_nm_int :
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 108 [Style: line-length] [line-length]

end
// Add integrity bits
{req.intg, req.data} = prim_secded_pkg::prim_secded_inv_39_32_enc(req.data);

// If data_was_uninitialized is true then we want to force bad integrity bits: invert the
// correct ones, which we know will break things for the codes we use.
if (p_sequencer.cfg.enable_bad_intg_on_uninit_access &&
data_was_uninitialized) begin
if ((p_sequencer.cfg.enable_bad_intg_on_uninit_access && data_was_uninitialized) || enable_intg_error) begin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 114 [Style: line-length] [line-length]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put enable_int_error on new line.

@@ -221,6 +223,9 @@ module core_ibex_tb_top;
assign dut_if.rf_ren_b = dut.u_ibex_top.u_ibex_core.rf_ren_b;
assign dut_if.rf_rd_a_wb_match = dut.u_ibex_top.u_ibex_core.rf_rd_a_wb_match;
assign dut_if.rf_rd_b_wb_match = dut.u_ibex_top.u_ibex_core.rf_rd_b_wb_match;
assign dut_if.sync_exc_seen = dut.u_ibex_top.u_ibex_core.cs_registers_i.cpuctrlsts_part_q.sync_exc_seen;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [verible-verilog-lint] reported by reviewdog 🐶
Line length exceeds max: 100; is: 109 [Style: line-length] [line-length]

This test picks between inserting an integrity error or a bus error
to the response in the case of a memory request from Ibex. Introduces
a control knob `enable_mem_intg_err` which can control the rate of
having integrity errors per request.

This commit also disables checking for double fault alerts in the
scoreboard because they're expected to be seen while simulating and
they don't cause infinite loop problems because every time a memory
response is requested the error causing part is just randomized.
That means Ibex trying to execute same instruction again would have
a chance to succeed this time.

Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
@GregAC GregAC mentioned this pull request Nov 5, 2022
15 tasks
@GregAC GregAC force-pushed the mem_intg_testing branch 3 times, most recently from 7f9e142 to a279618 Compare November 6, 2022 12:07
This commit is mainly an extension to cosim environment to drive the newly
introduced state variable `nmi_int` in Spike.

This commit
 - Extends RVFI interface by a single bit (ext_nmi_int)
 - Configures cosim to set nmi_int inside Spike

Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
Signed-off-by: Canberk Topal <ctopal@lowrisc.org>
When Ibex does a load that receives data with bad integrity it
suppresses the write to the destination register. The implements
matching functionality for cosim.
Copy link
Contributor

@ctopal ctopal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@GregAC GregAC merged commit 7592bb9 into lowRISC:master Nov 7, 2022
@GregAC GregAC deleted the mem_intg_testing branch November 7, 2022 16:24
Comment on lines +66 to +67
stop_seq = 1'b0;
seq_finished = 1'b0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Squash this one and the first commit?

end
// Add integrity bits
{req.intg, req.data} = prim_secded_pkg::prim_secded_inv_39_32_enc(req.data);

// If data_was_uninitialized is true then we want to force bad integrity bits: invert the
// correct ones, which we know will break things for the codes we use.
if (p_sequencer.cfg.enable_bad_intg_on_uninit_access &&
data_was_uninitialized) begin
if ((p_sequencer.cfg.enable_bad_intg_on_uninit_access && data_was_uninitialized) || enable_intg_error) begin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put enable_int_error on new line.

+instr_cnt=10000
+randomize_csr=1
+enable_unaligned_load_store=1
+suppress_pmp_setup=1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the disable_pmp_exception_handler routine?

@@ -376,6 +377,12 @@ bool SpikeCosim::check_sync_trap(uint32_t write_reg,
return false;
}

// If we see an internal NMI, that means we receive an extra memory intf item.
// Deleting that is necessary since next Load/Store would fail otherwise.
if (processor->get_state()->mcause->read() == 0xFFFFFFE0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we check the nmi_int value instead of mcause?

Comment on lines +298 to +302
if (suppress_reg_write) {
// If we suppressed a register write restore the old register state now
processor->get_state()->XPR.write(suppressed_write_reg,
suppressed_write_reg_data);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a way to stop the write in the first place instead of undoing it?

Comment on lines +968 to +1006
bool SpikeCosim::pc_is_load(uint32_t pc, uint32_t &rd_out) {
uint16_t insn_16;

if (!backdoor_read_mem(pc, 2, reinterpret_cast<uint8_t *>(&insn_16))) {
return false;
}

// C.LW
if ((insn_16 & 0xE003) == 0x4000) {
rd_out = ((insn_16 >> 2) & 0x7) + 8;
return true;
}

// C.LWSP
if ((insn_16 & 0xE003) == 0x4002) {
rd_out = (insn_16 >> 7) & 0x1F;
return rd_out != 0;
}

uint16_t insn_32;

if (!backdoor_read_mem(pc, 4, reinterpret_cast<uint8_t *>(&insn_32))) {
return false;
}

// LB/LH/LW/LBU/LHU
if ((insn_32 & 0x7F) == 0x3) {
uint32_t func = (insn_32 >> 12) & 0x7;
if ((func == 0x3) || (func == 0x6) || (func == 0x7)) {
// Not valid load encodings
return false;
}

rd_out = (insn_32 >> 7) & 0x1F;
return true;
}

return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that this replicates decode logic, although I don't have a concrete alternative in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants