[dv,clkmgr] sec cm dv component
Signed-off-by: Jaedon Kim <jdonjdon@google.com>
diff --git a/hw/ip/clkmgr/dv/cov/clkmgr_cov_bind.sv b/hw/ip/clkmgr/dv/cov/clkmgr_cov_bind.sv
new file mode 100644
index 0000000..81594ae
--- /dev/null
+++ b/hw/ip/clkmgr/dv/cov/clkmgr_cov_bind.sv
@@ -0,0 +1,38 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Description:
+// Clock manager coverage bindings for multi bus input
+module clkmgr_cov_bind;
+ bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_idle_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (idle_i)
+ );
+
+ bind clkmgr cip_mubi_cov_if #(.Width(lc_ctrl_pkg::TxWidth)) u_lc_hw_debug_en_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (lc_hw_debug_en_i)
+ );
+
+ bind clkmgr cip_mubi_cov_if #(.Width(lc_ctrl_pkg::TxWidth)) u_lc_clk_byp_req_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (lc_clk_byp_req_i)
+ );
+
+ bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_io_clk_byp_ack_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (io_clk_byp_ack_i)
+ );
+
+ bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_all_clk_byp_ack_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (all_clk_byp_ack_i)
+ );
+
+ bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_div_step_down_req_mubi_cov_if (
+ .rst_ni (rst_ni),
+ .mubi (div_step_down_req_i)
+ );
+
+endmodule // clkmgr_cov_bind
diff --git a/hw/ip/clkmgr/dv/env/clkmgr_env_pkg.sv b/hw/ip/clkmgr/dv/env/clkmgr_env_pkg.sv
index b495222..e2b3318 100644
--- a/hw/ip/clkmgr/dv/env/clkmgr_env_pkg.sv
+++ b/hw/ip/clkmgr/dv/env/clkmgr_env_pkg.sv
@@ -95,6 +95,16 @@
ClkMesrUsb
} clk_mesr_e;
+ // Mubi test mode
+ typedef enum int {
+ ClkmgrMubiNone = 0,
+ ClkmgrMubiIdle = 1,
+ ClkmgrMubiLcCtrl = 2,
+ ClkmgrMubiLcHand = 3,
+ ClkmgrMubiHand = 4,
+ ClkmgrMubiDiv = 5
+ } clkmgr_mubi_e;
+
// This is to examine separately the measurement and timeout recoverable error bits.
typedef logic [ClkMesrUsb:0] recov_bits_t;
diff --git a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv
index 297b38d..901dd12 100644
--- a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv
+++ b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv
@@ -31,6 +31,7 @@
lc_tx_t extclk_ctrl_low_speed_sel;
lc_tx_t extclk_ctrl_sel;
+ clkmgr_mubi_e mubi_mode;
virtual function void set_scanmode_on_low_weight();
scanmode_on_weight = 2;
@@ -80,6 +81,8 @@
endfunction
task pre_start();
+ mubi_mode = ClkmgrMubiNone;
+ void'($value$plusargs("clkmgr_mubi_mode=%0d", mubi_mode));
// Disable the assertions requiring strict mubi4 and lc_tx_t to test non-strict-true values.
$assertoff(0, "prim_mubi4_sync");
$assertoff(0, "prim_lc_sync");
@@ -335,5 +338,4 @@
// Increasing its frequency improves DV efficiency without compromising quality.
cfg.aon_clk_rst_vif.set_freq_mhz((1.0 * FakeAonClkHz) / 1_000_000);
endtask
-
endclass : clkmgr_base_vseq
diff --git a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv
index 87a4f6e..7c70bb4 100644
--- a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv
+++ b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv
@@ -45,11 +45,22 @@
mubi4_t div_step_down_req_non_true;
function void post_randomize();
- lc_clk_byp_req = get_rand_lc_tx_val(8, 2, 2);
- lc_debug_en = get_rand_lc_tx_val(8, 2, 2);
- io_clk_byp_ack_non_true = get_rand_mubi4_val(0, 2, 8);
- all_clk_byp_ack_non_true = get_rand_mubi4_val(0, 2, 8);
- div_step_down_req_non_true = get_rand_mubi4_val(0, 2, 8);
+ if (mubi_mode == ClkmgrMubiLcHand) begin
+ // increase weight of illgal value only in ClkmgrMubiLcHand
+ lc_clk_byp_req = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(14));
+ end else begin
+ lc_clk_byp_req = get_rand_lc_tx_val(.t_weight(8), .f_weight(2), .other_weight(2));
+ end
+ if (mubi_mode == ClkmgrMubiLcCtrl) begin
+ // increase weight of illgal value only in ClkmgrMubiLcHand
+ lc_debug_en = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(14));
+ end else begin
+ lc_debug_en = get_rand_lc_tx_val(.t_weight(8), .f_weight(2), .other_weight(2));
+ end
+
+ io_clk_byp_ack_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8));
+ all_clk_byp_ack_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8));
+ div_step_down_req_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8));
`uvm_info(`gfn, $sformatf(
"randomize gives lc_clk_byp_req=0x%x, lc_debug_en=0x%x", lc_clk_byp_req, lc_debug_en),
@@ -60,16 +71,34 @@
// Notice only all_clk_byp_req and io_clk_byp_req Mubi4True and Mubi4False cause transitions.
local task delayed_update_all_clk_byp_ack(mubi4_t value, int cycles);
+ if (mubi_mode == ClkmgrMubiHand && value == MuBi4True) begin
+ cfg.clk_rst_vif.wait_clks($urandom_range(1, 10));
+ cfg.clkmgr_vif.update_all_clk_byp_ack(get_rand_mubi4_val(.t_weight(0),
+ .f_weight(1),
+ .other_weight(1)));
+ end
cfg.clk_rst_vif.wait_clks(cycles);
cfg.clkmgr_vif.update_all_clk_byp_ack(value);
endtask
local task delayed_update_div_step_down_req(mubi4_t value, int cycles);
+ if (mubi_mode == ClkmgrMubiDiv && value == MuBi4True) begin
+ cfg.clk_rst_vif.wait_clks($urandom_range(1, 10));
+ cfg.clkmgr_vif.update_div_step_down_req(get_rand_mubi4_val(.t_weight(0),
+ .f_weight(1),
+ .other_weight(1)));
+ end
cfg.clk_rst_vif.wait_clks(cycles);
cfg.clkmgr_vif.update_div_step_down_req(value);
endtask
local task delayed_update_io_clk_byp_ack(mubi4_t value, int cycles);
+ if (mubi_mode == ClkmgrMubiHand && value == MuBi4True) begin
+ cfg.clk_rst_vif.wait_clks($urandom_range(1, 10));
+ cfg.clkmgr_vif.update_io_clk_byp_ack(get_rand_mubi4_val(.t_weight(0),
+ .f_weight(1),
+ .other_weight(1)));
+ end
cfg.clk_rst_vif.wait_clks(cycles);
cfg.clkmgr_vif.update_io_clk_byp_ack(value);
endtask
diff --git a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv
index da02a00..32b8462 100644
--- a/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv
+++ b/hw/ip/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv
@@ -5,7 +5,7 @@
// trans test vseq
// This is a more randomized version of the corresponding test in the smoke sequence.
// Starts with random units busy, set the hints at random. The idle units whose hint bit is off
-// will be disabled, but the others will remain enabled. Then all units are made idle to check
+// will be disabled, but the others will remain enabled. Then all units are made idle to check
// that status matches hints. Prior to the next round this raises all hints to avoid units whose
// clock is off but are not idle.
//
@@ -44,6 +44,8 @@
bool_idle = mubi_hintables_to_hintables(idle);
`DV_CHECK_EQ(value, initial_hints | ~bool_idle, $sformatf(
"Busy units have status high: hints=0x%x, idle=0x%x", initial_hints, bool_idle))
+ // Add random idle
+ if (mubi_mode == ClkmgrMubiIdle) drive_idle();
// Setting all idle should make hint_status match hints.
cfg.clkmgr_vif.update_idle({NUM_TRANS{MuBi4True}});
@@ -51,6 +53,9 @@
csr_rd(.ptr(ral.clk_hints_status), .value(value));
`DV_CHECK_EQ(value, initial_hints, "All idle: units status matches hints")
+
+ if (mubi_mode == ClkmgrMubiIdle) drive_idle();
+
// Now set all hints, and the status should also be all ones.
csr_wr(.ptr(ral.clk_hints), .value('1));
cfg.io_clk_rst_vif.wait_clks(IO_DIV4_SYNC_CYCLES);
@@ -62,4 +67,16 @@
end
endtask : body
+ task drive_idle();
+ int period;
+
+ repeat (30) begin
+ period = $urandom_range(1, 10);
+ @cfg.clkmgr_vif.trans_cb;
+ cfg.clkmgr_vif.idle_i = get_rand_mubi4_val(.t_weight(0),
+ .f_weight(0),
+ .other_weight(1));
+ repeat(period) @cfg.clkmgr_vif.trans_cb;
+ end
+ endtask // drive_idle
endclass : clkmgr_trans_vseq