Fix inlining static initializer in V3Gate (#7503)
V3Gate could incorrectly inline a non-constant static initializer of a variable into the use site if there are no other drivers. Disabling. Fixes #5381
This commit is contained in:
parent
c8893b64de
commit
cee174c4b6
|
|
@ -146,6 +146,7 @@ bool AstBasicDType::ascending() const {
|
|||
|
||||
bool AstActive::hasClocked() const { return m_sentreep->hasClocked(); }
|
||||
bool AstActive::hasCombo() const { return m_sentreep->hasCombo(); }
|
||||
bool AstActive::hasStatic() const { return m_sentreep->hasStatic(); }
|
||||
|
||||
AstAlways::AstAlways(AstAssignW* assignp)
|
||||
: ASTGEN_SUPER_Always(assignp->fileline(), assignp)
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@ public:
|
|||
// METHODS
|
||||
inline bool hasClocked() const;
|
||||
inline bool hasCombo() const;
|
||||
inline bool hasStatic() const;
|
||||
};
|
||||
class AstAlias final : public AstNode {
|
||||
// Alias construct - Used for source level net alias, and also for variable aliases internally
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class GateEitherVertex VL_NOT_FINAL : public V3GraphVertex {
|
|||
bool m_reducible = true; // True if this node should be able to be eliminated
|
||||
bool m_dedupable = true; // True if this node should be able to be deduped
|
||||
bool m_consumed = false; // Output goes to something meaningful
|
||||
bool m_staticInit = false; // True if this node is a static initializer
|
||||
public:
|
||||
explicit GateEitherVertex(V3Graph* graphp)
|
||||
: V3GraphVertex{graphp} {}
|
||||
|
|
@ -56,10 +57,12 @@ public:
|
|||
bool reducible() const { return m_reducible; }
|
||||
bool dedupable() const { return m_dedupable; }
|
||||
bool consumed() const { return m_consumed; }
|
||||
bool staticInit() const { return m_staticInit; }
|
||||
void setConsumed(const char* /*consumedReason*/) {
|
||||
// if (!m_consumed) UINFO(0, "\t\tSetConsumed " << consumedReason << " " << this);
|
||||
m_consumed = true;
|
||||
}
|
||||
void setStaticInit() { m_staticInit = true; }
|
||||
void clearReducible(const char* /*nonReducibleReason*/) {
|
||||
// UINFO(0, " NR: " << nonReducibleReason << " " << name());
|
||||
m_reducible = false;
|
||||
|
|
@ -196,6 +199,7 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
const AstScope* m_scopep = nullptr; // Current scope being processed
|
||||
AstActive* m_activep = nullptr; // Current active
|
||||
bool m_inClockedActive = false; // Underneath clocked active
|
||||
bool m_inStaticActive = false; // Underneath static active
|
||||
bool m_inSenItem = false; // Underneath AstSenItem; any varrefs are clocks
|
||||
|
||||
// METHODS
|
||||
|
|
@ -219,6 +223,8 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
m_logicVertexp->clearReducibleAndDedupable(nonReducibleReason);
|
||||
} else if (m_inClockedActive) {
|
||||
m_logicVertexp->clearReducible("Clocked logic"); // but dedupable
|
||||
} else if (m_inStaticActive) {
|
||||
m_logicVertexp->setStaticInit();
|
||||
}
|
||||
if (consumeReason) m_logicVertexp->setConsumed(consumeReason);
|
||||
checkNode(nodep);
|
||||
|
|
@ -242,8 +248,10 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
UASSERT_OBJ(!m_activep, nodep, "Should not nest");
|
||||
VL_RESTORER(m_activep);
|
||||
VL_RESTORER(m_inClockedActive);
|
||||
VL_RESTORER(m_inStaticActive);
|
||||
m_activep = nodep;
|
||||
m_inClockedActive = nodep->hasClocked();
|
||||
m_inStaticActive = nodep->hasStatic();
|
||||
|
||||
// AstVarScope::user2 -> bool: Signal used in SenItem in *this* active block
|
||||
const VNUser2InUse user2InUse;
|
||||
|
|
@ -700,6 +708,9 @@ class GateInline final {
|
|||
if (!VN_IS(substp, NodeVarRef)) continue;
|
||||
}
|
||||
|
||||
// Only inline static initializer if constant known at compile time
|
||||
if (lVtxp->staticInit() && !VN_IS(substp, Const)) continue;
|
||||
|
||||
// Process it
|
||||
++m_statInlined;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ test.scenarios('simulator')
|
|||
|
||||
test.compile(verilator_flags2=["--timing"])
|
||||
|
||||
test.execute(fails=test.vlt_all) # Issue #5381
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module t (
|
|||
input clk
|
||||
);
|
||||
|
||||
str_t bar_in;
|
||||
str_t bar_in = '0; // Set bar_in to 0 initially
|
||||
str_t bar_out;
|
||||
|
||||
Sub sub (
|
||||
|
|
@ -28,8 +28,6 @@ module t (
|
|||
integer i;
|
||||
str_t initOut;
|
||||
|
||||
bar_in = '0; // Set bar_in to 0 initially
|
||||
|
||||
// Wait for the first falling edge of the clock
|
||||
@(negedge clk);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue