blob: 2442bead94d87590369f67edc8a7d88de4531d4d [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Implements functional coverage for PATTGEN.
interface pattgen_cov_if (
input logic clk_i
);
import uvm_pkg::*;
import dv_utils_pkg::*;
import pattgen_env_pkg::*;
`include "dv_fcov_macros.svh"
`include "uvm_macros.svh"
parameter uint NO_DATA_BINS = 10;
parameter uint NO_PREDIV_BINS = 10;
parameter uint NO_REPS_BINS = 5;
parameter uint NO_LEN_BINS = 5;
`define CH0_PATH u_pattgen_core.chan0
`define CH1_PATH u_pattgen_core.chan1
wire rep_cnt_en_ch0 = `CH0_PATH.rep_cnt_en;
wire rep_cnt_en_ch1 = `CH1_PATH.rep_cnt_en;
wire len_q0 = `CH0_PATH.len_q;
wire len_q1 = `CH1_PATH.len_q;
wire reps_q0 = `CH0_PATH.reps_q;
wire reps_q1 = `CH1_PATH.reps_q;
wire clk_cnt_q0 = `CH0_PATH.clk_cnt_q;
wire clk_cnt_q1 = `CH1_PATH.clk_cnt_q;
wire bit_cnt_q0 = `CH0_PATH.bit_cnt_q;
wire bit_cnt_q1 = `CH1_PATH.bit_cnt_q;
wire rep_cnt_q0 = `CH0_PATH.rep_cnt_q;
wire rep_cnt_q1 = `CH1_PATH.rep_cnt_q;
wire prediv_q0 = `CH0_PATH.prediv_q;
wire prediv_q1 = `CH1_PATH.prediv_q;
bit en_full_cov = 1'b1;
bit en_intg_cov = 1'b1;
// If en_full_cov is set, then en_intg_cov
//must also be set since it is a subset.
bit en_intg_cov_loc;
assign en_intg_cov_loc = en_full_cov | en_intg_cov;
covergroup ctrl_cg @(posedge clk_i);
option.name = "ctrl_cg";
option.comment = "Enable and polarity coverage";
cp_enable_ch0: coverpoint `CH0_PATH.enable;
cp_enable_ch1: coverpoint `CH1_PATH.enable;
cp_polarity_ch0: coverpoint `CH0_PATH.polarity_q;
cp_polarity_ch1: coverpoint `CH1_PATH.polarity_q;
cross_contr: cross cp_enable_ch0, cp_enable_ch1,
cp_polarity_ch0, cp_polarity_ch1;
endgroup : ctrl_cg
`DV_FCOV_INSTANTIATE_CG(ctrl_cg, en_full_cov)
wire ch0_cnt_match_prediv = (prediv_q0 == clk_cnt_q0);
wire ch0_cnt_reset = (clk_cnt_q0 == 0);
wire ch0_cnt_match_len = (len_q0 == bit_cnt_q0);
wire ch0_cnt_len_reset = (bit_cnt_q0 == 0);
wire ch0_cnt_match_reps = (reps_q0 == rep_cnt_q0);
wire ch0_cnt_reset_reps = (rep_cnt_q0 == 0);
wire ch1_cnt_match_prediv = (prediv_q1 == clk_cnt_q1);
wire ch1_cnt_reset = (clk_cnt_q1 == 0);
wire ch1_cnt_match_len = (len_q1 == bit_cnt_q1);
wire ch1_cnt_len_reset = (bit_cnt_q1 == 0);
wire ch1_cnt_match_reps = (reps_q1 == rep_cnt_q1);
wire ch1_cnt_reset_reps = (rep_cnt_q1 == 0);
covergroup pattgen_ch0_cnt_reset_cg @(posedge clk_i);
option.name = "ch0_cnt_reset_cg";
option.comment = "Counters reset after match";
cp_reps_trans_ch0: coverpoint {ch0_cnt_match_reps, ch0_cnt_reset_reps, rep_cnt_en_ch0}{
bins trans2Zero_reps = (3'b100 => 3'b101 => 3'b010);
bins others = default;
}
cp_reps_reset_trans_ch0: coverpoint {ch0_cnt_match_reps, ch0_cnt_reset_reps}{
bins trans2Zero_reps = (2'b10 => 2'b01);
bins others = default;
}
cp_len_reset_trans_ch0: coverpoint {ch0_cnt_match_len, ch0_cnt_len_reset}{
bins trans2Zero_len = (2'b10 => 2'b01);
bins others = default;
}
cp_prediv_reset_trans_ch0: coverpoint {ch0_cnt_match_prediv, ch0_cnt_reset}{
bins trans2Zero_prediv = (2'b10 => 2'b01);
bins others = default;
}
cp_cross_reps_len_prediv: cross cp_reps_reset_trans_ch0, cp_len_reset_trans_ch0,
cp_len_reset_trans_ch0;
cp_match_reps_tr_ch0: coverpoint {ch0_cnt_match_reps}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
cp_reset_reps_tr_ch0: coverpoint {ch0_cnt_reset_reps}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
cp_rep_cnt_en_tr_ch0: coverpoint {rep_cnt_en_ch0}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
endgroup : pattgen_ch0_cnt_reset_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_ch0_cnt_reset_cg, en_full_cov)
covergroup pattgen_ch1_cnt_reset_cg @(posedge clk_i);
option.name = "ch1_cnt_reset_cg";
option.comment = "Counters reset after match";
cp_reps_trans_ch1: coverpoint {ch1_cnt_match_reps, ch1_cnt_reset_reps, rep_cnt_en_ch1}{
bins trans2Zero_reps = (3'b100 => 3'b101 => 3'b010);
bins others = default;
}
cp_reps_reset_trans_ch1: coverpoint {ch1_cnt_match_reps, ch1_cnt_reset_reps}{
bins trans2Zero_reps = (2'b10 => 2'b01);
bins others = default;
}
cp_len_reset_trans_ch1: coverpoint {ch1_cnt_match_len, ch1_cnt_len_reset}{
bins trans2Zero_len = (2'b10 => 2'b01);
bins others = default;
}
cp_prediv_reset_trans_ch1: coverpoint {ch1_cnt_match_prediv, ch1_cnt_reset}{
bins trans2Zero_prediv = (2'b10 => 2'b01);
bins others = default;
}
cp_cross_reps_len_prediv_ch1: cross cp_reps_reset_trans_ch1, cp_len_reset_trans_ch1,
cp_len_reset_trans_ch1;
cp_match_reps_tr_ch1: coverpoint {ch1_cnt_match_reps}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
cp_reset_reps_tr_ch1: coverpoint {ch1_cnt_reset_reps}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
cp_rep_cnt_en_tr_ch1: coverpoint {rep_cnt_en_ch1}{
bins zero2one = (1'b0 => 1'b1);
bins one2zero = (1'b1 => 1'b0);
}
endgroup : pattgen_ch1_cnt_reset_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_ch1_cnt_reset_cg, en_full_cov)
covergroup inter_cg @(posedge clk_i);
option.name = "inter_cg";
option.comment = "Interrupts checking";
cp_intr_enab_ch0: coverpoint
u_pattgen_core.reg2hw.intr_enable.done_ch0.q;
cp_intr_state_ch0: coverpoint
u_pattgen_core.reg2hw.intr_state.done_ch0.q;
cp_intr_test_ch0: coverpoint
u_pattgen_core.reg2hw.intr_test.done_ch0.q;
intr_cross: cross cp_intr_enab_ch0, cp_intr_state_ch0, cp_intr_test_ch0;
endgroup : inter_cg
`DV_FCOV_INSTANTIATE_CG(inter_cg, en_full_cov)
//NOTE upper and lower parts of data cannot be accessed with CHAN* macro
//because channels receive merged 64 bit data.
covergroup pattgen_data_ch0_0_cg @(posedge clk_i);
option.name = "pattgen_data_ch0_0_cg";
option.comment = "Data coverage in LSB Chan0";
cp_data_ch00: coverpoint {tb.dut.u_pattgen_core.ch0_ctrl.data[31:0]}{
bins maxim = {DataMax};
bins mid[NO_DATA_BINS] = {[DataMin + 1:DataMax - 1]};
bins minim = {DataMin};
}
endgroup : pattgen_data_ch0_0_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_data_ch0_0_cg, en_full_cov)
covergroup pattgen_data_ch0_1_cg @(posedge clk_i);
option.name = "pattgen_data_ch0_1_cg";
option.comment = "Data coverage in MSB Chan0";
cp_data_ch01: coverpoint {tb.dut.u_pattgen_core.ch0_ctrl.data[63:32]}{
bins maxim = {DataMax};
bins mid[NO_DATA_BINS] = {[DataMin +1:DataMax - 1]};
bins minim = {DataMin};
}
endgroup : pattgen_data_ch0_1_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_data_ch0_1_cg, en_full_cov)
covergroup pattgen_data_ch1_0_cg @(posedge clk_i);
option.name = "pattgen_data_ch1_0_cg";
option.comment = "Data coverage in LSB Chan1";
cp_data_ch10: coverpoint {tb.dut.u_pattgen_core.ch1_ctrl.data[31:0]}{
bins maxim = {DataMax};
bins mid[NO_DATA_BINS] = {[DataMin +1 : DataMax - 1]};
bins minim = {DataMin};
}
endgroup : pattgen_data_ch1_0_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_data_ch1_0_cg, en_full_cov)
covergroup pattgen_data_ch1_1_cg @(posedge clk_i);
option.name = "pattgen_data_ch1_1_cg";
option.comment = "Data coverage in MSB Chan1";
cp_data_ch11: coverpoint {tb.dut.u_pattgen_core.ch1_ctrl.data[63:32]}{
bins maxim = {DataMax};
bins mid[NO_DATA_BINS] = {[DataMin + 1:DataMax - 1]};
bins minim = {DataMin};
}
endgroup : pattgen_data_ch1_1_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_data_ch1_1_cg, en_full_cov)
covergroup pattgen_prediv_ch0_cg @(posedge clk_i);
option.name = "pattgen_prediv_ch0_cg";
option.comment = "Chan0 Pre-divide clock coefficient coverage";
cp_prediv_ch0: coverpoint {prediv_q0}{
bins maxim = {PredivMaxValue};
bins mid[NO_PREDIV_BINS] = {[PredivMinValue + 1:PredivMaxValue - 1]};
bins minim = {PredivMinValue};
}
endgroup : pattgen_prediv_ch0_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_prediv_ch0_cg, en_full_cov)
covergroup pattgen_prediv_ch1_cg @(posedge clk_i);
option.name = "pattgen_prediv_ch1_cg";
option.comment = "Chan1 Pre-divide clock coefficient coverage";
cp_prediv_ch1: coverpoint {prediv_q1}{
bins maxim = {PredivMaxValue};
bins mid[NO_PREDIV_BINS] = {[PredivMinValue + 1:PredivMaxValue - 1]};
bins minim = {PredivMinValue};
}
endgroup : pattgen_prediv_ch1_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_prediv_ch1_cg, en_full_cov)
covergroup pattgen_reps_ch0_cg @(posedge clk_i);
option.name = "pattgen_reps_ch0_cg";
option.comment = "Chan0 repetition coefficient coverage";
cp_reps_ch0: coverpoint {reps_q0}{
bins maxim = {RepsMaxValue};
bins mid[NO_REPS_BINS] = {[RepsMinValue + 1:RepsMaxValue - 1]};
bins minim = {RepsMinValue};
}
endgroup : pattgen_reps_ch0_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_reps_ch0_cg, en_full_cov)
covergroup pattgen_reps_ch1_cg @(posedge clk_i);
option.name = "pattgen_reps_ch1_cg";
option.comment = "Chan1 repetition coefficient coverage";
cp_reps_ch1: coverpoint {reps_q1}{
bins maxim_1 = {RepsMaxValue};
bins mid_1[NO_REPS_BINS] = {[RepsMinValue + 1:RepsMaxValue - 1]};
bins minim_1 = {RepsMinValue};
}
endgroup : pattgen_reps_ch1_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_reps_ch1_cg, en_full_cov)
covergroup pattgen_len_ch0_cg @(posedge clk_i);
option.name = "pattgen_len_ch0_cg";
option.comment = "Chan0 length coverage";
cp_len_ch0: coverpoint {len_q0}{
bins maxim = {LenMaxValue};
bins middle[NO_LEN_BINS] = {[LenMinValue + 1:LenMaxValue - 1]};
bins minim = {LenMinValue};
}
endgroup : pattgen_len_ch0_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_len_ch0_cg, en_full_cov)
covergroup pattgen_len_ch1_cg @(posedge clk_i);
option.name = "pattgen_len_ch1_cg";
option.comment = "Chan1 length coverage";
cp_len_ch1: coverpoint {len_q1}{
bins maxim_1 = {LenMaxValue};
bins middle_1[NO_LEN_BINS] = {[LenMinValue + 1:LenMaxValue - 1]};
bins minim_1 = {LenMinValue};
}
endgroup : pattgen_len_ch1_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_len_ch1_cg, en_full_cov)
covergroup roll_cg @(posedge clk_i);
option.name = "roll_cg";
option.comment = "Cover max/min values of counters";
cp_prediv_cnt_ch0: coverpoint {prediv_q0}{
bins maxim_0 = {'hffffffff};
bins mid_range_0[NO_PREDIV_BINS] = {[1:'hfffffffe]};
bins minim_0 = {0};
}
cp_prediv_cnt_ch1: coverpoint {prediv_q1}{
bins maxim_1 = {'hffffffff};
bins mid_range_1[NO_PREDIV_BINS] = {[1:'hfffffffe]};
bins minim_1 = {0};
}
cp_len_cnt_ch0: coverpoint {len_q0}{
bins maxim_0 = {'h3f};
bins mid_range_0[NO_LEN_BINS] = {[1:'h3e]};
bins minim_0 = {0};
}
cp_len_cnt_ch1: coverpoint {len_q1}{
bins maxim_1 = {'h3f};
bins mid_range_1[NO_LEN_BINS] = {[1:'h3e]};
bins minim_1 = {0};
}
cp_reps_cnt_ch0: coverpoint {reps_q0}{
bins maxim_0 = {'h3ff};
bins mid_range_0[NO_REPS_BINS] = {[1:'h3fe]};
bins minim_0 = {0};
}
cp_reps_cnt_ch1: coverpoint {reps_q1}{
bins maxim_1 = {'h3ff};
bins mid_range_1[NO_REPS_BINS] = {[1:'h3fe]};
bins minim_1 = {0};
}
cross_rollover_cnt_ch0: cross cp_prediv_cnt_ch0, cp_len_cnt_ch0, cp_reps_cnt_ch0;
cross_rollover_cnt_ch1: cross cp_prediv_cnt_ch1, cp_len_cnt_ch1, cp_reps_cnt_ch1;
endgroup : roll_cg
`DV_FCOV_INSTANTIATE_CG(roll_cg, en_full_cov)
covergroup pattgen_op_cg @(posedge clk_i);
option.name = "pattgen_op_cg";
option.comment = "Chan0 and Chan1 interrupt done and event done coverage";
cp_intr_done_ch0_o: coverpoint u_pattgen_core.intr_done_ch0_o;
cp_intr_done_ch1_o: coverpoint u_pattgen_core.intr_done_ch1_o;
cp_event_done_ch0: coverpoint `CH0_PATH.event_done_o;
cp_event_done_ch1: coverpoint `CH1_PATH.event_done_o;
endgroup : pattgen_op_cg
`DV_FCOV_INSTANTIATE_CG(pattgen_op_cg, en_full_cov)
endinterface : pattgen_cov_if