blob: 410d7d370003bf5d03798e1ada80c302fc46ee0e [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
/**
* Covergoups that are dependent on run-time parameters that may be available
* only in build_phase can be defined here
* Covergroups may also be wrapped inside helper classes if needed.
*/
// covergroup to sample all SW input bits are toggled and gated by regwen
class keymgr_sw_input_cg_wrap;
localparam int Width = bus_params_pkg::BUS_DW;
covergroup keymgr_sw_input_cg (string name)
with function sample(bit [Width-1:0] sw_input,
bit regwen);
option.per_instance = 1;
option.name = name;
sw_input_cp: coverpoint sw_input {
option.auto_bin_max = Width;
}
regwen_cp: coverpoint regwen;
sw_input_x_regwen_cr: cross sw_input_cp, regwen_cp;
endgroup
function new(string name);
keymgr_sw_input_cg = new(name);
endfunction : new
function void sample(bit [Width-1:0] sw_input, bit regwen);
keymgr_sw_input_cg.sample(sw_input, regwen);
endfunction : sample
endclass
class keymgr_env_cov extends cip_base_env_cov #(.CFG_T(keymgr_env_cfg));
`uvm_component_utils(keymgr_env_cov)
keymgr_sw_input_cg_wrap sw_input_cg_wrap[string];
// covergroup for keymgr state and operation with op_status and CDI sel, sideload destination
covergroup state_and_op_cg with function sample(keymgr_pkg::keymgr_working_state_e state,
keymgr_pkg::keymgr_ops_e op,
keymgr_pkg::keymgr_op_status_e op_status,
keymgr_cdi_type_e cdi,
keymgr_pkg::keymgr_key_dest_e dest);
state_cp: coverpoint state;
op_cp: coverpoint op;
op_status_cp: coverpoint op_status {
// only sample when op is done
ignore_bins illegal = {keymgr_pkg::OpIdle, keymgr_pkg::OpWip};
}
cdi_cp: coverpoint cdi iff (!(op inside {keymgr_pkg::OpAdvance, keymgr_pkg::OpDisable}));
dest_cp: coverpoint dest iff (op inside {keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut});
op_x_state_cross: cross op_cp, cdi_cp, dest_cp, state_cp;
op_x_status_cross: cross op_cp, cdi_cp, dest_cp, op_status_cp;
endgroup
// Covergroup to sample LC disable occurs at all the states or during operations
covergroup lc_disable_cg with function sample(keymgr_pkg::keymgr_working_state_e state,
keymgr_pkg::keymgr_ops_e op,
bit wip);
state_cp: coverpoint state;
op_cp: coverpoint op iff (wip == 1);
wip_cp: coverpoint wip;
// state crosses with wip or idle
state_x_wip_cross: cross state_cp, wip_cp;
// state crosses with operations
state_x_op_cross: cross state_cp, op_cp;
endgroup
// Covergroup to sample sideload_clear in all the states and followed by all the operations
covergroup sideload_clear_cg with function sample(bit [2:0] sideload_clear,
keymgr_pkg::keymgr_working_state_e state,
keymgr_pkg::keymgr_ops_e op,
bit aes_sl_avail,
bit kmac_sl_avail,
bit otbn_sl_avail,
bit regwen);
sideload_clear_cp: coverpoint sideload_clear {
bins clear_none = {0};
bins clear_one[] = {[1:3]};
bins clear_all = {[4:$]};
}
// the state where sideload_clear occurs
state_cp: coverpoint state;
// the operation followed by sideload_clear
op_cp: coverpoint op;
aes_sl_avail_cp: coverpoint aes_sl_avail;
kmac_sl_avail_cp: coverpoint kmac_sl_avail;
otbn_sl_avail_cp: coverpoint otbn_sl_avail;
regwen_cp: coverpoint regwen;
sideload_clear_x_state_op_cross: cross sideload_clear, state, op;
sideload_clear_x_sl_avail_cross: cross sideload_clear_cp, aes_sl_avail, kmac_sl_avail,
otbn_sl_avail;
sideload_clear_x_regwen_cross: cross sideload_clear_cp, regwen_cp;
endgroup
covergroup err_code_cg with function sample(keymgr_pkg::keymgr_err_pos_e err_code);
err_code_cp: coverpoint err_code {
// this is done in a direct test
ignore_bins ignore = {keymgr_pkg::ErrShadowUpdate};
illegal_bins illegal = {keymgr_pkg::ErrLastPos};
}
endgroup
covergroup invalid_hw_input_cg with function sample(
keymgr_invalid_hw_input_type_e invalid_hw_input);
invalid_hw_input_cp: coverpoint invalid_hw_input;
endgroup
covergroup fault_status_cg with function sample(keymgr_pkg::keymgr_fault_pos_e fault);
fault_cp: coverpoint fault {
// these are done in a direct test
ignore_bins ignore = {keymgr_pkg::FaultRegIntg, keymgr_pkg::FaultShadow};
illegal_bins illegal = {keymgr_pkg::FaultLastPos};
}
endgroup
// when async and sync fault both happen, use these 2 CP to enable both orders are covered
covergroup sync_async_fault_cross_cg with function sample(bit sync_fault_trig_first = 1,
bit async_fault_trig_first = 1);
sync_fault_trig_first_cp: coverpoint sync_fault_trig_first {
bins sync_first = {1};
}
async_fault_trig_first_cp: coverpoint async_fault_trig_first {
bins async_first = {1};
}
endgroup
// Covergroup to cover small values that TB can actually check EDN request sends correctly, and
// large values to make sure all bits are toggled
covergroup reseed_interval_cg with function sample(bit[15:0] reseed_interval);
reseed_interval_cp: coverpoint reseed_interval {
bins small_values[5] = {[50:100]};
bins large_values[32] = {[100:16'hffff]};
}
endgroup
// Covergroup to sample key version comparion with OpGenSwOut and OpGenHwOut in legal states
// When comparison is CompareOpGt, it's SW invalid input
covergroup key_version_compare_cg with function sample(compare_op_e key_version_cmp,
keymgr_pkg::keymgr_working_state_e state,
keymgr_pkg::keymgr_ops_e op);
key_version_cmp_cp: coverpoint key_version_cmp {
bins legal_values[] = {CompareOpEq, CompareOpGt, CompareOpLt};
}
state_cp: coverpoint state {
bins legal_states[] = {keymgr_pkg::StCreatorRootKey, keymgr_pkg::StOwnerIntKey,
keymgr_pkg::StOwnerKey};
}
op_cp: coverpoint op {
bins legal_states[] = {keymgr_pkg::OpGenSwOut, keymgr_pkg::OpGenHwOut};
}
key_ver_x_state_x_op_cross: cross key_version_cmp_cp, state_cp, op_cp;
endgroup
function new(string name, uvm_component parent);
super.new(name, parent);
state_and_op_cg = new();
lc_disable_cg = new();
sideload_clear_cg = new();
err_code_cg = new();
invalid_hw_input_cg = new();
fault_status_cg = new();
sync_async_fault_cross_cg = new();
reseed_interval_cg = new();
key_version_compare_cg = new();
endfunction : new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
foreach (cfg.ral.sealing_sw_binding[i]) begin
create_sw_input_cg_obj(cfg.ral.sealing_sw_binding[i].get_name());
end
foreach (cfg.ral.attest_sw_binding[i]) begin
create_sw_input_cg_obj(cfg.ral.attest_sw_binding[i].get_name());
end
foreach (cfg.ral.salt[i]) begin
create_sw_input_cg_obj(cfg.ral.salt[i].get_name());
end
foreach (cfg.ral.key_version[i]) begin
create_sw_input_cg_obj(cfg.ral.key_version[i].get_name());
end
create_sw_input_cg_obj(cfg.ral.max_creator_key_ver_shadowed.get_name());
create_sw_input_cg_obj(cfg.ral.max_owner_int_key_ver_shadowed.get_name());
create_sw_input_cg_obj(cfg.ral.max_owner_key_ver_shadowed.get_name());
create_sw_input_cg_obj(cfg.ral.start.get_name());
endfunction
virtual function void create_sw_input_cg_obj(string name);
sw_input_cg_wrap[name] = new(name);
endfunction
endclass