diff --git a/cv32e40s/bsp/corev_uvmt.h b/cv32e40s/bsp/corev_uvmt.h index d7022b3ca7..94d73856d0 100644 --- a/cv32e40s/bsp/corev_uvmt.h +++ b/cv32e40s/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/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv b/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv index 9d1f1a9107..6e3210808e 100644 --- a/cv32e40s/env/corev-dv/cv32e40s_asm_program_gen.sv +++ b/cv32e40s/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,8 +600,10 @@ 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 str = ".section .mtvec_handler, \"ax\""; instr_stream.push_back(str); @@ -598,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); @@ -607,7 +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); + + // 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/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv index 48804c2db2..e6172209ce 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv +++ b/cv32e40s/env/uvme/uvme_cv32e40s_cfg.sv @@ -28,18 +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_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; @@ -60,23 +62,25 @@ 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_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 ) + `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 +337,19 @@ 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 { + 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; + } + } + /** * Creates sub-configuration objects. */ @@ -370,19 +387,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 +414,42 @@ 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_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 + 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 +466,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 +481,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 +491,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/cv32e40s/env/uvme/uvme_cv32e40s_env.sv b/cv32e40s/env/uvme/uvme_cv32e40s_env.sv index caf1983d17..9a7f83cf89 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_env.sv +++ b/cv32e40s/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 + uvma_obi_memory_vp_base_seq_c#( + .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), + .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() + ); + + 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 `endif // __UVME_CV32E40S_ENV_SV__ diff --git a/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv b/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv index 6134e59ee0..cc0ef42b06 100644 --- a/cv32e40s/env/uvme/uvme_cv32e40s_pkg.sv +++ b/cv32e40s/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/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv index 24c00186e1..5924eeefb9 100644 --- a/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_fencei_tamper_seq.sv +++ b/cv32e40s/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/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv new file mode 100644 index 0000000000..8acbc0606b --- /dev/null +++ b/cv32e40s/env/uvme/vseq/uvme_cv32e40s_vp_obi_err_await_goahead_seq.sv @@ -0,0 +1,59 @@ +// 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 ) + + 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); + 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; + + 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) + endtask + + +endclass diff --git a/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml b/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml index 467563d1ea..ff832c3fea 100644 --- a/cv32e40s/tests/programs/corev-dv/corev_rand_data_obi_err_debug/test.yaml +++ b/cv32e40s/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 diff --git a/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv b/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv index 2feb828cc4..eb1ed3c90a 100644 --- a/cv32e40s/tests/uvmt/base-tests/uvmt_cv32e40s_base_test_constants.sv +++ b/cv32e40s/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" diff --git a/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv b/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv index f0681078b4..2ea3b7b6de 100644 --- a/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv +++ b/lib/uvm_agents/uvma_obi_memory/src/obj/uvma_obi_memory_cfg.sv @@ -76,27 +76,29 @@ class uvma_obi_memory_cfg_c extends uvm_object; rand bit drv_slv_err_one_shot_mode; bit drv_slv_err_one_shot_flag; - rand uvma_obi_memory_drv_slv_exokay_mode_enum drv_slv_exokay_mode; - rand int unsigned drv_slv_exokay_failure_wgt; - rand int unsigned drv_slv_exokay_success_wgt; + rand uvma_obi_memory_drv_slv_exokay_mode_enum drv_slv_exokay_mode; + rand int unsigned drv_slv_exokay_failure_wgt; + rand int unsigned drv_slv_exokay_success_wgt; // Directed error generation memory address range // If the valid bit is asserted any address in range will repsond with error = 1 - bit [31:0] directed_slv_err_addr_min; - bit [31:0] directed_slv_err_addr_max; - bit directed_slv_err_valid; + bit [31:0] directed_slv_err_addr_min; + bit [31:0] directed_slv_err_addr_max; + bit directed_slv_err_valid; // Directed exokay generation memory address range // if the "valid" bit is asserted any address in range will respond // with exokay == 0 - bit [31:0] directed_slv_exokay_addr_min; - bit [31:0] directed_slv_exokay_addr_max; - bit directed_slv_exokay_valid; + bit [31:0] directed_slv_exokay_addr_min; + bit [31:0] directed_slv_exokay_addr_max; + bit directed_slv_exokay_valid; - bit [31:0] directed_slv_reservation_addr_min; - bit [31:0] directed_slv_reservation_addr_max; - bit directed_slv_reservation_valid; - bit [31:0] directed_slv_nr_reserved_words = 32'b1; + bit [31:0] directed_slv_reservation_addr_min; + bit [31:0] directed_slv_reservation_addr_max; + bit directed_slv_reservation_valid; + bit [31:0] directed_slv_nr_reserved_words = 32'b1; + + rand bit random_err_await_goahead = 0; `uvm_object_utils_begin(uvma_obi_memory_cfg_c) @@ -191,6 +193,7 @@ class uvma_obi_memory_cfg_c extends uvm_object; soft drv_slv_err_mode == UVMA_OBI_MEMORY_DRV_SLV_ERR_MODE_OK; soft drv_slv_err_one_shot_mode == 0; soft drv_slv_exokay_mode == UVMA_OBI_MEMORY_DRV_SLV_EXOKAY_MODE_SUCCESS; + soft random_err_await_goahead == 0; } constraint stall_disable_cons { @@ -335,10 +338,15 @@ function int unsigned uvma_obi_memory_cfg_c::calc_random_rvalid_latency(); endfunction : calc_random_rvalid_latency + function bit uvma_obi_memory_cfg_c::calc_random_err(bit[31:0] addr); bit err; + if (random_err_await_goahead) begin + return 0; + end + // If we are in "one-shot" mode and have already calculated an error, // then skip any new errors (until the code resets the flag) if (drv_slv_err_one_shot_mode && drv_slv_err_one_shot_flag) begin @@ -375,6 +383,7 @@ function bit uvma_obi_memory_cfg_c::calc_random_err(bit[31:0] addr); endfunction : calc_random_err + function bit uvma_obi_memory_cfg_c::calc_random_exokay(bit[31:0] addr, bit is_SCW); bit exokay; diff --git a/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv b/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv index ebf46798c0..484e2f2d40 100644 --- a/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv +++ b/lib/uvm_agents/uvma_obi_memory/src/seq/uvma_obi_memory_slv_base_seq.sv @@ -129,18 +129,21 @@ task uvma_obi_memory_slv_base_seq_c::body(); endtask : body + task uvma_obi_memory_slv_base_seq_c::do_response(ref uvma_obi_memory_mon_trn_c mon_req); `uvm_fatal("OBI_MEMORY_SLV_SEQ", "Call to pure virtual task") endtask : do_response + function void uvma_obi_memory_slv_base_seq_c::add_latencies(uvma_obi_memory_slv_seq_item_c slv_rsp); slv_rsp.rvalid_latency = cfg.calc_random_rvalid_latency(); endfunction : add_latencies + function void uvma_obi_memory_slv_base_seq_c::add_r_fields(uvma_obi_memory_mon_trn_c mon_req, uvma_obi_memory_slv_seq_item_c slv_rsp); // This is just a convenience function @@ -157,12 +160,14 @@ function void uvma_obi_memory_slv_base_seq_c::add_r_fields(uvma_obi_memory_mon_t endfunction : add_r_fields + function void uvma_obi_memory_slv_base_seq_c::add_err(uvma_obi_memory_slv_seq_item_c slv_rsp); slv_rsp.err = cfg.calc_random_err(slv_rsp.orig_trn.address); endfunction : add_err + function void uvma_obi_memory_slv_base_seq_c::add_exokay(uvma_obi_memory_mon_trn_c mon_req, uvma_obi_memory_slv_seq_item_c slv_rsp); if (mon_req.atop[5] != 1'b1 || !(mon_req.atop[4:0] inside {5'h2, 5'h3})) begin @@ -188,6 +193,7 @@ function void uvma_obi_memory_slv_base_seq_c::add_ruser(uvma_obi_memory_slv_seq_ endfunction : add_ruser + function void uvma_obi_memory_slv_base_seq_c::add_rchk(uvma_obi_memory_slv_seq_item_c slv_rsp); if(cfg.chk_scheme == UVMA_OBI_MEMORY_CHK_TIED) begin