mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
This commit is contained in:
@@ -63,6 +63,7 @@ Daniel Bates
|
||||
Danny Oler
|
||||
Dave Sargeant
|
||||
David Garau
|
||||
David Harris
|
||||
David Horton
|
||||
David Ledger
|
||||
David Metz
|
||||
|
||||
+15
-10
@@ -880,10 +880,12 @@ class ParamProcessor final {
|
||||
V3LinkDotIfaceCapture::forEach([&](const V3LinkDotIfaceCapture::CapturedEntry& entry) {
|
||||
if (!entry.refp) return;
|
||||
if (entry.cloneCellPath != cloneCP) return;
|
||||
UASSERT_OBJ(
|
||||
entry.ownerModp
|
||||
&& (entry.ownerModp == newModp || entry.ownerModp->name() == srcName),
|
||||
entry.refp, "clone ledger entry for '" << cloneCP << "' has unexpected owner");
|
||||
// Owner may also be a class nested in newModp (e.g. a covergroup).
|
||||
const AstNodeModule* const ownerp = entry.ownerModp;
|
||||
UASSERT_OBJ(ownerp == newModp || ownerp->name() == srcName
|
||||
|| ownerp->aboveLoopp() == newModp,
|
||||
entry.refp,
|
||||
"clone ledger entry for '" << cloneCP << "' has unexpected owner");
|
||||
if (entry.cellPath.empty()) return;
|
||||
|
||||
AstRefDType* const refp = entry.refp;
|
||||
@@ -1022,12 +1024,15 @@ class ParamProcessor final {
|
||||
if (AstRefDType* const clonedRefp = entry.refp->clonep()) {
|
||||
// Use newname (unique specialized module name) as cloneCellPath.
|
||||
const string cloneCP = newname;
|
||||
// A cloned captured ref lives inside srcModp's tree, so its owner
|
||||
// is srcModp (SV has no nested module definitions).
|
||||
UASSERT_OBJ(
|
||||
entry.ownerModp == srcModp, clonedRefp,
|
||||
"cloned captured RefDType owner is not the specialized module");
|
||||
AstNodeModule* const clonedOwnerp = newModp;
|
||||
// Owner is srcModp or a class nested in it (e.g. a covergroup);
|
||||
// cloneTree() populated clonep() for the nested case.
|
||||
AstNodeModule* clonedOwnerp = newModp;
|
||||
if (entry.ownerModp != srcModp) {
|
||||
clonedOwnerp = entry.ownerModp->clonep();
|
||||
UASSERT_OBJ(clonedOwnerp, clonedRefp,
|
||||
"captured RefDType owner was not cloned with the "
|
||||
"specialized module");
|
||||
}
|
||||
const V3LinkDotIfaceCapture::TemplateKey tkey{
|
||||
entry.ownerModp ? entry.ownerModp->name() : "", entry.refp->name(),
|
||||
entry.cellPath};
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
__vlAnonCG_cg.cp_insn.ecall: 1
|
||||
__vlAnonCG_cg2.cp_insn.ebreak: 1
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
import coverage_covergroup_common
|
||||
|
||||
test.scenarios('vlt_all')
|
||||
|
||||
coverage_covergroup_common.run(test)
|
||||
@@ -0,0 +1,85 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 David Harris
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
interface trace_if #(parameter int ILEN = 32, parameter int XLEN = 32) ();
|
||||
logic clk;
|
||||
logic [ILEN-1:0] insn;
|
||||
endinterface
|
||||
|
||||
package cov_pkg;
|
||||
|
||||
class TraceData #(parameter int ILEN = 32, parameter int XLEN = 32);
|
||||
logic [ILEN-1:0] insn;
|
||||
endclass
|
||||
|
||||
class Instr #(parameter int ILEN = 32, parameter int XLEN = 32);
|
||||
TraceData #(ILEN, XLEN) current;
|
||||
function new();
|
||||
current = new();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class CovBase #(parameter int ILEN = 32, parameter int XLEN = 32);
|
||||
typedef Instr #(ILEN, XLEN) ins_t;
|
||||
|
||||
// A virtual interface member is what puts an interface type reference
|
||||
// inside this class, alongside the covergroup below.
|
||||
virtual trace_if #(ILEN, XLEN) vif;
|
||||
|
||||
covergroup cg with function sample(ins_t ins);
|
||||
cp_insn: coverpoint ins.current.insn {
|
||||
bins ecall = {32'h00000073};
|
||||
}
|
||||
endgroup
|
||||
|
||||
// A second covergroup, so one nested class is preceded by another
|
||||
covergroup cg2 with function sample(ins_t ins);
|
||||
cp_insn: coverpoint ins.current.insn {
|
||||
bins ebreak = {32'h00100073};
|
||||
}
|
||||
endgroup
|
||||
|
||||
function new(virtual trace_if #(ILEN, XLEN) vif);
|
||||
this.vif = vif;
|
||||
cg = new();
|
||||
cg2 = new();
|
||||
endfunction
|
||||
|
||||
function void do_sample();
|
||||
ins_t ins = new();
|
||||
ins.current.insn = 32'h00000073;
|
||||
cg.sample(ins);
|
||||
ins.current.insn = 32'h00100073;
|
||||
cg2.sample(ins);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
endpackage
|
||||
|
||||
import cov_pkg::*;
|
||||
|
||||
class Cov #(parameter int ILEN = 32, parameter int XLEN = 32)
|
||||
extends CovBase #(ILEN, XLEN);
|
||||
function new(virtual trace_if #(ILEN, XLEN) vif);
|
||||
super.new(vif);
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module worker(trace_if vif);
|
||||
// Specialized from parameters read off the interface instance
|
||||
Cov #(vif.ILEN, vif.XLEN) cov;
|
||||
initial begin
|
||||
cov = new(vif);
|
||||
cov.do_sample();
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t;
|
||||
trace_if #(32, 64) vif();
|
||||
worker worker(vif);
|
||||
endmodule
|
||||
Reference in New Issue
Block a user