Support unassigned virtual interfaces (#5265) (#6245)

This commit is contained in:
Szymon Gizler 2025-08-01 12:39:13 +02:00 committed by GitHub
parent d0f0919830
commit 61f4c97f40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 30 deletions

View File

@ -516,30 +516,39 @@ public:
} else {
ifacerefp->v3fatalSrc("Unlinked interface");
}
} else if (ifacerefp->ifaceViaCellp()->dead()) {
if (varp->isIfaceRef()) {
if (forPrimary() && !varp->isIfaceParent()
&& !v3Global.opt.topIfacesSupported()) {
// Only AstIfaceRefDType's at this point correspond to ports;
// haven't made additional ones for interconnect yet, so assert is simple
// What breaks later is we don't have a Scope/Cell representing
// the interface to attach to
varp->v3warn(E_UNSUPPORTED,
"Unsupported: Interfaced port on top level module");
}
ifacerefp->v3error("Parent instance's interface is not found: "
<< AstNode::prettyNameQ(ifacerefp->ifaceName()) << '\n'
<< ifacerefp->warnMore()
<< "... Perhaps intended an interface instantiation but "
"are missing parenthesis (IEEE 1800-2023 25.3)?");
} else {
ifacerefp->v3warn(
E_UNSUPPORTED,
"Unsupported: virtual interface never assigned any actual interface");
varp->dtypep(ifacerefp->findCHandleDType());
VL_DO_DANGLING(ifacerefp->unlinkFrBack()->deleteTree(), ifacerefp);
} else if (ifacerefp->ifaceViaCellp()->dead() && varp->isIfaceRef()) {
if (forPrimary() && !varp->isIfaceParent() && !v3Global.opt.topIfacesSupported()) {
// Only AstIfaceRefDType's at this point correspond to ports;
// haven't made additional ones for interconnect yet, so assert is simple
// What breaks later is we don't have a Scope/Cell representing
// the interface to attach to
varp->v3warn(E_UNSUPPORTED,
"Unsupported: Interfaced port on top level module");
}
ifacerefp->v3error("Parent instance's interface is not found: "
<< AstNode::prettyNameQ(ifacerefp->ifaceName()) << '\n'
<< ifacerefp->warnMore()
<< "... Perhaps intended an interface instantiation but "
"are missing parenthesis (IEEE 1800-2023 25.3)?");
continue;
} else if (ifacerefp->ifaceViaCellp()->dead()
|| !existsNodeSym(ifacerefp->ifaceViaCellp())) {
// virtual interface never assigned any actual interface
ifacerefp->ifacep()->dead(false);
varp->dtypep(ifacerefp->dtypep());
// Create dummy cell to keep the virtual interface alive
// (later stages assume that non-dead interface has associated cell)
AstCell* const ifacecellp
= new AstCell{ifacerefp->ifacep()->fileline(),
ifacerefp->ifacep()->fileline(),
ifacerefp->ifacep()->name() + "__02E" + varp->name(),
ifacerefp->ifaceName(),
nullptr,
nullptr,
nullptr};
ifacecellp->modp(ifacerefp->ifacep());
VSymEnt* const symp = new VSymEnt{&m_syms, ifacecellp};
ifacerefp->ifacep()->user1p(symp);
}
VSymEnt* const ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp());
VSymEnt* ifOrPortSymp = ifaceSymp;
@ -2787,7 +2796,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
void visit(AstTypeTable*) override {}
void visit(AstConstPool*) override {}
void visit(AstNodeModule* nodep) override {
if (nodep->dead()) return;
if (nodep->dead() || !m_statep->existsNodeSym(nodep)) return;
LINKDOT_VISIT_START();
UINFO(8, indent() << "visit " << nodep);
checkNoDot(nodep);

View File

@ -9,8 +9,10 @@
import vltest_bootstrap
test.scenarios('linter')
test.scenarios('simulator')
test.lint(fails=True, expect_filename=test.golden_filename)
test.compile()
test.execute()
test.passes()

View File

@ -1,5 +0,0 @@
%Error-UNSUPPORTED: t/t_interface_virtual_unused_bad.v:14:12: Unsupported: virtual interface never assigned any actual interface
14 | virtual QBus q8;
| ^~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to