From 3c2065019790c2361aea9cd3eab74f16cb66217e Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Mon, 20 Nov 2023 11:04:04 +0100 Subject: [PATCH 01/16] fix compilation Signed-off-by: Robin Pedersen --- .../uvmt_cv32e40s_pmp_assert.sv | 0 .../uvmt_cv32e40s_pmprvfi_assert.sv | 0 .../uvmt_cv32e40s_umode_assert.sv | 20 ++--- .../uvmt_cv32e40s_umode_cov.sv | 0 tb/uvmt/uvmt_cv32e40s_tb.sv | 88 +++++++++++-------- tb/uvmt/uvmt_cv32e40s_tb_files.flist | 28 +++--- 6 files changed, 73 insertions(+), 63 deletions(-) rename tb/{uvmt => assertions}/uvmt_cv32e40s_pmp_assert.sv (100%) rename tb/{uvmt => assertions}/uvmt_cv32e40s_pmprvfi_assert.sv (100%) rename tb/{uvmt => assertions}/uvmt_cv32e40s_umode_assert.sv (98%) rename tb/{uvmt => assertions}/uvmt_cv32e40s_umode_cov.sv (100%) diff --git a/tb/uvmt/uvmt_cv32e40s_pmp_assert.sv b/tb/assertions/uvmt_cv32e40s_pmp_assert.sv similarity index 100% rename from tb/uvmt/uvmt_cv32e40s_pmp_assert.sv rename to tb/assertions/uvmt_cv32e40s_pmp_assert.sv diff --git a/tb/uvmt/uvmt_cv32e40s_pmprvfi_assert.sv b/tb/assertions/uvmt_cv32e40s_pmprvfi_assert.sv similarity index 100% rename from tb/uvmt/uvmt_cv32e40s_pmprvfi_assert.sv rename to tb/assertions/uvmt_cv32e40s_pmprvfi_assert.sv diff --git a/tb/uvmt/uvmt_cv32e40s_umode_assert.sv b/tb/assertions/uvmt_cv32e40s_umode_assert.sv similarity index 98% rename from tb/uvmt/uvmt_cv32e40s_umode_assert.sv rename to tb/assertions/uvmt_cv32e40s_umode_assert.sv index fa86e3469..67dd3cff7 100644 --- a/tb/uvmt/uvmt_cv32e40s_umode_assert.sv +++ b/tb/assertions/uvmt_cv32e40s_umode_assert.sv @@ -932,21 +932,21 @@ module uvmt_cv32e40s_umode_assert // vplan:InstrProt - a_instr_prot: assert property ( + a_rvfi_instr_prot: assert property ( rvfi_valid |-> - (rvfi_if.instr_prot[2:1] == rvfi_if.rvfi_mode) || + (rvfi_if.rvfi_instr_prot[2:1] == rvfi_if.rvfi_mode) || (rvfi_if.rvfi_trap.exception_cause == cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) || (rvfi_trap.debug_cause == DBG_CAUSE_TRIGGER) //Note: Triggers can overshadow access faults ) else `uvm_error(info_tag, "the prot on fetch must match the mode on retirement"); - a_instr_prot_legal: assert property ( + a_rvfi_instr_prot_legal: assert property ( rvfi_valid && (rvfi_if.rvfi_trap.exception_cause != cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) |-> - (rvfi_if.instr_prot[2:0] inside {3'b 000, 3'b 110}) - ) else `uvm_error(info_tag, "instr_prot illegal value"); + (rvfi_if.rvfi_instr_prot[2:0] inside {3'b 000, 3'b 110}) + ) else `uvm_error(info_tag, "rvfi_instr_prot illegal value"); a_prot_iside_legal: assert property ( obi_iside_prot inside {3'b 000, 3'b 110} @@ -959,14 +959,14 @@ module uvmt_cv32e40s_umode_assert rvfi_valid && (rvfi_if.rvfi_mem_rmask || rvfi_if.rvfi_mem_wmask) |-> - (rvfi_if.mem_prot[2:1] == effective_rvfi_privmode) + (rvfi_if.rvfi_mem_prot[2:1] == effective_rvfi_privmode) ) else `uvm_error(info_tag, "the prot on load/store must match the effective mode on retirement"); a_data_prot_legal: assert property ( rvfi_valid && (rvfi_if.rvfi_trap.exception_cause != cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) |-> - (rvfi_if.mem_prot[2:0] inside {3'b 001, 3'b 111}) + (rvfi_if.rvfi_mem_prot[2:0] inside {3'b 001, 3'b 111}) ) else `uvm_error(info_tag, "data_prot illegal value"); a_prot_dside_legal: assert property ( @@ -977,7 +977,7 @@ module uvmt_cv32e40s_umode_assert logic [NMEM-1:0] mem_act; for (genvar i = 0; i < NMEM; i++) begin: gen_data_prot_equals always_comb begin - data_prot_equals[i] = (rvfi_if.mem_prot[i*3+:3] == rvfi_if.mem_prot[2:0]); + data_prot_equals[i] = (rvfi_if.rvfi_mem_prot[i*3+:3] == rvfi_if.rvfi_mem_prot[2:0]); mem_act[i] = |rvfi_if.check_mem_act(i); end end @@ -1008,7 +1008,7 @@ module uvmt_cv32e40s_umode_assert rvfi_if.rvfi_valid && rvfi_if.rvfi_dbg_mode |-> - (rvfi_if.instr_prot[2:1] == MODE_M) || + (rvfi_if.rvfi_instr_prot[2:1] == MODE_M) || (rvfi_if.rvfi_trap.exception_cause == cv32e40s_pkg::EXC_CAUSE_INSTR_FAULT) ) else `uvm_error(info_tag, "dmode should fetch as mmode"); @@ -1017,7 +1017,7 @@ module uvmt_cv32e40s_umode_assert rvfi_valid && (|rvfi_if.rvfi_mem_rmask || |rvfi_if.rvfi_mem_wmask) |-> - (rvfi_if.mem_prot[2:1] == effective_rvfi_privmode) + (rvfi_if.rvfi_mem_prot[2:1] == effective_rvfi_privmode) ) else `uvm_error(info_tag, "dmode should fetch as effective mode"); diff --git a/tb/uvmt/uvmt_cv32e40s_umode_cov.sv b/tb/assertions/uvmt_cv32e40s_umode_cov.sv similarity index 100% rename from tb/uvmt/uvmt_cv32e40s_umode_cov.sv rename to tb/assertions/uvmt_cv32e40s_umode_cov.sv diff --git a/tb/uvmt/uvmt_cv32e40s_tb.sv b/tb/uvmt/uvmt_cv32e40s_tb.sv index 84a5619b3..474a5f623 100644 --- a/tb/uvmt/uvmt_cv32e40s_tb.sv +++ b/tb/uvmt/uvmt_cv32e40s_tb.sv @@ -164,45 +164,55 @@ module uvmt_cv32e40s_tb; // "rvfi_instr_if" bind cv32e40s_wrapper - uvma_rvfi_instr_if_t#(uvmt_cv32e40s_base_test_pkg::ILEN, - uvmt_cv32e40s_base_test_pkg::XLEN) rvfi_instr_if(.clk(clk_i), - .reset_n(rst_ni), - - .rvfi_valid(rvfi_i.rvfi_valid[0]), - .rvfi_order(rvfi_i.rvfi_order[uvma_rvfi_pkg::ORDER_WL*0+:uvma_rvfi_pkg::ORDER_WL]), - .rvfi_insn(rvfi_i.rvfi_insn[uvmt_cv32e40s_base_test_pkg::ILEN*0+:uvmt_cv32e40s_base_test_pkg::ILEN]), - .rvfi_trap(rvfi_i.rvfi_trap), - .rvfi_halt(rvfi_i.rvfi_halt[0]), - .rvfi_intr(rvfi_i.rvfi_intr), - .rvfi_dbg(rvfi_i.rvfi_dbg), - .rvfi_dbg_mode(rvfi_i.rvfi_dbg_mode), - .rvfi_nmip(rvfi_i.rvfi_nmip), - .rvfi_mode(rvfi_i.rvfi_mode[uvma_rvfi_pkg::MODE_WL*0+:uvma_rvfi_pkg::MODE_WL]), - .rvfi_ixl(rvfi_i.rvfi_ixl[uvma_rvfi_pkg::IXL_WL*0+:uvma_rvfi_pkg::IXL_WL]), - .rvfi_pc_rdata(rvfi_i.rvfi_pc_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_pc_wdata(rvfi_i.rvfi_pc_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs1_addr(rvfi_i.rvfi_rs1_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rs1_rdata(rvfi_i.rvfi_rs1_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs2_addr(rvfi_i.rvfi_rs2_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rs2_rdata(rvfi_i.rvfi_rs2_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rs3_addr('0), - .rvfi_rs3_rdata('0), - .rvfi_rd1_addr(rvfi_i.rvfi_rd_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), - .rvfi_rd1_wdata(rvfi_i.rvfi_rd_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_rd2_addr('0), - .rvfi_rd2_wdata('0), - .rvfi_gpr_rdata(rvfi_i.rvfi_gpr_rdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_gpr_rmask(rvfi_i.rvfi_gpr_rmask[32*0 +:32]), - .rvfi_gpr_wdata(rvfi_i.rvfi_gpr_wdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_gpr_wmask(rvfi_i.rvfi_gpr_wmask[32*0 +:32]), - .rvfi_mem_addr(rvfi_i.rvfi_mem_addr[ uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_rdata(rvfi_i.rvfi_mem_rdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_rmask(rvfi_i.rvfi_mem_rmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), - .rvfi_mem_wdata(rvfi_i.rvfi_mem_wdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), - .rvfi_mem_wmask(rvfi_i.rvfi_mem_wmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), - .instr_prot(rvfi_i.rvfi_instr_prot), - .mem_prot(rvfi_i.rvfi_mem_prot) - ); + uvma_rvfi_instr_if_t#( + uvmt_cv32e40s_base_test_pkg::ILEN, + uvmt_cv32e40s_base_test_pkg::XLEN + ) rvfi_instr_if( + .clk (clk_i), + .reset_n (rst_ni), + + .rvfi_valid (rvfi_i.rvfi_valid[0]), + .rvfi_order (rvfi_i.rvfi_order[uvma_rvfi_pkg::ORDER_WL*0+:uvma_rvfi_pkg::ORDER_WL]), + .rvfi_insn (rvfi_i.rvfi_insn[uvmt_cv32e40s_base_test_pkg::ILEN*0+:uvmt_cv32e40s_base_test_pkg::ILEN]), + .rvfi_trap (rvfi_i.rvfi_trap), + .rvfi_halt (rvfi_i.rvfi_halt[0]), + .rvfi_intr (rvfi_i.rvfi_intr), + .rvfi_dbg (rvfi_i.rvfi_dbg), + .rvfi_dbg_mode (rvfi_i.rvfi_dbg_mode), + .rvfi_nmip (rvfi_i.rvfi_nmip), + .rvfi_mode (rvfi_i.rvfi_mode[uvma_rvfi_pkg::MODE_WL*0+:uvma_rvfi_pkg::MODE_WL]), + .rvfi_ixl (rvfi_i.rvfi_ixl[uvma_rvfi_pkg::IXL_WL*0+:uvma_rvfi_pkg::IXL_WL]), + .rvfi_pc_rdata (rvfi_i.rvfi_pc_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_pc_wdata (rvfi_i.rvfi_pc_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs1_addr (rvfi_i.rvfi_rs1_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rs1_rdata (rvfi_i.rvfi_rs1_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs2_addr (rvfi_i.rvfi_rs2_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rs2_rdata (rvfi_i.rvfi_rs2_rdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rs3_addr ('0), + .rvfi_rs3_rdata ('0), + .rvfi_rd1_addr (rvfi_i.rvfi_rd_addr[uvma_rvfi_pkg::GPR_ADDR_WL*0+:uvma_rvfi_pkg::GPR_ADDR_WL]), + .rvfi_rd1_wdata (rvfi_i.rvfi_rd_wdata[uvmt_cv32e40s_base_test_pkg::XLEN*0+:uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_rd2_addr ('0), + .rvfi_rd2_wdata ('0), + .rvfi_gpr_rdata (rvfi_i.rvfi_gpr_rdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_gpr_rmask (rvfi_i.rvfi_gpr_rmask[32*0 +:32]), + .rvfi_gpr_wdata (rvfi_i.rvfi_gpr_wdata[32*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:32*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_gpr_wmask (rvfi_i.rvfi_gpr_wmask[32*0 +:32]), + .rvfi_mem_addr (rvfi_i.rvfi_mem_addr[ uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_rdata (rvfi_i.rvfi_mem_rdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_rmask (rvfi_i.rvfi_mem_rmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), + .rvfi_mem_wdata (rvfi_i.rvfi_mem_wdata[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN]), + .rvfi_mem_wmask (rvfi_i.rvfi_mem_wmask[uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8*0 +:uvma_rvfi_pkg::NMEM*uvmt_cv32e40s_base_test_pkg::XLEN/8]), + .rvfi_instr_prot (rvfi_i.rvfi_instr_prot), + .rvfi_instr_memtype (rvfi_i.rvfi_instr_memtype), + .rvfi_instr_dbg (rvfi_i.rvfi_instr_dbg), + .rvfi_mem_prot (rvfi_i.rvfi_mem_prot), + .rvfi_mem_exokay (rvfi_i.rvfi_mem_exokay), + .rvfi_mem_err (rvfi_i.rvfi_mem_err), + .rvfi_mem_atop (rvfi_i.rvfi_mem_atop), + .rvfi_mem_memtype (rvfi_i.rvfi_mem_memtype), + .rvfi_mem_dbg (rvfi_i.rvfi_mem_dbg) + ); // RVFI CSR binds `RVFI_CSR_BIND(cpuctrl) diff --git a/tb/uvmt/uvmt_cv32e40s_tb_files.flist b/tb/uvmt/uvmt_cv32e40s_tb_files.flist index f73eec0cb..7aeba8124 100644 --- a/tb/uvmt/uvmt_cv32e40s_tb_files.flist +++ b/tb/uvmt/uvmt_cv32e40s_tb_files.flist @@ -18,39 +18,39 @@ ${DV_UVMT_PATH}/uvmt_cv32e40s_dut_wrap.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_tb.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_fencei_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmp_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmprvfi_assert.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_umode_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_clic_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_debug_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_triggers_assert_cov.sv -${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_fencei_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_integration_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_pma_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_pmp_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_pmprvfi_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_rvfi_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_umode_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_triggers_assert_cov.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_bus_protocol_hardening_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_data_independent_timing_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_reduced_profiling_infrastructure_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_clic_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_interrupt_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_csrs_pmp_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_hardened_pc_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_interface_integrity_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_dummy_and_hint_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_bus_protocol_hardening_assert.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_security_alerts_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_reduced_profiling_infrastructure_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_register_file_ecc_assert.sv +${DV_UVMT_PATH}/uvmt_cv32e40s_xsecure_assert/uvmt_cv32e40s_xsecure_security_alerts_assert.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_zc_assert.sv ${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pma_model.sv ${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_pmp_model.sv -${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_obi_phases_monitor.sv +${DV_UVMT_PATH}/../assertions/uvmt_cv32e40s_umode_cov.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_rchk_shim.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_fifo.sv -${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match_mem.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_obi_phases_monitor.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match.sv +${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_sl_trigger_match_mem.sv ${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_support_logic.sv -${DV_UVMT_PATH}/support_logic/uvmt_cv32e40s_rchk_shim.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_pma_cov.sv ${DV_UVMT_PATH}/uvmt_cv32e40s_rvfi_cov.sv -${DV_UVMT_PATH}/uvmt_cv32e40s_umode_cov.sv From 68823bb665a3e2159d9c0e8690aa8dd2419b2d1a Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Thu, 30 Nov 2023 23:07:04 +0100 Subject: [PATCH 02/16] counter test Signed-off-by: Kristine Dosvik --- .../mhpmcounter_write_test.c | 241 ++++++++++++++++++ .../custom/mhpmcounter_write_test/test.yaml | 4 + 2 files changed, 245 insertions(+) create mode 100644 tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c create mode 100644 tests/programs/custom/mhpmcounter_write_test/test.yaml diff --git a/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c new file mode 100644 index 000000000..9e8b61455 --- /dev/null +++ b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c @@ -0,0 +1,241 @@ +// Copyright 2023 Silicon Labs, Inc. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may +// not use this file except in compliance with the License, or, at your option, +// the Apache License version 2.0. +// +// You may obtain a copy of the License at +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +int write_mhpmcounters() +{ + uint32_t reg = 0; + __asm__ volatile("mv %0, x0" : "=r"(reg)); + __asm__ volatile("not %0, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB03, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB04, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB05, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB06, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB07, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB08, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB09, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0A, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0B, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0C, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0D, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0E, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB0F, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB10, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB11, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB12, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB13, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB14, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB15, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB16, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB17, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB18, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB19, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1A, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1B, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1C, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1D, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1E, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB1F, %0" :: "r"(reg)); + + return 0; +} + +int write_mhpmcounterhs() +{ + uint32_t reg = 0; + __asm__ volatile("csrrs x0, 0xB83, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB84, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB85, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB86, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB87, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB88, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB89, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8A, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8B, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8C, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8D, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8E, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB8F, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB90, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB91, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB92, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB93, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB94, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB95, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB96, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB97, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB98, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB99, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9A, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9B, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9C, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9D, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9E, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, 0xB9F, %0" :: "r"(reg)); + + return 0; +} + +int check_mhpmcounters_are_zero() +{ + uint32_t reg = 0; + __asm__ volatile("csrr %0, 0xB03" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB04" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB05" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB06" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB07" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB08" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB09" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0A" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0B" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0C" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0D" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0E" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB0F" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB10" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB11" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB12" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB13" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB14" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB15" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB16" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB17" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB18" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB19" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1A" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1B" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1C" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1D" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1E" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB1F" : "=r"(reg)); + if(reg != 0) return 1; + + return 0; +} + +int check_mhpmcounterhs_are_zero() +{ + uint32_t reg = 0; + __asm__ volatile("csrr %0, 0xB83" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB84" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB85" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB86" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB87" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB88" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB89" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8A" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8B" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8C" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8D" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8E" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB8F" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB90" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB91" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB92" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB93" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB94" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB95" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB96" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB97" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB98" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB99" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9A" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9B" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9C" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9D" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9E" : "=r"(reg)); + if(reg != 0) return 1; + __asm__ volatile("csrr %0, 0xB9F" : "=r"(reg)); + if(reg != 0) return 1; + + return 0; +} + + +int main() +{ + uint32_t is_failure = 0; + + write_mhpmcounters(); + write_mhpmcounterhs(); + + is_failure += check_mhpmcounters_are_zero(); + is_failure += check_mhpmcounterhs_are_zero(); + + if (is_failure) return EXIT_FAILURE; + return EXIT_SUCCESS; + +} diff --git a/tests/programs/custom/mhpmcounter_write_test/test.yaml b/tests/programs/custom/mhpmcounter_write_test/test.yaml new file mode 100644 index 000000000..9f061158d --- /dev/null +++ b/tests/programs/custom/mhpmcounter_write_test/test.yaml @@ -0,0 +1,4 @@ +name: mhpmcounter_write_test +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Write to mhpmcounters. Is only verifyed by ISS, should be verifyed that we get excpected behaviour? From 6e075671f23bcec5518b5e003f35fdbc510f1d13 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Thu, 30 Nov 2023 23:10:07 +0100 Subject: [PATCH 03/16] add to regression Signed-off-by: Kristine Dosvik --- regress/cv32e40s_full.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/regress/cv32e40s_full.yaml b/regress/cv32e40s_full.yaml index 66ba231d9..b00d1cc98 100644 --- a/regress/cv32e40s_full.yaml +++ b/regress/cv32e40s_full.yaml @@ -576,3 +576,10 @@ tests: builds: [ uvmt_cv32e40s_clic ] dir: cv32e40s/sim/uvmt cmd: make test TEST=zcmt_test + + mhpmcounter_write_test: + description: test writing to mhpm counters + builds: [ uvmt_cv32e40s ] + dir: cv32e40s/sim/uvmt + cmd: make test TEST=mhpmcounter_write_test + From da26c6a817a97503eba363299fda9b827cd1f0da Mon Sep 17 00:00:00 2001 From: Marton Teilgard Date: Fri, 1 Dec 2023 11:23:17 +0100 Subject: [PATCH 04/16] updated latest link2cov Signed-off-by: Marton Teilgard --- .../Zc/RV32Zc_Extension_Instructions.csv | 2 +- .../Zc/RV32Zc_Extension_Instructions.json | 2 +- .../Zc/RV32Zc_Extension_Instructions.xlsx | Bin 308036 -> 307818 bytes .../Simulation/interrupts/CV32E40SX_CLIC.csv | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.json | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.xlsx | Bin 39023 -> 38990 bytes .../CV32E40SX_PMA_VerifPlan.csv | 2 +- .../CV32E40SX_PMA_VerifPlan.json | 4 ++-- .../CV32E40SX_PMA_VerifPlan.xlsx | Bin 31338 -> 31369 bytes 9 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv b/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv index 4ebef3b9c..715c024e6 100644 --- a/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv +++ b/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.csv @@ -153,7 +153,7 @@ Note: Deprioritize as this is furthest from ratification ",cm.jt,jump via table without link,Verify all possible variations of index,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,"Verify interrupts(maskable and non-maskable), debug and single stepping can not stop execution after the instruction has started to change state. Make sure external interrupts happen at all stages of execution. Expect atomic execution",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.controller_i.controller_fsm_i.controller_fsm_sva.a_no_sequence_interrupt,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,,,Verify all table jump-related fetches are checked by PMP/PMA. Specifically break/follow the rules for both systems,Check against ISS,Directed Non-Self-Checking,Testcase,"Coverage hole, evaluate priority",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,Verify all table jump-related fetches are checked by PMP/PMA. Specifically break/follow the rules for both systems,Check against ISS,Directed Non-Self-Checking,Testcase,DTC: zcmt_test,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,cm.jalt,jump via table and link to ra,Verify all possible variations of index,Check against ISS,Constrained-Random,Functional Coverage,"Imperas generated coverage, hierarchy path: uvmt_cv32e40s_tb.imperas_dv.idv_trace2cov.cov_1.obj_[instr]",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,"Verify interrupts(maskable and non-maskable), debug and single stepping can not stop execution after the instruction has started to change state. Make sure external interrupts happen at all stages of execution. Expect atomic execution",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.controller_i.controller_fsm_i.controller_fsm_sva.a_no_sequence_interrupt,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json b/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json index 40230e39d..b58b9d3ce 100644 --- a/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json +++ b/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.json @@ -656,7 +656,7 @@ "Pass/Fail Criteria": "Check against ISS", "Test Type": "Directed Non-Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "Coverage hole, evaluate priority", + "Link to Coverage": "DTC: zcmt_test", "": "" }, { diff --git a/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx b/docs/VerifPlans/Simulation/Zc/RV32Zc_Extension_Instructions.xlsx index 18948feb0732fed1c37293ad077e6d65caac1464..c1dccad2071983b0598f37001ab8d49072ee5da8 100644 GIT binary patch delta 56446 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 diff --git a/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv b/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv index b73b1938c..55569d0bc 100644 --- a/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv +++ b/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.csv @@ -319,7 +319,7 @@ COV: *.pma_cov_data_i.gen_rvfi_cg.cover_item_covergroup_cg_rvfi_inst_rvfi_cg_cro COV: *.pma_cov_instr_i.cover_item_covergroup_cg_mpu_inst_mpu_cg_cross_x_allow_jvt_*","TODO missing random test? Note: This is not maximally comprehensive, but the modelling that would otherwise be required is disproportionately complex." -Zce spec. proposal,,,"Instruction fetch exceptions occurring when executing an address in the jump table should lead to mepc being set to the C.TBLJ* instruction, and mtval to the address in the jump table entry",Verify that an instruction fetch exception resulting from a jump table entry leads to mepc being set to the C.TBLJ* instruction and mtval to the address in the jump table entry.,Self Checking Test,Directed Self-Checking,Testcase,DTC: TODO,TODO missing directed test? +Zce spec. proposal,,,"Instruction fetch exceptions occurring when executing an address in the jump table should lead to mepc being set to the C.TBLJ* instruction, and mtval to the address in the jump table entry",Verify that an instruction fetch exception resulting from a jump table entry leads to mepc being set to the C.TBLJ* instruction and mtval to the address in the jump table entry.,Self Checking Test,Directed Self-Checking,Testcase,Covered in Zc verif plan, Risc-V Debug spec.,Debug mode,Single step PMA exceptions,"Any instruction fetch exception that occurs while single stepping, causes debug mode to be re-entered after PC is changed to the exception handler and the appropriate tval and cause registers are updated","Verify that instruction fetches to PMA IO regions fails, the appropriate CSRs and PC is updated to the appropriate values and debug mode is reentered. ",Self Checking Test,Directed Self-Checking,Testcase,DTC: cv32e40s/tests/programs/custom/pma_debug/, ,,Program buffer PMA exceptions,Exceptions in the program buffer should cause the program buffer code to end and cmderr set to 3 (exception error),"Verify that program buffer code attempting to fetch instructions from PMA IO region fails, PC is set to dm_exception_addr_i and cmderr is set to 3 (exception error). No other registers should be changed due to this exception.",Self Checking Test,Directed Self-Checking,Testcase,DTC: cv32e40s/tests/programs/custom/pma_debug/, 40s UM 0.8.0,DebugRange,DebugRange,"""CV32E40S overrules the PMA and PMP settings for the Debug Module region when it is in debug mode""","Attempt access within/outside the dm region, in both dmode/not, check that the combo within/dmode never gets blocked and that the other combos follow the ordinary rules.",Assertion Check,Constrained-Random,Code Coverage,"A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.if_stage_i.mpu_i.pma_assert_instr_i.a_dm_region diff --git a/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json b/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json index 15f4039e8..44b443062 100644 --- a/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json +++ b/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.json @@ -692,8 +692,8 @@ "Pass/Fail Criteria": "Self Checking Test", "Test Type": "Directed Self-Checking", "Coverage Method": "Testcase", - "Link to Coverage": "DTC: TODO", - "Comment": "TODO missing directed test?" + "Link to Coverage": "Covered in Zc verif plan", + "Comment": "" }, { "Requirement Location": "Risc-V Debug spec.", diff --git a/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx b/docs/VerifPlans/Simulation/privileged_spec/CV32E40SX_PMA_VerifPlan.xlsx index d65209864c8622458bcf2acee5d08242fdb44f11..2728600b5b0ecc8ce497c4d8e29fc700bf7c3aa2 100644 GIT binary patch delta 15504 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 LLe0AVN8$efj8v#x From 6492b1b5c7db774a96465ec0c1de71ebeca5c5ed Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 1 Dec 2023 12:50:49 +0100 Subject: [PATCH 05/16] CSR names instead of registers Signed-off-by: Kristine Dosvik --- .../mhpmcounter_write_test.c | 233 +++++++++--------- 1 file changed, 117 insertions(+), 116 deletions(-) diff --git a/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c index 9e8b61455..e11414218 100644 --- a/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c +++ b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c @@ -20,40 +20,41 @@ #include #include + int write_mhpmcounters() { uint32_t reg = 0; __asm__ volatile("mv %0, x0" : "=r"(reg)); __asm__ volatile("not %0, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB03, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB04, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB05, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB06, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB07, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB08, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB09, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0A, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0B, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0C, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0D, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0E, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB0F, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB10, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB11, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB12, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB13, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB14, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB15, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB16, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB17, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB18, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB19, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1A, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1B, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1C, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1D, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1E, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB1F, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter3, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter4, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter5, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter6, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter7, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter8, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter9, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter10, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter11, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter12, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter13, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter14, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter15, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter16, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter17, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter18, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter19, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter20, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter21, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter22, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter23, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter24, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter25, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter26, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter27, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter28, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter29, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter30, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter31, %0" :: "r"(reg)); return 0; } @@ -61,35 +62,35 @@ int write_mhpmcounters() int write_mhpmcounterhs() { uint32_t reg = 0; - __asm__ volatile("csrrs x0, 0xB83, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB84, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB85, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB86, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB87, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB88, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB89, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8A, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8B, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8C, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8D, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8E, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB8F, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB90, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB91, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB92, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB93, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB94, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB95, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB96, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB97, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB98, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB99, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9A, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9B, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9C, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9D, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9E, %0" :: "r"(reg)); - __asm__ volatile("csrrs x0, 0xB9F, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter3h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter4h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter5h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter6h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter7h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter8h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter9h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter10h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter11h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter12h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter13h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter14h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter15h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter16h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter17h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter18h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter19h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter20h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter21h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter22h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter23h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter24h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter25h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter26h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter27h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter28h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter29h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter30h, %0" :: "r"(reg)); + __asm__ volatile("csrrs x0, mhpmcounter31h, %0" :: "r"(reg)); return 0; } @@ -97,63 +98,63 @@ int write_mhpmcounterhs() int check_mhpmcounters_are_zero() { uint32_t reg = 0; - __asm__ volatile("csrr %0, 0xB03" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter3" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB04" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter4" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB05" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter5" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB06" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter6" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB07" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter7" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB08" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter8" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB09" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter9" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0A" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter10" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0B" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter11" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0C" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter12" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0D" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter13" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0E" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter14" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB0F" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter15" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB10" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter16" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB11" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter17" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB12" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter18" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB13" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter19" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB14" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter20" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB15" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter21" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB16" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter22" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB17" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter23" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB18" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter24" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB19" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter25" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1A" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter26" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1B" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter27" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1C" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter28" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1D" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter29" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1E" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter30" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB1F" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter31" : "=r"(reg)); if(reg != 0) return 1; return 0; @@ -162,63 +163,63 @@ int check_mhpmcounters_are_zero() int check_mhpmcounterhs_are_zero() { uint32_t reg = 0; - __asm__ volatile("csrr %0, 0xB83" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter3h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB84" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter4h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB85" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter5h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB86" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter6h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB87" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter7h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB88" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter8h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB89" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter9h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8A" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter10h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8B" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter11h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8C" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter12h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8D" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter13h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8E" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter14h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB8F" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter15h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB90" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter16h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB91" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter17h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB92" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter18h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB93" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter19h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB94" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter20h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB95" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter21h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB96" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter22h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB97" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter23h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB98" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter24h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB99" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter25h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9A" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter26h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9B" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter27h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9C" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter28h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9D" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter29h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9E" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter30h" : "=r"(reg)); if(reg != 0) return 1; - __asm__ volatile("csrr %0, 0xB9F" : "=r"(reg)); + __asm__ volatile("csrr %0, mhpmcounter31h" : "=r"(reg)); if(reg != 0) return 1; return 0; From cf317238faea1e0aca1fd320b39cf52f25d26deb Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 1 Dec 2023 13:01:35 +0100 Subject: [PATCH 06/16] change config to clic_default Signed-off-by: Kristine Dosvik --- regress/cv32e40s_full.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regress/cv32e40s_full.yaml b/regress/cv32e40s_full.yaml index b00d1cc98..4ce0a40bd 100644 --- a/regress/cv32e40s_full.yaml +++ b/regress/cv32e40s_full.yaml @@ -579,7 +579,7 @@ tests: mhpmcounter_write_test: description: test writing to mhpm counters - builds: [ uvmt_cv32e40s ] + builds: [ uvmt_cv32e40s_clic ] dir: cv32e40s/sim/uvmt cmd: make test TEST=mhpmcounter_write_test From cf4613aa7324cea310430d3b73179d3dd666b123 Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Fri, 1 Dec 2023 13:38:04 +0100 Subject: [PATCH 07/16] zc_test: add mva01s bugfix sanity Signed-off-by: Robin Pedersen --- tests/programs/custom/zc_test/zc_test.c | 39 +++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/tests/programs/custom/zc_test/zc_test.c b/tests/programs/custom/zc_test/zc_test.c index 3bac064f2..34c751b67 100644 --- a/tests/programs/custom/zc_test/zc_test.c +++ b/tests/programs/custom/zc_test/zc_test.c @@ -111,6 +111,17 @@ void m_external_irq_handler(void) { } +static void +test_mva01s_same_register(void) +{ + printf("test_mva01s_same_register: start\n"); + __asm__ volatile( + "cm.mva01s s2, s2" + : : : "s2" + ); + printf("test_mva01s_same_register: done\n"); +} + int main(int argc, char *argv[]) { @@ -120,10 +131,15 @@ int main(int argc, char *argv[]) test_instr_num = 0; + // Setup + printf("Enabling irq. \n"); enable_all_irq(); + + // Test: PushPop + printf("\n\nTesting push/pop instructions. \n"); test_active = pushpop; @@ -138,11 +154,13 @@ int main(int argc, char *argv[]) interrupt_push_pop(i); } + + // Test: Popret + printf("\n\nTesting popret instructions. \n"); test_active = popret; test_instr_num = 0; - for (int i = PUSH_RLIST_MIN; i <= PUSH_RLIST_MAX; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -154,11 +172,13 @@ int main(int argc, char *argv[]) interrupt_popret(i); } + + // Test: Popretz + printf("\n\nTesting popretz instructions. \n"); test_active = popretz; test_instr_num = 0; - for (int i = PUSH_RLIST_MIN; i <= PUSH_RLIST_MAX; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -171,6 +191,8 @@ int main(int argc, char *argv[]) } + // Test: Mvsa01 + printf("\n\nTesting mvsa01 instructions. \n"); test_active = mvsa; test_instr_num = 0; @@ -191,12 +213,18 @@ int main(int argc, char *argv[]) i = iteratorVault; } + + // Test: Mva01s + printf("\n\nTesting mva01s instructions. \n"); + test_active = mvas; test_instr_num = 0; + //creating random values for the target registers rnd0 = vp_random_num(0xFFFFFFFE, 0x0); rnd1 = vp_random_num(0xFFFFFFFE, 0x0); + for (int i = 0; i < MVAS_INSTR_SIZE; i++) { glb_irq_line = 0x1 << EX_IRQ_LINE; @@ -212,6 +240,13 @@ int main(int argc, char *argv[]) } + // Test: Mva01s - Same Register (Sanity check of RTL bugfix.) + + test_mva01s_same_register(); + + + // ErrorCheck & Exit + if(exp_irq != ex_traps_entered) { printf("\tERROR: %u interrupts taken, expected %u", (unsigned int)ex_traps_entered, (unsigned int)exp_irq); failureCount += 1; From 35ab8ca8eee8b71808b81e310711b184af34b19c Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 1 Dec 2023 16:34:12 +0100 Subject: [PATCH 08/16] update write to mhpmcounterh Signed-off-by: Kristine Dosvik --- .../custom/mhpmcounter_write_test/mhpmcounter_write_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c index e11414218..5cc0039fa 100644 --- a/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c +++ b/tests/programs/custom/mhpmcounter_write_test/mhpmcounter_write_test.c @@ -62,6 +62,8 @@ int write_mhpmcounters() int write_mhpmcounterhs() { uint32_t reg = 0; + __asm__ volatile("mv %0, x0" : "=r"(reg)); + __asm__ volatile("not %0, %0" :: "r"(reg)); __asm__ volatile("csrrs x0, mhpmcounter3h, %0" :: "r"(reg)); __asm__ volatile("csrrs x0, mhpmcounter4h, %0" :: "r"(reg)); __asm__ volatile("csrrs x0, mhpmcounter5h, %0" :: "r"(reg)); From a406135fa92ccce8ea895b501717c2e99c015e93 Mon Sep 17 00:00:00 2001 From: Marton Teilgard Date: Thu, 7 Dec 2023 10:31:16 +0100 Subject: [PATCH 09/16] removing unused if from tb Signed-off-by: Marton Teilgard --- tb/uvmt/uvmt_cv32e40s_dut_wrap.sv | 3 +-- tb/uvmt/uvmt_cv32e40s_tb.sv | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv b/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv index c5d8ced4e..06350ca69 100644 --- a/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv +++ b/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv @@ -55,7 +55,6 @@ module uvmt_cv32e40s_dut_wrap uvma_wfe_wu_if_t wfe_wu_if, uvmt_cv32e40s_vp_status_if_t vp_status_if, uvme_cv32e40s_core_cntrl_if_t core_cntrl_if, - uvmt_cv32e40s_core_status_if_t core_status_if, uvma_obi_memory_if_t obi_instr_if, uvma_obi_memory_if_t obi_data_if, uvma_fencei_if_t fencei_if @@ -166,7 +165,7 @@ module uvmt_cv32e40s_dut_wrap .alert_minor_o ( alert_minor ), .fetch_enable_i ( core_cntrl_if.fetch_en ), - .core_sleep_o ( core_status_if.core_busy ) + .core_sleep_o () ); // instantiate rchk shim diff --git a/tb/uvmt/uvmt_cv32e40s_tb.sv b/tb/uvmt/uvmt_cv32e40s_tb.sv index 6cf84133e..70efa042b 100644 --- a/tb/uvmt/uvmt_cv32e40s_tb.sv +++ b/tb/uvmt/uvmt_cv32e40s_tb.sv @@ -82,8 +82,6 @@ module uvmt_cv32e40s_tb; .exit_valid(), .exit_value()); // Status information generated by the Virtual Peripherals in the DUT WRAPPER memory. uvme_cv32e40s_core_cntrl_if_t core_cntrl_if(); - uvmt_cv32e40s_core_status_if_t core_status_if(.core_busy(), - .sec_lvl()); // Core status outputs // RVVI SystemVerilog Interface `ifndef FORMAL @@ -103,7 +101,6 @@ module uvmt_cv32e40s_tb; .interrupt_if (interrupt_if), .vp_status_if (vp_status_if), .core_cntrl_if (core_cntrl_if), - .core_status_if (core_status_if), .obi_instr_if (obi_instr_if), .obi_data_if (obi_data_if), .fencei_if (fencei_if), @@ -2056,7 +2053,6 @@ module uvmt_cv32e40s_tb; // Virtual Peripheral Status interface uvm_config_db#(virtual uvmt_cv32e40s_vp_status_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("vp_status_vif"), .value(vp_status_if) ); uvm_config_db#(virtual uvme_cv32e40s_core_cntrl_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("core_cntrl_vif"), .value(core_cntrl_if) ); - uvm_config_db#(virtual uvmt_cv32e40s_core_status_if_t )::set(.cntxt(null), .inst_name("*"), .field_name("core_status_vif"), .value(core_status_if) ); uvm_config_db#(virtual uvmt_cv32e40s_debug_cov_assert_if_t )::set(.cntxt(null), .inst_name("*.env"), .field_name("debug_cov_vif"),.value(dut_wrap.cv32e40s_wrapper_i.debug_cov_assert_if)); uvm_config_db#(virtual uvmt_cv32e40s_support_logic_module_o_if_t )::set(.cntxt(null), .inst_name("*.env"), .field_name("support_logic_vif"),.value(dut_wrap.cv32e40s_wrapper_i.support_logic_module_o_if)); From 120215d66ee5e7d50e954289c2ac31cbd938ea1a Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Tue, 5 Dec 2023 13:49:15 +0100 Subject: [PATCH 10/16] add 'obi err await goahead' flag and logic Signed-off-by: Robin Pedersen --- env/corev-dv/cv32e40s_asm_program_gen.sv | 23 ++++- env/uvme/uvme_cv32e40s_cfg.sv | 86 +++++++++++++------ .../corev_rand_data_obi_err_debug/test.yaml | 1 + 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/env/corev-dv/cv32e40s_asm_program_gen.sv b/env/corev-dv/cv32e40s_asm_program_gen.sv index 9d1f1a910..d36e737e4 100644 --- a/env/corev-dv/cv32e40s_asm_program_gen.sv +++ b/env/corev-dv/cv32e40s_asm_program_gen.sv @@ -19,17 +19,19 @@ //----------------------------------------------------------------------------------------- // CV32E40S CORE-V assembly program generator - extension of the RISC-V assembly program generator. // -// Overrides gen_program_header() and gen_test_done() +// Overrides gen_program_header() and gen_test_done() and other riscv-dv functions. //----------------------------------------------------------------------------------------- class cv32e40s_asm_program_gen extends corev_asm_program_gen; `uvm_object_utils(cv32e40s_asm_program_gen) + function new (string name = ""); super.new(name); endfunction + virtual function void gen_program_header(); string instr[]; cv32e40s_instr_gen_config corev_cfg; @@ -99,6 +101,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_program_header + virtual function void trap_vector_init(int hart); string instr[]; privileged_reg_t trap_vec_reg; @@ -153,6 +156,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("trap_vec_init", hart), instr); endfunction : trap_vector_init + virtual function void gen_illegal_instr_handler(int hart); string instr[$]; string load_instr = (XLEN == 32) ? "lw" : "ld"; @@ -195,6 +199,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("illegal_instr_handler", hart), instr); endfunction + virtual function void gen_instr_fault_handler(int hart); string instr[$]; string load_instr = (XLEN == 32) ? "lw" : "ld"; @@ -232,6 +237,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("instr_fault_handler", hart), instr); endfunction + // TODO: handshake correct csr based on delegation virtual function void gen_load_fault_handler(int hart); string instr[$]; @@ -253,6 +259,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("load_fault_handler", hart), instr); endfunction + // TODO: handshake correct csr based on delegation virtual function void gen_store_fault_handler(int hart); string instr[$]; @@ -273,6 +280,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("store_fault_handler", hart), instr); endfunction + virtual function void gen_interrupt_vector_table(int hart, string mode, privileged_reg_t status, @@ -344,6 +352,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; end endfunction : gen_interrupt_vector_table + // Setup EPC before entering target privileged mode virtual function void setup_epc(int hart); string instr[$]; @@ -362,6 +371,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; gen_section(get_label("mepc_setup", hart), instr); endfunction + // Interrupt handler routine // Override from risc-dv: // 1. Remove MIP read, since interrupts are auto-cleared, mip will not track through the ISS @@ -516,6 +526,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_interrupt_handler_section + // Override gen_stack_section to add debugger stack generation section // Implmeneted as a post-step to super.gen_stack_section() virtual function void gen_stack_section(int hart); @@ -535,6 +546,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; endfunction : gen_stack_section + // Override of init_gpr to remove cfg.dp from initiailization if a debug section is generated virtual function void init_gpr(); string str; @@ -560,6 +572,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; end endfunction + // generate NMI handler. // will be placed at a fixed address in memory, set in linker file virtual function void gen_nmi_handler_section(int hart); @@ -587,6 +600,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; nmi_handler_instr); endfunction : gen_nmi_handler_section + virtual function void gen_section(string label, string instr[$]); string str; if(label == "mtvec_handler" && cfg.mtvec_mode == VECTORED) begin @@ -610,4 +624,11 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; instr_stream.push_back(""); endfunction : gen_section + + virtual function void gen_init_section(int hart); + super.gen_init_section(hart); + + //instr_stream.push_back("TODO haha"); + endfunction + endclass : cv32e40s_asm_program_gen diff --git a/env/uvme/uvme_cv32e40s_cfg.sv b/env/uvme/uvme_cv32e40s_cfg.sv index 48804c2db..ff99b296a 100644 --- a/env/uvme/uvme_cv32e40s_cfg.sv +++ b/env/uvme/uvme_cv32e40s_cfg.sv @@ -28,18 +28,19 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; // Integrals rand int unsigned sys_clk_period; cv32e40s_pkg::b_ext_e b_ext; - bit obi_memory_instr_random_err_enabled = 0; - bit obi_memory_instr_one_shot_err_enabled = 0; - bit obi_memory_data_random_err_enabled = 0; - bit obi_memory_data_one_shot_err_enabled = 0; - bit iss_suppress_invalid_msg = 0; - bit nmi_timeout_instr_plusarg_valid = 0; - bit irq_min_limit_plusarg_valid = 0; - bit single_step_min_limit_plusarg_valid = 0; - bit irq_single_step_threshold_plusarg_valid = 0; - bit clic_irq_clear_on_ack_plusarg_valid = 0; + bit obi_memory_instr_random_err_enabled = 0; + bit obi_memory_instr_one_shot_err_enabled = 0; + bit obi_memory_data_random_err_enabled = 0; + bit obi_memory_data_random_err_await_goahead = 0; + bit obi_memory_data_one_shot_err_enabled = 0; + bit iss_suppress_invalid_msg = 0; + bit nmi_timeout_instr_plusarg_valid = 0; + bit irq_min_limit_plusarg_valid = 0; + bit single_step_min_limit_plusarg_valid = 0; + bit irq_single_step_threshold_plusarg_valid = 0; + bit clic_irq_clear_on_ack_plusarg_valid = 0; rand bit clic_irq_clear_on_ack; - rand bit buserr_scoreboarding_enabled = 1; + rand bit buserr_scoreboarding_enabled = 1; rand int unsigned fetch_toggle_initial_delay; rand int unsigned nmi_timeout_instr; rand int unsigned single_step_min_limit; @@ -60,23 +61,24 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; rand uvma_pma_cfg_c#(ILEN,XLEN) pma_cfg; `uvm_object_utils_begin(uvme_cv32e40s_cfg_c) - `uvm_field_int ( enabled, UVM_DEFAULT ) - `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT ) - `uvm_field_int ( cov_model_enabled, UVM_DEFAULT ) - `uvm_field_int ( trn_log_enabled, UVM_DEFAULT ) - `uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT ) - `uvm_field_int ( sys_clk_period, UVM_DEFAULT | UVM_DEC ) - `uvm_field_enum (b_ext_e, b_ext, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_one_shot_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( iss_suppress_invalid_msg, UVM_DEFAULT ) - `uvm_field_int ( fetch_toggle_initial_delay, UVM_DEFAULT ) - `uvm_field_int ( nmi_timeout_instr, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( single_step_min_limit, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( irq_min_limit, UVM_DEFAULT | UVM_DEC ) - `uvm_field_int ( irq_single_step_threshold, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( enabled, UVM_DEFAULT ) + `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT ) + `uvm_field_int ( cov_model_enabled, UVM_DEFAULT ) + `uvm_field_int ( trn_log_enabled, UVM_DEFAULT ) + `uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT ) + `uvm_field_int ( sys_clk_period, UVM_DEFAULT | UVM_DEC ) + `uvm_field_enum (b_ext_e, b_ext, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_await_goahead, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( iss_suppress_invalid_msg, UVM_DEFAULT ) + `uvm_field_int ( fetch_toggle_initial_delay, UVM_DEFAULT ) + `uvm_field_int ( nmi_timeout_instr, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( single_step_min_limit, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( irq_min_limit, UVM_DEFAULT | UVM_DEC ) + `uvm_field_int ( irq_single_step_threshold, UVM_DEFAULT | UVM_DEC ) `uvm_field_object(isacov_cfg , UVM_DEFAULT) `uvm_field_object(clknrst_cfg , UVM_DEFAULT) @@ -333,6 +335,11 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; obi_memory_data_cfg.drv_slv_err_one_shot_mode == obi_memory_data_one_shot_err_enabled; } + constraint obi_memory_data_random_err_await_goahead_cons { + obi_memory_data_cfg.random_err_await_goahead == + obi_memory_data_random_err_await_goahead; + } + /** * Creates sub-configuration objects. */ @@ -370,19 +377,25 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; endclass : uvme_cv32e40s_cfg_c + function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); super.new(name); core_name = "CV32E40S"; + + // Read Plusargs + if ($test$plusargs("USE_ISS")) begin use_iss = 1; end + if ($test$plusargs("trn_log_disabled")) begin trn_log_enabled = 0; trn_log_enabled.rand_mode(0); end + if ($test$plusargs("buserr_sb_disabled")) begin buserr_scoreboarding_enabled = 0; buserr_scoreboarding_enabled.rand_mode(0); @@ -391,27 +404,38 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); if ($test$plusargs("obi_memory_instr_random_err")) begin obi_memory_instr_random_err_enabled = 1; end + if ($test$plusargs("obi_memory_instr_one_shot_err")) begin obi_memory_instr_one_shot_err_enabled = 1; end + if ($test$plusargs("obi_memory_data_random_err")) begin obi_memory_data_random_err_enabled = 1; end + + if ($test$plusargs("obi_memory_data_random_err_await_goahead")) begin + obi_memory_data_random_err_await_goahead = 1; + end + if ($test$plusargs("obi_memory_data_one_shot_err")) begin obi_memory_data_one_shot_err_enabled = 1; end + if ($value$plusargs("nmi_timeout_instr=%d", nmi_timeout_instr)) begin nmi_timeout_instr_plusarg_valid = 1; nmi_timeout_instr.rand_mode(0); end + if ($value$plusargs("irq_single_step_threshold=%0d", irq_single_step_threshold)) begin irq_single_step_threshold_plusarg_valid = 1; irq_single_step_threshold.rand_mode(0); end + if ($value$plusargs("irq_min_limit=%0d", irq_min_limit)) begin irq_min_limit_plusarg_valid = 1; irq_min_limit.rand_mode(0); end + if ($value$plusargs("single_step_min_limit=%0d", single_step_min_limit)) begin single_step_min_limit_plusarg_valid = 1; single_step_min_limit.rand_mode(0); @@ -428,6 +452,8 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); end + // Create Configs + isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg"); clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg"); interrupt_cfg = uvma_interrupt_cfg_c::type_id::create("interrupt_cfg"); @@ -441,6 +467,8 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); pma_cfg = uvma_pma_cfg_c#(ILEN,XLEN)::type_id::create("pma_cfg"); + // Assign loggers and configs + obi_memory_instr_cfg.mon_logger_name = "OBII"; obi_memory_data_cfg.mon_logger_name = "OBID"; @@ -449,12 +477,14 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); endfunction : new + function void uvme_cv32e40s_cfg_c::pre_randomize(); `uvm_info("CFG", $sformatf("Pre-randomize num_mhpmcounters = %0d", num_mhpmcounters), UVM_LOW); endfunction : pre_randomize + function void uvme_cv32e40s_cfg_c::post_randomize(); super.post_randomize(); diff --git a/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml b/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml index 467563d1e..ff832c3fe 100644 --- a/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml +++ b/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml @@ -5,6 +5,7 @@ description: > plusargs: > +random_fetch_toggle +obi_memory_data_random_err_enabled + +obi_memory_data_random_err_await_goahead +obi_memory_data_one_shot_err_enabled +gen_irq_noise +gen_random_debug From d586472233c34d31587e6e95681d1df154bfb80a Mon Sep 17 00:00:00 2001 From: Marton Teilgard Date: Thu, 7 Dec 2023 13:04:42 +0100 Subject: [PATCH 11/16] fixed indentation issue Signed-off-by: Marton Teilgard --- tb/uvmt/uvmt_cv32e40s_dut_wrap.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv b/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv index 06350ca69..90c1523d5 100644 --- a/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv +++ b/tb/uvmt/uvmt_cv32e40s_dut_wrap.sv @@ -165,7 +165,7 @@ module uvmt_cv32e40s_dut_wrap .alert_minor_o ( alert_minor ), .fetch_enable_i ( core_cntrl_if.fetch_en ), - .core_sleep_o () + .core_sleep_o () ); // instantiate rchk shim From 8245d30b963805a4fbbf69a65f8cef4948e310f7 Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Thu, 7 Dec 2023 10:52:16 +0100 Subject: [PATCH 12/16] create 'obi err await goahead' vp Signed-off-by: Robin Pedersen --- bsp/corev_uvmt.h | 38 +++++++------ env/uvme/uvme_cv32e40s_env.sv | 31 +++++++++++ env/uvme/uvme_cv32e40s_pkg.sv | 3 +- ...e_cv32e40s_vp_obi_err_await_goahead_seq.sv | 55 +++++++++++++++++++ .../uvmt_cv32e40s_base_test_constants.sv | 40 +++++++------- 5 files changed, 129 insertions(+), 38 deletions(-) create mode 100644 env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv diff --git a/bsp/corev_uvmt.h b/bsp/corev_uvmt.h index d7022b3ca..94d73856d 100644 --- a/bsp/corev_uvmt.h +++ b/bsp/corev_uvmt.h @@ -25,25 +25,27 @@ #define CV_VP_REGISTER_BASE 0x00800000 -#define CV_VP_VIRTUAL_PRINTER_OFFSET 0x00000000 -#define CV_VP_RANDOM_NUM_OFFSET 0x00000040 -#define CV_VP_CYCLE_COUNTER_OFFSET 0x00000080 -#define CV_VP_STATUS_FLAGS_OFFSET 0x000000c0 -#define CV_VP_FENCEI_TAMPER_OFFSET 0x00000100 -#define CV_VP_INTR_TIMER_OFFSET 0x00000140 -#define CV_VP_DEBUG_CONTROL_OFFSET 0x00000180 -#define CV_VP_OBI_SLV_RESP_OFFSET 0x000001c0 -#define CV_VP_SIG_WRITER_OFFSET 0x00000200 +#define CV_VP_VIRTUAL_PRINTER_OFFSET 0x00000000 +#define CV_VP_RANDOM_NUM_OFFSET 0x00000040 +#define CV_VP_CYCLE_COUNTER_OFFSET 0x00000080 +#define CV_VP_STATUS_FLAGS_OFFSET 0x000000c0 +#define CV_VP_FENCEI_TAMPER_OFFSET 0x00000100 +#define CV_VP_INTR_TIMER_OFFSET 0x00000140 +#define CV_VP_DEBUG_CONTROL_OFFSET 0x00000180 +#define CV_VP_OBI_SLV_RESP_OFFSET 0x000001c0 +#define CV_VP_SIG_WRITER_OFFSET 0x00000200 +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET 0x00000240 -#define CV_VP_VIRTUAL_PRINTER_BASE (CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET) -#define CV_VP_RANDOM_NUM_BASE (CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET) -#define CV_VP_CYCLE_COUNTER_BASE (CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET) -#define CV_VP_STATUS_FLAGS_BASE (CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET) -#define CV_VP_INTR_TIMER_BASE (CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET) -#define CV_VP_DEBUG_CONTROL_BASE (CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET) -#define CV_VP_OBI_SLV_RESP_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET) -#define CV_VP_SIG_WRITER_BASE (CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET) -#define CV_VP_FENCEI_TAMPER_BASE (CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET) +#define CV_VP_CYCLE_COUNTER_BASE (CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET) +#define CV_VP_DEBUG_CONTROL_BASE (CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET) +#define CV_VP_FENCEI_TAMPER_BASE (CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET) +#define CV_VP_INTR_TIMER_BASE (CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET) +#define CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET) +#define CV_VP_OBI_SLV_RESP_BASE (CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET) +#define CV_VP_RANDOM_NUM_BASE (CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET) +#define CV_VP_SIG_WRITER_BASE (CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET) +#define CV_VP_STATUS_FLAGS_BASE (CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET) +#define CV_VP_VIRTUAL_PRINTER_BASE (CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET) // -------------------------------------------------------------------------- // Registers inside the OBI_SLV_RESP VP diff --git a/env/uvme/uvme_cv32e40s_env.sv b/env/uvme/uvme_cv32e40s_env.sv index caf1983d1..cb1c13ca9 100644 --- a/env/uvme/uvme_cv32e40s_env.sv +++ b/env/uvme/uvme_cv32e40s_env.sv @@ -760,6 +760,37 @@ function void uvme_cv32e40s_env_c::install_vp_register_seqs(uvma_obi_memory_slv_ vp_seq.cv32e40s_cntxt = cntxt; end + begin + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c new_vp_seq; + +/* TODO delete? + uvma_obi_memory_vp_base_seq_c#( + .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), + .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH), + .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .ADDR_WIDTH (ENV_PARAM_DATA_ADDR_WIDTH), + .DATA_WIDTH (ENV_PARAM_DATA_DATA_WIDTH), + .ID_WIDTH (ENV_PARAM_DATA_ID_WIDTH), + .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), + .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH) + ) registered_vp_base_vseq; +*/ + + void' ( + data_slv_seq.register_vp_vseq( + "vp_obi_err_await_goahead", + CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE, + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c::get_type() + ) + ); + +/* TODO delete? + if ( ! $cast(new_vp_seq, registered_vp_base_vseq) ) begin + `uvm_fatal("CV32E40SVPSEQ", $sformatf("Could not cast vp_obi_err_await_goahead correctly")); + end +*/ + end + endfunction : install_vp_register_seqs `endif // __UVME_CV32E40S_ENV_SV__ diff --git a/env/uvme/uvme_cv32e40s_pkg.sv b/env/uvme/uvme_cv32e40s_pkg.sv index 6134e59ee..cc0ef42b0 100644 --- a/env/uvme/uvme_cv32e40s_pkg.sv +++ b/env/uvme/uvme_cv32e40s_pkg.sv @@ -74,10 +74,11 @@ package uvme_cv32e40s_pkg; `include "uvme_cv32e40s_nmi_timeout_vseq.sv" `include "uvme_cv32e40s_irq_ss_timeout_vseq.sv" `include "uvme_cv32e40s_vp_debug_control_seq.sv" + `include "uvme_cv32e40s_vp_fencei_tamper_seq.sv" `include "uvme_cv32e40s_vp_interrupt_timer_seq.sv" + `include "uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv" `include "uvme_cv32e40s_vp_sig_writer_seq.sv" `include "uvme_cv32e40s_vp_status_flags_seq.sv" - `include "uvme_cv32e40s_vp_fencei_tamper_seq.sv" `include "uvme_cv32e40s_interrupt_noise_vseq.sv" `include "uvme_cv32e40s_clic_noise_vseq.sv" `include "uvme_cv32e40s_vseq_lib.sv" diff --git a/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv b/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv new file mode 100644 index 000000000..10b2bed99 --- /dev/null +++ b/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv @@ -0,0 +1,55 @@ +// Copyright 2023 Silicon Labs, Inc. +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may +// not use this file except in compliance with the License, or, at your option, +// the Apache License version 2.0. +// +// You may obtain a copy of the License at +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. + + +class uvme_cv32e40s_vp_obi_err_await_goahead_seq_c + extends uvma_obi_memory_vp_base_seq_c #( + .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), + .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH), + .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .ADDR_WIDTH (ENV_PARAM_DATA_ADDR_WIDTH), + .DATA_WIDTH (ENV_PARAM_DATA_DATA_WIDTH), + .ID_WIDTH (ENV_PARAM_DATA_ID_WIDTH), + .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), + .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH) + ); + + `uvm_object_utils( uvme_cv32e40s_vp_obi_err_await_goahead_seq_c ) + + + function new(string name="uvme_cv32e40s_vp_obi_err_await_goahead_seq_c"); + super.new(name); + endfunction + + + function int unsigned get_num_words(); + return 1; + endfunction + + + virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn); + uvma_obi_memory_slv_seq_item_c slv_rsp; + + $display("TODO vp_body"); + + `uvm_create(slv_rsp) + `uvm_send(slv_rsp) + endtask + + +endclass diff --git a/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv b/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv index 2feb828cc..eb1ed3c90 100644 --- a/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv +++ b/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv @@ -52,25 +52,27 @@ parameter CV_VP_REGISTER_BASE = 32'h0080_0000; parameter CV_VP_REGISTER_SIZE = 32'h0000_1000; - parameter CV_VP_VIRTUAL_PRINTER_OFFSET = 32'h0000_0000; - parameter CV_VP_RANDOM_NUM_OFFSET = 32'h0000_0040; - parameter CV_VP_CYCLE_COUNTER_OFFSET = 32'h0000_0080; - parameter CV_VP_STATUS_FLAGS_OFFSET = 32'h0000_00c0; - parameter CV_VP_FENCEI_TAMPER_OFFSET = 32'h0000_0100; - parameter CV_VP_INTR_TIMER_OFFSET = 32'h0000_0140; - parameter CV_VP_DEBUG_CONTROL_OFFSET = 32'h0000_0180; - parameter CV_VP_OBI_SLV_RESP_OFFSET = 32'h0000_01c0; - parameter CV_VP_SIG_WRITER_OFFSET = 32'h0000_0200; - - parameter CV_VP_VIRTUAL_PRINTER_BASE = CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET; - parameter CV_VP_RANDOM_NUM_BASE = CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET; - parameter CV_VP_CYCLE_COUNTER_BASE = CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET; - parameter CV_VP_STATUS_FLAGS_BASE = CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET; - parameter CV_VP_INTR_TIMER_BASE = CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET; - parameter CV_VP_DEBUG_CONTROL_BASE = CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET; - parameter CV_VP_OBI_SLV_RESP_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET; - parameter CV_VP_SIG_WRITER_BASE = CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET; - parameter CV_VP_FENCEI_TAMPER_BASE = CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET; + parameter CV_VP_VIRTUAL_PRINTER_OFFSET = 32'h0000_0000; + parameter CV_VP_RANDOM_NUM_OFFSET = 32'h0000_0040; + parameter CV_VP_STATUS_FLAGS_OFFSET = 32'h0000_00c0; + parameter CV_VP_CYCLE_COUNTER_OFFSET = 32'h0000_0080; + parameter CV_VP_FENCEI_TAMPER_OFFSET = 32'h0000_0100; + parameter CV_VP_INTR_TIMER_OFFSET = 32'h0000_0140; + parameter CV_VP_DEBUG_CONTROL_OFFSET = 32'h0000_0180; + parameter CV_VP_OBI_SLV_RESP_OFFSET = 32'h0000_01c0; + parameter CV_VP_SIG_WRITER_OFFSET = 32'h0000_0200; + parameter CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET = 32'h0000_0240; + + parameter CV_VP_CYCLE_COUNTER_BASE = CV_VP_REGISTER_BASE + CV_VP_CYCLE_COUNTER_OFFSET; + parameter CV_VP_DEBUG_CONTROL_BASE = CV_VP_REGISTER_BASE + CV_VP_DEBUG_CONTROL_OFFSET; + parameter CV_VP_FENCEI_TAMPER_BASE = CV_VP_REGISTER_BASE + CV_VP_FENCEI_TAMPER_OFFSET; + parameter CV_VP_INTR_TIMER_BASE = CV_VP_REGISTER_BASE + CV_VP_INTR_TIMER_OFFSET; + parameter CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_ERR_AWAIT_GOAHEAD_OFFSET; + parameter CV_VP_OBI_SLV_RESP_BASE = CV_VP_REGISTER_BASE + CV_VP_OBI_SLV_RESP_OFFSET; + parameter CV_VP_RANDOM_NUM_BASE = CV_VP_REGISTER_BASE + CV_VP_RANDOM_NUM_OFFSET; + parameter CV_VP_SIG_WRITER_BASE = CV_VP_REGISTER_BASE + CV_VP_SIG_WRITER_OFFSET; + parameter CV_VP_STATUS_FLAGS_BASE = CV_VP_REGISTER_BASE + CV_VP_STATUS_FLAGS_OFFSET; + parameter CV_VP_VIRTUAL_PRINTER_BASE = CV_VP_REGISTER_BASE + CV_VP_VIRTUAL_PRINTER_OFFSET; `ifdef PARAM_SET_0 `include "cvverif_param_set_0.svh" From 37f101e1480f76440759a06c2e44caf38b32b4b0 Mon Sep 17 00:00:00 2001 From: Robin Pedersen Date: Sun, 10 Dec 2023 16:32:09 +0100 Subject: [PATCH 13/16] effectuate obi_err_await_goahaed vp Signed-off-by: Robin Pedersen --- env/corev-dv/cv32e40s_asm_program_gen.sv | 15 +++++- env/uvme/uvme_cv32e40s_cfg.sv | 52 ++++++++++++------- env/uvme/uvme_cv32e40s_env.sv | 42 +++++++-------- .../uvme_cv32e40s_vp_fencei_tamper_seq.sv | 2 +- ...e_cv32e40s_vp_obi_err_await_goahead_seq.sv | 6 ++- 5 files changed, 74 insertions(+), 43 deletions(-) diff --git a/env/corev-dv/cv32e40s_asm_program_gen.sv b/env/corev-dv/cv32e40s_asm_program_gen.sv index d36e737e4..6e3210808 100644 --- a/env/corev-dv/cv32e40s_asm_program_gen.sv +++ b/env/corev-dv/cv32e40s_asm_program_gen.sv @@ -603,6 +603,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; virtual function void gen_section(string label, string instr[$]); string str; + if(label == "mtvec_handler" && cfg.mtvec_mode == VECTORED) begin str = ".section .mtvec_handler, \"ax\""; instr_stream.push_back(str); @@ -612,6 +613,7 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; str = format_string($sformatf("%0s:", label), LABEL_STR_LEN); instr_stream.push_back(str); end + foreach(instr[i]) begin str = {indent, instr[i]}; instr_stream.push_back(str); @@ -621,14 +623,25 @@ class cv32e40s_asm_program_gen extends corev_asm_program_gen; instr_stream.push_back(str); end end + instr_stream.push_back(""); endfunction : gen_section virtual function void gen_init_section(int hart); + string instrs[]; + string label; + super.gen_init_section(hart); - //instr_stream.push_back("TODO haha"); + // After the "init" section, bus errors can safely occur without havoc + label = get_label("obi_err_goahead", hart); + instrs = { + $sformatf("li x%0d, 0x%08x", cfg.gpr[0], CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE), + $sformatf("sw x0, 0(x%0d)", cfg.gpr[0]) + }; + gen_section(label, instrs); endfunction + endclass : cv32e40s_asm_program_gen diff --git a/env/uvme/uvme_cv32e40s_cfg.sv b/env/uvme/uvme_cv32e40s_cfg.sv index ff99b296a..e6172209c 100644 --- a/env/uvme/uvme_cv32e40s_cfg.sv +++ b/env/uvme/uvme_cv32e40s_cfg.sv @@ -28,19 +28,20 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; // Integrals rand int unsigned sys_clk_period; cv32e40s_pkg::b_ext_e b_ext; - bit obi_memory_instr_random_err_enabled = 0; - bit obi_memory_instr_one_shot_err_enabled = 0; - bit obi_memory_data_random_err_enabled = 0; - bit obi_memory_data_random_err_await_goahead = 0; - bit obi_memory_data_one_shot_err_enabled = 0; - bit iss_suppress_invalid_msg = 0; - bit nmi_timeout_instr_plusarg_valid = 0; - bit irq_min_limit_plusarg_valid = 0; - bit single_step_min_limit_plusarg_valid = 0; - bit irq_single_step_threshold_plusarg_valid = 0; - bit clic_irq_clear_on_ack_plusarg_valid = 0; + bit obi_memory_data_one_shot_err_enabled = 0; + bit obi_memory_data_random_err_await_goahead = 0; + bit obi_memory_data_random_err_enabled = 0; + bit obi_memory_instr_one_shot_err_enabled = 0; + bit obi_memory_instr_random_err_await_goahead = 0; + bit obi_memory_instr_random_err_enabled = 0; + bit iss_suppress_invalid_msg = 0; + bit nmi_timeout_instr_plusarg_valid = 0; + bit irq_min_limit_plusarg_valid = 0; + bit single_step_min_limit_plusarg_valid = 0; + bit irq_single_step_threshold_plusarg_valid = 0; + bit clic_irq_clear_on_ack_plusarg_valid = 0; rand bit clic_irq_clear_on_ack; - rand bit buserr_scoreboarding_enabled = 1; + rand bit buserr_scoreboarding_enabled = 1; rand int unsigned fetch_toggle_initial_delay; rand int unsigned nmi_timeout_instr; rand int unsigned single_step_min_limit; @@ -67,12 +68,13 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; `uvm_field_int ( trn_log_enabled, UVM_DEFAULT ) `uvm_field_int ( buserr_scoreboarding_enabled, UVM_DEFAULT ) `uvm_field_int ( sys_clk_period, UVM_DEFAULT | UVM_DEC ) - `uvm_field_enum (b_ext_e, b_ext, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) - `uvm_field_int ( obi_memory_data_random_err_await_goahead, UVM_DEFAULT ) + `uvm_field_enum(b_ext_e, b_ext, UVM_DEFAULT ) `uvm_field_int ( obi_memory_data_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_await_goahead, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_data_random_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_one_shot_err_enabled, UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_random_err_await_goahead,UVM_DEFAULT ) + `uvm_field_int ( obi_memory_instr_random_err_enabled, UVM_DEFAULT ) `uvm_field_int ( iss_suppress_invalid_msg, UVM_DEFAULT ) `uvm_field_int ( fetch_toggle_initial_delay, UVM_DEFAULT ) `uvm_field_int ( nmi_timeout_instr, UVM_DEFAULT | UVM_DEC ) @@ -335,9 +337,17 @@ class uvme_cv32e40s_cfg_c extends uvma_core_cntrl_cfg_c; obi_memory_data_cfg.drv_slv_err_one_shot_mode == obi_memory_data_one_shot_err_enabled; } + constraint obi_memory_data_random_err_await_goahead_cons { - obi_memory_data_cfg.random_err_await_goahead == - obi_memory_data_random_err_await_goahead; + if (obi_memory_data_random_err_await_goahead) { + obi_memory_data_cfg.random_err_await_goahead == 1; + } + } + + constraint obi_memory_instr_random_err_await_goahead_cons { + if (obi_memory_instr_random_err_await_goahead) { + obi_memory_instr_cfg.random_err_await_goahead == 1; + } } /** @@ -417,6 +427,10 @@ function uvme_cv32e40s_cfg_c::new(string name="uvme_cv32e40s_cfg"); obi_memory_data_random_err_await_goahead = 1; end + if ($test$plusargs("obi_memory_instr_random_err_await_goahead")) begin + obi_memory_instr_random_err_await_goahead = 1; + end + if ($test$plusargs("obi_memory_data_one_shot_err")) begin obi_memory_data_one_shot_err_enabled = 1; end diff --git a/env/uvme/uvme_cv32e40s_env.sv b/env/uvme/uvme_cv32e40s_env.sv index cb1c13ca9..9a7f83cf8 100644 --- a/env/uvme/uvme_cv32e40s_env.sv +++ b/env/uvme/uvme_cv32e40s_env.sv @@ -761,34 +761,34 @@ function void uvme_cv32e40s_env_c::install_vp_register_seqs(uvma_obi_memory_slv_ end begin - uvme_cv32e40s_vp_obi_err_await_goahead_seq_c new_vp_seq; - -/* TODO delete? uvma_obi_memory_vp_base_seq_c#( - .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), - .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH), - .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), .ADDR_WIDTH (ENV_PARAM_DATA_ADDR_WIDTH), + .AUSER_WIDTH (ENV_PARAM_DATA_AUSER_WIDTH), .DATA_WIDTH (ENV_PARAM_DATA_DATA_WIDTH), .ID_WIDTH (ENV_PARAM_DATA_ID_WIDTH), - .ACHK_WIDTH (ENV_PARAM_DATA_ACHK_WIDTH), - .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH) - ) registered_vp_base_vseq; -*/ - - void' ( - data_slv_seq.register_vp_vseq( - "vp_obi_err_await_goahead", - CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE, - uvme_cv32e40s_vp_obi_err_await_goahead_seq_c::get_type() - ) + .RCHK_WIDTH (ENV_PARAM_DATA_RCHK_WIDTH), + .RUSER_WIDTH (ENV_PARAM_DATA_RUSER_WIDTH), + .WUSER_WIDTH (ENV_PARAM_DATA_WUSER_WIDTH) + ) new_created_base_seq; + + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c casted_seq_handle; + + new_created_base_seq = data_slv_seq.register_vp_vseq( + "vp_obi_err_await_goahead", + CV_VP_OBI_ERR_AWAIT_GOAHEAD_BASE, + uvme_cv32e40s_vp_obi_err_await_goahead_seq_c::get_type() ); -/* TODO delete? - if ( ! $cast(new_vp_seq, registered_vp_base_vseq) ) begin - `uvm_fatal("CV32E40SVPSEQ", $sformatf("Could not cast vp_obi_err_await_goahead correctly")); + if (!$cast(casted_seq_handle, new_created_base_seq)) begin + `uvm_fatal( + "CV32E40SVPSEQ", + $sformatf("Could not cast/assign vp_obi_err_await_goahead") + ); end -*/ + + casted_seq_handle.obi_memory_cfg_instr = cfg.obi_memory_instr_cfg; + casted_seq_handle.obi_memory_cfg_data = cfg.obi_memory_data_cfg; end endfunction : install_vp_register_seqs diff --git a/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv b/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv index 24c00186e..5924eeefb 100644 --- a/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv +++ b/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv @@ -40,7 +40,7 @@ class uvme_cv32e40s_vp_fencei_tamper_seq_c#( .RCHK_WIDTH(RCHK_WIDTH) ); - uvme_cv32e40s_cntxt_c cv32e40s_cntxt; + uvme_cv32e40s_cntxt_c cv32e40s_cntxt; bit enabled = 0; bit [31:0] addr; diff --git a/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv b/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv index 10b2bed99..8acbc0606 100644 --- a/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv +++ b/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv @@ -31,6 +31,9 @@ class uvme_cv32e40s_vp_obi_err_await_goahead_seq_c `uvm_object_utils( uvme_cv32e40s_vp_obi_err_await_goahead_seq_c ) + uvma_obi_memory_cfg_c obi_memory_cfg_instr; + uvma_obi_memory_cfg_c obi_memory_cfg_data; + function new(string name="uvme_cv32e40s_vp_obi_err_await_goahead_seq_c"); super.new(name); @@ -45,7 +48,8 @@ class uvme_cv32e40s_vp_obi_err_await_goahead_seq_c virtual task vp_body(uvma_obi_memory_mon_trn_c mon_trn); uvma_obi_memory_slv_seq_item_c slv_rsp; - $display("TODO vp_body"); + obi_memory_cfg_instr.random_err_await_goahead = 0; + obi_memory_cfg_data.random_err_await_goahead = 0; `uvm_create(slv_rsp) `uvm_send(slv_rsp) From f845cb74347aae4a03b4a04ad7d550a48b025756 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 13:19:17 +0100 Subject: [PATCH 14/16] minhv pma block test Signed-off-by: Kristine Dosvik --- regress/cv32e40s_full.yaml | 6 + tests/cfg/pma_test_cfg_2.yaml | 1 + .../custom/minhv_pma_block/minhv_pma_block.c | 174 ++++++++++++++++++ .../programs/custom/minhv_pma_block/test.yaml | 8 + 4 files changed, 189 insertions(+) create mode 100644 tests/programs/custom/minhv_pma_block/minhv_pma_block.c create mode 100644 tests/programs/custom/minhv_pma_block/test.yaml diff --git a/regress/cv32e40s_full.yaml b/regress/cv32e40s_full.yaml index 4ce0a40bd..97184ca53 100644 --- a/regress/cv32e40s_full.yaml +++ b/regress/cv32e40s_full.yaml @@ -583,3 +583,9 @@ tests: dir: cv32e40s/sim/uvmt cmd: make test TEST=mhpmcounter_write_test + minhv_pma_block: + description: test minhv=1 and pma block of mepc address + builds: [ uvmt_cv32e40s_pma_2 ] + dir: cv32e40s/sim/uvmt + cmd: make test TEST=minhv_pma_block + diff --git a/tests/cfg/pma_test_cfg_2.yaml b/tests/cfg/pma_test_cfg_2.yaml index 0edf69a0d..185269bf1 100644 --- a/tests/cfg/pma_test_cfg_2.yaml +++ b/tests/cfg/pma_test_cfg_2.yaml @@ -2,6 +2,7 @@ name: pma_test_cfg_2 description: PMA configuration for the PMA_TEST_CFG_2 test case compile_flags: > +define+PMA_TEST_CFG_2 + +define+CLIC_EN +define+ZBA_ZBB_ZBC_ZBS plusargs: > +enable_pma=1 diff --git a/tests/programs/custom/minhv_pma_block/minhv_pma_block.c b/tests/programs/custom/minhv_pma_block/minhv_pma_block.c new file mode 100644 index 000000000..3ce0a9c16 --- /dev/null +++ b/tests/programs/custom/minhv_pma_block/minhv_pma_block.c @@ -0,0 +1,174 @@ +// +// Copyright 2023 Silicon Labs, Inc. +// +// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://solderpad.org/licenses/ +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Author: Kristine Døsvik +// +// Test minhv=1 and pma block of mepc address. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + + +extern volatile uint32_t recovery_pt_mret; +volatile uint32_t g_entered_trap_handler; +volatile uint32_t g_trapped_mcause; + +int execute_from_io_region(); +__attribute__((interrupt ("machine"))) void u_sw_irq_handler(void); +void trap_handler(void); + + +int main(int argc, char **argv){ + + int is_failure = 0; + + is_failure += execute_from_io_region(); + + if(is_failure){ + return EXIT_FAILURE; + } else { + return EXIT_SUCCESS; + } +} + + +int execute_from_io_region() { + + volatile uint32_t io_addr = 0xFFFFEFFF << 2; + volatile uint32_t mcause_excode = 0x0; + volatile uint32_t mcause_excode_expected = 0x1; //Execution attempt from I/O region. + volatile uint32_t mret_dont_trap = 0; + volatile uint32_t test_fail = 0; + g_entered_trap_handler = 0; + + // Load an IO memory address into mepc + __asm__ volatile ( R"( + csrrw zero, mepc, %[io_addr] + )" :: [io_addr] "r"(io_addr)); + + // Set minhv and mpp = M + __asm__ volatile ( R"( + lui t0, 0x70000 + csrrs zero, mcause, t0 + )"::: "t0"); + + __asm__ volatile ( R"( + mret + )":::); + + // Mret traps. + + // This should never execute (deliberate dead code), as the mret make the pc take a jump + mret_dont_trap += 1; + + // Execution should continue here + __asm__ volatile ( R"( + .global recovery_pt_mret + recovery_pt_mret: add x0, x0, x0 + )":::); + + + mcause_excode = g_trapped_mcause & 0x7ff; + + printf("Mret traps: %08lx, expected: 1\n", g_entered_trap_handler); + printf("Mret dont trap: %08lx, expected: 0\n", mret_dont_trap); + printf("mcause excode: %08lx, expected: %08lx (execution attempt from I/O region).\n", mcause_excode, mcause_excode_expected); + test_fail += (g_entered_trap_handler != 1) || mret_dont_trap || (mcause_excode != mcause_excode_expected); + + printf("g_trapped_mcause: %08lx", g_trapped_mcause); + + return test_fail; +} + + +__attribute__((interrupt ("machine"))) +void u_sw_irq_handler(void) { + __asm__ volatile (R"( + # Backup "sp", use debug's own stack + # csrw dscratch0, sp + # la sp, __debugger_stack_start + + # Backup all GPRs + sw a0, -4(sp) + sw a1, -8(sp) + sw a2, -12(sp) + sw a3, -16(sp) + sw a4, -20(sp) + sw a5, -24(sp) + sw a6, -28(sp) + sw a7, -32(sp) + sw t0, -36(sp) + sw t1, -40(sp) + sw t2, -44(sp) + sw t3, -48(sp) + sw t4, -52(sp) + sw t5, -56(sp) + sw t6, -60(sp) + addi sp, sp, -64 + cm.push {ra, s0-s11}, -64 + + # Call the handler actual + call ra, trap_handler + + # Restore all GPRs + cm.pop {ra, s0-s11}, 64 + addi sp, sp, 64 + lw a0, -4(sp) + lw a1, -8(sp) + lw a2, -12(sp) + lw a3, -16(sp) + lw a4, -20(sp) + lw a5, -24(sp) + lw a6, -28(sp) + lw a7, -32(sp) + lw t0, -36(sp) + lw t1, -40(sp) + lw t2, -44(sp) + lw t3, -48(sp) + lw t4, -52(sp) + lw t5, -56(sp) + lw t6, -60(sp) + + # Restore "sp" + # csrr sp, dscratch0 + + # Done + mret + )"); +} + +void trap_handler(void) { + + g_entered_trap_handler += 1; + + __asm__ volatile ( R"( + # Get recovery mepc and replace mepc + la t0, recovery_pt_mret + csrrw zero, mepc, t0 + + # read and clear mcause except mpp, which is set + 4: lui t0, 0x30000 + csrrw %[g_trapped_mcause], mcause, t0 + + )" : [g_trapped_mcause]"=r"(g_trapped_mcause) :: "t0"); + + return; +} + diff --git a/tests/programs/custom/minhv_pma_block/test.yaml b/tests/programs/custom/minhv_pma_block/test.yaml new file mode 100644 index 000000000..4f43e93d6 --- /dev/null +++ b/tests/programs/custom/minhv_pma_block/test.yaml @@ -0,0 +1,8 @@ +name: minhv_pma_block +uvm_test: uvmt_$(CV_CORE_LC)_firmware_test_c +description: > + Use CFG=p,a_test_cfg_2. Test minhv=1 and pma block of mepc address +plusargs: > + +clic_irq_clear_on_ack=0 +cflags: > + -mno-relax From 13846ff196345c9320d782b200b52118ccf46457 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 13:36:59 +0100 Subject: [PATCH 15/16] add minhv_pma_block to vplan Signed-off-by: Kristine Dosvik --- .../Simulation/interrupts/CV32E40SX_CLIC.csv | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.json | 2 +- .../Simulation/interrupts/CV32E40SX_CLIC.xlsx | Bin 38990 -> 38973 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv b/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv index aa233dbbf..5c9e6559a 100644 --- a/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv +++ b/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv @@ -58,7 +58,7 @@ CLIC 8675ec,Interrupt CSR,mtvt,"Function ptr reads treated as instruction fetch, Note, instruction fetch is treated as an implicit read, thus do not require PMP read permissions, but execute permission is required. -Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,clic::invalid_mtvt_ptr_exec_mret +Both the pointer fetch and the fetch of the actual instruction located at the pointer address should be covered by the above restrictions. ",Assertion Check,"ENV capability, not specific test",Functional Coverage,"clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" UM v0.3.0 Common,Interrupt CSR,mtvt,"Always aligned to 2^(max(6, 2+SMCLIC_ID_WIDTH)","Assert that mtvt [max(6, 2+SMCLIC_ID_WIDTH)-1:0] = 0",Assertion Check,"ENV capability, not specific test",Functional Coverage,a_mtvt_alignment_correct CLIC 8675ec,Interrupt CSR,mtvt,"Determine alignment by software access, Write ones to lower order bits and read back",Test that correct alignment can be inferred by writing to these fields and read back.,Self Checking Test,Directed Self-Checking,Testcase,clic :: w_mtvt_rd_alignment diff --git a/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json b/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json index 3f639822f..ed0491458 100644 --- a/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json +++ b/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json @@ -338,7 +338,7 @@ "Pass/Fail Criteria": "Assertion Check", "Test Type": "ENV capability, not specific test", "Coverage Method": "Functional Coverage", - "Link to Coverage": "clic::invalid_mtvt_ptr_exec_mret" + "Link to Coverage": "clic::invalid_mtvt_ptr_exec_mret, minhv_pma_block.c" }, { "Requirement Location": "UM v0.3.0 Common", diff --git a/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx b/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx index fed058066c2573899d4036afd5ca50347c7c11d6..9af84b66045a780ba6fbe47cbbc0a8d4896cd9b4 100644 GIT binary patch delta 2212 zcmYjSS6Gt^5=}x6y-6rir7k5X9T5;hPe5tHMWrbMp$4y_KoBBg1cdwq#70+Xfh8pL zqV(QW1nE_Jhg|Aq-S6AI=Vi`!9?m?>nVFsvNNowE1i{48`G_$CP6q;M04OFwY`_~h zUwC@iY2*>=^MyouBI+i@IhRy$@Yi+k;0AezxNbDSX@9t09Yc`mwk*$VYH>NFjV@z~ zt?SVWYlWW%tnlrLhmWI4#xkBOEhewMcO5cK&=LW!_ zOkO)7+t&9Vw+Rl$>20r}C5k!N{MaX%kM=@}4j$PRIQwc=;Ns@h8 zBYwQ0p25owmJx%zKQGGr1Zf`M0MDZ9@E(V3!8W&LuG^Cnb7Ju8H1Te7=2$rF=tSp2jLp(VL^!7r0n4cDl5 zFznW($A=K}E%Nmw;Cn%AV>m6qG_bNgsU>3B=!p7aSg$hB3PN^Qs_KxA<>IUMu++42xIb)KclMzaqfH!{UIU@;_R0L zRZ&L!%dW60r`LBpE~oW;033w&4xU%iM`mYz8Fo?ZCmm2Vxn{5Fs>ZYrCg3!nB%Q#? zKmQeHkE&{y*AK{^{;byb*t&bUxQ46`NGS6IZvYN*FVqRb;Et)`8UmEqWwB=~)H)%% zs(T|s#T8O1U$*3I|3VG^an~f*NIBZQs0V3|Mo?vk8f{R4= z3$_Vh@okPOM}SvdIhM8Vl9z|)V(@3n9>r%)%qGPa?F`xeo6P3DJ@wVy*Qt(UjDINX zP6uMl;#}unJBVP{>*(lu+QM^Ax*I7PgYgpTmmOxpM(yX@>tXNJJ3aU$iM}=w^<^uRzUiD{iy_a)Y}LhDxsBo(K`vdvAUJB!Q){irW8k7VHLgEr zC<|BD2|1x74{%zjv#jX8^cRGKK(1tIgaBONs(#4k#cnS{&OD3g2RE(Phr3F{)=%jG zRVF^N(|r?u2K85Wmr}?%co{JEnzfV!S492nNn^~uQm21m3R?AJOX^_LtWOOs2JWC( zLVwTqv{vya$*;%d3*Dvd?pDo-zFQHno9G6nZ^PP>0F>VqAxpg3(?2s!tua8vj#`j( zSuthNk;=opVnu;=A)=yT3k{|WnPyfRHdFJzluS%jIi}g!I00Nq9t}GZ+UNm2=FwGl z2xF-r<;!buRn8{Oye|onk{YqKP`zG78A>yNvI(*MfWgzaj-JL(B570!$Am(!9Jfqn;wd{UGeo#UFP0-1N*Uc;7IkentP7Y zS2(2qJtg1xZH9mRYcBvrp9}?ofPScuqKzdOq6FdtF@l&uAdm#;_c;;=f!tR>AlRAm ze;l#_r+_hpS^2E+1J21R5R&R|nvtvmRs{Nz4ZsBeH&I;VfBE?ZIy3$!){Frp(EzLs zBoNIYA`gN1P+?%3s0O(mdPb!IREh#v9|%p+gCHY-#}Nv^d@>iXl_CW81K3mT&fMKo j<^G#C;AJX57z^a4UIAMHv#EMuT|n}c3}YkVKi&QYG&Lah delta 2224 zcmYjSX*kr28=V;q31i8WG49PWwsA4G6b578-O5399j^dbbD)(8DjV|>J z$#T0ka}x^HFI96vjaF1w`gLC};rHqnt<40^k9W0KHeC;^6p;_@&SAu(!%4F*<21wd z&Bmi}UQSn^d(*CI_`iUZASWa$?G^$*Rnz>x^Ytzf(`T(eBA6zpHFK41*&00e< zde7gSMC+NL;cZ8Lv~pSFR*zJ)R9&{AkJYPlK~@lDJ9|6$i5<6icjl>EI}*m#o(ez! zE2!T>`k)v4+EZHDy>(~WSJ$j^!s6J|UDJl}e#Lg#9_f>xcEw$d*k2SFE9TrOM~1yg zL7mCGwll=)*OmPD{8?H`?V=b{LfjNsb-P9w>u9d!5kTmb((y8Zsgbph#|2|~FYu{Q zuxJjg=r7BF#st|`f%};0#3zRyByg(>b|a={NGOk1-YQvPP#}c*k*h?>A}+(}$!8U~ zMsl*RXWTg%isXEOIA*>L^X%$ZAc(d+dKaeY)gQ|d2G77n)=6EeFVX}gybZ3zxf~sy zd4{8+mDWwlOWkWy3~;(duI?$hE9gpHvE2sbML~42~$y!4OpORxsH!+lD=sJBxK8Crs)<*4EyT zUfy7Z>0@F-OXYb9sCx~JyVZ^&H@+VRH=nSz^4JU&FHVh(5)^wBK}kUlMjPgySt*_E zP*2}A8~A0d2h;^)re#;O9jUT^7;gQz!RxuA>h@q*$VNe))? zC2X&+i)qcnyi#O8`sjJ0PN!+W`uNB9iSwi-S?2s3NpU-wPG|pRV-eAZ^Rztu@h7p` z@gp?g;+gUMp|QNtH?n=IDW$$b7Fg^XffJEO4UzHgd-in&bM!0XdD&yJR3`Gll5b+P zfbv8rKS>+!BNUjgjZedz{9fjM5k-7;Qyz7CM9Foq^P55ujZX#3pt8rMAQSEZiWVMe zZkx`&OH^H*vzO1YLRe=Od@dB$uvFbRM>V`CD zGiQ%e_H162B|g5o)NM0|`hk8>Bxp2?7+xBh+D&xmcWGybRHrW(C)D)K7M7_X94y-& z0^F^dK4h<@?-|**oe)fc6jCNFEv0EekXBd#gyfe~YMS^S+JEeOw<@6$o9llu7zmBN z@1YV-BW^p8UZF__FEw(>M!87V9<;E3{i0K4SycO)2T%5~DpL4-d8F~65jcX=jnUca znT#zC8Pi)>pbqHR?up&XI6aywq4B9QSa%g0vgpRkFFOC^ujY}rcQ+e*S58D*2VdW4 zW&`g$nPCBVkRb#KGCKcg2T9=sBG-ebF+G?hA9-_GQX2ldB)RJvr^T@K%-A-sqfH^S zj%*ZosU5q?o1{p#g3*jRi5Nwwr={8Srz2W3M12aXFCPVFK{xD%<^NcC&+uPQk2TnR za>$N-5sR_8qo(>ue!b>BN(E0*=9M z9Lrr{!+CeD=@%4slKbNh^C_Brw8bEs$M zbYqag8G=fhrxF2oP~JteZGk{uzzJBWPyn>?O?M~KA17)td_1n6^2Qxh}6!U z?+PVspidKOH;OpQLlPRaeu;j&B)44^^j|Tl z!HB=b_R(xO!~dM_5bK`m3{3aKvdjZ|A(DJCdX^sh93sF4PTTPeTS6vbH`7)l)lGPl zkdow=AGmXua6@;!>Zo53k&FFV^6rTPJ`_u2#yD+pu`&&=y7+Ct^EHOgj&AJ^Ub-`w zHoua+ir7dPTF$$F`RdfLM(HU>Lu%@Gg>5r^9fY|GS#_S5L%V*hu<2M9#?XBh-x4C>JJp_bqcx*1F< z9E^%UgR^vXSa8H4lm_uxSm-&>HwzDQqk?`^EI6Ji07k_K@cefK0Qa)&pe^9JY&rD5 mzJfv^+b{@3@IT5S$^bL7b)l}{Xg2=vF~J-e&N13Qguel~g!2dh From 1bfcdc6b52c3e47d2a36e496de596d6889e66153 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Tue, 12 Dec 2023 14:39:27 +0100 Subject: [PATCH 16/16] remove uncomment code, fix io address, include bsp Signed-off-by: Kristine Dosvik --- .../programs/custom/minhv_pma_block/minhv_pma_block.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/programs/custom/minhv_pma_block/minhv_pma_block.c b/tests/programs/custom/minhv_pma_block/minhv_pma_block.c index 3ce0a9c16..cafc28a3f 100644 --- a/tests/programs/custom/minhv_pma_block/minhv_pma_block.c +++ b/tests/programs/custom/minhv_pma_block/minhv_pma_block.c @@ -24,7 +24,9 @@ #include #include #include +#include "bsp.h" +#define RND_ADDRS_IN_PMA_CFG_2_IO_REGION 0xE0100010 extern volatile uint32_t recovery_pt_mret; volatile uint32_t g_entered_trap_handler; @@ -51,9 +53,9 @@ int main(int argc, char **argv){ int execute_from_io_region() { - volatile uint32_t io_addr = 0xFFFFEFFF << 2; + volatile uint32_t io_addr = RND_ADDRS_IN_PMA_CFG_2_IO_REGION; volatile uint32_t mcause_excode = 0x0; - volatile uint32_t mcause_excode_expected = 0x1; //Execution attempt from I/O region. + volatile uint32_t mcause_excode_expected = EXC_CAUSE_INSTR_ACC_FAULT; //Execution attempt from I/O region. volatile uint32_t mret_dont_trap = 0; volatile uint32_t test_fail = 0; g_entered_trap_handler = 0; @@ -101,10 +103,6 @@ int execute_from_io_region() { __attribute__((interrupt ("machine"))) void u_sw_irq_handler(void) { __asm__ volatile (R"( - # Backup "sp", use debug's own stack - # csrw dscratch0, sp - # la sp, __debugger_stack_start - # Backup all GPRs sw a0, -4(sp) sw a1, -8(sp)