From b95708412ac1bdb67240edf1e7241cd81c441f4d Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 13:30:30 +0100 Subject: [PATCH 1/8] [dv,clk_mgr] vendor clk_mgr DV environment and update paths --- .../clkmgr/data/clkmgr_testplan.hjson | 14 ++--- .../ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson | 16 ++--- hw/vendor/lowrisc_ip.vendor.hjson | 2 +- .../clkmgr/data/clkmgr_testplan.hjson.tpl | 14 ++--- .../clkmgr/dv/clkmgr_sim_cfg.hjson.tpl | 16 ++--- .../lowrisc_ip/clkmgr/0001_Fix_DV_Paths.patch | 61 +++++++++++++++++++ 6 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 hw/vendor/patches/lowrisc_ip/clkmgr/0001_Fix_DV_Paths.patch diff --git a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson index 5debb3a72..7809c7845 100644 --- a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson @@ -3,14 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 { name: "clkmgr" - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", + import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", "clkmgr_sec_cm_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] testpoints: [ { name: smoke diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson b/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson index 88395d721..7d80f55c4 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson @@ -12,7 +12,7 @@ tb: tb // Simulator used to sign off this block - tool: vcs + tool: xcelium // Fusesoc core file used for building the file list. fusesoc_core: lowrisc:mocha_dv:clkmgr_sim:0.1 @@ -25,14 +25,14 @@ // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" ] // Add additional tops for simulation. diff --git a/hw/vendor/lowrisc_ip.vendor.hjson b/hw/vendor/lowrisc_ip.vendor.hjson index 17483f5fc..e64bb6f99 100644 --- a/hw/vendor/lowrisc_ip.vendor.hjson +++ b/hw/vendor/lowrisc_ip.vendor.hjson @@ -42,7 +42,7 @@ // Hardware IP templates. {from: "hw/ip_templates/alert_handler", to: "ip_templates/alert_handler"}, // Dependency of reset manager. - {from: "hw/ip_templates/clkmgr", to: "ip_templates/clkmgr"}, + {from: "hw/ip_templates/clkmgr", to: "ip_templates/clkmgr", patch_dir: "clkmgr"}, {from: "hw/ip_templates/gpio", to: "ip_templates/gpio", patch_dir: "gpio"}, // General purpose I/O {from: "hw/ip_templates/pwrmgr", to: "ip_templates/pwrmgr", patch_dir: "pwrmgr"}, {from: "hw/ip_templates/rstmgr", to: "ip_templates/rstmgr", patch_dir: "rstmgr"}, diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl index 42a26b6ca..61293f6ba 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl @@ -3,14 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 { name: "clkmgr" - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", + import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", "clkmgr_sec_cm_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] testpoints: [ { name: smoke diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl index 7a869dc33..746d9b7d4 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl @@ -12,7 +12,7 @@ tb: tb // Simulator used to sign off this block - tool: vcs + tool: xcelium // Fusesoc core file used for building the file list. fusesoc_core: ${instance_vlnv("lowrisc:dv:clkmgr_sim:0.1")} @@ -25,14 +25,14 @@ // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" ] // Add additional tops for simulation. diff --git a/hw/vendor/patches/lowrisc_ip/clkmgr/0001_Fix_DV_Paths.patch b/hw/vendor/patches/lowrisc_ip/clkmgr/0001_Fix_DV_Paths.patch new file mode 100644 index 000000000..0d485213f --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/clkmgr/0001_Fix_DV_Paths.patch @@ -0,0 +1,61 @@ +diff --git a/data/clkmgr_testplan.hjson.tpl b/data/clkmgr_testplan.hjson.tpl +index 42a26b6c..61293f6b 100644 +--- a/data/clkmgr_testplan.hjson.tpl ++++ b/data/clkmgr_testplan.hjson.tpl +@@ -3,14 +3,14 @@ + // SPDX-License-Identifier: Apache-2.0 + { + name: "clkmgr" +- import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", ++ import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", + "clkmgr_sec_cm_testplan.hjson", +- "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] ++ "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] + testpoints: [ + { + name: smoke +diff --git a/dv/clkmgr_sim_cfg.hjson.tpl b/dv/clkmgr_sim_cfg.hjson.tpl +index 7a869dc3..746d9b7d 100644 +--- a/dv/clkmgr_sim_cfg.hjson.tpl ++++ b/dv/clkmgr_sim_cfg.hjson.tpl +@@ -12,7 +12,7 @@ + tb: tb + + // Simulator used to sign off this block +- tool: vcs ++ tool: xcelium + + // Fusesoc core file used for building the file list. + fusesoc_core: ${instance_vlnv("lowrisc:dv:clkmgr_sim:0.1")} +@@ -25,14 +25,14 @@ + + // Import additional common sim cfg files. + import_cfgs: [// Project wide common sim cfg file +- "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/common_sim_cfg.hjson", + // Common CIP test lists +- "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", +- "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/csr_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/tl_access_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/stress_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/sec_cm_tests.hjson", ++ "{proj_root}/hw/vendor/lowrisc_ip/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson" + ] + + // Add additional tops for simulation. From de91e04c686a9d13d68231a79aa70af23bf100f5 Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 13:34:00 +0100 Subject: [PATCH 2/8] [dv,clk_mgr] generate hint clock names from config The DV templates hardcode earlgrey's four hint clocks (aes, hmac, kmac, otbn) and build signal names from them. Mocha has one hint clock, clk_main_hint, so the generated environment referred to signals that don't exist and wouldn't compile. --- .../ip_autogen/clkmgr/dv/env/clkmgr_if.sv | 4 +- .../dv/env/seq_lib/clkmgr_smoke_vseq.sv | 5 +- .../ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv | 4 +- hw/top_chip/ip_autogen/clkmgr/dv/tb.sv | 5 +- .../clkmgr/dv/env/clkmgr_if.sv.tpl | 16 ++- .../dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl | 8 +- .../clkmgr/dv/sva/clkmgr_bind.sv.tpl | 8 ++ .../ip_templates/clkmgr/dv/tb.sv.tpl | 12 ++- .../clkmgr/0002_Generalize_Hint_Clocks.patch | 100 ++++++++++++++++++ 9 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 hw/vendor/patches/lowrisc_ip/clkmgr/0002_Generalize_Hint_Clocks.patch diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/env/clkmgr_if.sv b/hw/top_chip/ip_autogen/clkmgr/dv/env/clkmgr_if.sv index 2ad83c548..971ee3bd3 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/env/clkmgr_if.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/env/clkmgr_if.sv @@ -52,13 +52,13 @@ interface clkmgr_if ( clk_hints_t clk_hints_csr; always_comb clk_hints_csr = '{ - none: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_none_hint.q + none: `CLKMGR_HIER.reg2hw.clk_hints.q }; clk_hints_t clk_hints_status_csr; always_comb clk_hints_status_csr = '{ - none: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_none_val_qs + none: `CLKMGR_HIER.u_reg.clk_hints_status_qs }; prim_mubi_pkg::mubi4_t jitter_enable_csr; always_comb begin diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv index 32a3dc315..ac16c42f0 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv @@ -67,10 +67,7 @@ class clkmgr_smoke_vseq extends clkmgr_base_vseq; uvm_reg_field value_bit; } trans_descriptor_t; trans_descriptor_t trans_descriptors[NUM_TRANS] = '{ - '{TransAes, ral.clk_hints.clk_main_aes_hint, ral.clk_hints_status.clk_main_aes_val}, - '{TransHmac, ral.clk_hints.clk_main_hmac_hint, ral.clk_hints_status.clk_main_hmac_val}, - '{TransKmac, ral.clk_hints.clk_main_kmac_hint, ral.clk_hints_status.clk_main_kmac_val}, - '{TransOtbn, ral.clk_hints.clk_main_otbn_hint, ral.clk_hints_status.clk_main_otbn_val} + '{TransNone, ral.clk_hints.clk_main_hint_hint, ral.clk_hints_status.clk_main_hint_val} }; idle = 0; // Changes in idle take at least 10 cycles to stick. diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv b/hw/top_chip/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv index 5a098e45e..7c736abf8 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv @@ -40,10 +40,10 @@ module clkmgr_bind; bind clkmgr clkmgr_trans_sva_if clkmgr_none_trans_sva_if ( .clk(clk_main_i), .rst_n(rst_main_ni), - .hint(reg2hw.clk_hints.clk_main_hint_hint.q), + .hint(reg2hw.clk_hints.q), .idle(idle_i[HintMainHint] == prim_mubi_pkg::MuBi4True), .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), - .status(hw2reg.clk_hints_status.clk_main_hint_val.d), + .status(hw2reg.clk_hints_status.d), .trans_clk(clocks_o.clk_main_hint) ); diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/tb.sv b/hw/top_chip/ip_autogen/clkmgr/dv/tb.sv index 60d58bc41..30d97bc45 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/tb.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/tb.sv @@ -77,10 +77,7 @@ module tb; .clk_enables({ reg2hw.clk_enables.q}), .clk_hints({ - reg2hw.clk_hints.clk_main_otbn_hint.q, - reg2hw.clk_hints.clk_main_kmac_hint.q, - reg2hw.clk_hints.clk_main_hmac_hint.q, - reg2hw.clk_hints.clk_main_aes_hint.q}) + reg2hw.clk_hints.q}) ); rst_shadowed_if rst_shadowed_if ( diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/clkmgr_if.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/clkmgr_if.sv.tpl index e6c751f24..dbdc84061 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/clkmgr_if.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/clkmgr_if.sv.tpl @@ -85,18 +85,26 @@ interface clkmgr_if ( clk_hints_t clk_hints_csr; always_comb clk_hints_csr = '{ -% for target in list(reversed(hint_targets)): +% for clk, sig in list(reversed(list(typed_clocks['hint_clks'].items()))): <% sep = '' if loop.last else ',' %>\ - ${target}: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_${target}_hint.q${sep} + % if len(typed_clocks['hint_clks']) == 1: + ${sig['endpoint_ip']}: `CLKMGR_HIER.reg2hw.clk_hints.q${sep} + % else: + ${sig['endpoint_ip']}: `CLKMGR_HIER.reg2hw.clk_hints.${clk}_hint.q${sep} + % endif % endfor }; clk_hints_t clk_hints_status_csr; always_comb clk_hints_status_csr = '{ -% for target in list(reversed(hint_targets)): +% for clk, sig in list(reversed(list(typed_clocks['hint_clks'].items()))): <% sep = '' if loop.last else ',' %>\ - ${target}: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_${target}_val_qs${sep} + % if len(typed_clocks['hint_clks']) == 1: + ${sig['endpoint_ip']}: `CLKMGR_HIER.u_reg.clk_hints_status_qs${sep} + % else: + ${sig['endpoint_ip']}: `CLKMGR_HIER.u_reg.clk_hints_status_${clk}_val_qs${sep} + % endif % endfor }; % if ext_clk_bypass: diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl index 567295e56..a851d99da 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl @@ -70,10 +70,10 @@ class clkmgr_smoke_vseq extends clkmgr_base_vseq; uvm_reg_field value_bit; } trans_descriptor_t; trans_descriptor_t trans_descriptors[NUM_TRANS] = '{ - '{TransAes, ral.clk_hints.clk_main_aes_hint, ral.clk_hints_status.clk_main_aes_val}, - '{TransHmac, ral.clk_hints.clk_main_hmac_hint, ral.clk_hints_status.clk_main_hmac_val}, - '{TransKmac, ral.clk_hints.clk_main_kmac_hint, ral.clk_hints_status.clk_main_kmac_val}, - '{TransOtbn, ral.clk_hints.clk_main_otbn_hint, ral.clk_hints_status.clk_main_otbn_val} +% for clk, sig in typed_clocks['hint_clks'].items(): +<% sep = '' if loop.last else ',' %>\ + '{Trans${sig['endpoint_ip'].capitalize()}, ral.clk_hints.${clk}_hint, ral.clk_hints_status.${clk}_val}${sep} +% endfor }; idle = 0; // Changes in idle take at least 10 cycles to stick. diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/sva/clkmgr_bind.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/sva/clkmgr_bind.sv.tpl index 7eb396fd1..0ced01285 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/sva/clkmgr_bind.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/sva/clkmgr_bind.sv.tpl @@ -48,10 +48,18 @@ module clkmgr_bind; bind clkmgr clkmgr_trans_sva_if clkmgr_${sig['endpoint_ip']}_trans_sva_if ( .clk(clk_${sig['src_name']}_i), .rst_n(rst_${sig['src_name']}_ni), +% if len(typed_clocks['hint_clks']) == 1: + .hint(reg2hw.clk_hints.q), +% else: .hint(reg2hw.clk_hints.${clk}_hint.q), +% endif .idle(idle_i[${hint_names[clk]}] == prim_mubi_pkg::MuBi4True), .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), +% if len(typed_clocks['hint_clks']) == 1: + .status(hw2reg.clk_hints_status.d), +% else: .status(hw2reg.clk_hints_status.${clk}_val.d), +% endif .trans_clk(clocks_o.${clk}) ); diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/tb.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/tb.sv.tpl index 5a2e8ef9a..8fb888352 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/tb.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/tb.sv.tpl @@ -90,10 +90,14 @@ module tb; % endif % endfor .clk_hints({ - reg2hw.clk_hints.clk_main_otbn_hint.q, - reg2hw.clk_hints.clk_main_kmac_hint.q, - reg2hw.clk_hints.clk_main_hmac_hint.q, - reg2hw.clk_hints.clk_main_aes_hint.q}) +% for clk in list(reversed(list(typed_clocks['hint_clks'].keys()))): +<% sep = "})" if loop.last else "," %>\ + % if len(typed_clocks['hint_clks']) == 1: + reg2hw.clk_hints.q${sep} + % else: + reg2hw.clk_hints.${clk}_hint.q${sep} + % endif +% endfor ); rst_shadowed_if rst_shadowed_if ( diff --git a/hw/vendor/patches/lowrisc_ip/clkmgr/0002_Generalize_Hint_Clocks.patch b/hw/vendor/patches/lowrisc_ip/clkmgr/0002_Generalize_Hint_Clocks.patch new file mode 100644 index 000000000..3a9c7e24f --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/clkmgr/0002_Generalize_Hint_Clocks.patch @@ -0,0 +1,100 @@ +diff --git a/dv/env/clkmgr_if.sv.tpl b/dv/env/clkmgr_if.sv.tpl +index e6c751f2..dbdc8406 100644 +--- a/dv/env/clkmgr_if.sv.tpl ++++ b/dv/env/clkmgr_if.sv.tpl +@@ -85,18 +85,26 @@ interface clkmgr_if ( + clk_hints_t clk_hints_csr; + always_comb + clk_hints_csr = '{ +-% for target in list(reversed(hint_targets)): ++% for clk, sig in list(reversed(list(typed_clocks['hint_clks'].items()))): + <% sep = '' if loop.last else ',' %>\ +- ${target}: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_${target}_hint.q${sep} ++ % if len(typed_clocks['hint_clks']) == 1: ++ ${sig['endpoint_ip']}: `CLKMGR_HIER.reg2hw.clk_hints.q${sep} ++ % else: ++ ${sig['endpoint_ip']}: `CLKMGR_HIER.reg2hw.clk_hints.${clk}_hint.q${sep} ++ % endif + % endfor + }; + + clk_hints_t clk_hints_status_csr; + always_comb + clk_hints_status_csr = '{ +-% for target in list(reversed(hint_targets)): ++% for clk, sig in list(reversed(list(typed_clocks['hint_clks'].items()))): + <% sep = '' if loop.last else ',' %>\ +- ${target}: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_${target}_val_qs${sep} ++ % if len(typed_clocks['hint_clks']) == 1: ++ ${sig['endpoint_ip']}: `CLKMGR_HIER.u_reg.clk_hints_status_qs${sep} ++ % else: ++ ${sig['endpoint_ip']}: `CLKMGR_HIER.u_reg.clk_hints_status_${clk}_val_qs${sep} ++ % endif + % endfor + }; + % if ext_clk_bypass: +diff --git a/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl b/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl +index 567295e5..a851d99d 100644 +--- a/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl ++++ b/dv/env/seq_lib/clkmgr_smoke_vseq.sv.tpl +@@ -70,10 +70,10 @@ class clkmgr_smoke_vseq extends clkmgr_base_vseq; + uvm_reg_field value_bit; + } trans_descriptor_t; + trans_descriptor_t trans_descriptors[NUM_TRANS] = '{ +- '{TransAes, ral.clk_hints.clk_main_aes_hint, ral.clk_hints_status.clk_main_aes_val}, +- '{TransHmac, ral.clk_hints.clk_main_hmac_hint, ral.clk_hints_status.clk_main_hmac_val}, +- '{TransKmac, ral.clk_hints.clk_main_kmac_hint, ral.clk_hints_status.clk_main_kmac_val}, +- '{TransOtbn, ral.clk_hints.clk_main_otbn_hint, ral.clk_hints_status.clk_main_otbn_val} ++% for clk, sig in typed_clocks['hint_clks'].items(): ++<% sep = '' if loop.last else ',' %>\ ++ '{Trans${sig['endpoint_ip'].capitalize()}, ral.clk_hints.${clk}_hint, ral.clk_hints_status.${clk}_val}${sep} ++% endfor + }; + idle = 0; + // Changes in idle take at least 10 cycles to stick. +diff --git a/dv/sva/clkmgr_bind.sv.tpl b/dv/sva/clkmgr_bind.sv.tpl +index 7eb396fd..0ced0128 100644 +--- a/dv/sva/clkmgr_bind.sv.tpl ++++ b/dv/sva/clkmgr_bind.sv.tpl +@@ -48,10 +48,18 @@ module clkmgr_bind; + bind clkmgr clkmgr_trans_sva_if clkmgr_${sig['endpoint_ip']}_trans_sva_if ( + .clk(clk_${sig['src_name']}_i), + .rst_n(rst_${sig['src_name']}_ni), ++% if len(typed_clocks['hint_clks']) == 1: ++ .hint(reg2hw.clk_hints.q), ++% else: + .hint(reg2hw.clk_hints.${clk}_hint.q), ++% endif + .idle(idle_i[${hint_names[clk]}] == prim_mubi_pkg::MuBi4True), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), ++% if len(typed_clocks['hint_clks']) == 1: ++ .status(hw2reg.clk_hints_status.d), ++% else: + .status(hw2reg.clk_hints_status.${clk}_val.d), ++% endif + .trans_clk(clocks_o.${clk}) + ); + +diff --git a/dv/tb.sv.tpl b/dv/tb.sv.tpl +index 5a2e8ef9..8fb88835 100644 +--- a/dv/tb.sv.tpl ++++ b/dv/tb.sv.tpl +@@ -90,10 +90,14 @@ module tb; + % endif + % endfor + .clk_hints({ +- reg2hw.clk_hints.clk_main_otbn_hint.q, +- reg2hw.clk_hints.clk_main_kmac_hint.q, +- reg2hw.clk_hints.clk_main_hmac_hint.q, +- reg2hw.clk_hints.clk_main_aes_hint.q}) ++% for clk in list(reversed(list(typed_clocks['hint_clks'].keys()))): ++<% sep = "})" if loop.last else "," %>\ ++ % if len(typed_clocks['hint_clks']) == 1: ++ reg2hw.clk_hints.q${sep} ++ % else: ++ reg2hw.clk_hints.${clk}_hint.q${sep} ++ % endif ++% endfor + ); + + rst_shadowed_if rst_shadowed_if ( From 9519ee97803b7638e14ead0a7d6c5d77129a67ba Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 13:38:03 +0100 Subject: [PATCH 3/8] [dv,clk_mgr] stop CSR tests from writing measure_ctrl_regwen Clock measurement is disabled in mocha, so the hardware holds its config lock open instead of letting software clear it. The randomized CSR tests write to the lock, read back a different value, and fail. Exclude it from the tests that write to it. --- hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson | 5 +++++ .../ip_templates/clkmgr/data/clkmgr.hjson.tpl | 7 +++++++ .../0003_Exclude_Measure_Ctrl_Regwen.patch | 17 +++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 hw/vendor/patches/lowrisc_ip/clkmgr/0003_Exclude_Measure_Ctrl_Regwen.patch diff --git a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson index d3a28c362..3c2fe2b11 100644 --- a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson @@ -319,6 +319,11 @@ ''' }, ] + // Clock measurement is intentionally disabled in this configuration: the source clocks are + // supplied from outside the top and are assumed already stable, so there is no calibration + // step. calib_rdy is therefore tied MuBi4False, and hardware holds this regwen at 1, making + // the rw0c behaviour unobservable and randomized CSR writes unpredictable. + tags: ["excl:CsrNonInitTests:CsrExclWrite"] }, { name: "IO_MEAS_CTRL_EN", desc: ''' diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr.hjson.tpl index f47d0210e..9d0670659 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr.hjson.tpl @@ -553,6 +553,13 @@ rg_srcs = get_rg_srcs(typed_clocks) ''' }, ] +% if not ext_clk_bypass: + // Clock measurement is intentionally disabled in this configuration: the source clocks are + // supplied from outside the top and are assumed already stable, so there is no calibration + // step. calib_rdy is therefore tied MuBi4False, and hardware holds this regwen at 1, making + // the rw0c behaviour unobservable and randomized CSR writes unpredictable. + tags: ["excl:CsrNonInitTests:CsrExclWrite"] +% endif }, % for src in rg_srcs: { name: "${src.upper()}_MEAS_CTRL_EN", diff --git a/hw/vendor/patches/lowrisc_ip/clkmgr/0003_Exclude_Measure_Ctrl_Regwen.patch b/hw/vendor/patches/lowrisc_ip/clkmgr/0003_Exclude_Measure_Ctrl_Regwen.patch new file mode 100644 index 000000000..d8fa4f11f --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/clkmgr/0003_Exclude_Measure_Ctrl_Regwen.patch @@ -0,0 +1,17 @@ +diff --git a/data/clkmgr.hjson.tpl b/data/clkmgr.hjson.tpl +--- a/data/clkmgr.hjson.tpl ++++ b/data/clkmgr.hjson.tpl +@@ -553,6 +553,13 @@ + ''' + }, + ] ++% if not ext_clk_bypass: ++ // Clock measurement is intentionally disabled in this configuration: the source clocks are ++ // supplied from outside the top and are assumed already stable, so there is no calibration ++ // step. calib_rdy is therefore tied MuBi4False, and hardware holds this regwen at 1, making ++ // the rw0c behaviour unobservable and randomized CSR writes unpredictable. ++ tags: ["excl:CsrNonInitTests:CsrExclWrite"] ++% endif + }, + % for src in rg_srcs: + { name: "${src.upper()}_MEAS_CTRL_EN", From 607cb066e0fd3e68d5720ae7dae6828a546575b1 Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 13:41:55 +0100 Subject: [PATCH 4/8] [dv,clk_mgr] drop the interrupt testplan import clk_mgr has no interrupts, but the testplan still imported the shared interrupt testplan. That added an interrupt test to the V2 regression that doesn't exist, so every dvsim run logged an error about it and the report carried testpoints that could never be covered. --- .../ip_autogen/clkmgr/data/clkmgr_testplan.hjson | 2 +- .../clkmgr/data/clkmgr_testplan.hjson.tpl | 2 +- .../clkmgr/0004_Drop_Intr_Test_Testplan.patch | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 hw/vendor/patches/lowrisc_ip/clkmgr/0004_Drop_Intr_Test_Testplan.patch diff --git a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson index 7809c7845..3c9874c10 100644 --- a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 { name: "clkmgr" + // clkmgr has no interrupts, so intr_test_testplan.hjson is deliberately not imported. import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl index 61293f6ba..408bf4046 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 { name: "clkmgr" + // clkmgr has no interrupts, so intr_test_testplan.hjson is deliberately not imported. import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", diff --git a/hw/vendor/patches/lowrisc_ip/clkmgr/0004_Drop_Intr_Test_Testplan.patch b/hw/vendor/patches/lowrisc_ip/clkmgr/0004_Drop_Intr_Test_Testplan.patch new file mode 100644 index 000000000..f49e0b7f3 --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/clkmgr/0004_Drop_Intr_Test_Testplan.patch @@ -0,0 +1,13 @@ +diff --git a/data/clkmgr_testplan.hjson.tpl b/data/clkmgr_testplan.hjson.tpl +--- a/data/clkmgr_testplan.hjson.tpl ++++ b/data/clkmgr_testplan.hjson.tpl +@@ -3,8 +3,8 @@ + // SPDX-License-Identifier: Apache-2.0 + { + name: "clkmgr" ++ // clkmgr has no interrupts, so intr_test_testplan.hjson is deliberately not imported. + import_testplans: ["hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/csr_testplan.hjson", +- "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + "hw/vendor/lowrisc_ip/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", From 20d2a4b73a3188a77fe03f729d43db005d81f735 Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 13:58:21 +0100 Subject: [PATCH 5/8] [dv,clk_mgr] skip the tests that need clock measurement Clock measurement is disabled in mocha, so any test that tries to exercise it can't pass. Drop the two measurement tests and their testpoints, and skip the measurement checks inside the tests that also cover other things. --- .../clkmgr/data/clkmgr_sec_cm_testplan.hjson | 8 +- .../clkmgr/data/clkmgr_testplan.hjson | 68 ------- .../ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson | 8 - .../dv/env/seq_lib/clkmgr_regwen_vseq.sv | 40 ----- .../dv/env/seq_lib/clkmgr_stress_all_vseq.sv | 2 - .../data/clkmgr_sec_cm_testplan.hjson.tpl | 13 ++ .../clkmgr/data/clkmgr_testplan.hjson.tpl | 5 + .../clkmgr/dv/clkmgr_sim_cfg.hjson.tpl | 10 ++ .../dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl | 5 + .../env/seq_lib/clkmgr_stress_all_vseq.sv.tpl | 3 + ...5_Gate_Measurement_On_Ext_Clk_Bypass.patch | 170 ++++++++++++++++++ 11 files changed, 212 insertions(+), 120 deletions(-) create mode 100644 hw/vendor/patches/lowrisc_ip/clkmgr/0005_Gate_Measurement_On_Ext_Clk_Bypass.patch diff --git a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson index e286eb3dc..2091154b5 100644 --- a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson @@ -43,7 +43,9 @@ - Measurement error should trigger a recoverable alert ''' stage: V2S - tests: ["clkmgr_frequency"] + // Unverified: measurement is intentionally disabled in this configuration, so this + // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. + tests: [] } { name: sec_cm_timeout_clk_bkgn_chk @@ -55,7 +57,9 @@ - Timeout should cause a recoverable alert ''' stage: V2S - tests: ["clkmgr_frequency_timeout"] + // Unverified: measurement is intentionally disabled in this configuration, so this + // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. + tests: [] } { name: sec_cm_meas_config_shadow diff --git a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson index 3c9874c10..8f1a262d8 100644 --- a/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson @@ -129,72 +129,6 @@ stage: V2 tests: ["clkmgr_smoke"] } - { - name: frequency - desc: '''This tests the frequency counters measured count functionality. - - These counters compute the number of cycles of each clock relative - to the aon timer, and compares it to the corresponding - thresholds written into the `*_meas_ctrl_shadowed` CSR. Measurements - beyond these thresholds trigger a recoverable alert and set a bit - in the `recov_err_code` CSR. Also, if the counters reach their - maximum value they don't wrap around. - - If clock calibration is lost, indicated by the `calib_rdy_i` input - being `prim_mubi_pkg::MuBi4False`, the measurements stop, no - error is triggered, and `measure_ctrl_regwen` is set to 1. - - **Stimulus**: - - Randomly set slow, correct, and fast interval for each counter - and test. - - Randomly set the `calib_rdy_i` input. - - Randomly trigger a clock saturation by forcing its cycle count - to be near its maximum value while counting. - - **Check**: - - Slow and fast intervals should cause a recoverable alert. - - Coverage collected per clock. - ''' - stage: V2 - tests: ["clkmgr_frequency"] - } - { - name: frequency_timeout - desc: '''This tests the frequency counters timeout functionality. - - These counters compute the number of cycles of some clock relative - to the aon timer. It should trigger a recoverable alert when there - is no valid measurement when enabled, leading to a timeout. This is - separate from the `frequently` testpoint to simplify the test checks. - - **Stimulus**: - - Randomly stop measured clocks to trigger a timeout. - - **Check**: - - Timeout should cause a recoverable alert. - - Coverage collected per clock. - ''' - stage: V2 - tests: ["clkmgr_frequency_timeout"] - } - { - name: frequency_overflow - desc: '''This tests the overflow feature in prim_clock_meas. - - This needs to modify the state of the counter to trigger the - feature. - - **Stimulus**: - - Program the counter. Whenever it hits the value of 1, set it to - the range - 2. - - **Check**: - - The internal cnt_ovfl flop is set. - - The fast_o output should be set. - ''' - stage: V2 - tests: ["clkmgr_frequency"] - } { name: regwen desc: '''This tests the behavior of the regwen CSRs. @@ -218,8 +152,6 @@ desc: '''This runs random sequences in succession. Randomly chooses from the following sequences: - - clkmgr_frequency_timeout_vseq, - - clkmgr_frequency_vseq, - clkmgr_peri_vseq, - clkmgr_smoke_vseq, - clkmgr_trans_vseq diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson b/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson index 7d80f55c4..ee53e854d 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson +++ b/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson @@ -70,14 +70,6 @@ name: clkmgr_smoke uvm_test_seq: clkmgr_smoke_vseq } - { - name: clkmgr_frequency - uvm_test_seq: clkmgr_frequency_vseq - } - { - name: clkmgr_frequency_timeout - uvm_test_seq: clkmgr_frequency_timeout_vseq - } { name: clkmgr_peri uvm_test_seq: clkmgr_peri_vseq diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv index 45e54b2ae..16388d8e9 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv @@ -24,45 +24,6 @@ class clkmgr_regwen_vseq extends clkmgr_base_vseq; `uvm_info(`gfn, "Check jitter_regwen done", UVM_MEDIUM) endtask : check_jitter_regwen - // This must be careful to turn measurements off right after checking the updates - // to avoid measurement errors. We could set the thresholds correctly, but we - // might as well set them randomly for good measure. Carefully masks only the - // real bits for the comparison. - task check_meas_ctrl_regwen(); - bit regwen_enable; - `DV_CHECK_STD_RANDOMIZE_FATAL(regwen_enable) - csr_wr(.ptr(ral.measure_ctrl_regwen), .value(regwen_enable)); - foreach (ExpectedCounts[clk]) begin - clk_mesr_e clk_mesr = clk_mesr_e'(clk); - uvm_reg ctrl_shadowed = meas_ctrl_regs[clk_mesr].ctrl_lo.get_dv_base_reg_parent(); - uvm_reg_data_t prev_en; - mubi4_t new_en = get_rand_mubi4_val(1, 1, 2); - int prev_ctrl; - int max_threshold = ExpectedCounts[clk] + 2; - int min_threshold = ExpectedCounts[clk] - 2; - int new_ctrl = get_meas_ctrl_value(min_threshold, max_threshold, - meas_ctrl_regs[clk_mesr].ctrl_lo, meas_ctrl_regs[clk_mesr].ctrl_hi); - int actual_ctrl; - int lo_mask = ((1 << meas_ctrl_regs[clk_mesr].ctrl_lo.get_n_bits()) - 1) << - meas_ctrl_regs[clk_mesr].ctrl_lo.get_lsb_pos(); - int hi_mask = ((1 << meas_ctrl_regs[clk_mesr].ctrl_hi.get_n_bits()) - 1) << - meas_ctrl_regs[clk_mesr].ctrl_hi.get_lsb_pos(); - `uvm_info(`gfn, $sformatf( - "Check %0s regwen = %b", meas_ctrl_regs[clk_mesr].name, regwen_enable), - UVM_MEDIUM) - csr_rd(.ptr(meas_ctrl_regs[clk_mesr].en), .value(prev_en)); - csr_rd(.ptr(ctrl_shadowed), .value(prev_ctrl)); - csr_wr(.ptr(ctrl_shadowed), .value(new_ctrl)); - csr_wr(.ptr(meas_ctrl_regs[clk_mesr].en), .value(new_en)); - csr_rd_check(.ptr(meas_ctrl_regs[clk_mesr].en), - .compare_value(mubi4_t'(regwen_enable ? new_en : prev_en))); - csr_wr(.ptr(meas_ctrl_regs[clk_mesr].en), .value(MuBi4False)); - csr_rd_check(.ptr(ctrl_shadowed), .compare_value(regwen_enable ? new_ctrl : prev_ctrl), - .compare_mask(lo_mask | hi_mask)); - `uvm_info(`gfn, $sformatf("Check %0s regwen done", meas_ctrl_regs[clk_mesr].name), - UVM_MEDIUM) - end - endtask : check_meas_ctrl_regwen task body(); // Make sure the aon clock is running as slow as it is meant to, otherwise the aon clock @@ -73,7 +34,6 @@ class clkmgr_regwen_vseq extends clkmgr_base_vseq; `uvm_info(`gfn, $sformatf("Will run %0d rounds", num_trans), UVM_MEDIUM) for (int i = 0; i < num_trans; ++i) begin check_jitter_regwen(); - check_meas_ctrl_regwen(); apply_reset("HARD"); // This is to make sure we don't start writes immediately after reset, // otherwise the tl_agent could mistakenly consider the following read diff --git a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv index 7f97b4257..b288f6eba 100644 --- a/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv +++ b/hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv @@ -11,8 +11,6 @@ class clkmgr_stress_all_vseq extends clkmgr_base_vseq; task body(); string seq_names[] = { - "clkmgr_frequency_timeout_vseq", - "clkmgr_frequency_vseq", "clkmgr_peri_vseq", "clkmgr_smoke_vseq", "clkmgr_trans_vseq" diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_sec_cm_testplan.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_sec_cm_testplan.hjson.tpl index 05ec432a8..50acce77a 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_sec_cm_testplan.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_sec_cm_testplan.hjson.tpl @@ -21,6 +21,7 @@ // // Please ensure that this testplan is imported in: // .../clkmgr/data/clkmgr_testplan.hjson +<% measurement_live = ext_clk_bypass %>\ { testpoints: [ { @@ -43,7 +44,13 @@ - Measurement error should trigger a recoverable alert ''' stage: V2S + % if measurement_live: tests: ["clkmgr_frequency"] + % else: + // Unverified: measurement is intentionally disabled in this configuration, so this + // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. + tests: [] + % endif } { name: sec_cm_timeout_clk_bkgn_chk @@ -55,7 +62,13 @@ - Timeout should cause a recoverable alert ''' stage: V2S + % if measurement_live: tests: ["clkmgr_frequency_timeout"] + % else: + // Unverified: measurement is intentionally disabled in this configuration, so this + // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. + tests: [] + % endif } { name: sec_cm_meas_config_shadow diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl index 408bf4046..a86a5be48 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/data/clkmgr_testplan.hjson.tpl @@ -1,6 +1,7 @@ // Copyright lowRISC contributors (OpenTitan project). // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% measurement_live = ext_clk_bypass %>\ { name: "clkmgr" // clkmgr has no interrupts, so intr_test_testplan.hjson is deliberately not imported. @@ -183,6 +184,7 @@ stage: V2 tests: ["clkmgr_smoke"] } + % if measurement_live: { name: frequency desc: '''This tests the frequency counters measured count functionality. @@ -249,6 +251,7 @@ stage: V2 tests: ["clkmgr_frequency"] } + % endif { name: regwen desc: '''This tests the behavior of the regwen CSRs. @@ -275,8 +278,10 @@ % if ext_clk_bypass: - clkmgr_extclk_vseq, % endif + % if measurement_live: - clkmgr_frequency_timeout_vseq, - clkmgr_frequency_vseq, + % endif - clkmgr_peri_vseq, - clkmgr_smoke_vseq, - clkmgr_trans_vseq diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl index 746d9b7d4..996c23d7d 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/clkmgr_sim_cfg.hjson.tpl @@ -1,6 +1,14 @@ // Copyright lowRISC contributors (OpenTitan project). // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<%doc> +Clock measurement is intentionally disabled in this configuration: the source clocks are supplied +from outside the top and are assumed already stable, so there is no calibration step and calib_rdy +is tied MuBi4False. clkmgr_meas_chk then clears the measurement enable and measure_ctrl_regwen is +held open, so any sequence exercising measurement cannot pass. These are gated on measurement_live +rather than deleted, so they return automatically if the configuration ever changes. +\ +<% measurement_live = ext_clk_bypass %>\ { // Name of the sim cfg - typically same as the name of the DUT. name: clkmgr @@ -76,6 +84,7 @@ uvm_test_seq: clkmgr_extclk_vseq } % endif + % if measurement_live: { name: clkmgr_frequency uvm_test_seq: clkmgr_frequency_vseq @@ -84,6 +93,7 @@ name: clkmgr_frequency_timeout uvm_test_seq: clkmgr_frequency_timeout_vseq } + % endif { name: clkmgr_peri uvm_test_seq: clkmgr_peri_vseq diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl index 20ae44349..c790da7e1 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl @@ -1,6 +1,7 @@ // Copyright lowRISC contributors (OpenTitan project). // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% measurement_live = ext_clk_bypass %>\ // The regwen vseq attempts to write to registers whose regwen is randomly on or off to check // the register contents is not updated when off. More details in the clkmgr_testplan.hjson file. @@ -39,6 +40,7 @@ class clkmgr_regwen_vseq extends clkmgr_base_vseq; endtask : check_extclk_regwen % endif +% if measurement_live: // This must be careful to turn measurements off right after checking the updates // to avoid measurement errors. We could set the thresholds correctly, but we // might as well set them randomly for good measure. Carefully masks only the @@ -78,6 +80,7 @@ class clkmgr_regwen_vseq extends clkmgr_base_vseq; UVM_MEDIUM) end endtask : check_meas_ctrl_regwen +% endif task body(); // Make sure the aon clock is running as slow as it is meant to, otherwise the aon clock @@ -91,7 +94,9 @@ class clkmgr_regwen_vseq extends clkmgr_base_vseq; % if ext_clk_bypass: check_extclk_regwen(); % endif + % if measurement_live: check_meas_ctrl_regwen(); + % endif apply_reset("HARD"); // This is to make sure we don't start writes immediately after reset, // otherwise the tl_agent could mistakenly consider the following read diff --git a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl index 87ac1e2b0..3991f3346 100644 --- a/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl +++ b/hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl @@ -1,6 +1,7 @@ // Copyright lowRISC contributors (OpenTitan project). // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% measurement_live = ext_clk_bypass %>\ // combine all clkmgr seqs (except below seqs) in one seq to run sequentially // 1. csr seq, which requires scb to be disabled @@ -14,8 +15,10 @@ class clkmgr_stress_all_vseq extends clkmgr_base_vseq; % if ext_clk_bypass: "clkmgr_extclk_vseq", % endif + % if measurement_live: "clkmgr_frequency_timeout_vseq", "clkmgr_frequency_vseq", + % endif "clkmgr_peri_vseq", "clkmgr_smoke_vseq", "clkmgr_trans_vseq" diff --git a/hw/vendor/patches/lowrisc_ip/clkmgr/0005_Gate_Measurement_On_Ext_Clk_Bypass.patch b/hw/vendor/patches/lowrisc_ip/clkmgr/0005_Gate_Measurement_On_Ext_Clk_Bypass.patch new file mode 100644 index 000000000..96bcc4a2c --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/clkmgr/0005_Gate_Measurement_On_Ext_Clk_Bypass.patch @@ -0,0 +1,170 @@ +diff --git a/data/clkmgr_testplan.hjson.tpl b/data/clkmgr_testplan.hjson.tpl +--- a/data/clkmgr_testplan.hjson.tpl ++++ b/data/clkmgr_testplan.hjson.tpl +@@ -1,6 +1,7 @@ + // Copyright lowRISC contributors (OpenTitan project). + // Licensed under the Apache License, Version 2.0, see LICENSE for details. + // SPDX-License-Identifier: Apache-2.0 ++<% measurement_live = ext_clk_bypass %>\ + { + name: "clkmgr" + // clkmgr has no interrupts, so intr_test_testplan.hjson is deliberately not imported. +@@ -183,6 +184,7 @@ + stage: V2 + tests: ["clkmgr_smoke"] + } ++ % if measurement_live: + { + name: frequency + desc: '''This tests the frequency counters measured count functionality. +@@ -249,6 +251,7 @@ + stage: V2 + tests: ["clkmgr_frequency"] + } ++ % endif + { + name: regwen + desc: '''This tests the behavior of the regwen CSRs. +@@ -275,8 +278,10 @@ + % if ext_clk_bypass: + - clkmgr_extclk_vseq, + % endif ++ % if measurement_live: + - clkmgr_frequency_timeout_vseq, + - clkmgr_frequency_vseq, ++ % endif + - clkmgr_peri_vseq, + - clkmgr_smoke_vseq, + - clkmgr_trans_vseq +diff --git a/data/clkmgr_sec_cm_testplan.hjson.tpl b/data/clkmgr_sec_cm_testplan.hjson.tpl +--- a/data/clkmgr_sec_cm_testplan.hjson.tpl ++++ b/data/clkmgr_sec_cm_testplan.hjson.tpl +@@ -21,6 +21,7 @@ + // + // Please ensure that this testplan is imported in: + // .../clkmgr/data/clkmgr_testplan.hjson ++<% measurement_live = ext_clk_bypass %>\ + { + testpoints: [ + { +@@ -43,7 +44,13 @@ + - Measurement error should trigger a recoverable alert + ''' + stage: V2S ++ % if measurement_live: + tests: ["clkmgr_frequency"] ++ % else: ++ // Unverified: measurement is intentionally disabled in this configuration, so this ++ // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. ++ tests: [] ++ % endif + } + { + name: sec_cm_timeout_clk_bkgn_chk +@@ -55,7 +62,13 @@ + - Timeout should cause a recoverable alert + ''' + stage: V2S ++ % if measurement_live: + tests: ["clkmgr_frequency_timeout"] ++ % else: ++ // Unverified: measurement is intentionally disabled in this configuration, so this ++ // countermeasure cannot be exercised. The clkmgr_meas_chk hardware is still instantiated. ++ tests: [] ++ % endif + } + { + name: sec_cm_meas_config_shadow +diff --git a/dv/clkmgr_sim_cfg.hjson.tpl b/dv/clkmgr_sim_cfg.hjson.tpl +--- a/dv/clkmgr_sim_cfg.hjson.tpl ++++ b/dv/clkmgr_sim_cfg.hjson.tpl +@@ -1,6 +1,14 @@ + // Copyright lowRISC contributors (OpenTitan project). + // Licensed under the Apache License, Version 2.0, see LICENSE for details. + // SPDX-License-Identifier: Apache-2.0 ++<%doc> ++Clock measurement is intentionally disabled in this configuration: the source clocks are supplied ++from outside the top and are assumed already stable, so there is no calibration step and calib_rdy ++is tied MuBi4False. clkmgr_meas_chk then clears the measurement enable and measure_ctrl_regwen is ++held open, so any sequence exercising measurement cannot pass. These are gated on measurement_live ++rather than deleted, so they return automatically if the configuration ever changes. ++\ ++<% measurement_live = ext_clk_bypass %>\ + { + // Name of the sim cfg - typically same as the name of the DUT. + name: clkmgr +@@ -76,6 +84,7 @@ + uvm_test_seq: clkmgr_extclk_vseq + } + % endif ++ % if measurement_live: + { + name: clkmgr_frequency + uvm_test_seq: clkmgr_frequency_vseq +@@ -84,6 +93,7 @@ + name: clkmgr_frequency_timeout + uvm_test_seq: clkmgr_frequency_timeout_vseq + } ++ % endif + { + name: clkmgr_peri + uvm_test_seq: clkmgr_peri_vseq +diff --git a/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl b/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl +--- a/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl ++++ b/dv/env/seq_lib/clkmgr_regwen_vseq.sv.tpl +@@ -1,6 +1,7 @@ + // Copyright lowRISC contributors (OpenTitan project). + // Licensed under the Apache License, Version 2.0, see LICENSE for details. + // SPDX-License-Identifier: Apache-2.0 ++<% measurement_live = ext_clk_bypass %>\ + + // The regwen vseq attempts to write to registers whose regwen is randomly on or off to check + // the register contents is not updated when off. More details in the clkmgr_testplan.hjson file. +@@ -39,6 +40,7 @@ + endtask : check_extclk_regwen + + % endif ++% if measurement_live: + // This must be careful to turn measurements off right after checking the updates + // to avoid measurement errors. We could set the thresholds correctly, but we + // might as well set them randomly for good measure. Carefully masks only the +@@ -78,6 +80,7 @@ + UVM_MEDIUM) + end + endtask : check_meas_ctrl_regwen ++% endif + + task body(); + // Make sure the aon clock is running as slow as it is meant to, otherwise the aon clock +@@ -91,7 +94,9 @@ + % if ext_clk_bypass: + check_extclk_regwen(); + % endif ++ % if measurement_live: + check_meas_ctrl_regwen(); ++ % endif + apply_reset("HARD"); + // This is to make sure we don't start writes immediately after reset, + // otherwise the tl_agent could mistakenly consider the following read +diff --git a/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl b/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl +--- a/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl ++++ b/dv/env/seq_lib/clkmgr_stress_all_vseq.sv.tpl +@@ -1,6 +1,7 @@ + // Copyright lowRISC contributors (OpenTitan project). + // Licensed under the Apache License, Version 2.0, see LICENSE for details. + // SPDX-License-Identifier: Apache-2.0 ++<% measurement_live = ext_clk_bypass %>\ + + // combine all clkmgr seqs (except below seqs) in one seq to run sequentially + // 1. csr seq, which requires scb to be disabled +@@ -14,8 +15,10 @@ + % if ext_clk_bypass: + "clkmgr_extclk_vseq", + % endif ++ % if measurement_live: + "clkmgr_frequency_timeout_vseq", + "clkmgr_frequency_vseq", ++ % endif + "clkmgr_peri_vseq", + "clkmgr_smoke_vseq", + "clkmgr_trans_vseq" From 85d6a4426434d30b19a35778297d6a909c0aca6a Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 14:03:41 +0100 Subject: [PATCH 6/8] [dv,clk_mgr] register clk_mgr in the mocha DV regression --- hw/top_chip/dv/mocha_sim_cfgs.hjson | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/top_chip/dv/mocha_sim_cfgs.hjson b/hw/top_chip/dv/mocha_sim_cfgs.hjson index 13dd99898..1619e262f 100644 --- a/hw/top_chip/dv/mocha_sim_cfgs.hjson +++ b/hw/top_chip/dv/mocha_sim_cfgs.hjson @@ -31,6 +31,7 @@ "{proj_root}/hw/vendor/lowrisc_ip/ip/i2c/dv/i2c_sim_cfg.hjson", "{proj_root}/hw/vendor/lowrisc_ip/ip/kmac/dv/kmac_unmasked_sim_cfg.hjson", "{proj_root}/hw/top_chip/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson", + "{proj_root}/hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson", "{proj_root}/hw/top_chip/ip_autogen/gpio/dv/gpio_sim_cfg.hjson", "{proj_root}/hw/top_chip/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson", "{proj_root}/hw/top_chip/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson", From 523cf6c9932e3c78cf707c63c63b8cf2c33e66b3 Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 14:06:32 +0100 Subject: [PATCH 7/8] [dv] fix alert agent getting stuck after a reset The alert agent answers alerts coming from the design. If a reset lands at the wrong moment the agent ends up waiting forever for a reply that will never arrive, and stops answering alerts for the rest of the test. Tests then hang or time out waiting for an alert the design has already sent. --- .../seq_lib/alert_receiver_alert_rsp_seq.sv | 14 ++++++++++- .../0003-alert_agent_rsp_seq_reset_race.patch | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 hw/vendor/patches/lowrisc_ip/dv_sv/0003-alert_agent_rsp_seq_reset_race.patch diff --git a/hw/vendor/lowrisc_ip/dv/sv/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv b/hw/vendor/lowrisc_ip/dv/sv/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv index 433439e2d..db8d2baa4 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv +++ b/hw/vendor/lowrisc_ip/dv/sv/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv @@ -54,7 +54,19 @@ task alert_receiver_alert_rsp_seq::default_rsp_thread(); int_err == 0; ) finish_item(rsp); - get_response(rsp); + // Stop waiting for the response on reset. The driver only reports done for items already + // queued in m_pending_alert_rsps, so an item accepted just as reset asserts never gets its + // response and get_response() would block forever, leaving this agent unable to ack any + // further alert for the rest of the simulation. Only the response wait is escaped here: + // killing start_item/finish_item instead would abort sequencer arbitration and trip + // SEQREQZMB. + fork begin : isolation_fork + fork + get_response(rsp); + wait (cfg.in_reset); + join_any + disable fork; + end join end : send_rsp join endtask : default_rsp_thread diff --git a/hw/vendor/patches/lowrisc_ip/dv_sv/0003-alert_agent_rsp_seq_reset_race.patch b/hw/vendor/patches/lowrisc_ip/dv_sv/0003-alert_agent_rsp_seq_reset_race.patch new file mode 100644 index 000000000..84a824be1 --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/dv_sv/0003-alert_agent_rsp_seq_reset_race.patch @@ -0,0 +1,25 @@ +diff --git a/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv b/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv +index 433439e2..db8d2baa 100644 +--- a/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv ++++ b/alert_esc_agent/seq_lib/alert_receiver_alert_rsp_seq.sv +@@ -54,7 +54,19 @@ task alert_receiver_alert_rsp_seq::default_rsp_thread(); + int_err == 0; + ) + finish_item(rsp); +- get_response(rsp); ++ // Stop waiting for the response on reset. The driver only reports done for items already ++ // queued in m_pending_alert_rsps, so an item accepted just as reset asserts never gets its ++ // response and get_response() would block forever, leaving this agent unable to ack any ++ // further alert for the rest of the simulation. Only the response wait is escaped here: ++ // killing start_item/finish_item instead would abort sequencer arbitration and trip ++ // SEQREQZMB. ++ fork begin : isolation_fork ++ fork ++ get_response(rsp); ++ wait (cfg.in_reset); ++ join_any ++ disable fork; ++ end join + end : send_rsp + join + endtask : default_rsp_thread From 53b593e9a6c5f456e9b5e74d1ff366b899027cdc Mon Sep 17 00:00:00 2001 From: tchilikov-semify Date: Tue, 18 Aug 2026 14:16:38 +0100 Subject: [PATCH 8/8] [dv] don't run register accesses while the shadow reset is held The shadow register test holds a reset line low for a while, then lets go. It also starts a second sequence that reads and writes registers at the same time. But holding that reset low blocks the register interface by design, so those accesses just queue up and never complete. If the reset is held longer than the access timeout, the test dies. Start the register sequence after the reset is released instead of before it is applied. The other half of this task already does it in that order. --- .../cip_base_vseq__shadow_reg_errors.svh | 10 ++++++- .../0004-shadow_reg_csr_rw_ordering.patch | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 hw/vendor/patches/lowrisc_ip/dv_sv/0004-shadow_reg_csr_rw_ordering.patch diff --git a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh index ec13cf5ac..119ed918f 100644 --- a/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh +++ b/hw/vendor/lowrisc_ip/dv/sv/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh @@ -238,7 +238,10 @@ virtual task glitch_shadowed_reset(ref dv_base_reg shadowed_csr[$], // Randomly choose to glitch `rst_n` or `shadowed_rst_n` pin. if ($urandom_range(0, 1)) begin - ready_to_trigger_csr_rw = 1; + // Do not release the csr_rw sequence here. While rst_shadowed_n is held low a reg_top asserts + // shadow_busy, which drives tlul_adapter_reg's busy_i and holds a_ready low, so every CSR + // access blocks until the pin is reconnected at the end of this task. csr_rw is released + // there instead, matching the ordering the IP-reset branch below already uses. `uvm_info(`gfn, "toggle shadow reset pin", UVM_HIGH) cfg.rst_shadowed_vif.drive_shadow_rst_pin(0); end else begin @@ -274,6 +277,11 @@ virtual task glitch_shadowed_reset(ref dv_base_reg shadowed_csr[$], cfg.clk_rst_vif.wait_clks($urandom_range(50, 200)); cfg.rst_shadowed_vif.reconnect_shadowed_rst_n_to_rst_n(); + + // The CSR interface is reachable again now that the shadow reset is reconnected, so the csr_rw + // sequence can safely be released (a no-op if the IP-reset branch already did so). + ready_to_trigger_csr_rw = 1; + has_fatal_alert = alert_name != ""; endtask diff --git a/hw/vendor/patches/lowrisc_ip/dv_sv/0004-shadow_reg_csr_rw_ordering.patch b/hw/vendor/patches/lowrisc_ip/dv_sv/0004-shadow_reg_csr_rw_ordering.patch new file mode 100644 index 000000000..78a4ed911 --- /dev/null +++ b/hw/vendor/patches/lowrisc_ip/dv_sv/0004-shadow_reg_csr_rw_ordering.patch @@ -0,0 +1,27 @@ +diff --git a/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh b/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh +--- a/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh ++++ b/cip_lib/seq_lib/cip_base_vseq__shadow_reg_errors.svh +@@ -238,7 +238,10 @@ + + // Randomly choose to glitch `rst_n` or `shadowed_rst_n` pin. + if ($urandom_range(0, 1)) begin +- ready_to_trigger_csr_rw = 1; ++ // Do not release the csr_rw sequence here. While rst_shadowed_n is held low a reg_top asserts ++ // shadow_busy, which drives tlul_adapter_reg's busy_i and holds a_ready low, so every CSR ++ // access blocks until the pin is reconnected at the end of this task. csr_rw is released ++ // there instead, matching the ordering the IP-reset branch below already uses. + `uvm_info(`gfn, "toggle shadow reset pin", UVM_HIGH) + cfg.rst_shadowed_vif.drive_shadow_rst_pin(0); + end else begin +@@ -274,6 +277,11 @@ + cfg.clk_rst_vif.wait_clks($urandom_range(50, 200)); + + cfg.rst_shadowed_vif.reconnect_shadowed_rst_n_to_rst_n(); ++ ++ // The CSR interface is reachable again now that the shadow reset is reconnected, so the csr_rw ++ // sequence can safely be released (a no-op if the IP-reset branch already did so). ++ ready_to_trigger_csr_rw = 1; ++ + has_fatal_alert = alert_name != ""; + endtask +