Fix eliminating assignments to DPI-read vaiables (#7158)

This commit is contained in:
Geza Lore
2026-02-28 10:09:01 -05:00
committed by GitHub
parent face700f29
commit 2ceea267e5
7 changed files with 96 additions and 5 deletions
+4
View File
@@ -1933,6 +1933,7 @@ class AstVar final : public AstNode {
bool m_isLatched : 1; // Not assigned in all control paths of combo always
bool m_isForceable : 1; // May be forced/released externally from user C code
bool m_isForcedByCode : 1; // May be forced/released from AstAssignForce/AstRelease
bool m_isReadByDpi : 1; // This variable can be read by a DPI Export
bool m_isWrittenByDpi : 1; // This variable can be written by a DPI Export
bool m_isWrittenBySuspendable : 1; // This variable can be written by a suspendable process
bool m_ignorePostRead : 1; // Ignore reads in 'Post' blocks during ordering
@@ -1987,6 +1988,7 @@ class AstVar final : public AstNode {
m_isLatched = false;
m_isForceable = false;
m_isForcedByCode = false;
m_isReadByDpi = false;
m_isWrittenByDpi = false;
m_isWrittenBySuspendable = false;
m_ignorePostRead = false;
@@ -2152,6 +2154,8 @@ public:
void setForceable() { m_isForceable = true; }
void setForcedByCode() { m_isForcedByCode = true; }
bool isForced() const { return m_isForceable || m_isForcedByCode; }
bool isReadByDpi() const { return m_isReadByDpi; }
void setReadByDpi() { m_isReadByDpi = true; }
bool isWrittenByDpi() const { return m_isWrittenByDpi; }
void setWrittenByDpi() { m_isWrittenByDpi = true; }
bool isWrittenBySuspendable() const { return m_isWrittenBySuspendable; }
+4
View File
@@ -2880,6 +2880,8 @@ void AstVar::dump(std::ostream& str) const {
if (isSigPublic()) str << " [P]";
if (isSigUserRdPublic()) str << " [PRD]";
if (isSigUserRWPublic()) str << " [PWR]";
if (isReadByDpi()) str << " [DPIRD]";
if (isWrittenByDpi()) str << " [DPIWR]";
if (isInternal()) str << " [INTERNAL]";
if (isLatched()) str << " [LATCHED]";
if (isUsedLoopIdx()) str << " [LOOPIDX]";
@@ -2927,6 +2929,8 @@ void AstVar::dumpJson(std::ostream& str) const {
if (dtypep()) dumpJsonStr(str, "dtypeName", dtypep()->name());
dumpJsonBoolFuncIf(str, isSigUserRdPublic);
dumpJsonBoolFuncIf(str, isSigUserRWPublic);
dumpJsonBoolFuncIf(str, isReadByDpi);
dumpJsonBoolFuncIf(str, isWrittenByDpi);
dumpJsonBoolFuncIf(str, isGParam);
dumpJsonBoolFuncIf(str, isParam);
dumpJsonBoolFuncIf(str, attrScBv);
+1
View File
@@ -129,6 +129,7 @@ public:
const AstVar* const varp = vscp->varp();
// We don't optimize any public sigs
if (varp->isSigPublic()) return;
if (varp->isReadByDpi()) return;
if (varp->sensIfacep()) return;
// Check the var entry, and remove if appropriate
AstNodeStmt* const oldassp = entr.assignp();
+12 -5
View File
@@ -1428,15 +1428,22 @@ class TaskVisitor final : public VNVisitor {
// Mark non-local variables written by the exported function
bool writesNonLocals = false;
cfuncp->foreach([&writesNonLocals](AstVarRef* refp) {
if (refp->access().isReadOnly()) return; // Ignore read reference
AstVar* const varp = refp->varScopep()->varp();
// We are ignoring function locals as they should not be referenced anywhere
// outside the enclosing AstCFunc, hence they are irrelevant for code ordering.
if (varp->isFuncLocal()) return;
// Mark it as written by DPI export
varp->setWrittenByDpi();
// Remember we had some
writesNonLocals = true;
// Check if written
if (refp->access().isWriteOrRW()) {
// Mark it as written by DPI export
varp->setWrittenByDpi();
// Remember we had some
writesNonLocals = true;
}
// Check if read
if (refp->access().isReadOrRW()) {
// Mark it as read by DPI export
varp->setReadByDpi();
}
});
// If this DPI export writes some non-local variables, set the DPI Export Trigger flag