diff --git a/README.md b/README.md index 9f4c530b9..57084041c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.*_
# **Caliptra Hands-On Guide** # -_*Last Update: 2023/07/28*_ +_*Last Update: 2023/08/24*_ ## **Tools Used** ## diff --git a/Release_Notes.md b/Release_Notes.md index 882e45416..5a7af9ed0 100644 --- a/Release_Notes.md +++ b/Release_Notes.md @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.*_
# **Release Notes** # -_*Last Update: 2023/07/26*_ +_*Last Update: 2023/08/24*_ ## Rev 0p8 ## diff --git a/docs/Caliptra_Integration_Specification.pdf b/docs/Caliptra_Integration_Specification.pdf index 68d970cdb..d58dc68c2 100755 Binary files a/docs/Caliptra_Integration_Specification.pdf and b/docs/Caliptra_Integration_Specification.pdf differ diff --git a/docs/Caliptra_TestPlan.xlsx b/docs/Caliptra_TestPlan.xlsx index 214c77aa3..f93fe7421 100755 Binary files a/docs/Caliptra_TestPlan.xlsx and b/docs/Caliptra_TestPlan.xlsx differ diff --git a/src/aes/config/aes.vf b/src/aes/config/aes.vf index 94fac0674..9592049a5 100644 --- a/src/aes/config/aes.vf +++ b/src/aes/config/aes.vf @@ -21,6 +21,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/aes/config/aes_pkg.vf b/src/aes/config/aes_pkg.vf index 70a3333fc..5c75eb1af 100644 --- a/src/aes/config/aes_pkg.vf +++ b/src/aes/config/aes_pkg.vf @@ -21,6 +21,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/ahb_lite_bus/config/ahb_lite_bus.vf b/src/ahb_lite_bus/config/ahb_lite_bus.vf index 992fbdeb0..86fbbb2e2 100644 --- a/src/ahb_lite_bus/config/ahb_lite_bus.vf +++ b/src/ahb_lite_bus/config/ahb_lite_bus.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv ${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_bus_inf.sv ${CALIPTRA_ROOT}/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv diff --git a/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv b/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv index b5963adcf..017539252 100644 --- a/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv +++ b/src/ahb_lite_bus/rtl/ahb_lite_2to1_mux.sv @@ -29,6 +29,7 @@ module ahb_lite_2to1_mux #( // --------------------------------------- input logic hclk, input logic hreset_n, + input logic force_bus_idle, // --------------------------------------- // From Initiator 0 @@ -81,7 +82,9 @@ module ahb_lite_2to1_mux #( //Initiator 0 always takes priority logic initiator0_address_ph, initiator1_address_ph; +logic initiator0_data_ph_nq, initiator1_data_ph_nq; logic initiator0_data_ph, initiator1_data_ph; +logic initiator0_pend_addr_ph_nq, initiator1_pend_addr_ph_nq; logic initiator0_pend_addr_ph, initiator1_pend_addr_ph; logic initiator0_gnt, initiator1_gnt; logic [AHB_LITE_ADDR_WIDTH-1:0] initiator0_pend_haddr, initiator1_pend_haddr; @@ -94,8 +97,8 @@ logic initiator0_pend_hwrite, initiator1_pend_hwrite; logic initiator0_hwrite, initiator1_hwrite; //Detect address phase -always_comb initiator0_address_ph = hsel_i_0 & hready_i_0 & htrans_i_0 inside {2'b10, 2'b11}; -always_comb initiator1_address_ph = hsel_i_1 & hready_i_1 & htrans_i_1 inside {2'b10, 2'b11}; +always_comb initiator0_address_ph = hsel_i_0 & hready_i_0 & htrans_i_0 inside {2'b10, 2'b11} & ~force_bus_idle; +always_comb initiator1_address_ph = hsel_i_1 & hready_i_1 & htrans_i_1 inside {2'b10, 2'b11} & ~force_bus_idle; always_ff @(posedge hclk or negedge hreset_n) begin if (~hreset_n) begin @@ -107,10 +110,10 @@ always_ff @(posedge hclk or negedge hreset_n) begin initiator1_pend_hsize <= '0; initiator0_pend_hwrite <= '0; initiator1_pend_hwrite <= '0; - initiator0_pend_addr_ph <= '0; - initiator1_pend_addr_ph <= '0; - initiator0_data_ph <= '0; - initiator1_data_ph <= '0; + initiator0_pend_addr_ph_nq <= '0; + initiator1_pend_addr_ph_nq <= '0; + initiator0_data_ph_nq <= '0; + initiator1_data_ph_nq <= '0; end else begin //Capture the address during the address phase for each initiator @@ -124,15 +127,20 @@ always_ff @(posedge hclk or negedge hreset_n) begin initiator1_pend_hwrite <= initiator1_address_ph & ~initiator1_pend_addr_ph ? hwrite_i_1 : initiator1_pend_hwrite; //Capture pending address phase when initiators collide - initiator0_pend_addr_ph <= (initiator0_address_ph | initiator0_pend_addr_ph) & ~(hreadyout_i & initiator0_gnt); - initiator1_pend_addr_ph <= (initiator1_address_ph | initiator1_pend_addr_ph) & ~(hreadyout_i & initiator1_gnt); + initiator0_pend_addr_ph_nq <= (initiator0_address_ph | initiator0_pend_addr_ph) & ~(hreadyout_i & initiator0_gnt); + initiator1_pend_addr_ph_nq <= (initiator1_address_ph | initiator1_pend_addr_ph) & ~(hreadyout_i & initiator1_gnt); //Transition to data phase when endpoint accepts address phase, hold when not ready - initiator0_data_ph <= (initiator0_gnt) | (initiator0_data_ph & ~hreadyout_i); - initiator1_data_ph <= (initiator1_gnt) | (initiator1_data_ph & ~hreadyout_i); + initiator0_data_ph_nq <= (initiator0_gnt) | (initiator0_data_ph & ~hreadyout_i); + initiator1_data_ph_nq <= (initiator1_gnt) | (initiator1_data_ph & ~hreadyout_i); end end +always_comb initiator0_data_ph = initiator0_data_ph_nq & ~force_bus_idle; +always_comb initiator1_data_ph = initiator1_data_ph_nq & ~force_bus_idle; +always_comb initiator0_pend_addr_ph = initiator0_pend_addr_ph_nq & ~force_bus_idle; +always_comb initiator1_pend_addr_ph = initiator1_pend_addr_ph_nq & ~force_bus_idle; + always_comb initiator0_haddr = initiator0_pend_addr_ph ? initiator0_pend_haddr : haddr_i_0; always_comb initiator0_htrans = initiator0_pend_addr_ph ? initiator0_pend_htrans : htrans_i_0; always_comb initiator0_hsize = initiator0_pend_addr_ph ? initiator0_pend_hsize : hsize_i_0; @@ -183,13 +191,13 @@ always_comb hready_o = initiator1_gnt | (initiator1_data_ph & ~initiator0_gnt) ? //Send the data coming from responder when selected always_comb hresp_o_0 = initiator0_data_ph ? hresp_i : '0; always_comb hrdata_o_0 = initiator0_data_ph ? hrdata_i : '0; -always_comb hready_o_0 = initiator0_pend_addr_ph ? '0 : - initiator0_data_ph ? hreadyout_i : '1; +always_comb hready_o_0 = initiator0_data_ph ? hreadyout_i : + initiator0_pend_addr_ph ? '0 : '1; always_comb hresp_o_1 = initiator1_data_ph? hresp_i: '0; always_comb hrdata_o_1 = initiator1_data_ph ? hrdata_i: '0; -always_comb hready_o_1 = initiator1_pend_addr_ph ? '0 : - initiator1_data_ph ? hreadyout_i : '1; +always_comb hready_o_1 = initiator1_data_ph ? hreadyout_i : + initiator1_pend_addr_ph ? '0 : '1; `CALIPTRA_ASSERT_MUTEX(ERR_2TO1MUX_MUTEX_DATA_PH, {initiator0_data_ph,initiator1_data_ph}, hclk, hreset_n) `CALIPTRA_ASSERT_NEVER(ERR_2TO1MUX_BAD_HTRANS, (htrans_o == 2'b01), hclk, hreset_n) diff --git a/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv b/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv index 4a1128e3f..918529300 100644 --- a/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv +++ b/src/ahb_lite_bus/rtl/ahb_lite_address_decoder.sv @@ -27,7 +27,7 @@ module ahb_lite_address_decoder #( // --------------------------------------- input logic hclk, input logic hreset_n, - + input logic force_bus_idle, // --------------------------------------- // From Initiator Interface Port // --------------------------------------- @@ -56,8 +56,6 @@ module ahb_lite_address_decoder #( output logic [NUM_RESPONDERS-1:0][1:0] htrans_o, output logic [NUM_RESPONDERS-1:0][2:0] hsize_o, - input logic force_bus_idle, - // ---------------------------------------------- // Responder Disable // ---------------------------------------------- diff --git a/src/caliptra_prim/config/caliptra_prim.vf b/src/caliptra_prim/config/caliptra_prim.vf index 68537448d..59740aec8 100644 --- a/src/caliptra_prim/config/caliptra_prim.vf +++ b/src/caliptra_prim/config/caliptra_prim.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/csrng/config/csrng.vf b/src/csrng/config/csrng.vf index 91cfc1488..ef06dd886 100644 --- a/src/csrng/config/csrng.vf +++ b/src/csrng/config/csrng.vf @@ -18,6 +18,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/csrng/config/csrng_tb.vf b/src/csrng/config/csrng_tb.vf index 484a8df5f..4793e52ec 100644 --- a/src/csrng/config/csrng_tb.vf +++ b/src/csrng/config/csrng_tb.vf @@ -19,6 +19,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/datavault/config/datavault.vf b/src/datavault/config/datavault.vf index 26a98c56a..829d888e8 100644 --- a/src/datavault/config/datavault.vf +++ b/src/datavault/config/datavault.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/datavault/rtl/dv_defines_pkg.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv ${CALIPTRA_ROOT}/src/datavault/rtl/dv_reg_pkg.sv diff --git a/src/doe/config/doe_cbc_tb.vf b/src/doe/config/doe_cbc_tb.vf index 6feae6b6b..343b1bc45 100644 --- a/src/doe/config/doe_cbc_tb.vf +++ b/src/doe/config/doe_cbc_tb.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/doe/rtl/doe_defines_pkg.sv diff --git a/src/doe/config/doe_core_cbc_tb.vf b/src/doe/config/doe_core_cbc_tb.vf index 2838f10b9..be61bb115 100644 --- a/src/doe/config/doe_core_cbc_tb.vf +++ b/src/doe/config/doe_core_cbc_tb.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/doe/rtl/doe_defines_pkg.sv diff --git a/src/doe/config/doe_ctrl.vf b/src/doe/config/doe_ctrl.vf index e4141e256..09ff0b298 100644 --- a/src/doe/config/doe_ctrl.vf +++ b/src/doe/config/doe_ctrl.vf @@ -13,6 +13,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/doe/rtl/doe_defines_pkg.sv diff --git a/src/ecc/config/compile.yml b/src/ecc/config/compile.yml index afc86d44f..369d1ed2c 100755 --- a/src/ecc/config/compile.yml +++ b/src/ecc/config/compile.yml @@ -59,6 +59,20 @@ targets: - $COMPILE_ROOT/tb/ecc_top_tb.sv tops: [ecc_top_tb] --- +provides: [ecc_montgomerymultiplier_tb] +schema_version: 2.4.0 +requires: + - ecc_top +targets: + tb: + directories: + - $COMPILE_ROOT/tb + files: + - $COMPILE_ROOT/tb/ecc_montgomerymultiplier_tb.sv + tops: [ecc_montgomerymultiplier_tb] + sim: + pre_exec: 'echo "[PRE-EXEC] Copying Mont multiplication test vector to $PWD" && cp $COMPILE_ROOT/tb/test_vectors/mm_test_vectors*.hex .' +--- provides: [ecc_coverage] schema_version: 2.4.0 requires: diff --git a/src/ecc/config/ecc_montgomerymultiplier_tb.vf b/src/ecc/config/ecc_montgomerymultiplier_tb.vf new file mode 100644 index 000000000..0754d8f22 --- /dev/null +++ b/src/ecc/config/ecc_montgomerymultiplier_tb.vf @@ -0,0 +1,81 @@ ++incdir+${CALIPTRA_ROOT}/src/integration/rtl ++incdir+${CALIPTRA_ROOT}/src/libs/rtl ++incdir+${CALIPTRA_ROOT}/src/keyvault/rtl ++incdir+${CALIPTRA_ROOT}/src/pcrvault/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/tb ++incdir+${CALIPTRA_ROOT}/src/sha512/rtl ++incdir+${CALIPTRA_ROOT}/src/sha512_masked/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac/rtl ++incdir+${CALIPTRA_ROOT}/src/hmac_drbg/rtl ++incdir+${CALIPTRA_ROOT}/src/ecc/rtl +${CALIPTRA_ROOT}/src/integration/rtl/config_defines.svh +${CALIPTRA_ROOT}/src/integration/rtl/caliptra_reg_defines.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sva.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_macros.svh +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_sram.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_defines_pkg.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_ahb_srom.sv +${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv +${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv +${CALIPTRA_ROOT}/src/ecc/tb/ecc_montgomerymultiplier_tb.sv +${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg_pkg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_reg.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_fsm.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_read_client.sv +${CALIPTRA_ROOT}/src/keyvault/rtl/kv_write_client.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg_pkg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_reg.sv +${CALIPTRA_ROOT}/src/pcrvault/rtl/pv.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_params_pkg.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_ctrl.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512.sv +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_core.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_h_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_k_constants.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_w_mem.v +${CALIPTRA_ROOT}/src/sha512/rtl/sha512_reg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_defines_pkg.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_core.sv +${CALIPTRA_ROOT}/src/sha512_masked/rtl/sha512_masked_lfsr.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_param_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg_pkg.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_ctrl.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac.sv +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_core.v +${CALIPTRA_ROOT}/src/hmac/rtl/hmac_reg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg.sv +${CALIPTRA_ROOT}/src/hmac_drbg/rtl/hmac_drbg_lfsr.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_defines_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_params_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_uop_pkg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_top.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_reg.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_dsa_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_scalar_blinding.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_hmac_drbg_interface.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_arith_unit.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_ctrl.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pm_sequencer.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_ram_tdp_file.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_fau.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_montgomerymultiplier.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_first.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_pe_final.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_mult_dsp.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_add_sub_mod_alter.sv +${CALIPTRA_ROOT}/src/ecc/rtl/ecc_adder.sv \ No newline at end of file diff --git a/src/ecc/config/ecc_top.vf b/src/ecc/config/ecc_top.vf index 3eb6d8175..51e02138b 100644 --- a/src/ecc/config/ecc_top.vf +++ b/src/ecc/config/ecc_top.vf @@ -18,6 +18,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/ecc/config/ecc_top_tb.vf b/src/ecc/config/ecc_top_tb.vf index fb65558ab..ea081512c 100644 --- a/src/ecc/config/ecc_top_tb.vf +++ b/src/ecc/config/ecc_top_tb.vf @@ -20,6 +20,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/ecc/coverage/ecc_top_cov_if.sv b/src/ecc/coverage/ecc_top_cov_if.sv index 1f41a375b..97f1a8cac 100644 --- a/src/ecc/coverage/ecc_top_cov_if.sv +++ b/src/ecc/coverage/ecc_top_cov_if.sv @@ -39,8 +39,39 @@ interface ecc_top_cov_if logic pubkeyx_input_outofrange; logic pubkeyy_input_outofrange; logic pubkey_input_invalid; + logic pcr_sign_input_invalid; + logic keygen_process; logic signing_process; logic verifying_process; + + + logic mod_p_q; + logic add_en; + logic add_sub_i; + logic [383 : 0] add_res0; + logic add_cout0; + logic add_cout1; + logic add_res_less_than_prime; + logic add_res_greater_than_prime; + logic add_res_greater_than_384_bit; + + logic mult_ready; + logic mult_last_reduction; + logic mult_final_subtraction; + + assign mod_p_q = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.mod_p_q; + assign add_en = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.add_en_i; + assign add_sub_i = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.sub_i; + assign add_res0 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.r0_reg; + assign add_cout0 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.carry0_reg; + assign add_cout1 = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_ADDER_SUBTRACTOR.carry1; + assign add_res_less_than_prime = ((add_cout0 == 1'b0) & (add_res0 < ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.prime_i)); + assign add_res_greater_than_prime = ((add_cout0 == 1'b0) & (add_res0 >= ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.prime_i)); + assign add_res_greater_than_384_bit = (add_cout0 == 1'b1); + + assign mult_ready = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_MULTIPLIER.ready_o; + assign mult_last_reduction = ecc_top.ecc_dsa_ctrl_i.ecc_arith_unit_i.ecc_fau_i.i_MULTIPLIER.last_reduction; + assign mult_final_subtraction = mult_ready & mult_last_reduction; assign ecc_cmd = ecc_top.ecc_dsa_ctrl_i.cmd_reg; assign pcr_sign_mode = ecc_top.ecc_dsa_ctrl_i.pcr_sign_mode; @@ -67,6 +98,8 @@ interface ecc_top_cov_if assign pubkeyx_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyx_input_outofrange; assign pubkeyy_input_outofrange = ecc_top.ecc_dsa_ctrl_i.pubkeyy_input_outofrange; assign pubkey_input_invalid = ecc_top.ecc_dsa_ctrl_i.pubkey_input_invalid; + assign pcr_sign_input_invalid = ecc_top.ecc_dsa_ctrl_i.pcr_sign_input_invalid; + assign keygen_process = ecc_top.ecc_dsa_ctrl_i.keygen_process; assign signing_process = ecc_top.ecc_dsa_ctrl_i.signing_process; assign verifying_process = ecc_top.ecc_dsa_ctrl_i.verifying_process; @@ -90,6 +123,7 @@ interface ecc_top_cov_if pubkeyx_input_outofrange_cp: coverpoint pubkeyx_input_outofrange; pubkeyy_input_outofrange_cp: coverpoint pubkeyy_input_outofrange; pubkey_input_invalid_cp: coverpoint pubkey_input_invalid; + pcr_sign_input_invalid_cp: coverpoint pcr_sign_input_invalid; cmd_ready_cp: cross ecc_sw_cmd, ready; cmd_kv_cp: cross ecc_cmd, dest_keyvault; @@ -99,9 +133,19 @@ interface ecc_top_cov_if zeroize_cmd_cp: cross zeroize, ecc_cmd; zeroize_error_cp: cross zeroize, error_flag; zeroize_ready_cp: cross ready, zeroize; + pcr_sign_input_invalid_cmd_cp: cross error_flag, ecc_cmd; + error_keygen_cp: cross error_flag, keygen_process; error_signing_cp: cross error_flag, signing_process; error_verifying_cp: cross error_flag, verifying_process; + // modular operation + mult_final_subtraction_cp: coverpoint mult_final_subtraction; + add_carry_cp: cross mod_p_q, add_sub_i, add_cout0, add_cout1; + add_result_less_than_prime_cp: cross mod_p_q, add_sub_i, add_res_less_than_prime; + add_result_greater_than_prime_cp: cross mod_p_q, add_sub_i, add_res_greater_than_prime; + add_result_greater_than_384_bit_cp: cross mod_p_q, add_sub_i, add_res_greater_than_384_bit; + + endgroup ecc_top_cov_grp ecc_top_cov_grp1 = new(); diff --git a/src/ecc/rtl/ecc_add_sub_mod_alter.sv b/src/ecc/rtl/ecc_add_sub_mod_alter.sv index d9d6d208c..2bf3eb332 100644 --- a/src/ecc/rtl/ecc_add_sub_mod_alter.sv +++ b/src/ecc/rtl/ecc_add_sub_mod_alter.sv @@ -51,6 +51,7 @@ module ecc_add_sub_mod_alter #( logic carry0_reg; logic carry1; + logic [1 : 0] push_result_reg; ecc_adder #( .RADIX(REG_SIZE) @@ -84,22 +85,31 @@ module ecc_add_sub_mod_alter #( if(!reset_n) begin r0_reg <= '0; carry0_reg <= '0; - ready_o <= 1'b0; end else if (zeroize) begin r0_reg <= '0; carry0_reg <= '0; - ready_o <= 1'b0; end else if (add_en_i) begin r0_reg <= r0; carry0_reg <= carry0; - ready_o <= 1'b0; end - else - ready_o <= 1'b1; end + // Determines when results are ready + always_ff @(posedge clk or negedge reset_n) begin + if (!reset_n) + push_result_reg <= 2'b0; + else if (zeroize) + push_result_reg <= 2'b0; + else if (add_en_i) + push_result_reg <= 2'b10; + else // one shift to right + push_result_reg <= (push_result_reg >> 1); + end + + assign ready_o = push_result_reg[0]; + assign res_o = sub_n ? (carry0_reg ^ carry1)? r1 : r0 : (carry0_reg) ? r0 : r1; endmodule diff --git a/src/ecc/rtl/ecc_dsa_ctrl.sv b/src/ecc/rtl/ecc_dsa_ctrl.sv index 389ee7542..48eb05af2 100644 --- a/src/ecc/rtl/ecc_dsa_ctrl.sv +++ b/src/ecc/rtl/ecc_dsa_ctrl.sv @@ -201,6 +201,7 @@ module ecc_dsa_ctrl logic pubkeyx_input_outofrange; logic pubkeyy_input_outofrange; logic pubkey_input_invalid; + logic pcr_sign_input_invalid; logic error_flag; logic error_flag_reg; @@ -649,7 +650,9 @@ module ecc_dsa_ctrl assign pubkeyy_input_outofrange = verifying_process & (pubkeyy_reg >= PRIME); assign pubkey_input_invalid = verifying_process & (pk_chk_reg != 0); - assign error_flag = privkey_input_outofrange | r_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid; + assign pcr_sign_input_invalid = ((cmd_reg == KEYGEN) | (cmd_reg == VERIFY)) & pcr_sign_mode; + + assign error_flag = privkey_input_outofrange | r_output_outofrange | r_input_outofrange | s_input_outofrange | pubkeyx_input_outofrange | pubkeyy_input_outofrange | pubkey_input_invalid | pcr_sign_input_invalid; //---------------------------------------------------------------- // ECDSA_FSM_flow diff --git a/src/ecc/rtl/ecc_fau.sv b/src/ecc/rtl/ecc_fau.sv index b729cec65..56b82a6ec 100644 --- a/src/ecc/rtl/ecc_fau.sv +++ b/src/ecc/rtl/ecc_fau.sv @@ -51,7 +51,9 @@ module ecc_fau #( reg mult_start; reg mult_start_dly; wire mult_start_edge; - reg add_en; + logic add_start; + logic add_start_dly; + logic add_start_edge; reg sub; logic add_ready_o; @@ -97,7 +99,7 @@ module ecc_fau #( .reset_n(reset_n), .zeroize(zeroize), - .add_en_i(add_en), + .add_en_i(add_start_edge), .sub_i(sub), .opa_i(opa_i), .opb_i(opb_i), @@ -114,34 +116,41 @@ module ecc_fau #( begin if (!reset_n) begin mult_start <= '0; - add_en <= '0; + add_start <= '0; sub <= '0; end else if (zeroize) begin mult_start <= '0; - add_en <= '0; + add_start <= '0; sub <= '0; end else begin mult_start <= mult_en_i; - add_en <= add_en_i; + add_start <= add_en_i; sub <= sub_i; end end always_ff @(posedge clk or negedge reset_n) begin - if (!reset_n) + if (!reset_n) begin mult_start_dly <= '0; - else if (zeroize) + add_start_dly <= '0; + end + else if (zeroize) begin mult_start_dly <= '0; - else + add_start_dly <= '0; + end + else begin mult_start_dly <= mult_start; + add_start_dly <= add_start; + end end assign ready_garbage_bit = add_ready_o & mult_ready_o; // generate a pulse enable for mult assign mult_start_edge = mult_start & ~mult_start_dly; + assign add_start_edge = add_start & ~add_start_dly; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. diff --git a/src/ecc/rtl/ecc_montgomerymultiplier.sv b/src/ecc/rtl/ecc_montgomerymultiplier.sv index df0fb79a2..db767af83 100644 --- a/src/ecc/rtl/ecc_montgomerymultiplier.sv +++ b/src/ecc/rtl/ecc_montgomerymultiplier.sv @@ -100,6 +100,7 @@ module ecc_montgomerymultiplier #( logic [RADIX-1 : 0] last_s_reg; logic [FULL_REG_SIZE-1:0] p_internal; logic [FULL_REG_SIZE-1:0] p_subtracted_internal; + logic last_reduction; //---------------------------------------------------------------- // Processing elements (PEs) @@ -291,8 +292,15 @@ module ecc_montgomerymultiplier #( always_comb sub_b_i[t1] = 1; else always_comb sub_b_i[t1] = sub_b_o[t1 - 1]; - - always_comb sub_b_o[t1] = sub_res[t1][RADIX]; + + always_ff @(posedge clk or negedge reset_n) begin + if (~reset_n) + sub_b_o[t1] <= '0; + else if (zeroize) + sub_b_o[t1] <= '0; + else + sub_b_o[t1] <= sub_res[t1][RADIX]; + end end endgenerate @@ -337,7 +345,8 @@ module ecc_montgomerymultiplier #( end endgenerate - assign p_o = (sub_b_o[2*(PE_UNITS+1)])? p_subtracted_internal[REG_SIZE-1:0] : p_internal[REG_SIZE-1:0]; + always_comb last_reduction = (sub_b_o[2*(PE_UNITS+1)]); + assign p_o = (last_reduction)? p_subtracted_internal[REG_SIZE-1:0] : p_internal[REG_SIZE-1:0]; // Determines when results are ready based on S_NUM always_ff @(posedge clk or negedge reset_n) begin diff --git a/src/ecc/rtl/ecc_pm_ctrl.sv b/src/ecc/rtl/ecc_pm_ctrl.sv index 4d53778ec..0593c5f65 100644 --- a/src/ecc/rtl/ecc_pm_ctrl.sv +++ b/src/ecc/rtl/ecc_pm_ctrl.sv @@ -65,7 +65,7 @@ module ecc_pm_ctrl //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam [7 : 0] MULT_DELAY = 8'd38; //39 -1; + localparam [7 : 0] MULT_DELAY = 8'd39; //40 -1; localparam [7 : 0] ADD_DELAY = 8'd1; // 2 -1; localparam [9 : 0] Secp384_SCA_MONT_COUNT = REG_SIZE[9 : 0] + RND_SIZE[9 : 0]; diff --git a/src/ecc/tb/ecc_montgomerymultiplier_tb.sv b/src/ecc/tb/ecc_montgomerymultiplier_tb.sv index eb11056c5..5fef6665d 100644 --- a/src/ecc/tb/ecc_montgomerymultiplier_tb.sv +++ b/src/ecc/tb/ecc_montgomerymultiplier_tb.sv @@ -22,9 +22,9 @@ //====================================================================== module ecc_montgomerymultiplier_tb #( - parameter OPERAND_WIDTH = 384, - parameter WORD_WIDTH = 32, - parameter TEST_VECTOR_NUM = 102 + parameter OPERAND_WIDTH = 16, + parameter WORD_WIDTH = 4, + parameter TEST_VECTOR_NUM = 5 ) (); @@ -91,6 +91,7 @@ module ecc_montgomerymultiplier_tb #( mm_dut ( .clk (clk_tb), .reset_n (reset_n_tb), + .zeroize (1'b0), .start_i (start_i_tb), .opa_i (opa_i_tb), @@ -317,7 +318,8 @@ module ecc_montgomerymultiplier_tb #( $display(" -= Testbench for mm started =-"); $display(" ==============================\n"); - fname = $sformatf("/home/mojtabab/workspace_aha_poc/ws1/Caliptra/src/ecc/tb/test_vectors/mm_test_vectors_%0d_key_%0d_word_%0d.hex", TEST_VECTOR_NUM, OPERAND_WIDTH, WORD_WIDTH); + fname = $sformatf("mm_test_vectors_%0d_key_%0d_word_%0d.hex", TEST_VECTOR_NUM, OPERAND_WIDTH, WORD_WIDTH); + read_test_vectors(fname); init_sim(); diff --git a/src/ecc/tb/test_vectors/mm_test_vectors_5_key_16_word_4.hex b/src/ecc/tb/test_vectors/mm_test_vectors_5_key_16_word_4.hex new file mode 100644 index 000000000..56ea6deda --- /dev/null +++ b/src/ecc/tb/test_vectors/mm_test_vectors_5_key_16_word_4.hex @@ -0,0 +1,30 @@ +0013 +0d79 +fffb +0d +0000 +0 +0015 +00ff +fff1 +0f +b00c +1 +0026 +e509 +fffb +0d +0000 +2 +c15f +5445 +fff1 +0f +0006 +3 +bfff +2fff +fff1 +0f +002f +4 \ No newline at end of file diff --git a/src/entropy_src/config/entropy_src.vf b/src/entropy_src/config/entropy_src.vf index 128b930d5..f8a916e71 100644 --- a/src/entropy_src/config/entropy_src.vf +++ b/src/entropy_src/config/entropy_src.vf @@ -21,6 +21,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/entropy_src/config/entropy_src_tb.vf b/src/entropy_src/config/entropy_src_tb.vf index e2c40dcf8..f0f720b91 100644 --- a/src/entropy_src/config/entropy_src_tb.vf +++ b/src/entropy_src/config/entropy_src_tb.vf @@ -21,6 +21,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/hmac/config/hmac_ctrl.vf b/src/hmac/config/hmac_ctrl.vf index b618103cb..666c3371f 100644 --- a/src/hmac/config/hmac_ctrl.vf +++ b/src/hmac/config/hmac_ctrl.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/hmac/config/hmac_ctrl_tb.vf b/src/hmac/config/hmac_ctrl_tb.vf index b17fb88cc..1ca5eaa69 100644 --- a/src/hmac/config/hmac_ctrl_tb.vf +++ b/src/hmac/config/hmac_ctrl_tb.vf @@ -18,6 +18,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/hmac_drbg/config/hmac_drbg.vf b/src/hmac_drbg/config/hmac_drbg.vf index 53a97cedd..2e7367213 100644 --- a/src/hmac_drbg/config/hmac_drbg.vf +++ b/src/hmac_drbg/config/hmac_drbg.vf @@ -17,6 +17,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/hmac_drbg/config/hmac_drbg_tb.vf b/src/hmac_drbg/config/hmac_drbg_tb.vf index 5bddc715c..9754c6784 100644 --- a/src/hmac_drbg/config/hmac_drbg_tb.vf +++ b/src/hmac_drbg/config/hmac_drbg_tb.vf @@ -18,6 +18,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/integration/asserts/caliptra_top_sva.sv b/src/integration/asserts/caliptra_top_sva.sv index e717d00b8..19fa0f0f3 100644 --- a/src/integration/asserts/caliptra_top_sva.sv +++ b/src/integration/asserts/caliptra_top_sva.sv @@ -121,14 +121,14 @@ module caliptra_top_sva KV_debug_value0: assert property ( @(posedge `SVA_RDC_CLK) disable iff(!`KEYVAULT_PATH.cptra_pwrgood) - (`KEYVAULT_PATH.flush_keyvault || `SOC_IFC_TOP_PATH.cptra_error_fatal || `CPTRA_TOP_PATH.scan_mode) && (`KEYVAULT_PATH.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value == 0) && `KEYVAULT_PATH.cptra_pwrgood |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword] == CLP_DEBUG_MODE_KV_0) + $rose(~`CPTRA_TOP_PATH.cptra_security_state_Latched.debug_locked || `SOC_IFC_TOP_PATH.cptra_error_fatal || `CPTRA_TOP_PATH.cptra_scan_mode_Latched) && (`KEYVAULT_PATH.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value == 0) && `KEYVAULT_PATH.cptra_pwrgood |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword] == CLP_DEBUG_MODE_KV_0) ) else $display("SVA ERROR: KV not flushed with correct debug values"); KV_debug_value1: assert property ( @(posedge `SVA_RDC_CLK) disable iff(!`KEYVAULT_PATH.cptra_pwrgood) - (`KEYVAULT_PATH.flush_keyvault || `SOC_IFC_TOP_PATH.cptra_error_fatal || `CPTRA_TOP_PATH.scan_mode) && (`KEYVAULT_PATH.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value == 1) && `KEYVAULT_PATH.cptra_pwrgood |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword] == CLP_DEBUG_MODE_KV_1) + $rose(~`CPTRA_TOP_PATH.cptra_security_state_Latched.debug_locked || `SOC_IFC_TOP_PATH.cptra_error_fatal || `CPTRA_TOP_PATH.cptra_scan_mode_Latched) && (`KEYVAULT_PATH.kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value == 1) && `KEYVAULT_PATH.cptra_pwrgood |=> (`KEYVAULT_PATH.kv_reg1.hwif_out.KEY_ENTRY[entry][dword] == CLP_DEBUG_MODE_KV_1) ) else $display("SVA ERROR: KV not flushed with correct debug values"); end @@ -402,7 +402,8 @@ module caliptra_top_sva doe_key_clear: assert property ( @(posedge `DOE_INST_PATH.clk) - `DOE_INST_PATH.zeroize & !`CPTRA_TOP_PATH.cptra_in_debug_scan_mode |=> (`DOE_INST_PATH.core_key == 0) + disable iff(`CPTRA_TOP_PATH.cptra_in_debug_scan_mode) + `DOE_INST_PATH.zeroize |=> (`DOE_INST_PATH.core_key == 0) ) else $display("SVA ERROR: DOE key clear mismatch!"); @@ -501,8 +502,31 @@ module caliptra_top_sva @(posedge `SVA_RDC_CLK) `ECC_PATH.dsa_valid_reg |-> `ECC_PATH.dsa_ready_reg ) - else $display("SVA ERROR: ECC VALID flag mismatch!"); + else $display("SVA ERROR: ECC VALID flag mismatch!"); + //SVA for modular operations + ecc_opa_input: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.add_en_i | `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.mult_en_i) |-> (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.opa_i < `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.prime_i) + ) + else $display("SVA ERROR: ECC opa input is not valid!"); + + ecc_opb_input: assert property ( + @(posedge `SVA_RDC_CLK) + (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.add_en_i | `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.mult_en_i) |-> (`ECC_PATH.ecc_arith_unit_i.ecc_fau_i.opb_i < `ECC_PATH.ecc_arith_unit_i.ecc_fau_i.prime_i) + ) + else $display("SVA ERROR: ECC opb input is not valid!"); + ecc_add_result: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.ecc_arith_unit_i.ecc_instr_s.opcode.add_we |-> (`ECC_PATH.ecc_arith_unit_i.add_res_s < `ECC_PATH.ecc_arith_unit_i.adder_prime) + ) + else $display("SVA ERROR: ECC adder result is not valid!"); + + ecc_mult_result: assert property ( + @(posedge `SVA_RDC_CLK) + `ECC_PATH.ecc_arith_unit_i.ecc_instr_s.opcode.mult_we |-> (`ECC_PATH.ecc_arith_unit_i.mult_res_s < `ECC_PATH.ecc_arith_unit_i.adder_prime) + ) + else $display("SVA ERROR: ECC multiplier result is not valid!"); endmodule diff --git a/src/integration/config/caliptra_top.vf b/src/integration/config/caliptra_top.vf index 34d6e44c3..44074db29 100644 --- a/src/integration/config/caliptra_top.vf +++ b/src/integration/config/caliptra_top.vf @@ -35,6 +35,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/integration/config/caliptra_top_tb.vf b/src/integration/config/caliptra_top_tb.vf index 51dcb7db6..836578fd2 100644 --- a/src/integration/config/caliptra_top_tb.vf +++ b/src/integration/config/caliptra_top_tb.vf @@ -48,6 +48,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/integration/config/caliptra_top_trng_tb.vf b/src/integration/config/caliptra_top_trng_tb.vf index 7ce229833..6e8b39584 100644 --- a/src/integration/config/caliptra_top_trng_tb.vf +++ b/src/integration/config/caliptra_top_trng_tb.vf @@ -48,6 +48,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/integration/rtl/caliptra_reg.h b/src/integration/rtl/caliptra_reg.h index 9d61afdb6..eb10fd96d 100644 --- a/src/integration/rtl/caliptra_reg.h +++ b/src/integration/rtl/caliptra_reg.h @@ -5183,6 +5183,8 @@ #define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (0x1c0) #define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9) #define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (0x200) +#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10) +#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (0x1fffc00) #define CLP_MBOX_CSR_MBOX_UNLOCK (0x30020020) #define MBOX_CSR_MBOX_UNLOCK (0x20) #define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0) @@ -5564,6 +5566,26 @@ #define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK (0x10c) #define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_LOW (0) #define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_MASK (0x1) +#define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_0 (0x30030110) +#define SOC_IFC_REG_CPTRA_WDT_CFG_0 (0x110) +#define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_1 (0x30030114) +#define SOC_IFC_REG_CPTRA_WDT_CFG_1 (0x114) +#define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (0x30030118) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (0x118) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_LOW (0) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_MASK (0xffff) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_LOW (16) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_MASK (0xffff0000) +#define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (0x3003011c) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (0x11c) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_LOW (0) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_MASK (0xffff) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_LOW (16) +#define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_MASK (0xffff0000) +#define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_0 (0x30030120) +#define SOC_IFC_REG_CPTRA_RSVD_REG_0 (0x120) +#define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_1 (0x30030124) +#define SOC_IFC_REG_CPTRA_RSVD_REG_1 (0x124) #define CLP_SOC_IFC_REG_FUSE_UDS_SEED_0 (0x30030200) #define SOC_IFC_REG_FUSE_UDS_SEED_0 (0x200) #define CLP_SOC_IFC_REG_FUSE_UDS_SEED_1 (0x30030204) diff --git a/src/integration/rtl/caliptra_reg_defines.svh b/src/integration/rtl/caliptra_reg_defines.svh index 2fa125816..c7af5ea04 100644 --- a/src/integration/rtl/caliptra_reg_defines.svh +++ b/src/integration/rtl/caliptra_reg_defines.svh @@ -5183,6 +5183,8 @@ `define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (32'h1c0) `define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9) `define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (32'h200) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (32'h1fffc00) `define CLP_MBOX_CSR_MBOX_UNLOCK (32'h30020020) `define MBOX_CSR_MBOX_UNLOCK (32'h20) `define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0) @@ -5564,6 +5566,26 @@ `define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK (32'h10c) `define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_LOW (0) `define SOC_IFC_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_MASK (32'h1) +`define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_0 (32'h30030110) +`define SOC_IFC_REG_CPTRA_WDT_CFG_0 (32'h110) +`define CLP_SOC_IFC_REG_CPTRA_WDT_CFG_1 (32'h30030114) +`define SOC_IFC_REG_CPTRA_WDT_CFG_1 (32'h114) +`define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h30030118) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h118) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_LOW (0) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_MASK (32'hffff) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_LOW (16) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_MASK (32'hffff0000) +`define CLP_SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h3003011c) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h11c) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_LOW (0) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_MASK (32'hffff) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_LOW (16) +`define SOC_IFC_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_MASK (32'hffff0000) +`define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_0 (32'h30030120) +`define SOC_IFC_REG_CPTRA_RSVD_REG_0 (32'h120) +`define CLP_SOC_IFC_REG_CPTRA_RSVD_REG_1 (32'h30030124) +`define SOC_IFC_REG_CPTRA_RSVD_REG_1 (32'h124) `define CLP_SOC_IFC_REG_FUSE_UDS_SEED_0 (32'h30030200) `define SOC_IFC_REG_FUSE_UDS_SEED_0 (32'h200) `define CLP_SOC_IFC_REG_FUSE_UDS_SEED_1 (32'h30030204) diff --git a/src/integration/rtl/caliptra_top.sv b/src/integration/rtl/caliptra_top.sv index b100bcb39..4319daa81 100755 --- a/src/integration/rtl/caliptra_top.sv +++ b/src/integration/rtl/caliptra_top.sv @@ -188,6 +188,8 @@ module caliptra_top logic [6:0] cptra_uncore_dmi_reg_addr; logic [31:0] cptra_uncore_dmi_reg_wdata; security_state_t cptra_security_state_Latched; + security_state_t cptra_security_state_Latched_d; + security_state_t cptra_security_state_Latched_f; logic cptra_dmi_reg_en_preQ; logic fw_update_rst_window; @@ -243,10 +245,11 @@ module caliptra_top logic clear_obf_secrets; logic clear_secrets; - logic cptra_security_state_captured, scan_mode_f, scan_mode_switch; - logic debugUnlock_or_scan_mode_switch, clear_obf_secrets_debugScanQ, cptra_scan_mode_Latched, debug_lock_to_unlock_switch; - var security_state_t security_state_f; - + logic cptra_security_state_captured; + logic scan_mode_switch; + logic debug_lock_or_scan_mode_switch, clear_obf_secrets_debugScanQ, debug_lock_switch; + logic cptra_scan_mode_Latched, cptra_scan_mode_Latched_d, cptra_scan_mode_Latched_f; + logic [TOTAL_OBF_KEY_BITS-1:0] cptra_obf_key_dbg; logic [`CLP_OBF_FE_DWORDS-1 :0][31:0] obf_field_entropy_dbg; logic [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed_dbg; @@ -407,7 +410,7 @@ el2_veer_wrapper rvtop ( .rst_l ( cptra_uc_rst_b), `endif .dbg_rst_l ( cptra_pwrgood), - .clk ( clk ), + .clk ( rdc_clk_cg ), .rst_vec ( reset_vector[31:1]), .nmi_int ( nmi_int ), .nmi_vec ( nmi_vector[31:1]), @@ -553,9 +556,9 @@ el2_veer_wrapper rvtop ( ) u_sb_lsu_ahb_mux ( .hclk (clk_cg), .hreset_n (cptra_noncore_rst_b), - + .force_bus_idle (fw_update_rst_window), // Initiator 0 - .hsel_i_0 (~fw_update_rst_window), + .hsel_i_0 (1'b1 ), .haddr_i_0 (lsu_ahb.haddr ), .hwdata_i_0 (lsu_ahb.hwdata), .hwrite_i_0 (lsu_ahb.hwrite), @@ -567,7 +570,7 @@ el2_veer_wrapper rvtop ( .hrdata_o_0 (lsu_ahb.hrdata), // Initiator 1 - .hsel_i_1 (~fw_update_rst_window), + .hsel_i_1 (1'b1 ), .haddr_i_1 (sb_ahb.haddr ), .hwdata_i_1 (sb_ahb.hwdata ), .hwrite_i_1 (sb_ahb.hwrite ), @@ -594,35 +597,47 @@ el2_veer_wrapper rvtop ( // Security State value captured on a Caliptra reset deassertion (0->1 signal transition) always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin if (~cptra_noncore_rst_b) begin - cptra_security_state_Latched <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; //Setting the default value to be debug locked and in production mode - security_state_f <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; //Setting the default value to be debug locked and in production mode + cptra_security_state_Latched_d <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; //Setting the default value to be debug locked and in production mode + cptra_security_state_Latched_f <= '{device_lifecycle: DEVICE_PRODUCTION, debug_locked: 1'b1}; + cptra_security_state_captured <= 0; - scan_mode_f <= 0; end else if(!cptra_security_state_captured) begin - cptra_security_state_Latched <= security_state; - cptra_scan_mode_Latched <= scan_mode; + cptra_security_state_Latched_d <= security_state; cptra_security_state_captured <= 1; end else begin - // Latched State is different than flopped value of security state - // Latched State is used if we want to open the JTAG and is - // determined to do so only at reset exit time - // Asset flushing happens 'anytime' switch happens for safe side - //security_state_f <= security_state; - security_state_f <= security_state; - scan_mode_f <= scan_mode; + cptra_security_state_Latched_f <= cptra_security_state_Latched_d; + end + end + + always_ff @(posedge clk or negedge cptra_pwrgood) begin + if (~cptra_pwrgood) begin + cptra_scan_mode_Latched_d <= '0; + cptra_scan_mode_Latched_f <= '0; + end + else begin + cptra_scan_mode_Latched_d <= scan_mode; + cptra_scan_mode_Latched_f <= cptra_scan_mode_Latched_d; end end + //Lock debug unless both flops are unlocked + assign cptra_security_state_Latched.debug_locked = cptra_security_state_Latched_d.debug_locked | cptra_security_state_Latched_f.debug_locked; + //Pass on the latched value of device lifecycle + assign cptra_security_state_Latched.device_lifecycle = cptra_security_state_Latched_d.device_lifecycle; + //Only assert scan mode once both flops have set + assign cptra_scan_mode_Latched = cptra_scan_mode_Latched_d & cptra_scan_mode_Latched_f; + // When scan mode goes from 0->1, generate a pulse to clear the assets // Note that when scan goes to '1, Caliptra state as well as SOC state // gets messed up. So switch to scan is destructive (obvious! Duh!) - assign scan_mode_switch = ~scan_mode_f & scan_mode; - // 1->0 transition (Debug locked to unlocked) - assign debug_lock_to_unlock_switch = security_state_f.debug_locked & ~security_state.debug_locked; - assign debugUnlock_or_scan_mode_switch = debug_lock_to_unlock_switch | scan_mode_switch; - assign clear_obf_secrets_debugScanQ = clear_obf_secrets | debugUnlock_or_scan_mode_switch | cptra_error_fatal; + assign scan_mode_switch = cptra_scan_mode_Latched_d & ~cptra_scan_mode_Latched_f; + // Detect transition of debug mode + assign debug_lock_switch = cptra_security_state_Latched_d.debug_locked ^ cptra_security_state_Latched_f.debug_locked; + assign debug_lock_or_scan_mode_switch = debug_lock_switch | scan_mode_switch | cptra_error_fatal; + + assign clear_obf_secrets_debugScanQ = clear_obf_secrets | cptra_in_debug_scan_mode | cptra_error_fatal; //=========================================================================- // Clock gating instance @@ -653,6 +668,7 @@ ahb_lite_2to1_mux #( ) u_ahb_lite_2to1_mux ( .hclk (clk_cg), .hreset_n (cptra_uc_rst_b), + .force_bus_idle (fw_update_rst_window), // From Initiator 0 // Inputs .hsel_i_0 (responder_inst[`CALIPTRA_SLAVE_SEL_IMEM].hsel), @@ -752,7 +768,7 @@ sha512_ctrl #( .error_intr(sha512_error_intr), .notif_intr(sha512_notif_intr), - .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); sha256_ctrl #( @@ -775,11 +791,11 @@ sha256_ctrl #( .error_intr(sha256_error_intr), .notif_intr(sha256_notif_intr), - .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); //override device secrets with debug values in Debug or Scan Mode -always_comb cptra_in_debug_scan_mode = ~security_state.debug_locked | scan_mode; +always_comb cptra_in_debug_scan_mode = ~cptra_security_state_Latched.debug_locked | cptra_scan_mode_Latched; always_comb cptra_obf_key_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_OBF_KEY : cptra_obf_key_reg; always_comb obf_uds_seed_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_UDS_SEED : obf_uds_seed; always_comb obf_field_entropy_dbg = cptra_in_debug_scan_mode ? `CLP_DEBUG_MODE_FIELD_ENTROPY : obf_field_entropy; @@ -810,7 +826,7 @@ doe_ctrl #( .clear_obf_secrets(clear_obf_secrets), //Output .kv_write (kv_write[KV_NUM_WRITE-1]), .kv_wr_resp (kv_wr_resp[KV_NUM_WRITE-1]), - .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); @@ -842,7 +858,7 @@ ecc_top1 .error_intr (ecc_error_intr), .notif_intr (ecc_notif_intr), - .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); hmac_ctrl #( @@ -869,7 +885,7 @@ hmac_ctrl #( .error_intr(hmac_error_intr), .notif_intr(hmac_notif_intr), - .debugUnlock_or_scan_mode_switch(debugUnlock_or_scan_mode_switch) + .debugUnlock_or_scan_mode_switch(debug_lock_or_scan_mode_switch) ); @@ -895,7 +911,8 @@ key_vault1 .hreadyout_o (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hreadyout), .hrdata_o (responder_inst[`CALIPTRA_SLAVE_SEL_KV].hrdata), - .debugUnlock_or_scan_mode_switch (debugUnlock_or_scan_mode_switch | cptra_error_fatal), + .cptra_in_debug_scan_mode(cptra_in_debug_scan_mode), + .debugUnlock_or_scan_mode_switch (debug_lock_or_scan_mode_switch), .kv_read (kv_read), .kv_write (kv_write), @@ -1165,7 +1182,7 @@ soc_ifc_top1 .mailbox_data_avail(mailbox_data_avail), .mailbox_flow_done(mailbox_flow_done), - .security_state(security_state), + .security_state(cptra_security_state_Latched), .BootFSM_BrkPoint (BootFSM_BrkPoint), @@ -1216,7 +1233,7 @@ soc_ifc_top1 .timer_intr(timer_int), //Obfuscated UDS and FE .clear_obf_secrets(clear_obf_secrets_debugScanQ), //input - includes debug & scan modes to do the register clearing - .scan_mode_f(scan_mode_f), + .scan_mode_f(cptra_scan_mode_Latched), .cptra_obf_key(cptra_obf_key), .cptra_obf_key_reg(cptra_obf_key_reg), .obf_field_entropy(obf_field_entropy), diff --git a/src/integration/stimulus/L0_regression.yml b/src/integration/stimulus/L0_regression.yml index 3a2b88fb9..66e8a16fc 100644 --- a/src/integration/stimulus/L0_regression.yml +++ b/src/integration/stimulus/L0_regression.yml @@ -61,3 +61,4 @@ contents: #smoke test jtag #smoke test generic input wire to fw interrupt - ../test_suites/smoke_test_clk_gating/smoke_test_clk_gating.yml + - ../test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.yml diff --git a/src/integration/stimulus/testsuites/uvmf_caliptra_top_nightly_directed_regression.yml b/src/integration/stimulus/testsuites/uvmf_caliptra_top_nightly_directed_regression.yml index bf6df5c6c..5baa312a8 100644 --- a/src/integration/stimulus/testsuites/uvmf_caliptra_top_nightly_directed_regression.yml +++ b/src/integration/stimulus/testsuites/uvmf_caliptra_top_nightly_directed_regression.yml @@ -7,8 +7,8 @@ contents: path: "" config: params: - # 24 hours to help diagnose timeout problem for this test - timeout: 1440 + # 12 hours + timeout: 720 weight: 100 generations: 1 formats: diff --git a/src/integration/stimulus/testsuites/uvmf_caliptra_top_promote_regression.yml b/src/integration/stimulus/testsuites/uvmf_caliptra_top_promote_regression.yml index d4ae686a4..77fcfc323 100644 --- a/src/integration/stimulus/testsuites/uvmf_caliptra_top_promote_regression.yml +++ b/src/integration/stimulus/testsuites/uvmf_caliptra_top_promote_regression.yml @@ -7,9 +7,9 @@ contents: path: "" weight: 100 generations: 1 - # Use seed 1 for the promote test, for consistent results formats: generate: "reseed {template}.yml -seed 1" path: "{template_basename}__1.yml" templates: $CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_cmdline_test : { weight 100 } + #$CALIPTRA_ROOT/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_rand_test : { weight 500 } diff --git a/src/integration/tb/caliptra_top_tb.sv b/src/integration/tb/caliptra_top_tb.sv index dfea071fc..12fbb8487 100755 --- a/src/integration/tb/caliptra_top_tb.sv +++ b/src/integration/tb/caliptra_top_tb.sv @@ -847,7 +847,7 @@ module caliptra_top_tb ( end S_APB_WR_SOC_STEPPING_ID: begin PADDR = `CLP_SOC_IFC_REG_FUSE_SOC_STEPPING_ID; - PWDATA = {16'h0, 16'h1357}; + PWDATA = $urandom(); end S_APB_WR_FUSE_DONE: begin PADDR = `CLP_SOC_IFC_REG_CPTRA_FUSE_WR_DONE; diff --git a/src/integration/tb/caliptra_top_tb_services.sv b/src/integration/tb/caliptra_top_tb_services.sv index 69349e3ff..8534e5660 100644 --- a/src/integration/tb/caliptra_top_tb_services.sv +++ b/src/integration/tb/caliptra_top_tb_services.sv @@ -246,6 +246,7 @@ module caliptra_top_tb_services // 8'he7 - Reset mailbox out-of-order flag when non-fatal error is masked (allows the test to continue) // 8'he8 - Enable scan mode when DOE fsm transitions to done state // 8'he9 - Force dmi_reg_en input to clk gate to emulate JTAG accesses + // 8'hea - Set random values to WDT timer1 and timer2 // 8'heb - Inject fatal error // 8'hec - Inject randomized UDS test vector // 8'hed - Inject randomized FE test vector @@ -832,11 +833,13 @@ endgenerate //IV_NO set_wdt_timer2_period <= 'b0; end else begin - if(caliptra_top_dut.soc_ifc_top1.i_wdt.wdt_timer1_timeout_serviced) begin - set_wdt_timer1_period <= 'b1; - end - if(caliptra_top_dut.soc_ifc_top1.i_wdt.wdt_timer2_timeout_serviced) begin - set_wdt_timer2_period <= 'b1; + if (!UVM_TB) begin + if(caliptra_top_dut.soc_ifc_top1.i_wdt.wdt_timer1_timeout_serviced) begin + set_wdt_timer1_period <= 'b1; + end + if(caliptra_top_dut.soc_ifc_top1.i_wdt.wdt_timer2_timeout_serviced) begin + set_wdt_timer2_period <= 'b1; + end end if(reset_wdt_timer_period) begin set_wdt_timer1_period <= 'b0; @@ -849,15 +852,25 @@ endgenerate //IV_NO if(set_wdt_timer1_period) begin force caliptra_top_dut.soc_ifc_top1.timer1_timeout_period = 64'hFFFFFFFF_FFFFFFFF; end - else begin + else if(reset_wdt_timer_period) begin release caliptra_top_dut.soc_ifc_top1.timer1_timeout_period; end + if(set_wdt_timer2_period) begin force caliptra_top_dut.soc_ifc_top1.timer2_timeout_period = 64'hFFFFFFFF_FFFFFFFF; end - else begin + else if(reset_wdt_timer_period) begin release caliptra_top_dut.soc_ifc_top1.timer2_timeout_period; end + + end + + always @(negedge clk) begin + if((WriteData[7:0] == 8'hea) && mailbox_write) begin + force caliptra_top_dut.soc_ifc_top1.timer1_timeout_period = {32'h0000_0000, $urandom_range(32'h0000_0001,32'h0000_0FFF)}; + force caliptra_top_dut.soc_ifc_top1.timer2_timeout_period = {32'h0000_0000, $urandom_range(32'h0000_0001,32'h0000_0FFF)}; + end + //Use 'hF1 code to reset these values in the test end diff --git a/src/integration/test_suites/caliptra_fmc/caliptra_isr.h b/src/integration/test_suites/caliptra_fmc/caliptra_isr.h index 8f5779e04..542d6572b 100644 --- a/src/integration/test_suites/caliptra_fmc/caliptra_isr.h +++ b/src/integration/test_suites/caliptra_fmc/caliptra_isr.h @@ -185,6 +185,14 @@ inline void service_soc_ifc_error_intr() { *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_MASK; + } if (sts == 0) { VPRINTF(ERROR,"bad soc_ifc_error_intr sts:%x\n", sts); SEND_STDOUT_CTRL(0x1); diff --git a/src/integration/test_suites/caliptra_rt/caliptra_rt.c b/src/integration/test_suites/caliptra_rt/caliptra_rt.c index 8cf4bd655..64dfe16cb 100644 --- a/src/integration/test_suites/caliptra_rt/caliptra_rt.c +++ b/src/integration/test_suites/caliptra_rt/caliptra_rt.c @@ -92,6 +92,12 @@ void nmi_handler() { SEND_STDOUT_CTRL(0x1); } } + else { + VPRINTF(LOW, "In NMI handler\n"); + if (lsu_read_32(CLP_SOC_IFC_REG_CPTRA_HW_ERROR_FATAL) & SOC_IFC_REG_CPTRA_HW_ERROR_FATAL_NMI_PIN_MASK) + VPRINTF(LOW, "Saw hw_error_fatal.nmi_pin assertion\n"); + while(1); + } } void caliptra_rt() { @@ -107,6 +113,12 @@ void caliptra_rt() { uint32_t loop_iter; uint32_t temp; // multi-purpose variable + //WDT vars + int i; + int wdt_rand_t1_val; + int wdt_rand_t2_val; + int mode; + VPRINTF(MEDIUM, "----------------------------------\n"); VPRINTF(LOW, "- Caliptra Validation RT!!\n" ); VPRINTF(MEDIUM, "----------------------------------\n"); @@ -117,8 +129,47 @@ void caliptra_rt() { // Runtime flow -- set ready for RT soc_ifc_set_flow_status_field(SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_RUNTIME_MASK); + VPRINTF(LOW, "Enabling WDT intr\n"); + lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R, SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER1_TIMEOUT_EN_MASK | SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTR_EN_R_ERROR_WDT_TIMER2_TIMEOUT_EN_MASK); + lsu_write_32(CLP_SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R, SOC_IFC_REG_INTR_BLOCK_RF_GLOBAL_INTR_EN_R_ERROR_EN_MASK); + + wdt_rand_t1_val = rand() % 0xfff; + wdt_rand_t2_val = rand() % 0xfff; + mode = rand() % 2; //0 - independent mode, 1 - cascade mode + if (mode){ + VPRINTF(LOW, "Restarting WDT in cascade mode (only t1 timeout)\n"); + //TODO also add t2 timeout (NMI event) + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN, SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, wdt_rand_t1_val); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0x00000000); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK); + } + else { + VPRINTF(LOW, "Restarting WDT in independent mode\n"); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_EN, SOC_IFC_REG_CPTRA_WDT_TIMER1_EN_TIMER1_EN_MASK); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, wdt_rand_t1_val); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0x00000000); + + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_EN, SOC_IFC_REG_CPTRA_WDT_TIMER2_EN_TIMER2_EN_MASK); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0, wdt_rand_t2_val); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1, 0x00000000); + + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_MASK); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL, SOC_IFC_REG_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_MASK); + + while (!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T1_TIMEOUT_MASK)); + //Reset timer period to avoid hangs in test + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_0, 0xffffffff); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER1_TIMEOUT_PERIOD_1, 0xffffffff); + + while (!(lsu_read_32(CLP_SOC_IFC_REG_CPTRA_WDT_STATUS) & SOC_IFC_REG_CPTRA_WDT_STATUS_T2_TIMEOUT_MASK)); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_0, 0xffffffff); + lsu_write_32(CLP_SOC_IFC_REG_CPTRA_WDT_TIMER2_TIMEOUT_PERIOD_1, 0xffffffff); + + } // Initialization init_interrupts(); + lsu_write_32(CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTR_EN_R, 0); // FIXME tmp workaround to UVM issue with predicting SHA accelerator interrupts while(1) { // Service received interrupts @@ -132,7 +183,13 @@ void caliptra_rt() { cptra_intr_rcv.soc_ifc_error &= ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK; } if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { + enum mbox_fsm_e state; cptra_intr_rcv.soc_ifc_error &= ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + // If we entered the error state, we must use force-unlock to reset the mailbox state + state = (lsu_read_32(CLP_MBOX_CSR_MBOX_STATUS) & MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK) >> MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_LOW; + if (state == MBOX_ERROR) { + lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); + } } if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK) { cptra_intr_rcv.soc_ifc_error &= ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK; @@ -212,9 +269,24 @@ void caliptra_rt() { } if (cptra_intr_rcv.soc_ifc_notif ) { + uint8_t fsm_chk; VPRINTF(LOW, "Intr received: soc_ifc_notif\n"); if (cptra_intr_rcv.soc_ifc_notif & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) { cptra_intr_rcv.soc_ifc_notif &= ~SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK; + fsm_chk = soc_ifc_chk_execute_uc(); + if (fsm_chk != 0) { + if (fsm_chk == 0xF) { + if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { + cptra_intr_rcv.soc_ifc_error &= ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit after servicing\n"); + } else { + VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n"); + SEND_STDOUT_CTRL(0x1); + while(1); + } + } + continue; + } //read the mbox command op = soc_ifc_read_mbox_cmd(); if (op.cmd & MBOX_CMD_FIELD_FW_MASK) { @@ -294,17 +366,57 @@ void caliptra_rt() { } + fsm_chk = soc_ifc_chk_execute_uc(); + if (fsm_chk != 0) { + if (fsm_chk == 0xF) { + if (cptra_intr_rcv.soc_ifc_error & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { + cptra_intr_rcv.soc_ifc_error &= ~SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + VPRINTF(LOW, "Clearing FW soc_ifc_error intr bit after servicing\n"); + } else { + VPRINTF(ERROR, "After finding an error and resetting the mailbox with force unlock, RT firmware has not received an soc_ifc_err_intr!\n"); + SEND_STDOUT_CTRL(0x1); + while(1); + } + } + continue; + } soc_ifc_set_mbox_status_field(DATA_READY); } else { VPRINTF(MEDIUM, "Received mailbox command (no expected RESP) from SOC! Got 0x%x\n", op.cmd); + VPRINTF(MEDIUM, "Got command with DLEN 0x%x\n", op.dlen); + //Command to exercise direct read path to mailbox + if (op.cmd == MBOX_CMD_DIR_RD) { + // Read provided data through direct path + for (loop_iter = 0; loop_iter> MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_LOW; + if (state == MBOX_EXECUTE_UC) { + VPRINTF(HIGH,"SOC_IFC: Check mbox_status.mbox_fsm_ps found MBOX_EXECUTE_UC\n"); + return 0; + } else if (state == MBOX_IDLE) { + VPRINTF(WARNING,"SOC_IFC: Check mbox_status.mbox_fsm_ps found MBOX_IDLE\n"); + return 1; + } else if (state == MBOX_ERROR) { + VPRINTF(ERROR,"SOC_IFC: Check mbox_status.mbox_fsm_ps found MBOX_ERROR, executing mailbox force-unlock\n"); + lsu_write_32(CLP_MBOX_CSR_MBOX_UNLOCK, MBOX_CSR_MBOX_UNLOCK_UNLOCK_MASK); + return 0xF; + } else { + VPRINTF(FATAL,"SOC_IFC: Check mbox_status.mbox_fsm_ps found unexpected state 0x%x\n", state); + return 0xFF; + } +} + void soc_ifc_set_mbox_status_field(enum mbox_status_e field) { VPRINTF(MEDIUM,"SOC_IFC: Set mbox_status field: 0x%x\n", field); uint32_t reg; diff --git a/src/integration/test_suites/libs/soc_ifc/soc_ifc.h b/src/integration/test_suites/libs/soc_ifc/soc_ifc.h index df90343e4..488fb7c89 100644 --- a/src/integration/test_suites/libs/soc_ifc/soc_ifc.h +++ b/src/integration/test_suites/libs/soc_ifc/soc_ifc.h @@ -57,6 +57,7 @@ enum { }; enum mbox_cmd_e { + MBOX_CMD_DIR_RD = 0x01000000, MBOX_CMD_UC_BASIC = 0x20000000, MBOX_CMD_UC_OVERRUN = 0x20000001, MBOX_CMD_RESP_BASIC = 0x40000000, @@ -93,7 +94,11 @@ enum sha_accel_mode_e { inline uint32_t soc_ifc_mbox_read_dataout_single() { return lsu_read_32(CLP_MBOX_CSR_MBOX_DATAOUT); } +inline uint32_t soc_ifc_mbox_dir_read_dataout_single(uint32_t rdptr) { + return lsu_read_32(0x30000000 + rdptr); +} void soc_ifc_clear_execute_reg(); +uint8_t soc_ifc_chk_execute_uc(); void soc_ifc_set_mbox_status_field(enum mbox_status_e field); void soc_ifc_set_flow_status_field(uint32_t field); void soc_ifc_clr_flow_status_field(uint32_t field); diff --git a/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c b/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c index e92734cdd..d6d358ca7 100644 --- a/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c +++ b/src/integration/test_suites/smoke_test_ecc_errortrigger/smoke_test_ecc_errortrigger.c @@ -219,6 +219,7 @@ void main() { uint8_t offset; volatile uint32_t * reg_ptr; + uint8_t privkey_inject_cmd; if(rst_count == 0) { @@ -461,7 +462,7 @@ void main() { //inject seed to kv key reg (in RTL) printf("Inject PRIVKEY into KV slot 7\n"); - uint8_t privkey_inject_cmd = 0x88 + 0x7; + privkey_inject_cmd = 0x88 + 0x7; printf("%c", privkey_inject_cmd); printf("Inject MSG into SHA512 digest\n"); @@ -482,8 +483,87 @@ void main() { } ecc_zeroize(); + //Issue warm reset + rst_count++; + printf("%c",0xf6); } + else if(rst_count == 7) { + // wait for ECC to be ready + while((lsu_read_32(CLP_ECC_REG_ECC_STATUS) & ECC_REG_ECC_STATUS_READY_MASK) == 0); + + printf("\n TEST PCR WITH INVALID INPUT COMMAND\n"); + + // Program ECC IV + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_IV_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_IV_11) { + *reg_ptr++ = ecc_iv[offset++]; + } + + //inject seed to kv key reg (in RTL) + printf("Inject PRIVKEY into KV slot 7\n"); + privkey_inject_cmd = 0x88 + 0x7; + printf("%c", privkey_inject_cmd); + + printf("Inject MSG into SHA512 digest\n"); + printf("%c", 0x90); + + // Enable ECC PCR KEYGEN core + printf("\nECC PCR KEYGEN\n"); + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_KEYGEN | + ((1 << ECC_REG_ECC_CTRL_PCR_SIGN_LOW) & ECC_REG_ECC_CTRL_PCR_SIGN_MASK)); + + + // wait for ECC KEYGEN process to be done + wait_for_ecc_intr(); + if ((cptra_intr_rcv.ecc_error == 0)){ + printf("\nECC PCR invalid command error is not detected.\n"); + printf("%c", 0x1); + while(1); + } + + ecc_zeroize(); + //Issue warm reset + rst_count++; + printf("%c",0xf6); + } + else if(rst_count == 8) { + // wait for ECC to be ready + while((lsu_read_32(CLP_ECC_REG_ECC_STATUS) & ECC_REG_ECC_STATUS_READY_MASK) == 0); + + printf("\n TEST PCR WITH INVALID INPUT COMMAND\n"); + + // Program ECC IV + reg_ptr = (uint32_t*) CLP_ECC_REG_ECC_IV_0; + offset = 0; + while (reg_ptr <= (uint32_t*) CLP_ECC_REG_ECC_IV_11) { + *reg_ptr++ = ecc_iv[offset++]; + } + + //inject seed to kv key reg (in RTL) + printf("Inject PRIVKEY into KV slot 7\n"); + privkey_inject_cmd = 0x88 + 0x7; + printf("%c", privkey_inject_cmd); + + printf("Inject MSG into SHA512 digest\n"); + printf("%c", 0x90); + + // Enable ECC PCR VERIFYING core + printf("\nECC PCR VERIFYING\n"); + lsu_write_32(CLP_ECC_REG_ECC_CTRL, ECC_CMD_VERIFYING | + ((1 << ECC_REG_ECC_CTRL_PCR_SIGN_LOW) & ECC_REG_ECC_CTRL_PCR_SIGN_MASK)); + + // wait for ECC VERIFYING process to be done + wait_for_ecc_intr(); + if ((cptra_intr_rcv.ecc_error == 0)){ + printf("\nECC PCR invalid command error is not detected.\n"); + printf("%c", 0x1); + while(1); + } + + ecc_zeroize(); + } printf("%c",0xff); //End the test diff --git a/src/integration/test_suites/smoke_test_iccm_reset/caliptra_isr.h b/src/integration/test_suites/smoke_test_iccm_reset/caliptra_isr.h new file mode 100644 index 000000000..8f5779e04 --- /dev/null +++ b/src/integration/test_suites/smoke_test_iccm_reset/caliptra_isr.h @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// +// --------------------------------------------------------------------- +// File: caliptra_isr.h +// Description: +// Provides function declarations for use by external test files, so +// that the ISR functionality may behave like a library. +// TODO: +// This header file includes inline function definitions for event and +// test specific interrupt service behavior, so it should be copied and +// modified for each test. +// --------------------------------------------------------------------- + +#ifndef CALIPTRA_ISR_H + #define CALIPTRA_ISR_H + +#define EN_ISR_PRINTS 1 + +#include "caliptra_defines.h" +#include +#include "printf.h" + +/* --------------- symbols/typedefs --------------- */ +typedef struct { + uint32_t doe_error; + uint32_t doe_notif; + uint32_t ecc_error; + uint32_t ecc_notif; + uint32_t hmac_error; + uint32_t hmac_notif; + uint32_t kv_error; + uint32_t kv_notif; + uint32_t sha512_error; + uint32_t sha512_notif; + uint32_t sha256_error; + uint32_t sha256_notif; + uint32_t qspi_error; + uint32_t qspi_notif; + uint32_t uart_error; + uint32_t uart_notif; + uint32_t i3c_error; + uint32_t i3c_notif; + uint32_t soc_ifc_error; + uint32_t soc_ifc_notif; + uint32_t sha512_acc_error; + uint32_t sha512_acc_notif; +} caliptra_intr_received_s; +extern volatile caliptra_intr_received_s cptra_intr_rcv; + +////////////////////////////////////////////////////////////////////////////// +// Function Declarations +// + +// Performs all the CSR setup to configure and enable vectored external interrupts +void init_interrupts(void); + +// These inline functions are used to insert event-specific functionality into the +// otherwise generic ISR that gets laid down by the parameterized macro "nonstd_veer_isr" +inline void service_doe_error_intr() {return;} +inline void service_doe_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.doe_notif |= DOE_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad doe_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_ecc_error_intr() {return;} +inline void service_ecc_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.ecc_notif |= ECC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad ecc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_hmac_error_intr() {return;} +inline void service_hmac_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.hmac_notif |= HMAC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad hmac_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_kv_error_intr() {return;} +inline void service_kv_notif_intr() {return;} +inline void service_sha512_error_intr() {return;} +inline void service_sha512_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha512_notif |= SHA512_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha512_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_sha256_error_intr() {return;} +inline void service_sha256_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha256_notif |= SHA256_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha256_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_qspi_error_intr() {return;} +inline void service_qspi_notif_intr() {return;} +inline void service_uart_error_intr() {return;} +inline void service_uart_notif_intr() {return;} +inline void service_i3c_error_intr() {return;} +inline void service_i3c_notif_intr() {return;} + +inline void service_soc_ifc_error_intr() { + uint32_t * reg = (uint32_t *) (CLP_SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INTERNAL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_INV_DEV_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_CMD_FAIL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_BAD_FUSE_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_ICCM_BLOCKED_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; + cptra_intr_rcv.soc_ifc_error |= SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_MBOX_ECC_UNC_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad soc_ifc_error_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_soc_ifc_notif_intr () { + uint32_t * reg = (uint32_t *) (CLP_SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_AVAIL_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_MBOX_ECC_COR_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_DEBUG_LOCKED_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SCAN_MODE_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_SOC_REQ_LOCK_STS_MASK; + } + if (sts & SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK) { + *reg = SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK; + cptra_intr_rcv.soc_ifc_notif |= SOC_IFC_REG_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_GEN_IN_TOGGLE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad soc_ifc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + +inline void service_sha512_acc_error_intr() {return;} +inline void service_sha512_acc_notif_intr() { + uint32_t * reg = (uint32_t *) (CLP_SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R); + uint32_t sts = *reg; + /* Write 1 to Clear the pending interrupt */ + if (sts & SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK) { + *reg = SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + cptra_intr_rcv.sha512_acc_notif |= SHA512_ACC_CSR_INTR_BLOCK_RF_NOTIF_INTERNAL_INTR_R_NOTIF_CMD_DONE_STS_MASK; + } + if (sts == 0) { + VPRINTF(ERROR,"bad sha512_acc_notif_intr sts:%x\n", sts); + SEND_STDOUT_CTRL(0x1); + while(1); + } +} + + +#endif //CALIPTRA_ISR_H diff --git a/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.c b/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.c new file mode 100644 index 000000000..c1c3ef473 --- /dev/null +++ b/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// + +#include "caliptra_defines.h" +#include "caliptra_isr.h" +#include "riscv-csr.h" +#include +#include +#include "printf.h" + +volatile char* stdout = (char *)STDOUT; +volatile uint32_t intr_count = 0; +volatile uint32_t rst_count __attribute__((section(".dccm.persistent"))) = 0; +volatile uint32_t iter __attribute__((section(".dccm.persistent"))) = 0; +#ifdef CPT_VERBOSITY + enum printf_verbosity verbosity_g = CPT_VERBOSITY; +#else + enum printf_verbosity verbosity_g = LOW; +#endif + +volatile caliptra_intr_received_s cptra_intr_rcv = { + .doe_error = 0, + .doe_notif = 0, + .ecc_error = 0, + .ecc_notif = 0, + .hmac_error = 0, + .hmac_notif = 0, + .kv_error = 0, + .kv_notif = 0, + .sha512_error = 0, + .sha512_notif = 0, + .sha256_error = 0, + .sha256_notif = 0, + .qspi_error = 0, + .qspi_notif = 0, + .uart_error = 0, + .uart_notif = 0, + .i3c_error = 0, + .i3c_notif = 0, + .soc_ifc_error = 0, + .soc_ifc_notif = 0, + .sha512_acc_error = 0, + .sha512_acc_notif = 0, +}; + +extern uintptr_t iccm_code0_start, iccm_code0_end; +volatile uint32_t * soc_ifc_fw_update_reset = (uint32_t *) (CLP_SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET); +void exec_iccm (void) __attribute__ ((aligned(4),section (".data_iccm0"))); + +void main() { + uint32_t * ICCM = (uint32_t *) RV_ICCM_SADR; + uint32_t * code_word = 0; + uint32_t * iccm_dest = ICCM; + void (* iccm_fn) (void) = (void*) ICCM; + VPRINTF(LOW,"---------------------------\n"); + VPRINTF(LOW," Smoke test ICCM/DCCM + reset !!\n"); + VPRINTF(LOW,"---------------------------\n"); + + rst_count++; + + //Call interrupt init + init_interrupts(); + if(rst_count == 1) { + + code_word = (uint32_t *) &iccm_code0_start; + VPRINTF(LOW, "Copying code from %x [through %x] to %x\n", (uintptr_t) code_word, &iccm_code0_end, (uintptr_t) iccm_dest); + while (code_word < (uint32_t *) &iccm_code0_end) { + VPRINTF(ALL, "at %x: %x\n", (uintptr_t) code_word, *code_word); + *iccm_dest++ = *code_word++; + } + + VPRINTF(LOW, "Execute function from ICCM\n"); + iccm_fn(); + + //Issue warm reset + VPRINTF(LOW, "Issue warm reset\n"); + SEND_STDOUT_CTRL(0xf6); + } + else if(rst_count == 2) { + VPRINTF(LOW, "Execute function from ICCM after warm reset\n"); + iccm_fn(); + + //Issue cold reset + VPRINTF(LOW, "Issue cold reset\n"); + SEND_STDOUT_CTRL(0xf5); + + } + else if(rst_count == 3) { + VPRINTF(LOW, "Execute function from ICCM after cold reset\n"); + iccm_fn(); + + //Issue fw update reset + VPRINTF(LOW, "Issue core only reset\n"); + *soc_ifc_fw_update_reset = SOC_IFC_REG_INTERNAL_FW_UPDATE_RESET_CORE_RST_MASK; + } + else if (rst_count == 4) { + VPRINTF(LOW, "Execute function from ICCM after core reset\n"); + iccm_fn(); + } + + return; +} + +void exec_iccm (void) { + VPRINTF (LOW, "In exec_iccm function, before incrementing = %d\n", iter); + iter++; + VPRINTF (LOW, "In exec_iccm function, after incrementing = %d\n", iter); +} diff --git a/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.yml b/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.yml new file mode 100644 index 000000000..206f00d19 --- /dev/null +++ b/src/integration/test_suites/smoke_test_iccm_reset/smoke_test_iccm_reset.yml @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# +--- +seed: 1 +testname: smoke_test_iccm_reset \ No newline at end of file diff --git a/src/integration/uvmf_caliptra_top/config/compile.yml b/src/integration/uvmf_caliptra_top/config/compile.yml index 1a022de2a..a6eaa74e2 100644 --- a/src/integration/uvmf_caliptra_top/config/compile.yml +++ b/src/integration/uvmf_caliptra_top/config/compile.yml @@ -78,3 +78,44 @@ global: - '-sv_lib libapb3_IN_SystemVerilog_VCS_full' # Report "MVC_ERROR" as "UVM_ERROR" - '+QVIP_UVM_REPORTING' +--- +provides: [uvmf_caliptra_top_itrng] +schema_version: 2.4.0 +requires: + - uvmf_caliptra_top +targets: + tb: + tops: + - hdl_top + - hvl_top + sim: + pre_exec: | + echo "[PRE-EXEC] Copying SHA512 Vectors to $(pwd)" + cp ${COMPILE_ROOT}/../tb/vectors/SHA*.rsp . + $TOOLS/scripts/run_test_makefile +global: + tool: + vcs: + default: + - '-assert svaext' + - +define+CLP_ASSERT_ON + - '-noinherit_timescale=1ns/1ps' + - '+define+CALIPTRA_INTERNAL_TRNG' + # Suppress a warning due to calling $fgets as task instead of function + # i.e. discarding the return value. This is in auto-generated code. + - '+warn=noRVOSFD' + # Suppress NOTE about repeated package imports within the same + # package (each .svh file included in the auto-generated UVM _pkg.sv + # files imports the same dependencies) + - '-suppress=SV-LCM-PPWI' + elab: + # Suppress warnings about too few port connections - auto-generated interfaces + # declare all signals as inout, but are driven at a lower layer than the + # instantiation, so they will always flag this + - '-suppress=TFIPC' + sim: + - '-sv_root $QUESTA_MVC_HOME/questa_mvc_core/linux_x86_64_gcc-6.2.0_vcs' + - '-sv_lib libahb_IN_SystemVerilog_VCS_full' + - '-sv_lib libapb3_IN_SystemVerilog_VCS_full' + # Report "MVC_ERROR" as "UVM_ERROR" + - '+QVIP_UVM_REPORTING' diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv index 5652f4e6b..514477d8f 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/parameters/caliptra_top_parameters_pkg.sv @@ -45,6 +45,7 @@ package caliptra_top_parameters_pkg; parameter string soc_ifc_subenv_cptra_ctrl_agent_BFM = "soc_ifc_subenv_cptra_ctrl_agent_BFM"; /* [3] */ parameter string soc_ifc_subenv_soc_ifc_status_agent_BFM = "soc_ifc_subenv_soc_ifc_status_agent_BFM"; /* [4] */ parameter string soc_ifc_subenv_cptra_status_agent_BFM = "soc_ifc_subenv_cptra_status_agent_BFM"; /* [5] */ + parameter string soc_ifc_subenv_mbox_sram_agent_BFM = "soc_ifc_subenv_mbox_sram_agent_BFM"; /* [6] */ // pragma uvmf custom package_item_additional begin // pragma uvmf custom package_item_additional end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv index 93d8bb71e..b045cc380 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/caliptra_top_sequences_pkg.sv @@ -47,6 +47,8 @@ package caliptra_top_sequences_pkg; import soc_ifc_status_pkg_hdl::*; import cptra_status_pkg::*; import cptra_status_pkg_hdl::*; + import mbox_sram_pkg::*; + import mbox_sram_pkg_hdl::*; import caliptra_top_parameters_pkg::*; import caliptra_top_env_pkg::*; import qvip_ahb_lite_slave_params_pkg::*; @@ -70,6 +72,7 @@ package caliptra_top_sequences_pkg; `include "src/caliptra_top_rand_sequence.svh" `include "src/caliptra_top_cmdline_sequence.svh" `include "src/caliptra_top_rom_sequence.svh" + `include "src/caliptra_top_wdt_sequence.svh" // pragma uvmf custom package_item_additional end endpackage diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_bench_sequence_base.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_bench_sequence_base.svh index d0303bd74..cf13af914 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_bench_sequence_base.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_bench_sequence_base.svh @@ -57,6 +57,8 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq; typedef soc_ifc_status_responder_sequence soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t; soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + typedef mbox_sram_responder_sequence soc_ifc_subenv_mbox_sram_agent_responder_seq_t; + soc_ifc_subenv_mbox_sram_agent_responder_seq_t soc_ifc_subenv_mbox_sram_agent_responder_seq; // pragma uvmf custom sequences end // Sequencer handles for each active interface in the environment @@ -64,6 +66,8 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; uvm_sequencer #(soc_ifc_subenv_soc_ifc_ctrl_agent_transaction_t) soc_ifc_subenv_soc_ifc_ctrl_agent_sequencer; typedef soc_ifc_status_transaction soc_ifc_subenv_soc_ifc_status_agent_transaction_t; uvm_sequencer #(soc_ifc_subenv_soc_ifc_status_agent_transaction_t) soc_ifc_subenv_soc_ifc_status_agent_sequencer; + typedef mbox_sram_transaction soc_ifc_subenv_mbox_sram_agent_transaction_t; + uvm_sequencer #(soc_ifc_subenv_mbox_sram_agent_transaction_t) soc_ifc_subenv_mbox_sram_agent_sequencer; // Sequencer handles for each QVIP interface mvc_sequencer uvm_test_top_environment_soc_ifc_subenv_qvip_ahb_lite_slave_subenv_ahb_lite_slave_0_sqr; @@ -77,6 +81,7 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; cptra_ctrl_configuration soc_ifc_subenv_cptra_ctrl_agent_config; soc_ifc_status_configuration soc_ifc_subenv_soc_ifc_status_agent_config; cptra_status_configuration soc_ifc_subenv_cptra_status_agent_config; + mbox_sram_configuration soc_ifc_subenv_mbox_sram_agent_config; // pragma uvmf custom class_item_additional begin // pragma uvmf custom class_item_additional end @@ -101,10 +106,13 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; `uvm_fatal("CFG" , "uvm_config_db #( soc_ifc_status_configuration )::get cannot find resource soc_ifc_subenv_soc_ifc_status_agent_BFM" ) if( !uvm_config_db #( cptra_status_configuration )::get( null , UVMF_CONFIGURATIONS , soc_ifc_subenv_cptra_status_agent_BFM , soc_ifc_subenv_cptra_status_agent_config ) ) `uvm_fatal("CFG" , "uvm_config_db #( cptra_status_configuration )::get cannot find resource soc_ifc_subenv_cptra_status_agent_BFM" ) + if( !uvm_config_db #( mbox_sram_configuration )::get( null , UVMF_CONFIGURATIONS , soc_ifc_subenv_mbox_sram_agent_BFM , soc_ifc_subenv_mbox_sram_agent_config ) ) + `uvm_fatal("CFG" , "uvm_config_db #( mbox_sram_configuration )::get cannot find resource soc_ifc_subenv_mbox_sram_agent_BFM" ) // Assign the sequencer handles from the handles within agent configurations soc_ifc_subenv_soc_ifc_ctrl_agent_sequencer = soc_ifc_subenv_soc_ifc_ctrl_agent_config.get_sequencer(); soc_ifc_subenv_soc_ifc_status_agent_sequencer = soc_ifc_subenv_soc_ifc_status_agent_config.get_sequencer(); + soc_ifc_subenv_mbox_sram_agent_sequencer = soc_ifc_subenv_mbox_sram_agent_config.get_sequencer(); // Retrieve QVIP sequencer handles from the uvm_config_db if( !uvm_config_db #(mvc_sequencer)::get( null,UVMF_SEQUENCERS,"uvm_test_top.environment.soc_ifc_subenv.qvip_apb5_slave_subenv.apb5_master_0", uvm_test_top_environment_soc_ifc_subenv_qvip_apb5_slave_subenv_apb5_master_0_sqr) ) @@ -124,17 +132,20 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; caliptra_top_env_seq = caliptra_top_env_sequence_base_t::type_id::create("caliptra_top_env_seq"); - soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); - soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); + soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_mbox_sram_agent_responder_seq = soc_ifc_subenv_mbox_sram_agent_responder_seq_t::type_id::create("soc_ifc_subenv_mbox_sram_agent_responder_seq"); fork soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_reset(); soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_reset(); soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_reset(); soc_ifc_subenv_cptra_status_agent_config.wait_for_reset(); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_reset(); join // Start RESPONDER sequences here fork soc_ifc_subenv_soc_ifc_status_agent_responder_seq.start(soc_ifc_subenv_soc_ifc_status_agent_sequencer); + soc_ifc_subenv_mbox_sram_agent_responder_seq.start(soc_ifc_subenv_mbox_sram_agent_sequencer); join_none // Start INITIATOR sequences here fork @@ -151,6 +162,7 @@ caliptra_top_env_seq.start(top_configuration.vsqr); soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(400); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_cmdline_sequence.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_cmdline_sequence.svh index a92b05136..7b45d983f 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_cmdline_sequence.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_cmdline_sequence.svh @@ -85,6 +85,7 @@ class caliptra_top_cmdline_sequence extends caliptra_top_bench_sequence_base; soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_mbox_sram_agent_responder_seq = soc_ifc_subenv_mbox_sram_agent_responder_seq_t::type_id::create("soc_ifc_subenv_mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; @@ -95,6 +96,7 @@ class caliptra_top_cmdline_sequence extends caliptra_top_bench_sequence_base; // Start RESPONDER sequences here fork soc_ifc_subenv_soc_ifc_status_agent_responder_seq.start(soc_ifc_subenv_soc_ifc_status_agent_sequencer); + soc_ifc_subenv_mbox_sram_agent_responder_seq.start(soc_ifc_subenv_mbox_sram_agent_sequencer); join_none fork @@ -151,6 +153,7 @@ class caliptra_top_cmdline_sequence extends caliptra_top_bench_sequence_base; soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(400); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rand_sequence.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rand_sequence.svh index d8447b61e..5e6d44890 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rand_sequence.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rand_sequence.svh @@ -65,6 +65,9 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_SMALL, IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_MEDIUM, IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_LARGE, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_SMALL, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE, IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT, IDX_SOC_IFC_ENV_RST_WARM, IDX_SOC_IFC_ENV_RST_COLD, @@ -73,7 +76,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; IDX_SOC_IFC_ENV_MBOX_SHA_ACCEL, IDX_SOC_IFC_ENV_SHA_ACCEL, IDX_SOC_IFC_ENV_FW_UPD, - IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS + IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS, + IDX_SOC_IFC_ENV_MBOX_DIR_READ } rand_seq_idx; rand int iteration_count; @@ -83,9 +87,9 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; constraint avail_env_seqs_c { rand_seq_idx dist { //IDX_SOC_IFC_ENV_MBOX_RAND_FW := 0, - IDX_SOC_IFC_ENV_MBOX_RAND_SMALL := 100, - IDX_SOC_IFC_ENV_MBOX_RAND_MEDIUM := 100, - IDX_SOC_IFC_ENV_MBOX_RAND_LARGE := 10, + IDX_SOC_IFC_ENV_MBOX_RAND_SMALL := 20, + IDX_SOC_IFC_ENV_MBOX_RAND_MEDIUM := 20, + IDX_SOC_IFC_ENV_MBOX_RAND_LARGE := 2, IDX_SOC_IFC_ENV_MBOX_MIN := 100, IDX_SOC_IFC_ENV_MBOX_MAX := 10, IDX_SOC_IFC_ENV_MBOX_RAND_PAUSER_SMALL := 100, @@ -93,7 +97,7 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; IDX_SOC_IFC_ENV_MBOX_RAND_PAUSER_LARGE := 10, IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_SMALL := 100, IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_MEDIUM := 100, - IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_LARGE := 10, + IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_LARGE := 5, IDX_SOC_IFC_ENV_MBOX_RAND_MEDIUM_INTERFERENCE := 100, IDX_SOC_IFC_ENV_MBOX_DLEN_INVALID := 10, IDX_SOC_IFC_ENV_MBOX_DLEN_OVERFLOW_SMALL := 100, @@ -102,6 +106,9 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_SMALL := 100, IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_MEDIUM := 100, IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_LARGE := 10, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_SMALL := 200, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_MEDIUM := 200, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE := 20, IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT := 200, IDX_SOC_IFC_ENV_RST_WARM := 100, IDX_SOC_IFC_ENV_RST_COLD := 100, @@ -110,20 +117,47 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; IDX_SOC_IFC_ENV_MBOX_SHA_ACCEL := 100, IDX_SOC_IFC_ENV_SHA_ACCEL := 100, IDX_SOC_IFC_ENV_FW_UPD := 10, - IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS := 100 + IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS := 100, + IDX_SOC_IFC_ENV_MBOX_DIR_READ := 100 }; } + constraint disable_long_env_seqs_c { + !(rand_seq_idx inside {IDX_SOC_IFC_ENV_MBOX_RAND_LARGE, + IDX_SOC_IFC_ENV_MBOX_MAX, + IDX_SOC_IFC_ENV_MBOX_RAND_PAUSER_LARGE, + IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_RAND_DELAY_LARGE, + IDX_SOC_IFC_ENV_MBOX_DLEN_INVALID, + IDX_SOC_IFC_ENV_MBOX_DLEN_OVERFLOW_LARGE, + IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_LARGE, + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE, + IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT}); + } constraint iter_count_c { iteration_count inside {[1:10]}; } + constraint iter_count_short_c { + iteration_count < 5; + } function new(string name = "" ); super.new(name); reg_model = top_configuration.soc_ifc_subenv_config.soc_ifc_rm; + // The short test suite is used in promote pipeline to quickly check for UVM issues + if ($test$plusargs("CLP_SHORT_SUITE")) begin + this.disable_long_env_seqs_c.constraint_mode(1); + this.iter_count_short_c.constraint_mode(1); + end + else begin + this.disable_long_env_seqs_c.constraint_mode(0); + this.iter_count_short_c.constraint_mode(0); + end + // Users can manually override the number of random iterations to any desired value if ($value$plusargs("CALIPTRA_TOP_RAND_ITER=%0d", iteration_count)) begin `uvm_info("CALIPTRA_TOP_RAND_TEST", $sformatf("Received Command Line Iteration Count Argument of %0d", iteration_count), UVM_LOW); iteration_count.rand_mode(0); this.iter_count_c.constraint_mode(0); + this.iter_count_short_c.constraint_mode(0); end else begin if (!this.randomize(iteration_count)) @@ -167,6 +201,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; bit pauser_valid_initialized = 1'b0; uvm_object obj; int ii; + int unsigned mbox_ecc_single_error_burst; + int unsigned mbox_ecc_single_error_delay_clocks; caliptra_top_env_seq = caliptra_top_env_sequence_base_t::type_id::create("caliptra_top_env_seq"); soc_ifc_env_bringup_seq = soc_ifc_env_bringup_sequence_t::type_id::create("soc_ifc_env_bringup_seq"); @@ -176,6 +212,7 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_mbox_sram_agent_responder_seq = soc_ifc_subenv_mbox_sram_agent_responder_seq_t::type_id::create("soc_ifc_subenv_mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; @@ -193,11 +230,27 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; // Start RESPONDER sequences here fork soc_ifc_subenv_soc_ifc_status_agent_responder_seq.start(soc_ifc_subenv_soc_ifc_status_agent_sequencer); + soc_ifc_subenv_mbox_sram_agent_responder_seq.start(soc_ifc_subenv_mbox_sram_agent_sequencer); join_none // // Start INITIATOR sequences here // fork // repeat (25) soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq.start(soc_ifc_subenv_soc_ifc_ctrl_agent_sequencer); // join + fork + forever begin + if (!std::randomize(mbox_ecc_single_error_burst,mbox_ecc_single_error_delay_clocks) with {mbox_ecc_single_error_burst dist {1 :/ 1000, [2:5] :/ 100, [6:31] :/ 20, [32:131071] :/ 1, [131072:524288] :/ 1}; + mbox_ecc_single_error_delay_clocks dist {1 :/ 1, [2:31] :/ 3, [32:127] :/ 5, [128:1023] :/ 3, [1024:131072] :/ 1}; }) + `uvm_fatal("CALIPTRA_TOP_RAND_TEST", "Failed to randomize mbox ecc bit flip injection parameters") + else + `uvm_info("CALIPTRA_TOP_RAND_TEST", $sformatf("Randomized mbox ecc bit flip injection parameters: burst [%0d] delay [%0d clocks]", mbox_ecc_single_error_burst, mbox_ecc_single_error_delay_clocks), UVM_DEBUG) + soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(mbox_ecc_single_error_delay_clocks); + `uvm_info("CALIPTRA_TOP_RAND_TEST", $sformatf("Injecting mbox ecc error with burst [%0d]", mbox_ecc_single_error_burst), UVM_DEBUG) + repeat(mbox_ecc_single_error_burst) begin + soc_ifc_subenv_mbox_sram_agent_config.inject_ecc_error |= 2'b01; + @soc_ifc_subenv_mbox_sram_agent_responder_seq.new_rsp; + end + end + join_none fork forever @(soc_ifc_subenv_soc_ifc_status_agent_responder_seq.new_rsp) sts_rsp_count++; join_none @@ -287,6 +340,12 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; obj = soc_ifc_env_mbox_dlen_underflow_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_DLEN_UNDERFLOW_LARGE: obj = soc_ifc_env_mbox_dlen_underflow_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_SMALL: + obj = soc_ifc_env_mbox_reg_axs_invalid_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_MEDIUM: + obj = soc_ifc_env_mbox_reg_axs_invalid_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_REG_AXS_INV_LARGE: + obj = soc_ifc_env_mbox_reg_axs_invalid_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_MULTI_AGENT: // TODO PAUSER init first? obj = soc_ifc_env_mbox_rand_multi_agent_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); @@ -306,6 +365,8 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; obj = soc_ifc_env_mbox_fw_upd_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_UC_REG_ACCESS: obj = soc_ifc_env_mbox_uc_reg_access_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_DIR_READ: + obj = soc_ifc_env_mbox_dir_read_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); default: `uvm_error("CALIPTRA_TOP_RAND_TEST", $sformatf("rand_seq_idx randomized to illegal value: %p", rand_seq_idx)) endcase @@ -343,10 +404,11 @@ class caliptra_top_rand_sequence extends caliptra_top_bench_sequence_base; // the last sequence to allow for the last sequence item to flow // through the design. fork - soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(400); - soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(400); - soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(400); - soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(400); + soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(4000); + soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(4000); + soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(4000); + soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(4000); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(4000); join // pragma uvmf custom body end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh index 2498b50af..9182b23a6 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_rom_sequence.svh @@ -30,6 +30,7 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base; `uvm_object_utils( caliptra_top_rom_sequence ); rand soc_ifc_env_rom_bringup_sequence_t soc_ifc_env_bringup_seq; + rand soc_ifc_env_trng_write_data_sequence_t soc_ifc_env_trng_write_data_seq; rand soc_ifc_env_mbox_rom_fw_sequence_t soc_ifc_env_mbox_rom_seq; rand soc_ifc_env_sequence_base_t soc_ifc_env_seq_ii[]; // Local handle to register model for convenience @@ -70,6 +71,7 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base; soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_mbox_sram_agent_responder_seq = soc_ifc_subenv_mbox_sram_agent_responder_seq_t::type_id::create("soc_ifc_subenv_mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; @@ -79,6 +81,7 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base; // Start RESPONDER sequences here fork soc_ifc_subenv_soc_ifc_status_agent_responder_seq.start(soc_ifc_subenv_soc_ifc_status_agent_sequencer); + soc_ifc_subenv_mbox_sram_agent_responder_seq.start(soc_ifc_subenv_mbox_sram_agent_sequencer); join_none fork @@ -92,6 +95,21 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base; `uvm_info("CALIPTRA_TOP_BRINGUP", "SoC completed poweron and observed reset deassertion to system", UVM_LOW) +`ifndef CALIPTRA_INTERNAL_TRNG + `uvm_info("CALIPTRA_TOP_ROM_TEST", "Initiating TRNG responder sequence in an infinite loop to handle ROM TRNG requests", UVM_LOW) + fork + forever begin + soc_ifc_env_trng_write_data_seq = soc_ifc_env_trng_write_data_sequence_t::type_id::create("soc_ifc_env_trng_write_data_seq"); + soc_ifc_env_trng_write_data_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + if (!soc_ifc_env_trng_write_data_seq.randomize()) + `uvm_fatal("CALIPTRA_TOP_ROM_TEST", $sformatf("caliptra_top_rom_sequence::body() - %s randomization failed", soc_ifc_env_trng_write_data_seq.get_type_name())); + soc_ifc_env_trng_write_data_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + end + join_none +`else + `uvm_info("CALIPTRA_TOP_ROM_TEST", "Not initiating TRNG responder sequence to handle ROM TRNG requests because INTERNAL TRNG is enabled", UVM_LOW) +`endif + run_firmware_init(soc_ifc_env_mbox_rom_seq); // After firmware init, wait for generic_output_wires write to 0xFF @@ -108,6 +126,7 @@ class caliptra_top_rom_sequence extends caliptra_top_bench_sequence_base; soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(400); soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(400); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_wdt_sequence.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_wdt_sequence.svh new file mode 100644 index 000000000..4f38ab7d5 --- /dev/null +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/sequences/src/caliptra_top_wdt_sequence.svh @@ -0,0 +1,179 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +// +//---------------------------------------------------------------------- +// +// DESCRIPTION: This file contains the top level sequence used in caliptra_top_wdt_test. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class caliptra_top_wdt_sequence extends caliptra_top_bench_sequence_base; + + `uvm_object_utils( caliptra_top_wdt_sequence ); + + rand soc_ifc_env_bringup_sequence_t soc_ifc_env_bringup_seq; + rand soc_ifc_env_pauser_init_sequence_t soc_ifc_env_pauser_init_seq; + rand soc_ifc_env_mbox_real_fw_sequence_t soc_ifc_env_mbox_fmc_seq; + rand soc_ifc_env_mbox_real_fw_sequence_t soc_ifc_env_mbox_rt_seq; + rand soc_ifc_env_reset_warm_sequence_t soc_ifc_env_reset_warm_seq; + rand soc_ifc_env_reset_cold_sequence_t soc_ifc_env_reset_cold_seq; + // Local handle to register model for convenience + soc_ifc_reg_model_top reg_model; + + + rand int iteration_count; + int sts_rsp_count = 0; + int rsp_count = 0; + + + function new(string name = "" ); + super.new(name); + reg_model = top_configuration.soc_ifc_subenv_config.soc_ifc_rm; + endfunction + + // **************************************************************************** + virtual task run_firmware_init(soc_ifc_env_mbox_real_fw_sequence_t fmc_seq, soc_ifc_env_mbox_real_fw_sequence_t rt_seq); + bit ready_for_fw = 0; + bit ready_for_rt = 0; + while (!ready_for_fw) begin + while(!sts_rsp_count)soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); // Wait for new status updates + `uvm_info("CALIPTRA_TOP_WDT_TEST", "Observed status response, checking contents", UVM_DEBUG) + sts_rsp_count = 0; // We only care about the latest rsp, so even if count > 1, reset back to 0 + ready_for_fw = soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.ready_for_fw_push; + end + if (!fmc_seq.randomize() with { fmc_seq.mbox_op_rand.cmd == mbox_cmd_e'(MBOX_CMD_FMC_UPDATE); }) + `uvm_fatal("CALIPTRA_TOP_WDT_TEST", "caliptra_top_wdt_sequence::body() - fmc_seq randomization failed") + fmc_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + if (!rt_seq.randomize() with { rt_seq.mbox_op_rand.cmd == mbox_cmd_e'(MBOX_CMD_RT_UPDATE); }) + `uvm_fatal("CALIPTRA_TOP_WDT_TEST", "caliptra_top_wdt_sequence::body() - rt_seq randomization failed") + rt_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + + // Wait for RT image to set the ready_for_rt bit + while (!ready_for_rt) begin + while(!sts_rsp_count)soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); // Wait for new status updates + `uvm_info("CALIPTRA_TOP_WDT_TEST", "Observed status response, checking contents", UVM_DEBUG) + sts_rsp_count = 0; // We only care about the latest rsp, so even if count > 1, reset back to 0 + ready_for_rt = soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.ready_for_runtime; + end + endtask + + // **************************************************************************** + virtual task body(); + // pragma uvmf custom body begin + // Construct sequences here + bit pauser_valid_initialized = 1'b0; + uvm_object obj; + int ii; + bit nmi_intr; + bit hw_error_fatal; + uvm_status_e reg_sts; + uvm_reg_data_t wdt_status_data; + + caliptra_top_env_seq = caliptra_top_env_sequence_base_t::type_id::create("caliptra_top_env_seq"); + soc_ifc_env_bringup_seq = soc_ifc_env_bringup_sequence_t::type_id::create("soc_ifc_env_bringup_seq"); + soc_ifc_env_pauser_init_seq = soc_ifc_env_pauser_init_sequence_t::type_id::create("soc_ifc_env_pauser_init_seq"); + soc_ifc_env_mbox_fmc_seq = soc_ifc_env_mbox_real_fw_sequence_t::type_id::create("soc_ifc_env_mbox_fmc_seq"); + soc_ifc_env_mbox_rt_seq = soc_ifc_env_mbox_real_fw_sequence_t::type_id::create("soc_ifc_env_mbox_rt_seq"); + soc_ifc_env_reset_warm_seq = soc_ifc_env_reset_warm_sequence_t::type_id::create("soc_ifc_env_reset_warm_seq"); + soc_ifc_env_reset_cold_seq = soc_ifc_env_reset_cold_sequence_t::type_id::create("soc_ifc_env_reset_cold_seq"); + + soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq = soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_ctrl_agent_random_seq"); + soc_ifc_subenv_soc_ifc_status_agent_responder_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_subenv_soc_ifc_status_agent_responder_seq"); + soc_ifc_subenv_mbox_sram_agent_responder_seq = soc_ifc_subenv_mbox_sram_agent_responder_seq_t::type_id::create("soc_ifc_subenv_mbox_sram_agent_responder_seq"); + + // Handle to the responder sequence for getting response transactions + soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + soc_ifc_env_pauser_init_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + soc_ifc_env_mbox_fmc_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + soc_ifc_env_mbox_rt_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + soc_ifc_env_reset_warm_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + soc_ifc_env_reset_cold_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_subenv_soc_ifc_status_agent_responder_seq; + + reg_model.reset(); + // Start RESPONDER sequences here + fork + soc_ifc_subenv_soc_ifc_status_agent_responder_seq.start(soc_ifc_subenv_soc_ifc_status_agent_sequencer); + soc_ifc_subenv_mbox_sram_agent_responder_seq.start(soc_ifc_subenv_mbox_sram_agent_sequencer); + join_none + + fork + forever @(soc_ifc_subenv_soc_ifc_status_agent_responder_seq.new_rsp) begin + sts_rsp_count++; + rsp_count++; + end + join_none + + if(!soc_ifc_env_bringup_seq.randomize()) + `uvm_fatal("CALIPTRA_TOP_WDT_TEST", "caliptra_top_wdt_sequence::body() - soc_ifc_env_bringup_seq randomization failed") + soc_ifc_env_bringup_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + + `uvm_info("CALIPTRA_TOP_BRINGUP", "SoC completed poweron and observed reset deassertion to system", UVM_LOW) + + run_firmware_init(soc_ifc_env_mbox_fmc_seq,soc_ifc_env_mbox_rt_seq); + + // //-------------------------------- + // //Wait for NMI to occur - TODO + // `uvm_info("KNU", $sformatf("FW init done, hw_error_fatal = %0d", hw_error_fatal),UVM_MEDIUM); + // while (!hw_error_fatal) begin + // `uvm_info("KNU", "Inside while loop",UVM_MEDIUM); + // while(!rsp_count)soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); // Wait for new status updates + // `uvm_info("CALIPTRA_TOP_WDT_TEST", "Observed status response, checking contents", UVM_MEDIUM) + // `uvm_info("CALIPTRA_TOP_WDT_TEST", soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.convert2string(), UVM_MEDIUM) + // // `uvm_info("CALIPTRA_TOP_WDT_TEST", $sformatf("response error fatal = %0d",soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.cptra_error_fatal_intr_pending), UVM_MEDIUM) + // rsp_count = 0; // We only care about the latest rsp, so even if count > 1, reset back to 0 + // hw_error_fatal = soc_ifc_subenv_soc_ifc_status_agent_responder_seq.rsp.cptra_error_fatal_intr_pending; + // end + // `uvm_info("KNU", $sformatf("Outside while loop, hw_error_fatal = %h", hw_error_fatal),UVM_MEDIUM); + + // // //TODO: add APB seq to read hw_error_fatal reg to see if it's NMI or not + // `uvm_info("CALIPTRA_TOP_WDT_TEST", "Encountered NMI, issuing reset", UVM_MEDIUM); + // //soc_ifc_env_bringup_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + // reg_model.reset(); //TODO needed? + // // if (!soc_ifc_env_reset_cold_seq.randomize()) + // // `uvm_fatal("CALIPTRA_TOP_WDT_TEST", "caliptra_top_wdt_sequence::body() - soc_ifc_env_bringup_seq randomization failed") + // // soc_ifc_env_reset_cold_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + // // reg_model.reset(); //TODO needed? + // if(!soc_ifc_env_bringup_seq.randomize()) + // `uvm_fatal("CALIPTRA_TOP_WDT_TEST", "caliptra_top_wdt_sequence::body() - soc_ifc_env_bringup_seq randomization failed") + // soc_ifc_env_bringup_seq.start(top_configuration.soc_ifc_subenv_config.vsqr); + //-------------------------------- + + // UVMF_CHANGE_ME : Extend the simulation XXX number of clocks after + // the last sequence to allow for the last sequence item to flow + // through the design. + fork + soc_ifc_subenv_soc_ifc_ctrl_agent_config.wait_for_num_clocks(10000); + soc_ifc_subenv_cptra_ctrl_agent_config.wait_for_num_clocks(10000); + soc_ifc_subenv_soc_ifc_status_agent_config.wait_for_num_clocks(10000); + soc_ifc_subenv_cptra_status_agent_config.wait_for_num_clocks(10000); + soc_ifc_subenv_mbox_sram_agent_config.wait_for_num_clocks(10000); + join + + // pragma uvmf custom body end + endtask + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv index c4884273f..6ad20d141 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/testbench/hdl_top.sv @@ -109,16 +109,22 @@ import uvmf_base_pkg_hdl::*; logic jtag_trst_n = '0; // JTAG Reset logic jtag_tdo; // JTAG TDO - logic mbox_sram_cs; - logic mbox_sram_we; - logic [14:0] mbox_sram_addr; - logic [MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata; - logic [MBOX_DATA_AND_ECC_W-1:0] mbox_sram_rdata; + mbox_sram_req_t mbox_sram_req; + mbox_sram_resp_t mbox_sram_resp; + logic mbox_sram_cs_stub_inactive; + logic mbox_sram_we_stub_inactive; + logic [14:0] mbox_sram_addr_stub_inactive; + logic [MBOX_DATA_AND_ECC_W-1:0] mbox_sram_wdata_stub_inactive; + logic [MBOX_DATA_AND_ECC_W-1:0] mbox_sram_rdata_stub_inactive; logic imem_cs; logic [`CALIPTRA_IMEM_ADDR_WIDTH-1:0] imem_addr; logic [`CALIPTRA_IMEM_DATA_WIDTH-1:0] imem_rdata; + logic etrng_req; + logic [3:0] itrng_data; + logic itrng_valid; + //device lifecycle security_state_t security_state_stub_inactive; @@ -153,12 +159,19 @@ import uvmf_base_pkg_hdl::*; .clk(clk), .dummy(1'b1) // pragma uvmf custom soc_ifc_subenv_cptra_status_agent_bus_connections end ); + mbox_sram_if soc_ifc_subenv_mbox_sram_agent_bus( + // pragma uvmf custom soc_ifc_subenv_mbox_sram_agent_bus_connections begin + .clk(clk), .dummy(1'b1) + // pragma uvmf custom soc_ifc_subenv_mbox_sram_agent_bus_connections end + ); soc_ifc_ctrl_monitor_bfm soc_ifc_subenv_soc_ifc_ctrl_agent_mon_bfm(soc_ifc_subenv_soc_ifc_ctrl_agent_bus.monitor_port); cptra_ctrl_monitor_bfm soc_ifc_subenv_cptra_ctrl_agent_mon_bfm(soc_ifc_subenv_cptra_ctrl_agent_bus.monitor_port); soc_ifc_status_monitor_bfm soc_ifc_subenv_soc_ifc_status_agent_mon_bfm(soc_ifc_subenv_soc_ifc_status_agent_bus.monitor_port); cptra_status_monitor_bfm soc_ifc_subenv_cptra_status_agent_mon_bfm(soc_ifc_subenv_cptra_status_agent_bus.monitor_port); + mbox_sram_monitor_bfm soc_ifc_subenv_mbox_sram_agent_mon_bfm(soc_ifc_subenv_mbox_sram_agent_bus.monitor_port); soc_ifc_ctrl_driver_bfm soc_ifc_subenv_soc_ifc_ctrl_agent_drv_bfm(soc_ifc_subenv_soc_ifc_ctrl_agent_bus.initiator_port); soc_ifc_status_driver_bfm soc_ifc_subenv_soc_ifc_status_agent_drv_bfm(soc_ifc_subenv_soc_ifc_status_agent_bus.responder_port); + mbox_sram_driver_bfm soc_ifc_subenv_mbox_sram_agent_drv_bfm(soc_ifc_subenv_mbox_sram_agent_bus.responder_port); // pragma uvmf custom dut_instantiation begin // AHB Clock/reset @@ -207,11 +220,11 @@ import uvmf_base_pkg_hdl::*; .ready_for_fw_push(soc_ifc_subenv_soc_ifc_status_agent_bus.ready_for_fw_push ), .ready_for_runtime(soc_ifc_subenv_soc_ifc_status_agent_bus.ready_for_runtime ), - .mbox_sram_cs (mbox_sram_cs ), - .mbox_sram_we (mbox_sram_we ), - .mbox_sram_addr (mbox_sram_addr ), - .mbox_sram_wdata(mbox_sram_wdata), - .mbox_sram_rdata(mbox_sram_rdata), + .mbox_sram_cs (mbox_sram_req.cs ), + .mbox_sram_we (mbox_sram_req.we ), + .mbox_sram_addr (mbox_sram_req.addr ), + .mbox_sram_wdata(mbox_sram_req.wdata), + .mbox_sram_rdata(mbox_sram_resp.rdata), .imem_cs (imem_cs ), .imem_addr (imem_addr ), @@ -225,16 +238,23 @@ import uvmf_base_pkg_hdl::*; .cptra_error_fatal (soc_ifc_subenv_soc_ifc_status_agent_bus.cptra_error_fatal), .cptra_error_non_fatal(soc_ifc_subenv_soc_ifc_status_agent_bus.cptra_error_non_fatal), // External TRNG +`ifdef CALIPTRA_INTERNAL_TRNG + .etrng_req (etrng_req), + // Internal TRNG + .itrng_data (itrng_data ), + .itrng_valid (itrng_valid), +`else .etrng_req (soc_ifc_subenv_soc_ifc_status_agent_bus.trng_req), // Internal TRNG - .itrng_data (4'h0), // TODO - .itrng_valid (1'b0), // TODO + .itrng_data (4'h0), + .itrng_valid (1'b0), +`endif .generic_input_wires (soc_ifc_subenv_soc_ifc_ctrl_agent_bus.generic_input_wires), .generic_output_wires(soc_ifc_subenv_soc_ifc_status_agent_bus.generic_output_wires), .security_state(soc_ifc_subenv_soc_ifc_ctrl_agent_bus.security_state), - .scan_mode (1'b0) + .scan_mode (1'b0) // TODO ); assign uvm_test_top_environment_soc_ifc_subenv_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PWUSER = 0; assign uvm_test_top_environment_soc_ifc_subenv_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PRUSER = 0; @@ -282,6 +302,7 @@ import uvmf_base_pkg_hdl::*; assign soc_ifc_subenv_cptra_status_agent_bus.cptra_noncore_rst_b = caliptra_top_dut.cptra_noncore_rst_b; assign soc_ifc_subenv_cptra_status_agent_bus.cptra_obf_key_reg = caliptra_top_dut.cptra_obf_key_reg; assign soc_ifc_subenv_cptra_status_agent_bus.cptra_uc_rst_b = caliptra_top_dut.cptra_uc_rst_b; + assign soc_ifc_subenv_cptra_status_agent_bus.fw_update_rst_window = caliptra_top_dut.fw_update_rst_window; assign soc_ifc_subenv_cptra_status_agent_bus.iccm_lock = caliptra_top_dut.iccm_lock; assign soc_ifc_subenv_cptra_status_agent_bus.nmi_vector = caliptra_top_dut.nmi_vector; assign soc_ifc_subenv_cptra_status_agent_bus.nmi_intr = caliptra_top_dut.nmi_int; @@ -297,6 +318,23 @@ import uvmf_base_pkg_hdl::*; assign soc_ifc_subenv_cptra_ctrl_agent_bus.iccm_axs_blocked = caliptra_top_dut.ahb_lite_resp_access_blocked[`CALIPTRA_SLAVE_SEL_IDMA]; assign soc_ifc_subenv_cptra_ctrl_agent_bus.rv_ecc_sts = caliptra_top_dut.rv_ecc_sts; + assign soc_ifc_subenv_mbox_sram_agent_bus.mbox_sram_req = mbox_sram_req; + assign mbox_sram_resp = soc_ifc_subenv_mbox_sram_agent_bus.mbox_sram_resp; + +`ifdef CALIPTRA_INTERNAL_TRNG + //=========================================================================- + // Physical RNG used for Internal TRNG + //=========================================================================- + physical_rng physical_rng_i ( + .clk (clk), + .enable (etrng_req), + .data (itrng_data), + .valid (itrng_valid) + ); + + assign soc_ifc_subenv_soc_ifc_status_agent_bus.trng_req = 1'b0; +`endif + //=========================================================================- // Services for SRAM exports, STDOUT, etc //=========================================================================- @@ -311,11 +349,11 @@ import uvmf_base_pkg_hdl::*; .el2_mem_export (el2_mem_export), //SRAM interface for mbox - .mbox_sram_cs (mbox_sram_cs ), - .mbox_sram_we (mbox_sram_we ), - .mbox_sram_addr (mbox_sram_addr ), - .mbox_sram_wdata(mbox_sram_wdata), - .mbox_sram_rdata(mbox_sram_rdata), + .mbox_sram_cs (mbox_sram_cs_stub_inactive ), + .mbox_sram_we (mbox_sram_we_stub_inactive ), + .mbox_sram_addr (mbox_sram_addr_stub_inactive ), + .mbox_sram_wdata(mbox_sram_wdata_stub_inactive), + .mbox_sram_rdata(mbox_sram_rdata_stub_inactive), //SRAM interface for imem .imem_cs (imem_cs ), @@ -346,8 +384,10 @@ import uvmf_base_pkg_hdl::*; uvm_config_db #( virtual cptra_ctrl_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_cptra_ctrl_agent_BFM , soc_ifc_subenv_cptra_ctrl_agent_mon_bfm ); uvm_config_db #( virtual soc_ifc_status_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_soc_ifc_status_agent_BFM , soc_ifc_subenv_soc_ifc_status_agent_mon_bfm ); uvm_config_db #( virtual cptra_status_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_cptra_status_agent_BFM , soc_ifc_subenv_cptra_status_agent_mon_bfm ); + uvm_config_db #( virtual mbox_sram_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_mbox_sram_agent_BFM , soc_ifc_subenv_mbox_sram_agent_mon_bfm ); uvm_config_db #( virtual soc_ifc_ctrl_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_soc_ifc_ctrl_agent_BFM , soc_ifc_subenv_soc_ifc_ctrl_agent_drv_bfm ); uvm_config_db #( virtual soc_ifc_status_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_soc_ifc_status_agent_BFM , soc_ifc_subenv_soc_ifc_status_agent_drv_bfm ); + uvm_config_db #( virtual mbox_sram_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_subenv_mbox_sram_agent_BFM , soc_ifc_subenv_mbox_sram_agent_drv_bfm ); end endmodule diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv index 4523e9579..051084252 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/caliptra_top_tests_pkg.sv @@ -65,6 +65,7 @@ package caliptra_top_tests_pkg; `include "src/register_test.svh" `include "src/example_derived_test.svh" `include "src/caliptra_top_rand_test.svh" + `include "src/caliptra_top_wdt_test.svh" `include "src/caliptra_top_cmdline_test.svh" `include "src/caliptra_top_rom_test.svh" diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.svh new file mode 100644 index 000000000..504820b6c --- /dev/null +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.svh @@ -0,0 +1,72 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This test extends test_top and makes +// changes to test_top using the UVM factory type_override: +// +// Test scenario: +// Randomized activity to Caliptra +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +class caliptra_top_wdt_test extends test_top; + + `uvm_component_utils( caliptra_top_wdt_test ); + + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + + virtual function void build_phase(uvm_phase phase); + // The factory override below is an example of how to replace the caliptra_top_bench_sequence_base + // sequence with the example_derived_test_sequence. + caliptra_top_bench_sequence_base::type_id::set_type_override(caliptra_top_wdt_sequence::get_type()); + // Execute the build_phase of test_top AFTER all factory overrides have been created. + super.build_phase(phase); + // pragma uvmf custom configuration_settings_post_randomize begin + // UVMF_CHANGE_ME Test specific configuration values can be set here. + // The configuration structure has already been randomized. + // pragma uvmf custom configuration_settings_post_randomize end + endfunction + + // FIXME this disables uvm_warning messages! We should fix the warnings, but for + // now this reduces sim.log (for regressions) to a manageable level + // NOTE: UVM_WARNING now re-enabled, need to clean this up after some regression cycles + virtual function void start_of_simulation_phase(uvm_phase phase); + super.start_of_simulation_phase(phase); + if ($test$plusargs("CLP_REGRESSION")) begin + uvm_top.set_report_verbosity_level_hier(UVM_NONE); +// this.environment.soc_ifc_subenv.soc_ifc_pred.set_report_severity_action(UVM_WARNING,UVM_NO_ACTION); +// this.environment.soc_ifc_subenv.soc_ifc_sb.set_report_severity_action(UVM_WARNING,UVM_NO_ACTION); + // Since en_sb is recently set to 0, this is unavailable and gives null-object + //this.environment.soc_ifc_subenv.qvip_apb5_slave_subenv.apb5_master_0.get_analysis_component("checker").set_report_severity_id_action(UVM_WARNING,"scoreboard_debug",UVM_NO_ACTION); + end + endfunction + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + + diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.yml b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.yml new file mode 100644 index 000000000..1f1af25ad --- /dev/null +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/caliptra_top_wdt_test.yml @@ -0,0 +1,6 @@ +--- +# Random seed desired... +seed: ${PLAYBOOK_RANDOM_SEED} +plusargs: +- '+UVM_TESTNAME=caliptra_top_wdt_test' +testname: caliptra_top_wdt_test diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/test_top.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/test_top.svh index d7b840b4a..1d0b78285 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/test_top.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/project_benches/caliptra_top/tb/tests/src/test_top.svh @@ -52,7 +52,8 @@ qvip_memory_message_handler message_handler; soc_ifc_subenv_soc_ifc_ctrl_agent_BFM /* soc_ifc_subenv_soc_ifc_ctrl_agent [2] */ , soc_ifc_subenv_cptra_ctrl_agent_BFM /* soc_ifc_subenv_cptra_ctrl_agent [3] */ , soc_ifc_subenv_soc_ifc_status_agent_BFM /* soc_ifc_subenv_soc_ifc_status_agent [4] */ , - soc_ifc_subenv_cptra_status_agent_BFM /* soc_ifc_subenv_cptra_status_agent [5] */ + soc_ifc_subenv_cptra_status_agent_BFM /* soc_ifc_subenv_cptra_status_agent [5] */ , + soc_ifc_subenv_mbox_sram_agent_BFM /* soc_ifc_subenv_mbox_sram_agent [6] */ }; uvmf_active_passive_t interface_activities[] = { @@ -61,7 +62,8 @@ uvmf_active_passive_t interface_activities[] = { ACTIVE /* soc_ifc_subenv_soc_ifc_ctrl_agent [2] */ , PASSIVE /* soc_ifc_subenv_cptra_ctrl_agent [3] */ , ACTIVE /* soc_ifc_subenv_soc_ifc_status_agent [4] */ , - PASSIVE /* soc_ifc_subenv_cptra_status_agent [5] */ }; + PASSIVE /* soc_ifc_subenv_cptra_status_agent [5] */ , + ACTIVE /* soc_ifc_subenv_mbox_sram_agent [6] */ }; // pragma uvmf custom class_item_additional begin // pragma uvmf custom class_item_additional end diff --git a/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/src/caliptra_top_env_configuration.svh b/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/src/caliptra_top_env_configuration.svh index 8c57ff4c2..52763e73d 100644 --- a/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/src/caliptra_top_env_configuration.svh +++ b/src/integration/uvmf_caliptra_top/uvmf_template_output/verification_ip/environment_packages/caliptra_top_env_pkg/src/caliptra_top_env_configuration.svh @@ -130,11 +130,11 @@ rand soc_ifc_subenv_config_t soc_ifc_subenv_config; super.initialize(sim_level, environment_path, interface_names, register_model, interface_activity); // Interface initialization for sub-environments - soc_ifc_subenv_interface_names = new[6]; - soc_ifc_subenv_interface_activity = new[6]; + soc_ifc_subenv_interface_names = new[7]; + soc_ifc_subenv_interface_activity = new[7]; - soc_ifc_subenv_interface_names = interface_names[0:5]; - soc_ifc_subenv_interface_activity = interface_activity[0:5]; + soc_ifc_subenv_interface_names = interface_names[0:6]; + soc_ifc_subenv_interface_activity = interface_activity[0:6]; diff --git a/src/keyvault/config/keyvault.vf b/src/keyvault/config/keyvault.vf index 825fd9d1c..40ef426e3 100644 --- a/src/keyvault/config/keyvault.vf +++ b/src/keyvault/config/keyvault.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv diff --git a/src/keyvault/rtl/kv.sv b/src/keyvault/rtl/kv.sv index f5a1e08cd..4188fde2f 100644 --- a/src/keyvault/rtl/kv.sv +++ b/src/keyvault/rtl/kv.sv @@ -29,7 +29,8 @@ module kv input logic rst_b, input logic core_only_rst_b, input logic cptra_pwrgood, - input logic fw_update_rst_window, + input logic fw_update_rst_window, + input logic cptra_in_debug_scan_mode, input logic debugUnlock_or_scan_mode_switch, //uC AHB Lite Interface @@ -61,8 +62,6 @@ logic kv_reg_read_error, kv_reg_write_error; logic [AHB_ADDR_WIDTH-1:0] uc_req_addr; kv_uc_req_t uc_req; -logic debug_locked_f; -logic debug_unlocked; logic flush_keyvault; logic [31:0] debug_value; @@ -77,6 +76,8 @@ logic [KV_NUM_KEYS-1:0] lock_use_q; kv_reg__in_t kv_reg_hwif_in; kv_reg__out_t kv_reg_hwif_out; +logic [KV_NUM_KEYS-1:0] key_entry_clear; + ahb_slv_sif #( .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), .AHB_DATA_WIDTH(AHB_DATA_WIDTH), @@ -115,7 +116,8 @@ always_comb uc_req_error = kv_reg_read_error | kv_reg_write_error; always_comb uc_req_hold = '0; //Flush the keyvault with the debug value when FW pokes the register or we detect debug mode unlocking -always_comb flush_keyvault = debugUnlock_or_scan_mode_switch | kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values.value; +always_comb flush_keyvault = debugUnlock_or_scan_mode_switch | + (cptra_in_debug_scan_mode & kv_reg_hwif_out.CLEAR_SECRETS.wr_debug_values.value); //Pick between keyvault debug mode 0 or 1 always_comb debug_value = kv_reg_hwif_out.CLEAR_SECRETS.sel_debug_value.value ? CLP_DEBUG_MODE_KV_1 : CLP_DEBUG_MODE_KV_0; @@ -125,31 +127,52 @@ always_comb begin : keyvault_pcr_signing end end +//Generate clear signal for each key entry +//don't clear when writes are locked +//hold the clear when writes are in progress +generate + for (genvar g_entry = 0; g_entry < KV_NUM_KEYS; g_entry++) begin + always_ff@(posedge clk or negedge rst_b) begin + if(~rst_b) begin + key_entry_clear[g_entry] <= '0; + end + else begin + key_entry_clear[g_entry] <= (kv_reg_hwif_out.KEY_CTRL[g_entry].clear.value & ~lock_wr_q[g_entry] & ~lock_use_q[g_entry]) | + (key_entry_clear[g_entry] & key_entry_ctrl_we[g_entry]); + end + end + end +endgenerate + always_comb begin : keyvault_ctrl //keyvault control registers for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin - //Qualify lock signals as they are on fw upd reset and create RDC violations if allowed to reset asynchronously - lock_wr_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_wr.value & ~fw_update_rst_window; - lock_use_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_use.value & ~fw_update_rst_window; - //once lock is set, only reset can unset it - kv_reg_hwif_in.KEY_CTRL[entry].lock_wr.swwel = lock_wr_q[entry]; - kv_reg_hwif_in.KEY_CTRL[entry].lock_use.swwel = lock_use_q[entry]; - //clear dest valid and last dword - kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry]; - kv_reg_hwif_in.KEY_CTRL[entry].last_dword.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry]; //init for AND-OR key_entry_ctrl_we[entry] = '0; key_entry_dest_valid_next[entry] = '0; key_entry_last_dword_next[entry] = '0; + + //Qualify lock signals as they are on fw upd reset and create RDC violations if allowed to reset asynchronously + lock_wr_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_wr.value & ~fw_update_rst_window; + lock_use_q[entry] = kv_reg_hwif_out.KEY_CTRL[entry].lock_use.value & ~fw_update_rst_window; + for (int client = 0; client < KV_NUM_WRITE; client++) begin - key_entry_ctrl_we[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en; - key_entry_dest_valid_next[entry] |= kv_write[client].write_en & (kv_write[client].write_entry == entry) ? kv_write[client].write_dest_valid : '0; + key_entry_ctrl_we[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en & + ~lock_wr_q[entry] & ~lock_use_q[entry]; + key_entry_dest_valid_next[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en ? kv_write[client].write_dest_valid : '0; //store the final offset on the last write cycle, we'll use that to signal last dword on reads - key_entry_last_dword_next[entry] |= kv_write[client].write_en & (kv_write[client].write_entry == entry) ? kv_write[client].write_offset : '0; + key_entry_last_dword_next[entry] |= (kv_write[client].write_entry == entry) & kv_write[client].write_en ? kv_write[client].write_offset : '0; end - kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.we = key_entry_ctrl_we[entry]; + //once lock is set, only reset can unset it + kv_reg_hwif_in.KEY_CTRL[entry].lock_wr.swwel = lock_wr_q[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].lock_use.swwel = lock_use_q[entry]; + //clear dest valid and last dword + kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.hwclr = key_entry_clear[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].last_dword.hwclr = key_entry_clear[entry]; + + kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.we = key_entry_ctrl_we[entry] & ~key_entry_clear[entry]; kv_reg_hwif_in.KEY_CTRL[entry].dest_valid.next = key_entry_dest_valid_next[entry]; - kv_reg_hwif_in.KEY_CTRL[entry].last_dword.we = key_entry_ctrl_we[entry]; + kv_reg_hwif_in.KEY_CTRL[entry].last_dword.we = key_entry_ctrl_we[entry] & ~key_entry_clear[entry]; kv_reg_hwif_in.KEY_CTRL[entry].last_dword.next = key_entry_last_dword_next[entry]; end @@ -169,10 +192,9 @@ always_comb begin : keyvault_ctrl key_entry_next[entry][dword] |= flush_keyvault ? debug_value : kv_write[client].write_en & (kv_write[client].write_entry == entry) ? kv_write[client].write_data : '0; end - kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.we = key_entry_we[entry][dword]; + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.we = key_entry_we[entry][dword] & ~key_entry_clear[entry]; kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.next = key_entry_next[entry][dword]; - //don't clear when writes are locked - kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.hwclr = kv_reg_hwif_out.KEY_CTRL[entry].clear.value & ~lock_wr_q[entry] & ~lock_use_q[entry]; + kv_reg_hwif_in.KEY_ENTRY[entry][dword].data.hwclr = key_entry_clear[entry]; end end end @@ -200,14 +222,13 @@ always_comb begin : keyvault_readmux end end -//Write error when attempting to write to entry that is locked for writes +//Write error when attempting to write to entry that is locked for writes, use, or is being cleared always_comb begin : keyvault_write_resp for (int client = 0 ; client < KV_NUM_WRITE; client++) begin kv_wr_resp[client].error = '0; for (int entry = 0; entry < KV_NUM_KEYS; entry++) begin kv_wr_resp[client].error |= (kv_write[client].write_entry == entry) & kv_write[client].write_en & - lock_wr_q[entry] & - lock_use_q[entry]; + (key_entry_clear[entry] | lock_wr_q[entry] | lock_use_q[entry]); end end end diff --git a/src/keyvault/rtl/kv_fsm.sv b/src/keyvault/rtl/kv_fsm.sv index bcf2f65ea..d0c770834 100644 --- a/src/keyvault/rtl/kv_fsm.sv +++ b/src/keyvault/rtl/kv_fsm.sv @@ -38,6 +38,7 @@ module kv_fsm output logic [OFFSET_W-1:0] write_offset, output logic write_pad, output logic [31:0] pad_data, + output logic write_last, output logic ready, @@ -96,6 +97,7 @@ always_comb arc_KV_LENGTH_KV_DONE = kv_fsm_ps == KV_LENGTH; always_comb arc_KV_DONE_KV_IDLE = '1; always_comb offset_rst = arc_KV_RW_KV_DONE | arc_KV_LENGTH_KV_DONE; +always_comb write_last = arc_KV_RW_KV_DONE | arc_KV_LENGTH_KV_DONE; always_comb begin : kv_fsm_comb kv_fsm_ns = kv_fsm_ps; diff --git a/src/keyvault/rtl/kv_read_client.sv b/src/keyvault/rtl/kv_read_client.sv index 17f3a2077..a556604b1 100644 --- a/src/keyvault/rtl/kv_read_client.sv +++ b/src/keyvault/rtl/kv_read_client.sv @@ -67,6 +67,7 @@ kv_read_fsm .write_en(write_en), .write_offset(write_offset), .write_pad(write_pad), + .write_last(), .pad_data(pad_data), .ready(kv_ready), .done(read_done) diff --git a/src/keyvault/rtl/kv_write_client.sv b/src/keyvault/rtl/kv_write_client.sv index 969341d97..f8a2ca670 100644 --- a/src/keyvault/rtl/kv_write_client.sv +++ b/src/keyvault/rtl/kv_write_client.sv @@ -50,6 +50,7 @@ logic [DATA_OFFSET_W-1:0] dest_write_offset; logic dest_write_en; logic [31:0] pad_data; logic write_pad; +logic write_last; //dest write block kv_fsm #( @@ -68,6 +69,7 @@ kv_dest_write_fsm .write_en(dest_write_en), .write_offset(dest_write_offset), .write_pad(write_pad), + .write_last(write_last), .pad_data(pad_data), .ready(kv_ready), .done(dest_done) @@ -79,8 +81,8 @@ always_comb kv_write.write_entry = write_ctrl_reg.write_entry; always_comb kv_write.write_offset = dest_write_offset; always_comb kv_write.write_en = dest_write_en; always_comb kv_write.write_data = dest_data[(DATA_NUM_DWORDS-1) - dest_read_offset]; - -always_comb kv_write.write_dest_valid = write_ctrl_reg.write_dest_vld; +//write zeroes here until last cycle +always_comb kv_write.write_dest_valid = write_last ? write_ctrl_reg.write_dest_vld : '0; always_ff @(posedge clk or negedge rst_b) begin if (!rst_b) begin diff --git a/src/keyvault/uvmf_kv/kv_interfaces.yaml b/src/keyvault/uvmf_kv/kv_interfaces.yaml index e86ace813..49130c75c 100644 --- a/src/keyvault/uvmf_kv/kv_interfaces.yaml +++ b/src/keyvault/uvmf_kv/kv_interfaces.yaml @@ -28,6 +28,9 @@ uvmf: - name: debug_locked dir: output width: '1' + - name: cptra_in_debug_scan_mode + dir: output + width: '1' transaction_constraints: - name: wait_cycles_c @@ -54,6 +57,10 @@ uvmf: type: bit iscompare: 'False' isrand: 'False' + - name: scan_mode + type: bit + iscompare: 'False' + isrand: 'False' #################### WRITE #################### kv_write: diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hdl_top.sv b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hdl_top.sv index 15a4ea314..7fdc017ce 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hdl_top.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/project_benches/kv/tb/testbench/hdl_top.sv @@ -203,7 +203,7 @@ import uvmf_base_pkg_hdl::*; .rst_b (kv_rst_agent_bus.rst_b ), .core_only_rst_b (kv_rst_agent_bus.core_only_rst_b), .cptra_pwrgood (kv_rst_agent_bus.cptra_pwrgood), - + .cptra_in_debug_scan_mode (kv_rst_agent_bus.cptra_in_debug_scan_mode), .debugUnlock_or_scan_mode_switch (kv_rst_agent_bus.debug_locked), //uC AHB Lite Interface diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv index 2955b5cce..0132574a6 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/registers/kv_reg_model_top_pkg.sv @@ -169,11 +169,12 @@ package kv_reg_model_top_pkg; rand uvm_reg_field debug_mode_unlocked; rand uvm_reg_field clear_secrets_bit; + rand uvm_reg_field cptra_in_debug_scan_mode; // Function: new // function new(string name = "kv_val_reg"); - super.new(name, 2, UVM_NO_COVERAGE); + super.new(name, 3, UVM_NO_COVERAGE); endfunction @@ -185,6 +186,10 @@ package kv_reg_model_top_pkg; clear_secrets_bit = uvm_reg_field::type_id::create("clear_secrets_bit"); clear_secrets_bit.configure(this, 1, 1, "RW", 0, 1'b0, 1, 1, 1); + + cptra_in_debug_scan_mode = uvm_reg_field::type_id::create("cptra_in_debug_scan_mode"); + cptra_in_debug_scan_mode.configure(this, 1, 2, "RW", 0, 1'b0, 1, 1, 1); + endfunction endclass @@ -213,6 +218,26 @@ package kv_reg_model_top_pkg; clear.configure(this, 32, 0, "RW", 0, 32'b0, 1, 1, 1); endfunction endclass + + class kv_val_ctrl_derived extends uvm_reg; + `uvm_object_utils(kv_val_ctrl_derived) + + rand uvm_reg_field clear_derived; //32 bits, one for each KEY_CTRL + + // Function: new + // + function new(string name = "kv_val_ctrl_derived"); + super.new(name, 32, UVM_NO_COVERAGE); + endfunction + + + // Function: build + // + virtual function void build(); + clear_derived = uvm_reg_field::type_id::create("clear_derived"); + clear_derived.configure(this, 32, 0, "RW", 0, 32'b0, 1, 1, 1); + endfunction + endclass // pragma uvmf custom define_register_classes end // pragma uvmf custom define_block_map_coverage_class begin @@ -221,37 +246,37 @@ package kv_reg_model_top_pkg; // // Coverage for the 'ahb_map' in 'kv_reg_model' //-------------------------------------------------------------------- - class kv_ahb_map_coverage extends uvm_object; - `uvm_object_utils(kv_ahb_map_coverage) + // class kv_ahb_map_coverage extends uvm_object; + // `uvm_object_utils(kv_ahb_map_coverage) - covergroup ra_cov(string name) with function sample(uvm_reg_addr_t addr, bit is_read); + // covergroup ra_cov(string name) with function sample(uvm_reg_addr_t addr, bit is_read); - option.per_instance = 1; - option.name = name; + // option.per_instance = 1; + // option.name = name; - ADDR: coverpoint addr { - bins example_reg0 = {'h0}; - bins example_reg1 = {'h1}; - } + // ADDR: coverpoint addr { + // bins example_reg0 = {'h0}; + // bins example_reg1 = {'h1}; + // } - RW: coverpoint is_read { - bins RD = {1}; - bins WR = {0}; - } + // RW: coverpoint is_read { + // bins RD = {1}; + // bins WR = {0}; + // } - ACCESS: cross ADDR, RW; + // ACCESS: cross ADDR, RW; - endgroup: ra_cov + // endgroup: ra_cov - function new(string name = "kv_ahb_map_coverage"); - ra_cov = new(name); - endfunction: new + // function new(string name = "kv_ahb_map_coverage"); + // ra_cov = new(name); + // endfunction: new - function void sample(uvm_reg_addr_t offset, bit is_read); - ra_cov.sample(offset, is_read); - endfunction: sample + // function void sample(uvm_reg_addr_t offset, bit is_read); + // ra_cov.sample(offset, is_read); + // endfunction: sample - endclass: kv_ahb_map_coverage + // endclass: kv_ahb_map_coverage // pragma uvmf custom define_block_map_coverage_class end //TODO: Add coverage classes for each of the maps @@ -270,6 +295,7 @@ package kv_reg_model_top_pkg; rand kv_val_reg val_reg; rand kv_val_ctrl val_ctrl; + rand kv_val_ctrl_derived val_ctrl_derived; // pragma uvmf custom instantiate_registers_within_block end uvm_reg_map default_map; @@ -291,7 +317,7 @@ package kv_reg_model_top_pkg; uvm_reg_map kv_ecc_seed_read_map; //TODO add coverage for the other maps - kv_ahb_map_coverage ahb_map_cg; + // kv_ahb_map_coverage ahb_map_cg; // Function: new // @@ -303,20 +329,20 @@ package kv_reg_model_top_pkg; // virtual function void build(); ahb_map = create_map("ahb_map", 0, 4, UVM_LITTLE_ENDIAN); - if(has_coverage(UVM_CVR_ADDR_MAP)) begin - ahb_map_cg = kv_ahb_map_coverage::type_id::create("ahb_map_cg"); - ahb_map_cg.ra_cov.set_inst_name(this.get_full_name()); - void'(set_coverage(UVM_CVR_ADDR_MAP)); - end + // if(has_coverage(UVM_CVR_ADDR_MAP)) begin + // ahb_map_cg = kv_ahb_map_coverage::type_id::create("ahb_map_cg"); + // ahb_map_cg.ra_cov.set_inst_name(this.get_full_name()); + // void'(set_coverage(UVM_CVR_ADDR_MAP)); + // end // pragma uvmf custom construct_configure_build_registers_within_block begin - example_reg0 = kv_example_reg0::type_id::create("example_reg0"); - example_reg0.configure(this, null, "example_reg0"); - example_reg0.build(); - example_reg1 = kv_example_reg1::type_id::create("example_reg1"); - example_reg1.configure(this, null, "example_reg1"); - example_reg1.build(); + // example_reg0 = kv_example_reg0::type_id::create("example_reg0"); + // example_reg0.configure(this, null, "example_reg0"); + // example_reg0.build(); + // example_reg1 = kv_example_reg1::type_id::create("example_reg1"); + // example_reg1.configure(this, null, "example_reg1"); + // example_reg1.build(); val_reg = kv_val_reg::type_id::create("val_reg"); val_reg.configure(this,null,"val_reg"); @@ -325,6 +351,10 @@ package kv_reg_model_top_pkg; val_ctrl = kv_val_ctrl::type_id::create("val_ctrl"); val_ctrl.configure(this,null,"val_ctrl"); val_ctrl.build(); + + val_ctrl_derived = kv_val_ctrl_derived::type_id::create("val_ctrl_derived"); + val_ctrl_derived.configure(this,null,"val_ctrl_derived"); + val_ctrl_derived.build(); // pragma uvmf custom construct_configure_build_registers_within_block end // pragma uvmf custom add_registers_to_block_map begin //ahb_map.add_reg(example_reg0, 'h0, "RW"); @@ -358,6 +388,7 @@ package kv_reg_model_top_pkg; //Add debug_mode reg to all maps (only for TB purposes) default_map.add_reg(val_reg, 'h1_0000, "RW"); default_map.add_reg(val_ctrl, 'h1_0004, "RW"); + default_map.add_reg(val_ctrl_derived, 'h1_0008, "RW"); kv_hmac_write_map.add_reg(val_reg, 'h1_0000, "RW"); kv_sha512_write_map.add_reg(val_reg, 'h1_0000, "RW"); @@ -369,8 +400,14 @@ package kv_reg_model_top_pkg; kv_ecc_write_map.add_reg (val_ctrl, 'h1_0004, "RW"); kv_doe_write_map.add_reg (val_ctrl, 'h1_0004, "RW"); + kv_hmac_write_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_sha512_write_map.add_reg(val_ctrl_derived, 'h1_0008, "RW"); + kv_ecc_write_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_doe_write_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_AHB_map.add_reg(val_reg, 'h1_0000, "RW"); kv_AHB_map.add_reg(val_ctrl, 'h1_0004, "RW"); + kv_AHB_map.add_reg(val_ctrl_derived, 'h1_0008, "RW"); kv_hmac_key_read_map.add_reg(val_reg, 'h1_0000, "RW"); kv_hmac_block_read_map.add_reg(val_reg, 'h1_0000, "RW"); @@ -383,6 +420,12 @@ package kv_reg_model_top_pkg; kv_sha512_block_read_map.add_reg(val_ctrl, 'h1_0004, "RW"); kv_ecc_privkey_read_map.add_reg (val_ctrl, 'h1_0004, "RW"); kv_ecc_seed_read_map.add_reg (val_ctrl, 'h1_0004, "RW"); + + kv_hmac_key_read_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_hmac_block_read_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_sha512_block_read_map.add_reg(val_ctrl_derived, 'h1_0008, "RW"); + kv_ecc_privkey_read_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); + kv_ecc_seed_read_map.add_reg (val_ctrl_derived, 'h1_0008, "RW"); endfunction @@ -413,13 +456,13 @@ package kv_reg_model_top_pkg; // Function: sample // - function void sample(uvm_reg_addr_t offset, bit is_read, uvm_reg_map map); - if(get_coverage(UVM_CVR_ADDR_MAP)) begin - if(map.get_name() == "ahb_map_cg") begin - ahb_map_cg.sample(offset, is_read); - end - end - endfunction: sample + // function void sample(uvm_reg_addr_t offset, bit is_read, uvm_reg_map map); + // if(get_coverage(UVM_CVR_ADDR_MAP)) begin + // if(map.get_name() == "ahb_map_cg") begin + // ahb_map_cg.sample(offset, is_read); + // end + // end + // endfunction: sample endclass diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_configuration.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_configuration.svh index 9eed524e9..5c69a35cf 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_configuration.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_env_configuration.svh @@ -110,7 +110,7 @@ extends uvmf_environment_configuration_base; qvip_ahb_lite_slave_subenv_config = qvip_ahb_lite_slave_env_configuration::type_id::create("qvip_ahb_lite_slave_subenv_config"); kv_configuration_cg=new; - `uvm_warning("COVERAGE_MODEL_REVIEW", "A covergroup has been constructed which may need review because of either generation or re-generation with merging. Please note that configuration variables added as a result of re-generation and merging are not automatically added to the covergroup. Remove this warning after the covergroup has been reviewed.") + `uvm_info("COVERAGE_MODEL_REVIEW", "TODO: A covergroup has been constructed which may need review because of either generation or re-generation with merging. Please note that configuration variables added as a result of re-generation and merging are not automatically added to the covergroup. Remove this warning after the covergroup has been reviewed.", UVM_MEDIUM) // pragma uvmf custom new begin // pragma uvmf custom new end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh index eccc290f4..7b9db72bf 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_predictor.svh @@ -301,11 +301,12 @@ class kv_predictor #( last_dword_written[entry] = 'h0; //Clear last dword on hard rst end end - else if (t.debug_mode) begin + else if (t.debug_mode | t.scan_mode) begin //Set val_reg to 1 for use in reg predictor p_kv_rm.val_reg.debug_mode_unlocked.set(1'b1); + p_kv_rm.val_reg.cptra_in_debug_scan_mode.set(1'b1); - if (clear_secrets_data[1] == 'h1) begin + if (clear_secrets_data[p_kv_rm.kv_reg_rm.CLEAR_SECRETS.sel_debug_value.get_lsb_pos()] == 'h1) begin for(entry = 0; entry < KV_NUM_KEYS; entry++) begin //Debug mode should flush all regs inspite of locks for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin @@ -351,8 +352,13 @@ class kv_predictor #( end //If debug mode was unlocked, set a val register to let reg predictor know - if (!t.debug_mode) + if (!t.debug_mode) begin p_kv_rm.val_reg.debug_mode_unlocked.set(1'b0); + //TODO: resetting debug_scan_mode needed? + if (!t.scan_mode) begin + p_kv_rm.val_reg.cptra_in_debug_scan_mode.set(1'b0); + end + end // Code for sending output transaction out through kv_sb_ap // Please note that each broadcasted transaction should be a different object than previously @@ -586,8 +592,8 @@ class kv_predictor #( string reg_name; reg [KV_DATA_W-1:0] data_active; reg [ahb_lite_slave_0_params::AHB_WDATA_WIDTH-1:0] address_aligned; - uvm_reg val_ctrl; - uvm_reg_data_t val_ctrl_data; + uvm_reg val_ctrl, val_reg, val_ctrl_derived; + uvm_reg_data_t val_ctrl_data, val_reg_data, val_ctrl_derived_data; ahb_slave_0_ae_debug = t; `uvm_info("PRED", "Transaction Received through ahb_slave_0_ae", UVM_MEDIUM) @@ -604,30 +610,40 @@ class kv_predictor #( //Copy txn and modify required fields later kv_sb_ahb_ap_output_transaction.copy(ahb_txn); - if (ahb_txn.address == `KV_REG_CLEAR_SECRETS) begin - p_kv_rm.val_reg.clear_secrets_bit.set(1'b1); - if (data_active[1:0] == 'h1) begin - for(entry = 0; entry < KV_NUM_KEYS; entry++) begin - //Read locks before clearing - do not clear if locked - kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); - kv_reg_data = kv_reg.get_mirrored_value(); - if(kv_reg_data[1:0] == 2'b00) begin - for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin - p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict(CLP_DEBUG_MODE_KV_0); - p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].set(CLP_DEBUG_MODE_KV_0); + //Read val reg to determine if we're in debug mode + val_reg = p_kv_rm.get_reg_by_name("val_reg"); + val_reg_data = val_reg.get(); + + //Only allow clear_secrets during debug mode + if ((ahb_txn.address == `KV_REG_CLEAR_SECRETS) ) begin + //Update val register with CLEAR_SECRETS wr_debug_values field + p_kv_rm.val_reg.clear_secrets_bit.set(data_active[p_kv_rm.kv_reg_rm.CLEAR_SECRETS.wr_debug_values.get_lsb_pos()]); + + if (val_reg_data[p_kv_rm.val_reg.cptra_in_debug_scan_mode.get_lsb_pos()]) begin //[2]) begin + //Only allow clear operation if in debug mode + if (data_active[1:0] == 'h1) begin + for(entry = 0; entry < KV_NUM_KEYS; entry++) begin + //Read locks before clearing - do not clear if locked + kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); + kv_reg_data = kv_reg.get_mirrored_value(); + if(kv_reg_data[1:0] == 2'b00) begin + for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin + p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict(CLP_DEBUG_MODE_KV_0); + p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].set(CLP_DEBUG_MODE_KV_0); + end end end end - end - else if(data_active[1:0] == 'h3) begin - for(entry = 0; entry < KV_NUM_KEYS; entry++) begin - //Read locks before clearing - kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); - kv_reg_data = kv_reg.get_mirrored_value(); - if(kv_reg_data[1:0] == 2'b00) begin - for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin - p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict(CLP_DEBUG_MODE_KV_1); - p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].set(CLP_DEBUG_MODE_KV_1); + else if(data_active[1:0] == 'h3) begin + for(entry = 0; entry < KV_NUM_KEYS; entry++) begin + //Read locks before clearing + kv_reg = p_kv_rm.get_reg_by_name($sformatf("KEY_CTRL[%0d]",entry)); + kv_reg_data = kv_reg.get_mirrored_value(); + if(kv_reg_data[1:0] == 2'b00) begin + for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin + p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict(CLP_DEBUG_MODE_KV_1); + p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].set(CLP_DEBUG_MODE_KV_1); + end end end end @@ -646,8 +662,13 @@ class kv_predictor #( if(data_active[2] && !kv_reg_data[0] && !kv_reg_data[1]) begin val_ctrl_data[entry] = 'b1; //In design, clear is a single pulse reg. This val_ctrl[*] will be reset in kv_reg_predictor + val_ctrl_derived_data[entry] = 'b1; //p_kv_rm.kv_reg_rm.kv_val_ctrl.predict(val_ctrl_data); + `uvm_info("PRED", "Setting clear field of val_ctrl register", UVM_MEDIUM) p_kv_rm.val_ctrl.set(val_ctrl_data); + + `uvm_info("PRED", "Setting clear field of val_ctrl_derived register", UVM_MEDIUM) + p_kv_rm.val_ctrl_derived.set(val_ctrl_derived_data); //Clear the entry that is being accessed for(offset = 0; offset < KV_NUM_DWORDS; offset++) begin p_kv_rm.kv_reg_rm.KEY_ENTRY[entry][offset].predict('h0); @@ -733,8 +754,9 @@ endclass t_expected.error = 'b0; end - if (val_ctrl_data[t_received.read_entry]) + if (val_ctrl_data[t_received.read_entry]) begin last_dword_written[t_received.read_entry] = 'h0; + end t_expected.last = (last_dword_written[t_received.read_entry] == t_received.read_offset); t_expected.read_entry = t_received.read_entry; @@ -742,10 +764,11 @@ endclass endfunction function void kv_predictor::populate_expected_kv_write_txn (ref kv_sb_ap_output_transaction_write_t t_expected, kv_write_transaction t_received); - uvm_reg kv_reg; - uvm_reg_data_t kv_reg_data; + uvm_reg kv_reg, val_ctrl_derived; + uvm_reg_data_t kv_reg_data, val_ctrl_derived_data; logic lock_use; logic lock_wr; + logic clear; //TODO: This logic takes advantage of the fact that reg model writes happen without a 1 clk delay. //So when predictor reads the CTRL reg, the lock info is already up to date @@ -756,16 +779,38 @@ endclass lock_wr = kv_reg_data[0]; lock_use = kv_reg_data[1]; - //Copy received txn - t_expected = t_received; + val_ctrl_derived = p_kv_rm.get_reg_by_name("val_ctrl_derived"); + val_ctrl_derived_data = val_ctrl_derived.get(); - //Error should be set when writing to locked regs - if(lock_wr || lock_use) - t_expected.error = 'b1; + //Copy received txn + // t_expected = t_received; + t_expected.write_en = t_received.write_en; + t_expected.write_entry = t_received.write_entry; + t_expected.write_offset = t_received.write_offset; + t_expected.write_data = t_received.write_data; + t_expected.write_dest_valid = t_received.write_dest_valid; + + //Error should be set when writing to locked regs //TODO: error when entry is being cleared during write + if (t_received.write_en) begin + if(lock_wr || lock_use) begin + t_expected.error = 1'b1; + `uvm_info("PRED", "Trying to write to a locked reg", UVM_MEDIUM) + end + else if (/*this.write_in_progress[t_received.write_entry] &&*/ val_ctrl_derived_data[t_received.write_entry]) begin + t_expected.error = 1'b1; + `uvm_info("PRED","Attempts to clear a reg while write is in progress results in an error", UVM_MEDIUM) + `uvm_info("PRED", $sformatf("Write entry = %0d, val_ctrl_derived_data = %b", t_received.write_entry, val_ctrl_derived_data), UVM_MEDIUM) + end + else begin + t_expected.error = 1'b0; + //Keep track of last dword written + last_dword_written[t_received.write_entry] = t_received.write_offset; + end + end + else begin + t_expected.error = 1'b0; + end - //Keep track of last dword written - last_dword_written[t_received.write_entry] = t_received.write_offset; - endfunction // pragma uvmf custom external end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh index 860b98850..de58e86f4 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_reg_predictor.svh @@ -65,8 +65,8 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B uvm_reg_data_t val_reg_data; uvm_reg_item val_reg_item; - uvm_reg val_ctrl; - uvm_reg_data_t val_ctrl_data; + uvm_reg val_ctrl, val_ctrl_derived; + uvm_reg_data_t val_ctrl_data, val_ctrl_derived_data; uvm_reg_item val_ctrl_item; logic lock_wr; @@ -100,44 +100,36 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //Calculate CTRL addr based on entry info addr = convert_kv_to_ctrl_addr(entry_offset); - //Build rw_ctrl (reg model txn for CTRL reg) - rw_ctrl = rw; - rw_ctrl.addr = uvm_reg_addr_t'(addr); - - //----------------------------------------------- - //Read val reg first - //----------------------------------------------- - val_reg = map.get_reg_by_offset('h1_0000); - val_reg_data = val_reg.get(); - - val_ctrl = map.get_reg_by_offset('h1_0004); - val_ctrl_data = val_ctrl.get(); //----------------------------------------------- //Below steps are to read CTRL reg data from reg model //and append dest valid to it (we want to keep lock bits same) //----------------------------------------------- + //Build rw_ctrl (reg model txn for CTRL reg) + rw_ctrl = rw; + rw_ctrl.addr = uvm_reg_addr_t'(addr); + kv_reg = map.get_reg_by_offset(rw.addr, (rw.kind == UVM_READ)); kv_reg_ctrl = map.get_reg_by_offset(rw_ctrl.addr, (rw_ctrl.kind == UVM_READ)); - + //TODO: reg null check? //Read CTRL reg data kv_reg_ctrl_data = kv_reg_ctrl.get_mirrored_value(); //Append dest valid to it kv_reg_ctrl_data = {kv_reg_ctrl_data[31:21], last_dword, kv_reg_ctrl_data[16:14], /*5'h1F*/write_dest_valid, kv_reg_ctrl_data[8:0]}; rw_ctrl.data = kv_reg_ctrl_data; + //----------------------------------------------- - //Predict ctrl reg data so it gets updated in reg model + //Read val reg first //----------------------------------------------- - kv_reg_ctrl_item = new; - kv_reg_ctrl_item.element_kind = UVM_REG; - kv_reg_ctrl_item.element = kv_reg_ctrl; - kv_reg_ctrl_item.path = UVM_PREDICT; - kv_reg_ctrl_item.map = map; - kv_reg_ctrl_item.kind = UVM_WRITE; - kv_reg_ctrl_item.value[0] |= kv_reg_ctrl_data; + val_reg = map.get_reg_by_offset('h1_0000); + val_reg_data = val_reg.get(); + + val_ctrl = map.get_reg_by_offset('h1_0004); + val_ctrl_data = val_ctrl.get(); + + val_ctrl_derived = map.get_reg_by_offset('h1_0008); + val_ctrl_derived_data = val_ctrl_derived.get(); - //Update CTRL reg - kv_reg_ctrl.do_predict(kv_reg_ctrl_item, UVM_PREDICT_DIRECT); //----------------------------------------------- //Update val_ctrl reg to reset clear bit for the entry that is being written @@ -155,6 +147,25 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //Update CTRL reg val_ctrl.do_predict(val_ctrl_item, UVM_PREDICT_DIRECT); + //----------------------------------------------- + //Update val_ctrl_derived reg to reset clear bits for all other entries except current one + //This will be used to hold the clear until writes are finished to current entry + //----------------------------------------------- + for (int i = 0; i < KV_NUM_KEYS; i++) begin + val_ctrl_derived_data[i] /*[entry_offset[4:0]]*/ = (val_ctrl_derived_data[i] & (i == entry_offset[4:0])); //'b0; //Reset clear bit of current entry + end + + val_ctrl_item = new; + val_ctrl_item.element_kind = UVM_REG; + val_ctrl_item.element = val_ctrl_derived; + val_ctrl_item.path = UVM_PREDICT; + val_ctrl_item.map = map; + val_ctrl_item.kind = UVM_WRITE; + val_ctrl_item.value[0] |= val_ctrl_derived_data; + + //Update CTRL reg + val_ctrl_derived.do_predict(val_ctrl_item, UVM_PREDICT_DIRECT); + //----------------------------------------------- //Check clear secrets and lock_wr/use before writing //----------------------------------------------- @@ -169,14 +180,38 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B //If lock_wr, lock_use, debug mode or clear secrets is enabled, do not write to reg model //TODO: Revisit lock and clear condition - if (!lock_wr && !lock_use && !clear_secrets_data[0] && !val_reg_data[0])begin // && !val_reg_data[1]) begin + //TODO: Can write to regs during debug mode. Remove check after updating sequences + `uvm_info("KV_REG_PRED", $sformatf("OUTSIDE, lock_wr = %0d, lock_use = %0d, clear_secrets_wren = %0d, val_reg_data = %b", lock_wr, lock_use, clear_secrets_data[0], val_reg_data), UVM_FULL) + if (!lock_wr && !lock_use && !(clear_secrets_data[0] && val_reg_data[2]) && !val_reg_data[0]) begin + `uvm_info("KV_REG_PRED", "Writing to KEY_ENTRY", UVM_FULL) super.write(tr); + + `uvm_info("KV_REG_PRED", "Updating KEY_CTRL", UVM_FULL) + + //----------------------------------------------- + //Predict ctrl reg data so it gets updated in reg model + //----------------------------------------------- + kv_reg_ctrl_item = new; + kv_reg_ctrl_item.element_kind = UVM_REG; + kv_reg_ctrl_item.element = kv_reg_ctrl; + kv_reg_ctrl_item.path = UVM_PREDICT; + kv_reg_ctrl_item.map = map; + kv_reg_ctrl_item.kind = UVM_WRITE; + kv_reg_ctrl_item.value[0] |= kv_reg_ctrl_data; + + //Update CTRL reg + kv_reg_ctrl.do_predict(kv_reg_ctrl_item, UVM_PREDICT_DIRECT); + end + else begin + `uvm_info("KV_REG_PRED", "Skipping write to KEY_ENTRY", UVM_FULL) + `uvm_info("KV_REG_PRED", $sformatf("lock_wr = %0d, lock_use = %0d, clear_secrets_data = %0d, val_reg_data = %b", lock_wr, lock_use, clear_secrets_data[0], val_reg_data), UVM_FULL) end //----------------------------------------------- //Clear secrets wren bit back to 0 (single pulse behv) - do this if clear_secrets reg is not being written to in the same cycle //----------------------------------------------- if(val_reg_data[1]) begin + `uvm_info("KV_REG_PRED", "Clear_secrets bit is reset after a single pulse", UVM_FULL) clear_secrets_item = new; clear_secrets_item.element_kind = UVM_REG; clear_secrets_item.element = clear_secrets_reg; @@ -196,7 +231,7 @@ class kv_reg_predictor#(type BUSTYPE=int) extends uvm_reg_predictor #(.BUSTYPE(B val_reg_item.path = UVM_PREDICT; val_reg_item.map = map; val_reg_item.kind = UVM_WRITE; - val_reg_item.value[0] |= {1'b0,val_reg_data[0]}; //Clear and clear_secrets_bit are single pulse, so make them 0. Keep debug_mode as is + val_reg_item.value[0] |= {val_reg_data[2],1'b0,val_reg_data[0]}; //Clear and clear_secrets_bit are single pulse, so make them 0. Keep debug_mode as is val_reg.do_predict(val_reg_item, UVM_PREDICT_DIRECT); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh index 76791e6c6..37b51bb32 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/environment_packages/kv_env_pkg/src/kv_wr_rd_lock_sequence.svh @@ -198,6 +198,47 @@ class kv_wr_rd_lock_sequence #( end end + //TODO: this needs env clean up! (Emulate 1 clk delay between key_entry_clear and wr_resp_error) + // //clear x write + // // fork + + // //Issue and wait for reset + // if(configuration.kv_rst_agent_config.sequencer != null) + // kv_rst_agent_poweron_seq.start(configuration.kv_rst_agent_config.sequencer); + // else + // `uvm_error("KV_WR_RD_LOCK", "kv_rst_agent_config.sequencer is null!") + + // // begin + // //Set each CTRL reg with random lock data + // for(int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin + // // if (write_entry_temp < KV_NUM_KEYS-1) begin + // // lock_data = $urandom_range(1,7); //Can set one of lock_wr, lock_use, clear or all together + // reg_model.kv_reg_rm.KEY_CTRL[write_entry_temp].write(sts, 'h4, UVM_FRONTDOOR, reg_model.kv_AHB_map, this); + // `uvm_info("KNU_LOCK", $sformatf("Setting KEY CTRL: %d", write_entry_temp), UVM_MEDIUM) + // assert(sts == UVM_IS_OK) else `uvm_error("AHB_LOCK_SET", $sformatf("Failed when writing to KEY_CTRL[%d]",write_entry_temp)) + // // end + + // for (int write_offset_temp = 0; write_offset_temp < KV_NUM_DWORDS; write_offset_temp++) begin + // // Construct the transaction + // uvm_config_db#(reg [KV_ENTRY_ADDR_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_entry",write_entry_temp); + // uvm_config_db#(reg [KV_ENTRY_SIZE_W-1:0])::set(null, "uvm_test_top.environment.kv_hmac_write_agent.sequencer.hmac_write_seq", "local_write_offset",write_offset_temp); + // `uvm_info("KNU_WRITE", $sformatf("Writing to entry: %0d, offset: %0d", write_entry_temp, write_offset_temp), UVM_MEDIUM) + // hmac_write_seq.start(configuration.kv_hmac_write_agent_config.sequencer); + // end + + + // end + // // end + + // // begin + // //Write to all entries, random offsets + // // for (int write_entry_temp = 0; write_entry_temp < KV_NUM_KEYS; write_entry_temp++) begin + + // // end + + // // end + // // join + endtask endclass \ No newline at end of file diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction.svh index e53230806..1642ac4e6 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_read_pkg/src/kv_read_transaction.svh @@ -124,7 +124,7 @@ class kv_read_transaction #( virtual function string convert2string(); // pragma uvmf custom convert2string begin // UVMF_CHANGE_ME : Customize format if desired. - return $sformatf("read_entry:0x%x read_offset:0x%x error: 0x%x last_dword: 0x%x read_data:0x%x ",read_entry,read_offset,error,last,read_data); + return $sformatf("read_entry:0x%x read_offset:0x%x read_resp_err: 0x%x last_dword: 0x%x read_data:0x%x ",read_entry,read_offset,error,last,read_data); // pragma uvmf custom convert2string end endfunction diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_cold_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_cold_rst_sequence.svh index 99bfe2ea9..80d5f746a 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_cold_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_cold_rst_sequence.svh @@ -57,6 +57,7 @@ class kv_rst_cold_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b1; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_COLD_RST", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -71,6 +72,7 @@ class kv_rst_cold_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b1; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_COLD_RST", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -85,6 +87,7 @@ class kv_rst_cold_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_COLD_RST", {"Response:",req.convert2string()},UVM_MEDIUM) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_core_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_core_rst_sequence.svh index 1b3aa73d2..770007363 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_core_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_core_rst_sequence.svh @@ -56,6 +56,7 @@ class kv_rst_core_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_CORE_RST", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -70,6 +71,7 @@ class kv_rst_core_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_CORE_RST", {"Response:",req.convert2string()},UVM_MEDIUM) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_sequence.svh index 09869a7b7..129d9fc8b 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_debug_sequence.svh @@ -56,6 +56,7 @@ class kv_rst_debug_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b1; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_DEBUG", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -70,6 +71,7 @@ class kv_rst_debug_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_DEBUG", {"Response:",req.convert2string()},UVM_MEDIUM) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_driver_bfm.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_driver_bfm.sv index b396edd94..8e81c2500 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_driver_bfm.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_driver_bfm.sv @@ -116,6 +116,8 @@ end reg fw_update_rst_window_o = 'bz; tri debug_locked_i; reg debug_locked_o = 'bz; + tri cptra_in_debug_scan_mode_i; + reg cptra_in_debug_scan_mode_o = 'bz; // Bi-directional signals @@ -139,6 +141,8 @@ end assign fw_update_rst_window_i = bus.fw_update_rst_window; assign bus.debug_locked = (initiator_responder == INITIATOR) ? debug_locked_o : 'bz; assign debug_locked_i = bus.debug_locked; + assign bus.cptra_in_debug_scan_mode = (initiator_responder == INITIATOR) ? cptra_in_debug_scan_mode_o : 'bz; + assign cptra_in_debug_scan_mode_i = bus.cptra_in_debug_scan_mode; // Proxy handle to UVM driver kv_rst_pkg::kv_rst_driver proxy; @@ -175,6 +179,7 @@ end core_only_rst_b_o <= 'bz; fw_update_rst_window_o <= 'bz; debug_locked_o <= 'b1; + cptra_in_debug_scan_mode_o <= 'b0; // Bi-directional signals end @@ -257,6 +262,11 @@ end cptra_pwrgood_o <= 1'b0; if (initiator_struct.debug_mode) debug_locked_o <= 1'b1; + if (initiator_struct.debug_mode | initiator_struct.scan_mode) + cptra_in_debug_scan_mode_o <= 1'b1; + else + cptra_in_debug_scan_mode_o <= 1'b0; + // Wait for the responder to complete the transfer then place the responder data into // kv_rst_responder_struct. @@ -279,6 +289,7 @@ end kv_rst_responder_struct.assert_rst = !rst_b_i; kv_rst_responder_struct.assert_core_rst = !core_only_rst_b_i; kv_rst_responder_struct.debug_mode = debug_locked_i; + kv_rst_responder_struct.scan_mode = cptra_in_debug_scan_mode_i & !debug_locked_i; responder_struct = kv_rst_responder_struct; endtask // pragma uvmf custom initiate_and_get_response end diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_if.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_if.sv index 6bffa8363..e9fc3aafd 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_if.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_if.sv @@ -37,6 +37,7 @@ // .dut_signal_port(kv_rst_bus.rst_b), // Agent output // .dut_signal_port(kv_rst_bus.core_only_rst_b), // Agent output // .dut_signal_port(kv_rst_bus.debug_locked), // Agent output +// .dut_signal_port(kv_rst_bus.cptra_in_debug_scan_mode), // Agent output import uvmf_base_pkg_hdl::*; import kv_rst_pkg_hdl::*; @@ -50,7 +51,8 @@ interface kv_rst_if inout tri rst_b, inout tri core_only_rst_b, inout tri fw_update_rst_window, - inout tri debug_locked + inout tri debug_locked, + inout tri cptra_in_debug_scan_mode ); modport monitor_port @@ -61,7 +63,8 @@ modport monitor_port input rst_b, input core_only_rst_b, input fw_update_rst_window, - input debug_locked + input debug_locked, + input cptra_in_debug_scan_mode ); modport initiator_port @@ -72,7 +75,8 @@ modport initiator_port output rst_b, output core_only_rst_b, output fw_update_rst_window, - output debug_locked + output debug_locked, + output cptra_in_debug_scan_mode ); modport responder_port @@ -83,7 +87,8 @@ modport responder_port input rst_b, input core_only_rst_b, input fw_update_rst_window, - input debug_locked + input debug_locked, + input cptra_in_debug_scan_mode ); diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_macros.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_macros.svh index 51aa84b58..2cdcba5c9 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_macros.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_macros.svh @@ -68,6 +68,7 @@ typedef struct packed { \ bit assert_core_rst ; \ int unsigned wait_cycles ; \ bit debug_mode ; \ + bit scan_mode ; \ } kv_rst_monitor_s; `define kv_rst_TO_MONITOR_STRUCT_FUNCTION \ @@ -78,7 +79,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ };\ return ( kv_rst_monitor_struct);\ endfunction\ @@ -90,7 +92,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ } = kv_rst_monitor_struct;\ endfunction @@ -105,6 +108,7 @@ typedef struct packed { \ bit assert_core_rst ; \ int unsigned wait_cycles ; \ bit debug_mode ; \ + bit scan_mode ; \ } kv_rst_initiator_s; `define kv_rst_TO_INITIATOR_STRUCT_FUNCTION \ @@ -115,7 +119,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ };\ return ( kv_rst_initiator_struct);\ endfunction @@ -127,7 +132,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ } = kv_rst_initiator_struct;\ endfunction @@ -142,6 +148,7 @@ typedef struct packed { \ bit assert_core_rst ; \ int unsigned wait_cycles ; \ bit debug_mode ; \ + bit scan_mode ; \ } kv_rst_responder_s; `define kv_rst_TO_RESPONDER_STRUCT_FUNCTION \ @@ -152,7 +159,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ };\ return ( kv_rst_responder_struct);\ endfunction @@ -164,7 +172,8 @@ typedef struct packed { \ this.assert_rst , \ this.assert_core_rst , \ this.wait_cycles , \ - this.debug_mode \ + this.debug_mode , \ + this.scan_mode \ } = kv_rst_responder_struct;\ endfunction // pragma uvmf custom additional begin diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_monitor_bfm.sv b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_monitor_bfm.sv index 22ddc2100..2d27cd624 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_monitor_bfm.sv +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_monitor_bfm.sv @@ -88,6 +88,7 @@ end tri core_only_rst_b_i; tri fw_update_rst_window_i; tri debug_locked_i; + tri cptra_in_debug_scan_mode_i; assign clk_i = bus.clk; assign dummy_i = bus.dummy; assign cptra_pwrgood_i = bus.cptra_pwrgood; @@ -95,6 +96,7 @@ end assign core_only_rst_b_i = bus.core_only_rst_b; assign fw_update_rst_window_i = bus.fw_update_rst_window; assign debug_locked_i = bus.debug_locked; + assign cptra_in_debug_scan_mode_i = bus.cptra_in_debug_scan_mode; // Proxy handle to UVM monitor kv_rst_pkg::kv_rst_monitor proxy; @@ -106,6 +108,7 @@ end reg core_only_rst_b_o = 'b0; reg fw_update_rst_window_o = 'b0; reg debug_locked_o = 'b0; + reg cptra_in_debug_scan_mode_o = 'b0; function bit any_signal_changed(); @@ -113,7 +116,8 @@ end |(rst_b_i ^ rst_b_o) || |(core_only_rst_b_i ^ core_only_rst_b_o) || |(fw_update_rst_window_i ^ fw_update_rst_window_o) || - |(debug_locked_i ^ debug_locked_o); + |(debug_locked_i ^ debug_locked_o) || + |(cptra_in_debug_scan_mode_i ^ cptra_in_debug_scan_mode_o); endfunction @@ -195,7 +199,8 @@ end // kv_rst_monitor_struct.xyz = cptra_pwrgood_i; // // kv_rst_monitor_struct.xyz = rst_b_i; // // kv_rst_monitor_struct.xyz = core_only_rst_b_i; // - // kv_rst_monitor_struct.xyz = debug_locked_i; // + // kv_rst_monitor_struct.xyz = debug_locked_i; // + // kv_rst_monitor_struct.xyz = cptra_in_debug_scan_mode_i; // // pragma uvmf custom do_monitor begin // UVMF_CHANGE_ME : Implement protocol monitoring. The commented reference code // below are examples of how to capture signal values and assign them to @@ -211,12 +216,14 @@ end core_only_rst_b_o <= core_only_rst_b_i; fw_update_rst_window_o <= fw_update_rst_window_i; debug_locked_o <= debug_locked_i; + cptra_in_debug_scan_mode_o <= cptra_in_debug_scan_mode_i; kv_rst_monitor_struct.set_pwrgood = cptra_pwrgood_i; kv_rst_monitor_struct.assert_rst = !rst_b_i; kv_rst_monitor_struct.assert_core_rst = !core_only_rst_b_i; kv_rst_monitor_struct.wait_cycles = 0; kv_rst_monitor_struct.debug_mode = debug_locked_i; + kv_rst_monitor_struct.scan_mode = cptra_in_debug_scan_mode_i & !debug_locked_i; // pragma uvmf custom do_monitor end endtask diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_poweron_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_poweron_sequence.svh index 66f53ec66..8d0fa8c15 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_poweron_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_poweron_sequence.svh @@ -56,6 +56,7 @@ class kv_rst_poweron_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b1; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_POWERON", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -69,6 +70,7 @@ class kv_rst_poweron_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b1; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_POWERON", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -82,6 +84,7 @@ class kv_rst_poweron_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_POWERON", {"Response:",req.convert2string()},UVM_MEDIUM) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction.svh index 0ed69e68e..fdbcca661 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction.svh @@ -37,6 +37,7 @@ class kv_rst_transaction extends uvmf_transaction_base; bit assert_core_rst ; rand int unsigned wait_cycles ; rand bit debug_mode ; + rand bit scan_mode ; //Constraints for the transaction variables: constraint wait_cycles_c { wait_cycles dist {[1:25] := 80, [25:100] := 15, [100:500] := 5}; } @@ -120,7 +121,7 @@ class kv_rst_transaction extends uvmf_transaction_base; virtual function string convert2string(); // pragma uvmf custom convert2string begin // UVMF_CHANGE_ME : Customize format if desired. - return $sformatf("set_pwrgood:0x%x assert_rst:0x%x assert_core_rst:0x%x wait_cycles:0x%x debug_mode:0x%x",set_pwrgood,assert_rst,assert_core_rst,wait_cycles,debug_mode); + return $sformatf("set_pwrgood:0x%x assert_rst:0x%x assert_core_rst:0x%x wait_cycles:0x%x debug_mode:0x%x scan_mode: 0x%x",set_pwrgood,assert_rst,assert_core_rst,wait_cycles,debug_mode,scan_mode); // pragma uvmf custom convert2string end endfunction @@ -167,6 +168,7 @@ class kv_rst_transaction extends uvmf_transaction_base; this.assert_core_rst = RHS.assert_core_rst; this.wait_cycles = RHS.wait_cycles; this.debug_mode = RHS.debug_mode; + this.scan_mode = RHS.scan_mode; // pragma uvmf custom do_copy end endfunction diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction_coverage.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction_coverage.svh index 48c717306..025bfaad1 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction_coverage.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_transaction_coverage.svh @@ -48,10 +48,15 @@ class kv_rst_transaction_coverage extends uvm_subscriber #(.T(kv_rst_transactio assert_core_rst: coverpoint coverage_trans.assert_core_rst; //wait_cycles: coverpoint coverage_trans.wait_cycles; debug_mode: coverpoint coverage_trans.debug_mode; + // scan_mode: coverpoint coverage_trans.scan_mode; warm_rstXdbg: cross assert_rst, debug_mode; cold_rstXdbg: cross set_pwrgood, debug_mode; core_rstXdbg: cross assert_core_rst, debug_mode; + + // warm_rstXscan: cross assert_rst, scan_mode; + // cold_rstXscan: cross set_pwrgood, scan_mode; + // core_rstXscan: cross assert_core_rst, scan_mode; // pragma uvmf custom covergroup end endgroup diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_warm_rst_sequence.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_warm_rst_sequence.svh index 4dc4e3f7b..8bc89e23d 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_warm_rst_sequence.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/src/kv_rst_warm_rst_sequence.svh @@ -56,6 +56,7 @@ class kv_rst_warm_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b1; req.assert_core_rst = 1'b1; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_WARM_RST", {"Response:",req.convert2string()},UVM_MEDIUM) @@ -70,6 +71,7 @@ class kv_rst_warm_rst_sequence extends kv_rst_sequence_base; req.assert_rst = 1'b0; req.assert_core_rst = 1'b0; req.debug_mode = 1'b0; + req.scan_mode = 1'b0; finish_item(req); `uvm_info("KV_RST_WARM_RST", {"Response:",req.convert2string()},UVM_MEDIUM) diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/yaml/kv_rst_interface.yaml b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/yaml/kv_rst_interface.yaml index 0fcb48a9d..977f71987 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/yaml/kv_rst_interface.yaml +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_rst_pkg/yaml/kv_rst_interface.yaml @@ -28,6 +28,10 @@ uvmf: name: debug_locked reset_value: '''bz' width: '1' + - dir: output + name: cptra_in_debug_scan_mode + reset_value: '''bz' + width: '1' reset: dummy reset_assertion_level: 'False' transaction_constraints: @@ -65,4 +69,10 @@ uvmf: name: debug_mode type: bit unpacked_dimension: '' + - comment: '' + iscompare: 'False' + isrand: 'False' + name: scan_mode + type: bit + unpacked_dimension: '' use_dpi_link: 'False' diff --git a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_transaction.svh b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_transaction.svh index f903218f2..3744645df 100644 --- a/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_transaction.svh +++ b/src/keyvault/uvmf_kv/uvmf_template_output/verification_ip/interface_packages/kv_write_pkg/src/kv_write_transaction.svh @@ -126,7 +126,7 @@ class kv_write_transaction #( virtual function string convert2string(); // pragma uvmf custom convert2string begin // UVMF_CHANGE_ME : Customize format if desired. - return $sformatf("write_en:0x%x write_entry:0x%x write_offset: 0x%x write_data:0x%x write_dest_valid:0x%x error:0x%x",write_en,write_entry,write_offset,write_data,write_dest_valid,error); + return $sformatf("write_en:0x%x write_entry:0x%x write_offset: 0x%x write_data:0x%x write_dest_valid:0x%x write_resp_err:0x%x",write_en,write_entry,write_offset,write_data,write_dest_valid,error); // pragma uvmf custom convert2string end endfunction diff --git a/src/libs/config/compile.yml b/src/libs/config/compile.yml index 3569036ed..c15f5de4b 100644 --- a/src/libs/config/compile.yml +++ b/src/libs/config/compile.yml @@ -16,6 +16,7 @@ targets: - $COMPILE_ROOT/rtl/ahb_slv_sif.sv - $COMPILE_ROOT/rtl/caliptra_icg.sv - $COMPILE_ROOT/rtl/clk_gate.sv + - $COMPILE_ROOT/rtl/caliptra_2ff_sync.sv rtl: directories: [$COMPILE_ROOT/rtl] files: @@ -28,6 +29,7 @@ targets: - $COMPILE_ROOT/rtl/ahb_slv_sif.sv - $COMPILE_ROOT/rtl/caliptra_icg.sv - $COMPILE_ROOT/rtl/clk_gate.sv + - $COMPILE_ROOT/rtl/caliptra_2ff_sync.sv - $COMPILE_ROOT/rtl/ahb_to_reg_adapter.sv --- provides: [uvm_lib] diff --git a/src/libs/config/libs.vf b/src/libs/config/libs.vf index 89d3b44e4..7c0d4c77b 100644 --- a/src/libs/config/libs.vf +++ b/src/libs/config/libs.vf @@ -11,4 +11,5 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv \ No newline at end of file diff --git a/src/libs/rtl/caliptra_2ff_sync.sv b/src/libs/rtl/caliptra_2ff_sync.sv new file mode 100644 index 000000000..9124daa92 --- /dev/null +++ b/src/libs/rtl/caliptra_2ff_sync.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +module caliptra_2ff_sync #( parameter WIDTH=1, + parameter RST_VAL=0) + ( + input logic clk, + input logic rst_b, + input logic [WIDTH-1:0] din, + output logic [WIDTH-1:0] dout + +); + +logic din_ff; + +always_ff@(posedge clk or negedge rst_b) begin + if(!rst_b) begin + dout <= RST_VAL; + din_ff <= RST_VAL; + end + else begin + din_ff <= din; + dout <= din_ff; + end +end + + +endmodule \ No newline at end of file diff --git a/src/libs/rtl/clk_gate.sv b/src/libs/rtl/clk_gate.sv index f4916668a..448a03bc6 100644 --- a/src/libs/rtl/clk_gate.sv +++ b/src/libs/rtl/clk_gate.sv @@ -77,11 +77,11 @@ end `ifdef TECH_SPECIFIC_ICG `USER_ICG user_icg (.clk(clk), .en(!disable_clk), .clk_cg(clk_cg)); `USER_ICG user_soc_ifc_icg (.clk(clk), .en(!disable_soc_ifc_clk), .clk_cg(soc_ifc_clk_cg)); -`USER_ICG user_rdc_icg (.clk(clk), .en(!rdc_clk_dis), .clk_cg(rdc_clk_cg)); + `USER_ICG user_rdc_icg (.clk(clk), .en(!rdc_clk_dis), .clk_cg(rdc_clk_cg)); `else `CALIPTRA_ICG caliptra_icg (.clk(clk), .en(!disable_clk), .clk_cg(clk_cg)); `CALIPTRA_ICG caliptra_soc_ifc_icg (.clk(clk), .en(!disable_soc_ifc_clk), .clk_cg(soc_ifc_clk_cg)); -`CALIPTRA_ICG caliptra_rdc_icg (.clk(clk), .en(!rdc_clk_dis), .clk_cg(rdc_clk_cg)); + `CALIPTRA_ICG caliptra_rdc_icg (.clk(clk), .en(!rdc_clk_dis), .clk_cg(rdc_clk_cg)); `endif endmodule diff --git a/src/pcrvault/config/pcrvault.vf b/src/pcrvault/config/pcrvault.vf index a7a532662..5e59b1772 100644 --- a/src/pcrvault/config/pcrvault.vf +++ b/src/pcrvault/config/pcrvault.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv diff --git a/src/pcrvault/config/pv_defines_pkg.vf b/src/pcrvault/config/pv_defines_pkg.vf index 5a992edb0..ab7aa0fd0 100644 --- a/src/pcrvault/config/pv_defines_pkg.vf +++ b/src/pcrvault/config/pv_defines_pkg.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_gen_hash.sv diff --git a/src/sha256/config/sha256_ctrl.vf b/src/sha256/config/sha256_ctrl.vf index e81c64f20..1a53cf1eb 100644 --- a/src/sha256/config/sha256_ctrl.vf +++ b/src/sha256/config/sha256_ctrl.vf @@ -12,6 +12,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_to_reg_adapter.sv ${CALIPTRA_ROOT}/src/sha256/rtl/sha256_reg_pkg.sv ${CALIPTRA_ROOT}/src/sha256/rtl/sha256_params_pkg.sv diff --git a/src/sha256/config/sha256_ctrl_tb.vf b/src/sha256/config/sha256_ctrl_tb.vf index 5e7a74bb3..7889eaad5 100644 --- a/src/sha256/config/sha256_ctrl_tb.vf +++ b/src/sha256/config/sha256_ctrl_tb.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_if.sv ${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_bind.sv ${CALIPTRA_ROOT}/src/sha256/tb/sha256_ctrl_tb.sv diff --git a/src/sha256/config/sha256_random_test.vf b/src/sha256/config/sha256_random_test.vf index 4478f6937..1d5ed66c8 100644 --- a/src/sha256/config/sha256_random_test.vf +++ b/src/sha256/config/sha256_random_test.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_if.sv ${CALIPTRA_ROOT}/src/sha256/coverage/sha256_ctrl_cov_bind.sv ${CALIPTRA_ROOT}/src/sha256/tb/sha256_random_test.sv diff --git a/src/sha512/config/sha512_ctrl.vf b/src/sha512/config/sha512_ctrl.vf index a6b4d84b4..71a30643d 100644 --- a/src/sha512/config/sha512_ctrl.vf +++ b/src/sha512/config/sha512_ctrl.vf @@ -14,6 +14,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/sha512/config/sha512_ctrl_32bit_tb.vf b/src/sha512/config/sha512_ctrl_32bit_tb.vf index e2019914a..621c83d2e 100644 --- a/src/sha512/config/sha512_ctrl_32bit_tb.vf +++ b/src/sha512/config/sha512_ctrl_32bit_tb.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/sha512_masked/config/sha512_masked_core.vf b/src/sha512_masked/config/sha512_masked_core.vf index db9267f6f..e9d04af99 100644 --- a/src/sha512_masked/config/sha512_masked_core.vf +++ b/src/sha512_masked/config/sha512_masked_core.vf @@ -15,6 +15,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/sha512_masked/config/sha512_masked_core_tb.vf b/src/sha512_masked/config/sha512_masked_core_tb.vf index e27a927a8..b9fa2a419 100644 --- a/src/sha512_masked/config/sha512_masked_core_tb.vf +++ b/src/sha512_masked/config/sha512_masked_core_tb.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_defines_pkg.sv ${CALIPTRA_ROOT}/src/keyvault/rtl/kv_macros.svh ${CALIPTRA_ROOT}/src/pcrvault/rtl/pv_defines_pkg.sv diff --git a/src/soc_ifc/config/soc_ifc_tb.vf b/src/soc_ifc/config/soc_ifc_tb.vf index 08dc99aee..55dbfb700 100644 --- a/src/soc_ifc/config/soc_ifc_tb.vf +++ b/src/soc_ifc/config/soc_ifc_tb.vf @@ -18,6 +18,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv ${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv ${CALIPTRA_ROOT}/src/soc_ifc/coverage/soc_ifc_cov_if.sv diff --git a/src/soc_ifc/config/soc_ifc_top.vf b/src/soc_ifc/config/soc_ifc_top.vf index de8b74cdc..4e1965ce5 100644 --- a/src/soc_ifc/config/soc_ifc_top.vf +++ b/src/soc_ifc/config/soc_ifc_top.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_pkg.sv ${CALIPTRA_ROOT}/src/soc_ifc/rtl/soc_ifc_reg_pkg.sv ${CALIPTRA_ROOT}/src/riscv_core/veer_el2/rtl/el2_pdef.vh diff --git a/src/soc_ifc/rtl/caliptra_top_reg.h b/src/soc_ifc/rtl/caliptra_top_reg.h index 6325f3b8f..e2c597f16 100644 --- a/src/soc_ifc/rtl/caliptra_top_reg.h +++ b/src/soc_ifc/rtl/caliptra_top_reg.h @@ -47,6 +47,8 @@ #define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (0x1c0) #define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9) #define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (0x200) +#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10) +#define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (0x1fffc00) #define CALIPTRA_TOP_REG_MBOX_CSR_MBOX_UNLOCK (0x30020020) #define MBOX_CSR_MBOX_UNLOCK (0x20) #define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0) @@ -341,6 +343,26 @@ #define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK (0x10c) #define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_LOW (0) #define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_MASK (0x1) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_0 (0x30030110) +#define GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_0 (0x110) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_1 (0x30030114) +#define GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_1 (0x114) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (0x30030118) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (0x118) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_LOW (0) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_MASK (0xffff) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_LOW (16) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_MASK (0xffff0000) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (0x3003011c) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (0x11c) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_LOW (0) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_MASK (0xffff) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_LOW (16) +#define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_MASK (0xffff0000) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_0 (0x30030120) +#define GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_0 (0x120) +#define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_1 (0x30030124) +#define GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_1 (0x124) #define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0 (0x30030200) #define GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0 (0x200) #define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_1 (0x30030204) diff --git a/src/soc_ifc/rtl/caliptra_top_reg_defines.svh b/src/soc_ifc/rtl/caliptra_top_reg_defines.svh index 5a828d98a..9677a065e 100644 --- a/src/soc_ifc/rtl/caliptra_top_reg_defines.svh +++ b/src/soc_ifc/rtl/caliptra_top_reg_defines.svh @@ -48,6 +48,8 @@ `define MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK (32'h1c0) `define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_LOW (9) `define MBOX_CSR_MBOX_STATUS_SOC_HAS_LOCK_MASK (32'h200) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_LOW (10) +`define MBOX_CSR_MBOX_STATUS_MBOX_RDPTR_MASK (32'h1fffc00) `define CALIPTRA_TOP_REG_MBOX_CSR_MBOX_UNLOCK (32'h30020020) `define MBOX_CSR_MBOX_UNLOCK (32'h20) `define MBOX_CSR_MBOX_UNLOCK_UNLOCK_LOW (0) @@ -342,6 +344,26 @@ `define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK (32'h10c) `define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_LOW (0) `define GENERIC_AND_FUSE_REG_CPTRA_FUSE_PAUSER_LOCK_LOCK_MASK (32'h1) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_0 (32'h30030110) +`define GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_0 (32'h110) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_1 (32'h30030114) +`define GENERIC_AND_FUSE_REG_CPTRA_WDT_CFG_1 (32'h114) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h30030118) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0 (32'h118) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_LOW (0) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_LOW_THRESHOLD_MASK (32'hffff) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_LOW (16) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_0_HIGH_THRESHOLD_MASK (32'hffff0000) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h3003011c) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1 (32'h11c) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_LOW (0) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_REPETITION_COUNT_MASK (32'hffff) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_LOW (16) +`define GENERIC_AND_FUSE_REG_CPTRA_ITRNG_ENTROPY_CONFIG_1_RSVD_MASK (32'hffff0000) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_0 (32'h30030120) +`define GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_0 (32'h120) +`define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_1 (32'h30030124) +`define GENERIC_AND_FUSE_REG_CPTRA_RSVD_REG_1 (32'h124) `define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0 (32'h30030200) `define GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0 (32'h200) `define CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_1 (32'h30030204) diff --git a/src/soc_ifc/rtl/mbox.sv b/src/soc_ifc/rtl/mbox.sv index 2aece02b6..f86604b25 100644 --- a/src/soc_ifc/rtl/mbox.sv +++ b/src/soc_ifc/rtl/mbox.sv @@ -33,6 +33,7 @@ module mbox output logic mbox_error, output logic [DATA_W-1:0] rdata, + output logic [DATA_W-1:0] dir_rdata, input logic sha_sram_req_dv, input logic [MBOX_ADDR_W-1:0] sha_sram_req_addr, @@ -106,6 +107,7 @@ logic mbox_rd_full, mbox_rd_full_nxt; logic inc_rdptr; logic rst_mbox_rdptr; logic rst_mbox_wrptr; +logic sram_rd_ecc_en; logic [DATA_W-1:0] sram_rdata; logic [MBOX_ECC_DATA_W-1:0] sram_rdata_ecc; logic [DATA_W-1:0] sram_rdata_cor; @@ -193,21 +195,26 @@ always_comb arc_FORCE_MBOX_UNLOCK = hwif_out.mbox_unlock.unlock.value; // NOTE: Any APB agent can trigger the error at any point during a uC->SOC flow // by writing to mbox_status (since it's a valid_receiver). // FIXED! valid_receiver is restricted by FSM state now. -always_comb arc_MBOX_RDY_FOR_CMD_MBOX_ERROR = req_dv && req_data.soc_req && valid_requester && +always_comb arc_MBOX_RDY_FOR_CMD_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_CMD) && + req_dv && req_data.soc_req && ~req_hold && valid_requester && (req_data.write ? (!hwif_out.mbox_cmd.command.swmod) : (hwif_out.mbox_dataout.dataout.swacc)); -always_comb arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR = req_dv && req_data.soc_req && valid_requester && +always_comb arc_MBOX_RDY_FOR_DLEN_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_DLEN) && + req_dv && req_data.soc_req && ~req_hold && valid_requester && (req_data.write ? (!hwif_out.mbox_dlen.length.swmod) : (hwif_out.mbox_dataout.dataout.swacc)); -always_comb arc_MBOX_RDY_FOR_DATA_MBOX_ERROR = req_dv && req_data.soc_req && valid_requester && +always_comb arc_MBOX_RDY_FOR_DATA_MBOX_ERROR = (mbox_fsm_ps == MBOX_RDY_FOR_DATA) && + req_dv && req_data.soc_req && ~req_hold && valid_requester && (req_data.write ? (!(hwif_out.mbox_datain.datain.swmod || hwif_out.mbox_execute.execute.swmod)) : (hwif_out.mbox_dataout.dataout.swacc)); -always_comb arc_MBOX_EXECUTE_UC_MBOX_ERROR = req_dv && req_data.soc_req && valid_requester && +always_comb arc_MBOX_EXECUTE_UC_MBOX_ERROR = (mbox_fsm_ps == MBOX_EXECUTE_UC) && + req_dv && req_data.soc_req && ~req_hold && valid_requester && (req_data.write ? (1'b1/* any write by 'valid' soc is illegal here */) : (hwif_out.mbox_dataout.dataout.swacc)); -always_comb arc_MBOX_EXECUTE_SOC_MBOX_ERROR = req_dv && req_data.soc_req && +always_comb arc_MBOX_EXECUTE_SOC_MBOX_ERROR = (mbox_fsm_ps == MBOX_EXECUTE_SOC) && + req_dv && req_data.soc_req && ~req_hold && (req_data.write ? ((valid_requester && !(hwif_out.mbox_execute.execute.swmod)) || - (~soc_has_lock && !(hwif_out.mbox_status.status.swmod || hwif_out.mbox_dlen.length.swmod))) : + (~soc_has_lock && !(hwif_out.mbox_status.status.swmod))) : (1'b0 /* any read allowed by SoC during this stage; dataout consumption is expected */)); //capture the dlen when we change to execute states, this ensures that only the dlen programmed @@ -250,7 +257,7 @@ always_comb begin : mbox_fsm_combo end // Flag a non-fatal error, but don't change states, if mbox is already IDLE // when an unexpected SOC access happens - if (req_dv && req_data.soc_req && (req_data.write || hwif_out.mbox_dataout.dataout.swacc)) begin + if (req_dv && req_data.soc_req && !req_hold && (req_data.write || hwif_out.mbox_dataout.dataout.swacc)) begin mbox_protocol_error_nxt.axs_without_lock = 1'b1; end end @@ -380,7 +387,7 @@ end // Any ol' PAUSER is fine for reg-reads (except dataout) // NOTE: This only captures accesses by APB agents that are valid, but do not // have lock. Invalid agent accesses are blocked by arbiter. -assign mbox_inv_pauser_axs = req_dv && req_data.soc_req && +assign mbox_inv_pauser_axs = req_dv && req_data.soc_req && !req_hold && !valid_requester && !valid_receiver && (req_data.write || hwif_out.mbox_dataout.dataout.swacc); @@ -403,6 +410,7 @@ always_ff @(posedge clk or negedge rst_b) begin sram_ecc_cor_waddr <= '0; dlen_in_dws <= '0; mbox_protocol_error <= '0; + sram_rd_ecc_en <= '0; end else begin mbox_fsm_ps <= mbox_fsm_ns; @@ -420,6 +428,8 @@ always_ff @(posedge clk or negedge rst_b) begin dlen_in_dws <= latch_dlen_in_dws ? dlen_in_dws_nxt : dlen_in_dws; mbox_protocol_error <= mbox_protocol_error_nxt; + //enable ecc for mbox protocol, direct reads, or SHA direct reads + sram_rd_ecc_en <= mbox_protocol_sram_rd | (dir_req_dv_q & ~sha_sram_req_dv & ~req_data.write) | sha_sram_req_dv; end end @@ -451,7 +461,8 @@ always_comb sram_waddr = sram_ecc_cor_we ? sram_ecc_cor_waddr : dir_req_dv_q ? dir_req_addr : mbox_wrptr; //data phase after request for direct access //We want to mask the read data for certain accesses -always_comb rdata = dir_req_rd_phase ? sram_rdata_cor : ({DATA_W{~mask_rdata}} & csr_rdata); +always_comb rdata = ({DATA_W{~mask_rdata}} & csr_rdata); +always_comb dir_rdata = dir_req_rd_phase ? sram_rdata_cor : '0; always_comb begin: mbox_sram_inf //read live on direct access, or when pointer has been incremented, for pre-load on read pointer reset, or ecc correction @@ -478,7 +489,7 @@ initial assert(DATA_W == 32) else $error("%m::rvecc_encode supports 32-bit data width; must change SRAM ECC implementation to support DATA_W = %d", DATA_W); // synthesis translate_on rvecc_decode ecc_decode ( - .en (dir_req_rd_phase | mbox_protocol_sram_rd_f), + .en (sram_rd_ecc_en ), .sed_ded ( 1'b0 ), // 1 : means only detection .din (sram_rdata ), .ecc_in (sram_rdata_ecc ), @@ -542,10 +553,12 @@ always_comb hwif_in.mbox_execute.execute.hwclr = arc_FORCE_MBOX_UNLOCK; always_comb hwif_in.mbox_status.ecc_single_error.hwset = sram_single_ecc_error; always_comb hwif_in.mbox_status.ecc_double_error.hwset = sram_double_ecc_error; always_comb hwif_in.mbox_status.soc_has_lock.next = soc_has_lock; +always_comb hwif_in.mbox_status.mbox_rdptr.next = mbox_rdptr; always_comb dmi_reg.MBOX_DLEN = hwif_out.mbox_dlen.length.value; always_comb dmi_reg.MBOX_DOUT = hwif_out.mbox_dataout.dataout.value; -always_comb dmi_reg.MBOX_STATUS = {22'd0, /* [31:10] */ +always_comb dmi_reg.MBOX_STATUS = {7'd0, /* [31:25] */ + hwif_out.mbox_status.mbox_rdptr.value, /* [24:10]*/ hwif_out.mbox_status.soc_has_lock.value, /* [9] */ hwif_out.mbox_status.mbox_fsm_ps.value, /* [8:6] */ hwif_out.mbox_status.ecc_double_error.value, /* [5] */ diff --git a/src/soc_ifc/rtl/mbox_csr.rdl b/src/soc_ifc/rtl/mbox_csr.rdl index 31741af08..8a67121be 100644 --- a/src/soc_ifc/rtl/mbox_csr.rdl +++ b/src/soc_ifc/rtl/mbox_csr.rdl @@ -177,6 +177,13 @@ addrmap mbox_csr { [br]SOC Access: RO [br]TAP Access [in debug/manuf mode]: RO"; sw=r; hw=rw;} soc_has_lock=1'b0; + field { + name = "Current Mailbox Read Pointer"; + desc = "Returns the current read pointer for the mailbox + [br]Caliptra Access: RO + [br]SOC Access: RO + [br]TAP Access [in debug/manuf mode]: RO"; + sw=r; hw=rw;} mbox_rdptr[15] = 0; } mbox_status; reg { diff --git a/src/soc_ifc/rtl/mbox_csr.sv b/src/soc_ifc/rtl/mbox_csr.sv index 88889f9f2..cefd5b73d 100644 --- a/src/soc_ifc/rtl/mbox_csr.sv +++ b/src/soc_ifc/rtl/mbox_csr.sv @@ -169,6 +169,10 @@ module mbox_csr ( logic next; logic load_next; } soc_has_lock; + struct packed{ + logic [14:0] next; + logic load_next; + } mbox_rdptr; } mbox_status; struct packed{ struct packed{ @@ -231,6 +235,9 @@ module mbox_csr ( struct packed{ logic value; } soc_has_lock; + struct packed{ + logic [14:0] value; + } mbox_rdptr; } mbox_status; struct packed{ struct packed{ @@ -491,6 +498,25 @@ module mbox_csr ( end end assign hwif_out.mbox_status.soc_has_lock.value = field_storage.mbox_status.soc_has_lock.value; + // Field: mbox_csr.mbox_status.mbox_rdptr + always_comb begin + automatic logic [14:0] next_c = field_storage.mbox_status.mbox_rdptr.value; + automatic logic load_next_c = '0; + if(1) begin // HW Write + next_c = hwif_in.mbox_status.mbox_rdptr.next; + load_next_c = '1; + end + field_combo.mbox_status.mbox_rdptr.next = next_c; + field_combo.mbox_status.mbox_rdptr.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.mbox_status.mbox_rdptr.value <= 'h0; + end else if(field_combo.mbox_status.mbox_rdptr.load_next) begin + field_storage.mbox_status.mbox_rdptr.value <= field_combo.mbox_status.mbox_rdptr.next; + end + end + assign hwif_out.mbox_status.mbox_rdptr.value = field_storage.mbox_status.mbox_rdptr.value; // Field: mbox_csr.mbox_unlock.unlock always_comb begin automatic logic [0:0] next_c = field_storage.mbox_unlock.unlock.value; @@ -536,7 +562,8 @@ module mbox_csr ( assign readback_array[7][5:5] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.ecc_double_error.value : '0; assign readback_array[7][8:6] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.mbox_fsm_ps.value : '0; assign readback_array[7][9:9] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.soc_has_lock.value : '0; - assign readback_array[7][31:10] = '0; + assign readback_array[7][24:10] = (decoded_reg_strb.mbox_status && !decoded_req_is_wr) ? field_storage.mbox_status.mbox_rdptr.value : '0; + assign readback_array[7][31:25] = '0; assign readback_array[8][0:0] = (decoded_reg_strb.mbox_unlock && !decoded_req_is_wr) ? field_storage.mbox_unlock.unlock.value : '0; assign readback_array[8][31:1] = '0; diff --git a/src/soc_ifc/rtl/mbox_csr_pkg.sv b/src/soc_ifc/rtl/mbox_csr_pkg.sv index 62a7d3ee7..1c9766e24 100644 --- a/src/soc_ifc/rtl/mbox_csr_pkg.sv +++ b/src/soc_ifc/rtl/mbox_csr_pkg.sv @@ -56,12 +56,17 @@ package mbox_csr_pkg; logic next; } mbox_csr__mbox_status__soc_has_lock__in_t; + typedef struct packed{ + logic [14:0] next; + } mbox_csr__mbox_status__mbox_rdptr__in_t; + typedef struct packed{ mbox_csr__mbox_status__status__in_t status; mbox_csr__mbox_status__ecc_single_error_next_e066e214_wel_e066e214__in_t ecc_single_error; mbox_csr__mbox_status__ecc_double_error_next_e066e214_wel_e066e214__in_t ecc_double_error; mbox_csr__mbox_status__mbox_fsm_ps__in_t mbox_fsm_ps; mbox_csr__mbox_status__soc_has_lock__in_t soc_has_lock; + mbox_csr__mbox_status__mbox_rdptr__in_t mbox_rdptr; } mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760__in_t; typedef struct packed{ @@ -158,12 +163,17 @@ package mbox_csr_pkg; logic value; } mbox_csr__mbox_status__soc_has_lock__out_t; + typedef struct packed{ + logic [14:0] value; + } mbox_csr__mbox_status__mbox_rdptr__out_t; + typedef struct packed{ mbox_csr__mbox_status__status__out_t status; mbox_csr__mbox_status__ecc_single_error_next_e066e214_wel_e066e214__out_t ecc_single_error; mbox_csr__mbox_status__ecc_double_error_next_e066e214_wel_e066e214__out_t ecc_double_error; mbox_csr__mbox_status__mbox_fsm_ps__out_t mbox_fsm_ps; mbox_csr__mbox_status__soc_has_lock__out_t soc_has_lock; + mbox_csr__mbox_status__mbox_rdptr__out_t mbox_rdptr; } mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760__out_t; typedef struct packed{ diff --git a/src/soc_ifc/rtl/mbox_csr_uvm.sv b/src/soc_ifc/rtl/mbox_csr_uvm.sv index 0ad0fac8e..760853a1a 100644 --- a/src/soc_ifc/rtl/mbox_csr_uvm.sv +++ b/src/soc_ifc/rtl/mbox_csr_uvm.sv @@ -225,12 +225,14 @@ package mbox_csr_uvm; mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760_bit_cg ecc_double_error_bit_cg[1]; mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760_bit_cg mbox_fsm_ps_bit_cg[3]; mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760_bit_cg soc_has_lock_bit_cg[1]; + mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760_bit_cg mbox_rdptr_bit_cg[15]; mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760_fld_cg fld_cg; rand uvm_reg_field status; rand uvm_reg_field ecc_single_error; rand uvm_reg_field ecc_double_error; rand uvm_reg_field mbox_fsm_ps; rand uvm_reg_field soc_has_lock; + rand uvm_reg_field mbox_rdptr; function new(string name = "mbox_csr__mbox_status_ecc_double_error_38cec4b0_ecc_single_error_9c62b760"); super.new(name, 32, build_coverage(UVM_CVR_ALL)); @@ -252,12 +254,15 @@ package mbox_csr_uvm; this.mbox_fsm_ps.configure(this, 3, 6, "RO", 1, 'h0, 1, 1, 0); this.soc_has_lock = new("soc_has_lock"); this.soc_has_lock.configure(this, 1, 9, "RO", 1, 'h0, 1, 1, 0); + this.mbox_rdptr = new("mbox_rdptr"); + this.mbox_rdptr.configure(this, 15, 10, "RO", 1, 'h0, 1, 1, 0); if (has_coverage(UVM_CVR_REG_BITS)) begin foreach(status_bit_cg[bt]) status_bit_cg[bt] = new(); foreach(ecc_single_error_bit_cg[bt]) ecc_single_error_bit_cg[bt] = new(); foreach(ecc_double_error_bit_cg[bt]) ecc_double_error_bit_cg[bt] = new(); foreach(mbox_fsm_ps_bit_cg[bt]) mbox_fsm_ps_bit_cg[bt] = new(); foreach(soc_has_lock_bit_cg[bt]) soc_has_lock_bit_cg[bt] = new(); + foreach(mbox_rdptr_bit_cg[bt]) mbox_rdptr_bit_cg[bt] = new(); end if (has_coverage(UVM_CVR_FIELD_VALS)) fld_cg = new(); diff --git a/src/soc_ifc/rtl/soc_ifc_arb.sv b/src/soc_ifc/rtl/soc_ifc_arb.sv index 4becee65a..8660009a9 100644 --- a/src/soc_ifc/rtl/soc_ifc_arb.sv +++ b/src/soc_ifc/rtl/soc_ifc_arb.sv @@ -40,6 +40,7 @@ module soc_ifc_arb input logic mbox_req_hold, output soc_ifc_req_t mbox_req_data, input logic [SOC_IFC_DATA_W-1:0] mbox_rdata, + input logic [SOC_IFC_DATA_W-1:0] mbox_dir_rdata, input logic mbox_error, //SHA inf output logic sha_req_dv, @@ -192,7 +193,8 @@ always_comb sha_req_data = ({$bits(soc_ifc_req_t){soc_sha_gnt}} & soc_req_data) //drive the appropriate read data back to uc or soc //AND/OR mux here, assert that requests are always mutex -always_comb uc_rdata = ({MBOX_DATA_W{uc_mbox_req}} & mbox_rdata) | +always_comb uc_rdata = ({MBOX_DATA_W{uc_mbox_reg_req}} & mbox_rdata) | + ({MBOX_DATA_W{uc_mbox_dir_req}} & mbox_dir_rdata) | ({MBOX_DATA_W{uc_reg_req}} & soc_ifc_reg_rdata) | ({MBOX_DATA_W{uc_sha_req}} & sha_rdata); diff --git a/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv b/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv index eee1cbdbe..e5b522184 100644 --- a/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv +++ b/src/soc_ifc/rtl/soc_ifc_boot_fsm.sv @@ -19,6 +19,7 @@ module soc_ifc_boot_fsm input logic clk, input logic cptra_pwrgood, input logic cptra_rst_b, + input logic scan_mode, input logic fw_update_rst, input logic [7:0] fw_update_rst_wait_cycles, @@ -42,6 +43,9 @@ module soc_ifc_boot_fsm `include "caliptra_sva.svh" +logic cptra_uc_rst_b_nq; +logic cptra_noncore_rst_b_nq; + //present and next state boot_fsm_state_e boot_fsm_ns; //arcs between states - global rst @@ -65,10 +69,11 @@ logic [7:0] wait_count; logic wait_count_rst; logic wait_count_decr; -logic cptra_rst_window,cptra_rst_window_f,cptra_rst_window_ff; +logic cptra_rst_window; +logic cptra_rst_window_sync, cptra_rst_window_sync_f, cptra_rst_window_sync_2f; //move to fuse state when SoC de-asserts reset -always_comb arc_BOOT_IDLE_BOOT_FUSE = (boot_fsm_ps == BOOT_IDLE) & ~cptra_rst_window; +always_comb arc_BOOT_IDLE_BOOT_FUSE = (boot_fsm_ps == BOOT_IDLE) & ~cptra_rst_window_sync & ~cptra_rst_window_sync_f & ~cptra_rst_window_sync_2f; //move from fuse state to done when fuse done register is set OR //if it was already set (since its locked across warm reset), that the write was observed from SOC always_comb arc_BOOT_FUSE_BOOT_DONE = fuse_done & fuse_wr_done_observed; @@ -79,12 +84,13 @@ always_comb arc_BOOT_FUSE_BOOT_WAIT = BootFSM_BrkPoint; //dummy arc for terminal state lint check always_comb arc_BOOT_DONE_BOOT_IDLE = '0; -always_comb arc_IDLE = cptra_rst_window; +always_comb arc_IDLE = cptra_rst_window_sync; //Masks combo paths from uc reset flops into other reset domains always_comb fw_update_rst_window = boot_fsm_ps inside {BOOT_FW_RST,BOOT_WAIT}; //clock gate all flops on warm reset to prevent RDC metastability issues -always_comb rdc_clk_dis = cptra_rst_window | cptra_rst_window_f | cptra_rst_window_ff; +//cover 2 clocks after synchronized reset assertion (cptra_rst_window_sync) to handle bootfsm transitions +always_comb rdc_clk_dis = cptra_rst_window_sync | cptra_rst_window_sync_f | cptra_rst_window_sync_2f; //move to rst state when reg bit is set to 1. This state will assert fw_rst to uc always_comb arc_BOOT_DONE_BOOT_FWRST = (boot_fsm_ps == BOOT_DONE) & fw_update_rst; @@ -100,7 +106,6 @@ always_comb arc_BOOT_WAIT_BOOT_DONE = (wait_count == '0) & ~(BootFSM_BrkPoint & always_comb begin boot_fsm_ns = boot_fsm_ps; - ready_for_fuses = '0; fw_upd_rst_executed = '0; fsm_synch_noncore_rst_b = '0; fsm_iccm_unlock = '0; @@ -108,7 +113,7 @@ always_comb begin wait_count_decr = 0; wait_count_rst = 0; - unique casez (boot_fsm_ps) + unique case (boot_fsm_ps) inside BOOT_IDLE: begin if (arc_BOOT_IDLE_BOOT_FUSE) begin boot_fsm_ns = BOOT_FUSE; @@ -131,11 +136,10 @@ always_comb begin boot_fsm_ns = BOOT_DONE; end end - ready_for_fuses = 1'b1; //reset flags fsm_synch_uc_rst_b = '0; - fsm_synch_noncore_rst_b = '0; + fsm_synch_noncore_rst_b = '1; fsm_iccm_unlock = '0; wait_count_decr = 0; wait_count_rst = 0; @@ -188,6 +192,15 @@ always_comb begin wait_count_rst = 0; wait_count_decr = 0; end + default: begin + boot_fsm_ns = boot_fsm_ps; + fw_upd_rst_executed = '0; + fsm_synch_noncore_rst_b = '0; + fsm_iccm_unlock = '0; + fsm_synch_uc_rst_b = '0; + wait_count_decr = 0; + wait_count_rst = 0; + end endcase end @@ -198,32 +211,48 @@ always_ff @(posedge clk or negedge cptra_pwrgood) begin boot_fsm_ps <= BOOT_IDLE; synch_noncore_rst_b <= '0; synch_uc_rst_b <= 0; - cptra_noncore_rst_b <= '0; - cptra_uc_rst_b <= '0; + cptra_noncore_rst_b_nq <= '0; + cptra_uc_rst_b_nq <= '0; + + cptra_rst_window_sync_f <= '1; + cptra_rst_window_sync_2f <= '1; end else begin boot_fsm_ps <= arc_IDLE ? BOOT_IDLE : boot_fsm_ns; synch_noncore_rst_b <= fsm_synch_noncore_rst_b; synch_uc_rst_b <= fsm_synch_uc_rst_b; - cptra_noncore_rst_b <= synch_noncore_rst_b; - cptra_uc_rst_b <= synch_noncore_rst_b && synch_uc_rst_b; //uc comes out of rst only when both global and fw rsts are deasserted (through 2FF sync) + cptra_noncore_rst_b_nq <= synch_noncore_rst_b; + cptra_uc_rst_b_nq <= synch_noncore_rst_b && synch_uc_rst_b; //uc comes out of rst only when both global and fw rsts are deasserted (through 2FF sync) + + cptra_rst_window_sync_f <= cptra_rst_window_sync; + cptra_rst_window_sync_2f <= cptra_rst_window_sync_f; end end +//protect resets during scan mode +//TODO dft override for reset? +assign cptra_noncore_rst_b = cptra_noncore_rst_b_nq | scan_mode; +assign cptra_uc_rst_b = cptra_uc_rst_b_nq | scan_mode; + //uC reset generation always_ff @(posedge clk or negedge cptra_rst_b) begin if (~cptra_rst_b) begin cptra_rst_window <= '1; - cptra_rst_window_f <= '1; - cptra_rst_window_ff <= '1; - wait_count <= '0; - iccm_unlock <= 0; end else begin cptra_rst_window <= 0; - cptra_rst_window_f <= cptra_rst_window; - cptra_rst_window_ff <= cptra_rst_window_f; + end +end +// Ready for fuses output signal +always_ff @(posedge clk or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin + ready_for_fuses <= 1'b0; + wait_count <= '0; + iccm_unlock <= 0; + end + else begin + ready_for_fuses <= (boot_fsm_ps == BOOT_FUSE) && !fuse_wr_done_observed; wait_count <= (wait_count_decr && (wait_count != '0)) ? wait_count - 1 : wait_count_rst ? fw_update_rst_wait_cycles : wait_count ; @@ -231,6 +260,8 @@ always_ff @(posedge clk or negedge cptra_rst_b) begin end end +caliptra_2ff_sync #(.WIDTH(1), .RST_VAL('d1)) i_rst_window_sync (.clk(clk), .rst_b(cptra_pwrgood), .din(cptra_rst_window), .dout(cptra_rst_window_sync)); + //Check for x prop `CALIPTRA_ASSERT_KNOWN(ERR_FSM_ARC_X, {arc_BOOT_FUSE_BOOT_DONE, arc_BOOT_DONE_BOOT_FWRST, arc_BOOT_WAIT_BOOT_DONE}, clk, cptra_rst_b) `CALIPTRA_ASSERT_KNOWN(ERR_FSM_STATE_X, boot_fsm_ps, clk, cptra_rst_b) diff --git a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl index ca0529e0f..bd3aa0ac3 100644 --- a/src/soc_ifc/rtl/soc_ifc_external_reg.rdl +++ b/src/soc_ifc/rtl/soc_ifc_external_reg.rdl @@ -84,11 +84,11 @@ reg { [br]SOC Access: RO"; rw_ro status[24]=0; field {desc="DEV ID CSR ready"; sw=rw; swwel = soc_req; hw=r ; resetsignal = cptra_rst_b;} idevid_csr_ready[1]=0; - field {desc="Boot FSM State"; sw=r; hw=w ; resetsignal = cptra_rst_b;} boot_fsm_ps[3]; + field {desc="Boot FSM State"; sw=r; hw=w ; /* no storage, no reset */} boot_fsm_ps[3]; field {desc="Indicates Caliptra is ready for Firmware Download"; sw=rw; swwel = soc_req; hw=r ; resetsignal = cptra_rst_b;} ready_for_fw[1]=0; field {desc="Indicates Caliptra is ready for RT flows"; sw=rw; swwel = soc_req; hw=r ; resetsignal = cptra_rst_b;} ready_for_runtime[1]=0; field {desc="Indicates Caliptra is ready for Fuses to be programmed. - Read-only to both Caliptra and SOC."; sw=r; hw=w ; resetsignal = cptra_rst_b;} ready_for_fuses[1]; + Read-only to both Caliptra and SOC."; sw=r; hw=w ; /* no storage, no reset */} ready_for_fuses[1]; field {desc="Indicates Caliptra is has completed Mailbox Flow."; sw=rw; swwel = soc_req; hw=r ; resetsignal = cptra_rst_b;} mailbox_flow_done[1]=0; } CPTRA_FLOW_STATUS; reg { @@ -257,6 +257,7 @@ reg { reg { name = "Caliptra HW RevID"; desc = "Caliptra HW revision ID that matches the official final release milestone + SoC stepping ID is repopulated with the value in the fuse register on every warm reset [br]Caliptra Access: RO [br]SOC Access: RO"; field {sw=r; resetsignal = cptra_rst_b;} CPTRA_GENERATION[16]=1; @@ -348,7 +349,7 @@ reg { [br]Caliptra Access: RW [br]SOC Access: RW [br]Read-Only once locked by FUSE_PAUSER_LOCK."; - field {sw=rw; hw=r; swwel; resetsignal = cptra_rst_b;} PAUSER[32]=0xFFFF_FFFF; + field {sw=rw; hw=r; swwel; resetsignal = cptra_pwrgood;} PAUSER[32]=0xFFFF_FFFF; } CPTRA_FUSE_VALID_PAUSER; reg { @@ -360,5 +361,31 @@ reg { [br]Caliptra Access: RW [br]SOC Access: RW [br]Read-Only once locked."; - field {sw=rw; hw=r; swwel; resetsignal=cptra_rst_b;} LOCK=0; + field {sw=rw; hw=r; swwel; resetsignal=cptra_pwrgood;} LOCK=0; } CPTRA_FUSE_PAUSER_LOCK; + +reg { + name = "Caliptra WDT1 Config"; + desc = "SOC provided count in cycles for WDT1 timeout."; + field {sw=rw; hw=na; resetsignal = cptra_pwrgood;} TIMEOUT[32]=0; + } CPTRA_WDT_CFG[2]; + +reg { + name = "Caliptra iTRNG Entropy Configuration 0"; + desc = "Adaptive threshold values for entropy source health tests."; + field {sw=rw; resetsignal=cptra_rst_b;} low_threshold[16]=0; + field {sw=rw; resetsignal=cptra_rst_b;} high_threshold[16]=0; + } CPTRA_iTRNG_ENTROPY_CONFIG_0; + +reg { + name = "Caliptra iTRNG Entropy Configuration 1"; + desc = "Repetition count value for entropy source health tests."; + field {sw=rw; resetsignal=cptra_rst_b;} repetition_count[16]=0; + field {sw=rw; resetsignal=cptra_rst_b;} RSVD[16]=0; + } CPTRA_iTRNG_ENTROPY_CONFIG_1; + +reg { + name = "Caliptra Reserved Registers"; + desc = "Set of reserved registers for survivability"; + field {sw=rw; resetsignal=cptra_rst_b;} RSVD[32]=0; + } CPTRA_RSVD_REG[2]; \ No newline at end of file diff --git a/src/soc_ifc/rtl/soc_ifc_reg.sv b/src/soc_ifc/rtl/soc_ifc_reg.sv index fb6f0a13a..c81364f56 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg.sv +++ b/src/soc_ifc/rtl/soc_ifc_reg.sv @@ -101,6 +101,10 @@ module soc_ifc_reg ( logic CPTRA_WDT_STATUS; logic CPTRA_FUSE_VALID_PAUSER; logic CPTRA_FUSE_PAUSER_LOCK; + logic [2-1:0]CPTRA_WDT_CFG; + logic CPTRA_iTRNG_ENTROPY_CONFIG_0; + logic CPTRA_iTRNG_ENTROPY_CONFIG_1; + logic [2-1:0]CPTRA_RSVD_REG; logic [12-1:0]fuse_uds_seed; logic [8-1:0]fuse_field_entropy; logic [12-1:0]fuse_key_manifest_pk_hash; @@ -230,6 +234,14 @@ module soc_ifc_reg ( decoded_reg_strb.CPTRA_WDT_STATUS = cpuif_req_masked & (cpuif_addr == 'h104); decoded_reg_strb.CPTRA_FUSE_VALID_PAUSER = cpuif_req_masked & (cpuif_addr == 'h108); decoded_reg_strb.CPTRA_FUSE_PAUSER_LOCK = cpuif_req_masked & (cpuif_addr == 'h10c); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_WDT_CFG[i0] = cpuif_req_masked & (cpuif_addr == 'h110 + i0*'h4); + end + decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 = cpuif_req_masked & (cpuif_addr == 'h118); + decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 = cpuif_req_masked & (cpuif_addr == 'h11c); + for(int i0=0; i0<2; i0++) begin + decoded_reg_strb.CPTRA_RSVD_REG[i0] = cpuif_req_masked & (cpuif_addr == 'h120 + i0*'h4); + end for(int i0=0; i0<12; i0++) begin decoded_reg_strb.fuse_uds_seed[i0] = cpuif_req_masked & (cpuif_addr == 'h200 + i0*'h4); end @@ -574,6 +586,38 @@ module soc_ifc_reg ( logic load_next; } LOCK; } CPTRA_FUSE_PAUSER_LOCK; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } TIMEOUT; + } [2-1:0]CPTRA_WDT_CFG; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } low_threshold; + struct packed{ + logic [15:0] next; + logic load_next; + } high_threshold; + } CPTRA_iTRNG_ENTROPY_CONFIG_0; + struct packed{ + struct packed{ + logic [15:0] next; + logic load_next; + } repetition_count; + struct packed{ + logic [15:0] next; + logic load_next; + } RSVD; + } CPTRA_iTRNG_ENTROPY_CONFIG_1; + struct packed{ + struct packed{ + logic [31:0] next; + logic load_next; + } RSVD; + } [2-1:0]CPTRA_RSVD_REG; struct packed{ struct packed{ logic [31:0] next; @@ -1391,6 +1435,32 @@ module soc_ifc_reg ( logic value; } LOCK; } CPTRA_FUSE_PAUSER_LOCK; + struct packed{ + struct packed{ + logic [31:0] value; + } TIMEOUT; + } [2-1:0]CPTRA_WDT_CFG; + struct packed{ + struct packed{ + logic [15:0] value; + } low_threshold; + struct packed{ + logic [15:0] value; + } high_threshold; + } CPTRA_iTRNG_ENTROPY_CONFIG_0; + struct packed{ + struct packed{ + logic [15:0] value; + } repetition_count; + struct packed{ + logic [15:0] value; + } RSVD; + } CPTRA_iTRNG_ENTROPY_CONFIG_1; + struct packed{ + struct packed{ + logic [31:0] value; + } RSVD; + } [2-1:0]CPTRA_RSVD_REG; struct packed{ struct packed{ logic [31:0] value; @@ -2736,8 +2806,8 @@ module soc_ifc_reg ( field_combo.CPTRA_FUSE_VALID_PAUSER.PAUSER.next = next_c; field_combo.CPTRA_FUSE_VALID_PAUSER.PAUSER.load_next = load_next_c; end - always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin - if(~hwif_in.cptra_rst_b) begin + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin field_storage.CPTRA_FUSE_VALID_PAUSER.PAUSER.value <= 'hffffffff; end else if(field_combo.CPTRA_FUSE_VALID_PAUSER.PAUSER.load_next) begin field_storage.CPTRA_FUSE_VALID_PAUSER.PAUSER.value <= field_combo.CPTRA_FUSE_VALID_PAUSER.PAUSER.next; @@ -2755,14 +2825,126 @@ module soc_ifc_reg ( field_combo.CPTRA_FUSE_PAUSER_LOCK.LOCK.next = next_c; field_combo.CPTRA_FUSE_PAUSER_LOCK.LOCK.load_next = load_next_c; end - always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin - if(~hwif_in.cptra_rst_b) begin + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin field_storage.CPTRA_FUSE_PAUSER_LOCK.LOCK.value <= 'h0; end else if(field_combo.CPTRA_FUSE_PAUSER_LOCK.LOCK.load_next) begin field_storage.CPTRA_FUSE_PAUSER_LOCK.LOCK.value <= field_combo.CPTRA_FUSE_PAUSER_LOCK.LOCK.next; end end assign hwif_out.CPTRA_FUSE_PAUSER_LOCK.LOCK.value = field_storage.CPTRA_FUSE_PAUSER_LOCK.LOCK.value; + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_WDT_CFG[].TIMEOUT + always_comb begin + automatic logic [31:0] next_c = field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_WDT_CFG[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.next = next_c; + field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_pwrgood) begin + if(~hwif_in.cptra_pwrgood) begin + field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value <= 'h0; + end else if(field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.load_next) begin + field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value <= field_combo.CPTRA_WDT_CFG[i0].TIMEOUT.next; + end + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold + always_comb begin + automatic logic [15:0] next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value <= 'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold + always_comb begin + automatic logic [15:0] next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value <= 'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count + always_comb begin + automatic logic [15:0] next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value & ~decoded_wr_biten[15:0]) | (decoded_wr_data[15:0] & decoded_wr_biten[15:0]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value <= 'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.next; + end + end + // Field: soc_ifc_reg.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD + always_comb begin + automatic logic [15:0] next_c = field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value & ~decoded_wr_biten[31:16]) | (decoded_wr_data[31:16] & decoded_wr_biten[31:16]); + load_next_c = '1; + end + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.next = next_c; + field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value <= 'h0; + end else if(field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.load_next) begin + field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value <= field_combo.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.next; + end + end + for(genvar i0=0; i0<2; i0++) begin + // Field: soc_ifc_reg.CPTRA_RSVD_REG[].RSVD + always_comb begin + automatic logic [31:0] next_c = field_storage.CPTRA_RSVD_REG[i0].RSVD.value; + automatic logic load_next_c = '0; + if(decoded_reg_strb.CPTRA_RSVD_REG[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.CPTRA_RSVD_REG[i0].RSVD.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.CPTRA_RSVD_REG[i0].RSVD.next = next_c; + field_combo.CPTRA_RSVD_REG[i0].RSVD.load_next = load_next_c; + end + always_ff @(posedge clk or negedge hwif_in.cptra_rst_b) begin + if(~hwif_in.cptra_rst_b) begin + field_storage.CPTRA_RSVD_REG[i0].RSVD.value <= 'h0; + end else if(field_combo.CPTRA_RSVD_REG[i0].RSVD.load_next) begin + field_storage.CPTRA_RSVD_REG[i0].RSVD.value <= field_combo.CPTRA_RSVD_REG[i0].RSVD.next; + end + end + end for(genvar i0=0; i0<12; i0++) begin // Field: soc_ifc_reg.fuse_uds_seed[].seed always_comb begin @@ -5239,7 +5421,7 @@ module soc_ifc_reg ( logic [31:0] readback_data; // Assign readback values to a flattened array - logic [180-1:0][31:0] readback_array; + logic [186-1:0][31:0] readback_array; assign readback_array[0][0:0] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.iccm_ecc_unc.value : '0; assign readback_array[0][1:1] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.dccm_ecc_unc.value : '0; assign readback_array[0][2:2] = (decoded_reg_strb.CPTRA_HW_ERROR_FATAL && !decoded_req_is_wr) ? field_storage.CPTRA_HW_ERROR_FATAL.nmi_pin.value : '0; @@ -5332,151 +5514,161 @@ module soc_ifc_reg ( assign readback_array[66][31:0] = (decoded_reg_strb.CPTRA_FUSE_VALID_PAUSER && !decoded_req_is_wr) ? field_storage.CPTRA_FUSE_VALID_PAUSER.PAUSER.value : '0; assign readback_array[67][0:0] = (decoded_reg_strb.CPTRA_FUSE_PAUSER_LOCK && !decoded_req_is_wr) ? field_storage.CPTRA_FUSE_PAUSER_LOCK.LOCK.value : '0; assign readback_array[67][31:1] = '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 68][31:0] = (decoded_reg_strb.CPTRA_WDT_CFG[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_WDT_CFG[i0].TIMEOUT.value : '0; + end + assign readback_array[70][15:0] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.low_threshold.value : '0; + assign readback_array[70][31:16] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_0 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_0.high_threshold.value : '0; + assign readback_array[71][15:0] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.repetition_count.value : '0; + assign readback_array[71][31:16] = (decoded_reg_strb.CPTRA_iTRNG_ENTROPY_CONFIG_1 && !decoded_req_is_wr) ? field_storage.CPTRA_iTRNG_ENTROPY_CONFIG_1.RSVD.value : '0; + for(genvar i0=0; i0<2; i0++) begin + assign readback_array[i0*1 + 72][31:0] = (decoded_reg_strb.CPTRA_RSVD_REG[i0] && !decoded_req_is_wr) ? field_storage.CPTRA_RSVD_REG[i0].RSVD.value : '0; + end for(genvar i0=0; i0<12; i0++) begin - assign readback_array[i0*1 + 68][31:0] = (decoded_reg_strb.fuse_key_manifest_pk_hash[i0] && !decoded_req_is_wr) ? field_storage.fuse_key_manifest_pk_hash[i0].hash.value : '0; + assign readback_array[i0*1 + 74][31:0] = (decoded_reg_strb.fuse_key_manifest_pk_hash[i0] && !decoded_req_is_wr) ? field_storage.fuse_key_manifest_pk_hash[i0].hash.value : '0; end - assign readback_array[80][3:0] = (decoded_reg_strb.fuse_key_manifest_pk_hash_mask && !decoded_req_is_wr) ? field_storage.fuse_key_manifest_pk_hash_mask.mask.value : '0; - assign readback_array[80][31:4] = '0; + assign readback_array[86][3:0] = (decoded_reg_strb.fuse_key_manifest_pk_hash_mask && !decoded_req_is_wr) ? field_storage.fuse_key_manifest_pk_hash_mask.mask.value : '0; + assign readback_array[86][31:4] = '0; for(genvar i0=0; i0<12; i0++) begin - assign readback_array[i0*1 + 81][31:0] = (decoded_reg_strb.fuse_owner_pk_hash[i0] && !decoded_req_is_wr) ? field_storage.fuse_owner_pk_hash[i0].hash.value : '0; + assign readback_array[i0*1 + 87][31:0] = (decoded_reg_strb.fuse_owner_pk_hash[i0] && !decoded_req_is_wr) ? field_storage.fuse_owner_pk_hash[i0].hash.value : '0; end - assign readback_array[93][31:0] = (decoded_reg_strb.fuse_fmc_key_manifest_svn && !decoded_req_is_wr) ? field_storage.fuse_fmc_key_manifest_svn.svn.value : '0; + assign readback_array[99][31:0] = (decoded_reg_strb.fuse_fmc_key_manifest_svn && !decoded_req_is_wr) ? field_storage.fuse_fmc_key_manifest_svn.svn.value : '0; for(genvar i0=0; i0<4; i0++) begin - assign readback_array[i0*1 + 94][31:0] = (decoded_reg_strb.fuse_runtime_svn[i0] && !decoded_req_is_wr) ? field_storage.fuse_runtime_svn[i0].svn.value : '0; + assign readback_array[i0*1 + 100][31:0] = (decoded_reg_strb.fuse_runtime_svn[i0] && !decoded_req_is_wr) ? field_storage.fuse_runtime_svn[i0].svn.value : '0; end - assign readback_array[98][0:0] = (decoded_reg_strb.fuse_anti_rollback_disable && !decoded_req_is_wr) ? field_storage.fuse_anti_rollback_disable.dis.value : '0; - assign readback_array[98][31:1] = '0; + assign readback_array[104][0:0] = (decoded_reg_strb.fuse_anti_rollback_disable && !decoded_req_is_wr) ? field_storage.fuse_anti_rollback_disable.dis.value : '0; + assign readback_array[104][31:1] = '0; for(genvar i0=0; i0<24; i0++) begin - assign readback_array[i0*1 + 99][31:0] = (decoded_reg_strb.fuse_idevid_cert_attr[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_cert_attr[i0].cert.value : '0; + assign readback_array[i0*1 + 105][31:0] = (decoded_reg_strb.fuse_idevid_cert_attr[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_cert_attr[i0].cert.value : '0; end for(genvar i0=0; i0<4; i0++) begin - assign readback_array[i0*1 + 123][31:0] = (decoded_reg_strb.fuse_idevid_manuf_hsm_id[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value : '0; - end - assign readback_array[127][1:0] = (decoded_reg_strb.fuse_life_cycle && !decoded_req_is_wr) ? field_storage.fuse_life_cycle.life_cycle.value : '0; - assign readback_array[127][31:2] = '0; - assign readback_array[128][0:0] = (decoded_reg_strb.fuse_lms_verify && !decoded_req_is_wr) ? field_storage.fuse_lms_verify.lms_verify.value : '0; - assign readback_array[128][31:1] = '0; - assign readback_array[129][31:0] = (decoded_reg_strb.fuse_lms_revocation && !decoded_req_is_wr) ? field_storage.fuse_lms_revocation.lms_revocation.value : '0; - assign readback_array[130][15:0] = (decoded_reg_strb.fuse_soc_stepping_id && !decoded_req_is_wr) ? field_storage.fuse_soc_stepping_id.soc_stepping_id.value : '0; - assign readback_array[130][31:16] = '0; - assign readback_array[131][0:0] = (decoded_reg_strb.internal_iccm_lock && !decoded_req_is_wr) ? field_storage.internal_iccm_lock.lock.value : '0; - assign readback_array[131][31:1] = '0; - assign readback_array[132][0:0] = (decoded_reg_strb.internal_fw_update_reset && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset.core_rst.value : '0; - assign readback_array[132][31:1] = '0; - assign readback_array[133][7:0] = (decoded_reg_strb.internal_fw_update_reset_wait_cycles && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value : '0; - assign readback_array[133][31:8] = '0; - assign readback_array[134][31:0] = (decoded_reg_strb.internal_nmi_vector && !decoded_req_is_wr) ? field_storage.internal_nmi_vector.vec.value : '0; - assign readback_array[135][0:0] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value : '0; - assign readback_array[135][1:1] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value : '0; - assign readback_array[135][2:2] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value : '0; - assign readback_array[135][31:3] = '0; - assign readback_array[136][0:0] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value : '0; - assign readback_array[136][1:1] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value : '0; - assign readback_array[136][2:2] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value : '0; - assign readback_array[136][31:3] = '0; - assign readback_array[137][31:0] = (decoded_reg_strb.internal_fw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_fatal_mask.mask.value : '0; - assign readback_array[138][31:0] = (decoded_reg_strb.internal_fw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_non_fatal_mask.mask.value : '0; - assign readback_array[139][31:0] = (decoded_reg_strb.internal_rv_mtime_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_l.count_l.value : '0; - assign readback_array[140][31:0] = (decoded_reg_strb.internal_rv_mtime_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_h.count_h.value : '0; - assign readback_array[141][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_l.compare_l.value : '0; - assign readback_array[142][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_h.compare_h.value : '0; - assign readback_array[143][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; - assign readback_array[143][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; - assign readback_array[143][31:2] = '0; - assign readback_array[144][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value : '0; - assign readback_array[144][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value : '0; - assign readback_array[144][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value : '0; - assign readback_array[144][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value : '0; - assign readback_array[144][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value : '0; - assign readback_array[144][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value : '0; - assign readback_array[144][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value : '0; - assign readback_array[144][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value : '0; - assign readback_array[144][31:8] = '0; - assign readback_array[145][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value : '0; - assign readback_array[145][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value : '0; - assign readback_array[145][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value : '0; - assign readback_array[145][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value : '0; - assign readback_array[145][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value : '0; - assign readback_array[145][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value : '0; - assign readback_array[145][31:6] = '0; - assign readback_array[146][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; - assign readback_array[146][31:1] = '0; - assign readback_array[147][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; - assign readback_array[147][31:1] = '0; - assign readback_array[148][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value : '0; - assign readback_array[148][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value : '0; - assign readback_array[148][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value : '0; - assign readback_array[148][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value : '0; - assign readback_array[148][4:4] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value : '0; - assign readback_array[148][5:5] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value : '0; - assign readback_array[148][6:6] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value : '0; - assign readback_array[148][7:7] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value : '0; - assign readback_array[148][31:8] = '0; - assign readback_array[149][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value : '0; - assign readback_array[149][1:1] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value : '0; - assign readback_array[149][2:2] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value : '0; - assign readback_array[149][3:3] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value : '0; - assign readback_array[149][4:4] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value : '0; - assign readback_array[149][5:5] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value : '0; - assign readback_array[149][31:6] = '0; - assign readback_array[150][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value : '0; - assign readback_array[150][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value : '0; - assign readback_array[150][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value : '0; - assign readback_array[150][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value : '0; - assign readback_array[150][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value : '0; - assign readback_array[150][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value : '0; - assign readback_array[150][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value : '0; - assign readback_array[150][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value : '0; + assign readback_array[i0*1 + 129][31:0] = (decoded_reg_strb.fuse_idevid_manuf_hsm_id[i0] && !decoded_req_is_wr) ? field_storage.fuse_idevid_manuf_hsm_id[i0].hsm_id.value : '0; + end + assign readback_array[133][1:0] = (decoded_reg_strb.fuse_life_cycle && !decoded_req_is_wr) ? field_storage.fuse_life_cycle.life_cycle.value : '0; + assign readback_array[133][31:2] = '0; + assign readback_array[134][0:0] = (decoded_reg_strb.fuse_lms_verify && !decoded_req_is_wr) ? field_storage.fuse_lms_verify.lms_verify.value : '0; + assign readback_array[134][31:1] = '0; + assign readback_array[135][31:0] = (decoded_reg_strb.fuse_lms_revocation && !decoded_req_is_wr) ? field_storage.fuse_lms_revocation.lms_revocation.value : '0; + assign readback_array[136][15:0] = (decoded_reg_strb.fuse_soc_stepping_id && !decoded_req_is_wr) ? field_storage.fuse_soc_stepping_id.soc_stepping_id.value : '0; + assign readback_array[136][31:16] = '0; + assign readback_array[137][0:0] = (decoded_reg_strb.internal_iccm_lock && !decoded_req_is_wr) ? field_storage.internal_iccm_lock.lock.value : '0; + assign readback_array[137][31:1] = '0; + assign readback_array[138][0:0] = (decoded_reg_strb.internal_fw_update_reset && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset.core_rst.value : '0; + assign readback_array[138][31:1] = '0; + assign readback_array[139][7:0] = (decoded_reg_strb.internal_fw_update_reset_wait_cycles && !decoded_req_is_wr) ? field_storage.internal_fw_update_reset_wait_cycles.wait_cycles.value : '0; + assign readback_array[139][31:8] = '0; + assign readback_array[140][31:0] = (decoded_reg_strb.internal_nmi_vector && !decoded_req_is_wr) ? field_storage.internal_nmi_vector.vec.value : '0; + assign readback_array[141][0:0] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_iccm_ecc_unc.value : '0; + assign readback_array[141][1:1] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_dccm_ecc_unc.value : '0; + assign readback_array[141][2:2] = (decoded_reg_strb.internal_hw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_fatal_mask.mask_nmi_pin.value : '0; + assign readback_array[141][31:3] = '0; + assign readback_array[142][0:0] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_no_lock.value : '0; + assign readback_array[142][1:1] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_prot_ooo.value : '0; + assign readback_array[142][2:2] = (decoded_reg_strb.internal_hw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_hw_error_non_fatal_mask.mask_mbox_ecc_unc.value : '0; + assign readback_array[142][31:3] = '0; + assign readback_array[143][31:0] = (decoded_reg_strb.internal_fw_error_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_fatal_mask.mask.value : '0; + assign readback_array[144][31:0] = (decoded_reg_strb.internal_fw_error_non_fatal_mask && !decoded_req_is_wr) ? field_storage.internal_fw_error_non_fatal_mask.mask.value : '0; + assign readback_array[145][31:0] = (decoded_reg_strb.internal_rv_mtime_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_l.count_l.value : '0; + assign readback_array[146][31:0] = (decoded_reg_strb.internal_rv_mtime_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtime_h.count_h.value : '0; + assign readback_array[147][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_l && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_l.compare_l.value : '0; + assign readback_array[148][31:0] = (decoded_reg_strb.internal_rv_mtimecmp_h && !decoded_req_is_wr) ? field_storage.internal_rv_mtimecmp_h.compare_h.value : '0; + assign readback_array[149][0:0] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.error_en.value : '0; + assign readback_array[149][1:1] = (decoded_reg_strb.intr_block_rf.global_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.global_intr_en_r.notif_en.value : '0; + assign readback_array[149][31:2] = '0; + assign readback_array[150][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_internal_en.value : '0; + assign readback_array[150][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_inv_dev_en.value : '0; + assign readback_array[150][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_cmd_fail_en.value : '0; + assign readback_array[150][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_bad_fuse_en.value : '0; + assign readback_array[150][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_iccm_blocked_en.value : '0; + assign readback_array[150][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_mbox_ecc_unc_en.value : '0; + assign readback_array[150][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer1_timeout_en.value : '0; + assign readback_array[150][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_en_r.error_wdt_timer2_timeout_en.value : '0; assign readback_array[150][31:8] = '0; - assign readback_array[151][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value : '0; - assign readback_array[151][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value : '0; - assign readback_array[151][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value : '0; - assign readback_array[151][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value : '0; - assign readback_array[151][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value : '0; - assign readback_array[151][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value : '0; + assign readback_array[151][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_cmd_avail_en.value : '0; + assign readback_array[151][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_mbox_ecc_cor_en.value : '0; + assign readback_array[151][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_debug_locked_en.value : '0; + assign readback_array[151][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_scan_mode_en.value : '0; + assign readback_array[151][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_soc_req_lock_en.value : '0; + assign readback_array[151][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_en_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_en_r.notif_gen_in_toggle_en.value : '0; assign readback_array[151][31:6] = '0; - assign readback_array[152][31:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value : '0; - assign readback_array[153][31:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value : '0; - assign readback_array[154][31:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value : '0; - assign readback_array[155][31:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value : '0; - assign readback_array[156][31:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value : '0; - assign readback_array[157][31:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value : '0; - assign readback_array[158][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value : '0; - assign readback_array[159][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value : '0; - assign readback_array[160][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value : '0; - assign readback_array[161][31:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value : '0; - assign readback_array[162][31:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value : '0; - assign readback_array[163][31:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value : '0; - assign readback_array[164][31:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value : '0; - assign readback_array[165][31:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value : '0; - assign readback_array[166][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value : '0; - assign readback_array[166][31:1] = '0; - assign readback_array[167][0:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value : '0; - assign readback_array[167][31:1] = '0; - assign readback_array[168][0:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value : '0; - assign readback_array[168][31:1] = '0; - assign readback_array[169][0:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value : '0; - assign readback_array[169][31:1] = '0; - assign readback_array[170][0:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value : '0; - assign readback_array[170][31:1] = '0; - assign readback_array[171][0:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value : '0; - assign readback_array[171][31:1] = '0; - assign readback_array[172][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value : '0; + assign readback_array[152][0:0] = (decoded_reg_strb.intr_block_rf.error_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_global_intr_r.agg_sts.value : '0; + assign readback_array[152][31:1] = '0; + assign readback_array[153][0:0] = (decoded_reg_strb.intr_block_rf.notif_global_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_global_intr_r.agg_sts.value : '0; + assign readback_array[153][31:1] = '0; + assign readback_array[154][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_internal_sts.value : '0; + assign readback_array[154][1:1] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_inv_dev_sts.value : '0; + assign readback_array[154][2:2] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_cmd_fail_sts.value : '0; + assign readback_array[154][3:3] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_bad_fuse_sts.value : '0; + assign readback_array[154][4:4] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_iccm_blocked_sts.value : '0; + assign readback_array[154][5:5] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_mbox_ecc_unc_sts.value : '0; + assign readback_array[154][6:6] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer1_timeout_sts.value : '0; + assign readback_array[154][7:7] = (decoded_reg_strb.intr_block_rf.error_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_r.error_wdt_timer2_timeout_sts.value : '0; + assign readback_array[154][31:8] = '0; + assign readback_array[155][0:0] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_cmd_avail_sts.value : '0; + assign readback_array[155][1:1] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_mbox_ecc_cor_sts.value : '0; + assign readback_array[155][2:2] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_debug_locked_sts.value : '0; + assign readback_array[155][3:3] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_scan_mode_sts.value : '0; + assign readback_array[155][4:4] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_soc_req_lock_sts.value : '0; + assign readback_array[155][5:5] = (decoded_reg_strb.intr_block_rf.notif_internal_intr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_internal_intr_r.notif_gen_in_toggle_sts.value : '0; + assign readback_array[155][31:6] = '0; + assign readback_array[156][0:0] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_internal_trig.value : '0; + assign readback_array[156][1:1] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_inv_dev_trig.value : '0; + assign readback_array[156][2:2] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_cmd_fail_trig.value : '0; + assign readback_array[156][3:3] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_bad_fuse_trig.value : '0; + assign readback_array[156][4:4] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_iccm_blocked_trig.value : '0; + assign readback_array[156][5:5] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_mbox_ecc_unc_trig.value : '0; + assign readback_array[156][6:6] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer1_timeout_trig.value : '0; + assign readback_array[156][7:7] = (decoded_reg_strb.intr_block_rf.error_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_intr_trig_r.error_wdt_timer2_timeout_trig.value : '0; + assign readback_array[156][31:8] = '0; + assign readback_array[157][0:0] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_cmd_avail_trig.value : '0; + assign readback_array[157][1:1] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_mbox_ecc_cor_trig.value : '0; + assign readback_array[157][2:2] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_debug_locked_trig.value : '0; + assign readback_array[157][3:3] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_scan_mode_trig.value : '0; + assign readback_array[157][4:4] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_soc_req_lock_trig.value : '0; + assign readback_array[157][5:5] = (decoded_reg_strb.intr_block_rf.notif_intr_trig_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_intr_trig_r.notif_gen_in_toggle_trig.value : '0; + assign readback_array[157][31:6] = '0; + assign readback_array[158][31:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_r.cnt.value : '0; + assign readback_array[159][31:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_r.cnt.value : '0; + assign readback_array[160][31:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_r.cnt.value : '0; + assign readback_array[161][31:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_r.cnt.value : '0; + assign readback_array[162][31:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_r.cnt.value : '0; + assign readback_array[163][31:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_r.cnt.value : '0; + assign readback_array[164][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_r.cnt.value : '0; + assign readback_array[165][31:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_r.cnt.value : '0; + assign readback_array[166][31:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_r.cnt.value : '0; + assign readback_array[167][31:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_r.cnt.value : '0; + assign readback_array[168][31:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_r.cnt.value : '0; + assign readback_array[169][31:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_r.cnt.value : '0; + assign readback_array[170][31:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_r.cnt.value : '0; + assign readback_array[171][31:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_r.cnt.value : '0; + assign readback_array[172][0:0] = (decoded_reg_strb.intr_block_rf.error_internal_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_internal_intr_count_incr_r.pulse.value : '0; assign readback_array[172][31:1] = '0; - assign readback_array[173][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value : '0; + assign readback_array[173][0:0] = (decoded_reg_strb.intr_block_rf.error_inv_dev_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_inv_dev_intr_count_incr_r.pulse.value : '0; assign readback_array[173][31:1] = '0; - assign readback_array[174][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value : '0; + assign readback_array[174][0:0] = (decoded_reg_strb.intr_block_rf.error_cmd_fail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_cmd_fail_intr_count_incr_r.pulse.value : '0; assign readback_array[174][31:1] = '0; - assign readback_array[175][0:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value : '0; + assign readback_array[175][0:0] = (decoded_reg_strb.intr_block_rf.error_bad_fuse_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_bad_fuse_intr_count_incr_r.pulse.value : '0; assign readback_array[175][31:1] = '0; - assign readback_array[176][0:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value : '0; + assign readback_array[176][0:0] = (decoded_reg_strb.intr_block_rf.error_iccm_blocked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_iccm_blocked_intr_count_incr_r.pulse.value : '0; assign readback_array[176][31:1] = '0; - assign readback_array[177][0:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value : '0; + assign readback_array[177][0:0] = (decoded_reg_strb.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_mbox_ecc_unc_intr_count_incr_r.pulse.value : '0; assign readback_array[177][31:1] = '0; - assign readback_array[178][0:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value : '0; + assign readback_array[178][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer1_timeout_intr_count_incr_r.pulse.value : '0; assign readback_array[178][31:1] = '0; - assign readback_array[179][0:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value : '0; + assign readback_array[179][0:0] = (decoded_reg_strb.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.error_wdt_timer2_timeout_intr_count_incr_r.pulse.value : '0; assign readback_array[179][31:1] = '0; + assign readback_array[180][0:0] = (decoded_reg_strb.intr_block_rf.notif_cmd_avail_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_cmd_avail_intr_count_incr_r.pulse.value : '0; + assign readback_array[180][31:1] = '0; + assign readback_array[181][0:0] = (decoded_reg_strb.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_mbox_ecc_cor_intr_count_incr_r.pulse.value : '0; + assign readback_array[181][31:1] = '0; + assign readback_array[182][0:0] = (decoded_reg_strb.intr_block_rf.notif_debug_locked_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_debug_locked_intr_count_incr_r.pulse.value : '0; + assign readback_array[182][31:1] = '0; + assign readback_array[183][0:0] = (decoded_reg_strb.intr_block_rf.notif_scan_mode_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_scan_mode_intr_count_incr_r.pulse.value : '0; + assign readback_array[183][31:1] = '0; + assign readback_array[184][0:0] = (decoded_reg_strb.intr_block_rf.notif_soc_req_lock_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_soc_req_lock_intr_count_incr_r.pulse.value : '0; + assign readback_array[184][31:1] = '0; + assign readback_array[185][0:0] = (decoded_reg_strb.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r && !decoded_req_is_wr) ? field_storage.intr_block_rf.notif_gen_in_toggle_intr_count_incr_r.pulse.value : '0; + assign readback_array[185][31:1] = '0; // Reduce the array always_comb begin @@ -5484,7 +5676,7 @@ module soc_ifc_reg ( readback_done = decoded_req & ~decoded_req_is_wr; readback_err = '0; readback_data_var = '0; - for(int i=0; i<180; i++) readback_data_var |= readback_array[i]; + for(int i=0; i<186; i++) readback_data_var |= readback_array[i]; readback_data = readback_data_var; end diff --git a/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh b/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh index e2fa1bef8..0b835415e 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh +++ b/src/soc_ifc/rtl/soc_ifc_reg_covergroups.svh @@ -831,6 +831,90 @@ endgroup + /*----------------------- SOC_IFC_REG__CPTRA_WDT_CFG COVERGROUPS -----------------------*/ + covergroup soc_ifc_reg__CPTRA_WDT_CFG_bit_cg with function sample(input bit reg_bit); + option.per_instance = 1; + reg_bit_cp : coverpoint reg_bit { + bins value[2] = {0,1}; + } + reg_bit_edge_cp : coverpoint reg_bit { + bins rise = (0 => 1); + bins fall = (1 => 0); + } + + endgroup + covergroup soc_ifc_reg__CPTRA_WDT_CFG_fld_cg with function sample( + input bit [32-1:0] TIMEOUT + ); + option.per_instance = 1; + TIMEOUT_cp : coverpoint TIMEOUT; + + endgroup + + /*----------------------- SOC_IFC_REG__CPTRA_ITRNG_ENTROPY_CONFIG_0 COVERGROUPS -----------------------*/ + covergroup soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0_bit_cg with function sample(input bit reg_bit); + option.per_instance = 1; + reg_bit_cp : coverpoint reg_bit { + bins value[2] = {0,1}; + } + reg_bit_edge_cp : coverpoint reg_bit { + bins rise = (0 => 1); + bins fall = (1 => 0); + } + + endgroup + covergroup soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0_fld_cg with function sample( + input bit [16-1:0] low_threshold, + input bit [16-1:0] high_threshold + ); + option.per_instance = 1; + low_threshold_cp : coverpoint low_threshold; + high_threshold_cp : coverpoint high_threshold; + + endgroup + + /*----------------------- SOC_IFC_REG__CPTRA_ITRNG_ENTROPY_CONFIG_1 COVERGROUPS -----------------------*/ + covergroup soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1_bit_cg with function sample(input bit reg_bit); + option.per_instance = 1; + reg_bit_cp : coverpoint reg_bit { + bins value[2] = {0,1}; + } + reg_bit_edge_cp : coverpoint reg_bit { + bins rise = (0 => 1); + bins fall = (1 => 0); + } + + endgroup + covergroup soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1_fld_cg with function sample( + input bit [16-1:0] repetition_count, + input bit [16-1:0] RSVD + ); + option.per_instance = 1; + repetition_count_cp : coverpoint repetition_count; + RSVD_cp : coverpoint RSVD; + + endgroup + + /*----------------------- SOC_IFC_REG__CPTRA_RSVD_REG COVERGROUPS -----------------------*/ + covergroup soc_ifc_reg__CPTRA_RSVD_REG_bit_cg with function sample(input bit reg_bit); + option.per_instance = 1; + reg_bit_cp : coverpoint reg_bit { + bins value[2] = {0,1}; + } + reg_bit_edge_cp : coverpoint reg_bit { + bins rise = (0 => 1); + bins fall = (1 => 0); + } + + endgroup + covergroup soc_ifc_reg__CPTRA_RSVD_REG_fld_cg with function sample( + input bit [32-1:0] RSVD + ); + option.per_instance = 1; + RSVD_cp : coverpoint RSVD; + + endgroup + /*----------------------- SOC_IFC_REG__FUSE_UDS_SEED COVERGROUPS -----------------------*/ covergroup soc_ifc_reg__fuse_uds_seed_bit_cg with function sample(input bit reg_bit); option.per_instance = 1; diff --git a/src/soc_ifc/rtl/soc_ifc_reg_sample.svh b/src/soc_ifc/rtl/soc_ifc_reg_sample.svh index e615824cc..e677131de 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_sample.svh +++ b/src/soc_ifc/rtl/soc_ifc_reg_sample.svh @@ -980,6 +980,110 @@ end endfunction + /*----------------------- SOC_IFC_REG__CPTRA_WDT_CFG SAMPLE FUNCTIONS -----------------------*/ + function void soc_ifc_reg__CPTRA_WDT_CFG::sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + m_current = get(); + m_data = data; + m_is_read = is_read; + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(TIMEOUT_bit_cg[bt]) this.TIMEOUT_bit_cg[bt].sample(data[0 + bt]); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( data[31:0]/*TIMEOUT*/ ); + end + endfunction + + function void soc_ifc_reg__CPTRA_WDT_CFG::sample_values(); + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(TIMEOUT_bit_cg[bt]) this.TIMEOUT_bit_cg[bt].sample(TIMEOUT.get_mirrored_value() >> bt); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( TIMEOUT.get_mirrored_value() ); + end + endfunction + + /*----------------------- SOC_IFC_REG__CPTRA_ITRNG_ENTROPY_CONFIG_0 SAMPLE FUNCTIONS -----------------------*/ + function void soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0::sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + m_current = get(); + m_data = data; + m_is_read = is_read; + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(low_threshold_bit_cg[bt]) this.low_threshold_bit_cg[bt].sample(data[0 + bt]); + foreach(high_threshold_bit_cg[bt]) this.high_threshold_bit_cg[bt].sample(data[16 + bt]); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( data[15:0]/*low_threshold*/ , data[31:16]/*high_threshold*/ ); + end + endfunction + + function void soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0::sample_values(); + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(low_threshold_bit_cg[bt]) this.low_threshold_bit_cg[bt].sample(low_threshold.get_mirrored_value() >> bt); + foreach(high_threshold_bit_cg[bt]) this.high_threshold_bit_cg[bt].sample(high_threshold.get_mirrored_value() >> bt); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( low_threshold.get_mirrored_value() , high_threshold.get_mirrored_value() ); + end + endfunction + + /*----------------------- SOC_IFC_REG__CPTRA_ITRNG_ENTROPY_CONFIG_1 SAMPLE FUNCTIONS -----------------------*/ + function void soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1::sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + m_current = get(); + m_data = data; + m_is_read = is_read; + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(repetition_count_bit_cg[bt]) this.repetition_count_bit_cg[bt].sample(data[0 + bt]); + foreach(RSVD_bit_cg[bt]) this.RSVD_bit_cg[bt].sample(data[16 + bt]); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( data[15:0]/*repetition_count*/ , data[31:16]/*RSVD*/ ); + end + endfunction + + function void soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1::sample_values(); + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(repetition_count_bit_cg[bt]) this.repetition_count_bit_cg[bt].sample(repetition_count.get_mirrored_value() >> bt); + foreach(RSVD_bit_cg[bt]) this.RSVD_bit_cg[bt].sample(RSVD.get_mirrored_value() >> bt); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( repetition_count.get_mirrored_value() , RSVD.get_mirrored_value() ); + end + endfunction + + /*----------------------- SOC_IFC_REG__CPTRA_RSVD_REG SAMPLE FUNCTIONS -----------------------*/ + function void soc_ifc_reg__CPTRA_RSVD_REG::sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + m_current = get(); + m_data = data; + m_is_read = is_read; + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(RSVD_bit_cg[bt]) this.RSVD_bit_cg[bt].sample(data[0 + bt]); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( data[31:0]/*RSVD*/ ); + end + endfunction + + function void soc_ifc_reg__CPTRA_RSVD_REG::sample_values(); + if (get_coverage(UVM_CVR_REG_BITS)) begin + foreach(RSVD_bit_cg[bt]) this.RSVD_bit_cg[bt].sample(RSVD.get_mirrored_value() >> bt); + end + if (get_coverage(UVM_CVR_FIELD_VALS)) begin + this.fld_cg.sample( RSVD.get_mirrored_value() ); + end + endfunction + /*----------------------- SOC_IFC_REG__FUSE_UDS_SEED SAMPLE FUNCTIONS -----------------------*/ function void soc_ifc_reg__fuse_uds_seed::sample(uvm_reg_data_t data, uvm_reg_data_t byte_en, diff --git a/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv b/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv index 0a982a1f3..249f71bb5 100644 --- a/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv +++ b/src/soc_ifc/rtl/soc_ifc_reg_uvm.sv @@ -1214,6 +1214,136 @@ package soc_ifc_reg_uvm; endfunction : build endclass : soc_ifc_reg__CPTRA_FUSE_PAUSER_LOCK + // Reg - soc_ifc_reg::CPTRA_WDT_CFG + class soc_ifc_reg__CPTRA_WDT_CFG extends uvm_reg; + protected uvm_reg_data_t m_current; + protected uvm_reg_data_t m_data; + protected bit m_is_read; + + soc_ifc_reg__CPTRA_WDT_CFG_bit_cg TIMEOUT_bit_cg[32]; + soc_ifc_reg__CPTRA_WDT_CFG_fld_cg fld_cg; + rand uvm_reg_field TIMEOUT; + + function new(string name = "soc_ifc_reg__CPTRA_WDT_CFG"); + super.new(name, 32, build_coverage(UVM_CVR_ALL)); + endfunction : new + extern virtual function void sample_values(); + extern protected virtual function void sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + + virtual function void build(); + this.TIMEOUT = new("TIMEOUT"); + this.TIMEOUT.configure(this, 32, 0, "RW", 0, 'h0, 1, 1, 0); + if (has_coverage(UVM_CVR_REG_BITS)) begin + foreach(TIMEOUT_bit_cg[bt]) TIMEOUT_bit_cg[bt] = new(); + end + if (has_coverage(UVM_CVR_FIELD_VALS)) + fld_cg = new(); + endfunction : build + endclass : soc_ifc_reg__CPTRA_WDT_CFG + + // Reg - soc_ifc_reg::CPTRA_iTRNG_ENTROPY_CONFIG_0 + class soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0 extends uvm_reg; + protected uvm_reg_data_t m_current; + protected uvm_reg_data_t m_data; + protected bit m_is_read; + + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0_bit_cg low_threshold_bit_cg[16]; + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0_bit_cg high_threshold_bit_cg[16]; + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0_fld_cg fld_cg; + rand uvm_reg_field low_threshold; + rand uvm_reg_field high_threshold; + + function new(string name = "soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0"); + super.new(name, 32, build_coverage(UVM_CVR_ALL)); + endfunction : new + extern virtual function void sample_values(); + extern protected virtual function void sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + + virtual function void build(); + this.low_threshold = new("low_threshold"); + this.low_threshold.configure(this, 16, 0, "RW", 0, 'h0, 1, 1, 0); + this.high_threshold = new("high_threshold"); + this.high_threshold.configure(this, 16, 16, "RW", 0, 'h0, 1, 1, 0); + if (has_coverage(UVM_CVR_REG_BITS)) begin + foreach(low_threshold_bit_cg[bt]) low_threshold_bit_cg[bt] = new(); + foreach(high_threshold_bit_cg[bt]) high_threshold_bit_cg[bt] = new(); + end + if (has_coverage(UVM_CVR_FIELD_VALS)) + fld_cg = new(); + endfunction : build + endclass : soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0 + + // Reg - soc_ifc_reg::CPTRA_iTRNG_ENTROPY_CONFIG_1 + class soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1 extends uvm_reg; + protected uvm_reg_data_t m_current; + protected uvm_reg_data_t m_data; + protected bit m_is_read; + + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1_bit_cg repetition_count_bit_cg[16]; + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1_bit_cg RSVD_bit_cg[16]; + soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1_fld_cg fld_cg; + rand uvm_reg_field repetition_count; + rand uvm_reg_field RSVD; + + function new(string name = "soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1"); + super.new(name, 32, build_coverage(UVM_CVR_ALL)); + endfunction : new + extern virtual function void sample_values(); + extern protected virtual function void sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + + virtual function void build(); + this.repetition_count = new("repetition_count"); + this.repetition_count.configure(this, 16, 0, "RW", 0, 'h0, 1, 1, 0); + this.RSVD = new("RSVD"); + this.RSVD.configure(this, 16, 16, "RW", 0, 'h0, 1, 1, 0); + if (has_coverage(UVM_CVR_REG_BITS)) begin + foreach(repetition_count_bit_cg[bt]) repetition_count_bit_cg[bt] = new(); + foreach(RSVD_bit_cg[bt]) RSVD_bit_cg[bt] = new(); + end + if (has_coverage(UVM_CVR_FIELD_VALS)) + fld_cg = new(); + endfunction : build + endclass : soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1 + + // Reg - soc_ifc_reg::CPTRA_RSVD_REG + class soc_ifc_reg__CPTRA_RSVD_REG extends uvm_reg; + protected uvm_reg_data_t m_current; + protected uvm_reg_data_t m_data; + protected bit m_is_read; + + soc_ifc_reg__CPTRA_RSVD_REG_bit_cg RSVD_bit_cg[32]; + soc_ifc_reg__CPTRA_RSVD_REG_fld_cg fld_cg; + rand uvm_reg_field RSVD; + + function new(string name = "soc_ifc_reg__CPTRA_RSVD_REG"); + super.new(name, 32, build_coverage(UVM_CVR_ALL)); + endfunction : new + extern virtual function void sample_values(); + extern protected virtual function void sample(uvm_reg_data_t data, + uvm_reg_data_t byte_en, + bit is_read, + uvm_reg_map map); + + virtual function void build(); + this.RSVD = new("RSVD"); + this.RSVD.configure(this, 32, 0, "RW", 0, 'h0, 1, 1, 0); + if (has_coverage(UVM_CVR_REG_BITS)) begin + foreach(RSVD_bit_cg[bt]) RSVD_bit_cg[bt] = new(); + end + if (has_coverage(UVM_CVR_FIELD_VALS)) + fld_cg = new(); + endfunction : build + endclass : soc_ifc_reg__CPTRA_RSVD_REG + // Reg - soc_ifc_reg::fuse_uds_seed class soc_ifc_reg__fuse_uds_seed extends uvm_reg; protected uvm_reg_data_t m_current; @@ -3612,6 +3742,10 @@ package soc_ifc_reg_uvm; rand soc_ifc_reg__CPTRA_WDT_STATUS CPTRA_WDT_STATUS; rand soc_ifc_reg__CPTRA_FUSE_VALID_PAUSER CPTRA_FUSE_VALID_PAUSER; rand soc_ifc_reg__CPTRA_FUSE_PAUSER_LOCK CPTRA_FUSE_PAUSER_LOCK; + rand soc_ifc_reg__CPTRA_WDT_CFG CPTRA_WDT_CFG[2]; + rand soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_0 CPTRA_iTRNG_ENTROPY_CONFIG_0; + rand soc_ifc_reg__CPTRA_iTRNG_ENTROPY_CONFIG_1 CPTRA_iTRNG_ENTROPY_CONFIG_1; + rand soc_ifc_reg__CPTRA_RSVD_REG CPTRA_RSVD_REG[2]; rand soc_ifc_reg__fuse_uds_seed fuse_uds_seed[12]; rand soc_ifc_reg__fuse_field_entropy fuse_field_entropy[8]; rand soc_ifc_reg__fuse_key_manifest_pk_hash fuse_key_manifest_pk_hash[12]; @@ -3850,6 +3984,30 @@ package soc_ifc_reg_uvm; this.CPTRA_FUSE_PAUSER_LOCK.build(); this.default_map.add_reg(this.CPTRA_FUSE_PAUSER_LOCK, 'h10c); + foreach(this.CPTRA_WDT_CFG[i0]) begin + this.CPTRA_WDT_CFG[i0] = new($sformatf("CPTRA_WDT_CFG[%0d]", i0)); + this.CPTRA_WDT_CFG[i0].configure(this); + + this.CPTRA_WDT_CFG[i0].build(); + this.default_map.add_reg(this.CPTRA_WDT_CFG[i0], 'h110 + i0*'h4); + end + this.CPTRA_iTRNG_ENTROPY_CONFIG_0 = new("CPTRA_iTRNG_ENTROPY_CONFIG_0"); + this.CPTRA_iTRNG_ENTROPY_CONFIG_0.configure(this); + + this.CPTRA_iTRNG_ENTROPY_CONFIG_0.build(); + this.default_map.add_reg(this.CPTRA_iTRNG_ENTROPY_CONFIG_0, 'h118); + this.CPTRA_iTRNG_ENTROPY_CONFIG_1 = new("CPTRA_iTRNG_ENTROPY_CONFIG_1"); + this.CPTRA_iTRNG_ENTROPY_CONFIG_1.configure(this); + + this.CPTRA_iTRNG_ENTROPY_CONFIG_1.build(); + this.default_map.add_reg(this.CPTRA_iTRNG_ENTROPY_CONFIG_1, 'h11c); + foreach(this.CPTRA_RSVD_REG[i0]) begin + this.CPTRA_RSVD_REG[i0] = new($sformatf("CPTRA_RSVD_REG[%0d]", i0)); + this.CPTRA_RSVD_REG[i0].configure(this); + + this.CPTRA_RSVD_REG[i0].build(); + this.default_map.add_reg(this.CPTRA_RSVD_REG[i0], 'h120 + i0*'h4); + end foreach(this.fuse_uds_seed[i0]) begin this.fuse_uds_seed[i0] = new($sformatf("fuse_uds_seed[%0d]", i0)); this.fuse_uds_seed[i0].configure(this); diff --git a/src/soc_ifc/rtl/soc_ifc_top.sv b/src/soc_ifc/rtl/soc_ifc_top.sv index 164f2f14b..5629dd4b5 100644 --- a/src/soc_ifc/rtl/soc_ifc_top.sv +++ b/src/soc_ifc/rtl/soc_ifc_top.sv @@ -143,6 +143,7 @@ logic mbox_dir_req_dv; logic mbox_req_hold; soc_ifc_req_t mbox_req_data; logic [SOC_IFC_DATA_W-1:0] mbox_rdata; +logic [SOC_IFC_DATA_W-1:0] mbox_dir_rdata; logic mbox_error; //sha req inf @@ -194,6 +195,7 @@ logic pwrgood_toggle_hint; logic Warm_Reset_Capture_Flag; logic BootFSM_BrkPoint_Latched; +logic BootFSM_BrkPoint_valid; logic BootFSM_BrkPoint_Flag; logic dmi_inc_rdptr; @@ -233,6 +235,7 @@ soc_ifc_boot_fsm i_soc_ifc_boot_fsm ( .clk(clk), .cptra_pwrgood(cptra_pwrgood), .cptra_rst_b (cptra_rst_b), + .scan_mode(scan_mode_f), .fw_update_rst (soc_ifc_reg_hwif_out.internal_fw_update_reset.core_rst.value), .fw_update_rst_wait_cycles (soc_ifc_reg_hwif_out.internal_fw_update_reset_wait_cycles.wait_cycles.value), .ready_for_fuses(ready_for_fuses), @@ -241,7 +244,7 @@ soc_ifc_boot_fsm i_soc_ifc_boot_fsm ( .fuse_done(soc_ifc_reg_hwif_out.CPTRA_FUSE_WR_DONE.done.value), .fuse_wr_done_observed(fuse_wr_done_reg_write_observed), - .BootFSM_BrkPoint(BootFSM_BrkPoint_Latched), + .BootFSM_BrkPoint(BootFSM_BrkPoint_valid), .BootFSM_Continue(soc_ifc_reg_hwif_out.CPTRA_BOOTFSM_GO.GO.value), .cptra_noncore_rst_b(cptra_noncore_rst_b), //goes to all other blocks @@ -267,7 +270,7 @@ apb_slv_sif #( i_apb_slv_sif_soc_ifc ( //AMBA APB INF .PCLK(soc_ifc_clk_cg), - .PRESETn(cptra_rst_b), + .PRESETn(cptra_noncore_rst_b), .PADDR(paddr_i), .PPROT('0), .PSEL(psel_i), @@ -363,6 +366,7 @@ soc_ifc_arb #( .mbox_req_hold(mbox_req_hold), .mbox_req_data(mbox_req_data), .mbox_rdata(mbox_rdata), + .mbox_dir_rdata(mbox_dir_rdata), .mbox_error(mbox_error), //SHA inf .sha_req_dv(sha_req_dv), @@ -461,19 +465,21 @@ logic cptra_in_dbg_or_manuf_mode; assign cptra_in_dbg_or_manuf_mode = ~(security_state.debug_locked) | ((security_state.debug_locked) & (security_state.device_lifecycle == DEVICE_MANUFACTURING)); -always_ff @(posedge rdc_clk_cg or negedge cptra_rst_b) begin - if (~cptra_rst_b) begin +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin BootFSM_BrkPoint_Latched <= 0; BootFSM_BrkPoint_Flag <= 0; end // Breakpoint value captured on a Caliptra reset deassertion (0->1 signal transition) and is reset on BootFSM_Continue is set // BootFSM_Continue's reset value is zero else if(!BootFSM_BrkPoint_Flag) begin - BootFSM_BrkPoint_Latched <= BootFSM_BrkPoint & cptra_in_dbg_or_manuf_mode; + BootFSM_BrkPoint_Latched <= BootFSM_BrkPoint; BootFSM_BrkPoint_Flag <= 1; end end +assign BootFSM_BrkPoint_valid = BootFSM_BrkPoint_Latched & cptra_in_dbg_or_manuf_mode; + // pwrgood_hint informs if the powergood toggled always_ff @(posedge rdc_clk_cg or negedge cptra_pwrgood) begin if(~cptra_pwrgood) begin @@ -485,8 +491,8 @@ always_ff @(posedge rdc_clk_cg or negedge cptra_pwrgood) begin end end -always_ff @(posedge rdc_clk_cg or negedge cptra_rst_b) begin - if (~cptra_rst_b) begin +always_ff @(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if (~cptra_noncore_rst_b) begin Warm_Reset_Capture_Flag <= 0; end else if(!Warm_Reset_Capture_Flag) begin @@ -560,8 +566,8 @@ always_comb soc_ifc_reg_hwif_in.CPTRA_FUSE_PAUSER_LOCK.LOCK.swwel = soc_ifc_reg_ // Can't write to RW-able fuses once fuse_done is set (implies the register is being locked using the fuse_wr_done) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -always_ff @(posedge soc_ifc_clk_cg or negedge cptra_rst_b) begin - if(~cptra_rst_b) begin +always_ff @(posedge soc_ifc_clk_cg or negedge cptra_noncore_rst_b) begin + if(~cptra_noncore_rst_b) begin fuse_wr_done_reg_write_observed <= 0; end else begin @@ -716,8 +722,8 @@ assign nmi_intr = t2_timeout && !timer2_en; //Only issue nmi if WDT // sets CPTRA_FW_ERROR_FATAL or when a HW condition occurs that sets a bit // in CPTRA_HW_ERROR_FATAL // Interrupt only deasserts on reset -always_ff@(posedge rdc_clk_cg or negedge cptra_rst_b) begin - if(~cptra_rst_b) begin +always_ff@(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if(~cptra_noncore_rst_b) begin cptra_error_fatal <= 1'b0; end // FW write that SETS a new (non-masked) bit results in interrupt assertion @@ -737,8 +743,8 @@ always_ff@(posedge rdc_clk_cg or negedge cptra_rst_b) begin cptra_error_fatal <= cptra_error_fatal; end end -always_ff@(posedge rdc_clk_cg or negedge cptra_rst_b) begin - if(~cptra_rst_b) begin +always_ff@(posedge rdc_clk_cg or negedge cptra_noncore_rst_b) begin + if(~cptra_noncore_rst_b) begin cptra_error_non_fatal <= 1'b0; end // FW write that SETS a new (non-masked) bit results in interrupt assertion @@ -814,6 +820,7 @@ i_mbox ( .req_data(mbox_req_data), .mbox_error(mbox_error), .rdata(mbox_rdata), + .dir_rdata(mbox_dir_rdata), .sha_sram_req_dv(sha_sram_req_dv), .sha_sram_req_addr(sha_sram_req_addr), .sha_sram_resp(sha_sram_resp), @@ -974,7 +981,7 @@ always_ff @(posedge rdc_clk_cg or negedge cptra_pwrgood) begin end end -`CALIPTRA_ASSERT_KNOWN(ERR_AHB_INF_X, {hreadyout_o,hresp_o}, clk, cptra_rst_b) +`CALIPTRA_ASSERT_KNOWN(ERR_AHB_INF_X, {hreadyout_o,hresp_o}, clk, cptra_noncore_rst_b) //this generates an NMI in the core, but we don't have a handler so it just hangs -`CALIPTRA_ASSERT_NEVER(ERR_SOC_IFC_AHB_ERR, hresp_o, clk, cptra_rst_b) +`CALIPTRA_ASSERT_NEVER(ERR_SOC_IFC_AHB_ERR, hresp_o, clk, cptra_noncore_rst_b) endmodule diff --git a/src/soc_ifc/stimulus/testsuites/soc_ifc_nightly_directed_regression.yml b/src/soc_ifc/stimulus/testsuites/soc_ifc_nightly_directed_regression.yml index 2821f9aa5..430c2d8a2 100644 --- a/src/soc_ifc/stimulus/testsuites/soc_ifc_nightly_directed_regression.yml +++ b/src/soc_ifc/stimulus/testsuites/soc_ifc_nightly_directed_regression.yml @@ -21,5 +21,5 @@ contents: ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/soc_reg_wrmrst_test: {weight 12} ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/soc_reg_invalid_test: {weight 6} ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/rvtime_reg_test: {weight 3} - ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/sha_acc_intrblk_test.yml: {weight 3} - ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/soc_reg_intrblk_test.yml: {weight 3} + ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/sha_acc_intrblk_test: {weight 3} + ${CALIPTRA_ROOT}/src/soc_ifc/stimulus/tests/directed/soc_reg_intrblk_test: {weight 3} diff --git a/src/soc_ifc/stimulus/testsuites/uvmf_soc_ifc_promote_regression.yml b/src/soc_ifc/stimulus/testsuites/uvmf_soc_ifc_promote_regression.yml index df620ae70..b49a59d56 100644 --- a/src/soc_ifc/stimulus/testsuites/uvmf_soc_ifc_promote_regression.yml +++ b/src/soc_ifc/stimulus/testsuites/uvmf_soc_ifc_promote_regression.yml @@ -6,10 +6,10 @@ contents: tags: ["L0", "SOC_IFC", "directed", "smoke_test"] path: "" weight: 100 - generations: 1 - # Use seed 1 for the promote test, for consistent results + generations: 6 formats: - generate: "reseed {template}.yml -seed 1" - path: "{template_basename}__1.yml" + generate: "reseed {template}.yml -seed {seed}" + path: "{template_basename}__{seed}.yml" templates: $CALIPTRA_ROOT/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/soc_ifc_cmdline_test : { weight 100 } + $CALIPTRA_ROOT/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/soc_ifc_rand_test : { weight 500 } diff --git a/src/soc_ifc/tb/fuse_reg_pauser_test.svh b/src/soc_ifc/tb/fuse_reg_pauser_test.svh index 093fb401f..d8714de07 100644 --- a/src/soc_ifc/tb/fuse_reg_pauser_test.svh +++ b/src/soc_ifc/tb/fuse_reg_pauser_test.svh @@ -96,8 +96,8 @@ task fuse_reg_pauser_test; tphase = "1b"; // NOTE. simulate_caliptra_boot() is necessary for noncore_rst_b to be deasserted - simulate_caliptra_boot(); - wait (cptra_noncore_rst_b_tb == 1'b1); + //simulate_caliptra_boot(); + //wait (cptra_noncore_rst_b_tb == 1'b1); // Set pauser valid to non-default wrtrans.update_byname("CPTRA_FUSE_VALID_PAUSER", 0, tid); @@ -217,7 +217,7 @@ task fuse_reg_pauser_test; tphase = "2b"; warm_reset_dut(); - reset_exp_data(); + warm_reset_exp_data(); sb.del_all(); simulate_caliptra_boot(); @@ -229,7 +229,7 @@ task fuse_reg_pauser_test; // $display("TB. DEBUG if status of cptra_noncore_rst_b_tb = 1'b%b", cptra_noncore_rst_b_tb); // end - read_reg_chk_inrange(GET_APB, "CPTRA_FUSE_PAUSER_LOCK", tid, '0, '0); + read_reg_chk_inrange(GET_APB, "CPTRA_FUSE_PAUSER_LOCK", tid, 'd1, 'd1); @(posedge clk_tb); diff --git a/src/soc_ifc/tb/soc_ifc_tb.sv b/src/soc_ifc/tb/soc_ifc_tb.sv index f78a9190c..808760bc7 100644 --- a/src/soc_ifc/tb/soc_ifc_tb.sv +++ b/src/soc_ifc/tb/soc_ifc_tb.sv @@ -70,9 +70,9 @@ module soc_ifc_tb parameter MBOX_DLEN_VAL = 32'h0000001C; - parameter MBOX_UDS_ADDR = 32'h3003_0200; - parameter MBOX_FE_ADDR = 32'h3003_0230; - parameter MBOX_FUSE_DONE_ADDR = 32'h3003_00ac; + parameter MBOX_UDS_ADDR = SOCIFC_BASE + `SOC_IFC_REG_FUSE_UDS_SEED_0; + parameter MBOX_FE_ADDR = SOCIFC_BASE + `SOC_IFC_REG_FUSE_FIELD_ENTROPY_0; + parameter MBOX_FUSE_DONE_ADDR = SOCIFC_BASE + `SOC_IFC_REG_CPTRA_FUSE_WR_DONE; parameter AHB_ADDR_WIDTH = `CALIPTRA_SLAVE_ADDR_WIDTH(`CALIPTRA_SLAVE_SEL_SOC_IFC); // 18 parameter AHB_DATA_WIDTH = `CALIPTRA_AHB_HDATA_SIZE; // 32 diff --git a/src/soc_ifc/tb/soc_ifc_tb_pkg.sv b/src/soc_ifc/tb/soc_ifc_tb_pkg.sv index 866528805..9150d838d 100644 --- a/src/soc_ifc/tb/soc_ifc_tb_pkg.sv +++ b/src/soc_ifc/tb/soc_ifc_tb_pkg.sv @@ -252,8 +252,8 @@ package soc_ifc_tb_pkg; // These address ranges (inclusive) in each extent have no definition extent_t _undefined_addr_ranges [$] = { - '{addr_min: SOCIFC_BASE + 16'h010c, addr_max: SOCIFC_BASE + 16'h01fc}, - '{addr_min: SOCIFC_BASE + 16'h0348, addr_max: SOCIFC_BASE + 16'h05fc}, + '{addr_min: SOCIFC_BASE + 16'h0128, addr_max: SOCIFC_BASE + 16'h01fc}, + '{addr_min: SOCIFC_BASE + 16'h034c, addr_max: SOCIFC_BASE + 16'h05fc}, '{addr_min: SOCIFC_BASE + 16'h0650, addr_max: SOCIFC_BASE + 16'h07fc}, '{addr_min: SOCIFC_BASE + 16'h0824, addr_max: SOCIFC_BASE + 16'h08fc}, '{addr_min: SOCIFC_BASE + 16'h0920, addr_max: SOCIFC_BASE + 16'h097c}, @@ -282,6 +282,8 @@ package soc_ifc_tb_pkg; "CPTRA_FW_EXTENDED_ERROR_INFO": 32'hffff_ffff, "CPTRA_RESET_REASON": 32'h2, // field WARM_RESET "CPTRA_FUSE_WR_DONE": 32'h1, // field 0 + "CPTRA_FUSE_VALID_PAUSER": 32'hffff_ffff, + "CPTRA_FUSE_PAUSER_LOCK": 32'h1, "CPTRA_TIMER_CONFIG": 32'hffff_ffff, "INTERNAL_RV_MTIME_L": 32'hffff_ffff, "INTERNAL_RV_MTIME_H": 32'hffff_ffff, @@ -310,10 +312,11 @@ package soc_ifc_tb_pkg; "FUSE_LIFE_CYCLE" : `SOC_IFC_REG_FUSE_LIFE_CYCLE_LIFE_CYCLE_MASK, "FUSE_LMS_VERIFY" : `SOC_IFC_REG_FUSE_LMS_VERIFY_LMS_VERIFY_MASK, "CPTRA_FLOW_STATUS" : (`SOC_IFC_REG_CPTRA_FLOW_STATUS_STATUS_MASK | - `SOC_IFC_REG_CPTRA_FLOW_STATUS_BOOT_FSM_PS_MASK | + `SOC_IFC_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_MASK | + //`SOC_IFC_REG_CPTRA_FLOW_STATUS_BOOT_FSM_PS_MASK | `SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FW_MASK | `SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_RUNTIME_MASK | - `SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_MASK | + //`SOC_IFC_REG_CPTRA_FLOW_STATUS_READY_FOR_FUSES_MASK | `SOC_IFC_REG_CPTRA_FLOW_STATUS_MAILBOX_FLOW_DONE_MASK), "CPTRA_MBOX_PAUSER_LOCK" : `SOC_IFC_REG_CPTRA_MBOX_PAUSER_LOCK_0_LOCK_MASK, // same for all 5 pausers "CPTRA_TRNG_PAUSER_LOCK" : `SOC_IFC_REG_CPTRA_TRNG_PAUSER_LOCK_LOCK_MASK, @@ -731,7 +734,8 @@ package soc_ifc_tb_pkg; exp_data = '0; // write-one to clear -- effectively always 0 end - "CPTRA_FLOW_STATUS" : exp_data = ahb_indata & get_mask(addr_name) | apb_rodata; // 32'hbfff_ffff; // apb-RO + "CPTRA_FLOW_STATUS" : exp_data = curr_data & ~get_mask(addr_name) | + ahb_indata & get_mask(addr_name) | apb_rodata; // 32'hb1ff_ffff; // apb-RO "CPTRA_RESET_REASON" : exp_data = ahb_rodata | apb_rodata; // bit 1:0 is RO "CPTRA_SECURITY_STATE" : exp_data = curr_data & get_mask(addr_name); // & sscode; // bit 3:0 is RO diff --git a/src/soc_ifc/uvmf_soc_ifc/config/compile.yml b/src/soc_ifc/uvmf_soc_ifc/config/compile.yml index 02b0c1f87..1f9cf8295 100644 --- a/src/soc_ifc/uvmf_soc_ifc/config/compile.yml +++ b/src/soc_ifc/uvmf_soc_ifc/config/compile.yml @@ -16,6 +16,8 @@ targets: - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers files: @@ -39,6 +41,11 @@ targets: - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv + - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv - ${COMPILE_ROOT}/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv --- diff --git a/src/soc_ifc/uvmf_soc_ifc/mbox_sram_interface.yaml b/src/soc_ifc/uvmf_soc_ifc/mbox_sram_interface.yaml new file mode 100644 index 000000000..52470e489 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/mbox_sram_interface.yaml @@ -0,0 +1,67 @@ +uvmf: + interfaces: + mbox_sram: + clock: clk + reset: dummy + reset_assertion_level: 'False' + + config_constraints: [] + config_vars: + - name: "inject_ecc_error" + type: "bit [1:0]" + isrand: "False" + value: "2'b00" + comment: "Controls injection of ECC errors for write transactions. Bit[0]: Single Bit Error. Bit[1]: Double Bit Error" + - name: "auto_clear_ecc_error_injection" + type: "bit" + isrand: "False" + value: "1'b1" + comment: "When set, causes the mbox_sram_responder_sequence to clear the variable 'inject_ecc_error' after a single ECC error is injected" + + hdl_typedefs: [] + hvl_typedefs: [] + + # NOTE: This agent will be in RESPONDER mode, which inverts + # all port's polarities + ports: + - name: mbox_sram_req + dir: output + width: '$bits(mbox_sram_req_t)' + # cs (1) + we (1) + addr (15) + data (32) + ecc (7) = 56 + - name: mbox_sram_resp + dir: input + width: '$bits(mbox_sram_resp_t)' + # data (32) + ecc (7) = 39 + + transaction_constraints: [] +# - name: wait_cycles_c +# value: '{ wait_cycles dist {[1:25] := 80, [25:100] := 15, [100:500] := 5}; }' + + transaction_vars: + - name: is_read + type: bit + iscompare: 'True' + isrand: 'True' + - name: address + type: bit [MBOX_ADDR_W-1:0] + iscompare: 'True' + isrand: 'True' + - name: data + type: bit [MBOX_DATA_W-1:0] + iscompare: 'True' + isrand: 'True' + # ECC would be generated based on data, post_randomize, in the case where + # this transaction is generated as stimulus. + # We mostly expect to use this i/f as an observer though. + - name: data_ecc + type: bit [MBOX_ECC_DATA_W-1:0] + iscompare: 'True' + isrand: 'False' + - name: ecc_single_bit_error + type: bit + iscompare: 'True' + isrand: 'True' + - name: ecc_double_bit_error + type: bit + iscompare: 'True' + isrand: 'True' diff --git a/src/soc_ifc/uvmf_soc_ifc/run_yaml_uvmf_scripts.sh b/src/soc_ifc/uvmf_soc_ifc/run_yaml_uvmf_scripts.sh index 80497eeda..f0597c4d7 100755 --- a/src/soc_ifc/uvmf_soc_ifc/run_yaml_uvmf_scripts.sh +++ b/src/soc_ifc/uvmf_soc_ifc/run_yaml_uvmf_scripts.sh @@ -4,6 +4,7 @@ python ${UVMF_HOME}/scripts/yaml2uvmf.py --merge_source uvmf_template_output \ soc_ifc_global.yaml \ soc_ifc_ctrl_interface.yaml \ soc_ifc_status_interface.yaml \ + mbox_sram_interface.yaml \ soc_ifc_util_comp_soc_ifc_predictor.yaml \ soc_ifc_util_comp_soc_ifc_scoreboard.yaml \ ../../libs/uvmf/qvip_ahb_lite_slave_dir/uvmf/qvip_ahb_lite_slave_subenv_config.yaml \ diff --git a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_bench.yaml b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_bench.yaml index 5b35bf45d..a5b3fbc4c 100755 --- a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_bench.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_bench.yaml @@ -18,6 +18,8 @@ uvmf: value: ACTIVE - bfm_name: cptra_status_agent value: ACTIVE + - bfm_name: mbox_sram_agent + value: ACTIVE clock_half_period: 5ns clock_phase_offset: 0ns diff --git a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_environment.yaml b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_environment.yaml index ca462f3c2..468989270 100755 --- a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_environment.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_environment.yaml @@ -17,6 +17,9 @@ uvmf: - name: cptra_status_agent type: cptra_status initiator_responder: "RESPONDER" + - name: mbox_sram_agent + type: mbox_sram + initiator_responder: "RESPONDER" analysis_components: - name: soc_ifc_pred @@ -66,6 +69,8 @@ uvmf: receiver: soc_ifc_pred.soc_ifc_ctrl_agent_ae # - driver: cptra_ctrl_agent.monitored_ap # Caliptra Control receiver: soc_ifc_pred.cptra_ctrl_agent_ae # + - driver: mbox_sram_agent.monitored_ap # Mailbox SRAM i/f + receiver: soc_ifc_pred.mbox_sram_agent_ae # # - driver: qvip_ahb_lite_master_subenv.ahb_master_0.export_rw # AHB # receiver: soc_ifc_pred.ahb_master_0_ae # # - driver: qvip_apb5_master_subenv.apb5_master_0.export_rw # APB diff --git a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_status_interface.yaml b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_status_interface.yaml index 0a364677b..6f69cbd21 100755 --- a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_status_interface.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_status_interface.yaml @@ -122,6 +122,9 @@ uvmf: - name: cptra_uc_rst_b dir: output width: '1' + - name: fw_update_rst_window + dir: output + width: '1' #Obfuscated UDS and FE - name: cptra_obf_key_reg @@ -197,6 +200,10 @@ uvmf: type: bit iscompare: 'True' isrand: 'False' + - name: fw_update_rst_window + type: bit + iscompare: 'True' + isrand: 'False' #Obfuscated UDS and FE - name: cptra_obf_key_reg diff --git a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_util_comp_soc_ifc_predictor.yaml b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_util_comp_soc_ifc_predictor.yaml index 692d4f915..8d8ce87cb 100755 --- a/src/soc_ifc/uvmf_soc_ifc/soc_ifc_util_comp_soc_ifc_predictor.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/soc_ifc_util_comp_soc_ifc_predictor.yaml @@ -7,6 +7,8 @@ uvmf: type: 'soc_ifc_ctrl_transaction' - name: cptra_ctrl_agent_ae type: 'cptra_ctrl_transaction' + - name: mbox_sram_agent_ae + type: 'mbox_sram_transaction' - name: ahb_slave_0_ae type: 'mvc_sequence_item_base' # type: 'ahb_master_burst_transfer #(ahb_lite_slave_0_params::AHB_NUM_MASTERS, diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/docs/interfaces.csv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/docs/interfaces.csv index dd76c8f8e..e411f7a9a 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/docs/interfaces.csv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/docs/interfaces.csv @@ -27,4 +27,5 @@ soc_ifc_ctrl_agent, soc_ifc_ctrl_driver_bfm soc_ifc_ctrl_monitor_bfm, soc_ifc_ct cptra_ctrl_agent, cptra_ctrl_driver_bfm cptra_ctrl_monitor_bfm, cptra_ctrl_transaction, cptra_ctrl_pkg_cptra_ctrl_agent_BFM, soc_ifc_status_agent, soc_ifc_status_driver_bfm soc_ifc_status_monitor_bfm, soc_ifc_status_transaction, soc_ifc_status_pkg_soc_ifc_status_agent_BFM, cptra_status_agent, cptra_status_driver_bfm cptra_status_monitor_bfm, cptra_status_transaction, cptra_status_pkg_cptra_status_agent_BFM, +mbox_sram_agent, mbox_sram_driver_bfm mbox_sram_monitor_bfm, mbox_sram_transaction, mbox_sram_pkg_mbox_sram_agent_BFM, diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/Makefile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/Makefile index 1b5fcb327..6c3120c72 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/Makefile +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/Makefile @@ -87,6 +87,7 @@ include $(UVMF_VIP_LIBRARY_HOME)/interface_packages/soc_ifc_ctrl_pkg/Makefile include $(UVMF_VIP_LIBRARY_HOME)/interface_packages/cptra_ctrl_pkg/Makefile include $(UVMF_VIP_LIBRARY_HOME)/interface_packages/soc_ifc_status_pkg/Makefile include $(UVMF_VIP_LIBRARY_HOME)/interface_packages/cptra_status_pkg/Makefile +include $(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/Makefile # Include all requisite environment package targets for this bench include $(UVMF_VIP_LIBRARY_HOME)/environment_packages/soc_ifc_env_pkg/Makefile @@ -196,7 +197,7 @@ comp_hvl : comp_hvl_core comp_hvl_core : comp_qvip comp_qvip_utils_pkg \ - comp_soc_ifc_ctrl_pkg comp_cptra_ctrl_pkg comp_soc_ifc_status_pkg comp_cptra_status_pkg \ + comp_soc_ifc_ctrl_pkg comp_cptra_ctrl_pkg comp_soc_ifc_status_pkg comp_cptra_status_pkg comp_mbox_sram_pkg \ comp_soc_ifc_env_pkg \ comp_soc_ifc_parameters_pkg comp_soc_ifc_sequence_pkg comp_soc_ifc_tests_pkg @@ -204,7 +205,7 @@ comp_uvmf_core : comp_uvm_pkg comp_uvmf_base_pkg make_build: comp_soc_ifc_dut comp_uvmf_core comp_hvl comp_test_bench -hvl_build: q_comp_soc_ifc_ctrl_pkg q_comp_cptra_ctrl_pkg q_comp_soc_ifc_status_pkg q_comp_cptra_status_pkg comp_soc_ifc_env_pkg comp_soc_ifc_sequence_pkg comp_soc_ifc_tests_pkg hvl_comp_testbench link optimize +hvl_build: q_comp_soc_ifc_ctrl_pkg q_comp_cptra_ctrl_pkg q_comp_soc_ifc_status_pkg q_comp_cptra_status_pkg q_comp_mbox_sram_pkg comp_soc_ifc_env_pkg comp_soc_ifc_sequence_pkg comp_soc_ifc_tests_pkg hvl_comp_testbench link optimize vinfo_build: comp_qvip comp_soc_ifc_vhdl_dut build_hdl_vinfo build_hvl_vinfo $(VINFO_TGT) diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/compile.do b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/compile.do index ea7be28a2..f45e56a43 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/compile.do +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/compile.do @@ -58,6 +58,7 @@ do $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/soc_ifc_ctrl_pkg/compile.do do $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/cptra_ctrl_pkg/compile.do do $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/soc_ifc_status_pkg/compile.do do $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/cptra_status_pkg/compile.do +do $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/compile.do ################################################################### ## UVMF ENVIRONMENT COMPILATION diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/viswave.do b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/viswave.do index 7fb0d70b7..58934106e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/viswave.do +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/viswave.do @@ -28,6 +28,12 @@ wave group cptra_status_agent_bus wave add -group cptra_status_agent_bus hdl_top.cptra_status_agent_bus.* -radix hexadecimal -tag F0 wave group cptra_status_agent_bus -collapse wave insertion [expr [wave index insertpoint] +1] +wave spacer -backgroundcolor Salmon { mbox_sram_agent } +wave add uvm_test_top.environment.mbox_sram_agent.mbox_sram_agent_monitor.txn_stream -radix string -tag F0 +wave group mbox_sram_agent_bus +wave add -group mbox_sram_agent_bus hdl_top.mbox_sram_agent_bus.* -radix hexadecimal -tag F0 +wave group mbox_sram_agent_bus -collapse +wave insertion [expr [wave index insertpoint] +1] wave update on WaveSetStreamView diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/wave.do b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/wave.do index 7e0fc1e33..1ba8a1615 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/wave.do +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/sim/wave.do @@ -15,6 +15,9 @@ add wave -noupdate -group soc_ifc_status_agent_bus /hdl_top/soc_ifc_status_agent add wave -noupdate -divider cptra_status_agent add wave -noupdate /uvm_root/uvm_test_top/environment/cptra_status_agent/cptra_status_agent_monitor/txn_stream add wave -noupdate -group cptra_status_agent_bus /hdl_top/cptra_status_agent_bus/* +add wave -noupdate -divider mbox_sram_agent +add wave -noupdate /uvm_root/uvm_test_top/environment/mbox_sram_agent/mbox_sram_agent_monitor/txn_stream +add wave -noupdate -group mbox_sram_agent_bus /hdl_top/mbox_sram_agent_bus/* TreeUpdate [SetDefaultTree] quietly wave cursor active 0 diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/soc_ifc_sve.F b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/soc_ifc_sve.F index c88496249..2114f41e2 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/soc_ifc_sve.F +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/soc_ifc_sve.F @@ -12,6 +12,7 @@ -F ${UVMF_VIP_LIBRARY_HOME}/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg_sve.F -F ${UVMF_VIP_LIBRARY_HOME}/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg_sve.F -F ${UVMF_VIP_LIBRARY_HOME}/interface_packages/cptra_status_pkg/cptra_status_pkg_sve.F +-F ${UVMF_VIP_LIBRARY_HOME}/interface_packages/mbox_sram_pkg/mbox_sram_pkg_sve.F // Environment Files -F ${UVMF_VIP_LIBRARY_HOME}/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg_sve.F diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters/soc_ifc_parameters_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters/soc_ifc_parameters_pkg.sv index d6e073e1e..af3cb9a50 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters/soc_ifc_parameters_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/parameters/soc_ifc_parameters_pkg.sv @@ -45,6 +45,7 @@ package soc_ifc_parameters_pkg; parameter string cptra_ctrl_agent_BFM = "cptra_ctrl_agent_BFM"; /* [3] */ parameter string soc_ifc_status_agent_BFM = "soc_ifc_status_agent_BFM"; /* [4] */ parameter string cptra_status_agent_BFM = "cptra_status_agent_BFM"; /* [5] */ + parameter string mbox_sram_agent_BFM = "mbox_sram_agent_BFM"; /* [6] */ // pragma uvmf custom package_item_additional begin // pragma uvmf custom package_item_additional end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.compile index 1243f5665..943dc7955 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.compile +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.compile @@ -4,6 +4,7 @@ needs: - ../../../../verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl.compile - ../../../../verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status.compile - ../../../../verification_ip/interface_packages/cptra_status_pkg/cptra_status.compile + - ../../../../verification_ip/interface_packages/mbox_sram_pkg/mbox_sram.compile - ../../../../verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile - ../parameters/soc_ifc_parameters_pkg.compile src: diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.sv index f109f898e..2c25d7490 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.sv @@ -47,6 +47,8 @@ package soc_ifc_sequences_pkg; import soc_ifc_status_pkg_hdl::*; import cptra_status_pkg::*; import cptra_status_pkg_hdl::*; + import mbox_sram_pkg::*; + import mbox_sram_pkg_hdl::*; import soc_ifc_parameters_pkg::*; import soc_ifc_env_pkg::*; import qvip_ahb_lite_slave_params_pkg::*; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.vinfo index fea3885f7..035e660ea 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.vinfo +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/soc_ifc_sequences_pkg.vinfo @@ -3,6 +3,7 @@ @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_status_pkg/cptra_status_pkg.vinfo +@use $UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo @use $UVMF_PROJECT_DIR/tb/parameters/soc_ifc_parameters_pkg.vinfo +incdir+@vinfodir diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/register_test_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/register_test_sequence.svh index 09993ee2a..85a802e5d 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/register_test_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/register_test_sequence.svh @@ -55,6 +55,7 @@ class register_test_sequence extends soc_ifc_bench_sequence_base; cptra_ctrl_agent_config.wait_for_reset(); soc_ifc_status_agent_config.wait_for_reset(); cptra_status_agent_config.wait_for_reset(); + mbox_sram_agent_config.wait_for_reset(); // pragma uvmf custom register_test_reset end join diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_bench_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_bench_sequence_base.svh index d3465bf39..3dfaeaac9 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_bench_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_bench_sequence_base.svh @@ -56,6 +56,8 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; soc_ifc_status_agent_responder_seq_t soc_ifc_status_agent_responder_seq; typedef cptra_status_responder_sequence cptra_status_agent_responder_seq_t; cptra_status_agent_responder_seq_t cptra_status_agent_responder_seq; + typedef mbox_sram_responder_sequence mbox_sram_agent_responder_seq_t; + mbox_sram_agent_responder_seq_t mbox_sram_agent_responder_seq; // pragma uvmf custom sequences end // Sequencer handles for each active interface in the environment @@ -67,6 +69,8 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; uvm_sequencer #(soc_ifc_status_agent_transaction_t) soc_ifc_status_agent_sequencer; typedef cptra_status_transaction cptra_status_agent_transaction_t; uvm_sequencer #(cptra_status_agent_transaction_t) cptra_status_agent_sequencer; + typedef mbox_sram_transaction mbox_sram_agent_transaction_t; + uvm_sequencer #(mbox_sram_agent_transaction_t) mbox_sram_agent_sequencer; // Sequencer handles for each QVIP interface mvc_sequencer uvm_test_top_environment_qvip_ahb_lite_slave_subenv_ahb_lite_slave_0_sqr; @@ -80,6 +84,7 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; cptra_ctrl_configuration cptra_ctrl_agent_config; soc_ifc_status_configuration soc_ifc_status_agent_config; cptra_status_configuration cptra_status_agent_config; + mbox_sram_configuration mbox_sram_agent_config; // Local handle to register model for convenience soc_ifc_reg_model_top reg_model; uvm_status_e status; @@ -107,12 +112,15 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; `uvm_fatal("CFG" , "uvm_config_db #( soc_ifc_status_configuration )::get cannot find resource soc_ifc_status_agent_BFM" ) if( !uvm_config_db #( cptra_status_configuration )::get( null , UVMF_CONFIGURATIONS , cptra_status_agent_BFM , cptra_status_agent_config ) ) `uvm_fatal("CFG" , "uvm_config_db #( cptra_status_configuration )::get cannot find resource cptra_status_agent_BFM" ) + if( !uvm_config_db #( mbox_sram_configuration )::get( null , UVMF_CONFIGURATIONS , mbox_sram_agent_BFM , mbox_sram_agent_config ) ) + `uvm_fatal("CFG" , "uvm_config_db #( mbox_sram_configuration )::get cannot find resource mbox_sram_agent_BFM" ) // Assign the sequencer handles from the handles within agent configurations soc_ifc_ctrl_agent_sequencer = soc_ifc_ctrl_agent_config.get_sequencer(); cptra_ctrl_agent_sequencer = cptra_ctrl_agent_config.get_sequencer(); soc_ifc_status_agent_sequencer = soc_ifc_status_agent_config.get_sequencer(); cptra_status_agent_sequencer = cptra_status_agent_config.get_sequencer(); + mbox_sram_agent_sequencer = mbox_sram_agent_config.get_sequencer(); // Retrieve QVIP sequencer handles from the uvm_config_db if( !uvm_config_db #(mvc_sequencer)::get( null,UVMF_SEQUENCERS,"uvm_test_top.environment.qvip_ahb_lite_slave_subenv.ahb_lite_slave_0", uvm_test_top_environment_qvip_ahb_lite_slave_subenv_ahb_lite_slave_0_sqr) ) @@ -139,17 +147,20 @@ rand soc_ifc_env_sequence_base_t soc_ifc_env_seq; cptra_ctrl_agent_random_seq = cptra_ctrl_agent_random_seq_t::type_id::create("cptra_ctrl_agent_random_seq"); soc_ifc_status_agent_responder_seq = soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_status_agent_responder_seq"); cptra_status_agent_responder_seq = cptra_status_agent_responder_seq_t::type_id::create("cptra_status_agent_responder_seq"); + mbox_sram_agent_responder_seq = mbox_sram_agent_responder_seq_t::type_id::create("mbox_sram_agent_responder_seq"); fork soc_ifc_ctrl_agent_config.wait_for_reset(); cptra_ctrl_agent_config.wait_for_reset(); soc_ifc_status_agent_config.wait_for_reset(); cptra_status_agent_config.wait_for_reset(); + mbox_sram_agent_config.wait_for_reset(); join reg_model.reset(); // Start RESPONDER sequences here fork soc_ifc_status_agent_responder_seq.start(soc_ifc_status_agent_sequencer); cptra_status_agent_responder_seq.start(cptra_status_agent_sequencer); + mbox_sram_agent_responder_seq.start(mbox_sram_agent_sequencer); join_none // Start INITIATOR sequences here fork @@ -167,6 +178,7 @@ soc_ifc_env_seq.start(top_configuration.vsqr); cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_status_agent_config.wait_for_num_clocks(400); cptra_status_agent_config.wait_for_num_clocks(400); + mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_cmdline_test_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_cmdline_test_sequence.svh index 2d04e5be8..75c9e8608 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_cmdline_test_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_cmdline_test_sequence.svh @@ -36,6 +36,7 @@ class soc_ifc_cmdline_test_sequence extends soc_ifc_bench_sequence_base; rand soc_ifc_env_bringup_sequence_t soc_ifc_env_bringup_seq; rand soc_ifc_env_cptra_rst_wait_sequence_t soc_ifc_env_cptra_rst_wait_seq; + rand soc_ifc_env_cptra_init_interrupts_sequence_t soc_ifc_env_cptra_init_interrupts_seq; function new(string name = "" ); super.new(name); @@ -53,20 +54,25 @@ class soc_ifc_cmdline_test_sequence extends soc_ifc_bench_sequence_base; soc_ifc_env_bringup_seq = soc_ifc_env_bringup_sequence_t::type_id::create("soc_ifc_env_bringup_seq"); soc_ifc_env_cptra_rst_wait_seq = soc_ifc_env_cptra_rst_wait_sequence_t::type_id::create("soc_ifc_env_cptra_rst_wait_seq"); + soc_ifc_env_cptra_init_interrupts_seq = soc_ifc_env_cptra_init_interrupts_sequence_t::type_id::create("soc_ifc_env_cptra_init_interrupts_seq"); + soc_ifc_ctrl_agent_random_seq = soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_ctrl_agent_random_seq"); cptra_ctrl_agent_random_seq = cptra_ctrl_agent_random_seq_t::type_id::create("cptra_ctrl_agent_random_seq"); soc_ifc_status_agent_responder_seq = soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_status_agent_responder_seq"); cptra_status_agent_responder_seq = cptra_status_agent_responder_seq_t::type_id::create("cptra_status_agent_responder_seq"); + mbox_sram_agent_responder_seq = mbox_sram_agent_responder_seq_t::type_id::create("mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_status_agent_responder_seq; soc_ifc_env_cptra_rst_wait_seq.cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; + soc_ifc_env_cptra_init_interrupts_seq.cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; reg_model.reset(); // Start RESPONDER sequences here fork soc_ifc_status_agent_responder_seq.start(soc_ifc_status_agent_sequencer); cptra_status_agent_responder_seq.start(cptra_status_agent_sequencer); + mbox_sram_agent_responder_seq.start(mbox_sram_agent_sequencer); join_none // Start INITIATOR sequences here @@ -84,6 +90,12 @@ class soc_ifc_cmdline_test_sequence extends soc_ifc_bench_sequence_base; end join + // Always initialize interrupts + // TODO - if we make this random, we can test both interrupt-driven and + // polling behavior + soc_ifc_env_cptra_init_interrupts_seq.start(top_configuration.vsqr); + `uvm_info("SOC_IFC_CMDLINE_TEST", "Completed interrupt init", UVM_MEDIUM) + // Run cmdline provided env sequences clp = uvm_cmdline_processor::get_inst(); if (!clp.get_arg_values("+CLP_SEQ=", seq_names)) @@ -115,6 +127,7 @@ class soc_ifc_cmdline_test_sequence extends soc_ifc_bench_sequence_base; cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_status_agent_config.wait_for_num_clocks(400); cptra_status_agent_config.wait_for_num_clocks(400); + mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_rand_test_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_rand_test_sequence.svh index ebe212e74..d2ef25610 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_rand_test_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_rand_test_sequence.svh @@ -34,6 +34,7 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; rand soc_ifc_env_bringup_sequence_t soc_ifc_env_bringup_seq; rand soc_ifc_env_cptra_rst_wait_sequence_t soc_ifc_env_cptra_rst_wait_seq; + rand soc_ifc_env_cptra_init_interrupts_sequence_t soc_ifc_env_cptra_init_interrupts_seq; rand soc_ifc_env_pauser_init_sequence_t soc_ifc_env_pauser_init_seq; rand soc_ifc_env_sequence_base_t soc_ifc_env_seq_ii[]; // TODO: To add new sequences to the randomized portion of this test: @@ -43,20 +44,29 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; rand enum int { IDX_SOC_IFC_ENV_MBOX_TOP_RAND_SMALL, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE, IDX_SOC_IFC_ENV_MBOX_TOP_MIN, IDX_SOC_IFC_ENV_MBOX_TOP_MAX, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_SMALL_UNLOCK, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM_UNLOCK, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE_UNLOCK, IDX_SOC_IFC_ENV_MBOX_TOP_CONTENTION, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL_UNLOCK, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM_UNLOCK, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE_UNLOCK, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_SMALL, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_LARGE, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_SMALL, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_LARGE, IDX_SOC_IFC_ENV_MBOX_TOP_DLEN_VIOLATION, IDX_SOC_IFC_ENV_MBOX_TOP_MULTI_AGENT, IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_RAND_SMALL, + IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_REG_AXS_INV_SMALL, IDX_SOC_IFC_ENV_RST_WARM, IDX_SOC_IFC_ENV_RST_COLD, IDX_SOC_IFC_ENV_MBOX_RST_WARM_RAND_MEDIUM, @@ -69,39 +79,74 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; constraint avail_env_seqs_c { rand_seq_idx dist { IDX_SOC_IFC_ENV_MBOX_TOP_RAND_SMALL := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE := 1, IDX_SOC_IFC_ENV_MBOX_TOP_MIN := 25, IDX_SOC_IFC_ENV_MBOX_TOP_MAX := 1, - IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_SMALL_UNLOCK := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM_UNLOCK := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE_UNLOCK := 1, IDX_SOC_IFC_ENV_MBOX_TOP_CONTENTION := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE := 1, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL_UNLOCK := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM_UNLOCK := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE_UNLOCK := 1, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_SMALL := 25, IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_MEDIUM := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_LARGE := 1, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_SMALL := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_MEDIUM := 25, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_LARGE := 1, IDX_SOC_IFC_ENV_MBOX_TOP_DLEN_VIOLATION := 25, IDX_SOC_IFC_ENV_MBOX_TOP_MULTI_AGENT := 10, IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_RAND_SMALL := 25, + IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_REG_AXS_INV_SMALL := 25, IDX_SOC_IFC_ENV_RST_WARM := 1, IDX_SOC_IFC_ENV_RST_COLD := 1, IDX_SOC_IFC_ENV_MBOX_RST_WARM_RAND_MEDIUM := 10, IDX_SOC_IFC_ENV_MBOX_RST_COLD_RAND_MEDIUM := 10 }; } + constraint disable_long_env_seqs_c { + !(rand_seq_idx inside {IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE, + IDX_SOC_IFC_ENV_MBOX_TOP_MAX, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE_UNLOCK, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE_UNLOCK, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_LARGE, + IDX_SOC_IFC_ENV_MBOX_TOP_DLEN_VIOLATION, + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_LARGE, + IDX_SOC_IFC_ENV_MBOX_TOP_MULTI_AGENT}); + } // FIXME we're also running multiple iterations of this testcase in the regression. // What is the criteria for iteration count WITHIN the sequence? constraint iter_count_c { iteration_count inside {[1:10]}; } + constraint iter_count_short_c { + iteration_count < 5; + } function new(string name = "" ); super.new(name); + // The short test suite is used in promote pipeline to quickly check for UVM issues + if ($test$plusargs("CLP_SHORT_SUITE")) begin + this.disable_long_env_seqs_c.constraint_mode(1); + this.iter_count_short_c.constraint_mode(1); + end + else begin + this.disable_long_env_seqs_c.constraint_mode(0); + this.iter_count_short_c.constraint_mode(0); + end + // Users can manually override the number of random iterations to any desired value if ($value$plusargs("SOC_IFC_RAND_ITER=%0d", iteration_count)) begin `uvm_info("SOC_IFC_RAND_TEST", $sformatf("Received Command Line Iteration Count Argument of %0d", iteration_count), UVM_LOW); iteration_count.rand_mode(0); this.iter_count_c.constraint_mode(0); + this.iter_count_short_c.constraint_mode(0); end else begin if (!this.randomize(iteration_count)) @@ -119,20 +164,25 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; uvm_object obj; int ii; bit do_pauser_init; + int unsigned mbox_ecc_single_error_burst; + int unsigned mbox_ecc_single_error_delay_clocks; soc_ifc_env_bringup_seq = soc_ifc_env_bringup_sequence_t::type_id::create("soc_ifc_env_bringup_seq"); soc_ifc_env_cptra_rst_wait_seq = soc_ifc_env_cptra_rst_wait_sequence_t::type_id::create("soc_ifc_env_cptra_rst_wait_seq"); - soc_ifc_env_pauser_init_seq = soc_ifc_env_pauser_init_sequence_t::type_id::create("soc_ifc_env_pauser_init_seq"); + soc_ifc_env_cptra_init_interrupts_seq = soc_ifc_env_cptra_init_interrupts_sequence_t::type_id::create("soc_ifc_env_cptra_init_interrupts_seq"); + soc_ifc_env_pauser_init_seq = soc_ifc_env_pauser_init_sequence_t::type_id::create("soc_ifc_env_pauser_init_seq"); soc_ifc_ctrl_agent_random_seq = soc_ifc_ctrl_agent_random_seq_t::type_id::create("soc_ifc_ctrl_agent_random_seq"); cptra_ctrl_agent_random_seq = cptra_ctrl_agent_random_seq_t::type_id::create("cptra_ctrl_agent_random_seq"); soc_ifc_status_agent_responder_seq = soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_status_agent_responder_seq"); cptra_status_agent_responder_seq = cptra_status_agent_responder_seq_t::type_id::create("cptra_status_agent_responder_seq"); + mbox_sram_agent_responder_seq = mbox_sram_agent_responder_seq_t::type_id::create("mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_status_agent_responder_seq; soc_ifc_env_cptra_rst_wait_seq.cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; + soc_ifc_env_cptra_init_interrupts_seq.cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; soc_ifc_env_pauser_init_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_status_agent_responder_seq; // fork @@ -146,9 +196,25 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; fork soc_ifc_status_agent_responder_seq.start(soc_ifc_status_agent_sequencer); cptra_status_agent_responder_seq.start(cptra_status_agent_sequencer); + mbox_sram_agent_responder_seq.start(mbox_sram_agent_sequencer); join_none // Start INITIATOR sequences here + fork + forever begin + if (!std::randomize(mbox_ecc_single_error_burst,mbox_ecc_single_error_delay_clocks) with {mbox_ecc_single_error_burst dist {1 :/ 1000, [2:5] :/ 100, [6:31] :/ 20, [32:131071] :/ 1, [131072:524288] :/ 1}; + mbox_ecc_single_error_delay_clocks dist {1 :/ 1, [2:31] :/ 3, [32:127] :/ 5, [128:1023] :/ 3, [1024:131072] :/ 1}; }) + `uvm_fatal("SOC_IFC_RAND_TEST", "Failed to randomize mbox ecc bit flip injection parameters") + else + `uvm_info("SOC_IFC_RAND_TEST", $sformatf("Randomized mbox ecc bit flip injection parameters: burst [%0d] delay [%0d clocks]", mbox_ecc_single_error_burst, mbox_ecc_single_error_delay_clocks), UVM_DEBUG) + soc_ifc_ctrl_agent_config.wait_for_num_clocks(mbox_ecc_single_error_delay_clocks); + `uvm_info("SOC_IFC_RAND_TEST", $sformatf("Injecting mbox ecc error with burst [%0d]", mbox_ecc_single_error_burst), UVM_DEBUG) + repeat(mbox_ecc_single_error_burst) begin + mbox_sram_agent_config.inject_ecc_error |= 2'b01; + @mbox_sram_agent_responder_seq.new_rsp; + end + end + join_none fork begin // Bringup (set pwrgood, deassert cptra_rst_b, write fuses) @@ -163,17 +229,26 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; end join - // Choose whether or not to initialize/lock PAUSER valid values at random - if (!std::randomize(do_pauser_init) with { do_pauser_init dist {0:/25, 1:/75}; }) - `uvm_error("SOC_IFC_RAND_TEST", "Failed to randomize do_pauser_init") - else if (do_pauser_init) begin - if(!soc_ifc_env_pauser_init_seq.randomize()) - `uvm_fatal("SOC_IFC_RAND_TEST", "soc_ifc_rand_test_sequence::body() - soc_ifc_env_pauser_init_seq randomization failed"); - soc_ifc_env_pauser_init_seq.start(top_configuration.vsqr); - end - else begin - `uvm_info("SOC_IFC_RAND_TEST", "Skipping PAUSER init", UVM_MEDIUM) - end + fork + // Choose whether or not to initialize/lock PAUSER valid values at random + if (!std::randomize(do_pauser_init) with { do_pauser_init dist {0:/25, 1:/75}; }) + `uvm_error("SOC_IFC_RAND_TEST", "Failed to randomize do_pauser_init") + else if (do_pauser_init) begin + if(!soc_ifc_env_pauser_init_seq.randomize()) + `uvm_fatal("SOC_IFC_RAND_TEST", "soc_ifc_rand_test_sequence::body() - soc_ifc_env_pauser_init_seq randomization failed"); + soc_ifc_env_pauser_init_seq.start(top_configuration.vsqr); + end + else begin + `uvm_info("SOC_IFC_RAND_TEST", "Skipping PAUSER init", UVM_MEDIUM) + end + // Always initialize interrupts + // TODO - if we make this random, we can test both interrupt-driven and + // polling behavior + begin + soc_ifc_env_cptra_init_interrupts_seq.start(top_configuration.vsqr); + `uvm_info("SOC_IFC_RAND_TEST", "Completed interrupt init", UVM_MEDIUM) + end + join for (ii = 0; ii < iteration_count; ii++) begin: RAND_LOOP if(!this.randomize(rand_seq_idx)) `uvm_fatal("SOC_IFC_RAND_TEST", "Failed to randomize rand_seq_idx"); @@ -184,6 +259,8 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; obj = soc_ifc_env_top_mbox_rand_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM: obj = soc_ifc_env_top_mbox_rand_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE: + obj = soc_ifc_env_top_mbox_rand_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_MIN: obj = soc_ifc_env_top_mbox_min_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_MAX: @@ -192,26 +269,42 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; obj = soc_ifc_env_top_mbox_rand_small_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_MEDIUM_UNLOCK: obj = soc_ifc_env_top_mbox_rand_medium_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_LARGE_UNLOCK: + obj = soc_ifc_env_top_mbox_rand_large_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_CONTENTION: obj = soc_ifc_env_top_mbox_contention_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL: obj = soc_ifc_env_top_mbox_rand_pauser_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM: obj = soc_ifc_env_top_mbox_rand_pauser_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE: + obj = soc_ifc_env_top_mbox_rand_pauser_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_SMALL_UNLOCK: obj = soc_ifc_env_top_mbox_rand_pauser_small_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_MEDIUM_UNLOCK: obj = soc_ifc_env_top_mbox_rand_pauser_medium_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_PAUSER_LARGE_UNLOCK: + obj = soc_ifc_env_top_mbox_rand_pauser_large_unlock_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_SMALL: obj = soc_ifc_env_top_mbox_rand_delay_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_MEDIUM: obj = soc_ifc_env_top_mbox_rand_delay_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_RAND_DELAY_LARGE: + obj = soc_ifc_env_top_mbox_rand_delay_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_SMALL: + obj = soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_MEDIUM: + obj = soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_MBOX_TOP_REG_AXS_INV_LARGE: + obj = soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_DLEN_VIOLATION: obj = soc_ifc_env_top_mbox_dlen_violation_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_MBOX_TOP_MULTI_AGENT: obj = soc_ifc_env_top_mbox_multi_agent_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_RAND_SMALL: obj = soc_ifc_env_top_cptra_mbox_rand_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); + IDX_SOC_IFC_ENV_CPTRA_MBOX_TOP_REG_AXS_INV_SMALL: + obj = soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_RST_WARM: obj = soc_ifc_env_top_reset_warm_sequence_t::get_type().create_object($sformatf("soc_ifc_env_seq_ii[%0d]",ii)); IDX_SOC_IFC_ENV_RST_COLD: @@ -233,6 +326,20 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; soc_ifc_env_seq_ii[ii].soc_ifc_status_agent_rsp_seq = soc_ifc_status_agent_responder_seq; soc_ifc_env_seq_ii[ii].cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; soc_ifc_env_seq_ii[ii].start(top_configuration.vsqr); + + // If the last run sequence triggered a reset, rerun interrupt initialization + case (rand_seq_idx) inside + IDX_SOC_IFC_ENV_RST_WARM, + IDX_SOC_IFC_ENV_RST_COLD, + IDX_SOC_IFC_ENV_MBOX_RST_WARM_RAND_MEDIUM, + IDX_SOC_IFC_ENV_MBOX_RST_COLD_RAND_MEDIUM: begin + `uvm_info("SOC_IFC_RAND_TEST", "Rerunning interrupt init after reset", UVM_MEDIUM) + soc_ifc_env_cptra_init_interrupts_seq = soc_ifc_env_cptra_init_interrupts_sequence_t::type_id::create($sformatf("soc_ifc_env_cptra_init_interrupts_seq[%0d]",ii)); + soc_ifc_env_cptra_init_interrupts_seq.cptra_status_agent_rsp_seq = cptra_status_agent_responder_seq; + soc_ifc_env_cptra_init_interrupts_seq.start(top_configuration.vsqr); + `uvm_info("SOC_IFC_RAND_TEST", "Completed interrupt init", UVM_MEDIUM) + end + endcase end // UVMF_CHANGE_ME : Extend the simulation XXX number of clocks after @@ -243,6 +350,7 @@ class soc_ifc_rand_test_sequence extends soc_ifc_bench_sequence_base; cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_status_agent_config.wait_for_num_clocks(400); cptra_status_agent_config.wait_for_num_clocks(400); + mbox_sram_agent_config.wait_for_num_clocks(400); join // pragma uvmf custom body end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_trng_test_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_trng_test_sequence.svh index 0e838834a..4c9999757 100755 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_trng_test_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/sequences/src/soc_ifc_trng_test_sequence.svh @@ -75,8 +75,6 @@ class soc_ifc_trng_test_sequence extends soc_ifc_bench_sequence_base; // **************************************************************************** virtual task body(); - // pragma uvmf custom body begin - // Construct sequences here uvm_object obj; int ii; @@ -89,6 +87,7 @@ class soc_ifc_trng_test_sequence extends soc_ifc_bench_sequence_base; cptra_ctrl_agent_random_seq = cptra_ctrl_agent_random_seq_t::type_id::create("cptra_ctrl_agent_random_seq"); soc_ifc_status_agent_responder_seq = soc_ifc_status_agent_responder_seq_t::type_id::create("soc_ifc_status_agent_responder_seq"); cptra_status_agent_responder_seq = cptra_status_agent_responder_seq_t::type_id::create("cptra_status_agent_responder_seq"); + mbox_sram_agent_responder_seq = mbox_sram_agent_responder_seq_t::type_id::create("mbox_sram_agent_responder_seq"); // Handle to the responder sequence for getting response transactions soc_ifc_env_bringup_seq.soc_ifc_status_agent_rsp_seq = soc_ifc_status_agent_responder_seq; @@ -100,6 +99,7 @@ class soc_ifc_trng_test_sequence extends soc_ifc_bench_sequence_base; fork soc_ifc_status_agent_responder_seq.start(soc_ifc_status_agent_sequencer); cptra_status_agent_responder_seq.start(cptra_status_agent_sequencer); + mbox_sram_agent_responder_seq.start(mbox_sram_agent_sequencer); join_none // Start INITIATOR sequences here @@ -148,6 +148,7 @@ class soc_ifc_trng_test_sequence extends soc_ifc_bench_sequence_base; cptra_ctrl_agent_config.wait_for_num_clocks(400); soc_ifc_status_agent_config.wait_for_num_clocks(400); cptra_status_agent_config.wait_for_num_clocks(400); + mbox_sram_agent_config.wait_for_num_clocks(400); join if (1) // TODO -- how to properly choose which to print? diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.compile index 9c923c2dc..408eb4545 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.compile +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.compile @@ -8,5 +8,6 @@ needs: - ../../../../verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_hdl.compile - ../../../../verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_hdl.compile - ../../../../verification_ip/interface_packages/cptra_status_pkg/cptra_status_hdl.compile + - ../../../../verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hdl.compile src: - hdl_top.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv index 06de1efdb..20a92522c 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.sv @@ -82,28 +82,6 @@ import uvmf_base_pkg_hdl::*; // pragma uvmf custom reset_generator end // pragma uvmf custom module_item_additional begin -import soc_ifc_pkg::*; - mbox_sram_req_t mbox_sram_req; - mbox_sram_resp_t mbox_sram_resp; - - //SRAM for mbox - caliptra_sram - #( - .DATA_WIDTH(MBOX_DATA_AND_ECC_W), - .DEPTH(MBOX_DEPTH) - ) - i_mbox_ram - ( - .clk_i(clk), - - .cs_i (mbox_sram_req.cs ), - .we_i (mbox_sram_req.we ), - .addr_i (mbox_sram_req.addr ), - .wdata_i(mbox_sram_req.wdata), - - .rdata_o(mbox_sram_resp.rdata) - ); - initial i_mbox_ram.ram = '{default:8'h0}; // pragma uvmf custom module_item_additional end // Instantiate the signal bundle, monitor bfm and driver bfm for each interface. @@ -130,14 +108,21 @@ import soc_ifc_pkg::*; .clk(clk), .dummy(1'b1) // pragma uvmf custom cptra_status_agent_bus_connections end ); + mbox_sram_if mbox_sram_agent_bus( + // pragma uvmf custom mbox_sram_agent_bus_connections begin + .clk(clk), .dummy(1'b1) + // pragma uvmf custom mbox_sram_agent_bus_connections end + ); soc_ifc_ctrl_monitor_bfm soc_ifc_ctrl_agent_mon_bfm(soc_ifc_ctrl_agent_bus.monitor_port); cptra_ctrl_monitor_bfm cptra_ctrl_agent_mon_bfm(cptra_ctrl_agent_bus.monitor_port); soc_ifc_status_monitor_bfm soc_ifc_status_agent_mon_bfm(soc_ifc_status_agent_bus.monitor_port); cptra_status_monitor_bfm cptra_status_agent_mon_bfm(cptra_status_agent_bus.monitor_port); + mbox_sram_monitor_bfm mbox_sram_agent_mon_bfm(mbox_sram_agent_bus.monitor_port); soc_ifc_ctrl_driver_bfm soc_ifc_ctrl_agent_drv_bfm(soc_ifc_ctrl_agent_bus.initiator_port); cptra_ctrl_driver_bfm cptra_ctrl_agent_drv_bfm(cptra_ctrl_agent_bus.initiator_port); soc_ifc_status_driver_bfm soc_ifc_status_agent_drv_bfm(soc_ifc_status_agent_bus.responder_port); cptra_status_driver_bfm cptra_status_agent_drv_bfm(cptra_status_agent_bus.responder_port); + mbox_sram_driver_bfm mbox_sram_agent_drv_bfm(mbox_sram_agent_bus.responder_port); // pragma uvmf custom dut_instantiation begin // AHB Clock/reset @@ -161,7 +146,7 @@ import soc_ifc_pkg::*; .soc_ifc_clk_cg (clk ), .rdc_clk_cg (clk ), .rdc_clk_dis (), - .fw_update_rst_window (), + .fw_update_rst_window (cptra_status_agent_bus.fw_update_rst_window), .cptra_pwrgood (soc_ifc_ctrl_agent_bus.cptra_pwrgood ), .cptra_rst_b (soc_ifc_ctrl_agent_bus.cptra_rst_b ), .ready_for_fuses (soc_ifc_status_agent_bus.ready_for_fuses ), @@ -177,8 +162,8 @@ import soc_ifc_pkg::*; .generic_output_wires(soc_ifc_status_agent_bus.generic_output_wires), //SRAM interface - .mbox_sram_req(mbox_sram_req), - .mbox_sram_resp(mbox_sram_resp), + .mbox_sram_req(mbox_sram_agent_bus.mbox_sram_req), + .mbox_sram_resp(mbox_sram_agent_bus.mbox_sram_resp), //APB Interface with SoC .paddr_i (uvm_test_top_environment_qvip_apb5_slave_subenv_qvip_hdl.apb5_master_0_PADDR[17:0]), @@ -280,10 +265,12 @@ import soc_ifc_pkg::*; uvm_config_db #( virtual cptra_ctrl_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , cptra_ctrl_agent_BFM , cptra_ctrl_agent_mon_bfm ); uvm_config_db #( virtual soc_ifc_status_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_status_agent_BFM , soc_ifc_status_agent_mon_bfm ); uvm_config_db #( virtual cptra_status_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , cptra_status_agent_BFM , cptra_status_agent_mon_bfm ); + uvm_config_db #( virtual mbox_sram_monitor_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , mbox_sram_agent_BFM , mbox_sram_agent_mon_bfm ); uvm_config_db #( virtual soc_ifc_ctrl_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_ctrl_agent_BFM , soc_ifc_ctrl_agent_drv_bfm ); uvm_config_db #( virtual cptra_ctrl_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , cptra_ctrl_agent_BFM , cptra_ctrl_agent_drv_bfm ); uvm_config_db #( virtual soc_ifc_status_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , soc_ifc_status_agent_BFM , soc_ifc_status_agent_drv_bfm ); uvm_config_db #( virtual cptra_status_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , cptra_status_agent_BFM , cptra_status_agent_drv_bfm ); + uvm_config_db #( virtual mbox_sram_driver_bfm )::set( null , UVMF_VIRTUAL_INTERFACES , mbox_sram_agent_BFM , mbox_sram_agent_drv_bfm ); end endmodule diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.vinfo index 684e5069f..b4204c2c8 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.vinfo +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/testbench/hdl_top.vinfo @@ -5,4 +5,5 @@ @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_ctrl_pkg/cptra_ctrl_bfm.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/soc_ifc_status_pkg/soc_ifc_status_bfm.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_status_pkg/cptra_status_bfm.vinfo +@use $UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_bfm.vinfo hdl_top.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.compile index a98a9e77e..863735d42 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.compile +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.compile @@ -4,6 +4,7 @@ needs: - ../../../../verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl.compile - ../../../../verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status.compile - ../../../../verification_ip/interface_packages/cptra_status_pkg/cptra_status.compile + - ../../../../verification_ip/interface_packages/mbox_sram_pkg/mbox_sram.compile - ../../../../verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile - ../parameters/soc_ifc_parameters_pkg.compile - ../sequences/soc_ifc_sequences_pkg.compile diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.sv index 65cac7397..b06dc5f37 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.sv @@ -47,6 +47,8 @@ package soc_ifc_tests_pkg; import soc_ifc_status_pkg_hdl::*; import cptra_status_pkg::*; import cptra_status_pkg_hdl::*; + import mbox_sram_pkg::*; + import mbox_sram_pkg_hdl::*; import qvip_ahb_lite_slave_pkg::*; import qvip_apb5_slave_pkg::*; import QUESTA_MVC::*; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.vinfo index f8d3f85bb..a9a3e891c 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.vinfo +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/soc_ifc_tests_pkg.vinfo @@ -3,6 +3,7 @@ @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_status_pkg/cptra_status_pkg.vinfo +@use $UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo @use $UVMF_PROJECT_DIR/tb/parameters/soc_ifc_parameters_pkg.vinfo @use $UVMF_PROJECT_DIR/tb/sequences/soc_ifc_sequences_pkg.vinfo diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/test_top.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/test_top.svh index fa64454af..b5d8893a9 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/test_top.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/tb/tests/src/test_top.svh @@ -52,7 +52,8 @@ qvip_memory_message_handler message_handler; soc_ifc_ctrl_agent_BFM /* soc_ifc_ctrl_agent [2] */ , cptra_ctrl_agent_BFM /* cptra_ctrl_agent [3] */ , soc_ifc_status_agent_BFM /* soc_ifc_status_agent [4] */ , - cptra_status_agent_BFM /* cptra_status_agent [5] */ + cptra_status_agent_BFM /* cptra_status_agent [5] */ , + mbox_sram_agent_BFM /* mbox_sram_agent [6] */ }; uvmf_active_passive_t interface_activities[] = { @@ -61,7 +62,8 @@ uvmf_active_passive_t interface_activities[] = { ACTIVE /* soc_ifc_ctrl_agent [2] */ , ACTIVE /* cptra_ctrl_agent [3] */ , ACTIVE /* soc_ifc_status_agent [4] */ , - ACTIVE /* cptra_status_agent [5] */ }; + ACTIVE /* cptra_status_agent [5] */ , + ACTIVE /* mbox_sram_agent [6] */ }; // pragma uvmf custom class_item_additional begin // pragma uvmf custom class_item_additional end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/yaml/soc_ifc_bench.yaml b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/yaml/soc_ifc_bench.yaml index 956ac2c87..755953538 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/yaml/soc_ifc_bench.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/project_benches/soc_ifc/yaml/soc_ifc_bench.yaml @@ -10,6 +10,8 @@ uvmf: value: ACTIVE - bfm_name: cptra_status_agent value: ACTIVE + - bfm_name: mbox_sram_agent + value: ACTIVE active_passive_default: ACTIVE clock_half_period: 5ns clock_phase_offset: 0ns diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base.svh index 8c17daba4..6ce03ec1d 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base.svh @@ -46,6 +46,9 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base extends uvm_r input uvm_reg_map map); soc_ifc_reg_delay_job_intr_block_rf_ext delay_job; uvm_reg_block rm; + soc_ifc_reg__intr_block_t_ext sir_intr_rm; + sha512_acc_csr__intr_block_t_ext sac_intr_rm; + bit fld_hwset_active = 1'b0; uvm_reg sts_reg; string event_name ; uvm_reg en_reg ; @@ -58,6 +61,17 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base extends uvm_r delay_job.map = map; sts_reg = fld.get_parent(); rm = sts_reg.get_parent(); /* intr_block_rf_ext */ + if (rm.get_parent().get_name() == "sha512_acc_csr_rm") begin + if (!$cast(sac_intr_rm,rm)) `uvm_fatal("SOC_IFC_REG_CBS", {"Failed to get handle of expected sub-type for parent uvm_reg_block. ", fld.get_full_name()}) + fld_hwset_active = sac_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()]; + end + else if (rm.get_parent().get_name() == "soc_ifc_reg_rm") begin + if (!$cast(sir_intr_rm,rm)) `uvm_fatal("SOC_IFC_REG_CBS", {"Failed to get handle of expected sub-type for parent uvm_reg_block. ", fld.get_full_name()}) + fld_hwset_active = sir_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()]; + end + else begin + `uvm_fatal("SOC_IFC_REG_CBS", "Callback is registered to an unrecognized register block!") + end // Get a base-name for the event by truncating the '_sts' suffix event_name = fld.get_name().substr(0,fld.get_name().len()-5); en_reg = rm.get_reg_by_name("error_intr_en_r"); @@ -67,8 +81,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base extends uvm_r cnt_fld = rm.get_reg_by_name({event_name, "_intr_count_r"}).get_field_by_name("cnt"); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end @@ -77,9 +94,42 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base extends uvm_r // Predict an increment to event interrupt counter // regardless of interrupt enablement (the sts reg being // set is all that is tracked by the interrupt counter) + // FIXME if a new interrupt event occurs while the interrupt sts is already 1, + // this won't increment the counter, even though it should. if (value & ~previous) begin - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s triggers increment on %s from %d to %d", fld.get_name(), cnt_fld.get_name(), cnt_fld.get_mirrored_value(), cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)), UVM_HIGH) - cnt_fld.predict(cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)); + `uvm_info("SOC_IFC_REG_CBS", $sformatf("hwset to %s triggers increment on %s from %d to %d", fld.get_name(), cnt_fld.get_name(), cnt_fld.get_mirrored_value(), cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)), UVM_HIGH) + cnt_fld.predict(cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1), .kind(UVM_PREDICT_WRITE), .path(UVM_PREDICT), .map(map)); + end + + // Anytime an access intr sts register predicts a value of 1, we can treat + // that as a hwset (even if it's just an AHB/APB read) because we _know_ a + // W1C won't result in value=1, which is the case we're protecting against + // by tracking this hwset flag. + // We must track the hwset flag for all value=1 (not just the transitions + // where previous=0) because occasionally an actual hwset will occur when + // the interrupt is already pending, and we still must protect against W1C + // in that case. + if (value) begin + if (sir_intr_rm != null) begin + sir_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b1; + fork + begin + uvm_wait_for_nba_region(); + sir_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b0; + end + join_none + end + else if (sac_intr_rm != null) begin + sac_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b1; + fork + begin + uvm_wait_for_nba_region(); + sac_intr_rm.error_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b0; + end + join_none + end + else + `uvm_fatal("SOC_IFC_REG_CBS", "Bad handle") end // On rising edge of field value, schedule a delay job to check if the @@ -88,31 +138,43 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base extends uvm_r // Global interrupt pin "agg_sts" is non-sticky if ((value & ~previous)) begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin assertion"}, UVM_MEDIUM) + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin check delay job"}, UVM_MEDIUM) delay_job.req_fld = fld; delay_job.sts_reg = sts_reg; delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end + // On falling edge of field value, caused by W1C, check if another thread + // is already attempting to perform hwset to this interrupt field (hwset is + // higher priority than W1C). + else if ((~value & previous) && fld_hwset_active) + begin + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " attempts to clear the interrupt bit but is preempted by an active hwset"}, UVM_MEDIUM) + value = previous; + // NOTE: No delay job is scheduled because no changes are predicted to + // other interrupt register fields based on this activity + end // On falling edge of field value, schedule a delay job to // check if the interrupt output pin will // transition from high to low. // Global interrupt pin "agg_sts" is non-sticky else if ((~value & previous)) begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin deassertion"}, UVM_MEDIUM) + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin check delay job"}, UVM_MEDIUM) delay_job.req_fld = fld; delay_job.sts_reg = sts_reg; delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end else begin `uvm_info("SOC_IFC_REG_CBS", - $sformatf("Write to %s does not trigger interrupt output transition due to %s: [%x], %s: [%x], masked %s: [%x], and %s: [%x]", + $sformatf("Access to %s does not trigger interrupt output transition due to %s: [%x], %s: [%x], masked %s: [%x], and %s: [%x]", fld.get_name(), en_glb.get_name(), en_glb.get_mirrored_value(), diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base.svh index c47910d29..bc171833e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base.svh @@ -65,8 +65,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base extends uvm_reg_cbs sts_glb = rm.get_reg_by_name("error_global_intr_r").get_field_by_name("agg_sts"); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end @@ -83,6 +86,7 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base extends uvm_reg_cbs delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end // On falling edge of field value, check if the interrupt output pin will @@ -96,6 +100,7 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_en_r_base extends uvm_reg_cbs delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end else begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_trig_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_trig_r_base.svh index 007ffa230..b1c2a509f 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_trig_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_trig_r_base.svh @@ -48,8 +48,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_error_intr_trig_r_base extends uvm_reg_c sts_fld = sts_reg.get_field_by_name({event_name, "_sts"}); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base.svh index 995f6fefa..0d2e20c33 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base.svh @@ -51,46 +51,49 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base extends uvm_reg_cb sts_glb = rm.get_reg_by_name({event_type, "_global_intr_r"}).get_field_by_name("agg_sts"); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end `uvm_info("SOC_IFC_REG_CBS", $sformatf("Access to %s with path %p", fld.get_full_name(), path), UVM_FULL) - // On rising edge of field value, check if the interrupt output pin will - // transition to high. - // Global interrupt pin "agg_sts" is non-sticky - if ((value & ~previous) && - |( en_reg.get_mirrored_value() & - sts_reg.get_mirrored_value()) && - ~sts_glb.get_mirrored_value()) - begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin assertion"}, UVM_MEDIUM) - sts_glb.predict(1'b1); - end - // On falling edge of field value, check if the interrupt output pin will - // transition from high to low. - // Global interrupt pin "agg_sts" is non-sticky - else if ((~value & previous) && - sts_glb.get_mirrored_value()) - begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin deassertion"}, UVM_MEDIUM) - sts_glb.predict(1'b0); - end - else begin - `uvm_info("SOC_IFC_REG_CBS", - $sformatf("Write to %s with value %0d does not trigger interrupt output transition due to %s: [0x%x], %s: [0x%x], and %s: [%x]", - fld.get_name(), - value, - en_reg.get_name(), - en_reg.get_mirrored_value(), - sts_reg.get_name(), - sts_reg.get_mirrored_value(), - sts_glb.get_name(), - sts_glb.get_mirrored_value()), - UVM_HIGH) - end +// // On rising edge of field value, check if the interrupt output pin will +// // transition to high. +// // Global interrupt pin "agg_sts" is non-sticky +// if ((value & ~previous) && +// |( en_reg.get_mirrored_value() & +// sts_reg.get_mirrored_value()) && +// ~sts_glb.get_mirrored_value()) +// begin +// `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin assertion"}, UVM_MEDIUM) +// sts_glb.predict(1'b1); +// end +// // On falling edge of field value, check if the interrupt output pin will +// // transition from high to low. +// // Global interrupt pin "agg_sts" is non-sticky +// else if ((~value & previous) && +// sts_glb.get_mirrored_value()) +// begin +// `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin deassertion"}, UVM_MEDIUM) +// sts_glb.predict(1'b0); +// end +// else begin +// `uvm_info("SOC_IFC_REG_CBS", +// $sformatf("Write to %s with value %0d does not trigger interrupt output transition due to %s: [0x%x], %s: [0x%x], and %s: [%x]", +// fld.get_name(), +// value, +// en_reg.get_name(), +// en_reg.get_mirrored_value(), +// sts_reg.get_name(), +// sts_reg.get_mirrored_value(), +// sts_glb.get_name(), +// sts_glb.get_mirrored_value()), +// UVM_HIGH) +// end endfunction endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_internal.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_internal.svh new file mode 100644 index 000000000..0ad25c667 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_internal.svh @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +//---------------------------------------------------------------------- + +// General callback that implements the swwel=soc_req behavior for "internal" registers +class soc_ifc_reg_cbs_intr_block_rf_ext_internal extends uvm_reg_cbs; + + `uvm_object_utils(soc_ifc_reg_cbs_intr_block_rf_ext_internal) + + string AHB_map_name = "soc_ifc_AHB_map"; + string APB_map_name = "soc_ifc_APB_map"; + + uvm_queue #(soc_ifc_reg_delay_job) delay_jobs; + + function new(string name = "uvm_reg_cbs"); + super.new(name); + if (!uvm_config_db#(uvm_queue#(soc_ifc_reg_delay_job))::get(null, "soc_ifc_reg_model_top", "delay_jobs", delay_jobs)) + `uvm_error("SOC_IFC_REG_CBS", "Failed to get handle for 'delay_jobs' queue from config database!") + endfunction + + // Function: post_predict + // + // Called by the method + // after a successful UVM_PREDICT_READ or UVM_PREDICT_WRITE prediction. + // + // ~previous~ is the previous value in the mirror and + // ~value~ is the latest predicted value. Any change to ~value~ will + // modify the predicted mirror value. + // + virtual function void post_predict(input uvm_reg_field fld, + input uvm_reg_data_t previous, + inout uvm_reg_data_t value, + input uvm_predict_e kind, + input uvm_path_e path, + input uvm_reg_map map); + uvm_reg_block blk = fld.get_parent().get_parent(); /* intr_block_rf_ext */ + if (blk.get_name() != "intr_block_rf_ext") `uvm_fatal ("SOC_IFC_REG_CBS", "Failed to get valid parent class handle") + if (map.get_name() == this.AHB_map_name) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("post_predict called with kind [%p] on map [%s] has no effect on internal register field %s", kind, map.get_name(), fld.get_full_name()), UVM_FULL) + end + else if (map.get_name() == this.APB_map_name) begin + case (kind) inside + UVM_PREDICT_WRITE: begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("post_predict blocked write attempt to internal reg field %s on map %s. value: 0x%x previous: 0x%x", fld.get_full_name(), map.get_name(), value, previous), UVM_LOW) + value = previous; + end + default: begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("post_predict called with kind [%p] on map [%s] has no effect on internal register field %s. value: 0x%x previous: 0x%x", kind, map.get_name(), fld.get_full_name(), value, previous), UVM_FULL) + end + endcase + end + else begin + `uvm_error("SOC_IFC_REG_CBS", {"post_predict called through unsupported reg map! ", map.get_name()}) + end + endfunction + +endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base.svh index b58f537ee..6946128d1 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base.svh @@ -46,6 +46,9 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base extends uvm_r input uvm_reg_map map); soc_ifc_reg_delay_job_intr_block_rf_ext delay_job; uvm_reg_block rm; + soc_ifc_reg__intr_block_t_ext sir_intr_rm; + sha512_acc_csr__intr_block_t_ext sac_intr_rm; + bit fld_hwset_active = 1'b0; uvm_reg sts_reg; string event_name ; uvm_reg en_reg ; @@ -58,6 +61,17 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base extends uvm_r delay_job.map = map; sts_reg = fld.get_parent(); rm = sts_reg.get_parent(); /* intr_block_rf_ext */ + if (rm.get_parent().get_name() == "sha512_acc_csr_rm") begin + if (!$cast(sac_intr_rm,rm)) `uvm_fatal("SOC_IFC_REG_CBS", {"Failed to get handle of expected sub-type for parent uvm_reg_block. ", fld.get_full_name()}) + fld_hwset_active = sac_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()]; + end + else if (rm.get_parent().get_name() == "soc_ifc_reg_rm") begin + if (!$cast(sir_intr_rm,rm)) `uvm_fatal("SOC_IFC_REG_CBS", {"Failed to get handle of expected sub-type for parent uvm_reg_block. ", fld.get_full_name()}) + fld_hwset_active = sir_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()]; + end + else begin + `uvm_fatal("SOC_IFC_REG_CBS", "Callback is registered to an unrecognized register block!") + end // Get a base-name for the event by truncating the '_sts' suffix event_name = fld.get_name().substr(0,fld.get_name().len()-5); en_reg = rm.get_reg_by_name("notif_intr_en_r"); @@ -67,8 +81,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base extends uvm_r cnt_fld = rm.get_reg_by_name({event_name, "_intr_count_r"}).get_field_by_name("cnt"); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end @@ -77,9 +94,42 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base extends uvm_r // Predict an increment to event interrupt counter // regardless of interrupt enablement (the sts reg being // set is all that is tracked by the interrupt counter) + // FIXME if a new interrupt event occurs while the interrupt sts is already 1, + // this won't increment the counter, even though it should. if (value & ~previous) begin - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s triggers increment on %s from %d to %d", fld.get_name(), cnt_fld.get_name(), cnt_fld.get_mirrored_value(), cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)), UVM_HIGH) - cnt_fld.predict(cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)); + `uvm_info("SOC_IFC_REG_CBS", $sformatf("hwset to %s triggers increment on %s from %d to %d", fld.get_name(), cnt_fld.get_name(), cnt_fld.get_mirrored_value(), cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1)), UVM_HIGH) + cnt_fld.predict(cnt_fld.get_mirrored_value() + uvm_reg_data_t'(1), .kind(UVM_PREDICT_WRITE), .path(UVM_PREDICT), .map(map)); + end + + // Anytime an access intr sts register predicts a value of 1, we can treat + // that as a hwset (even if it's just an AHB/APB read) because we _know_ a + // W1C won't result in value=1, which is the case we're protecting against + // by tracking this hwset flag. + // We must track the hwset flag for all value=1 (not just the transitions + // where previous=0) because occasionally an actual hwset will occur when + // the interrupt is already pending, and we still must protect against W1C + // in that case. + if (value) begin + if (sir_intr_rm != null) begin + sir_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b1; + fork + begin + uvm_wait_for_nba_region(); + sir_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b0; + end + join_none + end + else if (sac_intr_rm != null) begin + sac_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b1; + fork + begin + uvm_wait_for_nba_region(); + sac_intr_rm.notif_internal_intr_r_hwset_active[fld.get_lsb_pos()] = 1'b0; + end + join_none + end + else + `uvm_fatal("SOC_IFC_REG_CBS", "Bad handle") end // On rising edge of field value, schedule a delay job to check if the @@ -88,31 +138,43 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base extends uvm_r // Global interrupt pin "agg_sts" is non-sticky if ((value & ~previous)) begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin assertion"}, UVM_MEDIUM) + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin check delay job"}, UVM_MEDIUM) delay_job.req_fld = fld; delay_job.sts_reg = sts_reg; delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end + // On falling edge of field value, caused by W1C, check if another thread + // is already attempting to perform hwset to this interrupt field (hwset is + // higher priority than W1C). + else if ((~value & previous) && fld_hwset_active) + begin + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " attempts to clear the interrupt bit but is preempted by an active hwset"}, UVM_MEDIUM) + value = previous; + // NOTE: No delay job is scheduled because no changes are predicted to + // other interrupt register fields based on this activity + end // On falling edge of field value, schedule a delay job to // check if the interrupt output pin will // transition from high to low. // Global interrupt pin "agg_sts" is non-sticky else if ((~value & previous)) begin - `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin deassertion"}, UVM_MEDIUM) + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin check delay job"}, UVM_MEDIUM) delay_job.req_fld = fld; delay_job.sts_reg = sts_reg; delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end else begin `uvm_info("SOC_IFC_REG_CBS", - $sformatf("Write to %s does not trigger interrupt output transition due to %s: [%x], %s: [%x], masked %s: [%x], and %s: [%x]", + $sformatf("Access to %s does not trigger interrupt output transition due to %s: [%x], %s: [%x], masked %s: [%x], and %s: [%x]", fld.get_name(), en_glb.get_name(), en_glb.get_mirrored_value(), diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base.svh index d5d60f907..bd138f03b 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base.svh @@ -65,8 +65,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base extends uvm_reg_cbs sts_glb = rm.get_reg_by_name("notif_global_intr_r").get_field_by_name("agg_sts"); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end @@ -83,6 +86,7 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base extends uvm_reg_cbs delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end // On falling edge of field value, check if the interrupt output pin will @@ -96,6 +100,7 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base extends uvm_reg_cbs delay_job.en_reg = en_reg; delay_job.sts_glb = sts_glb; delay_job.en_glb = en_glb; + delay_job.grab_values(); delay_jobs.push_back(delay_job); end else begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base.svh index 0c221185c..360bd46dc 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base.svh @@ -48,8 +48,11 @@ class soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base extends uvm_reg_c sts_fld = sts_reg.get_field_by_name({event_name, "_sts"}); if (map.get_name() == this.APB_map_name) begin - if (kind == UVM_PREDICT_WRITE) - `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to interrupt register through APB interface!") + if (kind == UVM_PREDICT_WRITE) begin + `uvm_warning("SOC_IFC_REG_CBS", {"Unexpected write to interrupt register ", fld.get_full_name(), " through APB interface is blocked!"}) + value = previous; + return; + end else `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to interrupt register through APB interface!", UVM_LOW) end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command.svh index b58126495..2fc026380 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command.svh @@ -130,7 +130,10 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command extends soc_ifc_reg_cbs_mbox_csr error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] causes a mbox no_lock protocol error. Delay job is queued to update DUT model.", fld.get_name(), map.get_name(), value), UVM_HIGH) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] causes a mbox no_lock protocol violation. Delay job is queued to update DUT model.", fld.get_name(), map.get_name(), value), UVM_HIGH) + end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) end else begin error_job = soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error::type_id::create("error_job"); @@ -141,7 +144,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command extends soc_ifc_reg_cbs_mbox_csr error_job.state_nxt = MBOX_ERROR; error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during unexpected mailbox state [%p] results in mbox ooo protocol error!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during unexpected mailbox state [%p] results in mbox ooo protocol violation!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end end default: begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain.svh index eee2faf34..19cc7df57 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain.svh @@ -125,7 +125,10 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain extends soc_ifc_reg_cbs_mbox_c error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to [%s] on map [%s] with value [%x] causes a mbox no_lock protocol error. Delay job is queued to update DUT model.", fld.get_name(), map.get_name(), value), UVM_HIGH) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to [%s] on map [%s] with value [%x] causes a mbox no_lock protocol violation. Delay job is queued to update DUT model.", fld.get_name(), map.get_name(), value), UVM_HIGH) + end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) end else begin mbox_fsm_state_e mbox_fsm_ps; @@ -138,7 +141,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_datain_datain extends soc_ifc_reg_cbs_mbox_c error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); mbox_fsm_ps = mbox_fsm_state_e'(rm.mbox_status.mbox_fsm_ps.get_mirrored_value()); - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during unexpected mailbox state [%p] [%p] results in mbox ooo protocol error!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs, mbox_fsm_ps)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during unexpected mailbox state [%p] [%p] results in mbox ooo protocol violation!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs, mbox_fsm_ps), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end end default: begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout.svh index 3451015da..41a9a7c7d 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout.svh @@ -56,6 +56,10 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout extends soc_ifc_reg_cbs_mbox error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) + end + // FIXME should we treat all writes to mbox_dataout as protocol error? else if ((kind == UVM_PREDICT_WRITE) || ((!rm.mbox_fn_state_sigs.soc_receive_stage && !rm.mbox_fn_state_sigs.soc_done_stage) && rm.mbox_datain_to_dataout_predict.is_off())) begin @@ -68,6 +72,7 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_dataout_dataout extends soc_ifc_reg_cbs_mbox error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); `uvm_error("SOC_IFC_REG_CBS", $sformatf("Access to dataout of kind [%p] is unexpected on map [%s]! Flagging mailbox protocol violation. Mailbox state tracker: %p", kind, map.get_name(), rm.mbox_fn_state_sigs)) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end end endcase diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length.svh index 19917958c..019df9fa3 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length.svh @@ -113,7 +113,10 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length extends soc_ifc_reg_cbs_mbox_csr error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("DLEN written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("DLEN written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs), UVM_LOW) + end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) end else begin error_job = soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error::type_id::create("error_job"); @@ -124,7 +127,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_dlen_length extends soc_ifc_reg_cbs_mbox_csr error_job.state_nxt = MBOX_ERROR; error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("DLEN written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("DLEN written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end end default: begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute.svh index cb45362c8..aa25c9ad8 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute.svh @@ -33,6 +33,9 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_execute_execute extends soc_ifc_reg_de skip = 1; end end + if (rm.mbox_fn_state_sigs.mbox_error) begin + skip = 1; + end if (rm.mbox_lock.lock.get_mirrored_value() && !skip) begin rm.mbox_status.mbox_fsm_ps.predict(state_nxt, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); case (state_nxt) inside @@ -91,10 +94,11 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_execute_execute extends soc_ifc_reg_de end else begin `uvm_info("SOC_IFC_REG_DELAY_JOB", - $sformatf("Delay job for mbox_execute does not predict any changes due to: mbox_lock mirror [%d] mbox_unlock mirror [%d] mbox_fsm_ps [%p]", + $sformatf("Delay job for mbox_execute does not predict any changes due to: mbox_lock mirror [%d] skip [%d] mbox_fsm_ps [%p] mbox_fn_state_sigs [%p]", rm.mbox_lock.lock.get_mirrored_value(), skip, /*rm.mbox_unlock.unlock.get_mirrored_value(),*/ - rm.mbox_status.mbox_fsm_ps.get_mirrored_value()), + rm.mbox_status.mbox_fsm_ps.get_mirrored_value(), + rm.mbox_fn_state_sigs), UVM_LOW) end endtask @@ -203,7 +207,10 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute extends soc_ifc_reg_cbs_mbox error_job.set_delay_cycles(0); error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("EXECUTE written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("EXECUTE written during unexpected mailbox state [%p]!", rm.mbox_fn_state_sigs), UVM_LOW) + end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) end else if (!rm.mbox_fn_state_sigs.soc_done_stage && !(rm.mbox_fn_state_sigs.soc_data_stage /*&& mbox_fsm_state_e'(rm.mbox_status.mbox_fsm_ps.get_mirrored_value()) == MBOX_RDY_FOR_DATA*/)) begin @@ -213,16 +220,17 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute extends soc_ifc_reg_cbs_mbox error_job.set_delay_cycles(0); error_job.state_nxt = MBOX_ERROR; error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("EXECUTE written during unexpected mailbox state [%p]! FSM mirror: [%p]", rm.mbox_fn_state_sigs, rm.mbox_status.mbox_fsm_ps.get_mirrored_value())) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("EXECUTE written during unexpected mailbox state [%p]! FSM mirror: [%p]", rm.mbox_fn_state_sigs, rm.mbox_status.mbox_fsm_ps.get_mirrored_value()), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end // Clearing 'execute' - Expect sts pin change if (~value & previous) begin if (rm.mbox_data_q.size() != 0 || rm.mbox_resp_q.size() != 0) begin - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Clearing mbox_execute when data queues are not empty! Did the receiver fetch the amount of data it expected to? mbox_data_q.size() [%0d] mbox_resp_q.size() [%0d]", rm.mbox_data_q.size(), rm.mbox_resp_q.size())) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Clearing mbox_execute when data queues are not empty! Did the receiver fetch the amount of data it expected to? mbox_data_q.size() [%0d] mbox_resp_q.size() [%0d]", rm.mbox_data_q.size(), rm.mbox_resp_q.size()), UVM_LOW) end if (!rm.mbox_fn_state_sigs.soc_done_stage) begin - `uvm_error("SOC_IFC_REG_CBS", $sformatf("SOC is clearing mbox_execute in unexpected mbox FSM state: [%p]", rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("mbox_execute is cleared by SOC in unexpected mbox FSM state: [%p]", rm.mbox_fn_state_sigs), UVM_LOW) end `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to mbox_execute clears the field and ends a command"), UVM_HIGH) rm.mbox_data_q.delete(); @@ -237,7 +245,7 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_execute_execute extends soc_ifc_reg_cbs_mbox int unsigned dlen_cap_dw = (mbox_dlen_mirrored(rm) < (mm.get_size() * mm.get_n_bytes())) ? mbox_dlen_mirrored_dword_ceil(rm) : (mm.get_size() * mm.get_n_bytes()) >> ($clog2(MBOX_DATA_W/8)); if (!rm.mbox_fn_state_sigs.soc_data_stage) - `uvm_error("SOC_IFC_REG_CBS", $sformatf("mbox_execute is set by SOC when in an unexpected state [%p]!", rm.mbox_fn_state_sigs)) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("mbox_execute is set by SOC when in an unexpected state [%p]!", rm.mbox_fn_state_sigs), UVM_LOW) // Round dlen up to nearest dword boundary and compare with data queue size // On transfer of control, remove extraneous entries from data_q since // reads of these values will be gated for the receiver in DUT diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock.svh index 795747d5d..f77f7c932 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock.svh @@ -127,10 +127,23 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock extends soc_ifc_reg_cbs_mbox_csr; else if (map.get_name() == this.APB_map_name) begin case (kind) inside UVM_PREDICT_READ: begin + // Reading mbox_lock when it is already locked (by uC) + // triggers a notification interrupt to the uC in Caliptra + if (value & previous) begin + if (rm.mbox_fn_state_sigs.mbox_idle) begin + `uvm_error("SOC_IFC_REG_CBS", $sformatf("Read from mbox_lock on map [%s] with value [%x] and previous [%x] is unexpected in state [%p]!", map.get_name(), value, previous, rm.mbox_fn_state_sigs)) + end + else if (!rm.mbox_status.soc_has_lock.get_mirrored_value()) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Read from mbox_lock on map [%s] with value [%x] and previous [%x] in state [%p] triggers a notification interrupt for soc_req_lock!", map.get_name(), value, previous, rm.mbox_fn_state_sigs), UVM_HIGH) + rm.get_parent().get_block_by_name("soc_ifc_reg_rm").get_block_by_name("intr_block_rf_ext").get_field_by_name("notif_soc_req_lock_sts").predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, rm.get_parent().get_map_by_name(this.AHB_map_name)); /* AHB-access only, use AHB map*/ + end + else begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Read from mbox_lock on map [%s] with value [%x] and previous [%x] in state [%p] has no effect due to soc_has_lock: [%0d]", map.get_name(), value, previous, rm.mbox_fn_state_sigs, rm.mbox_status.soc_has_lock.get_mirrored_value()), UVM_FULL) + end + end // Rising edge on RS - // Reading mbox_lock when it is already locked has no effect, so - // only calculate predictions on acquiring lock - if (value & ~previous) begin + // Calculate predictions on acquiring lock + else if (value & ~previous) begin if (rm.mbox_fn_state_sigs.mbox_idle) begin delay_job.state_nxt = MBOX_RDY_FOR_CMD; delay_jobs.push_back(delay_job); @@ -155,6 +168,7 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock extends soc_ifc_reg_cbs_mbox_csr; end end default: begin + // FIXME only do an error job if not idle? error_job = soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error::type_id::create("error_job"); error_job.rm = rm; error_job.map = map; @@ -163,7 +177,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock extends soc_ifc_reg_cbs_mbox_csr; error_job.state_nxt = MBOX_ERROR; error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write attempt to %s is unexpected! mailbox state [%p], FSM mirror: [%p]", fld.get_name(), rm.mbox_fn_state_sigs, rm.mbox_status.mbox_fsm_ps.get_mirrored_value())) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write attempt to %s is unexpected! mailbox state [%p], FSM mirror: [%p]", fld.get_name(), rm.mbox_fn_state_sigs, rm.mbox_status.mbox_fsm_ps.get_mirrored_value()), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end endcase end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh index 653014b0a..0e27ee264 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_mbox_csr_mbox_status_status.svh @@ -78,7 +78,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_status_status extends soc_ifc_reg_cbs_mbox_c if (map.get_name() == this.AHB_map_name) begin case (kind) inside UVM_PREDICT_WRITE: begin - if (mbox_status_e'(value) != mbox_status_e'(previous) && + if (rm.mbox_fn_state_sigs.uc_receive_stage && + mbox_status_e'(value) != mbox_status_e'(previous) && mbox_status_e'(value) != CMD_BUSY) begin if (!rm.mbox_status.soc_has_lock.get_mirrored_value()) begin `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write to mbox_status in state [%p] on map [%s] is unexpected!", rm.mbox_fn_state_sigs, map.get_name())) @@ -122,7 +123,7 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_status_status extends soc_ifc_reg_cbs_mbox_c end end else begin - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to mbox_status on map [%s] with value [%x] does not update the status field (previous value [%x]), so no state change is predicted", map.get_name(), mbox_status_e'(value), mbox_status_e'(previous)), UVM_MEDIUM) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to mbox_status on map [%s] with value [%x] during state [%p] does not update the status field (previous value [%x]), so no state change is predicted", map.get_name(), mbox_status_e'(value), rm.mbox_fn_state_sigs, mbox_status_e'(previous)), UVM_MEDIUM) end end default: begin @@ -133,10 +134,11 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_status_status extends soc_ifc_reg_cbs_mbox_c else if (map.get_name() == this.APB_map_name) begin case (kind) inside UVM_PREDICT_WRITE: begin - if (mbox_status_e'(value) != mbox_status_e'(previous) && + if (rm.mbox_fn_state_sigs.soc_receive_stage && + mbox_status_e'(value) != mbox_status_e'(previous) && mbox_status_e'(value) != CMD_BUSY) begin if (rm.mbox_status.soc_has_lock.get_mirrored_value()) begin - `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write to mbox_status in state [%p] on map [%s] is unexpected!", rm.mbox_fn_state_sigs, map.get_name())) + `uvm_warning("SOC_IFC_REG_CBS", $sformatf("Write to mbox_status in state [%p] on map [%s] is unexpected! soc_has_lock is %x", rm.mbox_fn_state_sigs, map.get_name(), rm.mbox_status.soc_has_lock.get_mirrored_value())) end else begin if (rm.mbox_data_q.size() > 0) begin @@ -161,8 +163,12 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_status_status extends soc_ifc_reg_cbs_mbox_c error_job.set_delay_cycles(0); error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] causes a mbox no_lock protocol violation. Delay job is queued to update DUT model.", fld.get_name(), map.get_name(), value), UVM_HIGH) delay_jobs.push_back(error_job); end + else if (rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during mailbox state [%p] has no additional side effects!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) + end else if (!rm.mbox_fn_state_sigs.soc_receive_stage) begin error_job = soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error::type_id::create("error_job"); error_job.rm = rm; @@ -172,6 +178,8 @@ class soc_ifc_reg_cbs_mbox_csr_mbox_status_status extends soc_ifc_reg_cbs_mbox_c error_job.state_nxt = MBOX_ERROR; error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; delay_jobs.push_back(error_job); + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Write to %s on map [%s] with value [%x] during unexpected mailbox state [%p] results in mbox ooo protocol violation!", fld.get_name(), map.get_name(), value, rm.mbox_fn_state_sigs), UVM_LOW) + rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; end end default: begin diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART.svh new file mode 100644 index 000000000..bb2af36b0 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART.svh @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +//---------------------------------------------------------------------- + +class soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART extends uvm_reg_cbs; + + `uvm_object_utils(soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART) + + string AHB_map_name = "soc_ifc_AHB_map"; + string APB_map_name = "soc_ifc_APB_map"; + + // Function: post_predict + // + // Called by the method + // after a successful UVM_PREDICT_READ or UVM_PREDICT_WRITE prediction. + // + // ~previous~ is the previous value in the mirror and + // ~value~ is the latest predicted value. Any change to ~value~ will + // modify the predicted mirror value. + // + virtual function void post_predict(input uvm_reg_field fld, + input uvm_reg_data_t previous, + inout uvm_reg_data_t value, + input uvm_predict_e kind, + input uvm_path_e path, + input uvm_reg_map map); + // uvm_reg_block rm; + // string event_name; + // uvm_reg sts_reg; + // uvm_reg_field sts_fld; + + // rm = fld.get_parent().get_parent(); /* intr_block_rf_ext */ + // // Get a base-name for the event by truncating the '_trig' suffix + // event_name = fld.get_name().substr(0,fld.get_name().len()-6); + // sts_reg = rm.get_reg_by_name("error_internal_intr_r"); + // sts_fld = sts_reg.get_field_by_name({event_name, "_sts"}); + + if (map.get_name() == this.APB_map_name) begin + if (kind == UVM_PREDICT_WRITE) + `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to WDT_TIMER1_CTRL register through APB interface!") + else + `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to WDT_TIMER1_CTRL register through APB interface!", UVM_LOW) + end + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Access to %s with path %p", fld.get_full_name(), path), UVM_FULL) + + if (kind == UVM_PREDICT_WRITE) begin + // On rising edge of field trigger value, predict interrupt status will + // be set + if (value & ~previous) begin + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name()}, UVM_MEDIUM) + // - Use UVM_PREDICT_READ kind so that all the callbacks associated with + // notif__sts are also called to detect interrupt pin assertion + // - Use UVM_PREDICT_READ instead of UVM_PREDICT_WRITE so that + // "do_predict" bypasses the access-check and does not enforce W1C + // behavior on this attempt to set interrupt status to 1 + end + + // Because WDT timer restart is single-pulse, it should auto-clear immediately on + // being written. + // So set predicted value to 0. + value = 0; + `uvm_info("SOC_IFC_REG_CBS", + $sformatf("Write to %s results in mirrored value forcibly predicted to [%x]", + fld.get_name(), + value), + UVM_HIGH) + end + endfunction + +endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART.svh new file mode 100644 index 000000000..129a5e19c --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART.svh @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +//---------------------------------------------------------------------- + +class soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART extends uvm_reg_cbs; + + `uvm_object_utils(soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART) + + string AHB_map_name = "soc_ifc_AHB_map"; + string APB_map_name = "soc_ifc_APB_map"; + + // Function: post_predict + // + // Called by the method + // after a successful UVM_PREDICT_READ or UVM_PREDICT_WRITE prediction. + // + // ~previous~ is the previous value in the mirror and + // ~value~ is the latest predicted value. Any change to ~value~ will + // modify the predicted mirror value. + // + virtual function void post_predict(input uvm_reg_field fld, + input uvm_reg_data_t previous, + inout uvm_reg_data_t value, + input uvm_predict_e kind, + input uvm_path_e path, + input uvm_reg_map map); + // uvm_reg_block rm; + // string event_name; + // uvm_reg sts_reg; + // uvm_reg_field sts_fld; + + // rm = fld.get_parent().get_parent(); /* intr_block_rf_ext */ + // // Get a base-name for the event by truncating the '_trig' suffix + // event_name = fld.get_name().substr(0,fld.get_name().len()-6); + // sts_reg = rm.get_reg_by_name("error_internal_intr_r"); + // sts_fld = sts_reg.get_field_by_name({event_name, "_sts"}); + + if (map.get_name() == this.APB_map_name) begin + if (kind == UVM_PREDICT_WRITE) + `uvm_warning("SOC_IFC_REG_CBS", "Unexpected write to WDT_TIMER2_CTRL register through APB interface!") + else + `uvm_info("SOC_IFC_REG_CBS", "Unexpected read to WDT_TIMER2_CTRL register through APB interface!", UVM_LOW) + end + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Access to %s with path %p", fld.get_full_name(), path), UVM_FULL) + + if (kind == UVM_PREDICT_WRITE) begin + // On rising edge of field trigger value, predict interrupt status will + // be set + if (value & ~previous) begin + `uvm_info("SOC_IFC_REG_CBS", {"Predicted update to ", fld.get_name(), " triggers interrupt output pin assertion"}, UVM_MEDIUM) + // - Use UVM_PREDICT_READ kind so that all the callbacks associated with + // notif__sts are also called to detect interrupt pin assertion + // - Use UVM_PREDICT_READ instead of UVM_PREDICT_WRITE so that + // "do_predict" bypasses the access-check and does not enforce W1C + // behavior on this attempt to set interrupt status to 1 + end + + // Because WDT timer restart is single-pulse, it should auto-clear immediately on + // being written. + // So set predicted value to 0. + value = 0; + `uvm_info("SOC_IFC_REG_CBS", + $sformatf("Write to %s results in mirrored value forcibly predicted to [%x]", + fld.get_name(), + value), + UVM_HIGH) + end + endfunction + +endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_internal_fw_update_reset.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_internal_fw_update_reset.svh index 8c02163f2..71d04dbff 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_internal_fw_update_reset.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_cbs_soc_ifc_reg_internal_fw_update_reset.svh @@ -20,14 +20,48 @@ class soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst extend soc_ifc_reg_ext rm; /* soc_ifc_reg_rm */ uvm_reg_block rm_top; uvm_reg_map map; - bit iccm_unlock; + bit iccm_unlock = 1'b0; + bit fsm_done_to_rst = 1'b0; + bit fsm_rst_to_wait = 1'b0; + bit fsm_wait_to_done = 1'b0; virtual task do_job(); `uvm_info("SOC_IFC_REG_DELAY_JOB", "Running delayed job for soc_ifc_reg.internal_fw_update_reset.core_rst", UVM_LOW) rm_top = rm.get_parent(); - `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x", rm.internal_iccm_lock.lock.get_mirrored_value()), UVM_LOW) - if (iccm_unlock) rm.internal_iccm_lock.lock.predict(uvm_reg_data_t'(0)); - `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x", rm.internal_iccm_lock.lock.get_mirrored_value()), UVM_LOW) + `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + if (fsm_done_to_rst) begin + rm.boot_fn_state_sigs = '{boot_fw_rst: 1'b1, default: 1'b0}; + `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + end + else if (fsm_rst_to_wait && rm.boot_fn_state_sigs.boot_fw_rst) begin + rm.boot_fn_state_sigs = '{boot_wait: 1'b1, default: 1'b0}; + `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + // This delay job should also trigger the assertion of uC reset in the predictor + end + else if (fsm_wait_to_done && rm.boot_fn_state_sigs.boot_wait) begin + rm.boot_fn_state_sigs = '{boot_done: 1'b1, default: 1'b0}; + `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + // This delay job should also trigger the de-assertion of fw_update_rst_window in the predictor + end + else if (iccm_unlock && rm.boot_fn_state_sigs.boot_done) begin + rm.internal_iccm_lock.lock.predict(uvm_reg_data_t'(0)); + `uvm_info("SOC_IFC_REG_CBS", $sformatf("iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + // This delay job should also trigger the de-assertion of iccm_lock in the predictor + end + else if (rm.boot_fn_state_sigs.boot_done) begin + `uvm_info("SOC_IFC_REG_CBS", $sformatf("Delay job should trigger uC reset deassertion. iccm_lock value 0x%x, boot FSM tracker: [%p]", rm.internal_iccm_lock.lock.get_mirrored_value(), rm.boot_fn_state_sigs), UVM_LOW) + // This delay job should also trigger the de-assertion of uC reset in the predictor + end + else begin + `uvm_error("SOC_IFC_REG_CBS", + $sformatf("Delay job for internal_fw_update_reset_core_rst ran with unexpected options and Boot FSM state! options: [iccm:%0x fwrst:%0x wait:%0x done:%0x] iccm_lock value 0x%x, boot FSM tracker: [%p]", + iccm_unlock , + fsm_done_to_rst , + fsm_rst_to_wait , + fsm_wait_to_done, + rm.internal_iccm_lock.lock.get_mirrored_value(), + rm.boot_fn_state_sigs)) + end endtask endclass @@ -55,32 +89,67 @@ class soc_ifc_reg_cbs_soc_ifc_reg_internal_fw_update_reset extends soc_ifc_reg_c input uvm_path_e path, input uvm_reg_map map); + soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst delay_job_boot_fsm_fwrst; + soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst delay_job_boot_fsm_wait; + soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst delay_job_rst_window; soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst delay_job_iccm_unlock; soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst delay_job_uc_rst; soc_ifc_reg_ext rm; /* soc_ifc_reg_rm */ uvm_reg_block blk = fld.get_parent().get_parent(); /* soc_ifc_reg_rm */ if (!$cast(rm,blk)) `uvm_fatal ("SOC_IFC_REG_CBS", "Failed to get valid class handle") + + delay_job_boot_fsm_fwrst = soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst::type_id::create("delay_job_boot_fsm_fwrst"); + delay_job_boot_fsm_fwrst.rm = rm; + delay_job_boot_fsm_fwrst.map = map; + delay_job_boot_fsm_fwrst.fsm_done_to_rst = 1; + delay_job_boot_fsm_fwrst.set_delay_cycles(0); // transition to state boot_fw_rst occurs 1 clock after the reg write + + delay_job_boot_fsm_wait = soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst::type_id::create("delay_job_boot_fsm_wait"); + delay_job_boot_fsm_wait.rm = rm; + delay_job_boot_fsm_wait.map = map; + delay_job_boot_fsm_wait.fsm_rst_to_wait = 1; + delay_job_boot_fsm_wait.set_delay_cycles(delay_job_boot_fsm_fwrst.get_delay_cycles() + 2); //transition to state boot_wait (and uC reset assertion) occurs 2 clocks after the boot_fw_rst state + + delay_job_rst_window = soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst::type_id::create("delay_job_rst_window"); + delay_job_rst_window.rm = rm; + delay_job_rst_window.map = map; + delay_job_rst_window.fsm_wait_to_done = 1; + delay_job_rst_window.set_delay_cycles(delay_job_boot_fsm_wait.get_delay_cycles()+1+rm.internal_fw_update_reset_wait_cycles.wait_cycles.get_mirrored_value()); //calculate total delay until transition to state boot_done and deassertion of fw_update_rst_window + delay_job_iccm_unlock = soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst::type_id::create("delay_job_iccm_unlock"); delay_job_iccm_unlock.rm = rm; delay_job_iccm_unlock.map = map; delay_job_iccm_unlock.iccm_unlock = 1; - //account for state transitions + variable wait cycle time - delay_job_iccm_unlock.set_delay_cycles(3+rm.internal_fw_update_reset_wait_cycles.wait_cycles.get_mirrored_value()); + delay_job_iccm_unlock.set_delay_cycles(delay_job_rst_window.get_delay_cycles()+1); //this iccm unlock comes 1 clock after state transition + delay_job_uc_rst = soc_ifc_reg_delay_job_soc_ifc_reg_internal_fw_update_reset_core_rst::type_id::create("delay_job_uc_rst"); delay_job_uc_rst.rm = rm; delay_job_uc_rst.map = map; - delay_job_uc_rst.iccm_unlock = 0; - //this reset de-assertion comes 1 clock after iccm unlocks - delay_job_uc_rst.set_delay_cycles(delay_job_iccm_unlock.get_delay_cycles()+1); + delay_job_uc_rst.set_delay_cycles(delay_job_iccm_unlock.get_delay_cycles()+1); // Deassertion of uC reset is the last event triggered by this reg access + if (map.get_name() == this.AHB_map_name) begin case (kind) inside UVM_PREDICT_WRITE: begin if (value & !previous) begin - //push a delayed job for de-assertion of iccm lock - `uvm_info("SOC_IFC_REG_CBS", $sformatf("Sending delay job for internal register field %s with %d clk delay", fld.get_full_name(), delay_job_iccm_unlock.get_delay_cycles()), UVM_LOW) + //push a job to catch transition to boot_fw_rst state 1 clock later + delay_jobs.push_back(delay_job_boot_fsm_fwrst); + //push a job to catch transition to boot_wait state and assertion of uC reset 1 clock later + delay_jobs.push_back(delay_job_boot_fsm_wait); + //push another job to catch de-assertion of fw_update_rst_window on state transition to boot_done + delay_jobs.push_back(delay_job_rst_window); + //push a delayed job for de-assertion of iccm lock 1 clock later delay_jobs.push_back(delay_job_iccm_unlock); //push another job to catch de-assertion of reset 1 clock later delay_jobs.push_back(delay_job_uc_rst); + `uvm_info("SOC_IFC_REG_CBS", + $sformatf("Sending 5 delay jobs for internal register field %s with clk delays: [%0d] [%0d] [%0d] [%0d] [%0d]", + fld.get_full_name(), + delay_job_boot_fsm_fwrst.get_delay_cycles(), + delay_job_boot_fsm_wait.get_delay_cycles(), + delay_job_rst_window.get_delay_cycles(), + delay_job_iccm_unlock.get_delay_cycles(), + delay_job_uc_rst.get_delay_cycles()), + UVM_LOW) end else begin `uvm_info("SOC_IFC_REG_CBS", $sformatf("post_predict called with kind [%p] on map [%s] has no effect on internal register field %s", kind, map.get_name(), fld.get_full_name()), UVM_FULL) end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh index 104250200..ce1d56484 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_intr_block_rf_ext.svh @@ -25,24 +25,58 @@ class soc_ifc_reg_delay_job_intr_block_rf_ext extends soc_ifc_reg_delay_job; uvm_reg_field sts_glb; uvm_reg_map map; + uvm_reg_data_t val_sts_reg; + uvm_reg_data_t val_en_reg ; + uvm_reg_data_t val_en_glb ; + uvm_reg_data_t val_sts_glb; + + virtual function void grab_values(); + fork + begin + // Wait for all predictor callbacks to run for every intr bit accessed + // during the current clock cycle, so mirrors are up to date + uvm_wait_for_nba_region(); + // Snapshot of current value, since next cycle may see value changes again + val_sts_reg = sts_reg.get_mirrored_value(); + val_en_reg = en_reg .get_mirrored_value(); + val_en_glb = en_glb .get_mirrored_value(); + val_sts_glb = sts_glb.get_mirrored_value(); + end + join_none + endfunction + virtual task do_job(); `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("Running delayed job for %s", req_fld.get_full_name()), UVM_MEDIUM) - if (~sts_glb.get_mirrored_value() && |(sts_reg.get_mirrored_value() & en_reg.get_mirrored_value()) && en_glb.get_mirrored_value()) begin + if (!/*val_sts_glb*/sts_glb.get_mirrored_value() && |(val_sts_reg/*sts_reg.get_mirrored_value()*/ & val_en_reg/*en_reg.get_mirrored_value()*/) /*&& val_en_glb / * en_glb.get_mirrored_value()*/) begin sts_glb.predict(1'b1); - `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being set.", map.get_name(), req_fld.get_full_name()), UVM_HIGH) + `uvm_info("SOC_IFC_REG_DELAY_JOB", + $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being set to 0x%0x. Values: en_reg(latched) [0x%0x(0x%0x)] sts_reg [0x%0x(0x%0x)] en_glb [0x%0x(0x%0x)] sts_glb [0x%0x(0x%0x)]", + map.get_name(), req_fld.get_full_name(), sts_glb.get_mirrored_value(), + en_reg.get_mirrored_value(), val_en_reg , + sts_reg.get_mirrored_value(), val_sts_reg, + en_glb.get_mirrored_value(), val_en_glb , + sts_glb.get_mirrored_value(), val_sts_glb), + UVM_HIGH) end - else if (sts_glb.get_mirrored_value() && ~(|(sts_reg.get_mirrored_value() & en_reg.get_mirrored_value()) && en_glb.get_mirrored_value())) begin + else if (/*val_sts_glb*/sts_glb.get_mirrored_value() && !(|(val_sts_reg/*sts_reg.get_mirrored_value()*/ & val_en_reg/*en_reg.get_mirrored_value()*/) /*&& val_en_glb / * en_glb.get_mirrored_value()*/)) begin sts_glb.predict(1'b0); - `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being cleared.", map.get_name(), req_fld.get_full_name()), UVM_HIGH) + `uvm_info("SOC_IFC_REG_DELAY_JOB", + $sformatf("post_predict called through map [%p] on %s results in interrupt status bit being cleared to 0x%0x. Values: en_reg(latched) [0x%0x(0x%0x)] sts_reg [0x%0x(0x%0x)] en_glb [0x%0x(0x%0x)] sts_glb [0x%0x(0x%0x)]", + map.get_name(), req_fld.get_full_name(), sts_glb.get_mirrored_value(), + en_reg.get_mirrored_value(), val_en_reg , + sts_reg.get_mirrored_value(), val_sts_reg, + en_glb.get_mirrored_value(), val_en_glb , + sts_glb.get_mirrored_value(), val_sts_glb), + UVM_HIGH) end else begin `uvm_info("SOC_IFC_REG_DELAY_JOB", - $sformatf("Delay job for %s does not predict any changes due to: en_reg [%d] sts_reg [%d] en_glb [%d] sts_glb [%d]", + $sformatf("Delay job for %s does not predict any changes due to: en_reg(latched) [0x%0x(0x%0x)] sts_reg [0x%0x(0x%0x)] en_glb [0x%0x(0x%0x)] sts_glb [0x%0x(0x%0x)]", req_fld.get_full_name(), - en_reg.get_mirrored_value(), - sts_reg.get_mirrored_value(), - en_glb.get_mirrored_value(), - sts_glb.get_mirrored_value()), + en_reg.get_mirrored_value(), val_en_reg , + sts_reg.get_mirrored_value(), val_sts_reg, + en_glb.get_mirrored_value(), val_en_glb , + sts_glb.get_mirrored_value(), val_sts_glb), UVM_MEDIUM) end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh index 0a7084aaa..bd57d181e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error.svh @@ -57,7 +57,6 @@ class soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error extends soc_ifc_reg_delay_j non_fatal_fld.predict(1'b1, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); rm.mbox_status.mbox_fsm_ps.predict(state_nxt, .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(map)); - rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; `uvm_info("SOC_IFC_REG_DELAY_JOB", $sformatf("delay_job scheduled for access through map [%p] on [%s] results in state transition. Functional state tracker: [%p] mbox_fsm_ps transition [%p]", map.get_name(), fld.get_full_name(), rm.mbox_fn_state_sigs, state_nxt), UVM_FULL) end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv index dd60ba190..b4fd5cab5 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/registers/soc_ifc_reg_model_top_pkg.sv @@ -49,6 +49,14 @@ package soc_ifc_reg_model_top_pkg; apb5_master_0_params::APB3_PWDATA_BIT_WIDTH, apb5_master_0_params::APB3_PRDATA_BIT_WIDTH) apb_reg_adapter_t; + typedef struct packed { + bit boot_idle; + bit boot_fuse; + bit boot_fw_rst; + bit boot_wait; + bit boot_done; + } boot_fn_state_s; + typedef struct packed { bit mbox_idle; bit uc_cmd_stage; @@ -70,52 +78,120 @@ package soc_ifc_reg_model_top_pkg; /* DEFINE REGISTER CLASSES */ // pragma uvmf custom define_register_classes begin + + // These macros are used to copy the "HARD" reset value to a new reset type, "NONCORE", + // and then track the configuration of the provided register. + // When called, these macros expect that a queue has already been created called "blk_flds". + // The queue tracks all extant registers within the enclosing uvm_reg_block. + // This macro removes from that queue the uvm_reg_field that was provided as an arguement. + // This allows the calling context to check that the queue of blk_flds is empty at the end, + // and thus enforce that a custom reset configuration is defined for all register fields. + // The "NO_CP" macros do not create a "NONCORE" reset type (e.g for regs on pwrgood domain) + // but they still remove the field from the check to confirm that a reset + // configuration has been assigned. + `define FLD_DO_CP_NONCORE_RST(fld_h) begin \ + if (fld_h.has_reset("HARD")) \ + fld_h.set_reset(fld_h.get_reset("HARD"), "NONCORE"); \ + end + `define REG____CP_NONCORE_RST(reg_h) begin \ + uvm_reg_field reg_flds[$]; \ + reg_h.get_fields(reg_flds); \ + foreach (reg_flds[ii]) begin \ + int del_idx[$]; \ + `FLD_DO_CP_NONCORE_RST(reg_flds[ii]) \ + del_idx = blk_flds.find_first_index(fl) with (fl == reg_flds[ii]); \ + blk_flds.delete(del_idx.pop_front()); \ + end \ + end + `define REG_NO_CP_NONCORE_RST(reg_h) begin \ + uvm_reg_field reg_flds[$]; \ + reg_h.get_fields(reg_flds); \ + foreach (reg_flds[ii]) begin \ + int del_idx[$]; \ + del_idx = blk_flds.find_first_index(fl) with (fl == reg_flds[ii]); \ + blk_flds.delete(del_idx.pop_front()); \ + end \ + end + `define FLD____CP_NONCORE_RST(fld_h) begin \ + int del_idx[$]; \ + `FLD_DO_CP_NONCORE_RST(fld_h) \ + del_idx = blk_flds.find_first_index(fl) with (fl == fld_h); \ + blk_flds.delete(del_idx.pop_front()); \ + end + `define FLD_NO_CP_NONCORE_RST(fld_h) begin \ + int del_idx[$]; \ + del_idx = blk_flds.find_first_index(fl) with (fl == fld_h); \ + blk_flds.delete(del_idx.pop_front()); \ + end + // ------------------ END of reset config macros ------------------ // + class soc_ifc_reg__intr_block_t_ext extends soc_ifc_reg__intr_block_t; uvm_reg_map soc_ifc_reg_intr_AHB_map; uvm_reg_map soc_ifc_reg_intr_APB_map; + // HWSET has precedence over SW W1C, so use these variables to track + // active hwset activity in case contention must be resolved + bit [31:0] notif_internal_intr_r_hwset_active = 0; + bit [31:0] error_internal_intr_r_hwset_active = 0; + function new(string name = "soc_ifc_reg__intr_block_t_ext"); super.new(name); endfunction : new // FIXME Manually maintaining a list here of registers that are configured // as soft-resettable (i.e. cptra_rst_b instead of cptra_pwrgood) + // or noncore-resettable (i.e. cptra_noncore_rst_b instead of cptra_pwrgood) // Ideally would be auto-generated. - virtual function void set_soft_reset_values(); - if ( this.global_intr_en_r .has_reset("HARD" )) this.global_intr_en_r .set_reset(this.global_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.error_intr_en_r .has_reset("HARD" )) this.error_intr_en_r .set_reset(this.error_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.notif_intr_en_r .has_reset("HARD" )) this.notif_intr_en_r .set_reset(this.notif_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.error_global_intr_r .has_reset("HARD" )) this.error_global_intr_r .set_reset(this.error_global_intr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_global_intr_r .has_reset("HARD" )) this.notif_global_intr_r .set_reset(this.notif_global_intr_r .get_reset("HARD"), "SOFT"); -// this.error_internal_intr_r .set_reset(this.error_internal_intr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_internal_intr_r .has_reset("HARD" )) this.notif_internal_intr_r .set_reset(this.notif_internal_intr_r .get_reset("HARD"), "SOFT"); - if ( this.error_intr_trig_r .has_reset("HARD" )) this.error_intr_trig_r .set_reset(this.error_intr_trig_r .get_reset("HARD"), "SOFT"); - if ( this.notif_intr_trig_r .has_reset("HARD" )) this.notif_intr_trig_r .set_reset(this.notif_intr_trig_r .get_reset("HARD"), "SOFT"); -// if ( this.error_internal_intr_count_r .has_reset("HARD" )) this.error_internal_intr_count_r .set_reset(this.error_internal_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error_inv_dev_intr_count_r .has_reset("HARD" )) this.error_inv_dev_intr_count_r .set_reset(this.error_inv_dev_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error_cmd_fail_intr_count_r .has_reset("HARD" )) this.error_cmd_fail_intr_count_r .set_reset(this.error_cmd_fail_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error_bad_fuse_intr_count_r .has_reset("HARD" )) this.error_bad_fuse_intr_count_r .set_reset(this.error_bad_fuse_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error_iccm_blocked_intr_count_r .has_reset("HARD" )) this.error_iccm_blocked_intr_count_r .set_reset(this.error_iccm_blocked_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error_mbox_ecc_unc_intr_count_r .has_reset("HARD" )) this.error_mbox_ecc_unc_intr_count_r .set_reset(this.error_mbox_ecc_unc_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.notif_cmd_avail_intr_count_r .has_reset("HARD" )) this.notif_cmd_avail_intr_count_r .set_reset(this.notif_cmd_avail_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.notif_mbox_ecc_cor_intr_count_r .has_reset("HARD" )) this.notif_mbox_ecc_cor_intr_count_r .set_reset(this.notif_mbox_ecc_cor_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.notif_debug_locked_intr_count_r .has_reset("HARD" )) this.notif_debug_locked_intr_count_r .set_reset(this.notif_debug_locked_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.notif_scan_mode_intr_count_r .has_reset("HARD" )) this.notif_scan_mode_intr_count_r .set_reset(this.notif_scan_mode_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.error_internal_intr_count_incr_r .has_reset("HARD" )) this.error_internal_intr_count_incr_r .set_reset(this.error_internal_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error_inv_dev_intr_count_incr_r .has_reset("HARD" )) this.error_inv_dev_intr_count_incr_r .set_reset(this.error_inv_dev_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error_cmd_fail_intr_count_incr_r .has_reset("HARD" )) this.error_cmd_fail_intr_count_incr_r .set_reset(this.error_cmd_fail_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error_bad_fuse_intr_count_incr_r .has_reset("HARD" )) this.error_bad_fuse_intr_count_incr_r .set_reset(this.error_bad_fuse_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error_iccm_blocked_intr_count_incr_r .has_reset("HARD" )) this.error_iccm_blocked_intr_count_incr_r .set_reset(this.error_iccm_blocked_intr_count_incr_r.get_reset("HARD"), "SOFT"); - if ( this.error_mbox_ecc_unc_intr_count_incr_r .has_reset("HARD" )) this.error_mbox_ecc_unc_intr_count_incr_r .set_reset(this.error_mbox_ecc_unc_intr_count_incr_r.get_reset("HARD"), "SOFT"); - if ( this.notif_cmd_avail_intr_count_incr_r .has_reset("HARD" )) this.notif_cmd_avail_intr_count_incr_r .set_reset(this.notif_cmd_avail_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_mbox_ecc_cor_intr_count_incr_r .has_reset("HARD" )) this.notif_mbox_ecc_cor_intr_count_incr_r .set_reset(this.notif_mbox_ecc_cor_intr_count_incr_r.get_reset("HARD"), "SOFT"); - if ( this.notif_debug_locked_intr_count_incr_r .has_reset("HARD" )) this.notif_debug_locked_intr_count_incr_r .set_reset(this.notif_debug_locked_intr_count_incr_r.get_reset("HARD"), "SOFT"); - if ( this.notif_scan_mode_intr_count_incr_r .has_reset("HARD" )) this.notif_scan_mode_intr_count_incr_r .set_reset(this.notif_scan_mode_intr_count_incr_r .get_reset("HARD"), "SOFT"); + virtual function void configure_reset_values(); + // Track reset configuration against a queue of all registers in this block, to ensure each register is handled + uvm_reg_field blk_flds[$]; + get_fields(blk_flds, UVM_NO_HIER); + `REG____CP_NONCORE_RST(this.global_intr_en_r ) + `REG____CP_NONCORE_RST(this.error_intr_en_r ) + `REG____CP_NONCORE_RST(this.notif_intr_en_r ) + `REG____CP_NONCORE_RST(this.error_global_intr_r ) + `REG____CP_NONCORE_RST(this.notif_global_intr_r ) + `REG_NO_CP_NONCORE_RST(this.error_internal_intr_r ) + `REG____CP_NONCORE_RST(this.notif_internal_intr_r ) + `REG____CP_NONCORE_RST(this.error_intr_trig_r ) + `REG____CP_NONCORE_RST(this.notif_intr_trig_r ) + `REG_NO_CP_NONCORE_RST(this.error_internal_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_inv_dev_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_cmd_fail_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_bad_fuse_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_iccm_blocked_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_mbox_ecc_unc_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_wdt_timer1_timeout_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error_wdt_timer2_timeout_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_cmd_avail_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_mbox_ecc_cor_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_debug_locked_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_scan_mode_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_soc_req_lock_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_gen_in_toggle_intr_count_r ) + `REG____CP_NONCORE_RST(this.error_internal_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_inv_dev_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_cmd_fail_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_bad_fuse_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_iccm_blocked_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_mbox_ecc_unc_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_wdt_timer1_timeout_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error_wdt_timer2_timeout_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_cmd_avail_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_mbox_ecc_cor_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_debug_locked_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_scan_mode_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_soc_req_lock_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_gen_in_toggle_intr_count_incr_r ) + while (blk_flds.size() != 0) begin + uvm_reg_field cur_fld = blk_flds.pop_front(); + `uvm_error("SOC_IFC_REG__INTR_BLOCK_T_EXT", {"No extended reset configuration defined for ", cur_fld.get_full_name()}) + end endfunction virtual function void build(); super.build(); - this.set_soft_reset_values(); + this.configure_reset_values(); this.soc_ifc_reg_intr_AHB_map = create_map("intr_AHB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); this.soc_ifc_reg_intr_APB_map = create_map("intr_APB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); endfunction @@ -148,122 +224,113 @@ package soc_ifc_reg_model_top_pkg; // should never be used in practice rand soc_ifc_reg__intr_block_t_ext intr_block_rf_ext; + // Tracks functional state of Boot FSM internally, without reference to + // the value read from CPTRA_FLOW_STATUS + boot_fn_state_s boot_fn_state_sigs; + + extern virtual function void reset(string kind = "HARD"); function new(string name = "soc_ifc_reg_ext"); super.new(name); + boot_fn_state_sigs = '{boot_idle: 1'b1, default: 1'b0}; endfunction : new // FIXME Manually maintaining a list here of registers that are configured // as soft-resettable (i.e. cptra_rst_b instead of cptra_pwrgood) + // or noncore-resettable (i.e. cptra_noncore_rst_b instead of cptra_pwrgood) // Ideally would be auto-generated. - virtual function void set_soft_reset_values(); - byte ii; -// this.CPTRA_HW_ERROR_FATAL. set_reset(this.CPTRA_HW_ERROR_FATAL. get_reset("HARD"), "SOFT"); -// this.CPTRA_HW_ERROR_NON_FATAL. set_reset(this.CPTRA_HW_ERROR_NON_FATAL. get_reset("HARD"), "SOFT"); -// this.CPTRA_FW_ERROR_FATAL. set_reset(this.CPTRA_FW_ERROR_FATAL. get_reset("HARD"), "SOFT"); -// this.CPTRA_FW_ERROR_NON_FATAL. set_reset(this.CPTRA_FW_ERROR_NON_FATAL. get_reset("HARD"), "SOFT"); -// this.CPTRA_HW_ERROR_ENC. set_reset(this.CPTRA_HW_ERROR_ENC. get_reset("HARD"), "SOFT"); -// this.CPTRA_FW_ERROR_ENC. set_reset(this.CPTRA_FW_ERROR_ENC. get_reset("HARD"), "SOFT"); -// this.CPTRA_FW_EXTENDED_ERROR_INFO[8]. set_reset(this.CPTRA_FW_EXTENDED_ERROR_INFO[8]. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_BOOT_STATUS. has_reset("HARD" )) this.CPTRA_BOOT_STATUS. set_reset(this.CPTRA_BOOT_STATUS. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.status. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.status. set_reset(this.CPTRA_FLOW_STATUS.status. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.idevid_csr_ready. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.idevid_csr_ready. set_reset(this.CPTRA_FLOW_STATUS.idevid_csr_ready. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.boot_fsm_ps. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.boot_fsm_ps. set_reset(this.CPTRA_FLOW_STATUS.boot_fsm_ps. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.ready_for_fw. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.ready_for_fw. set_reset(this.CPTRA_FLOW_STATUS.ready_for_fw. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.ready_for_runtime. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.ready_for_runtime. set_reset(this.CPTRA_FLOW_STATUS.ready_for_runtime. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.ready_for_fuses. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.ready_for_fuses. set_reset(this.CPTRA_FLOW_STATUS.ready_for_fuses. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FLOW_STATUS.mailbox_flow_done. has_reset("HARD" )) this.CPTRA_FLOW_STATUS.mailbox_flow_done. set_reset(this.CPTRA_FLOW_STATUS.mailbox_flow_done. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_RESET_REASON.FW_UPD_RESET. has_reset("HARD" )) this.CPTRA_RESET_REASON.FW_UPD_RESET. set_reset(this.CPTRA_RESET_REASON.FW_UPD_RESET. get_reset("HARD"), "SOFT"); -// this.CPTRA_RESET_REASON.WARM_RESET. set_reset(this.CPTRA_RESET_REASON.WARM_RESET. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_SECURITY_STATE.device_lifecycle.has_reset("HARD" )) this.CPTRA_SECURITY_STATE.device_lifecycle.set_reset(this.CPTRA_SECURITY_STATE.device_lifecycle.get_reset("HARD"), "SOFT"); - if ( this.CPTRA_SECURITY_STATE.debug_locked. has_reset("HARD" )) this.CPTRA_SECURITY_STATE.debug_locked. set_reset(this.CPTRA_SECURITY_STATE.debug_locked. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_SECURITY_STATE.scan_mode. has_reset("HARD" )) this.CPTRA_SECURITY_STATE.scan_mode. set_reset(this.CPTRA_SECURITY_STATE.scan_mode. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_SECURITY_STATE.rsvd. has_reset("HARD" )) this.CPTRA_SECURITY_STATE.rsvd. set_reset(this.CPTRA_SECURITY_STATE.rsvd. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_MBOX_VALID_PAUSER); ii++) begin - if ( this.CPTRA_MBOX_VALID_PAUSER[ii]. has_reset("HARD" )) this.CPTRA_MBOX_VALID_PAUSER[ii]. set_reset(this.CPTRA_MBOX_VALID_PAUSER[ii]. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_MBOX_PAUSER_LOCK[ii]. has_reset("HARD" )) this.CPTRA_MBOX_PAUSER_LOCK[ii]. set_reset(this.CPTRA_MBOX_PAUSER_LOCK[ii]. get_reset("HARD"), "SOFT"); - end - if ( this.CPTRA_TRNG_VALID_PAUSER. has_reset("HARD" )) this.CPTRA_TRNG_VALID_PAUSER. set_reset(this.CPTRA_TRNG_VALID_PAUSER. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_TRNG_PAUSER_LOCK. has_reset("HARD" )) this.CPTRA_TRNG_PAUSER_LOCK. set_reset(this.CPTRA_TRNG_PAUSER_LOCK. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_TRNG_DATA); ii++) begin - if ( this.CPTRA_TRNG_DATA[ii]. has_reset("HARD" )) this.CPTRA_TRNG_DATA[ii]. set_reset(this.CPTRA_TRNG_DATA[ii]. get_reset("HARD"), "SOFT"); - end - if ( this.CPTRA_TRNG_CTRL.clear. has_reset("HARD" )) this.CPTRA_TRNG_CTRL.clear. set_reset(this.CPTRA_TRNG_CTRL.clear. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_TRNG_STATUS.DATA_REQ. has_reset("HARD" )) this.CPTRA_TRNG_STATUS.DATA_REQ. set_reset(this.CPTRA_TRNG_STATUS.DATA_REQ. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_TRNG_STATUS.DATA_WR_DONE. has_reset("HARD" )) this.CPTRA_TRNG_STATUS.DATA_WR_DONE. set_reset(this.CPTRA_TRNG_STATUS.DATA_WR_DONE. get_reset("HARD"), "SOFT"); -// this.CPTRA_FUSE_WR_DONE. set_reset(this.CPTRA_FUSE_WR_DONE. get_reset("HARD"), "SOFT"); -// this.CPTRA_TIMER_CONFIG. set_reset(this.CPTRA_TIMER_CONFIG. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_BOOTFSM_GO. has_reset("HARD" )) this.CPTRA_BOOTFSM_GO. set_reset(this.CPTRA_BOOTFSM_GO. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_DBG_MANUF_SERVICE_REG. has_reset("HARD" )) this.CPTRA_DBG_MANUF_SERVICE_REG. set_reset(this.CPTRA_DBG_MANUF_SERVICE_REG. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_CLK_GATING_EN. has_reset("HARD" )) this.CPTRA_CLK_GATING_EN. set_reset(this.CPTRA_CLK_GATING_EN. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_GENERIC_INPUT_WIRES); ii++) begin - if ( this.CPTRA_GENERIC_INPUT_WIRES[ii]. has_reset("HARD" )) this.CPTRA_GENERIC_INPUT_WIRES[ii]. set_reset(this.CPTRA_GENERIC_INPUT_WIRES[ii]. get_reset("HARD"), "SOFT"); - end - for (ii=0; ii<$size(this.CPTRA_GENERIC_OUTPUT_WIRES); ii++) begin - if ( this.CPTRA_GENERIC_OUTPUT_WIRES[ii]. has_reset("HARD" )) this.CPTRA_GENERIC_OUTPUT_WIRES[ii]. set_reset(this.CPTRA_GENERIC_OUTPUT_WIRES[ii]. get_reset("HARD"), "SOFT"); - end - if ( this.CPTRA_FUSE_VALID_PAUSER. has_reset("HARD" )) this.CPTRA_FUSE_VALID_PAUSER. set_reset(this.CPTRA_FUSE_VALID_PAUSER. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_FUSE_PAUSER_LOCK. has_reset("HARD" )) this.CPTRA_FUSE_PAUSER_LOCK. set_reset(this.CPTRA_FUSE_PAUSER_LOCK. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_HW_REV_ID.CPTRA_GENERATION. has_reset("HARD" )) this.CPTRA_HW_REV_ID.CPTRA_GENERATION. set_reset(this.CPTRA_HW_REV_ID.CPTRA_GENERATION. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_HW_REV_ID.SOC_STEPPING_ID. has_reset("HARD" )) this.CPTRA_HW_REV_ID.SOC_STEPPING_ID. set_reset(this.CPTRA_HW_REV_ID.SOC_STEPPING_ID. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_FW_REV_ID); ii++) begin - if ( this.CPTRA_FW_REV_ID[ii]. has_reset("HARD" )) this.CPTRA_FW_REV_ID[ii]. set_reset(this.CPTRA_FW_REV_ID[ii]. get_reset("HARD"), "SOFT"); - end - if ( this.CPTRA_WDT_TIMER1_EN. has_reset("HARD" )) this.CPTRA_WDT_TIMER1_EN. set_reset(this.CPTRA_WDT_TIMER1_EN. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_WDT_TIMER1_CTRL. has_reset("HARD" )) this.CPTRA_WDT_TIMER1_CTRL. set_reset(this.CPTRA_WDT_TIMER1_CTRL. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD); ii++) begin - if ( this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[ii].has_reset("HARD" )) this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[ii].set_reset(this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[ii]. get_reset("HARD"), "SOFT"); - end - if ( this.CPTRA_WDT_TIMER2_EN. has_reset("HARD" )) this.CPTRA_WDT_TIMER2_EN. set_reset(this.CPTRA_WDT_TIMER2_EN. get_reset("HARD"), "SOFT"); - if ( this.CPTRA_WDT_TIMER2_CTRL. has_reset("HARD" )) this.CPTRA_WDT_TIMER2_CTRL. set_reset(this.CPTRA_WDT_TIMER2_CTRL. get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD); ii++) begin - if ( this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[ii].has_reset("HARD" )) this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[ii].set_reset(this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[ii]. get_reset("HARD"), "SOFT"); + virtual function void configure_reset_values(); + // Track reset configuration against a queue of all fields in this block, to ensure each register is handled + uvm_reg_field blk_flds[$]; + get_fields(blk_flds, UVM_NO_HIER); + `REG_NO_CP_NONCORE_RST(this.CPTRA_HW_ERROR_FATAL ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_HW_ERROR_NON_FATAL ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FW_ERROR_FATAL ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FW_ERROR_NON_FATAL ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_HW_ERROR_ENC ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FW_ERROR_ENC ) + foreach(this.CPTRA_FW_EXTENDED_ERROR_INFO[ii]) `REG_NO_CP_NONCORE_RST(this.CPTRA_FW_EXTENDED_ERROR_INFO[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_BOOT_STATUS ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.status ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.idevid_csr_ready ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.boot_fsm_ps ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.ready_for_fw ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.ready_for_runtime ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.ready_for_fuses ) + `FLD____CP_NONCORE_RST(this.CPTRA_FLOW_STATUS.mailbox_flow_done ) + `FLD____CP_NONCORE_RST(this.CPTRA_RESET_REASON.FW_UPD_RESET ) + `FLD_NO_CP_NONCORE_RST(this.CPTRA_RESET_REASON.WARM_RESET ) + `FLD____CP_NONCORE_RST(this.CPTRA_SECURITY_STATE.device_lifecycle) + `FLD____CP_NONCORE_RST(this.CPTRA_SECURITY_STATE.debug_locked ) + `FLD____CP_NONCORE_RST(this.CPTRA_SECURITY_STATE.scan_mode ) + `FLD____CP_NONCORE_RST(this.CPTRA_SECURITY_STATE.rsvd ) + foreach(this.CPTRA_MBOX_VALID_PAUSER[ii]) `REG____CP_NONCORE_RST(this.CPTRA_MBOX_VALID_PAUSER[ii] ) + foreach(this.CPTRA_MBOX_PAUSER_LOCK[ii]) `REG____CP_NONCORE_RST(this.CPTRA_MBOX_PAUSER_LOCK[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_TRNG_VALID_PAUSER ) + `REG____CP_NONCORE_RST(this.CPTRA_TRNG_PAUSER_LOCK ) + foreach(this.CPTRA_TRNG_DATA[ii]) `REG____CP_NONCORE_RST(this.CPTRA_TRNG_DATA[ii] ) + `FLD____CP_NONCORE_RST(this.CPTRA_TRNG_CTRL.clear ) + `FLD____CP_NONCORE_RST(this.CPTRA_TRNG_STATUS.DATA_REQ ) + `FLD____CP_NONCORE_RST(this.CPTRA_TRNG_STATUS.DATA_WR_DONE ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FUSE_WR_DONE ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_TIMER_CONFIG ) + `REG____CP_NONCORE_RST(this.CPTRA_BOOTFSM_GO ) + `REG____CP_NONCORE_RST(this.CPTRA_DBG_MANUF_SERVICE_REG ) + `REG____CP_NONCORE_RST(this.CPTRA_CLK_GATING_EN ) + foreach(this.CPTRA_GENERIC_INPUT_WIRES[ii]) `REG____CP_NONCORE_RST(this.CPTRA_GENERIC_INPUT_WIRES[ii] ) + foreach(this.CPTRA_GENERIC_OUTPUT_WIRES[ii]) `REG____CP_NONCORE_RST(this.CPTRA_GENERIC_OUTPUT_WIRES[ii] ) + `FLD____CP_NONCORE_RST(this.CPTRA_HW_REV_ID.CPTRA_GENERATION ) + `FLD____CP_NONCORE_RST(this.CPTRA_HW_REV_ID.SOC_STEPPING_ID ) + foreach(this.CPTRA_FW_REV_ID[ii]) `REG____CP_NONCORE_RST(this.CPTRA_FW_REV_ID[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_HW_CONFIG ) + `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER1_EN ) + `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER1_CTRL ) + foreach(this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[ii]) `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER2_EN ) + `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER2_CTRL ) + foreach(this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[ii]) `REG____CP_NONCORE_RST(this.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_WDT_STATUS ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FUSE_VALID_PAUSER ) + `REG_NO_CP_NONCORE_RST(this.CPTRA_FUSE_PAUSER_LOCK ) + foreach(this.CPTRA_WDT_CFG[ii]) `REG_NO_CP_NONCORE_RST(this.CPTRA_WDT_CFG[ii] ) + `REG____CP_NONCORE_RST(this.CPTRA_iTRNG_ENTROPY_CONFIG_0 ) + `REG____CP_NONCORE_RST(this.CPTRA_iTRNG_ENTROPY_CONFIG_1 ) + foreach(this.CPTRA_RSVD_REG[ii]) `REG____CP_NONCORE_RST(this.CPTRA_RSVD_REG[ii] ) + foreach(this.fuse_uds_seed[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_uds_seed[ii] ) + foreach(this.fuse_field_entropy[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_field_entropy[ii] ) + foreach(this.fuse_key_manifest_pk_hash[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_key_manifest_pk_hash[ii] ) + `REG_NO_CP_NONCORE_RST(this.fuse_key_manifest_pk_hash_mask ) + foreach(this.fuse_owner_pk_hash[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_owner_pk_hash[ii] ) + `REG_NO_CP_NONCORE_RST(this.fuse_fmc_key_manifest_svn ) + foreach(this.fuse_runtime_svn[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_runtime_svn[ii] ) + `REG_NO_CP_NONCORE_RST(this.fuse_anti_rollback_disable ) + foreach(this.fuse_idevid_cert_attr[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_idevid_cert_attr[ii] ) + foreach(this.fuse_idevid_manuf_hsm_id[ii]) `REG_NO_CP_NONCORE_RST(this.fuse_idevid_manuf_hsm_id[ii] ) + `REG_NO_CP_NONCORE_RST(this.fuse_life_cycle ) + `REG_NO_CP_NONCORE_RST(this.fuse_lms_verify ) + `REG_NO_CP_NONCORE_RST(this.fuse_lms_revocation ) + `REG_NO_CP_NONCORE_RST(this.fuse_soc_stepping_id ) + foreach(this.internal_obf_key[ii]) `REG_NO_CP_NONCORE_RST(this.internal_obf_key[ii] ) + `REG____CP_NONCORE_RST(this.internal_iccm_lock )/* TODO also FW reset */ + `REG____CP_NONCORE_RST(this.internal_fw_update_reset ) + `REG____CP_NONCORE_RST(this.internal_fw_update_reset_wait_cycles ) + `REG____CP_NONCORE_RST(this.internal_nmi_vector ) + `REG____CP_NONCORE_RST(this.internal_hw_error_fatal_mask ) + `REG____CP_NONCORE_RST(this.internal_hw_error_non_fatal_mask ) + `REG____CP_NONCORE_RST(this.internal_fw_error_fatal_mask ) + `REG____CP_NONCORE_RST(this.internal_fw_error_non_fatal_mask ) + `REG_NO_CP_NONCORE_RST(this.internal_rv_mtime_l ) + `REG_NO_CP_NONCORE_RST(this.internal_rv_mtime_h ) + `REG_NO_CP_NONCORE_RST(this.internal_rv_mtimecmp_l ) + `REG_NO_CP_NONCORE_RST(this.internal_rv_mtimecmp_h ) + while (blk_flds.size() != 0) begin + uvm_reg_field cur_fld = blk_flds.pop_front(); + `uvm_error("SOC_IFC_REG_EXT", {"No extended reset configuration defined for ", cur_fld.get_full_name()}) end - if ( this.CPTRA_WDT_STATUS. has_reset("HARD" )) this.CPTRA_WDT_STATUS. set_reset(this.CPTRA_WDT_STATUS. get_reset("HARD"), "SOFT"); -// for (ii=0; ii<$size(this.fuse_uds_seed); ii++) begin -// if ( this.fuse_uds_seed[ii]. has_reset("HARD" )) this.fuse_uds_seed[ii]. set_reset(this.fuse_uds_seed[ii]. get_reset("HARD"), "SOFT"); -// end -// for (ii=0; ii<$size(this.fuse_field_entropy); ii++) begin -// if ( this.fuse_field_entropy[ii]. has_reset("HARD" )) this.fuse_field_entropy[ii]. set_reset(this.fuse_field_entropy[ii]. get_reset("HARD"), "SOFT"); -// end -// for (ii=0; ii<$size(this.fuse_key_manifest_pk_hash); ii++) begin -// if ( this.fuse_key_manifest_pk_hash[ii]. has_reset("HARD" )) this.fuse_key_manifest_pk_hash[ii]. set_reset(this.fuse_key_manifest_pk_hash[ii]. get_reset("HARD"), "SOFT"); -// end -// if ( this.fuse_key_manifest_pk_hash_mask. has_reset("HARD" )) this.fuse_key_manifest_pk_hash_mask. set_reset(this.fuse_key_manifest_pk_hash_mask. get_reset("HARD"), "SOFT"); -// for (ii=0; ii<$size(this.fuse_owner_pk_hash); ii++) begin -// if ( this.fuse_owner_pk_hash[ii]. has_reset("HARD" )) this.fuse_owner_pk_hash[ii]. set_reset(this.fuse_owner_pk_hash[ii]. get_reset("HARD"), "SOFT"); -// end -// if ( this.fuse_fmc_key_manifest_svn. has_reset("HARD" )) this.fuse_fmc_key_manifest_svn. set_reset(this.fuse_fmc_key_manifest_svn. get_reset("HARD"), "SOFT"); -// for (ii=0; ii<$size(this.fuse_runtime_svn); ii++) begin -// if ( this.fuse_runtime_svn[ii]. has_reset("HARD" )) this.fuse_runtime_svn[ii]. set_reset(this.fuse_runtime_svn[ii]. get_reset("HARD"), "SOFT"); -// end -// if ( this.fuse_anti_rollback_disable. has_reset("HARD" )) this.fuse_anti_rollback_disable. set_reset(this.fuse_anti_rollback_disable. get_reset("HARD"), "SOFT"); -// for (ii=0; ii<$size(this.fuse_idevid_cert_attr); ii++) begin -// if ( this.fuse_idevid_cert_attr[ii]. has_reset("HARD" )) this.fuse_idevid_cert_attr[ii]. set_reset(this.fuse_idevid_cert_attr[ii]. get_reset("HARD"), "SOFT"); -// end -// for (ii=0; ii<$size(this.fuse_idevid_manuf_hsm_id); ii++) begin -// if ( this.fuse_idevid_manuf_hsm_id[ii]. has_reset("HARD" )) this.fuse_idevid_manuf_hsm_id[ii]. set_reset(this.fuse_idevid_manuf_hsm_id[ii]. get_reset("HARD"), "SOFT"); -// end -// if ( this.fuse_life_cycle. has_reset("HARD" )) this.fuse_life_cycle. set_reset(this.fuse_life_cycle. get_reset("HARD"), "SOFT"); -// for (ii=0; ii<$size(this.internal_obf_key); ii++) begin -// if ( this.internal_obf_key[ii]. has_reset("HARD" )) this.internal_obf_key[ii]. set_reset(this.internal_obf_key[ii]. get_reset("HARD"), "SOFT"); /* requires manual prediction based on a set of reset conditions */ -// end - if ( this.internal_iccm_lock. has_reset("HARD" )) this.internal_iccm_lock. set_reset(this.internal_iccm_lock. get_reset("HARD"), "SOFT"); /* TODO also FW reset */ - if ( this.internal_fw_update_reset. has_reset("HARD" )) this.internal_fw_update_reset. set_reset(this.internal_fw_update_reset. get_reset("HARD"), "SOFT"); - if ( this.internal_fw_update_reset_wait_cycles. has_reset("HARD" )) this.internal_fw_update_reset_wait_cycles. set_reset(this.internal_fw_update_reset_wait_cycles. get_reset("HARD"), "SOFT"); - if ( this.internal_nmi_vector. has_reset("HARD" )) this.internal_nmi_vector. set_reset(this.internal_nmi_vector. get_reset("HARD"), "SOFT"); - if ( this.internal_hw_error_fatal_mask. has_reset("HARD" )) this.internal_hw_error_fatal_mask. set_reset(this.internal_hw_error_fatal_mask. get_reset("HARD"), "SOFT"); - if ( this.internal_hw_error_non_fatal_mask. has_reset("HARD" )) this.internal_hw_error_non_fatal_mask. set_reset(this.internal_hw_error_non_fatal_mask. get_reset("HARD"), "SOFT"); - if ( this.internal_fw_error_fatal_mask. has_reset("HARD" )) this.internal_fw_error_fatal_mask. set_reset(this.internal_fw_error_fatal_mask. get_reset("HARD"), "SOFT"); - if ( this.internal_fw_error_non_fatal_mask. has_reset("HARD" )) this.internal_fw_error_non_fatal_mask. set_reset(this.internal_fw_error_non_fatal_mask. get_reset("HARD"), "SOFT"); -// if ( this.internal_mtime_l. has_reset("HARD" )) this.internal_mtime_l. set_reset(this.internal_mtime_l. get_reset("HARD"), "SOFT"); -// if ( this.internal_mtime_h. has_reset("HARD" )) this.internal_mtime_h. set_reset(this.internal_mtime_h. get_reset("HARD"), "SOFT"); -// if ( this.internal_mtimecmp_l. has_reset("HARD" )) this.internal_mtimecmp_l. set_reset(this.internal_mtimecmp_l. get_reset("HARD"), "SOFT"); -// if ( this.internal_mtimecmp_h. has_reset("HARD" )) this.internal_mtimecmp_h. set_reset(this.internal_mtimecmp_h. get_reset("HARD"), "SOFT"); endfunction virtual function void build(); super.build(); - this.set_soft_reset_values(); + this.configure_reset_values(); this.intr_block_rf_ext = new("intr_block_rf_ext"); this.intr_block_rf_ext.configure(this); this.intr_block_rf_ext.build(); // This configures the default_map, which is used to find reg offsets for other maps @@ -302,6 +369,16 @@ package soc_ifc_reg_model_top_pkg; endclass : soc_ifc_reg_ext + function void soc_ifc_reg_ext::reset(string kind = "HARD"); + super.reset(kind); + // BOOT FSM State Changes + // "NONCORE" does not cause a state change - it results FROM state changes + // TODO what to do for FW update? + if (kind inside {"HARD", "SOFT"}) begin + boot_fn_state_sigs = '{boot_idle: 1'b1, default: 1'b0}; + end + endfunction + class mbox_csr_ext extends mbox_csr; uvm_reg_map mbox_csr_AHB_map; uvm_reg_map mbox_csr_APB_map; @@ -330,22 +407,30 @@ package soc_ifc_reg_model_top_pkg; // FIXME Manually maintaining a list here of registers that are configured // as soft-resettable (i.e. cptra_rst_b instead of cptra_pwrgood) + // or noncore-resettable (i.e. cptra_noncore_rst_b instead of cptra_pwrgood) // Ideally would be auto-generated. - virtual function void set_soft_reset_values(); - if ( this.mbox_lock .has_reset("HARD" )) this.mbox_lock .set_reset(this.mbox_lock .get_reset("HARD"), "SOFT"); - if ( this.mbox_user .has_reset("HARD" )) this.mbox_user .set_reset(this.mbox_user .get_reset("HARD"), "SOFT"); - if ( this.mbox_cmd .has_reset("HARD" )) this.mbox_cmd .set_reset(this.mbox_cmd .get_reset("HARD"), "SOFT"); - if ( this.mbox_dlen .has_reset("HARD" )) this.mbox_dlen .set_reset(this.mbox_dlen .get_reset("HARD"), "SOFT"); - if ( this.mbox_datain .has_reset("HARD" )) this.mbox_datain .set_reset(this.mbox_datain .get_reset("HARD"), "SOFT"); - if ( this.mbox_dataout.has_reset("HARD" )) this.mbox_dataout.set_reset(this.mbox_dataout.get_reset("HARD"), "SOFT"); - if ( this.mbox_execute.has_reset("HARD" )) this.mbox_execute.set_reset(this.mbox_execute.get_reset("HARD"), "SOFT"); - if ( this.mbox_status .has_reset("HARD" )) this.mbox_status .set_reset(this.mbox_status .get_reset("HARD"), "SOFT"); - if ( this.mbox_unlock .has_reset("HARD" )) this.mbox_unlock .set_reset(this.mbox_unlock .get_reset("HARD"), "SOFT"); + virtual function void configure_reset_values(); + // Track reset configuration against a queue of all registers in this block, to ensure each register is handled + uvm_reg_field blk_flds[$]; + get_fields(blk_flds, UVM_NO_HIER); + `REG____CP_NONCORE_RST(this.mbox_lock ) + `REG____CP_NONCORE_RST(this.mbox_user ) + `REG____CP_NONCORE_RST(this.mbox_cmd ) + `REG____CP_NONCORE_RST(this.mbox_dlen ) + `REG____CP_NONCORE_RST(this.mbox_datain ) + `REG____CP_NONCORE_RST(this.mbox_dataout) + `REG____CP_NONCORE_RST(this.mbox_execute) + `REG____CP_NONCORE_RST(this.mbox_status ) + `REG____CP_NONCORE_RST(this.mbox_unlock ) + while (blk_flds.size() != 0) begin + uvm_reg_field cur_fld = blk_flds.pop_front(); + `uvm_error("MBOX_CSR_EXT", {"No extended reset configuration defined for ", cur_fld.get_full_name()}) + end endfunction virtual function void build(); super.build(); - this.set_soft_reset_values(); + this.configure_reset_values(); this.mbox_csr_AHB_map = create_map("AHB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); this.mbox_csr_APB_map = create_map("APB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); endfunction @@ -366,14 +451,19 @@ package soc_ifc_reg_model_top_pkg; function void mbox_csr_ext::reset(string kind = "HARD"); super.reset(kind); - mbox_data_q.delete(); - mbox_resp_q.delete(); - mbox_lock_clr_miss.reset(); - mbox_datain_to_dataout_predict.reset(); - - // Mailbox State Changes - // TODO what to do for FW update? - mbox_fn_state_sigs = '{mbox_idle: 1'b1, default: 1'b0}; + // "SOFT" reset doesn't impact mbox registers until it propagates to the NONCORE reset. + // Since there's a delay, wait until the NONCORE reset is called to clobber data queues and + // reg model internal semaphores + if (kind inside {"HARD", "NONCORE"}) begin + mbox_data_q.delete(); + mbox_resp_q.delete(); + mbox_lock_clr_miss.reset(); + mbox_datain_to_dataout_predict.reset(); + + // Mailbox State Changes + // TODO what to do for FW update? + mbox_fn_state_sigs = '{mbox_idle: 1'b1, default: 1'b0}; + end endfunction @@ -381,38 +471,51 @@ package soc_ifc_reg_model_top_pkg; uvm_reg_map sha512_acc_csr_intr_AHB_map; uvm_reg_map sha512_acc_csr_intr_APB_map; + // HWSET has precedence over SW W1C, so use these variables to track + // active hwset activity in case contention must be resolved + bit [31:0] notif_internal_intr_r_hwset_active = 0; + bit [31:0] error_internal_intr_r_hwset_active = 0; + function new(string name = "sha512_acc_csr__intr_block_t_ext"); super.new(name); endfunction : new // FIXME Manually maintaining a list here of registers that are configured // as soft-resettable (i.e. cptra_rst_b instead of cptra_pwrgood) + // or noncore-resettable (i.e. cptra_noncore_rst_b instead of cptra_pwrgood) // Ideally would be auto-generated. - virtual function void set_soft_reset_values(); - if ( this.global_intr_en_r .has_reset("HARD" )) this.global_intr_en_r .set_reset(this.global_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.error_intr_en_r .has_reset("HARD" )) this.error_intr_en_r .set_reset(this.error_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.notif_intr_en_r .has_reset("HARD" )) this.notif_intr_en_r .set_reset(this.notif_intr_en_r .get_reset("HARD"), "SOFT"); - if ( this.error_global_intr_r .has_reset("HARD" )) this.error_global_intr_r .set_reset(this.error_global_intr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_global_intr_r .has_reset("HARD" )) this.notif_global_intr_r .set_reset(this.notif_global_intr_r .get_reset("HARD"), "SOFT"); -// this.error_internal_intr_r .set_reset(this.error_internal_intr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_internal_intr_r .has_reset("HARD" )) this.notif_internal_intr_r .set_reset(this.notif_internal_intr_r .get_reset("HARD"), "SOFT"); - if ( this.error_intr_trig_r .has_reset("HARD" )) this.error_intr_trig_r .set_reset(this.error_intr_trig_r .get_reset("HARD"), "SOFT"); - if ( this.notif_intr_trig_r .has_reset("HARD" )) this.notif_intr_trig_r .set_reset(this.notif_intr_trig_r .get_reset("HARD"), "SOFT"); -// if ( this.error0_intr_count_r .has_reset("HARD" )) this.error0_intr_count_r .set_reset(this.error0_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error1_intr_count_r .has_reset("HARD" )) this.error1_intr_count_r .set_reset(this.error1_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error2_intr_count_r .has_reset("HARD" )) this.error2_intr_count_r .set_reset(this.error2_intr_count_r .get_reset("HARD"), "SOFT"); -// if ( this.error3_intr_count_r .has_reset("HARD" )) this.error3_intr_count_r .set_reset(this.error3_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.notif_cmd_done_intr_count_r .has_reset("HARD" )) this.notif_cmd_done_intr_count_r .set_reset(this.notif_cmd_done_intr_count_r .get_reset("HARD"), "SOFT"); - if ( this.error0_intr_count_incr_r .has_reset("HARD" )) this.error0_intr_count_incr_r .set_reset(this.error0_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error1_intr_count_incr_r .has_reset("HARD" )) this.error1_intr_count_incr_r .set_reset(this.error1_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error2_intr_count_incr_r .has_reset("HARD" )) this.error2_intr_count_incr_r .set_reset(this.error2_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.error3_intr_count_incr_r .has_reset("HARD" )) this.error3_intr_count_incr_r .set_reset(this.error3_intr_count_incr_r .get_reset("HARD"), "SOFT"); - if ( this.notif_cmd_done_intr_count_incr_r .has_reset("HARD" )) this.notif_cmd_done_intr_count_incr_r .set_reset(this.notif_cmd_done_intr_count_incr_r .get_reset("HARD"), "SOFT"); + virtual function void configure_reset_values(); + // Track reset configuration against a queue of all registers in this block, to ensure each register is handled + uvm_reg_field blk_flds[$]; + get_fields(blk_flds, UVM_NO_HIER); + `REG____CP_NONCORE_RST(this.global_intr_en_r ) + `REG____CP_NONCORE_RST(this.error_intr_en_r ) + `REG____CP_NONCORE_RST(this.notif_intr_en_r ) + `REG____CP_NONCORE_RST(this.error_global_intr_r ) + `REG____CP_NONCORE_RST(this.notif_global_intr_r ) + `REG_NO_CP_NONCORE_RST(this.error_internal_intr_r ) + `REG____CP_NONCORE_RST(this.notif_internal_intr_r ) + `REG____CP_NONCORE_RST(this.error_intr_trig_r ) + `REG____CP_NONCORE_RST(this.notif_intr_trig_r ) + `REG_NO_CP_NONCORE_RST(this.error0_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error1_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error2_intr_count_r ) + `REG_NO_CP_NONCORE_RST(this.error3_intr_count_r ) + `REG____CP_NONCORE_RST(this.notif_cmd_done_intr_count_r ) + `REG____CP_NONCORE_RST(this.error0_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error1_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error2_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.error3_intr_count_incr_r ) + `REG____CP_NONCORE_RST(this.notif_cmd_done_intr_count_incr_r ) + while (blk_flds.size() != 0) begin + uvm_reg_field cur_fld = blk_flds.pop_front(); + `uvm_error("SHA512_ACC_CSR__INTR_BLOCK_T_EXT", {"No extended reset configuration defined for ", cur_fld.get_full_name()}) + end endfunction virtual function void build(); super.build(); - this.set_soft_reset_values(); + this.configure_reset_values(); this.sha512_acc_csr_intr_AHB_map = create_map("intr_AHB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); this.sha512_acc_csr_intr_APB_map = create_map("intr_APB_reg_map", 0, 4, UVM_LITTLE_ENDIAN); endfunction @@ -451,26 +554,31 @@ package soc_ifc_reg_model_top_pkg; // FIXME Manually maintaining a list here of registers that are configured // as soft-resettable (i.e. cptra_rst_b instead of cptra_pwrgood) + // or noncore-resettable (i.e. cptra_noncore_rst_b instead of cptra_pwrgood) // Ideally would be auto-generated. - virtual function void set_soft_reset_values(); - byte ii; - if ( this.LOCK .has_reset("HARD" )) this.LOCK .set_reset(this.LOCK .get_reset("HARD"), "SOFT"); - if ( this.USER .has_reset("HARD" )) this.USER .set_reset(this.USER .get_reset("HARD"), "SOFT"); - if ( this.MODE .has_reset("HARD" )) this.MODE .set_reset(this.MODE .get_reset("HARD"), "SOFT"); - if ( this.START_ADDRESS .has_reset("HARD" )) this.START_ADDRESS .set_reset(this.START_ADDRESS .get_reset("HARD"), "SOFT"); - if ( this.DLEN .has_reset("HARD" )) this.DLEN .set_reset(this.DLEN .get_reset("HARD"), "SOFT"); - if ( this.DATAIN .has_reset("HARD" )) this.DATAIN .set_reset(this.DATAIN .get_reset("HARD"), "SOFT"); - if ( this.EXECUTE .has_reset("HARD" )) this.EXECUTE .set_reset(this.EXECUTE .get_reset("HARD"), "SOFT"); - if ( this.STATUS .has_reset("HARD" )) this.STATUS .set_reset(this.STATUS .get_reset("HARD"), "SOFT"); - for (ii=0; ii<$size(this.DIGEST); ii++) begin - if ( this.DIGEST[ii] .has_reset("HARD" )) this.DIGEST[ii] .set_reset(this.DIGEST[ii] .get_reset("HARD"), "SOFT"); + virtual function void configure_reset_values(); + // Track reset configuration against a queue of all fields in this block, to ensure each register is handled + uvm_reg_field blk_flds[$]; + get_fields(blk_flds, UVM_NO_HIER); + `REG____CP_NONCORE_RST(this.LOCK ) + `REG____CP_NONCORE_RST(this.USER ) + `REG____CP_NONCORE_RST(this.MODE ) + `REG____CP_NONCORE_RST(this.START_ADDRESS ) + `REG____CP_NONCORE_RST(this.DLEN ) + `REG____CP_NONCORE_RST(this.DATAIN ) + `REG____CP_NONCORE_RST(this.EXECUTE ) + `REG____CP_NONCORE_RST(this.STATUS ) + foreach(this.DIGEST[ii]) `REG____CP_NONCORE_RST(this.DIGEST[ii] ) + `REG____CP_NONCORE_RST(this.CONTROL ) + while (blk_flds.size() != 0) begin + uvm_reg_field cur_fld = blk_flds.pop_front(); + `uvm_error("SHA512_ACC_CSR_EXT", {"No extended reset configuration defined for ", cur_fld.get_full_name()}) end - if ( this.CONTROL .has_reset("HARD" )) this.CONTROL .set_reset(this.CONTROL .get_reset("HARD"), "SOFT"); endfunction virtual function void build(); super.build(); - this.set_soft_reset_values(); + this.configure_reset_values(); this.intr_block_rf_ext = new("intr_block_rf_ext"); this.intr_block_rf_ext.configure(this); this.intr_block_rf_ext.build(); // This configures the default_map, which is used to find reg offsets for other maps @@ -533,6 +641,7 @@ package soc_ifc_reg_model_top_pkg; `include "soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base.svh" `include "soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base.svh" `include "soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base.svh" + `include "soc_ifc_reg_cbs_intr_block_rf_ext_internal.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_HW_ERROR_FATAL.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_HW_ERROR_NON_FATAL.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_DATA_DATA.svh" @@ -541,6 +650,8 @@ package soc_ifc_reg_model_top_pkg; `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER.svh" + `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART.svh" + `include "soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_secret.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_fuse.svh" `include "soc_ifc_reg_cbs_soc_ifc_reg_key.svh" @@ -653,6 +764,7 @@ package soc_ifc_reg_model_top_pkg; soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base soc_ifc_reg_intr_block_rf_ext_notif_internal_intr_r_base_cb; soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base soc_ifc_reg_intr_block_rf_ext_notif_intr_en_r_base_cb; soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base soc_ifc_reg_intr_block_rf_ext_notif_intr_trig_r_base_cb; + soc_ifc_reg_cbs_intr_block_rf_ext_internal soc_ifc_reg_intr_block_rf_ext_internal_cb; soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base sha512_acc_csr_intr_block_rf_ext_global_intr_en_r_base_cb; soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base sha512_acc_csr_intr_block_rf_ext_error_internal_intr_r_base_cb; @@ -661,6 +773,8 @@ package soc_ifc_reg_model_top_pkg; soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base sha512_acc_csr_intr_block_rf_ext_notif_internal_intr_r_base_cb; soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base sha512_acc_csr_intr_block_rf_ext_notif_intr_en_r_base_cb; soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base sha512_acc_csr_intr_block_rf_ext_notif_intr_trig_r_base_cb; + soc_ifc_reg_cbs_intr_block_rf_ext_internal sha512_acc_csr_intr_block_rf_ext_internal_cb; + soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock mbox_csr_mbox_lock_lock_cb; soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command mbox_csr_mbox_cmd_command_cb; @@ -680,6 +794,8 @@ package soc_ifc_reg_model_top_pkg; soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ_cb; soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE_cb; soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER_cb; + soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_cb; + soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_cb; soc_ifc_reg_cbs_soc_ifc_reg_secret soc_ifc_reg_secret_cb; soc_ifc_reg_cbs_soc_ifc_reg_fuse soc_ifc_reg_fuse_cb; @@ -759,6 +875,7 @@ package soc_ifc_reg_model_top_pkg; soc_ifc_reg_intr_block_rf_ext_notif_internal_intr_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base::type_id::create("soc_ifc_reg_intr_block_rf_ext_notif_internal_intr_r_base_cb"); soc_ifc_reg_intr_block_rf_ext_notif_intr_en_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base ::type_id::create("soc_ifc_reg_intr_block_rf_ext_notif_intr_en_r_base_cb" ); soc_ifc_reg_intr_block_rf_ext_notif_intr_trig_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base ::type_id::create("soc_ifc_reg_intr_block_rf_ext_notif_intr_trig_r_base_cb" ); + soc_ifc_reg_intr_block_rf_ext_internal_cb = soc_ifc_reg_cbs_intr_block_rf_ext_internal ::type_id::create("soc_ifc_reg_intr_block_rf_ext_internal_cb" ); sha512_acc_csr_intr_block_rf_ext_global_intr_en_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_global_intr_en_r_base ::type_id::create("sha512_acc_csr_intr_block_rf_ext_global_intr_en_r_base_cb" ); sha512_acc_csr_intr_block_rf_ext_error_internal_intr_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_error_internal_intr_r_base::type_id::create("sha512_acc_csr_intr_block_rf_ext_error_internal_intr_r_base_cb"); @@ -767,6 +884,7 @@ package soc_ifc_reg_model_top_pkg; sha512_acc_csr_intr_block_rf_ext_notif_internal_intr_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_internal_intr_r_base::type_id::create("sha512_acc_csr_intr_block_rf_ext_notif_internal_intr_r_base_cb"); sha512_acc_csr_intr_block_rf_ext_notif_intr_en_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_en_r_base ::type_id::create("sha512_acc_csr_intr_block_rf_ext_notif_intr_en_r_base_cb" ); sha512_acc_csr_intr_block_rf_ext_notif_intr_trig_r_base_cb = soc_ifc_reg_cbs_intr_block_rf_ext_notif_intr_trig_r_base ::type_id::create("sha512_acc_csr_intr_block_rf_ext_notif_intr_trig_r_base_cb" ); + sha512_acc_csr_intr_block_rf_ext_internal_cb = soc_ifc_reg_cbs_intr_block_rf_ext_internal ::type_id::create("sha512_acc_csr_intr_block_rf_ext_internal_cb" ); mbox_csr_mbox_lock_lock_cb = soc_ifc_reg_cbs_mbox_csr_mbox_lock_lock ::type_id::create("mbox_csr_mbox_lock_lock_cb" ); mbox_csr_mbox_cmd_command_cb = soc_ifc_reg_cbs_mbox_csr_mbox_cmd_command ::type_id::create("mbox_csr_mbox_cmd_command_cb" ); @@ -786,6 +904,8 @@ package soc_ifc_reg_model_top_pkg; soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ_cb = soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ ::type_id::create("soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_REQ_cb" ); soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE_cb = soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE::type_id::create("soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE_cb"); soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER_cb = soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER::type_id::create("soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER_cb"); + soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_cb = soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART::type_id::create("soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_cb"); + soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_cb = soc_ifc_reg_cbs_soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART::type_id::create("soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_cb"); soc_ifc_reg_secret_cb = soc_ifc_reg_cbs_soc_ifc_reg_secret ::type_id::create("soc_ifc_reg_secret_cb"); soc_ifc_reg_fuse_cb = soc_ifc_reg_cbs_soc_ifc_reg_fuse ::type_id::create("soc_ifc_reg_fuse_cb"); @@ -818,6 +938,34 @@ package soc_ifc_reg_model_top_pkg; foreach (notif_sts_flds [ii]) uvm_reg_field_cb::add(notif_sts_flds [ii], soc_ifc_reg_intr_block_rf_ext_notif_internal_intr_r_base_cb); foreach (error_trig_flds[ii]) uvm_reg_field_cb::add(error_trig_flds[ii], soc_ifc_reg_intr_block_rf_ext_error_intr_trig_r_base_cb ); foreach (notif_trig_flds[ii]) uvm_reg_field_cb::add(notif_trig_flds[ii], soc_ifc_reg_intr_block_rf_ext_notif_intr_trig_r_base_cb ); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_inv_dev_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_cmd_fail_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_bad_fuse_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_iccm_blocked_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_mbox_ecc_unc_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_wdt_timer1_timeout_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_wdt_timer2_timeout_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_cmd_avail_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_mbox_ecc_cor_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_debug_locked_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_scan_mode_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_soc_req_lock_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_gen_in_toggle_intr_count_r .cnt, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_inv_dev_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_cmd_fail_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_bad_fuse_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_iccm_blocked_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_mbox_ecc_unc_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_wdt_timer1_timeout_intr_count_incr_r.pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.error_wdt_timer2_timeout_intr_count_incr_r.pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_cmd_avail_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_mbox_ecc_cor_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_debug_locked_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_scan_mode_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_soc_req_lock_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.soc_ifc_reg_rm.intr_block_rf_ext.notif_gen_in_toggle_intr_count_incr_r .pulse, soc_ifc_reg_intr_block_rf_ext_internal_cb); /* -- sha512_acc_csr interrupts -- */ uvm_reg_field_cb::add(sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.error_en, sha512_acc_csr_intr_block_rf_ext_global_intr_en_r_base_cb ); @@ -840,6 +988,16 @@ package soc_ifc_reg_model_top_pkg; foreach (notif_sts_flds [ii]) uvm_reg_field_cb::add(notif_sts_flds [ii], sha512_acc_csr_intr_block_rf_ext_notif_internal_intr_r_base_cb); foreach (error_trig_flds[ii]) uvm_reg_field_cb::add(error_trig_flds[ii], sha512_acc_csr_intr_block_rf_ext_error_intr_trig_r_base_cb ); foreach (notif_trig_flds[ii]) uvm_reg_field_cb::add(notif_trig_flds[ii], sha512_acc_csr_intr_block_rf_ext_notif_intr_trig_r_base_cb ); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error0_intr_count_r .cnt, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error1_intr_count_r .cnt, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error2_intr_count_r .cnt, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error3_intr_count_r .cnt, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.notif_cmd_done_intr_count_r .cnt, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error0_intr_count_incr_r .pulse, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error1_intr_count_incr_r .pulse, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error2_intr_count_incr_r .pulse, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.error3_intr_count_incr_r .pulse, sha512_acc_csr_intr_block_rf_ext_internal_cb); + uvm_reg_field_cb::add(this.sha512_acc_csr_rm.intr_block_rf_ext.notif_cmd_done_intr_count_incr_r .pulse, sha512_acc_csr_intr_block_rf_ext_internal_cb); /* -- mbox_csr -- */ uvm_reg_field_cb::add(mbox_csr_rm.mbox_lock .lock , mbox_csr_mbox_lock_lock_cb ); @@ -867,6 +1025,8 @@ package soc_ifc_reg_model_top_pkg; uvm_reg_field_cb::add(soc_ifc_reg_rm.CPTRA_TRNG_STATUS .DATA_WR_DONE, soc_ifc_reg_CPTRA_TRNG_STATUS_DATA_WR_DONE_cb ); uvm_reg_field_cb::add(soc_ifc_reg_rm.CPTRA_TRNG_VALID_PAUSER .PAUSER , soc_ifc_reg_CPTRA_TRNG_VALID_PAUSER_PAUSER_cb ); uvm_reg_field_cb::add(soc_ifc_reg_rm.CPTRA_TRNG_CTRL .clear , soc_ifc_reg_CPTRA_TRNG_CTRL_CLEAR_cb ); + uvm_reg_field_cb::add(soc_ifc_reg_rm.CPTRA_WDT_TIMER1_CTRL .timer1_restart, soc_ifc_reg_CPTRA_WDT_TIMER1_CTRL_TIMER1_RESTART_cb ); + uvm_reg_field_cb::add(soc_ifc_reg_rm.CPTRA_WDT_TIMER2_CTRL .timer2_restart, soc_ifc_reg_CPTRA_WDT_TIMER2_CTRL_TIMER2_RESTART_cb ); foreach (soc_ifc_reg_rm.fuse_uds_seed[ii]) uvm_reg_field_cb::add(soc_ifc_reg_rm.fuse_uds_seed[ii].seed , soc_ifc_reg_secret_cb); foreach (soc_ifc_reg_rm.fuse_field_entropy[ii]) uvm_reg_field_cb::add(soc_ifc_reg_rm.fuse_field_entropy[ii].seed , soc_ifc_reg_secret_cb); @@ -885,6 +1045,10 @@ package soc_ifc_reg_model_top_pkg; foreach (soc_ifc_reg_rm.internal_obf_key[ii]) uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_obf_key[ii].key , soc_ifc_reg_key_cb); uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_iccm_lock.lock , soc_ifc_reg_internal_cb); uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_fw_update_reset.core_rst , soc_ifc_reg_internal_fw_update_reset_cb) ; + uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_rv_mtime_l.count_l , soc_ifc_reg_internal_cb); + uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_rv_mtime_h.count_h , soc_ifc_reg_internal_cb); + uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_rv_mtimecmp_l.compare_l , soc_ifc_reg_internal_cb); + uvm_reg_field_cb::add(soc_ifc_reg_rm.internal_rv_mtimecmp_h.compare_h , soc_ifc_reg_internal_cb); /* -- sha512_acc_csr -- */ uvm_reg_field_cb::add(sha512_acc_csr_rm.LOCK.LOCK, sha512_acc_csr_LOCK_LOCK_cb); uvm_reg_field_cb::add(sha512_acc_csr_rm.EXECUTE.EXECUTE, sha512_acc_csr_EXECUTE_EXECUTE_cb); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/cptra/soc_ifc_env_cptra_init_interrupts_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/cptra/soc_ifc_env_cptra_init_interrupts_sequence.svh new file mode 100644 index 000000000..e830f1173 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/cptra/soc_ifc_env_cptra_init_interrupts_sequence.svh @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initialize Caliptra SOC_IFC interrupts +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_cptra_init_interrupts_sequence extends soc_ifc_env_sequence_base #(.CONFIG_T(soc_ifc_env_configuration_t)); + + + `uvm_object_utils( soc_ifc_env_cptra_init_interrupts_sequence ); + + + uvm_status_e reg_sts; + + function new(string name = "" ); + super.new(name); + + endfunction + + virtual task body(); + + uvm_reg_data_t data; + uvm_reg_field flds[$]; + int sts_rsp_count = 0; + reg_model = configuration.soc_ifc_rm; + + if (cptra_status_agent_rsp_seq == null) + `uvm_fatal("CPTRA_INIT_INTR", "SOC_IFC ENV caliptra reset wait sequence expected a handle to the cptra status agent responder sequence (from bench-level sequence) but got null!") + fork + forever begin + @(cptra_status_agent_rsp_seq.new_rsp) sts_rsp_count++; + end + join_none + + // Clear debug locked interrupt + data = (uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_debug_locked_sts.get_lsb_pos()); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + + // Interrupt Enable (Global) + data = (uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_lsb_pos()) | + (uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_lsb_pos()); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + if (reg_sts != UVM_IS_OK) + `uvm_error("CPTRA_INIT_INTR", $sformatf("Register access failed (%s)", "global_intr_en_r")) + + // Interrupt Enable (Errors) + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_intr_en_r.get_fields(flds); + data = 0; + foreach (flds[ii]) data |= (uvm_reg_data_t'(1) << flds[ii].get_lsb_pos()); + flds.delete(); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_intr_en_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + if (reg_sts != UVM_IS_OK) + `uvm_error("CPTRA_INIT_INTR", $sformatf("Register access failed (%s)", "error_intr_en_r")) + + // Interrupt Enable (Notifications) + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_intr_en_r.get_fields(flds); + data = 0; + foreach (flds[ii]) data |= (uvm_reg_data_t'(1) << flds[ii].get_lsb_pos()); + flds.delete(); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_intr_en_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + if (reg_sts != UVM_IS_OK) + `uvm_error("CPTRA_INIT_INTR", $sformatf("Register access failed (%s)", "notif_intr_en_r")) + + endtask + +endclass diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh index 4feed95b4..5253bd642 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_reset_sequence_base.svh @@ -36,18 +36,24 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI caliptra_apb_user apb_user_obj; typedef struct packed { - bit set_bootfsm_breakpoint; + bit set_bootfsm_breakpoint; + security_state_t security_state; } ctrl_reset_seq_context_t; rand uvm_reg_data_t uds_seed_rand [12]; rand uvm_reg_data_t field_entropy_rand [32]; + rand uvm_reg_data_t owner_pk_hash_rand [12]; + rand uvm_reg_data_t key_manifest_pk_hash_rand [12]; rand uvm_reg_data_t idevid_cert_attr_rand [24]; rand uvm_reg_data_t soc_stepping_id_rand; rand struct packed { bit uds; bit field_entropy; + bit [0:11] key_manifest_pk_hash; + bit [0:11] owner_pk_hash; bit soc_stepping_id; bit [0:23] idevid_cert_attr; + bit lms_verify; } fuses_to_set; @@ -75,6 +81,7 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI else `uvm_error("SOC_IFC_RST", "soc_ifc_ctrl_agent_config.sequencer is null!") ctx.set_bootfsm_breakpoint = soc_ifc_ctrl_seq.set_bootfsm_breakpoint; + ctx.security_state = soc_ifc_ctrl_seq.security_state; endtask @@ -95,16 +102,18 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI end join_none - wait(sts_rsp_count > 0); - `uvm_info("SOC_IFC_RST", "Received response from status agent", UVM_MEDIUM) - if (sts_rsp_count > 1) - `uvm_error("SOC_IFC_RST", "Missed response activity during reset sequence") - fuse_ready = soc_ifc_status_agent_rsp_seq.rsp.ready_for_fuses; - sts_rsp_count--; - if (!fuse_ready) - `uvm_error("SOC_IFC_RST", "Unexpected status transition while waiting for Mailbox readiness for fuses") - else - `uvm_info("SOC_IFC_RST", "Fuse ready, initiating fuse download", UVM_LOW) + while (!fuse_ready) begin + wait(sts_rsp_count > 0); + `uvm_info("SOC_IFC_RST", "Received response from status agent", UVM_MEDIUM) + if (sts_rsp_count > 1) + `uvm_error("SOC_IFC_RST", "Missed response activity during reset sequence") + fuse_ready = soc_ifc_status_agent_rsp_seq.rsp.ready_for_fuses; + sts_rsp_count--; + if (!fuse_ready) + `uvm_info("SOC_IFC_RST", "Received status transition while waiting for Mailbox ready_for_fuses, ready_for_fuses still not set", UVM_MEDIUM) + else + `uvm_info("SOC_IFC_RST", $sformatf("Fuse ready, initiating fuse download with fuses_to_set: [%p]", this.fuses_to_set), UVM_LOW) + end // Write UDS if (this.fuses_to_set.uds) begin @@ -124,6 +133,24 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI end end + // Key Manifest PK Hash (Vendor) + foreach (this.fuses_to_set.key_manifest_pk_hash[ii]) begin + if (this.fuses_to_set.key_manifest_pk_hash[ii]) begin + `uvm_info("SOC_IFC_RST", $sformatf("Writing Key Manifest PK Hash [%d] to fuse bank with value 0x%0x", ii, key_manifest_pk_hash_rand[ii]), UVM_LOW) + reg_model.soc_ifc_reg_rm.fuse_key_manifest_pk_hash[ii].write(sts, key_manifest_pk_hash_rand[ii], UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", $sformatf("Failed when writing to Key Manifest PK Hash [%d]", ii)) + end + end + + // Owner PK Hash + foreach (this.fuses_to_set.owner_pk_hash[ii]) begin + if (this.fuses_to_set.owner_pk_hash[ii]) begin + `uvm_info("SOC_IFC_RST", $sformatf("Writing Owner PK Hash [%d] to fuse bank with value 0x%0x", ii, owner_pk_hash_rand[ii]), UVM_LOW) + reg_model.soc_ifc_reg_rm.fuse_owner_pk_hash[ii].write(sts, owner_pk_hash_rand[ii], UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", $sformatf("Failed when writing to Owner PK Hash [%d]", ii)) + end + end + // Write SoC Stepping ID if (this.fuses_to_set.soc_stepping_id) begin `uvm_info("SOC_IFC_RST", "Writing SOC Stepping ID to fuse bank", UVM_LOW) @@ -140,6 +167,14 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI end end + // Write LMS Verify Bit + if (this.fuses_to_set.lms_verify) begin + uvm_reg_data_t lms_verify_data = 1 << reg_model.soc_ifc_reg_rm.fuse_lms_verify.lms_verify.get_lsb_pos(); + `uvm_info("SOC_IFC_RST", "Writing LMS Verify=1 to fuse bank", UVM_LOW) + reg_model.soc_ifc_reg_rm.fuse_lms_verify.write(sts, lms_verify_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + if (sts != UVM_IS_OK) `uvm_error("SOC_IFC_RST", "Failed when writing to lms_verify") + end + // Set Fuse Done reg_model.soc_ifc_reg_rm.CPTRA_FUSE_WR_DONE.write(sts, `UVM_REG_DATA_WIDTH'(1), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); `uvm_info("SOC_IFC_RST", $sformatf("Fuse download completed, status: %p", sts), UVM_MEDIUM) @@ -164,10 +199,12 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI data_check = BOOT_WAIT << reg_model.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.boot_fsm_ps.get_lsb_pos(); // If set_bootfsm_breakpoint is randomized to 1, we need to release bootfsm by writing GO - if (ctrl_rst_ctx.set_bootfsm_breakpoint) begin + // bootfsm_breakpoint is qualified by debug mode and device_lifecycle, so incorporate that here + if (ctrl_rst_ctx.set_bootfsm_breakpoint && (!ctrl_rst_ctx.security_state.debug_locked || (ctrl_rst_ctx.security_state.debug_locked && ctrl_rst_ctx.security_state.device_lifecycle == DEVICE_MANUFACTURING))) begin //Poll boot status until we are in FSM state BOOT_WAIT reg_model.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.read(sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); while ((data & data_mask) != data_check) begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(20); reg_model.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.read(sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); end `uvm_info("SOC_IFC_RST", "BootFSM Breakpoint is set, writing GO", UVM_MEDIUM) @@ -175,7 +212,7 @@ class soc_ifc_env_reset_sequence_base extends soc_ifc_env_sequence_base #(.CONFI `uvm_info("SOC_IFC_RST", $sformatf("Write to BootFSM GO completed, status: %p", sts), UVM_MEDIUM) end else begin - `uvm_info("SOC_IFC_RST", "BootFSM Breakpoint not set, reset sequence complete", UVM_MEDIUM) + `uvm_info("SOC_IFC_RST", "BootFSM Breakpoint not set (or disabled based on security_state), reset sequence complete", UVM_MEDIUM) end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh index f20646097..ac1f522f8 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/bringup/soc_ifc/soc_ifc_env_rom_bringup_sequence.svh @@ -33,11 +33,43 @@ class soc_ifc_env_rom_bringup_sequence extends soc_ifc_env_reset_sequence_base; typedef soc_ifc_ctrl_rom_poweron_sequence soc_ifc_ctrl_agent_poweron_sequence_t; + // Decide which fuses to initialize constraint always_set_uds_c { this.fuses_to_set.uds == 1'b1; } constraint always_set_fe_c { this.fuses_to_set.field_entropy == 1'b1; } + // Roughly once per week, assuming the nightly Directed regression isn't running every day (since it is triggered by a PR) + constraint infrequently_set_lms_verify_c { this.fuses_to_set.lms_verify dist {0 :/ 4, 1 :/ 1}; } + constraint always_set_key_manifest_pk_hash_c { this.fuses_to_set.key_manifest_pk_hash == {12{1'b1}}; } + constraint always_set_owner_pk_hash_c { this.fuses_to_set.owner_pk_hash == {12{1'b1}}; } constraint always_set_idevid_c { this.fuses_to_set.idevid_cert_attr[0] == 1'b1; this.fuses_to_set.idevid_cert_attr[6] == 1'b1; this.fuses_to_set.idevid_cert_attr[7] == 1'b1; } + // Configure the values to set to initialized fuses + constraint key_manifest_pk_hash_values_c { key_manifest_pk_hash_rand[0] == 32'h6DC8DE16; + key_manifest_pk_hash_rand[1] == 32'hD559D129; + key_manifest_pk_hash_rand[2] == 32'h7BAB1E43; + key_manifest_pk_hash_rand[3] == 32'hEBD7C533; + key_manifest_pk_hash_rand[4] == 32'hDFE57001; + key_manifest_pk_hash_rand[5] == 32'h1AA56220; + key_manifest_pk_hash_rand[6] == 32'h0F66AD6D; + key_manifest_pk_hash_rand[7] == 32'h87051086; + key_manifest_pk_hash_rand[8] == 32'hC785E930; + key_manifest_pk_hash_rand[9] == 32'hD3D947B4; + key_manifest_pk_hash_rand[10] == 32'h7495822E; + key_manifest_pk_hash_rand[11] == 32'hCB643FF1; + solve this.fuses_to_set before this.key_manifest_pk_hash_rand; } + constraint owner_pk_hash_values_c { owner_pk_hash_rand[0] == 32'hF58D4920; + owner_pk_hash_rand[1] == 32'hBA65DA44; + owner_pk_hash_rand[2] == 32'hB0F728BC; + owner_pk_hash_rand[3] == 32'hFB893202; + owner_pk_hash_rand[4] == 32'hCFAAA942; + owner_pk_hash_rand[5] == 32'hBC66A0C0; + owner_pk_hash_rand[6] == 32'h007A2CE2; + owner_pk_hash_rand[7] == 32'h29A8E08F; + owner_pk_hash_rand[8] == 32'h9E8EEBAE; + owner_pk_hash_rand[9] == 32'hB36E9CC0; + owner_pk_hash_rand[10] == 32'h962E4B7A; + owner_pk_hash_rand[11] == 32'h50214999; + solve this.fuses_to_set before this.owner_pk_hash_rand; } constraint idevid_values_c { idevid_cert_attr_rand[0] == '0; /* SHA1 */ idevid_cert_attr_rand[6] == 32'hFFFF_FFFF; /* UEID LSWord */ idevid_cert_attr_rand[7] == 32'hFFFF_FFFF; /* MSWord */} diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh index 4a5ffbf8f..7ea25378e 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_handler_sequence.svh @@ -31,6 +31,9 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base `uvm_object_utils( soc_ifc_env_cptra_mbox_handler_sequence ) + int sts_rsp_count = 0; + int ntf_rsp_count = 0; + int err_rsp_count = 0; mbox_op_s op; int mbox_resp_expected_dlen = 0; // Number of response data bytes to provide uvm_status_e reg_sts; @@ -38,9 +41,11 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base rand longint unsigned force_unlock_delay_cycles; bit unlock_proc_active = 1'b0; + bit op_started = 1'b0; bit seq_done = 1'b0; uvm_event in_report_reg_sts; + extern virtual task handler_setup(); extern virtual task mbox_wait_for_command(output op_sts_e op_sts); extern virtual task mbox_get_command(); extern virtual task mbox_pop_dataout(); @@ -91,7 +96,6 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base //========================================== virtual task body(); - int sts_rsp_count = 0; op_sts_e op_sts; reg_model = configuration.soc_ifc_rm; @@ -99,10 +103,17 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base `uvm_fatal("CPTRA_MBOX_HANDLER", "SOC_IFC ENV caliptra mailbox handler sequence expected a handle to the cptra status agent responder sequence (from bench-level sequence) but got null!") fork forever begin - @(cptra_status_agent_rsp_seq.new_rsp) sts_rsp_count++; + @(cptra_status_agent_rsp_seq.new_rsp) begin + sts_rsp_count += (cptra_status_agent_rsp_seq.rsp.soc_ifc_notif_intr_pending || + cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) ? 0 : 1; + ntf_rsp_count += cptra_status_agent_rsp_seq.rsp.soc_ifc_notif_intr_pending; + err_rsp_count += cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending; + end end join_none + handler_setup(); + fork begin: ALL_TIME_CONSUMING_TASKS // Wait for a mailbox command to be received @@ -131,6 +142,9 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base // Wait for the command to complete. // Either we clear the lock (via force_unlock), or the SOC requestor does. + // If the SOC requestor triggered a mbox protocol violation and this sequence + // is not randomly injecting force_unlock, the force_unlock thread will still set + // mbox_unlock to reset the mailbox state machine and service the error. `uvm_info("CPTRA_MBOX_HANDLER", "Waiting for mbox_lock to deassert, indicating end of mailbox flow", UVM_MEDIUM) while (reg_model.mbox_csr_rm.mbox_lock.lock.get_mirrored_value()) begin configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); @@ -144,7 +158,8 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base // After forcibly unlocking mailbox, kill any remaining activity. // If force unlock is randomized to "off" for this run // of the sequence, this won't ever run. - in_report_reg_sts.wait_on(); /* Wait for pending bus transfers (in ALL_TIME_CONSUMING_TASKS) to finish to avoid deadlock */ + if (op_started) + in_report_reg_sts.wait_on(); /* Wait for pending bus transfers (in ALL_TIME_CONSUMING_TASKS) to finish to avoid deadlock */ disable ALL_TIME_CONSUMING_TASKS; `uvm_info("CPTRA_MBOX_HANDLER", "Disabled ALL_TIME_CONSUMING_TASKS", UVM_HIGH) end: DO_FORCE_UNLOCK @@ -165,6 +180,46 @@ class soc_ifc_env_cptra_mbox_handler_sequence extends soc_ifc_env_sequence_base endclass +//========================================== +// Task: handler_setup +// Description: Prep the system to receive a new mailbox command. +// This includes servicing/clearing any interrupts already +// pending on sequence entry (except new command intr) +//========================================== +task soc_ifc_env_cptra_mbox_handler_sequence::handler_setup(); + uvm_reg_data_t data; + + if (sts_rsp_count) begin + `uvm_warning("CPTRA_MBOX_HANDLER", "Did not expect to receive any new cptra_status transactions at sequence entry!") + sts_rsp_count = 0; + end + + // Clear notifications + if (ntf_rsp_count) begin + `uvm_warning("CPTRA_MBOX_HANDLER", "Did not expect to receive any new cptra_status notification interrupt transactions at sequence entry!") + ntf_rsp_count = 0; + end + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "notif_internal_intr_r"); + if (data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()] && + cptra_status_agent_rsp_seq.rsp.soc_ifc_notif_intr_pending) begin + ntf_rsp_count = 1; // Roll this interrupt event forward to 'mbox_wait_for_command' + end + // Clear all interrupts except for cmd available + data &= ~(uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "notif_internal_intr_r"); + // Clear errors + if (err_rsp_count) begin + `uvm_warning("CPTRA_MBOX_HANDLER", "Did not expect to receive any new cptra_status err interrupt transactions at sequence entry!") + err_rsp_count = 0; + end + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); +endtask + //========================================== // Task: mbox_wait_for_command // Description: Poll for availability of new @@ -175,12 +230,20 @@ endclass task soc_ifc_env_cptra_mbox_handler_sequence::mbox_wait_for_command(output op_sts_e op_sts); uvm_reg_data_t data; op_sts = CPTRA_TIMEOUT; + // Wait for notification interrupt indicating command is available + while (ntf_rsp_count == 0) begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + if (ntf_rsp_count != 0 && !cptra_status_agent_rsp_seq.rsp.soc_ifc_notif_intr_pending) begin + ntf_rsp_count = 0; + end + end + ntf_rsp_count = 0; + op_started = 1; + // Clear interrupt reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "notif_internal_intr_r"); - while (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()]) begin - configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(200); - reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); - report_reg_sts(reg_sts, "notif_internal_intr_r"); + if (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()]) begin + `uvm_error("CPTRA_MBOX_HANDLER", "After receiving notification interrupt, notif_cmd_avail_sts is not set!") end data &= uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos(); reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); @@ -284,13 +347,41 @@ endtask //========================================== task soc_ifc_env_cptra_mbox_handler_sequence::mbox_wait_and_force_unlock(); uvm_reg_data_t data; + mbox_fsm_state_e state; // Wait... - if (!inject_force_unlock) begin - // This task never exits if force unlock is disabled - forever configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1000); + // If force unlock is disabled, this task will only exit upon detecting + // an ERROR that requires servicing, whereupon force_unlock will still + // be set to recover. In either case, only an event resulting in force + // unlock causes this routine to break + while(!inject_force_unlock) begin + if (err_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) begin + `uvm_info("CPTRA_MBOX_HANDLER", "Received soc_ifc_err_intr, clearing and (if needed) proceeding to mbox_unlock", UVM_MEDIUM) + // Read and clear any error interrupts + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(10/*TODO rand delays*/); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + err_rsp_count = 0; + // Next, check if we need to proceed to mbox_unlock step + if (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]) begin + continue; + end + reg_model.mbox_csr_rm.mbox_status.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "mbox_status"); + state = mbox_fsm_state_e'(data >> reg_model.mbox_csr_rm.mbox_status.mbox_fsm_ps.get_lsb_pos()); + // If we're in the error state, the only recovery is by mbox_unlock - proceed to that step + if (state == MBOX_ERROR) begin + `uvm_info("CPTRA_MBOX_HANDLER", "After servicing soc_ifc_err_intr, proceeding with mbox_unlock", UVM_MEDIUM) + break; + end + end + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(10/*TODO rand delays*/); + end + if (inject_force_unlock) begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(force_unlock_delay_cycles); end - configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(force_unlock_delay_cycles); // Start the unlock proc unlock_proc_active = 1'b1; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh index 1bde83c26..1f7c6d80d 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_interference_handler_sequence.svh @@ -53,10 +53,11 @@ endclass task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_for_command(output op_sts_e op_sts); byte ii; + uvm_reg_data_t data; op_sts = CPTRA_TIMEOUT; - reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); - report_reg_sts(reg_sts, "notif_internal_intr_r"); - while (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()]) begin + op_started = 1; + // Wait for notification interrupt indicating command is available + while (ntf_rsp_count == 0) begin uvm_reg_data_t dlen; byte unsigned mem_n_bytes; @@ -90,8 +91,16 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_for_command end end configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(cycles); - reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); - report_reg_sts(reg_sts, "notif_internal_intr_r"); + if (ntf_rsp_count != 0 && !cptra_status_agent_rsp_seq.rsp.soc_ifc_notif_intr_pending) begin + ntf_rsp_count = 0; + end + end + ntf_rsp_count = 0; + // Clear interrupt + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "notif_internal_intr_r"); + if (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos()]) begin + `uvm_error("CPTRA_MBOX_HANDLER", "After receiving notification interrupt, notif_cmd_avail_sts is not set!") end data &= uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos(); reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); @@ -110,6 +119,7 @@ endtask //========================================== task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_and_force_unlock(); uvm_reg_data_t data; + mbox_fsm_state_e state; uvm_event force_unlock_delay_complete = new("force_unlock_delay_complete"); // Start the unlock proc prior to burst accesses so that the parent @@ -118,17 +128,50 @@ task soc_ifc_env_cptra_mbox_interference_handler_sequence::mbox_wait_and_force_u unlock_proc_active = 1'b1; // Wait... - // This task never exits if force unlock is disabled - do begin - force_unlock_delay_complete.reset(); - fork - begin + // If force unlock is disabled, this task will only exit upon detecting + // an ERROR that requires servicing, whereupon force_unlock will still + // be set to recover. In either case, only an event resulting in force + // unlock causes this routine to break + force_unlock_delay_complete.reset(); + fork + begin + if (inject_force_unlock) begin configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(force_unlock_delay_cycles); - force_unlock_delay_complete.trigger(); end - burst_random_reg_accesses(force_unlock_delay_complete); - join - end while (!inject_force_unlock); + else begin + `uvm_info("CPTRA_MBOX_HANDLER", "Not injecting force unlock - burst random reg accesses until any err interrupt is observed", UVM_HIGH) + forever begin + if (err_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) begin + `uvm_info("CPTRA_MBOX_HANDLER", "Received soc_ifc_err_intr, clearing and (if needed) proceeding to mbox_unlock", UVM_MEDIUM) + // Read and clear any error interrupts + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(10/*TODO rand delays*/); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + err_rsp_count = 0; + // Next, check if we need to proceed to mbox_unlock step + if (!data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]) begin + continue; + end + reg_model.mbox_csr_rm.mbox_status.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "mbox_status"); + state = mbox_fsm_state_e'(data >> reg_model.mbox_csr_rm.mbox_status.mbox_fsm_ps.get_lsb_pos()); + // If we're in the error state, the only recovery is by mbox_unlock - proceed to that step + if (state == MBOX_ERROR) begin + `uvm_info("CPTRA_MBOX_HANDLER", "After servicing soc_ifc_err_intr, proceeding with mbox_unlock", UVM_MEDIUM) + break; + end + end + else begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(10/*TODO rand delays*/); + end + end + end + force_unlock_delay_complete.trigger(); + end + burst_random_reg_accesses(force_unlock_delay_complete); + join // After waiting the requisite number of cycles, check mbox_status. // If SOC doesn't currently have the lock, doing a force-unlock has no diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh index 37a9b8e6a..0fb458a71 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/cptra/soc_ifc_env_cptra_mbox_req_sequence_base.svh @@ -39,6 +39,7 @@ class soc_ifc_env_cptra_mbox_req_sequence_base extends soc_ifc_env_sequence_base rand mbox_op_s mbox_op_rand; int sts_rsp_count; uvm_status_e reg_sts; + bit mbox_sts_is_error = 0; rand bit do_ahb_lock_check; rand bit retry_failed_reg_axs; // Certain random sequences force the command to be outside of the defined @@ -58,7 +59,7 @@ class soc_ifc_env_cptra_mbox_req_sequence_base extends soc_ifc_env_sequence_base extern virtual task mbox_set_cmd(input mbox_op_s op); extern virtual task mbox_push_datain(); extern virtual task mbox_execute(); - extern virtual task mbox_check_status(output mbox_status_e data); + extern virtual task mbox_check_status(output mbox_status_e data, output mbox_fsm_state_e state); extern virtual task mbox_poll_status(); extern virtual task mbox_clr_execute(); extern virtual task mbox_teardown(); @@ -313,7 +314,7 @@ endtask // Task: mbox_check_status // Description: Read mbox_status //========================================== -task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_check_status(output mbox_status_e data); +task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_check_status(output mbox_status_e data, output mbox_fsm_state_e state); uvm_reg_data_t reg_data; reg_model.mbox_csr_rm.mbox_status.read(reg_sts, reg_data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "mbox_status"); @@ -323,6 +324,7 @@ task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_check_status(output mbox_sta end else begin data = mbox_status_e'(reg_data >> reg_model.mbox_csr_rm.mbox_status.status.get_lsb_pos()); + state = mbox_fsm_state_e'(reg_data >> reg_model.mbox_csr_rm.mbox_status.mbox_fsm_ps.get_lsb_pos()); end endtask @@ -330,17 +332,28 @@ endtask // Task: mbox_poll_status // Description: Issue calls to mbox_check_status // until status change indicates control is -// returned to SOC. +// returned to uC. //========================================== task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_poll_status(); mbox_status_e data; + mbox_fsm_state_e state; uvm_reg_data_t mask; // Poll mbox_status register do begin configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(200); - mbox_check_status(data); - end while (data == CMD_BUSY); + mbox_check_status(data, state); + end while (data == CMD_BUSY && !(state inside {MBOX_IDLE, MBOX_ERROR})); + + // We should have an error interrupt in response to the ERROR state, which + // will be serviced at a later step. + // We do not expect the cmd_avail_sts interrupt, and there is no point in + // continuing this task (to report on the mbox_status field) when we've hit + // a protocol error. + if (state == MBOX_ERROR) begin + mbox_sts_is_error = 1; + return; + end // Clear Interrupt Status, which is set on transfer SOC->uC mask = uvm_reg_data_t'(1) << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_cmd_avail_sts.get_lsb_pos(); @@ -351,25 +364,50 @@ task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_poll_status(); // Evaluate status field if (data == DATA_READY) begin - `uvm_error("CPTRA_MBOX_SEQ", $sformatf("Received status %p when not expecting any bytes of response data!", data)) + `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received status %p when not expecting any bytes of response data!", data), UVM_LOW) end else if (data == CMD_FAILURE) begin - `uvm_error("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data)) + `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data), UVM_LOW) end else if (data == CMD_COMPLETE) begin `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received status %p from SOC in response to command", data), UVM_FULL) end else begin - `uvm_error("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data)) + `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data), UVM_LOW) end endtask //========================================== // Task: mbox_clr_execute // Description: End the mailbox flow by writing -// 0 to mbox_execute register +// 0 to mbox_execute register (or +// by force-unlock if necessary) //========================================== task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_clr_execute(); + uvm_reg_data_t data; + // We have to stall a couple clocks to allow interrupts to assert in case + // we read the MBOX_ERROR status, since there is a small delay as the signal + // propagates through registers. + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(2); + // Now, check for the expected error interrupt + if (sts_rsp_count > 0 && cptra_status_agent_rsp_seq.rsp.soc_ifc_err_intr_pending) begin + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "error_internal_intr_r"); + if (data[reg_model.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_cmd_fail_sts.get_lsb_pos()]) begin + // Force unlock to recover from error and reset mailbox to IDLE state + reg_model.mbox_csr_rm.mbox_unlock.write(reg_sts, uvm_reg_data_t'(1 << reg_model.mbox_csr_rm.mbox_unlock.unlock.get_lsb_pos()), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "mbox_unlock"); + return; /* force unlock trumps the write to mbox_execute, so we're done at this point */ + end + else if (mbox_sts_is_error) begin + `uvm_error("CPTRA_MBOX_SEQ", "Error interrupt following cmd failure does not have cmd_fail bit set!") + end + end + else if (mbox_sts_is_error) begin + `uvm_error("CPTRA_MBOX_SEQ", "Error encountered but no interrupt received") + end reg_model.mbox_csr_rm.mbox_execute.write(reg_sts, uvm_reg_data_t'(0), UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); report_reg_sts(reg_sts, "mbox_execute"); endtask @@ -380,7 +418,26 @@ endtask // to add any end-of-sequence functionality. //========================================== task soc_ifc_env_cptra_mbox_req_sequence_base::mbox_teardown(); + uvm_reg_data_t data, mask; + + // Clear any pending notification interrupts that made it through to the end of the sequence + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.read(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "notif_internal_intr_r"); + // Any unexpected interrupts should trigger a tb error + mask = ~((1 << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_mbox_ecc_cor_sts.get_lsb_pos()) | + (1 << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_debug_locked_sts.get_lsb_pos()) | + (1 << reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_soc_req_lock_sts.get_lsb_pos())); + if (data & mask) begin + `uvm_error("CPTRA_MBOX_SEQ", $sformatf("Received notification interrupt for unexpected event: 0x%0x", data)) + end + else begin + reg_model.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.write(reg_sts, data, UVM_FRONTDOOR, reg_model.soc_ifc_AHB_map, this); + report_reg_sts(reg_sts, "notif_internal_intr_r"); + `uvm_info("CPTRA_MBOX_SEQ", $sformatf("Received and cleared notification interrupt for events: 0x%0x", data), UVM_HIGH) + end + // Summary at sequence end + `uvm_info("CPTRA_MBOX_SEQ", $sformatf("uC initiated mailbox flow is completed. Ending status: %s", mbox_sts_is_error ? "hit protocol violation" : "no protocol violation"), UVM_LOW) 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_dir_read_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_dir_read_sequence.svh new file mode 100644 index 000000000..bc4aba89e --- /dev/null +++ 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_dir_read_sequence.svh @@ -0,0 +1,42 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Extended from mbox_base sequence to provide additional +// functionality in a test that sends mailbox commands +// of a size that exceeds mailbox capacity. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_mbox_dir_read_sequence extends soc_ifc_env_mbox_sequence_base; + + `uvm_object_utils( soc_ifc_env_mbox_dir_read_sequence ) + + // Constrain command to undefined opcode + constraint mbox_cmd_dir_read_c { (mbox_op_rand.cmd.cmd_e == MBOX_CMD_DIR_RD); } + + // Constrain size to something reasonable + constraint mbox_dlen_max_c { mbox_op_rand.dlen <= 2000; } + + function new(string name = "" ); + super.new(name); + endfunction + +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_reg_axs_invalid_large_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_reg_axs_invalid_large_sequence.svh new file mode 100644 index 000000000..3be9c04ba --- /dev/null +++ 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_reg_axs_invalid_large_sequence.svh @@ -0,0 +1,41 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Extended from mbox_base sequence to provide additional +// functionality in a test that sends large commands. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_mbox_reg_axs_invalid_large_sequence extends soc_ifc_env_mbox_reg_axs_invalid_sequence; + + `uvm_object_utils( soc_ifc_env_mbox_reg_axs_invalid_large_sequence ) + + // Constrain size to a large command + // Min. size: 16KiB + constraint mbox_dlen_min_large_c { mbox_op_rand.dlen > 32'h0000_4000; } + // Constrain response data size to also be large + // Min. size: 16KiB + constraint mbox_resp_dlen_min_large_c { mbox_op_rand.cmd.cmd_s.resp_reqd -> mbox_resp_expected_dlen >= 32'h0000_4000; } + // 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 < (mbox_op_rand.dlen * 5); } + +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_reg_axs_invalid_medium_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_reg_axs_invalid_medium_sequence.svh new file mode 100644 index 000000000..674413d75 --- /dev/null +++ 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_reg_axs_invalid_medium_sequence.svh @@ -0,0 +1,45 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Extended from mbox_base sequence to provide additional +// functionality in a test that sends medium-sized mailbox commands. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_mbox_reg_axs_invalid_medium_sequence extends soc_ifc_env_mbox_reg_axs_invalid_sequence; + + `uvm_object_utils( soc_ifc_env_mbox_reg_axs_invalid_medium_sequence ) + + // Constrain dlen to be a medium command + // Max. size: 4096B + constraint mbox_dlen_max_medium_c { mbox_op_rand.dlen <= 32'h0000_1000; } + // Minimum 512B + constraint mbox_dlen_min_medium_c { mbox_op_rand.dlen >= 32'h0000_0200; } + // Constrain response data size to also be medium + // Max. size: 4096B + // Min. size: 512B + constraint mbox_resp_dlen_max_medium_c { mbox_resp_expected_dlen <= 32'h0000_1000; } + constraint mbox_resp_dlen_min_medium_c { mbox_op_rand.cmd.cmd_s.resp_reqd -> mbox_resp_expected_dlen >= 32'h0000_0200; } + // 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 < (mbox_op_rand.dlen * 12); } + +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_reg_axs_invalid_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_reg_axs_invalid_sequence.svh new file mode 100644 index 000000000..e0112ea05 --- /dev/null +++ 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_reg_axs_invalid_sequence.svh @@ -0,0 +1,194 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Extended from mbox_base sequence to provide additional +// functionality in a test that sends mailbox commands +// of a size that exceeds mailbox capacity. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_mbox_reg_axs_invalid_sequence extends soc_ifc_env_mbox_sequence_base; + + `uvm_object_utils( soc_ifc_env_mbox_reg_axs_invalid_sequence ) + + // Constrain command to undefined opcode + constraint mbox_cmd_undef_c { !(mbox_op_rand.cmd.cmd_s inside {defined_cmds}); } + + extern virtual task mbox_do_random_reg_write(process mainline); + extern virtual function uvm_reg_data_t get_rand_wr_data(uvm_reg axs_reg); + + function new(string name = "" ); + super.new(name); + endfunction + + //========================================== + // Task: body + // Description: Implement main functionality for + // SOC-side transmission of mailbox request. + // Override default body to inject random + // (deliberately erroneous) register accesses + // throughout a normal test flow. + //========================================== + virtual task body(); + + op_sts_e op_sts; + process mbox_flow_proc; + + sts_rsp_count = 0; + + fork + forever begin + @(soc_ifc_status_agent_rsp_seq.new_rsp) sts_rsp_count++; + end + join_none + + `uvm_info("MBOX_SEQ", $sformatf("Initiating command sequence to mailbox with cmd: [%p] dlen: [%p] resp_dlen: [%p]", mbox_op_rand.cmd.cmd_e, mbox_op_rand.dlen, mbox_resp_expected_dlen), UVM_MEDIUM) + + fork + begin: MBOX_FLOW + mbox_flow_proc = process::self(); + 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); + 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); + mbox_poll_status(); if (rand_delay_en) do_rand_delay(1, step_delay); + end + begin: ERR_INJECT_FLOW + wait(mbox_flow_proc != null); + mbox_do_random_reg_write(mbox_flow_proc); + end + join + mbox_clr_execute(); if (rand_delay_en) do_rand_delay(1, step_delay); + mbox_teardown(); + + endtask + +endclass + +//========================================== +// Task: mbox_do_random_reg_write +// Description: Do some random reg write that will +// (most likely) be invalid and trigger +// the protocol error violation. +//========================================== +task soc_ifc_env_mbox_reg_axs_invalid_sequence::mbox_do_random_reg_write(process mainline); + uvm_reg mbox_regs[$]; + int unsigned rand_idx; + uvm_reg_data_t rand_wr_data; + caliptra_apb_user local_apb_user_obj; + uvm_status_e local_reg_sts; + + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_cmd ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_dlen ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_datain ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_dataout); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_execute); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_status ); + + if (!std::randomize(rand_idx) with {rand_idx < mbox_regs.size(); }) + `uvm_fatal("MBOX_SEQ", "Failed to randomize reg idx") + + // Wait and do the reg write at some random point in the sequence + do_rand_delay(1, DLY_CUSTOM); + // Data used depends on which reg is being accessed to force invalid contents + rand_wr_data = get_rand_wr_data(mbox_regs[rand_idx]); + // Get a randomized PAUSER for this transaction - 50% chance of being valid + local_apb_user_obj = new(); + if (!local_apb_user_obj.randomize() with {if (pauser_locked.locked) + (addr_user == pauser_locked.pauser) dist + {1 :/ 1, + 0 :/ 1}; + else + (addr_user inside {mbox_valid_users}) dist + {1 :/ 1, + 0 :/ 1}; }) + `uvm_error("MBOX_SEQ", "Failed to randomize APB PAUSER override value") + else + `uvm_info("MBOX_SEQ", $sformatf("Randomized APB PAUSER override value to 0x%x", local_apb_user_obj.addr_user), UVM_HIGH) + // Pause the main mailbox flow to prevent race conditions (on accesses to the same register, triggering is_busy UVM_WARNING) + if (mainline.status() inside {process::RUNNING,process::WAITING}) begin + in_report_reg_sts.wait_on(); + `uvm_info("MBOX_SEQ", $sformatf("Pausing main mailbox flow to allow random reg access injection"), UVM_HIGH) + mainline.suspend(); + in_report_reg_sts.reset(); + end + else begin + `uvm_info("MBOX_SEQ", $sformatf("Main mailbox flow is in state [%s], so it will not be suspended for random reg access injection", mainline.status().name()), UVM_HIGH) + end + if (mbox_regs[rand_idx].get_name() == "mbox_dataout") begin + `uvm_info("MBOX_SEQ", {"Performing random register access to ", mbox_regs[rand_idx].get_name()}, UVM_LOW) + mbox_regs[rand_idx].read(local_reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(local_reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + else if (mbox_regs[rand_idx].get_name() == "mbox_datain") begin + `uvm_info("MBOX_SEQ", {"Performing random register access to ", mbox_regs[rand_idx].get_name()}, UVM_LOW) + mbox_regs[rand_idx].write(local_reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(local_reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + else begin + `uvm_info("MBOX_SEQ", {"Performing random register access to ", mbox_regs[rand_idx].get_name()}, UVM_LOW) + mbox_regs[rand_idx].write(local_reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(local_reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + if (mainline.status() == process::SUSPENDED) begin + `uvm_info("MBOX_SEQ", $sformatf("Resuming main mailbox flow after random reg access injection"), UVM_HIGH) + mainline.resume(); + end +endtask + +//========================================== +// Task: get_rand_wr_data +// Description: Generate random data according +// to a set of rules related to which register +// is being accessed, with intent to cause +// a protocol violation. +//========================================== +function uvm_reg_data_t soc_ifc_env_mbox_reg_axs_invalid_sequence::get_rand_wr_data(uvm_reg axs_reg); + uvm_reg_data_t tmp_data; + case (axs_reg.get_name()) inside + "mbox_cmd": begin + tmp_data = mbox_op_rand.cmd; + end + "mbox_dlen": begin + tmp_data = mbox_op_rand.dlen; + end + "mbox_datain", + "mbox_dataout": begin + std::randomize(tmp_data); + end + "mbox_execute": begin + uvm_reg_data_t msk; + msk = ~(uvm_reg_data_t'(1) << reg_model.mbox_csr_rm.mbox_execute.execute.get_lsb_pos()); + std::randomize(tmp_data) with {(tmp_data & msk) == 0;}; + end + "mbox_status": begin + uvm_reg_data_t msk; + msk = ((uvm_reg_data_t'(1) << reg_model.mbox_csr_rm.mbox_status.status.get_n_bits()) - 1) << reg_model.mbox_csr_rm.mbox_status.status.get_lsb_pos(); + msk = ~msk; + std::randomize(tmp_data) with {(tmp_data & msk) == 0;}; + end + default: begin + `uvm_fatal("MBOX_SEQ", "Bad reg") + end + endcase + return tmp_data; +endfunction 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_reg_axs_invalid_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_reg_axs_invalid_small_sequence.svh new file mode 100644 index 000000000..33429c4e8 --- /dev/null +++ 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_reg_axs_invalid_small_sequence.svh @@ -0,0 +1,41 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Extended from mbox_base sequence to provide additional +// functionality in a test that sends small mailbox commands. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_mbox_reg_axs_invalid_small_sequence extends soc_ifc_env_mbox_reg_axs_invalid_sequence; + + `uvm_object_utils( soc_ifc_env_mbox_reg_axs_invalid_small_sequence ) + + // Constrain dlen to be a small command + // Max. size: 512B + constraint mbox_dlen_max_small_c { mbox_op_rand.dlen <= 32'h0000_0200; } + // Constrain response data size to also be small + // Max. size: 512B + constraint mbox_resp_dlen_max_small_c { mbox_resp_expected_dlen < 32'h0000_0200; } + // 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 < (mbox_op_rand.dlen * 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_rom_fw_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_rom_fw_sequence.svh index e50e215b6..5e265b325 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_rom_fw_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_rom_fw_sequence.svh @@ -36,7 +36,7 @@ class soc_ifc_env_mbox_rom_fw_sequence extends soc_ifc_env_mbox_sequence_base; // This shouldn't be randomized, specify it constraint mbox_cmd_c { mbox_op_rand.cmd == mbox_cmd_e'(MBOX_CMD_ROM_FW_UPD); } - constraint mbox_dlen_c { mbox_op_rand.dlen == 10644; } + constraint mbox_dlen_c { mbox_op_rand.dlen == 13708; } // Response data is only non-zero if a response is requested, and also must // be small enough to fit in the mailbox // Firmware team encodes commands differently from this environment; response 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 5dc6bd96d..ab62c1dfd 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 @@ -38,6 +38,7 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG rand int mbox_resp_expected_dlen; // Number of response data bytes to expect int sts_rsp_count; uvm_status_e reg_sts; + uvm_event in_report_reg_sts; rand bit do_apb_lock_check; rand bit retry_failed_reg_axs; @@ -45,7 +46,8 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG DLY_ZERO, DLY_SMALL, DLY_MEDIUM, - DLY_LARGE + DLY_LARGE, + DLY_CUSTOM } delay_scale_e; rand delay_scale_e poll_delay, step_delay, data_delay; @@ -92,9 +94,9 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG extern virtual task do_rand_delay(input bit do_delay_randomize=1, input delay_scale_e scale=DLY_SMALL); extern virtual function void set_pauser_prob_vals(); - extern virtual function bit pauser_used_is_valid(); + extern virtual function bit pauser_used_is_valid(caliptra_apb_user user_handle = null); extern virtual function caliptra_apb_user get_rand_user(int unsigned invalid_prob = FORCE_VALID_PAUSER); - extern virtual function void report_reg_sts(uvm_status_e reg_sts, string name); + extern virtual task report_reg_sts(uvm_status_e reg_sts, string name, caliptra_apb_user user_handle = null); // Constrain command to not be firmware or uC-initiated constraint mbox_cmd_c { mbox_op_rand.cmd.cmd_s.fw == 1'b0; @@ -125,6 +127,10 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG constraint delay_scale_c { poll_delay == DLY_MEDIUM; step_delay == DLY_SMALL; data_delay == DLY_ZERO; } + // Should not be overridden + constraint delay_scale_valid_c { poll_delay != DLY_CUSTOM; + step_delay != DLY_CUSTOM; + data_delay != DLY_CUSTOM; } // These constraints conflict with each other - only the one that is applicable // should be enabled; this is done in the definition of do_rand_delay constraint zero_delay_c { rand_delay == 0;} @@ -140,6 +146,10 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG [ 16 : 255] :/ 25, [ 256:1023] :/ 500, [1024:8191] :/ 300};} + // This deliberately intractable constraint must be overridden + // by a child sequence if random delays are expected to be driven + // by some custom rule set. + constraint custom_delay_c { rand_delay == 0; rand_delay == 1; } //========================================== // Function: new @@ -166,6 +176,9 @@ class soc_ifc_env_mbox_sequence_base extends soc_ifc_env_sequence_base #(.CONFIG this.small_delay_c .constraint_mode(1); this.medium_delay_c.constraint_mode(0); this.large_delay_c .constraint_mode(0); + this.custom_delay_c.constraint_mode(0); + + in_report_reg_sts = new("in_report_reg_sts"); endfunction //========================================== @@ -530,21 +543,34 @@ task soc_ifc_env_mbox_sequence_base::mbox_poll_status(); `uvm_info("MBOX_SEQ", "Detected mailbox state transition to IDLE - was mbox_unlock expected?", UVM_HIGH) end else if (data == DATA_READY) begin - if (mbox_resp_expected_dlen == 0) + 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) + end + else if (mbox_resp_expected_dlen == 0) `uvm_error("MBOX_SEQ", $sformatf("Received status %p when not expecting any bytes of response data!", data)) else begin mbox_read_resp_data(); end end else if (data == CMD_FAILURE) begin - `uvm_error("MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data)) + if (sts_rsp_count > 0 && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) begin + `uvm_info("MBOX_SEQ", $sformatf("Unexpected mailbox status [%p] likely is the result of a spurious reg access injection specifically intended to cause a protocol violation", data), UVM_HIGH) + end + else begin + `uvm_error("MBOX_SEQ", $sformatf("Received mailbox status %p unexpectedly, since there is no pending non_fatal error interrupt", data)) + end end else if (data == CMD_COMPLETE) begin - if (mbox_resp_expected_dlen != 0) + if (mbox_resp_expected_dlen != 0 && sts_rsp_count > 0 && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) + `uvm_info("MBOX_SEQ", $sformatf("Unexpected status [%p] when expecting 0x%x bytes of response data likely is the result of a spurious reg access injection specifically intended to cause a protocol violation", data, mbox_resp_expected_dlen), UVM_HIGH) + else if (mbox_resp_expected_dlen != 0) `uvm_error("MBOX_SEQ", $sformatf("Received status %p when expecting 0x%x bytes of response data!", data, mbox_resp_expected_dlen)) end else begin - `uvm_error("MBOX_SEQ", $sformatf("Received unexpected mailbox status %p", data)) + if (sts_rsp_count > 0 && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) + `uvm_info("MBOX_SEQ", $sformatf("Unexpected mailbox status [%p] likely is the result of a spurious reg access injection specifically intended to cause a protocol violation", data), UVM_HIGH) + else + `uvm_error("MBOX_SEQ", $sformatf("Received unexpected mailbox status [%p]", data)) end endtask @@ -610,6 +636,7 @@ task soc_ifc_env_mbox_sequence_base::do_rand_delay(input bit do_delay_randomize= this.small_delay_c .constraint_mode(scale == DLY_SMALL); this.medium_delay_c.constraint_mode(scale == DLY_MEDIUM); this.large_delay_c .constraint_mode(scale == DLY_LARGE); + this.custom_delay_c.constraint_mode(scale == DLY_CUSTOM); if (!this.randomize(rand_delay)) `uvm_error("MBOX_SEQ", $sformatf("Failed to randomize rand_delay with scale %p", scale)) else @@ -675,11 +702,14 @@ endfunction // Description: Assess whether the most recent APB // transfer used a valid PAUSER or not //========================================== -function bit soc_ifc_env_mbox_sequence_base::pauser_used_is_valid(); +function bit soc_ifc_env_mbox_sequence_base::pauser_used_is_valid(caliptra_apb_user user_handle = null); + caliptra_apb_user user; + if (user_handle == null) user = this.apb_user_obj; + else user = user_handle; if (this.pauser_locked.locked) - return this.apb_user_obj.get_addr_user() == this.pauser_locked.pauser; + return user.get_addr_user() == this.pauser_locked.pauser; else - return this.apb_user_obj.get_addr_user() inside mbox_valid_users; + return user.get_addr_user() inside mbox_valid_users; endfunction //========================================== @@ -688,20 +718,29 @@ endfunction // of the most recent APB transfer, accounting for // the PAUSER value that was used. //========================================== -function void soc_ifc_env_mbox_sequence_base::report_reg_sts(uvm_status_e reg_sts, string name); +task soc_ifc_env_mbox_sequence_base::report_reg_sts(uvm_status_e reg_sts, string name, caliptra_apb_user user_handle = null); + caliptra_apb_user user; + int waiters = in_report_reg_sts.get_num_waiters(); + in_report_reg_sts.trigger(); + if (user_handle == null) user = this.apb_user_obj; + else user = user_handle; // APB error is flagged only for PAUSER that doesn't match the registered // values, it does not check that PAUSER matches the exact value in // mbox_user that was stored when lock was acquired (this results in a // silent error but a successful reg read). // Ergo, check against mbox_valid_users instead of pauser_locked. - if (reg_sts != UVM_IS_OK && this.apb_user_obj.get_addr_user() inside mbox_valid_users) + if (reg_sts != UVM_IS_OK && user.get_addr_user() inside mbox_valid_users) `uvm_error("MBOX_SEQ", - $sformatf("Register access failed unexpectedly with valid PAUSER! 0x%x (%s)", this.apb_user_obj.get_addr_user(), name)) - else if (reg_sts == UVM_IS_OK && !(this.apb_user_obj.get_addr_user() inside mbox_valid_users)) + $sformatf("Register access failed unexpectedly with valid PAUSER! 0x%x (%s)", user.get_addr_user(), name)) + else if (reg_sts == UVM_IS_OK && !(user.get_addr_user() inside mbox_valid_users)) `uvm_error("MBOX_SEQ", - $sformatf("Register access passed unexpectedly with invalid PAUSER! 0x%x (%s)", this.apb_user_obj.get_addr_user(), name)) + $sformatf("Register access passed unexpectedly with invalid PAUSER! 0x%x (%s)", user.get_addr_user(), name)) else `uvm_info("MBOX_SEQ", - $sformatf("Register access to (%s) with pauser_used_is_valid: %b and reg_sts: %p", name, this.pauser_used_is_valid(), reg_sts), + $sformatf("Register access to (%s) with pauser_used_is_valid: %b and reg_sts: %p", name, this.pauser_used_is_valid(user), reg_sts), UVM_HIGH) -endfunction + if (waiters) + in_report_reg_sts.wait_off(); + else + in_report_reg_sts.reset(); +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_soc_mbox_handler_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_soc_mbox_handler_sequence.svh index 4941d69a1..028e280af 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_soc_mbox_handler_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_soc_mbox_handler_sequence.svh @@ -36,6 +36,7 @@ class soc_ifc_env_soc_mbox_handler_sequence extends soc_ifc_env_sequence_base #( mbox_op_s op; uvm_status_e reg_sts; int sts_rsp_count = 0; + uvm_event in_report_reg_sts; // PAUSER tracking/override bit [apb5_master_0_params::PAUSER_WIDTH-1:0] mbox_valid_users [6]; @@ -48,9 +49,10 @@ class soc_ifc_env_soc_mbox_handler_sequence extends soc_ifc_env_sequence_base #( extern virtual task mbox_pop_dataout(); extern virtual task mbox_set_status(); extern virtual task mbox_check_fsm(); + extern virtual task mbox_wait_done(); extern virtual task mbox_teardown(); - extern virtual function void report_reg_sts(uvm_status_e sts, string name); + extern virtual task report_reg_sts(uvm_status_e sts, string name, caliptra_apb_user user_handle = null); //========================================== @@ -63,6 +65,9 @@ class soc_ifc_env_soc_mbox_handler_sequence extends soc_ifc_env_sequence_base #( // Setup a User object to override PAUSER apb_user_obj = new(); + // Event + in_report_reg_sts = new(); + endfunction //========================================== @@ -106,16 +111,13 @@ class soc_ifc_env_soc_mbox_handler_sequence extends soc_ifc_env_sequence_base #( // Get COMMAND mbox_get_command(); - - // Get DATAOUT mbox_pop_dataout(); - // Set STATUS + // Return control to uC mbox_set_status(); - - // Check FSM status configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(2); // Takes a few cycles for FSM update to propagate into register mbox_check_fsm(); + mbox_wait_done(); // End of Sequence mbox_teardown(); @@ -272,11 +274,48 @@ task soc_ifc_env_soc_mbox_handler_sequence::mbox_check_fsm(); report_reg_sts(reg_sts,"mbox_status"); fsm_state = mbox_fsm_state_e'(data >> reg_model.mbox_csr_rm.mbox_status.mbox_fsm_ps.get_lsb_pos()); - if (fsm_state != MBOX_EXECUTE_UC) begin + if (fsm_state inside {MBOX_IDLE, MBOX_ERROR} && (sts_rsp_count > 0) && soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending) begin + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Observed mailbox FSM state: %p, which is not a failure since it corresponds with non_fatal HW interrupt", fsm_state), UVM_MEDIUM) + end + else if (fsm_state != MBOX_EXECUTE_UC) begin `uvm_error("SOC_MBOX_HANDLER", $sformatf("Unexpected mailbox FSM state: %p", fsm_state)) end endtask +//========================================== +// Task: mbox_wait_done +// Description: Wait for uC to end the mailbox flow as indicated +// by mbox_lock being relinquished. +// If necessary, service any cptra HW error (fatal or +// non_fatal) that occurred. +//========================================== +task soc_ifc_env_soc_mbox_handler_sequence::mbox_wait_done(); + uvm_reg_data_t non_fatal, fatal; + + // Wait for lock to clear + while(reg_model.mbox_csr_rm.mbox_lock.get_mirrored_value()) + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + + // Check for interrupts + if (sts_rsp_count && (soc_ifc_status_agent_rsp_seq.rsp.cptra_error_non_fatal_intr_pending || + soc_ifc_status_agent_rsp_seq.rsp.cptra_error_fatal_intr_pending)) begin + // Read status + reg_model.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.read(reg_sts, non_fatal, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + report_reg_sts(reg_sts, "CPTRA_HW_ERROR_NON_FATAL"); + reg_model.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.read(reg_sts, fatal, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + report_reg_sts(reg_sts, "CPTRA_HW_ERROR_FATAL"); + + if (~|fatal && ~|non_fatal) + `uvm_error("SOC_MBOX_HANDLER", $sformatf("Received status response transaction with cptra error asserted [%s] but both fatal and non_fatal registers are 0!", soc_ifc_status_agent_rsp_seq.rsp.convert2string())) + + // Write 1 to clear + reg_model.soc_ifc_reg_rm.CPTRA_HW_ERROR_NON_FATAL.write(reg_sts, non_fatal, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + report_reg_sts(reg_sts, "CPTRA_HW_ERROR_NON_FATAL"); + reg_model.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.write(reg_sts, fatal, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); + report_reg_sts(reg_sts, "CPTRA_HW_ERROR_FATAL"); + end +endtask + //========================================== // Task: mbox_teardown // Description: Placeholder task to allow derived classes @@ -293,20 +332,29 @@ endtask // of the most recent APB transfer, accounting for // the PAUSER value that was used. //========================================== -function void soc_ifc_env_soc_mbox_handler_sequence::report_reg_sts(uvm_status_e sts, string name); +task soc_ifc_env_soc_mbox_handler_sequence::report_reg_sts(uvm_status_e sts, string name, caliptra_apb_user user_handle = null); + caliptra_apb_user user; + int waiters = in_report_reg_sts.get_num_waiters(); + in_report_reg_sts.trigger(); + if (user_handle == null) user = this.apb_user_obj; + else user = user_handle; // APB error is flagged only for PAUSER that doesn't match the registered // values, it does not check that PAUSER matches the exact value in // mbox_user that was stored when lock was acquired (this results in a // silent error but a successful reg read). // Ergo, check against mbox_valid_users instead of pauser_locked. - if (sts != UVM_IS_OK && this.apb_user_obj.get_addr_user() inside mbox_valid_users) + if (sts != UVM_IS_OK && user.get_addr_user() inside mbox_valid_users) `uvm_error("SOC_MBOX_HANDLER", - $sformatf("Register access failed unexpectedly with valid PAUSER! 0x%x (%s)", this.apb_user_obj.get_addr_user(), name)) - else if (sts == UVM_IS_OK && !(this.apb_user_obj.get_addr_user() inside mbox_valid_users)) + $sformatf("Register access failed unexpectedly with valid PAUSER! 0x%x (%s)", user.get_addr_user(), name)) + else if (sts == UVM_IS_OK && !(user.get_addr_user() inside mbox_valid_users)) `uvm_error("SOC_MBOX_HANDLER", - $sformatf("Register access passed unexpectedly with invalid PAUSER! 0x%x (%s)", this.apb_user_obj.get_addr_user(), name)) + $sformatf("Register access passed unexpectedly with invalid PAUSER! 0x%x (%s)", user.get_addr_user(), name)) else `uvm_info("SOC_MBOX_HANDLER", $sformatf("Register access to (%s) with pauser_used_is_valid: %b and sts: %p", name, 1/* this.pauser_used_is_valid()*/, sts), UVM_HIGH) -endfunction + if (waiters) + in_report_reg_sts.wait_off(); + else + in_report_reg_sts.reset(); +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_soc_mbox_reg_axs_invalid_handler_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_soc_mbox_reg_axs_invalid_handler_sequence.svh new file mode 100644 index 000000000..44cf1d5ec --- /dev/null +++ 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_soc_mbox_reg_axs_invalid_handler_sequence.svh @@ -0,0 +1,201 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to wait for Mailbox commands (from uC) and +// respond/handle the command. +// This sequence also injects protocol errors into the mailbox +// by performing out-of-order register accesses. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence extends soc_ifc_env_soc_mbox_handler_sequence; + + + `uvm_object_utils( soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence ) + + extern virtual task mbox_do_random_reg_write(process mainline); + extern virtual function uvm_reg_data_t get_rand_wr_data(uvm_reg axs_reg); + + //========================================== + // Task: body + // Description: Implement main functionality for + // Caliptra-side handling of received + // mailbox request. + //========================================== + virtual task body(); + + op_sts_e op_sts; + process mbox_flow_proc; + reg_model = configuration.soc_ifc_rm; + + if (soc_ifc_status_agent_rsp_seq == null) + `uvm_fatal("SOC_MBOX_HANDLER", "SOC_IFC ENV SOC mailbox handler sequence expected a handle to the soc_ifc status agent responder sequence (from bench-level sequence) but got null!") + fork + forever begin + @(soc_ifc_status_agent_rsp_seq.new_rsp) sts_rsp_count++; + end + join_none + + // Setup + mbox_setup(); + + fork + begin: HANDLER_FLOW + mbox_flow_proc = process::self(); + // Wait for a mailbox command to be received + mbox_wait_for_command(op_sts); + if (op_sts != CPTRA_SUCCESS) begin + `uvm_error("SOC_MBOX_HANDLER", "Unsuccessful return code from wait_for_command_avail()") + end + + // Get COMMAND + mbox_get_command(); + mbox_pop_dataout(); + + // Return control to uC + mbox_set_status(); + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(2); // Takes a few cycles for FSM update to propagate into register + mbox_check_fsm(); + end + begin: ERR_INJECT_FLOW + wait(mbox_flow_proc != null); + mbox_do_random_reg_write(mbox_flow_proc); + end + join + mbox_wait_done(); + + // End of Sequence + mbox_teardown(); + + endtask + +endclass + +//========================================== +// Task: mbox_do_random_reg_write +// Description: Do some random reg write that will +// (most likely) be invalid and trigger +// the protocol error violation. +//========================================== +task soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence::mbox_do_random_reg_write(process mainline); + uvm_reg mbox_regs[$]; + int unsigned rand_idx; + int unsigned rand_delay; + uvm_reg_data_t rand_wr_data; + caliptra_apb_user local_apb_user_obj; + + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_cmd ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_dlen ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_datain ); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_dataout); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_execute); + mbox_regs.push_back(reg_model.mbox_csr_rm.mbox_status ); + + if (!std::randomize(rand_idx) with {rand_idx < mbox_regs.size(); }) + `uvm_fatal("SOC_MBOX_HANDLER", "Failed to randomize reg idx") + + // Wait to do the reg write at some random point in the sequence + std::randomize(rand_delay) with {rand_delay dist {[1:255] :/ 5, [256:1023] :/ 3, [1024:65535] :/ 1};}; + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(rand_delay); + + // Data used depends on which reg is being accessed to force invalid contents + rand_wr_data = get_rand_wr_data(mbox_regs[rand_idx]); + + // Get a randomized PAUSER for this transaction - 50% chance of being valid + local_apb_user_obj = new(); + if (!local_apb_user_obj.randomize() with {(addr_user inside {mbox_valid_users}) dist + {1 :/ 1, + 0 :/ 1}; }) + `uvm_error("SOC_MBOX_HANDLER", "Failed to randomize APB PAUSER override value") + else + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Randomized APB PAUSER override value to 0x%x", local_apb_user_obj.addr_user), UVM_HIGH) + + // Pause the main mailbox responder flow to prevent race conditions (on accesses to the same register, triggering is_busy UVM_WARNING) + if (mainline.status() inside {process::RUNNING,process::WAITING}) begin + in_report_reg_sts.wait_on(); + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Pausing main mailbox flow to allow random reg access injection"), UVM_HIGH) + mainline.suspend(); + in_report_reg_sts.reset(); + end + else begin + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Main mailbox flow is in state [%s], so it will not be suspended for random reg access injection", mainline.status().name()), UVM_HIGH) + end + + // Do the access + `uvm_info("SOC_MBOX_HANDLER", {"Performing random register access to ", mbox_regs[rand_idx].get_name()}, UVM_LOW) + if (mbox_regs[rand_idx].get_name() == "mbox_dataout") begin + mbox_regs[rand_idx].read(reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + else if (mbox_regs[rand_idx].get_name() == "mbox_datain") begin + wait(reg_model.mbox_csr_rm.mbox_fn_state_sigs.uc_receive_stage == 1'b0); + mbox_regs[rand_idx].write(reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + else begin + mbox_regs[rand_idx].write(reg_sts, rand_wr_data, UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(local_apb_user_obj)); + report_reg_sts(reg_sts, mbox_regs[rand_idx].get_name(), local_apb_user_obj); + end + if (mainline.status() == process::SUSPENDED) begin + `uvm_info("SOC_MBOX_HANDLER", $sformatf("Resuming main mailbox flow after random reg access injection"), UVM_HIGH) + mainline.resume(); + end +endtask + +//========================================== +// Task: get_rand_wr_data +// Description: Generate random data according +// to a set of rules related to which register +// is being accessed, with intent to cause +// a protocol violation. +//========================================== +function uvm_reg_data_t soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence::get_rand_wr_data(uvm_reg axs_reg); + uvm_reg_data_t tmp_data; + case (axs_reg.get_name()) inside + "mbox_cmd": begin + tmp_data = op.cmd; + end + "mbox_dlen": begin + tmp_data = op.dlen; + end + "mbox_datain", + "mbox_dataout": begin + std::randomize(tmp_data); + end + "mbox_execute": begin + uvm_reg_data_t msk; + msk = ~(uvm_reg_data_t'(1) << reg_model.mbox_csr_rm.mbox_execute.execute.get_lsb_pos()); + std::randomize(tmp_data) with {(tmp_data & msk) == 0;}; + end + "mbox_status": begin + uvm_reg_data_t msk; + msk = (uvm_reg_data_t'(1) << reg_model.mbox_csr_rm.mbox_status.status.get_n_bits()) - 1; + msk = ~msk; + std::randomize(tmp_data) with {(tmp_data & msk) == 0;}; + end + default: begin + `uvm_fatal("SOC_MBOX_HANDLER", "Bad reg") + end + endcase + return tmp_data; +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_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_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh new file mode 100644 index 000000000..e97196520 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh @@ -0,0 +1,44 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence extends soc_ifc_env_top_cptra_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence ) + + extern virtual function create_seqs(); + +endclass + +function soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::create_seqs(); + uvm_object obj; + obj = soc_ifc_env_cptra_mbox_req_rand_small_sequence_t::get_type().create_object("soc_ifc_env_cptra_mbox_seq"); + if(!$cast(soc_ifc_env_cptra_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID_SMALL", "soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::create_seqs() - .create_object() failed") + obj = soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence_t::get_type().create_object("soc_ifc_env_soc_handler_seq"); + if(!$cast(soc_ifc_env_soc_handler_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID_SMALL", "soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence::create_seqs() - .create_object() failed") +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_sequence.svh new file mode 100644 index 000000000..c9b5f5629 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_sequence.svh @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_mbox_rand_large_sequence extends soc_ifc_env_top_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_mbox_rand_large_sequence ) + + extern virtual function create_seqs(); + +endclass + +function soc_ifc_env_top_mbox_rand_large_sequence::create_seqs(); + uvm_object obj; + obj = soc_ifc_env_mbox_rand_large_sequence_t::get_type().create_object("soc_ifc_env_mbox_seq"); + if(!$cast(soc_ifc_env_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_RAND_LARGE", "soc_ifc_env_top_mbox_rand_large_sequence::create_seqs() - .create_object() failed") + soc_ifc_env_cptra_handler_seq = soc_ifc_env_cptra_mbox_handler_sequence_t::type_id::create("soc_ifc_env_cptra_handler_seq"); +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_unlock_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_unlock_sequence.svh new file mode 100644 index 000000000..db69abf2a --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_rand_large_unlock_sequence.svh @@ -0,0 +1,51 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_mbox_rand_large_unlock_sequence extends soc_ifc_env_top_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_mbox_rand_large_unlock_sequence ) + + extern virtual function create_seqs(); + extern virtual function randomize_seqs(); + +endclass + +function soc_ifc_env_top_mbox_rand_large_unlock_sequence::create_seqs(); + uvm_object obj; + obj = soc_ifc_env_mbox_rand_large_sequence_t::get_type().create_object("soc_ifc_env_mbox_seq"); + if(!$cast(soc_ifc_env_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_RAND_LARGE", "soc_ifc_env_top_mbox_rand_large_unlock_sequence::create_seqs() - .create_object() failed") + soc_ifc_env_cptra_handler_seq = soc_ifc_env_cptra_mbox_handler_sequence_t::type_id::create("soc_ifc_env_cptra_handler_seq"); +endfunction + +function soc_ifc_env_top_mbox_rand_large_unlock_sequence::randomize_seqs(); + if(!soc_ifc_env_mbox_seq.randomize()) + `uvm_fatal("SOC_IFC_MBOX_TOP", $sformatf("soc_ifc_env_top_mbox_rand_large_unlock_sequence::body() - %s randomization failed", soc_ifc_env_mbox_seq.get_type_name())); + if(!soc_ifc_env_cptra_handler_seq.randomize() with { inject_force_unlock == 1'b1; }) + `uvm_fatal("SOC_IFC_MBOX_TOP", $sformatf("soc_ifc_env_top_mbox_rand_large_unlock_sequence::body() - %s randomization failed", soc_ifc_env_cptra_handler_seq.get_type_name())); +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence.svh new file mode 100644 index 000000000..5576ddb0c --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence.svh @@ -0,0 +1,53 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence extends soc_ifc_env_top_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence ) + + extern virtual function create_seqs(); + +endclass + +function soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence::create_seqs(); + uvm_object obj; + enum { + BASE, + INTRFR + } handler_type; + obj = soc_ifc_env_mbox_reg_axs_invalid_large_sequence_t::get_type().create_object("soc_ifc_env_mbox_seq"); + if(!$cast(soc_ifc_env_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence::create_seqs() - .create_object() failed") + void'(std::randomize(handler_type)); + case (handler_type) inside + BASE: obj = soc_ifc_env_cptra_mbox_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + INTRFR: obj = soc_ifc_env_cptra_mbox_interference_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + default: `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", $sformatf("Bad handler type - %p", handler_type)) + endcase + if(!$cast(soc_ifc_env_cptra_handler_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence::create_seqs() - .create_object() failed") +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence.svh new file mode 100644 index 000000000..bf207b577 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence.svh @@ -0,0 +1,53 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence extends soc_ifc_env_top_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence ) + + extern virtual function create_seqs(); + +endclass + +function soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence::create_seqs(); + uvm_object obj; + enum { + BASE, + INTRFR + } handler_type; + obj = soc_ifc_env_mbox_reg_axs_invalid_medium_sequence_t::get_type().create_object("soc_ifc_env_mbox_seq"); + if(!$cast(soc_ifc_env_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence::create_seqs() - .create_object() failed") + void'(std::randomize(handler_type)); + case (handler_type) inside + BASE: obj = soc_ifc_env_cptra_mbox_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + INTRFR: obj = soc_ifc_env_cptra_mbox_interference_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + default: `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", $sformatf("Bad handler type - %p", handler_type)) + endcase + if(!$cast(soc_ifc_env_cptra_handler_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence::create_seqs() - .create_object() failed") +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_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_env_top_mbox_reg_axs_invalid_small_sequence.svh new file mode 100644 index 000000000..fbe6034ec --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence.svh @@ -0,0 +1,53 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Sequence to initiate (and respond) to mailbox command +// "TOP" sequence because it invokes lower level env sequences +// to facilitate the uC/SoC sides of mailbox command handling +// and this sequence defines the whole mailbox flow. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence extends soc_ifc_env_top_mbox_sequence_base; + + + `uvm_object_utils( soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence ) + + extern virtual function create_seqs(); + +endclass + +function soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence::create_seqs(); + uvm_object obj; + enum { + BASE, + INTRFR + } handler_type; + obj = soc_ifc_env_mbox_reg_axs_invalid_small_sequence_t::get_type().create_object("soc_ifc_env_mbox_seq"); + if(!$cast(soc_ifc_env_mbox_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence::create_seqs() - .create_object() failed") + void'(std::randomize(handler_type)); + case (handler_type) inside + BASE: obj = soc_ifc_env_cptra_mbox_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + INTRFR: obj = soc_ifc_env_cptra_mbox_interference_handler_sequence_t::get_type().create_object("soc_ifc_env_cptra_handler_seq"); + default: `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", $sformatf("Bad handler type - %p", handler_type)) + endcase + if(!$cast(soc_ifc_env_cptra_handler_seq,obj)) `uvm_fatal("SOC_IFC_TOP_MBOX_REG_AXS_INVALID", "soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence::create_seqs() - .create_object() failed") +endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/trng/soc_ifc/soc_ifc_env_trng_write_data_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/trng/soc_ifc/soc_ifc_env_trng_write_data_sequence.svh index d2acca98a..5f4a8b35e 100755 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/trng/soc_ifc/soc_ifc_env_trng_write_data_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/sequences/trng/soc_ifc/soc_ifc_env_trng_write_data_sequence.svh @@ -31,6 +31,7 @@ class soc_ifc_env_trng_write_data_sequence extends soc_ifc_env_sequence_base #(. rand bit trng_write_done; rand bit [3:0] trng_num_dwords; + int sts_rsp_count; bit trng_data_req; bit [apb5_master_0_params::PAUSER_WIDTH-1:0] trng_valid_user; @@ -69,15 +70,24 @@ class soc_ifc_env_trng_write_data_sequence extends soc_ifc_env_sequence_base #(. virtual task body(); + sts_rsp_count = 0; + + fork + forever begin + @(soc_ifc_status_agent_rsp_seq.new_rsp) sts_rsp_count++; + end + join_none + soc_ifc_env_trng_setup(); - `uvm_info("TRNG_REQ_SEQ", $sformatf("Responding to TRNG_DATA_REQ with %0d dwords", trng_num_dwords), UVM_DEBUG) if (this.trng_data_req == 1'b0) soc_ifc_env_trng_poll_data_req(); if (this.trng_data_req) begin + `uvm_info("TRNG_REQ_SEQ", $sformatf("Responding to TRNG_DATA_REQ with %0d dwords", trng_num_dwords), UVM_FULL) soc_ifc_env_trng_write_data(); soc_ifc_env_trng_write_done(); soc_ifc_env_trng_wait_idle(); end + `uvm_info("TRNG_REQ_SEQ", "TRNG write data sequence completed", UVM_HIGH) endtask @@ -108,6 +118,7 @@ task soc_ifc_env_trng_write_data_sequence::soc_ifc_env_trng_setup(); // Assign user and use throughout sequence apb_user_obj.set_addr_user(trng_valid_user); + `uvm_info("TRNG_REQ_SEQ", $sformatf("trng_valid_user initialized to value 0x%x", trng_valid_user), UVM_HIGH) endtask @@ -120,10 +131,15 @@ task soc_ifc_env_trng_write_data_sequence::soc_ifc_env_trng_poll_data_req(); soc_ifc_env_trng_check_data_req(data_req); while (data_req == 1'b0) begin - configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(200); - soc_ifc_env_trng_check_data_req(data_req); + wait (sts_rsp_count != 0); + data_req = soc_ifc_status_agent_rsp_seq.rsp.trng_req_pending; + sts_rsp_count = 0; end + soc_ifc_env_trng_check_data_req(data_req); + if (!data_req) + `uvm_error("TRNG_REQ_SEQ", "Got status transaction with trng_req_pending, but read from CPTRA_TRNG_STATUS.DATA_REQ returned 0!") this.trng_data_req = data_req; + `uvm_info("TRNG_REQ_SEQ", $sformatf("Got status transaction with trng_req_pending, read from CPTRA_TRNG_STATUS.DATA_REQ returned %d", data_req), UVM_MEDIUM) endtask //========================================== @@ -152,7 +168,7 @@ task soc_ifc_env_trng_write_data_sequence::soc_ifc_env_trng_write_data(); uvm_reg_data_t data; for (ii = 0; ii < this.trng_num_dwords; ii++) begin if (!std::randomize(data)) `uvm_error("TRNG_REQ_SEQ", "Failed to randomize data") - `uvm_info("TRNG_REQ_SEQ", $sformatf("Sending TRNG_DATA[%0d]: 0x%0x", ii, data), UVM_DEBUG) + `uvm_info("TRNG_REQ_SEQ", $sformatf("Sending TRNG_DATA[%0d]: 0x%0x", ii, data), UVM_HIGH) reg_model.soc_ifc_reg_rm.CPTRA_TRNG_DATA[ii].write(reg_sts, uvm_reg_data_t'(data), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); if (reg_sts != UVM_IS_OK) `uvm_error("TRNG_REQ_SEQ", "Register access failed (TRNG_DATA)") @@ -165,7 +181,7 @@ endtask //========================================== task soc_ifc_env_trng_write_data_sequence::soc_ifc_env_trng_write_done(); uvm_status_e reg_sts; - `uvm_info("TRNG_REQ_SEQ", "Sending TRNG_DONE", UVM_DEBUG) + `uvm_info("TRNG_REQ_SEQ", "Sending TRNG_DONE", UVM_MEDIUM) reg_model.soc_ifc_reg_rm.CPTRA_TRNG_STATUS.write(reg_sts, uvm_reg_data_t'(trng_write_done) << reg_model.soc_ifc_reg_rm.CPTRA_TRNG_STATUS.DATA_WR_DONE.get_lsb_pos(), UVM_FRONTDOOR, reg_model.soc_ifc_APB_map, this, .extension(apb_user_obj)); if (reg_sts != UVM_IS_OK) `uvm_error("TRNG_REQ_SEQ", "Register access failed (TRNG_DONE)") @@ -191,4 +207,5 @@ task soc_ifc_env_trng_write_data_sequence::soc_ifc_env_trng_wait_idle(); if (reg_sts != UVM_IS_OK) `uvm_error("TRNG_REQ_SEQ", "Register access failed (CPTRA_TRNG_STATUS)") end + `uvm_info("TRNG_REQ_SEQ", "Observed TRNG_DONE cleared to 0", UVM_HIGH) endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile index 8f6852326..57aedbdc2 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.compile @@ -4,6 +4,7 @@ needs: - ../../../verification_ip/interface_packages/cptra_ctrl_pkg/cptra_ctrl_hvl.compile - ../../../verification_ip/interface_packages/soc_ifc_status_pkg/soc_ifc_status_hvl.compile - ../../../verification_ip/interface_packages/cptra_status_pkg/cptra_status_hvl.compile + - ../../../verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hvl.compile src: - registers/soc_ifc_reg_model_top_pkg.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv index 311abaebb..336300eda 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.sv @@ -50,6 +50,8 @@ package soc_ifc_env_pkg; import soc_ifc_status_pkg_hdl::*; import cptra_status_pkg::*; import cptra_status_pkg_hdl::*; + import mbox_sram_pkg::*; + import mbox_sram_pkg_hdl::*; import soc_ifc_reg_model_top_pkg::*; import qvip_ahb_lite_slave_pkg::*; import qvip_ahb_lite_slave_params_pkg::*; @@ -58,6 +60,7 @@ package soc_ifc_env_pkg; `uvm_analysis_imp_decl(_soc_ifc_ctrl_agent_ae) `uvm_analysis_imp_decl(_cptra_ctrl_agent_ae) + `uvm_analysis_imp_decl(_mbox_sram_agent_ae) `uvm_analysis_imp_decl(_ahb_slave_0_ae) `uvm_analysis_imp_decl(_apb5_slave_0_ae) `uvm_analysis_imp_decl(_expected_analysis_export) @@ -75,6 +78,7 @@ package soc_ifc_env_pkg; `uvm_analysis_imp_decl(_cov_cptra_ctrl_ae) `uvm_analysis_imp_decl(_cov_cptra_status_ae) `uvm_analysis_imp_decl(_cov_ahb_ae) + `uvm_analysis_imp_decl(_cov_mbox_sram_ae) // pragma uvmf custom package_imports_additional begin import soc_ifc_pkg::*; @@ -155,8 +159,18 @@ package soc_ifc_env_pkg; typedef soc_ifc_env_mbox_rand_delay_medium_sequence soc_ifc_env_mbox_rand_delay_medium_sequence_t; `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_rand_delay_large_sequence.svh" typedef soc_ifc_env_mbox_rand_delay_large_sequence soc_ifc_env_mbox_rand_delay_large_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_sequence.svh" + typedef soc_ifc_env_mbox_reg_axs_invalid_sequence soc_ifc_env_mbox_reg_axs_invalid_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_small_sequence.svh" + typedef soc_ifc_env_mbox_reg_axs_invalid_small_sequence soc_ifc_env_mbox_reg_axs_invalid_small_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_medium_sequence.svh" + typedef soc_ifc_env_mbox_reg_axs_invalid_medium_sequence soc_ifc_env_mbox_reg_axs_invalid_medium_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_reg_axs_invalid_large_sequence.svh" + typedef soc_ifc_env_mbox_reg_axs_invalid_large_sequence soc_ifc_env_mbox_reg_axs_invalid_large_sequence_t; `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_invalid_sequence.svh" typedef soc_ifc_env_mbox_dlen_invalid_sequence soc_ifc_env_mbox_dlen_invalid_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_dir_read_sequence.svh" + typedef soc_ifc_env_mbox_dir_read_sequence soc_ifc_env_mbox_dir_read_sequence_t; `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_sequence.svh" typedef soc_ifc_env_mbox_dlen_overflow_sequence soc_ifc_env_mbox_dlen_overflow_sequence_t; `include "sequences/mbox/soc_ifc/soc_ifc_env_mbox_dlen_overflow_small_sequence.svh" @@ -191,6 +205,8 @@ package soc_ifc_env_pkg; typedef soc_ifc_env_trng_write_data_sequence soc_ifc_env_trng_write_data_sequence_t; `include "sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_handler_sequence.svh" typedef soc_ifc_env_soc_mbox_handler_sequence soc_ifc_env_soc_mbox_handler_sequence_t; + `include "sequences/mbox/soc_ifc/soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence.svh" + typedef soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence soc_ifc_env_soc_mbox_reg_axs_invalid_handler_sequence_t; ///////////////////// Sequences usable from soc_ifc bench only ///////////////////// // These sequences include stimulus for the internal/caliptra-side of the @@ -198,6 +214,8 @@ package soc_ifc_env_pkg; /* TODO: If desired in top-level rand sequence, add this to the rand_seq_idx enum/avail_env_seqs_c constraint */ `include "sequences/bringup/cptra/soc_ifc_env_cptra_rst_wait_sequence.svh" typedef soc_ifc_env_cptra_rst_wait_sequence soc_ifc_env_cptra_rst_wait_sequence_t; + `include "sequences/bringup/cptra/soc_ifc_env_cptra_init_interrupts_sequence.svh" + typedef soc_ifc_env_cptra_init_interrupts_sequence soc_ifc_env_cptra_init_interrupts_sequence_t; `include "sequences/bringup/soc_ifc_env_top_reset_warm_sequence.svh" typedef soc_ifc_env_top_reset_warm_sequence soc_ifc_env_top_reset_warm_sequence_t; `include "sequences/bringup/soc_ifc_env_top_reset_cold_sequence.svh" @@ -224,10 +242,14 @@ package soc_ifc_env_pkg; typedef soc_ifc_env_top_mbox_rand_small_sequence soc_ifc_env_top_mbox_rand_small_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_rand_medium_sequence.svh" typedef soc_ifc_env_top_mbox_rand_medium_sequence soc_ifc_env_top_mbox_rand_medium_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_mbox_rand_large_sequence.svh" + typedef soc_ifc_env_top_mbox_rand_large_sequence soc_ifc_env_top_mbox_rand_large_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_rand_small_unlock_sequence.svh" typedef soc_ifc_env_top_mbox_rand_small_unlock_sequence soc_ifc_env_top_mbox_rand_small_unlock_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_rand_medium_unlock_sequence.svh" typedef soc_ifc_env_top_mbox_rand_medium_unlock_sequence soc_ifc_env_top_mbox_rand_medium_unlock_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_mbox_rand_large_unlock_sequence.svh" + typedef soc_ifc_env_top_mbox_rand_large_unlock_sequence soc_ifc_env_top_mbox_rand_large_unlock_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_contention_sequence.svh" typedef soc_ifc_env_top_mbox_contention_sequence soc_ifc_env_top_mbox_contention_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_rand_pauser_sequence.svh" @@ -256,6 +278,12 @@ package soc_ifc_env_pkg; typedef soc_ifc_env_top_mbox_rand_delay_medium_sequence soc_ifc_env_top_mbox_rand_delay_medium_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_rand_delay_large_sequence.svh" typedef soc_ifc_env_top_mbox_rand_delay_large_sequence soc_ifc_env_top_mbox_rand_delay_large_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence.svh" + typedef soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence soc_ifc_env_top_mbox_reg_axs_invalid_small_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence.svh" + typedef soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence soc_ifc_env_top_mbox_reg_axs_invalid_medium_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence.svh" + typedef soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence soc_ifc_env_top_mbox_reg_axs_invalid_large_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_multi_agent_sequence.svh" typedef soc_ifc_env_top_mbox_multi_agent_sequence soc_ifc_env_top_mbox_multi_agent_sequence_t; `include "sequences/mbox/soc_ifc_env_top_mbox_dlen_violation_sequence.svh" @@ -270,6 +298,8 @@ package soc_ifc_env_pkg; typedef soc_ifc_env_top_cptra_mbox_sequence_base soc_ifc_env_top_cptra_mbox_sequence_base_t; `include "sequences/mbox/soc_ifc_env_top_cptra_mbox_rand_small_sequence.svh" typedef soc_ifc_env_top_cptra_mbox_rand_small_sequence soc_ifc_env_top_cptra_mbox_rand_small_sequence_t; + `include "sequences/mbox/soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence.svh" + typedef soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence soc_ifc_env_top_cptra_mbox_reg_axs_invalid_small_sequence_t; // pragma uvmf custom package_item_additional end endpackage diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo index e54e883b1..ae707c7ab 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/soc_ifc_env_pkg.vinfo @@ -3,6 +3,7 @@ @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_ctrl_pkg/cptra_ctrl_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/soc_ifc_status_pkg/soc_ifc_status_pkg.vinfo @use $UVMF_VIP_LIBRARY_HOME/interface_packages/cptra_status_pkg/cptra_status_pkg.vinfo +@use $UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo registers/soc_ifc_reg_model_top_pkg.sv +incdir+@vinfodir soc_ifc_env_pkg.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_configuration.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_configuration.svh index ee9cd8f47..fbf7ef959 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_configuration.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_configuration.svh @@ -57,6 +57,9 @@ extends uvmf_environment_configuration_base; typedef cptra_status_configuration cptra_status_agent_config_t; rand cptra_status_agent_config_t cptra_status_agent_config; + typedef mbox_sram_configuration mbox_sram_agent_config_t; + rand mbox_sram_agent_config_t mbox_sram_agent_config; + qvip_ahb_lite_slave_env_configuration qvip_ahb_lite_slave_subenv_config; @@ -90,6 +93,7 @@ extends uvmf_environment_configuration_base; cptra_ctrl_agent_config = cptra_ctrl_agent_config_t::type_id::create("cptra_ctrl_agent_config"); soc_ifc_status_agent_config = soc_ifc_status_agent_config_t::type_id::create("soc_ifc_status_agent_config"); cptra_status_agent_config = cptra_status_agent_config_t::type_id::create("cptra_status_agent_config"); + mbox_sram_agent_config = mbox_sram_agent_config_t::type_id::create("mbox_sram_agent_config"); qvip_ahb_lite_slave_subenv_config = qvip_ahb_lite_slave_env_configuration::type_id::create("qvip_ahb_lite_slave_subenv_config"); qvip_apb5_slave_subenv_config = qvip_apb5_slave_env_configuration::type_id::create("qvip_apb5_slave_subenv_config"); @@ -133,6 +137,7 @@ extends uvmf_environment_configuration_base; "\n", cptra_ctrl_agent_config.convert2string, "\n", soc_ifc_status_agent_config.convert2string, "\n", cptra_status_agent_config.convert2string, + "\n", mbox_sram_agent_config.convert2string, "\n", qvip_ahb_lite_slave_subenv_config.convert2string, "\n", qvip_apb5_slave_subenv_config.convert2string @@ -186,6 +191,9 @@ extends uvmf_environment_configuration_base; cptra_status_agent_config.initialize( interface_activity[5], {environment_path,".cptra_status_agent"}, interface_names[5]); cptra_status_agent_config.initiator_responder = RESPONDER; cptra_status_agent_config.has_coverage = 1; + mbox_sram_agent_config.initialize( interface_activity[6], {environment_path,".mbox_sram_agent"}, interface_names[6]); + mbox_sram_agent_config.initiator_responder = RESPONDER; + mbox_sram_agent_config.has_coverage = 1; // pragma uvmf custom reg_model_config_initialize begin // Register model creation and configuation diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_cov_subscriber.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_cov_subscriber.svh index 6a2b74050..b77ae11d4 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_cov_subscriber.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_cov_subscriber.svh @@ -429,6 +429,7 @@ class soc_ifc_env_cov_subscriber #( uvm_analysis_imp_cov_cptra_ctrl_ae #(cptra_ctrl_transaction, this_type) cptra_ctrl_ae; uvm_analysis_imp_cov_cptra_status_ae #(cptra_status_transaction, this_type) cptra_status_ae; uvm_analysis_imp_cov_ahb_ae #(mvc_sequence_item_base, this_type) ahb_ae; + uvm_analysis_imp_cov_mbox_sram_ae #(mbox_sram_transaction, this_type) mbox_sram_ae; //------------------------------------------------------------------------------------------ // Constructor @@ -449,6 +450,7 @@ class soc_ifc_env_cov_subscriber #( cptra_ctrl_ae = new("cptra_ctrl_ae" , this); cptra_status_ae = new("cptra_status_ae" , this); ahb_ae = new("ahb_ae" , this); + mbox_sram_ae = new("mbox_sram_ae" , this); c_soc_ifc_rm = configuration.soc_ifc_rm; soc_ifc_env_mbox_steps_cg.set_inst_name($sformatf("soc_ifc_env_mbox_steps_cg_%s",get_full_name())); @@ -473,7 +475,7 @@ class soc_ifc_env_cov_subscriber #( // SOC_IFC CTRL - write //------------------------------------------------------------------------------------------ virtual function void write_cov_soc_ifc_ctrl_ae(soc_ifc_ctrl_transaction txn); - `uvm_info("SOC_IFC_COV_SOC_IFC_CTRL", {"Collecting coverage on transaction: ", txn.convert2string()}, UVM_MEDIUM) + `uvm_info("SOC_IFC_COV_SOC_IFC_CTRL", {"Collecting coverage on transaction: ", txn.convert2string()}, UVM_HIGH) if (!txn.set_pwrgood || txn.assert_rst) begin `uvm_info("SOC_IFC_COV_SOC_IFC_CTRL", $sformatf("Got next_step [%p]", pred.next_step), UVM_FULL) soc_ifc_env_mbox_steps_cg.sample(.is_ahb(NOT_AHB_REQ), .next_step(pred.next_step)); @@ -489,6 +491,13 @@ class soc_ifc_env_cov_subscriber #( // `uvm_fatal("FIXME", "FIXME") endfunction + //------------------------------------------------------------------------------------------ + // MBOX SRAM - write + //------------------------------------------------------------------------------------------ + virtual function void write_cov_mbox_sram_ae(mbox_sram_transaction txn); +// `uvm_fatal("FIXME", "FIXME") + endfunction + //------------------------------------------------------------------------------------------ // AHB - write //------------------------------------------------------------------------------------------ @@ -501,7 +510,7 @@ class soc_ifc_env_cov_subscriber #( if (!$cast(ahb_txn,txn)) `uvm_fatal("SOC_IFC_ENV_COV", "AHB coverage analysis import received invalid transaction") if (c_soc_ifc_rm.soc_ifc_AHB_map.get_mem_by_offset(ahb_txn.address) != null) begin: MEM_HANDLE - `uvm_info("SOC_IFC_COV_AHB", $sformatf("Detected access to mailbox at address: 0x%x", ahb_txn.address), UVM_MEDIUM) + `uvm_info("SOC_IFC_COV_AHB", $sformatf("Detected access to mailbox at address: 0x%x", ahb_txn.address), UVM_HIGH) axs_mem = c_soc_ifc_rm.soc_ifc_AHB_map.get_mem_by_offset(ahb_txn.address); end: MEM_HANDLE else begin: REG_HANDLE @@ -519,7 +528,7 @@ class soc_ifc_env_cov_subscriber #( `uvm_error("SOC_IFC_COV_AHB", $sformatf("AHB transaction to address: 0x%x decodes to null from soc_ifc_AHB_map", ahb_txn.address)) end else begin: REG_AXS - `uvm_info("SOC_IFC_COV_AHB", {"Collecting coverage on access to register: ", axs_reg.get_full_name()}, UVM_MEDIUM) + `uvm_info("SOC_IFC_COV_AHB", {"Collecting coverage on access to register: ", axs_reg.get_full_name()}, UVM_HIGH) // Non-interrupt registers have 2-levels of ancestry back to reg_model top if (axs_reg.get_parent().get_parent().get_name() == "soc_ifc_rm") begin case (axs_reg.get_name()) inside @@ -570,7 +579,7 @@ class soc_ifc_env_cov_subscriber #( `uvm_error("SOC_IFC_COV_APB", $sformatf("APB transaction to address: 0x%x decodes to null from soc_ifc_APB_map", apb_txn.addr)) end else begin: REG_AXS - `uvm_info("SOC_IFC_COV_APB", {"Collecting coverage on access to register: ", axs_reg.get_full_name()}, UVM_MEDIUM) + `uvm_info("SOC_IFC_COV_APB", {"Collecting coverage on access to register: ", axs_reg.get_full_name()}, UVM_HIGH) case (axs_reg.get_name()) inside "mbox_lock", "mbox_user", diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_sequence_base.svh index 3a7ba5eb4..1cb88c7da 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_sequence_base.svh @@ -55,6 +55,7 @@ class soc_ifc_env_sequence_base #( // Responder agent sequencers in soc_ifc_environment: // configuration.soc_ifc_status_agent_config.sequencer // configuration.cptra_status_agent_config.sequencer + // configuration.mbox_sram_agent_config.sequencer typedef soc_ifc_ctrl_random_sequence soc_ifc_ctrl_agent_random_sequence_t; @@ -76,6 +77,18 @@ class soc_ifc_env_sequence_base #( `uvm_info(this.get_type_name(), "In: pre_start() for sequence", UVM_NONE) endtask + virtual function get_mbox_sram_ecc_error_injection(); + return this.configuration.mbox_sram_agent_config.inject_ecc_error; + endfunction + virtual function set_mbox_sram_ecc_single_error_injection(); + this.configuration.mbox_sram_agent_config.inject_ecc_error |= 2'b01; + endfunction + virtual function set_mbox_sram_ecc_double_error_injection(); + this.configuration.mbox_sram_agent_config.inject_ecc_error |= 2'b10; + endfunction + virtual function clr_mbox_sram_ecc_error_injection(); + this.configuration.mbox_sram_agent_config.inject_ecc_error = 2'b00; + endfunction // pragma uvmf custom class_item_additional end function new(string name = "" ); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh index 9acbec885..bcc8dd5d8 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_env_typedefs.svh @@ -45,6 +45,7 @@ * [29]: uC->SoC command */ typedef enum logic [31:0] { + MBOX_CMD_DIR_RD = 32'h01000000, MBOX_CMD_UC_BASIC = 32'h20000000, MBOX_CMD_UC_OVERRUN = 32'h20000001, MBOX_CMD_RESP_BASIC = 32'h40000000, diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_environment.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_environment.svh index f3685d805..2be6c1251 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_environment.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_environment.svh @@ -54,6 +54,9 @@ class soc_ifc_environment extends uvmf_environment_base #( typedef cptra_status_agent cptra_status_agent_t; cptra_status_agent_t cptra_status_agent; + typedef mbox_sram_agent mbox_sram_agent_t; + mbox_sram_agent_t mbox_sram_agent; + @@ -172,6 +175,8 @@ class soc_ifc_environment extends uvmf_environment_base #( soc_ifc_status_agent.set_config(configuration.soc_ifc_status_agent_config); cptra_status_agent = cptra_status_agent_t::type_id::create("cptra_status_agent",this); cptra_status_agent.set_config(configuration.cptra_status_agent_config); + mbox_sram_agent = mbox_sram_agent_t::type_id::create("mbox_sram_agent",this); + mbox_sram_agent.set_config(configuration.mbox_sram_agent_config); soc_ifc_pred = soc_ifc_pred_t::type_id::create("soc_ifc_pred",this); soc_ifc_pred.configuration = configuration; soc_ifc_sb = soc_ifc_sb_t::type_id::create("soc_ifc_sb",this); @@ -210,6 +215,7 @@ class soc_ifc_environment extends uvmf_environment_base #( super.connect_phase(phase); soc_ifc_ctrl_agent.monitored_ap.connect(soc_ifc_pred.soc_ifc_ctrl_agent_ae); cptra_ctrl_agent.monitored_ap.connect(soc_ifc_pred.cptra_ctrl_agent_ae); + mbox_sram_agent.monitored_ap.connect(soc_ifc_pred.mbox_sram_agent_ae); soc_ifc_pred.soc_ifc_sb_ap.connect(soc_ifc_sb.expected_analysis_export); soc_ifc_pred.cptra_sb_ap.connect(soc_ifc_sb.expected_cptra_analysis_export); soc_ifc_pred.soc_ifc_sb_ahb_ap.connect(soc_ifc_sb.expected_ahb_analysis_export); @@ -232,6 +238,7 @@ class soc_ifc_environment extends uvmf_environment_base #( soc_ifc_pred.cptra_cov_ap .connect (soc_ifc_env_cov_sub.cptra_ctrl_ae ); soc_ifc_status_agent.monitored_ap.connect (soc_ifc_env_cov_sub.soc_ifc_status_ae); cptra_status_agent .monitored_ap.connect (soc_ifc_env_cov_sub.cptra_status_ae ); + mbox_sram_agent .monitored_ap.connect (soc_ifc_env_cov_sub.mbox_sram_ae ); qvip_ahb_lite_slave_subenv_ahb_lite_slave_0_ap["burst_transfer_cov"].connect(soc_ifc_env_cov_sub.ahb_ae ); qvip_apb5_slave_subenv_apb5_master_0_ap ["trans_ap_cov"] .connect(soc_ifc_env_cov_sub.apb_ae ); end:connect_coverage @@ -316,6 +323,9 @@ task soc_ifc_environment::handle_reset(string kind = "HARD"); this.cptra_status_agent.handle_reset(kind); this.soc_ifc_status_agent.handle_reset(kind); + // Reset mbox_sram agent (needed to reset the ECC error injection) + this.mbox_sram_agent.handle_reset(kind); + // Reset scoreboard according to kind this.soc_ifc_sb.handle_reset(kind); 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 00d56bd37..ea6ed26c0 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 @@ -29,6 +29,7 @@ // // soc_ifc_ctrl_agent_ae receives transactions of type soc_ifc_ctrl_transaction // cptra_ctrl_agent_ae receives transactions of type cptra_ctrl_transaction +// mbox_sram_agent_ae receives transactions of type mbox_sram_transaction // ahb_slave_0_ae receives transactions of type mvc_sequence_item_base // apb5_slave_0_ae receives transactions of type mvc_sequence_item_base // @@ -81,6 +82,11 @@ class soc_ifc_predictor #( .BASE_T(BASE_T) ) ) cptra_ctrl_agent_ae; + uvm_analysis_imp_mbox_sram_agent_ae #(mbox_sram_transaction, soc_ifc_predictor #( + .CONFIG_T(CONFIG_T), + .BASE_T(BASE_T) + ) +) mbox_sram_agent_ae; uvm_analysis_imp_ahb_slave_0_ae #(mvc_sequence_item_base, soc_ifc_predictor #( .CONFIG_T(CONFIG_T), .BASE_T(BASE_T) @@ -146,6 +152,7 @@ class soc_ifc_predictor #( // Define transaction handles for debug visibility soc_ifc_ctrl_transaction soc_ifc_ctrl_agent_ae_debug; cptra_ctrl_transaction cptra_ctrl_agent_ae_debug; + mbox_sram_transaction mbox_sram_agent_ae_debug; mvc_sequence_item_base ahb_slave_0_ae_debug; mvc_sequence_item_base apb5_slave_0_ae_debug; @@ -158,18 +165,22 @@ class soc_ifc_predictor #( bit soc_ifc_rst_in_asserted = 1'b1; bit noncore_rst_out_asserted = 1'b1; bit uc_rst_out_asserted = 1'b1; - bit uc_rst_out_pend_val = 1'b0; + bit fw_update_rst_window = 1'b0; bit soc_ifc_error_intr_pending = 1'b0; bit soc_ifc_notif_intr_pending = 1'b0; bit sha_err_intr_pending = 1'b0; // TODO bit sha_notif_intr_pending = 1'b0; // TODO bit timer_intr_pending = 1'b1; + bit nmi_intr_pending = 1'b0; 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; // TODO + bit ready_for_runtime = 1'b0; bit mailbox_flow_done = 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; @@ -177,10 +188,12 @@ class soc_ifc_predictor #( int dataout_count = 0; bit [31:0] nmi_vector = 32'h0; - bit iccm_locked = 1'b0; // TODO + bit iccm_locked = 1'b0; bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg = '{default:32'h0}; // FIXME use reg-model value? security_state_t security_state = '{debug_locked: 1'b1, device_lifecycle: DEVICE_UNPROVISIONED}; bit bootfsm_breakpoint = 1'b0; + bit cptra_in_dbg_or_manuf_mode = 1'b0; + int unsigned fw_update_wait_count = 0; bit [63:0] generic_output_wires = 64'h0; @@ -207,17 +220,33 @@ class soc_ifc_predictor #( reset_flag hard_reset_flag; reset_flag soft_reset_flag; + //WDT vars: + bit [63:0] t1_count, t2_count; + bit wdt_error_intr_sent; + bit wdt_t2_error_intr_sent; + bit wdt_nmi_intr_sent; + bit reset_wdt_count; + bit wdt_t1_restart; + bit wdt_t2_restart; + extern task poll_and_run_delay_jobs(); extern function void send_delayed_expected_transactions(); extern function bit check_mbox_no_lock_error(soc_ifc_sb_apb_ap_output_transaction_t txn, uvm_reg axs_reg); + extern function bit check_mbox_ooo_error(soc_ifc_sb_apb_ap_output_transaction_t txn, uvm_reg axs_reg); + extern function bit check_mbox_inv_user_error(soc_ifc_sb_apb_ap_output_transaction_t txn, uvm_reg axs_reg); extern task update_mtime_mirrors(); extern task mtime_counter_task(); extern function bit mtime_lt_mtimecmp(); + extern task wdt_counter_task(); + extern task wdt_counter_trial(); extern function bit valid_requester(input uvm_transaction txn); extern function bit valid_receiver(input uvm_transaction txn); extern function bit sha_valid_user(input uvm_transaction txn); + extern function void predict_boot_wait_boot_done(); extern task handle_reset(input string kind = "HARD"); extern function void predict_reset(input string kind = "HARD"); + extern function bit soc_ifc_status_txn_expected_after_noncore_reset(); + extern function bit cptra_status_txn_expected_after_noncore_reset(); extern function bit soc_ifc_status_txn_expected_after_warm_reset(); extern function bit cptra_status_txn_expected_after_warm_reset(); extern function bit soc_ifc_status_txn_expected_after_cold_reset(); @@ -241,6 +270,7 @@ class soc_ifc_predictor #( soc_ifc_ctrl_agent_ae = new("soc_ifc_ctrl_agent_ae", this); cptra_ctrl_agent_ae = new("cptra_ctrl_agent_ae", this); + mbox_sram_agent_ae = new("mbox_sram_agent_ae", this); ahb_slave_0_ae = new("ahb_slave_0_ae", this); apb5_slave_0_ae = new("apb5_slave_0_ae", this); soc_ifc_sb_ap = new("soc_ifc_sb_ap", this ); @@ -266,6 +296,7 @@ class soc_ifc_predictor #( fork poll_and_run_delay_jobs(); mtime_counter_task(); + wdt_counter_task(); join_none super.run_phase(phase); endtask @@ -283,7 +314,7 @@ class soc_ifc_predictor #( soc_ifc_ctrl_agent_ae_debug = t; `uvm_info("PRED_SOC_IFC_CTRL", "Transaction Received through soc_ifc_ctrl_agent_ae", UVM_MEDIUM) - `uvm_info("PRED_SOC_IFC_CTRL", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("PRED_SOC_IFC_CTRL", {" Data: ",t.convert2string()}, UVM_HIGH) // Construct one of each output transaction type. soc_ifc_sb_ap_output_transaction = soc_ifc_sb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ap_output_transaction"); cptra_sb_ap_output_transaction = cptra_sb_ap_output_transaction_t::type_id::create("cptra_sb_ap_output_transaction"); @@ -304,11 +335,14 @@ class soc_ifc_predictor #( end if (!t.assert_rst) `uvm_fatal("PRED_SOC_IFC_CTRL", "Bad initial boot with cptra_rst_b deasserted") + if (!p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_idle) + `uvm_fatal("PRED_SOC_IFC_CTRL", $sformatf("Bad initial boot FSM prediction: %p", p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs)) if (reset_handled.is_on()) begin `uvm_error("PRED_SOC_IFC_CTRL", "reset_handled event unexpectedly set on receiving soc_ifc_ctrl_transaction for initial boot reset") reset_handled.reset(); end predict_reset("HARD"); + reset_predicted.trigger(hard_reset_flag/*"HARD"*/); end // Cold reset assertion else if (!t.set_pwrgood) begin @@ -355,6 +389,12 @@ class soc_ifc_predictor #( send_cptra_sts_txn |= (t.cptra_obf_key_rand[ii] != cptra_obf_key_reg[ii]); end cptra_obf_key_reg = t.cptra_obf_key_rand; + reset_predicted.reset(); + // No new signal predictions since it was all done on Cold reset assertion. + // But trigger the soft reset event to indicate to the predict_reset delay spinoff task + // that the soft reset is done (once cptra_rst_b deasserts) + reset_predicted.trigger(soft_reset_flag/*"SOFT"*/); + `uvm_info("PRED_SOC_IFC_CTRL", $sformatf("In response to cold_reset deassertion, send_cptra_sts_txn: %d", send_cptra_sts_txn), UVM_NONE) end // Warm reset assertion else if (t.assert_rst && !soc_ifc_rst_in_asserted) begin @@ -375,18 +415,21 @@ class soc_ifc_predictor #( // Todo check for breakpoint assertion and flag an expected AHB write to clear it soc_ifc_rst_in_asserted = 1'b0; p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.predict(1'b1); - noncore_rst_out_asserted = 1'b1; - uc_rst_out_asserted = 1'b1; - bootfsm_breakpoint = t.set_bootfsm_breakpoint; + cptra_in_dbg_or_manuf_mode = ~t.security_state.debug_locked || t.security_state.device_lifecycle == DEVICE_MANUFACTURING; + bootfsm_breakpoint = t.set_bootfsm_breakpoint && cptra_in_dbg_or_manuf_mode; + reset_predicted.reset(); send_soc_ifc_sts_txn = 1; send_cptra_sts_txn = 0; // cptra sts transaction not expected until after CPTRA_FUSE_WR_DONE + reset_wdt_count = 1'b0; + fork + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(6); // FIXME, correct delay value? + rdc_clk_gate_active = 1'b0; + join_none + `uvm_info("PRED_SOC_IFC_CTRL", $sformatf("In response to warm_reset deassertion, send_soc_ifc_sts_txn: %d", send_soc_ifc_sts_txn), UVM_NONE) end // Normal operation else begin - //TODO beyond detecting uc_rst_asserted, this block needs more logic - noncore_rst_out_asserted = 1'b0; // <-- all status transactions after the first one should reflect Caliptra reset deasserted - uc_rst_out_asserted = 1'b1; // FIXME - send_cptra_sts_txn = 1; + //TODO this block needs more logic end end @@ -400,7 +443,6 @@ class soc_ifc_predictor #( soc_ifc_sb_ap.write(soc_ifc_sb_ap_output_transaction); `uvm_info("PRED_SOC_IFC_CTRL", "Transaction submitted through soc_ifc_sb_ap", UVM_MEDIUM) end - // TODO // Code for sending output transaction out through cptra_sb_ap // Please note that each broadcasted transaction should be a different object than previously // broadcasted transactions. Creation of a different object is done by constructing the transaction @@ -451,7 +493,7 @@ class soc_ifc_predictor #( cptra_ctrl_agent_ae_debug = t; `uvm_info("PRED_CPTRA_CTRL", "Transaction Received through cptra_ctrl_agent_ae", UVM_MEDIUM) - `uvm_info("PRED_CPTRA_CTRL", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("PRED_CPTRA_CTRL", {" Data: ",t.convert2string()}, UVM_HIGH) // Construct one of each output transaction type. soc_ifc_sb_ap_output_transaction = soc_ifc_sb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ap_output_transaction"); cptra_sb_ap_output_transaction = cptra_sb_ap_output_transaction_t::type_id::create("cptra_sb_ap_output_transaction"); @@ -466,10 +508,6 @@ class soc_ifc_predictor #( // "do_predict" bypasses the access-check and does not enforce W1C // behavior on this attempt to set interrupt status to 1 p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_iccm_blocked_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); /* AHB-access only, use AHB map*/ - if (!soc_ifc_error_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value()) begin - soc_ifc_error_intr_pending = 1'b1; - send_cptra_sts_txn = 1'b1; - end end if (t.assert_clear_secrets) begin foreach (p_soc_ifc_rm.soc_ifc_reg_rm.internal_obf_key[ii]) p_soc_ifc_rm.soc_ifc_reg_rm.internal_obf_key[ii].key.reset(); @@ -530,6 +568,80 @@ class soc_ifc_predictor #( // pragma uvmf custom cptra_ctrl_agent_ae_predictor end endfunction + // FUNCTION: write_mbox_sram_agent_ae + // Transactions received through mbox_sram_agent_ae initiate the execution of this function. + // This function performs prediction of DUT output values based on DUT input, configuration and state + virtual function void write_mbox_sram_agent_ae(mbox_sram_transaction t); + // pragma uvmf custom mbox_sram_agent_ae_predictor begin + // Flags control whether each transaction is sent to scoreboard + bit send_soc_ifc_sts_txn = 0; + bit send_cptra_sts_txn = 0; + bit send_ahb_txn = 0; + bit send_apb_txn = 0; + + mbox_sram_agent_ae_debug = t; + `uvm_info("PRED_MBOX_SRAM", "Transaction Received through mbox_sram_agent_ae", UVM_MEDIUM) + `uvm_info("PRED_MBOX_SRAM", {" Data: ",t.convert2string()}, UVM_HIGH) + // Construct one of each output transaction type. + soc_ifc_sb_ap_output_transaction = soc_ifc_sb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ap_output_transaction"); + cptra_sb_ap_output_transaction = cptra_sb_ap_output_transaction_t::type_id::create("cptra_sb_ap_output_transaction"); + soc_ifc_sb_ahb_ap_output_transaction = soc_ifc_sb_ahb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ahb_ap_output_transaction"); + soc_ifc_sb_apb_ap_output_transaction = soc_ifc_sb_apb_ap_output_transaction_t::type_id::create("soc_ifc_sb_apb_ap_output_transaction"); + + if (t.is_read && t.ecc_double_bit_error) begin + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_mbox_ecc_unc_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); /* AHB-access only, use AHB map*/ + `uvm_info("PRED_MBOX_SRAM", "Received read transaction with Double bit ECC corruption, triggering the err interrupt", UVM_MEDIUM) + end + else if (t.is_read && t.ecc_single_bit_error) begin + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_internal_intr_r.notif_mbox_ecc_cor_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); /* AHB-access only, use AHB map*/ + `uvm_info("PRED_MBOX_SRAM", "Received read transaction with Single bit ECC corruption, triggering the notification interrupt", UVM_MEDIUM) + end + else begin + `uvm_info("PRED_MBOX_SRAM", "Received mailbox SRAM transaction does not cause a system state change prediction", UVM_FULL) + end + // TODO HW_ERROR_NON_FATAL activity? + + // Code for sending output transaction out through soc_ifc_sb_ap + // Please note that each broadcasted transaction should be a different object than previously + // broadcasted transactions. Creation of a different object is done by constructing the transaction + // using either new() or create(). Broadcasting a transaction object more than once to either the + // same subscriber or multiple subscribers will result in unexpected and incorrect behavior. + if (send_soc_ifc_sts_txn) begin + populate_expected_soc_ifc_status_txn(soc_ifc_sb_ap_output_transaction); + soc_ifc_sb_ap.write(soc_ifc_sb_ap_output_transaction); + `uvm_error("PRED_MBOX_SRAM", "NULL Transaction submitted through soc_ifc_sb_ap") + end + // Code for sending output transaction out through cptra_sb_ap + // Please note that each broadcasted transaction should be a different object than previously + // broadcasted transactions. Creation of a different object is done by constructing the transaction + // using either new() or create(). Broadcasting a transaction object more than once to either the + // same subscriber or multiple subscribers will result in unexpected and incorrect behavior. + if (send_cptra_sts_txn) begin + populate_expected_cptra_status_txn(cptra_sb_ap_output_transaction); + cptra_sb_ap.write(cptra_sb_ap_output_transaction); + `uvm_error("PRED_MBOX_SRAM", "NULL Transaction submitted through cptra_sb_ap") + end + // Code for sending output transaction out through soc_ifc_sb_ahb_ap + // Please note that each broadcasted transaction should be a different object than previously + // broadcasted transactions. Creation of a different object is done by constructing the transaction + // using either new() or create(). Broadcasting a transaction object more than once to either the + // same subscriber or multiple subscribers will result in unexpected and incorrect behavior. + if (send_ahb_txn) begin + soc_ifc_sb_ahb_ap.write(soc_ifc_sb_ahb_ap_output_transaction); + `uvm_error("PRED_MBOX_SRAM", "NULL Transaction submitted through soc_ifc_sb_ahb_ap") + end + // Code for sending output transaction out through soc_ifc_sb_apb_ap + // Please note that each broadcasted transaction should be a different object than previously + // broadcasted transactions. Creation of a different object is done by constructing the transaction + // using either new() or create(). Broadcasting a transaction object more than once to either the + // same subscriber or multiple subscribers will result in unexpected and incorrect behavior. + if (send_apb_txn) begin + soc_ifc_sb_apb_ap.write(soc_ifc_sb_apb_ap_output_transaction); + `uvm_error("PRED_MBOX_SRAM", "NULL Transaction submitted through soc_ifc_sb_apb_ap") + end + // pragma uvmf custom mbox_sram_agent_ae_predictor end + endfunction + // FUNCTION: write_ahb_slave_0_ae // Transactions received through ahb_slave_0_ae initiate the execution of this function. // This function performs prediction of DUT output values based on DUT input, configuration and state @@ -546,10 +658,14 @@ class soc_ifc_predictor #( bit send_cptra_sts_txn = 0; bit send_ahb_txn = 1; bit send_apb_txn = 0; + bit wdt_cascade = 0; + bit wdt_independent = 0; + bit wdt_t1_timeout = 0; + bit wdt_t2_timeout = 0; ahb_slave_0_ae_debug = t; `uvm_info("PRED_AHB", "Transaction Received through ahb_slave_0_ae", UVM_MEDIUM) - `uvm_info("PRED_AHB", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("PRED_AHB", {" Data: ",t.convert2string()}, UVM_HIGH) // Construct one of each output transaction type. soc_ifc_sb_ap_output_transaction = soc_ifc_sb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ap_output_transaction"); @@ -582,6 +698,11 @@ class soc_ifc_predictor #( if (!configuration.enable_reg_prediction) begin do_reg_prediction = 1'b0; end + else if (rdc_clk_gate_active || noncore_rst_out_asserted) begin + do_reg_prediction = 1'b0; + if (ahb_txn.RnW == AHB_READ) + soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + end else if (axs_mem != null) begin do_reg_prediction = 1'b0; end @@ -753,7 +874,10 @@ class soc_ifc_predictor #( end // Calculate any other system effects from the register access - if (axs_mem != null) begin: MEM_AXS + if (rdc_clk_gate_active || noncore_rst_out_asserted) begin + `uvm_info("PRED_AHB", {"On access to register: ", axs_reg.get_full_name(), " reset is asserted, skipping system prediction"}, UVM_MEDIUM) + end + else if (axs_mem != null) begin: MEM_AXS `uvm_info("PRED_AHB", $sformatf("Not performing any system prediction for access to mailbox at address: 0x%x", ahb_txn.address), UVM_FULL) end// MEM_AXS else if (axs_reg != null) begin: REG_AXS @@ -1054,7 +1178,7 @@ class soc_ifc_predictor #( end end "CPTRA_DBG_MANUF_SERVICE_REG": begin - `uvm_info("PRED_APB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) + `uvm_info("PRED_AHB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) end "CPTRA_CLK_GATING_EN": begin if (ahb_txn.RnW == AHB_WRITE) begin @@ -1087,9 +1211,9 @@ class soc_ifc_predictor #( 32'hfc: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Clear the isr_active bit]", UVM_MEDIUM) 32'hfd: - `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM single bit error injection]", UVM_MEDIUM) + `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM single bit flip injection]", UVM_MEDIUM) 32'hfe: - `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM double bit error injection]", UVM_MEDIUM) + `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES [Toggle random SRAM double bit flip injection]", UVM_MEDIUM) 32'hff: `uvm_info("PRED_AHB", "Observed write to CPTRA_GENERIC_OUTPUT_WIRES to End the simulation with a Success status", UVM_LOW) endcase @@ -1123,33 +1247,69 @@ class soc_ifc_predictor #( `uvm_info("PRED_AHB", {"Read to ", axs_reg.get_name(), " has no effect on system"}, UVM_MEDIUM) end end - "CPTRA_WDT_TIMER1_EN", - "CPTRA_WDT_TIMER1_CTRL", + "CPTRA_WDT_TIMER1_EN": begin + if (ahb_txn.RnW == AHB_WRITE) begin + `uvm_info("PRED_AHB", {"Detected write to ", axs_reg.get_name()," register on AHB interface, starting WDT timer1"}, UVM_MEDIUM); + end + end + "CPTRA_WDT_TIMER1_CTRL": begin + if (ahb_txn.RnW == AHB_WRITE) begin + // Handled in callbacks via reg predictor + `uvm_info("PRED_AHB", $sformatf("Handling access to %s. This will restart WDT timer1", axs_reg.get_name()), UVM_MEDIUM); + //Capture restart bit so the counters can be updated + wdt_t1_restart = data_active[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_CTRL.timer1_restart.get_lsb_pos()]; + end + end "CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0]", - "CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1]", - "CPTRA_WDT_TIMER2_EN", - "CPTRA_WDT_TIMER2_CTRL", + "CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1]": begin + if (ahb_txn.RnW == AHB_WRITE) begin + `uvm_info("PRED_AHB", {"Write to ",axs_reg.get_name()," register on AHB interface has no side-effect"}, UVM_HIGH) // TODO + end + end + "CPTRA_WDT_TIMER2_EN": begin + if (ahb_txn.RnW == AHB_WRITE) begin + `uvm_info("PRED_AHB", {"Detected write to ", axs_reg.get_name(), " register on AHB interface, starting WDT timer2"}, UVM_MEDIUM); + end + end + "CPTRA_WDT_TIMER2_CTRL": begin + if (ahb_txn.RnW == AHB_WRITE) begin + // Handled in callbacks via reg predictor + `uvm_info("PRED_AHB", $sformatf("Handling access to %s. This will restart WDT timer2", axs_reg.get_name()), UVM_MEDIUM); + //Capture restart bit so the counters can be updated + wdt_t2_restart = data_active[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_CTRL.timer2_restart.get_lsb_pos()]; + end + end "CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0]", - "CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1]", - "CPTRA_WDT_STATUS": begin + "CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1]": begin if (ahb_txn.RnW == AHB_WRITE) begin - `uvm_error("PRED_AHB", {"Add prediction for write to ",axs_reg.get_name()," register on AHB interface"}) // TODO + `uvm_info("PRED_AHB", {"Write to ",axs_reg.get_name()," register on AHB interface has no side-effect"}, UVM_HIGH) // TODO end end + "CPTRA_WDT_STATUS": begin + `uvm_info("PRED_AHB", "AHB access of WDT status", UVM_MEDIUM); + end "CPTRA_FUSE_VALID_PAUSER", "CPTRA_FUSE_PAUSER_LOCK": begin if (ahb_txn.RnW == AHB_WRITE) begin `uvm_error("PRED_AHB", {"Add prediction for write to ",axs_reg.get_name()," register on AHB interface"}) // TODO end end + ["CPTRA_WDT_CFG[0]":"CPTRA_WDT_CFG[1]"], + "CPTRA_iTRNG_ENTROPY_CONFIG_0", + "CPTRA_iTRNG_ENTROPY_CONFIG_1", + ["CPTRA_RSVD_REG[0]":"CPTRA_RSVD_REG[1]"]: begin + `uvm_info("PRED_AHB", {"Access to ", axs_reg.get_name(), " has no effect on system"}, UVM_MEDIUM) + end ["fuse_uds_seed[0]" :"fuse_uds_seed[9]" ], ["fuse_uds_seed[10]":"fuse_uds_seed[11]"]: begin if (fuse_update_enabled) begin + `uvm_error("PRED_AHB", {"Unexpected write to ", axs_reg.get_name(), " should not occur when fuse_update_enabled == 1!"}) send_cptra_sts_txn = 1'b1; end end ["fuse_field_entropy[0]" :"fuse_field_entropy[7]" ]: begin if (fuse_update_enabled) begin + `uvm_error("PRED_AHB", {"Unexpected write to ", axs_reg.get_name(), " should not occur when fuse_update_enabled == 1!"}) send_cptra_sts_txn = 1'b1; end end @@ -1184,16 +1344,8 @@ class soc_ifc_predictor #( end end "internal_fw_update_reset": begin - if (ahb_txn.RnW == AHB_WRITE) begin - if(data_active[p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_update_reset.core_rst.get_lsb_pos()]) begin - //Send cptra status txn for uc rst asserted - `uvm_info("FW_RST_DEBUG", "Sending cptra status txn for uc rst toggle due to fw upd reset", UVM_LOW) - uc_rst_out_asserted = 1; - populate_expected_cptra_status_txn(cptra_sb_ap_output_transaction); - cptra_sb_ap.write(cptra_sb_ap_output_transaction); - `uvm_info("PRED_AHB", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) - end - end + // Handled in callbacks via reg predictor + `uvm_info("PRED_AHB", $sformatf("Handling access to register %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) end "internal_fw_update_reset_wait_cycles": begin if (ahb_txn.RnW == AHB_WRITE) begin @@ -1257,17 +1409,19 @@ class soc_ifc_predictor #( // 2-levels of ancestry back to unique parent else if (axs_reg.get_parent().get_parent().get_name() == "soc_ifc_reg_rm") begin case (axs_reg.get_name()) inside - "global_intr_en_r", + "global_intr_en_r": begin + if (ahb_txn.RnW == AHB_WRITE) begin + send_cptra_sts_txn = (!this.soc_ifc_error_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value()) || + (!this.soc_ifc_notif_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value()); + this.soc_ifc_error_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value(); + this.soc_ifc_notif_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value(); + end + end "error_intr_en_r", "notif_intr_en_r", "error_intr_trig_r", "notif_intr_trig_r": begin - if (ahb_txn.RnW == AHB_WRITE) begin - send_cptra_sts_txn = (!this.soc_ifc_error_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value()) || - (!this.soc_ifc_notif_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()); - this.soc_ifc_error_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value(); - this.soc_ifc_notif_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value(); - end + `uvm_info("PRED_AHB", $sformatf("Write to %s handled in callback", axs_reg.get_name()), UVM_DEBUG) end "error_global_intr_r", "notif_global_intr_r": begin @@ -1282,8 +1436,32 @@ class soc_ifc_predictor #( // but this does not result in a cptra status transaction because we only // capture rising edges as a transaction `uvm_info("PRED_AHB", {"Write to ", axs_reg.get_name(), " attempts to clear an interrupt"}, UVM_HIGH) - this.soc_ifc_error_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value(); - this.soc_ifc_notif_intr_pending = p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value(); + + //If the WDT timeout interrupt bits are being cleared, also reset the t1/t2 count values and the corresponding + //interrupt flags (used in wdt_counter_task) + wdt_cascade = (p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_EN.timer1_en.get_mirrored_value() && !(p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_EN.timer2_en.get_mirrored_value())); + wdt_independent = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_EN.timer2_en.get_mirrored_value(); + wdt_t1_timeout = (this.t1_count == {p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1].timer1_timeout_period.get_mirrored_value(), p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0].timer1_timeout_period.get_mirrored_value()}); + wdt_t2_timeout = (this.t2_count == {p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1].timer2_timeout_period.get_mirrored_value(), p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0].timer2_timeout_period.get_mirrored_value()}); + + if (wdt_cascade && wdt_t1_timeout && data_active[`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_LOW]) begin + this.t1_count = 'h0; + this.t2_count = 'h0; + this.wdt_error_intr_sent = 1'b0; + end + else if (wdt_independent) begin + if (data_active[`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER1_TIMEOUT_STS_LOW]) begin + if (wdt_t1_timeout) + this.t1_count = 'h0; + this.wdt_error_intr_sent = 1'b0; + end + if (data_active[`SOC_IFC_REG_INTR_BLOCK_RF_ERROR_INTERNAL_INTR_R_ERROR_WDT_TIMER2_TIMEOUT_STS_LOW]) begin + if (wdt_t2_timeout) + this.t2_count = 'h0; + this.wdt_t2_error_intr_sent = 1'b0; + end + end + end end "error_internal_intr_count_r", @@ -1332,17 +1510,19 @@ class soc_ifc_predictor #( // 2-levels of ancestry back to unique parent else if (axs_reg.get_parent().get_parent().get_name() == "sha512_acc_csr_rm") begin case (axs_reg.get_name()) inside - "global_intr_en_r", + "global_intr_en_r": begin + if (ahb_txn.RnW == AHB_WRITE) begin + send_cptra_sts_txn = (!this.sha_err_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value()) || + (!this.sha_notif_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value()); + this.sha_err_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value(); + this.sha_notif_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value(); + end + end "error_intr_en_r", "notif_intr_en_r", "error_intr_trig_r", "notif_intr_trig_r": begin - if (ahb_txn.RnW == AHB_WRITE) begin - send_cptra_sts_txn = (!this.sha_err_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value()) || - (!this.sha_notif_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()); - this.sha_err_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value(); - this.sha_notif_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value(); - end + `uvm_info("PRED_AHB", $sformatf("Write to %s handled in callback", axs_reg.get_name()), UVM_DEBUG) end "error_global_intr_r", "notif_global_intr_r": begin @@ -1357,8 +1537,6 @@ class soc_ifc_predictor #( // but this does not result in a cptra status transaction because we only // capture rising edges as a transaction `uvm_info("PRED_AHB", {"Write to ", axs_reg.get_name(), " attempts to clear an interrupt"}, UVM_HIGH) - this.sha_err_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value(); - this.sha_notif_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value(); end end "error0_intr_count_r", @@ -1454,7 +1632,7 @@ class soc_ifc_predictor #( apb5_slave_0_ae_debug = t; `uvm_info("PRED_APB", "Transaction Received through apb5_slave_0_ae", UVM_MEDIUM) - `uvm_info("PRED_APB", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("PRED_APB", {" Data: ",t.convert2string()}, UVM_HIGH) // Construct one of each output transaction type. soc_ifc_sb_ap_output_transaction = soc_ifc_sb_ap_output_transaction_t::type_id::create("soc_ifc_sb_ap_output_transaction"); @@ -1471,6 +1649,11 @@ class soc_ifc_predictor #( if (!configuration.enable_reg_prediction) begin do_reg_prediction = 1'b0; end + // This is because of the RDC CLK GATE disablement... + else if (rdc_clk_gate_active || noncore_rst_out_asserted) begin + do_reg_prediction = 1'b0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; + end else begin // Mailbox accesses are discarded based on valid_requester/valid_receiver // (i.e. PAUSER + state info) @@ -1575,7 +1758,7 @@ class soc_ifc_predictor #( if (apb_txn.read_or_write == APB3_TRANS_READ && apb_txn.slave_err) begin do_reg_prediction = 1'b0; // "Expected" read data is 0 - soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end end "MODE", @@ -1588,7 +1771,7 @@ class soc_ifc_predictor #( if (apb_txn.slave_err) begin do_reg_prediction = 1'b0; // "Expected" read data is 0 - soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end end end @@ -1596,7 +1779,7 @@ class soc_ifc_predictor #( if (apb_txn.slave_err) begin do_reg_prediction = 1'b0; // "Expected" read data is 0 - soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end end "EXECUTE": begin @@ -1607,7 +1790,7 @@ class soc_ifc_predictor #( if (apb_txn.slave_err) begin do_reg_prediction = 1'b0; // "Expected" read data is 0 - soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end end end @@ -1617,7 +1800,7 @@ class soc_ifc_predictor #( if (apb_txn.slave_err) begin do_reg_prediction = 1'b0; // "Expected" read data is 0 - soc_ifc_sb_ahb_ap_output_transaction.data[0] = 0; + soc_ifc_sb_apb_ap_output_transaction.rd_data = 0; end end "CONTROL": begin @@ -1640,7 +1823,10 @@ class soc_ifc_predictor #( end // Calculate any other system effects from the register access - if (axs_reg == null) begin + if (rdc_clk_gate_active || noncore_rst_out_asserted) begin + `uvm_info("PRED_APB", {"On access to register: ", axs_reg.get_full_name(), " reset is asserted, skipping system prediction"}, UVM_MEDIUM) + end + else if (axs_reg == null) begin `uvm_error("PRED_APB", $sformatf("APB transaction to address: 0x%x decodes to null from soc_ifc_APB_map", apb_txn.addr)) end else begin @@ -1673,21 +1859,40 @@ class soc_ifc_predictor #( `uvm_info("PRED_APB", $sformatf("Logged mailbox step [%p]", next_step), UVM_HIGH) end void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end end "mbox_user": begin - if (check_mbox_no_lock_error(apb_txn, axs_reg)) begin + if (check_mbox_no_lock_error(apb_txn, axs_reg) || check_mbox_ooo_error(apb_txn, axs_reg)) begin `uvm_warning("PRED_APB", {"Access to RO register: ", axs_reg.get_name(), " triggers mailbox protocol violation"}) 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; + send_soc_ifc_sts_txn = 1'b1; + end else begin `uvm_info("PRED_APB", {"Read to ", axs_reg.get_name(), " has no effect on system"}, UVM_MEDIUM) end + void'(check_mbox_inv_user_error(apb_txn, axs_reg)); // Log the step for coverage next_step = '{null_action: 1'b1, default: 1'b0}; `uvm_info("PRED_APB", $sformatf("Logged mailbox step [%p]", next_step), UVM_HIGH) end "mbox_cmd": begin void'(check_mbox_no_lock_error(apb_txn, axs_reg)); - if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end + if (apb_txn.read_or_write == APB3_TRANS_WRITE && + do_reg_prediction && + p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_cmd_stage) begin // Log the step for coverage next_step = '{cmd_wr: 1'b1, default: 1'b0}; `uvm_info("PRED_APB", $sformatf("Logged mailbox step [%p]", next_step), UVM_HIGH) @@ -1705,6 +1910,12 @@ class soc_ifc_predictor #( end "mbox_dlen": begin void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin // Log the step for coverage if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_dlen_stage) @@ -1730,6 +1941,12 @@ class soc_ifc_predictor #( "mbox_datain": begin `uvm_info("PRED_APB", $sformatf("Access to mailbox datain, write count: %d", datain_count), UVM_FULL) void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin // Log the step for coverage if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.soc_data_stage) @@ -1747,6 +1964,12 @@ class soc_ifc_predictor #( "mbox_dataout": begin `uvm_info("PRED_APB", $sformatf("Access to mailbox dataout, read count: %d", dataout_count), UVM_FULL) void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end // Log the step for coverage next_step = '{null_action: 1'b1, default: 1'b0}; if (apb_txn.read_or_write == APB3_TRANS_READ && do_reg_prediction) begin @@ -1761,6 +1984,12 @@ class soc_ifc_predictor #( end "mbox_execute": begin void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end // Log the step for coverage next_step = '{null_action: 1'b1, default: 1'b0}; if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin @@ -1776,6 +2005,12 @@ class soc_ifc_predictor #( end "mbox_status": begin void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + 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; + send_soc_ifc_sts_txn = 1'b1; + end if (apb_txn.read_or_write == APB3_TRANS_WRITE && do_reg_prediction) begin // Log the step for coverage next_step = '{status_wr: 1'b1, default: 1'b0}; @@ -1794,6 +2029,8 @@ class soc_ifc_predictor #( end "mbox_unlock": begin void'(check_mbox_no_lock_error(apb_txn, axs_reg)); + void'(check_mbox_ooo_error(apb_txn, axs_reg)); + void'(check_mbox_inv_user_error(apb_txn, axs_reg)); // Log the step for coverage next_step = '{null_action: 1'b1, default: 1'b0}; `uvm_info("PRED_APB", $sformatf("Logged mailbox step [%p]", next_step), UVM_HIGH) @@ -1856,6 +2093,8 @@ class soc_ifc_predictor #( cptra_error_non_fatal = 1'b0; end end + "CPTRA_BOOT_STATUS", + "CPTRA_FLOW_STATUS", "CPTRA_RESET_REASON", "CPTRA_SECURITY_STATE": begin if (apb_txn.read_or_write == APB3_TRANS_WRITE) @@ -1912,44 +2151,94 @@ class soc_ifc_predictor #( // end end "CPTRA_FUSE_WR_DONE": begin - if (apb_txn.wr_data != axs_reg.get() && apb_txn.read_or_write == APB3_TRANS_WRITE) - `uvm_error("PRED_APB", $sformatf("APB transaction with data: 0x%x, write: %p, may not match reg model value: %x", apb_txn.wr_data, apb_txn.read_or_write, axs_reg.get())) // Only expect a status transaction if this fuse download is occuring during boot sequence // FIXME // Even after a warm reset, we expect a write to this register (although the write is dropped) // When writing fuse done, if breakpoint is set we're going to wait state where noncore reset will be de-asserted // SoC or JTAG would check for boot fsm to be in wait state before setting GO when ready to advance and bring uc out of reset - if (noncore_rst_out_asserted && (apb_txn.wr_data == 1/*FIXME hardcoded*/) && apb_txn.read_or_write == APB3_TRANS_WRITE) begin + if (p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_fuse && + apb_txn.wr_data[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FUSE_WR_DONE.done.get_lsb_pos()] && + apb_txn.read_or_write == APB3_TRANS_WRITE) + begin //predict ready for fuses de-assertion p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.predict(1'b0); - noncore_rst_out_asserted = 1'b0; - uc_rst_out_asserted = bootfsm_breakpoint; - send_soc_ifc_sts_txn = 1'b1; - send_cptra_sts_txn = 1'b1; - fuse_update_enabled = 1'b0; + if (bootfsm_breakpoint) begin + // Similar logic should be tied to the fw_update_reset reg callback + p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs = '{boot_wait: 1'b1, default: 1'b0}; +// uc_rst_out_asserted = 1; // No transition - this is already asserted on entry to boot_wait by merit of predict_reset("NONCORE") + fw_update_rst_window = 1'b1; + send_cptra_sts_txn = 1'b1; + `uvm_info("PRED_APB", $sformatf("Write to %s results in uc reset assertion and boot FSM state transition to %p", axs_reg.get_name(), p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs), UVM_HIGH) + fork + begin + fw_update_wait_count = p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_update_reset_wait_cycles.wait_cycles.get_mirrored_value(); + repeat(32'(p_soc_ifc_rm.soc_ifc_reg_rm.internal_fw_update_reset_wait_cycles.wait_cycles.get_mirrored_value())) begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + if (fw_update_wait_count == 0) + `uvm_fatal("PRED_APB", "Decrement will underflow!") + fw_update_wait_count--; + end + if (!bootfsm_breakpoint) begin + cptra_sb_ap_output_transaction_t local_cptra_sb_ap_txn; + `uvm_info("PRED_APB", $sformatf("After expiration of fw_update reset counter, bootfsm_breakpoint is already cleared. Submitting transaction prediction immediately for state change."), UVM_HIGH) + predict_boot_wait_boot_done(); + local_cptra_sb_ap_txn = cptra_sb_ap_output_transaction_t::type_id::create("local_cptra_sb_ap_txn"); + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); // fw_update_rst_window + cptra_sb_ap.write(local_cptra_sb_ap_txn); + `uvm_info("PRED_APB", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) + end + else begin + `uvm_info("PRED_APB", $sformatf("After expiration of fw_update reset counter, bootfsm_breakpoint is still set. Predicted state change and reset signal updates will be handled on BOOTFSM_GO."), UVM_HIGH) + end + end + join_none + end + else begin + predict_boot_wait_boot_done(); +// send_cptra_sts_txn = 1'b1; // fw_update_rst_window was never asserted + `uvm_info("PRED_APB", $sformatf("Write to %s results in uc reset deassertion and boot FSM state transition to %p", axs_reg.get_name(), p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs), UVM_HIGH) + end + fuse_update_enabled = 1'b0; + send_soc_ifc_sts_txn = 1'b1; // for ready_for_fuses + end + else begin + `uvm_info("PRED_APB", $sformatf("Write to %s has no effect on boot FSM due to state [%p] breakpoint [%d] and txn type [%p]", axs_reg.get_name(), p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs, bootfsm_breakpoint, apb_txn.read_or_write), UVM_FULL) end end "CPTRA_BOOTFSM_GO": begin // FIXME -- use reg predictor somehow? //When uc reset is still asserted and we're writing to bootfsm go, expect uc to be brough out of reset - uvm_reg_data_t fuse_wr_done = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FUSE_WR_DONE.get(); + bit setting_go = apb_txn.read_or_write == APB3_TRANS_WRITE && + apb_txn.wr_data[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_BOOTFSM_GO.GO.get_lsb_pos()]; - if (uc_rst_out_asserted && + if (p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_wait && bootfsm_breakpoint && - apb_txn.read_or_write == APB3_TRANS_WRITE && - (apb_txn.wr_data[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_BOOTFSM_GO.GO.get_lsb_pos()])) begin + setting_go) begin - bootfsm_breakpoint = 1'b0; - if (fuse_wr_done[p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FUSE_WR_DONE.done.get_lsb_pos()]) begin - noncore_rst_out_asserted = 1'b0; - uc_rst_out_asserted = 1'b0; - send_cptra_sts_txn = 1'b1; + if (fw_update_wait_count == 0) begin + `uvm_info("PRED_APB", $sformatf("Write to %s results in boot FSM state transition and uC reset deassertion", axs_reg.get_name()), UVM_MEDIUM) + predict_boot_wait_boot_done(); + send_cptra_sts_txn = 1'b1; // fw_update_rst_window + end + else begin + // State transition will be triggered in the thread spawned by CPTRA_FUSE_WR_DONE write instead + `uvm_info("PRED_APB", $sformatf("Write to %s clears bootfsm_breakpoint, but state transition is delayed by %d cycles", axs_reg.get_name(), fw_update_wait_count), UVM_HIGH) end end + else begin + `uvm_info("PRED_APB", $sformatf("Write to %s has no effect on boot FSM due to state [%p] breakpoint [%d] and 'setting_go' [%d]", axs_reg.get_name(), p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs, bootfsm_breakpoint, setting_go), UVM_DEBUG) + end + bootfsm_breakpoint &= ~setting_go; end "CPTRA_DBG_MANUF_SERVICE_REG": begin `uvm_info("PRED_APB", $sformatf("Handling access to %s. Nothing to do.", axs_reg.get_name()), UVM_DEBUG) end + ["CPTRA_WDT_CFG[0]":"CPTRA_WDT_CFG[1]"], + "CPTRA_iTRNG_ENTROPY_CONFIG_0", + "CPTRA_iTRNG_ENTROPY_CONFIG_1", + ["CPTRA_RSVD_REG[0]":"CPTRA_RSVD_REG[1]"]: begin + `uvm_info("PRED_APB", {"Access to ", axs_reg.get_name(), " has no effect on system"}, UVM_MEDIUM) + end ["fuse_uds_seed[0]" :"fuse_uds_seed[9]" ], ["fuse_uds_seed[10]":"fuse_uds_seed[11]"]: begin if (fuse_update_enabled) begin @@ -2156,12 +2445,12 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); end // === soc_ifc_notif_intr_pending === // Setting 'execute' - Expect a uC interrupt if enabled - if (!soc_ifc_notif_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()) begin + if (!soc_ifc_notif_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value()) begin `uvm_info("PRED_DLY", "Delay job triggers soc_ifc notification interrupt output", UVM_HIGH) soc_ifc_notif_intr_pending = 1'b1; send_cptra_sts_txn = 1'b1; end - else if (soc_ifc_notif_intr_pending && !p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()) begin + else if (soc_ifc_notif_intr_pending && !(p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value())) begin `uvm_info("PRED_DLY", "Delay job causes soc_ifc notification interrupt deassertion", UVM_HIGH) soc_ifc_notif_intr_pending = 1'b0; end @@ -2179,13 +2468,13 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); end // Check for any Error Interrupt - if (!soc_ifc_error_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value()) begin - `uvm_info("PRED_DLY", "Delay job triggers soc_ifc error interrupt output", UVM_HIGH) + if (!soc_ifc_error_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value()) begin + `uvm_info("PRED_DLY", "Delay job triggers soc_ifc error_intr output", UVM_HIGH) soc_ifc_error_intr_pending = 1'b1; send_cptra_sts_txn = 1'b1; end - else if (soc_ifc_error_intr_pending && !p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value()) begin - `uvm_info("PRED_DLY", "Delay job causes soc_ifc error interrupt deassertion", UVM_HIGH) + else if (soc_ifc_error_intr_pending && !(p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.global_intr_en_r.error_en.get_mirrored_value())) begin + `uvm_info("PRED_DLY", "Delay job causes soc_ifc error_intr deassertion", UVM_HIGH) soc_ifc_error_intr_pending = 1'b0; end @@ -2201,34 +2490,58 @@ function void soc_ifc_predictor::send_delayed_expected_transactions(); send_cptra_sts_txn = 1; end + // // Check for NMI Interrupt + // if (!nmi_intr_pending && p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.nmi_pin.get_mirrored_value()) begin + // `uvm_info("PRED_DLY", "Delay job triggers nmi interrupt output", UVM_MEDIUM) + // nmi_intr_pending = 1'b1; + // send_cptra_sts_txn = 1'b1; + // end + // SHA Accel Notification Interrupt // Expect a status transition on sha_notif_intr_pending // whenever a write changes the value of SHA Accelerator Execute // and triggers a delayed prediction job resulting in interrupt firing - if (!sha_notif_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()) begin - sha_notif_intr_pending = p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value(); + if (!sha_notif_intr_pending && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value()) begin + sha_notif_intr_pending = 1; if (sha_notif_intr_pending) begin - `uvm_info("PRED_AHB", "Delay job triggers sha_notif_intr_pending transition", UVM_HIGH) + `uvm_info("PRED_DLY", "Delay job triggers sha_notif_intr_pending transition", UVM_HIGH) send_cptra_sts_txn = 1'b1; end end - else if (sha_notif_intr_pending && !p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value()) begin + else if (sha_notif_intr_pending && !(p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() && p_soc_ifc_rm.sha512_acc_csr_rm.intr_block_rf_ext.global_intr_en_r.notif_en.get_mirrored_value())) begin `uvm_info("PRED_DLY", "Delay job causes sha512_acc notification interrupt deassertion", UVM_HIGH) sha_notif_intr_pending = 1'b0; end + ///////////////// ORDERING MUST BE PRESERVED FOR THESE ASSIGNMENTS ///////////////// + // Check for uC reset changes (both transitions due to delay job + // scheduled from internal_fw_update_reset callback) + if (p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_wait && !uc_rst_out_asserted) begin + uc_rst_out_asserted = 1; + send_cptra_sts_txn = 1; + end + // uC reset deassertion is delayed from iccm_lock and fw_update_rst_window transitions + else if (p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_done && !iccm_locked && !fw_update_rst_window && uc_rst_out_asserted) begin + uc_rst_out_asserted = 0; + send_cptra_sts_txn = 1; + end + + if ((p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_fw_rst || p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_wait) && !fw_update_rst_window) begin + fw_update_rst_window = 1; + send_cptra_sts_txn = 1; + end + else if (p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs.boot_done && fw_update_rst_window) begin + fw_update_rst_window = 0; + send_cptra_sts_txn = 1; + end + // Check for iccm unlock change if (iccm_locked && ~|p_soc_ifc_rm.soc_ifc_reg_rm.internal_iccm_lock.lock.get_mirrored_value()) begin `uvm_info("PRED_DLY", $sformatf("Detected de-assertion of ICCM LOCK"), UVM_LOW) iccm_locked = 0; - uc_rst_out_pend_val = 1; - send_cptra_sts_txn = 1; - end - else if (uc_rst_out_pend_val) begin - uc_rst_out_asserted = 0; - uc_rst_out_pend_val = 0; send_cptra_sts_txn = 1; end + ///////////////// END ORDERED ASSIGNMENTS ///////////////// ////////////////////////////////////////////////// // Send expected transactions to Scoreboard @@ -2326,8 +2639,123 @@ function bit soc_ifc_predictor::check_mbox_no_lock_error(soc_ifc_sb_apb_ap_outpu error_job.state_nxt = MBOX_IDLE; error_job.error = '{axs_without_lock: 1'b1, default: 1'b0}; p_soc_ifc_rm.delay_jobs.push_back(error_job); - `uvm_info("SOC_IFC_REG_CBS", $sformatf("%s to %s on map [%s] with value [%x] causes a mbox no_lock protocol violation. Delay job is queued to update DUT model.", txn.read_or_write.name(), fld.get_name(), p_soc_ifc_APB_map.get_name(), txn.read_or_write == APB3_TRANS_WRITE ? txn.wr_data : txn.rd_data), UVM_HIGH) + `uvm_info("MBOX_NO_LOCK_CHK", + $sformatf("%s to %s on map [%s] with value [%x] causes a mbox no_lock protocol violation. Delay job is queued to update DUT model.", + txn.read_or_write.name(), + fld.get_name(), + p_soc_ifc_APB_map.get_name(), + txn.read_or_write == APB3_TRANS_WRITE ? txn.wr_data : txn.rd_data), + UVM_LOW) + end + return is_error; +endfunction + +function bit soc_ifc_predictor::check_mbox_ooo_error(soc_ifc_sb_apb_ap_output_transaction_t txn, uvm_reg axs_reg); + soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error error_job; + uvm_reg_field fld; + bit is_error = 0; + // Only check for access-out-of-order errors here that will not be caught + // by reg prediction callbacks. + // That means that register accesses where valid_requester/valid_receiver is false + // (as applicable to the register in question) might trigger an error if the inverse + // is true (valid_receiver/valid_requester). + // When !soc_has_lock, valid_receiver must be true for any writes made, + // but not necessarily valid_requester. + // Since valid_requester may be false, the reg_prediction is not done, and + // thus the callback can't catch this scenario. + if (txn.addr_user inside mbox_valid_users) begin + case (axs_reg.get_name()) inside + "mbox_lock": begin + fld = axs_reg.get_field_by_name("lock"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && !p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_idle; + end + "mbox_user": begin + fld = axs_reg.get_field_by_name("user"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && !p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_idle; + end + "mbox_cmd": begin + fld = axs_reg.get_field_by_name("command"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && valid_receiver(txn) && !valid_requester(txn); + end + "mbox_dlen": begin + fld = axs_reg.get_field_by_name("length"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && valid_receiver(txn) && !valid_requester(txn); + end + "mbox_datain": begin + fld = axs_reg.get_field_by_name("datain"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && valid_receiver(txn) && !valid_requester(txn); + end + "mbox_dataout": begin + fld = axs_reg.get_field_by_name("dataout"); + is_error = !valid_receiver(txn) && valid_requester(txn); + end + "mbox_execute": begin + fld = axs_reg.get_field_by_name("execute"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && valid_receiver(txn) && !valid_requester(txn); + end + "mbox_status": begin + fld = axs_reg.get_field_by_name("status"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && !valid_receiver(txn) && valid_requester(txn); + end + "mbox_unlock": begin + fld = axs_reg.get_field_by_name("unlock"); + is_error = txn.read_or_write == APB3_TRANS_WRITE && !p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_idle; + end + default: begin + `uvm_error("MBOX_OOO_CHK", "This function should not be called for access to non-mailbox regs") + end + endcase + end + if (is_error && p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_error) begin + `uvm_info("MBOX_OOO_CHK", + $sformatf("%s to %s on map [%s] with value [%x] calculates as a mbox out_of_order protocol violation, but no delay job is scheduled since predictor is already in state [%p].", + txn.read_or_write.name(), + fld.get_name(), + p_soc_ifc_APB_map.get_name(), + txn.read_or_write == APB3_TRANS_WRITE ? txn.wr_data : txn.rd_data, + p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs), + UVM_LOW) + end + else if (is_error) begin + error_job = soc_ifc_reg_delay_job_mbox_csr_mbox_prot_error::type_id::create("error_job"); + error_job.rm = p_soc_ifc_rm.mbox_csr_rm; + error_job.map = p_soc_ifc_APB_map; + error_job.fld = fld; + error_job.set_delay_cycles(0); + error_job.state_nxt = MBOX_ERROR; + error_job.error = '{axs_incorrect_order: 1'b1, default: 1'b0}; + p_soc_ifc_rm.delay_jobs.push_back(error_job); + `uvm_info("MBOX_OOO_CHK", $sformatf("%s to %s on map [%s] with value [%x] causes a mbox out_of_order protocol violation. Delay job is queued to update DUT model.", txn.read_or_write.name(), fld.get_name(), p_soc_ifc_APB_map.get_name(), txn.read_or_write == APB3_TRANS_WRITE ? txn.wr_data : txn.rd_data), UVM_LOW) + p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs = '{mbox_error: 1'b1, default: 1'b0}; + end + return is_error; +endfunction + +function bit soc_ifc_predictor::check_mbox_inv_user_error(soc_ifc_sb_apb_ap_output_transaction_t txn, uvm_reg axs_reg); + bit is_error = 0; + // The invalid PAUSER error is only flagged for write attempts by an agent + // that is considered 'valid', but which currently doesn't have lock + // (exception: reads to mbox_dataout while not holding lock also flagged) + if (txn.addr_user inside mbox_valid_users) begin + case (axs_reg.get_name()) inside + "mbox_lock": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + "mbox_user": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + "mbox_cmd": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + "mbox_dlen": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) || valid_receiver(txn)); + "mbox_datain": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + "mbox_dataout": is_error = !(valid_requester(txn) || valid_receiver(txn)); + "mbox_execute": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + "mbox_status": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) || valid_receiver(txn)); + // Unwriteable via APB, but writes still don't flag a PAUSER invalid error + "mbox_unlock": is_error = txn.read_or_write == APB3_TRANS_WRITE && !(valid_requester(txn) ); + default: `uvm_error("MBOX_INV_USER_CHK", "This function should not be called for access to non-mailbox regs") + endcase + end + if (is_error) begin + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_inv_dev_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); /* AHB-access only, use AHB map*/ + `uvm_info("MBOX_INV_USER_CHK", $sformatf("%s to %s on map [%s] with user [0x%x] causes a mbox invalid PAUSER detection.", txn.read_or_write.name(), axs_reg.get_name(), p_soc_ifc_APB_map.get_name(), txn.addr_user), UVM_LOW) end + return is_error; endfunction task soc_ifc_predictor::update_mtime_mirrors(); @@ -2339,26 +2767,35 @@ task soc_ifc_predictor::update_mtime_mirrors(); p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.get_mirrored_value() << 32; new_mtime = mtime + 1; // In clock cycles - if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.is_busy()) begin - uvm_wait_for_nba_region(); + fork if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.is_busy()) begin - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.predict(new_mtime[31:00], .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(p_soc_ifc_AHB_map)); + uvm_wait_for_nba_region(); + // If mtime_l transitions from busy to not busy on the current clock edge, leave the mirror at the value it just acquired instead of overwriting + // (unless the value was not updated by the recent transfer, e.g. because it was an APB transfer) + // Else, predict a new value (which will be overwritten later when the active transfer completes) + if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.is_busy() || (mtime[31:00] == p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.get_mirrored_value())) begin + p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.predict(new_mtime[31:00], .kind(UVM_PREDICT_WRITE), .path(UVM_PREDICT), .map(p_soc_ifc_AHB_map)); + end + new_mtime[31:00] = p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.get_mirrored_value(); + end + else begin + p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.predict(new_mtime[31:00]); end - new_mtime[31:00] = p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.get_mirrored_value(); - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.predict(new_mtime[63:32]); - end - else if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.is_busy()) begin - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.predict(new_mtime[31:00]); - uvm_wait_for_nba_region(); if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.is_busy()) begin - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.predict(new_mtime[63:32], .kind(UVM_PREDICT_READ), .path(UVM_PREDICT), .map(p_soc_ifc_AHB_map)); + uvm_wait_for_nba_region(); + // If mtime_h transitions from busy to not busy on the current clock edge, leave the mirror at the value it just acquired instead of overwriting + // (unless the value was not updated by the recent transfer, e.g. because it was an APB transfer) + // Else, predict a new value (which will be overwritten later when the active transfer completes) + if (p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.is_busy() || (mtime[63:32] == p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.get_mirrored_value())) begin + p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.predict(new_mtime[63:32], .kind(UVM_PREDICT_WRITE), .path(UVM_PREDICT), .map(p_soc_ifc_AHB_map)); + end + new_mtime[63:32] = p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.get_mirrored_value(); end - new_mtime[63:32] = p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.get_mirrored_value(); - end - else begin - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.predict(new_mtime[63:32]); - p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_l.count_l.predict(new_mtime[31:00]); - end + else begin + p_soc_ifc_rm.soc_ifc_reg_rm.internal_rv_mtime_h.count_h.predict(new_mtime[63:32]); + end + join + `uvm_info("PRED", $sformatf("Updated mtime register mirrors to 0x%x", new_mtime), UVM_DEBUG) endtask @@ -2385,25 +2822,202 @@ function bit soc_ifc_predictor::mtime_lt_mtimecmp(); return mtime < mtimecmp; endfunction -function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_warm_reset(); - /* FIXME calculate this from the reg-model somehow? */ - return p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.get_mirrored_value() || 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 */ +//If WDT is enabled via reg write, emulate behavior here +task soc_ifc_predictor::wdt_counter_task(); + bit timer1_debug_flag, timer2_debug_flag; + forever begin + uvm_reg_data_t wdt_reg_data; + logic wdt_t1_en; + logic wdt_t2_en; + logic cascade, independent; + logic [63:0] wdt_t1_period, wdt_t2_period; + bit wdt_t1_restart_temp; + + cptra_sb_ap_output_transaction_t local_cptra_sb_ap_txn; + local_cptra_sb_ap_txn = cptra_sb_ap_output_transaction_t::type_id::create("local_cptra_sb_ap_txn"); + + //Poll for WDT enable bits + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_EN.timer1_en.get(); //_mirrored_value(); + wdt_t1_en = wdt_reg_data[0]; + + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_EN.timer2_en.get(); //_mirrored_value(); + wdt_t2_en = wdt_reg_data[0]; + + cascade = (wdt_t1_en && !wdt_t2_en); + independent = wdt_t2_en; + + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[0].timer1_timeout_period.get(); + wdt_t1_period[31:0] = wdt_reg_data[31:0]; + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER1_TIMEOUT_PERIOD[1].timer1_timeout_period.get(); + wdt_t1_period[63:32] = wdt_reg_data[31:0]; + + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[0].timer2_timeout_period.get(); + wdt_t2_period[31:0] = wdt_reg_data[31:0]; + wdt_reg_data = p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_WDT_TIMER2_TIMEOUT_PERIOD[1].timer2_timeout_period.get(); + wdt_t2_period[63:32] = wdt_reg_data[31:0]; + + //Reset event + if (this.reset_wdt_count) begin + `uvm_info("PRED_WDT", "Resetting WDT t1 and t2 counts due to a reset event", UVM_HIGH) + this.t1_count = 'h0; + this.t2_count = 'h0; + this.wdt_error_intr_sent = 1'b0; + this.wdt_t2_error_intr_sent = 1'b0; + this.wdt_nmi_intr_sent = 1'b0; + end + + //Cascade mode + if (cascade) begin + if (this.wdt_t1_restart) begin + this.t1_count = 'h0; + `uvm_info("PRED_WDT", "Cascade mode, received t1 pet - restarting t1 count", UVM_MEDIUM) + this.wdt_t1_restart = 1'b0; //Reset flag so we can capture another restart event + end + else if (this.t1_count != wdt_t1_period) begin + this.t1_count++; + if (!($time % 500)) + `uvm_info("PRED_WDT", $sformatf("In cascade mode. t1_count increments to 0x%x, wdt_to_period is 0x%x", this.t1_count, wdt_t1_period), UVM_DEBUG) + end + else begin + //T1 expired, so send out soc error intr, and start t2 counter + if (!this.wdt_error_intr_sent) begin + `uvm_info("PRED_WDT", "Timer1 expired in cascade mode. Starting timer2", UVM_MEDIUM) + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_wdt_timer1_timeout_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); + + //Set a flag so we don't keep sending transactions while the timer holds value until interrupt + //is serviced or reset + this.wdt_error_intr_sent = 1'b1; + end + + if (this.wdt_t2_restart) begin + `uvm_error("PRED_WDT", "Cascade mode, received t2 pet - unexpected t2 pet!") + end + else if (this.t2_count != wdt_t2_period) begin + this.t2_count++; + if (!($time % 500)) + `uvm_info("PRED_WDT", $sformatf("In cascade mode. t2_count increments to 0x%x, wdt_to_period is 0x%x", this.t2_count, wdt_t2_period), UVM_DEBUG) + end + else begin + if (!this.wdt_nmi_intr_sent) begin + `uvm_info("PRED_WDT", "Timer2 expired in cascade mode. Expecting NMI to be handled", UVM_MEDIUM); + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_HW_ERROR_FATAL.nmi_pin.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); //TODO: use default map? + + //Sending cptra_status_txn in the same clock as NMI + nmi_intr_pending = 1'b1; + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); + cptra_sb_ap.write(local_cptra_sb_ap_txn); + + //Set a flag so we don't keep sending transactions while the timer holds value until interrupt + //is serviced or reset + this.wdt_nmi_intr_sent = 1'b1; + end + end + end + end //Cascade mode + else if (independent) begin + if (this.wdt_t1_restart) begin + this.t1_count = 'h0; + `uvm_info("PRED_WDT", "Independent mode, received t1 pet - restarting t1 count", UVM_MEDIUM) + this.wdt_t1_restart = 1'b0; //Reset flag so we can capture another restart event + end + else if (this.t1_count != wdt_t1_period) begin + this.t1_count++; + if (!($time % 500)) + `uvm_info("PRED_WDT", $sformatf("In independent mode. t1_count increments to 0x%x, wdt_to_period is 0x%x", this.t1_count, wdt_t1_period), UVM_DEBUG) + end + else begin + //T1 expired, so send out soc error intr + if (!this.wdt_error_intr_sent) begin + `uvm_info("PRED_WDT", "Independent mode, T1 expired", UVM_MEDIUM) + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_wdt_timer1_timeout_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); + + //Set a flag so we don't keep sending transactions while the timer holds value until interrupt + //is serviced or reset + this.wdt_error_intr_sent = 1'b1; + timer1_debug_flag = 0; + end + else if (!timer1_debug_flag) begin + `uvm_info("PRED_WDT", "Independent mode, T1 expired, but wdt_error_intr_sent is already set!", UVM_DEBUG) + timer1_debug_flag = 1; + end + end + //------------------------------------------------- + //Timer 2 + //------------------------------------------------- + if (this.wdt_t2_restart) begin + this.t2_count = 'h0; + `uvm_info("PRED_WDT", "Independent mode, received t2 pet - restarting t2 count", UVM_MEDIUM) + this.wdt_t2_restart = 1'b0; //Reset flag so we can capture another restart event + end + else if (this.t2_count != wdt_t2_period) begin + this.t2_count++; + if (!($time % 500)) + `uvm_info("PRED_WDT", $sformatf("In independent mode. t2_count increments to 0x%x, wdt_to_period is 0x%x", this.t2_count, wdt_t2_period), UVM_DEBUG) + end + else begin + //T2 expired, so send out soc error intr + if (!this.wdt_t2_error_intr_sent) begin + `uvm_info("PRED_WDT", "Independent mode, T2 expired", UVM_MEDIUM) + p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_internal_intr_r.error_wdt_timer2_timeout_sts.predict(1'b1, -1, UVM_PREDICT_READ, UVM_PREDICT, p_soc_ifc_AHB_map); + + //Set a flag so we don't keep sending transactions while the timer holds value until interrupt + //is serviced or reset + this.wdt_t2_error_intr_sent = 1'b1; + timer2_debug_flag = 0; + end + else if (!timer2_debug_flag) begin + `uvm_info("PRED_WDT", "Independent mode, T2 expired, but wdt_t2_error_intr_sent is already set!", UVM_DEBUG) + timer2_debug_flag = 1; + end + end + + end //Independent mode + + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + // Hit an issue where this task would make predictions and schedule delay jobs before poll_and_run_delay_jobs() had + // kicked off the current cycle's jobs - so delay jobs (to intr pins) were not being delayed. + // Stall until after the task poll_and_run_delay_jobs has already forked delay jobs before reentering wdt loop and predicting new updates + uvm_wait_for_nba_region(); + + end //forever +endtask + + +function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_noncore_reset(); + /* 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 */ endfunction -function bit soc_ifc_predictor::cptra_status_txn_expected_after_warm_reset(); +function bit soc_ifc_predictor::cptra_status_txn_expected_after_noncore_reset(); /* FIXME calculate this from the reg-model somehow? */ - return !noncore_rst_out_asserted || - !uc_rst_out_asserted || -// p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.error_global_intr_r.agg_sts.get_mirrored_value() || -// p_soc_ifc_rm.soc_ifc_reg_rm.intr_block_rf_ext.notif_global_intr_r.agg_sts.get_mirrored_value() || -// sha_err_intr_pending || -// sha_notif_intr_pending || -// timer_intr_pending || -// nmi_intr_pending || - iccm_locked || + // NOTE: Interrupt signals deasserting (due to reset) will not result in a + // status transaction, because only interrupt rising edges are detected + return !noncore_rst_out_asserted || + !uc_rst_out_asserted || + iccm_locked || |nmi_vector; endfunction +function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_warm_reset(); + // Most soc_ifc_status signals are actually reset by the noncore reset assertion (later) + // instead of the cptra_rst_b + return p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.get_mirrored_value(); +endfunction + +function bit soc_ifc_predictor::cptra_status_txn_expected_after_warm_reset(); + // NOTE: Almost all (maybe all?) cptra_status signals persists across warm reset + // until it cascades into the assertion of noncore reset. + return 0; +endfunction + +function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_cold_reset(); + return soc_ifc_status_txn_expected_after_warm_reset() || soc_ifc_status_txn_expected_after_noncore_reset(); /* all resets are expected in conjunction with cold */ +endfunction + +function bit soc_ifc_predictor::cptra_status_txn_expected_after_cold_reset(); + return cptra_status_txn_expected_after_warm_reset() || cptra_status_txn_expected_after_noncore_reset(); /* all resets are expected in conjunction with cold */ +endfunction + function bit soc_ifc_predictor::valid_requester(input uvm_transaction txn); soc_ifc_sb_ahb_ap_output_transaction_t ahb_txn; soc_ifc_sb_apb_ap_output_transaction_t apb_txn; @@ -2441,7 +3055,7 @@ function bit soc_ifc_predictor::valid_requester(input uvm_transaction txn); return valid_requester; end else begin - `uvm_error("PRED", "valid_requester received invalid transaction - cannot cast as AHB or APB!") + `uvm_error("PRED_VALID_REQ", "valid_requester received invalid transaction - cannot cast as AHB or APB!") valid_requester = 0; return valid_requester; end @@ -2490,7 +3104,7 @@ function bit soc_ifc_predictor::valid_receiver(input uvm_transaction txn); return valid_receiver; end else begin - `uvm_error("PRED", "valid_receiver received invalid transaction - cannot cast as AHB or APB!") + `uvm_error("PRED_VALID_RCV", "valid_receiver received invalid transaction - cannot cast as AHB or APB!") valid_receiver = 0; return valid_receiver; end @@ -2531,12 +3145,33 @@ function bit soc_ifc_predictor::sha_valid_user(input uvm_transaction txn); return sha_valid_user; end else begin - `uvm_error("PRED", "sha_valid_user received invalid transaction - cannot cast as AHB or APB!") + `uvm_error("PRED_VALID_SHA", "sha_valid_user received invalid transaction - cannot cast as AHB or APB!") sha_valid_user = 0; return sha_valid_user; end endfunction +function void soc_ifc_predictor::predict_boot_wait_boot_done(); + cptra_sb_ap_output_transaction_t local_cptra_sb_ap_txn; + + p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs = '{boot_done: 1'b1, default: 1'b0}; + fw_update_rst_window = 1'b0; + + fork + begin + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(1); + if (uc_rst_out_asserted) begin + uc_rst_out_asserted = 1'b0; + local_cptra_sb_ap_txn = cptra_sb_ap_output_transaction_t::type_id::create("local_cptra_sb_ap_txn"); + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); + cptra_sb_ap.write(local_cptra_sb_ap_txn); + `uvm_info("PRED_BOOT", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) + end + end + join_none + +endfunction + task soc_ifc_predictor::handle_reset(input string kind = "HARD"); uvm_object obj_triggered; reset_flag kind_predicted; @@ -2548,75 +3183,166 @@ task soc_ifc_predictor::handle_reset(input string kind = "HARD"); reset_handled.trigger(kind_handled); reset_predicted.wait_trigger_data(obj_triggered); if (!$cast(kind_predicted, obj_triggered)) - `uvm_fatal("SOC_IFC_PRED", "Failed to retrieve triggered reset_flag") + `uvm_fatal("PRED_HANDLE_RESET", "Failed to retrieve triggered reset_flag") if (kind_handled != kind_predicted) - `uvm_error("SOC_IFC_PRED", $sformatf("handle_reset called with different reset type [%s] than was processed in predictor [%s]!", kind_handled.get_name(), kind_predicted.get_name())) - reset_predicted.reset(); + `uvm_error("PRED_HANDLE_RESET", $sformatf("handle_reset called with different reset type [%s] than was processed in predictor [%s]!", kind_handled.get_name(), kind_predicted.get_name())) endtask function void soc_ifc_predictor::predict_reset(input string kind = "HARD"); uvm_reg all_regs[$]; - - `uvm_info("SOC_IFC_PRED", $sformatf("Predicting reset of kind: %p", kind), UVM_LOW) + reset_flag last_predicted_kind = null; + + `uvm_info("PRED_RESET", $sformatf("Predicting reset of kind: %p", kind), UVM_LOW) + + // Monitor the assertion of internal resets, which assert instantly for HARD reset + // but are delayed slightly from SOFT resets + if (kind == "HARD") begin: IMMEDIATE_INTERNAL_RESET_ASSERTION + `uvm_info("PRED_RESET", $sformatf("Reset prediction of kind: %p results in immediate assertion of internal resets", kind), UVM_MEDIUM) + noncore_rst_out_asserted = 1'b1; + uc_rst_out_asserted = 1'b1; + rdc_clk_gate_active = 1'b1; + end + else if (kind == "SOFT") begin + fork + begin: DELAY_INTERNAL_RESET_ASSERTION + cptra_sb_ap_output_transaction_t local_cptra_sb_ap_txn; + soc_ifc_sb_ap_output_transaction_t local_soc_ifc_sb_ap_txn; + bit send_soc_ifc_sts_txn = soc_ifc_status_txn_expected_after_noncore_reset(); + + // Do the noncore reset + `uvm_info("PRED_RESET", $sformatf("Reset prediction of kind: %p results in assertion of internal resets after a delay", kind), UVM_MEDIUM) + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(3); // FIXME, correct delay value? + predict_reset("NONCORE"); + + // Send predicted transactions + if (1) begin + local_cptra_sb_ap_txn = cptra_sb_ap_output_transaction_t::type_id::create("local_cptra_sb_ap_txn"); + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); + cptra_sb_ap.write(local_cptra_sb_ap_txn); + `uvm_info("PRED_RESET", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) + end + if (send_soc_ifc_sts_txn) begin + local_soc_ifc_sb_ap_txn = soc_ifc_sb_ap_output_transaction_t::type_id::create("local_soc_ifc_sb_ap_txn"); + populate_expected_soc_ifc_status_txn(local_soc_ifc_sb_ap_txn); + soc_ifc_sb_ap.write(local_soc_ifc_sb_ap_txn); + `uvm_info("PRED_RESET", "Transaction submitted through soc_ifc_sb_ap", UVM_MEDIUM) + end + end: DELAY_INTERNAL_RESET_ASSERTION + join_none + end + else if (kind == "NONCORE") begin: IMMEDIATE_INTERNAL_RESET_DEASSERTION + `uvm_info("PRED_RESET", $sformatf("Reset prediction of kind: %p results in assertion of internal resets", kind), UVM_MEDIUM) + noncore_rst_out_asserted = 1'b1; + uc_rst_out_asserted = 1'b1; + rdc_clk_gate_active = 1'b1; + end + + // Track the BOOT FSM internally + if (kind inside {"HARD", "SOFT"}) begin: BOOT_FSM_THREAD + p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs = '{boot_idle: 1'b1, default: 1'b0}; + // schedule the delayed transition to next state + // Wait for the reset deassertion transactions to be detected, indicating + // BOOT FSM can progress and subsequent + fork + begin + cptra_sb_ap_output_transaction_t local_cptra_sb_ap_txn; + `uvm_info("PRED_RESET", $sformatf("Reset prediction of kind: %p will result in state change after reset deasserts. Wait for cptra_rst_b==1...", kind), UVM_MEDIUM) + while (last_predicted_kind != soft_reset_flag) begin + uvm_object obj_predicted; + reset_predicted.wait_ptrigger_data(obj_predicted); + reset_predicted.wait_off(); + $cast(last_predicted_kind,obj_predicted); + `uvm_info("PRED_RESET", $sformatf("After reset_predicted was cleared, last predicted kind was: %s", last_predicted_kind.get_name()), UVM_MEDIUM) + end + p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs = '{boot_fuse: 1'b1, default: 1'b0}; + `uvm_info("PRED_RESET", $sformatf("After detecting warm reset deassertion, boot FSM state change predicted: [%p]", p_soc_ifc_rm.soc_ifc_reg_rm.boot_fn_state_sigs), UVM_MEDIUM) + // NOTE: Next state progression is triggered by write to CPTRA_FUSE_WR_DONE + + // Now, deassertion of noncore reset is delayed from state transition by 2 cycles + configuration.soc_ifc_ctrl_agent_config.wait_for_num_clocks(2); // FIXME, correct delay value? + noncore_rst_out_asserted = 1'b0; + + // Send predicted transactions + if (1) begin + local_cptra_sb_ap_txn = cptra_sb_ap_output_transaction_t::type_id::create("local_cptra_sb_ap_txn"); + populate_expected_cptra_status_txn(local_cptra_sb_ap_txn); + cptra_sb_ap.write(local_cptra_sb_ap_txn); + `uvm_info("PRED_RESET", "Transaction submitted through cptra_sb_ap", UVM_MEDIUM) + end + end + join_none + end // Predict value changes due to reset - soc_ifc_rst_in_asserted = 1'b1; - noncore_rst_out_asserted = 1'b1; - uc_rst_out_asserted = 1'b1; - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.predict(1'b0); + fw_update_wait_count = 0; + + if (kind inside {"HARD", "SOFT"}) begin: RESET_VAL_CHANGES_HARD_SOFT + soc_ifc_rst_in_asserted = 1'b1; + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_FLOW_STATUS.ready_for_fuses.predict(1'b0); + + cptra_error_fatal = 1'b0; + cptra_error_non_fatal = 1'b0; + end: RESET_VAL_CHANGES_HARD_SOFT + + // Signals that are tied to reg values are not reset by warm reset until it + // propagates to the internal resets // FIXME: Do a reg-model reset and then extract these from the reg_model??? - ready_for_fw_push = 1'b0; - ready_for_runtime = 1'b0; - nmi_vector = '0; - iccm_locked = 1'b0; - mailbox_data_avail = 1'b0; - soc_ifc_error_intr_pending = 1'b0; - soc_ifc_notif_intr_pending = 1'b0; - sha_err_intr_pending = 1'b0; - sha_notif_intr_pending = 1'b0; - - cptra_error_fatal = 1'b0; - cptra_error_non_fatal = 1'b0; - - generic_output_wires = '0; - - // FIXME get rid of this variable? - mbox_valid_users = '{p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[0].PAUSER.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[1].PAUSER.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[2].PAUSER.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[3].PAUSER.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[4].PAUSER.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[0].PAUSER.get_reset(kind)/*This entry is for the non-programmable default value */}; - mbox_valid_users_locked = {p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[0].LOCK.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[1].LOCK.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[2].LOCK.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[3].LOCK.get_reset(kind), - p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[4].LOCK.get_reset(kind)}; - - trng_data_req = 1'b0; - - // Mailbox 'step' represents how the current transaction affects the mailbox - // flow, and is used for coverage. - if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_idle) - next_step = '{null_action: 1'b1, default: 1'b0}; - else - next_step = '{reset: 1'b1, default: 1'b0}; - fork - begin - // This allows coverage subscriber to observe both prev_step and next_step before the transition - uvm_wait_for_nba_region(); - prev_step = next_step; - end - join_none + if (kind inside {"HARD", "NONCORE"}) begin: RESET_VAL_CHANGES_HARD_NONCORE + ready_for_fw_push = 1'b0; + ready_for_runtime = 1'b0; + nmi_vector = '0; + iccm_locked = 1'b0; + mailbox_data_avail = 1'b0; + soc_ifc_error_intr_pending = 1'b0; + soc_ifc_notif_intr_pending = 1'b0; + sha_err_intr_pending = 1'b0; + sha_notif_intr_pending = 1'b0; + + generic_output_wires = '0; + + //WDT + nmi_intr_pending = 1'b0; //Reset nmi_intr on reset assertion + reset_wdt_count = 1'b1; + + // FIXME get rid of this variable? + mbox_valid_users = '{p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[0].PAUSER.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[1].PAUSER.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[2].PAUSER.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[3].PAUSER.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[4].PAUSER.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_VALID_PAUSER[0].PAUSER.get_reset(kind)/*This entry is for the non-programmable default value */}; + mbox_valid_users_locked = {p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[0].LOCK.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[1].LOCK.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[2].LOCK.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[3].LOCK.get_reset(kind), + p_soc_ifc_rm.soc_ifc_reg_rm.CPTRA_MBOX_PAUSER_LOCK[4].LOCK.get_reset(kind)}; + + trng_data_req = 1'b0; + + // Mailbox 'step' represents how the current transaction affects the mailbox + // flow, and is used for coverage. + if (p_soc_ifc_rm.mbox_csr_rm.mbox_fn_state_sigs.mbox_idle) + next_step = '{null_action: 1'b1, default: 1'b0}; + else + next_step = '{reset: 1'b1, default: 1'b0}; + fork + begin + // This allows coverage subscriber to observe both prev_step and next_step before the transition + uvm_wait_for_nba_region(); + prev_step = next_step; + end + join_none - if (kind == "HARD") begin + datain_count = 0; + dataout_count = 0; + + end: RESET_VAL_CHANGES_HARD_NONCORE + + if (kind == "HARD") begin: RESET_VAL_CHANGES_HARD cptra_pwrgood_asserted = 1'b0; timer_intr_pending = 1'b1; fuse_update_enabled = 1'b1; // Fuses only latch new values from APB write after a cold-reset (which clears CPTRA_FUSE_WR_DONE) - end - - datain_count = 0; - dataout_count = 0; + end: RESET_VAL_CHANGES_HARD // TODO clear the delay_jobs queue? @@ -2624,30 +3350,28 @@ function void soc_ifc_predictor::predict_reset(input string kind = "HARD"); // FIXME SOFT reset is not fully defined for our reg-model yet // FIXME move this to env? p_soc_ifc_rm.reset(kind); - // If any reg access was in progress when reset occurred, clear the busy - // flag (since the APB/AHB sequencers and any mailbox sequences were killed) - p_soc_ifc_rm.get_registers(all_regs, UVM_HIER); - foreach (all_regs[ii]) begin - if (all_regs[ii].is_busy()) begin - `uvm_info("SOC_IFC_PRED", $sformatf("After resetting the reg-model, found a busy reg: [%s]. Resetting the busy bit.", all_regs[ii].get_full_name()), UVM_FULL) - // TODO: This is not in the official API, and the 'reset' function doesn't - // automatically clear busy. Not sure how to do this properly - all_regs[ii].Xset_busyX(0); + + if (kind inside {"HARD","NONCORE"}) begin: RESET_REG_BUSY_NONCORE_HARD + // If any reg access was in progress when reset occurred, clear the busy + // flag (since the APB/AHB sequencers and any mailbox sequences were killed). + // We don't run this for warm/soft resets because cptra_rst_b doesn't immediately + // reset the AHB interface, so pending transactions might still complete. + p_soc_ifc_rm.get_registers(all_regs, UVM_HIER); + foreach (all_regs[ii]) begin + if (all_regs[ii].is_busy()) begin + `uvm_info("PRED_RESET", $sformatf("After resetting the reg-model, found a busy reg: [%s]. Resetting the busy bit.", all_regs[ii].get_full_name()), UVM_FULL) + // TODO: This is not in the official API, and the 'reset' function doesn't + // automatically clear busy. Not sure how to do this properly + all_regs[ii].Xset_busyX(0); + end end - end + end: RESET_REG_BUSY_NONCORE_HARD + // TODO skip key reset for SOFT reset type? soc_ifc_status_txn_key = 0; cptra_status_txn_key = 0; endfunction -function bit soc_ifc_predictor::soc_ifc_status_txn_expected_after_cold_reset(); - return soc_ifc_status_txn_expected_after_warm_reset(); /* warm reset is expected in conjunction with cold */ -endfunction - -function bit soc_ifc_predictor::cptra_status_txn_expected_after_cold_reset(); - return cptra_status_txn_expected_after_warm_reset(); /* warm reset is expected in conjunction with cold */ -endfunction - function bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] soc_ifc_predictor::get_expected_obf_field_entropy(); byte ii; bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] fe; @@ -2682,6 +3406,7 @@ endfunction function void soc_ifc_predictor::populate_expected_cptra_status_txn(ref cptra_sb_ap_output_transaction_t txn); txn.noncore_rst_asserted = this.noncore_rst_out_asserted; txn.uc_rst_asserted = this.uc_rst_out_asserted; + txn.fw_update_rst_window = this.fw_update_rst_window; txn.soc_ifc_err_intr_pending = this.soc_ifc_error_intr_pending; txn.soc_ifc_notif_intr_pending = this.soc_ifc_notif_intr_pending; txn.sha_err_intr_pending = this.sha_err_intr_pending; @@ -2691,7 +3416,7 @@ function void soc_ifc_predictor::populate_expected_cptra_status_txn(ref cptra_sb txn.obf_field_entropy = this.get_expected_obf_field_entropy(); txn.obf_uds_seed = this.get_expected_obf_uds_seed(); txn.nmi_vector = this.nmi_vector; - txn.nmi_intr_pending = 1'b0/*FIXME*/; + txn.nmi_intr_pending = this.nmi_intr_pending; txn.iccm_locked = this.iccm_locked; txn.set_key(cptra_status_txn_key++); endfunction diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_scoreboard.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_scoreboard.svh index ba58abb99..ce8e4b7b2 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_scoreboard.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/src/soc_ifc_scoreboard.svh @@ -208,7 +208,7 @@ class soc_ifc_scoreboard #( soc_ifc_status_monitor_s soc_ifc_status_monitor_struct_rpt = '{default:0}; `uvm_info("SCBD_SOC_IFC_STS", $sformatf("Transaction Received through expected_analysis_export with key: [%0d]", t.get_key()), UVM_MEDIUM) - `uvm_info("SCBD_SOC_IFC_STS", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_SOC_IFC_STS", {" Data: ",t.convert2string()}, UVM_HIGH) soc_ifc_expected_hash[t.get_key()] = t; soc_ifc_status_monitor_struct_prev = soc_ifc_status_monitor_struct; @@ -240,7 +240,7 @@ class soc_ifc_scoreboard #( virtual function void write_expected_cptra_analysis_export(cptra_status_transaction t); // pragma uvmf custom expected_cptra_analysis_export_scoreboard begin `uvm_info("SCBD_CPTRA_STS", $sformatf("Transaction Received through expected_cptra_analysis_export with key: [%0d]", t.get_key()), UVM_MEDIUM) - `uvm_info("SCBD_CPTRA_STS", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_CPTRA_STS", {" Data: ",t.convert2string()}, UVM_HIGH) cptra_expected_hash[t.get_key()] = t; if (reset_handled.is_on()) begin @@ -263,7 +263,7 @@ class soc_ifc_scoreboard #( bit txn_eq; `uvm_info("SCBD_SOC_IFC_STS", $sformatf("Transaction Received through actual_analysis_export with key: [%0d]", t.get_key()), UVM_MEDIUM) - `uvm_info("SCBD_SOC_IFC_STS", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_SOC_IFC_STS", {" Data: ",t.convert2string()}, UVM_HIGH) // Check for expected analysis port to receive first transaction after a reset before proceeding with the actual check // This indicates the environment level reset is finished and the predictor had time to forward an expected @@ -379,7 +379,7 @@ class soc_ifc_scoreboard #( bit txn_eq; `uvm_info("SCBD_CPTRA_STS", $sformatf("Transaction Received through actual_cptra_analysis_export with key: [%0d]", t.get_key()), UVM_MEDIUM) - `uvm_info("SCBD_CPTRA_STS", {" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_CPTRA_STS", {" Data: ",t.convert2string()}, UVM_HIGH) // Check for expected analysis port to receive first transaction after a reset before proceeding with the actual check if (reset_handled.is_on()) @@ -419,7 +419,7 @@ class soc_ifc_scoreboard #( `uvm_fatal("SCBD_AHB","Cast from mvc_sequence_item_base to ahb_master_burst_transfer #(ahb_lite_slave_0_params::AHB_NUM_MASTERS, ahb_lite_slave_0_params::AHB_NUM_MASTER_BITS, ahb_lite_slave_0_params::AHB_NUM_SLAVES, ahb_lite_slave_0_params::AHB_ADDRESS_WIDTH, ahb_lite_slave_0_params::AHB_WDATA_WIDTH, ahb_lite_slave_0_params::AHB_RDATA_WIDTH) in write_expected_ahb_analysis_export failed!") end `uvm_info("SCBD_AHB", "Transaction Received through expected_ahb_analysis_export", UVM_MEDIUM) - `uvm_info("SCBD_AHB",{" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_AHB",{" Data: ",t.convert2string()}, UVM_HIGH) ahb_expected_q.push_back(t); @@ -440,7 +440,7 @@ class soc_ifc_scoreboard #( `uvm_fatal("SCBD_APB","Cast from mvc_sequence_item_base to apb3_host_apb3_transaction #(apb5_master_0_params::APB3_SLAVE_COUNT, apb5_master_0_params::APB3_PADDR_BIT_WIDTH, apb5_master_0_params::APB3_PWDATA_BIT_WIDTH, apb5_master_0_params::APB3_PRDATA_BIT_WIDTH) in write_expected_apb_analysis_export failed!") end `uvm_info("SCBD_APB", "Transaction Received through expected_apb_analysis_export", UVM_MEDIUM) - `uvm_info("SCBD_APB",{" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_APB",{" Data: ",t.convert2string()}, UVM_HIGH) apb_expected_q.push_back(t); @@ -463,7 +463,7 @@ class soc_ifc_scoreboard #( `uvm_fatal("SCBD_AHB","Cast from mvc_sequence_item_base to ahb_master_burst_transfer #(ahb_lite_slave_0_params::AHB_NUM_MASTERS, ahb_lite_slave_0_params::AHB_NUM_MASTER_BITS, ahb_lite_slave_0_params::AHB_NUM_SLAVES, ahb_lite_slave_0_params::AHB_ADDRESS_WIDTH, ahb_lite_slave_0_params::AHB_WDATA_WIDTH, ahb_lite_slave_0_params::AHB_RDATA_WIDTH) in write_actual_ahb_analysis_export failed!") end `uvm_info("SCBD_AHB", "Transaction Received through actual_ahb_analysis_export", UVM_MEDIUM) - `uvm_info("SCBD_AHB",{" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_AHB",{" Data: ",t.convert2string()}, UVM_HIGH) if (ahb_expected_q.size() > 0) begin t_exp = ahb_expected_q.pop_front(); @@ -500,7 +500,7 @@ class soc_ifc_scoreboard #( `uvm_fatal("SCBD_APB","Cast from mvc_sequence_item_base to apb3_host_apb3_transaction #(apb5_master_0_params::APB3_SLAVE_COUNT, apb5_master_0_params::APB3_PADDR_BIT_WIDTH, apb5_master_0_params::APB3_PWDATA_BIT_WIDTH, apb5_master_0_params::APB3_PRDATA_BIT_WIDTH) in write_actual_apb_analysis_export failed!") end `uvm_info("SCBD_APB", "Transaction Received through actual_apb_analysis_export", UVM_MEDIUM) - `uvm_info("SCBD_APB",{" Data: ",t.convert2string()}, UVM_FULL) + `uvm_info("SCBD_APB",{" Data: ",t.convert2string()}, UVM_HIGH) if (apb_expected_q.size() > 0) begin t_exp = apb_expected_q.pop_front(); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_environment.yaml b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_environment.yaml index a8ba2df23..111d254aa 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_environment.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_environment.yaml @@ -14,6 +14,9 @@ uvmf: - initiator_responder: RESPONDER name: cptra_status_agent type: cptra_status + - initiator_responder: RESPONDER + name: mbox_sram_agent + type: mbox_sram analysis_components: - name: soc_ifc_pred parameters: [] @@ -67,6 +70,9 @@ uvmf: - driver: cptra_ctrl_agent.monitored_ap receiver: soc_ifc_pred.cptra_ctrl_agent_ae validate: 'True' + - driver: mbox_sram_agent.monitored_ap + receiver: soc_ifc_pred.mbox_sram_agent_ae + validate: 'True' - driver: soc_ifc_pred.soc_ifc_sb_ap receiver: soc_ifc_sb.expected_analysis_export validate: 'True' diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_util_comp_soc_ifc_predictor.yaml b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_util_comp_soc_ifc_predictor.yaml index ed86e0948..9b07c8789 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_util_comp_soc_ifc_predictor.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/environment_packages/soc_ifc_env_pkg/yaml/soc_ifc_util_comp_soc_ifc_predictor.yaml @@ -6,6 +6,8 @@ uvmf: type: soc_ifc_ctrl_transaction - name: cptra_ctrl_agent_ae type: cptra_ctrl_transaction + - name: mbox_sram_agent_ae + type: mbox_sram_transaction - name: ahb_slave_0_ae type: mvc_sequence_item_base - name: apb5_slave_0_ae diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv index e6d7b955f..fb0d7ec78 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_driver_bfm.sv @@ -110,6 +110,8 @@ end reg cptra_noncore_rst_b_o = 'b0; tri cptra_uc_rst_b_i; reg cptra_uc_rst_b_o = 'b0; + tri fw_update_rst_window_i; + reg fw_update_rst_window_o = 'bz; tri [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg_i; reg [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg_o = 'bz; tri [`CLP_OBF_FE_DWORDS-1:0][31:0] obf_field_entropy_i; @@ -149,6 +151,8 @@ end assign cptra_noncore_rst_b_i = bus.cptra_noncore_rst_b; assign bus.cptra_uc_rst_b = (initiator_responder == INITIATOR) ? cptra_uc_rst_b_o : 'bz; assign cptra_uc_rst_b_i = bus.cptra_uc_rst_b; + assign bus.fw_update_rst_window = (initiator_responder == INITIATOR) ? fw_update_rst_window_o : 'bz; + assign fw_update_rst_window_i = bus.fw_update_rst_window; assign bus.cptra_obf_key_reg = (initiator_responder == INITIATOR) ? cptra_obf_key_reg_o : 'bz; assign cptra_obf_key_reg_i = bus.cptra_obf_key_reg; assign bus.obf_field_entropy = (initiator_responder == INITIATOR) ? obf_field_entropy_o : 'bz; @@ -204,6 +208,7 @@ end // INITIATOR mode output signals cptra_noncore_rst_b_o <= 'b0; cptra_uc_rst_b_o <= 'b0; + fw_update_rst_window_o <= 'bz; cptra_obf_key_reg_o <= 'bz; obf_field_entropy_o <= 'bz; obf_uds_seed_o <= 'bz; @@ -230,6 +235,7 @@ end else return |(cptra_noncore_rst_b_i ^ cptra_noncore_rst_b_o ) || |(cptra_uc_rst_b_i ^ cptra_uc_rst_b_o ) || + |(fw_update_rst_window_i ^ fw_update_rst_window_o ) || |(cptra_obf_key_reg_i ^ cptra_obf_key_reg_o ) || |(obf_field_entropy_i ^ obf_field_entropy_o ) || |(obf_uds_seed_i ^ obf_uds_seed_o ) || @@ -282,6 +288,7 @@ end // bit timer_intr_pending ; // bit noncore_rst_asserted ; // bit uc_rst_asserted ; + // bit fw_update_rst_window ; // bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; // bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; // bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; @@ -296,6 +303,7 @@ end // bit timer_intr_pending ; // bit noncore_rst_asserted ; // bit uc_rst_asserted ; + // bit fw_update_rst_window ; // bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; // bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; // bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; @@ -318,6 +326,7 @@ end // Initiator output signals // cptra_noncore_rst_b_o <= cptra_status_initiator_struct.xyz; // // cptra_uc_rst_b_o <= cptra_status_initiator_struct.xyz; // + // fw_update_rst_window_o <= cptra_status_initiator_struct.xyz; // // cptra_obf_key_reg_o <= cptra_status_initiator_struct.xyz; // [`CLP_OBF_KEY_DWORDS-1:0][31:0] // obf_field_entropy_o <= cptra_status_initiator_struct.xyz; // [`CLP_OBF_FE_DWORDS-1:0][31:0] // obf_uds_seed_o <= cptra_status_initiator_struct.xyz; // [`CLP_OBF_UDS_DWORDS-1:0][31:0] @@ -367,6 +376,7 @@ bit first_transfer=1; // bit timer_intr_pending ; // bit noncore_rst_asserted ; // bit uc_rst_asserted ; + // bit fw_update_rst_window ; // bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; // bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; // bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; @@ -381,6 +391,7 @@ bit first_transfer=1; // bit timer_intr_pending ; // bit noncore_rst_asserted ; // bit uc_rst_asserted ; + // bit fw_update_rst_window ; // bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; // bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; // bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; @@ -396,6 +407,7 @@ bit first_transfer=1; // Responder input signals // cptra_status_responder_struct.xyz = cptra_noncore_rst_b_i; // // cptra_status_responder_struct.xyz = cptra_uc_rst_b_i; // + // cptra_status_responder_struct.xyz = fw_update_rst_window_i; // // cptra_status_responder_struct.xyz = cptra_obf_key_reg_i; // [`CLP_OBF_KEY_DWORDS-1:0][31:0] // cptra_status_responder_struct.xyz = obf_field_entropy_i; // [`CLP_OBF_FE_DWORDS-1:0][31:0] // cptra_status_responder_struct.xyz = obf_uds_seed_i; // [`CLP_OBF_UDS_DWORDS-1:0][31:0] @@ -424,7 +436,8 @@ bit first_transfer=1; // end // Wait for next transfer then gather info from intiator about the transfer. // Place the data into the cptra_status_initiator_struct. - do begin + @(posedge clk_i); + while (!any_signal_changed()) begin soc_ifc_error_intr_o <= soc_ifc_error_intr_i; soc_ifc_notif_intr_o <= soc_ifc_notif_intr_i; sha_error_intr_o <= sha_error_intr_i ; @@ -433,9 +446,9 @@ bit first_transfer=1; nmi_intr_o <= nmi_intr_i ; @(posedge clk_i); end - while (!any_signal_changed()); cptra_noncore_rst_b_o <= cptra_noncore_rst_b_i ; cptra_uc_rst_b_o <= cptra_uc_rst_b_i ; + fw_update_rst_window_o <= fw_update_rst_window_i; cptra_obf_key_reg_o <= cptra_obf_key_reg_i ; obf_field_entropy_o <= obf_field_entropy_i ; obf_uds_seed_o <= obf_uds_seed_i ; @@ -458,6 +471,7 @@ bit first_transfer=1; cptra_status_initiator_struct.timer_intr_pending = timer_intr_i; cptra_status_initiator_struct.noncore_rst_asserted = !cptra_noncore_rst_b_i; cptra_status_initiator_struct.uc_rst_asserted = !cptra_uc_rst_b_i; + cptra_status_initiator_struct.fw_update_rst_window = fw_update_rst_window_i; cptra_status_initiator_struct.cptra_obf_key_reg = cptra_obf_key_reg_i; cptra_status_initiator_struct.obf_field_entropy = obf_field_entropy_i; cptra_status_initiator_struct.obf_uds_seed = obf_uds_seed_i; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv index c07de9ed1..15468ad29 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_if.sv @@ -35,6 +35,7 @@ // // .dut_signal_port(cptra_status_bus.cptra_noncore_rst_b), // Agent output // .dut_signal_port(cptra_status_bus.cptra_uc_rst_b), // Agent output +// .dut_signal_port(cptra_status_bus.fw_update_rst_window), // Agent output // .dut_signal_port(cptra_status_bus.cptra_obf_key_reg), // Agent output // .dut_signal_port(cptra_status_bus.obf_field_entropy), // Agent output // .dut_signal_port(cptra_status_bus.obf_uds_seed), // Agent output @@ -57,6 +58,7 @@ interface cptra_status_if input tri dummy, inout tri cptra_noncore_rst_b, inout tri cptra_uc_rst_b, + inout tri fw_update_rst_window, inout tri [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg, inout tri [`CLP_OBF_FE_DWORDS-1:0][31:0] obf_field_entropy, inout tri [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed, @@ -76,6 +78,7 @@ modport monitor_port input dummy, input cptra_noncore_rst_b, input cptra_uc_rst_b, + input fw_update_rst_window, input cptra_obf_key_reg, input obf_field_entropy, input obf_uds_seed, @@ -95,6 +98,7 @@ modport initiator_port input dummy, output cptra_noncore_rst_b, output cptra_uc_rst_b, + output fw_update_rst_window, output cptra_obf_key_reg, output obf_field_entropy, output obf_uds_seed, @@ -114,6 +118,7 @@ modport responder_port input dummy, input cptra_noncore_rst_b, input cptra_uc_rst_b, + input fw_update_rst_window, input cptra_obf_key_reg, input obf_field_entropy, input obf_uds_seed, diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_macros.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_macros.svh index 023c88048..c17f0bbe4 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_macros.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_macros.svh @@ -70,6 +70,7 @@ typedef struct packed { \ bit timer_intr_pending ; \ bit noncore_rst_asserted ; \ bit uc_rst_asserted ; \ + bit fw_update_rst_window ; \ bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; \ bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; \ bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; \ @@ -89,6 +90,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ @@ -109,6 +111,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ @@ -131,6 +134,7 @@ typedef struct packed { \ bit timer_intr_pending ; \ bit noncore_rst_asserted ; \ bit uc_rst_asserted ; \ + bit fw_update_rst_window ; \ bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; \ bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; \ bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; \ @@ -150,6 +154,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ @@ -170,6 +175,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ @@ -192,6 +198,7 @@ typedef struct packed { \ bit timer_intr_pending ; \ bit noncore_rst_asserted ; \ bit uc_rst_asserted ; \ + bit fw_update_rst_window ; \ bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; \ bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; \ bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; \ @@ -211,6 +218,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ @@ -231,6 +239,7 @@ typedef struct packed { \ this.timer_intr_pending , \ this.noncore_rst_asserted , \ this.uc_rst_asserted , \ + this.fw_update_rst_window , \ this.cptra_obf_key_reg , \ this.obf_field_entropy , \ this.obf_uds_seed , \ diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv index 972aff800..9932169ff 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_monitor_bfm.sv @@ -85,6 +85,7 @@ end tri dummy_i; tri cptra_noncore_rst_b_i; tri cptra_uc_rst_b_i; + tri fw_update_rst_window_i; tri [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg_i; tri [`CLP_OBF_FE_DWORDS-1:0][31:0] obf_field_entropy_i; tri [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed_i; @@ -100,6 +101,7 @@ end assign dummy_i = bus.dummy; assign cptra_noncore_rst_b_i = bus.cptra_noncore_rst_b; assign cptra_uc_rst_b_i = bus.cptra_uc_rst_b; + assign fw_update_rst_window_i = bus.fw_update_rst_window; assign cptra_obf_key_reg_i = bus.cptra_obf_key_reg; assign obf_field_entropy_i = bus.obf_field_entropy; assign obf_uds_seed_i = bus.obf_uds_seed; @@ -119,6 +121,7 @@ end // pragma uvmf custom interface_item_additional begin reg cptra_noncore_rst_b_o = 'b0; reg cptra_uc_rst_b_o = 'b0; + reg fw_update_rst_window_o = 'b0; reg [`CLP_OBF_KEY_DWORDS-1:0][31:0] cptra_obf_key_reg_o = 'b0; reg [`CLP_OBF_FE_DWORDS-1:0][31:0] obf_field_entropy_o = 'b0; reg [`CLP_OBF_UDS_DWORDS-1:0][31:0] obf_uds_seed_o = 'b0; @@ -139,6 +142,7 @@ end else return |(cptra_noncore_rst_b_i ^ cptra_noncore_rst_b_o ) || |(cptra_uc_rst_b_i ^ cptra_uc_rst_b_o ) || + |(fw_update_rst_window_i ^ fw_update_rst_window_o ) || |(cptra_obf_key_reg_i ^ cptra_obf_key_reg_o ) || |(obf_field_entropy_i ^ obf_field_entropy_o ) || |(obf_uds_seed_i ^ obf_uds_seed_o ) || @@ -225,6 +229,7 @@ end // // cptra_status_monitor_struct.timer_intr_pending // // cptra_status_monitor_struct.noncore_rst_asserted // // cptra_status_monitor_struct.uc_rst_asserted + // // cptra_status_monitor_struct.fw_update_rst_window // // cptra_status_monitor_struct.cptra_obf_key_reg // // cptra_status_monitor_struct.obf_field_entropy // // cptra_status_monitor_struct.obf_uds_seed @@ -240,6 +245,7 @@ end // All available input signals listed. // cptra_status_monitor_struct.xyz = cptra_noncore_rst_b_i; // // cptra_status_monitor_struct.xyz = cptra_uc_rst_b_i; // + // cptra_status_monitor_struct.xyz = fw_update_rst_window_i; // // cptra_status_monitor_struct.xyz = cptra_obf_key_reg_i; // [`CLP_OBF_KEY_DWORDS-1:0][31:0] // cptra_status_monitor_struct.xyz = obf_field_entropy_i; // [`CLP_OBF_FE_DWORDS-1:0][31:0] // cptra_status_monitor_struct.xyz = obf_uds_seed_i; // [`CLP_OBF_UDS_DWORDS-1:0][31:0] @@ -275,6 +281,7 @@ end end cptra_noncore_rst_b_o <= cptra_noncore_rst_b_i ; cptra_uc_rst_b_o <= cptra_uc_rst_b_i ; + fw_update_rst_window_o <= fw_update_rst_window_i; cptra_obf_key_reg_o <= cptra_obf_key_reg_i ; obf_field_entropy_o <= obf_field_entropy_i ; obf_uds_seed_o <= obf_uds_seed_i ; @@ -291,6 +298,7 @@ end // Variables within the cptra_status_initiator_struct: cptra_status_monitor_struct.noncore_rst_asserted = !cptra_noncore_rst_b_i; cptra_status_monitor_struct.uc_rst_asserted = !cptra_uc_rst_b_i; + cptra_status_monitor_struct.fw_update_rst_window = fw_update_rst_window_i; cptra_status_monitor_struct.soc_ifc_err_intr_pending = soc_ifc_error_intr_i; cptra_status_monitor_struct.soc_ifc_notif_intr_pending = soc_ifc_notif_intr_i; cptra_status_monitor_struct.sha_err_intr_pending = sha_error_intr_i; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction.svh index d089b362b..5e8e7edb3 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction.svh @@ -39,6 +39,7 @@ class cptra_status_transaction extends uvmf_transaction_base; bit timer_intr_pending ; bit noncore_rst_asserted ; bit uc_rst_asserted ; + bit fw_update_rst_window ; bit [`CLP_OBF_KEY_DWORDS-1:0] [31:0] cptra_obf_key_reg ; bit [`CLP_OBF_FE_DWORDS-1:0] [31:0] obf_field_entropy ; bit [`CLP_OBF_UDS_DWORDS-1:0] [31:0] obf_uds_seed ; @@ -127,7 +128,7 @@ class cptra_status_transaction extends uvmf_transaction_base; virtual function string convert2string(); // pragma uvmf custom convert2string begin // UVMF_CHANGE_ME : Customize format if desired. - return $sformatf("soc_ifc_err_intr_pending:0x%x soc_ifc_notif_intr_pending:0x%x sha_err_intr_pending:0x%x sha_notif_intr_pending:0x%x timer_intr_pending:0x%x noncore_rst_asserted:0x%x uc_rst_asserted:0x%x cptra_obf_key_reg:0x%x obf_field_entropy:0x%x obf_uds_seed:0x%x nmi_vector:0x%x nmi_intr_pending:0x%x iccm_locked:0x%x %s",soc_ifc_err_intr_pending,soc_ifc_notif_intr_pending,sha_err_intr_pending,sha_notif_intr_pending,timer_intr_pending,noncore_rst_asserted,uc_rst_asserted,cptra_obf_key_reg,obf_field_entropy,obf_uds_seed,nmi_vector,nmi_intr_pending,iccm_locked,super.convert2string()); + return $sformatf("soc_ifc_err_intr_pending:0x%x soc_ifc_notif_intr_pending:0x%x sha_err_intr_pending:0x%x sha_notif_intr_pending:0x%x timer_intr_pending:0x%x noncore_rst_asserted:0x%x uc_rst_asserted:0x%x fw_update_rst_window:0x%x cptra_obf_key_reg:0x%x obf_field_entropy:0x%x obf_uds_seed:0x%x nmi_vector:0x%x nmi_intr_pending:0x%x iccm_locked:0x%x %s",soc_ifc_err_intr_pending,soc_ifc_notif_intr_pending,sha_err_intr_pending,sha_notif_intr_pending,timer_intr_pending,noncore_rst_asserted,uc_rst_asserted,fw_update_rst_window,cptra_obf_key_reg,obf_field_entropy,obf_uds_seed,nmi_vector,nmi_intr_pending,iccm_locked,super.convert2string()); // pragma uvmf custom convert2string end endfunction @@ -162,6 +163,7 @@ class cptra_status_transaction extends uvmf_transaction_base; &&(this.timer_intr_pending == RHS.timer_intr_pending) &&(this.noncore_rst_asserted == RHS.noncore_rst_asserted) &&(this.uc_rst_asserted == RHS.uc_rst_asserted) + &&(this.fw_update_rst_window == RHS.fw_update_rst_window) &&(this.cptra_obf_key_reg == RHS.cptra_obf_key_reg) &&(this.obf_field_entropy == RHS.obf_field_entropy) &&(this.obf_uds_seed == RHS.obf_uds_seed) @@ -189,6 +191,7 @@ class cptra_status_transaction extends uvmf_transaction_base; this.timer_intr_pending = RHS.timer_intr_pending; this.noncore_rst_asserted = RHS.noncore_rst_asserted; this.uc_rst_asserted = RHS.uc_rst_asserted; + this.fw_update_rst_window = RHS.fw_update_rst_window; this.cptra_obf_key_reg = RHS.cptra_obf_key_reg; this.obf_field_entropy = RHS.obf_field_entropy; this.obf_uds_seed = RHS.obf_uds_seed; @@ -225,6 +228,7 @@ class cptra_status_transaction extends uvmf_transaction_base; $add_attribute(transaction_view_h,timer_intr_pending,"timer_intr_pending"); $add_attribute(transaction_view_h,noncore_rst_asserted,"noncore_rst_asserted"); $add_attribute(transaction_view_h,uc_rst_asserted,"uc_rst_asserted"); + $add_attribute(transaction_view_h,fw_update_rst_window,"fw_update_rst_window"); $add_attribute(transaction_view_h,cptra_obf_key_reg,"cptra_obf_key_reg"); $add_attribute(transaction_view_h,obf_field_entropy,"obf_field_entropy"); $add_attribute(transaction_view_h,obf_uds_seed,"obf_uds_seed"); diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction_coverage.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction_coverage.svh index efebb6553..e2b53b1f5 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction_coverage.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/src/cptra_status_transaction_coverage.svh @@ -86,6 +86,11 @@ class cptra_status_transaction_coverage extends uvm_subscriber #(.T(cptra_statu bins rise = (0 => 1); bins fall = (1 => 0); } + fw_update_rst_window: coverpoint coverage_trans.fw_update_rst_window; + fw_update_rst_window_transition: coverpoint coverage_trans.fw_update_rst_window { + bins rise = (0 => 1); + bins fall = (1 => 0); + } cptra_obf_key_reg: coverpoint coverage_trans.cptra_obf_key_reg { bins zero_key = {0}; bins rand_key = {[1:{`CLP_OBF_KEY_DWORDS{32'hFFFF_FFFF}}-1]}; diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/yaml/cptra_status_interface.yaml b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/yaml/cptra_status_interface.yaml index 170711166..9622bc4dd 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/yaml/cptra_status_interface.yaml +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/cptra_status_pkg/yaml/cptra_status_interface.yaml @@ -20,6 +20,10 @@ uvmf: name: cptra_uc_rst_b reset_value: '''bz' width: '1' + - dir: output + name: fw_update_rst_window + reset_value: '''bz' + width: '1' - dir: output name: cptra_obf_key_reg reset_value: '''bz' @@ -110,6 +114,12 @@ uvmf: name: uc_rst_asserted type: bit unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'False' + name: fw_update_rst_window + type: bit + unpacked_dimension: '' - comment: '' iscompare: 'True' isrand: 'False' diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.project b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.project new file mode 100644 index 000000000..25262dcd1 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.project @@ -0,0 +1,30 @@ + + + mbox_sram_pkg + + + + + + org.python.pydev.PyDevBuilder + + + + + net.sf.sveditor.core.SVProjectBuilder + + + + + + net.sf.sveditor.core.SVNature + org.python.pydev.pythonNature + + + + UVMF_VIP_LIBRARY_HOME + $%7BPARENT-2-PROJECT_LOC%7D + + + + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.svproject b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.svproject new file mode 100644 index 000000000..82ebbab03 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/.svproject @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/Makefile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/Makefile new file mode 100644 index 000000000..60c82949b --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/Makefile @@ -0,0 +1,66 @@ +# mbox_sram interface packages source +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + +mbox_sram_PKG = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f + +mbox_sram_PKG_HDL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f + +mbox_sram_PKG_XRTL = \ + +incdir+$(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_xrtl.f + +COMP_mbox_sram_PKG_TGT_0 = q_comp_mbox_sram_pkg +COMP_mbox_sram_PKG_TGT_1 = v_comp_mbox_sram_pkg +COMP_mbox_sram_PKG_TGT = $(COMP_mbox_sram_PKG_TGT_$(USE_VELOCE)) + +comp_mbox_sram_pkg: $(COMP_mbox_sram_PKG_TGT) + +q_comp_mbox_sram_pkg: + $(HDL_COMP_CMD) $(mbox_sram_PKG_HDL) + $(HVL_COMP_CMD) $(mbox_sram_PKG) + $(HDL_COMP_CMD) $(mbox_sram_PKG_XRTL) + +v_comp_mbox_sram_pkg: + $(HVL_COMP_CMD) $(mbox_sram_PKG_HDL) + $(HVL_COMP_CMD) $(mbox_sram_PKG) + $(VELANALYZE_CMD) $(mbox_sram_PKG_HDL) + $(VELANALYZE_HVL_CMD) $(mbox_sram_PKG) + $(HDL_COMP_CMD) $(mbox_sram_PKG_XRTL) + +ifeq ($(MTI_VCO_MODE),64) + GCC_COMP_ARCH = -m64 +else + GCC_COMP_ARCH = -m32 +endif + +export mbox_sram_IF_DPI_SRC ?= $(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/dpi + +C_FILE_COMPILE_LIST_mbox_sram_pkg = \ + +O_FILE_COMPILE_LIST_mbox_sram_pkg = $(notdir $(C_FILE_COMPILE_LIST_mbox_sram_pkg:.c=.o)) + +GCC_COMP_ARGS_mbox_sram_pkg += -I$(mbox_sram_IF_DPI_SRC) \ + -fPIC + +GCC_COMP_ARGS_mbox_sram_pkg += $(mbox_sram_IF_GCC_COMP_ARGUMENTS) + +GCC_LINK_ARGS_mbox_sram_pkg += \ + \ + -o .so + +comp_mbox_sram_pkg_c_files: + @echo "--------------------------------" + @echo "Compiling Interface C source" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_COMP_ARGS_mbox_sram_pkg) $(C_FILE_COMPILE_LIST_mbox_sram_pkg) + @echo "--------------------------------" + @echo "Linking Interface C objects into a shared object" + @echo "--------------------------------" + gcc $(GCC_COMP_ARCH) $(GCC_LINK_ARGS_mbox_sram_pkg) $(O_FILE_COMPILE_LIST_mbox_sram_pkg) + @echo "--------------------------------" + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/compile.do b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/compile.do new file mode 100644 index 000000000..e20bed409 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/compile.do @@ -0,0 +1,14 @@ +# Tcl do file for compile of mbox_sram interface + +# pragma uvmf custom additional begin +# pragma uvmf custom additional end + + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f + +vlog -sv -timescale 1ps/1ps -suppress 2223,2286 +incdir+$env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg \ + -F $env(UVMF_VIP_LIBRARY_HOME)/interface_packages/mbox_sram_pkg/mbox_sram_filelist_xrtl.f \ No newline at end of file diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram.compile new file mode 100644 index 000000000..b0b806055 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram.compile @@ -0,0 +1,3 @@ +needs: + - mbox_sram_hvl.compile + - mbox_sram_hdl.compile diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_bfm.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_bfm.vinfo new file mode 100644 index 000000000..a738c1152 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_bfm.vinfo @@ -0,0 +1,6 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +@use mbox_sram_pkg_hdl.vinfo ++incdir+@vinfodir +src/mbox_sram_if.sv +src/mbox_sram_driver_bfm.sv +src/mbox_sram_monitor_bfm.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_common.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_common.compile new file mode 100644 index 000000000..f701a7be2 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_common.compile @@ -0,0 +1,7 @@ +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.compile +incdir: + - . + - ${uvm_path}/src +src: + - mbox_sram_pkg_hdl.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f new file mode 100644 index 000000000..91803d05e --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f new file mode 100644 index 000000000..f4fb8adc1 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f @@ -0,0 +1 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv \ No newline at end of file diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_xrtl.f b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_xrtl.f new file mode 100644 index 000000000..85b63fa2f --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_filelist_xrtl.f @@ -0,0 +1,3 @@ +$UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv +$UVMF_VIP_LIBRARY_HOME/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hdl.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hdl.compile new file mode 100644 index 000000000..032a5e03c --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hdl.compile @@ -0,0 +1,9 @@ +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.compile + - ./mbox_sram_common.compile +incdir: + - . +src: + - src/mbox_sram_if.sv + - src/mbox_sram_monitor_bfm.sv + - src/mbox_sram_driver_bfm.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hvl.compile b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hvl.compile new file mode 100644 index 000000000..da9f7fe81 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_hvl.compile @@ -0,0 +1,7 @@ +needs: + - $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.compile + - ./mbox_sram_common.compile +incdir: + - . +src: + - mbox_sram_pkg.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv new file mode 100644 index 000000000..3d9b7ecf4 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.sv @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that will run on the host simulator. +// +// CONTAINS: +// - +// - +// - + +// - +// - +// - + +// - +// - +// - + +// - +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package mbox_sram_pkg; + + import uvm_pkg::*; + import uvmf_base_pkg_hdl::*; + import uvmf_base_pkg::*; + import mbox_sram_pkg_hdl::*; + + `include "uvm_macros.svh" + + // pragma uvmf custom package_imports_additional begin + import soc_ifc_pkg::*; + // pragma uvmf custom package_imports_additional end + `include "src/mbox_sram_macros.svh" + + export mbox_sram_pkg_hdl::*; + + + + // Parameters defined as HVL parameters + + `include "src/mbox_sram_typedefs.svh" + `include "src/mbox_sram_transaction.svh" + + `include "src/mbox_sram_configuration.svh" + `include "src/mbox_sram_driver.svh" + `include "src/mbox_sram_monitor.svh" + + `include "src/mbox_sram_transaction_coverage.svh" + `include "src/mbox_sram_sequence_base.svh" + `include "src/mbox_sram_random_sequence.svh" + + `include "src/mbox_sram_responder_sequence.svh" + `include "src/mbox_sram2reg_adapter.svh" + + `include "src/mbox_sram_agent.svh" + + // pragma uvmf custom package_item_additional begin + // UVMF_CHANGE_ME : When adding new interface sequences to the src directory + // be sure to add the sequence file here so that it will be + // compiled as part of the interface package. Be sure to place + // the new sequence after any base sequences of the new sequence. + typedef mbox_sram_responder_sequence mbox_sram_agent_responder_seq_t; + // pragma uvmf custom package_item_additional end + +endpackage + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo new file mode 100644 index 000000000..2d5289a09 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg.vinfo @@ -0,0 +1,4 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg.vinfo +@use mbox_sram_pkg_hdl.vinfo ++incdir+@vinfodir +mbox_sram_pkg.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv new file mode 100644 index 000000000..82e9bb46a --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.sv @@ -0,0 +1,52 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// PACKAGE: This file defines all of the files contained in the +// interface package that needs to be compiled and synthesized +// for running on Veloce. +// +// CONTAINS: +// - +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +package mbox_sram_pkg_hdl; + + import uvmf_base_pkg_hdl::*; + + // pragma uvmf custom package_imports_additional begin + // pragma uvmf custom package_imports_additional end + + // Parameters defined as HDL parameters + + `include "src/mbox_sram_typedefs_hdl.svh" + `include "src/mbox_sram_macros.svh" + + // pragma uvmf custom package_item_additional begin + // pragma uvmf custom package_item_additional end + +endpackage + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.vinfo b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.vinfo new file mode 100644 index 000000000..b490cd934 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_hdl.vinfo @@ -0,0 +1,2 @@ +@use $UVMF_HOME/uvmf_base_pkg/uvmf_base_pkg_hdl.vinfo +mbox_sram_pkg_hdl.sv diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_sve.F b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_sve.F new file mode 100644 index 000000000..690a04c08 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/mbox_sram_pkg_sve.F @@ -0,0 +1,10 @@ +// UVM ++incdir+${UVM_HOME}/src +${UVM_HOME}/src/uvm_pkg.sv + +// Common UVMF files +-f ${UVMF_HOME}/common/common_sve.f + ++incdir+. +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hdl.f +-f ${UVMF_VIP_LIBRARY_HOME}/interface_packages/mbox_sram_pkg/mbox_sram_filelist_hvl.f diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram2reg_adapter.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram2reg_adapter.svh new file mode 100644 index 000000000..deba1e67c --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram2reg_adapter.svh @@ -0,0 +1,112 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains the UVM register adapter for the mbox_sram interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram2reg_adapter extends uvm_reg_adapter; + + `uvm_object_utils( mbox_sram2reg_adapter ) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //-------------------------------------------------------------------- + // new + //-------------------------------------------------------------------- + function new (string name = "mbox_sram2reg_adapter" ); + super.new(name); + // pragma uvmf custom new begin + // UVMF_CHANGE_ME : Configure the adapter regarding byte enables and provides response. + + // Does the protocol the Agent is modeling support byte enables? + // 0 = NO + // 1 = YES + supports_byte_enable = 0; + + // Does the Agent's Driver provide separate response sequence items? + // i.e. Does the driver call seq_item_port.put() + // and do the sequences call get_response()? + // 0 = NO + // 1 = YES + provides_responses = 0; + // pragma uvmf custom new end + + endfunction: new + + //-------------------------------------------------------------------- + // reg2bus + //-------------------------------------------------------------------- + virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw); + + mbox_sram_transaction trans_h = mbox_sram_transaction ::type_id::create("trans_h"); + + // pragma uvmf custom reg2bus begin + // UVMF_CHANGE_ME : Fill in the reg2bus adapter mapping registe fields to protocol fields. + + //Adapt the following for your sequence item type + // trans_h.op = (rw.kind == UVM_READ) ? WB_READ : WB_WRITE; + //Copy over address + // trans_h.addr = rw.addr; + //Copy over write data + // trans_h.data = rw.data; + + // pragma uvmf custom reg2bus end + + // Return the adapted transaction + return trans_h; + + endfunction: reg2bus + + //-------------------------------------------------------------------- + // bus2reg + //-------------------------------------------------------------------- + virtual function void bus2reg(uvm_sequence_item bus_item, + ref uvm_reg_bus_op rw); + mbox_sram_transaction trans_h; + if (!$cast(trans_h, bus_item)) begin + `uvm_fatal("ADAPT","Provided bus_item is not of the correct type") + return; + end + // pragma uvmf custom bus2reg begin + // UVMF_CHANGE_ME : Fill in the bus2reg adapter mapping protocol fields to register fields. + //Adapt the following for your sequence item type + //Copy over instruction type + // rw.kind = (trans_h.op == WB_WRITE) ? UVM_WRITE : UVM_READ; + //Copy over address + // rw.addr = trans_h.addr; + //Copy over read data + // rw.data = trans_h.data; + //Check for errors on the bus and return UVM_NOT_OK if there is an error + // rw.status = UVM_IS_OK; + // pragma uvmf custom bus2reg end + + endfunction: bus2reg + +endclass : mbox_sram2reg_adapter + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_agent.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_agent.svh new file mode 100644 index 000000000..ba0eb1e33 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_agent.svh @@ -0,0 +1,71 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: Protocol specific agent class definition +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_agent extends uvmf_parameterized_agent #( + .CONFIG_T(mbox_sram_configuration ), + .DRIVER_T(mbox_sram_driver ), + .MONITOR_T(mbox_sram_monitor ), + .COVERAGE_T(mbox_sram_transaction_coverage ), + .TRANS_T(mbox_sram_transaction ) + ); + + `uvm_component_utils( mbox_sram_agent ) + +// pragma uvmf custom class_item_additional begin + extern task handle_reset(string kind = "HARD"); +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// FUNCTION : new() +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** + // FUNCTION: build_phase + virtual function void build_phase(uvm_phase phase); +// pragma uvmf custom build_phase_pre_super begin +// pragma uvmf custom build_phase_pre_super end + super.build_phase(phase); + if (configuration.active_passive == ACTIVE) begin + // Place sequencer handle into configuration object + // so that it may be retrieved from configuration + // rather than using uvm_config_db + configuration.sequencer = this.sequencer; + end + endfunction + +endclass + +// pragma uvmf custom external begin +task mbox_sram_agent::handle_reset(string kind = "HARD"); + configuration.handle_reset(kind); +endtask +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_configuration.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_configuration.svh new file mode 100644 index 000000000..4b3c2e2c3 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_configuration.svh @@ -0,0 +1,203 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class contains all variables and functions used +// to configure the mbox_sram agent and its bfm's. It gets the +// bfm's from the uvm_config_db for use by the agent. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_configuration extends uvmf_parameterized_agent_configuration_base #( + .DRIVER_BFM_BIND_T(virtual mbox_sram_driver_bfm ), + .MONITOR_BFM_BIND_T( virtual mbox_sram_monitor_bfm )); + + `uvm_object_utils( mbox_sram_configuration ) + + // Controls injection of ECC errors for write transactions. Bit[0]: Single Bit Error. Bit[1]: Double Bit Error + bit [1:0] inject_ecc_error = 2'b00; + // When set, causes the mbox_sram_responder_sequence to clear the variable 'inject_ecc_error' after a single ECC error is injected + bit auto_clear_ecc_error_injection = 1'b1; + + // Sequencer handle populated by agent + uvm_sequencer #(mbox_sram_transaction ) sequencer; + + //Constraints for the configuration variables: + + // pragma uvmf custom class_item_additional begin + extern task handle_reset(string kind = "HARD"); + // pragma uvmf custom class_item_additional end + + covergroup mbox_sram_configuration_cg; + // pragma uvmf custom covergroup begin + option.auto_bin_max=1024; + coverpoint inject_ecc_error; + coverpoint auto_clear_ecc_error_injection; + // pragma uvmf custom covergroup end + endgroup + + //******************************************************************* + //******************************************************************* + // Structure used to pass configuration variables to monitor and driver BFM's. + // Use to_struct function to pack variables into structure. + // Use from_struct function to unpack variables from structure. + // This structure is defined in mbox_sram_macros.svh + `mbox_sram_CONFIGURATION_STRUCT + mbox_sram_configuration_s mbox_sram_configuration_struct; + //******************************************************************* + // FUNCTION: to_struct() + // This function packs variables into a mbox_sram_configuration_s + // structure. The function returns the handle to the mbox_sram_configuration_struct. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_CONFIGURATION_TO_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_struct() + // This function unpacks the struct provided as an argument into + // variables of this class. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_CONFIGURATION_FROM_STRUCT_FUNCTION + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + // Construct the covergroup for this configuration class + mbox_sram_configuration_cg = new; + endfunction + + // **************************************************************************** + // FUNCTION: post_randomize() + // This function is automatically called after the randomize() function + // is executed. + // + function void post_randomize(); + super.post_randomize(); + mbox_sram_configuration_cg.sample(); + endfunction + + // **************************************************************************** + // FUNCTION: initialize + // This function causes the configuration to retrieve + // its virtual interface handle from the uvm_config_db. + // This function also makes itself available to its + // agent through the uvm_config_db. + // + // ARGUMENTS: + // uvmf_active_passive_t activity: + // This argument identifies the simulation level + // as either BLOCK, CHIP, SIMULATION, etc. + // + // AGENT_PATH: + // This argument identifies the path to this + // configurations agent. This configuration + // makes itself available to the agent specified + // by agent_path by placing itself into the + // uvm_config_db. + // + // INTERFACE_NAME: + // This argument identifies the string name of + // this configurations BFM's. This string + // name is used to retrieve the driver and + // monitor BFM from the uvm_config_db. + // + virtual function void initialize(uvmf_active_passive_t activity, + string agent_path, + string interface_name); + + super.initialize( activity, agent_path, interface_name); + // The covergroup is given the same name as the interface + mbox_sram_configuration_cg.set_inst_name(interface_name); + + // This configuration places itself into the uvm_config_db for the agent, identified by the agent_path variable, to retrieve. + uvm_config_db #( mbox_sram_configuration + )::set( null ,agent_path,UVMF_AGENT_CONFIG, this ); + + // This configuration also places itself in the config db using the same identifier used by the interface. This allows users to access + // configuration variables and the interface through the bfm api class rather than directly accessing the BFM. This is useful for + // accessingthe BFM when using Veloce + uvm_config_db #( mbox_sram_configuration + )::set( null ,UVMF_CONFIGURATIONS, interface_name, this ); + + mbox_sram_configuration_cg.set_inst_name($sformatf("mbox_sram_configuration_cg_%s",get_full_name())); + +// This code is to aid in debugging parameter mismatches between the BFM and its corresponding agent. +// Enable this debug by setting UVM_VERBOSITY to UVM_DEBUG +// Setting UVM_VERBOSITY to UVM_DEBUG causes all BFM's and all agents to display their parameter settings. +// All of the messages from this feature have a UVM messaging id value of "CFG" +// The transcript or run.log can be parsed to ensure BFM parameter settings match its corresponding agents parameter settings. + `uvm_info("CFG", + $psprintf("The agent at '%s' is using interface named %s has the following parameters: ", agent_path, interface_name, ), + UVM_DEBUG) + + // pragma uvmf custom initialize begin + // This controls whether or not the agent returns a transaction handle in the driver when calling + // item_done() back into the sequencer or not. If set to 1, a transaction is sent back which means + // the sequence on the other end must use the get_response() part of the driver/sequence API. If + // this doesn't occur, there will eventually be response_queue overflow errors during the test. + return_transaction_response = 1'b1; + + // pragma uvmf custom initialize end + + endfunction + + // **************************************************************************** + // TASK: wait_for_reset + // *[Required]* Blocks until reset is released. The wait_for_reset operation is performed + // by a task in the monitor bfm. + virtual task wait_for_reset(); + monitor_bfm.wait_for_reset(); + endtask + + // **************************************************************************** + // TASK: wait_for_num_clocks + // *[Required]* Blocks until specified number of clocks have elapsed. The wait_for_num_clocks + // operation is performed by a task in the monitor bfm. + virtual task wait_for_num_clocks(int clocks); + monitor_bfm.wait_for_num_clocks(clocks); + endtask + + // **************************************************************************** + // FUNCTION : convert2string() + // This function is used to convert variables in this class into a string for log messaging. + // + virtual function string convert2string (); + // pragma uvmf custom convert2string begin + return $sformatf("inject_ecc_error:0x%x auto_clear_ecc_error_injection:0x%x ",inject_ecc_error,auto_clear_ecc_error_injection); + // pragma uvmf custom convert2string end + endfunction + + // **************************************************************************** + // FUNCTION: get_sequencer + function uvm_sequencer #(mbox_sram_transaction) get_sequencer(); + return sequencer; + endfunction + +endclass + +// pragma uvmf custom external begin +task mbox_sram_configuration::handle_reset(string kind = "HARD"); + inject_ecc_error = 0; +endtask +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver.svh new file mode 100644 index 000000000..c083be2b0 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver.svh @@ -0,0 +1,105 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class passes transactions between the sequencer +// and the BFM driver interface. It accesses the driver BFM +// through the bfm handle. This driver +// passes transactions to the driver BFM through the access +// task. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_driver extends uvmf_driver_base #( + .CONFIG_T(mbox_sram_configuration ), + .BFM_BIND_T(virtual mbox_sram_driver_bfm ), + .REQ(mbox_sram_transaction ), + .RSP(mbox_sram_transaction )); + + `uvm_component_utils( mbox_sram_driver ) +//******************************************************************* +// Macros that define structs located in mbox_sram_macros.svh +//******************************************************************* +// Initiator macro used by mbox_sram_driver and mbox_sram_driver_bfm +// to communicate initiator driven data to mbox_sram_driver_bfm. +`mbox_sram_INITIATOR_STRUCT + mbox_sram_initiator_s mbox_sram_initiator_struct; +//******************************************************************* +// Responder macro used by mbox_sram_driver and mbox_sram_driver_bfm +// to communicate Responder driven data to mbox_sram_driver_bfm. +`mbox_sram_RESPONDER_STRUCT + mbox_sram_responder_s mbox_sram_responder_struct; + +// pragma uvmf custom class_item_additional begin +// pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent=null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the driver BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// driver BFM. This allows the driver BFM to call tasks and function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// **************************************************************************** +// This task is called by the run_phase in uvmf_driver_base. + virtual task access( inout REQ txn ); +// pragma uvmf custom access begin + if (configuration.initiator_responder==RESPONDER) begin + // Complete current transfer and wait for next transfer + bfm.respond_and_wait_for_next_transfer( + mbox_sram_initiator_struct, + txn.to_responder_struct() + ); + // Unpack information about initiated transfer received by this responder + txn.from_initiator_struct(mbox_sram_initiator_struct); + end else begin + // Initiate a transfer and get response + bfm.initiate_and_get_response( + txn.to_initiator_struct(), + mbox_sram_responder_struct + ); + // Unpack transfer response information received by this initiator + txn.from_responder_struct(mbox_sram_responder_struct); + end +// pragma uvmf custom access end + endtask + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv new file mode 100644 index 000000000..6c9359089 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_driver_bfm.sv @@ -0,0 +1,334 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +import soc_ifc_pkg::*; +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This interface performs the mbox_sram signal driving. It is +// accessed by the uvm mbox_sram driver through a virtual interface +// handle in the mbox_sram configuration. It drives the singals passed +// in through the port connection named bus of type mbox_sram_if. +// +// Input signals from the mbox_sram_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// This bfm drives signals with a _o suffix. These signals +// are driven onto signals within mbox_sram_if based on INITIATOR/RESPONDER and/or +// ARBITRATION/GRANT status. +// +// The output signal connections are as follows: +// signal_o -> bus.signal +// +// +// Interface functions and tasks used by UVM components: +// +// configure: +// This function gets configuration attributes from the +// UVM driver to set any required BFM configuration +// variables such as 'initiator_responder'. +// +// initiate_and_get_response: +// This task is used to perform signaling activity for initiating +// a protocol transfer. The task initiates the transfer, using +// input data from the initiator struct. Then the task captures +// response data, placing the data into the response struct. +// The response struct is returned to the driver class. +// +// respond_and_wait_for_next_transfer: +// This task is used to complete a current transfer as a responder +// and then wait for the initiator to start the next transfer. +// The task uses data in the responder struct to drive protocol +// signals to complete the transfer. The task then waits for +// the next transfer. Once the next transfer begins, data from +// the initiator is placed into the initiator struct and sent +// to the responder sequence for processing to determine +// what data to respond with. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import mbox_sram_pkg_hdl::*; +`include "src/mbox_sram_macros.svh" + +interface mbox_sram_driver_bfm + (mbox_sram_if bus); + // The following pragma and additional ones in-lined further below are for running this BFM on Veloce + // pragma attribute mbox_sram_driver_bfm partition_interface_xif + +`ifndef XRTL +// This code is to aid in debugging parameter mismatches between the BFM and its corresponding agent. +// Enable this debug by setting UVM_VERBOSITY to UVM_DEBUG +// Setting UVM_VERBOSITY to UVM_DEBUG causes all BFM's and all agents to display their parameter settings. +// All of the messages from this feature have a UVM messaging id value of "CFG" +// The transcript or run.log can be parsed to ensure BFM parameter settings match its corresponding agents parameter settings. +import uvm_pkg::*; +`include "uvm_macros.svh" +initial begin : bfm_vs_agent_parameter_debug + `uvm_info("CFG", + $psprintf("The BFM at '%m' has the following parameters: ", ), + UVM_DEBUG) +end +`endif + + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + bit [1:0] inject_ecc_error ; + bit auto_clear_ecc_error_injection ; + + tri clk_i; + tri dummy_i; + + // Signal list (all signals are capable of being inputs and outputs for the sake + // of supporting both INITIATOR and RESPONDER mode operation. Expectation is that + // directionality in the config file was from the point-of-view of the INITIATOR + + // INITIATOR mode input signals + tri [$bits(mbox_sram_resp_t)-1:0] mbox_sram_resp_i; +// reg [$bits(mbox_sram_resp_t)-1:0] mbox_sram_resp_o = 'bz; + mbox_sram_resp_t mbox_sram_resp_o = 'bz; + + // INITIATOR mode output signals +// tri [$bits(mbox_sram_req_t)-1:0] mbox_sram_req_i; + mbox_sram_req_t mbox_sram_req_i; + reg [$bits(mbox_sram_req_t)-1:0] mbox_sram_req_o = 'bz; + + // Bi-directional signals + + + assign clk_i = bus.clk; + assign dummy_i = bus.dummy; + + // These are signals marked as 'input' by the config file, but the signals will be + // driven by this BFM if put into RESPONDER mode (flipping all signal directions around) + assign mbox_sram_resp_i = bus.mbox_sram_resp; + assign bus.mbox_sram_resp = (initiator_responder == RESPONDER) ? mbox_sram_resp_o : 'bz; + + + // These are signals marked as 'output' by the config file, but the outputs will + // not be driven by this BFM unless placed in INITIATOR mode. + assign bus.mbox_sram_req = (initiator_responder == INITIATOR) ? mbox_sram_req_o : 'bz; + assign mbox_sram_req_i = bus.mbox_sram_req; + + // Proxy handle to UVM driver + mbox_sram_pkg::mbox_sram_driver proxy; + // pragma tbx oneway proxy.my_function_name_in_uvm_driver + + // **************************************************************************** + // **************************************************************************** + // Macros that define structs located in mbox_sram_macros.svh + // **************************************************************************** + // Struct for passing configuration data from mbox_sram_driver to this BFM + // **************************************************************************** + `mbox_sram_CONFIGURATION_STRUCT + // **************************************************************************** + // Structs for INITIATOR and RESPONDER data flow + //******************************************************************* + // Initiator macro used by mbox_sram_driver and mbox_sram_driver_bfm + // to communicate initiator driven data to mbox_sram_driver_bfm. + `mbox_sram_INITIATOR_STRUCT + mbox_sram_initiator_s initiator_struct; + // Responder macro used by mbox_sram_driver and mbox_sram_driver_bfm + // to communicate Responder driven data to mbox_sram_driver_bfm. + `mbox_sram_RESPONDER_STRUCT + mbox_sram_responder_s responder_struct; + + // **************************************************************************** +// pragma uvmf custom reset_condition_and_response begin + // Always block used to return signals to reset value upon assertion of reset + always @( negedge dummy_i ) + begin + // RESPONDER mode output signals + mbox_sram_resp_o <= 'bz; + // INITIATOR mode output signals + mbox_sram_req_o <= 'bz; + // Bi-directional signals + + end +// pragma uvmf custom reset_condition_and_response end + + // pragma uvmf custom interface_item_additional begin + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the driver BFM. It is called by the driver within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the driver BFM needs to be aware of the new configuration + // variables. + // + + function void configure(mbox_sram_configuration_s mbox_sram_configuration_arg); // pragma tbx xtf + initiator_responder = mbox_sram_configuration_arg.initiator_responder; + inject_ecc_error = mbox_sram_configuration_arg.inject_ecc_error; + auto_clear_ecc_error_injection = mbox_sram_configuration_arg.auto_clear_ecc_error_injection; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + +// pragma uvmf custom initiate_and_get_response begin +// **************************************************************************** +// UVMF_CHANGE_ME +// This task is used by an initator. The task first initiates a transfer then +// waits for the responder to complete the transfer. + task initiate_and_get_response( + // This argument passes transaction variables used by an initiator + // to perform the initial part of a protocol transfer. The values + // come from a sequence item created in a sequence. + input mbox_sram_initiator_s mbox_sram_initiator_struct, + // This argument is used to send data received from the responder + // back to the sequence item. The sequence item is returned to the sequence. + output mbox_sram_responder_s mbox_sram_responder_struct + );// pragma tbx xtf + // + // Members within the mbox_sram_initiator_struct: + // bit is_read ; + // bit [MBOX_ADDR_W-1:0] address ; + // bit [MBOX_DATA_W-1:0] data ; + // bit [MBOX_ECC_DATA_W-1:0] data_ecc ; + // bit ecc_single_bit_error ; + // bit ecc_double_bit_error ; + // Members within the mbox_sram_responder_struct: + // bit is_read ; + // bit [MBOX_ADDR_W-1:0] address ; + // bit [MBOX_DATA_W-1:0] data ; + // bit [MBOX_ECC_DATA_W-1:0] data_ecc ; + // bit ecc_single_bit_error ; + // bit ecc_double_bit_error ; + initiator_struct = mbox_sram_initiator_struct; + // + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge clk_i); + // + // How to assign a responder struct member, named xyz, from a signal. + // All available initiator input and inout signals listed. + // Initiator input signals + // mbox_sram_responder_struct.xyz = mbox_sram_resp_i; // [$bits(mbox_sram_resp_t)-1:0] + // Initiator inout signals + // How to assign a signal from an initiator struct member named xyz. + // All available initiator output and inout signals listed. + // Notice the _o. Those are storage variables that allow for procedural assignment. + // Initiator output signals + // mbox_sram_req_o <= mbox_sram_initiator_struct.xyz; // [$bits(mbox_sram_req_t)-1:0] + // Initiator inout signals + // Initiate a transfer using the data received. + @(posedge clk_i); + @(posedge clk_i); + // Wait for the responder to complete the transfer then place the responder data into + // mbox_sram_responder_struct. + @(posedge clk_i); + @(posedge clk_i); + `uvm_fatal("MBOX_SRAM_DRIVER_BFM", "Unimplemented initiate_and_get_response") + responder_struct = mbox_sram_responder_struct; + endtask +// pragma uvmf custom initiate_and_get_response end + +// pragma uvmf custom respond_and_wait_for_next_transfer begin +// **************************************************************************** +// The first_transfer variable is used to prevent completing a transfer in the +// first call to this task. For the first call to this task, there is not +// current transfer to complete. +bit first_transfer=1; + +// UVMF_CHANGE_ME +// This task is used by a responder. The task first completes the current +// transfer in progress then waits for the initiator to start the next transfer. + task respond_and_wait_for_next_transfer( + // This argument is used to send data received from the initiator + // back to the sequence item. The sequence determines how to respond. + output mbox_sram_initiator_s mbox_sram_initiator_struct, + // This argument passes transaction variables used by a responder + // to complete a protocol transfer. The values come from a sequence item. + input mbox_sram_responder_s mbox_sram_responder_struct + );// pragma tbx xtf + // Variables within the mbox_sram_initiator_struct: + // bit is_read ; + // bit [MBOX_ADDR_W-1:0] address ; + // bit [MBOX_DATA_W-1:0] data ; + // bit [MBOX_ECC_DATA_W-1:0] data_ecc ; + // bit ecc_single_bit_error ; + // bit ecc_double_bit_error ; + // Variables within the mbox_sram_responder_struct: + // bit is_read ; + // bit [MBOX_ADDR_W-1:0] address ; + // bit [MBOX_DATA_W-1:0] data ; + // bit [MBOX_ECC_DATA_W-1:0] data_ecc ; + // bit ecc_single_bit_error ; + // bit ecc_double_bit_error ; + // Reference code; + // How to wait for signal value + // while (control_signal == 1'b1) @(posedge clk_i); + // + // How to assign a responder struct member, named xyz, from a signal. + // All available responder input and inout signals listed. + // Responder input signals + // mbox_sram_responder_struct.xyz = mbox_sram_req_i; // [$bits(mbox_sram_req_t)-1:0] + // Responder inout signals + // How to assign a signal, named xyz, from an initiator struct member. + // All available responder output and inout signals listed. + // Notice the _o. Those are storage variables that allow for procedural assignment. + // Responder output signals + // mbox_sram_resp_o <= mbox_sram_initiator_struct.xyz; // [$bits(mbox_sram_resp_t)-1:0] + // Responder inout signals + + responder_struct <= mbox_sram_responder_struct; + if (!first_transfer) begin + // Perform transfer response here. + // Reply using data recieved in the mbox_sram_responder_struct. + if (mbox_sram_responder_struct.is_read) begin + mbox_sram_resp_o.rdata.data <= mbox_sram_responder_struct.data; + mbox_sram_resp_o.rdata.ecc <= mbox_sram_responder_struct.data_ecc; + end + @(posedge clk_i); + end + while (mbox_sram_req_i.cs !== 1'b1) @(posedge clk_i); + // Wait for next transfer then gather info from intiator about the transfer. + // Place the data into the mbox_sram_initiator_struct. + mbox_sram_initiator_struct.is_read = ~mbox_sram_req_i.we; + mbox_sram_initiator_struct.address = mbox_sram_req_i.addr; + mbox_sram_initiator_struct.data = mbox_sram_req_i.wdata.data; + mbox_sram_initiator_struct.data_ecc = mbox_sram_req_i.wdata.ecc; + mbox_sram_initiator_struct.ecc_single_bit_error = mbox_sram_req_i.we && proxy.configuration.inject_ecc_error[0]; + mbox_sram_initiator_struct.ecc_double_bit_error = mbox_sram_req_i.we && proxy.configuration.inject_ecc_error[1]; + if (mbox_sram_initiator_struct.ecc_single_bit_error || mbox_sram_initiator_struct.ecc_double_bit_error) `uvm_info("MBOX_SRAM_DRIVER_BFM", "Injecting ECC bit flip", UVM_DEBUG) + else if (mbox_sram_req_i.we) `uvm_info("MBOX_SRAM_DRIVER_BFM", "Receiving SRAM write without ECC bit flip", UVM_DEBUG) + if (proxy.configuration.auto_clear_ecc_error_injection && |proxy.configuration.inject_ecc_error) begin + proxy.configuration.inject_ecc_error = 2'b00; + `uvm_info("MBOX_SRAM_DRIVER_BFM", "Resetting inject_ecc_error value to 0", UVM_DEBUG) + end + first_transfer = 0; + initiator_struct = mbox_sram_initiator_struct; + endtask +// pragma uvmf custom respond_and_wait_for_next_transfer end + + +endinterface + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv new file mode 100644 index 000000000..d84655f20 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_if.sv @@ -0,0 +1,83 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface contains the mbox_sram interface signals. +// It is instantiated once per mbox_sram bus. Bus Functional Models, +// BFM's named mbox_sram_driver_bfm, are used to drive signals on the bus. +// BFM's named mbox_sram_monitor_bfm are used to monitor signals on the +// bus. This interface signal bundle is passed in the port list of +// the BFM in order to give the BFM access to the signals in this +// interface. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// This template can be used to connect a DUT to these signals +// +// .dut_signal_port(mbox_sram_bus.mbox_sram_req), // Agent output +// .dut_signal_port(mbox_sram_bus.mbox_sram_resp), // Agent input + +import uvmf_base_pkg_hdl::*; +import mbox_sram_pkg_hdl::*; + +interface mbox_sram_if + + ( + input tri clk, + input tri dummy, + inout tri [$bits(mbox_sram_req_t)-1:0] mbox_sram_req, + inout tri [$bits(mbox_sram_resp_t)-1:0] mbox_sram_resp + ); + +modport monitor_port + ( + input clk, + input dummy, + input mbox_sram_req, + input mbox_sram_resp + ); + +modport initiator_port + ( + input clk, + input dummy, + output mbox_sram_req, + input mbox_sram_resp + ); + +modport responder_port + ( + input clk, + input dummy, + input mbox_sram_req, + output mbox_sram_resp + ); + + +// pragma uvmf custom interface_item_additional begin +// pragma uvmf custom interface_item_additional end + +endinterface + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_infact_coverage_strategy.csv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_infact_coverage_strategy.csv new file mode 100644 index 000000000..1c218e146 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_infact_coverage_strategy.csv @@ -0,0 +1,6 @@ +Global +auto_bin_max, 64 + +Name,Type,Include +rand_fields,coverpoint,=rand *.** + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_macros.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_macros.svh new file mode 100644 index 000000000..19d629026 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_macros.svh @@ -0,0 +1,186 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This file contains macros used with the mbox_sram package. +// These macros include packed struct definitions. These structs are +// used to pass data between classes, hvl, and BFM's, hdl. Use of +// structs are more efficient and simpler to modify. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_struct +// and from_struct methods defined in the macros below that are used in +// the mbox_sram_configuration class. +// + `define mbox_sram_CONFIGURATION_STRUCT \ +typedef struct packed { \ + bit [1:0] inject_ecc_error;\ + bit auto_clear_ecc_error_injection;\ + uvmf_active_passive_t active_passive; \ + uvmf_initiator_responder_t initiator_responder; \ + } mbox_sram_configuration_s; + + `define mbox_sram_CONFIGURATION_TO_STRUCT_FUNCTION \ + virtual function mbox_sram_configuration_s to_struct();\ + mbox_sram_configuration_struct = \ + {\ + this.inject_ecc_error,\ + this.auto_clear_ecc_error_injection,\ + this.active_passive,\ + this.initiator_responder\ + };\ + return ( mbox_sram_configuration_struct );\ + endfunction + + `define mbox_sram_CONFIGURATION_FROM_STRUCT_FUNCTION \ + virtual function void from_struct(mbox_sram_configuration_s mbox_sram_configuration_struct);\ + {\ + this.inject_ecc_error,\ + this.auto_clear_ecc_error_injection,\ + this.active_passive,\ + this.initiator_responder \ + } = mbox_sram_configuration_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_monitor_struct +// and from_monitor_struct methods of the mbox_sram_transaction class. +// + `define mbox_sram_MONITOR_STRUCT typedef struct packed { \ + bit is_read ; \ + bit [MBOX_ADDR_W-1:0] address ; \ + bit [MBOX_DATA_W-1:0] data ; \ + bit [MBOX_ECC_DATA_W-1:0] data_ecc ; \ + bit ecc_single_bit_error ; \ + bit ecc_double_bit_error ; \ + } mbox_sram_monitor_s; + + `define mbox_sram_TO_MONITOR_STRUCT_FUNCTION \ + virtual function mbox_sram_monitor_s to_monitor_struct();\ + mbox_sram_monitor_struct = \ + { \ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + };\ + return ( mbox_sram_monitor_struct);\ + endfunction\ + + `define mbox_sram_FROM_MONITOR_STRUCT_FUNCTION \ + virtual function void from_monitor_struct(mbox_sram_monitor_s mbox_sram_monitor_struct);\ + {\ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + } = mbox_sram_monitor_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_initiator_struct +// and from_initiator_struct methods of the mbox_sram_transaction class. +// Also update the comments in the driver BFM. +// + `define mbox_sram_INITIATOR_STRUCT typedef struct packed { \ + bit is_read ; \ + bit [MBOX_ADDR_W-1:0] address ; \ + bit [MBOX_DATA_W-1:0] data ; \ + bit [MBOX_ECC_DATA_W-1:0] data_ecc ; \ + bit ecc_single_bit_error ; \ + bit ecc_double_bit_error ; \ + } mbox_sram_initiator_s; + + `define mbox_sram_TO_INITIATOR_STRUCT_FUNCTION \ + virtual function mbox_sram_initiator_s to_initiator_struct();\ + mbox_sram_initiator_struct = \ + {\ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + };\ + return ( mbox_sram_initiator_struct);\ + endfunction + + `define mbox_sram_FROM_INITIATOR_STRUCT_FUNCTION \ + virtual function void from_initiator_struct(mbox_sram_initiator_s mbox_sram_initiator_struct);\ + {\ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + } = mbox_sram_initiator_struct;\ + endfunction + +// **************************************************************************** +// When changing the contents of this struct, be sure to update the to_responder_struct +// and from_responder_struct methods of the mbox_sram_transaction class. +// Also update the comments in the driver BFM. +// + `define mbox_sram_RESPONDER_STRUCT typedef struct packed { \ + bit is_read ; \ + bit [MBOX_ADDR_W-1:0] address ; \ + bit [MBOX_DATA_W-1:0] data ; \ + bit [MBOX_ECC_DATA_W-1:0] data_ecc ; \ + bit ecc_single_bit_error ; \ + bit ecc_double_bit_error ; \ + } mbox_sram_responder_s; + + `define mbox_sram_TO_RESPONDER_STRUCT_FUNCTION \ + virtual function mbox_sram_responder_s to_responder_struct();\ + mbox_sram_responder_struct = \ + {\ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + };\ + return ( mbox_sram_responder_struct);\ + endfunction + + `define mbox_sram_FROM_RESPONDER_STRUCT_FUNCTION \ + virtual function void from_responder_struct(mbox_sram_responder_s mbox_sram_responder_struct);\ + {\ + this.is_read , \ + this.address , \ + this.data , \ + this.data_ecc , \ + this.ecc_single_bit_error , \ + this.ecc_double_bit_error \ + } = mbox_sram_responder_struct;\ + endfunction +// pragma uvmf custom additional begin +// pragma uvmf custom additional end diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor.svh new file mode 100644 index 000000000..701ca2ef4 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor.svh @@ -0,0 +1,101 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class receives mbox_sram transactions observed by the +// mbox_sram monitor BFM and broadcasts them through the analysis port +// on the agent. It accesses the monitor BFM through the monitor +// task. This UVM component captures transactions +// for viewing in the waveform viewer if the +// enable_transaction_viewing flag is set in the configuration. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_monitor extends uvmf_monitor_base #( + .CONFIG_T(mbox_sram_configuration ), + .BFM_BIND_T(virtual mbox_sram_monitor_bfm ), + .TRANS_T(mbox_sram_transaction )); + + `uvm_component_utils( mbox_sram_monitor ) + +// Structure used to pass data from monitor BFM to monitor class in agent. +// Use to_monitor_struct function to pack transaction variables into structure. +// Use from_monitor_struct function to unpack transaction variables from structure. +`mbox_sram_MONITOR_STRUCT + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + +// **************************************************************************** +// This function is the standard SystemVerilog constructor. +// + function new( string name = "", uvm_component parent = null ); + super.new( name, parent ); + endfunction + +// **************************************************************************** +// This function sends configuration object variables to the monitor BFM +// using the configuration struct. +// + virtual function void configure(input CONFIG_T cfg); + bfm.configure( cfg.to_struct() ); + + endfunction + +// **************************************************************************** +// This function places a handle to this class in the proxy variable in the +// monitor BFM. This allows the monitor BFM to call the notify_transaction +// function within this class. +// + virtual function void set_bfm_proxy_handle(); + bfm.proxy = this; endfunction + +// *************************************************************************** + virtual task run_phase(uvm_phase phase); + // Start monitor BFM thread and don't call super.run() in order to + // override the default monitor proxy 'pull' behavior with the more + // emulation-friendly BFM 'push' approach using the notify_transaction + // function below + bfm.start_monitoring(); + endtask + +// ************************************************************************** + +// This function is called by the monitor BFM. It receives data observed by the +// monitor BFM. Data is passed using the mbox_sram_monitor_struct. + virtual function void notify_transaction(input mbox_sram_monitor_s mbox_sram_monitor_struct); + + + trans = new("trans"); + trans.from_monitor_struct(mbox_sram_monitor_struct); + trans.start_time = time_stamp; + trans.end_time = $time; + time_stamp = trans.end_time; + + analyze(trans); + endfunction + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv new file mode 100644 index 000000000..191287ca8 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_monitor_bfm.sv @@ -0,0 +1,238 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +import soc_ifc_pkg::*; +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This interface performs the mbox_sram signal monitoring. +// It is accessed by the uvm mbox_sram monitor through a virtual +// interface handle in the mbox_sram configuration. It monitors the +// signals passed in through the port connection named bus of +// type mbox_sram_if. +// +// Input signals from the mbox_sram_if are assigned to an internal input +// signal with a _i suffix. The _i signal should be used for sampling. +// +// The input signal connections are as follows: +// bus.signal -> signal_i +// +// Interface functions and tasks used by UVM components: +// monitor(inout TRANS_T txn); +// This task receives the transaction, txn, from the +// UVM monitor and then populates variables in txn +// from values observed on bus activity. This task +// blocks until an operation on the mbox_sram bus is complete. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +import uvmf_base_pkg_hdl::*; +import mbox_sram_pkg_hdl::*; +`include "src/mbox_sram_macros.svh" + + +interface mbox_sram_monitor_bfm + ( mbox_sram_if bus ); + // The pragma below and additional ones in-lined further down are for running this BFM on Veloce + // pragma attribute mbox_sram_monitor_bfm partition_interface_xif + +`ifndef XRTL +// This code is to aid in debugging parameter mismatches between the BFM and its corresponding agent. +// Enable this debug by setting UVM_VERBOSITY to UVM_DEBUG +// Setting UVM_VERBOSITY to UVM_DEBUG causes all BFM's and all agents to display their parameter settings. +// All of the messages from this feature have a UVM messaging id value of "CFG" +// The transcript or run.log can be parsed to ensure BFM parameter settings match its corresponding agents parameter settings. +import uvm_pkg::*; +`include "uvm_macros.svh" +initial begin : bfm_vs_agent_parameter_debug + `uvm_info("CFG", + $psprintf("The BFM at '%m' has the following parameters: ", ), + UVM_DEBUG) +end +`endif + + + // Structure used to pass transaction data from monitor BFM to monitor class in agent. +`mbox_sram_MONITOR_STRUCT + mbox_sram_monitor_s mbox_sram_monitor_struct; + + // Structure used to pass configuration data from monitor class to monitor BFM. + `mbox_sram_CONFIGURATION_STRUCT + + + // Config value to determine if this is an initiator or a responder + uvmf_initiator_responder_t initiator_responder; + // Custom configuration variables. + // These are set using the configure function which is called during the UVM connect_phase + bit [1:0] inject_ecc_error ; + bit auto_clear_ecc_error_injection ; + + tri clk_i; + tri dummy_i; + tri mbox_sram_req_t mbox_sram_req_i; + tri mbox_sram_resp_t mbox_sram_resp_i; + assign clk_i = bus.clk; + assign dummy_i = bus.dummy; + assign mbox_sram_req_i = bus.mbox_sram_req; + assign mbox_sram_resp_i = bus.mbox_sram_resp; + + // Proxy handle to UVM monitor + mbox_sram_pkg::mbox_sram_monitor proxy; + // pragma tbx oneway proxy.notify_transaction + + // pragma uvmf custom interface_item_additional begin + function bit [1:0] rvecc_decode ( input [31:0] din, input [6:0] ecc_in); + bit [6:0] ecc_check; + + // Generate the ecc bits + ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; + ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]; + ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]; + ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31]; + + // This is the parity bit + ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])); + + rvecc_decode[0] = (ecc_check[6:0] != 0) & ecc_check[6]; // Single-bit error + rvecc_decode[1] = (ecc_check[6:0] != 0) & ~ecc_check[6]; // Double-bit error + + endfunction: rvecc_decode + // pragma uvmf custom interface_item_additional end + + //****************************************************************** + task wait_for_reset();// pragma tbx xtf +// @(posedge clk_i) ; +// do_wait_for_reset(); + endtask + + // **************************************************************************** + task do_wait_for_reset(); + // pragma uvmf custom reset_condition begin + wait ( dummy_i === 1 ) ; + @(posedge clk_i) ; + // pragma uvmf custom reset_condition end + endtask + + // pragma uvmf custom wait_for_num_clocks begin + //**************************************************************************** + // Inject pragmas's here to throw a warning on regeneration. + // Task must have automatic lifetime so that it can be concurrently invoked + // by multiple entities with a different wait value. + task automatic wait_for_num_clocks(input int unsigned count); // pragma tbx xtf + if (count == 0) `uvm_fatal("CFG", "wait_for_num_clocks called with count of 0 - this will lead to a hang"); + @(posedge clk_i); + repeat (count-1) @(posedge clk_i); + endtask + // pragma uvmf custom wait_for_num_clocks end + + //****************************************************************** + event go; + function void start_monitoring();// pragma tbx xtf + -> go; + endfunction + + // **************************************************************************** + initial begin + @go; + forever begin + do_monitor( mbox_sram_monitor_struct ); + proxy.notify_transaction( mbox_sram_monitor_struct ); + // Back-to-back writes require a clock in between to avoid a 0-time forever loop. + // Reads already inject the extra clock cycle, so we can check cs again immediately. + if (!mbox_sram_monitor_struct.is_read) @(posedge clk_i); + + end + end + + //****************************************************************** + // The configure() function is used to pass agent configuration + // variables to the monitor BFM. It is called by the monitor within + // the agent at the beginning of the simulation. It may be called + // during the simulation if agent configuration variables are updated + // and the monitor BFM needs to be aware of the new configuration + // variables. + // + function void configure(mbox_sram_configuration_s mbox_sram_configuration_arg); // pragma tbx xtf + initiator_responder = mbox_sram_configuration_arg.initiator_responder; + inject_ecc_error = mbox_sram_configuration_arg.inject_ecc_error; + auto_clear_ecc_error_injection = mbox_sram_configuration_arg.auto_clear_ecc_error_injection; + // pragma uvmf custom configure begin + // pragma uvmf custom configure end + endfunction + + + // **************************************************************************** + + task do_monitor(output mbox_sram_monitor_s mbox_sram_monitor_struct); + // + // Available struct members: + // // mbox_sram_monitor_struct.is_read + // // mbox_sram_monitor_struct.address + // // mbox_sram_monitor_struct.data + // // mbox_sram_monitor_struct.data_ecc + // // mbox_sram_monitor_struct.ecc_single_bit_error + // // mbox_sram_monitor_struct.ecc_double_bit_error + // // + // Reference code; + // How to wait for signal value + // while (control_signal === 1'b1) @(posedge clk_i); + // + // How to assign a struct member, named xyz, from a signal. + // All available input signals listed. + // mbox_sram_monitor_struct.xyz = mbox_sram_req_i; // [$bits(mbox_sram_req_t)-1:0] + // mbox_sram_monitor_struct.xyz = mbox_sram_resp_i; // [$bits(mbox_sram_resp_t)-1:0] + // pragma uvmf custom do_monitor begin + // UVMF_CHANGE_ME : Implement protocol monitoring. The commented reference code + // below are examples of how to capture signal values and assign them to + // structure members. All available input signals are listed. The 'while' + // code example shows how to wait for a synchronous flow control signal. This + // task should return when a complete transfer has been observed. Once this task is + // exited with captured values, it is then called again to wait for and observe + // the next transfer. One clock cycle is consumed between calls to do_monitor. + while (mbox_sram_req_i.cs !== 1'b1) @(posedge clk_i); + mbox_sram_monitor_struct.is_read = ~mbox_sram_req_i.we; + mbox_sram_monitor_struct.address = mbox_sram_req_i.addr; + mbox_sram_monitor_struct.data = mbox_sram_req_i.wdata.data; + mbox_sram_monitor_struct.data_ecc = mbox_sram_req_i.wdata.ecc; + // For writes, the monitored transaction signals the _intent_ to inject an ECC error + // at the responder sequence + mbox_sram_monitor_struct.ecc_single_bit_error = proxy.configuration.inject_ecc_error[0]; + mbox_sram_monitor_struct.ecc_double_bit_error = proxy.configuration.inject_ecc_error[1]; + // If a write is detected, return immediately (that's the whole transaction) + if (mbox_sram_req_i.we) return; + // If a read, continue another clock cycle to capture return data + @(posedge clk_i); + mbox_sram_monitor_struct.data = mbox_sram_resp_i.rdata.data; + mbox_sram_monitor_struct.data_ecc = mbox_sram_resp_i.rdata.ecc; + // For reads, the monitored transaction signals the calculation of actual ECC errors + // observed on the data returned from the responder sequence + {mbox_sram_monitor_struct.ecc_double_bit_error, + mbox_sram_monitor_struct.ecc_single_bit_error} = rvecc_decode(mbox_sram_monitor_struct.data, mbox_sram_monitor_struct.data_ecc); + // pragma uvmf custom do_monitor end + endtask + + +endinterface + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_random_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_random_sequence.svh new file mode 100644 index 000000000..90ce2cdb4 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_random_sequence.svh @@ -0,0 +1,67 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This sequences randomizes the mbox_sram transaction and sends it +// to the UVM driver. +// +// This sequence constructs and randomizes a mbox_sram_transaction. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_random_sequence + extends mbox_sram_sequence_base ; + + `uvm_object_utils( mbox_sram_random_sequence ) + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //***************************************************************** + function new(string name = ""); + super.new(name); + endfunction: new + + // **************************************************************************** + // TASK : body() + // This task is automatically executed when this sequence is started using the + // start(sequencerHandle) task. + // + task body(); + + // Construct the transaction + req=mbox_sram_transaction::type_id::create("req"); + start_item(req); + // Randomize the transaction + if(!req.randomize()) `uvm_fatal("SEQ", "mbox_sram_random_sequence::body()-mbox_sram_transaction randomization failed") + // Send the transaction to the mbox_sram_driver_bfm via the sequencer and mbox_sram_driver. + finish_item(req); + `uvm_info("SEQ", {"Response:",req.convert2string()},UVM_MEDIUM) + + endtask + +endclass: mbox_sram_random_sequence + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_responder_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_responder_sequence.svh new file mode 100644 index 000000000..97e8efc3c --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_responder_sequence.svh @@ -0,0 +1,122 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class can be used to provide stimulus when an interface +// has been configured to run in a responder mode. It +// will never finish by default, always going back to the driver +// and driver BFM for the next transaction with which to respond. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_responder_sequence + extends mbox_sram_sequence_base ; + + `uvm_object_utils( mbox_sram_responder_sequence ) + + // pragma uvmf custom class_item_additional begin + // Implement a model of the Mailbox SRAM + localparam NUM_BYTES = MBOX_DATA_AND_ECC_W/8 + ((MBOX_DATA_AND_ECC_W % 8) ? 1 : 0); + // TODO support initialization from mailbox.hex + logic [7:0] ram [MBOX_DEPTH][NUM_BYTES-1:0] = '{default: 8'h00}; + + function bit [1:0] rvecc_decode ( input [31:0] din, input [6:0] ecc_in); + bit [6:0] ecc_check; + + // Generate the ecc bits + ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]; + ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]; + ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]; + ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]; + ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31]; + + // This is the parity bit + ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])); + + rvecc_decode[0] = (ecc_check[6:0] != 0) & ecc_check[6]; // Single-bit error + rvecc_decode[1] = (ecc_check[6:0] != 0) & ~ecc_check[6]; // Double-bit error + + endfunction: rvecc_decode + // pragma uvmf custom class_item_additional end + + function new(string name = "mbox_sram_responder_sequence"); + super.new(name); + endfunction + + task body(); + req=mbox_sram_transaction::type_id::create("req"); + forever begin + start_item(req); + finish_item(req); + // pragma uvmf custom body begin + // Do something here with the resulting req item. The + // finish_item() call above will block until the req transaction is ready + // to be handled by the responder sequence. + // If this was an item that required a response, the expectation is + // that the response should be populated within this transaction now. + wait(new_rsp.triggered); + if (req.compare(rsp)) `uvm_info("MBOX_SRAM_SEQ", "req and rsp are the same after finish_item", UVM_DEBUG) + else `uvm_error("MBOX_SRAM_SEQ", $sformatf("NOTE: req and rsp are different after finish_item.\nreq: %s\nrsp: %s", req.convert2string(), rsp.convert2string())) + // The 'rsp' is actually a request from the DUT, we need to create a response + if (rsp.is_read) begin + byte unsigned ii; + for (ii=0;iinew_rsp; + // Display the received response transaction + `uvm_info("SEQ", {"New response transaction:",rsp.convert2string()}, UVM_MEDIUM) + end + join_none + endtask + + // **************************************************************************** + // TASK : pre_body() + // This task is called automatically when start is called with call_pre_post set to 1 (default). + // By calling get_responses() within pre_body() any derived sequences are automatically + // processing response transactions. Only un-comment this call to get_responses() if you + // have configured the interface driver to utilize the response transaction path by setting + // the configuration variable "return_transaction_response" to 1. Otherwise it is possible + // to impact runtime performance and memory utilization. + // + virtual task pre_body(); + // pragma uvmf custom pre_body begin + get_responses(); + // pragma uvmf custom pre_body end + endtask + + // **************************************************************************** + // TASK : body() + // This task is called automatically when start is called. This sequence sends + // a req sequence item to the sequencer identified as an argument in the call + // to start. + // + virtual task body(); + // pragma uvmf custom body begin + start_item(req); + finish_item(req); + // pragma uvmf custom body end + endtask + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name =""); + super.new( name ); + // pragma uvmf custom new begin + req = mbox_sram_transaction_req_t::type_id::create("req"); + rsp = mbox_sram_transaction_rsp_t::type_id::create("rsp"); + // pragma uvmf custom new end + endfunction + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction.svh new file mode 100644 index 000000000..dd3049af0 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction.svh @@ -0,0 +1,216 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class defines the variables required for an mbox_sram +// transaction. Class variables to be displayed in waveform transaction +// viewing are added to the transaction viewing stream in the add_to_wave +// function. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +class mbox_sram_transaction extends uvmf_transaction_base; + + `uvm_object_utils( mbox_sram_transaction ) + + rand bit is_read ; + rand bit [MBOX_ADDR_W-1:0] address ; + rand bit [MBOX_DATA_W-1:0] data ; + bit [MBOX_ECC_DATA_W-1:0] data_ecc ; + rand bit ecc_single_bit_error ; + rand bit ecc_double_bit_error ; + + //Constraints for the transaction variables: + + // pragma uvmf custom class_item_additional begin + // pragma uvmf custom class_item_additional end + + //******************************************************************* + //******************************************************************* + // Macros that define structs and associated functions are + // located in mbox_sram_macros.svh + + //******************************************************************* + // Monitor macro used by mbox_sram_monitor and mbox_sram_monitor_bfm + // This struct is defined in mbox_sram_macros.svh + `mbox_sram_MONITOR_STRUCT + mbox_sram_monitor_s mbox_sram_monitor_struct; + //******************************************************************* + // FUNCTION: to_monitor_struct() + // This function packs transaction variables into a mbox_sram_monitor_s + // structure. The function returns the handle to the mbox_sram_monitor_struct. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_TO_MONITOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_monitor_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_FROM_MONITOR_STRUCT_FUNCTION + + //******************************************************************* + // Initiator macro used by mbox_sram_driver and mbox_sram_driver_bfm + // to communicate initiator driven data to mbox_sram_driver_bfm. + // This struct is defined in mbox_sram_macros.svh + `mbox_sram_INITIATOR_STRUCT + mbox_sram_initiator_s mbox_sram_initiator_struct; + //******************************************************************* + // FUNCTION: to_initiator_struct() + // This function packs transaction variables into a mbox_sram_initiator_s + // structure. The function returns the handle to the mbox_sram_initiator_struct. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_TO_INITIATOR_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_initiator_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_FROM_INITIATOR_STRUCT_FUNCTION + + //******************************************************************* + // Responder macro used by mbox_sram_driver and mbox_sram_driver_bfm + // to communicate Responder driven data to mbox_sram_driver_bfm. + // This struct is defined in mbox_sram_macros.svh + `mbox_sram_RESPONDER_STRUCT + mbox_sram_responder_s mbox_sram_responder_struct; + //******************************************************************* + // FUNCTION: to_responder_struct() + // This function packs transaction variables into a mbox_sram_responder_s + // structure. The function returns the handle to the mbox_sram_responder_struct. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_TO_RESPONDER_STRUCT_FUNCTION + //******************************************************************* + // FUNCTION: from_responder_struct() + // This function unpacks the struct provided as an argument into transaction + // variables of this class. + // This function is defined in mbox_sram_macros.svh + `mbox_sram_FROM_RESPONDER_STRUCT_FUNCTION + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new( string name = "" ); + super.new( name ); + endfunction + + // **************************************************************************** + // FUNCTION: convert2string() + // This function converts all variables in this class to a single string for + // logfile reporting. + // + virtual function string convert2string(); + // pragma uvmf custom convert2string begin + // UVMF_CHANGE_ME : Customize format if desired. + return $sformatf("is_read:0x%x address:0x%x data:0x%x data_ecc:0x%x ecc_single_bit_error:0x%x ecc_double_bit_error:0x%x ",is_read,address,data,data_ecc,ecc_single_bit_error,ecc_double_bit_error); + // pragma uvmf custom convert2string end + endfunction + + //******************************************************************* + // FUNCTION: do_print() + // This function is automatically called when the .print() function + // is called on this class. + // + virtual function void do_print(uvm_printer printer); + // pragma uvmf custom do_print begin + // UVMF_CHANGE_ME : Current contents of do_print allows for the use of UVM 1.1d, 1.2 or P1800.2. + // Update based on your own printing preference according to your preferred UVM version + $display(convert2string()); + // pragma uvmf custom do_print end + endfunction + + //******************************************************************* + // FUNCTION: do_compare() + // This function is automatically called when the .compare() function + // is called on this class. + // + virtual function bit do_compare (uvm_object rhs, uvm_comparer comparer); + mbox_sram_transaction RHS; + if (!$cast(RHS,rhs)) return 0; + // pragma uvmf custom do_compare begin + // UVMF_CHANGE_ME : Eliminate comparison of variables not to be used for compare + return (super.do_compare(rhs,comparer) + &&(this.is_read == RHS.is_read) + &&(this.address == RHS.address) + &&(this.data == RHS.data) + &&(this.data_ecc == RHS.data_ecc) + &&(this.ecc_single_bit_error == RHS.ecc_single_bit_error) + &&(this.ecc_double_bit_error == RHS.ecc_double_bit_error) + ); + // pragma uvmf custom do_compare end + endfunction + + //******************************************************************* + // FUNCTION: do_copy() + // This function is automatically called when the .copy() function + // is called on this class. + // + virtual function void do_copy (uvm_object rhs); + mbox_sram_transaction RHS; + assert($cast(RHS,rhs)); + // pragma uvmf custom do_copy begin + super.do_copy(rhs); + this.is_read = RHS.is_read; + this.address = RHS.address; + this.data = RHS.data; + this.data_ecc = RHS.data_ecc; + this.ecc_single_bit_error = RHS.ecc_single_bit_error; + this.ecc_double_bit_error = RHS.ecc_double_bit_error; + // pragma uvmf custom do_copy end + endfunction + + // **************************************************************************** + // FUNCTION: add_to_wave() + // This function is used to display variables in this class in the waveform + // viewer. The start_time and end_time variables must be set before this + // function is called. If the start_time and end_time variables are not set + // the transaction will be hidden at 0ns on the waveform display. + // + virtual function void add_to_wave(int transaction_viewing_stream_h); + `ifdef QUESTA + if (transaction_view_h == 0) begin + transaction_view_h = $begin_transaction(transaction_viewing_stream_h,"mbox_sram_transaction",start_time); + end + super.add_to_wave(transaction_view_h); + // pragma uvmf custom add_to_wave begin + // UVMF_CHANGE_ME : Color can be applied to transaction entries based on content, example below + // case() + // 1 : $add_color(transaction_view_h,"red"); + // default : $add_color(transaction_view_h,"grey"); + // endcase + // UVMF_CHANGE_ME : Eliminate transaction variables not wanted in transaction viewing in the waveform viewer + $add_attribute(transaction_view_h,is_read,"is_read"); + $add_attribute(transaction_view_h,address,"address"); + $add_attribute(transaction_view_h,data,"data"); + $add_attribute(transaction_view_h,data_ecc,"data_ecc"); + $add_attribute(transaction_view_h,ecc_single_bit_error,"ecc_single_bit_error"); + $add_attribute(transaction_view_h,ecc_double_bit_error,"ecc_double_bit_error"); + // pragma uvmf custom add_to_wave end + $end_transaction(transaction_view_h,end_time); + $free_transaction(transaction_view_h); + `endif // QUESTA + endfunction + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction_coverage.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction_coverage.svh new file mode 100644 index 000000000..9c935c889 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_transaction_coverage.svh @@ -0,0 +1,107 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: This class records mbox_sram transaction information using +// a covergroup named mbox_sram_transaction_cg. An instance of this +// coverage component is instantiated in the uvmf_parameterized_agent +// if the has_coverage flag is set. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +covergroup mbox_sram_transaction_bit_cg with function sample(input bit val); + option.per_instance = 1; + ea_bit: coverpoint val; +endgroup + +class mbox_sram_transaction_coverage extends uvm_subscriber #(.T(mbox_sram_transaction )); + + `uvm_component_utils( mbox_sram_transaction_coverage ) + + T coverage_trans; + + // pragma uvmf custom class_item_additional begin + mbox_sram_transaction_bit_cg address_bit_cg[MBOX_ADDR_W]; + mbox_sram_transaction_bit_cg data_bit_cg[MBOX_DATA_W]; + mbox_sram_transaction_bit_cg data_ecc_bit_cg[MBOX_ECC_DATA_W]; + // pragma uvmf custom class_item_additional end + + // **************************************************************************** + covergroup mbox_sram_transaction_cg; + // pragma uvmf custom covergroup begin + // UVMF_CHANGE_ME : Add coverage bins, crosses, exclusions, etc. according to coverage needs. + option.auto_bin_max=1024; + option.per_instance=1; + is_read: coverpoint coverage_trans.is_read; + address: coverpoint coverage_trans.address; + data: coverpoint coverage_trans.data; + data_ecc: coverpoint coverage_trans.data_ecc; + ecc_single_bit_error: coverpoint coverage_trans.ecc_single_bit_error; + ecc_double_bit_error: coverpoint coverage_trans.ecc_double_bit_error; + // TODO add checks for ecc single/double errors, address='0, address='1, address alignment cases + // TODO add cross for read transaction, write transaction + // pragma uvmf custom covergroup end + endgroup + + // **************************************************************************** + // FUNCTION : new() + // This function is the standard SystemVerilog constructor. + // + function new(string name="", uvm_component parent=null); + super.new(name,parent); + mbox_sram_transaction_cg=new; + foreach (coverage_trans.address[bt]) address_bit_cg[bt] = new; + foreach (coverage_trans.data[bt]) data_bit_cg[bt] = new; + foreach (coverage_trans.data_ecc[bt]) data_ecc_bit_cg[bt] = new; + endfunction + + // **************************************************************************** + // FUNCTION : build_phase() + // This function is the standard UVM build_phase. + // + function void build_phase(uvm_phase phase); + mbox_sram_transaction_cg.set_inst_name($sformatf("mbox_sram_transaction_cg_%s",get_full_name())); + foreach (coverage_trans.address[bt]) address_bit_cg[bt].set_inst_name($sformatf("address_bit_cg_%d_%s", bt, get_full_name())); + foreach (coverage_trans.data[bt]) data_bit_cg[bt].set_inst_name($sformatf("data_bit_cg_%d_%s", bt, get_full_name())); + foreach (coverage_trans.data_ecc[bt]) data_ecc_bit_cg[bt].set_inst_name($sformatf("data_ecc_bit_cg_%d_%s", bt, get_full_name())); + endfunction + + // **************************************************************************** + // FUNCTION: write (T t) + // This function is automatically executed when a transaction arrives on the + // analysis_export. It copies values from the variables in the transaction + // to local variables used to collect functional coverage. + // + virtual function void write (T t); + `uvm_info("COV","Received transaction",UVM_HIGH); + coverage_trans = t; + mbox_sram_transaction_cg.sample(); + foreach (coverage_trans.address [bt]) address_bit_cg [bt].sample(coverage_trans.address [bt]); + foreach (coverage_trans.data [bt]) data_bit_cg [bt].sample(coverage_trans.data [bt]); + foreach (coverage_trans.data_ecc[bt]) data_ecc_bit_cg[bt].sample(coverage_trans.data_ecc[bt]); + endfunction + +endclass + +// pragma uvmf custom external begin +// pragma uvmf custom external end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs.svh new file mode 100644 index 000000000..f2a7bdb94 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs.svh @@ -0,0 +1,34 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the host server when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs_hdl.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs_hdl.svh new file mode 100644 index 000000000..0d58518e2 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/src/mbox_sram_typedefs_hdl.svh @@ -0,0 +1,35 @@ +//---------------------------------------------------------------------- +// Created with uvmf_gen version 2022.3 +//---------------------------------------------------------------------- +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// 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. + +// pragma uvmf custom header begin +// pragma uvmf custom header end +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// +// DESCRIPTION: +// This file contains defines and typedefs to be compiled for use in +// the simulation running on the emulator when using Veloce. +// +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// + + + +// pragma uvmf custom additional begin +// pragma uvmf custom additional end + diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/yaml/mbox_sram_interface.yaml b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/yaml/mbox_sram_interface.yaml new file mode 100644 index 000000000..903678275 --- /dev/null +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/mbox_sram_pkg/yaml/mbox_sram_interface.yaml @@ -0,0 +1,73 @@ +uvmf: + interfaces: + mbox_sram: + clock: clk + config_constraints: [] + config_vars: + - comment: 'Controls injection of ECC errors for write transactions. Bit[0]: Single Bit Error. Bit[1]: Double Bit Error' + isrand: 'False' + name: inject_ecc_error + type: bit [1:0] + value: 1'b0 + - comment: When set, causes the mbox_sram_responder_sequence to clear the variable 'inject_ecc_error' after a single ECC error is injected + isrand: 'False' + name: auto_clear_ecc_error_injection + type: bit + value: 1'b1 + existing_library_component: 'True' + gen_inbound_streaming_driver: 'False' + hdl_pkg_parameters: [] + hdl_typedefs: [] + hvl_pkg_parameters: [] + hvl_typedefs: [] + parameters: [] + ports: + - dir: output + name: mbox_sram_req + reset_value: '''bz' + width: $bits(mbox_sram_req_t) + - dir: input + name: mbox_sram_resp + reset_value: '''bz' + width: $bits(mbox_sram_resp_t) + reset: dummy + reset_assertion_level: 'False' + transaction_constraints: [] + transaction_vars: + - comment: '' + iscompare: 'True' + isrand: 'True' + name: is_read + type: bit + unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'True' + name: address + type: bit [MBOX_ADDR_W-1:0] + unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'True' + name: data + type: bit [MBOX_DATA_W-1:0] + unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'False' + name: data_ecc + type: bit [MBOX_ECC_DATA_W-1:0] + unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'True' + name: ecc_single_bit_error + type: bit + unpacked_dimension: '' + - comment: '' + iscompare: 'True' + isrand: 'True' + name: ecc_double_bit_error + type: bit + unpacked_dimension: '' + use_dpi_link: 'False' diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_reset_sequence_base.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_reset_sequence_base.svh index 671e2018f..715992a1a 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_reset_sequence_base.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_reset_sequence_base.svh @@ -37,6 +37,7 @@ class soc_ifc_ctrl_reset_sequence_base // pragma uvmf custom class_item_additional begin bit warm_reset_only = 1'b0; bit set_bootfsm_breakpoint; + security_state_t security_state; bit [7:0] [31:0] cptra_obf_key ; // pragma uvmf custom class_item_additional end @@ -106,6 +107,7 @@ class soc_ifc_ctrl_reset_sequence_base req.wait_cycles = 0; // Send the transaction to the soc_ifc_ctrl_driver_bfm via the sequencer and soc_ifc_ctrl_driver. finish_item(req); + this.security_state = req.security_state; `uvm_info("SOC_IFC_CTRL_RST", {"Response:",req.convert2string()},UVM_MEDIUM) endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_rom_poweron_sequence.svh b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_rom_poweron_sequence.svh index 215317411..841c92a7b 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_rom_poweron_sequence.svh +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_ctrl_pkg/src/soc_ifc_ctrl_rom_poweron_sequence.svh @@ -48,7 +48,7 @@ class soc_ifc_ctrl_rom_poweron_sequence req=soc_ifc_ctrl_transaction::type_id::create("pwr_req"); start_item(req); // Randomize the transaction (must be DEVICE_UNPROVISIONED for ROM bringup) - if(!req.randomize() with {security_state.device_lifecycle == DEVICE_UNPROVISIONED;}) + if(!req.randomize() with {security_state.device_lifecycle != DEVICE_UNPROVISIONED;}) `uvm_fatal("SOC_IFC_CTRL_RST", "soc_ifc_ctrl_reset_sequence_base::body()-soc_ifc_ctrl_transaction randomization failed") req.set_pwrgood = 1'b0; req.assert_rst = 1'b1; // active-low assertion diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv index 308e98511..54133ce34 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_driver_bfm.sv @@ -370,12 +370,12 @@ bit first_transfer=1; // end // Wait for next transfer then gather info from intiator about the transfer. // Place the data into the soc_ifc_status_initiator_struct. - do begin + @(posedge clk_i); + while (!any_signal_changed()) begin cptra_error_fatal_o <= cptra_error_fatal_i ; cptra_error_non_fatal_o <= cptra_error_non_fatal_i; @(posedge clk_i); end - while (!any_signal_changed()); ready_for_fuses_o <= ready_for_fuses_i ; ready_for_fw_push_o <= ready_for_fw_push_i ; ready_for_runtime_o <= ready_for_runtime_i ; @@ -394,9 +394,9 @@ bit first_transfer=1; soc_ifc_status_initiator_struct.ready_for_runtime = ready_for_runtime_i; soc_ifc_status_initiator_struct.mailbox_data_avail = mailbox_data_avail_i; soc_ifc_status_initiator_struct.mailbox_flow_done = mailbox_flow_done_i; - soc_ifc_status_responder_struct.cptra_error_fatal_intr_pending = cptra_error_fatal_i; // - soc_ifc_status_responder_struct.cptra_error_non_fatal_intr_pending = cptra_error_non_fatal_i; // - soc_ifc_status_responder_struct.trng_req_pending = trng_req_i; // + soc_ifc_status_initiator_struct.cptra_error_fatal_intr_pending = cptra_error_fatal_i; + soc_ifc_status_initiator_struct.cptra_error_non_fatal_intr_pending = cptra_error_non_fatal_i; + soc_ifc_status_initiator_struct.trng_req_pending = trng_req_i; soc_ifc_status_initiator_struct.generic_output_val = generic_output_wires_i; end endtask diff --git a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv index ff71b0e9b..f4ed4b30a 100644 --- a/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv +++ b/src/soc_ifc/uvmf_soc_ifc/uvmf_template_output/verification_ip/interface_packages/soc_ifc_status_pkg/src/soc_ifc_status_monitor_bfm.sv @@ -258,6 +258,7 @@ end soc_ifc_status_monitor_struct.trng_req_pending = trng_req_i; soc_ifc_status_monitor_struct.generic_output_val = generic_output_wires_i; end + // pragma uvmf custom do_monitor end endtask diff --git a/src/spi_host/config/spi_host.vf b/src/spi_host/config/spi_host.vf index 812e54c18..1b0661420 100644 --- a/src/spi_host/config/spi_host.vf +++ b/src/spi_host/config/spi_host.vf @@ -15,6 +15,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/spi_host/config/spi_host_tb.vf b/src/spi_host/config/spi_host_tb.vf index 94e621e4b..687e76aca 100644 --- a/src/spi_host/config/spi_host_tb.vf +++ b/src/spi_host/config/spi_host_tb.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/spi_host/config/spiflash.vf b/src/spi_host/config/spiflash.vf index 4789cfae0..6821ad3d0 100644 --- a/src/spi_host/config/spiflash.vf +++ b/src/spi_host/config/spiflash.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/uart/config/uart.vf b/src/uart/config/uart.vf index 92778e365..469205a79 100644 --- a/src/uart/config/uart.vf +++ b/src/uart/config/uart.vf @@ -15,6 +15,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv diff --git a/src/uart/config/uart_tb.vf b/src/uart/config/uart_tb.vf index 788eafb97..4332da0e6 100644 --- a/src/uart/config/uart_tb.vf +++ b/src/uart/config/uart_tb.vf @@ -16,6 +16,7 @@ ${CALIPTRA_ROOT}/src/libs/rtl/apb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv ${CALIPTRA_ROOT}/src/libs/rtl/caliptra_icg.sv ${CALIPTRA_ROOT}/src/libs/rtl/clk_gate.sv +${CALIPTRA_ROOT}/src/libs/rtl/caliptra_2ff_sync.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_util_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_alert_pkg.sv ${CALIPTRA_ROOT}/src/caliptra_prim/rtl/caliptra_prim_subreg_pkg.sv