mirror of
https://github.com/verilator/verilator.git
synced 2025-07-31 07:56:10 +00:00
Dfg: Fix crash on additional driver from non-DFG logic
Ensure variables written by non-DFG code are kept Fixes #3740
This commit is contained in:
parent
6736e92cdb
commit
dbcaad99c5
@ -94,7 +94,10 @@ class AstToDfgVisitor final : public VNVisitor {
|
||||
nodep->foreach([this](const AstVarRef* refp) {
|
||||
// No need to (and in fact cannot) mark variables with unsupported dtypes
|
||||
if (!DfgVertex::isSupportedDType(refp->varp()->dtypep())) return;
|
||||
// Mark vertex as having a module reference outside current DFG
|
||||
getNet(refp->varp())->setHasModRefs();
|
||||
// Mark variable as written from non-DFG logic
|
||||
if (refp->access().isWriteOrRW()) refp->varp()->user3(true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -415,14 +415,14 @@ class DfgToAstVisitor final : DfgVisitor {
|
||||
// Remap all references to point to the canonical variables, if one exists
|
||||
VNDeleter deleter;
|
||||
m_modp->foreach([&](AstVarRef* refp) {
|
||||
// Any variable that is written outside the DFG will have itself as the canonical
|
||||
// var, so need not be replaced, furthermore, if a variable is traced, we don't
|
||||
// want to update the write ref we just created above, so we only replace read only
|
||||
// references.
|
||||
if (!refp->access().isReadOnly()) return;
|
||||
// Any variable that is written partially outside the DFG will have itself as the
|
||||
// canonical var, so need not be replaced, furthermore, if a variable is traced, we
|
||||
// don't want to update the write-refs we just created above, so we only replace
|
||||
// read-only references to those variables to those variables we know are not written
|
||||
// in non-DFG logic.
|
||||
if (!refp->access().isReadOnly() || refp->varp()->user3()) return;
|
||||
const auto it = m_canonVars.find(refp->varp());
|
||||
if (it == m_canonVars.end()) return;
|
||||
if (it->second == refp->varp()) return;
|
||||
if (it == m_canonVars.end() || it->second == refp->varp()) return;
|
||||
refp->replaceWith(new AstVarRef{refp->fileline(), it->second, refp->access()});
|
||||
deleter.pushDeletep(refp);
|
||||
});
|
||||
|
@ -244,9 +244,12 @@ void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
|
||||
// NODE STATE
|
||||
// AstVar::user1 -> Used by V3DfgPasses::astToDfg
|
||||
// AstVar::user2 -> bool: Flag indicating referenced by AstVarXRef
|
||||
// AstVar::user1 -> Used by V3DfgPasses::astToDfg and DfgPassed::dfgToAst
|
||||
// AstVar::user2 -> bool: Flag indicating referenced by AstVarXRef (set just below)
|
||||
// AstVar::user3 -> bool: Flag indicating written by logic not representable as DFG
|
||||
// (set by V3DfgPasses::astToDfg)
|
||||
const VNUser2InUse user2InUse;
|
||||
const VNUser3InUse user3InUse;
|
||||
|
||||
// Mark cross-referenced variables
|
||||
netlistp->foreach([](const AstVarXRef* xrefp) { xrefp->varp()->user2(true); });
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
if (v3Global.opt.trace() && varp()->isTrace()) return true;
|
||||
// Keep if public
|
||||
if (varp()->isSigPublic()) return true;
|
||||
// Keep if written in non-DFG code
|
||||
if (varp()->user3()) return true;
|
||||
// Otherwise it can be removed
|
||||
return false;
|
||||
}
|
||||
|
16
test_regress/t/t_dfg_multidriver_non_dfg.pl
Executable file
16
test_regress/t/t_dfg_multidriver_non_dfg.pl
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2022 by Geza Lore. 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
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile();
|
||||
|
||||
ok(1);
|
||||
1;
|
22
test_regress/t/t_dfg_multidriver_non_dfg.v
Normal file
22
test_regress/t/t_dfg_multidriver_non_dfg.v
Normal file
@ -0,0 +1,22 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2022 by Geza Lore.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module t(
|
||||
input wire i,
|
||||
output wire o
|
||||
);
|
||||
logic a;
|
||||
logic b;
|
||||
initial begin
|
||||
a = 1'd0;
|
||||
b = 1'd0;
|
||||
end
|
||||
assign a = ~i;
|
||||
assign b = a;
|
||||
assign o = b;
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user