Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -29,6 +29,7 @@
"{proj_root}/hw/vendor/lowrisc_ip/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson",
"{proj_root}/hw/vendor/lowrisc_ip/ip/i2c/dv/i2c_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
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 @@ -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
Expand Down
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: ${instance_vlnv("lowrisc: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 @@ -88,19 +88,10 @@
name: clkmgr_peri
uvm_test_seq: clkmgr_peri_vseq
}
{
name: clkmgr_trans
uvm_test_seq: clkmgr_trans_vseq
}
{
name: clkmgr_clk_status
uvm_test_seq: clkmgr_clk_status_vseq
}
{
name: clkmgr_idle_intersig_mubi
uvm_test_seq: clkmgr_trans_vseq
run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiIdle"]
}
% if ext_clk_bypass:
{
name: clkmgr_lc_ctrl_intersig_mubi
Expand Down
15 changes: 0 additions & 15 deletions hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/env/clkmgr_if.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,7 @@ interface clkmgr_if (
};

clk_hints_t clk_hints_csr;
always_comb
clk_hints_csr = '{
% for target in list(reversed(hint_targets)):
<% sep = '' if loop.last else ',' %>\
${target}: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_${target}_hint.q${sep}
% endfor
};

clk_hints_t clk_hints_status_csr;
always_comb
clk_hints_status_csr = '{
% for target in list(reversed(hint_targets)):
<% sep = '' if loop.last else ',' %>\
${target}: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_${target}_val_qs${sep}
% endfor
};
% if ext_clk_bypass:

prim_mubi_pkg::mubi4_t extclk_ctrl_csr_sel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class clkmgr_smoke_vseq extends clkmgr_base_vseq;
cfg.clk_rst_vif.wait_clks(10);
test_jitter();
test_peri_clocks();
test_trans_clocks();
endtask : body

// Simply flip the jitter enable CSR. The side-effects are checked in the scoreboard.
Expand Down Expand Up @@ -53,58 +52,4 @@ class clkmgr_smoke_vseq extends clkmgr_base_vseq;
csr_wr(.ptr(ral.clk_enables), .value(ral.clk_enables.get_reset()));
endtask : test_peri_clocks

// Starts with all units busy, and for each one this clears the hint and reads the hint status,
// expecting it to remain at 1 since the unit is busy; then it sets the corresponding idle bit
// and reads status again, expecting it to be low.
//
// We disable the value checks when reset is active since the reads return unpredictable data.
task test_trans_clocks();
trans_e trans;
logic bit_value;
logic [TL_DW-1:0] value;
mubi_hintables_t idle;
hintables_t bool_idle;
typedef struct {
trans_e unit;
uvm_reg_field hint_bit;
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}
};
idle = 0;
// Changes in idle take at least 10 cycles to stick.
cfg.clkmgr_vif.update_idle(idle);
cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);

trans = trans.first;
csr_rd(.ptr(ral.clk_hints), .value(value));
`uvm_info(`gfn, $sformatf("Starting hints at 0x%0x, idle at 0x%x", value, idle), UVM_MEDIUM)
do begin
trans_descriptor_t descriptor = trans_descriptors[int'(trans)];
`uvm_info(`gfn, $sformatf("Clearing %s hint bit", descriptor.unit.name), UVM_MEDIUM)
csr_wr(.ptr(descriptor.hint_bit), .value(1'b0));
csr_rd(.ptr(descriptor.value_bit), .value(bit_value));
if (!cfg.under_reset) begin
`DV_CHECK_EQ(bit_value, 1'b1, $sformatf(
"%s hint value cannot drop while busy", descriptor.unit.name()))
end
`uvm_info(`gfn, $sformatf("Setting %s idle bit", descriptor.unit.name), UVM_MEDIUM)
cfg.clk_rst_vif.wait_clks(1);
idle[trans] = prim_mubi_pkg::MuBi4True;
cfg.clkmgr_vif.update_idle(idle);
// Some cycles for the logic to settle.
cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
csr_rd(.ptr(descriptor.value_bit), .value(bit_value));
if (!cfg.under_reset) begin
`DV_CHECK_EQ(bit_value, 1'b0, $sformatf(
"%s hint value should drop when idle", descriptor.unit.name()))
end
trans = trans.next();
end while (trans != trans.first);
csr_wr(.ptr(ral.clk_hints), .value(ral.clk_hints.get_reset()));
endtask : test_trans_clocks
endclass : clkmgr_smoke_vseq
Original file line number Diff line number Diff line change
Expand Up @@ -29,70 +29,70 @@ class clkmgr_trans_vseq extends clkmgr_base_vseq;
% endif
% endfor

task body();
for (int i = 0; i < num_trans; ++i) begin
logic bit_value;
hintables_t value;
hintables_t bool_idle;

`DV_CHECK_RANDOMIZE_FATAL(this)

csr_rd(.ptr(ral.clk_hints_status), .value(value));

`uvm_info(`gfn, $sformatf("Initial clk_hints_status: %b", value), UVM_MEDIUM)
cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode));

// add random value if mubi idle test
if (mubi_mode == ClkmgrMubiIdle) drive_idle(idle);
print_mubi_hintable(idle);
control_ip_clocks();
`uvm_info(`gfn, $sformatf("Idle = 0x%x", cfg.clkmgr_vif.idle_i), UVM_MEDIUM)
cfg.clk_rst_vif.wait_clks(10);
`uvm_info(`gfn, $sformatf("Updating hints to 0x%0x", initial_hints), UVM_MEDIUM)
csr_wr(.ptr(ral.clk_hints), .value(initial_hints));

// Extra wait because of synchronizers plus counters.
cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
// We expect the status to be determined by hints and idle, ignoring scanmode.
bool_idle = mubi_hintables_to_hintables(idle);
value = initial_hints | ~bool_idle;
csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value),
.err_msg($sformatf(
"Busy units have status high: hints=0x%x, idle=0x%x",
initial_hints,
bool_idle
)));

// Setting all idle should make hint_status match hints.
`uvm_info(`gfn, "Setting all units idle", UVM_MEDIUM)
cfg.clkmgr_vif.update_idle({NUM_TRANS{MuBi4True}});
cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);

csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(initial_hints),
.err_msg("All idle: expect status matches hints"));

// Now set all hints, and the status should also be all ones.
value = '1;
csr_wr(.ptr(ral.clk_hints), .value(value));
cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
// We expect all units to be on.
csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value),
.err_msg("All idle and all hints high: units status should be high"));

// Set hints to the reset value for stress tests.
csr_wr(.ptr(ral.clk_hints), .value(ral.clk_hints.get_reset()));
end
endtask : body

task drive_idle(ref mubi_hintables_t tbl);
int period;
mubi_hintables_t rand_idle;
foreach (rand_idle[i])
rand_idle[i] = get_rand_mubi4_val(.t_weight(0), .f_weight(0), .other_weight(1));

@cfg.clkmgr_vif.trans_cb;
cfg.clkmgr_vif.idle_i = rand_idle;

tbl = rand_idle;
endtask : drive_idle
// task body();
// for (int i = 0; i < num_trans; ++i) begin
// logic bit_value;
// hintables_t value;
// hintables_t bool_idle;
//
// `DV_CHECK_RANDOMIZE_FATAL(this)
//
// csr_rd(.ptr(ral.clk_hints_status), .value(value));
//
// `uvm_info(`gfn, $sformatf("Initial clk_hints_status: %b", value), UVM_MEDIUM)
// cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode));
//
// // add random value if mubi idle test
// if (mubi_mode == ClkmgrMubiIdle) drive_idle(idle);
// print_mubi_hintable(idle);
// control_ip_clocks();
// `uvm_info(`gfn, $sformatf("Idle = 0x%x", cfg.clkmgr_vif.idle_i), UVM_MEDIUM)
// cfg.clk_rst_vif.wait_clks(10);
// `uvm_info(`gfn, $sformatf("Updating hints to 0x%0x", initial_hints), UVM_MEDIUM)
// csr_wr(.ptr(ral.clk_hints), .value(initial_hints));
//
// // Extra wait because of synchronizers plus counters.
// cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
// // We expect the status to be determined by hints and idle, ignoring scanmode.
// bool_idle = mubi_hintables_to_hintables(idle);
// value = initial_hints | ~bool_idle;
// csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value),
// .err_msg($sformatf(
// "Busy units have status high: hints=0x%x, idle=0x%x",
// initial_hints,
// bool_idle
// )));
//
// // Setting all idle should make hint_status match hints.
// `uvm_info(`gfn, "Setting all units idle", UVM_MEDIUM)
// cfg.clkmgr_vif.update_idle({NUM_TRANS{MuBi4True}});
// cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
//
// csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(initial_hints),
// .err_msg("All idle: expect status matches hints"));
//
// // Now set all hints, and the status should also be all ones.
// value = '1;
// csr_wr(.ptr(ral.clk_hints), .value(value));
// cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES);
// // We expect all units to be on.
// csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value),
// .err_msg("All idle and all hints high: units status should be high"));
//
// // Set hints to the reset value for stress tests.
// csr_wr(.ptr(ral.clk_hints), .value(ral.clk_hints.get_reset()));
// end
// endtask : body
//
// task drive_idle(ref mubi_hintables_t tbl);
// int period;
// mubi_hintables_t rand_idle;
// foreach (rand_idle[i])
// rand_idle[i] = get_rand_mubi4_val(.t_weight(0), .f_weight(0), .other_weight(1));
//
// @cfg.clkmgr_vif.trans_cb;
// cfg.clkmgr_vif.idle_i = rand_idle;
//
// tbl = rand_idle;
// endtask : drive_idle
endclass : clkmgr_trans_vseq
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@
`include "clkmgr_regwen_vseq.sv"
`include "clkmgr_smoke_vseq.sv"
`include "clkmgr_stress_all_vseq.sv"
`include "clkmgr_trans_vseq.sv"
12 changes: 0 additions & 12 deletions hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/sva/clkmgr_bind.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,7 @@ module clkmgr_bind;
);

% endfor
// Assertions for transactional clocks.
% for clk, sig in typed_clocks['hint_clks'].items():
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),
.hint(reg2hw.clk_hints.${clk}_hint.q),
.idle(idle_i[${hint_names[clk]}] == prim_mubi_pkg::MuBi4True),
.scanmode(scanmode_i == prim_mubi_pkg::MuBi4True),
.status(hw2reg.clk_hints_status.${clk}_val.d),
.trans_clk(clocks_o.${clk})
);

% endfor
% if ext_clk_bypass:
bind clkmgr clkmgr_extclk_sva_if clkmgr_extclk_sva_if (
.clk_i,
Expand Down
18 changes: 2 additions & 16 deletions hw/vendor/lowrisc_ip/ip_templates/clkmgr/dv/tb.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,9 @@ module tb;
u_reg.u_fatal_err_code_shadow_storage_err.qs,
u_reg.u_fatal_err_code_idle_cnt.qs,
u_reg.u_fatal_err_code_reg_intg.qs
}),
.clk_enables({
% for clk in [c for c in reversed(typed_clocks['sw_clks'].values())]:
<% sep = "})," if loop.last else "," %>\
% if len(typed_clocks['sw_clks']) == 1:
reg2hw.clk_enables.q${sep}
% else:
reg2hw.clk_enables.clk_${clk['src_name']}_peri_en.q${sep}
% 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})
})
);

rst_shadowed_if rst_shadowed_if (
.rst_n(rst_n),
.rst_shadowed_n(rst_shadowed_n)
Expand Down
Loading
Loading