Skip to content

Commit

Permalink
Merged PR 123991: EL2 Mem Interface modports, new double-bit error in…
Browse files Browse the repository at this point in the history
…jection testcase, fix for UVM edge case

Use modports at every port connection point for the EL2 Mem export interface, which resolves #179

Add a new UVM testcase that injects double bit errors into the Mailbox SRAM during a mailbox flow operation and checks the response

Fix for an edge case in a UVM test where response data size (communicated through in-band data payload) is corrupted as part of an error injection test in the uvmf_soc_ifc suite.

Related work items: #519675
  • Loading branch information
calebofearth committed Sep 13, 2023
1 parent 9d5f727 commit ca3b71b
Show file tree
Hide file tree
Showing 20 changed files with 376 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/integration/rtl/caliptra_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module caliptra_top
//TODO update with I3C interface signals

// Caliptra Memory Export Interface
el2_mem_if el2_mem_export,
el2_mem_if.veer_sram_src el2_mem_export,

//SRAM interface for mbox
output logic mbox_sram_cs,
Expand Down
4 changes: 2 additions & 2 deletions src/integration/tb/caliptra_top_tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ caliptra_top caliptra_top_dut (
.uart_rx(uart_loopback),
`endif

.el2_mem_export(el2_mem_export),
.el2_mem_export(el2_mem_export.veer_sram_src),

.ready_for_fuses(ready_for_fuses),
.ready_for_fw_push(ready_for_fw_push),
Expand Down Expand Up @@ -1193,7 +1193,7 @@ caliptra_top_tb_services #(
.cptra_rst_b(cptra_rst_b),

// Caliptra Memory Export Interface
.el2_mem_export (el2_mem_export),
.el2_mem_export (el2_mem_export.veer_sram_sink),

//SRAM interface for mbox
.mbox_sram_cs (mbox_sram_cs ),
Expand Down
2 changes: 1 addition & 1 deletion src/integration/tb/caliptra_top_tb_services.sv
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ module caliptra_top_tb_services
input wire logic cptra_rst_b,

// Caliptra Memory Export Interface
el2_mem_if.top el2_mem_export,
el2_mem_if.veer_sram_sink el2_mem_export,

//SRAM interface for mbox
input wire logic mbox_sram_cs,
Expand Down
2 changes: 1 addition & 1 deletion src/integration/tb/caliptra_veer_sram_export.sv
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module caliptra_veer_sram_export import caliptra_top_tb_pkg::*; #(
// [2] - Single bit, DCCM Error Injection
// [3] - Double bit, DCCM Error Injection
input veer_sram_error_injection_mode_t sram_error_injection_mode,
el2_mem_if.top el2_mem_export
el2_mem_if.veer_sram_sink el2_mem_export
);

//////////////////////////////////////////////////////
Expand Down
33 changes: 26 additions & 7 deletions src/integration/test_suites/caliptra_rt/caliptra_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ volatile caliptra_intr_received_s cptra_intr_rcv = {
flag &= mask; \
csr_set_bits_mstatus(MSTATUS_MIE_BIT_MASK);

#ifndef MY_RANDOM_SEED
#define MY_RANDOM_SEED 17
#endif // MY_RANDOM_SEED


enum gen_in_value {
WDT_CASCADE = 0x0000abab,
Expand Down Expand Up @@ -137,6 +141,10 @@ void caliptra_rt() {
//set NMI vector
lsu_write_32((uintptr_t) (CLP_SOC_IFC_REG_INTERNAL_NMI_VECTOR), (uint32_t) (nmi_handler));

// Initialize rand num generator
VPRINTF(LOW,"\nUsing random seed = %d\n\n", MY_RANDOM_SEED);
srand((uint32_t) MY_RANDOM_SEED);

// Runtime flow -- set ready for RT
soc_ifc_set_flow_status_field(SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_RUNTIME_MASK);

Expand Down Expand Up @@ -328,7 +336,7 @@ void caliptra_rt() {
if (fsm_chk == 0xF) {
if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) {
CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK)
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit after servicing\n");
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (cmd fail) after servicing\n");
} else {
VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n");
SEND_STDOUT_CTRL(0x1);
Expand All @@ -346,7 +354,7 @@ void caliptra_rt() {
}
VPRINTF(MEDIUM, "Triggering FW update reset\n");
//Trigger firmware update reset, new fw will get copied over from ROM
soc_ifc_set_fw_update_reset();
soc_ifc_set_fw_update_reset((uint8_t) (rand() & 0xFF));
}
else if (op.cmd & MBOX_CMD_FIELD_RESP_MASK) {
VPRINTF(MEDIUM, "Received mailbox command (expecting RESP) from SOC! Got 0x%x\n", op.cmd);
Expand Down Expand Up @@ -412,7 +420,6 @@ void caliptra_rt() {
lsu_write_32((uintptr_t) (CLP_MBOX_CSR_MBOX_DLEN), temp);

// Write response data
srand((uint32_t) (op.cmd ^ read_data)); // Initialize rand num generator
for (loop_iter = 0; loop_iter<temp; loop_iter+=4) {
lsu_write_32((uintptr_t) (CLP_MBOX_CSR_MBOX_DATAIN), rand());
}
Expand All @@ -424,7 +431,7 @@ void caliptra_rt() {
if (fsm_chk == 0xF) {
if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) {
CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK)
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit after servicing\n");
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (cmd fail) after servicing\n");
} else {
VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n");
SEND_STDOUT_CTRL(0x1);
Expand All @@ -433,7 +440,13 @@ void caliptra_rt() {
}
continue;
}
soc_ifc_set_mbox_status_field(DATA_READY);
if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) {
CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK)
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (ECC unc) after servicing\n");
soc_ifc_set_mbox_status_field(CMD_FAILURE);
} else {
soc_ifc_set_mbox_status_field(DATA_READY);
}
}
else {
VPRINTF(MEDIUM, "Received mailbox command (no expected RESP) from SOC! Got 0x%x\n", op.cmd);
Expand All @@ -460,7 +473,7 @@ void caliptra_rt() {
if (fsm_chk == 0xF) {
if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) {
CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK)
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit after servicing\n");
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (cmd fail) after servicing\n");
} else {
VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n");
SEND_STDOUT_CTRL(0x1);
Expand All @@ -470,7 +483,13 @@ void caliptra_rt() {
continue;
}
//Mark the command complete
soc_ifc_set_mbox_status_field(CMD_COMPLETE);
if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) {
CLEAR_INTR_FLAG_SAFELY(cptra_intr_rcv.soc_ifc_error, ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK)
VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit (ECC unc) after servicing\n");
soc_ifc_set_mbox_status_field(CMD_FAILURE);
} else {
soc_ifc_set_mbox_status_field(CMD_COMPLETE);
}
}
}
if (cptra_intr_rcv.soc_ifc_notif & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK) {
Expand Down
13 changes: 11 additions & 2 deletions src/integration/test_suites/libs/soc_ifc/soc_ifc.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,18 @@ void soc_ifc_fw_update(mbox_op_s op) {
}
}

void soc_ifc_set_fw_update_reset() {
VPRINTF(MEDIUM,"SOC_IFC: Set fw update reset\n");
void soc_ifc_set_fw_update_reset(uint8_t wait_cycles) {
uint32_t reg;
VPRINTF(MEDIUM,"SOC_IFC: Set fw update reset with wait_cycles [%d] (%s)\n", wait_cycles, wait_cycles > 5 ? "will override" : wait_cycles > 0 ? "will use default 5" : "won't override");
// A 0-value argument means don't override the current value
if (wait_cycles) {
// Enforce minimum wait_cycles of 5
if (wait_cycles > 5) {
lsu_write_32(CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES, wait_cycles);
} else {
lsu_write_32(CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_WAIT_CYCLES, 5);
}
}
reg = lsu_read_32(CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET);
reg = (reg | SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_CORE_RST_MASK);
lsu_write_32(CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET,reg);
Expand Down
2 changes: 1 addition & 1 deletion src/integration/test_suites/libs/soc_ifc/soc_ifc.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ uint8_t soc_ifc_chk_execute_uc();
void soc_ifc_set_mbox_status_field(enum mbox_status_e field);
void soc_ifc_set_flow_status_field(uint32_t field);
void soc_ifc_clr_flow_status_field(uint32_t field);
void soc_ifc_set_fw_update_reset();
void soc_ifc_set_fw_update_reset(uint8_t wait_cycles);
inline void soc_ifc_set_iccm_lock() {
lsu_write_32((CLP_SOC_IFC_REG_INTERNAL_ICCM_LOCK), SOC_IFC_REG_INTERNAL_ICCM_LOCK_LOCK_MASK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_SMALL,
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_MEDIUM,
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_SMALL,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_MEDIUM,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_LARGE,
IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT,
IDX_SOC_IFC_ENV_RST_WARM,
IDX_SOC_IFC_ENV_RST_COLD,
Expand Down Expand Up @@ -109,6 +112,9 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_SMALL := 200,
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_MEDIUM := 200,
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE := 20,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_SMALL := 200,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_MEDIUM := 200,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_LARGE := 10,
IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT := 200,
IDX_SOC_IFC_ENV_RST_WARM := 100,
IDX_SOC_IFC_ENV_RST_COLD := 100,
Expand All @@ -131,6 +137,7 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
IDX_SOC_IFC_ENV_MBOX_DLEN_OVERFLOW_LARGE,
IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_LARGE,
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE,
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_LARGE,
IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT});
}
constraint iter_count_c {
Expand Down Expand Up @@ -346,6 +353,12 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base;
obj = soc_ifc_env_mbox_reg_axs_invalid_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE:
obj = soc_ifc_env_mbox_reg_axs_invalid_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_SMALL:
obj = soc_ifc_env_mbox_sram_double_bit_flip_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_MEDIUM:
obj = soc_ifc_env_mbox_sram_double_bit_flip_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_2BIT_FLIP_LARGE:
obj = soc_ifc_env_mbox_sram_double_bit_flip_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT:
// TODO PAUSER init first?
obj = soc_ifc_env_mbox_rand_multi_agent_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ import uvmf_base_pkg_hdl::*;
.qspi_d_o (/*TODO*/),
.qspi_d_en_o (/*TODO*/),

.el2_mem_export(el2_mem_export),
.el2_mem_export(el2_mem_export.veer_sram_src),

.ready_for_fuses (soc_ifc_subenv_soc_ifc_status_agent_bus.ready_for_fuses ),
.ready_for_fw_push(soc_ifc_subenv_soc_ifc_status_agent_bus.ready_for_fw_push ),
Expand Down Expand Up @@ -346,7 +346,7 @@ import uvmf_base_pkg_hdl::*;
.cptra_rst_b(soc_ifc_subenv_soc_ifc_ctrl_agent_bus.cptra_rst_b ),

// Caliptra Memory Export Interface
.el2_mem_export (el2_mem_export),
.el2_mem_export (el2_mem_export.veer_sram_sink),

//SRAM interface for mbox
.mbox_sram_cs (mbox_sram_cs_stub_inactive ),
Expand Down
22 changes: 19 additions & 3 deletions src/riscv_core/veer_el2/rtl/el2_mem.sv
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,37 @@ import el2_pkg::*;
output logic [pt.ICACHE_NUM_WAYS-1:0] ic_rd_hit,
output logic ic_tag_perr, // Icache Tag parity error

el2_mem_if mem_export,
el2_mem_if.veer_sram_src mem_export,


input logic scan_mode

);

logic active_clk;
el2_mem_if mem_export_local ();
rvoclkhdr active_cg ( .en(1'b1), .l1clk(active_clk), .* );

assign mem_export .clk = clk;
assign mem_export_local.clk = clk;

assign mem_export .iccm_clken = mem_export_local.iccm_clken;
assign mem_export .iccm_wren_bank = mem_export_local.iccm_wren_bank;
assign mem_export .iccm_addr_bank = mem_export_local.iccm_addr_bank;
assign mem_export .iccm_bank_wr_data = mem_export_local.iccm_bank_wr_data;
assign mem_export_local.iccm_bank_dout = mem_export. iccm_bank_dout;

assign mem_export .dccm_clken = mem_export_local.dccm_clken;
assign mem_export .dccm_wren_bank = mem_export_local.dccm_wren_bank;
assign mem_export .dccm_addr_bank = mem_export_local.dccm_addr_bank;
assign mem_export .dccm_wr_data_bank = mem_export_local.dccm_wr_data_bank;
assign mem_export_local.dccm_bank_dout = mem_export .dccm_bank_dout;

// DCCM Instantiation
if (pt.DCCM_ENABLE == 1) begin: Gen_dccm_enable
el2_lsu_dccm_mem #(.pt(pt)) dccm (
.clk_override(dccm_clk_override),
.dccm_mem_export(mem_export.veer_dccm),
.dccm_mem_export(mem_export_local.veer_dccm),
.*
);
end else begin: Gen_dccm_disable
Expand Down Expand Up @@ -121,7 +137,7 @@ if (pt.ICCM_ENABLE) begin : iccm
.clk_override(icm_clk_override),
.iccm_rw_addr(iccm_rw_addr[pt.ICCM_BITS-1:1]),
.iccm_rd_data(iccm_rd_data[63:0]),
.iccm_mem_export(mem_export.veer_iccm)
.iccm_mem_export(mem_export_local.veer_iccm)
);
end
else begin
Expand Down
3 changes: 1 addition & 2 deletions src/riscv_core/veer_el2/rtl/el2_veer_wrapper.sv
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ import soc_ifc_pkg::*;
input logic [31:4] core_id,

// Caliptra Memory Export Interface
el2_mem_if el2_mem_export,
el2_mem_if.veer_sram_src el2_mem_export,

// Caliptra ECC status signals
output logic cptra_iccm_ecc_single_error,
Expand Down Expand Up @@ -710,7 +710,6 @@ import soc_ifc_pkg::*;
.mem_export(el2_mem_export),
.*
);
assign el2_mem_export.clk = active_l2clk;


// JTAG/DMI instance
Expand Down
12 changes: 11 additions & 1 deletion src/riscv_core/veer_el2/rtl/lib/el2_mem_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,17 @@ modport veer_dccm (
input dccm_bank_dout
);

modport top (
modport veer_sram_src (
output clk,
// ICCM
output iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data,
input iccm_bank_dout,
// DCCM
output dccm_clken, dccm_wren_bank, dccm_addr_bank, dccm_wr_data_bank,
input dccm_bank_dout
);

modport veer_sram_sink (
input clk,
// ICCM
input iccm_clken, iccm_wren_bank, iccm_addr_bank, iccm_bank_wr_data,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,15 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base

// If resp data is required, set DATAIN
if (op.cmd.cmd_s.resp_reqd) begin
mbox_push_datain();
if (mbox_resp_expected_dlen == 0) begin
// We should only have 'resp_reqd' and 'exp_dlen == 0' if
// a spurious write triggered MBOX_ERROR and caused us to fail
// on reading back the dataout
mbox_check_fsm();
end
else begin
mbox_push_datain();
end
end

// Set STATUS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ task soc_ifc_env_mbox_sequence_base::mbox_poll_status();
end
else if (data == CMD_FAILURE) begin
if (sts_rsp_count > 0 && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) begin
`uvm_info("MBOX_SEQ", $sformatf("Unexpected mailbox status [%p] likely is the result of a spurious reg access injection specifically intended to cause a protocol violation", data), UVM_HIGH)
`uvm_info("MBOX_SEQ", $sformatf("Unexpected mailbox status [%p] likely is the result of a spurious reg access injection specifically intended to cause a protocol violation or a mailbox SRAM double bit flip", data), UVM_HIGH)
end
else begin
`uvm_error("MBOX_SEQ", $sformatf("Received mailbox status %p unexpectedly, since there is no pending non_fatal error interrupt", data))
Expand Down Expand Up @@ -599,7 +599,7 @@ task soc_ifc_env_mbox_sequence_base::mbox_clr_execute();

if (rand_delay_en) do_rand_delay(1, step_delay);

// Check for any non-fatal mailbox protocol errors that occurred during the test
// Check for any non-fatal mailbox protocol or sram errors that occurred during the test
reg_model.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.read(reg_sts, err, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(get_rand_user(500)));
// don't use report_reg_sts since this isn't a mbox reg and doesn't have pauser requirements
if (reg_sts != UVM_IS_OK) begin
Expand Down
Loading

0 comments on commit ca3b71b

Please sign in to comment.