my OG test, a test that should fail, and a variant of the OG with nested tasks
This commit is contained in:
parent
c801718ba1
commit
76886e14e6
|
|
@ -442,6 +442,16 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
<< " (IEEE 1800-2023 13.5): " << nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
|
||||
// EOM
|
||||
// If writeSummary is enabled, task/function definitions are treated as non-executed.
|
||||
// Their effects are applied at call sites via writeSummary(), so don't let definition
|
||||
// traversal create phantom "other writes" for MULTIDRIVEN.
|
||||
if (m_enableWriteSummary && m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic
|
||||
&& !m_inBBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int usr = 1; usr < (m_alwaysCombp ? 3 : 2); ++usr) {
|
||||
UndrivenVarEntry* const entryp = getEntryp(nodep->varp(), usr);
|
||||
const bool fdrv = nodep->access().isWriteOrRW()
|
||||
|
|
@ -573,6 +583,15 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
iterateChildrenConst(nodep);
|
||||
|
||||
if (!m_enableWriteSummary || !m_capturep) return;
|
||||
|
||||
// EOM
|
||||
// If writeSummary is enabled, task/function definitions are treated as non-executed.
|
||||
// Do not apply writeSummary at calls inside a task definition, or they will look like
|
||||
// independent drivers (phantom MULTIDRIVEN).
|
||||
if (m_taskp && !m_alwaysp && !m_inContAssign && !m_inInitialStatic && !m_inBBox) {
|
||||
return;
|
||||
}
|
||||
|
||||
AstNodeFTask* const calleep = nodep->taskp();
|
||||
if (!calleep) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@ VL_DEFINE_DEBUG_FUNCTIONS;
|
|||
namespace {
|
||||
|
||||
constexpr int DBG = 9;
|
||||
|
||||
struct Stats final {
|
||||
uint64_t ftasks = 0;
|
||||
uint64_t varWrites = 0;
|
||||
uint64_t callEdges = 0;
|
||||
} g_stats;
|
||||
|
||||
static std::string taskNameQ(const AstNodeFTask* taskp) {
|
||||
if (!taskp) return "<null>";
|
||||
return taskp->prettyNameQ();
|
||||
|
|
@ -105,7 +107,7 @@ private:
|
|||
|
||||
} // namespace
|
||||
|
||||
bool V3UndrivenCapture::enableWriteSummary = false;
|
||||
bool V3UndrivenCapture::enableWriteSummary = true;
|
||||
|
||||
// static
|
||||
void V3UndrivenCapture::sortUniqueVars(std::vector<Var>& vec) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
%Warning-MULTIDRIVEN: t/t_lint_taskcall_multidriven_bad.v:28:15: Variable written to in always_comb also written by other process (IEEE 1800-2023 9.2.2.2): 'out'
|
||||
: ... note: In instance 't'
|
||||
t/t_lint_taskcall_multidriven_bad.v:28:15:
|
||||
28 | if (sel2) out = 1'b1;
|
||||
| ^~~
|
||||
t/t_lint_taskcall_multidriven_bad.v:20:5: ... Location of other write
|
||||
20 | out = 1'b0;
|
||||
| ^~~
|
||||
... For warning description see https://verilator.org/warn/MULTIDRIVEN?v=latest
|
||||
... Use "/* verilator lint_off MULTIDRIVEN */" and lint_on around source to disable this message.
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('linter')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t (
|
||||
input logic sel
|
||||
, input logic sel2
|
||||
, input logic d
|
||||
, output logic out
|
||||
);
|
||||
|
||||
task automatic do_stuff(input logic din);
|
||||
out = din;
|
||||
endtask
|
||||
|
||||
// Driver #1 (via task call)
|
||||
always_comb begin
|
||||
out = 1'b0;
|
||||
if (sel) do_stuff(d);
|
||||
end
|
||||
|
||||
// Driver #2 (separate process)
|
||||
// I only want the MULTIDRIVEN.
|
||||
/* verilator lint_off LATCH */
|
||||
always_comb begin
|
||||
if (sel2) out = 1'b1;
|
||||
end
|
||||
/* verilator lint_on LATCH */
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module mod #()(
|
||||
input logic sel
|
||||
,output logic val
|
||||
);
|
||||
|
||||
logic l0;
|
||||
|
||||
task do_stuff();
|
||||
l0 = 'b1;
|
||||
endtask
|
||||
|
||||
always_comb begin
|
||||
l0 = 'b0;
|
||||
|
||||
if(sel) begin
|
||||
do_stuff();
|
||||
end
|
||||
end
|
||||
|
||||
assign val = l0;
|
||||
|
||||
endmodule
|
||||
|
||||
module m_tb#()();
|
||||
|
||||
logic sel, val;
|
||||
|
||||
mod m(
|
||||
.sel(sel)
|
||||
,.val(val)
|
||||
);
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
sel = 'b0;
|
||||
`checkd(val, 1'b0);
|
||||
#1;
|
||||
sel = 'b1;
|
||||
`checkd(val, 1'b1);
|
||||
#1;
|
||||
sel = 'b0;
|
||||
`checkd(val, 1'b0);
|
||||
#1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#5;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
module mod #()(
|
||||
input logic sel
|
||||
,output logic val
|
||||
);
|
||||
|
||||
logic l0;
|
||||
|
||||
task do_inner();
|
||||
l0 = 'b1;
|
||||
endtask
|
||||
|
||||
task do_outer();
|
||||
do_inner();
|
||||
endtask
|
||||
|
||||
always_comb begin
|
||||
l0 = 'b0;
|
||||
if (sel) do_outer();
|
||||
end
|
||||
|
||||
assign val = l0;
|
||||
|
||||
endmodule
|
||||
|
||||
module m_tb#()();
|
||||
|
||||
logic sel, val;
|
||||
|
||||
mod m(
|
||||
.sel(sel)
|
||||
,.val(val)
|
||||
);
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
sel = 'b0;
|
||||
`checkd(val, 1'b0);
|
||||
#1;
|
||||
sel = 'b1;
|
||||
`checkd(val, 1'b1);
|
||||
#1;
|
||||
sel = 'b0;
|
||||
`checkd(val, 1'b0);
|
||||
#1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#5;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue