Fix interface inside generate, bug1001, bug1003.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
f0af8726e3
commit
5e54d3e41a
2
Changes
2
Changes
|
|
@ -15,7 +15,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||||
|
|
||||||
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
|
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
|
||||||
|
|
||||||
**** Fix interface inside generate, bug998. [Johan Bjork]
|
**** Fix interface inside generate, bug998, bug1001, bug1003. [Johan Bjork]
|
||||||
|
|
||||||
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
|
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,13 @@ private:
|
||||||
}
|
}
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||||
|
UINFO(9, " VARXREF "<<nodep<<endl);
|
||||||
|
if (m_namedScope != "" && nodep->inlinedDots() == "") {
|
||||||
|
nodep->inlinedDots(m_namedScope);
|
||||||
|
UINFO(9, " rescope to "<<nodep<<endl);
|
||||||
|
}
|
||||||
|
}
|
||||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||||
// Similar code in V3Inline
|
// Similar code in V3Inline
|
||||||
|
|
@ -218,7 +225,7 @@ private:
|
||||||
}
|
}
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
m_ifDepth = prevIfDepth;
|
m_ifDepth = prevIfDepth;
|
||||||
}
|
}
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,9 @@ private:
|
||||||
exprp);
|
exprp);
|
||||||
m_modp->addStmtp(assp);
|
m_modp->addStmtp(assp);
|
||||||
if (debug()>=9) assp->dumpTree(cout," _new: ");
|
if (debug()>=9) assp->dumpTree(cout," _new: ");
|
||||||
} else if (nodep->modVarp()->isIfaceRef()) {
|
} else if (nodep->modVarp()->isIfaceRef()
|
||||||
|
|| (nodep->modVarp()->subDTypep()->castUnpackArrayDType()
|
||||||
|
&& nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) {
|
||||||
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
||||||
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||||
AstVarRef* refp = exprp->castVarRef();
|
AstVarRef* refp = exprp->castVarRef();
|
||||||
|
|
@ -194,6 +196,8 @@ private:
|
||||||
// the IfaceRef.
|
// the IfaceRef.
|
||||||
if (isIface) {
|
if (isIface) {
|
||||||
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
|
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
|
||||||
|
AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType();
|
||||||
|
origIfaceRefp->cellp(NULL);
|
||||||
AstVar* varNewp = ifaceVarp->cloneTree(false);
|
AstVar* varNewp = ifaceVarp->cloneTree(false);
|
||||||
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||||
arrdtype->addNextHere(ifaceRefp);
|
arrdtype->addNextHere(ifaceRefp);
|
||||||
|
|
@ -220,6 +224,32 @@ private:
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||||
|
bool isIface = nodep->dtypep()->castUnpackArrayDType()
|
||||||
|
&& nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||||
|
if (isIface) {
|
||||||
|
AstUnpackArrayDType* arrdtype = nodep->dtypep()->castUnpackArrayDType();
|
||||||
|
AstNode* prev = NULL;
|
||||||
|
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
|
||||||
|
AstVar* varNewp = nodep->cloneTree(false);
|
||||||
|
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||||
|
arrdtype->addNextHere(ifaceRefp);
|
||||||
|
ifaceRefp->cellp(NULL);
|
||||||
|
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||||
|
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||||
|
varNewp->dtypep(ifaceRefp);
|
||||||
|
if (!prev) {
|
||||||
|
prev = varNewp;
|
||||||
|
} else {
|
||||||
|
prev->addNextHere(varNewp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodep->addNextHere(prev);
|
||||||
|
if (debug()==9) { prev->dumpTree(cout, "newintf: "); cout << endl; }
|
||||||
|
}
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||||
// Any non-direct pins need reconnection with a part-select
|
// Any non-direct pins need reconnection with a part-select
|
||||||
if (!nodep->exprp()) return; // No-connect
|
if (!nodep->exprp()) return; // No-connect
|
||||||
|
|
@ -260,17 +290,55 @@ private:
|
||||||
string index = AstNode::encodeNumber(constp->toSInt());
|
string index = AstNode::encodeNumber(constp->toSInt());
|
||||||
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
|
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
|
||||||
AstVarXRef* newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
|
AstVarXRef* newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
|
||||||
AstVar* varp = varrefp->varp()->cloneTree(true);
|
|
||||||
varp->name(varp->name() + "__TMP__" + "__BRA__" + index + "__KET__");
|
|
||||||
if (!nodep->modVarp()->dtypep()) nodep->v3fatalSrc("No dtype for AstPin");
|
|
||||||
varp->dtypep(nodep->modVarp()->dtypep());
|
|
||||||
newp->addNextHere(varp);
|
|
||||||
newp->varp(varp);
|
|
||||||
newp->dtypep(nodep->modVarp()->dtypep());
|
newp->dtypep(nodep->modVarp()->dtypep());
|
||||||
newp->packagep(varrefp->packagep());
|
newp->packagep(varrefp->packagep());
|
||||||
arrselp->addNextHere(newp);
|
arrselp->addNextHere(newp);
|
||||||
arrselp->unlinkFrBack()->deleteTree();
|
arrselp->unlinkFrBack()->deleteTree();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
AstVar* pinVarp = nodep->modVarp();
|
||||||
|
AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType();
|
||||||
|
if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType())
|
||||||
|
return;
|
||||||
|
AstNode* prevp = NULL;
|
||||||
|
AstNode* prevPinp = NULL;
|
||||||
|
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
||||||
|
// Clone pin varp:
|
||||||
|
for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) {
|
||||||
|
AstVar* varNewp = pinVarp->cloneTree(false);
|
||||||
|
AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType();
|
||||||
|
ifaceRefp->cellp(NULL);
|
||||||
|
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||||
|
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||||
|
varNewp->dtypep(ifaceRefp);
|
||||||
|
if (!prevp) {
|
||||||
|
prevp = varNewp;
|
||||||
|
} else {
|
||||||
|
prevp->addNextHere(varNewp);
|
||||||
|
}
|
||||||
|
// Now also clone the pin itself and update its varref
|
||||||
|
AstPin* newp = nodep->cloneTree(false);
|
||||||
|
newp->modVarp(varNewp);
|
||||||
|
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||||
|
// And replace exprp with a new varxref
|
||||||
|
AstVarRef* varrefp = newp->exprp()->castVarRef();
|
||||||
|
string newname = varrefp->name () + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||||
|
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
|
||||||
|
newVarXRefp->varp(newp->modVarp());
|
||||||
|
newVarXRefp->dtypep(newp->modVarp()->dtypep());
|
||||||
|
newp->exprp()->unlinkFrBack()->deleteTree();
|
||||||
|
newp->exprp(newVarXRefp);
|
||||||
|
if (!prevPinp) {
|
||||||
|
prevPinp = newp;
|
||||||
|
} else {
|
||||||
|
prevPinp->addNextHere(newp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pinVarp->replaceWith(prevp);
|
||||||
|
nodep->replaceWith(prevPinp);
|
||||||
|
pushDeletep(pinVarp);
|
||||||
|
pushDeletep(nodep);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,6 +414,7 @@ public:
|
||||||
// Done. Interface
|
// Done. Interface
|
||||||
} else if (!alwaysCvt
|
} else if (!alwaysCvt
|
||||||
&& connectXRefp
|
&& connectXRefp
|
||||||
|
&& connectXRefp->varp()
|
||||||
&& connectXRefp->varp()->isIfaceRef()) {
|
&& connectXRefp->varp()->isIfaceRef()) {
|
||||||
} else if (!alwaysCvt
|
} else if (!alwaysCvt
|
||||||
&& connBasicp
|
&& connBasicp
|
||||||
|
|
|
||||||
|
|
@ -352,13 +352,14 @@ private:
|
||||||
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
|
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
|
||||||
nodep->modp()->name());
|
nodep->modp()->name());
|
||||||
idtypep->ifacep(NULL); // cellp overrides
|
idtypep->ifacep(NULL); // cellp overrides
|
||||||
|
// In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst
|
||||||
|
idtypep->cellp(nodep); // Only set when real parent cell known.
|
||||||
AstVar* varp;
|
AstVar* varp;
|
||||||
if (nodep->rangep()) {
|
if (nodep->rangep()) {
|
||||||
AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
|
AstNodeArrayDType* arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
|
||||||
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
||||||
VFlagChildDType(), arrp);
|
VFlagChildDType(), arrp);
|
||||||
} else {
|
} else {
|
||||||
idtypep->cellp(nodep); // Only set when real parent cell known
|
|
||||||
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
|
||||||
VFlagChildDType(), idtypep);
|
VFlagChildDType(), idtypep);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -365,12 +365,22 @@ public:
|
||||||
void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE
|
void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE
|
||||||
m_ifaceVarSyms.push_back(symp);
|
m_ifaceVarSyms.push_back(symp);
|
||||||
}
|
}
|
||||||
|
// Iface for a raw or arrayed iface
|
||||||
|
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||||
|
AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType();
|
||||||
|
if (!ifacerefp) {
|
||||||
|
if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) {
|
||||||
|
ifacerefp = arrp->subDTypep()->castIfaceRefDType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ifacerefp;
|
||||||
|
}
|
||||||
void computeIfaceVarSyms() {
|
void computeIfaceVarSyms() {
|
||||||
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
|
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
|
||||||
VSymEnt* varSymp = *it;
|
VSymEnt* varSymp = *it;
|
||||||
AstVar* varp = varSymp->nodep()->castVar();
|
AstVar* varp = varSymp->nodep()->castVar();
|
||||||
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
|
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
|
||||||
AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType();
|
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||||
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
|
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
|
||||||
if (!ifacerefp->ifaceViaCellp()) {
|
if (!ifacerefp->ifaceViaCellp()) {
|
||||||
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
|
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
|
||||||
|
|
@ -408,6 +418,10 @@ public:
|
||||||
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
|
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
|
||||||
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
|
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
|
||||||
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
|
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
|
||||||
|
if (rhsp->nodep()->castCell()
|
||||||
|
&& !rhsp->nodep()->castCell()->modp()->castIface()) {
|
||||||
|
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
|
||||||
|
}
|
||||||
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
|
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
|
||||||
}
|
}
|
||||||
void computeScopeAliases() {
|
void computeScopeAliases() {
|
||||||
|
|
@ -515,6 +529,17 @@ public:
|
||||||
return lookupSymp;
|
return lookupSymp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string removeLastInlineScope(const string& name) {
|
||||||
|
string out = name;
|
||||||
|
string dot = "__DOT__";
|
||||||
|
size_t dotPos = out.rfind(dot, out.size() - dot.length() - 2);
|
||||||
|
if (dotPos == string::npos) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return out.erase(dotPos + dot.length(), string::npos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VSymEnt* findSymPrefixed(VSymEnt* lookupSymp, const string& dotname, string& baddot) {
|
VSymEnt* findSymPrefixed(VSymEnt* lookupSymp, const string& dotname, string& baddot) {
|
||||||
// Find symbol in given point in hierarchy, allowing prefix (post-Inline)
|
// Find symbol in given point in hierarchy, allowing prefix (post-Inline)
|
||||||
// For simplicity lookupSymp may be passed NULL result from findDotted
|
// For simplicity lookupSymp may be passed NULL result from findDotted
|
||||||
|
|
@ -525,7 +550,15 @@ public:
|
||||||
<<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname)
|
<<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname)
|
||||||
<<" at se"<<lookupSymp
|
<<" at se"<<lookupSymp
|
||||||
<<endl);
|
<<endl);
|
||||||
VSymEnt* foundp = lookupSymp->findIdFallback(lookupSymp->symPrefix() + dotname); // Might be NULL
|
string prefix = lookupSymp->symPrefix();
|
||||||
|
VSymEnt* foundp = NULL;
|
||||||
|
while (!foundp) {
|
||||||
|
foundp = lookupSymp->findIdFallback(prefix + dotname); // Might be NULL
|
||||||
|
if (prefix == "") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prefix = removeLastInlineScope(prefix);
|
||||||
|
}
|
||||||
if (!foundp) baddot = dotname;
|
if (!foundp) baddot = dotname;
|
||||||
return foundp;
|
return foundp;
|
||||||
}
|
}
|
||||||
|
|
@ -842,10 +875,12 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||||
VSymEnt* insp = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
|
VSymEnt* insp = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
|
||||||
if (m_statep->forPrimary() && nodep->isGParam()) {
|
if (m_statep->forPrimary() && nodep->isGParam()) {
|
||||||
m_paramNum++;
|
m_paramNum++;
|
||||||
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber"+cvtToStr(m_paramNum), nodep, m_packagep);
|
VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
|
||||||
|
nodep, m_packagep);
|
||||||
symp->exported(false);
|
symp->exported(false);
|
||||||
}
|
}
|
||||||
if (nodep->subDTypep()->castIfaceRefDType()) {
|
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep());
|
||||||
|
if (ifacerefp) {
|
||||||
// Can't resolve until interfaces and modport names are known; see notes at top
|
// Can't resolve until interfaces and modport names are known; see notes at top
|
||||||
m_statep->insertIfaceVarSym(insp);
|
m_statep->insertIfaceVarSym(insp);
|
||||||
}
|
}
|
||||||
|
|
@ -1111,7 +1146,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
||||||
&& nodep->varp()->isIfaceParent()) {
|
&& nodep->varp()->isIfaceParent()) {
|
||||||
UINFO(9,"Iface parent ref var "<<nodep->varp()->name()<<" "<<nodep<<endl);
|
UINFO(9,"Iface parent ref var "<<nodep->varp()->name()<<" "<<nodep<<endl);
|
||||||
// Find the interface cell the var references
|
// Find the interface cell the var references
|
||||||
AstIfaceRefDType* dtypep = nodep->varp()->dtypep()->castIfaceRefDType();
|
AstIfaceRefDType* dtypep = LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
|
||||||
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
|
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
|
||||||
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
|
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
|
||||||
string ifcellname = dtypep->cellName();
|
string ifcellname = dtypep->cellName();
|
||||||
|
|
@ -1154,9 +1189,18 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
||||||
AstVarRef* refp = nodep->rhsp()->castVarRef();
|
AstVarRef* refp = nodep->rhsp()->castVarRef();
|
||||||
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
|
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
|
||||||
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
|
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
|
||||||
string scopename = refp ? refp->name() : xrefp->name();
|
string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : "";
|
||||||
string baddot; VSymEnt* okSymp;
|
VSymEnt* symp = NULL;
|
||||||
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
|
string scopename;
|
||||||
|
while (!symp) {
|
||||||
|
scopename = refp ? refp->name() : (inl.size() ? (inl + xrefp->name()) : xrefp->name());
|
||||||
|
string baddot; VSymEnt* okSymp;
|
||||||
|
symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
|
||||||
|
if (inl == "")
|
||||||
|
break;
|
||||||
|
inl = LinkDotState::removeLastInlineScope(inl);
|
||||||
|
}
|
||||||
|
if (!symp) UINFO(9,"No symbol for interface alias rhs ("<<string(refp?"VARREF ":"VARXREF ")<<scopename<<")"<<endl);
|
||||||
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
|
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
|
||||||
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"<<(void*)symp<<" "<<symp->nodep()<<endl);
|
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"<<(void*)symp<<" "<<symp->nodep()<<endl);
|
||||||
rhsSymp = symp;
|
rhsSymp = symp;
|
||||||
|
|
@ -1647,7 +1691,8 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (AstVar* varp = foundp->nodep()->castVar()) {
|
else if (AstVar* varp = foundp->nodep()->castVar()) {
|
||||||
if (AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType()) {
|
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||||
|
if (ifacerefp) {
|
||||||
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
|
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
|
||||||
// Really this is a scope reference into an interface
|
// Really this is a scope reference into an interface
|
||||||
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
|
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
|
||||||
|
|
@ -2068,6 +2113,7 @@ private:
|
||||||
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
|
||||||
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
checkNoDot(nodep);
|
checkNoDot(nodep);
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,10 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||||
AstVar* modvarp = pinp->modVarp();
|
AstVar* modvarp = pinp->modVarp();
|
||||||
if (modvarp->isIfaceRef()) {
|
if (modvarp->isIfaceRef()) {
|
||||||
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
|
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
|
||||||
|
if (!portIrefp) {
|
||||||
|
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||||
|
}
|
||||||
|
|
||||||
AstIfaceRefDType* pinIrefp = NULL;
|
AstIfaceRefDType* pinIrefp = NULL;
|
||||||
AstNode* exprp = pinp->exprp();
|
AstNode* exprp = pinp->exprp();
|
||||||
if (exprp
|
if (exprp
|
||||||
|
|
@ -512,12 +516,23 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
||||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||||
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||||
//UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
else if (exprp
|
||||||
|
&& exprp->castVarRef()
|
||||||
|
&& exprp->castVarRef()->varp()
|
||||||
|
&& exprp->castVarRef()->varp()->subDTypep()
|
||||||
|
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
|
||||||
|
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||||
|
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||||
|
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||||
|
|
||||||
if (!pinIrefp) {
|
UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
||||||
|
|
||||||
|
if (!portIrefp) {
|
||||||
|
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not an interface" << modvarp);
|
||||||
|
} else if (!pinIrefp) {
|
||||||
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
|
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
|
||||||
} else {
|
} else {
|
||||||
//UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
|
UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
|
||||||
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
|
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
|
||||||
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
|
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
|
||||||
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp);
|
longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+paramValueNumber(pinIrefp);
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ void process () {
|
||||||
if (!v3Global.opt.xmlOnly()) {
|
if (!v3Global.opt.xmlOnly()) {
|
||||||
// Remove cell arrays (must be between V3Width and scoping)
|
// Remove cell arrays (must be between V3Width and scoping)
|
||||||
V3Inst::dearrayAll(v3Global.rootp());
|
V3Inst::dearrayAll(v3Global.rootp());
|
||||||
|
V3LinkDot::linkDotArrayed(v3Global.rootp());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v3Global.opt.xmlOnly()) {
|
if (!v3Global.opt.xmlOnly()) {
|
||||||
|
|
|
||||||
|
|
@ -3735,9 +3735,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
AstVarType type = GRAMMARP->m_varIO;
|
AstVarType type = GRAMMARP->m_varIO;
|
||||||
if (dtypep->castIfaceRefDType()) {
|
|
||||||
if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); VL_DANGLING(arrayp); }
|
|
||||||
}
|
|
||||||
if (!dtypep) { // Created implicitly
|
if (!dtypep) { // Created implicitly
|
||||||
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
|
dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
|
||||||
} else { // May make new variables with same type, so clone
|
} else { // May make new variables with same type, so clone
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug998
|
||||||
|
|
||||||
|
interface intf
|
||||||
|
#(parameter PARAM = 0)
|
||||||
|
();
|
||||||
|
logic val;
|
||||||
|
function integer func (); return 5; endfunction
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t1(intf mod_intf);
|
||||||
|
initial begin
|
||||||
|
$display("%m %d", mod_intf.val);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t();
|
||||||
|
generate
|
||||||
|
begin : TestIf
|
||||||
|
intf #(.PARAM(1)) my_intf [0:0] ();
|
||||||
|
t1 t (.mod_intf(my_intf[0]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug998
|
||||||
|
|
||||||
|
interface intf
|
||||||
|
#(parameter PARAM = 0)
|
||||||
|
();
|
||||||
|
logic val;
|
||||||
|
function integer func (); return 5; endfunction
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t1(intf mod_intf);
|
||||||
|
initial begin
|
||||||
|
$display("%m %d", mod_intf.val);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t2(intf mod_intfs [1:0]);
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
t1 t(.mod_intf(mod_intfs[0]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t();
|
||||||
|
|
||||||
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
|
||||||
|
t2 t2 (.mod_intfs(my_intf));
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -9,23 +9,52 @@ interface intf
|
||||||
#(parameter PARAM = 0)
|
#(parameter PARAM = 0)
|
||||||
();
|
();
|
||||||
logic val;
|
logic val;
|
||||||
|
function integer func (); return 5; endfunction
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
module t1(intf mod_intf);
|
module t1(intf mod_intf);
|
||||||
initial begin
|
initial begin
|
||||||
$display("%d", mod_intf.val);
|
$display("%m %d", mod_intf.val);
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module t();
|
module t();
|
||||||
generate
|
generate
|
||||||
begin : TestIf
|
begin : TestIf
|
||||||
intf #(.PARAM(1)) my_intf;
|
intf #(.PARAM(1)) my_intf ();
|
||||||
|
assign my_intf.val = '0;
|
||||||
t1 t (.mod_intf(my_intf));
|
t1 t (.mod_intf(my_intf));
|
||||||
initial begin
|
// initial $display("%0d", my_intf.func());
|
||||||
$write("*-* All Finished *-*\n");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
intf #(.PARAM(1)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
t1 t (.mod_intf(my_intf));
|
||||||
|
// initial $display("%0d", my_intf.func());
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
localparam LP = 1;
|
||||||
|
logic val;
|
||||||
|
|
||||||
|
generate begin
|
||||||
|
if (LP) begin
|
||||||
|
intf #(.PARAM(2)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
assign val = my_intf.val;
|
||||||
|
end else begin
|
||||||
|
intf #(.PARAM(3)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
assign val = my_intf.val;
|
||||||
|
end
|
||||||
|
end endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("%0d", val);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug1001
|
||||||
|
|
||||||
|
interface intf
|
||||||
|
#(parameter PARAM = 0)
|
||||||
|
();
|
||||||
|
logic val;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t();
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (1) begin
|
||||||
|
intf #(.PARAM(2)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
end else begin
|
||||||
|
intf #(.PARAM(3)) my_intf ();
|
||||||
|
assign my_intf.val = '0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
if (1) begin
|
||||||
|
intf #(.PARAM(2)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
end else begin
|
||||||
|
intf #(.PARAM(3)) my_intf ();
|
||||||
|
assign my_intf.val = '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
begin
|
||||||
|
begin
|
||||||
|
if (1) begin
|
||||||
|
intf #(.PARAM(2)) my_intf ();
|
||||||
|
assign my_intf.val = '1;
|
||||||
|
end else begin
|
||||||
|
intf #(.PARAM(3)) my_intf ();
|
||||||
|
assign my_intf.val = '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug998
|
||||||
|
|
||||||
|
interface intf
|
||||||
|
#(parameter PARAM = 0)
|
||||||
|
();
|
||||||
|
logic val;
|
||||||
|
function integer func (); return 5; endfunction
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t1(intf mod_intf);
|
||||||
|
initial begin
|
||||||
|
$display("%m %d", mod_intf.val);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t();
|
||||||
|
|
||||||
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
|
||||||
|
generate
|
||||||
|
genvar the_genvar;
|
||||||
|
begin
|
||||||
|
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||||
|
begin
|
||||||
|
assign my_intf[the_genvar].val = '1;
|
||||||
|
t1 t (.mod_intf(my_intf[the_genvar]));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
genvar the_second_genvar;
|
||||||
|
begin
|
||||||
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
for (the_second_genvar = 0; the_second_genvar < 2; the_second_genvar++) begin : TestIf
|
||||||
|
begin
|
||||||
|
assign my_intf[the_second_genvar].val = '1;
|
||||||
|
t1 t (.mod_intf(my_intf[the_second_genvar]));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
genvar the_third_genvar;
|
||||||
|
begin
|
||||||
|
for (the_third_genvar = 0; the_third_genvar < 2; the_third_genvar++) begin : TestIf
|
||||||
|
begin
|
||||||
|
intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
assign my_intf[the_third_genvar].val = '1;
|
||||||
|
t1 t (.mod_intf(my_intf[the_third_genvar]));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug998
|
||||||
|
|
||||||
|
interface intf
|
||||||
|
#(parameter PARAM = 0)
|
||||||
|
();
|
||||||
|
logic val;
|
||||||
|
function integer func (); return 5; endfunction
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t1(intf mod_intf);
|
||||||
|
initial begin
|
||||||
|
$display("%m %d", mod_intf.val);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t();
|
||||||
|
|
||||||
|
//intf #(.PARAM(1)) my_intf [1:0] ();
|
||||||
|
intf #(.PARAM(1)) my_intf ();
|
||||||
|
|
||||||
|
generate
|
||||||
|
genvar the_genvar;
|
||||||
|
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||||
|
//assign my_intf[the_genvar].val = '1;
|
||||||
|
//t1 t (.mod_intf(my_intf[the_genvar]));
|
||||||
|
t1 t (.mod_intf(my_intf));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// t1 t (.mod_intf(my_intf[1]));
|
||||||
|
|
||||||
|
// generate
|
||||||
|
// begin : TestIf
|
||||||
|
// assign my_intf[1].val = '1;
|
||||||
|
// t1 t (.mod_intf(my_intf[1]));
|
||||||
|
// end
|
||||||
|
// endgenerate
|
||||||
|
|
||||||
|
// generate
|
||||||
|
// begin
|
||||||
|
// assign my_intf[0].val = '1;
|
||||||
|
// t1 t (.mod_intf(my_intf[0]));
|
||||||
|
// end
|
||||||
|
// endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty.
|
||||||
|
|
||||||
|
// bug998
|
||||||
|
|
||||||
|
module t1(input logic foo);
|
||||||
|
initial begin
|
||||||
|
$display("%m %d", foo);
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t();
|
||||||
|
|
||||||
|
logic [1:0] my_foo;
|
||||||
|
|
||||||
|
generate
|
||||||
|
genvar the_genvar;
|
||||||
|
for (the_genvar = 0; the_genvar < 2; the_genvar++) begin : TestIf
|
||||||
|
//logic tmp_foo;
|
||||||
|
//assign tmp_foo = my_foo[the_genvar];
|
||||||
|
t1 t (.foo(my_foo[the_genvar]));
|
||||||
|
//t1 t (.foo(tmp_foo));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2015 by Johan Bjork.
|
||||||
|
|
||||||
|
parameter N = 4;
|
||||||
|
|
||||||
|
interface a_if #(parameter PARAM = 0) ();
|
||||||
|
logic long_name;
|
||||||
|
modport source (output long_name);
|
||||||
|
modport sink (input long_name);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module intf_source
|
||||||
|
(
|
||||||
|
input logic [N-1:0] intf_input,
|
||||||
|
a_if.source i_intf_source[N-1:0]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign i_intf_source[i].long_name = intf_input[i];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module intf_sink
|
||||||
|
(
|
||||||
|
output [N-1:0] a_out,
|
||||||
|
a_if.sink i_intf_sink[N-1:0]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign a_out[i] = i_intf_sink[i].long_name;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t
|
||||||
|
(
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
logic [N-1:0] a_in;
|
||||||
|
logic [N-1:0] a_out;
|
||||||
|
logic [N-1:0] ack_out;
|
||||||
|
a_if #(.PARAM(1)) tl_intf [N-1:0] ();
|
||||||
|
intf_source source(a_in, tl_intf);
|
||||||
|
intf_sink sink(a_out, tl_intf);
|
||||||
|
|
||||||
|
initial a_in = '0;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
if (ack_out != a_out) begin
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (& a_in) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2015 by Johan Bjork.
|
||||||
|
|
||||||
|
parameter N = 4;
|
||||||
|
|
||||||
|
interface a_if #(parameter PARAM = 0) ();
|
||||||
|
logic long_name;
|
||||||
|
modport source (output long_name);
|
||||||
|
modport sink (input long_name);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module intf_source
|
||||||
|
(
|
||||||
|
input logic [N-1:0] intf_input,
|
||||||
|
a_if.source i_intf_source[N-1:0]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign i_intf_source[i].long_name = intf_input[i];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module intf_sink
|
||||||
|
(
|
||||||
|
output [N-1:0] a_out,
|
||||||
|
a_if.sink i_intf_sink[N-1:0]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign a_out[i] = i_intf_sink[i].long_name;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t
|
||||||
|
(
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
logic [N-1:0] a_in;
|
||||||
|
logic [N-1:0] a_out;
|
||||||
|
logic [N-1:0] ack_out;
|
||||||
|
// verilator lint_off LITENDIAN
|
||||||
|
a_if #(.PARAM(1)) tl_intf [N] ();
|
||||||
|
// verilator lint_on LITENDIAN
|
||||||
|
intf_source source(a_in, tl_intf);
|
||||||
|
intf_sink sink(a_out, tl_intf);
|
||||||
|
|
||||||
|
initial a_in = '0;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
if (ack_out != a_out) begin
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (& a_in) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||||
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2015 by Johan Bjork.
|
||||||
|
|
||||||
|
parameter N = 4;
|
||||||
|
// verilator lint_off LITENDIAN
|
||||||
|
|
||||||
|
interface a_if #(parameter PARAM = 0) ();
|
||||||
|
logic long_name;
|
||||||
|
modport source (output long_name);
|
||||||
|
modport sink (input long_name);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module intf_source
|
||||||
|
(
|
||||||
|
input logic [0:N-1] intf_input,
|
||||||
|
a_if.source i_intf_source[0:N-1]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign i_intf_source[i].long_name = intf_input[i];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module intf_sink
|
||||||
|
(
|
||||||
|
output [0:N-1] a_out,
|
||||||
|
a_if.sink i_intf_sink[0:N-1]
|
||||||
|
);
|
||||||
|
generate
|
||||||
|
for (genvar i=0; i < N;i++) begin
|
||||||
|
assign a_out[i] = i_intf_sink[i].long_name;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module t
|
||||||
|
(
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
logic [0:N-1] a_in;
|
||||||
|
logic [0:N-1] a_out;
|
||||||
|
logic [0:N-1] ack_out;
|
||||||
|
a_if #(.PARAM(1)) tl_intf [0:N-1] ();
|
||||||
|
intf_source source(a_in, tl_intf);
|
||||||
|
intf_sink sink(a_out, tl_intf);
|
||||||
|
|
||||||
|
initial a_in = '0;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
a_in <= a_in + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
ack_out <= ack_out + { {N-1 {1'b0}}, 1'b1 };
|
||||||
|
if (ack_out != a_out) begin
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (& a_in) begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue