diff --git a/.github/workflow_metadata/pr_hash b/.github/workflow_metadata/pr_hash index c02dc341e..f9a72d94b 100644 --- a/.github/workflow_metadata/pr_hash +++ b/.github/workflow_metadata/pr_hash @@ -1 +1 @@ -f3cb8ff4aa4c7b5a753ebf231de215e8ce1934d851bf919332b53f0042fe2e151aa82a4ec67a58e448f1a4ebf2d14d3c \ No newline at end of file +fab6c87e214d418f246590abc80ce5acbff6ab3211181509da704c57546ef46fccefa05b529bb463d06fbf9fefdeee36 \ No newline at end of file diff --git a/.github/workflow_metadata/pr_timestamp b/.github/workflow_metadata/pr_timestamp index 077cc62e9..0a7c2b83f 100644 --- a/.github/workflow_metadata/pr_timestamp +++ b/.github/workflow_metadata/pr_timestamp @@ -1 +1 @@ -1725662210 \ No newline at end of file +1725922621 \ No newline at end of file diff --git a/src/integration/test_suites/libs/soc_ifc/soc_ifc.c b/src/integration/test_suites/libs/soc_ifc/soc_ifc.c index bd890a7bb..38a59154e 100644 --- a/src/integration/test_suites/libs/soc_ifc/soc_ifc.c +++ b/src/integration/test_suites/libs/soc_ifc/soc_ifc.c @@ -236,22 +236,33 @@ void soc_ifc_fw_update(mbox_op_s op) { } uint8_t soc_ifc_sanitize_mbox_n_bytes(uint32_t byte_count, uint32_t attempt_count) { + uint32_t notif_intr_en; if (byte_count > MBOX_DIR_SPAN) { VPRINTF(FATAL, "SOC_IFC: Illegal byte_count 0x%x\n", byte_count); SEND_STDOUT_CTRL(0x1); } - if (soc_ifc_mbox_acquire_lock(attempt_count) != 0) { + if(soc_ifc_mbox_acquire_lock(attempt_count) != 0) { VPRINTF(WARNING, "Failed to acquire lock - mbox sanitize\n"); - lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); - if (soc_ifc_mbox_acquire_lock(1) != 0) { - VPRINTF(FATAL, "FATAL: Failed to acquire lock after force unlock\n"); - return 1; + for(uint32_t ii=1; ii 0; rand_delay < (mbox_op_rand.dlen * 25); } + constraint custom_delay_c { rand_delay > 0; + rand_delay < ((mbox_op_rand.dlen+1) * 25); } endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh index 96ccc2a7b..c8277bedf 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sequence_base.svh @@ -39,11 +39,13 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG int sts_rsp_count; uvm_status_e reg_sts; uvm_event in_report_reg_sts; + process teardown_proc; rand bit do_apb_lock_check; rand bit retry_failed_reg_axs; bit mbox_sts_exp_error = 0; // Indicates this sequence will inject an error, which should manifest as a CMD_FAILURE response status // TODO make this more comprehensive/intelligent about randomized error injection mbox_sts_exp_error_type_e mbox_sts_exp_error_type = EXP_ERR_NONE; // Known error types to expect/handle from test sequences + bit saw_mbox_unlock = 1'b0; int datain_ii = MBOX_SIZE_BYTES/4; // Initialize to max value. This iterator is reset in mbox_push_datain for loop, but is // evaluated against specific offsets for some error checking cases. So give it an // unambiguously invalid init value prior to use. @@ -232,7 +234,7 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG sts_rsp_count = 0; fork - forever begin + while (teardown_proc == null) begin @(soc_ifc_status_agent_rsp_seq.new_rsp) sts_rsp_count++; end join_none @@ -241,6 +243,12 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG mbox_setup(); if (rand_delay_en) do_rand_delay(1, step_delay); mbox_acquire_lock(op_sts); if (rand_delay_en) do_rand_delay(1, step_delay); + fork + while ((teardown_proc == null) && (!saw_mbox_unlock)) begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + saw_mbox_unlock = reg_model.mbox_csr_rm.mbox_unlock.unlock.get_mirrored_value(); + end + join_none mbox_set_cmd(mbox_op_rand); if (rand_delay_en) do_rand_delay(1, step_delay); mbox_push_datain(); if (rand_delay_en) do_rand_delay(1, step_delay); mbox_execute(); if (rand_delay_en) do_rand_delay(1, step_delay); @@ -519,6 +527,8 @@ task soc_ifc_env_mbox_sequence_base::mbox_read_resp_data(); "soc_ifc_env_mbox_reg_axs_invalid_medium_sequence", "soc_ifc_env_mbox_reg_axs_invalid_large_sequence"}) `uvm_info("MBOX_SEQ", $sformatf("SOC received response data with mbox_dlen [%0d] that does not match the expected data amount [%0d]! Not flagging err since this is an invalid reg-access sequence [%s]", dlen, mbox_resp_expected_dlen, this.get_type_name()), UVM_LOW) + else if (saw_mbox_unlock) + `uvm_info("MBOX_SEQ", $sformatf("SOC received response data with mbox_dlen [%0d] that does not match the expected data amount [%0d]! Not flagging err since mbox_unlock was observed", dlen, mbox_resp_expected_dlen), UVM_LOW) else `uvm_error("MBOX_SEQ", $sformatf("SOC received response data with mbox_dlen [%0d] that does not match the expected data amount [%0d]!", dlen, mbox_resp_expected_dlen)) end @@ -552,11 +562,14 @@ task soc_ifc_env_mbox_sequence_base::mbox_poll_status(); do begin do_rand_delay(1, poll_delay); mbox_check_status(data, state); - end while (data == CMD_BUSY && state != MBOX_IDLE); + end while (data == CMD_BUSY && state != MBOX_IDLE && !saw_mbox_unlock); if (state == MBOX_IDLE) begin `uvm_info("MBOX_SEQ", "Detected mailbox state transition to IDLE - was mbox_unlock expected?", UVM_HIGH) end + else if (saw_mbox_unlock) begin + `uvm_info("MBOX_SEQ", "Detected mailbox unlock - was mbox_unlock expected?", UVM_HIGH) + end else if (data == DATA_READY) begin if (mbox_resp_expected_dlen == 0 && sts_rsp_count > 0 && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) begin `uvm_info("MBOX_SEQ", $sformatf("Unexpected status [%p] likely is the result of a spurious reg access injection specifically intended to cause a protocol violation", data), UVM_HIGH) @@ -635,6 +648,7 @@ endtask // Currently just reports PAUSER violation count. //========================================== task soc_ifc_env_mbox_sequence_base::mbox_teardown(); + this.teardown_proc = process::self(); // Summary at sequence end `uvm_info("MBOX_SEQ", $sformatf("Count of mailbox accesses performed with invalid PAUSER: %0d", hit_invalid_pauser_count), UVM_MEDIUM) endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sram_double_bit_flip_small_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sram_double_bit_flip_small_sequence.svh index 37e77b4b1..1f17d6a31 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sram_double_bit_flip_small_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc/soc_ifc_env_mbox_sram_double_bit_flip_small_sequence.svh @@ -37,8 +37,11 @@ class soc_ifc_env_mbox_sram_double_bit_flip_small_sequence extends soc_ifc_env_m // Valid solution for the custom delay ruleset, to control random delays while // waiting to inject random error accesses constraint custom_delay_c { rand_delay > 0; - rand_delay dist {[1 :mbox_op_rand.dlen*2 -1] :/ 250, - [mbox_op_rand.dlen*2 :mbox_op_rand.dlen*5 -1] :/ 100, - [mbox_op_rand.dlen*5 :mbox_op_rand.dlen*15-1] :/ 25}; } + if (mbox_op_rand.dlen == 0) + rand_delay < 25; + else + rand_delay dist {[1 :mbox_op_rand.dlen*2 -1] :/ 250, + [mbox_op_rand.dlen*2 :mbox_op_rand.dlen*5 -1] :/ 100, + [mbox_op_rand.dlen*5 :mbox_op_rand.dlen*15-1] :/ 25}; } endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh index 68f963afa..663963435 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_predictor.svh @@ -53,6 +53,18 @@ class reset_flag extends uvm_object; endclass `endif +`define SOC_IFC_PRED_PULSE_1_CYCLE(pulse_sig) \ + begin \ + pulse_sig = 1'b1; \ + fork \ + begin \ + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); \ + uvm_wait_for_nba_region(); \ + pulse_sig = 1'b0; \ + end \ + join_none \ + end + class soc_ifc_predictor #( type CONFIG_T, type BASE_T = uvm_component @@ -177,14 +189,18 @@ class soc_ifc_predictor #( bit cptra_error_fatal = 1'b0; bit cptra_error_non_fatal = 1'b0; bit fuse_update_enabled = 1'b1; - bit ready_for_fw_push = 1'b0; // TODO - bit ready_for_runtime = 1'b0; - bit mailbox_flow_done = 1'b0; + bit ready_for_fw_push = 1'b0; + bit ready_for_fw_push_fall = 1'b0; + bit ready_for_runtime = 1'b0; + bit ready_for_runtime_fall = 1'b0; + bit mailbox_flow_done = 1'b0; + bit mailbox_flow_done_fall = 1'b0; bit clk_gate_active = 1'b1; // TODO bit rdc_clk_gate_active = 1'b1; bit soc_ifc_clk_gate_active = 1'b1; // TODO - bit mailbox_data_avail = 1'b0; + bit mailbox_data_avail = 1'b0; + bit mailbox_data_avail_fall = 1'b0; int datain_count = 0; int dataout_count = 0; @@ -199,7 +215,8 @@ class soc_ifc_predictor #( bit cptra_in_dbg_or_manuf_mode = 1'b0; int unsigned fw_update_wait_count = 0; - bit [63:0] generic_output_wires = 64'h0; + bit [63:0] generic_output_wires = 64'h0; + bit generic_output_wires_fall = 1'b0; bit [apb5_master_0_params::PAUSER_WIDTH-1:0] mbox_valid_users [6] = '{default: '1}; bit [4:0] mbox_valid_users_locked = 5'b00000; @@ -1169,6 +1186,12 @@ class soc_ifc_predictor #( ((p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fw.get_mirrored_value() != this.ready_for_fw_push) || (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_runtime.get_mirrored_value() != this.ready_for_runtime) || (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.mailbox_flow_done.get_mirrored_value() != this.mailbox_flow_done))) begin + if (this.ready_for_fw_push && !p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fw .get_mirrored_value()) + `SOC_IFC_PRED_PULSE_1_CYCLE(this.ready_for_fw_push_fall) + if (this.ready_for_runtime && !p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_runtime.get_mirrored_value()) + `SOC_IFC_PRED_PULSE_1_CYCLE(this.ready_for_runtime_fall) + if (this.mailbox_flow_done && !p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.mailbox_flow_done.get_mirrored_value()) + `SOC_IFC_PRED_PULSE_1_CYCLE(this.mailbox_flow_done_fall) this.ready_for_fw_push = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fw .get_mirrored_value(); this.ready_for_runtime = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_runtime.get_mirrored_value(); this.mailbox_flow_done = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.mailbox_flow_done.get_mirrored_value(); @@ -1276,12 +1299,16 @@ class soc_ifc_predictor #( endcase send_soc_ifc_sts_txn = data_active != generic_output_wires[31:0]; generic_output_wires = {generic_output_wires[63:32],data_active}; // FIXME for data width? + if (!data_active && |generic_output_wires[31:0] && ~|generic_output_wires[63:32]) + `SOC_IFC_PRED_PULSE_1_CYCLE(generic_output_wires_fall) end end "CPTRA_GENERIC_OUTPUT_WIRES[1]": begin if (ahb_txn.RnW == AHB_WRITE) begin send_soc_ifc_sts_txn = data_active != generic_output_wires[63:32]; generic_output_wires = {data_active,generic_output_wires[31:0]}; // FIXME for data width? + if (!data_active && |generic_output_wires[63:32] && ~|generic_output_wires[31:0]) + `SOC_IFC_PRED_PULSE_1_CYCLE(generic_output_wires_fall) end end "CPTRA_HW_REV_ID": begin @@ -1957,6 +1984,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end end @@ -1966,6 +1994,7 @@ class soc_ifc_predictor #( end else if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end else begin @@ -1982,6 +2011,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end if (apb_txn.read_or_write == APB3_TRANS_WRITE && @@ -2008,6 +2038,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error && mailbox_data_avail) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin @@ -2043,6 +2074,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin @@ -2066,6 +2098,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end // Log the step for coverage @@ -2086,6 +2119,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end // Log the step for coverage @@ -2107,6 +2141,7 @@ class soc_ifc_predictor #( void'(check_mbox_inv_user_error(apb_txn, axs_reg)); if (mailbox_data_avail && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin @@ -2508,8 +2543,9 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); // are sticky else if (mailbox_data_avail && !p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_receive_stage && !p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_done_stage) begin `uvm_info("PRED_DLY", $sformatf("Resetting mailbox_data_avail"), UVM_HIGH) - send_soc_ifc_sts_txn = 1'b1; mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) + send_soc_ifc_sts_txn = 1'b1; end // Write to mbox_status hands control back to SOC // if the status field is updated, the mbox flow has not been @@ -2528,6 +2564,7 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); !p_soc_ifc_rm.mbox_csr_rm.mbox_unlock.unlock.get_mirrored_value() && p_soc_ifc_rm.mbox_csr_rm.mbox_lock.lock.get_mirrored_value()) begin `uvm_info("PRED_DLY", "Observed transition to uc_done_stage after delay job, triggering mailbox_data_avail deassertion", UVM_HIGH) mailbox_data_avail = 1'b0; + `SOC_IFC_PRED_PULSE_1_CYCLE(mailbox_data_avail_fall) send_soc_ifc_sts_txn = 1'b1; end // === soc_ifc_notif_intr_pending === @@ -3129,8 +3166,15 @@ endtask function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_noncore_reset(); + // If the reset occurs in the clock cycle immediately after status signals are deasserted + // by some other cause, the expected transaction is flushed from the scoreboard, but the + // signal deassertion will still be observed at the same time as the reset. + // Thus, generate an expected status transaction for these signals based on falling edges. /* FIXME calculate all of these from the reg-model somehow? */ - return ready_for_fw_push || ready_for_runtime || mailbox_data_avail || |generic_output_wires /*|| trng_req_pending*/; /* only expect a soc_ifc_status_transaction if some signal will transition */ + return ready_for_fw_push || ready_for_fw_push_fall || + ready_for_runtime || ready_for_runtime_fall || + mailbox_data_avail || mailbox_data_avail_fall || + |generic_output_wires || generic_output_wires_fall /*|| trng_req_pending*/; /* only expect a soc_ifc_status_transaction if some signal will transition */ endfunction function bit soc_ifc_predictor::cptra_status_txn_expected_after_noncore_reset();