[pattgen, dv] Update pattgen dv
- Add functional coverage dv/cov
- Update scoreboard for coverage
Signed-off-by: Hoang Tung <Hoang.Tung@wdc.com>
diff --git a/hw/ip/pattgen/data/pattgen_testplan.hjson b/hw/ip/pattgen/data/pattgen_testplan.hjson
index 5d64b48..3275a90 100644
--- a/hw/ip/pattgen/data/pattgen_testplan.hjson
+++ b/hw/ip/pattgen/data/pattgen_testplan.hjson
@@ -5,7 +5,7 @@
name: "pattgen"
import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson",
"hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson",
-"hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson",
+ "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson",
"hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson"],
entries: [
{
diff --git a/hw/ip/pattgen/dv/cov/pattgen_cov.core b/hw/ip/pattgen/dv/cov/pattgen_cov.core
new file mode 100644
index 0000000..26d55ed
--- /dev/null
+++ b/hw/ip/pattgen/dv/cov/pattgen_cov.core
@@ -0,0 +1,20 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:dv:pattgen_cov:0.1"
+description: "PATTGEN functional coverage interface & bind."
+
+filesets:
+ files_dv:
+ depend:
+ - lowrisc:dv:dv_utils
+ files:
+ - pattgen_cov_if.sv
+ - pattgen_cov_bind.sv
+ file_type: systemVerilogSource
+
+targets:
+ default:
+ filesets:
+ - files_dv
diff --git a/hw/ip/pattgen/dv/cov/pattgen_cov_bind.sv b/hw/ip/pattgen/dv/cov/pattgen_cov_bind.sv
new file mode 100644
index 0000000..82c936c
--- /dev/null
+++ b/hw/ip/pattgen/dv/cov/pattgen_cov_bind.sv
@@ -0,0 +1,10 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Binds PATTGEN functional coverage interaface to the top level PATTGEN module.
+module pattgen_cov_bind;
+
+ bind pattgen pattgen_cov_if u_pattgen_cov_if (.*);
+
+endmodule
diff --git a/hw/ip/pattgen/dv/cov/pattgen_cov_if.sv b/hw/ip/pattgen/dv/cov/pattgen_cov_if.sv
new file mode 100644
index 0000000..a1bf1c6
--- /dev/null
+++ b/hw/ip/pattgen/dv/cov/pattgen_cov_if.sv
@@ -0,0 +1,82 @@
+// 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::*;
+ `include "dv_fcov_macros.svh"
+
+ 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;
+
+ bit ch0_perf, ch1_perf;
+ assign ch0_perf = {u_pattgen_core.ch0_ctrl.len,
+ u_pattgen_core.ch0_ctrl.reps,
+ u_pattgen_core.ch0_ctrl.prediv} == 'h0;
+ assign ch1_perf = {u_pattgen_core.ch1_ctrl.len,
+ u_pattgen_core.ch1_ctrl.reps,
+ u_pattgen_core.ch1_ctrl.prediv} == 'h0;
+
+ covergroup pattgen_op_cg @(u_pattgen_core.ch0_ctrl.enable or u_pattgen_core.ch1_ctrl.enable);
+ option.name = "pattgen_op_cg";
+ option.comment = "PATTGEN CH0 and CH1 operation";
+ option.per_instance = 1;
+
+ // Channel 0 coverpoints
+ cp_enable: coverpoint {u_pattgen_core.ch1_ctrl.enable, u_pattgen_core.ch0_ctrl.enable} {
+ bins CH0_ENABLE = (2'b00 => 2'b01);
+ bins CH0_DISABLE = (2'b01 => 2'b00);
+ bins CH1_ENABLE = (2'b00 => 2'b10);
+ bins CH1_DISABLE = (2'b10 => 2'b00);
+ bins CHX_ENABLE = (2'b00 => 2'b11); // CHX: dual channels
+ bins CHX_DISABLE = (2'b11 => 2'b00);
+ bins CHX_OTHERS = default;
+ }
+ // Channel 0 coverpoints
+ cp_ch0_perf: coverpoint {ch0_perf} {
+ bins LOW_PERF = {'h0};
+ bins TYP_PERF = {!'h0};
+ }
+ cp_ch0_polarity: coverpoint {u_pattgen_core.ch0_ctrl.polarity} {
+ bins TX_CLK_FALL = {1'b0};
+ bins TX_CLK_RISE = {1'b1};
+ }
+
+ // Channel 1 coverpoints
+ cp_ch1_perf: coverpoint {ch1_perf} {
+ bins LOW_PERF = {'h0};
+ bins TYP_PERF = {!'h0};
+ }
+ cp_ch1_polarity: coverpoint {u_pattgen_core.ch1_ctrl.polarity} {
+ bins TX_CLK_FALL = {1'b0};
+ bins TX_CLK_RISE = {1'b1};
+ }
+
+ // Cross coverpoints
+ cr_ch0_op: cross cp_enable, cp_ch0_polarity, cp_ch0_perf {
+ bins CH0_OP_ENABLE = binsof(cp_enable.CH0_ENABLE);
+ bins CH0_OP_DISABLE = binsof(cp_enable.CH0_DISABLE);
+ }
+ cr_ch1_op: cross cp_enable, cp_ch1_polarity, cp_ch1_perf {
+ bins CH1_OP_ENABLE = binsof(cp_enable.CH1_ENABLE);
+ bins CH1_OP_DISABLE = binsof(cp_enable.CH1_DISABLE);
+ }
+ cr_chx_op: cross cp_enable, cp_ch0_polarity, cp_ch0_perf, cp_ch1_polarity, cp_ch1_perf {
+ bins CHX_OP_ENABLE = binsof(cp_enable.CHX_ENABLE);
+ bins CHX_OP_DISABLE = binsof(cp_enable.CHX_DISABLE);
+ }
+
+ endgroup : pattgen_op_cg
+
+ `DV_FCOV_INSTANTIATE_CG(pattgen_op_cg, en_full_cov)
+
+endinterface : pattgen_cov_if
diff --git a/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv b/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
index 41c3b86..e95cd53 100644
--- a/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
+++ b/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
@@ -10,10 +10,6 @@
`uvm_component_utils(pattgen_scoreboard)
`uvm_component_new
- //****************************************************
- // TODO: This is still WIP (cleaned up later)
- //****************************************************
-
// TLM fifos hold the transactions sent by monitor
uvm_tlm_analysis_fifo #(pattgen_item) item_fifo[NUM_PATTGEN_CHANNELS];
@@ -23,6 +19,7 @@
local pattgen_item exp_item_q[NUM_PATTGEN_CHANNELS][$];
// local variables
local pattgen_channel_cfg channel_cfg[NUM_PATTGEN_CHANNELS-1:0];
+ local bit [NumPattgenIntr-1:0] intr_exp_at_addr_phase;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
@@ -34,11 +31,17 @@
task run_phase(uvm_phase phase);
super.run_phase(phase);
- for (uint i = 0; i < NUM_PATTGEN_CHANNELS; i++) begin
- fork
- automatic uint channel = i;
- compare_trans(channel);
- join_none
+ forever begin
+ `DV_SPINWAIT_EXIT(
+ for (uint i = 0; i < NUM_PATTGEN_CHANNELS; i++) begin
+ fork
+ automatic uint channel = i;
+ compare_trans(channel);
+ join_none
+ end
+ wait fork;,
+ @(negedge cfg.clk_rst_vif.rst_n),
+ )
end
endtask : run_phase
@@ -48,6 +51,9 @@
bit do_read_check = 1'b1;
bit write = item.is_write();
+ bit addr_phase_write = (write && channel == AddrChannel);
+ bit data_phase_read = (!write && channel == DataChannel);
+
uvm_reg_addr_t csr_addr = ral.get_word_aligned_addr(item.a_addr);
// if access was to a valid csr, get the csr handle
if (csr_addr inside {cfg.csr_addrs}) begin
@@ -58,7 +64,7 @@
end
// address write phase
- if (write && channel == AddrChannel) begin
+ if (addr_phase_write) begin
// if incoming access is a write to a valid csr, then make updates right away
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
@@ -131,7 +137,12 @@
// no special handle is needed
end
"intr_state": begin
- // TODO: add coverage
+ bit[TL_DW-1:0] intr_wdata = item.a_data;
+ fork begin
+ bit [NumPattgenIntr-1:0] pre_intr = intr_exp;
+ cfg.clk_rst_vif.wait_clks(1);
+ intr_exp &= ~intr_wdata;
+ end join_none
end
default: begin
`uvm_fatal(`gfn, $sformatf("\n scb: write to invalid csr: %0s", csr.get_full_name()))
@@ -139,10 +150,13 @@
endcase
end
- // On reads, if do_read_check, is set, then check mirrored_value against item.d_data
- if (!write && channel == DataChannel) begin
+ // On reads and & data phase, if do_read_check, is set, then
+ // check mirrored_value against item.d_data
+ if (data_phase_read) begin
case (csr.get_name())
"intr_state": begin
+ pattgen_intr_e intr;
+ bit [TL_DW-1:0] intr_en = ral.intr_enable.get_mirrored_value();
do_read_check = 1'b0;
// done_ch0/done_ch1 is asserted to indicate a pattern is completely generated
reg_value = item.d_data;
@@ -153,6 +167,13 @@
for (uint i = 0; i < NUM_PATTGEN_CHANNELS; i++) begin
generate_exp_items(.channel(i), .error_injected(1'b0));
end
+ foreach (intr_exp[i]) begin
+ intr = pattgen_intr_e'(i); // cast to enum to get interrupt name
+ if (cfg.en_cov) begin
+ cov.intr_cg.sample(intr, intr_en[intr], intr_exp[intr]);
+ cov.intr_pins_cg.sample(intr, cfg.intr_vif.pins[intr]);
+ end
+ end
end
"ctrl", "size", "intr_test", "intr_enable",
"prediv_ch0", "data_ch0_0", "data_ch0_1",
diff --git a/hw/ip/pattgen/dv/env/seq_lib/pattgen_perf_vseq.sv b/hw/ip/pattgen/dv/env/seq_lib/pattgen_perf_vseq.sv
index 730d926..599f451 100644
--- a/hw/ip/pattgen/dv/env/seq_lib/pattgen_perf_vseq.sv
+++ b/hw/ip/pattgen/dv/env/seq_lib/pattgen_perf_vseq.sv
@@ -23,7 +23,7 @@
1'b0 :/ cfg.seq_cfg.pattgen_low_polarity_pct,
1'b1 :/ (100 - cfg.seq_cfg.pattgen_low_polarity_pct)
};
- ch_cfg.prediv dist {0 :/ 1, 1024 :/ 2};
+ ch_cfg.prediv dist {0 :/ 1, 1024 :/ 1};
ch_cfg.len dist {0 :/ 1, 1023 :/ 1};
ch_cfg.reps dist {0 :/ 1, 63 :/ 1};
// dependent constraints
diff --git a/hw/ip/pattgen/dv/pattgen_sim.core b/hw/ip/pattgen/dv/pattgen_sim.core
index 2b63661..4550314 100644
--- a/hw/ip/pattgen/dv/pattgen_sim.core
+++ b/hw/ip/pattgen/dv/pattgen_sim.core
@@ -13,6 +13,7 @@
depend:
- lowrisc:dv:pattgen_test
- lowrisc:dv:pattgen_sva
+ - lowrisc:dv:pattgen_cov
files:
- tb.sv
file_type: systemVerilogSource
diff --git a/hw/ip/pattgen/dv/pattgen_sim_cfg.hjson b/hw/ip/pattgen/dv/pattgen_sim_cfg.hjson
index 33ae366..0e3f898 100644
--- a/hw/ip/pattgen/dv/pattgen_sim_cfg.hjson
+++ b/hw/ip/pattgen/dv/pattgen_sim_cfg.hjson
@@ -41,7 +41,13 @@
// Default UVM test and seq class name.
uvm_test: pattgen_base_test
- uvm_test_seq: pattgen_base_vseq
+ uvm_test_seq: pattgen_base_vseq,
+
+ // additional top for coverage
+ sim_tops: [ "pattgen_bind", "pattgen_cov_bind"]
+
+ // Pattgen functional coverage
+ xcelium_cov_refine_files: ["{proj_root}/hw/ip/pattgen/dv/cov/pattgen_cov.vRefine"]
// List of test specifications.
tests: [