mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Support linting for top module interfaces (#3635)
This commit is contained in:
@@ -200,6 +200,35 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
ioNames.insert(oldvarp->name());
|
||||
}
|
||||
}
|
||||
else if (v3Global.opt.topIfacesSupported() && oldvarp->isIfaceRef()) {
|
||||
const AstNodeDType* const subtypep = oldvarp->subDTypep();
|
||||
if (VN_IS(subtypep, IfaceRefDType)) {
|
||||
const AstIfaceRefDType* const ifacerefp = VN_AS(subtypep, IfaceRefDType);
|
||||
if (!ifacerefp->cellp()) {
|
||||
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
|
||||
// UINFO(8, "Multitop dup interface found: " << oldvarp << endl);
|
||||
dupNames.insert(oldvarp->name());
|
||||
} else {
|
||||
ioNames.insert(oldvarp->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (VN_IS(subtypep, UnpackArrayDType)) {
|
||||
const AstUnpackArrayDType* const arrp = VN_AS(subtypep, UnpackArrayDType);
|
||||
const AstNodeDType* const arrsubtypep = arrp->subDTypep();
|
||||
if (VN_IS(arrsubtypep, IfaceRefDType)) {
|
||||
const AstIfaceRefDType* const ifacerefp = VN_AS(arrsubtypep, IfaceRefDType);
|
||||
if (!ifacerefp->cellp()) {
|
||||
if (ioNames.find(oldvarp->name()) != ioNames.end()) {
|
||||
// UINFO(8, "Multitop dup interface array found: " << oldvarp << endl);
|
||||
dupNames.insert(oldvarp->name());
|
||||
} else {
|
||||
ioNames.insert(oldvarp->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,6 +286,81 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
pinp->modVarp(oldvarp);
|
||||
cellp->addPinsp(pinp);
|
||||
}
|
||||
else if (v3Global.opt.topIfacesSupported() && oldvarp->isIfaceRef()) {
|
||||
// for each interface port on oldmodp instantiate a corresponding interface cell in $root
|
||||
const AstNodeDType* const subtypep = oldvarp->subDTypep();
|
||||
if (VN_IS(subtypep, IfaceRefDType)) {
|
||||
const AstIfaceRefDType* const ifacerefp = VN_AS(subtypep, IfaceRefDType);
|
||||
if (!ifacerefp->cellp()) {
|
||||
string name = oldvarp->name();
|
||||
if (dupNames.find(name) != dupNames.end()) {
|
||||
// __02E=. while __DOT__ looks nicer but will break V3LinkDot
|
||||
name = oldmodp->name() + "__02E" + name;
|
||||
}
|
||||
|
||||
AstCell* ifacecellp = new AstCell{newmodp->fileline(), newmodp->fileline(), name, ifacerefp->ifaceName(), nullptr, nullptr, nullptr};
|
||||
ifacecellp->modp(ifacerefp->ifacep());
|
||||
newmodp->addStmtsp(ifacecellp);
|
||||
|
||||
AstIfaceRefDType* const idtypep = new AstIfaceRefDType{newmodp->fileline(), name, ifacerefp->ifaceName()};
|
||||
idtypep->ifacep(nullptr);
|
||||
idtypep->dtypep(idtypep);
|
||||
idtypep->cellp(ifacecellp);
|
||||
rootp->typeTablep()->addTypesp(idtypep);
|
||||
|
||||
AstVar* varp = new AstVar{newmodp->fileline(), VVarType::IFACEREF, name + "__Viftop", idtypep};
|
||||
varp->isIfaceParent(true);
|
||||
ifacecellp->addNextHere(varp);
|
||||
ifacecellp->hasIfaceVar(true);
|
||||
|
||||
AstPin* const pinp = new AstPin{
|
||||
oldvarp->fileline(), 0, varp->name(),
|
||||
new AstVarRef{varp->fileline(), varp,
|
||||
oldvarp->isWritable() ? VAccess::WRITE : VAccess::READ}};
|
||||
pinp->modVarp(oldvarp);
|
||||
cellp->addPinsp(pinp);
|
||||
}
|
||||
}
|
||||
else if (VN_IS(subtypep, UnpackArrayDType)) {
|
||||
const AstUnpackArrayDType* const oldarrp = VN_AS(subtypep, UnpackArrayDType);
|
||||
const AstNodeDType* const arrsubtypep = oldarrp->subDTypep();
|
||||
if (VN_IS(arrsubtypep, IfaceRefDType)) {
|
||||
const AstIfaceRefDType* const ifacerefp = VN_AS(arrsubtypep, IfaceRefDType);
|
||||
if (!ifacerefp->cellp()) {
|
||||
string name = oldvarp->name();
|
||||
if (dupNames.find(name) != dupNames.end()) {
|
||||
// __02E=. while __DOT__ looks nicer but will break V3LinkDot
|
||||
name = oldmodp->name() + "__02E" + name;
|
||||
}
|
||||
|
||||
AstUnpackArrayDType* arraydtypep = VN_AS(oldvarp->dtypep(), UnpackArrayDType);
|
||||
AstCell* ifacearraycellp = new AstCell{newmodp->fileline(), newmodp->fileline(), name, ifacerefp->ifaceName(), nullptr, nullptr, arraydtypep->rangep()->cloneTree(true)};
|
||||
ifacearraycellp->modp(ifacerefp->ifacep());
|
||||
newmodp->addStmtsp(ifacearraycellp);
|
||||
|
||||
AstIfaceRefDType* const idtypep = new AstIfaceRefDType{newmodp->fileline(), name, ifacerefp->ifaceName()};
|
||||
idtypep->ifacep(nullptr);
|
||||
idtypep->dtypep(idtypep);
|
||||
idtypep->cellp(ifacearraycellp);
|
||||
rootp->typeTablep()->addTypesp(idtypep);
|
||||
|
||||
AstNodeArrayDType* const arrp = new AstUnpackArrayDType{newmodp->fileline(), idtypep, arraydtypep->rangep()->cloneTree(true)};
|
||||
AstVar* varp = new AstVar{newmodp->fileline(), VVarType::IFACEREF, name + "__Viftop", arrp};
|
||||
varp->isIfaceParent(true);
|
||||
ifacearraycellp->addNextHere(varp);
|
||||
ifacearraycellp->hasIfaceVar(true);
|
||||
rootp->typeTablep()->addTypesp(arrp);
|
||||
|
||||
AstPin* const pinp = new AstPin{
|
||||
oldvarp->fileline(), 0, varp->name(),
|
||||
new AstVarRef{varp->fileline(), varp,
|
||||
oldvarp->isWritable() ? VAccess::WRITE : VAccess::READ}};
|
||||
pinp->modVarp(oldvarp);
|
||||
cellp->addPinsp(pinp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user