Skip to content
1 change: 1 addition & 0 deletions hw/top_chip/dv/mocha_sim_cfgs.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions hw/top_chip/ip_autogen/clkmgr/data/clkmgr.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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: '''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
82 changes: 7 additions & 75 deletions hw/top_chip/ip_autogen/clkmgr/data/clkmgr_testplan.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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",
// 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/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
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down
24 changes: 8 additions & 16 deletions hw/top_chip/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions hw/top_chip/ip_autogen/clkmgr/dv/env/clkmgr_if.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 0 additions & 40 deletions hw/top_chip/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions hw/top_chip/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);

Expand Down
5 changes: 1 addition & 4 deletions hw/top_chip/ip_autogen/clkmgr/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
2 changes: 1 addition & 1 deletion hw/vendor/lowrisc_ip.vendor.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading
Loading