Add `--coverage-per-instance`
This commit is contained in:
parent
6b48b772d3
commit
cf8713aebc
|
|
@ -377,6 +377,7 @@ detailed descriptions of these arguments.
|
|||
--coverage-fsm Enable FSM state/arc coverage
|
||||
--coverage-line Enable line coverage
|
||||
--coverage-max-width <width> Maximum array depth for coverage
|
||||
--coverage-per-instance Enable per-instance coverage counters
|
||||
--coverage-toggle Enable toggle coverage
|
||||
--coverage-underscore Enable coverage of _signals
|
||||
--coverage-user Enable SVL user coverage
|
||||
|
|
|
|||
|
|
@ -317,6 +317,20 @@ Summary:
|
|||
toggle coverage. Defaults to 256, as covering large vectors may greatly
|
||||
slow coverage simulations.
|
||||
|
||||
.. option:: --coverage-per-instance
|
||||
|
||||
For Verilator-inserted coverage, preserve generated coverage counters and
|
||||
``.dat`` records per hierarchy instance. This option must be specified when
|
||||
Verilating the model, together with one or more coverage instrumentation
|
||||
options, for example :vlopt:`--coverage`, :vlopt:`--coverage-line`,
|
||||
:vlopt:`--coverage-toggle`, :vlopt:`--coverage-expr`,
|
||||
:vlopt:`--coverage-fsm`, or :vlopt:`--coverage-user`. It may increase
|
||||
generated model size, counter memory, coverage write time, and ``.dat`` file
|
||||
size.
|
||||
|
||||
This does not affect SystemVerilog ``cover``, which uses the IEEE-specified
|
||||
coverage option ``per_instance``.
|
||||
|
||||
.. option:: --coverage-toggle
|
||||
|
||||
Enables adding signal toggle coverage. See :ref:`Toggle Coverage`.
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ private:
|
|||
|
||||
if (v3Global.opt.coverage()) {
|
||||
puts("// Write coverage data (since Verilated with --coverage)\n");
|
||||
if (v3Global.opt.coveragePerInstance()) {
|
||||
puts("contextp->coveragep()->forcePerInstance(true);\n");
|
||||
}
|
||||
puts("contextp->coveragep()->write();\n");
|
||||
puts("\n");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-coverage-fsm", OnOff, &m_coverageFsm);
|
||||
DECL_OPTION("-coverage-line", OnOff, &m_coverageLine);
|
||||
DECL_OPTION("-coverage-max-width", Set, &m_coverageMaxWidth);
|
||||
DECL_OPTION("-coverage-per-instance", OnOff, &m_coveragePerInstance);
|
||||
DECL_OPTION("-coverage-toggle", OnOff, &m_coverageToggle);
|
||||
DECL_OPTION("-coverage-underscore", OnOff, &m_coverageUnderscore);
|
||||
DECL_OPTION("-coverage-user", OnOff, &m_coverageUser);
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ private:
|
|||
bool m_coverageExpr = false; // main switch: --coverage-expr
|
||||
bool m_coverageFsm = false; // main switch: --coverage-fsm
|
||||
bool m_coverageLine = false; // main switch: --coverage-block
|
||||
bool m_coveragePerInstance = false; // main switch: --coverage-per-instance
|
||||
bool m_coverageToggle = false; // main switch: --coverage-toggle
|
||||
bool m_coverageUnderscore = false; // main switch: --coverage-underscore
|
||||
bool m_coverageUser = false; // main switch: --coverage-func
|
||||
|
|
@ -524,6 +525,7 @@ public:
|
|||
bool coverageExpr() const { return m_coverageExpr; }
|
||||
bool coverageFsm() const { return m_coverageFsm; }
|
||||
bool coverageLine() const { return m_coverageLine; }
|
||||
bool coveragePerInstance() const { return m_coveragePerInstance; }
|
||||
bool coverageToggle() const { return m_coverageToggle; }
|
||||
bool coverageUnderscore() const { return m_coverageUnderscore; }
|
||||
bool coverageUser() const { return m_coverageUser; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
// // verilator_coverage annotation
|
||||
// DESCRIPTION: Verilator: Coverage per-instance hierarchy for duplicate module instances
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module child (
|
||||
input clk,
|
||||
input en
|
||||
);
|
||||
`ifdef INLINE_CHILD //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
%000001 reg [3:0] count = 0;
|
||||
-000001 point: type=line comment=block hier=tb.dut.u_a
|
||||
-000001 point: type=line comment=block hier=tb.dut.u_b
|
||||
|
||||
%000009 always @(posedge clk) begin
|
||||
-000009 point: type=line comment=block hier=tb.dut.u_a
|
||||
-000009 point: type=line comment=block hier=tb.dut.u_b
|
||||
%000008 if (en) begin
|
||||
-000004 point: type=branch comment=if hier=tb.dut.u_a
|
||||
-000001 point: type=branch comment=if hier=tb.dut.u_b
|
||||
-000005 point: type=branch comment=else hier=tb.dut.u_a
|
||||
-000008 point: type=branch comment=else hier=tb.dut.u_b
|
||||
%000004 count <= count + 1'b1;
|
||||
-000004 point: type=branch comment=if hier=tb.dut.u_a
|
||||
-000001 point: type=branch comment=if hier=tb.dut.u_b
|
||||
%000008 end else begin
|
||||
-000005 point: type=branch comment=else hier=tb.dut.u_a
|
||||
-000008 point: type=branch comment=else hier=tb.dut.u_b
|
||||
%000008 count <= count;
|
||||
-000005 point: type=branch comment=else hier=tb.dut.u_a
|
||||
-000008 point: type=branch comment=else hier=tb.dut.u_b
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t (
|
||||
input clk
|
||||
);
|
||||
%000001 reg [3:0] cyc = 0;
|
||||
-000001 point: type=line comment=block hier=tb.dut
|
||||
|
||||
// Over 9 clock edges, u_a.en is true for cyc 0..3, so u_a should report
|
||||
// if coverage of 4, else coverage of 5, and line coverage of 9.
|
||||
child u_a (
|
||||
.clk(clk),
|
||||
.en(cyc < 4)
|
||||
);
|
||||
|
||||
// u_b.en is true only for cyc 0, so u_b should report if coverage of 1,
|
||||
// else coverage of 8, and line coverage of 9.
|
||||
child u_b (
|
||||
.clk(clk),
|
||||
.en(cyc == 0)
|
||||
);
|
||||
|
||||
%000009 always @(posedge clk) begin
|
||||
-000009 point: type=line comment=block hier=tb.dut
|
||||
%000009 cyc <= cyc + 1'b1;
|
||||
-000009 point: type=line comment=block hier=tb.dut
|
||||
end
|
||||
endmodule
|
||||
|
||||
module tb;
|
||||
%000001 reg clk = 0;
|
||||
-000001 point: type=line comment=block hier=tb
|
||||
|
||||
t dut (
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
000017 always #1 clk = !clk;
|
||||
+000017 point: type=line comment=block hier=tb
|
||||
|
||||
%000009 always @(posedge clk) begin
|
||||
-000009 point: type=line comment=block hier=tb
|
||||
%000008 if (dut.cyc == 8) begin
|
||||
-000001 point: type=branch comment=if hier=tb
|
||||
-000008 point: type=branch comment=else hier=tb
|
||||
%000001 $write("*-* All Finished *-*\n");
|
||||
-000001 point: type=branch comment=if hier=tb
|
||||
%000001 $finish;
|
||||
-000001 point: type=branch comment=if hier=tb
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// DESCRIPTION: Verilator: Coverage per-instance hierarchy for duplicate module instances
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module child (
|
||||
input clk,
|
||||
input en
|
||||
);
|
||||
`ifdef INLINE_CHILD //verilator inline_module
|
||||
`else //verilator no_inline_module
|
||||
`endif
|
||||
reg [3:0] count = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (en) begin
|
||||
count <= count + 1'b1;
|
||||
end else begin
|
||||
count <= count;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t (
|
||||
input clk
|
||||
);
|
||||
reg [3:0] cyc = 0;
|
||||
|
||||
// Over 9 clock edges, u_a.en is true for cyc 0..3, so u_a should report
|
||||
// if coverage of 4, else coverage of 5, and line coverage of 9.
|
||||
child u_a (
|
||||
.clk(clk),
|
||||
.en(cyc < 4)
|
||||
);
|
||||
|
||||
// u_b.en is true only for cyc 0, so u_b should report if coverage of 1,
|
||||
// else coverage of 8, and line coverage of 9.
|
||||
child u_b (
|
||||
.clk(clk),
|
||||
.en(cyc == 0)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1'b1;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module tb;
|
||||
reg clk = 0;
|
||||
|
||||
t dut (
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
always #1 clk = !clk;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (dut.cyc == 8) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#!/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 os
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(top_filename="t/t_cover_per_instance.v",
|
||||
v_flags2=["+define+INLINE_CHILD"],
|
||||
verilator_flags2=[
|
||||
'--binary',
|
||||
'--coverage-line',
|
||||
'--coverage-per-instance',
|
||||
'--top-module',
|
||||
'tb',
|
||||
'--timing',
|
||||
])
|
||||
|
||||
test.execute(all_run_flags=[" +verilator+coverage+file+" + test.obj_dir + "/coverage.dat"])
|
||||
|
||||
cov = test.obj_dir + "/coverage.dat"
|
||||
|
||||
test.run(cmd=[
|
||||
os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage",
|
||||
"--annotate-points",
|
||||
"--annotate",
|
||||
test.obj_dir + "/annotated-points",
|
||||
cov,
|
||||
],
|
||||
verilator_run=True)
|
||||
|
||||
test.files_identical(test.obj_dir + "/annotated-points/t_cover_per_instance.v",
|
||||
"t/t_cover_per_instance.out")
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#!/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 os
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(top_filename="t/t_cover_per_instance.v",
|
||||
verilator_flags2=[
|
||||
'--binary',
|
||||
'--coverage-line',
|
||||
'--coverage-per-instance',
|
||||
'--top-module',
|
||||
'tb',
|
||||
'--timing',
|
||||
])
|
||||
|
||||
test.execute(all_run_flags=[" +verilator+coverage+file+" + test.obj_dir + "/coverage.dat"])
|
||||
|
||||
cov = test.obj_dir + "/coverage.dat"
|
||||
|
||||
test.run(cmd=[
|
||||
os.environ["VERILATOR_ROOT"] + "/bin/verilator_coverage",
|
||||
"--annotate-points",
|
||||
"--annotate",
|
||||
test.obj_dir + "/annotated-points",
|
||||
cov,
|
||||
],
|
||||
verilator_run=True)
|
||||
|
||||
test.files_identical(test.obj_dir + "/annotated-points/t_cover_per_instance.v",
|
||||
"t/t_cover_per_instance.out")
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# SystemC::Coverage-3
|
||||
C 'ft/t_cover_per_instance_user.vl11n18tlinepagev_line/childoblockS11htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl11n18tlinepagev_line/childoblockS11htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl11n7ttogglepagev_toggle/childoobserved:0->1htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl11n7ttogglepagev_toggle/childoobserved:0->1htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl11n7ttogglepagev_toggle/childoobserved:1->0htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl11n7ttogglepagev_toggle/childoobserved:1->0htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[0]:0->1htb.dut_a' 2
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[0]:0->1htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[0]:1->0htb.dut_a' 2
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[0]:1->0htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[1]:0->1htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[1]:0->1htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[1]:1->0htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[1]:1->0htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[2]:0->1htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[2]:0->1htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[2]:1->0htb.dut_a' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[2]:1->0htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[3]:0->1htb.dut_a' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[3]:0->1htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[3]:1->0htb.dut_a' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n13ttogglepagev_toggle/childocount[3]:1->0htb.wrap_b.dut_b' 0
|
||||
C 'ft/t_cover_per_instance_user.vl12n21tlinepagev_line/childoblockS12htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl12n21tlinepagev_line/childoblockS12htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl15n5tuserpagev_user/childosame_stmtS15htb.dut_a.same_stmt' 4
|
||||
C 'ft/t_cover_per_instance_user.vl15n5tuserpagev_user/childosame_stmtS15htb.wrap_b.dut_b.same_stmt' 1
|
||||
C 'ft/t_cover_per_instance_user.vl17n3tlinepagev_line/childoblockS17-18htb.dut_a' 9
|
||||
C 'ft/t_cover_per_instance_user.vl17n3tlinepagev_line/childoblockS17-18htb.wrap_b.dut_b' 9
|
||||
C 'ft/t_cover_per_instance_user.vl19n5tbranchpagev_branch/childoifS19-20htb.dut_a' 4
|
||||
C 'ft/t_cover_per_instance_user.vl19n5tbranchpagev_branch/childoifS19-20htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl19n6tbranchpagev_branch/childoelseS21-22htb.dut_a' 5
|
||||
C 'ft/t_cover_per_instance_user.vl19n6tbranchpagev_branch/childoelseS21-22htb.wrap_b.dut_b' 8
|
||||
C 'ft/t_cover_per_instance_user.vl28n11ttogglepagev_toggle/wrapoclk:0->1htb.wrap_b' 9
|
||||
C 'ft/t_cover_per_instance_user.vl28n11ttogglepagev_toggle/wrapoclk:1->0htb.wrap_b' 8
|
||||
C 'ft/t_cover_per_instance_user.vl29n11ttogglepagev_toggle/wrapoen:0->1htb.wrap_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl29n11ttogglepagev_toggle/wrapoen:1->0htb.wrap_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl38n13tlinepagev_line/tboblockS38htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl38n7ttogglepagev_toggle/tboclk:0->1htb' 9
|
||||
C 'ft/t_cover_per_instance_user.vl38n7ttogglepagev_toggle/tboclk:1->0htb' 8
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[0]:0->1htb' 5
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[0]:1->0htb' 4
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[1]:0->1htb' 2
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[1]:1->0htb' 2
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[2]:0->1htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[2]:1->0htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[3]:0->1htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl39n13ttogglepagev_toggle/tbocyc[3]:1->0htb' 0
|
||||
C 'ft/t_cover_per_instance_user.vl39n19tlinepagev_line/tboblockS39htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl53n3tlinepagev_line/tboblockS53-54htb' 9
|
||||
C 'ft/t_cover_per_instance_user.vl57n3tlinepagev_line/tboblockS57htb' 17
|
||||
C 'ft/t_cover_per_instance_user.vl59n3tlinepagev_line/tboblockS59htb' 9
|
||||
C 'ft/t_cover_per_instance_user.vl60n5tbranchpagev_branch/tboifS60-62htb' 1
|
||||
C 'ft/t_cover_per_instance_user.vl60n6tbranchpagev_branch/tboelsehtb' 8
|
||||
C 'ft/t_cover_per_instance_user.vl8n11ttogglepagev_toggle/childoclk:0->1htb.dut_a' 9
|
||||
C 'ft/t_cover_per_instance_user.vl8n11ttogglepagev_toggle/childoclk:0->1htb.wrap_b.dut_b' 9
|
||||
C 'ft/t_cover_per_instance_user.vl8n11ttogglepagev_toggle/childoclk:1->0htb.dut_a' 8
|
||||
C 'ft/t_cover_per_instance_user.vl8n11ttogglepagev_toggle/childoclk:1->0htb.wrap_b.dut_b' 8
|
||||
C 'ft/t_cover_per_instance_user.vl9n11ttogglepagev_toggle/childoen:0->1htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl9n11ttogglepagev_toggle/childoen:0->1htb.wrap_b.dut_b' 1
|
||||
C 'ft/t_cover_per_instance_user.vl9n11ttogglepagev_toggle/childoen:1->0htb.dut_a' 1
|
||||
C 'ft/t_cover_per_instance_user.vl9n11ttogglepagev_toggle/childoen:1->0htb.wrap_b.dut_b' 1
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#!/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
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=[
|
||||
'--binary',
|
||||
'--assert',
|
||||
'--coverage-line',
|
||||
'--coverage-toggle',
|
||||
'--coverage-user',
|
||||
'--coverage-per-instance',
|
||||
'--top-module',
|
||||
'tb',
|
||||
'--timing',
|
||||
])
|
||||
|
||||
test.execute(all_run_flags=[" +verilator+coverage+file+" + test.obj_dir + "/coverage.dat"])
|
||||
|
||||
test.files_identical(test.obj_dir + "/coverage.dat", "t/" + test.name + ".out")
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// DESCRIPTION: Verilator: User coverage per-instance records for the same statement
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module child (
|
||||
input clk,
|
||||
input en
|
||||
);
|
||||
reg observed = 1'b0;
|
||||
reg [3:0] count = 0;
|
||||
|
||||
same_stmt:
|
||||
cover property (@(posedge clk) en);
|
||||
|
||||
always @(posedge clk) begin
|
||||
observed <= en;
|
||||
if (en) begin
|
||||
count <= count + 1'b1;
|
||||
end else begin
|
||||
count <= count;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module wrap (
|
||||
input clk,
|
||||
input en
|
||||
);
|
||||
child dut_b (
|
||||
.clk(clk),
|
||||
.en(en)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module tb;
|
||||
reg clk = 0;
|
||||
reg [3:0] cyc = 0;
|
||||
|
||||
// Same user cover statement at two different hierarchy points.
|
||||
// Expected with per_instance: dut_a count=4, wrap_b.dut_b count=1.
|
||||
child dut_a (
|
||||
.clk(clk),
|
||||
.en(cyc < 4)
|
||||
);
|
||||
|
||||
wrap wrap_b (
|
||||
.clk(clk),
|
||||
.en(cyc == 0)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1'b1;
|
||||
end
|
||||
|
||||
always #1 clk = !clk;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (cyc == 8) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue