blob: 89efcd41e83db0e88048c67aa200e803828fdaf5 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// put these covergoups outside the class in order to create them anywhere after get cfg object
// if more than one interrupt/alert registers, these can be reused
// in extended cov class, better to have the covergroup inside the class and create in new function
covergroup intr_cg (uint num_interrupts) with function sample(uint intr,
bit intr_en,
bit intr_state);
cp_intr: coverpoint intr {
bins all_values[] = {[0:num_interrupts-1]};
}
cp_intr_en: coverpoint intr_en;
cp_intr_state: coverpoint intr_state;
cross cp_intr, cp_intr_en, cp_intr_state;
endgroup
covergroup intr_test_cg (uint num_interrupts) with function sample(uint intr,
bit intr_test,
bit intr_en,
bit intr_state);
cp_intr: coverpoint intr {
bins all_values[] = {[0:num_interrupts-1]};
}
cp_intr_test: coverpoint intr_test;
cp_intr_en: coverpoint intr_en;
cp_intr_state: coverpoint intr_state;
cross cp_intr, cp_intr_test, cp_intr_en, cp_intr_state {
illegal_bins test_1_state_0 = binsof(cp_intr_test) intersect {1} &&
binsof(cp_intr_state) intersect {0};
}
endgroup
covergroup intr_pins_cg (uint num_interrupts) with function sample(uint intr_pin,
bit intr_pin_value);
cp_intr_pin: coverpoint intr_pin {
bins all_pins[] = {[0:num_interrupts-1]};
}
cp_intr_pin_value: coverpoint intr_pin_value {
bins values[] = {0, 1};
bins transitions[] = (0 => 1), (1 => 0);
}
cp_intr_pins_all_values: cross cp_intr_pin, cp_intr_pin_value;
endgroup
// This covergroup sampled at changing edges of both clocks.
covergroup resets_cg (string name) with function sample(logic [1:0] resets);
option.per_instance = 1;
option.name = name;
resets_trans: coverpoint resets {
// This coverpoint collects the toggle coverage as below:
// _ _ _ _ _ _
// RESET1 |_ _ _ _|
// _ _ _ _ _ _ _ _
// RESET0 |_ _ _ _|
bins rst1_start_first_end_first = ('b01 => 'b00 => 'b10 => 'b11);
// This coverpoint collects the toggle coverage as below:
// _ _ _ _ _ _ _ _
// RESET1 |_ _ _ _|
// _ _ _ _ _ _ _
// RESET0 |_ _ _ _|
bins rst1_start_last_end_last = ('b10 => 'b00 => 'b01 => 'b11);
// This coverpoint collects the toggle coverage as below:
// _ _ _ _ _ _ _ _
// RESET1 |_ _ _ _|
// _ _ _ _ _ _ _ _ _
// RESET0 |_ _|
bins rst1_start_first_end_last = ('b01 => 'b00 => 'b01 => 'b11);
// This coverpoint collects the toggle coverage as below:
// _ _ _ _ _ _ _ _ _
// RESET1 |_ _|
// _ _ _ _ _ _ _ _
// RESET0 |_ _ _ _|
bins rst1_start_last_end_first = ('b10 => 'b00 => 'b10 => 'b11);
}
endgroup
class tl_errors_cg_wrap;
// This covergroup sampled all kinds of TL error cases.
covergroup tl_errors_cg (string name)
with function sample(bit unmapped_err,
bit csr_size_err,
bit mem_byte_access_err,
bit mem_wo_err,
bit mem_ro_err,
bit tl_protocol_err,
bit write_w_instr_type_err,
bit instr_type_err);
option.per_instance = 1;
option.name = name;
// these cp should be disabled (set weight to 0), when they're not applicable for the block
cp_unmapped_err: coverpoint unmapped_err;
cp_csr_size_err: coverpoint csr_size_err;
cp_mem_byte_access_err: coverpoint mem_byte_access_err;
cp_mem_wo_err: coverpoint mem_wo_err;
cp_mem_ro_err: coverpoint mem_ro_err;
// we don't enumerate the various kinds of TL protocol errors here because there is a covergroup
// in tl_agent, which covers those
// No need to cover the case of 0, as protocol error may be the only error and 0 never happens.
cp_tl_protocol_err: coverpoint tl_protocol_err {
bins covered = {1};
}
cp_write_w_instr_type_err: coverpoint write_w_instr_type_err;
cp_instr_type_err: coverpoint instr_type_err;
endgroup
// Function: new
function new(string name);
tl_errors_cg = new(name);
endfunction : new
// Function: sample
function void sample(bit unmapped_err,
bit csr_size_err,
bit mem_byte_access_err,
bit mem_wo_err,
bit mem_ro_err,
bit tl_protocol_err,
bit write_w_instr_type_err,
bit instr_type_err);
tl_errors_cg.sample(unmapped_err, csr_size_err, mem_byte_access_err, mem_wo_err,
mem_ro_err, tl_protocol_err, write_w_instr_type_err, instr_type_err);
endfunction : sample
endclass
class tl_intg_err_cg_wrap;
// This covergroup sampled all kinds of TL integrity error and numbers of error bits.
covergroup tl_intg_err_cg (string name) with function sample(tl_intg_err_e tl_intg_err_type,
uint num_cmd_err_bits,
uint num_data_err_bits,
bit is_mem);
option.per_instance = 1;
option.name = name;
cp_tl_intg_err_type: coverpoint tl_intg_err_type;
cp_num_cmd_err_bits: coverpoint num_cmd_err_bits {
bins values[] = {[0:MAX_TL_ECC_ERRORS]};
}
cp_num_data_err_bits: coverpoint num_data_err_bits {
bins values[] = {[0:MAX_TL_ECC_ERRORS]};
}
cp_is_mem: coverpoint is_mem;
endgroup
// Function: new
function new(string name);
tl_intg_err_cg = new(name);
endfunction : new
// Function: sample
function void sample(tl_intg_err_e tl_intg_err_type,
uint num_cmd_err_bits,
uint num_data_err_bits,
bit is_mem);
tl_intg_err_cg.sample(tl_intg_err_type, num_cmd_err_bits, num_data_err_bits, is_mem);
endfunction : sample
endclass
class tl_intg_err_mem_subword_cg_wrap;
// Design handles mem subword write specially. Add this CG to cover all types subword write
// with integrity errors
covergroup tl_intg_err_mem_subword_cg (string name) with function sample(
tl_intg_err_e tl_intg_err_type,
bit write,
int num_enable_bytes);
option.per_instance = 1;
option.name = name;
cp_tl_intg_err_type: coverpoint tl_intg_err_type;
cp_num_num_enable_bytes: coverpoint num_enable_bytes {
bins full_word = {BUS_DW / 8};
bins partial = {[0 : BUS_DW / 8 - 1]};
}
cp_write: coverpoint write;
cr_all: cross cp_tl_intg_err_type, cp_num_num_enable_bytes, cp_write;
endgroup
// Function: new
function new(string name);
tl_intg_err_mem_subword_cg = new(name);
endfunction : new
// Function: sample
function void sample(tl_intg_err_e tl_intg_err_type,
uint write,
uint num_enable_bytes);
tl_intg_err_mem_subword_cg.sample(tl_intg_err_type, write, num_enable_bytes);
endfunction : sample
endclass
class cip_base_env_cov #(type CFG_T = cip_base_env_cfg) extends dv_base_env_cov #(CFG_T);
`uvm_component_param_utils(cip_base_env_cov #(CFG_T))
intr_cg intr_cg;
intr_test_cg intr_test_cg;
intr_pins_cg intr_pins_cg;
resets_cg resets_cg;
// Coverage for sticky interrupt functionality described in CIP specification
// As some interrupts are non-sticky, this covergroup should be populated on "as and when needed"
// basis in extended <ip>_env_cov class for interrupt types that are sticky
bit_toggle_cg_wrap sticky_intr_cov[string];
`uvm_component_new
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (cfg.num_interrupts != 0) begin
intr_cg = new(cfg.num_interrupts);
intr_test_cg = new(cfg.num_interrupts);
intr_pins_cg = new(cfg.num_interrupts);
end
if (cfg.num_edn) resets_cg = new("dut_and_edn_rsts");
endfunction
endclass