Fix ugly interface-to-non-interface errors, bug1112.
This commit is contained in:
parent
fa9208ccdd
commit
473d555dc1
|
|
@ -1759,26 +1759,29 @@ private:
|
|||
// Upper AstDot visitor will handle it from here
|
||||
}
|
||||
else if (foundp->nodep()->castCell()
|
||||
&& allowVar && m_cellp
|
||||
&& foundp->nodep()->castCell()->modp()->castIface()) {
|
||||
// Interfaces can be referenced like a variable for interconnect
|
||||
&& allowVar && m_cellp) {
|
||||
AstCell* cellp = foundp->nodep()->castCell();
|
||||
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
|
||||
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin
|
||||
string findName = nodep->name()+"__Viftop";
|
||||
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
|
||||
AstVar* ifaceRefVarp = ifaceSymp ? ifaceSymp->nodep()->castVar() : NULL;
|
||||
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<<findName);
|
||||
//
|
||||
ok = true;
|
||||
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
|
||||
m_ds.m_dotText += nodep->name();
|
||||
m_ds.m_dotSymp = foundp;
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
UINFO(9," cell -> iface varref "<<foundp->nodep()<<endl);
|
||||
AstNode* newp = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, false);
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
if (cellp->modp()->castIface()) {
|
||||
// Interfaces can be referenced like a variable for interconnect
|
||||
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
|
||||
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin
|
||||
string findName = nodep->name()+"__Viftop";
|
||||
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
|
||||
AstVar* ifaceRefVarp = ifaceSymp ? ifaceSymp->nodep()->castVar() : NULL;
|
||||
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<<findName);
|
||||
//
|
||||
ok = true;
|
||||
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
|
||||
m_ds.m_dotText += nodep->name();
|
||||
m_ds.m_dotSymp = foundp;
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
UINFO(9," cell -> iface varref "<<foundp->nodep()<<endl);
|
||||
AstNode* newp = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, false);
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
} else if (cellp->modp()->castNotFoundModule()) {
|
||||
cellp->v3error("Cannot find file containing interface: " << AstNode::prettyName(cellp->modp()->name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (AstVar* varp = foundp->nodep()->castVar()) {
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||
|
|
@ -1858,7 +1861,9 @@ private:
|
|||
}
|
||||
//
|
||||
if (!ok) {
|
||||
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="");
|
||||
//Cells/interfaces can't be implicit
|
||||
bool isCell = foundp ? foundp->nodep()->castCell() != NULL : false;
|
||||
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="" && !isCell);
|
||||
bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
|
||||
if (err) {
|
||||
if (foundp) {
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
AstVar* modvarp = pinp->modVarp();
|
||||
if (modvarp->isIfaceRef()) {
|
||||
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
|
||||
if (!portIrefp) {
|
||||
if (!portIrefp && modvarp->subDTypep()->castUnpackArrayDType()) {
|
||||
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
}
|
||||
|
||||
|
|
@ -574,7 +574,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
||||
|
||||
if (!portIrefp) {
|
||||
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not an interface" << modvarp);
|
||||
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");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2157,15 +2157,25 @@ private:
|
|||
// otherwise would need some mess to force both sides to proper size
|
||||
}
|
||||
}
|
||||
// Check if an interface is connected to a non-interface and vice versa
|
||||
AstNodeDType* modDTypep = nodep->modVarp()->dtypep();
|
||||
AstNodeDType* exprDTypep = nodep->exprp()->dtypep();
|
||||
if ((modDTypep->castIfaceRefDType() && !exprDTypep->castIfaceRefDType()) ||
|
||||
(exprDTypep->castIfaceRefDType() && !modDTypep->castIfaceRefDType())) {
|
||||
nodep->v3error("Illegal "<<nodep->prettyOperatorName()<<","
|
||||
<<" mismatch between port which is"<<(modDTypep->castIfaceRefDType()?"":" not")<<" an interface,"
|
||||
<<" and expression which is"<<(exprDTypep->castIfaceRefDType()?"":" not")<<" an interface.");
|
||||
}
|
||||
|
||||
// TODO Simple dtype checking, should be a more general check
|
||||
bool hiArray = nodep->exprp()->dtypep()->skipRefp()->castUnpackArrayDType();
|
||||
bool loArray = nodep->modVarp()->dtypep()->skipRefp()->castUnpackArrayDType();
|
||||
bool hiArray = exprDTypep->skipRefp()->castUnpackArrayDType();
|
||||
bool loArray = modDTypep->skipRefp()->castUnpackArrayDType();
|
||||
if (loArray != hiArray && pinwidth != conwidth) {
|
||||
nodep->v3error("Illegal "<<nodep->prettyOperatorName()<<","
|
||||
<<" mismatch between port which is"<<(hiArray?"":" not")<<" an array,"
|
||||
<<" and expression which is"<<(loArray?"":" not")<<" an array.");
|
||||
UINFO(1," Related lo: "<<nodep->exprp()->dtypep()->skipRefp()<<endl);
|
||||
UINFO(1," Related hi: "<<nodep->modVarp()->dtypep()->skipRefp()<<endl);
|
||||
UINFO(1," Related lo: "<<exprDTypep->skipRefp()<<endl);
|
||||
UINFO(1," Related hi: "<<modDTypep->skipRefp()<<endl);
|
||||
}
|
||||
iterateCheckAssign(nodep,"pin connection",nodep->exprp(),FINAL,subDTypep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ compile (
|
|||
# However we no longer gate optimize this
|
||||
expect=>
|
||||
q{%Error: t/t_interface_typo_bad.v:\d+: Parent cell's interface is not found: foo_intf
|
||||
%Warning-IMPLICIT: t/t_interface_typo_bad.v:\d+: Signal definition not found, creating implicitly: the_foo
|
||||
%Error: t/t_interface_typo_bad.v:\d+: Cannot find file containing interface: fo_intf
|
||||
%Error: t/t_interface_typo_bad.v:\d+: Found definition of 'the_foo' as a CELL but expected a variable
|
||||
.*},
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue