Internals: Add UASSERT_OBJ macro to replace hand-done ifs. No functional change intended.
This makes it easier to filter out correctly zero code-coverage lines.
This commit is contained in:
parent
7e54ff1b37
commit
8548ecfdac
|
|
@ -66,7 +66,7 @@ private:
|
|||
|
||||
// METHODS
|
||||
void addActive(AstActive* nodep) {
|
||||
if (!m_scopep) nodep->v3fatalSrc("NULL scope");
|
||||
UASSERT_OBJ(m_scopep, nodep, "NULL scope");
|
||||
m_scopep->addActivep(nodep);
|
||||
}
|
||||
// VISITORS
|
||||
|
|
@ -314,7 +314,8 @@ private:
|
|||
&& VN_IS(oldsensesp->sensesp(), SenItem)
|
||||
&& VN_CAST(oldsensesp->sensesp(), SenItem)->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
|
||||
UASSERT_OBJ(!oldsensesp->sensesp()->nextp(), nodep,
|
||||
"Never senitem should be alone, else the never should be eliminated.");
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
|
|
@ -391,11 +392,10 @@ private:
|
|||
}
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
AstSenItem* subitemp = nodep->sensesp();
|
||||
if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE
|
||||
&& subitemp->edgeType() != AstEdgeType::ET_POSEDGE
|
||||
&& subitemp->edgeType() != AstEdgeType::ET_NEGEDGE) {
|
||||
nodep->v3fatalSrc("Strange activity type under SenGate");
|
||||
}
|
||||
UASSERT_OBJ(subitemp->edgeType() == AstEdgeType::ET_ANYEDGE
|
||||
|| subitemp->edgeType() == AstEdgeType::ET_POSEDGE
|
||||
|| subitemp->edgeType() == AstEdgeType::ET_NEGEDGE,
|
||||
nodep, "Strange activity type under SenGate");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
|
|
|
|||
|
|
@ -72,14 +72,13 @@ private:
|
|||
UINFO(4," ACTIVE "<<nodep<<endl);
|
||||
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
|
||||
AstSenTree* sensesp = nodep->sensesp();
|
||||
if (!sensesp) nodep->v3fatalSrc("NULL");
|
||||
UASSERT_OBJ(sensesp, nodep, "NULL");
|
||||
if (sensesp->sensesp()
|
||||
&& VN_IS(sensesp->sensesp(), SenItem)
|
||||
&& VN_CAST(sensesp->sensesp(), SenItem)->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
if (VL_UNCOVERABLE(sensesp->sensesp()->nextp())) {
|
||||
nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
|
||||
}
|
||||
UASSERT_OBJ(!sensesp->sensesp()->nextp(), nodep,
|
||||
"Never senitem should be alone, else the never should be eliminated.");
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
|
|
@ -101,9 +100,8 @@ private:
|
|||
// Move the active's contents to the other active
|
||||
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
|
||||
if (nodep->sensesStorep()) {
|
||||
if (VL_UNCOVERABLE(sensesp != nodep->sensesStorep())) {
|
||||
nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
|
||||
}
|
||||
UASSERT_OBJ(sensesp == nodep->sensesStorep(), nodep,
|
||||
"sensesStore should have been deleted earlier if different");
|
||||
sensesp->unlinkFrBack();
|
||||
// There may be other references to same sense tree,
|
||||
// we'll be removing all references when we get to them,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private:
|
|||
} else {
|
||||
// V3Coverage assigned us a bucket to increment.
|
||||
AstCoverInc* covincp = VN_CAST(snodep->coverincp(), CoverInc);
|
||||
if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion");
|
||||
UASSERT_OBJ(covincp, snodep, "Missing AstCoverInc under assertion");
|
||||
covincp->unlinkFrBack();
|
||||
if (message!="") covincp->declp()->comment(message);
|
||||
bodysp = covincp;
|
||||
|
|
@ -317,10 +317,11 @@ private:
|
|||
iterateChildren(nodep);
|
||||
uint32_t ticks = 1;
|
||||
if (nodep->ticksp()) {
|
||||
if (!VN_IS(nodep->ticksp(), Const)) nodep->v3fatalSrc("Expected constant ticks, checked in V3Width");
|
||||
UASSERT_OBJ(VN_IS(nodep->ticksp(), Const), nodep,
|
||||
"Expected constant ticks, checked in V3Width");
|
||||
ticks = VN_CAST(nodep->ticksp(), Const)->toUInt();
|
||||
}
|
||||
if (ticks<1) nodep->v3fatalSrc("0 tick should have been checked in V3Width");
|
||||
UASSERT_OBJ(ticks>=1, nodep, "0 tick should have been checked in V3Width");
|
||||
AstNode* inp = nodep->exprp()->unlinkFrBack();
|
||||
AstVar* invarp = NULL;
|
||||
AstSenTree* sentreep = nodep->sentreep(); sentreep->unlinkFrBack();
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
|
|||
|
||||
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
|
||||
// Add to m_nextp, returns this
|
||||
UDEBUGONLY(if (!newp) nodep->v3fatalSrc("Null item passed to addNext"););
|
||||
UDEBUGONLY(UASSERT_OBJ(newp, nodep, "Null item passed to addNext"););
|
||||
nodep->debugTreeChange("-addNextThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-addNextNew: ", __LINE__, true);
|
||||
if (!nodep) { // verilog.y and lots of other places assume this
|
||||
|
|
@ -259,7 +259,8 @@ AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
|
|||
if (oldtailp->m_nextp) {
|
||||
if (oldtailp->m_headtailp) {
|
||||
oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end
|
||||
UDEBUGONLY(if (oldtailp->m_nextp) nodep->v3fatalSrc("Node had next, but headtail says it shouldn't"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!oldtailp->m_nextp, nodep,
|
||||
"Node had next, but headtail says it shouldn't"););
|
||||
} else {
|
||||
// Though inefficent, we are occasionally passed a addNext in the middle of a list.
|
||||
while (oldtailp->m_nextp != NULL) oldtailp = oldtailp->m_nextp;
|
||||
|
|
@ -337,9 +338,9 @@ void AstNode::addNextHere(AstNode* newp) {
|
|||
|
||||
void AstNode::setOp1p(AstNode* newp) {
|
||||
UASSERT(newp, "Null item passed to setOp1p");
|
||||
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!m_op1p, this, "Adding to non-empty, non-list op1"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op1"););
|
||||
this->debugTreeChange("-setOp1pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp1pNew: ", __LINE__, true);
|
||||
m_op1p = newp;
|
||||
|
|
@ -350,9 +351,9 @@ void AstNode::setOp1p(AstNode* newp) {
|
|||
|
||||
void AstNode::setOp2p(AstNode* newp) {
|
||||
UASSERT(newp, "Null item passed to setOp2p");
|
||||
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!m_op2p, this, "Adding to non-empty, non-list op2"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op2"););
|
||||
this->debugTreeChange("-setOp2pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp2pNew: ", __LINE__, true);
|
||||
m_op2p = newp;
|
||||
|
|
@ -363,9 +364,9 @@ void AstNode::setOp2p(AstNode* newp) {
|
|||
|
||||
void AstNode::setOp3p(AstNode* newp) {
|
||||
UASSERT(newp, "Null item passed to setOp3p");
|
||||
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!m_op3p, this, "Adding to non-empty, non-list op3"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op3"););
|
||||
this->debugTreeChange("-setOp3pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp3pNew: ", __LINE__, true);
|
||||
m_op3p = newp;
|
||||
|
|
@ -376,9 +377,9 @@ void AstNode::setOp3p(AstNode* newp) {
|
|||
|
||||
void AstNode::setOp4p(AstNode* newp) {
|
||||
UASSERT(newp, "Null item passed to setOp4p");
|
||||
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!m_op4p, this, "Adding to non-empty, non-list op4"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_backp, newp, "Adding already linked node"););
|
||||
UDEBUGONLY(UASSERT_OBJ(!newp->m_nextp, newp, "Adding list to non-list op4"););
|
||||
this->debugTreeChange("-setOp4pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp4pNew: ", __LINE__, true);
|
||||
m_op4p = newp;
|
||||
|
|
@ -580,9 +581,11 @@ void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set
|
|||
// Insert the whole old list following the new node's list.
|
||||
// Thus a unlink without next, followed by relink, gives the same list.
|
||||
AstNode* newlistlastp = newp->m_headtailp;
|
||||
if (newlistlastp->m_nextp && newlistlastp!=newp) newp->v3fatalSrc("Headtailp tail isn't at the tail");
|
||||
UASSERT_OBJ(!(newlistlastp->m_nextp && newlistlastp!=newp), newp,
|
||||
"Headtailp tail isn't at the tail");
|
||||
AstNode* oldlistlastp = pointpr->m_headtailp;
|
||||
if (oldlistlastp->m_nextp && oldlistlastp!=pointpr) newp->v3fatalSrc("Old headtailp tail isn't at the tail");
|
||||
UASSERT_OBJ(!(oldlistlastp->m_nextp && oldlistlastp!=pointpr), newp,
|
||||
"Old headtailp tail isn't at the tail");
|
||||
// Next links
|
||||
newlistlastp->m_nextp = pointpr;
|
||||
pointpr->m_backp = newlistlastp;
|
||||
|
|
@ -772,14 +775,15 @@ void AstNode::iterateAndNext(AstNVisitor& v) {
|
|||
// there's no lower level reason yet though the back must exist.
|
||||
AstNode* nodep = this;
|
||||
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
|
||||
if (VL_UNCOVERABLE(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
|
||||
UASSERT_OBJ(!(nodep && !nodep->m_backp), nodep,
|
||||
"iterateAndNext node has no back");
|
||||
#endif
|
||||
if (nodep) ASTNODE_PREFETCH(nodep->m_nextp);
|
||||
while (nodep) { // effectively: if (!this) return; // Callers rely on this
|
||||
if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp);
|
||||
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
|
||||
// Desirable check, but many places where multiple iterations are OK
|
||||
//if (VL_UNCOVERABLE(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
|
||||
// UASSERT_OBJ(!niterp->m_iterpp, niterp, "IterateAndNext under iterateAndNext may miss edits");
|
||||
// Optimization note: Doing PREFETCH_RW on m_iterpp is a net even
|
||||
// cppcheck-suppress nullPointer
|
||||
niterp->m_iterpp = &niterp;
|
||||
|
|
@ -856,7 +860,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
|
|||
else if (this->m_backp->m_op3p == this) nextnodepp = &(this->m_backp->m_op3p);
|
||||
else if (this->m_backp->m_op4p == this) nextnodepp = &(this->m_backp->m_op4p);
|
||||
else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp);
|
||||
if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself");
|
||||
UASSERT_OBJ(nextnodepp, this, "Node's back doesn't point to forward to node itself");
|
||||
{
|
||||
nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
}
|
||||
|
|
@ -934,13 +938,11 @@ V3Hash::V3Hash(const string& name) {
|
|||
|
||||
void AstNode::checkTreeIter(AstNode* backp) {
|
||||
// private: Check a tree and children
|
||||
if (backp != this->backp()) {
|
||||
this->v3fatalSrc("Back node inconsistent");
|
||||
}
|
||||
UASSERT_OBJ(backp == this->backp(), this, "Back node inconsistent");
|
||||
if (VN_IS(this, NodeTermop) || VN_IS(this, NodeVarRef)) {
|
||||
// Termops have a short-circuited iterateChildren, so check usage
|
||||
if (op1p()||op2p()||op3p()||op4p())
|
||||
this->v3fatalSrc("Terminal operation with non-terminals");
|
||||
UASSERT_OBJ(!(op1p()||op2p()||op3p()||op4p()), this,
|
||||
"Terminal operation with non-terminals");
|
||||
}
|
||||
if (m_op1p) m_op1p->checkTreeIterList(this);
|
||||
if (m_op2p) m_op2p->checkTreeIterList(this);
|
||||
|
|
@ -955,12 +957,13 @@ void AstNode::checkTreeIterList(AstNode* backp) {
|
|||
AstNode* tailp = this;
|
||||
for (AstNode* nodep=headp; nodep; nodep=nodep->nextp()) {
|
||||
nodep->checkTreeIter(backp);
|
||||
if (headp!=this && nextp()) this->v3fatalSrc("Headtailp should be null in middle of lists");
|
||||
UASSERT_OBJ(headp==this || !nextp(), this,
|
||||
"Headtailp should be null in middle of lists");
|
||||
tailp = nodep;
|
||||
backp = nodep;
|
||||
}
|
||||
if (headp->m_headtailp != tailp) headp->v3fatalSrc("Tail in headtailp is inconsistent");
|
||||
if (tailp->m_headtailp != headp) tailp->v3fatalSrc("Head in headtailp is inconsistent");
|
||||
UASSERT_OBJ(headp->m_headtailp == tailp, headp, "Tail in headtailp is inconsistent");
|
||||
UASSERT_OBJ(tailp->m_headtailp == headp, tailp, "Head in headtailp is inconsistent");
|
||||
}
|
||||
|
||||
void AstNode::checkTree() {
|
||||
|
|
@ -1096,12 +1099,13 @@ void AstNode::v3errorEnd(std::ostringstream& str) const {
|
|||
// Data type conversion
|
||||
|
||||
void AstNode::dtypeChgSigned(bool flag) {
|
||||
if (!dtypep()) this->v3fatalSrc("No dtype when changing to (un)signed");
|
||||
UASSERT_OBJ(dtypep(), this, "No dtype when changing to (un)signed");
|
||||
dtypeChgWidthSigned(dtypep()->width(), dtypep()->widthMin(),
|
||||
flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED);
|
||||
}
|
||||
void AstNode::dtypeChgWidth(int width, int widthMin) {
|
||||
if (!dtypep()) this->v3fatalSrc("No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise
|
||||
UASSERT_OBJ(dtypep(), this,
|
||||
"No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise
|
||||
dtypeChgWidthSigned(width, widthMin, dtypep()->numeric());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -642,28 +642,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
|||
}
|
||||
|
||||
bool AstSenTree::hasClocked() const {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (senp->isClocked()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasSettle() const {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (senp->isSettle()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasInitial() const {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (senp->isInitial()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasCombo() const {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (senp->isCombo()) return true;
|
||||
}
|
||||
|
|
@ -764,12 +764,12 @@ AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
|
|||
// Special walking tree inserters
|
||||
|
||||
void AstNode::addBeforeStmt(AstNode* newp, AstNode*) {
|
||||
if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt");
|
||||
UASSERT_OBJ(backp(), newp, "Can't find current statement to addBeforeStmt");
|
||||
// Look up; virtual call will find where to put it
|
||||
this->backp()->addBeforeStmt(newp, this);
|
||||
}
|
||||
void AstNode::addNextStmt(AstNode* newp, AstNode*) {
|
||||
if (!backp()) newp->v3fatalSrc("Can't find current statement to addNextStmt");
|
||||
UASSERT_OBJ(backp(), newp, "Can't find current statement to addNextStmt");
|
||||
// Look up; virtual call will find where to put it
|
||||
this->backp()->addNextStmt(newp, this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1941,7 +1941,7 @@ public:
|
|||
AstBind(FileLine* fl, const string& name, AstNode* cellsp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
if (!VN_IS(cellsp, Cell)) cellsp->v3fatalSrc("Only cells allowed to be bound");
|
||||
UASSERT_OBJ(VN_IS(cellsp, Cell), cellsp, "Only cells allowed to be bound");
|
||||
addNOp1p(cellsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Bind)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ private:
|
|||
|
||||
// Remap var names and replace lower Begins
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
if (nodep->genforp()) nodep->v3fatalSrc("GENFORs should have been expanded earlier");
|
||||
UASSERT_OBJ(!nodep->genforp(), nodep, "GENFORs should have been expanded earlier");
|
||||
}
|
||||
m_namedScope = oldScope;
|
||||
m_unnamedScope = oldUnnamed;
|
||||
|
|
|
|||
|
|
@ -60,10 +60,9 @@ public:
|
|||
// Called by operator delete on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()>=9) cout<<"-nodeDel: "<<cvtToHex(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (VL_UNCOVERABLE(iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED))) {
|
||||
reinterpret_cast<const AstNode*>(nodep)
|
||||
->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
|
||||
}
|
||||
UASSERT_OBJ(!(iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)),
|
||||
reinterpret_cast<const AstNode*>(nodep),
|
||||
"Deleting AstNode object that was never tracked or already deleted");
|
||||
if (iter!=s_nodes.end()) s_nodes.erase(iter);
|
||||
}
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
|
||||
|
|
@ -74,9 +73,8 @@ public:
|
|||
// Called by operator new on any node - only if VL_LEAK_CHECKS
|
||||
if (debug()>=9) cout<<"-nodeNew: "<<cvtToHex(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (VL_UNCOVERABLE(iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED))) {
|
||||
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
|
||||
}
|
||||
UASSERT_OBJ(!(iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED)),
|
||||
nodep, "Newing AstNode object that is already allocated");
|
||||
if (iter == s_nodes.end()) {
|
||||
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
|
||||
s_nodes.insert(make_pair(nodep, flags));
|
||||
|
|
@ -101,14 +99,12 @@ public:
|
|||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
} else {
|
||||
if (VL_UNCOVERABLE(!(iter->second & FLAG_ALLOCATED))) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
UASSERT_OBJ(iter->second & FLAG_ALLOCATED, nodep,
|
||||
"AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
}
|
||||
if (VL_UNCOVERABLE(iter->second & FLAG_IN_TREE)) {
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location");
|
||||
}
|
||||
UASSERT_OBJ(!(iter->second & FLAG_IN_TREE), nodep,
|
||||
"AstNode is already in tree at another location");
|
||||
}
|
||||
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
|
||||
if (iter == s_nodes.end()) {
|
||||
|
|
@ -230,36 +226,31 @@ public:
|
|||
class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
void checkWidthMin(const AstNode* nodep) {
|
||||
if (VL_UNCOVERABLE(nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH)) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
}
|
||||
UASSERT_OBJ(nodep->width() == nodep->widthMin()
|
||||
|| v3Global.widthMinUsage() != VWidthMinUsage::MATCHES_WIDTH,
|
||||
nodep, "Width != WidthMin");
|
||||
}
|
||||
void processAndIterate(AstNode* nodep) {
|
||||
BrokenTable::setUnder(nodep, true);
|
||||
const char* whyp = nodep->broken();
|
||||
if (VL_UNCOVERABLE(whyp)) {
|
||||
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
|
||||
}
|
||||
UASSERT_OBJ(!whyp, nodep,
|
||||
"Broken link in node (or something without maybePointedTo): "<<whyp);
|
||||
if (nodep->dtypep()) {
|
||||
if (VL_UNCOVERABLE(!nodep->dtypep()->brokeExists())) {
|
||||
nodep->v3fatalSrc("Broken link in node->dtypep() to "
|
||||
<<cvtToHex(nodep->dtypep()));
|
||||
} else if (VL_UNCOVERABLE(!VN_IS(nodep->dtypep(), NodeDType))) {
|
||||
nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "
|
||||
<<cvtToHex(nodep->dtypep()));
|
||||
}
|
||||
UASSERT_OBJ(nodep->dtypep()->brokeExists(), nodep,
|
||||
"Broken link in node->dtypep() to "<<cvtToHex(nodep->dtypep()));
|
||||
UASSERT_OBJ(VN_IS(nodep->dtypep(), NodeDType), nodep,
|
||||
"Non-dtype link in node->dtypep() to "<<cvtToHex(nodep->dtypep()));
|
||||
}
|
||||
if (v3Global.assertDTypesResolved()) {
|
||||
if (nodep->hasDType()) {
|
||||
if (VL_UNCOVERABLE(!nodep->dtypep())) nodep->v3fatalSrc(
|
||||
"No dtype on node with hasDType(): "<<nodep->prettyTypeName());
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep,
|
||||
"No dtype on node with hasDType(): "<<nodep->prettyTypeName());
|
||||
} else {
|
||||
if (VL_UNCOVERABLE(nodep->dtypep())) nodep->v3fatalSrc(
|
||||
"DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
UASSERT_OBJ(!nodep->dtypep(), nodep,
|
||||
"DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
}
|
||||
if (VL_UNCOVERABLE(nodep->getChildDTypep())) nodep->v3fatalSrc(
|
||||
"childDTypep() non-null on node after should have removed");
|
||||
UASSERT_OBJ(!nodep->getChildDTypep(), nodep,
|
||||
"childDTypep() non-null on node after should have removed");
|
||||
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
|
||||
}
|
||||
checkWidthMin(nodep);
|
||||
|
|
@ -268,12 +259,11 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
processAndIterate(nodep);
|
||||
if (VL_UNCOVERABLE(v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue())) {
|
||||
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
|
||||
}
|
||||
UASSERT_OBJ(!(v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue()),
|
||||
nodep, "Assignment LHS is not an lvalue");
|
||||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ private:
|
|||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
//if (debug()>=9) icondp->dumpTree(cout, " caseitem: ");
|
||||
AstConst* iconstp = VN_CAST(icondp, Const);
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
|
||||
UASSERT_OBJ(iconstp, nodep, "above 'can't parse' should have caught this");
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -633,9 +633,9 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
if (m_scopep) {
|
||||
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block");
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
||||
UINFO(5," VARREF to "<<varscp<<endl);
|
||||
// We use weight of one for normal edges,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public:
|
|||
m_tlChgFuncp->addStmtsp(new AstCReturn(m_scopetopp->fileline(), callp));
|
||||
} else {
|
||||
AstCReturn* returnp = VN_CAST(m_tlChgFuncp->stmtsp(), CReturn);
|
||||
if (!returnp) m_scopetopp->v3fatalSrc("Lost CReturn in top change function");
|
||||
UASSERT_OBJ(returnp, m_scopetopp, "Lost CReturn in top change function");
|
||||
// This is currently using AstLogOr which will shortcut the
|
||||
// evaluation if any function returns true. This is likely what
|
||||
// we want and is similar to the logic already in use inside
|
||||
|
|
@ -260,8 +260,8 @@ private:
|
|||
AstNode::user1ClearTree();
|
||||
// Create the change detection function
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level,"
|
||||
" perhaps you have no statements?");
|
||||
UASSERT_OBJ(scopep, nodep,
|
||||
"No scope found on top level, perhaps you have no statements?");
|
||||
m_statep->m_scopetopp = scopep;
|
||||
|
||||
// Create a wrapper change detection function that calls each change detection function
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ private:
|
|||
} else {
|
||||
nodep->dtypeChgWidth(width, nodep->widthMin());
|
||||
AstNodeDType* new_dtypep2 = nodep->dtypep();
|
||||
if (new_dtypep2 == old_dtypep) nodep->v3fatalSrc("Dtype didn't change when width changed");
|
||||
UASSERT_OBJ(new_dtypep2 != old_dtypep, nodep,
|
||||
"Dtype didn't change when width changed");
|
||||
old_dtypep->user3p(new_dtypep2); // Remember for next time
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -557,11 +557,10 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
for (V3GraphVertex* vertexp = m_graph.verticesBeginp();
|
||||
vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (GaterVarVertex* vVxp = dynamic_cast<GaterVarVertex*>(vertexp)) {
|
||||
if (!vVxp->inBeginp()) {
|
||||
// At this point, any variable not linked is an error
|
||||
// (It should have at least landed under the Head node)
|
||||
vVxp->nodep()->v3fatalSrc("Variable became stranded in clk gate detection");
|
||||
}
|
||||
// At this point, any variable not linked is an error
|
||||
// (It should have at least landed under the Head node)
|
||||
UASSERT_OBJ(vVxp->inBeginp(), vVxp->nodep(),
|
||||
"Variable became stranded in clk gate detection");
|
||||
if (!lastVxp || vVxp->sortCmp(lastVxp)) {
|
||||
// Different sources for this new node
|
||||
color++;
|
||||
|
|
@ -612,7 +611,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
// Edges from IFs represent a real IF branch in the equation tree
|
||||
//UINFO(9," ifver "<<cvtToHex(edgep)<<" cc"<<edgep->dotColor()<<endl);
|
||||
eqnp = cVxp->nodep()->condp()->cloneTree(true);
|
||||
if (!eqnp) cVxp->nodep()->v3fatalSrc("null condition");
|
||||
UASSERT_OBJ(eqnp, cVxp->nodep(), "null condition");
|
||||
if (cedgep->ifelseFalse()) {
|
||||
eqnp = new AstNot(eqnp->fileline(), eqnp);
|
||||
}
|
||||
|
|
@ -646,7 +645,8 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
lastExprp = newExprFromGraph(vVxp);
|
||||
}
|
||||
// Mark variable to move
|
||||
if (vVxp->nodep()->user2p()) vVxp->nodep()->v3fatalSrc("One variable got marked under two gaters");
|
||||
UASSERT_OBJ(!vVxp->nodep()->user2p(), vVxp->nodep(),
|
||||
"One variable got marked under two gaters");
|
||||
vVxp->nodep()->user2p(lastExprp);
|
||||
m_statBits += vVxp->nodep()->width(); // Moving a wide bus counts more!
|
||||
// There shouldn't be two possibilities we want to
|
||||
|
|
@ -675,7 +675,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
#else
|
||||
// Make a SenGate
|
||||
AstSenItem* oldsenitemsp = VN_CAST(nodep->sensesp()->sensesp(), SenItem);
|
||||
if (!oldsenitemsp) nodep->v3fatalSrc("SenTree doesn't have any SenItem under it");
|
||||
UASSERT_OBJ(oldsenitemsp, nodep, "SenTree doesn't have any SenItem under it");
|
||||
|
||||
AstSenTree* sensesp = new AstSenTree(nodep->fileline(),
|
||||
new AstSenGate(nodep->fileline(),
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ private:
|
|||
}
|
||||
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
||||
AstNode* senEqnp = createSenseEquation(sensesp->sensesp());
|
||||
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
|
||||
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* newifp = new AstIf(sensesp->fileline(), senEqnp, NULL, NULL);
|
||||
return (newifp);
|
||||
}
|
||||
|
|
@ -193,7 +193,8 @@ private:
|
|||
UINFO(4," TOPSCOPE "<<nodep<<endl);
|
||||
m_topScopep = nodep;
|
||||
m_scopep = nodep->scopep();
|
||||
if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?");
|
||||
UASSERT_OBJ(m_scopep, nodep,
|
||||
"No scope found on top level, perhaps you have no statements?");
|
||||
//VV***** We reset all user1p()
|
||||
AstNode::user1ClearTree();
|
||||
// Make top functions
|
||||
|
|
@ -263,7 +264,7 @@ private:
|
|||
m_scopep = nodep;
|
||||
iterateChildren(nodep);
|
||||
if (AstNode* movep = nodep->finalClksp()) {
|
||||
if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope");
|
||||
UASSERT_OBJ(m_topScopep, nodep, "Final clocks under non-top scope");
|
||||
movep->unlinkFrBackWithNext();
|
||||
m_evalFuncp->addFinalsp(movep);
|
||||
}
|
||||
|
|
@ -346,13 +347,14 @@ private:
|
|||
if (!m_topScopep || !nodep->stmtsp()) {
|
||||
// Not at the top or empty block...
|
||||
// Only empty blocks should be leftover on the non-top. Killem.
|
||||
if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active");
|
||||
UASSERT_OBJ(!nodep->stmtsp(), nodep, "Non-empty lower active");
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
} else if (m_mtaskBodyp) {
|
||||
UINFO(4," TR ACTIVE "<<nodep<<endl);
|
||||
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
if (nodep->hasClocked()) {
|
||||
if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity");
|
||||
UASSERT_OBJ(!nodep->hasInitial(), nodep,
|
||||
"Initial block should not have clock sensitivity");
|
||||
if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) {
|
||||
UINFO(4," sameSenseTree\n");
|
||||
} else {
|
||||
|
|
@ -377,7 +379,8 @@ private:
|
|||
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
if (nodep->hasClocked()) {
|
||||
// Remember the latest sensitivity so we can compare it next time
|
||||
if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity");
|
||||
UASSERT_OBJ(!nodep->hasInitial(), nodep,
|
||||
"Initial block should not have clock sensitivity");
|
||||
if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) {
|
||||
UINFO(4," sameSenseTree\n");
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ public:
|
|||
AstCCall* callp = eqit->second;
|
||||
if (!callp->user3()) { // !already done
|
||||
UINFO(4, " Called "<<callp<<endl);
|
||||
if (callp->funcp() != oldfuncp) callp->v3fatalSrc("Call list broken, points to call w/different func");
|
||||
UASSERT_OBJ(callp->funcp() == oldfuncp, callp,
|
||||
"Call list broken, points to call w/different func");
|
||||
if (newfuncp) {
|
||||
AstCCall* newp = new AstCCall(callp, newfuncp);
|
||||
// Special new AstCCall form above transfers children of callp to newfuncp
|
||||
|
|
@ -236,7 +237,7 @@ private:
|
|||
V3Hash hashval = it->first;
|
||||
AstNode* node1p = it->second;
|
||||
if (!VN_IS(node1p, CFunc)) continue;
|
||||
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes");
|
||||
UASSERT_OBJ(!hashval.isIllegal(), node1p, "Illegal (unhashed) nodes");
|
||||
for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) {
|
||||
AstNode* node2p = eqit->second;
|
||||
if (!(eqit->first == hashval)) break;
|
||||
|
|
|
|||
|
|
@ -589,9 +589,8 @@ private:
|
|||
void replaceNum(AstNode* oldp, const V3Number& num) {
|
||||
// Replace oldp node with a constant set to specified value
|
||||
UASSERT(oldp, "Null old");
|
||||
if (VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()) {
|
||||
oldp->v3fatalSrc("Already constant??");
|
||||
}
|
||||
UASSERT_OBJ(!(VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()),
|
||||
oldp, "Already constant??");
|
||||
AstNode* newp = new AstConst(oldp->fileline(), num);
|
||||
newp->dtypeFrom(oldp);
|
||||
if (debug()>5) oldp->dumpTree(cout, " const_old: ");
|
||||
|
|
@ -810,7 +809,8 @@ private:
|
|||
int rstart = rselp->lsbConst();
|
||||
int rwidth = rselp->widthConst();
|
||||
|
||||
if ((rstart + rwidth) != lstart) nodep->v3fatalSrc("tried to merge two selects which are not adjacent");
|
||||
UASSERT_OBJ((rstart + rwidth) == lstart, nodep,
|
||||
"tried to merge two selects which are not adjacent");
|
||||
AstSel* newselp = new AstSel(lselp->fromp()->fileline(),
|
||||
rselp->fromp()->cloneTree(false), rstart, lwidth+rwidth);
|
||||
UINFO(5, "merged two adjacent sel "<<lselp <<" and "<<rselp<< " to one "<<newselp<<endl);
|
||||
|
|
@ -1066,7 +1066,7 @@ private:
|
|||
int msb2 = lsb2+lc2p->width()-1;
|
||||
int lsb1 = msb2+1;
|
||||
int msb1 = lsb1+lc1p->width()-1;
|
||||
if (msb1!=(conp->width()-1)) nodep->v3fatalSrc("Width calc mismatch");
|
||||
UASSERT_OBJ(msb1 == (conp->width()-1), nodep, "Width calc mismatch");
|
||||
// Form ranges
|
||||
AstSel* sel1p = new AstSel(conp->fileline(), rhsp, lsb1, msb1-lsb1+1);
|
||||
AstSel* sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2-lsb2+1);
|
||||
|
|
@ -1081,7 +1081,7 @@ private:
|
|||
newp = AstNode::addNext(newp, asn1ap);
|
||||
newp = AstNode::addNext(newp, asn2ap);
|
||||
} else {
|
||||
if (!m_modp) nodep->v3fatalSrc("Not under module");
|
||||
UASSERT_OBJ(m_modp, nodep, "Not under module");
|
||||
// We could create just one temp variable, but we'll get better optimization
|
||||
// if we make one per term.
|
||||
string name1 = (string("__Vconcswap")+cvtToStr(m_modp->varNumGetInc()));
|
||||
|
|
@ -1234,7 +1234,7 @@ private:
|
|||
} else {
|
||||
// Fetch the result
|
||||
V3Number* outnump = simvis.fetchNumberNull(nodep);
|
||||
if (!outnump) nodep->v3fatalSrc("No number returned from simulation");
|
||||
UASSERT_OBJ(outnump, nodep, "No number returned from simulation");
|
||||
// Replace it
|
||||
replaceNum(nodep,*outnump); VL_DANGLING(nodep);
|
||||
}
|
||||
|
|
@ -1440,7 +1440,7 @@ private:
|
|||
AstNode* fromp = repp->lhsp();
|
||||
AstConst* lsbp = VN_CAST(nodep->lsbp(), Const); if (!lsbp) return false;
|
||||
AstNode* widthp = nodep->widthp(); if (!VN_IS(widthp, Const)) return false;
|
||||
if (!fromp->width()) nodep->v3fatalSrc("Not widthed");
|
||||
UASSERT_OBJ(fromp->width(), nodep, "Not widthed");
|
||||
if ((lsbp->toUInt() / fromp->width())
|
||||
!= ((lsbp->toUInt()+nodep->width()-1) / fromp->width())) return false;
|
||||
//
|
||||
|
|
@ -1500,7 +1500,7 @@ private:
|
|||
void replaceSelIntoBiop(AstSel* nodep) {
|
||||
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
|
||||
AstNodeBiop* fromp = VN_CAST(nodep->fromp()->unlinkFrBack(), NodeBiop);
|
||||
if (!fromp) nodep->v3fatalSrc("Called on non biop");
|
||||
UASSERT_OBJ(fromp, nodep, "Called on non biop");
|
||||
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->widthp()->unlinkFrBack();
|
||||
//
|
||||
|
|
@ -1517,7 +1517,7 @@ private:
|
|||
void replaceSelIntoUniop(AstSel* nodep) {
|
||||
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
|
||||
AstNodeUniop* fromp = VN_CAST(nodep->fromp()->unlinkFrBack(), NodeUniop);
|
||||
if (!fromp) nodep->v3fatalSrc("Called on non biop");
|
||||
UASSERT_OBJ(fromp, nodep, "Called on non biop");
|
||||
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->widthp()->unlinkFrBack();
|
||||
//
|
||||
|
|
@ -1564,7 +1564,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(nodep->varp(), nodep, "Not linked");
|
||||
bool did = false;
|
||||
if (m_doV && nodep->varp()->valuep() && !m_attrp) {
|
||||
//if (debug()) valuep->dumpTree(cout, " visitvaref: ");
|
||||
|
|
@ -1627,7 +1627,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstEnumItemRef* nodep) {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
|
||||
bool did = false;
|
||||
if (nodep->itemp()->valuep()) {
|
||||
//if (debug()) nodep->varp()->valuep()->dumpTree(cout, " visitvaref: ");
|
||||
|
|
@ -1682,7 +1682,7 @@ private:
|
|||
UINFO(8,"senItem(NOT...) "<<nodep<<" "<<invert<<endl);
|
||||
if (invert) nodep->edgeType( nodep->edgeType().invert() );
|
||||
AstNodeVarRef* senvarp = VN_CAST(lastSensp->unlinkFrBack(), NodeVarRef);
|
||||
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
|
||||
UASSERT_OBJ(senvarp, sensp, "Non-varref sensitivity variable");
|
||||
sensp->replaceWith(senvarp);
|
||||
sensp->deleteTree(); VL_DANGLING(sensp);
|
||||
} else if (!m_doNConst // Deal with later when doNConst missing
|
||||
|
|
@ -1690,7 +1690,8 @@ private:
|
|||
|| VN_IS(nodep->sensp(), Const))) {
|
||||
} else if (nodep->isIllegal()) { // Deal with later
|
||||
} else {
|
||||
if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable");
|
||||
UASSERT_OBJ(!(nodep->hasVar() && !nodep->varrefp()), nodep,
|
||||
"Null sensitivity variable");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ private:
|
|||
// duplicated), not the covertoggle, but we need to get back to the
|
||||
// covertoggle which is immediately above, so:
|
||||
AstCoverToggle* removep = VN_CAST(duporigp->backp(), CoverToggle);
|
||||
if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
|
||||
UASSERT_OBJ(removep, nodep, "CoverageJoin duplicate of wrong type");
|
||||
UINFO(8," Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
|
||||
UINFO(8," dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);
|
||||
// The CoverDecl the duplicate pointed to now needs to point to the
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private:
|
|||
AstVarScope* createVarSc(AstVarScope* oldvarscp, const string& name,
|
||||
int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
|
||||
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
|
||||
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
|
||||
UASSERT_OBJ(oldvarscp->scopep(), oldvarscp, "Var unscoped");
|
||||
AstVar* varp;
|
||||
AstNodeModule* addmodp = oldvarscp->scopep()->modp();
|
||||
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
|
||||
|
|
@ -158,7 +158,7 @@ private:
|
|||
}
|
||||
void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) {
|
||||
// Check for MULTIDRIVEN, and if so make new sentree that joins old & new sentree
|
||||
if (!oldactivep) varrefp->v3fatalSrc("<= old dly assignment not put under sensitivity block");
|
||||
UASSERT_OBJ(oldactivep, varrefp, "<= old dly assignment not put under sensitivity block");
|
||||
if (oldactivep->sensesp() != m_activep->sensesp()) {
|
||||
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
|
||||
&& !varrefp->varp()->user2()) {
|
||||
|
|
@ -203,10 +203,9 @@ private:
|
|||
} else {
|
||||
arrayselp = VN_CAST(lhsp, ArraySel);
|
||||
}
|
||||
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
|
||||
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
}
|
||||
UASSERT_OBJ(arrayselp, nodep, "No arraysel under bitsel?");
|
||||
UASSERT_OBJ(!VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType), nodep,
|
||||
"ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
|
||||
//
|
||||
//=== Dimensions: __Vdlyvdim__
|
||||
|
|
@ -217,8 +216,8 @@ private:
|
|||
dimvalp.push_front(valp);
|
||||
}
|
||||
AstVarRef* varrefp = VN_CAST(dimselp, VarRef);
|
||||
if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels");
|
||||
if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
UASSERT_OBJ(varrefp, nodep, "No var underneath arraysels");
|
||||
UASSERT_OBJ(varrefp->varScopep(), varrefp, "Var didn't get varscoped in V3Scope.cpp");
|
||||
varrefp->unlinkFrBack();
|
||||
AstVar* oldvarp = varrefp->varp();
|
||||
int modVecNum = m_scopeVecMap[varrefp->varScopep()]++;
|
||||
|
|
@ -333,7 +332,8 @@ private:
|
|||
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
|
||||
// we can share the IF statement too
|
||||
postLogicp = VN_CAST(finalp->user4p(), If);
|
||||
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||
UASSERT_OBJ(postLogicp, nodep,
|
||||
"Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||
} else {
|
||||
postLogicp = new AstIf(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), setvscp, false),
|
||||
|
|
@ -400,12 +400,12 @@ private:
|
|||
if (m_inDly && nodep->lvalue()) {
|
||||
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
|
||||
markVarUsage(nodep->varScopep(), VU_DLY);
|
||||
if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block");
|
||||
UASSERT_OBJ(m_activep, nodep, "<= not under sensitivity block");
|
||||
if (!m_activep->hasClocked()) {
|
||||
nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
|
||||
}
|
||||
AstVarScope* oldvscp = nodep->varScopep();
|
||||
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
UASSERT_OBJ(oldvscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
AstVarScope* dlyvscp = VN_CAST(oldvscp->user1p(), VarScope);
|
||||
if (dlyvscp) { // Multiple use of delayed variable
|
||||
AstActive* oldactivep = VN_CAST(dlyvscp->user2p(), Active);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ private:
|
|||
// bitmask instead of widths....)
|
||||
// See t_func_crc for an example test that requires this
|
||||
VFlagLogicPacked(), nodep->width());
|
||||
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
|
||||
UASSERT_OBJ(m_funcp, nodep, "Deep expression not under a function");
|
||||
m_funcp->addInitsp(varp);
|
||||
// Replace node tree with reference to var
|
||||
AstVarRef* newp = new AstVarRef(nodep->fileline(), varp, false);
|
||||
|
|
@ -134,7 +134,7 @@ private:
|
|||
// Marking of non-static functions (because they might need "this")
|
||||
// (Here instead of new vistor after V3Descope just to avoid another visitor)
|
||||
void needNonStaticFunc(AstNode* nodep) {
|
||||
if (!m_funcp) nodep->v3fatalSrc("Non-static accessor not under a function");
|
||||
UASSERT_OBJ(m_funcp, nodep, "Non-static accessor not under a function");
|
||||
if (m_funcp->isStatic().trueU()) {
|
||||
UINFO(5,"Mark non-public due to "<<nodep<<endl);
|
||||
m_funcp->isStatic(false);
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ private:
|
|||
AstCFunc* funcp = eachIt->second;
|
||||
FuncMmap::iterator nextIt2 = eachIt; ++nextIt2;
|
||||
bool moreOfSame = (nextIt2!=m_modFuncs.end() && nextIt2->first == name);
|
||||
if (!funcp->scopep()) funcp->v3fatalSrc("Not scoped");
|
||||
UASSERT_OBJ(funcp->scopep(), funcp, "Not scoped");
|
||||
|
||||
UINFO(6," Wrapping "<<name<<" "<<funcp<<endl);
|
||||
UINFO(6," at "<<newfuncp->argTypes()<<" und "<<funcp->argTypes()<<endl);
|
||||
|
|
@ -255,7 +255,7 @@ private:
|
|||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
iterateChildren(nodep);
|
||||
// Convert the hierch name
|
||||
if (!m_scopep) nodep->v3fatalSrc("Node not under scope");
|
||||
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
|
||||
bool hierThis;
|
||||
nodep->hiername(descopedName(nodep->varScopep()->scopep(), hierThis/*ref*/,
|
||||
nodep->varScopep()->varp()));
|
||||
|
|
@ -266,8 +266,8 @@ private:
|
|||
//UINFO(9," "<<nodep<<endl);
|
||||
iterateChildren(nodep);
|
||||
// Convert the hierch name
|
||||
if (!m_scopep) nodep->v3fatalSrc("Node not under scope");
|
||||
if (!nodep->funcp()->scopep()) nodep->v3fatalSrc("CFunc not under scope");
|
||||
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
|
||||
UASSERT_OBJ(nodep->funcp()->scopep(), nodep, "CFunc not under scope");
|
||||
bool hierThis;
|
||||
nodep->hiername(descopedName(nodep->funcp()->scopep(), hierThis/*ref*/));
|
||||
// Can't do this, as we may have more calls later
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public:
|
|||
puts(nodep->dtypep()->charIQWN());
|
||||
}
|
||||
void emitScIQW(AstVar* nodep) {
|
||||
if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable");
|
||||
UASSERT_OBJ(nodep->isSc(), nodep, "emitting SystemC operator on non-SC variable");
|
||||
puts(nodep->isScBigUint() ? "SB"
|
||||
: nodep->isScUint() ? "SU"
|
||||
: nodep->isScBv() ? "SW"
|
||||
|
|
@ -632,9 +632,9 @@ public:
|
|||
}
|
||||
virtual void visit(AstReplicate* nodep) {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
if ((static_cast<int>(VN_CAST(nodep->rhsp(), Const)->toUInt())
|
||||
* nodep->lhsp()->widthMin()) != nodep->widthMin())
|
||||
nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
|
||||
UASSERT_OBJ((static_cast<int>(VN_CAST(nodep->rhsp(), Const)->toUInt())
|
||||
* nodep->lhsp()->widthMin()) == nodep->widthMin(),
|
||||
nodep, "Replicate non-constant or width miscomputed");
|
||||
puts("VL_REPLICATE_");
|
||||
emitIQW(nodep);
|
||||
puts("OI(");
|
||||
|
|
@ -798,7 +798,7 @@ public:
|
|||
}
|
||||
virtual void visit(AstConst* nodep) {
|
||||
if (nodep->isWide()) {
|
||||
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Constant w/ no temp");
|
||||
UASSERT_OBJ(m_wideTempRefp, nodep, "Wide Constant w/ no temp");
|
||||
emitConstant(nodep, m_wideTempRefp, "");
|
||||
m_wideTempRefp = NULL; // We used it, barf if set it a second time
|
||||
} else {
|
||||
|
|
@ -909,8 +909,8 @@ class EmitCImp : EmitCStmts {
|
|||
else {
|
||||
AstNode* lhsp = changep->lhsp();
|
||||
AstNode* rhsp = changep->rhsp();
|
||||
if (!VN_IS(lhsp, VarRef) && !VN_IS(lhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
|
||||
if (!VN_IS(rhsp, VarRef) && !VN_IS(rhsp, ArraySel)) changep->v3fatalSrc("Not ref?");
|
||||
UASSERT_OBJ(VN_IS(lhsp, VarRef) || VN_IS(lhsp, ArraySel), changep, "Not ref?");
|
||||
UASSERT_OBJ(VN_IS(rhsp, VarRef) || VN_IS(rhsp, ArraySel), changep, "Not ref?");
|
||||
for (int word=0;
|
||||
word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1);
|
||||
++word) {
|
||||
|
|
@ -1164,9 +1164,8 @@ class EmitCImp : EmitCStmts {
|
|||
}
|
||||
|
||||
virtual void visit(AstExecGraph* nodep) {
|
||||
if (nodep != v3Global.rootp()->execGraphp()) {
|
||||
nodep->v3fatalSrc("ExecGraph should be a singleton!");
|
||||
}
|
||||
UASSERT_OBJ(nodep == v3Global.rootp()->execGraphp(), nodep,
|
||||
"ExecGraph should be a singleton!");
|
||||
// The location of the AstExecGraph within the containing _eval()
|
||||
// function is where we want to invoke the graph and wait for it to
|
||||
// complete. Do that now.
|
||||
|
|
@ -1185,10 +1184,8 @@ class EmitCImp : EmitCStmts {
|
|||
const ExecMTask* etp = dynamic_cast<const ExecMTask*>(vxp);
|
||||
if (etp->threadRoot()) execMTasks.push_back(etp);
|
||||
}
|
||||
if (execMTasks.size() >
|
||||
static_cast<unsigned>(v3Global.opt.threads())) {
|
||||
nodep->v3fatalSrc("More root mtasks than available threads");
|
||||
}
|
||||
UASSERT_OBJ(execMTasks.size() <= static_cast<unsigned>(v3Global.opt.threads()),
|
||||
nodep, "More root mtasks than available threads");
|
||||
|
||||
if (!execMTasks.empty()) {
|
||||
for (uint32_t i = 0; i < execMTasks.size(); ++i) {
|
||||
|
|
@ -1256,7 +1253,7 @@ public:
|
|||
|
||||
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
||||
AstBasicDType* basicp = nodep->basicp();
|
||||
if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
|
||||
UASSERT_OBJ(basicp, nodep, "Unimplemented: Outputting this data type");
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
|
|
@ -1417,7 +1414,8 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
|
|||
case 't': detail = true; detailp = thsp; break;
|
||||
case 'P':
|
||||
if (nodep->isWide()) {
|
||||
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
|
||||
UASSERT_OBJ(m_wideTempRefp, nodep,
|
||||
"Wide Op w/ no temp, perhaps missing op in V3EmitC?");
|
||||
COMMA;
|
||||
puts(m_wideTempRefp->hiername());
|
||||
puts(m_wideTempRefp->varp()->name());
|
||||
|
|
@ -1448,8 +1446,8 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
|
|||
break;
|
||||
case 'i':
|
||||
COMMA;
|
||||
if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); }
|
||||
else iterateAndNextNull(detailp);
|
||||
UASSERT_OBJ(detailp, nodep, "emitOperator() references undef node");
|
||||
iterateAndNextNull(detailp);
|
||||
needComma = true;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1654,7 +1652,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
|
|||
case '^': displayArg(nodep,&elistp,isScan, vfmt,'^'); break; // Realtime
|
||||
case 'v': displayArg(nodep, &elistp, isScan, vfmt, 'v'); break;
|
||||
case 'm': {
|
||||
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||
UASSERT_OBJ(scopenamep, nodep, "Display with %m but no AstScopeName");
|
||||
string suffix = scopenamep->scopePrettySymName();
|
||||
if (suffix=="") emitDispState.pushFormat("%S");
|
||||
else emitDispState.pushFormat("%N"); // Add a . when needed
|
||||
|
|
@ -1687,7 +1685,7 @@ void EmitCImp::emitVarReset(AstVar* varp) {
|
|||
if (varp->isIO() && m_modp->isTop() && optSystemC()) {
|
||||
// System C top I/O doesn't need loading, as the lower level subinst code does it.}
|
||||
} else if (varp->isParam()) {
|
||||
if (!varp->valuep()) varp->v3fatalSrc("No init for a param?");
|
||||
UASSERT_OBJ(varp->valuep(), varp, "No init for a param?");
|
||||
// If a simple CONST value we initialize it using an enum
|
||||
// If an ARRAYINIT we initialize it using an initial block similar to a signal
|
||||
//puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n");
|
||||
|
|
@ -1705,7 +1703,8 @@ void EmitCImp::emitVarReset(AstVar* varp) {
|
|||
int pos = 0;
|
||||
for (AstNode* itemp = initarp->initsp(); itemp; ++pos, itemp=itemp->nextp()) {
|
||||
int index = initarp->posIndex(pos);
|
||||
if (!initarp->defaultp() && index!=pos) initarp->v3fatalSrc("Not enough values in array initalizement");
|
||||
UASSERT_OBJ(initarp->defaultp() || index==pos, initarp,
|
||||
"Not enough values in array initalizement");
|
||||
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", VN_CAST(itemp, Const));
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1722,9 +1721,8 @@ void EmitCImp::emitVarReset(AstVar* varp) {
|
|||
arrayp;
|
||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
|
||||
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
}
|
||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
||||
"Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";");
|
||||
|
|
@ -1780,7 +1778,7 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
|
|||
|
||||
void EmitCImp::emitMTaskVertexCtors(bool* firstp) {
|
||||
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
|
||||
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Should have an execGraphp");
|
||||
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
|
||||
const V3Graph* depGraphp = execGraphp->depGraphp();
|
||||
|
||||
unsigned finalEdgesInCt = 0;
|
||||
|
|
@ -1962,9 +1960,8 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
|||
arrayp;
|
||||
arrayp = VN_CAST(elementp, UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
|
||||
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
}
|
||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
||||
"Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
// MSVC++ pre V7 doesn't support 'for (int ...)',
|
||||
// so declare in sep block
|
||||
|
|
@ -2062,9 +2059,8 @@ void EmitCImp::emitSensitives() {
|
|||
arrayp;
|
||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (VL_UNCOVERABLE(arrayp->msb() < arrayp->lsb())) {
|
||||
varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
}
|
||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
||||
"Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(arrayp->lsb())+";");
|
||||
|
|
@ -2404,7 +2400,7 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
|
|||
if (modp->isTop() && v3Global.opt.mtasks()) {
|
||||
// Emit the mtask func prototypes.
|
||||
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
|
||||
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Root should have an execGraphp");
|
||||
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
|
||||
const V3Graph* depGraphp = execGraphp->depGraphp();
|
||||
for (const V3GraphVertex* vxp = depGraphp->verticesBeginp();
|
||||
vxp; vxp = vxp->verticesNextp()) {
|
||||
|
|
@ -2424,7 +2420,7 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
|
|||
void EmitCImp::emitMTaskState() {
|
||||
ofp()->putsPrivate(true);
|
||||
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
|
||||
if (!execGraphp) v3Global.rootp()->v3fatalSrc("Root should have an execGraphp");
|
||||
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
|
||||
|
||||
const V3Graph* depGraphp = execGraphp->depGraphp();
|
||||
for (const V3GraphVertex* vxp = depGraphp->verticesBeginp();
|
||||
|
|
@ -2566,7 +2562,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isParam() && (varp->isUsedParam() || varp->isSigPublic())) {
|
||||
if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?");
|
||||
UASSERT_OBJ(varp->valuep(), nodep, "No init for a param?");
|
||||
// These should be static const values, however microsloth VC++ doesn't
|
||||
// support them. They also cause problems with GDB under GCC2.95.
|
||||
if (varp->isWide()) { // Unsupported for output
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ class EmitCSyms : EmitCBaseVisitor {
|
|||
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettySymName())));
|
||||
}
|
||||
if (nodep->dpiExport()) {
|
||||
if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function");
|
||||
UASSERT_OBJ(m_funcp, nodep, "ScopeName not under DPI function");
|
||||
m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(),
|
||||
ScopeFuncData(nodep, m_funcp, m_modp)));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -403,23 +403,23 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
case 'f': putfs(nodep, ""); break;
|
||||
case 'k': putbs(""); break;
|
||||
case 'l': {
|
||||
if (!lhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
|
||||
else iterateAndNextNull(lhsp);
|
||||
UASSERT_OBJ(lhsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(lhsp);
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
if (!rhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
|
||||
else iterateAndNextNull(rhsp);
|
||||
UASSERT_OBJ(rhsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(rhsp);
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
if (!thsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
|
||||
else iterateAndNextNull(thsp);
|
||||
UASSERT_OBJ(thsp, nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(thsp);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
if (!nodep->dtypep()) { nodep->v3fatalSrc("emitVerilog() references undef node"); }
|
||||
else iterateAndNextNull(nodep->dtypep());
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "emitVerilog() references undef node");
|
||||
iterateAndNextNull(nodep->dtypep());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -310,11 +310,17 @@ inline void v3errorEndFatal(std::ostringstream& sstr) {
|
|||
# define UDEBUGONLY(stmts) {if (0) {stmts}}
|
||||
#endif
|
||||
|
||||
#define UASSERT(condition,stmsg) { if (VL_UNCOVERABLE(!(condition))) { v3fatalSrc(stmsg); }}
|
||||
// Assertion without object, generally UOBJASSERT preferred
|
||||
#define UASSERT(condition,stmsg) \
|
||||
do { if (VL_UNCOVERABLE(!(condition))) { v3fatalSrc(stmsg); }} while(0)
|
||||
// Assertion with object
|
||||
#define UASSERT_OBJ(condition,obj,stmsg) \
|
||||
do { if (VL_UNCOVERABLE(!(condition))) { (obj)->v3fatalSrc(stmsg); }} while(0)
|
||||
// For use in V3Ast static functions only
|
||||
#define UASSERT_STATIC(condition,stmsg) \
|
||||
{ if (VL_UNCOVERABLE(!(condition))) { \
|
||||
std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__<<":"<<(stmsg)<<std::endl; abort(); } }
|
||||
do { if (VL_UNCOVERABLE(!(condition))) { \
|
||||
std::cerr<<"Internal Error: "<<__FILE__<<":"<<std::dec<<__LINE__ \
|
||||
<<":"<<(stmsg)<<std::endl; abort(); } } while(0)
|
||||
// Check self test values for expected value. Safe from side-effects.
|
||||
// Type argument can be removed when go to C++11 (use auto).
|
||||
#define UASSERT_SELFTEST(Type,got,exp) \
|
||||
|
|
@ -322,12 +328,14 @@ inline void v3errorEndFatal(std::ostringstream& sstr) {
|
|||
UASSERT(g==e, "Self-test failed '" #got "==" #exp "'"" got=" \
|
||||
<<g<<" expected="<<e); } while(0)
|
||||
|
||||
#define V3ERROR_NA { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); }
|
||||
#define V3ERROR_NA \
|
||||
do { v3error("Internal: Unexpected Call"); v3fatalSrc("Unexpected Call"); } while(0)
|
||||
|
||||
/// Declare a convenience debug() routine that may be added to any class in
|
||||
/// Verilator so that --debugi-<srcfile> will work to control UINFOs in
|
||||
/// that class:
|
||||
#define VL_DEBUG_FUNC static int debug() { \
|
||||
#define VL_DEBUG_FUNC \
|
||||
static int debug() { \
|
||||
static int level = -1; \
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); \
|
||||
return level; \
|
||||
|
|
|
|||
|
|
@ -239,9 +239,8 @@ private:
|
|||
}
|
||||
bool expandWide(AstNodeAssign* nodep, AstArraySel* rhsp) {
|
||||
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
|
||||
if (VL_UNCOVERABLE(VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType))) {
|
||||
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
}
|
||||
UASSERT_OBJ(!VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType), nodep,
|
||||
"ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
for (int w=0; w<nodep->widthWords(); w++) {
|
||||
addWordAssign(nodep, w, newAstWordSelClone(rhsp, w));
|
||||
}
|
||||
|
|
@ -324,11 +323,9 @@ private:
|
|||
newp = new AstCCast(nodep->fileline(), lhsp, nodep);
|
||||
}
|
||||
} else { // Long
|
||||
if (lhsp->isQuad() || lhsp->isWide()) {
|
||||
nodep->v3fatalSrc("extending larger thing into smaller?");
|
||||
} else {
|
||||
lhsp->dtypeFrom(nodep); // Just mark it, else nop
|
||||
}
|
||||
UASSERT_OBJ(!(lhsp->isQuad() || lhsp->isWide()), nodep,
|
||||
"extending larger thing into smaller?");
|
||||
lhsp->dtypeFrom(nodep); // Just mark it, else nop
|
||||
}
|
||||
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
|
||||
}
|
||||
|
|
@ -349,7 +346,7 @@ private:
|
|||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
// Remember, Sel's may have non-integer rhs, so need to optimize for that!
|
||||
if (nodep->widthMin() != nodep->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
UASSERT_OBJ(nodep->widthMin() == nodep->widthConst(), nodep, "Width mismatch");
|
||||
if (VN_IS(nodep->backp(), NodeAssign)
|
||||
&& nodep==VN_CAST(nodep->backp(), NodeAssign)->lhsp()) {
|
||||
// Sel is an LHS assignment select
|
||||
|
|
@ -468,7 +465,7 @@ private:
|
|||
}
|
||||
|
||||
bool expandWide(AstNodeAssign* nodep, AstSel* rhsp) {
|
||||
if (nodep->widthMin() != rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
UASSERT_OBJ(nodep->widthMin() == rhsp->widthConst(), nodep, "Width mismatch");
|
||||
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
|
||||
int lsb = rhsp->lsbConst();
|
||||
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
|
||||
|
|
@ -729,7 +726,8 @@ private:
|
|||
} else {
|
||||
UINFO(8," REPLICATE "<<nodep<<endl);
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
UASSERT_OBJ(constp, nodep,
|
||||
"Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->toUInt();
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) {
|
||||
lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
|
||||
|
|
@ -756,7 +754,7 @@ private:
|
|||
AstNode* lhsp = rhsp->lhsp();
|
||||
int lhswidth = lhsp->widthMin();
|
||||
const AstConst* constp = VN_CAST(rhsp->rhsp(), Const);
|
||||
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
UASSERT_OBJ(constp, rhsp, "Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->toUInt();
|
||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||
AstNode* newp;
|
||||
|
|
|
|||
|
|
@ -435,9 +435,9 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
if (m_scopep) {
|
||||
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block");
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
GateVarVertex* vvertexp = makeVarVertex(varscp);
|
||||
UINFO(5," VARREF to "<<varscp<<endl);
|
||||
if (m_inSenItem) vvertexp->setIsClock();
|
||||
|
|
@ -509,10 +509,9 @@ private:
|
|||
m_inSlow = lastslow;
|
||||
}
|
||||
virtual void visit(AstConcat* nodep) {
|
||||
if (VN_IS(nodep->backp(), NodeAssign)
|
||||
&& VN_CAST(nodep->backp(), NodeAssign)->lhsp()==nodep) {
|
||||
nodep->v3fatalSrc("Concat on LHS of assignment; V3Const should have deleted it");
|
||||
}
|
||||
UASSERT_OBJ(!(VN_IS(nodep->backp(), NodeAssign)
|
||||
&& VN_CAST(nodep->backp(), NodeAssign)->lhsp()==nodep),
|
||||
nodep, "Concat on LHS of assignment; V3Const should have deleted it");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
|
|
@ -850,14 +849,14 @@ private:
|
|||
// It's possible we substitute into something that will be reduced more later,
|
||||
// however, as we never delete the top Always/initial statement, all should be well.
|
||||
m_didReplace = true;
|
||||
if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var");
|
||||
UASSERT_OBJ(!nodep->lvalue(), nodep,
|
||||
"Can't replace lvalue assignments with const var");
|
||||
AstNode* substp = m_replaceTreep->cloneTree(false);
|
||||
if (VN_IS(nodep, NodeVarRef)
|
||||
&& VN_IS(substp, NodeVarRef)
|
||||
&& nodep->same(substp)) {
|
||||
// Prevent an infinite loop...
|
||||
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
|
||||
}
|
||||
UASSERT_OBJ(!(VN_IS(nodep, NodeVarRef)
|
||||
&& VN_IS(substp, NodeVarRef)
|
||||
&& nodep->same(substp)),
|
||||
// Prevent an infinite loop...
|
||||
substp, "Replacing node with itself; perhaps circular logic?");
|
||||
// Which fileline() to use?
|
||||
// If replacing with logic, an error/warning is likely to want to point to the logic
|
||||
// IE what we're replacing with.
|
||||
|
|
@ -1044,9 +1043,8 @@ public:
|
|||
AstNode* lhsp = m_assignp->lhsp();
|
||||
// Possible todo, handle more complex lhs expressions
|
||||
if (AstNodeVarRef* lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
|
||||
if (lhsVarRefp->varScopep() != consumerVarScopep) {
|
||||
consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign");
|
||||
}
|
||||
UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep,
|
||||
consumerVarScopep, "Consumer doesn't match lhs of assign");
|
||||
if (AstNodeAssign* dup = m_ghash.hashAndFindDupe(m_assignp, activep, m_ifCondp)) {
|
||||
return static_cast<AstNodeVarRef*>(dup->lhsp());
|
||||
}
|
||||
|
|
@ -1081,7 +1079,8 @@ private:
|
|||
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
|
||||
V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
GateLogicVertex* lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
|
||||
if (!vvertexp->dedupable()) vvertexp->varScp()->v3fatalSrc("GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
|
||||
UASSERT_OBJ(vvertexp->dedupable(), vvertexp->varScp(),
|
||||
"GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
|
||||
GateOkVisitor okVisitor(lvertexp->nodep(), false, true);
|
||||
if (okVisitor.isSimple()) {
|
||||
AstVarScope* dupVarScopep = dupVarRefp->varScopep();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ private:
|
|||
AstNode::user2ClearTree(); // user2p() used on entire tree
|
||||
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level");
|
||||
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
|
||||
m_scopetopp = scopep;
|
||||
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -96,7 +96,7 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (m_activep && !nodep->user3()) {
|
||||
nodep->user3(true);
|
||||
if (vscp->isCircular()) {
|
||||
|
|
@ -111,7 +111,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstActive* nodep) {
|
||||
m_activep = nodep;
|
||||
if (!nodep->sensesp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->sensesp(), nodep, "Unlinked");
|
||||
iterateChildren(nodep->sensesp()); // iterateAndNext?
|
||||
m_activep = NULL;
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -191,7 +191,7 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (m_activep) {
|
||||
UINFO(8," VarAct "<<nodep<<endl);
|
||||
vscp->user1(true);
|
||||
|
|
@ -212,7 +212,7 @@ private:
|
|||
virtual void visit(AstActive* nodep) {
|
||||
UINFO(8,"ACTIVE "<<nodep<<endl);
|
||||
m_activep = nodep;
|
||||
if (!nodep->sensesp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->sensesp(), nodep, "Unlinked");
|
||||
iterateChildren(nodep->sensesp()); // iterateAndNext?
|
||||
m_activep = NULL;
|
||||
iterateChildren(nodep);
|
||||
|
|
|
|||
|
|
@ -579,7 +579,7 @@ double V3Graph::orderDFSIterate(V3GraphVertex* vertexp) {
|
|||
// Compute fanouts of each node
|
||||
// If forward edge, don't double count that fanout
|
||||
if (vertexp->user() == 2) return vertexp->fanout(); // Already processed it
|
||||
if (vertexp->user() == 1) vertexp->v3fatalSrc("Loop found, backward edges should be dead");
|
||||
UASSERT_OBJ(vertexp->user() != 1, vertexp, "Loop found, backward edges should be dead");
|
||||
vertexp->user(1);
|
||||
double fanout = 0;
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ DfaVertex* DfaGraph::findStart() {
|
|||
vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->start()) {
|
||||
if (startp) vertexp->v3fatalSrc("Multiple start points in NFA graph");
|
||||
UASSERT_OBJ(!startp, vertexp, "Multiple start points in NFA graph");
|
||||
startp = vvertexp;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -118,9 +118,8 @@ private:
|
|||
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
|
||||
hash ^= hashVertex(nfaStatep);
|
||||
if (debug()) {
|
||||
if (nfaStatep->user()==m_step) {
|
||||
nfaStatep->v3fatalSrc("DFA state points to duplicate NFA state.");
|
||||
}
|
||||
UASSERT_OBJ(nfaStatep->user() != m_step, nfaStatep,
|
||||
"DFA state points to duplicate NFA state.");
|
||||
nfaStatep->user(m_step);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,9 +94,8 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
|
|||
|
||||
GraphPCNode* ourUserp = static_cast<GraphPCNode*>(vertexp->userp());
|
||||
if (checkOnly) {
|
||||
if (VL_UNCOVERABLE(ourUserp->m_cp[way] != critPathCost)) {
|
||||
vertexp->v3fatalSrc("Validation of critical paths failed");
|
||||
}
|
||||
UASSERT_OBJ(ourUserp->m_cp[way] == critPathCost,
|
||||
vertexp, "Validation of critical paths failed");
|
||||
} else {
|
||||
ourUserp->m_cp[way] = critPathCost;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,9 +60,7 @@ private:
|
|||
// Decrement blocking edges count, return true if the vertex is
|
||||
// newly unblocked
|
||||
bool unblock() {
|
||||
if (VL_UNCOVERABLE(m_numBlockingEdges <= 0)) {
|
||||
vertexp()->v3fatalSrc("Underflow of blocking edges");
|
||||
}
|
||||
UASSERT_OBJ(m_numBlockingEdges > 0, vertexp(), "Underflow of blocking edges");
|
||||
m_numBlockingEdges--;
|
||||
return (m_numBlockingEdges == 0);
|
||||
}
|
||||
|
|
@ -210,9 +208,8 @@ private:
|
|||
|
||||
typename WaitingVertices::iterator it =
|
||||
m_waitingVertices.find(toVertexp);
|
||||
if (VL_UNCOVERABLE(it == m_waitingVertices.end())) {
|
||||
toVertexp->v3fatalSrc("Found edge into vertex not in waiting list.");
|
||||
}
|
||||
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
|
||||
"Found edge into vertex not in waiting list.");
|
||||
if (it->second.unblock()) {
|
||||
m_readyVertices.insert(it->second);
|
||||
m_waitingVertices.erase(it);
|
||||
|
|
@ -225,9 +222,8 @@ private:
|
|||
|
||||
typename WaitingVertices::iterator it =
|
||||
m_waitingVertices.find(fromVertexp);
|
||||
if (VL_UNCOVERABLE(it == m_waitingVertices.end())) {
|
||||
fromVertexp->v3fatalSrc("Found edge into vertex not in waiting list.");
|
||||
}
|
||||
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,
|
||||
"Found edge into vertex not in waiting list.");
|
||||
if (it->second.unblock()) {
|
||||
m_readyVertices.insert(it->second);
|
||||
m_waitingVertices.erase(it);
|
||||
|
|
|
|||
|
|
@ -59,16 +59,15 @@ private:
|
|||
void nodeHashIterate(AstNode* nodep) {
|
||||
V3Hash thisHash;
|
||||
if (!m_cacheInUser4 || !nodep->user4()) {
|
||||
if (VN_IS(nodep->backp(), CFunc)
|
||||
&& !(VN_IS(nodep, NodeStmt) || VN_IS(nodep, CFunc))) {
|
||||
nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" in statement position but not marked stmt (node under function)");
|
||||
}
|
||||
UASSERT_OBJ(!(VN_IS(nodep->backp(), CFunc)
|
||||
&& !(VN_IS(nodep, NodeStmt) || VN_IS(nodep, CFunc))), nodep,
|
||||
"Node "<<nodep->prettyTypeName()
|
||||
<<" in statement position but not marked stmt (node under function)");
|
||||
V3Hash oldHash = m_lowerHash;
|
||||
{
|
||||
m_lowerHash = nodep->sameHash();
|
||||
if (m_lowerHash.isIllegal()) {
|
||||
nodep->v3fatalSrc("sameHash function undefined (returns 0) for node under CFunc.");
|
||||
}
|
||||
UASSERT_OBJ(!m_lowerHash.isIllegal(), nodep,
|
||||
"sameHash function undefined (returns 0) for node under CFunc.");
|
||||
// For identical nodes, the type should be the same thus
|
||||
// dtypep should be the same too
|
||||
m_lowerHash = V3Hash(m_lowerHash, V3Hash(nodep->type()<<6,
|
||||
|
|
@ -132,8 +131,8 @@ void V3Hashed::hash(AstNode* nodep) {
|
|||
}
|
||||
|
||||
bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) {
|
||||
if (!node1p->user4p()) node1p->v3fatalSrc("Called isIdentical on non-hashed nodes");
|
||||
if (!node2p->user4p()) node2p->v3fatalSrc("Called isIdentical on non-hashed nodes");
|
||||
UASSERT_OBJ(node1p->user4p(), node1p, "Called isIdentical on non-hashed nodes");
|
||||
UASSERT_OBJ(node2p->user4p(), node2p, "Called isIdentical on non-hashed nodes");
|
||||
return (node1p->user4p() == node2p->user4p() // Same hash
|
||||
&& node1p->sameTree(node2p));
|
||||
}
|
||||
|
|
@ -141,7 +140,7 @@ bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) {
|
|||
void V3Hashed::erase(iterator it) {
|
||||
AstNode* nodep = iteratorNodep(it);
|
||||
UINFO(8," erase "<<nodep<<endl);
|
||||
if (!nodep->user4p()) nodep->v3fatalSrc("Called removeNode on non-hashed node");
|
||||
UASSERT_OBJ(nodep->user4p(), nodep, "Called removeNode on non-hashed node");
|
||||
m_hashMmap.erase(it);
|
||||
nodep->user4p(NULL); // So we don't allow removeNode again
|
||||
}
|
||||
|
|
@ -196,7 +195,7 @@ void V3Hashed::dumpFile(const string& filename, bool tree) {
|
|||
|
||||
V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) {
|
||||
UINFO(8," findD "<<nodep<<endl);
|
||||
if (!nodep->user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node");
|
||||
UASSERT_OBJ(nodep->user4p(), nodep, "Called findDuplicate on non-hashed node");
|
||||
std::pair<HashMmap::iterator,HashMmap::iterator> eqrange = mmap().equal_range(nodeHash(nodep));
|
||||
for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) {
|
||||
AstNode* node2p = eqit->second;
|
||||
|
|
@ -209,7 +208,7 @@ V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) {
|
|||
|
||||
V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp) {
|
||||
UINFO(8," findD "<<nodep<<endl);
|
||||
if (!nodep->user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node");
|
||||
UASSERT_OBJ(nodep->user4p(), nodep, "Called findDuplicate on non-hashed node");
|
||||
std::pair<HashMmap::iterator,HashMmap::iterator> eqrange
|
||||
= mmap().equal_range(nodeHash(nodep));
|
||||
for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) {
|
||||
|
|
|
|||
|
|
@ -306,9 +306,8 @@ private:
|
|||
AstConst* exprconstp = VN_CAST(nodep->user2p(), Const);
|
||||
AstVarRef* exprvarrefp = VN_CAST(nodep->user2p(), VarRef);
|
||||
UINFO(8,"connectto: "<<nodep->user2p()<<endl);
|
||||
if (!exprconstp && !exprvarrefp) {
|
||||
nodep->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
}
|
||||
UASSERT_OBJ(exprconstp || exprvarrefp, nodep,
|
||||
"Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
if (exprconstp) {
|
||||
m_modp->addStmtp(new AstAssignW(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), nodep, true),
|
||||
|
|
@ -318,7 +317,7 @@ private:
|
|||
// the logic changes up and down; if we aliased, we might
|
||||
// remove the change detection on the output variable.
|
||||
UINFO(9,"public pin assign: "<<exprvarrefp<<endl);
|
||||
if (nodep->isNonOutput()) nodep->v3fatalSrc("Outputs only - inputs use AssignAlias");
|
||||
UASSERT_OBJ(!nodep->isNonOutput(), nodep, "Outputs only - inputs use AssignAlias");
|
||||
m_modp->addStmtp(
|
||||
new AstAssignW(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), true),
|
||||
|
|
@ -555,12 +554,11 @@ private:
|
|||
// delete it in later optimizations.
|
||||
AstVar* pinOldVarp = pinp->modVarp();
|
||||
AstVar* pinNewVarp = pinOldVarp->clonep();
|
||||
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
|
||||
UASSERT_OBJ(pinNewVarp, pinOldVarp, "Cloning failed");
|
||||
|
||||
AstNode* connectRefp = pinp->exprp();
|
||||
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
|
||||
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
}
|
||||
UASSERT_OBJ(VN_IS(connectRefp, Const) || VN_IS(connectRefp, VarRef), pinp,
|
||||
"Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
V3Inst::checkOutputShort(pinp);
|
||||
|
||||
// Propagate any attributes across the interconnect
|
||||
|
|
|
|||
|
|
@ -75,9 +75,8 @@ private:
|
|||
V3Inst::pinReconnectSimple(nodep, m_cellp, false);
|
||||
// Make an ASSIGNW (expr, pin)
|
||||
AstNode* exprp = nodep->exprp()->cloneTree(false);
|
||||
if (exprp->width() != nodep->modVarp()->width()) {
|
||||
nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple");
|
||||
}
|
||||
UASSERT_OBJ(exprp->width() == nodep->modVarp()->width(), nodep,
|
||||
"Width mismatch, should have been handled in pinReconnectSimple");
|
||||
if (nodep->modVarp()->isInoutish()) {
|
||||
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
|
||||
} else if (nodep->modVarp()->isWritable()) {
|
||||
|
|
@ -104,7 +103,8 @@ private:
|
|||
nodep->modVarp(), m_cellp->name(), false);
|
||||
const AstVarRef* refp = VN_CAST(exprp, VarRef);
|
||||
const AstVarXRef* xrefp = VN_CAST(exprp, VarXRef);
|
||||
if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef");
|
||||
UASSERT_OBJ(refp || xrefp, exprp,
|
||||
"Interfaces: Pin is not connected to a VarRef or VarXRef");
|
||||
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
|
||||
m_cellp->addNextHere(assp);
|
||||
} else {
|
||||
|
|
@ -249,7 +249,7 @@ private:
|
|||
virtual void visit(AstCell* nodep) {
|
||||
UINFO(4," CELL "<<nodep<<endl);
|
||||
// Find submodule vars
|
||||
if (!nodep->modp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->modp(), nodep, "Unlinked");
|
||||
m_deModVars.main(nodep->modp());
|
||||
//
|
||||
if (nodep->rangep()) {
|
||||
|
|
|
|||
|
|
@ -100,10 +100,9 @@ private:
|
|||
// (which at the V3Order stage represent verilog tasks, not to
|
||||
// the CFuncs that V3Order will generate.) So don't check for
|
||||
// collisions in CFuncs.
|
||||
if (nodep->user5p()) {
|
||||
nodep->v3fatalSrc("Node originally inserted below logic vertex "
|
||||
<<static_cast<AstNode*>(nodep->user5p()));
|
||||
}
|
||||
UASSERT_OBJ(!nodep->user5p(), nodep,
|
||||
"Node originally inserted below logic vertex "
|
||||
<<static_cast<AstNode*>(nodep->user5p()));
|
||||
nodep->user5p(const_cast<void*>(reinterpret_cast<const void*>(m_startNodep)));
|
||||
}
|
||||
|
||||
|
|
@ -235,25 +234,20 @@ private:
|
|||
// are no actives-under-actives. In any case, check that we're at
|
||||
// root:
|
||||
markCost(nodep);
|
||||
if (nodep != m_startNodep) {
|
||||
nodep->v3fatalSrc("Multiple actives, or not start node");
|
||||
}
|
||||
UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node");
|
||||
}
|
||||
virtual void visit(AstCCall* nodep) {
|
||||
VisitBase vb(this, nodep);
|
||||
iterateChildren(nodep);
|
||||
m_tracingCall = true;
|
||||
iterate(nodep->funcp());
|
||||
if (m_tracingCall) {
|
||||
nodep->v3fatalSrc("visit(AstCFunc) should have cleared m_tracingCall.");
|
||||
}
|
||||
UASSERT_OBJ(!m_tracingCall, nodep, "visit(AstCFunc) should have cleared m_tracingCall.");
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
// Don't count a CFunc other than by tracing a call or counting it
|
||||
// from the root
|
||||
if (!m_tracingCall && (nodep != m_startNodep)) {
|
||||
nodep->v3fatalSrc("AstCFunc not under AstCCall, or not start node");
|
||||
}
|
||||
UASSERT_OBJ(m_tracingCall || nodep == m_startNodep, nodep,
|
||||
"AstCFunc not under AstCCall, or not start node");
|
||||
m_tracingCall = false;
|
||||
bool saved_inCFunc = m_inCFunc;
|
||||
m_inCFunc = true;
|
||||
|
|
@ -287,7 +281,7 @@ public:
|
|||
InstrCountDumpVisitor(AstNode* nodep, std::ostream* osp)
|
||||
: m_osp(osp), m_depth(0) {
|
||||
// No check for NULL output, so...
|
||||
if (!osp) nodep->v3fatalSrc("Don't call if not dumping");
|
||||
UASSERT_OBJ(osp, nodep, "Don't call if not dumping");
|
||||
if (nodep) iterate(nodep);
|
||||
}
|
||||
virtual ~InstrCountDumpVisitor() {}
|
||||
|
|
|
|||
|
|
@ -299,10 +299,10 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
// Consumption/generation of a variable,
|
||||
// it's used so can't elim assignment before this use.
|
||||
if (!nodep->varScopep()) nodep->v3fatalSrc("NULL");
|
||||
UASSERT_OBJ(nodep->varScopep(), nodep, "NULL");
|
||||
//
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (nodep->lvalue()) {
|
||||
m_sideEffect = true; // $sscanf etc may have RHS vars that are lvalues
|
||||
m_lifep->complexAssign(vscp);
|
||||
|
|
@ -324,7 +324,7 @@ private:
|
|||
// Has to be direct assignment without any EXTRACTing.
|
||||
if (VN_IS(nodep->lhsp(), VarRef) && !m_sideEffect && !m_noopt) {
|
||||
AstVarScope* vscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope lost on variable");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope lost on variable");
|
||||
m_lifep->simpleAssign(vscp, nodep);
|
||||
} else {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ private:
|
|||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (AstVarScope* newvscp = reinterpret_cast<AstVarScope*>(vscp->user4p())) {
|
||||
UINFO(9, " Replace "<<nodep<<" to "<<newvscp<<endl);
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
|
||||
|
|
@ -267,14 +267,12 @@ private:
|
|||
iterateChildren(nodep);
|
||||
|
||||
if (v3Global.opt.mtasks()) {
|
||||
if (!m_mtasksGraphp) {
|
||||
nodep->v3fatalSrc("Should have initted m_mtasksGraphp by now");
|
||||
}
|
||||
UASSERT_OBJ(m_mtasksGraphp, nodep,
|
||||
"Should have initted m_mtasksGraphp by now");
|
||||
m_checker.reset(new GraphPathChecker(m_mtasksGraphp));
|
||||
} else {
|
||||
if (m_mtasksGraphp) {
|
||||
nodep->v3fatalSrc("Did not expect any m_mtasksGraphp in serial mode");
|
||||
}
|
||||
UASSERT_OBJ(!m_mtasksGraphp, nodep,
|
||||
"Did not expect any m_mtasksGraphp in serial mode");
|
||||
}
|
||||
|
||||
// Find all assignposts. Determine which ones can be
|
||||
|
|
@ -289,7 +287,7 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
|
||||
LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
if (nodep->lvalue()) {
|
||||
|
|
@ -311,9 +309,8 @@ private:
|
|||
if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
// rhsp is the dly var
|
||||
AstVarScope* dlyVarp = rhsp->varScopep();
|
||||
if (m_assignposts.find(dlyVarp) != m_assignposts.end()) {
|
||||
nodep->v3fatalSrc("LifePostLocation attempted duplicate dlyvar map addition");
|
||||
}
|
||||
UASSERT_OBJ(m_assignposts.find(dlyVarp) == m_assignposts.end(), nodep,
|
||||
"LifePostLocation attempted duplicate dlyvar map addition");
|
||||
LifeLocation loc(m_execMTaskp, ++m_sequence);
|
||||
m_assignposts[dlyVarp] = LifePostLocation(loc, nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ private:
|
|||
virtual void visit(AstPackageImport* nodep) {
|
||||
// Package Import: We need to do the package before the use of a package
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->packagep()) nodep->v3fatalSrc("Unlinked package"); // Parser should set packagep
|
||||
UASSERT_OBJ(nodep->packagep(), nodep, "Unlinked package"); // Parser should set packagep
|
||||
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(nodep->packagep()), 1, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ public:
|
|||
symp->fallbackp(NULL);
|
||||
rootEntp()->insert("$unit ", symp); // Space so can never name conflict with user code
|
||||
//
|
||||
if (m_dunitEntp) nodep->v3fatalSrc("Call insertDUnit only once");
|
||||
UASSERT_OBJ(!m_dunitEntp, nodep, "Call insertDUnit only once");
|
||||
m_dunitEntp = symp;
|
||||
}
|
||||
VSymEnt* insertTopCell(AstNodeModule* nodep, const string& scopename) {
|
||||
|
|
@ -265,7 +265,7 @@ public:
|
|||
}
|
||||
VSymEnt* insertCell(VSymEnt* abovep, VSymEnt* modSymp,
|
||||
AstCell* nodep, const string& scopename) {
|
||||
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9," INSERTcel se"<<cvtToHex(symp)<<" "<<scopename
|
||||
<<" above=se"<<cvtToHex(abovep)
|
||||
|
|
@ -289,7 +289,7 @@ public:
|
|||
AstCellInline* nodep, const string& basename) {
|
||||
// A fake point in the hierarchy, corresponding to an inlined module
|
||||
// This refrences to another Sym, and eventually resolves to a module with a prefix
|
||||
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9," INSERTinl se"<<cvtToHex(symp)
|
||||
<<" "<<basename<<" above=se"<<cvtToHex(abovep)
|
||||
|
|
@ -312,7 +312,7 @@ public:
|
|||
// After we remove begins these will go away
|
||||
// Note we fallback to the symbol table of the parent, as we want to find variables there
|
||||
// However, cells walk the graph, so cells will appear under the begin/ftask itself
|
||||
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9," INSERTblk se"<<cvtToHex(symp)
|
||||
<<" above=se"<<cvtToHex(abovep)<<" node="<<nodep<<endl);
|
||||
|
|
@ -329,7 +329,7 @@ public:
|
|||
}
|
||||
VSymEnt* insertSym(VSymEnt* abovep, const string& name,
|
||||
AstNode* nodep, AstPackage* packagep) {
|
||||
if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node");
|
||||
UASSERT_OBJ(abovep, nodep, "Null symbol table inserting node");
|
||||
VSymEnt* symp = new VSymEnt(&m_syms, nodep);
|
||||
UINFO(9," INSERTsym se"<<cvtToHex(symp)<<" name='"<<name
|
||||
<<"' above=se"<<cvtToHex(abovep)<<" node="<<nodep<<endl);
|
||||
|
|
@ -350,14 +350,13 @@ public:
|
|||
// Don't use this in ResolveVisitor, as we need to pick up the proper
|
||||
// reference under each SCOPE
|
||||
VSymEnt* symp = nodep->user1u().toSymEnt();
|
||||
if (!symp) nodep->v3fatalSrc("Module/etc never assigned a symbol entry?");
|
||||
UASSERT_OBJ(symp, nodep, "Module/etc never assigned a symbol entry?");
|
||||
return symp;
|
||||
}
|
||||
VSymEnt* getScopeSym(AstScope* nodep) {
|
||||
NameScopeSymMap::iterator it = m_nameScopeSymMap.find(nodep->name());
|
||||
if (it == m_nameScopeSymMap.end()) {
|
||||
nodep->v3fatalSrc("Scope never assigned a symbol entry?");
|
||||
}
|
||||
UASSERT_OBJ(it != m_nameScopeSymMap.end(), nodep,
|
||||
"Scope never assigned a symbol entry?");
|
||||
return it->second;
|
||||
}
|
||||
void implicitOkAdd(AstNodeModule* nodep, const string& varname) {
|
||||
|
|
@ -401,7 +400,7 @@ public:
|
|||
AstVar* varp = varSymp ? VN_CAST(varSymp->nodep(), Var) : NULL;
|
||||
UINFO(9, " insAllIface se"<<cvtToHex(varSymp)<<" "<<varp<<endl);
|
||||
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
|
||||
UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!");
|
||||
if (!ifacerefp->ifaceViaCellp()) {
|
||||
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
|
||||
ifacerefp->v3error("Cannot find file containing interface: "
|
||||
|
|
@ -444,10 +443,9 @@ public:
|
|||
// a child cell connecting to that interface
|
||||
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
|
||||
UINFO(9," insertScopeAlias se"<<cvtToHex(lhsp)<<" se"<<cvtToHex(rhsp)<<endl);
|
||||
if (VN_IS(rhsp->nodep(), Cell)
|
||||
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)) {
|
||||
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
|
||||
}
|
||||
UASSERT_OBJ(!(VN_IS(rhsp->nodep(), Cell)
|
||||
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)),
|
||||
rhsp->nodep(), "Got a non-IFACE alias RHS");
|
||||
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
|
||||
}
|
||||
void computeScopeAliases() {
|
||||
|
|
@ -714,7 +712,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
<<AstNode::prettyName(nodep->origName()));
|
||||
} else if (doit) {
|
||||
UINFO(4," Link Module: "<<nodep<<endl);
|
||||
if (nodep->dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?");
|
||||
UASSERT_OBJ(!nodep->dead(), nodep, "Module in cell tree mislabeled as dead?");
|
||||
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
m_packagep = VN_CAST(nodep, Package);
|
||||
if (standalonePkg) {
|
||||
|
|
@ -757,7 +755,8 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
m_packagep = NULL;
|
||||
}
|
||||
virtual void visit(AstScope* nodep) {
|
||||
if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope");
|
||||
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
|
||||
"Scopes should only exist right after V3Scope");
|
||||
// Ignored. Processed in next step
|
||||
}
|
||||
virtual void visit(AstCell* nodep) {
|
||||
|
|
@ -782,10 +781,9 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
string baddot;
|
||||
VSymEnt* okSymp;
|
||||
aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp);
|
||||
if (!aboveSymp) {
|
||||
nodep->v3fatalSrc("Can't find cell insertion point at '"
|
||||
<<baddot<<"' in: "<<nodep->prettyName());
|
||||
}
|
||||
UASSERT_OBJ(aboveSymp, nodep,
|
||||
"Can't find cell insertion point at '"
|
||||
<<baddot<<"' in: "<<nodep->prettyName());
|
||||
}
|
||||
{
|
||||
m_scope = m_scope+"."+nodep->name();
|
||||
|
|
@ -814,10 +812,9 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
string baddot;
|
||||
VSymEnt* okSymp;
|
||||
aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp);
|
||||
if (!aboveSymp) {
|
||||
nodep->v3fatalSrc("Can't find cellinline insertion point at '"
|
||||
<<baddot<<"' in: "<<nodep->prettyName());
|
||||
}
|
||||
UASSERT_OBJ(aboveSymp, nodep,
|
||||
"Can't find cellinline insertion point at '"
|
||||
<<baddot<<"' in: "<<nodep->prettyName());
|
||||
m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident);
|
||||
} else { // No __DOT__, just directly underneath
|
||||
m_statep->insertInline(aboveSymp, m_modSymp, nodep, nodep->name());
|
||||
|
|
@ -882,7 +879,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
virtual void visit(AstNodeFTask* nodep) {
|
||||
// NodeTask: Remember its name for later resolution
|
||||
UINFO(5," "<<nodep<<endl);
|
||||
if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Function/Task not under module?");
|
||||
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Function/Task not under module?");
|
||||
// Remember the existing symbol table scope
|
||||
VSymEnt* oldCurSymp = m_curSymp;
|
||||
{
|
||||
|
|
@ -917,7 +914,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstVar* nodep) {
|
||||
// Var: Remember its name for later resolution
|
||||
if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Var not under module?");
|
||||
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
|
||||
iterateChildren(nodep);
|
||||
if (!m_statep->forScopeCreation()) {
|
||||
// Find under either a task or the module's vars
|
||||
|
|
@ -965,7 +962,8 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// Then have "input foo" and "real foo" so the
|
||||
// dtype comes from the other side.
|
||||
AstNodeDType* newdtypep = nodep->subDTypep();
|
||||
if (!newdtypep || !nodep->childDTypep()) findvarp->v3fatalSrc("No child type?");
|
||||
UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp,
|
||||
"No child type?");
|
||||
bdtypep->unlinkFrBack()->deleteTree();
|
||||
newdtypep->unlinkFrBack();
|
||||
findvarp->childDTypep(newdtypep);
|
||||
|
|
@ -1027,18 +1025,18 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstTypedef* nodep) {
|
||||
// Remember its name for later resolution
|
||||
if (!m_curSymp) nodep->v3fatalSrc("Typedef not under module?");
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Typedef not under module?");
|
||||
iterateChildren(nodep);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
|
||||
}
|
||||
virtual void visit(AstParamTypeDType* nodep) {
|
||||
if (!m_curSymp) nodep->v3fatalSrc("Parameter type not under module?");
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Parameter type not under module?");
|
||||
iterateChildren(nodep);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
// For dotted resolution, ignore all AstVars under functions, otherwise shouldn't exist
|
||||
if (m_statep->forScopeCreation()) nodep->v3fatalSrc("No CFuncs expected in tree yet");
|
||||
UASSERT_OBJ(!m_statep->forScopeCreation(), nodep, "No CFuncs expected in tree yet");
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep) {
|
||||
// EnumItem: Remember its name for later resolution
|
||||
|
|
@ -1186,7 +1184,8 @@ private:
|
|||
UINFO(5," "<<nodep<<endl);
|
||||
if (nodep->dead() || !nodep->user4()) {
|
||||
UINFO(4,"Mark dead module "<<nodep<<endl);
|
||||
if (!m_statep->forPrearray()) nodep->v3fatalSrc("Dead module persisted past where should have removed");
|
||||
UASSERT_OBJ(m_statep->forPrearray(), nodep,
|
||||
"Dead module persisted past where should have removed");
|
||||
// Don't remove now, because we may have a tree of
|
||||
// parameterized modules with VARXREFs into the deleted module
|
||||
// region. V3Dead should cleanup.
|
||||
|
|
@ -1266,7 +1265,7 @@ private:
|
|||
virtual void visit(AstAssignAlias* nodep) {
|
||||
// tran gates need implicit creation
|
||||
// As VarRefs don't exist in forPrimary, sanity check
|
||||
if (m_statep->forPrimary()) nodep->v3fatalSrc("Assign aliases unexpected pre-dot");
|
||||
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
|
||||
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
|
|
@ -1317,7 +1316,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
}
|
||||
virtual void visit(AstScope* nodep) {
|
||||
UINFO(8," SCOPE "<<nodep<<endl);
|
||||
if (!m_statep->forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope");
|
||||
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
|
||||
"Scopes should only exist right after V3Scope");
|
||||
// Using the CELL names, we created all hierarchy. We now need to match this Scope
|
||||
// up with the hierarchy created by the CELL names.
|
||||
m_modSymp = m_statep->getScopeSym(nodep);
|
||||
|
|
@ -1335,20 +1335,21 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
// Find the interface cell the var references
|
||||
AstIfaceRefDType* dtypep
|
||||
= LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
|
||||
if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var");
|
||||
UASSERT_OBJ(dtypep, nodep, "Non AstIfaceRefDType on isIfaceRef() var");
|
||||
UINFO(9,"Iface parent dtype "<<dtypep<<endl);
|
||||
string ifcellname = dtypep->cellName();
|
||||
string baddot; VSymEnt* okSymp;
|
||||
VSymEnt* cellSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp);
|
||||
if (!cellSymp) nodep->v3fatalSrc("No symbol for interface cell: "
|
||||
<<nodep->prettyName(ifcellname));
|
||||
UASSERT_OBJ(cellSymp, nodep,
|
||||
"No symbol for interface cell: "<<nodep->prettyName(ifcellname));
|
||||
UINFO(5, " Found interface cell: se"<<cvtToHex(cellSymp)
|
||||
<<" "<<cellSymp->nodep()<<endl);
|
||||
if (dtypep->modportName()!="") {
|
||||
VSymEnt* mpSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp);
|
||||
if (!mpSymp) { nodep->v3fatalSrc("No symbol for interface modport: "
|
||||
<<nodep->prettyName(dtypep->modportName())); }
|
||||
else cellSymp = mpSymp;
|
||||
UASSERT_OBJ(mpSymp, nodep,
|
||||
"No symbol for interface modport: "
|
||||
<<nodep->prettyName(dtypep->modportName()));
|
||||
cellSymp = mpSymp;
|
||||
UINFO(5, " Found modport cell: se"
|
||||
<<cvtToHex(cellSymp)<<" "<<mpSymp->nodep()<<endl);
|
||||
}
|
||||
|
|
@ -1370,7 +1371,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
if (debug()>=9) nodep->dumpTree(cout, "-\t\t\t\talias: ");
|
||||
AstVarScope* fromVscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* toVscp = VN_CAST(nodep->rhsp(), VarRef)->varScopep();
|
||||
if (!fromVscp || !toVscp) nodep->v3fatalSrc("Bad alias scopes");
|
||||
UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes");
|
||||
fromVscp->user2p(toVscp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -1381,7 +1382,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
{
|
||||
AstVarRef* refp = VN_CAST(nodep->rhsp(), VarRef);
|
||||
AstVarXRef* xrefp = VN_CAST(nodep->rhsp(), VarXRef);
|
||||
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
UASSERT_OBJ(refp || xrefp, nodep,
|
||||
"Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
string inl = ((xrefp && xrefp->inlinedDots().size())
|
||||
? (xrefp->inlinedDots() + "__DOT__") : "");
|
||||
VSymEnt* symp = NULL;
|
||||
|
|
@ -1397,7 +1399,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
}
|
||||
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");
|
||||
UASSERT_OBJ(symp, nodep, "No symbol for interface alias rhs");
|
||||
UINFO(5, " Found a linked scope RHS: "<<scopename<<" se"
|
||||
<<cvtToHex(symp)<<" "<<symp->nodep()<<endl);
|
||||
rhsSymp = symp;
|
||||
|
|
@ -1407,11 +1409,12 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
const AstVarXRef* xrefp = VN_CAST(nodep->lhsp(), VarXRef);
|
||||
const AstVarRef* refp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
|
||||
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
UASSERT_OBJ(refp || xrefp, nodep,
|
||||
"Unsupported: Non Var(X)Ref attached to interface pin");
|
||||
string scopename = refp ? refp->varp()->name() : xrefp->dotted()+"."+xrefp->name();
|
||||
string baddot; VSymEnt* okSymp;
|
||||
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
|
||||
if (!symp) nodep->v3fatalSrc("No symbol for interface alias lhs");
|
||||
UASSERT_OBJ(symp, nodep, "No symbol for interface alias lhs");
|
||||
UINFO(5, " Found a linked scope LHS: "<<scopename
|
||||
<<" se"<<cvtToHex(symp)<<" "<<symp->nodep()<<endl);
|
||||
lhsSymp = symp;
|
||||
|
|
@ -1721,10 +1724,9 @@ private:
|
|||
checkNoDot(nodep);
|
||||
m_cellp = nodep;
|
||||
AstNode::user5ClearTree();
|
||||
if (!nodep->modp()) {
|
||||
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
}
|
||||
else {
|
||||
UASSERT_OBJ(nodep->modp(), nodep,
|
||||
"Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
{
|
||||
if (VN_IS(nodep->modp(), NotFoundModule)) {
|
||||
// Prevent warnings about missing pin connects
|
||||
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
|
|
@ -1751,7 +1753,7 @@ private:
|
|||
checkNoDot(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->modVarp()) {
|
||||
if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?");
|
||||
UASSERT_OBJ(m_pinSymp, nodep, "Pin not under cell?");
|
||||
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
|
||||
const char* whatp = nodep->param() ? "parameter pin" : "pin";
|
||||
if (!foundp) {
|
||||
|
|
@ -1852,8 +1854,8 @@ private:
|
|||
UINFO(9," linkPARSEREF "<<m_ds.ascii()<<" n="<<nodep<<endl);
|
||||
// m_curSymp is symbol table of outer expression
|
||||
// m_ds.m_dotSymp is symbol table relative to "."'s above now
|
||||
if (!m_ds.m_dotSymp) nodep->v3fatalSrc("NULL lookup symbol table");
|
||||
if (!m_statep->forPrimary()) nodep->v3fatalSrc("ParseRefs should no longer exist");
|
||||
UASSERT_OBJ(m_ds.m_dotSymp, nodep, "NULL lookup symbol table");
|
||||
UASSERT_OBJ(m_statep->forPrimary(), nodep, "ParseRefs should no longer exist");
|
||||
DotStates lastStates = m_ds;
|
||||
bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed
|
||||
if (start) {
|
||||
|
|
@ -1879,11 +1881,10 @@ private:
|
|||
expectWhat = "scope/variable";
|
||||
allowScope = true;
|
||||
allowVar = true;
|
||||
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) {
|
||||
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
}
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
packagep = VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep();
|
||||
if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
UASSERT_OBJ(packagep, m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
} else if (m_ds.m_dotPos == DP_SCOPE) {
|
||||
|
|
@ -1931,13 +1932,13 @@ private:
|
|||
if (VN_IS(cellp->modp(), Iface)) {
|
||||
// Interfaces can be referenced like a variable for interconnect
|
||||
VSymEnt* cellEntp = m_statep->getNodeSym(cellp);
|
||||
if (!cellEntp) nodep->v3fatalSrc("No interface sym entry");
|
||||
UASSERT_OBJ(cellEntp, nodep, "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 ? VN_CAST(ifaceSymp->nodep(), Var) : NULL;
|
||||
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "
|
||||
<<findName);
|
||||
UASSERT_OBJ(ifaceRefVarp, nodep,
|
||||
"Can't find interface var ref: "<<findName);
|
||||
//
|
||||
ok = true;
|
||||
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
|
||||
|
|
@ -1956,7 +1957,7 @@ private:
|
|||
else if (AstVar* varp = foundToVarp(foundp, nodep, false)) {
|
||||
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep());
|
||||
if (ifacerefp) {
|
||||
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
|
||||
UASSERT_OBJ(ifacerefp->ifaceViaCellp(), ifacerefp, "Unlinked interface");
|
||||
// Really this is a scope reference into an interface
|
||||
UINFO(9,"varref-ifaceref "<<m_ds.m_dotText<<" "<<nodep<<endl);
|
||||
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
|
||||
|
|
@ -2011,7 +2012,7 @@ private:
|
|||
<<modportp->prettyName());
|
||||
} else {
|
||||
AstCell* cellp = VN_CAST(m_ds.m_dotSymp->nodep(), Cell);
|
||||
if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell");
|
||||
UASSERT_OBJ(cellp, nodep, "Modport not referenced from a cell");
|
||||
AstIface* ifacep = VN_CAST(cellp->modp(), Iface);
|
||||
//string cellName = m_ds.m_dotText; // Use cellp->name
|
||||
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
|
||||
|
|
@ -2081,7 +2082,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (!nodep->varp()) {
|
||||
UINFO(9," linkVarRef se"<<cvtToHex(m_curSymp)<<" n="<<nodep<<endl);
|
||||
if (!m_curSymp) nodep->v3fatalSrc("NULL lookup symbol table");
|
||||
UASSERT_OBJ(m_curSymp, nodep, "NULL lookup symbol table");
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->lvalue()) : NULL) {
|
||||
nodep->varp(varp);
|
||||
|
|
@ -2110,10 +2111,9 @@ private:
|
|||
dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw)
|
||||
string inl = AstNode::dedotName(nodep->inlinedDots());
|
||||
dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp);
|
||||
if (!dotSymp) {
|
||||
nodep->v3fatalSrc("Couldn't resolve inlined scope '"
|
||||
<<baddot<<"' in: "<<nodep->inlinedDots());
|
||||
}
|
||||
UASSERT_OBJ(dotSymp, nodep,
|
||||
"Couldn't resolve inlined scope '"
|
||||
<<baddot<<"' in: "<<nodep->inlinedDots());
|
||||
}
|
||||
dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL
|
||||
if (!m_statep->forScopeCreation()) {
|
||||
|
|
@ -2190,12 +2190,10 @@ private:
|
|||
if (nodep->user3SetOnce()) return;
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) {
|
||||
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
}
|
||||
if (!VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep()) {
|
||||
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
}
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
|
|
@ -2369,12 +2367,10 @@ private:
|
|||
// Resolve its reference
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) {
|
||||
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
}
|
||||
if (!VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep()) {
|
||||
m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
}
|
||||
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), PackageRef),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep(),
|
||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
|
|
|
|||
|
|
@ -81,12 +81,10 @@ private:
|
|||
// Also this would otherwise prevent us from using a label twice
|
||||
// see t_func_return test.
|
||||
while (underp && VN_IS(underp, Var)) underp = underp->nextp();
|
||||
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
|
||||
UASSERT_OBJ(underp, nodep, "Break/disable/continue not under expected statement");
|
||||
UINFO(5," Underpoint is "<<underp<<endl);
|
||||
|
||||
if (!underp) {
|
||||
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
|
||||
return NULL;
|
||||
} else if (VN_IS(underp, JumpLabel)) {
|
||||
if (VN_IS(underp, JumpLabel)) {
|
||||
return VN_CAST(underp, JumpLabel);
|
||||
} else { // Move underp stuff to be under a new label
|
||||
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ void V3LinkLevel::modSortByLevel() {
|
|||
// pointers, may have a stale m_iterp() needing cleanup
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
if (v3Global.rootp()->modulesp()) v3Global.rootp()->v3fatalSrc("Unlink didn't work");
|
||||
UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work");
|
||||
for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) {
|
||||
AstNodeModule* nodep = *it;
|
||||
v3Global.rootp()->addModulep(nodep);
|
||||
|
|
@ -132,7 +132,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
|
|||
|
||||
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
|
||||
AstNodeModule* newmodp = rootp->modulesp();
|
||||
if (!newmodp || !newmodp->isTop()) rootp->v3fatalSrc("No TOP module found to insert under");
|
||||
UASSERT_OBJ(newmodp && newmodp->isTop(), rootp, "No TOP module found to insert under");
|
||||
|
||||
// Find all duplicate signal names (if multitop)
|
||||
typedef vl_unordered_set<std::string> NameSet;
|
||||
|
|
|
|||
|
|
@ -241,62 +241,62 @@ private:
|
|||
iterateChildren(nodep);
|
||||
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
|
||||
AstTypedef* typep = VN_CAST(nodep->backp(), Typedef);
|
||||
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
|
||||
UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef");
|
||||
typep->attrPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrScClocked(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrClockEn(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->sigUserRWPublic(true); m_varp->sigModPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->sigUserRWPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->sigUserRdPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->sigUserRWPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrIsolateAssign(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrSFormat(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrScBv(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) {
|
||||
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
|
||||
UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable");
|
||||
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
|
@ -337,7 +337,8 @@ private:
|
|||
else if (VN_IS(backp, Typedef)) break;
|
||||
else if (VN_IS(backp, NodeFTask)) break;
|
||||
}
|
||||
if (!backp) nodep->v3fatalSrc("Implicit enum/struct type created under unexpected node type");
|
||||
UASSERT_OBJ(backp, nodep,
|
||||
"Implicit enum/struct type created under unexpected node type");
|
||||
AstNodeDType* dtypep = nodep->childDTypep(); dtypep->unlinkFrBack();
|
||||
if (VN_IS(backp, Typedef)) { // A typedef doesn't need us to make yet another level of typedefing
|
||||
// For typedefs just remove the AstRefDType level of abstraction
|
||||
|
|
|
|||
|
|
@ -240,12 +240,12 @@ private:
|
|||
|
||||
virtual void visit(AstPragma* nodep) {
|
||||
if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) {
|
||||
if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module");
|
||||
UASSERT_OBJ(m_modp, nodep, "PUBLIC_MODULE not under a module");
|
||||
m_modp->modPublic(true);
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) {
|
||||
if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task");
|
||||
UASSERT_OBJ(m_ftaskp, nodep, "PUBLIC_TASK not under a task");
|
||||
m_ftaskp->taskPublic(true);
|
||||
m_modp->modPublic(true); // Need to get to the task...
|
||||
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
@ -387,7 +387,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
// Cleanup old-school displays without format arguments
|
||||
if (!nodep->hasFormat()) {
|
||||
if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format");
|
||||
UASSERT_OBJ(nodep->text()=="", nodep, "Non-format $sformatf should have \"\" format");
|
||||
if (VN_IS(nodep->exprsp(), Const)
|
||||
&& VN_CAST(nodep->exprsp(), Const)->num().isFromString()) {
|
||||
AstConst* fmtp = VN_CAST(nodep->exprsp()->unlinkFrBack(), Const);
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ private:
|
|||
for (; nodep; nodep=nodep->nextp()) {
|
||||
if (VN_IS(nodep, NodeAssign)) {
|
||||
if (AstVarRef* varrefp = VN_CAST(VN_CAST(nodep, NodeAssign)->lhsp(), VarRef)) {
|
||||
if (!varrefp->lvalue()) varrefp->v3fatalSrc("LHS assignment not lvalue");
|
||||
UASSERT_OBJ(varrefp->lvalue(), varrefp, "LHS assignment not lvalue");
|
||||
if (!varrefp->varp()->user4p()) {
|
||||
UINFO(4," FuncAsn "<<varrefp<<endl);
|
||||
varrefp->varp()->user4p(varrefp);
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public:
|
|||
// METHODS
|
||||
OrderVarVertex* newVarUserVertex(V3Graph* graphp, AstScope* scopep,
|
||||
AstVarScope* varscp, WhichVertex type, bool* createdp=NULL) {
|
||||
if (type>=WV_MAX) varscp->v3fatalSrc("Bad case");
|
||||
UASSERT_OBJ(type < WV_MAX, varscp, "Bad case");
|
||||
OrderVarVertex* vertexp = m_vertexp[type];
|
||||
if (!vertexp) {
|
||||
UINFO(6,"New vertex "<<varscp<<endl);
|
||||
|
|
@ -735,7 +735,7 @@ private:
|
|||
UINFO(4," STMT "<<nodep<<endl);
|
||||
//VV***** We reset user4p()
|
||||
AstNode::user4ClearTree();
|
||||
if (!m_activep || !m_activep->sensesp()) nodep->v3fatalSrc("NULL");
|
||||
UASSERT_OBJ(m_activep && m_activep->sensesp(), nodep, "NULL");
|
||||
// If inside combo logic, ignore the domain, we'll assign one based on interconnect
|
||||
AstSenTree* startDomainp = m_activep->sensesp();
|
||||
if (startDomainp->hasCombo()) startDomainp=NULL;
|
||||
|
|
@ -963,7 +963,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
// Process the last thing we're finishing
|
||||
if (m_topScopep) nodep->v3fatalSrc("Only one topscope should ever be created");
|
||||
UASSERT_OBJ(!m_topScopep, nodep, "Only one topscope should ever be created");
|
||||
UINFO(2," Loading tree...\n");
|
||||
//VV***** We reset userp()
|
||||
AstNode::user1ClearTree();
|
||||
|
|
@ -1022,7 +1022,8 @@ private:
|
|||
m_activeSenVxp = NULL;
|
||||
m_inClocked = nodep->hasClocked();
|
||||
// Grab the sensitivity list
|
||||
if (nodep->sensesStorep()) nodep->v3fatalSrc("Senses should have been activeTop'ed to be global!");
|
||||
UASSERT_OBJ(!nodep->sensesStorep(), nodep,
|
||||
"Senses should have been activeTop'ed to be global!");
|
||||
iterate(nodep->sensesp());
|
||||
// Collect statements under it
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -1040,15 +1041,15 @@ private:
|
|||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
if (m_scopep) {
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
UASSERT_OBJ(varscp, nodep, "Var didn't get varscoped in V3Scope.cpp");
|
||||
if (m_inSenTree) {
|
||||
// Add CLOCK dependency... This is a root of the tree we'll trace
|
||||
if (nodep->lvalue()) nodep->v3fatalSrc("How can a sensitivity be setting a var?");
|
||||
UASSERT_OBJ(!nodep->lvalue(), nodep, "How can a sensitivity be setting a var?");
|
||||
OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD);
|
||||
varVxp->isClock(true);
|
||||
new OrderEdge(&m_graph, varVxp, m_activeSenVxp, WEIGHT_MEDIUM);
|
||||
} else {
|
||||
if (!m_logicVxp) nodep->v3fatalSrc("Var ref not under a logic block");
|
||||
UASSERT_OBJ(m_logicVxp, nodep, "Var ref not under a logic block");
|
||||
// What new directions is this used
|
||||
// We don't want to add extra edges if the logic block has many usages of same var
|
||||
bool gen = false;
|
||||
|
|
@ -1307,8 +1308,8 @@ static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) {
|
|||
const AstSenItem* toSenListp = VN_CAST(top->sensesp(), SenItem);
|
||||
// If clk gating is ever reenabled, we may need to update this to handle
|
||||
// AstSenGate also.
|
||||
if (!fromSenListp) fromp->v3fatalSrc("sensitivity list item is not an AstSenItem");
|
||||
if (!toSenListp) top->v3fatalSrc("sensitivity list item is not an AstSenItem");
|
||||
UASSERT_OBJ(fromSenListp, fromp, "sensitivity list item is not an AstSenItem");
|
||||
UASSERT_OBJ(toSenListp, top, "sensitivity list item is not an AstSenItem");
|
||||
|
||||
if (fromSenListp->nextp()) return false;
|
||||
if (toSenListp->nextp()) return false;
|
||||
|
|
@ -1337,9 +1338,8 @@ inline void OrderMoveDomScope::ready(OrderVisitor* ovp) {
|
|||
|
||||
// Mark one vertex as finished, remove from ready list if done
|
||||
inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) {
|
||||
if (!m_onReadyList) {
|
||||
vertexp->v3fatalSrc("Moving vertex from ready when nothing was on que as ready.");
|
||||
}
|
||||
UASSERT_OBJ(m_onReadyList, vertexp,
|
||||
"Moving vertex from ready when nothing was on que as ready.");
|
||||
if (m_readyVertices.empty()) { // Else more work to get to later
|
||||
m_onReadyList = false;
|
||||
m_readyDomScopeE.unlink(ovp->m_pomReadyDomScope, this);
|
||||
|
|
@ -1406,9 +1406,8 @@ void OrderVisitor::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
|
|||
// First make sure input path is fully recursed
|
||||
processInputsInIterate(vertexp, todoVec);
|
||||
// Propagate PrimaryIn through simple assignments
|
||||
if (!vertexp->isFromInput()) {
|
||||
vertexp->v3fatalSrc("processInputsOutIterate only for input marked vertexes");
|
||||
}
|
||||
UASSERT_OBJ(vertexp->isFromInput(), vertexp,
|
||||
"processInputsOutIterate only for input marked vertexes");
|
||||
vertexp->user(3); // out-edges processed
|
||||
|
||||
{
|
||||
|
|
@ -1460,7 +1459,7 @@ void OrderVisitor::processCircular() {
|
|||
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||
if (edgep->weight()==0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
|
||||
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cuttable edge not of proper type");
|
||||
UINFO(6," CutCircularO: "<<vvertexp->name()<<endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
}
|
||||
|
|
@ -1468,7 +1467,7 @@ void OrderVisitor::processCircular() {
|
|||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
if (edgep->weight()==0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
|
||||
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cuttable edge not of proper type");
|
||||
UINFO(6," CutCircularI: "<<vvertexp->name()<<endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
}
|
||||
|
|
@ -1563,7 +1562,8 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
|
|||
}
|
||||
AstSenTree* newtreep = domainp->cloneTree(false);
|
||||
AstNodeSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
|
||||
if (!newtree2p) fromVertexp->domainp()->v3fatalSrc("No senitem found under clocked domain");
|
||||
UASSERT_OBJ(newtree2p, fromVertexp->domainp(),
|
||||
"No senitem found under clocked domain");
|
||||
newtreep->addSensesp(newtree2p);
|
||||
newtree2p = NULL; // Below edit may replace it
|
||||
V3Const::constifyExpensiveEdit(newtreep); // Remove duplicates
|
||||
|
|
@ -1759,9 +1759,7 @@ void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) {
|
|||
|
||||
void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp,
|
||||
OrderMoveDomScope* domScopep, int level) {
|
||||
if (vertexp->domScopep() != domScopep) {
|
||||
vertexp->v3fatalSrc("Domain mismatch; list misbuilt?");
|
||||
}
|
||||
UASSERT_OBJ(vertexp->domScopep() == domScopep, vertexp, "Domain mismatch; list misbuilt?");
|
||||
const OrderLogicVertex* lvertexp = vertexp->logicp();
|
||||
const AstScope* scopep = lvertexp->scopep();
|
||||
UINFO(5," POSmove l"<<std::setw(3)<<level<<" d="<<cvtToHex(lvertexp->domainp())
|
||||
|
|
|
|||
|
|
@ -204,16 +204,14 @@ private:
|
|||
// Find it in the clone structure
|
||||
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
|
||||
CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
|
||||
if (cloneiter == clonemapp->end()) {
|
||||
pinp->v3fatalSrc("Couldn't find pin in clone list");
|
||||
}
|
||||
UASSERT_OBJ(cloneiter != clonemapp->end(), pinp,
|
||||
"Couldn't find pin in clone list");
|
||||
pinp->modVarp(VN_CAST(cloneiter->second, Var));
|
||||
}
|
||||
else if (pinp->modPTypep()) {
|
||||
CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep());
|
||||
if (cloneiter == clonemapp->end()) {
|
||||
pinp->v3fatalSrc("Couldn't find pin in clone list");
|
||||
}
|
||||
UASSERT_OBJ(cloneiter != clonemapp->end(), pinp,
|
||||
"Couldn't find pin in clone list");
|
||||
pinp->modPTypep(VN_CAST(cloneiter->second, ParamTypeDType));
|
||||
}
|
||||
else {
|
||||
|
|
@ -318,7 +316,7 @@ private:
|
|||
return true;
|
||||
} else if (AstPin* pinp = VN_CAST(candp, Pin)) {
|
||||
UINFO(9,"Found interface parameter: "<<pinp<<endl);
|
||||
if (!pinp->exprp()) pinp->v3fatalSrc("Interface parameter pin missing expression");
|
||||
UASSERT_OBJ(pinp->exprp(), pinp, "Interface parameter pin missing expression");
|
||||
nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -455,7 +453,7 @@ private:
|
|||
virtual void visit(AstBegin* nodep) {
|
||||
if (nodep->genforp()) {
|
||||
AstGenFor* forp = VN_CAST(nodep->genforp(), GenFor);
|
||||
if (!forp) nodep->v3fatalSrc("Non-GENFOR under generate-for BEGIN");
|
||||
UASSERT_OBJ(forp, nodep, "Non-GENFOR under generate-for BEGIN");
|
||||
// We should have a GENFOR under here. We will be replacing the begin,
|
||||
// so process here rather than at the generate to avoid iteration problems
|
||||
UINFO(9," BEGIN "<<nodep<<endl);
|
||||
|
|
@ -560,7 +558,7 @@ public:
|
|||
void ParamVisitor::visitCell(AstCell* nodep) {
|
||||
// Cell: Check for parameters in the instantiation.
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->modp()) nodep->v3fatalSrc("Not linked?");
|
||||
UASSERT_OBJ(nodep->modp(), nodep, "Not linked?");
|
||||
// We always run this, even if no parameters, as need to look for interfaces,
|
||||
// and remove any recursive references
|
||||
{
|
||||
|
|
@ -777,7 +775,8 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
AstIfaceRefDType* cloneIrefp = portIrefp->clonep();
|
||||
UINFO(8," IfaceOld "<<portIrefp<<endl);
|
||||
UINFO(8," IfaceTo "<<pinIrefp<<endl);
|
||||
if (!cloneIrefp) portIrefp->v3fatalSrc("parameter clone didn't hit AstIfaceRefDType");
|
||||
UASSERT_OBJ(cloneIrefp, portIrefp,
|
||||
"parameter clone didn't hit AstIfaceRefDType");
|
||||
UINFO(8," IfaceClo "<<cloneIrefp<<endl);
|
||||
cloneIrefp->ifacep(pinIrefp->ifaceViaCellp());
|
||||
UINFO(8," IfaceNew "<<cloneIrefp<<endl);
|
||||
|
|
@ -796,7 +795,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
}
|
||||
else if (AstParamTypeDType* modptp = pinp->modPTypep()) {
|
||||
AstNodeDType* dtypep = VN_CAST(pinp->exprp(), NodeDType);
|
||||
if (!dtypep) pinp->v3fatalSrc("unlinked param dtype");
|
||||
UASSERT_OBJ(dtypep, pinp, "unlinked param dtype");
|
||||
if (modptp->childDTypep()) {
|
||||
pushDeletep(modptp->childDTypep()->unlinkFrBack());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,9 +109,8 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep,
|
|||
if (prevp) nrangep->unlinkFrBack();
|
||||
AstRange* rangep = VN_CAST(nrangep, Range);
|
||||
if (!rangep) {
|
||||
if (VL_UNCOVERABLE(!VN_IS(nrangep, UnsizedRange))) {
|
||||
nrangep->v3fatalSrc("Expected range or unsized range");
|
||||
}
|
||||
UASSERT_OBJ(VN_IS(nrangep, UnsizedRange), nrangep,
|
||||
"Expected range or unsized range");
|
||||
arrayp = new AstUnsizedArrayDType
|
||||
(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else if (isPacked) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public:
|
|||
private:
|
||||
// METHODS
|
||||
static VSymEnt* getTable(AstNode* nodep) {
|
||||
if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found");
|
||||
UASSERT_OBJ(nodep->user4p(), nodep, "Current symtable not found");
|
||||
return nodep->user4u().toSymEnt();
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ public:
|
|||
return;
|
||||
}
|
||||
m_sympStack.pop_back();
|
||||
if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; }
|
||||
UASSERT_OBJ(!m_sympStack.empty(), nodep, "symbol stack underflow");
|
||||
m_symCurrentp = m_sympStack.back();
|
||||
}
|
||||
void showUpward() {
|
||||
|
|
@ -139,10 +139,9 @@ public:
|
|||
void importItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Import from package::id_or_star to this
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
packagep->v3fatalSrc("Import package not found");
|
||||
return;
|
||||
}
|
||||
UASSERT_OBJ(symp, packagep,
|
||||
// Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
"Import package not found");
|
||||
// Walk old sym table and reinsert into current table
|
||||
// We let V3LinkDot report the error instead of us
|
||||
symCurrentp()->importFromPackage(&m_syms, symp, id_or_star);
|
||||
|
|
@ -150,10 +149,9 @@ public:
|
|||
void exportItem(AstNode* packagep, const string& id_or_star) {
|
||||
// Export from this the remote package::id_or_star
|
||||
VSymEnt* symp = getTable(packagep);
|
||||
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
packagep->v3fatalSrc("Export package not found");
|
||||
return;
|
||||
}
|
||||
UASSERT_OBJ(symp, packagep,
|
||||
// Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
|
||||
"Export package not found");
|
||||
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
|
||||
}
|
||||
void exportStarStar(AstNode* packagep) {
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ private:
|
|||
// important property of PartPropagateCp which allows it to be far
|
||||
// faster than a recursive algorithm on some graphs.
|
||||
CpMap::iterator it = m_seen.find(vxp);
|
||||
if (it != m_seen.end()) vxp->v3fatalSrc("Set CP on node twice");
|
||||
UASSERT_OBJ(it == m_seen.end(), vxp, "Set CP on node twice");
|
||||
m_seen[vxp] = cost;
|
||||
}
|
||||
uint32_t critPathCost(V3GraphVertex* vxp, GraphWay way) const {
|
||||
|
|
@ -452,7 +452,7 @@ public:
|
|||
// This is mtaskp's relative with longest !wayward inclusive CP:
|
||||
EdgeSet::reverse_iterator edgeIt = edges.rbegin();
|
||||
uint32_t edgeCp = (*edgeIt).value();
|
||||
if (edgeCp != cp) vxp->v3fatalSrc("CP doesn't match longest wayward edge");
|
||||
UASSERT_OBJ(edgeCp == cp, vxp, "CP doesn't match longest wayward edge");
|
||||
}
|
||||
private:
|
||||
VL_UNCOPYABLE(CpCostAccessor);
|
||||
|
|
@ -988,12 +988,10 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
|
|||
edgep; edgep = edgep->nextp(rev)) {
|
||||
// Run a few asserts on the initial mtask graph,
|
||||
// while we're iterating through...
|
||||
if (edgep->weight() == 0) {
|
||||
mtaskp->v3fatalSrc("Should be no cut edges in mtasks graph");
|
||||
}
|
||||
if (relatives.find(edgep->furtherp(rev)) != relatives.end()) {
|
||||
mtaskp->v3fatalSrc("Should be no redundant edges in mtasks graph");
|
||||
}
|
||||
UASSERT_OBJ(edgep->weight() != 0, mtaskp,
|
||||
"Should be no cut edges in mtasks graph");
|
||||
UASSERT_OBJ(relatives.find(edgep->furtherp(rev)) == relatives.end(), mtaskp,
|
||||
"Should be no redundant edges in mtasks graph");
|
||||
relatives.insert(edgep->furtherp(rev));
|
||||
|
||||
LogicMTask* relativep
|
||||
|
|
@ -1187,9 +1185,8 @@ public:
|
|||
for (V3GraphEdge* edgep = itp->outBeginp(); edgep;
|
||||
edgep=edgep->outNextp()) {
|
||||
m_sb.addElem(MTaskEdge::cast(edgep));
|
||||
if (neighbors.find(edgep->top()) != neighbors.end()) {
|
||||
itp->v3fatalSrc("Redundant edge found in input to PartContraction()");
|
||||
}
|
||||
UASSERT_OBJ(neighbors.find(edgep->top()) == neighbors.end(), itp,
|
||||
"Redundant edge found in input to PartContraction()");
|
||||
neighbors.insert(edgep->top());
|
||||
}
|
||||
siblingPairFromRelatives(GraphWay::REVERSE, itp, true);
|
||||
|
|
@ -1352,12 +1349,12 @@ private:
|
|||
LogicMTask* otherp = (pairp->bp() == mtaskp) ?
|
||||
pairp->ap() : pairp->bp();
|
||||
size_t erased = m_mtask2sibs[otherp].erase(pairp);
|
||||
if (erased <= 0) otherp->v3fatalSrc("Expected existing mtask");
|
||||
UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask");
|
||||
erased = m_pairs.erase(*pairp);
|
||||
if (erased <= 0) mtaskp->v3fatalSrc("Expected existing mtask");
|
||||
UASSERT_OBJ(erased > 0, mtaskp, "Expected existing mtask");
|
||||
}
|
||||
size_t erased = m_mtask2sibs.erase(mtaskp);
|
||||
if (erased <= 0) mtaskp->v3fatalSrc("Expected existing mtask");
|
||||
UASSERT_OBJ(erased > 0, mtaskp, "Expected existing mtask");
|
||||
}
|
||||
|
||||
void contract(MergeCandidate* mergeCanp) {
|
||||
|
|
@ -1571,24 +1568,21 @@ private:
|
|||
} else if (m_slowAsserts) {
|
||||
// It's fine if we already have this SiblingMC, we may have
|
||||
// created it earlier. Just confirm that we have associated data.
|
||||
if (m_mtask2sibs.find(ap) == m_mtask2sibs.end()) {
|
||||
ap->v3fatalSrc("Sibling not found");
|
||||
}
|
||||
if (m_mtask2sibs.find(bp) == m_mtask2sibs.end()) {
|
||||
bp->v3fatalSrc("Sibling not found");
|
||||
}
|
||||
UASSERT_OBJ(m_mtask2sibs.find(ap) != m_mtask2sibs.end(), ap,
|
||||
"Sibling not found");
|
||||
UASSERT_OBJ(m_mtask2sibs.find(bp) != m_mtask2sibs.end(), bp,
|
||||
"Sibling not found");
|
||||
bool found = false;
|
||||
for (SibpSet::iterator it = m_mtask2sibs[ap].begin();
|
||||
it != m_mtask2sibs[ap].end(); ++it) {
|
||||
const SiblingMC* sibsp = *it;
|
||||
if (!sibsp->removedFromSb() && !m_sb.contains(sibsp)) {
|
||||
ap->v3fatalSrc("One sibling must be the one we collided with");
|
||||
}
|
||||
UASSERT_OBJ(!(!sibsp->removedFromSb() && !m_sb.contains(sibsp)), ap,
|
||||
"One sibling must be the one we collided with");
|
||||
if ( (sibsp->ap() == ap && sibsp->bp() == bp)
|
||||
|| (sibsp->bp() == ap && sibsp->ap() == bp))
|
||||
found = true;
|
||||
}
|
||||
if (!found) ap->v3fatalSrc("Sibling not found");
|
||||
UASSERT_OBJ(found, ap, "Sibling not found");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1955,7 +1949,7 @@ private:
|
|||
while (!rankIt->second.empty()) {
|
||||
LogicMTaskSet::iterator begin = rankIt->second.begin();
|
||||
LogicMTask* donorp = *begin;
|
||||
if (donorp == mergedp) donorp->v3fatalSrc("Donor can't be merged edge");
|
||||
UASSERT_OBJ(donorp != mergedp, donorp, "Donor can't be merged edge");
|
||||
rankIt->second.erase(begin);
|
||||
// Merge donorp into mergedp.
|
||||
// Fix up the map, so donor's OLVs map to mergedp
|
||||
|
|
@ -1976,9 +1970,8 @@ private:
|
|||
}
|
||||
|
||||
if (lastMergedp) {
|
||||
if (lastMergedp->rank() >= mergedp->rank()) {
|
||||
mergedp->v3fatalSrc("Merging must be on lower rank");
|
||||
}
|
||||
UASSERT_OBJ(lastMergedp->rank() < mergedp->rank(), mergedp,
|
||||
"Merging must be on lower rank");
|
||||
if (!lastMergedp->hasRelative(GraphWay::FORWARD, mergedp)) {
|
||||
new MTaskEdge(m_mtasksp, lastMergedp, mergedp, 1);
|
||||
}
|
||||
|
|
@ -2309,7 +2302,7 @@ public:
|
|||
|
||||
// Update the ready list
|
||||
size_t erased = m_ready.erase(bestMtaskp);
|
||||
if (erased <= 0) bestMtaskp->v3fatalSrc("Should have erased something?");
|
||||
UASSERT_OBJ(erased > 0, bestMtaskp, "Should have erased something?");
|
||||
for (V3GraphEdge* edgeOutp = bestMtaskp->outBeginp();
|
||||
edgeOutp; edgeOutp = edgeOutp->outNextp()) {
|
||||
ExecMTask* nextp = dynamic_cast<ExecMTask*>(edgeOutp->top());
|
||||
|
|
@ -2318,9 +2311,8 @@ public:
|
|||
"Tasks after one being assigned should not be assigned yet");
|
||||
// They also should not be ready yet, since they only now
|
||||
// may become ready
|
||||
if (m_ready.find(nextp) != m_ready.end()) {
|
||||
nextp->v3fatalSrc("Tasks after one being assigned should not be ready");
|
||||
}
|
||||
UASSERT_OBJ(m_ready.find(nextp) == m_ready.end(), nextp,
|
||||
"Tasks after one being assigned should not be ready");
|
||||
bool isReady = true;
|
||||
for (V3GraphEdge* edgeInp = nextp->inBeginp();
|
||||
edgeInp; edgeInp = edgeInp->inNextp()) {
|
||||
|
|
@ -2514,7 +2506,7 @@ void V3Partition::setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp)
|
|||
UASSERT(it != vx2mtaskp->end(), "MTask map can't find id");
|
||||
LogicMTask* otherMTaskp = it->second;
|
||||
UASSERT(otherMTaskp, "NULL other Mtask");
|
||||
if (otherMTaskp == mtaskp) mtaskp->v3fatalSrc("Would create a cycle edge");
|
||||
UASSERT_OBJ(otherMTaskp != mtaskp, mtaskp, "Would create a cycle edge");
|
||||
|
||||
// Don't create redundant edges.
|
||||
if (mtaskp->hasRelative(GraphWay::FORWARD, otherMTaskp)) {
|
||||
|
|
@ -2543,7 +2535,7 @@ void V3Partition::go(V3Graph* mtasksp) {
|
|||
for (V3GraphVertex* vxp = m_fineDepsGraphp->verticesBeginp();
|
||||
vxp; vxp = vxp->verticesNextp()) {
|
||||
MTaskMoveVertex* mtmvVxp = dynamic_cast<MTaskMoveVertex*>(vxp);
|
||||
if (!mtmvVxp) vxp->v3fatalSrc("Every vertex here should be an MTaskMoveVertex");
|
||||
UASSERT_OBJ(mtmvVxp, vxp, "Every vertex here should be an MTaskMoveVertex");
|
||||
|
||||
LogicMTask* mtaskp = new LogicMTask(mtasksp, mtmvVxp);
|
||||
vx2mtask[mtmvVxp] = mtaskp;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ private:
|
|||
string newvarname = string("__Vilp");
|
||||
varp = new AstVar(fl, AstVarType::STMTTEMP,
|
||||
newvarname, VFlagLogicPacked(), 32);
|
||||
if (!cfuncp) fl->v3fatalSrc("Assignment not under a function");
|
||||
UASSERT_OBJ(cfuncp, fl, "Assignment not under a function");
|
||||
cfuncp->addInitsp(varp);
|
||||
cfuncp->user1p(varp);
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ private:
|
|||
|
||||
// Transform first assign into for loop body
|
||||
AstNodeAssign* bodyp = m_mgAssignps.front();
|
||||
if (bodyp->lhsp() != m_mgSelLp) bodyp->v3fatalSrc("Corrupt queue/state");
|
||||
UASSERT_OBJ(bodyp->lhsp() == m_mgSelLp, bodyp, "Corrupt queue/state");
|
||||
FileLine* fl = bodyp->fileline();
|
||||
AstVar* itp = findCreateVarTemp(fl, m_mgCfuncp);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ private:
|
|||
AstScope* scopep = it->second;
|
||||
if (nodep->packagep()) {
|
||||
PackageScopeMap::iterator it2 = m_packageScopes.find(nodep->packagep());
|
||||
if (it2==m_packageScopes.end()) nodep->v3fatalSrc("Can't locate package scope");
|
||||
UASSERT_OBJ(it2 != m_packageScopes.end(), nodep, "Can't locate package scope");
|
||||
scopep = it2->second;
|
||||
}
|
||||
VarScopeMap::iterator it3 = m_varScopes.find(make_pair(nodep->varp(), scopep));
|
||||
if (it3==m_varScopes.end()) nodep->v3fatalSrc("Can't locate varref scope");
|
||||
UASSERT_OBJ(it3 != m_varScopes.end(), nodep, "Can't locate varref scope");
|
||||
AstVarScope* varscp = it3->second;
|
||||
nodep->varScopep(varscp);
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ private:
|
|||
m_aboveCellp = cellp;
|
||||
m_aboveScopep = m_scopep;
|
||||
AstNodeModule* modp = cellp->modp();
|
||||
if (!modp) cellp->v3fatalSrc("Unlinked mod");
|
||||
UASSERT_OBJ(modp, cellp, "Unlinked mod");
|
||||
iterate(modp); // Recursive call to visit(AstNodeModule)
|
||||
}
|
||||
// Done, restore vars
|
||||
|
|
@ -251,7 +251,7 @@ private:
|
|||
if (v3Global.opt.isNoClocker(varscp->prettyName())) {
|
||||
nodep->attrClocker(AstVarAttrClocker::CLOCKER_NO);
|
||||
}
|
||||
if (!m_scopep) nodep->v3fatalSrc("No scope for var");
|
||||
UASSERT_OBJ(m_scopep, nodep, "No scope for var");
|
||||
m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp));
|
||||
m_scopep->addVarp(varscp);
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
// VarRef needs to point to VarScope
|
||||
// Make sure variable has made user1p.
|
||||
if (!nodep->varp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
|
||||
if (nodep->varp()->isIfaceRef()) {
|
||||
nodep->varScopep(NULL);
|
||||
} else {
|
||||
|
|
@ -378,9 +378,9 @@ private:
|
|||
UINFO(9," Old pkg-taskref "<<nodep<<endl);
|
||||
if (nodep->packagep()) {
|
||||
// Point to the clone
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked");
|
||||
AstNodeFTask* newp = VN_CAST(nodep->taskp()->user2p(), NodeFTask);
|
||||
if (!newp) nodep->v3fatalSrc("No clone for package function");
|
||||
UASSERT_OBJ(newp, nodep, "No clone for package function");
|
||||
nodep->taskp(newp);
|
||||
UINFO(9," New pkg-taskref "<<nodep<<endl);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -267,13 +267,13 @@ public:
|
|||
}
|
||||
V3Number* fetchNumber(AstNode* nodep) {
|
||||
V3Number* nump = fetchNumberNull(nodep);
|
||||
if (!nump) nodep->v3fatalSrc("No value found for node.");
|
||||
UASSERT_OBJ(nump, nodep, "No value found for node.");
|
||||
//UINFO(9," fetch num "<<*nump<<" on "<<nodep<<endl);
|
||||
return nump;
|
||||
}
|
||||
V3Number* fetchOutNumber(AstNode* nodep) {
|
||||
V3Number* nump = fetchOutNumberNull(nodep);
|
||||
if (!nump) nodep->v3fatalSrc("No value found for node.");
|
||||
UASSERT_OBJ(nump, nodep, "No value found for node.");
|
||||
return nump;
|
||||
}
|
||||
private:
|
||||
|
|
@ -314,7 +314,7 @@ private:
|
|||
AstNode* vscp;
|
||||
if (m_scoped) vscp = nodep->varScopep();
|
||||
else vscp = nodep->varp();
|
||||
if (!vscp) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(vscp, nodep, "Not linked");
|
||||
return vscp;
|
||||
}
|
||||
int unrollCount() {
|
||||
|
|
@ -347,7 +347,7 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
if (!optimizable()) return; // Accelerate
|
||||
if (!nodep->varp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
|
||||
iterateChildren(nodep->varp());
|
||||
AstNode* vscp = varOrScope(nodep);
|
||||
|
||||
|
|
@ -391,9 +391,9 @@ private:
|
|||
}
|
||||
}
|
||||
if (!m_checkOnly && optimizable()) { // simulating
|
||||
if (nodep->lvalue()) {
|
||||
nodep->v3fatalSrc("LHS varref should be handled in AstAssign visitor.");
|
||||
} else {
|
||||
UASSERT_OBJ(!nodep->lvalue(), nodep,
|
||||
"LHS varref should be handled in AstAssign visitor.");
|
||||
{
|
||||
// Return simulation value - copy by reference instead of value for speed
|
||||
V3Number* nump = fetchNumberNull(vscp);
|
||||
if (!nump) {
|
||||
|
|
@ -447,7 +447,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstEnumItemRef* nodep) {
|
||||
checkNodeInfo(nodep);
|
||||
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
AstNode* valuep = nodep->itemp()->valuep();
|
||||
if (valuep) {
|
||||
|
|
@ -572,9 +572,8 @@ private:
|
|||
iterateAndNextNull(nodep->rhsp()); // Value to assign
|
||||
handleAssignSelRecurse(nodep, selp, varrefp/*ref*/, lsb/*ref*/, 0);
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
if (!varrefp) {
|
||||
nodep->v3fatalSrc("Indicated optimizable, but no variable found on RHS of select");
|
||||
}
|
||||
UASSERT_OBJ(varrefp, nodep,
|
||||
"Indicated optimizable, but no variable found on RHS of select");
|
||||
AstNode* vscp = varOrScope(varrefp);
|
||||
V3Number outnum = V3Number(nodep);
|
||||
if (V3Number* vscpnump = fetchOutNumberNull(vscp)) {
|
||||
|
|
@ -796,9 +795,9 @@ private:
|
|||
UINFO(5," FUNCREF "<<nodep<<endl);
|
||||
if (!m_params) { badNodeType(nodep); return; }
|
||||
AstNodeFTask* funcp = VN_CAST(nodep->taskp(), NodeFTask);
|
||||
if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(funcp, nodep, "Not linked");
|
||||
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
|
||||
funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
funcp = VN_CAST(nodep->taskp(), NodeFTask); UASSERT_OBJ(funcp, nodep, "Not linked");
|
||||
// Apply function call values to function
|
||||
V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
|
||||
// Must do this in two steps, eval all params, then apply them
|
||||
|
|
@ -832,7 +831,7 @@ private:
|
|||
m_callStack.pop_front();
|
||||
if (!m_checkOnly && optimizable()) {
|
||||
// Grab return value from output variable (if it's a function)
|
||||
if (!funcp->fvarp()) nodep->v3fatalSrc("Function reference points at non-function");
|
||||
UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function");
|
||||
newNumber(nodep, *fetchNumber(funcp->fvarp()));
|
||||
}
|
||||
}
|
||||
|
|
@ -947,10 +946,7 @@ private:
|
|||
}
|
||||
void mainGuts(AstNode* nodep) {
|
||||
iterate(nodep);
|
||||
if (m_jumpp) {
|
||||
m_jumpp->v3fatalSrc("JumpGo branched to label that wasn't found");
|
||||
m_jumpp = NULL;
|
||||
}
|
||||
UASSERT_OBJ(!m_jumpp, m_jumpp, "JumpGo branched to label that wasn't found");
|
||||
}
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
|
|||
|
|
@ -161,9 +161,8 @@ class SliceVisitor : public AstNVisitor {
|
|||
}
|
||||
|
||||
virtual void visit(AstInitArray* nodep) {
|
||||
if (VL_UNCOVERABLE(m_assignp)) {
|
||||
nodep->v3fatalSrc("Array initialization should have been removed earlier");
|
||||
}
|
||||
UASSERT_OBJ(!m_assignp, nodep,
|
||||
"Array initialization should have been removed earlier");
|
||||
}
|
||||
|
||||
void expandBiOp(AstNodeBiop* nodep) {
|
||||
|
|
@ -202,7 +201,7 @@ class SliceVisitor : public AstNVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!logp) nodep->v3fatalSrc("Unpacked array with empty indices range");
|
||||
UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range");
|
||||
nodep->replaceWith(logp);
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
nodep = logp;
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ private:
|
|||
//UINFO(9," push "<<nodep<<endl);
|
||||
SplitLogicVertex* vertexp = new SplitLogicVertex(&m_graph, nodep);
|
||||
m_stmtStackps.push_back(vertexp);
|
||||
if (nodep->user3p()) nodep->v3fatalSrc("user3p should not be used; cleared in processBlock");
|
||||
UASSERT_OBJ(!nodep->user3p(), nodep, "user3p should not be used; cleared in processBlock");
|
||||
nodep->user3p(vertexp);
|
||||
}
|
||||
void scoreboardPopStmt() {
|
||||
|
|
@ -365,7 +365,7 @@ protected:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
if (!m_stmtStackps.empty()) {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Not linked");
|
||||
UASSERT_OBJ(vscp, nodep, "Not linked");
|
||||
if (!nodep->varp()->isConst()) { // Constant lookups can be ignored
|
||||
// ---
|
||||
// NOTE: Formerly at this location we would avoid
|
||||
|
|
@ -518,7 +518,7 @@ protected:
|
|||
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
|
||||
SplitLogicVertex* vvertexp = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
|
||||
uint32_t color = vvertexp->color();
|
||||
if (!color) nextp->v3fatalSrc("No node color assigned");
|
||||
UASSERT_OBJ(color, nextp, "No node color assigned");
|
||||
if (lastOfColor[color]) {
|
||||
new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp);
|
||||
}
|
||||
|
|
@ -580,9 +580,8 @@ protected:
|
|||
AstNode* firstp = nodep; // We may reorder, and nodep is no longer first.
|
||||
void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it
|
||||
nodep->user3p(NULL);
|
||||
if (!nodep->firstAbovep()) {
|
||||
nodep->v3fatalSrc("Node passed is in next list; should have processed all list at once");
|
||||
}
|
||||
UASSERT_OBJ(nodep->firstAbovep(), nodep,
|
||||
"Node passed is in next list; should have processed all list at once");
|
||||
// Process it
|
||||
if (!nodep->nextp()) {
|
||||
// Just one, so can't reorder. Just look for more blocks/statements.
|
||||
|
|
@ -656,7 +655,7 @@ public:
|
|||
const ColorSet& colors() const { return m_colors; }
|
||||
const ColorSet& colors(AstNodeIf* nodep) const {
|
||||
IfColorMap::const_iterator it = m_ifColors.find(nodep);
|
||||
if (it == m_ifColors.end()) nodep->v3fatalSrc("Unknown node in split color() map");
|
||||
UASSERT_OBJ(it != m_ifColors.end(), nodep, "Unknown node in split color() map");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
|
@ -758,7 +757,7 @@ protected:
|
|||
// for such an embedded if.
|
||||
|
||||
// Each leaf must have a user3p
|
||||
if (!nodep->user3p()) nodep->v3fatalSrc("null user3p in V3Split leaf");
|
||||
UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf");
|
||||
|
||||
// Clone the leaf into its new always block
|
||||
SplitLogicVertex* vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ public:
|
|||
if (!m_varp->isWide()
|
||||
&& !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) {
|
||||
AstNodeAssign* assp = m_whole.m_assignp;
|
||||
if (!assp) errp->v3fatalSrc("Reading whole that was never assigned");
|
||||
UASSERT_OBJ(assp, errp, "Reading whole that was never assigned");
|
||||
return (assp->rhsp());
|
||||
} else {
|
||||
return NULL;
|
||||
|
|
@ -145,7 +145,7 @@ public:
|
|||
AstNode* substWord(AstNode* errp, int word) { // Return what to substitute given word number for
|
||||
if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) {
|
||||
AstNodeAssign* assp = getWordAssignp(word);
|
||||
if (!assp) errp->v3fatalSrc("Reading a word that was never assigned, or bad word #");
|
||||
UASSERT_OBJ(assp, errp, "Reading a word that was never assigned, or bad word #");
|
||||
return (assp->rhsp());
|
||||
} else {
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -310,16 +310,15 @@ private:
|
|||
shift += invscp->width();
|
||||
// We're just using32 bit arithmetic, because there's no
|
||||
// way the input table can be 2^32 bytes!
|
||||
if (shift>31) nodep->v3fatalSrc("shift overflow");
|
||||
UASSERT_OBJ(shift <= 32, nodep, "shift overflow");
|
||||
UINFO(8," Input "<<invscp->name()<<" = "<<*(simvis.fetchNumber(invscp))<<endl);
|
||||
}
|
||||
|
||||
// Simulate
|
||||
simvis.mainTableEmulate(nodep);
|
||||
if (VL_UNCOVERABLE(!simvis.optimizable())) {
|
||||
simvis.whyNotNodep()->v3fatalSrc("Optimizable cleared, even though earlier test run said not: "
|
||||
<<simvis.whyNotMessage());
|
||||
}
|
||||
UASSERT_OBJ(simvis.optimizable(), simvis.whyNotNodep(),
|
||||
"Optimizable cleared, even though earlier test run said not: "
|
||||
<<simvis.whyNotMessage());
|
||||
|
||||
// If a output changed, add it to table
|
||||
int outnum = 0;
|
||||
|
|
@ -348,9 +347,9 @@ private:
|
|||
}
|
||||
|
||||
{ // Set changed table
|
||||
if (VL_UNCOVERABLE(inValue != inValueNextInitArray++)) {
|
||||
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
|
||||
}
|
||||
UASSERT_OBJ(inValue == inValueNextInitArray, nodep,
|
||||
"InitArray requires us to have the values in inValue order");
|
||||
inValueNextInitArray++;
|
||||
AstNode* setp = new AstConst(nodep->fileline(), outputChgMask);
|
||||
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,12 +120,12 @@ public:
|
|||
// METHODS
|
||||
AstScope* getScope(AstNodeFTask* nodep) {
|
||||
AstScope* scopep = VN_CAST(nodep->user3p(), Scope);
|
||||
if (!scopep) nodep->v3fatalSrc("No scope for function");
|
||||
UASSERT_OBJ(scopep, nodep, "No scope for function");
|
||||
return scopep;
|
||||
}
|
||||
AstVarScope* findVarScope(AstScope* scopep, AstVar* nodep) {
|
||||
VarToScopeMap::iterator iter = m_varToScopeMap.find(make_pair(scopep, nodep));
|
||||
if (iter == m_varToScopeMap.end()) nodep->v3fatalSrc("No scope for var");
|
||||
UASSERT_OBJ(iter != m_varToScopeMap.end(), nodep, "No scope for var");
|
||||
return iter->second;
|
||||
}
|
||||
bool ftaskNoInline(AstNodeFTask* nodep) {
|
||||
|
|
@ -199,7 +199,7 @@ private:
|
|||
pushDeletep(m_assignwp); m_assignwp = NULL;
|
||||
}
|
||||
// We make multiple edges if a task is called multiple times from another task.
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked task");
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked task");
|
||||
new TaskEdge(&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp()));
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
|
|
@ -269,7 +269,7 @@ private:
|
|||
if (nodep->varp()->user2p()) { // It's being converted to an alias.
|
||||
UINFO(9, " relinkVar "<<cvtToHex(nodep->varp()->user2p())<<" "<<nodep<<endl);
|
||||
AstVarScope* newvscp = VN_CAST(nodep->varp()->user2p(), VarScope);
|
||||
if (!newvscp) nodep->v3fatalSrc("not linked");
|
||||
UASSERT_OBJ(newvscp, nodep, "not linked");
|
||||
nodep->varScopep(newvscp);
|
||||
nodep->varp(nodep->varScopep()->varp());
|
||||
nodep->name(nodep->varp()->name());
|
||||
|
|
@ -362,7 +362,7 @@ private:
|
|||
AstNode* createInlinedFTask(AstNodeFTaskRef* refp,
|
||||
const string& namePrefix, AstVarScope* outvscp) {
|
||||
// outvscp is the variable for functions only, if NULL, it's a task
|
||||
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
|
||||
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
|
||||
AstNode* newbodysp = AstNode::cloneTreeNull(refp->taskp()->stmtsp(), true); // Maybe NULL
|
||||
AstNode* beginp = new AstComment(refp->fileline(), string("Function: ")+refp->name());
|
||||
if (newbodysp) beginp->addNext(newbodysp);
|
||||
|
|
@ -397,7 +397,7 @@ private:
|
|||
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) {
|
||||
// Connect to this exact variable
|
||||
AstVarScope* localVscp = varrefp->varScopep();
|
||||
if (!localVscp) varrefp->v3fatalSrc("Null var scope");
|
||||
UASSERT_OBJ(localVscp, varrefp, "Null var scope");
|
||||
portp->user2p(localVscp);
|
||||
pushDeletep(pinp);
|
||||
} else {
|
||||
|
|
@ -442,7 +442,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
if (refp->pinsp()) refp->v3fatalSrc("Pin wasn't removed by above loop");
|
||||
UASSERT_OBJ(!refp->pinsp(), refp, "Pin wasn't removed by above loop");
|
||||
{
|
||||
AstNode* nextstmtp;
|
||||
for (AstNode* stmtp = beginp; stmtp; stmtp=nextstmtp) {
|
||||
|
|
@ -479,9 +479,9 @@ private:
|
|||
AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix,
|
||||
AstVarScope* outvscp) {
|
||||
// outvscp is the variable for functions only, if NULL, it's a task
|
||||
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
|
||||
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
|
||||
AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp());
|
||||
if (!cfuncp) refp->v3fatalSrc("No non-inline task associated with this task call?");
|
||||
UASSERT_OBJ(cfuncp, refp, "No non-inline task associated with this task call?");
|
||||
//
|
||||
AstNode* beginp = new AstComment(refp->fileline(), string("Function: ")+refp->name());
|
||||
AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL);
|
||||
|
|
@ -543,7 +543,7 @@ private:
|
|||
if (refp->taskp()->dpiContext()) {
|
||||
// __Vscopep
|
||||
AstNode* snp = refp->scopeNamep()->unlinkFrBack();
|
||||
if (!snp) refp->v3fatalSrc("Missing scoping context");
|
||||
UASSERT_OBJ(snp, refp, "Missing scoping context");
|
||||
ccallp->addArgsp(snp);
|
||||
// __Vfilenamep
|
||||
ccallp->addArgsp(new AstCMath(refp->fileline(),
|
||||
|
|
@ -967,7 +967,7 @@ private:
|
|||
AstVar* rtnvarp = NULL;
|
||||
if (nodep->isFunction()) {
|
||||
AstVar* portp = VN_CAST(nodep->fvarp(), Var);
|
||||
if (!portp) nodep->v3fatalSrc("function without function output variable");
|
||||
UASSERT_OBJ(portp, nodep, "function without function output variable");
|
||||
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
|
||||
if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)");
|
||||
if (ftaskNoInline || nodep->dpiExport()) portp->funcReturn(false); // Converting return to 'outputs'
|
||||
|
|
@ -986,7 +986,8 @@ private:
|
|||
|
||||
if (nodep->dpiImport()) {
|
||||
if (nodep->dpiOpenChild()) { // The parent will make the dpi proto
|
||||
if (nodep->dpiOpenParent()) nodep->v3fatalSrc("DPI task should be parent or wrapper, not both");
|
||||
UASSERT_OBJ(!nodep->dpiOpenParent(), nodep,
|
||||
"DPI task should be parent or wrapper, not both");
|
||||
}
|
||||
else { // Parent or not open child, make wrapper
|
||||
string dpiproto = dpiprotoName(nodep, rtnvarp);
|
||||
|
|
@ -1066,7 +1067,8 @@ private:
|
|||
}
|
||||
|
||||
if (nodep->dpiExport()) {
|
||||
AstScopeName* snp = nodep->scopeNamep(); if (!snp) nodep->v3fatalSrc("Missing scoping context");
|
||||
AstScopeName* snp = nodep->scopeNamep();
|
||||
UASSERT_OBJ(snp, nodep, "Missing scoping context");
|
||||
snp->dpiExport(true); // The AstScopeName is really a statement(ish) for tracking, not a function
|
||||
snp->unlinkFrBack();
|
||||
cfuncp->addInitsp(snp);
|
||||
|
|
@ -1138,7 +1140,7 @@ private:
|
|||
// Return node that must be visited, if any
|
||||
// See also AstNode::addBeforeStmt; this predates that function
|
||||
if (debug()>=9) { nodep->dumpTree(cout, "-newstmt:"); }
|
||||
if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement");
|
||||
UASSERT_OBJ(m_insStmtp, nodep, "Function not underneath a statement");
|
||||
AstNode* visitp = NULL;
|
||||
if (m_insMode == IM_BEFORE) {
|
||||
// Add the whole thing before insertAt
|
||||
|
|
@ -1153,7 +1155,7 @@ private:
|
|||
else if (m_insMode == IM_WHILE_PRECOND) {
|
||||
UINFO(5," IM_While_Precond "<<m_insStmtp<<endl);
|
||||
AstWhile* whilep = VN_CAST(m_insStmtp, While);
|
||||
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
|
||||
UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE");
|
||||
whilep->addPrecondsp(newp);
|
||||
visitp = newp;
|
||||
}
|
||||
|
|
@ -1184,11 +1186,11 @@ private:
|
|||
m_scopep = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) {
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?");
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked?");
|
||||
iterateIntoFTask(nodep->taskp()); // First, do hierarchical funcs
|
||||
UINFO(4," FTask REF "<<nodep<<endl);
|
||||
if (debug()>=9) { nodep->dumpTree(cout, "-inlfunc:"); }
|
||||
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
|
||||
UASSERT_OBJ(m_scopep, nodep, "func ref not under scope");
|
||||
string namePrefix = ((VN_IS(nodep, FuncRef) ? "__Vfunc_":"__Vtask_")
|
||||
+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++));
|
||||
// Create output variable
|
||||
|
|
@ -1209,7 +1211,7 @@ private:
|
|||
// Replace the ref
|
||||
AstNode* visitp = NULL;
|
||||
if (VN_IS(nodep, FuncRef)) {
|
||||
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
||||
UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function");
|
||||
AstVarRef* outrefp = new AstVarRef(nodep->fileline(), outvscp, false);
|
||||
nodep->replaceWith(outrefp);
|
||||
// Insert new statements
|
||||
|
|
@ -1349,7 +1351,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
typedef std::map<string,int> NameToIndex;
|
||||
NameToIndex nameToIndex;
|
||||
V3TaskConnects tconnects;
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("unlinked");
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "unlinked");
|
||||
|
||||
// Find ports
|
||||
int tpinnum = 0;
|
||||
|
|
@ -1374,7 +1376,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
bool reorganize = false;
|
||||
for (AstNode* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
|
||||
nextp = pinp->nextp();
|
||||
AstArg* argp = VN_CAST(pinp, Arg); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
|
||||
AstArg* argp = VN_CAST(pinp, Arg);
|
||||
UASSERT_OBJ(argp, pinp, "Non-arg under ftask reference");
|
||||
if (argp->name() != "") {
|
||||
// By name
|
||||
NameToIndex::iterator it = nameToIndex.find(argp->name());
|
||||
|
|
@ -1460,7 +1463,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
while (nodep->pinsp()) nodep->pinsp()->unlinkFrBack(); // Must unlink each pin, not all pins linked together as one list
|
||||
for (int i=0; i<tpinnum; ++i) {
|
||||
AstArg* argp = tconnects[i].second;
|
||||
if (!argp) nodep->v3fatalSrc("Lost argument in func conversion");
|
||||
UASSERT_OBJ(argp, nodep, "Lost argument in func conversion");
|
||||
nodep->addPinsp(argp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ public:
|
|||
virtual FileLine* fileline() const { return nodep()->fileline(); }
|
||||
TraceTraceVertex* duplicatep() const { return m_duplicatep; }
|
||||
void duplicatep(TraceTraceVertex* dupp) {
|
||||
if (duplicatep()) nodep()->v3fatalSrc("Assigning duplicatep() to already duplicated node");
|
||||
UASSERT_OBJ(!duplicatep(), nodep(),
|
||||
"Assigning duplicatep() to already duplicated node");
|
||||
m_duplicatep = dupp;
|
||||
}
|
||||
};
|
||||
|
|
@ -205,10 +206,9 @@ private:
|
|||
if (TraceTraceVertex* vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) {
|
||||
AstTraceInc* nodep = vvertexp->nodep();
|
||||
if (nodep->valuep()) {
|
||||
if (nodep->valuep()->backp() != nodep) {
|
||||
nodep->v3fatalSrc("Trace duplicate back needs consistency,"
|
||||
" so we can map duplicates back to TRACEINCs");
|
||||
}
|
||||
UASSERT_OBJ(nodep->valuep()->backp() == nodep, nodep,
|
||||
"Trace duplicate back needs consistency,"
|
||||
" so we can map duplicates back to TRACEINCs");
|
||||
hashed.hash(nodep->valuep());
|
||||
UINFO(8, " Hashed "<<std::hex<<hashed.nodeHash(nodep->valuep())
|
||||
<<" "<<nodep<<endl);
|
||||
|
|
@ -229,7 +229,7 @@ private:
|
|||
if (dupit != hashed.end()) {
|
||||
AstTraceInc* dupincp
|
||||
= VN_CAST(hashed.iteratorNodep(dupit)->backp(), TraceInc);
|
||||
if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type");
|
||||
UASSERT_OBJ(dupincp, nodep, "Trace duplicate of wrong type");
|
||||
TraceTraceVertex* dupvertexp
|
||||
= dynamic_cast<TraceTraceVertex*>(dupincp->user1u().toGraphVertex());
|
||||
UINFO(8," Orig "<<nodep<<endl);
|
||||
|
|
@ -275,7 +275,8 @@ private:
|
|||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
|
||||
TraceActivityVertex* actVtxp
|
||||
= dynamic_cast<TraceActivityVertex*>(edgep->fromp());
|
||||
if (!actVtxp) vvertexp->nodep()->v3fatalSrc("Tracing a node with FROM non activity");
|
||||
UASSERT_OBJ(actVtxp, vvertexp->nodep(),
|
||||
"Tracing a node with FROM non activity");
|
||||
if (actVtxp->activityAlways()) {
|
||||
alwaysEdgep = edgep;
|
||||
break;
|
||||
|
|
@ -438,7 +439,8 @@ private:
|
|||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
|
||||
TraceActivityVertex* cfvertexp
|
||||
= dynamic_cast<TraceActivityVertex*>(edgep->fromp());
|
||||
if (!cfvertexp) vvertexp->nodep()->v3fatalSrc("Should have been function pointing to this trace");
|
||||
UASSERT_OBJ(cfvertexp, vvertexp->nodep(),
|
||||
"Should have been function pointing to this trace");
|
||||
UINFO(9," Activity: "<<cfvertexp<<endl);
|
||||
if (cfvertexp->activityAlways()) {
|
||||
// If code 0, we always trace; ignore other codes
|
||||
|
|
@ -550,7 +552,8 @@ private:
|
|||
dupvertexp = dupvertexp->duplicatep();
|
||||
UINFO(9," dupOf "<<cvtToHex(dupvertexp)<<" "<<cvtToHex(dupvertexp->nodep())
|
||||
<<" "<<dupvertexp<<endl);
|
||||
if (dupvertexp->duplicatep()) dupvertexp->nodep()->v3fatalSrc("Original node was marked as a duplicate");
|
||||
UASSERT_OBJ(!dupvertexp->duplicatep(), dupvertexp->nodep(),
|
||||
"Original node was marked as a duplicate");
|
||||
}
|
||||
|
||||
if (dupvertexp != vvertexp) {
|
||||
|
|
@ -644,7 +647,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level");
|
||||
UASSERT_OBJ(scopep, nodep, "No scope found on top level");
|
||||
m_highScopep = scopep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -692,21 +695,21 @@ private:
|
|||
}
|
||||
virtual void visit(AstTraceInc* nodep) {
|
||||
UINFO(8," TRACE "<<nodep<<endl);
|
||||
if (m_finding) nodep->v3fatalSrc("Traces should have been removed in prev step.");
|
||||
UASSERT_OBJ(!m_finding, nodep, "Traces should have been removed in prev step.");
|
||||
nodep->unlinkFrBack();
|
||||
|
||||
V3GraphVertex* vertexp = new TraceTraceVertex(&m_graph, nodep);
|
||||
nodep->user1p(vertexp);
|
||||
|
||||
if (!m_funcp || (!m_chgFuncp || !m_fullFuncp)) nodep->v3fatalSrc("Trace not under func");
|
||||
UASSERT_OBJ(m_funcp && m_chgFuncp && m_fullFuncp, nodep, "Trace not under func");
|
||||
m_tracep = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_tracep = NULL;
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (m_tracep) {
|
||||
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
|
||||
if (nodep->lvalue()) nodep->v3fatalSrc("Lvalue in trace? Should be const.");
|
||||
UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?");
|
||||
UASSERT_OBJ(!nodep->lvalue(), nodep, "Lvalue in trace? Should be const.");
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
|
||||
if (!varVtxp) {
|
||||
varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep());
|
||||
|
|
@ -720,7 +723,7 @@ private:
|
|||
}
|
||||
}
|
||||
else if (m_funcp && m_finding && nodep->lvalue()) {
|
||||
if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?");
|
||||
UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?");
|
||||
V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp);
|
||||
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
|
||||
if (varVtxp) { // else we're not tracing this signal
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ private:
|
|||
// it uses spaces to separate hierarchy components.
|
||||
m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name());
|
||||
if (m_traShowname.substr(0, 4) == "TOP ") m_traShowname.replace(0, 4, "");
|
||||
if (!m_initSubFuncp) nodep->v3fatalSrc("NULL");
|
||||
UASSERT_OBJ(m_initSubFuncp, nodep, "NULL");
|
||||
|
||||
m_traVscp = nodep;
|
||||
m_traValuep = NULL;
|
||||
|
|
|
|||
|
|
@ -300,12 +300,12 @@ class TristatePinVisitor : public TristateBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstArraySel* nodep) {
|
||||
// Doesn't work because we'd set lvalue on the array index's var
|
||||
if (m_lvalue) nodep->v3fatalSrc("ArraySel conversion to output, under tristate node");
|
||||
UASSERT_OBJ(!m_lvalue, nodep, "ArraySel conversion to output, under tristate node");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstSliceSel* nodep) {
|
||||
// Doesn't work because we'd set lvalue on the array index's var
|
||||
if (m_lvalue) nodep->v3fatalSrc("SliceSel conversion to output, under tristate node");
|
||||
UASSERT_OBJ(!m_lvalue, nodep, "SliceSel conversion to output, under tristate node");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
|
|
@ -1155,7 +1155,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
AstVar* outModVarp = static_cast<AstVar*>(nodep->modVarp()->user4p());
|
||||
if (!outModVarp) {
|
||||
// At top, no need for __out as might be input only. Otherwise resolvable.
|
||||
if (!m_modp->isTop()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(m_modp->isTop(), nodep, "Unlinked");
|
||||
} else {
|
||||
AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set
|
||||
outpinp = new AstPin(nodep->fileline(),
|
||||
|
|
@ -1305,7 +1305,8 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
UINFO(8, nodep<<endl);
|
||||
if (m_graphing) nodep->v3fatalSrc("Modules under modules not supported"); // Lots of per-module state breaks
|
||||
UASSERT_OBJ(!m_graphing, nodep,
|
||||
"Modules under modules not supported"); // Lots of per-module state breaks
|
||||
// Clear state
|
||||
m_tgraph.clear();
|
||||
m_unique = 0;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ private:
|
|||
// Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b,
|
||||
// Saves us teaching V3Const how to optimize, and it won't be needed again.
|
||||
if (AstIf* ifp = VN_CAST(prep->user2p(), If)) {
|
||||
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
|
||||
UASSERT_OBJ(!needDly, prep, "Should have already converted to non-delay");
|
||||
AstNRelinker replaceHandle;
|
||||
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
||||
AstNode* newp = new AstLogAnd(condp->fileline(),
|
||||
|
|
@ -285,7 +285,7 @@ private:
|
|||
} else {
|
||||
// Make a Vxrand variable
|
||||
// We use the special XTEMP type so it doesn't break pure functions
|
||||
if (!m_modp) nodep->v3fatalSrc("X number not under module");
|
||||
UASSERT_OBJ(m_modp, nodep, "X number not under module");
|
||||
string newvarname = (string("__Vxrand")
|
||||
+cvtToStr(m_modp->varNumGetInc()));
|
||||
AstVar* newvarp
|
||||
|
|
@ -391,7 +391,7 @@ private:
|
|||
// Find range of dtype we are selecting from
|
||||
int declElements = -1;
|
||||
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
|
||||
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
|
||||
UASSERT_OBJ(dtypep, nodep, "Select of non-selectable type");
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
declElements = adtypep->elementsConst();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -107,16 +107,17 @@ private:
|
|||
// Initial value check
|
||||
AstAssign* initAssp = VN_CAST(initp, Assign);
|
||||
if (!initAssp) return cantUnroll(nodep, "no initial assignment");
|
||||
if (initp->nextp() && initp->nextp()!=nodep) nodep->v3fatalSrc("initial assignment shouldn't be a list");
|
||||
UASSERT_OBJ(!(initp->nextp() && initp->nextp()!=nodep), nodep,
|
||||
"initial assignment shouldn't be a list");
|
||||
if (!VN_IS(initAssp->lhsp(), VarRef)) return cantUnroll(nodep, "no initial assignment to simple variable");
|
||||
//
|
||||
// Condition check
|
||||
if (condp->nextp()) nodep->v3fatalSrc("conditional shouldn't be a list");
|
||||
UASSERT_OBJ(!condp->nextp(), nodep, "conditional shouldn't be a list");
|
||||
//
|
||||
// Assignment of next value check
|
||||
AstAssign* incAssp = VN_CAST(incp, Assign);
|
||||
if (!incAssp) return cantUnroll(nodep, "no increment assignment");
|
||||
if (incAssp->nextp()) nodep->v3fatalSrc("increment shouldn't be a list");
|
||||
UASSERT_OBJ(!incAssp->nextp(), nodep, "increment shouldn't be a list");
|
||||
|
||||
m_forVarp = VN_CAST(initAssp->lhsp(), VarRef)->varp();
|
||||
m_forVscp = VN_CAST(initAssp->lhsp(), VarRef)->varScopep();
|
||||
|
|
@ -190,10 +191,7 @@ private:
|
|||
bool simulateTree(AstNode *nodep, const V3Number *loopValue,
|
||||
AstNode *dtypep, V3Number &outNum) {
|
||||
AstNode* clonep = nodep->cloneTree(true);
|
||||
if (!clonep) {
|
||||
nodep->v3fatalSrc("Failed to clone tree");
|
||||
return false;
|
||||
}
|
||||
UASSERT_OBJ(clonep, nodep, "Failed to clone tree");
|
||||
if (loopValue) {
|
||||
m_varValuep = new AstConst(nodep->fileline(), *loopValue);
|
||||
// Iteration requires a back, so put under temporary node
|
||||
|
|
|
|||
122
src/V3Width.cpp
122
src/V3Width.cpp
|
|
@ -561,7 +561,7 @@ private:
|
|||
// LSB is self-determined (IEEE 2012 11.5.1)
|
||||
// We also use SELs to shorten a signed constant etc, in this case they are signed.
|
||||
if (nodep->didWidth()) return;
|
||||
if (!m_vup) nodep->v3fatalSrc("Select under an unexpected context");
|
||||
UASSERT_OBJ(m_vup, nodep, "Select under an unexpected context");
|
||||
if (m_vup->prelim()) {
|
||||
if (debug()>=9) nodep->dumpTree(cout, "-selWidth: ");
|
||||
userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
|
|
@ -576,7 +576,7 @@ private:
|
|||
nodep->dtypeSetLogicBool(); return;
|
||||
}
|
||||
int width = nodep->widthConst();
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel
|
||||
if (VN_IS(nodep->lsbp(), Const)
|
||||
&& nodep->msbConst() < nodep->lsbConst()) {
|
||||
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
|
||||
|
|
@ -952,7 +952,8 @@ private:
|
|||
break;
|
||||
case AstAttrType::DIM_DIMENSIONS:
|
||||
case AstAttrType::DIM_UNPK_DIMENSIONS: {
|
||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
|
||||
"Unsized expression");
|
||||
std::pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->dimensions(true);
|
||||
int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS
|
||||
? dim.second : (dim.first+dim.second));
|
||||
|
|
@ -967,7 +968,8 @@ private:
|
|||
case AstAttrType::DIM_LOW:
|
||||
case AstAttrType::DIM_RIGHT:
|
||||
case AstAttrType::DIM_SIZE: {
|
||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
|
||||
"Unsized expression");
|
||||
std::pair<uint32_t,uint32_t> dim
|
||||
= nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
|
||||
uint32_t msbdim = dim.first+dim.second;
|
||||
|
|
@ -977,7 +979,8 @@ private:
|
|||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
else { // Need a runtime lookup table. Yuk.
|
||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
|
||||
"Unsized expression");
|
||||
AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim);
|
||||
AstNode* dimp = nodep->dimp()->unlinkFrBack();
|
||||
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
|
||||
|
|
@ -1083,7 +1086,7 @@ private:
|
|||
if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep()));
|
||||
// Effectively nodep->dtypeFrom(nodep->dtypeSkipRefp());
|
||||
// But might be recursive, so instead manually recurse into the referenced type
|
||||
if (!nodep->defp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->defp(), nodep, "Unlinked");
|
||||
nodep->dtypeFrom(nodep->defp());
|
||||
userIterate(nodep->defp(), NULL);
|
||||
nodep->widthFromSub(nodep->subDTypep());
|
||||
|
|
@ -1129,7 +1132,7 @@ private:
|
|||
// The cast may change signing, but we don't know the sign yet. Make it so.
|
||||
// Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting.
|
||||
AstBasicDType* basicp = nodep->dtypep()->basicp();
|
||||
if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type");
|
||||
UASSERT_OBJ(basicp, nodep, "Unimplemented: Casting non-simple data type");
|
||||
// When implement more complicated types need to convert childDTypep to
|
||||
// dtypep() not as a child
|
||||
if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) {
|
||||
|
|
@ -1162,7 +1165,8 @@ private:
|
|||
virtual void visit(AstCastSize* nodep) {
|
||||
// IEEE: Signedness of result is same as self-determined signedness
|
||||
// However, the result is same as BITSEL, so we do not sign extend the LHS
|
||||
if (!VN_IS(nodep->rhsp(), Const)) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
|
||||
UASSERT_OBJ(VN_IS(nodep->rhsp(), Const), nodep,
|
||||
"Unsupported: Non-const cast of size");
|
||||
//if (debug()) nodep->dumpTree(cout, " CastSizePre: ");
|
||||
if (m_vup->prelim()) {
|
||||
int width = VN_CAST(nodep->rhsp(), Const)->toSInt();
|
||||
|
|
@ -1215,7 +1219,7 @@ private:
|
|||
// with non-constant range gets size 1, not size 0. So use didWidth().
|
||||
if (nodep->didWidth()) return;
|
||||
if (nodep->doingWidth()) { // Early exit if have circular parameter definition
|
||||
if (!nodep->valuep()) nodep->v3fatalSrc("circular, but without value");
|
||||
UASSERT_OBJ(nodep->valuep(), nodep, "circular, but without value");
|
||||
nodep->v3error("Variable's initial value is circular: "<<nodep->prettyName());
|
||||
pushDeletep(nodep->valuep()->unlinkFrBack());
|
||||
nodep->valuep(new AstConst(nodep->fileline(), AstConst::LogicTrue()));
|
||||
|
|
@ -1227,7 +1231,7 @@ private:
|
|||
// Make sure dtype is sized
|
||||
if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep));
|
||||
nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep()));
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var");
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "No dtype determined for var");
|
||||
if (VN_IS(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
|
||||
if (!(m_ftaskp && m_ftaskp->dpiImport())) {
|
||||
nodep->v3error("Unsized/open arrays ('[]') are only supported in DPI imports");
|
||||
|
|
@ -1328,7 +1332,7 @@ private:
|
|||
// Note genvar's are also entered as integers
|
||||
nodep->dtypeFrom(nodep->varp());
|
||||
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
|
||||
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
|
||||
UASSERT_OBJ(nodep->widthMin(), nodep, "LHS var should be size complete");
|
||||
}
|
||||
//if (debug()>=9) nodep->dumpTree(cout, " VRout ");
|
||||
if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) {
|
||||
|
|
@ -1397,7 +1401,7 @@ private:
|
|||
virtual void visit(AstEnumItem* nodep) {
|
||||
UINFO(5," ENUMITEM "<<nodep<<endl);
|
||||
AstNodeDType* vdtypep = m_vup->dtypep();
|
||||
if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM");
|
||||
UASSERT_OBJ(vdtypep, nodep, "ENUMITEM not under ENUM");
|
||||
nodep->dtypep(vdtypep);
|
||||
if (nodep->valuep()) { // else the value will be assigned sequentially
|
||||
// Default type is int, but common to assign narrower values, so minwidth from value
|
||||
|
|
@ -1411,11 +1415,11 @@ private:
|
|||
if (!nodep->itemp()->didWidth()) {
|
||||
// We need to do the whole enum en-mass
|
||||
AstNode* enump = nodep->itemp();
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef not linked");
|
||||
UASSERT_OBJ(enump, nodep, "EnumItemRef not linked");
|
||||
for (; enump; enump=enump->backp()) {
|
||||
if (VN_IS(enump, EnumDType)) break;
|
||||
}
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum");
|
||||
UASSERT_OBJ(enump, nodep, "EnumItemRef can't deref back to an Enum");
|
||||
userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked
|
||||
}
|
||||
nodep->dtypeFrom(nodep->itemp());
|
||||
|
|
@ -1424,7 +1428,7 @@ private:
|
|||
// InitArray has type of the array; children are array values
|
||||
if (m_vup->prelim()) { // First stage evaluation
|
||||
AstNodeDType* vdtypep = m_vup->dtypep();
|
||||
if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor");
|
||||
UASSERT_OBJ(vdtypep, nodep, "InitArray type not assigned by AstPattern/Var visitor");
|
||||
nodep->dtypep(vdtypep);
|
||||
if (AstNodeArrayDType* arrayp = VN_CAST(vdtypep->skipRefp(), NodeArrayDType)) {
|
||||
userIterateChildren(nodep, WidthVP(arrayp->subDTypep(), BOTH).p());
|
||||
|
|
@ -1602,7 +1606,8 @@ private:
|
|||
if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF, BOTH).p());
|
||||
}
|
||||
// Find the fromp dtype - should be a class
|
||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
UASSERT_OBJ(nodep->fromp() && nodep->fromp()->dtypep(), nodep,
|
||||
"Unsized expression");
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL;
|
||||
UINFO(9," from dt "<<fromDtp<<endl);
|
||||
|
|
@ -1632,7 +1637,7 @@ private:
|
|||
nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
|
||||
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
|
||||
}
|
||||
if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const");
|
||||
UASSERT_OBJ(newp, nodep, "Enum method (perhaps enum item) not const");
|
||||
newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables
|
||||
nodep->replaceWith(newp);
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
@ -1665,7 +1670,7 @@ private:
|
|||
for (AstEnumItem* itemp = adtypep->itemsp();
|
||||
itemp; itemp = VN_CAST(itemp->nextp(), EnumItem)) {
|
||||
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
|
||||
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
|
||||
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
|
||||
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
|
||||
}
|
||||
if (adtypep->itemsp()->width() > 64 || msbdim >= (1<<16)) {
|
||||
|
|
@ -2053,10 +2058,11 @@ private:
|
|||
}
|
||||
virtual void visit(AstPatMember* nodep) {
|
||||
AstNodeDType* vdtypep = m_vup->dtypeNullp();
|
||||
if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor");
|
||||
UASSERT_OBJ(vdtypep, nodep, "Pattern member type not assigned by AstPattern visitor");
|
||||
nodep->dtypep(vdtypep);
|
||||
UINFO(9," PATMEMBER "<<nodep<<endl);
|
||||
if (nodep->lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed");
|
||||
UASSERT_OBJ(!nodep->lhssp()->nextp(), nodep,
|
||||
"PatMember value should be singular w/replicates removed");
|
||||
// Need to propagate assignment type downwards, even on prelim
|
||||
userIterateChildren(nodep, WidthVP(nodep->dtypep(), PRELIM).p());
|
||||
iterateCheck(nodep, "Pattern value", nodep->lhssp(), ASSIGN, FINAL, vdtypep, EXTEND_LHS);
|
||||
|
|
@ -2174,8 +2180,9 @@ private:
|
|||
{
|
||||
//if (debug()) nodep->dumpTree(cout, "- assin: ");
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p());
|
||||
if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?");
|
||||
if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?");
|
||||
UASSERT_OBJ(nodep->lhsp()->dtypep(), nodep, "How can LHS be untyped?");
|
||||
UASSERT_OBJ(nodep->lhsp()->dtypep()->widthSized(), nodep,
|
||||
"How can LHS be unsized?");
|
||||
nodep->dtypeFrom(nodep->lhsp());
|
||||
//
|
||||
// AstPattern needs to know the proposed data type of the lhs, so pass on the prelim
|
||||
|
|
@ -2559,7 +2566,7 @@ private:
|
|||
userIterateChildren(nodep, NULL);
|
||||
if (nodep->fvarp()) {
|
||||
m_funcp = VN_CAST(nodep, Func);
|
||||
if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function");
|
||||
UASSERT_OBJ(m_funcp, nodep, "FTask with function variable, but isn't a function");
|
||||
nodep->dtypeFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep()
|
||||
}
|
||||
nodep->didWidth(true);
|
||||
|
|
@ -2599,7 +2606,7 @@ private:
|
|||
// For arguments, is assignment-like context; see IEEE rules in AstNodeAssign
|
||||
// Function hasn't been widthed, so make it so.
|
||||
UINFO(5, " FTASKREF "<<nodep<<endl);
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked");
|
||||
if (nodep->didWidth()) return;
|
||||
userIterate(nodep->taskp(), NULL);
|
||||
//
|
||||
|
|
@ -2737,8 +2744,8 @@ private:
|
|||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
if (m_vup) nodep->v3fatalSrc("Visit function missing? Widthed expectation for this node: "
|
||||
<<nodep);
|
||||
UASSERT_OBJ(!m_vup, nodep,
|
||||
"Visit function missing? Widthed expectation for this node: "<<nodep);
|
||||
userIterateChildren(nodep, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -2799,7 +2806,7 @@ private:
|
|||
// LHS is self-determined
|
||||
// Width: 1 bit out
|
||||
// Sign: unsigned out (11.8.1)
|
||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
iterateCheckBool(nodep, "LHS", nodep->op1p(), BOTH);
|
||||
nodep->dtypeSetLogicBool();
|
||||
|
|
@ -2854,7 +2861,7 @@ private:
|
|||
// TODO: chandle/class handle/iface handle: WildEq/WildNeq same as Eq/Neq
|
||||
// TODO: chandle/class handle/iface handle only allowed to self-compare or against null
|
||||
// TODO: chandle/class handle/iface handle no relational compares
|
||||
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
|
||||
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
userIterateAndNext(nodep->rhsp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
|
|
@ -2895,7 +2902,7 @@ private:
|
|||
// Real if and only if real_allow set
|
||||
// IEEE, 11.4.4: relational compares (<,>,<=,>=,==,===,!=,!==) use
|
||||
// "zero padding" on unsigned
|
||||
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
|
||||
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
// See similar handling in visit_cmp_eq_gt where created
|
||||
iterateCheckReal(nodep, "LHS", nodep->lhsp(), BOTH);
|
||||
|
|
@ -2908,7 +2915,7 @@ private:
|
|||
// Widths: 1 bit out, lhs width == rhs width
|
||||
// String compare (not output)
|
||||
// Real if and only if real_allow set
|
||||
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
|
||||
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
// See similar handling in visit_cmp_eq_gt where created
|
||||
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
|
||||
|
|
@ -2919,7 +2926,7 @@ private:
|
|||
void visit_Os32_string(AstNodeUniop* nodep) {
|
||||
// CALLER: LenN
|
||||
// Widths: 32 bit out
|
||||
if (!nodep->lhsp()) nodep->v3fatalSrc("For unary ops only!");
|
||||
UASSERT_OBJ(nodep->lhsp(), nodep, "For unary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
// See similar handling in visit_cmp_eq_gt where created
|
||||
iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH);
|
||||
|
|
@ -2933,7 +2940,7 @@ private:
|
|||
// Signed: From lhs
|
||||
// IEEE-2012 Table 11-21:
|
||||
// Widths: out width = lhs width
|
||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(CONTEXT, PRELIM).p());
|
||||
if (!real_ok) checkCvtUS(nodep->lhsp());
|
||||
|
|
@ -2968,7 +2975,7 @@ private:
|
|||
// Width: Returns packed array, of size $bits(expression).
|
||||
// Sign: Output sign is as specified by operation
|
||||
// TODO: Type: Two-state if input is two-state, else four-state
|
||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||
UASSERT_OBJ(!nodep->op2p(), nodep, "For unary ops only!");
|
||||
if (m_vup->prelim()) {
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||
checkCvtUS(nodep->lhsp());
|
||||
|
|
@ -3039,7 +3046,7 @@ private:
|
|||
// Signed: if lhs & rhs signed
|
||||
// IEEE-2012 Table 11-21:
|
||||
// Width: max(LHS, RHS)
|
||||
if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
|
||||
UASSERT_OBJ(nodep->rhsp(), nodep, "For binary ops only!");
|
||||
// If errors are off, we need to follow the spec; thus we really need to do the max()
|
||||
// because the rhs could be larger, and we need to have proper editing to get the widths
|
||||
// to be the same for our operations.
|
||||
|
|
@ -3152,12 +3159,15 @@ private:
|
|||
bool widthBad(AstNode* nodep, AstNodeDType* expDTypep) {
|
||||
int expWidth = expDTypep->width();
|
||||
int expWidthMin = expDTypep->widthMin();
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
|
||||
<<" has no dtype?? Missing Visitor func?");
|
||||
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
|
||||
<<" has no expected width?? Missing Visitor func?");
|
||||
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()
|
||||
<<" has no expected width?? Missing Visitor func?");
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep,
|
||||
"Under node "<<nodep->prettyTypeName()
|
||||
<<" has no dtype?? Missing Visitor func?");
|
||||
UASSERT_OBJ(nodep->width() != 0, nodep,
|
||||
"Under node "<<nodep->prettyTypeName()
|
||||
<<" has no expected width?? Missing Visitor func?");
|
||||
UASSERT_OBJ(expWidth != 0, nodep,
|
||||
"Node "<<nodep->prettyTypeName()
|
||||
<<" has no expected width?? Missing Visitor func?");
|
||||
if (expWidthMin==0) expWidthMin = expWidth;
|
||||
if (nodep->dtypep()->width() == expWidth) return false;
|
||||
if (nodep->dtypep()->widthSized() && nodep->width() != expWidthMin) return true;
|
||||
|
|
@ -3296,7 +3306,7 @@ private:
|
|||
return node1p->skipRefp()->similarDType(node2p->skipRefp());
|
||||
}
|
||||
void iterateCheckFileDesc(AstNode* nodep, AstNode* underp, Stage stage) {
|
||||
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
|
||||
UASSERT_OBJ(stage == BOTH, nodep, "Bad call");
|
||||
// underp may change as a result of replacement
|
||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
|
||||
AstNodeDType* expDTypep = underp->findUInt32DType();
|
||||
|
|
@ -3346,8 +3356,8 @@ private:
|
|||
// Coerce child to any sized-number data type; child is self-determined
|
||||
// i.e. isolated from expected type.
|
||||
// e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs)
|
||||
if (determ != SELF) nodep->v3fatalSrc("Bad call");
|
||||
if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call");
|
||||
UASSERT_OBJ(determ == SELF, nodep, "Bad call");
|
||||
UASSERT_OBJ(stage == FINAL || stage == BOTH, nodep, "Bad call");
|
||||
// underp may change as a result of replacement
|
||||
if (stage & PRELIM) underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, PRELIM).p());
|
||||
underp = checkCvtUS(underp);
|
||||
|
|
@ -3359,7 +3369,7 @@ private:
|
|||
AstNode* rhsp, Stage stage, AstNodeDType* lhsDTypep) {
|
||||
// Check using assignment-like context rules
|
||||
//if (debug()) nodep->dumpTree(cout, "-checkass: ");
|
||||
if (stage != FINAL) nodep->v3fatalSrc("Bad width call");
|
||||
UASSERT_OBJ(stage == FINAL, nodep, "Bad width call");
|
||||
// We iterate and size the RHS based on the result of RHS evaluation
|
||||
bool lhsStream = (VN_IS(nodep, NodeAssign)
|
||||
&& VN_IS(VN_CAST(nodep, NodeAssign)->lhsp(), NodeStream));
|
||||
|
|
@ -3370,14 +3380,16 @@ private:
|
|||
}
|
||||
|
||||
void iterateCheckBool(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
||||
if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once
|
||||
UASSERT_OBJ(stage == BOTH, nodep,
|
||||
"Bad call"); // Booleans always self-determined so do BOTH at once
|
||||
// Underp is used in a self-determined but boolean context, reduce a
|
||||
// multibit number to one bit
|
||||
// stage is always BOTH so not passed as argument
|
||||
// underp may change as a result of replacement
|
||||
if (!underp) nodep->v3fatalSrc("Node has no type");
|
||||
UASSERT_OBJ(underp, nodep, "Node has no type");
|
||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, BOTH).p());
|
||||
if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
UASSERT_OBJ(underp && underp->dtypep(), nodep,
|
||||
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
//
|
||||
// For DOUBLE under a logical op, add implied test against zero, never a warning
|
||||
if (underp && underp->isDouble()) {
|
||||
|
|
@ -3417,8 +3429,9 @@ private:
|
|||
// Perform data type check on underp, which is underneath nodep used for error reporting
|
||||
// Returns the new underp
|
||||
// Conversion to/from doubles and integers are before iterating.
|
||||
if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck");
|
||||
if (!underp || !underp->dtypep()) nodep->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
UASSERT_OBJ(stage == FINAL, nodep, "Bad state to iterateCheck");
|
||||
UASSERT_OBJ(underp && underp->dtypep(), nodep,
|
||||
"Node has no type"); // Perhaps forgot to do a prelim visit on it?
|
||||
if (expDTypep == underp->dtypep()) { // Perfect
|
||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p());
|
||||
} else if (expDTypep->isDouble() && underp->isDouble()) { // Also good
|
||||
|
|
@ -3757,7 +3770,7 @@ private:
|
|||
// DTypes at parse time get added as a childDType to some node types such as AstVars.
|
||||
// We move them to global scope, so removing/changing a variable won't lose the dtype.
|
||||
AstNodeDType* dtnodep = nodep->getChildDTypep();
|
||||
if (!dtnodep) nodep->v3fatalSrc("Caller should check for NULL before calling moveChild");
|
||||
UASSERT_OBJ(dtnodep, nodep, "Caller should check for NULL before calling moveChild");
|
||||
UINFO(9,"moveChildDTypeEdit "<<dtnodep<<endl);
|
||||
dtnodep->unlinkFrBack(); // Make non-child
|
||||
v3Global.rootp()->typeTablep()->addTypesp(dtnodep);
|
||||
|
|
@ -3773,7 +3786,7 @@ private:
|
|||
// Alternative is to have WidthVP return information.
|
||||
// or have a call outside of normal visitor land.
|
||||
// or have a m_return type (but need to return if width called multiple times)
|
||||
if (!nodep) parentp->v3fatalSrc("Null dtype when widthing dtype");
|
||||
UASSERT_OBJ(nodep, parentp, "Null dtype when widthing dtype");
|
||||
userIterate(nodep, NULL);
|
||||
return nodep;
|
||||
}
|
||||
|
|
@ -3924,7 +3937,7 @@ private:
|
|||
}
|
||||
|
||||
// Find valid values and populate
|
||||
if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items");
|
||||
UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items");
|
||||
std::vector<AstNode*> values;
|
||||
values.resize(msbdim+1);
|
||||
for (unsigned i=0; i<(msbdim+1); ++i) {
|
||||
|
|
@ -3937,7 +3950,7 @@ private:
|
|||
for (AstEnumItem* itemp = firstp; itemp;) {
|
||||
AstEnumItem* nextp = VN_CAST(itemp->nextp(), EnumItem);
|
||||
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
|
||||
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
|
||||
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
|
||||
uint32_t i = vconstp->toUInt();
|
||||
if (attrType == AstAttrType::ENUM_NAME) {
|
||||
values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name());
|
||||
|
|
@ -3989,7 +4002,8 @@ private:
|
|||
UINFO(4,"Replicate openarray function "<<nodep->taskp()<<endl);
|
||||
AstNodeFTask* oldTaskp = nodep->taskp();
|
||||
oldTaskp->dpiOpenParentInc();
|
||||
if (oldTaskp->dpiOpenChild()) oldTaskp->v3fatalSrc("DPI task should be parent or child, not both");
|
||||
UASSERT_OBJ(!oldTaskp->dpiOpenChild(), oldTaskp,
|
||||
"DPI task should be parent or child, not both");
|
||||
AstNodeFTask* newTaskp = oldTaskp->cloneTree(false);
|
||||
newTaskp->dpiOpenChild(true);
|
||||
newTaskp->dpiOpenParentClear();
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ private:
|
|||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstConst* nodep) {
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype");
|
||||
UASSERT_OBJ(nodep->dtypep(), nodep, "No dtype");
|
||||
iterate(nodep->dtypep()); // Do datatype first
|
||||
if (AstConst* newp = newIfConstCommitSize(nodep)) {
|
||||
nodep->replaceWith(newp);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ private:
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (!basefromp || !basefromp->dtypep()) nodep->v3fatalSrc("Select with no from dtype");
|
||||
UASSERT_OBJ(basefromp && basefromp->dtypep(), nodep, "Select with no from dtype");
|
||||
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
|
||||
AstNode* errp = ddtypep;
|
||||
UINFO(9," fromData.ddtypep = "<<ddtypep<<endl);
|
||||
|
|
@ -96,10 +96,10 @@ private:
|
|||
}
|
||||
else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
|
||||
if (adtypep->isRanged()) {
|
||||
if (adtypep->rangep()
|
||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const)))
|
||||
nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||
UASSERT_OBJ(!(adtypep->rangep()
|
||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const))),
|
||||
nodep, "Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||
fromRange = adtypep->declRange();
|
||||
} else {
|
||||
nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is "
|
||||
|
|
@ -227,11 +227,10 @@ private:
|
|||
subp = newSubNeg(subp, fromRange.lo());
|
||||
}
|
||||
}
|
||||
if (VL_UNCOVERABLE(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0)) {
|
||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
}
|
||||
UASSERT_OBJ(!(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
|
||||
"Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
int elwidth = adtypep->width() / fromRange.elements();
|
||||
AstSel* newp
|
||||
= new AstSel(nodep->fileline(),
|
||||
|
|
@ -318,11 +317,10 @@ private:
|
|||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELEXTRACT(array, msb, lsb) -> SEL(array,
|
||||
// lsb*width-of-subindex, width-of-subindex*(msb-lsb))
|
||||
if (VL_UNCOVERABLE(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0)) {
|
||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
}
|
||||
UASSERT_OBJ(!(!fromRange.elements()
|
||||
|| (adtypep->width() % fromRange.elements())!=0), adtypep,
|
||||
"Array extraction with width miscomputed "
|
||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||
if (fromRange.littleEndian()) {
|
||||
// Below code assumes big bit endian; just works out if we swap
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
|
|
@ -344,7 +342,7 @@ private:
|
|||
newp->declElWidth(elwidth);
|
||||
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
|
||||
//if (debug()>=9) newp->dumpTree(cout, "--EXTBTn: ");
|
||||
if (newp->widthMin() != newp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
UASSERT_OBJ(newp->widthMin() == newp->widthConst(), nodep, "Width mismatch");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (VN_IS(ddtypep, BasicDType)) {
|
||||
|
|
|
|||
|
|
@ -1945,7 +1945,7 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
|
|||
yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null
|
||||
{ // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar
|
||||
AstBegin* lowerBegp = VN_CAST($9, Begin);
|
||||
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
|
||||
UASSERT_OBJ(!($9 && !lowerBegp), $9, "Child of GENFOR should have been begin");
|
||||
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
|
||||
AstNode* lowerNoBegp = lowerBegp->stmtsp();
|
||||
if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext();
|
||||
|
|
|
|||
Loading…
Reference in New Issue