Optimize interfaces in Dfg (#6332)

Interfaces that have no corresponding virtual interface references can
be safely optimized by Dfg after V3Scope. Enabling it to do so.
This commit is contained in:
Geza Lore 2025-08-26 11:24:15 +01:00 committed by GitHub
parent 5f23bf95f6
commit a841a962ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 5 deletions

View File

@ -2531,7 +2531,8 @@ public:
void classp(AstClass* classp) { m_classp = classp; } void classp(AstClass* classp) { m_classp = classp; }
}; };
class AstIface final : public AstNodeModule { class AstIface final : public AstNodeModule {
// A module declaration // An interface declaration
bool m_hasVirtualRef = false; // There exists a virtual interface reference for this interface
public: public:
AstIface(FileLine* fl, const string& name, const string& libname) AstIface(FileLine* fl, const string& name, const string& libname)
: ASTGEN_SUPER_Iface(fl, name, libname) {} : ASTGEN_SUPER_Iface(fl, name, libname) {}
@ -2540,6 +2541,8 @@ public:
// get false warnings if we enable this // get false warnings if we enable this
string verilogKwd() const override { return "interface"; } string verilogKwd() const override { return "interface"; }
bool timescaleMatters() const override { return false; } bool timescaleMatters() const override { return false; }
bool hasVirtualRef() const { return m_hasVirtualRef; }
void setHasVirtualRef() { m_hasVirtualRef = true; }
}; };
class AstModule final : public AstNodeModule { class AstModule final : public AstNodeModule {
// A module declaration // A module declaration

View File

@ -798,10 +798,16 @@ public:
// Returns true if variable can be represented in the graph // Returns true if variable can be represented in the graph
static bool isSupported(const AstVarScope* vscp) { static bool isSupported(const AstVarScope* vscp) {
// If the variable is not in a regular module, then we do not support it. AstNodeModule* const modp = vscp->scopep()->modp();
// This is especially needed for variabels in interfaces which might be if (VN_IS(modp, Module)) {
// referenced via virtual intefaces, which cannot be resovled statically. // Regular module supported
if (!VN_IS(vscp->scopep()->modp(), Module)) return false; } else if (AstIface* const ifacep = VN_CAST(modp, Iface)) {
// Interfaces supported if there are no virtual interfaces for
// them, otherwise they cannot be resovled statically.
if (ifacep->hasVirtualRef()) return false;
} else {
return false; // Anything else (package, class, etc) not supported
}
// Check the AstVar // Check the AstVar
return isSupported(vscp->varp()); return isSupported(vscp->varp());
} }

View File

@ -321,6 +321,15 @@ class DataflowOptimize final {
DataflowOptimize(AstNetlist* netlistp, const string& label) DataflowOptimize(AstNetlist* netlistp, const string& label)
: m_ctx{label} { : m_ctx{label} {
// Mark interfaces that might be referenced by a virtual interface
if (v3Global.hasVirtIfaces()) {
netlistp->typeTablep()->foreach([](AstIfaceRefDType* nodep) {
if (!nodep->isVirtual()) return;
nodep->ifaceViaCellp()->setHasVirtualRef();
});
}
if (!netlistp->topScopep()) { if (!netlistp->topScopep()) {
// Pre V3Scope application. Run on each module separately. // Pre V3Scope application. Run on each module separately.

View File

@ -9,7 +9,9 @@
interface intf interface intf
#(parameter PARAM = 0) #(parameter PARAM = 0)
(); ();
/* verilator lint_off MULTIDRIVEN */
logic val; logic val;
/* verilator lint_on MULTIDRIVEN */
function integer func (); return 5; endfunction function integer func (); return 5; endfunction
endinterface endinterface