Fix internals to make null-pointer-check clean. Also add more const's. No functional change intended, but likely something will break.
This commit is contained in:
parent
94e8cf1de9
commit
597d28b505
4
Changes
4
Changes
|
|
@ -4,6 +4,10 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||
|
||||
* Verilator 4.000 devel
|
||||
|
||||
** This is a major release. Any patches may require major rework to apply.
|
||||
|
||||
** Fix internals to make null-pointer-check clean.
|
||||
|
||||
**** Fix internals to avoid 'using namespace std'.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,6 @@ AC_SUBST(CFG_CXXFLAGS_WEXTRA)
|
|||
# Flags for compiling Verilator internals including parser always
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
|
||||
|
|
|
|||
|
|
@ -312,8 +312,8 @@ private:
|
|||
// Move always to appropriate ACTIVE based on its sense list
|
||||
if (oldsensesp
|
||||
&& oldsensesp->sensesp()
|
||||
&& oldsensesp->sensesp()->castSenItem()
|
||||
&& oldsensesp->sensesp()->castSenItem()->isNever()) {
|
||||
&& 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.");
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ private:
|
|||
AstSenTree* sensesp = nodep->sensesp();
|
||||
if (!sensesp) nodep->v3fatalSrc("NULL");
|
||||
if (sensesp->sensesp()
|
||||
&& sensesp->sensesp()->castSenItem()
|
||||
&& sensesp->sensesp()->castSenItem()->isNever()) {
|
||||
&& VN_IS(sensesp->sensesp(), SenItem)
|
||||
&& VN_CAST(sensesp->sensesp(), SenItem)->isNever()) {
|
||||
// Never executing. Kill it.
|
||||
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
|
|||
|
|
@ -105,12 +105,12 @@ private:
|
|||
//
|
||||
AstNode* bodysp = NULL;
|
||||
bool selfDestruct = false;
|
||||
if (AstPslCover* snodep = nodep->castPslCover()) {
|
||||
if (AstPslCover* snodep = VN_CAST(nodep, PslCover)) {
|
||||
if (!v3Global.opt.coverageUser()) {
|
||||
selfDestruct = true;
|
||||
} else {
|
||||
// V3Coverage assigned us a bucket to increment.
|
||||
AstCoverInc* covincp = snodep->coverincp()->castCoverInc();
|
||||
AstCoverInc* covincp = VN_CAST(snodep->coverincp(), CoverInc);
|
||||
if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion");
|
||||
covincp->unlinkFrBack();
|
||||
if (message!="") covincp->declp()->comment(message);
|
||||
|
|
@ -122,7 +122,7 @@ private:
|
|||
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
|
||||
bodysp = ifp;
|
||||
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
//
|
||||
AstNode* newp = new AstAlways (nodep->fileline(),
|
||||
VAlwaysKwd::ALWAYS,
|
||||
|
|
@ -146,7 +146,7 @@ private:
|
|||
AstNode* passsp = nodep->passsp(); if (passsp) passsp->unlinkFrBackWithNext();
|
||||
AstNode* failsp = nodep->failsp(); if (failsp) failsp->unlinkFrBackWithNext();
|
||||
//
|
||||
if (nodep->castVAssert()) {
|
||||
if (VN_IS(nodep, VAssert)) {
|
||||
if (passsp) passsp = newIfAssertOn(passsp);
|
||||
if (failsp) failsp = newIfAssertOn(failsp);
|
||||
} else {
|
||||
|
|
@ -155,7 +155,7 @@ private:
|
|||
|
||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp);
|
||||
AstNode* newp = ifp;
|
||||
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
//
|
||||
// Install it
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -227,7 +227,7 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
bool has_default=false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (itemp->isDefault()) has_default=true;
|
||||
}
|
||||
if (nodep->fullPragma() || nodep->priorityPragma()) {
|
||||
|
|
@ -246,7 +246,7 @@ private:
|
|||
// Not parallel, but harmlessly so.
|
||||
} else {
|
||||
AstNode* propp = NULL;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
AstNode* onep;
|
||||
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {
|
||||
|
|
|
|||
|
|
@ -828,7 +828,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
|
|||
// To solve this, this function returns the pointer to the replacement node,
|
||||
// which in many cases is just the same node that was passed in.
|
||||
AstNode* nodep = this; // Note "this" may point to bogus point later in this function
|
||||
if (nodep->castNetlist()) {
|
||||
if (VN_IS(nodep, Netlist)) {
|
||||
// Calling on top level; we know the netlist won't get replaced
|
||||
nodep->accept(v);
|
||||
} else if (!nodep->backp()) {
|
||||
|
|
@ -875,7 +875,7 @@ void AstNode::cloneRelinkTree() {
|
|||
//======================================================================
|
||||
// Comparison
|
||||
|
||||
bool AstNode::gateTreeIter() {
|
||||
bool AstNode::gateTreeIter() const {
|
||||
// private: Return true if the two trees are identical
|
||||
if (!isGateOptimizable()) return false;
|
||||
if (m_op1p && !m_op1p->gateTreeIter()) return false;
|
||||
|
|
@ -885,7 +885,7 @@ bool AstNode::gateTreeIter() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly) {
|
||||
bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ignNext, bool gateOnly) const {
|
||||
// private: Return true if the two trees are identical
|
||||
if (!node1p && !node2p) return true;
|
||||
if (!node1p || !node2p) return false;
|
||||
|
|
@ -927,7 +927,7 @@ void AstNode::checkTreeIter(AstNode* backp) {
|
|||
if (backp != this->backp()) {
|
||||
this->v3fatalSrc("Back node inconsistent");
|
||||
}
|
||||
if (castNodeTermop() || castNodeVarRef()) {
|
||||
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");
|
||||
|
|
@ -1055,7 +1055,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
|
|||
checkTree();
|
||||
// Broken isn't part of check tree because it can munge iterp's
|
||||
// set by other steps if it is called in the middle of other operations
|
||||
if (AstNetlist* netp=this->castNetlist()) V3Broken::brokenAll(netp);
|
||||
if (AstNetlist* netp=VN_CAST(this, Netlist)) V3Broken::brokenAll(netp);
|
||||
}
|
||||
// Next dump can indicate start from here
|
||||
editCountSetLast();
|
||||
|
|
|
|||
69
src/V3Ast.h
69
src/V3Ast.h
|
|
@ -44,6 +44,15 @@ class VFlagChildDType {}; // Used by parser.y to select constructor that sets c
|
|||
|
||||
//######################################################################
|
||||
|
||||
// (V)erilator (N)ode (is)): True if AstNode is of a a given AstType
|
||||
#define VN_IS(nodep,nodetypename) (AstNode::privateIs ## nodetypename(nodep))
|
||||
|
||||
// (V)erilator (N)ode (cast): Cast to given type if can; effectively dynamic_cast(nodep)(nodetypename)
|
||||
#define VN_CAST(nodep,nodetypename) (AstNode::privateCast ## nodetypename(nodep))
|
||||
#define VN_CAST_CONST(nodep,nodetypename) (AstNode::privateConstCast ## nodetypename(nodep) )
|
||||
|
||||
//######################################################################
|
||||
|
||||
class AstType {
|
||||
public:
|
||||
#include "V3Ast__gen_types.h" // From ./astgen
|
||||
|
|
@ -1048,8 +1057,8 @@ private:
|
|||
AstNode* cloneTreeIterList();
|
||||
void checkTreeIter(AstNode* backp);
|
||||
void checkTreeIterList(AstNode* backp);
|
||||
bool gateTreeIter();
|
||||
bool sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly);
|
||||
bool gateTreeIter() const;
|
||||
bool sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ignNext, bool gateOnly) const;
|
||||
void deleteTreeIter();
|
||||
void deleteNode();
|
||||
public:
|
||||
|
|
@ -1240,11 +1249,11 @@ public:
|
|||
|
||||
// ACCESSORS for specific types
|
||||
// Alas these can't be virtual or they break when passed a NULL
|
||||
bool isZero();
|
||||
bool isOne();
|
||||
bool isNeqZero();
|
||||
bool isAllOnes();
|
||||
bool isAllOnesV(); // Verilog width rules apply
|
||||
bool isZero() const;
|
||||
bool isOne() const;
|
||||
bool isNeqZero() const;
|
||||
bool isAllOnes() const;
|
||||
bool isAllOnesV() const; // Verilog width rules apply
|
||||
|
||||
// METHODS - data type changes especially for initial creation
|
||||
void dtypep(AstNodeDType* nodep) { if (m_dtypep != nodep) { m_dtypep = nodep; editCountInc(); } }
|
||||
|
|
@ -1303,8 +1312,8 @@ public:
|
|||
// METHODS - Iterate on a tree
|
||||
AstNode* cloneTree(bool cloneNextLink);
|
||||
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
|
||||
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
|
||||
bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable
|
||||
bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
|
||||
bool sameGateTree(const AstNode* node2p) const; // Does tree of this == node2p?, not allowing non-isGateOptimizable
|
||||
void deleteTree(); // Always deletes the next link
|
||||
void checkTree(); // User Interface version
|
||||
void checkIter() const;
|
||||
|
|
@ -1376,7 +1385,7 @@ public:
|
|||
virtual bool cleanOut() = 0; // True if output has extra upper bits zero
|
||||
// Someday we will generically support data types on every math node
|
||||
// Until then isOpaque indicates we shouldn't constant optimize this node type
|
||||
bool isOpaque() { return castCvtPackString()!=NULL; }
|
||||
bool isOpaque() { return VN_IS(this, CvtPackString); }
|
||||
};
|
||||
|
||||
class AstNodeTermop : public AstNodeMath {
|
||||
|
|
@ -1516,7 +1525,7 @@ public:
|
|||
AstNode* fromp() const { return lhsp(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
AstAttrOf* attrp() const { return op4p()->castAttrOf(); }
|
||||
AstAttrOf* attrp() const { return VN_CAST(op4p(), AttrOf); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
void thsp(AstNode* nodep) { return setOp3p(nodep); }
|
||||
|
|
@ -1611,7 +1620,7 @@ public:
|
|||
ASTNODE_BASE_FUNCS(NodeCase)
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = case condition <expression>
|
||||
AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions
|
||||
AstCaseItem* itemsp() const { return VN_CAST(op2p(), CaseItem); } // op2 = list of case expressions
|
||||
AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's
|
||||
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
|
|
@ -1774,8 +1783,9 @@ public:
|
|||
virtual void dump(std::ostream& str);
|
||||
// For basicp() we reuse the size to indicate a "fake" basic type of same size
|
||||
virtual AstBasicDType* basicp() const {
|
||||
return (isFourstate() ? findLogicDType(width(),width(),numeric())->castBasicDType()
|
||||
: findBitDType(width(),width(),numeric())->castBasicDType()); }
|
||||
return (isFourstate()
|
||||
? VN_CAST(findLogicDType(width(),width(),numeric()), BasicDType)
|
||||
: VN_CAST(findBitDType(width(),width(),numeric()), BasicDType)); }
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
|
||||
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
|
||||
|
|
@ -1785,7 +1795,7 @@ public:
|
|||
virtual bool similarDType(AstNodeDType* samep) const {
|
||||
return this==samep; // We don't compare members, require exact equivalence
|
||||
}
|
||||
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
|
||||
AstMemberDType* membersp() const { return VN_CAST(op1p(), MemberDType); } // op1 = AstMember list
|
||||
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool packed() const { return m_packed; }
|
||||
bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs
|
||||
|
|
@ -1836,13 +1846,13 @@ public:
|
|||
}
|
||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
|
||||
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||
AstRange* rangep() const { return VN_CAST(op2p(), Range); } // op2 = Array(s) of variable
|
||||
void rangep(AstRange* nodep);
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
|
|
@ -1927,7 +1937,7 @@ public:
|
|||
AstNode* stmtsp() const { return op3p(); } // op3 = List of statements
|
||||
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
||||
// op4 = scope name
|
||||
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
|
||||
AstScopeName* scopeNamep() const { return VN_CAST(op4p(), ScopeName); }
|
||||
// MORE ACCESSORS
|
||||
void dpiOpenParentInc() { ++m_dpiOpenParent; }
|
||||
void dpiOpenParentClear() { m_dpiOpenParent=0; }
|
||||
|
|
@ -1996,7 +2006,7 @@ public:
|
|||
AstNode* pinsp() const { return op2p(); }
|
||||
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// op3 = scope tracking
|
||||
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||
AstScopeName* scopeNamep() const { return VN_CAST(op3p(), ScopeName); }
|
||||
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
|
||||
};
|
||||
|
||||
|
|
@ -2029,7 +2039,7 @@ public:
|
|||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual string name() const { return m_name; }
|
||||
AstNode* stmtsp() const { return op2p(); } // op2 = List of statements
|
||||
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
||||
AstActive* activesp() const { return VN_CAST(op3p(), Active); } // op3 = List of i/sblocks
|
||||
// METHODS
|
||||
void addInlinesp(AstNode* nodep) { addOp1p(nodep); }
|
||||
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
|
||||
|
|
@ -2071,7 +2081,8 @@ public:
|
|||
|
||||
#include "V3Ast__gen_impl.h" // From ./astgen
|
||||
// Things like:
|
||||
// inline AstAlways* AstNode::castAlways() { return dynamic_cast<AstAlways*>(this);}
|
||||
// inline AstAlways* AstNode::castAlways() { return dynamic_cast<AstAlways*>(this);}
|
||||
// inline bool AstNode::privateIsaAlways(const AstNode* nodep) { return nodep && nodep->type() == AstType::atAlways; }
|
||||
|
||||
//######################################################################
|
||||
// Inline ACCESSORS
|
||||
|
|
@ -2080,17 +2091,17 @@ inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0;
|
|||
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
|
||||
inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize
|
||||
inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
|
||||
inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); }
|
||||
inline bool AstNode::isDouble() const { return dtypep() && VN_IS(dtypep(), BasicDType) && VN_CAST(dtypep(), BasicDType)->isDouble(); }
|
||||
inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
|
||||
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
|
||||
|
||||
inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); }
|
||||
inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); }
|
||||
inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); }
|
||||
inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); }
|
||||
inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); }
|
||||
inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, false); }
|
||||
inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(this, node2p, true, true); }
|
||||
inline bool AstNode::isZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isEqZero()); }
|
||||
inline bool AstNode::isNeqZero() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isNeqZero()); }
|
||||
inline bool AstNode::isOne() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->num().isEqOne()); }
|
||||
inline bool AstNode::isAllOnes() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->isEqAllOnes()); }
|
||||
inline bool AstNode::isAllOnesV() const { return (VN_IS(this, Const) && VN_CAST_CONST(this, Const)->isEqAllOnesV()); }
|
||||
inline bool AstNode::sameTree(const AstNode* node2p) const { return sameTreeIter(this, node2p, true, false); }
|
||||
inline bool AstNode::sameGateTree(const AstNode* node2p) const { return sameTreeIter(this, node2p, true, true); }
|
||||
|
||||
inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); }
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const char* AstIfaceRefDType::broken() const {
|
|||
}
|
||||
|
||||
AstIface* AstIfaceRefDType::ifaceViaCellp() const {
|
||||
return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
|
||||
return ((m_cellp && m_cellp->modp()) ? VN_CAST(m_cellp->modp(), Iface) : m_ifacep);
|
||||
}
|
||||
|
||||
const char* AstNodeVarRef::broken() const {
|
||||
|
|
@ -58,12 +58,13 @@ void AstNodeVarRef::cloneRelink() {
|
|||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
|
||||
AstConst* constp=VN_CAST(bitp(), Const);
|
||||
return (constp ? constp->toSInt() : 0);
|
||||
}
|
||||
|
||||
void AstNodeClassDType::repairMemberCache() {
|
||||
clearCache();
|
||||
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* itemp = membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
|
||||
if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
|
||||
else m_members.insert(make_pair(itemp->name(), itemp));
|
||||
}
|
||||
|
|
@ -71,7 +72,7 @@ void AstNodeClassDType::repairMemberCache() {
|
|||
|
||||
const char* AstNodeClassDType::broken() const {
|
||||
vl_unordered_set<AstMemberDType*> exists;
|
||||
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* itemp = membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
|
||||
exists.insert(itemp);
|
||||
}
|
||||
for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
|
||||
|
|
@ -243,7 +244,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
|
|||
arg += " (& "+name()+")";
|
||||
for (AstNodeDType* dtp=dtypep(); dtp; ) {
|
||||
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstUnpackArrayDType* adtypep = dtp->castUnpackArrayDType()) {
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtp, UnpackArrayDType)) {
|
||||
arg += "["+cvtToStr(adtypep->declRange().elements())+"]";
|
||||
dtp = adtypep->subDTypep();
|
||||
} else break;
|
||||
|
|
@ -315,7 +316,7 @@ string AstVar::vlPropInit() const {
|
|||
bool first = true;
|
||||
for (AstNodeDType* dtp=dtypep(); dtp; ) {
|
||||
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtp->castNodeArrayDType()) {
|
||||
if (AstNodeArrayDType* adtypep = VN_CAST(dtp, NodeArrayDType)) {
|
||||
if (first) {
|
||||
out += ", VerilatedVarProps::Unpacked()";
|
||||
first = false;
|
||||
|
|
@ -422,15 +423,15 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
|
|||
// See if this is a SC assignment; if so return that type
|
||||
// Historically sc variables are identified by a variable
|
||||
// attribute. TODO it would better be a data type attribute.
|
||||
if (AstVar* anodep = nodep->castVar()) {
|
||||
if (AstVar* anodep = VN_CAST(nodep, Var)) {
|
||||
if (anodep->isSc()) return anodep;
|
||||
else return NULL;
|
||||
}
|
||||
else if (nodep->castVarRef()) {
|
||||
if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
|
||||
else if (VN_IS(nodep, VarRef)) {
|
||||
if (VN_CAST(nodep, VarRef)->varp()->isSc()) return VN_CAST(nodep, VarRef)->varp();
|
||||
else return NULL;
|
||||
}
|
||||
else if (nodep->castArraySel()) {
|
||||
else if (VN_IS(nodep, ArraySel)) {
|
||||
if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
|
||||
if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
|
||||
if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
|
||||
|
|
@ -457,14 +458,14 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
|||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
if ((dim++)==dimension) {
|
||||
return dtypep;
|
||||
}
|
||||
dtypep = adtypep->subDTypep();
|
||||
continue;
|
||||
}
|
||||
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
// AstBasicDType - nothing below, return null
|
||||
if (adtypep->isRanged()) {
|
||||
if ((dim++) == dimension) {
|
||||
|
|
@ -473,7 +474,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
|
||||
else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
|
||||
if (adtypep->packed()) {
|
||||
if ((dim++) == dimension) {
|
||||
return adtypep;
|
||||
|
|
@ -492,7 +493,7 @@ uint32_t AstNodeDType::arrayUnpackedElements() {
|
|||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
entries *= adtypep->elementsConst();
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
|
|
@ -511,13 +512,13 @@ std::pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
|
|||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
for (AstNodeDType* dtypep=this; dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (adtypep->castPackArrayDType()) packed++;
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
if (VN_IS(adtypep, PackArrayDType)) packed++;
|
||||
else unpacked++;
|
||||
dtypep = adtypep->subDTypep();
|
||||
continue;
|
||||
}
|
||||
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
else if (const AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (includeBasic && adtypep->isRanged()) packed++;
|
||||
}
|
||||
break;
|
||||
|
|
@ -537,15 +538,15 @@ int AstNodeDType::widthPow2() const {
|
|||
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
|
||||
// Else AstArraySel etc; search for the base
|
||||
while (nodep) {
|
||||
if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; }
|
||||
else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; }
|
||||
if (VN_IS(nodep, ArraySel)) { nodep=VN_CAST(nodep, ArraySel)->fromp(); continue; }
|
||||
else if (VN_IS(nodep, Sel)) { nodep=VN_CAST(nodep, Sel)->fromp(); continue; }
|
||||
// AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
|
||||
else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; }
|
||||
else if (nodep->castNodePreSel()) {
|
||||
if (nodep->castNodePreSel()->attrp()) {
|
||||
nodep=nodep->castNodePreSel()->attrp();
|
||||
else if (VN_IS(nodep, AttrOf)) { nodep=VN_CAST(nodep, AttrOf)->fromp(); continue; }
|
||||
else if (VN_IS(nodep, NodePreSel)) {
|
||||
if (VN_CAST(nodep, NodePreSel)->attrp()) {
|
||||
nodep=VN_CAST(nodep, NodePreSel)->attrp();
|
||||
} else {
|
||||
nodep=nodep->castNodePreSel()->lhsp();
|
||||
nodep=VN_CAST(nodep, NodePreSel)->lhsp();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -579,7 +580,7 @@ string AstScope::nameDotless() const {
|
|||
|
||||
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=VN_CAST(textp->nextp(), Text)) {
|
||||
out += textp->text();
|
||||
}
|
||||
// TOP will be replaced by top->name()
|
||||
|
|
@ -591,7 +592,7 @@ string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
|
|||
|
||||
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
||||
string out;
|
||||
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
|
||||
for (AstText* textp=scopeTextp; textp; textp=VN_CAST(textp->nextp(), Text)) {
|
||||
out += textp->text();
|
||||
}
|
||||
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
|
||||
|
|
@ -609,28 +610,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
|||
|
||||
bool AstSenTree::hasClocked() const {
|
||||
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
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");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
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");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
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");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (senp->isCombo()) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -651,7 +652,7 @@ void AstTypeTable::clearCache() {
|
|||
m_detailedMap.clear();
|
||||
// Clear generic()'s so dead detection will work
|
||||
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
|
||||
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
|
||||
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
|
||||
bdtypep->generic(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -661,7 +662,7 @@ void AstTypeTable::repairCache() {
|
|||
// After we mass-change widthMin in V3WidthCommit, we need to correct the table.
|
||||
clearCache();
|
||||
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
|
||||
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
|
||||
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
|
||||
(void)findInsertSameDType(bdtypep);
|
||||
}
|
||||
}
|
||||
|
|
@ -812,7 +813,7 @@ void AstNode::dump(std::ostream& str) {
|
|||
if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
|
||||
}
|
||||
if (name()!="") {
|
||||
if (castConst()) str<<" "<<name(); // Already quoted
|
||||
if (VN_IS(this, Const)) str<<" "<<name(); // Already quoted
|
||||
else str<<" "<<V3Number::quoteNameControls(name());
|
||||
}
|
||||
}
|
||||
|
|
@ -934,7 +935,7 @@ void AstNodeDType::dumpSmall(std::ostream& str) {
|
|||
}
|
||||
void AstNodeArrayDType::dumpSmall(std::ostream& str) {
|
||||
this->AstNodeDType::dumpSmall(str);
|
||||
if (castPackArrayDType()) str<<"p"; else str<<"u";
|
||||
if (VN_IS(this, PackArrayDType)) str<<"p"; else str<<"u";
|
||||
str<<declRange();
|
||||
}
|
||||
void AstNodeArrayDType::dump(std::ostream& str) {
|
||||
|
|
|
|||
120
src/V3AstNodes.h
120
src/V3AstNodes.h
|
|
@ -132,11 +132,11 @@ public:
|
|||
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
|
||||
AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
|
||||
AstNode* rightp() const { return littleEndian()?msbp():lsbp(); }
|
||||
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int msbConst() const { AstConst* constp=VN_CAST(msbp(), Const); return (constp?constp->toSInt():0); }
|
||||
int lsbConst() const { AstConst* constp=VN_CAST(lsbp(), Const); return (constp?constp->toSInt():0); }
|
||||
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
|
||||
int leftConst() const { AstConst* constp=leftp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int rightConst() const { AstConst* constp=rightp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int leftConst() const { AstConst* constp=VN_CAST(leftp(), Const); return (constp?constp->toSInt():0); }
|
||||
int rightConst() const { AstConst* constp=VN_CAST(rightp(), Const); return (constp?constp->toSInt():0); }
|
||||
int leftToRightInc() const { return littleEndian()?1:-1; }
|
||||
bool littleEndian() const { return m_littleEndian; }
|
||||
void littleEndian(bool flag) { m_littleEndian=flag; }
|
||||
|
|
@ -168,7 +168,7 @@ public:
|
|||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
AstNode* exprp() const { return op1p(); } // op1 = Pin expression
|
||||
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Range of pin
|
||||
AstRange* rangep() const { return VN_CAST(op2p(), Range); } // op2 = Range of pin
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -188,7 +188,7 @@ public:
|
|||
}
|
||||
ASTNODE_NODE_FUNCS(ParamTypeDType)
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
|
|
@ -196,7 +196,7 @@ public:
|
|||
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
|
||||
virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); }
|
||||
virtual bool similarDType(AstNodeDType* samep) const {
|
||||
AstParamTypeDType* sp = samep->castParamTypeDType();
|
||||
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep);
|
||||
return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
|
||||
}
|
||||
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||
|
|
@ -227,7 +227,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(Typedef)
|
||||
virtual void dump(std::ostream& str);
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
||||
|
|
@ -279,7 +279,7 @@ public:
|
|||
return type()==samep->type() && same(samep); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
void* containerp() const { return m_containerp; }
|
||||
|
|
@ -373,7 +373,7 @@ public:
|
|||
virtual void dumpSmall(std::ostream& str);
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
|
|
@ -466,7 +466,7 @@ public:
|
|||
return type()==samep->type() && same(samep); }
|
||||
virtual string name() const { return m.m_keyword.ascii(); }
|
||||
virtual const char* broken() const { BROKEN_RTN(dtypep()!=this); return NULL; }
|
||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
|
||||
AstRange* rangep() const { return VN_CAST(op1p(), Range); } // op1 = Range of variable
|
||||
void rangep(AstRange* nodep) { setNOp1p(nodep); }
|
||||
void setSignedState(VSignedState signst) {
|
||||
// Note NOSIGN does NOT change the state; this is required by the parser
|
||||
|
|
@ -498,7 +498,7 @@ public:
|
|||
bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; }
|
||||
VNumRange declRange() const { return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange(); }
|
||||
void cvtRangeConst() { // Convert to smaller represenation
|
||||
if (rangep() && rangep()->msbp()->castConst() && rangep()->lsbp()->castConst()) {
|
||||
if (rangep() && VN_IS(rangep()->msbp(), Const) && VN_IS(rangep()->lsbp(), Const)) {
|
||||
m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(),
|
||||
rangep()->littleEndian());
|
||||
rangep()->unlinkFrBackWithNext()->deleteTree();
|
||||
|
|
@ -534,7 +534,7 @@ public:
|
|||
return skipRefp()->similarDType(samep->skipRefp()); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } // node's type() included elsewhere
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
|
|
@ -698,7 +698,7 @@ public:
|
|||
virtual bool hasDType() const { return true; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
|
|
@ -734,7 +734,7 @@ public:
|
|||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool hasDType() const { return true; }
|
||||
void name(const string& flag) { m_name = flag; }
|
||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range for name appending
|
||||
AstRange* rangep() const { return VN_CAST(op1p(), Range); } // op1 = Range for name appending
|
||||
void rangep(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstNode* valuep() const { return op2p(); } // op2 = Value
|
||||
void valuep(AstNode* nodep) { addOp2p(nodep); }
|
||||
|
|
@ -754,7 +754,7 @@ public:
|
|||
virtual string name() const { return itemp()->name(); }
|
||||
virtual const char* broken() const { BROKEN_RTN(!itemp()); return NULL; }
|
||||
virtual int instrCount() const { return 0; }
|
||||
virtual void cloneRelink() { if (m_itemp->clonep()) m_itemp = m_itemp->clonep()->castEnumItem(); }
|
||||
virtual void cloneRelink() { if (m_itemp->clonep()) m_itemp = VN_CAST(m_itemp->clonep(), EnumItem); }
|
||||
virtual bool same(const AstNode* samep) const {
|
||||
const AstEnumItemRef* sp = static_cast<const AstEnumItemRef*>(samep);
|
||||
return itemp() == sp->itemp(); }
|
||||
|
|
@ -794,13 +794,13 @@ public:
|
|||
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Data type
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable
|
||||
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
||||
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
|
||||
AstEnumItem* itemsp() const { return op2p()->castEnumItem(); } // op2 = AstEnumItem's
|
||||
AstEnumItem* itemsp() const { return VN_CAST(op2p(), EnumItem); } // op2 = AstEnumItem's
|
||||
void addValuesp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
|
|
@ -837,9 +837,9 @@ class AstArraySel : public AstNodeSel {
|
|||
// Children: varref|arraysel, math
|
||||
private:
|
||||
void init(AstNode* fromp) {
|
||||
if (fromp && fromp->dtypep()->skipRefp()->castNodeArrayDType()) {
|
||||
if (fromp && VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) {
|
||||
// Strip off array to find what array references
|
||||
dtypeFrom(fromp->dtypep()->skipRefp()->castNodeArrayDType()->subDTypep());
|
||||
dtypeFrom(VN_CAST(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep());
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
|
@ -945,9 +945,9 @@ public:
|
|||
AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp)
|
||||
:AstNodeTriop(fl, fromp, lsbp, widthp) {
|
||||
m_declElWidth = 1;
|
||||
if (widthp->castConst()) {
|
||||
dtypeSetLogicSized(widthp->castConst()->toUInt(),
|
||||
widthp->castConst()->toUInt(),
|
||||
if (VN_IS(widthp, Const)) {
|
||||
dtypeSetLogicSized(VN_CAST(widthp, Const)->toUInt(),
|
||||
VN_CAST(widthp, Const)->toUInt(),
|
||||
AstNumeric::UNSIGNED);
|
||||
}
|
||||
}
|
||||
|
|
@ -973,13 +973,13 @@ public:
|
|||
virtual bool sizeMattersThs() {return false;}
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode*) const { return true; }
|
||||
virtual int instrCount() const { return widthInstrs()*(lsbp()->castConst()?3:10); }
|
||||
virtual int instrCount() const { return widthInstrs()*(VN_CAST(lsbp(), Const)?3:10); }
|
||||
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
AstNode* lsbp() const { return op2p(); } // op2 = Msb selection expression
|
||||
AstNode* widthp() const { return op3p(); } // op3 = Width
|
||||
int widthConst() const { return widthp()->castConst()->toSInt(); }
|
||||
int lsbConst() const { return lsbp()->castConst()->toSInt(); }
|
||||
int msbConst() const { return lsbConst()+widthConst()-1; }
|
||||
int widthConst() const { return VN_CAST(widthp(), Const)->toSInt(); }
|
||||
int lsbConst() const { return VN_CAST(lsbp(), Const)->toSInt(); }
|
||||
int msbConst() const { return lsbConst()+widthConst()-1; }
|
||||
VNumRange& declRange() { return m_declRange; }
|
||||
void declRange(const VNumRange& flag) { m_declRange = flag; }
|
||||
int declElWidth() const { return m_declElWidth; }
|
||||
|
|
@ -1189,7 +1189,7 @@ public:
|
|||
string vlPropInit() const; // Return VerilatorVarProps initializer
|
||||
void combineType(AstVarType type);
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Range of variable
|
||||
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
||||
AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
|
||||
AstNode* valuep() const { return op3p(); } // op3 = Initial value that never changes (static const)
|
||||
|
|
@ -1396,7 +1396,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(TopScope)
|
||||
AstNode* stmtsp() const { return op1p(); }
|
||||
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstScope* scopep() const { return op2p()->castScope(); } // op1 = AstVarScope's
|
||||
AstScope* scopep() const { return VN_CAST(op2p(), Scope); } // op1 = AstVarScope's
|
||||
};
|
||||
|
||||
class AstVarScope : public AstNode {
|
||||
|
|
@ -1753,9 +1753,9 @@ public:
|
|||
void origName(const string& name) { m_origName = name; }
|
||||
string modName() const { return m_modName; } // * = Instance name
|
||||
void modName(const string& name) { m_modName = name; }
|
||||
AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
|
||||
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values
|
||||
AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged)
|
||||
AstPin* pinsp() const { return VN_CAST(op1p(), Pin); } // op1 = List of cell ports
|
||||
AstPin* paramsp() const { return VN_CAST(op2p(), Pin); } // op2 = List of parameter #(##) values
|
||||
AstRange* rangep() const { return VN_CAST(op3p(), Range); } // op3 = Range of arrayed instants (NULL=not ranged)
|
||||
AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated
|
||||
void addPinsp(AstPin* nodep) { addOp1p(nodep); }
|
||||
void addParamsp(AstPin* nodep) { addOp2p(nodep); }
|
||||
|
|
@ -1846,7 +1846,7 @@ public:
|
|||
AstBind(FileLine* fl, const string& name, AstNode* cellsp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
if (!cellsp->castCell()) cellsp->v3fatalSrc("Only cells allowed to be bound");
|
||||
if (!VN_IS(cellsp, Cell)) cellsp->v3fatalSrc("Only cells allowed to be bound");
|
||||
addNOp1p(cellsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Bind)
|
||||
|
|
@ -2061,7 +2061,7 @@ public:
|
|||
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
|
||||
void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge
|
||||
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
|
||||
AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized
|
||||
AstNodeVarRef* varrefp() const { return VN_CAST(op1p(), NodeVarRef); } // op1 = Signal sensitized
|
||||
//
|
||||
virtual bool isClocked() const { return edgeType().clockedStmt(); }
|
||||
virtual bool isCombo() const { return edgeType()==AstEdgeType::ET_COMBO; }
|
||||
|
|
@ -2083,7 +2083,7 @@ public:
|
|||
}
|
||||
ASTNODE_NODE_FUNCS(SenGate)
|
||||
virtual string emitVerilog() { return "(%l) %f&& (%r)"; }
|
||||
AstSenItem* sensesp() const { return op1p()->castSenItem(); }
|
||||
AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
void sensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { setOp2p(nodep); }
|
||||
|
|
@ -2110,7 +2110,7 @@ public:
|
|||
virtual void dump(std::ostream& str);
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
bool isMulti() const { return m_multi; }
|
||||
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
|
||||
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
|
||||
void addSensesp(AstNodeSenItem* nodep) { addOp1p(nodep); }
|
||||
void multi(bool flag) { m_multi = true; }
|
||||
// METHODS
|
||||
|
|
@ -2130,7 +2130,7 @@ public:
|
|||
ASTNODE_NODE_FUNCS(Always)
|
||||
//
|
||||
virtual void dump(std::ostream& str);
|
||||
AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list
|
||||
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
|
||||
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
|
||||
VAlwaysKwd keyword() const { return m_keyword; }
|
||||
|
|
@ -2150,7 +2150,7 @@ public:
|
|||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
//
|
||||
AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list
|
||||
AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
|
||||
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// Special accessors
|
||||
|
|
@ -2404,7 +2404,7 @@ public:
|
|||
virtual bool isPredictOptimizable() const { return true; }
|
||||
virtual bool isOutputter() const { return false; } // Though the AstCoverInc under this is an outputter
|
||||
// but isPure() true
|
||||
AstCoverInc* incp() const { return op1p()->castCoverInc(); }
|
||||
AstCoverInc* incp() const { return VN_CAST(op1p(), CoverInc); }
|
||||
void incp(AstCoverInc* nodep) { setOp1p(nodep); }
|
||||
AstNode* origp() const { return op2p(); }
|
||||
AstNode* changep() const { return op3p(); }
|
||||
|
|
@ -2514,7 +2514,7 @@ public:
|
|||
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
|
||||
string text() const { return m_text; } // * = Text to display
|
||||
void text(const string& text) { m_text=text; }
|
||||
AstScopeName* scopeNamep() const { return op2p()->castScopeName(); }
|
||||
AstScopeName* scopeNamep() const { return VN_CAST(op2p(), ScopeName); }
|
||||
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
|
||||
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
|
||||
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
|
||||
|
|
@ -2560,7 +2560,7 @@ public:
|
|||
void displayType(AstDisplayType type) { m_displayType = type; }
|
||||
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
|
||||
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
||||
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
|
||||
AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); }
|
||||
AstNode* filep() const { return op3p(); }
|
||||
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
|
||||
};
|
||||
|
|
@ -2589,7 +2589,7 @@ public:
|
|||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
||||
AstSFormatF* fmtp() const { return op1p()->castSFormatF(); }
|
||||
AstSFormatF* fmtp() const { return VN_CAST(op1p(), SFormatF); }
|
||||
AstNode* lhsp() const { return op3p(); }
|
||||
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
|
|
@ -3047,7 +3047,7 @@ public:
|
|||
addNOp2p(stablesp); addNOp3p(bodysp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(UntilStable)
|
||||
AstVarRef* stablesp() const { return op2p()->castVarRef(); } // op2= list of variables that must become stable
|
||||
AstVarRef* stablesp() const { return VN_CAST(op2p(), VarRef); } // op2= list of variables that must become stable
|
||||
AstNode* bodysp() const { return op3p(); } // op3= body of loop
|
||||
void addStablesp(AstVarRef* newp) { addOp2p(newp); }
|
||||
void addBodysp(AstNode* newp) { addOp3p(newp); }
|
||||
|
|
@ -3371,7 +3371,7 @@ public:
|
|||
AstSenTree* sensesp() const { return m_sensesp; }
|
||||
// op1 = Sensitivity tree, if a clocked block in early stages
|
||||
void sensesStorep(AstSenTree* nodep) { addOp1p(nodep); }
|
||||
AstSenTree* sensesStorep() const { return op1p()->castSenTree(); }
|
||||
AstSenTree* sensesStorep() const { return VN_CAST(op1p(), SenTree); }
|
||||
// op2 = Combo logic
|
||||
AstNode* stmtsp() const { return op2p(); }
|
||||
void addStmtsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
|
|
@ -3416,10 +3416,10 @@ public:
|
|||
virtual string emitVerilog() { return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
AstText* scopeAttrp() const { return op1p()->castText(); }
|
||||
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstText* scopeEntrp() const { return op2p()->castText(); }
|
||||
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
|
||||
AstText* scopeAttrp() const { return VN_CAST(op1p(), Text); }
|
||||
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
||||
AstText* scopeEntrp() const { return VN_CAST(op2p(), Text); }
|
||||
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
|
||||
string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
|
||||
string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope
|
||||
string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
|
||||
|
|
@ -3435,7 +3435,7 @@ public:
|
|||
addNOp1p(bodysp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(UdpTable)
|
||||
AstUdpTableLine* bodysp() const { return op1p()->castUdpTableLine(); } // op1 = List of UdpTableLines
|
||||
AstUdpTableLine* bodysp() const { return VN_CAST(op1p(), UdpTableLine); } // op1 = List of UdpTableLines
|
||||
};
|
||||
|
||||
class AstUdpTableLine : public AstNode {
|
||||
|
|
@ -3839,7 +3839,7 @@ public:
|
|||
virtual bool sizeMattersLhs() {return false;}
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); }
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op2p(), NodeDType); }
|
||||
};
|
||||
|
||||
class AstCastParse : public AstNode {
|
||||
|
|
@ -4904,7 +4904,7 @@ class AstReplicate : public AstNodeBiop {
|
|||
private:
|
||||
void init() {
|
||||
if (lhsp()) {
|
||||
if (AstConst* constp=rhsp()->castConst()) {
|
||||
if (const AstConst* constp = VN_CAST(rhsp(), Const)) {
|
||||
dtypeSetLogicSized(lhsp()->width()*constp->toUInt(), lhsp()->width()*constp->toUInt(), AstNumeric::UNSIGNED);
|
||||
}
|
||||
}
|
||||
|
|
@ -5020,7 +5020,7 @@ public:
|
|||
virtual bool cleanOut() {V3ERROR_NA; return "";}
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to
|
||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } // op1 = Type assigning to
|
||||
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
|
||||
|
|
@ -5084,7 +5084,7 @@ public:
|
|||
addNOp2p(bodysp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Clocking)
|
||||
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
|
||||
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Body
|
||||
};
|
||||
|
||||
|
|
@ -5104,7 +5104,7 @@ public:
|
|||
}
|
||||
ASTNODE_NODE_FUNCS(PslClocked)
|
||||
virtual bool hasDType() const { return true; } // Used under PslCover, which expects a bool child
|
||||
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
|
||||
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); } // op1 = Sensitivity list
|
||||
AstNode* disablep() const { return op2p(); } // op2 = disable
|
||||
AstNode* propp() const { return op3p(); } // op3 = property
|
||||
};
|
||||
|
|
@ -5128,7 +5128,7 @@ public:
|
|||
virtual bool same(const AstNode* samep) const { return samep->name() == name(); }
|
||||
virtual void name(const string& name) { m_name = name; }
|
||||
AstNode* propp() const { return op1p(); } // op1 = property
|
||||
AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain
|
||||
AstSenTree* sentreep() const { return VN_CAST(op2p(), SenTree); } // op2 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
||||
AstNode* coverincp() const { return op3p(); } // op3 = coverage node
|
||||
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
|
||||
|
|
@ -5477,7 +5477,7 @@ public:
|
|||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(const AstNode* samep) const { return true; }
|
||||
AstVarRef* varrefp() const { return op1p()->castVarRef(); } // op1= varref to reset
|
||||
AstVarRef* varrefp() const { return VN_CAST(op1p(), VarRef); } // op1= varref to reset
|
||||
};
|
||||
|
||||
class AstCStmt : public AstNodeStmt {
|
||||
|
|
@ -5519,7 +5519,7 @@ public:
|
|||
for (int i=0; i<AstBasicDTypeKwd::_ENUM_MAX; ++i) m_basicps[i] = NULL;
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(TypeTable)
|
||||
AstNodeDType* typesp() const { return op1p()->castNodeDType();} // op1 = List of dtypes
|
||||
AstNodeDType* typesp() const { return VN_CAST(op1p(), NodeDType);} // op1 = List of dtypes
|
||||
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
|
||||
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
|
||||
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
|
||||
|
|
@ -5555,10 +5555,10 @@ public:
|
|||
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
|
||||
return NULL;
|
||||
}
|
||||
AstNodeModule* modulesp() const { return op1p()->castNodeModule();} // op1 = List of modules
|
||||
AstNodeModule* topModulep() const { return op1p()->castNodeModule(); } // * = Top module in hierarchy (first one added, for now)
|
||||
AstNodeModule* modulesp() const { return VN_CAST(op1p(), NodeModule); } // op1 = List of modules
|
||||
AstNodeModule* topModulep() const { return VN_CAST(op1p(), NodeModule); } // * = Top module in hierarchy (first one added, for now)
|
||||
void addModulep(AstNodeModule* modulep) { addOp1p(modulep); }
|
||||
AstCFile* filesp() const { return op2p()->castCFile();} // op2 = List of files
|
||||
AstCFile* filesp() const { return VN_CAST(op2p(), CFile);} // op2 = List of files
|
||||
void addFilesp(AstCFile* filep) { addOp2p(filep); }
|
||||
AstNode* miscsp() const { return op3p();} // op3 = List of dtypes etc
|
||||
void addMiscsp(AstNode* nodep) { addOp3p(nodep); }
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public:
|
|||
|
||||
class BrokenCheckVisitor : public AstNVisitor {
|
||||
private:
|
||||
void checkWidthMin(AstNode* nodep) {
|
||||
void checkWidthMin(const AstNode* nodep) {
|
||||
if (nodep->width() != nodep->widthMin()
|
||||
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
|
||||
nodep->v3fatalSrc("Width != WidthMin");
|
||||
|
|
@ -225,7 +225,7 @@ private:
|
|||
}
|
||||
if (nodep->dtypep()) {
|
||||
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
|
||||
else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
|
||||
else if (!VN_IS(nodep->dtypep(), NodeDType)) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
|
||||
}
|
||||
if (v3Global.assertDTypesResolved()) {
|
||||
if (nodep->hasDType()) {
|
||||
|
|
@ -234,7 +234,7 @@ private:
|
|||
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
|
||||
}
|
||||
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
|
||||
if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep);
|
||||
if (const AstNodeDType* dnodep = VN_CAST(nodep, NodeDType)) checkWidthMin(dnodep);
|
||||
}
|
||||
checkWidthMin(nodep);
|
||||
nodep->iterateChildrenConst(*this);
|
||||
|
|
@ -244,8 +244,8 @@ private:
|
|||
processAndIterate(nodep);
|
||||
if (v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& nodep->lhsp()->castNodeVarRef()
|
||||
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_CAST(nodep->lhsp(), NodeVarRef)->lvalue()) {
|
||||
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ void V3CCtors::evalAsserts() {
|
|||
funcp->ifdef("VL_DEBUG");
|
||||
modp->addStmtp(funcp);
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstVar* varp = np->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(np, Var)) {
|
||||
if (varp->isPrimaryIn() && !varp->isSc()) {
|
||||
if (AstBasicDType* basicp = varp->dtypeSkipRefp()->castBasicDType()) {
|
||||
if (AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
|
||||
int storedWidth = basicp->widthAlignBytes() * 8;
|
||||
int lastWordWidth = varp->width() % storedWidth;
|
||||
if (lastWordWidth != 0) {
|
||||
|
|
@ -143,12 +143,12 @@ void V3CCtors::evalAsserts() {
|
|||
void V3CCtors::cctorsAll() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
evalAsserts();
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
|
||||
// Process each module in turn
|
||||
{
|
||||
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstVar* varp = np->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(np, Var)) {
|
||||
if (!varp->isIfaceParent() && !varp->isIfaceRef()) {
|
||||
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ void V3CCtors::cctorsAll() {
|
|||
(modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
|
||||
"if (0 && vlSymsp && first) {} // Prevent unused\n");
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
if (AstCoverDecl* coverp = np->castCoverDecl()) {
|
||||
if (AstCoverDecl* coverp = VN_CAST(np, CoverDecl)) {
|
||||
AstNode* backp = coverp->backp();
|
||||
coverp->unlinkFrBack();
|
||||
configure_coverage.add(coverp);
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ private:
|
|||
}
|
||||
|
||||
virtual void visit(AstNodeCase* nodep) {
|
||||
if (nodep->castCase() && nodep->castCase()->casex()) {
|
||||
if (VN_IS(nodep, Case) && VN_CAST(nodep, Case)->casex()) {
|
||||
nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)");
|
||||
}
|
||||
// Detect multiple defaults
|
||||
bool hitDefault = false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (itemp->isDefault()) {
|
||||
if (hitDefault) {
|
||||
nodep->v3error("Multiple default statements in case statement.");
|
||||
|
|
@ -84,7 +84,7 @@ private:
|
|||
{
|
||||
m_caseExprp = nodep;
|
||||
nodep->exprp()->accept(*this);
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
itemp->condsp()->iterateAndNext(*this);
|
||||
}
|
||||
m_caseExprp = NULL;
|
||||
|
|
@ -93,12 +93,12 @@ private:
|
|||
virtual void visit(AstConst* nodep) {
|
||||
// See also neverItem
|
||||
if (m_caseExprp && nodep->num().isFourState()) {
|
||||
if (m_caseExprp->castGenCase()) {
|
||||
if (VN_IS(m_caseExprp, GenCase)) {
|
||||
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
|
||||
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
|
||||
} else if (VN_IS(m_caseExprp, Case) && VN_CAST(m_caseExprp, Case)->casex()) {
|
||||
// Don't sweat it, we already complained about casex in general
|
||||
} else if (m_caseExprp->castCase() && (m_caseExprp->castCase()->casez()
|
||||
|| m_caseExprp->castCase()->caseInside())) {
|
||||
} else if (VN_IS(m_caseExprp, Case) && (VN_CAST(m_caseExprp, Case)->casez()
|
||||
|| VN_CAST(m_caseExprp, Case)->caseInside())) {
|
||||
if (nodep->num().isUnknown()) {
|
||||
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
|
||||
}
|
||||
|
|
@ -151,11 +151,11 @@ private:
|
|||
bool opaque = false;
|
||||
m_caseItems = 0;
|
||||
m_caseNoOverlapsAllCovered = true;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
if (icondp->width() > width) width = icondp->width();
|
||||
if (icondp->isDouble()) opaque = true;
|
||||
if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant
|
||||
if (!VN_IS(icondp, Const)) width = CASE_BARF; // Can't parse; not a constant
|
||||
m_caseItems++;
|
||||
}
|
||||
}
|
||||
|
|
@ -170,10 +170,10 @@ private:
|
|||
// Now pick up the values for each assignment
|
||||
// We can cheat and use uint32_t's because we only support narrow case's
|
||||
bool bitched = false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
AstConst* iconstp = VN_CAST(icondp, Const);
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
|
|
@ -215,7 +215,7 @@ private:
|
|||
// Convert valueItem from AstCaseItem* to the expression
|
||||
// Not done earlier, as we may now have a NULL because it's just a ";" NOP branch
|
||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||
m_valueItem[i] = m_valueItem[i]->castCaseItem()->bodysp();
|
||||
m_valueItem[i] = VN_CAST(m_valueItem[i], CaseItem)->bodysp();
|
||||
}
|
||||
return true; // All is fine
|
||||
}
|
||||
|
|
@ -310,7 +310,7 @@ private:
|
|||
// the appropriate IF AND terms.
|
||||
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
|
||||
bool hadDefault = false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (!itemp->condsp()) {
|
||||
// Default clause. Just make true, we'll optimize it away later
|
||||
itemp->condsp(new AstConst(itemp->fileline(), AstConst::LogicTrue()));
|
||||
|
|
@ -324,14 +324,14 @@ private:
|
|||
icondp->unlinkFrBack();
|
||||
|
||||
AstNode* condp = NULL; // Default is to use and1p/and2p
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
AstConst* iconstp = VN_CAST(icondp, Const);
|
||||
if (iconstp && neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
|
||||
// For simplicity, make expression that is not equal, and let later
|
||||
// optimizations remove it
|
||||
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
|
||||
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
|
||||
} else if (AstInsideRange* irangep = VN_CAST(icondp, InsideRange)) {
|
||||
// Similar logic in V3Width::visit(AstInside)
|
||||
AstNode* ap = AstGte::newTyped(itemp->fileline(),
|
||||
cexprp->cloneTree(false),
|
||||
|
|
@ -387,7 +387,7 @@ private:
|
|||
AstNode* grouprootp = NULL;
|
||||
AstIf* groupnextp = NULL;
|
||||
AstIf* itemnextp = NULL;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
|
||||
if (istmtsp) istmtsp->unlinkFrBackWithNext();
|
||||
// Expressioned clause
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ private:
|
|||
// Otherwise a (uint64)(a>b) would return wrong value, as
|
||||
// less than has undeterministic signedness.
|
||||
if (nodep->isQuad() && !nodep->lhsp()->isQuad()
|
||||
&& !nodep->lhsp()->castCCast()) {
|
||||
&& !VN_IS(nodep->lhsp(), CCast)) {
|
||||
insertCast(nodep->lhsp(), VL_WORDSIZE);
|
||||
}
|
||||
}
|
||||
|
|
@ -147,9 +147,9 @@ private:
|
|||
}
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (!nodep->lvalue()
|
||||
&& !nodep->backp()->castCCast()
|
||||
&& nodep->backp()->castNodeMath()
|
||||
&& !nodep->backp()->castArraySel()
|
||||
&& !VN_IS(nodep->backp(), CCast)
|
||||
&& VN_IS(nodep->backp(), NodeMath)
|
||||
&& !VN_IS(nodep->backp(), ArraySel)
|
||||
&& nodep->backp()->width()
|
||||
&& castSize(nodep) != castSize(nodep->varp())) {
|
||||
// Cast vars to IData first, else below has upper bits wrongly set
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ private:
|
|||
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
|
||||
AstNode* nodep = vertexp->nodep();
|
||||
string front = pad(filelineWidth(),nodep->fileline()->ascii()+":")+" "+prefix+" +- ";
|
||||
if (nodep->castVarScope()) {
|
||||
if (VN_IS(nodep, VarScope)) {
|
||||
*m_ofp<<front<<"Variable: "<<nodep->prettyName()<<endl;
|
||||
}
|
||||
else {
|
||||
|
|
@ -584,7 +584,7 @@ private:
|
|||
}
|
||||
// If multiple domains need to do complicated optimizations
|
||||
if (senedited) {
|
||||
senoutp = V3Const::constifyExpensiveEdit(senoutp)->castSenTree();
|
||||
senoutp = VN_CAST(V3Const::constifyExpensiveEdit(senoutp), SenTree);
|
||||
}
|
||||
if (traceDests) {
|
||||
vertexp->dstDomainSet(true); // Note it's set - domainp may be null, so can't use that
|
||||
|
|
@ -700,11 +700,11 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstSel* nodep) {
|
||||
if (!nodep->lsbp()->castConst()) setNodeHazard(nodep);
|
||||
if (!VN_IS(nodep->lsbp(), Const)) setNodeHazard(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNodeSel* nodep) {
|
||||
if (!nodep->bitp()->castConst()) setNodeHazard(nodep);
|
||||
if (!VN_IS(nodep->bitp(), Const)) setNodeHazard(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public:
|
|||
if (!m_tlChgFuncp->stmtsp()) {
|
||||
m_tlChgFuncp->addStmtsp(new AstCReturn(m_scopetopp->fileline(), callp));
|
||||
} else {
|
||||
AstCReturn* returnp = m_tlChgFuncp->stmtsp()->castCReturn();
|
||||
AstCReturn* returnp = VN_CAST(m_tlChgFuncp->stmtsp(), CReturn);
|
||||
if (!returnp) m_scopetopp->v3fatalSrc("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
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ private:
|
|||
if (old_dtypep->width() != width) {
|
||||
// Since any given dtype's cppWidth() is the same, we can just
|
||||
// remember one convertion for each, and reuse it
|
||||
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNodeDType()) {
|
||||
if (AstNodeDType* new_dtypep = VN_CAST(old_dtypep->user3p(), NodeDType)) {
|
||||
nodep->dtypep(new_dtypep);
|
||||
} else {
|
||||
nodep->dtypeChgWidth(width, nodep->widthMin());
|
||||
|
|
@ -90,8 +90,8 @@ private:
|
|||
}
|
||||
void computeCppWidth (AstNode* nodep) {
|
||||
if (!nodep->user2() && nodep->hasDType()) {
|
||||
if (nodep->castVar() || nodep->castNodeDType() // Don't want to change variable widths!
|
||||
|| nodep->dtypep()->skipRefp()->castUnpackArrayDType()) { // Or arrays
|
||||
if (VN_IS(nodep, Var) || VN_IS(nodep, NodeDType) // Don't want to change variable widths!
|
||||
|| VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { // Or arrays
|
||||
} else {
|
||||
setCppWidth(nodep);
|
||||
}
|
||||
|
|
@ -230,7 +230,7 @@ private:
|
|||
computeCppWidth(nodep);
|
||||
setClean (nodep, false);
|
||||
// We always clean, as we don't trust those pesky users.
|
||||
if (!nodep->backp()->castAnd()) {
|
||||
if (!VN_IS(nodep->backp(), And)) {
|
||||
insertClean(nodep);
|
||||
}
|
||||
insureCleanAndNext (nodep->bodysp());
|
||||
|
|
|
|||
|
|
@ -672,7 +672,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
AstSenTree* sensesp = nodep->sensesp()->cloneTree(true);
|
||||
#else
|
||||
// Make a SenGate
|
||||
AstSenItem* oldsenitemsp = nodep->sensesp()->sensesp()->castSenItem();
|
||||
AstSenItem* oldsenitemsp = VN_CAST(nodep->sensesp()->sensesp(), SenItem);
|
||||
if (!oldsenitemsp) nodep->v3fatalSrc("SenTree doesn't have any SenItem under it");
|
||||
|
||||
AstSenTree* sensesp = new AstSenTree(nodep->fileline(),
|
||||
|
|
@ -857,7 +857,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
AstVarScope* lastvscp = m_stmtVscp;
|
||||
bool lastpli = m_stmtInPli;
|
||||
m_directlyUnderAlw = under;
|
||||
if (nodep->castNodeStmt()) { // Restored below
|
||||
if (VN_IS(nodep, NodeStmt)) { // Restored below
|
||||
UINFO(9," Stmt: "<<nodep<<endl);
|
||||
m_stmtVscp = NULL;
|
||||
m_stmtInPli = false;
|
||||
|
|
@ -871,7 +871,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
|||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_directlyUnderAlw = lastdua;
|
||||
if (nodep->castNodeStmt()) { // Reset what set above; else propagate up to above statement
|
||||
if (VN_IS(nodep, NodeStmt)) { // Reset what set above; else propagate up to above statement
|
||||
m_stmtVscp = lastvscp;
|
||||
m_stmtInPli = lastpli;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,11 +154,11 @@ private:
|
|||
AstNode* createSenseEquation(AstNodeSenItem* nodesp) {
|
||||
// Nodep may be a list of elements; we need to walk it
|
||||
AstNode* senEqnp = NULL;
|
||||
for (AstNodeSenItem* senp = nodesp; senp; senp=senp->nextp()->castNodeSenItem()) {
|
||||
for (AstNodeSenItem* senp = nodesp; senp; senp=VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
AstNode* senOnep = NULL;
|
||||
if (AstSenItem* itemp = senp->castSenItem()) {
|
||||
if (AstSenItem* itemp = VN_CAST(senp, SenItem)) {
|
||||
senOnep = createSenItemEquation(itemp);
|
||||
} else if (AstSenGate* itemp = senp->castSenGate()) {
|
||||
} else if (AstSenGate* itemp = VN_CAST(senp, SenGate)) {
|
||||
senOnep = createSenGateEquation(itemp);
|
||||
} else {
|
||||
senp->v3fatalSrc("Strange node under sentree");
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ private:
|
|||
void walkEmptyFuncs() {
|
||||
for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) {
|
||||
AstNode* node1p = it->second;
|
||||
AstCFunc* oldfuncp = node1p->castCFunc();
|
||||
AstCFunc* oldfuncp = VN_CAST(node1p, CFunc);
|
||||
if (oldfuncp
|
||||
&& oldfuncp->emptyBody()
|
||||
&& !oldfuncp->dontCombine()) {
|
||||
|
|
@ -238,7 +238,7 @@ private:
|
|||
for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) {
|
||||
V3Hash hashval = it->first;
|
||||
AstNode* node1p = it->second;
|
||||
if (!node1p->castCFunc()) continue;
|
||||
if (!VN_IS(node1p, CFunc)) continue;
|
||||
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes");
|
||||
for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) {
|
||||
AstNode* node2p = eqit->second;
|
||||
|
|
@ -247,9 +247,9 @@ private:
|
|||
if (node1p->user3p() || node2p->user3p()) continue; // Already merged
|
||||
if (node1p->sameTree(node2p)) { // walk of tree has same comparison
|
||||
// Replace AstCCall's that point here
|
||||
replaceFuncWFunc(node2p->castCFunc(), node1p->castCFunc());
|
||||
replaceFuncWFunc(VN_CAST(node2p, CFunc), VN_CAST(node1p, CFunc));
|
||||
// Replacement may promote a slow routine to fast path
|
||||
if (!node2p->castCFunc()->slow()) node1p->castCFunc()->slow(false);
|
||||
if (!VN_CAST(node2p, CFunc)->slow()) VN_CAST(node1p, CFunc)->slow(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -265,7 +265,7 @@ private:
|
|||
pushDeletep(oldfuncp); VL_DANGLING(oldfuncp);
|
||||
}
|
||||
void replaceOnlyCallFunc(AstCCall* nodep) {
|
||||
if (AstCFunc* oldfuncp = nodep->backp()->castCFunc()) {
|
||||
if (AstCFunc* oldfuncp = VN_CAST(nodep->backp(), CFunc)) {
|
||||
//oldfuncp->dumpTree(cout,"MAYDEL: ");
|
||||
if (nodep->nextp()==NULL
|
||||
&& oldfuncp->initsp()==NULL
|
||||
|
|
|
|||
598
src/V3Const.cpp
598
src/V3Const.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -200,7 +200,7 @@ private:
|
|||
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
|
||||
const ToggleEnt& above,
|
||||
AstVar* varp, AstVar* chgVarp) { // Constant
|
||||
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
|
||||
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (bdtypep->isRanged()) {
|
||||
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
|
||||
int index_code = index_docs - bdtypep->lsb();
|
||||
|
|
@ -218,7 +218,7 @@ private:
|
|||
varp, chgVarp);
|
||||
}
|
||||
}
|
||||
else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
|
||||
else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
|
||||
int index_code = index_docs - adtypep->lsb();
|
||||
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
||||
|
|
@ -230,7 +230,7 @@ private:
|
|||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) {
|
||||
else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
||||
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
|
||||
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
|
||||
int index_code = index_docs - adtypep->lsb();
|
||||
|
|
@ -245,9 +245,9 @@ private:
|
|||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstStructDType* adtypep = dtypep->castStructDType()) {
|
||||
else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) {
|
||||
// For now it's packed, so similar to array
|
||||
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
int index_code = itemp->lsb();
|
||||
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
|
||||
|
|
@ -261,7 +261,7 @@ private:
|
|||
newent.cleanup();
|
||||
}
|
||||
}
|
||||
else if (AstUnionDType* adtypep = dtypep->castUnionDType()) {
|
||||
else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
|
||||
// Arbitrarially handle only the first member of the union
|
||||
if (AstMemberDType* itemp = adtypep->membersp()) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
|
|
@ -284,9 +284,9 @@ private:
|
|||
UINFO(4," IF: "<<nodep<<endl);
|
||||
if (m_checkBlock) {
|
||||
// An else-if. When we iterate the if, use "elsif" marking
|
||||
bool elsif = (nodep->elsesp()->castIf()
|
||||
&& !nodep->elsesp()->castIf()->nextp());
|
||||
if (elsif) nodep->elsesp()->castIf()->user1(true);
|
||||
bool elsif = (VN_IS(nodep->elsesp(), If)
|
||||
&& !VN_CAST(nodep->elsesp(), If)->nextp());
|
||||
if (elsif) VN_CAST(nodep->elsesp(), If)->user1(true);
|
||||
//
|
||||
nodep->ifsp()->iterateAndNext(*this);
|
||||
if (m_checkBlock && !m_inModOff
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ private:
|
|||
AstNode* duporigp = hashed.iteratorNodep(dupit);
|
||||
// Note hashed will point to the original variable (what's duplicated), not the covertoggle,
|
||||
// but we need to get back to the covertoggle which is immediately above, so:
|
||||
AstCoverToggle* removep = duporigp->backp()->castCoverToggle();
|
||||
AstCoverToggle* removep = VN_CAST(duporigp->backp(), CoverToggle);
|
||||
if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type");
|
||||
UINFO(8," Orig "<<nodep<<" -->> "<<nodep->incp()->declp()<<endl);
|
||||
UINFO(8," dup "<<removep<<" -->> "<<removep->incp()->declp()<<endl);
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ private:
|
|||
void checkDType(AstNodeDType* nodep) {
|
||||
if (!nodep->generic() // Don't remove generic types
|
||||
&& m_elimDTypes // dtypes stick around until post-widthing
|
||||
&& !nodep->castMemberDType() // Keep member names iff upper type exists
|
||||
&& !VN_IS(nodep, MemberDType) // Keep member names iff upper type exists
|
||||
) {
|
||||
m_dtypesp.push_back(nodep);
|
||||
}
|
||||
|
|
@ -229,7 +229,7 @@ private:
|
|||
checkAll(nodep);
|
||||
// Don't let packages with only public variables disappear
|
||||
// Normal modules may disappear, e.g. if they are parameterized then removed
|
||||
if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
|
||||
if (nodep->attrPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -242,7 +242,7 @@ private:
|
|||
virtual void visit(AstVar* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->isSigPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
|
||||
if (nodep->isSigPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
if (mightElimVar(nodep)) {
|
||||
m_varsp.push_back(nodep);
|
||||
}
|
||||
|
|
@ -254,7 +254,7 @@ private:
|
|||
nodep->rhsp()->iterateAndNext(*this);
|
||||
checkAll(nodep);
|
||||
// Has to be direct assignment without any EXTRACTing.
|
||||
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
|
||||
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
if (varrefp && !m_sideEffect
|
||||
&& varrefp->varScopep()) { // For simplicity, we only remove post-scoping
|
||||
m_assignMap.insert(make_pair(varrefp->varScopep(), nodep));
|
||||
|
|
@ -281,7 +281,7 @@ private:
|
|||
retry=false;
|
||||
AstNodeModule* nextmodp;
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
|
||||
nextmodp = modp->nextp()->castNodeModule();
|
||||
nextmodp = VN_CAST(modp->nextp(), NodeModule);
|
||||
if (modp->dead() || (modp->level()>2 && modp->user1()==0 && !modp->internal())) {
|
||||
// > 2 because L1 is the wrapper, L2 is the top user module
|
||||
UINFO(4," Dead module "<<modp<<endl);
|
||||
|
|
@ -376,9 +376,9 @@ private:
|
|||
// It's possible that there if a reference to each individual member, but
|
||||
// not to the dtype itself. Check and don't remove the parent dtype if
|
||||
// members are still alive.
|
||||
if ((classp = (*it)->castNodeClassDType())) {
|
||||
if ((classp = VN_CAST((*it), NodeClassDType))) {
|
||||
bool cont = true;
|
||||
for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = memberp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType *memberp = classp->membersp(); memberp; memberp = VN_CAST(memberp->nextp(), MemberDType)) {
|
||||
if (memberp->user1() != 0) {
|
||||
cont = false;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -188,25 +188,25 @@ private:
|
|||
AstNode* newlhsp = NULL; // NULL = unlink old assign
|
||||
AstSel* bitselp = NULL;
|
||||
AstArraySel* arrayselp = NULL;
|
||||
if (lhsp->castSel()) {
|
||||
bitselp = lhsp->castSel();
|
||||
arrayselp = bitselp->fromp()->castArraySel();
|
||||
if (VN_IS(lhsp, Sel)) {
|
||||
bitselp = VN_CAST(lhsp, Sel);
|
||||
arrayselp = VN_CAST(bitselp->fromp(), ArraySel);
|
||||
} else {
|
||||
arrayselp = lhsp->castArraySel();
|
||||
arrayselp = VN_CAST(lhsp, ArraySel);
|
||||
}
|
||||
if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?");
|
||||
if (arrayselp->dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
if (VN_IS(arrayselp->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
|
||||
UINFO(4,"AssignDlyArray: "<<nodep<<endl);
|
||||
//
|
||||
//=== Dimensions: __Vdlyvdim__
|
||||
std::deque<AstNode*> dimvalp; // Assignment value for each dimension of assignment
|
||||
AstNode* dimselp=arrayselp;
|
||||
for (; dimselp->castArraySel(); dimselp=dimselp->castArraySel()->fromp()) {
|
||||
AstNode* valp = dimselp->castArraySel()->bitp()->unlinkFrBack();
|
||||
for (; VN_IS(dimselp, ArraySel); dimselp=VN_CAST(dimselp, ArraySel)->fromp()) {
|
||||
AstNode* valp = VN_CAST(dimselp, ArraySel)->bitp()->unlinkFrBack();
|
||||
dimvalp.push_front(valp);
|
||||
}
|
||||
AstVarRef* varrefp = dimselp->castVarRef();
|
||||
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");
|
||||
varrefp->unlinkFrBack();
|
||||
|
|
@ -216,7 +216,7 @@ private:
|
|||
std::deque<AstNode*> dimreadps; // Read value for each dimension of assignment
|
||||
for (unsigned dimension=0; dimension<dimvalp.size(); dimension++) {
|
||||
AstNode* dimp = dimvalp[dimension];
|
||||
if (dimp->castConst()) { // bit = const, can just use it
|
||||
if (VN_IS(dimp, Const)) { // bit = const, can just use it
|
||||
dimreadps.push_front(dimp);
|
||||
} else {
|
||||
string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension)
|
||||
|
|
@ -235,7 +235,7 @@ private:
|
|||
AstNode* bitreadp=NULL; // Code to read Vdlyvlsb
|
||||
if (bitselp) {
|
||||
AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack();
|
||||
if (bitselp->fromp()->castConst()) {// vlsb = constant, can just push constant into where we use it
|
||||
if (VN_IS(bitselp->fromp(), Const)) { // vlsb = constant, can just push constant into where we use it
|
||||
bitreadp = lsbvaluep;
|
||||
} else {
|
||||
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||
|
|
@ -250,7 +250,7 @@ private:
|
|||
//
|
||||
//=== Value: __Vdlyvval__
|
||||
AstNode* valreadp; // Code to read Vdlyvval
|
||||
if (nodep->rhsp()->castConst()) { // vval = constant, can just push constant into where we use it
|
||||
if (VN_IS(nodep->rhsp(), Const)) { // vval = constant, can just push constant into where we use it
|
||||
valreadp = nodep->rhsp()->unlinkFrBack();
|
||||
} else {
|
||||
string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||
|
|
@ -268,7 +268,7 @@ private:
|
|||
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
|
||||
// This is good for code like:
|
||||
// for (i=0; i<5; i++) vector[i] <= something;
|
||||
setvscp = nodep->user3p()->castVarScope();
|
||||
setvscp = VN_CAST(nodep->user3p(), VarScope);
|
||||
++m_statSharedSet;
|
||||
} else { // Create new one
|
||||
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||
|
|
@ -303,9 +303,9 @@ private:
|
|||
// Build "IF (changeit) ...
|
||||
UINFO(9," For "<<setvscp<<endl);
|
||||
UINFO(9," & "<<varrefp<<endl);
|
||||
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castAlwaysPost();
|
||||
AstAlwaysPost* finalp = VN_CAST(varrefp->varScopep()->user4p(), AlwaysPost);
|
||||
if (finalp) {
|
||||
AstActive* oldactivep = finalp->user2p()->castActive();
|
||||
AstActive* oldactivep = VN_CAST(finalp->user2p(), Active);
|
||||
checkActivePost(varrefp, oldactivep);
|
||||
if (setinitp) oldactivep->addStmtsp(setinitp);
|
||||
} else { // first time we've dealt with this memory
|
||||
|
|
@ -321,7 +321,7 @@ private:
|
|||
if (finalp->user3p() == setvscp) {
|
||||
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
|
||||
// we can share the IF statement too
|
||||
postLogicp = finalp->user4p()->castIf();
|
||||
postLogicp = VN_CAST(finalp->user4p(), If);
|
||||
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||
} else {
|
||||
postLogicp = new AstIf (nodep->fileline(),
|
||||
|
|
@ -363,11 +363,11 @@ private:
|
|||
}
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
m_inDly = true;
|
||||
m_nextDlyp = nodep->nextp()->castAssignDly(); // Next assignment in same block, maybe NULL.
|
||||
m_nextDlyp = VN_CAST(nodep->nextp(), AssignDly); // Next assignment in same block, maybe NULL.
|
||||
if (m_cfuncp) nodep->v3error("Unsupported: Delayed assignment inside public function/task");
|
||||
if (nodep->lhsp()->castArraySel()
|
||||
|| (nodep->lhsp()->castSel()
|
||||
&& nodep->lhsp()->castSel()->fromp()->castArraySel())) {
|
||||
if (VN_IS(nodep->lhsp(), ArraySel)
|
||||
|| (VN_IS(nodep->lhsp(), Sel)
|
||||
&& VN_IS(VN_CAST(nodep->lhsp(), Sel)->fromp(), ArraySel))) {
|
||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* newlhsp = createDlyArray(nodep, lhsp);
|
||||
if (m_inLoop) nodep->v3warn(BLKLOOPINIT,"Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)");
|
||||
|
|
@ -394,9 +394,9 @@ private:
|
|||
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");
|
||||
AstVarScope* dlyvscp = oldvscp->user1p()->castVarScope();
|
||||
AstVarScope* dlyvscp = VN_CAST(oldvscp->user1p(), VarScope);
|
||||
if (dlyvscp) { // Multiple use of delayed variable
|
||||
AstActive* oldactivep = dlyvscp->user2p()->castActive();
|
||||
AstActive* oldactivep = VN_CAST(dlyvscp->user2p(), Active);
|
||||
checkActivePost(nodep, oldactivep);
|
||||
}
|
||||
if (!dlyvscp) { // First use of this delayed variable
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ private:
|
|||
if (m_stmtp
|
||||
&& (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it
|
||||
&& (m_maxdepth-m_depth) > v3Global.opt.compLimitParens()
|
||||
&& !nodep->backp()->castNodeStmt() // Not much point if we're about to use it
|
||||
&& !VN_IS(nodep->backp(), NodeStmt) // Not much point if we're about to use it
|
||||
) {
|
||||
m_maxdepth = m_depth;
|
||||
createDeepTemp(nodep);
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ private:
|
|||
void visitStmt(AstNodeStmt* nodep) {
|
||||
m_depth++;
|
||||
if (m_depth > v3Global.opt.compLimitBlocks()
|
||||
&& !nodep->castCCall()) { // Already done
|
||||
&& !VN_IS(nodep, CCall)) { // Already done
|
||||
UINFO(4, "DeepBlocks "<<m_depth<<" "<<nodep<<endl);
|
||||
AstNode* backp = nodep->backp(); // Only for debug
|
||||
if (debug()>=9) backp->dumpTree(cout,"- pre : ");
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ private:
|
|||
// True iff there's exactly one instance of this module in the design.
|
||||
int instances = 0;
|
||||
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (stmtp->castScope()) {
|
||||
if (VN_IS(stmtp, Scope)) {
|
||||
if (++instances > 1) { return false; }
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ private:
|
|||
funcp->declPrivate(true);
|
||||
AstNode* argsp = NULL;
|
||||
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput());
|
||||
if (argsp) argsp = argsp->addNextNull(newp);
|
||||
|
|
|
|||
178
src/V3EmitC.cpp
178
src/V3EmitC.cpp
|
|
@ -44,9 +44,11 @@
|
|||
|
||||
class EmitCStmts : public EmitCBaseVisitor {
|
||||
private:
|
||||
typedef std::vector<const AstVar*> VarVec;
|
||||
|
||||
bool m_suppressSemi;
|
||||
AstVarRef* m_wideTempRefp; // Variable that _WW macros should be setting
|
||||
std::vector<AstVar*> m_ctorVarsVec; // All variables in constructor order
|
||||
VarVec m_ctorVarsVec; // All variables in constructor order
|
||||
int m_splitSize; // # of cfunc nodes placed into output file
|
||||
int m_splitFilenum; // File number being created, 0 = primary
|
||||
|
||||
|
|
@ -74,7 +76,7 @@ public:
|
|||
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
const string& vfmt, char fmtLetter);
|
||||
|
||||
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
|
||||
void emitVarDecl(const AstVar* nodep, const string& prefixIfImp);
|
||||
typedef enum {EVL_CLASS_IO, EVL_CLASS_SIG, EVL_CLASS_TEMP, EVL_CLASS_PAR, EVL_CLASS_ALL,
|
||||
EVL_FUNC_ALL} EisWhich;
|
||||
void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp);
|
||||
|
|
@ -93,10 +95,10 @@ public:
|
|||
}
|
||||
void emitOpName(AstNode* nodep, const string& format,
|
||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
||||
void emitDeclArrayBrackets(AstVar* nodep) {
|
||||
void emitDeclArrayBrackets(const AstVar* nodep) {
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
||||
for (const AstUnpackArrayDType* arrayp=VN_CAST_CONST(nodep->dtypeSkipRefp(), UnpackArrayDType); arrayp;
|
||||
arrayp = VN_CAST_CONST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
}
|
||||
|
|
@ -104,7 +106,7 @@ public:
|
|||
void emitTypedefs(AstNode* firstp) {
|
||||
bool first = true;
|
||||
for (AstNode* loopp=firstp; loopp; loopp = loopp->nextp()) {
|
||||
if (AstTypedef* nodep = loopp->castTypedef()) {
|
||||
if (const AstTypedef* nodep = VN_CAST(loopp, Typedef)) {
|
||||
if (nodep->attrPublic()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
|
|
@ -113,16 +115,16 @@ public:
|
|||
} else {
|
||||
puts("\n");
|
||||
}
|
||||
if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) {
|
||||
if (const AstEnumDType* adtypep = VN_CAST(nodep->dtypep()->skipRefToEnump(), EnumDType)) {
|
||||
if (adtypep->width()>64) {
|
||||
putsDecoration("// enum "+nodep->name()+" // Ignored: Too wide for C++\n");
|
||||
} else {
|
||||
puts("enum "+nodep->name()+" {\n");
|
||||
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
|
||||
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), EnumItem)) {
|
||||
puts(itemp->name());
|
||||
puts(" = ");
|
||||
itemp->valuep()->iterateAndNext(*this);
|
||||
if (itemp->nextp()->castEnumItem()) puts(",");
|
||||
if (VN_IS(itemp->nextp(), EnumItem)) puts(",");
|
||||
puts("\n");
|
||||
}
|
||||
puts("};\n");
|
||||
|
|
@ -136,7 +138,7 @@ public:
|
|||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
bool paren = true; bool decind = false;
|
||||
if (AstSel* selp=nodep->lhsp()->castSel()) {
|
||||
if (AstSel* selp=VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (selp->widthMin()==1) {
|
||||
putbs("VL_ASSIGNBIT_");
|
||||
emitIQW(selp->fromp());
|
||||
|
|
@ -173,12 +175,12 @@ public:
|
|||
puts(cvtToStr(nodep->widthMin())+",");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
} else if (nodep->isWide()
|
||||
&& nodep->lhsp()->castVarRef()
|
||||
&& !nodep->rhsp()->castCMath()
|
||||
&& !nodep->rhsp()->castVarRef()
|
||||
&& !nodep->rhsp()->castArraySel()) {
|
||||
&& VN_IS(nodep->lhsp(), VarRef)
|
||||
&& !VN_IS(nodep->rhsp(), CMath)
|
||||
&& !VN_IS(nodep->rhsp(), VarRef)
|
||||
&& !VN_IS(nodep->rhsp(), ArraySel)) {
|
||||
// Wide functions assign into the array directly, don't need separate assign statement
|
||||
m_wideTempRefp = nodep->lhsp()->castVarRef();
|
||||
m_wideTempRefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
paren = false;
|
||||
} else if (nodep->isWide()) {
|
||||
putbs("VL_ASSIGN_W(");
|
||||
|
|
@ -189,7 +191,7 @@ public:
|
|||
nodep->lhsp()->iterateAndNext(*this);
|
||||
puts(" ");
|
||||
ofp()->blockInc(); decind = true;
|
||||
if (!nodep->rhsp()->castConst()) ofp()->putBreak();
|
||||
if (!VN_IS(nodep->rhsp(), Const)) ofp()->putBreak();
|
||||
puts("= ");
|
||||
}
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
|
|
@ -210,7 +212,7 @@ public:
|
|||
subnodep->accept(*this);
|
||||
comma = true;
|
||||
}
|
||||
if (nodep->backp()->castNodeMath() || nodep->backp()->castCReturn()) {
|
||||
if (VN_IS(nodep->backp(), NodeMath) || VN_IS(nodep->backp(), CReturn)) {
|
||||
// We should have a separate CCall for math and statement usage, but...
|
||||
puts(")");
|
||||
} else {
|
||||
|
|
@ -332,9 +334,9 @@ public:
|
|||
putbs(",");
|
||||
uint32_t array_lsb = 0;
|
||||
{
|
||||
AstVarRef* varrefp = nodep->memp()->castVarRef();
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||
if (!varrefp) { nodep->v3error("Readmem loading non-variable"); }
|
||||
else if (AstUnpackArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castUnpackArrayDType()) {
|
||||
else if (const AstUnpackArrayDType* adtypep = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
|
||||
array_lsb = adtypep->lsb();
|
||||
}
|
||||
|
|
@ -496,7 +498,7 @@ public:
|
|||
}
|
||||
virtual void visit(AstRedXor* nodep) {
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
visit(nodep->castNodeUniop());
|
||||
visit(VN_CAST(nodep, NodeUniop));
|
||||
} else {
|
||||
putbs("VL_REDXOR_");
|
||||
puts(cvtToStr(nodep->lhsp()->dtypep()->widthPow2()));
|
||||
|
|
@ -509,31 +511,31 @@ public:
|
|||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(nodep->castNodeBiop());
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPow* nodep) {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(nodep->castNodeBiop());
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowSS* nodep) {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(nodep->castNodeBiop());
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowSU* nodep) {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(nodep->castNodeBiop());
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstPowUS* nodep) {
|
||||
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3error("Unsupported: Power of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
visit(nodep->castNodeBiop());
|
||||
visit(VN_CAST(nodep, NodeBiop));
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) {
|
||||
// Extending a value of the same word width is just a NOP.
|
||||
|
|
@ -562,7 +564,7 @@ public:
|
|||
}
|
||||
virtual void visit(AstReplicate* nodep) {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
if (((int)nodep->rhsp()->castConst()->toUInt()
|
||||
if (((int)VN_CAST(nodep->rhsp(), Const)->toUInt()
|
||||
* nodep->lhsp()->widthMin()) != nodep->widthMin())
|
||||
nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
|
||||
puts("VL_REPLICATE_");
|
||||
|
|
@ -581,8 +583,8 @@ public:
|
|||
virtual void visit(AstStreamL* nodep) {
|
||||
// Attempt to use a "fast" stream function for slice size = power of 2
|
||||
if (!nodep->isWide()) {
|
||||
uint32_t isPow2 = nodep->rhsp()->castConst()->num().countOnes() == 1;
|
||||
uint32_t sliceSize = nodep->rhsp()->castConst()->toUInt();
|
||||
uint32_t isPow2 = VN_CAST(nodep->rhsp(), Const)->num().countOnes() == 1;
|
||||
uint32_t sliceSize = VN_CAST(nodep->rhsp(), Const)->toUInt();
|
||||
if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) {
|
||||
puts("VL_STREAML_FAST_");
|
||||
emitIQW(nodep);
|
||||
|
|
@ -593,7 +595,7 @@ public:
|
|||
puts(","+cvtToStr(nodep->rhsp()->widthMin()));
|
||||
puts(",");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
uint32_t rd_log2 = V3Number::log2b(nodep->rhsp()->castConst()->toUInt());
|
||||
uint32_t rd_log2 = V3Number::log2b(VN_CAST(nodep->rhsp(), Const)->toUInt());
|
||||
puts(cvtToStr(rd_log2)+")");
|
||||
return;
|
||||
}
|
||||
|
|
@ -606,7 +608,7 @@ public:
|
|||
puts(nodep->varp()->name());
|
||||
}
|
||||
void emitCvtPackStr(AstNode* nodep) {
|
||||
if (AstConst* constp = nodep->castConst()) {
|
||||
if (const AstConst* constp = VN_CAST(nodep, Const)) {
|
||||
putbs("std::string(");
|
||||
putsQuoted(constp->num().toString());
|
||||
puts(")");
|
||||
|
|
@ -656,7 +658,7 @@ public:
|
|||
puts(",");
|
||||
if (!assigntop) {
|
||||
puts(assignString);
|
||||
} else if (assigntop->castVarRef()) {
|
||||
} else if (VN_IS(assigntop, VarRef)) {
|
||||
puts(assigntop->hiername());
|
||||
puts(assigntop->varp()->name());
|
||||
} else {
|
||||
|
|
@ -677,7 +679,7 @@ public:
|
|||
puts(",");
|
||||
if (!assigntop) {
|
||||
puts(assignString);
|
||||
} else if (assigntop->castVarRef()) {
|
||||
} else if (VN_IS(assigntop, VarRef)) {
|
||||
puts(assigntop->hiername());
|
||||
puts(assigntop->varp()->name());
|
||||
} else {
|
||||
|
|
@ -790,8 +792,8 @@ class EmitCImp : EmitCStmts {
|
|||
AstNode* lhsp = changep->lhsp();
|
||||
AstNode* rhsp = changep->rhsp();
|
||||
static int addDoubleOr = 10; // Determined experimentally as best
|
||||
if (!lhsp->castVarRef() && !lhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
|
||||
if (!rhsp->castVarRef() && !rhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
|
||||
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?");
|
||||
for (int word=0; word<changep->lhsp()->widthWords(); word++) {
|
||||
if (!gotOne) {
|
||||
gotOne = true;
|
||||
|
|
@ -887,7 +889,7 @@ class EmitCImp : EmitCStmts {
|
|||
|
||||
if (nodep->initsp()) putsDecoration("// Variables\n");
|
||||
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* varp=subnodep->castVar()) {
|
||||
if (AstVar* varp=VN_CAST(subnodep, Var)) {
|
||||
if (varp->isFuncReturn()) emitVarDecl(varp, "");
|
||||
}
|
||||
}
|
||||
|
|
@ -937,8 +939,8 @@ class EmitCImp : EmitCStmts {
|
|||
bool gotOneIgnore = false;
|
||||
doubleOrDetect(nodep, gotOneIgnore);
|
||||
string varname;
|
||||
if (nodep->lhsp()->castVarRef()) {
|
||||
varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName();
|
||||
if (VN_IS(nodep->lhsp(), VarRef)) {
|
||||
varname = ": "+VN_CAST(nodep->lhsp(), VarRef)->varp()->prettyName();
|
||||
}
|
||||
puts(")) VL_DBG_MSGF(\" CHANGE: "+nodep->fileline()->ascii()
|
||||
+varname+"\\n\"); );\n");
|
||||
|
|
@ -996,7 +998,7 @@ public:
|
|||
//######################################################################
|
||||
// Internal EmitCStmts
|
||||
|
||||
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
||||
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
|
|
@ -1077,9 +1079,9 @@ void EmitCStmts::emitVarCtors() {
|
|||
puts("\n");
|
||||
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
|
||||
bool first = true;
|
||||
for (std::vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
||||
AstVar* varp = *it;
|
||||
bool isArray = !varp->dtypeSkipRefp()->castBasicDType();
|
||||
for (VarVec::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
||||
const AstVar* varp = *it;
|
||||
bool isArray = !VN_CAST(varp->dtypeSkipRefp(), BasicDType);
|
||||
if (isArray) {
|
||||
puts("// Skipping array: ");
|
||||
puts(varp->name());
|
||||
|
|
@ -1230,17 +1232,17 @@ struct EmitDispState {
|
|||
|
||||
void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
||||
if (emitDispState.m_format == ""
|
||||
&& nodep->castDisplay()) { // not fscanf etc, as they need to return value
|
||||
&& VN_IS(nodep, Display)) { // not fscanf etc, as they need to return value
|
||||
// NOP
|
||||
} else {
|
||||
// Format
|
||||
bool isStmt = false;
|
||||
if (AstFScanF* dispp = nodep->castFScanF()) {
|
||||
if (const AstFScanF* dispp = VN_CAST(nodep, FScanF)) {
|
||||
isStmt = false;
|
||||
puts("VL_FSCANF_IX(");
|
||||
dispp->filep()->iterate(*this);
|
||||
puts(",");
|
||||
} else if (AstSScanF* dispp = nodep->castSScanF()) {
|
||||
} else if (const AstSScanF* dispp = VN_CAST(nodep, SScanF)) {
|
||||
isStmt = false;
|
||||
checkMaxWords(dispp->fromp());
|
||||
puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X(");
|
||||
|
|
@ -1248,7 +1250,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
|||
puts(",");
|
||||
dispp->fromp()->iterate(*this);
|
||||
puts(",");
|
||||
} else if (AstDisplay* dispp = nodep->castDisplay()) {
|
||||
} else if (const AstDisplay* dispp = VN_CAST(nodep, Display)) {
|
||||
isStmt = true;
|
||||
if (dispp->filep()) {
|
||||
puts("VL_FWRITEF(");
|
||||
|
|
@ -1257,14 +1259,14 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
|||
} else {
|
||||
puts("VL_WRITEF(");
|
||||
}
|
||||
} else if (AstSFormat* dispp = nodep->castSFormat()) {
|
||||
} else if (const AstSFormat* dispp = VN_CAST(nodep, SFormat)) {
|
||||
isStmt = true;
|
||||
puts("VL_SFORMAT_X(");
|
||||
puts(cvtToStr(dispp->lhsp()->widthMin()));
|
||||
putbs(",");
|
||||
dispp->lhsp()->iterate(*this);
|
||||
putbs(",");
|
||||
} else if (AstSFormatF* dispp = nodep->castSFormatF()) {
|
||||
} else if (const AstSFormatF* dispp = VN_CAST(nodep, SFormatF)) {
|
||||
isStmt = false;
|
||||
if (dispp) {}
|
||||
puts("VL_SFORMATF_NX(");
|
||||
|
|
@ -1424,21 +1426,21 @@ void EmitCImp::emitVarReset(AstVar* varp) {
|
|||
// If an ARRAYINIT we initialize it using an initial block similar to a signal
|
||||
//puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n");
|
||||
}
|
||||
else if (AstInitArray* initarp = varp->valuep()->castInitArray()) {
|
||||
if (AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType()) {
|
||||
else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) {
|
||||
if (AstUnpackArrayDType* arrayp = VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||
if (initarp->defaultp()) {
|
||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||
puts("{ int __Vi=0;");
|
||||
puts(" for (; __Vi<"+cvtToStr(arrayp->elementsConst()));
|
||||
puts("; ++__Vi) {\n");
|
||||
emitSetVarConstant(varp->name()+"[__Vi]", initarp->defaultp()->castConst());
|
||||
emitSetVarConstant(varp->name()+"[__Vi]", VN_CAST(initarp->defaultp(), Const));
|
||||
puts("}}\n");
|
||||
}
|
||||
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");
|
||||
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", itemp->castConst());
|
||||
emitSetVarConstant(varp->name()+"["+cvtToStr(index)+"]", VN_CAST(itemp, Const));
|
||||
}
|
||||
} else {
|
||||
varp->v3fatalSrc("InitArray under non-arrayed var");
|
||||
|
|
@ -1450,8 +1452,9 @@ void EmitCImp::emitVarReset(AstVar* varp) {
|
|||
else {
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
||||
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
|
||||
arrayp;
|
||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
|
|
@ -1588,7 +1591,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
|||
// OK if this hash includes some things we won't dump, since just looking for loading the wrong model
|
||||
VHashSha1 hash;
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
hash.insert(varp->name());
|
||||
hash.insert(varp->dtypep()->width());
|
||||
}
|
||||
|
|
@ -1604,7 +1607,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
|||
// Save all members
|
||||
if (v3Global.opt.inhibitSim()) puts("os"+op+"__Vm_inhibitSim;\n");
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isIO() && modp->isTop() && optSystemC()) {
|
||||
// System C top I/O doesn't need loading, as the lower level subinst code does it.
|
||||
}
|
||||
|
|
@ -1613,8 +1616,9 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
|||
else {
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
||||
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
|
||||
arrayp;
|
||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
|
|
@ -1658,7 +1662,7 @@ void EmitCImp::emitStaticDecl(AstNodeModule* modp) {
|
|||
void EmitCImp::emitTextSection(AstType type) {
|
||||
int last_line = -999;
|
||||
for (AstNode* nodep = m_modp->stmtsp(); nodep != NULL; nodep = nodep->nextp()) {
|
||||
if (AstNodeText* textp = nodep->castNodeText()) {
|
||||
if (const AstNodeText* textp = VN_CAST(nodep, NodeText)) {
|
||||
if (nodep->type() == type) {
|
||||
if (last_line != nodep->fileline()->lineno()) {
|
||||
if (last_line < 0) {
|
||||
|
|
@ -1687,7 +1691,7 @@ void EmitCImp::emitCellCtors(AstNodeModule* modp) {
|
|||
puts(EmitCBaseVisitor::symTopAssign()+"\n");
|
||||
}
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCell* cellp=nodep->castCell()) {
|
||||
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
|
||||
puts("VL_CELL ("+cellp->name()+", "+modClassName(cellp->modp())+");\n");
|
||||
}
|
||||
}
|
||||
|
|
@ -1700,12 +1704,13 @@ void EmitCImp::emitSensitives() {
|
|||
putsDecoration("// Sensitivities on all clocks and combo inputs\n");
|
||||
puts("SC_METHOD(eval);\n");
|
||||
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) {
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
||||
for (AstUnpackArrayDType* arrayp=VN_CAST(varp->dtypeSkipRefp(), UnpackArrayDType);
|
||||
arrayp;
|
||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
|
|
@ -1799,7 +1804,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
|||
// Largest->smallest reduces the number of pad variables.
|
||||
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
|
||||
// TODO: Move this sort to an earlier visitor stage.
|
||||
typedef std::multimap<int, AstVar*> VarSortMap;
|
||||
typedef std::multimap<int, const AstVar*> VarSortMap;
|
||||
VarSortMap varAnonMap;
|
||||
VarSortMap varNonanonMap;
|
||||
int anonMembers = 0;
|
||||
|
|
@ -1807,13 +1812,13 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
|||
for (int isstatic=1; isstatic>=0; isstatic--) {
|
||||
if (prefixIfImp!="" && !isstatic) continue;
|
||||
for (AstNode* nodep=firstp; nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
if (const AstVar* varp = VN_CAST(nodep, Var)) {
|
||||
bool doit = true;
|
||||
switch (which) {
|
||||
case EVL_CLASS_IO: doit = varp->isIO(); break;
|
||||
case EVL_CLASS_SIG: doit = (varp->isSignal() && !varp->isIO()); break;
|
||||
case EVL_CLASS_TEMP: doit = (varp->isTemp() && !varp->isIO()); break;
|
||||
case EVL_CLASS_PAR: doit = (varp->isParam() && !varp->valuep()->castConst()); break;
|
||||
case EVL_CLASS_PAR: doit = (varp->isParam() && !VN_IS(varp->valuep(), Const)); break;
|
||||
case EVL_CLASS_ALL: doit = true; break;
|
||||
case EVL_FUNC_ALL: doit = true; break;
|
||||
default: v3fatalSrc("Bad Case");
|
||||
|
|
@ -1823,7 +1828,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
|||
int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes();
|
||||
int sortbytes = 9;
|
||||
if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0;
|
||||
else if (varp->dtypeSkipRefp()->castUnpackArrayDType()) sortbytes=8;
|
||||
else if (VN_IS(varp->dtypeSkipRefp(), UnpackArrayDType)) sortbytes=8;
|
||||
else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7;
|
||||
else if (varp->isScBv() || varp->isScBigUint()) sortbytes=6;
|
||||
else if (sigbytes==8) sortbytes=5;
|
||||
|
|
@ -1873,7 +1878,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
|||
for (int l1=0; l1<anonL1s && it != varAnonMap.end(); ++l1) {
|
||||
if (anonL1s != 1) puts("struct {\n");
|
||||
for (int l0=0; l0<lim && it != varAnonMap.end(); ++l0) {
|
||||
AstVar* varp = it->second;
|
||||
const AstVar* varp = it->second;
|
||||
emitVarDecl(varp, prefixIfImp);
|
||||
++it;
|
||||
}
|
||||
|
|
@ -1885,13 +1890,13 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
|||
}
|
||||
// Leftovers, just in case off by one error somewhere above
|
||||
for (; it != varAnonMap.end(); ++it) {
|
||||
AstVar* varp = it->second;
|
||||
const AstVar* varp = it->second;
|
||||
emitVarDecl(varp, prefixIfImp);
|
||||
}
|
||||
}
|
||||
// Output nonanons
|
||||
for (VarSortMap::iterator it = varNonanonMap.begin(); it != varNonanonMap.end(); ++it) {
|
||||
AstVar* varp = it->second;
|
||||
const AstVar* varp = it->second;
|
||||
emitVarDecl(varp, prefixIfImp);
|
||||
}
|
||||
}
|
||||
|
|
@ -1903,10 +1908,11 @@ struct CmpName {
|
|||
};
|
||||
|
||||
void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
|
||||
std::vector<AstCFunc*> funcsp;
|
||||
typedef std::vector<const AstCFunc*> FuncVec;
|
||||
FuncVec funcsp;
|
||||
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCFunc* funcp = nodep->castCFunc()) {
|
||||
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
|
||||
if (!funcp->skipDecl()) {
|
||||
funcsp.push_back(funcp);
|
||||
}
|
||||
|
|
@ -1915,8 +1921,8 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
|
|||
|
||||
stable_sort(funcsp.begin(), funcsp.end(), CmpName());
|
||||
|
||||
for (std::vector<AstCFunc*>::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
|
||||
AstCFunc* funcp = *it;
|
||||
for (FuncVec::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
|
||||
const AstCFunc* funcp = *it;
|
||||
if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
|
||||
ofp()->putsPrivate(funcp->declPrivate());
|
||||
if (funcp->ifdef()!="") puts("#ifdef "+funcp->ifdef()+"\n");
|
||||
|
|
@ -1961,7 +1967,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||
puts("class "+symClassName()+";\n");
|
||||
vl_unordered_set<string> didClassName;
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCell* cellp=nodep->castCell()) {
|
||||
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
|
||||
string className = modClassName(cellp->modp());
|
||||
if (didClassName.find(className)==didClassName.end()) {
|
||||
puts("class "+className+";\n");
|
||||
|
|
@ -1987,7 +1993,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||
{ // Instantiated cells
|
||||
bool did = false;
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCell* cellp=nodep->castCell()) {
|
||||
if (AstCell* cellp=VN_CAST(nodep, Cell)) {
|
||||
if (!did) {
|
||||
did = true;
|
||||
putsDecoration("// CELLS\n");
|
||||
|
|
@ -2031,17 +2037,17 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
|||
ofp()->putsPrivate(false); // public:
|
||||
emitVarList(modp->stmtsp(), EVL_CLASS_PAR, ""); // Only those that are non-CONST
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
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?");
|
||||
// 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
|
||||
putsDecoration("// enum WData "+varp->name()+" //wide");
|
||||
} else if (!varp->valuep()->castConst()) { // Unsupported for output
|
||||
} else if (!VN_IS(varp->valuep(), Const)) { // Unsupported for output
|
||||
//putsDecoration("// enum ..... "+varp->name()+" //not simple value, see variable above instead");
|
||||
} else if (varp->dtypep()->castBasicDType()
|
||||
&& varp->dtypep()->castBasicDType()->isOpaque()) { // Can't put out e.g. doubles
|
||||
} else if (VN_IS(varp->dtypep(), BasicDType)
|
||||
&& VN_CAST(varp->dtypep(), BasicDType)->isOpaque()) { // Can't put out e.g. doubles
|
||||
} else {
|
||||
puts("enum ");
|
||||
puts(varp->isQuad()?"_QData":"_IData");
|
||||
|
|
@ -2226,7 +2232,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
|
|||
emitImp (modp);
|
||||
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCFunc* funcp = nodep->castCFunc()) {
|
||||
if (AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
|
||||
if (splitNeeded()) {
|
||||
// Close old file
|
||||
delete m_ofp; m_ofp=NULL;
|
||||
|
|
@ -2329,21 +2335,21 @@ class EmitCTrace : EmitCStmts {
|
|||
}
|
||||
|
||||
bool emitTraceIsScBv(AstTraceInc* nodep) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScBv();
|
||||
}
|
||||
|
||||
bool emitTraceIsScBigUint(AstTraceInc* nodep) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScBigUint();
|
||||
}
|
||||
|
||||
bool emitTraceIsScUint(AstTraceInc* nodep) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScUint();
|
||||
|
|
@ -2404,8 +2410,8 @@ class EmitCTrace : EmitCStmts {
|
|||
puts(");\n");
|
||||
}
|
||||
void emitTraceValue(AstTraceInc* nodep, int arrayindex) {
|
||||
if (nodep->valuep()->castVarRef()) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
if (VN_IS(nodep->valuep(), VarRef)) {
|
||||
AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef);
|
||||
AstVar* varp = varrefp->varp();
|
||||
puts("(");
|
||||
if (emitTraceIsScBigUint(nodep)) puts("(vluint32_t*)");
|
||||
|
|
@ -2534,7 +2540,7 @@ public:
|
|||
void V3EmitC::emitc() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
// Process each module in turn
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
if (v3Global.opt.outputSplit()) {
|
||||
{ EmitCImp imp; imp.main(nodep, false, true); }
|
||||
{ EmitCImp imp; imp.main(nodep, true, false); }
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ public:
|
|||
v3Global.rootp()->addFilesp(cfilep);
|
||||
return cfilep;
|
||||
}
|
||||
string cFuncArgs(AstCFunc* nodep) {
|
||||
string cFuncArgs(const AstCFunc* nodep) {
|
||||
// Return argument list for given C function
|
||||
string args = nodep->argTypes();
|
||||
// Might be a user function with argument list.
|
||||
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
for (const AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (const AstVar* portp = VN_CAST_CONST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
if (args != "") args+= ", ";
|
||||
if (nodep->dpiImport() || nodep->dpiExportWrapper())
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ void EmitCSyms::emitSymHdr() {
|
|||
|
||||
// for
|
||||
puts("\n// INCLUDE MODULE CLASSES\n");
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
puts("#include \""+modClassName(nodep)+".h\"\n");
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +369,7 @@ void EmitCSyms::emitSymImp() {
|
|||
|
||||
// Includes
|
||||
puts("#include \""+symClassName()+".h\"\n");
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
puts("#include \""+modClassName(nodep)+".h\"\n");
|
||||
}
|
||||
|
||||
|
|
@ -481,10 +481,10 @@ void EmitCSyms::emitSymImp() {
|
|||
}
|
||||
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
bounds += " ,"; bounds += cvtToStr(adtypep->msb());
|
||||
bounds += ","; bounds += cvtToStr(adtypep->lsb());
|
||||
if (dtypep->castPackArrayDType()) pdim++; else udim++;
|
||||
if (VN_IS(dtypep, PackArrayDType)) pdim++; else udim++;
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
else break; // AstBasicDType - nothing below, 1
|
||||
|
|
@ -628,7 +628,7 @@ void EmitCSyms::emitDpiImp() {
|
|||
puts("return "+topClassName()+"::"+nodep->name()+"(");
|
||||
string args;
|
||||
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
if (args != "") args+= ", ";
|
||||
args += portp->name();
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public:
|
|||
else if (support==2 && slow) {
|
||||
}
|
||||
else {
|
||||
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) {
|
||||
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=VN_CAST(nodep->nextp(), CFile)) {
|
||||
if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) {
|
||||
putMakeClassEntry(of, nodep->name());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstNodeCase* nodep) {
|
||||
putfs(nodep,"");
|
||||
if (AstCase* casep = nodep->castCase()) {
|
||||
if (const AstCase* casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->priorityPragma()) puts("priority ");
|
||||
if (casep->uniquePragma()) puts("unique ");
|
||||
if (casep->unique0Pragma()) puts("unique0 ");
|
||||
|
|
@ -179,7 +179,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
puts(" (");
|
||||
nodep->exprp()->iterateAndNext(*this);
|
||||
puts(")\n");
|
||||
if (AstCase* casep = nodep->castCase()) {
|
||||
if (const AstCase* casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->fullPragma() || casep->parallelPragma()) {
|
||||
puts(" // synopsys");
|
||||
if (casep->fullPragma()) puts(" full_case");
|
||||
|
|
@ -316,7 +316,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
putfs(nodep,"");
|
||||
if (AstIf* ifp = nodep->castIf()) {
|
||||
if (const AstIf* ifp = VN_CAST(nodep, If)) {
|
||||
if (ifp->priorityPragma()) puts("priority ");
|
||||
if (ifp->uniquePragma()) puts("unique ");
|
||||
if (ifp->unique0Pragma()) puts("unique0 ");
|
||||
|
|
@ -462,10 +462,10 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstRange* nodep) {
|
||||
puts("[");
|
||||
if (nodep->msbp()->castConst() && nodep->lsbp()->castConst()) {
|
||||
if (VN_IS(nodep->msbp(), Const) && VN_IS(nodep->lsbp(), Const)) {
|
||||
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
|
||||
puts(cvtToStr(nodep->leftp()->castConst()->toSInt())); puts(":");
|
||||
puts(cvtToStr(nodep->rightp()->castConst()->toSInt())); puts("]");
|
||||
puts(cvtToStr(VN_CAST(nodep->leftp(), Const)->toSInt())); puts(":");
|
||||
puts(cvtToStr(VN_CAST(nodep->rightp(), Const)->toSInt())); puts("]");
|
||||
} else {
|
||||
nodep->leftp()->iterateAndNext(*this); puts(":");
|
||||
nodep->rightp()->iterateAndNext(*this); puts("]");
|
||||
|
|
@ -473,19 +473,19 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
virtual void visit(AstSel* nodep) {
|
||||
nodep->fromp()->iterateAndNext(*this); puts("[");
|
||||
if (nodep->lsbp()->castConst()) {
|
||||
if (VN_IS(nodep->lsbp(), Const)) {
|
||||
if (nodep->widthp()->isOne()) {
|
||||
if (nodep->lsbp()->castConst()) {
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()));
|
||||
if (VN_IS(nodep->lsbp(), Const)) {
|
||||
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()));
|
||||
} else {
|
||||
nodep->lsbp()->iterateAndNext(*this);
|
||||
}
|
||||
} else {
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()
|
||||
+nodep->widthp()->castConst()->toSInt()
|
||||
-1));
|
||||
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()
|
||||
+ VN_CAST(nodep->widthp(), Const)->toSInt()
|
||||
- 1));
|
||||
puts(":");
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()));
|
||||
puts(cvtToStr(VN_CAST(nodep->lsbp(), Const)->toSInt()));
|
||||
}
|
||||
} else {
|
||||
nodep->lsbp()->iterateAndNext(*this); putfs(nodep,"+:");
|
||||
|
|
@ -725,7 +725,7 @@ void V3EmitV::emitv() {
|
|||
EmitVFileVisitor visitor (v3Global.rootp(), &of);
|
||||
} else {
|
||||
// Process each module in turn
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
|
||||
V3OutVFile of (v3Global.opt.makeDir()
|
||||
+"/"+EmitCBaseVisitor::modClassName(modp)+"__Vout.v");
|
||||
of.putsHeader();
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ class EmitXmlFileVisitor : public AstNVisitor {
|
|||
void outputTag(AstNode* nodep, string tag) {
|
||||
if (tag=="") tag = VString::downcase(nodep->typeName());
|
||||
puts("<"+tag+" "+nodep->fileline()->xml());
|
||||
if (nodep->castNodeDType()) { puts(" id="); outputId(nodep); }
|
||||
if (VN_IS(nodep, NodeDType)) { puts(" id="); outputId(nodep); }
|
||||
if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); }
|
||||
if (nodep->tag()!="") { puts(" tag="); putsQuoted(nodep->tag()); }
|
||||
if (AstNodeDType* dtp = nodep->castNodeDType()) {
|
||||
if (AstNodeDType* dtp = VN_CAST(nodep, NodeDType)) {
|
||||
if (dtp->subDTypep()) { puts(" sub_dtype_id="); outputId(dtp->subDTypep()->skipRefp()); }
|
||||
} else {
|
||||
if (nodep->dtypep()) { puts(" dtype_id="); outputId(nodep->dtypep()->skipRefp()); }
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ private:
|
|||
void fixCloneLvalue (AstNode* nodep) {
|
||||
// In AstSel transforms, we call clone() on VarRefs that were lvalues,
|
||||
// but are now being used on the RHS of the assignment
|
||||
if (nodep->castVarRef()) nodep->castVarRef()->lvalue(false);
|
||||
if (VN_IS(nodep, VarRef)) VN_CAST(nodep, VarRef)->lvalue(false);
|
||||
// Iterate
|
||||
if (nodep->op1p()) fixCloneLvalue(nodep->op1p());
|
||||
if (nodep->op2p()) fixCloneLvalue(nodep->op2p());
|
||||
|
|
@ -178,9 +178,9 @@ private:
|
|||
|
||||
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
|
||||
// Return equation to get the VL_BITWORD of a constant or non-constant
|
||||
if (lsbp->castConst()) {
|
||||
if (VN_IS(lsbp, Const)) {
|
||||
return new AstConst (lsbp->fileline(),
|
||||
wordAdder + VL_BITWORD_I(lsbp->castConst()->toUInt()));
|
||||
wordAdder + VL_BITWORD_I(VN_CAST(lsbp, Const)->toUInt()));
|
||||
} else {
|
||||
AstNode* shiftp = new AstShiftR (lsbp->fileline(),
|
||||
lsbp->cloneTree(true),
|
||||
|
|
@ -201,17 +201,17 @@ private:
|
|||
// If there's a CONDBOUND safety to keep arrays in bounds,
|
||||
// we're going to AND it to a value that always fits inside a
|
||||
// word, so we don't need it.
|
||||
//if (nodep->castCondBound() && nodep->castCondBound()->lhsp()->castLte()) {
|
||||
// nodep = nodep->castCondBound()->rhsp();
|
||||
//if (VN_IS(nodep, CondBound) && VN_IS(VN_CAST(nodep, CondBound)->lhsp(), Lte)) {
|
||||
// nodep = VN_CAST(nodep, CondBound)->rhsp();
|
||||
//}
|
||||
return nodep;
|
||||
}
|
||||
|
||||
AstNode* newSelBitBit(AstNode* lsbp) {
|
||||
// Return equation to get the VL_BITBIT of a constant or non-constant
|
||||
if (lsbp->castConst()) {
|
||||
if (VN_IS(lsbp, Const)) {
|
||||
return new AstConst (lsbp->fileline(),
|
||||
VL_BITBIT_I(lsbp->castConst()->toUInt()));
|
||||
VL_BITBIT_I(VN_CAST(lsbp, Const)->toUInt()));
|
||||
} else {
|
||||
return new AstAnd (lsbp->fileline(),
|
||||
new AstConst(lsbp->fileline(), VL_WORDSIZE-1),
|
||||
|
|
@ -243,7 +243,7 @@ private:
|
|||
}
|
||||
bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) {
|
||||
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
|
||||
if (nodep->dtypep()->skipRefp()->castUnpackArrayDType()) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||
for (int w=0; w<nodep->widthWords(); w++) {
|
||||
addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
|
||||
}
|
||||
|
|
@ -352,7 +352,7 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
// Remember, Sel's may have non-integer rhs, so need to optimize for that!
|
||||
if (nodep->widthMin()!=(int)nodep->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
if (nodep->backp()->castNodeAssign() && nodep==nodep->backp()->castNodeAssign()->lhsp()) {
|
||||
if (VN_IS(nodep->backp(), NodeAssign) && nodep==VN_CAST(nodep->backp(), NodeAssign)->lhsp()) {
|
||||
// Sel is an LHS assignment select
|
||||
} else if (nodep->isWide()) {
|
||||
// See under ASSIGN(WIDE)
|
||||
|
|
@ -460,7 +460,7 @@ private:
|
|||
|
||||
bool expandWide (AstNodeAssign* nodep, AstSel* rhsp) {
|
||||
if (nodep->widthMin()!=(int)rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
if (rhsp->lsbp()->castConst() && VL_BITBIT_I(rhsp->lsbConst())==0) {
|
||||
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
|
||||
int lsb = rhsp->lsbConst();
|
||||
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
|
||||
for (int w=0; w<nodep->widthWords(); w++) {
|
||||
|
|
@ -513,7 +513,7 @@ private:
|
|||
// Yuk.
|
||||
bool destwide = lhsp->fromp()->isWide();
|
||||
bool ones = nodep->rhsp()->isAllOnesV();
|
||||
if (lhsp->lsbp()->castConst()) {
|
||||
if (VN_IS(lhsp->lsbp(), Const)) {
|
||||
// The code should work without this constant test, but it won't
|
||||
// constify as nicely as we'd like.
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
|
|
@ -702,7 +702,7 @@ private:
|
|||
newp = new AstNegate (nodep->fileline(), lhsp);
|
||||
} else {
|
||||
UINFO(8," REPLICATE "<<nodep<<endl);
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) nodep->v3fatalSrc("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);
|
||||
|
|
@ -727,7 +727,7 @@ private:
|
|||
UINFO(8," Wordize ASSIGN(REPLICATE) "<<nodep<<endl);
|
||||
AstNode* lhsp = rhsp->lhsp();
|
||||
int lhswidth = lhsp->widthMin();
|
||||
AstConst* constp = rhsp->rhsp()->castConst();
|
||||
const AstConst* constp = VN_CAST(rhsp->rhsp(), Const);
|
||||
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->toUInt();
|
||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||
|
|
@ -777,7 +777,7 @@ private:
|
|||
newAstWordSelClone (nodep->rhsp(), w));
|
||||
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
|
||||
}
|
||||
if (nodep->castNeq()) {
|
||||
if (VN_IS(nodep, Neq)) {
|
||||
newp = new AstNeq (nodep->fileline(),
|
||||
new AstConst (nodep->fileline(), 0), newp);
|
||||
} else {
|
||||
|
|
@ -873,36 +873,36 @@ private:
|
|||
m_stmtp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
bool did = false;
|
||||
if (nodep->isWide() && ((nodep->lhsp()->castVarRef()
|
||||
|| nodep->lhsp()->castArraySel()))
|
||||
if (nodep->isWide() && ((VN_IS(nodep->lhsp(), VarRef)
|
||||
|| VN_IS(nodep->lhsp(), ArraySel)))
|
||||
&& !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC
|
||||
&& !AstVar::scVarRecurse(nodep->rhsp())) {
|
||||
if (AstConst* rhsp = nodep->rhsp()->castConst()) {
|
||||
if (AstConst* rhsp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) {
|
||||
} else if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstSel* rhsp = nodep->rhsp()->castSel()) {
|
||||
} else if (AstSel* rhsp = VN_CAST(nodep->rhsp(), Sel)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) {
|
||||
} else if (AstArraySel* rhsp = VN_CAST(nodep->rhsp(), ArraySel)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstConcat* rhsp = nodep->rhsp()->castConcat()) {
|
||||
} else if (AstConcat* rhsp = VN_CAST(nodep->rhsp(), Concat)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstReplicate* rhsp = nodep->rhsp()->castReplicate()) {
|
||||
} else if (AstReplicate* rhsp = VN_CAST(nodep->rhsp(), Replicate)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstAnd* rhsp = nodep->rhsp()->castAnd()) {
|
||||
} else if (AstAnd* rhsp = VN_CAST(nodep->rhsp(), And)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstOr* rhsp = nodep->rhsp()->castOr()) {
|
||||
} else if (AstOr* rhsp = VN_CAST(nodep->rhsp(), Or)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstNot* rhsp = nodep->rhsp()->castNot()) {
|
||||
} else if (AstNot* rhsp = VN_CAST(nodep->rhsp(), Not)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstXor* rhsp = nodep->rhsp()->castXor()) {
|
||||
} else if (AstXor* rhsp = VN_CAST(nodep->rhsp(), Xor)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstXnor* rhsp = nodep->rhsp()->castXnor()) {
|
||||
} else if (AstXnor* rhsp = VN_CAST(nodep->rhsp(), Xnor)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
} else if (AstNodeCond* rhsp = nodep->rhsp()->castNodeCond()) {
|
||||
} else if (AstNodeCond* rhsp = VN_CAST(nodep->rhsp(), NodeCond)) {
|
||||
did = expandWide(nodep,rhsp);
|
||||
}
|
||||
} else if (AstSel* lhsp = nodep->lhsp()->castSel()) {
|
||||
} else if (AstSel* lhsp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
did = expandLhs(nodep,lhsp);
|
||||
}
|
||||
// Cleanup common code
|
||||
|
|
|
|||
|
|
@ -234,19 +234,19 @@ private:
|
|||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
m_substTreep = nodep->rhsp();
|
||||
if (!nodep->lhsp()->castNodeVarRef())
|
||||
if (!VN_IS(nodep->lhsp(), NodeVarRef))
|
||||
clearSimple("ASSIGN(non-VARREF)");
|
||||
else nodep->iterateChildren(*this);
|
||||
// We don't push logic other then assignments/NOTs into SenItems
|
||||
// This avoids a mess in computing what exactly a POSEDGE is
|
||||
// V3Const cleans up any NOTs by flipping the edges for us
|
||||
if (m_buffersOnly
|
||||
&& !(nodep->rhsp()->castVarRef()
|
||||
&& !(VN_IS(nodep->rhsp(), VarRef)
|
||||
// Avoid making non-clocked logic into clocked,
|
||||
// as it slows down the verilator_sim_benchmark
|
||||
|| (nodep->rhsp()->castNot()
|
||||
&& nodep->rhsp()->castNot()->lhsp()->castVarRef()
|
||||
&& nodep->rhsp()->castNot()->lhsp()->castVarRef()->varp()->isUsedClock())
|
||||
|| (VN_IS(nodep->rhsp(), Not)
|
||||
&& VN_IS(VN_CAST(nodep->rhsp(), Not)->lhsp(), VarRef)
|
||||
&& VN_CAST(VN_CAST(nodep->rhsp(), Not)->lhsp(), VarRef)->varp()->isUsedClock())
|
||||
)) {
|
||||
clearSimple("Not a buffer (goes to a clock)");
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ private:
|
|||
m_logicVertexp->clearReducible("Block Unreducible"); // Sequential logic is dedupable
|
||||
}
|
||||
if (consumeReason) m_logicVertexp->setConsumed(consumeReason);
|
||||
if (nodep->castSenItem()) m_logicVertexp->setConsumed("senItem");
|
||||
if (VN_IS(nodep, SenItem)) m_logicVertexp->setConsumed("senItem");
|
||||
nodep->iterateChildren(*this);
|
||||
m_logicVertexp = NULL;
|
||||
}
|
||||
|
|
@ -508,7 +508,7 @@ private:
|
|||
m_inSlow = lastslow;
|
||||
}
|
||||
virtual void visit(AstConcat* nodep) {
|
||||
if (nodep->backp()->castNodeAssign() && nodep->backp()->castNodeAssign()->lhsp()==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");
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -702,31 +702,31 @@ void GateVisitor::replaceAssigns() {
|
|||
// Take the Comments/assigns that were moved to the VarScope and change them to a
|
||||
// simple value assignment
|
||||
AstVarScope* vscp = vvertexp->varScp();
|
||||
if (vscp->valuep() && !vscp->valuep()->castNodeMath()) {
|
||||
if (vscp->valuep() && !VN_IS(vscp->valuep(), NodeMath)) {
|
||||
//if (debug()>9) vscp->dumpTree(cout, "-vscPre: ");
|
||||
while (AstNode* delp=vscp->valuep()->castComment()) {
|
||||
while (AstNode* delp=VN_CAST(vscp->valuep(), Comment)) {
|
||||
delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp);
|
||||
}
|
||||
if (AstInitial* delp=vscp->valuep()->castInitial()) {
|
||||
if (AstInitial* delp=VN_CAST(vscp->valuep(), Initial)) {
|
||||
AstNode* bodyp=delp->bodysp();
|
||||
bodyp->unlinkFrBackWithNext();
|
||||
delp->replaceWith(bodyp);
|
||||
delp->deleteTree(); VL_DANGLING(delp);
|
||||
}
|
||||
if (AstAlways* delp=vscp->valuep()->castAlways()) {
|
||||
if (AstAlways* delp=VN_CAST(vscp->valuep(), Always)) {
|
||||
AstNode* bodyp=delp->bodysp();
|
||||
bodyp->unlinkFrBackWithNext();
|
||||
delp->replaceWith(bodyp);
|
||||
delp->deleteTree(); VL_DANGLING(delp);
|
||||
}
|
||||
if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) {
|
||||
if (AstNodeAssign* delp=VN_CAST(vscp->valuep(), NodeAssign)) {
|
||||
AstNode* rhsp=delp->rhsp();
|
||||
rhsp->unlinkFrBack();
|
||||
delp->replaceWith(rhsp);
|
||||
delp->deleteTree(); VL_DANGLING(delp);
|
||||
}
|
||||
//if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<<endl;}
|
||||
if (!vscp->valuep()->castNodeMath()
|
||||
if (!VN_IS(vscp->valuep(), NodeMath)
|
||||
|| vscp->valuep()->nextp()) {
|
||||
vscp->dumpTree(std::cerr, "vscStrange: ");
|
||||
vscp->v3fatalSrc("Value of varscope not mathematical");
|
||||
|
|
@ -829,8 +829,8 @@ private:
|
|||
m_didReplace = true;
|
||||
if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var");
|
||||
AstNode* substp = m_replaceTreep->cloneTree(false);
|
||||
if (nodep->castNodeVarRef()
|
||||
&& substp->castNodeVarRef()
|
||||
if (VN_IS(nodep, NodeVarRef)
|
||||
&& VN_IS(substp, NodeVarRef)
|
||||
&& nodep->same(substp)) {
|
||||
// Prevent a infinite loop...
|
||||
substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?");
|
||||
|
|
@ -840,9 +840,9 @@ private:
|
|||
// IE what we're replacing with.
|
||||
// However a VARREF should point to the original as it's otherwise confusing
|
||||
// to throw warnings that point to a PIN rather than where the pin us used.
|
||||
if (substp->castVarRef()) substp->fileline(nodep->fileline());
|
||||
if (VN_IS(substp, VarRef)) substp->fileline(nodep->fileline());
|
||||
// Make the substp an rvalue like nodep. This facilitate the hashing in dedupe.
|
||||
if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false);
|
||||
if (AstNodeVarRef* varrefp = VN_CAST(substp, NodeVarRef)) varrefp->lvalue(false);
|
||||
nodep->replaceWith(substp);
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
|
@ -929,7 +929,7 @@ public:
|
|||
// So dupit is either a different, duplicate rhsp, or the end of the hash.
|
||||
if (dupit != m_hashed.end()) {
|
||||
m_hashed.erase(inserted);
|
||||
return m_hashed.iteratorNodep(dupit)->user2p()->castNodeAssign();
|
||||
return VN_CAST(m_hashed.iteratorNodep(dupit)->user2p(), NodeAssign);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1017,7 +1017,7 @@ public:
|
|||
if (m_dedupable && m_assignp) {
|
||||
AstNode* lhsp = m_assignp->lhsp();
|
||||
// Possible todo, handle more complex lhs expressions
|
||||
if (AstNodeVarRef* lhsVarRefp = lhsp->castNodeVarRef()) {
|
||||
if (AstNodeVarRef* lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
|
||||
if (lhsVarRefp->varScopep() != consumerVarScopep) consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign");
|
||||
if (AstNodeAssign* dup = m_hash.hashAndFindDupe(m_assignp,activep,m_ifCondp)) {
|
||||
return (AstNodeVarRef*) dup->lhsp();
|
||||
|
|
@ -1157,13 +1157,13 @@ private:
|
|||
|
||||
// assemble two Sel into one if possible
|
||||
AstSel* merge(AstSel* pre, AstSel* cur) {
|
||||
AstVarRef* preVarRefp = pre->fromp()->castVarRef();
|
||||
AstVarRef* curVarRefp = cur->fromp()->castVarRef();
|
||||
AstVarRef* preVarRefp = VN_CAST(pre->fromp(), VarRef);
|
||||
AstVarRef* curVarRefp = VN_CAST(cur->fromp(), VarRef);
|
||||
if (!preVarRefp || !curVarRefp || !curVarRefp->same(preVarRefp)) return NULL; // not the same var
|
||||
AstConst* pstart = pre->lsbp()->castConst();
|
||||
AstConst* pwidth = pre->widthp()->castConst();
|
||||
AstConst* cstart = cur->lsbp()->castConst();
|
||||
AstConst* cwidth = cur->widthp()->castConst();
|
||||
const AstConst* pstart = VN_CAST(pre->lsbp(), Const);
|
||||
const AstConst* pwidth = VN_CAST(pre->widthp(), Const);
|
||||
const AstConst* cstart = VN_CAST(cur->lsbp(), Const);
|
||||
const AstConst* cwidth = VN_CAST(cur->widthp(), Const);
|
||||
if (!pstart || !pwidth || !cstart || !cwidth) return NULL; // too complicated
|
||||
if (cur->lsbConst()+cur->widthConst() == pre->lsbConst())
|
||||
return new AstSel(curVarRefp->fileline(), curVarRefp->cloneTree(false), cur->lsbConst(), pre->widthConst()+cur->widthConst());
|
||||
|
|
@ -1175,10 +1175,10 @@ private:
|
|||
V3GraphEdge* oldedgep = edgep;
|
||||
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
|
||||
if (GateLogicVertex* lvertexp = dynamic_cast<GateLogicVertex*>(oldedgep->fromp())) {
|
||||
if (AstNodeAssign* assignp = lvertexp->nodep()->castNodeAssign()) {
|
||||
//if (lvertexp->outSize1() && assignp->lhsp()->castSel()) {
|
||||
if (assignp->lhsp()->castSel() && lvertexp->outSize1()) {
|
||||
UINFO(9, "assing to the nodep["<<assignp->lhsp()->castSel()->lsbConst()<<"]"<<endl);
|
||||
if (AstNodeAssign* assignp = VN_CAST(lvertexp->nodep(), NodeAssign)) {
|
||||
//if (lvertexp->outSize1() && VN_IS(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(assignp->lhsp(), Sel) && lvertexp->outSize1()) {
|
||||
UINFO(9, "assing to the nodep["<<VN_CAST(assignp->lhsp(), Sel)->lsbConst()<<"]"<<endl);
|
||||
// first assign with Sel-lhs
|
||||
if (!m_activep) m_activep = lvertexp->activep();
|
||||
if (!m_logicvp) m_logicvp = lvertexp;
|
||||
|
|
@ -1192,8 +1192,8 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
AstSel* preselp = m_assignp->lhsp()->castSel();
|
||||
AstSel* curselp = assignp->lhsp()->castSel();
|
||||
AstSel* preselp = VN_CAST(m_assignp->lhsp(), Sel);
|
||||
AstSel* curselp = VN_CAST(assignp->lhsp(), Sel);
|
||||
if (!preselp || !curselp) continue;
|
||||
|
||||
if (AstSel* newselp = merge(preselp, curselp)) {
|
||||
|
|
@ -1370,10 +1370,10 @@ private:
|
|||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) {
|
||||
GateClkDecompState* currState = (GateClkDecompState*) vu.c();
|
||||
int clk_offset = currState->m_offset;
|
||||
if (AstAssignW* assignp = lvertexp->nodep()->castAssignW()) {
|
||||
if (const AstAssignW* assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
|
||||
UINFO(9,"CLK DECOMP Logic (off = "<<clk_offset<<") - "<<lvertexp<<" : "<<m_clk_vsp<<endl);
|
||||
if (AstSel* rselp = assignp->rhsp()->castSel()) {
|
||||
if (rselp->lsbp()->castConst() && rselp->widthp()->castConst()) {
|
||||
if (AstSel* rselp = VN_CAST(assignp->rhsp(), Sel)) {
|
||||
if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) {
|
||||
if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) {
|
||||
UINFO(9,"CLK DECOMP Sel [ "<<rselp->msbConst()<<" : "<<rselp->lsbConst()<<" ] dropped clock ("<<clk_offset<<")"<<endl);
|
||||
return VNUser(0);
|
||||
|
|
@ -1382,7 +1382,7 @@ private:
|
|||
} else {
|
||||
return VNUser(0);
|
||||
}
|
||||
} else if (AstConcat* catp = assignp->rhsp()->castConcat()) {
|
||||
} else if (AstConcat* catp = VN_CAST(assignp->rhsp(), Concat)) {
|
||||
UINFO(9,"CLK DECOMP Concat searching - "<<assignp->lhsp()<<endl);
|
||||
int concat_offset;
|
||||
if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp, concat_offset)) {
|
||||
|
|
@ -1390,13 +1390,13 @@ private:
|
|||
}
|
||||
clk_offset += concat_offset;
|
||||
}
|
||||
if (AstSel* lselp = assignp->lhsp()->castSel()) {
|
||||
if (lselp->lsbp()->castConst() && lselp->widthp()->castConst()) {
|
||||
if (const AstSel* lselp = VN_CAST(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(lselp->lsbp(), Const) && VN_IS(lselp->widthp(), Const)) {
|
||||
clk_offset += lselp->lsbConst();
|
||||
} else {
|
||||
return VNUser(0);
|
||||
}
|
||||
} else if (AstVarRef* vrp = assignp->lhsp()->castVarRef()) {
|
||||
} else if (const AstVarRef* vrp = VN_CAST(assignp->lhsp(), VarRef)) {
|
||||
if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) {
|
||||
if (clk_offset != 0) {
|
||||
UINFO(9,"Should only make it here with clk_offset = 0"<<endl);
|
||||
|
|
@ -1468,7 +1468,7 @@ class GateDeassignVisitor : public GateBaseVisitor {
|
|||
private:
|
||||
// VISITORS
|
||||
virtual void visit(AstVarScope* nodep) {
|
||||
if (AstNodeAssign* assp = nodep->valuep()->castNodeAssign()) {
|
||||
if (AstNodeAssign* assp = VN_CAST(nodep->valuep(), NodeAssign)) {
|
||||
UINFO(5," Removeassign "<<assp<<endl);
|
||||
AstNode* valuep = assp->rhsp();
|
||||
valuep->unlinkFrBack();
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ private:
|
|||
// METHODS
|
||||
AstVarScope* genInpClk(AstVarScope* vscp) {
|
||||
if (vscp->user2p()) {
|
||||
return vscp->user2p()->castVarScope();
|
||||
return VN_CAST(vscp->user2p(), VarScope);
|
||||
} else {
|
||||
AstVar* varp = vscp->varp();
|
||||
string newvarname = "__VinpClk__"+vscp->scopep()->nameDotless()+"__"+varp->name();
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ private:
|
|||
// METHODS
|
||||
void nodeHashIterate(AstNode* nodep) {
|
||||
if (!nodep->user4()) {
|
||||
if (nodep->backp()->castCFunc()
|
||||
&& !(nodep->castNodeStmt() || nodep->castCFunc())) {
|
||||
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)");
|
||||
}
|
||||
V3Hash oldHash = m_lowerHash;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ private:
|
|||
m_allMods.push_back(nodep);
|
||||
m_modp->user2(CIL_MAYBE);
|
||||
m_modp->user4(0); // statement count
|
||||
if (m_modp->castIface()) {
|
||||
if (VN_IS(m_modp, Iface)) {
|
||||
// Inlining an interface means we no longer have a cell handle to resolve to.
|
||||
// If inlining moves post-scope this can perhaps be relaxed.
|
||||
cantInline("modIface",true);
|
||||
|
|
@ -200,7 +200,7 @@ private:
|
|||
|| v3Global.opt.inlineMult() < 1
|
||||
|| refs*statements < v3Global.opt.inlineMult())));
|
||||
// Packages aren't really "under" anything so they confuse this algorithm
|
||||
if (modp->castPackage()) doit = false;
|
||||
if (VN_IS(modp, Package)) doit = false;
|
||||
UINFO(4, " Inline="<<doit<<" Possible="<<allowed
|
||||
<<" Refs="<<refs<<" Stmts="<<statements<<" "<<modp<<endl);
|
||||
modp->user1(doit);
|
||||
|
|
@ -313,8 +313,8 @@ private:
|
|||
if (nodep->user2p()) {
|
||||
// Make an assignment, so we'll trace it properly
|
||||
// user2p is either a const or a var.
|
||||
AstConst* exprconstp = nodep->user2p()->castConst();
|
||||
AstVarRef* exprvarrefp = nodep->user2p()->castVarRef();
|
||||
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");
|
||||
|
|
@ -350,16 +350,16 @@ private:
|
|||
}
|
||||
}
|
||||
// Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module
|
||||
if (AstIfaceRefDType* ifacerefp = nodep->dtypep()->castIfaceRefDType()) {
|
||||
if (AstIfaceRefDType* ifacerefp = VN_CAST(nodep->dtypep(), IfaceRefDType)) {
|
||||
m_renamedInterfaces.insert(nodep->name());
|
||||
// Each inlined cell that contain an interface variable need to copy the IfaceRefDType and point it to
|
||||
// the newly cloned interface cell.
|
||||
AstIfaceRefDType* newdp = ifacerefp->cloneTree(false)->castIfaceRefDType();
|
||||
AstIfaceRefDType* newdp = VN_CAST(ifacerefp->cloneTree(false), IfaceRefDType);
|
||||
nodep->dtypep(newdp);
|
||||
ifacerefp->addNextHere(newdp);
|
||||
// Relink to point to newly cloned cell
|
||||
if (newdp->cellp()) {
|
||||
if (AstCell* newcellp = newdp->cellp()->user4p()->castCell()) {
|
||||
if (AstCell* newcellp = VN_CAST(newdp->cellp()->user4p(), Cell)) {
|
||||
newdp->cellp(newcellp);
|
||||
newdp->cellName(newcellp->name());
|
||||
// Tag the old ifacerefp to ensure it leaves no stale reference to the inlined cell.
|
||||
|
|
@ -390,9 +390,9 @@ private:
|
|||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp()->user2p() // It's being converted to an alias.
|
||||
&& !nodep->varp()->user3()
|
||||
&& !nodep->backp()->castAssignAlias()) { // Don't constant propagate aliases (we just made)
|
||||
AstConst* exprconstp = nodep->varp()->user2p()->castConst();
|
||||
AstVarRef* exprvarrefp = nodep->varp()->user2p()->castVarRef();
|
||||
&& !VN_IS(nodep->backp(), AssignAlias)) { // Don't constant propagate aliases (we just made)
|
||||
AstConst* exprconstp = VN_CAST(nodep->varp()->user2p(), Const);
|
||||
AstVarRef* exprvarrefp = VN_CAST(nodep->varp()->user2p(), VarRef);
|
||||
if (exprconstp) {
|
||||
nodep->replaceWith(exprconstp->cloneTree(true));
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
@ -535,7 +535,7 @@ private:
|
|||
// Better off before, as if module has multiple instantiations
|
||||
// we'll save work, and we can't call pinReconnectSimple in
|
||||
// this loop as it clone()s itself.
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (!pinp->exprp()) continue;
|
||||
V3Inst::pinReconnectSimple(pinp, nodep, m_modp, false);
|
||||
}
|
||||
|
|
@ -554,7 +554,7 @@ private:
|
|||
nodep->name(), nodep->modp()->origName());
|
||||
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
|
||||
// Create assignments to the pins
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (!pinp->exprp()) continue;
|
||||
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
|
||||
// Make new signal; even though we'll optimize the interconnect, we
|
||||
|
|
@ -565,17 +565,17 @@ private:
|
|||
if (!pinNewVarp) pinOldVarp->v3fatalSrc("Cloning failed");
|
||||
|
||||
AstNode* connectRefp = pinp->exprp();
|
||||
if (!connectRefp->castConst() && !connectRefp->castVarRef()) {
|
||||
if (!VN_IS(connectRefp, Const) && !VN_IS(connectRefp, VarRef)) {
|
||||
pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up");
|
||||
}
|
||||
if (pinNewVarp->isOutOnly() && connectRefp->castConst()) {
|
||||
if (pinNewVarp->isOutOnly() && VN_IS(connectRefp, Const)) {
|
||||
pinp->v3error("Output port is connected to a constant pin, electrical short");
|
||||
}
|
||||
|
||||
// Propagate any attributes across the interconnect
|
||||
pinNewVarp->propagateAttrFrom(pinOldVarp);
|
||||
if (connectRefp->castVarRef()) {
|
||||
connectRefp->castVarRef()->varp()->propagateAttrFrom(pinOldVarp);
|
||||
if (VN_IS(connectRefp, VarRef)) {
|
||||
VN_CAST(connectRefp, VarRef)->varp()->propagateAttrFrom(pinOldVarp);
|
||||
}
|
||||
|
||||
// One to one interconnect won't make a temporary variable.
|
||||
|
|
@ -641,7 +641,7 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
|
|||
// idea to avoid dumping the hugely exploded tree.
|
||||
AstNodeModule* nextmodp;
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
|
||||
nextmodp = modp->nextp()->castNodeModule();
|
||||
nextmodp = VN_CAST(modp->nextp(), NodeModule);
|
||||
if (modp->user1()) { // Was inlined
|
||||
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ private:
|
|||
UINFO(4," PIN "<<nodep<<endl);
|
||||
if (!nodep->exprp()) return; // No-connect
|
||||
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
|
||||
if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst())
|
||||
if (nodep->modVarp()->isOutOnly() && VN_IS(nodep->exprp(), Const))
|
||||
nodep->v3error("Output port is connected to a constant pin, electrical short");
|
||||
// Use user1p on the PIN to indicate we created an assign for this pin
|
||||
if (!nodep->user1SetOnce()) {
|
||||
|
|
@ -107,12 +107,12 @@ private:
|
|||
m_modp->addStmtp(assp);
|
||||
if (debug()>=9) assp->dumpTree(cout," _new: ");
|
||||
} else if (nodep->modVarp()->isIfaceRef()
|
||||
|| (nodep->modVarp()->subDTypep()->castUnpackArrayDType()
|
||||
&& nodep->modVarp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())) {
|
||||
|| (VN_IS(nodep->modVarp()->subDTypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_CAST(nodep->modVarp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))) {
|
||||
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
||||
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||
AstVarRef* refp = exprp->castVarRef();
|
||||
AstVarXRef* xrefp = exprp->castVarXRef();
|
||||
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");
|
||||
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
|
||||
m_modp->addStmtp(assp);
|
||||
|
|
@ -169,7 +169,7 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstVar* nodep) {
|
||||
if (nodep->dtypep()->castIfaceRefDType()) {
|
||||
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
|
||||
UINFO(8," dm-1-VAR "<<nodep<<endl);
|
||||
insert(nodep);
|
||||
}
|
||||
|
|
@ -231,16 +231,16 @@ private:
|
|||
|
||||
// VISITORS
|
||||
virtual void visit(AstVar* nodep) {
|
||||
if (nodep->dtypep()->castUnpackArrayDType()
|
||||
&& nodep->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType()) {
|
||||
if (VN_IS(nodep->dtypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_CAST(nodep->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType)) {
|
||||
UINFO(8," dv-vec-VAR "<<nodep<<endl);
|
||||
AstUnpackArrayDType* arrdtype = nodep->dtypep()->castUnpackArrayDType();
|
||||
AstUnpackArrayDType* arrdtype = VN_CAST(nodep->dtypep(), UnpackArrayDType);
|
||||
AstNode* prevp = NULL;
|
||||
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
|
||||
string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
UINFO(8,"VAR name insert "<<varNewName<<" "<<nodep<<endl);
|
||||
if (!m_deModVars.find(varNewName)) {
|
||||
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType)->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
ifaceRefp->cellp(NULL);
|
||||
|
||||
|
|
@ -271,10 +271,10 @@ private:
|
|||
if (nodep->rangep()) {
|
||||
m_cellRangep = nodep->rangep();
|
||||
|
||||
AstVar* ifaceVarp = nodep->nextp()->castVar();
|
||||
AstVar* ifaceVarp = VN_CAST(nodep->nextp(), Var);
|
||||
bool isIface = ifaceVarp
|
||||
&& ifaceVarp->dtypep()->castUnpackArrayDType()
|
||||
&& ifaceVarp->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
&& VN_IS(ifaceVarp->dtypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_CAST(ifaceVarp->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
|
||||
|
||||
// Make all of the required clones
|
||||
for (int i = 0; i < m_cellRangep->elementsConst(); i++) {
|
||||
|
|
@ -295,11 +295,11 @@ private:
|
|||
// If this AstCell is actually an interface instantiation, also clone the IfaceRef
|
||||
// within the same parent module as the cell
|
||||
if (isIface) {
|
||||
AstUnpackArrayDType* arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
|
||||
AstIfaceRefDType* origIfaceRefp = arrdtype->subDTypep()->castIfaceRefDType();
|
||||
AstUnpackArrayDType* arrdtype = VN_CAST(ifaceVarp->dtypep(), UnpackArrayDType);
|
||||
AstIfaceRefDType* origIfaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType);
|
||||
origIfaceRefp->cellp(NULL);
|
||||
AstVar* varNewp = ifaceVarp->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
|
||||
AstIfaceRefDType* ifaceRefp = VN_CAST(arrdtype->subDTypep(), IfaceRefDType)->cloneTree(false);
|
||||
arrdtype->addNextHere(ifaceRefp);
|
||||
ifaceRefp->cellp(newp);
|
||||
ifaceRefp->cellName(newp->name());
|
||||
|
|
@ -356,9 +356,9 @@ private:
|
|||
}
|
||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||
bool inputPin = nodep->modVarp()->isInput();
|
||||
if (!inputPin && !exprp->castVarRef()
|
||||
&& !exprp->castConcat() // V3Const will collapse the SEL with the one we're about to make
|
||||
&& !exprp->castSel()) { // V3Const will collapse the SEL with the one we're about to make
|
||||
if (!inputPin && !VN_IS(exprp, VarRef)
|
||||
&& !VN_IS(exprp, Concat) // V3Const will collapse the SEL with the one we're about to make
|
||||
&& !VN_IS(exprp, Sel)) { // V3Const will collapse the SEL with the one we're about to make
|
||||
nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires.");
|
||||
// Note spec allows more complicated matches such as slices and such
|
||||
}
|
||||
|
|
@ -369,19 +369,19 @@ private:
|
|||
} else {
|
||||
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
|
||||
}
|
||||
} else if (AstArraySel* arrselp = nodep->exprp()->castArraySel()) {
|
||||
if (AstUnpackArrayDType* arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) {
|
||||
if (!arrp->subDTypep()->castIfaceRefDType())
|
||||
} else if (AstArraySel* arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
|
||||
if (AstUnpackArrayDType* arrp = VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
|
||||
if (!VN_IS(arrp->subDTypep(), IfaceRefDType))
|
||||
return;
|
||||
|
||||
V3Const::constifyParamsEdit(arrselp->rhsp());
|
||||
AstConst* constp = arrselp->rhsp()->castConst();
|
||||
const AstConst* constp = VN_CAST(arrselp->rhsp(), Const);
|
||||
if (!constp) {
|
||||
nodep->v3error("Unsupported: Non-constant index when passing interface to module");
|
||||
return;
|
||||
}
|
||||
string index = AstNode::encodeNumber(constp->toSInt());
|
||||
AstVarRef* varrefp = arrselp->lhsp()->castVarRef();
|
||||
AstVarRef* varrefp = VN_CAST(arrselp->lhsp(), VarRef);
|
||||
AstVarXRef* newp = new AstVarXRef(nodep->fileline(), varrefp->name()+"__BRA__"+index+"__KET__", "", true);
|
||||
newp->dtypep(nodep->modVarp()->dtypep());
|
||||
newp->packagep(varrefp->packagep());
|
||||
|
|
@ -390,8 +390,8 @@ private:
|
|||
}
|
||||
} else {
|
||||
AstVar* pinVarp = nodep->modVarp();
|
||||
AstUnpackArrayDType* pinArrp = pinVarp->dtypep()->castUnpackArrayDType();
|
||||
if (!pinArrp || !pinArrp->subDTypep()->castIfaceRefDType())
|
||||
AstUnpackArrayDType* pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
|
||||
if (!pinArrp || !VN_IS(pinArrp->subDTypep(), IfaceRefDType))
|
||||
return;
|
||||
AstNode* prevp = NULL;
|
||||
AstNode* prevPinp = NULL;
|
||||
|
|
@ -405,7 +405,7 @@ private:
|
|||
if (!pinVarp->backp()) {
|
||||
varNewp = m_deModVars.find(varNewName);
|
||||
} else {
|
||||
AstIfaceRefDType* ifaceRefp = pinArrp->subDTypep()->castIfaceRefDType();
|
||||
AstIfaceRefDType* ifaceRefp = VN_CAST(pinArrp->subDTypep(), IfaceRefDType);
|
||||
ifaceRefp->cellp(NULL);
|
||||
varNewp = pinVarp->cloneTree(false);
|
||||
varNewp->name(varNewName);
|
||||
|
|
@ -429,7 +429,7 @@ private:
|
|||
newp->modVarp(varNewp);
|
||||
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
// And replace exprp with a new varxref
|
||||
AstVarRef* varrefp = newp->exprp()->castVarRef();
|
||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef);
|
||||
string newname = varrefp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
|
||||
newVarXRefp->varp(newp->modVarp());
|
||||
|
|
@ -504,12 +504,12 @@ public:
|
|||
// Note this module calles cloneTree() via new AstVar
|
||||
|
||||
AstVar* pinVarp = pinp->modVarp();
|
||||
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
|
||||
AstVarXRef* connectXRefp = pinp->exprp()->castVarXRef();
|
||||
AstBasicDType* pinBasicp = pinVarp->dtypep()->castBasicDType(); // Maybe NULL
|
||||
AstVarRef* connectRefp = VN_CAST(pinp->exprp(), VarRef);
|
||||
AstVarXRef* connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
|
||||
AstBasicDType* pinBasicp = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe NULL
|
||||
AstBasicDType* connBasicp = NULL;
|
||||
AstAssignW* assignp = NULL;
|
||||
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->castBasicDType();
|
||||
if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType);
|
||||
//
|
||||
if (!alwaysCvt
|
||||
&& connectRefp
|
||||
|
|
@ -532,7 +532,7 @@ public:
|
|||
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
|
||||
&& connBasicp->width() == pinVarp->width()) {
|
||||
// Done. One to one interconnect won't need a temporary variable.
|
||||
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
|
||||
} else if (!alwaysCvt && !forTristate && VN_IS(pinp->exprp(), Const)) {
|
||||
// Done. Constant.
|
||||
} else {
|
||||
// Make a new temp wire
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
m_assignp = assp;
|
||||
m_constp = NULL;
|
||||
m_everSet = true;
|
||||
if (assp->rhsp()->castConst()) m_constp = assp->rhsp()->castConst();
|
||||
if (VN_IS(assp->rhsp(), Const)) m_constp = VN_CAST(assp->rhsp(), Const);
|
||||
}
|
||||
inline void complexAssign() { // A[x]=... or some complicated assignment
|
||||
m_assignp = NULL;
|
||||
|
|
@ -329,8 +329,8 @@ private:
|
|||
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
|
||||
}
|
||||
// Has to be direct assignment without any EXTRACTing.
|
||||
if (nodep->lhsp()->castVarRef() && !m_sideEffect && !m_noopt) {
|
||||
AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep();
|
||||
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");
|
||||
m_lifep->simpleAssign(vscp, nodep);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ private:
|
|||
}
|
||||
}
|
||||
virtual void visit(AstAssignPost* nodep) {
|
||||
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
|
||||
if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) {
|
||||
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (AstVarRef* rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
// Scrunch these:
|
||||
// __Vdly__q = __PVT__clk_clocks;
|
||||
// ... {no reads or writes of __PVT__q after the first write to __Vdly__q}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ private:
|
|||
AstNodeModule* findModuleSym(const string& modName) {
|
||||
VSymEnt* foundp = m_mods.rootp()->findIdFallback(modName);
|
||||
if (!foundp) return NULL;
|
||||
else return foundp->nodep()->castNodeModule();
|
||||
else return VN_CAST(foundp->nodep(), NodeModule);
|
||||
}
|
||||
|
||||
AstNodeModule* resolveModule(AstNode* nodep, const string& modName) {
|
||||
|
|
@ -203,7 +203,7 @@ private:
|
|||
<<"' does not match "<<nodep->typeName()<<" name: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
if (nodep->castIface() || nodep->castPackage()) nodep->inLibrary(true); // Interfaces can't be at top, unless asked
|
||||
if (VN_IS(nodep, Iface) || VN_IS(nodep, Package)) nodep->inLibrary(true); // Interfaces can't be at top, unless asked
|
||||
bool topMatch = (v3Global.opt.topModule()==nodep->prettyName());
|
||||
if (topMatch) {
|
||||
m_topVertexp = vertex(nodep);
|
||||
|
|
@ -231,11 +231,11 @@ private:
|
|||
// but we might support modules-under-modules someday.
|
||||
AstNodeModule* modp = resolveModule(nodep, nodep->ifaceName());
|
||||
if (modp) {
|
||||
if (modp->castIface()) {
|
||||
if (VN_IS(modp, Iface)) {
|
||||
// Track module depths, so can sort list from parent down to children
|
||||
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false);
|
||||
if (!nodep->cellp()) nodep->ifacep(modp->castIface());
|
||||
} else if (modp->castNotFoundModule()) { // Will error out later
|
||||
if (!nodep->cellp()) nodep->ifacep(VN_CAST(modp, Iface));
|
||||
} else if (VN_IS(modp, NotFoundModule)) { // Will error out later
|
||||
} else {
|
||||
nodep->v3error("Non-interface used as an interface: "<<nodep->prettyName());
|
||||
}
|
||||
|
|
@ -298,7 +298,7 @@ private:
|
|||
// This lets us link the XREFs between the (uncloned) children so
|
||||
// they don't point to the same module which would
|
||||
// break parameter resolution.
|
||||
AstNodeModule* otherModp = cellmodp->user2p()->castNodeModule();
|
||||
AstNodeModule* otherModp = VN_CAST(cellmodp->user2p(), NodeModule);
|
||||
if (!otherModp) {
|
||||
otherModp = cellmodp->cloneTree(false);
|
||||
otherModp->name(otherModp->name()+"__Vrcm");
|
||||
|
|
@ -342,7 +342,7 @@ private:
|
|||
// Convert .* to list of pins
|
||||
bool pinStar = false;
|
||||
for (AstPin* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
|
||||
nextp = pinp->nextp()->castPin();
|
||||
nextp = VN_CAST(pinp->nextp(), Pin);
|
||||
if (pinp->dotStar()) {
|
||||
if (pinStar) pinp->v3error("Duplicate .* in a cell");
|
||||
pinStar = true;
|
||||
|
|
@ -351,10 +351,10 @@ private:
|
|||
}
|
||||
}
|
||||
// Convert unnamed pins to pin number based assignments
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (pinp->name()=="") pinp->name("__pinNumber"+cvtToStr(pinp->pinNum()));
|
||||
}
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
pinp->param(true);
|
||||
if (pinp->name()=="") pinp->name("__paramNumber"+cvtToStr(pinp->pinNum()));
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ private:
|
|||
nodep->modName(nodep->modp()->name());
|
||||
// Note what pins exist
|
||||
vl_unordered_set<string> ports; // Symbol table of all connected port names
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
|
||||
if (!pinp->exprp()) {
|
||||
if (pinp->name().substr(0, 11) == "__pinNumber") {
|
||||
|
|
@ -378,7 +378,7 @@ private:
|
|||
// We search ports, rather than in/out declarations as they aren't resolved yet,
|
||||
// and it's easier to do it now than in V3LinkDot when we'd need to repeat steps.
|
||||
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
|
||||
if (AstPort* portp = portnodep->castPort()) {
|
||||
if (const AstPort* portp = VN_CAST(portnodep, Port)) {
|
||||
if (ports.find(portp->name()) == ports.end()
|
||||
&& ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) {
|
||||
if (pinStar) {
|
||||
|
|
@ -398,7 +398,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
if (nodep->modp()->castIface()) {
|
||||
if (VN_IS(nodep->modp(), Iface)) {
|
||||
// Cell really is the parent's instantiation of an interface, not a normal module
|
||||
// Make sure we have a variable to refer to this cell, so can <ifacename>.<innermember>
|
||||
// in the same way that a child does. Rename though to avoid conflict with cell.
|
||||
|
|
@ -443,7 +443,7 @@ private:
|
|||
void readModNames() {
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstNodeModule* nextp,* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nextp) {
|
||||
nextp = nodep->nextp()->castNodeModule();
|
||||
nextp = VN_CAST(nodep->nextp(), NodeModule);
|
||||
AstNodeModule* foundp = findModuleSym(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) {
|
||||
|
|
|
|||
|
|
@ -190,13 +190,13 @@ public:
|
|||
|
||||
// METHODS
|
||||
static string nodeTextType(AstNode* nodep) {
|
||||
if (nodep->castVar()) return "variable";
|
||||
else if (nodep->castCell()) return "cell";
|
||||
else if (nodep->castTask()) return "task";
|
||||
else if (nodep->castFunc()) return "function";
|
||||
else if (nodep->castBegin()) return "block";
|
||||
else if (nodep->castIface()) return "interface";
|
||||
else if (nodep->castParamTypeDType()) return "parameter type";
|
||||
if (VN_IS(nodep, Var)) return "variable";
|
||||
else if (VN_IS(nodep, Cell)) return "cell";
|
||||
else if (VN_IS(nodep, Task)) return "task";
|
||||
else if (VN_IS(nodep, Func)) return "function";
|
||||
else if (VN_IS(nodep, Begin)) return "block";
|
||||
else if (VN_IS(nodep, Iface)) return "interface";
|
||||
else if (VN_IS(nodep, ParamTypeDType)) return "parameter type";
|
||||
else return nodep->prettyTypeName();
|
||||
}
|
||||
|
||||
|
|
@ -217,8 +217,8 @@ public:
|
|||
// Good.
|
||||
} else if (foundp->imported()) { // From package
|
||||
// We don't throw VARHIDDEN as if the import is later the symbol table's import wouldn't warn
|
||||
} else if (nodep->castBegin() && fnodep->castBegin()
|
||||
&& nodep->castBegin()->generate()) {
|
||||
} else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin)
|
||||
&& VN_CAST(nodep, Begin)->generate()) {
|
||||
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
|
||||
// See t_gen_forif.v for an example.
|
||||
} else {
|
||||
|
|
@ -370,10 +370,10 @@ public:
|
|||
}
|
||||
// Iface for a raw or arrayed iface
|
||||
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
|
||||
AstIfaceRefDType* ifacerefp = nodep->castIfaceRefDType();
|
||||
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
|
||||
if (!ifacerefp) {
|
||||
if (AstUnpackArrayDType* arrp = nodep->castUnpackArrayDType()) {
|
||||
ifacerefp = arrp->subDTypep()->castIfaceRefDType();
|
||||
if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) {
|
||||
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
|
||||
}
|
||||
}
|
||||
return ifacerefp;
|
||||
|
|
@ -381,7 +381,7 @@ public:
|
|||
void computeIfaceVarSyms() {
|
||||
for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) {
|
||||
VSymEnt* varSymp = *it;
|
||||
AstVar* varp = varSymp ? varSymp->nodep()->castVar() : NULL;
|
||||
AstVar* varp = varSymp ? VN_CAST(varSymp->nodep(), Var) : NULL;
|
||||
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
|
||||
AstIfaceRefDType* ifacerefp = ifaceRefFromArray(varp->subDTypep());
|
||||
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
|
||||
|
|
@ -403,7 +403,7 @@ public:
|
|||
VSymEnt* foundp = ifaceSymp->findIdFallback(ifacerefp->modportName());
|
||||
bool ok = false;
|
||||
if (foundp) {
|
||||
if (AstModport* modportp = foundp->nodep()->castModport()) {
|
||||
if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
UINFO(4,"Link Modport: "<<modportp<<endl);
|
||||
ifacerefp->modportp(modportp);
|
||||
ifOrPortSymp = foundp;
|
||||
|
|
@ -424,8 +424,8 @@ public:
|
|||
// Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface
|
||||
// Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell
|
||||
UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<<endl);
|
||||
if (rhsp->nodep()->castCell()
|
||||
&& !rhsp->nodep()->castCell()->modp()->castIface()) {
|
||||
if (VN_IS(rhsp->nodep(), Cell)
|
||||
&& !VN_IS(VN_CAST(rhsp->nodep(), Cell)->modp(), Iface)) {
|
||||
rhsp->nodep()->v3fatalSrc("Got a non-IFACE alias RHS");
|
||||
}
|
||||
m_scopeAliasMap[samn].insert(make_pair(lhsp, rhsp));
|
||||
|
|
@ -447,7 +447,7 @@ public:
|
|||
// srcp should be an interface reference pointing to the interface we want to import
|
||||
lhsp->importFromIface(symsp(), srcp);
|
||||
// Allow access to objects not permissible to be listed in a modport
|
||||
if (srcp->nodep()->castModport()) {
|
||||
if (VN_IS(srcp->nodep(), Modport)) {
|
||||
lhsp->importFromIface(symsp(), srcp->parentp(), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -499,8 +499,8 @@ public:
|
|||
// then look up (inst name or modname)
|
||||
if (firstId) {
|
||||
// Check this module - subcellnames
|
||||
AstCell* cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated below
|
||||
AstCellInline* inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated below
|
||||
AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell) : NULL; // Replicated below
|
||||
AstCellInline* inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline) : NULL; // Replicated below
|
||||
if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
}
|
||||
|
|
@ -512,8 +512,8 @@ public:
|
|||
bool crossedCell = false; // Crossed a cell boundary
|
||||
while (lookupSymp) {
|
||||
lookupSymp = lookupSymp->parentp();
|
||||
cellp = lookupSymp ? lookupSymp->nodep()->castCell() : NULL; // Replicated above
|
||||
inlinep = lookupSymp ? lookupSymp->nodep()->castCellInline() : NULL; // Replicated above
|
||||
cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell) : NULL; // Replicated above
|
||||
inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline) : NULL; // Replicated above
|
||||
if (lookupSymp) {
|
||||
UINFO(9,"\t\tUp to "<<lookupSymp<<endl);
|
||||
if (cellp || inlinep) {
|
||||
|
|
@ -525,7 +525,7 @@ public:
|
|||
}
|
||||
else if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
|
||||
lookupSymp = findSymp;
|
||||
if (crossedCell && lookupSymp->nodep()->castVar()) {
|
||||
if (crossedCell && VN_IS(lookupSymp->nodep(), Var)) {
|
||||
UINFO(9,"\t\tNot found but matches var name in parent "<<lookupSymp<<endl);
|
||||
return NULL; // Not found (but happens to be var name in parent)
|
||||
}
|
||||
|
|
@ -644,8 +644,8 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
virtual void visit(AstNetlist* nodep) {
|
||||
// Process $unit or other packages
|
||||
// Not needed - dotted references not allowed from inside packages
|
||||
//for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
// if (nodep->castPackage()) {}}
|
||||
//for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
// if (VN_IS(nodep, Package)) {}}
|
||||
|
||||
m_statep->insertDUnit(nodep);
|
||||
|
||||
|
|
@ -676,7 +676,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
UINFO(8," "<<nodep<<endl);
|
||||
// m_curSymp/m_modSymp maybe NULL for packages and non-top modules
|
||||
// Packages will be under top after the initial phases, but until then need separate handling
|
||||
bool standalonePkg = !m_modSymp && (m_statep->forPrearray() && nodep->castPackage());
|
||||
bool standalonePkg = !m_modSymp && (m_statep->forPrearray() && VN_IS(nodep, Package));
|
||||
bool doit = (m_modSymp || standalonePkg);
|
||||
string oldscope = m_scope;
|
||||
VSymEnt* oldModSymp = m_modSymp;
|
||||
|
|
@ -691,7 +691,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
UINFO(4," Link Module: "<<nodep<<endl);
|
||||
if (nodep->dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?");
|
||||
VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp();
|
||||
m_packagep = nodep->castPackage();
|
||||
m_packagep = VN_CAST(nodep, Package);
|
||||
if (standalonePkg) {
|
||||
if (m_packagep->isDollarUnit()) {
|
||||
m_curSymp = m_modSymp = m_statep->dunitEntp();
|
||||
|
|
@ -713,7 +713,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
nodep->user2(false);
|
||||
nodep->user4(true);
|
||||
// Interfaces need another pass when signals are resolved
|
||||
if (AstIface* ifacep = nodep->castIface()) {
|
||||
if (AstIface* ifacep = VN_CAST(nodep, Iface)) {
|
||||
m_statep->insertIfaceModSym(ifacep, m_curSymp);
|
||||
}
|
||||
} else { //!doit
|
||||
|
|
@ -829,7 +829,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// places such as tasks, where "task ...; begin ... end"
|
||||
// are common.
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (stmtp->castVar()) {
|
||||
if (VN_IS(stmtp, Var)) {
|
||||
++m_modBeginNum;
|
||||
nodep->name("unnamedblk"+cvtToStr(m_modBeginNum));
|
||||
break;
|
||||
|
|
@ -865,8 +865,8 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// This should probably be done in the Parser instead, as then we could
|
||||
// just attact normal signal attributes to it.
|
||||
if (nodep->fvarp()
|
||||
&& !nodep->fvarp()->castVar()) {
|
||||
AstNodeDType* dtypep = nodep->fvarp()->castNodeDType();
|
||||
&& !VN_IS(nodep->fvarp(), Var)) {
|
||||
AstNodeDType* dtypep = VN_CAST(nodep->fvarp(), NodeDType);
|
||||
// If unspecified, function returns one bit; however when we support NEW() it could
|
||||
// also return the class reference.
|
||||
if (dtypep) dtypep->unlinkFrBack();
|
||||
|
|
@ -894,7 +894,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// Find under either a task or the module's vars
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname?
|
||||
AstVar* findvarp = foundp ? foundp->nodep()->castVar() : NULL;
|
||||
AstVar* findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : NULL;
|
||||
bool ins=false;
|
||||
if (!foundp) {
|
||||
ins=true;
|
||||
|
|
@ -910,7 +910,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
nodep->fileline()->modifyStateInherit(nodep->fileline());
|
||||
AstBasicDType* bdtypep = findvarp->childDTypep()->castBasicDType();
|
||||
AstBasicDType* bdtypep = VN_CAST(findvarp->childDTypep(), BasicDType);
|
||||
if (bdtypep && bdtypep->implicit()) {
|
||||
// Then have "input foo" and "real foo" so the dtype comes from the other side.
|
||||
AstNodeDType* newdtypep = nodep->subDTypep();
|
||||
|
|
@ -991,7 +991,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
|||
// Find under either a task or the module's vars
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname?
|
||||
AstEnumItem* findvarp = foundp ? foundp->nodep()->castEnumItem() : NULL;
|
||||
AstEnumItem* findvarp = foundp ? VN_CAST(foundp->nodep(), EnumItem) : NULL;
|
||||
bool ins=false;
|
||||
if (!foundp) {
|
||||
ins=true;
|
||||
|
|
@ -1091,10 +1091,10 @@ private:
|
|||
void pinImplicitExprRecurse(AstNode* nodep) {
|
||||
// Under a pin, Check interconnect expression for a pin reference or a concat.
|
||||
// Create implicit variable as needed
|
||||
if (nodep->castDot()) { // Not creating a simple implied type,
|
||||
if (VN_IS(nodep, Dot)) { // Not creating a simple implied type,
|
||||
// and implying something else would just confuse later errors
|
||||
}
|
||||
else if (nodep->castVarRef() || nodep->castParseRef()) {
|
||||
else if (VN_IS(nodep, VarRef) || VN_IS(nodep, ParseRef)) {
|
||||
// To prevent user errors, we should only do single bit
|
||||
// implicit vars, however some netlists (MIPS) expect single
|
||||
// bit implicit wires to get created with range 0:0 etc.
|
||||
|
|
@ -1140,7 +1140,7 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<<nodep->prettyName()<<"(...etc...))");
|
||||
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
|
||||
AstCell* cellp = foundp ? foundp->nodep()->castCell() : NULL;
|
||||
AstCell* cellp = foundp ? VN_CAST(foundp->nodep(), Cell) : NULL;
|
||||
if (!cellp) {
|
||||
nodep->v3error("In defparam, cell "<<nodep->path()<<" never declared");
|
||||
} else {
|
||||
|
|
@ -1162,7 +1162,7 @@ private:
|
|||
// Need to set pin numbers after varnames are created
|
||||
// But before we do the final resolution based on names
|
||||
VSymEnt* foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name());
|
||||
AstVar* refp = foundp ? foundp->nodep()->castVar() : NULL;
|
||||
AstVar* refp = foundp ? VN_CAST(foundp->nodep(), Var) : NULL;
|
||||
if (!refp) {
|
||||
nodep->v3error("Input/output/inout declaration not found for port: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO() && !refp->isIfaceRef()) {
|
||||
|
|
@ -1187,10 +1187,10 @@ private:
|
|||
// 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");
|
||||
if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) {
|
||||
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
if (AstVarRef* forrefp = nodep->rhsp()->castVarRef()) {
|
||||
if (AstVarRef* forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -1282,8 +1282,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
|
||||
// we'll need to replace it with a VARXREF(aliased_to)
|
||||
if (debug()>=9) nodep->dumpTree(cout,"-\t\t\t\talias: ");
|
||||
AstVarScope* fromVscp = nodep->lhsp()->castVarRef()->varScopep();
|
||||
AstVarScope* toVscp = nodep->rhsp()->castVarRef()->varScopep();
|
||||
AstVarScope* fromVscp = VN_CAST(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* toVscp = VN_CAST(nodep->rhsp(), VarRef)->varScopep();
|
||||
if (!fromVscp || !toVscp) nodep->v3fatalSrc("Bad alias scopes");
|
||||
fromVscp->user2p(toVscp);
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -1293,8 +1293,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
if (debug()>=9) nodep->dumpTree(cout,"-\t\t\t\tavs: ");
|
||||
VSymEnt* rhsSymp;
|
||||
{
|
||||
AstVarRef* refp = nodep->rhsp()->castVarRef();
|
||||
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
|
||||
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");
|
||||
string inl = (xrefp && xrefp->inlinedDots().size()) ? (xrefp->inlinedDots() + "__DOT__") : "";
|
||||
VSymEnt* symp = NULL;
|
||||
|
|
@ -1314,8 +1314,8 @@ class LinkDotScopeVisitor : public AstNVisitor {
|
|||
}
|
||||
VSymEnt* lhsSymp;
|
||||
{
|
||||
AstVarXRef* xrefp = nodep->lhsp()->castVarXRef();
|
||||
AstVarRef* refp = nodep->lhsp()->castVarRef();
|
||||
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");
|
||||
string scopename = refp ? refp->varp()->name() : xrefp->dotted()+"."+xrefp->name();
|
||||
|
|
@ -1385,7 +1385,7 @@ class LinkDotIfaceVisitor : public AstNVisitor {
|
|||
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!symp) {
|
||||
nodep->v3error("Modport item not found: "<<nodep->prettyName());
|
||||
} else if (AstNodeFTask* ftaskp = symp->nodep()->castNodeFTask()) {
|
||||
} else if (AstNodeFTask* ftaskp = VN_CAST(symp->nodep(), NodeFTask)) {
|
||||
// Make symbol under modport that points at the _interface_'s var, not the modport.
|
||||
nodep->ftaskp(ftaskp);
|
||||
VSymEnt* subSymp = m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, NULL/*package*/);
|
||||
|
|
@ -1405,12 +1405,12 @@ class LinkDotIfaceVisitor : public AstNVisitor {
|
|||
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name());
|
||||
if (!symp) {
|
||||
nodep->v3error("Modport item not found: "<<nodep->prettyName());
|
||||
} else if (AstVar* varp = symp->nodep()->castVar()) {
|
||||
} else if (AstVar* varp = VN_CAST(symp->nodep(), Var)) {
|
||||
// Make symbol under modport that points at the _interface_'s var via the modport.
|
||||
// (Need modport still to test input/output markings)
|
||||
nodep->varp(varp);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, NULL/*package*/);
|
||||
} else if (AstVarScope* vscp = symp->nodep()->castVarScope()) {
|
||||
} else if (AstVarScope* vscp = VN_CAST(symp->nodep(), VarScope)) {
|
||||
// Make symbol under modport that points at the _interface_'s var, not the modport.
|
||||
nodep->varp(vscp->varp());
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), vscp, NULL/*package*/);
|
||||
|
|
@ -1531,10 +1531,10 @@ private:
|
|||
// Return a variable if possible, auto converting a modport to variable
|
||||
if (!symp) {
|
||||
return NULL;
|
||||
} else if (symp->nodep()->castVar()) {
|
||||
return symp->nodep()->castVar();
|
||||
} else if (symp->nodep()->castModportVarRef()) {
|
||||
AstModportVarRef* snodep = symp->nodep()->castModportVarRef();
|
||||
} else if (VN_IS(symp->nodep(), Var)) {
|
||||
return VN_CAST(symp->nodep(), Var);
|
||||
} else if (VN_IS(symp->nodep(), ModportVarRef)) {
|
||||
AstModportVarRef* snodep = VN_CAST(symp->nodep(), ModportVarRef);
|
||||
AstVar* varp = snodep->varp();
|
||||
if (lvalue && snodep->isInput()) {
|
||||
nodep->v3error("Attempt to drive input-only modport: "<<nodep->prettyName());
|
||||
|
|
@ -1545,8 +1545,8 @@ private:
|
|||
}
|
||||
}
|
||||
void taskFuncSwapCheck(AstNodeFTaskRef* nodep) {
|
||||
if (nodep->taskp() && nodep->taskp()->castTask()
|
||||
&& nodep->castFuncRef()) nodep->v3error("Illegal call of a task as a function: "<<nodep->prettyName());
|
||||
if (nodep->taskp() && VN_IS(nodep->taskp(), Task)
|
||||
&& VN_IS(nodep, FuncRef)) nodep->v3error("Illegal call of a task as a function: "<<nodep->prettyName());
|
||||
}
|
||||
inline void checkNoDot(AstNode* nodep) {
|
||||
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
|
||||
|
|
@ -1620,7 +1620,7 @@ private:
|
|||
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
}
|
||||
else {
|
||||
if (nodep->modp()->castNotFoundModule()) {
|
||||
if (VN_IS(nodep->modp(), NotFoundModule)) {
|
||||
// Prevent warnings about missing pin connects
|
||||
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree();
|
||||
|
|
@ -1649,14 +1649,14 @@ private:
|
|||
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name());
|
||||
const char* whatp = nodep->param() ? "parameter pin" : "pin";
|
||||
if (!foundp) {
|
||||
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
|
||||
if (nodep->name() == "__paramNumber1" && VN_IS(m_cellp->modp(), Primitive)) {
|
||||
// Primitive parameter is really a delay we can just ignore
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
|
||||
}
|
||||
else if (AstVar* refp = foundp->nodep()->castVar()) {
|
||||
else if (AstVar* refp = VN_CAST(foundp->nodep(), Var)) {
|
||||
if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
|
||||
nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<<nodep->prettyName());
|
||||
} else {
|
||||
|
|
@ -1664,7 +1664,7 @@ private:
|
|||
markAndCheckPinDup(nodep, refp, whatp);
|
||||
}
|
||||
}
|
||||
else if (AstParamTypeDType* refp = foundp->nodep()->castParamTypeDType()) {
|
||||
else if (AstParamTypeDType* refp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
|
||||
nodep->modPTypep(refp);
|
||||
markAndCheckPinDup(nodep, refp, whatp);
|
||||
}
|
||||
|
|
@ -1692,7 +1692,7 @@ private:
|
|||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
||||
// m_ds.m_dotText communicates the cell prefix between stages
|
||||
if (nodep->lhsp()->castPackageRef()) {
|
||||
if (VN_IS(nodep->lhsp(), PackageRef)) {
|
||||
//if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in dotted reference"); m_ds.m_dotErr=true; }
|
||||
m_ds.m_dotPos = DP_PACKAGE;
|
||||
} else {
|
||||
|
|
@ -1700,7 +1700,7 @@ private:
|
|||
nodep->lhsp()->iterateAndNext(*this);
|
||||
//if (debug()>=9) nodep->dumpTree("-dot-lho: ");
|
||||
}
|
||||
if (m_ds.m_unresolved && (nodep->lhsp()->castCellRef() || nodep->lhsp()->castCellArrayRef())) {
|
||||
if (m_ds.m_unresolved && (VN_IS(nodep->lhsp(), CellRef) || VN_IS(nodep->lhsp(), CellArrayRef))) {
|
||||
m_ds.m_unlinkedScope = nodep->lhsp();
|
||||
}
|
||||
if (!m_ds.m_dotErr) { // Once something wrong, give up
|
||||
|
|
@ -1766,8 +1766,8 @@ private:
|
|||
expectWhat = "scope/variable";
|
||||
allowScope = true;
|
||||
allowVar = true;
|
||||
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
packagep = m_ds.m_dotp->lhsp()->castPackageRef()->packagep();
|
||||
if (!VN_IS(m_ds.m_dotp->lhsp(), PackageRef)) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
packagep = VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep();
|
||||
if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
|
|
@ -1799,9 +1799,9 @@ private:
|
|||
// What fell out?
|
||||
bool ok = false;
|
||||
if (!foundp) {
|
||||
} else if (foundp->nodep()->castCell()
|
||||
|| foundp->nodep()->castBegin()
|
||||
|| foundp->nodep()->castModule()) { // if top
|
||||
} else if (VN_IS(foundp->nodep(), Cell)
|
||||
|| VN_IS(foundp->nodep(), Begin)
|
||||
|| VN_IS(foundp->nodep(), Module)) { // if top
|
||||
if (allowScope) {
|
||||
ok = true;
|
||||
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
|
||||
|
|
@ -1810,16 +1810,16 @@ private:
|
|||
m_ds.m_dotPos = DP_SCOPE;
|
||||
// Upper AstDot visitor will handle it from here
|
||||
}
|
||||
else if (foundp->nodep()->castCell()
|
||||
else if (VN_IS(foundp->nodep(), Cell)
|
||||
&& allowVar && m_cellp) {
|
||||
AstCell* cellp = foundp->nodep()->castCell();
|
||||
if (cellp->modp()->castIface()) {
|
||||
AstCell* cellp = VN_CAST(foundp->nodep(), Cell);
|
||||
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");
|
||||
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin
|
||||
string findName = nodep->name()+"__Viftop";
|
||||
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName);
|
||||
AstVar* ifaceRefVarp = ifaceSymp ? ifaceSymp->nodep()->castVar() : NULL;
|
||||
AstVar* ifaceRefVarp = ifaceSymp ? VN_CAST(ifaceSymp->nodep(), Var) : NULL;
|
||||
if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<<findName);
|
||||
//
|
||||
ok = true;
|
||||
|
|
@ -1830,7 +1830,7 @@ private:
|
|||
UINFO(9," cell -> iface varref "<<foundp->nodep()<<endl);
|
||||
AstNode* newp = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, false);
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
} else if (cellp->modp()->castNotFoundModule()) {
|
||||
} else if (VN_IS(cellp->modp(), NotFoundModule)) {
|
||||
cellp->v3error("Cannot find file containing interface: " << AstNode::prettyName(cellp->modp()->name()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1857,7 +1857,7 @@ private:
|
|||
refp->varp(varp);
|
||||
m_ds.m_dotText = "";
|
||||
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
|
||||
newp = new AstUnlinkedRef(nodep->fileline(), refp->castVarXRef(),
|
||||
newp = new AstUnlinkedRef(nodep->fileline(), VN_CAST(refp, VarXRef),
|
||||
refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
|
||||
m_ds.m_unlinkedScope = NULL;
|
||||
m_ds.m_unresolved = false;
|
||||
|
|
@ -1875,23 +1875,23 @@ private:
|
|||
ok = true;
|
||||
}
|
||||
}
|
||||
else if (AstModport* modportp = foundp->nodep()->castModport()) {
|
||||
else if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) {
|
||||
// A scope reference into an interface's modport (not necessarily at a pin connection)
|
||||
UINFO(9,"cell-ref-to-modport "<<m_ds.m_dotText<<" "<<nodep<<endl);
|
||||
UINFO(9,"dotSymp "<<m_ds.m_dotSymp<<" "<<m_ds.m_dotSymp->nodep()<<endl);
|
||||
// Iface was the previously dotted component
|
||||
if (!m_ds.m_dotSymp
|
||||
|| !m_ds.m_dotSymp->nodep()->castCell()
|
||||
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()
|
||||
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) {
|
||||
|| !VN_IS(m_ds.m_dotSymp->nodep(), Cell)
|
||||
|| !VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp()
|
||||
|| !VN_IS(VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp(), Iface)) {
|
||||
nodep->v3error("Modport not referenced as <interface>."<<modportp->prettyName());
|
||||
} else if (!m_ds.m_dotSymp->nodep()->castCell()->modp()
|
||||
|| !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) {
|
||||
} else if (!VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp()
|
||||
|| !VN_IS(VN_CAST(m_ds.m_dotSymp->nodep(), Cell)->modp(), Iface)) {
|
||||
nodep->v3error("Modport not referenced from underneath an interface: "<<modportp->prettyName());
|
||||
} else {
|
||||
AstCell* cellp = m_ds.m_dotSymp->nodep()->castCell();
|
||||
AstCell* cellp = VN_CAST(m_ds.m_dotSymp->nodep(), Cell);
|
||||
if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell");
|
||||
AstIface* ifacep = cellp->modp()->castIface();
|
||||
AstIface* ifacep = VN_CAST(cellp->modp(), Iface);
|
||||
//string cellName = m_ds.m_dotText; // Use cellp->name
|
||||
if (m_ds.m_dotText!="") m_ds.m_dotText += ".";
|
||||
m_ds.m_dotText += nodep->name();
|
||||
|
|
@ -1903,7 +1903,7 @@ private:
|
|||
nodep->replaceWith(refp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
else if (AstEnumItem* valuep = foundp->nodep()->castEnumItem()) {
|
||||
else if (AstEnumItem* valuep = VN_CAST(foundp->nodep(), EnumItem)) {
|
||||
if (allowVar) {
|
||||
AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep());
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
@ -1914,7 +1914,7 @@ private:
|
|||
//
|
||||
if (!ok) {
|
||||
// Cells/interfaces can't be implicit
|
||||
bool isCell = foundp ? foundp->nodep()->castCell() != NULL : false;
|
||||
bool isCell = foundp ? VN_IS(foundp->nodep(), Cell) : false;
|
||||
bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText=="" && !isCell);
|
||||
bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name()));
|
||||
if (err) {
|
||||
|
|
@ -2000,7 +2000,7 @@ private:
|
|||
// V3Inst may have expanded arrays of interfaces to AstVarXRef's even though they are in the same module
|
||||
// detect this and convert to normal VarRefs
|
||||
if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) {
|
||||
if (nodep->dtypep()->castIfaceRefDType()) {
|
||||
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), nodep->varp(), nodep->lvalue());
|
||||
nodep->replaceWith(newrefp);
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
@ -2009,14 +2009,14 @@ private:
|
|||
} else {
|
||||
string baddot;
|
||||
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
AstVarScope* vscp = foundp ? foundp->nodep()->castVarScope() : NULL;
|
||||
AstVarScope* vscp = foundp ? VN_CAST(foundp->nodep(), VarScope) : NULL;
|
||||
if (!vscp) {
|
||||
nodep->v3error("Can't find varpin scope of '"<<baddot<<"' in dotted signal: "<<nodep->dotted()+"."+nodep->prettyName());
|
||||
okSymp->cellErrorScopes(nodep);
|
||||
} else {
|
||||
while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal
|
||||
UINFO(7," Resolved pre-alias "<<vscp<<endl); // Also prints taskp
|
||||
vscp = vscp->user2p()->castVarScope();
|
||||
vscp = VN_CAST(vscp->user2p(), VarScope);
|
||||
}
|
||||
// Convert the VarXRef to a VarRef, so we don't need later optimizations to deal with VarXRef.
|
||||
nodep->varp(vscp->varp());
|
||||
|
|
@ -2054,9 +2054,9 @@ private:
|
|||
if (nodep->user3SetOnce()) return;
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep());
|
||||
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");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||
|
|
@ -2113,7 +2113,7 @@ private:
|
|||
VSymEnt* foundp = NULL;
|
||||
AstNodeFTask* taskp = NULL;
|
||||
foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
|
||||
taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL; // Maybe NULL
|
||||
taskp = foundp ? VN_CAST(foundp->nodep(), NodeFTask) : NULL; // Maybe NULL
|
||||
if (taskp) {
|
||||
nodep->taskp(taskp);
|
||||
nodep->packagep(foundp->packagep());
|
||||
|
|
@ -2215,9 +2215,9 @@ private:
|
|||
// Resolve its reference
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
|
||||
if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link");
|
||||
nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep());
|
||||
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");
|
||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), PackageRef)->packagep());
|
||||
m_ds.m_dotPos = DP_SCOPE;
|
||||
m_ds.m_dotp = NULL;
|
||||
} else {
|
||||
|
|
@ -2230,11 +2230,11 @@ private:
|
|||
} else {
|
||||
foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
}
|
||||
if (AstTypedef* defp = foundp ? foundp->nodep()->castTypedef() : NULL) {
|
||||
if (AstTypedef* defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : NULL) {
|
||||
nodep->refDTypep(defp->subDTypep());
|
||||
nodep->packagep(foundp->packagep());
|
||||
}
|
||||
else if (AstParamTypeDType* defp = foundp ? foundp->nodep()->castParamTypeDType() : NULL) {
|
||||
else if (AstParamTypeDType* defp = foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : NULL) {
|
||||
nodep->refDTypep(defp);
|
||||
nodep->packagep(foundp->packagep());
|
||||
}
|
||||
|
|
@ -2249,7 +2249,7 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
|
||||
AstNodeFTask* taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL;
|
||||
AstNodeFTask* taskp = foundp ? VN_CAST(foundp->nodep(), NodeFTask) : NULL;
|
||||
if (!taskp) { nodep->v3error("Can't find definition of exported task/function: "<<nodep->prettyName()); }
|
||||
else if (taskp->dpiExport()) {
|
||||
nodep->v3error("Function was already DPI Exported, duplicate not allowed: "<<nodep->prettyName());
|
||||
|
|
|
|||
|
|
@ -63,16 +63,16 @@ private:
|
|||
AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) {
|
||||
// Put label under given node, and if WHILE optionally at end of iteration
|
||||
UINFO(4,"Create label for "<<nodep<<endl);
|
||||
if (nodep->castJumpLabel()) return nodep->castJumpLabel(); // Done
|
||||
if (VN_IS(nodep, JumpLabel)) return VN_CAST(nodep, JumpLabel); // Done
|
||||
|
||||
AstNode* underp = NULL;
|
||||
bool under_and_next = true;
|
||||
if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp();
|
||||
else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp();
|
||||
else if (nodep->castWhile()) {
|
||||
if (VN_IS(nodep, Begin)) underp = VN_CAST(nodep, Begin)->stmtsp();
|
||||
else if (VN_IS(nodep, NodeFTask)) underp = VN_CAST(nodep, NodeFTask)->stmtsp();
|
||||
else if (VN_IS(nodep, While)) {
|
||||
if (endOfIter) {
|
||||
// Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip
|
||||
underp = nodep->castWhile()->bodysp();
|
||||
underp = VN_CAST(nodep, While)->bodysp();
|
||||
} else {
|
||||
underp = nodep; under_and_next=false; // IE we skip the entire while
|
||||
}
|
||||
|
|
@ -84,14 +84,14 @@ private:
|
|||
// Skip over variables as we'll just move them in a momement
|
||||
// Also this would otherwise prevent us from using a label twice
|
||||
// see t_func_return test.
|
||||
while (underp && underp->castVar()) underp = underp->nextp();
|
||||
while (underp && VN_IS(underp, Var)) underp = underp->nextp();
|
||||
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
|
||||
|
||||
if (!underp) {
|
||||
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
|
||||
return NULL;
|
||||
} else if (underp->castJumpLabel()) {
|
||||
return underp->castJumpLabel();
|
||||
} else 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);
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ private:
|
|||
// Keep any AstVars under the function not under the new JumpLabel
|
||||
for (AstNode* nextp, *varp=underp; varp; varp = nextp) {
|
||||
nextp = varp->nextp();
|
||||
if (varp->castVar()) {
|
||||
if (VN_IS(varp, Var)) {
|
||||
labelp->addPrev(varp->unlinkFrBack());
|
||||
}
|
||||
}
|
||||
|
|
@ -177,7 +177,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstReturn* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
AstFunc* funcp = m_ftaskp->castFunc();
|
||||
AstFunc* funcp = VN_CAST(m_ftaskp, Func);
|
||||
if (!m_ftaskp) { nodep->v3error("Return isn't underneath a task or function"); }
|
||||
else if (funcp && !nodep->lhsp()) { nodep->v3error("Return underneath a function should have return value"); }
|
||||
else if (!funcp && nodep->lhsp()) { nodep->v3error("Return underneath a task shouldn't have return value"); }
|
||||
|
|
@ -185,7 +185,7 @@ private:
|
|||
if (funcp && nodep->lhsp()) {
|
||||
// Set output variable to return value
|
||||
nodep->addPrev(new AstAssign(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), funcp->fvarp()->castVar(), true),
|
||||
new AstVarRef(nodep->fileline(), VN_CAST(funcp->fvarp(), Var), true),
|
||||
nodep->lhsp()->unlinkFrBackWithNext()));
|
||||
}
|
||||
// Jump to the end of the function call
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ private:
|
|||
// We'll deal with mismatching pins later
|
||||
if (!taskp) return;
|
||||
for (AstNode* stmtp = taskp->stmtsp(); stmtp && pinp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
if (portp->isInput()) {
|
||||
pinp->iterate(*this);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ void V3LinkLevel::modSortByLevel() {
|
|||
|
||||
ModVec vec;
|
||||
AstNodeModule* topp = NULL;
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=VN_CAST(nodep->nextp(), NodeModule)) {
|
||||
if (nodep->level()<=2) {
|
||||
if (topp) {
|
||||
nodep->v3warn(E_MULTITOP, "Unsupported: Multiple top level modules: "
|
||||
|
|
@ -108,7 +108,7 @@ void V3LinkLevel::wrapTop(AstNetlist* netlistp) {
|
|||
void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) {
|
||||
AstNodeModule* newmodp = netlistp->modulesp();
|
||||
if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process");
|
||||
AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule();
|
||||
AstNodeModule* oldmodp = VN_CAST(newmodp->nextp(), NodeModule);
|
||||
if (!oldmodp) netlistp->v3fatalSrc("No module found to process");
|
||||
|
||||
// Add instance
|
||||
|
|
@ -121,7 +121,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) {
|
|||
|
||||
// Add pins
|
||||
for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* oldvarp=subnodep->castVar()) {
|
||||
if (AstVar* oldvarp=VN_CAST(subnodep, Var)) {
|
||||
UINFO(8,"VARWRAP "<<oldvarp<<endl);
|
||||
if (oldvarp->isIO()) {
|
||||
AstVar* varp = oldvarp->cloneTree(false);
|
||||
|
|
@ -154,8 +154,8 @@ void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) {
|
|||
// This way all later SCOPE based optimizations can ignore packages
|
||||
AstNodeModule* newmodp = netlistp->modulesp();
|
||||
if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process");
|
||||
for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
if (modp->castPackage()) {
|
||||
for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=VN_CAST(modp->nextp(), NodeModule)) {
|
||||
if (VN_IS(modp, Package)) {
|
||||
AstCell* cellp = new AstCell(modp->fileline(),
|
||||
// Could add __03a__03a="::" to prevent conflict
|
||||
// with module names/"v"
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ private:
|
|||
cleanFileline(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->rangep()) {
|
||||
if (!nodep->rangep()->msbp()->castConst()
|
||||
|| !nodep->rangep()->lsbp()->castConst()) nodep->v3error("Enum ranges must be integral, per spec");
|
||||
if (!VN_IS(nodep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(nodep->rangep()->lsbp(), Const)) nodep->v3error("Enum ranges must be integral, per spec");
|
||||
int msb = nodep->rangep()->msbConst();
|
||||
int lsb = nodep->rangep()->lsbConst();
|
||||
int increment = (msb > lsb) ? -1 : 1;
|
||||
|
|
@ -142,9 +142,9 @@ private:
|
|||
|
||||
virtual void visit(AstVar* nodep) {
|
||||
cleanFileline(nodep);
|
||||
if (nodep->subDTypep()->castParseTypeDType()) {
|
||||
if (VN_IS(nodep->subDTypep(), ParseTypeDType)) {
|
||||
// It's a parameter type. Use a different node type for this.
|
||||
AstNodeDType* dtypep = nodep->valuep()->castNodeDType();
|
||||
AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType);
|
||||
if (!dtypep) {
|
||||
nodep->v3error("Parameter type's initial value isn't a type: "<<nodep->prettyName());
|
||||
nodep->unlinkFrBack();
|
||||
|
|
@ -204,7 +204,7 @@ private:
|
|||
cleanFileline(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
|
||||
AstTypedef* typep = nodep->backp()->castTypedef();
|
||||
AstTypedef* typep = VN_CAST(nodep->backp(), Typedef);
|
||||
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
|
||||
typep->attrPublic(true);
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
@ -296,13 +296,13 @@ private:
|
|||
// AstVar, AstTypedef, AstNodeFTask are common containers
|
||||
AstNode* backp = nodep->backp();
|
||||
for (; backp; backp=backp->backp()) {
|
||||
if (backp->castVar()) break;
|
||||
else if (backp->castTypedef()) break;
|
||||
else if (backp->castNodeFTask()) break;
|
||||
if (VN_IS(backp, Var)) break;
|
||||
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");
|
||||
AstNodeDType* dtypep = nodep->childDTypep(); dtypep->unlinkFrBack();
|
||||
if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing
|
||||
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
|
||||
nodep->replaceWith(dtypep);
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ private:
|
|||
// and any width errors will look a bit odd, but it works.
|
||||
AstNode* sensp = nodep->sensp();
|
||||
if (sensp
|
||||
&& !sensp->castNodeVarRef()
|
||||
&& !sensp->castConst()) {
|
||||
&& !VN_IS(sensp, NodeVarRef)
|
||||
&& !VN_IS(sensp, Const)) {
|
||||
// Make a new temp wire
|
||||
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
|
||||
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||
|
|
@ -145,11 +145,11 @@ private:
|
|||
// We can't just add under the module, because we may be inside a generate, begin, etc.
|
||||
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
|
||||
AstNode* addwherep = nodep; // Add to this element's next
|
||||
while (addwherep->castSenItem()
|
||||
|| addwherep->castSenTree()) {
|
||||
while (VN_IS(addwherep, SenItem)
|
||||
|| VN_IS(addwherep, SenTree)) {
|
||||
addwherep = addwherep->backp();
|
||||
}
|
||||
if (!addwherep->castAlways()) { // Assertion perhaps?
|
||||
if (!VN_IS(addwherep, Always)) { // Assertion perhaps?
|
||||
sensp->v3error("Unsupported: Non-single-bit pos/negedge clock statement under some complicated block");
|
||||
addwherep = m_modp;
|
||||
}
|
||||
|
|
@ -166,26 +166,26 @@ private:
|
|||
bool did=1;
|
||||
while (did) {
|
||||
did=0;
|
||||
if (AstNodeSel* selp = nodep->sensp()->castNodeSel()) {
|
||||
if (AstNodeSel* selp = VN_CAST(nodep->sensp(), NodeSel)) {
|
||||
AstNode* fromp = selp->fromp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
|
||||
did=1;
|
||||
}
|
||||
// NodeSel doesn't include AstSel....
|
||||
if (AstSel* selp = nodep->sensp()->castSel()) {
|
||||
if (AstSel* selp = VN_CAST(nodep->sensp(), Sel)) {
|
||||
AstNode* fromp = selp->fromp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
|
||||
did=1;
|
||||
}
|
||||
if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) {
|
||||
if (AstNodePreSel* selp = VN_CAST(nodep->sensp(), NodePreSel)) {
|
||||
AstNode* fromp = selp->lhsp()->unlinkFrBack();
|
||||
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
|
||||
did=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!nodep->sensp()->castNodeVarRef()
|
||||
&& !nodep->sensp()->castEnumItemRef() // V3Const will cleanup
|
||||
if (!VN_IS(nodep->sensp(), NodeVarRef)
|
||||
&& !VN_IS(nodep->sensp(), EnumItemRef) // V3Const will cleanup
|
||||
&& !nodep->isIllegal()) {
|
||||
if (debug()) nodep->dumpTree(cout,"-tree: ");
|
||||
nodep->v3error("Unsupported: Complex statement in sensitivity list");
|
||||
|
|
@ -203,16 +203,16 @@ private:
|
|||
// So we replicate it in another node
|
||||
// Note that V3Param knows not to replace AstVarRef's under AstAttrOf's
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
|
||||
if (AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
varrefp->cloneTree(false)));
|
||||
} else if (AstUnlinkedRef* uvxrp = basefromp->castUnlinkedRef()) { // Maybe unlinked - so need to clone
|
||||
} else if (AstUnlinkedRef* uvxrp = VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
|
||||
uvxrp->cloneTree(false)));
|
||||
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
|
||||
} else if (AstMemberSel* fromp = VN_CAST(basefromp, MemberSel)) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else if (AstEnumItemRef* fromp = basefromp->castEnumItemRef()) {
|
||||
} else if (AstEnumItemRef* fromp = VN_CAST(basefromp, EnumItemRef)) {
|
||||
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
|
||||
fromp->cloneTree(false)));
|
||||
} else {
|
||||
|
|
@ -307,7 +307,7 @@ private:
|
|||
skipCount--;
|
||||
continue;
|
||||
}
|
||||
AstConst *constp = argp->castConst();
|
||||
AstConst *constp = VN_CAST(argp, Const);
|
||||
bool isFromString = (constp) ? constp->num().isFromString() : false;
|
||||
if (isFromString) {
|
||||
int numchars = argp->dtypep()->width()/8;
|
||||
|
|
@ -357,15 +357,15 @@ private:
|
|||
|
||||
virtual void visit(AstFOpen* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFEof* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
|
|
@ -380,9 +380,9 @@ private:
|
|||
// Cleanup old-school displays without format arguments
|
||||
if (!nodep->hasFormat()) {
|
||||
if (nodep->text()!="") nodep->v3fatalSrc("Non-format $sformatf should have \"\" format");
|
||||
if (nodep->exprsp()->castConst()
|
||||
&& nodep->exprsp()->castConst()->num().isFromString()) {
|
||||
AstConst* fmtp = nodep->exprsp()->unlinkFrBack()->castConst();
|
||||
if (VN_IS(nodep->exprsp(), Const)
|
||||
&& VN_CAST(nodep->exprsp(), Const)->num().isFromString()) {
|
||||
AstConst* fmtp = VN_CAST(nodep->exprsp()->unlinkFrBack(), Const);
|
||||
nodep->text(fmtp->num().toString());
|
||||
pushDeletep(fmtp); VL_DANGLING(fmtp);
|
||||
}
|
||||
|
|
@ -390,7 +390,8 @@ private:
|
|||
}
|
||||
string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
|
||||
nodep->text(newFormat);
|
||||
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
|
||||
if ((VN_IS(nodep->backp(), Display)
|
||||
&& VN_CAST(nodep->backp(), Display)->displayType().needScopeTracking())
|
||||
|| nodep->formatScopeTracking()) {
|
||||
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
|
||||
}
|
||||
|
|
@ -408,7 +409,7 @@ private:
|
|||
// Massive hack, just tie off all outputs so our analysis can proceed
|
||||
AstVar* varoutp = NULL;
|
||||
for (AstNode* stmtp = m_modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* varp = stmtp->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isInput()) {
|
||||
} else if (varp->isOutput()) {
|
||||
if (varoutp) { varp->v3error("Multiple outputs not allowed in udp modules"); }
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ private:
|
|||
// We don't need to test for tracing; it would be in the tracefunc if it was needed
|
||||
UINFO(4," ModVar->BlkVar "<<nodep<<endl);
|
||||
++m_statLocVars;
|
||||
AstCFunc* newfuncp = nodep->user1p()->castCFunc();
|
||||
AstCFunc* newfuncp = VN_CAST(nodep->user1p(), CFunc);
|
||||
nodep->unlinkFrBack();
|
||||
newfuncp->addInitsp(nodep);
|
||||
// Done
|
||||
|
|
@ -175,8 +175,8 @@ private:
|
|||
// This could be more complicated; allow always-set under both branches of a IF.
|
||||
// If so, check for ArrayRef's and such, as they aren't acceptable.
|
||||
for (; nodep; nodep=nodep->nextp()) {
|
||||
if (nodep->castNodeAssign()) {
|
||||
if (AstVarRef* varrefp = nodep->castNodeAssign()->lhsp()->castVarRef()) {
|
||||
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");
|
||||
if (!varrefp->varp()->user4p()) {
|
||||
UINFO(4," FuncAsn "<<varrefp<<endl);
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ private:
|
|||
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
m_hasClk = false;
|
||||
if (AstVarRef* varrefp = nodep->rhsp()->castVarRef()) {
|
||||
if (AstVarRef* varrefp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
this->visit(varrefp);
|
||||
m_rightClkWidth = varrefp->width();
|
||||
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
|
||||
|
|
@ -298,7 +298,7 @@ private:
|
|||
return; // skip the marking
|
||||
}
|
||||
|
||||
AstVarRef* lhsp = nodep->lhsp()->castVarRef();
|
||||
const AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
if (lhsp && (lhsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_UNKNOWN)) {
|
||||
lhsp->varp()->attrClocker(AstVarAttrClocker::CLOCKER_YES); // mark as clocker
|
||||
m_newClkMarked = true; // enable a further run since new clocker is marked
|
||||
|
|
@ -343,8 +343,8 @@ private:
|
|||
virtual void visit(AstReplicate* nodep) {
|
||||
if (m_inAss) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->rhsp()->castConst()) {
|
||||
m_childClkWidth = m_childClkWidth * nodep->rhsp()->castConst()->toUInt();
|
||||
if (VN_IS(nodep->rhsp(), Const)) {
|
||||
m_childClkWidth = m_childClkWidth * VN_CAST(nodep->rhsp(), Const)->toUInt();
|
||||
} else {
|
||||
m_childClkWidth = nodep->width(); // can not check in this case.
|
||||
}
|
||||
|
|
@ -389,7 +389,7 @@ private:
|
|||
return level;
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef() )
|
||||
if (const AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef) )
|
||||
if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) {
|
||||
m_clkAss = true;
|
||||
UINFO(6, "node was marked as clocker "<<varrefp<<endl);
|
||||
|
|
@ -563,8 +563,8 @@ private:
|
|||
toLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->top());
|
||||
}
|
||||
//
|
||||
if ((fromLVtxp && fromLVtxp->nodep()->castInitial())
|
||||
|| (toLVtxp && toLVtxp->nodep()->castInitial())) {
|
||||
if ((fromLVtxp && VN_IS(fromLVtxp->nodep(), Initial))
|
||||
|| (toLVtxp && VN_IS(toLVtxp->nodep(), Initial))) {
|
||||
// IEEE does not specify ordering between initial blocks, so we can do whatever we want
|
||||
// We especially do not want to evaluate multiple times, so do not mark the edge circular
|
||||
}
|
||||
|
|
@ -1079,7 +1079,7 @@ void OrderVisitor::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
|
|||
processInputsInIterate(vvertexp, todoVec);
|
||||
}
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
|
||||
if (vvertexp->nodep()->castNodeAssign()) {
|
||||
if (VN_IS(vvertexp->nodep(), NodeAssign)) {
|
||||
processInputsInIterate(vvertexp, todoVec);
|
||||
}
|
||||
}
|
||||
|
|
@ -1340,8 +1340,8 @@ bool OrderVisitor::domainsExclusive(const AstSenTree* fromp,
|
|||
// always @(negedge A)
|
||||
//
|
||||
// ... unless you know more about A and B, which sounds hard.
|
||||
const AstSenItem* fromSenListp = fromp->sensesp()->castSenItem();
|
||||
const AstSenItem* toSenListp = top->sensesp()->castSenItem();
|
||||
const AstSenItem* fromSenListp = VN_CAST(fromp->sensesp(), SenItem);
|
||||
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");
|
||||
|
|
@ -1516,11 +1516,11 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
|
|||
<<" s="<<(void*)(scopep)<<" "<<lvertexp<<endl);
|
||||
AstSenTree* domainp = lvertexp->domainp();
|
||||
AstNode* nodep = lvertexp->nodep();
|
||||
AstNodeModule* modp = scopep->user1p()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func
|
||||
if (nodep->castUntilStable()) {
|
||||
AstNodeModule* modp = VN_CAST(scopep->user1p(), NodeModule); UASSERT(modp,"NULL"); // Stashed by visitor func
|
||||
if (VN_IS(nodep, UntilStable)) {
|
||||
nodep->v3fatalSrc("Not implemented");
|
||||
}
|
||||
else if (nodep->castSenTree()) {
|
||||
else if (VN_IS(nodep, SenTree)) {
|
||||
// Just ignore sensitivities, we'll deal with them when we move statements that need them
|
||||
}
|
||||
else { // Normal logic
|
||||
|
|
|
|||
126
src/V3Param.cpp
126
src/V3Param.cpp
|
|
@ -123,14 +123,14 @@ private:
|
|||
std::vector<int> usedLetter; usedLetter.resize(256);
|
||||
// Pass 1, assign first letter to each gparam's name
|
||||
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* varp = stmtp->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isGParam()||varp->isIfaceRef()) {
|
||||
char ch = varp->name()[0];
|
||||
ch = toupper(ch); if (ch<'A' || ch>'Z') ch='Z';
|
||||
varp->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
|
||||
usedLetter[static_cast<int>(ch)]++;
|
||||
}
|
||||
} else if (AstParamTypeDType* typep = stmtp->castParamTypeDType()) {
|
||||
} else if (AstParamTypeDType* typep = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
char ch = 'T';
|
||||
typep->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
|
||||
usedLetter[static_cast<int>(ch)]++;
|
||||
|
|
@ -175,7 +175,7 @@ private:
|
|||
void collectPins(CloneMap* clonemapp, AstNodeModule* modp) {
|
||||
// Grab all I/O so we can remap our pins later
|
||||
for (AstNode* stmtp=modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstVar* varp = stmtp->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(stmtp, Var)) {
|
||||
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
|
||||
// Cloning saved a pointer to the new node for us, so just follow that link.
|
||||
AstVar* oldvarp = varp->clonep();
|
||||
|
|
@ -183,7 +183,7 @@ private:
|
|||
clonemapp->insert(make_pair(oldvarp, varp));
|
||||
}
|
||||
}
|
||||
else if (AstParamTypeDType* ptp = stmtp->castParamTypeDType()) {
|
||||
else if (AstParamTypeDType* ptp = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
if (ptp->isGParam()) {
|
||||
AstParamTypeDType* oldptp = ptp->clonep();
|
||||
clonemapp->insert(make_pair(oldptp, ptp));
|
||||
|
|
@ -192,18 +192,18 @@ private:
|
|||
}
|
||||
}
|
||||
void relinkPins(CloneMap* clonemapp, AstPin* startpinp) {
|
||||
for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = startpinp; pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (pinp->modVarp()) {
|
||||
// Find it in the clone structure
|
||||
//UINFO(8,"Clone find 0x"<<hex<<(uint32_t)pinp->modVarp()<<endl);
|
||||
CloneMap::iterator cloneiter = clonemapp->find(pinp->modVarp());
|
||||
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
|
||||
pinp->modVarp(cloneiter->second->castVar());
|
||||
pinp->modVarp(VN_CAST(cloneiter->second, Var));
|
||||
}
|
||||
else if (pinp->modPTypep()) {
|
||||
CloneMap::iterator cloneiter = clonemapp->find(pinp->modPTypep());
|
||||
UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list");
|
||||
pinp->modPTypep(cloneiter->second->castParamTypeDType());
|
||||
pinp->modPTypep(VN_CAST(cloneiter->second, ParamTypeDType));
|
||||
}
|
||||
else {
|
||||
pinp->v3fatalSrc("Not linked?");
|
||||
|
|
@ -229,8 +229,8 @@ private:
|
|||
for (int nonIf=0; nonIf<2; ++nonIf) {
|
||||
for (CellList::iterator it=m_cellps.begin(); it!=m_cellps.end(); ++it) {
|
||||
AstCell* nodep = *it;
|
||||
if ((nonIf==0 && nodep->modp()->castIface())
|
||||
|| (nonIf==1 && !nodep->modp()->castIface())) {
|
||||
if ((nonIf==0 && VN_IS(nodep->modp(), Iface))
|
||||
|| (nonIf==1 && !VN_IS(nodep->modp(), Iface))) {
|
||||
visitCell(nodep);
|
||||
}
|
||||
}
|
||||
|
|
@ -253,7 +253,7 @@ private:
|
|||
UINFO(4," MOD-recursive-dead. "<<nodep<<endl); // Fake, made for recursive elimination
|
||||
nodep->dead(true); // So Dead checks won't count references to it
|
||||
} else if (nodep->level() <= 2 // Haven't added top yet, so level 2 is the top
|
||||
|| nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet
|
||||
|| VN_IS(nodep, Package)) { // Likewise haven't done wrapTopPackages yet
|
||||
// Add request to END of modules left to process
|
||||
m_todoModps.insert(make_pair(nodep->level(), nodep));
|
||||
visitModules();
|
||||
|
|
@ -275,7 +275,7 @@ private:
|
|||
if (nodep->isParam()) {
|
||||
if (!nodep->valuep()) { nodep->v3fatalSrc("Parameter without initial value"); }
|
||||
V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init()
|
||||
if (!nodep->valuep()->castConst()) { // Complex init, like an array
|
||||
if (!VN_IS(nodep->valuep(), Const)) { // Complex init, like an array
|
||||
// Make a new INITIAL to set the value.
|
||||
// This allows the normal array/struct handling code to properly initialize the parameter
|
||||
nodep->addNext(new AstInitial(nodep->fileline(),
|
||||
|
|
@ -293,11 +293,11 @@ private:
|
|||
bool ifaceParamReplace(AstVarXRef* nodep, AstNode* candp) {
|
||||
for (; candp; candp = candp->nextp()) {
|
||||
if (nodep->name() == candp->name()) {
|
||||
if (AstVar* varp = candp->castVar()) {
|
||||
if (AstVar* varp = VN_CAST(candp, Var)) {
|
||||
UINFO(9,"Found interface parameter: "<<varp<<endl);
|
||||
nodep->varp(varp);
|
||||
return true;
|
||||
} else if (AstPin* pinp = candp->castPin()) {
|
||||
} 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");
|
||||
nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep);
|
||||
|
|
@ -313,15 +313,15 @@ private:
|
|||
if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) {
|
||||
AstNode* backp = nodep;
|
||||
while ((backp = backp->backp())) {
|
||||
if (backp->castNodeModule()) {
|
||||
if (VN_IS(backp, NodeModule)) {
|
||||
UINFO(9,"Hit module boundary, done looking for interface"<<endl);
|
||||
break;
|
||||
}
|
||||
if (backp->castVar()
|
||||
&& backp->castVar()->isIfaceRef()
|
||||
&& backp->castVar()->childDTypep()
|
||||
&& backp->castVar()->childDTypep()->castIfaceRefDType()) {
|
||||
AstIfaceRefDType* ifacerefp = backp->castVar()->childDTypep()->castIfaceRefDType();
|
||||
if (VN_IS(backp, Var)
|
||||
&& VN_CAST(backp, Var)->isIfaceRef()
|
||||
&& VN_CAST(backp, Var)->childDTypep()
|
||||
&& VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType)) {
|
||||
AstIfaceRefDType* ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType);
|
||||
// Interfaces passed in on the port map have ifaces
|
||||
if (AstIface* ifacep = ifacerefp->ifacep()) {
|
||||
if (dotted == backp->name()) {
|
||||
|
|
@ -347,8 +347,8 @@ private:
|
|||
}
|
||||
|
||||
virtual void visit(AstUnlinkedRef* nodep) {
|
||||
AstVarXRef* varxrefp = nodep->op1p()->castVarXRef();
|
||||
AstNodeFTaskRef* taskrefp = nodep->op1p()->castNodeFTaskRef();
|
||||
AstVarXRef* varxrefp = VN_CAST(nodep->op1p(), VarXRef);
|
||||
AstNodeFTaskRef* taskrefp = VN_CAST(nodep->op1p(), NodeFTaskRef);
|
||||
if (varxrefp) {
|
||||
m_unlinkedTxt = varxrefp->dotted();
|
||||
} else if (taskrefp) {
|
||||
|
|
@ -369,7 +369,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstCellArrayRef* nodep) {
|
||||
V3Const::constifyParamsEdit(nodep->selp());
|
||||
if (AstConst* constp = nodep->selp()->castConst()) {
|
||||
if (const AstConst* constp = VN_CAST(nodep->selp(), Const)) {
|
||||
string index = AstNode::encodeNumber(constp->toSInt());
|
||||
string replacestr = nodep->name() + "__BRA__??__KET__";
|
||||
size_t pos = m_unlinkedTxt.find(replacestr);
|
||||
|
|
@ -408,7 +408,7 @@ private:
|
|||
V3Width::widthGenerateParamsEdit(nodep); // Param typed widthing will
|
||||
// NOT recurse the body.
|
||||
V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change
|
||||
if (AstConst* constp = nodep->condp()->castConst()) {
|
||||
if (const AstConst* constp = VN_CAST(nodep->condp(), Const)) {
|
||||
AstNode* keepp = (constp->isZero()
|
||||
? nodep->elsesp()
|
||||
: nodep->ifsp());
|
||||
|
|
@ -431,7 +431,7 @@ private:
|
|||
//! move to more generic constant expressions, such code will be needed here.
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
if (nodep->genforp()) {
|
||||
AstGenFor* forp = nodep->genforp()->castGenFor();
|
||||
AstGenFor* forp = VN_CAST(nodep->genforp(), GenFor);
|
||||
if (!forp) nodep->v3fatalSrc("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
|
||||
|
|
@ -468,9 +468,9 @@ private:
|
|||
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body,
|
||||
// don't trigger errors yet.
|
||||
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
|
||||
AstConst* exprp = nodep->exprp()->castConst();
|
||||
AstConst* exprp = VN_CAST(nodep->exprp(), Const);
|
||||
// Constify
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* ep = itemp->condsp(); ep; ) {
|
||||
AstNode* nextp = ep->nextp(); //May edit list
|
||||
ep->iterateAndNext(*this);
|
||||
|
|
@ -479,10 +479,10 @@ private:
|
|||
}
|
||||
}
|
||||
// Item match
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (!itemp->isDefault()) {
|
||||
for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) {
|
||||
if (AstConst* ccondp = ep->castConst()) {
|
||||
if (const AstConst* ccondp = VN_CAST(ep, Const)) {
|
||||
V3Number match (nodep->fileline(), 1);
|
||||
match.opEq(ccondp->num(), exprp->num());
|
||||
if (!keepp && match.isNeqZero()) {
|
||||
|
|
@ -495,7 +495,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Else default match
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (itemp->isDefault()) {
|
||||
if (!keepp) keepp=itemp->bodysp();
|
||||
}
|
||||
|
|
@ -550,20 +550,20 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
if (nodep->recursive()) any_overrides = true; // Must always clone __Vrcm (recursive modules)
|
||||
longname += "_";
|
||||
if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t");
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (!pinp->exprp()) continue; // No-connect
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
if (!modvarp->isGParam()) {
|
||||
pinp->v3error("Attempted parameter setting of non-parameter: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
|
||||
} else if (pinp->exprp()->castInitArray()
|
||||
&& modvarp->subDTypep()->castUnpackArrayDType()) {
|
||||
} else if (VN_IS(pinp->exprp(), InitArray)
|
||||
&& VN_IS(modvarp->subDTypep(), UnpackArrayDType)) {
|
||||
// Array assigned to array
|
||||
AstNode* exprp = pinp->exprp();
|
||||
longname += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp);
|
||||
any_overrides = true;
|
||||
} else {
|
||||
AstConst* exprp = pinp->exprp()->castConst();
|
||||
AstConst* origp = modvarp->valuep()->castConst();
|
||||
AstConst* exprp = VN_CAST(pinp->exprp(), Const);
|
||||
AstConst* origp = VN_CAST(modvarp->valuep(), Const);
|
||||
if (!exprp) {
|
||||
//if (debug()) pinp->dumpTree(cout,"error:");
|
||||
pinp->v3error("Can't convert defparam value to constant: Param "<<pinp->name()<<" of "<<nodep->prettyName());
|
||||
|
|
@ -583,7 +583,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
}
|
||||
}
|
||||
} else if (AstParamTypeDType* modvarp = pinp->modPTypep()) {
|
||||
AstNodeDType* exprp = pinp->exprp()->castNodeDType();
|
||||
AstNodeDType* exprp = VN_CAST(pinp->exprp(), NodeDType);
|
||||
AstNodeDType* origp = modvarp->subDTypep();
|
||||
if (!exprp) {
|
||||
pinp->v3error("Parameter type pin value isn't a type: Param "<<pinp->prettyName()<<" of "<<nodep->prettyName());
|
||||
|
|
@ -605,39 +605,39 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
}
|
||||
}
|
||||
IfaceRefRefs ifaceRefRefs;
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
AstVar* modvarp = pinp->modVarp();
|
||||
if (modvarp->isIfaceRef()) {
|
||||
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
|
||||
if (!portIrefp && modvarp->subDTypep()->castUnpackArrayDType()) {
|
||||
portIrefp = modvarp->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
AstIfaceRefDType* portIrefp = VN_CAST(modvarp->subDTypep(), IfaceRefDType);
|
||||
if (!portIrefp && VN_IS(modvarp->subDTypep(), UnpackArrayDType)) {
|
||||
portIrefp = VN_CAST(VN_CAST(modvarp->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
|
||||
}
|
||||
|
||||
AstIfaceRefDType* pinIrefp = NULL;
|
||||
AstNode* exprp = pinp->exprp();
|
||||
if (exprp
|
||||
&& exprp->castVarRef()
|
||||
&& exprp->castVarRef()->varp()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType())
|
||||
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType();
|
||||
&& VN_IS(exprp, VarRef)
|
||||
&& VN_CAST(exprp, VarRef)->varp()
|
||||
&& VN_CAST(exprp, VarRef)->varp()->subDTypep()
|
||||
&& VN_IS(VN_CAST(exprp, VarRef)->varp()->subDTypep(), IfaceRefDType))
|
||||
pinIrefp = VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), IfaceRefDType);
|
||||
else if (exprp
|
||||
&& exprp->op1p()
|
||||
&& exprp->op1p()->castVarRef()
|
||||
&& exprp->op1p()->castVarRef()->varp()
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
&& VN_IS(exprp->op1p(), VarRef)
|
||||
&& VN_CAST(exprp->op1p(), VarRef)->varp()
|
||||
&& VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep()
|
||||
&& VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)
|
||||
&& VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep()
|
||||
&& VN_CAST(VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))
|
||||
pinIrefp = VN_CAST(VN_CAST(VN_CAST(exprp->op1p(), VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
|
||||
else if (exprp
|
||||
&& exprp->castVarRef()
|
||||
&& exprp->castVarRef()->varp()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
|
||||
&& exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
|
||||
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
|
||||
&& VN_IS(exprp, VarRef)
|
||||
&& VN_CAST(exprp, VarRef)->varp()
|
||||
&& VN_CAST(exprp, VarRef)->varp()->subDTypep()
|
||||
&& VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)
|
||||
&& VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep()
|
||||
&& VN_CAST(VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))
|
||||
pinIrefp = VN_CAST(VN_CAST(VN_CAST(exprp, VarRef)->varp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType);
|
||||
|
||||
UINFO(9," portIfaceRef "<<portIrefp<<endl);
|
||||
|
||||
|
|
@ -698,9 +698,9 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
}
|
||||
// Keep tree sorted by level
|
||||
AstNodeModule* insertp = srcModp;
|
||||
while (insertp->nextp()->castNodeModule()
|
||||
&& insertp->nextp()->castNodeModule()->level() < cellmodp->level()) {
|
||||
insertp = insertp->nextp()->castNodeModule();
|
||||
while (VN_IS(insertp->nextp(), NodeModule)
|
||||
&& VN_CAST(insertp->nextp(), NodeModule)->level() < cellmodp->level()) {
|
||||
insertp = VN_CAST(insertp->nextp(), NodeModule);
|
||||
}
|
||||
insertp->addNextHere(cellmodp);
|
||||
|
||||
|
|
@ -730,7 +730,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
|
||||
// Assign parameters to the constants specified
|
||||
// DOES clone() so must be finished with module clonep() before here
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=VN_CAST(pinp->nextp(), Pin)) {
|
||||
if (pinp->exprp()) {
|
||||
if (AstVar* modvarp = pinp->modVarp()) {
|
||||
AstNode* newp = pinp->exprp(); // Const or InitArray
|
||||
|
|
@ -740,7 +740,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
|
|||
modvarp->valuep(newp->cloneTree(false));
|
||||
}
|
||||
else if (AstParamTypeDType* modptp = pinp->modPTypep()) {
|
||||
AstNodeDType* dtypep = pinp->exprp()->castNodeDType();
|
||||
AstNodeDType* dtypep = VN_CAST(pinp->exprp(), NodeDType);
|
||||
if (!dtypep) pinp->v3fatalSrc("unlinked param dtype");
|
||||
if (modptp->childDTypep()) pushDeletep(modptp->childDTypep()->unlinkFrBack());
|
||||
// Set this parameter to value requested by cell
|
||||
|
|
|
|||
|
|
@ -123,9 +123,9 @@ private:
|
|||
}
|
||||
|
||||
bool assignNoTemp(AstNodeAssign* nodep) {
|
||||
return (nodep->lhsp()->castVarRef()
|
||||
return (VN_IS(nodep->lhsp(), VarRef)
|
||||
&& !AstVar::scVarRecurse(nodep->lhsp())
|
||||
&& nodep->rhsp()->castConst());
|
||||
&& VN_IS(nodep->rhsp(), Const));
|
||||
}
|
||||
void checkNode(AstNode* nodep) {
|
||||
// Consider adding a temp for this expression.
|
||||
|
|
@ -141,14 +141,14 @@ private:
|
|||
if (nodep->isWide()) {
|
||||
if (m_assignLhs) {
|
||||
} else if (nodep->firstAbovep()
|
||||
&& nodep->firstAbovep()->castNodeAssign()
|
||||
&& assignNoTemp(nodep->firstAbovep()->castNodeAssign())) {
|
||||
&& VN_IS(nodep->firstAbovep(), NodeAssign)
|
||||
&& assignNoTemp(VN_CAST(nodep->firstAbovep(), NodeAssign))) {
|
||||
// Not much point if it's just a direct assignment to a constant
|
||||
} else if (nodep->backp()->castSel()
|
||||
&& nodep->backp()->castSel()->widthp() == nodep) {
|
||||
} else if (VN_IS(nodep->backp(), Sel)
|
||||
&& VN_CAST(nodep->backp(), Sel)->widthp() == nodep) {
|
||||
// AstSel::width must remain a constant
|
||||
} else if (nodep->firstAbovep()
|
||||
&& nodep->firstAbovep()->castArraySel()) {
|
||||
&& VN_IS(nodep->firstAbovep(), ArraySel)) {
|
||||
// ArraySel's are pointer refs, ignore
|
||||
} else {
|
||||
UINFO(4,"Cre Temp: "<<nodep<<endl);
|
||||
|
|
@ -267,7 +267,7 @@ private:
|
|||
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
|
||||
if (!nodep->user2SetOnce()) {
|
||||
UINFO(4," ShiftFix "<<nodep<<endl);
|
||||
AstConst* shiftp = nodep->rhsp()->castConst();
|
||||
const AstConst* shiftp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (shiftp && shiftp->num().mostSetBitP1() > 32) {
|
||||
shiftp->v3error("Unsupported: Shifting of by over 32-bit number isn't supported."
|
||||
<<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n");
|
||||
|
|
@ -359,8 +359,8 @@ private:
|
|||
virtual void visit(AstNodeCond* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (nodep->expr1p()->isWide()
|
||||
&& !nodep->condp()->castConst()
|
||||
&& !nodep->condp()->castVarRef()) {
|
||||
&& !VN_IS(nodep->condp(), Const)
|
||||
&& !VN_IS(nodep->condp(), VarRef)) {
|
||||
// We're going to need the expression several times in the expanded code,
|
||||
// so might as well make it a common expression
|
||||
createDeepTemp(nodep->condp(), false);
|
||||
|
|
@ -375,10 +375,10 @@ private:
|
|||
m_stmtp = NULL;
|
||||
if (v3Global.opt.autoflush()) {
|
||||
AstNode* searchp = nodep->nextp();
|
||||
while (searchp && searchp->castComment()) searchp = searchp->nextp();
|
||||
while (searchp && VN_IS(searchp, Comment)) searchp = searchp->nextp();
|
||||
if (searchp
|
||||
&& searchp->castDisplay()
|
||||
&& nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) {
|
||||
&& VN_IS(searchp, Display)
|
||||
&& nodep->filep()->sameGateTree(VN_CAST(searchp, Display)->filep())) {
|
||||
// There's another display next; we can just wait to flush
|
||||
} else {
|
||||
UINFO(4,"Autoflush "<<nodep<<endl);
|
||||
|
|
@ -393,7 +393,7 @@ private:
|
|||
// to avoid passing a pointer to a temporary.
|
||||
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
|
||||
if (expp->dtypep()->basicp()->isString()
|
||||
&& !expp->castVarRef()) {
|
||||
&& !VN_IS(expp, VarRef)) {
|
||||
createDeepTemp(expp, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,11 +110,11 @@ private:
|
|||
|
||||
m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(),
|
||||
nodep, scopename, m_aboveScopep, m_aboveCellp);
|
||||
if (nodep->castPackage()) m_packageScopes.insert(make_pair(nodep->castPackage(), m_scopep));
|
||||
if (VN_IS(nodep, Package)) m_packageScopes.insert(make_pair(VN_CAST(nodep, Package), m_scopep));
|
||||
|
||||
// Now for each child cell, iterate the module this cell points to
|
||||
for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) {
|
||||
if (AstCell* cellp = cellnextp->castCell()) {
|
||||
if (AstCell* cellp = VN_CAST(cellnextp, Cell)) {
|
||||
AstScope* oldScopep = m_scopep;
|
||||
AstCell* oldAbCellp = m_aboveCellp;
|
||||
AstScope* oldAbScopep = m_aboveScopep;
|
||||
|
|
@ -381,7 +381,7 @@ private:
|
|||
if (nodep->packagep()) {
|
||||
// Point to the clone
|
||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked");
|
||||
AstNodeFTask* newp = nodep->taskp()->user2p()->castNodeFTask();
|
||||
AstNodeFTask* newp = VN_CAST(nodep->taskp()->user2p(), NodeFTask);
|
||||
if (!newp) nodep->v3fatalSrc("No clone for package function");
|
||||
nodep->taskp(newp);
|
||||
UINFO(9," New pkg-taskref "<<nodep<<endl);
|
||||
|
|
|
|||
|
|
@ -119,14 +119,14 @@ private:
|
|||
|
||||
// Potentially very slow, intended for debugging
|
||||
string prettyNumber(V3Number* nump, AstNodeDType* dtypep) {
|
||||
if (AstRefDType* refdtypep = dtypep->castRefDType()) {
|
||||
if (AstRefDType* refdtypep = VN_CAST(dtypep, RefDType)) {
|
||||
dtypep = refdtypep->skipRefp();
|
||||
}
|
||||
if (AstStructDType* stp = dtypep->castStructDType()) {
|
||||
if (AstStructDType* stp = VN_CAST(dtypep, StructDType)) {
|
||||
if (stp->packed()) {
|
||||
std::ostringstream out;
|
||||
out<<"'{";
|
||||
for (AstMemberDType* itemp = stp->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* itemp = stp->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
|
||||
int width = itemp->width();
|
||||
int lsb = itemp->lsb();
|
||||
int msb = lsb + width - 1;
|
||||
|
|
@ -143,7 +143,7 @@ private:
|
|||
out<<"}";
|
||||
return out.str();
|
||||
}
|
||||
} else if (AstPackArrayDType * arrayp = dtypep->castPackArrayDType()) {
|
||||
} else if (AstPackArrayDType * arrayp = VN_CAST(dtypep, PackArrayDType)) {
|
||||
if (AstNodeDType * childTypep = arrayp->subDTypep()) {
|
||||
std::ostringstream out;
|
||||
out<<"[";
|
||||
|
|
@ -314,7 +314,7 @@ private:
|
|||
}
|
||||
void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
if (nodep->castAssignDly()) {
|
||||
if (VN_IS(nodep, AssignDly)) {
|
||||
// Don't do setNumber, as value isn't yet visible to following statements
|
||||
newOutNumber(vscp)->opAssign(*nump);
|
||||
} else {
|
||||
|
|
@ -341,9 +341,9 @@ private:
|
|||
// We can't have non-delayed assignments with same value on LHS and RHS
|
||||
// as we don't figure out variable ordering.
|
||||
// Delayed is OK though, as we'll decode the next state separately.
|
||||
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()
|
||||
&& !nodep->varp()->dtypeSkipRefp()->castPackArrayDType()
|
||||
&& !nodep->varp()->dtypeSkipRefp()->castStructDType())
|
||||
if (!VN_IS(nodep->varp()->dtypeSkipRefp(), BasicDType)
|
||||
&& !VN_IS(nodep->varp()->dtypeSkipRefp(), PackArrayDType)
|
||||
&& !VN_IS(nodep->varp()->dtypeSkipRefp(), StructDType))
|
||||
clearOptimizable(nodep,"Array references/not basic");
|
||||
if (nodep->lvalue()) {
|
||||
if (m_inDlyAssign) {
|
||||
|
|
@ -576,11 +576,11 @@ private:
|
|||
// Recurse down to find final variable being set (outVarrefp), with value to write on nodep->rhsp()
|
||||
checkNodeInfo(selp);
|
||||
selp->lsbp()->iterateAndNext(*this); // Bit index
|
||||
if (AstVarRef* varrefp = selp->fromp()->castVarRef()) {
|
||||
if (AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef)) {
|
||||
outVarrefpRef = varrefp;
|
||||
lsbRef = *fetchNumber(selp->lsbp());
|
||||
return; // And presumably still optimizable()
|
||||
} else if (AstSel* subselp = selp->lhsp()->castSel()) {
|
||||
} else if (AstSel* subselp = VN_CAST(selp->lhsp(), Sel)) {
|
||||
V3Number sublsb = V3Number(nodep->fileline());
|
||||
handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb/*ref*/, depth+1);
|
||||
if (optimizable()) {
|
||||
|
|
@ -595,7 +595,7 @@ private:
|
|||
virtual void visit(AstNodeAssign* nodep) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
if (!optimizable()) return; // Accelerate
|
||||
if (nodep->castAssignDly()) {
|
||||
if (VN_IS(nodep, AssignDly)) {
|
||||
if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
|
||||
m_anyAssignDly = true;
|
||||
m_inDlyAssign = true;
|
||||
|
|
@ -604,11 +604,11 @@ private:
|
|||
m_anyAssignComb = true;
|
||||
}
|
||||
|
||||
if (AstSel* selp = nodep->lhsp()->castSel()) {
|
||||
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) {
|
||||
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
|
||||
handleAssignSel(nodep, selp);
|
||||
}
|
||||
else if (!nodep->lhsp()->castVarRef()) {
|
||||
else if (!VN_IS(nodep->lhsp(), VarRef)) {
|
||||
clearOptimizable(nodep, "LHS isn't simple variable");
|
||||
}
|
||||
else if (m_checkOnly) {
|
||||
|
|
@ -617,7 +617,7 @@ private:
|
|||
else if (optimizable()) {
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
if (optimizable()) {
|
||||
AstNode* vscp = varOrScope(nodep->lhsp()->castVarRef());
|
||||
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
|
||||
assignOutNumber(nodep, vscp, fetchNumber(nodep->rhsp()));
|
||||
}
|
||||
}
|
||||
|
|
@ -636,7 +636,7 @@ private:
|
|||
} else if (optimizable()) {
|
||||
nodep->exprp()->iterateAndNext(*this);
|
||||
bool hit = false;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (!itemp->isDefault()) {
|
||||
for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) {
|
||||
if (hit) break;
|
||||
|
|
@ -653,7 +653,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Else default match
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
if (hit) break;
|
||||
if (!hit && itemp->isDefault()) {
|
||||
itemp->bodysp()->iterateAndNext(*this);
|
||||
|
|
@ -764,9 +764,9 @@ private:
|
|||
if (!optimizable()) return; // Accelerate
|
||||
UINFO(5," FUNCREF "<<nodep<<endl);
|
||||
if (!m_params) { badNodeType(nodep); return; }
|
||||
AstNodeFTask* funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
AstNodeFTask* funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
|
||||
funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
|
||||
funcp = VN_CAST(nodep->taskp(), NodeFTask); if (!funcp) nodep->v3fatalSrc("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
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class SliceVisitor : public AstNVisitor {
|
|||
|
||||
AstNode* cloneAndSel(AstNode* nodep, int elements, int offset) {
|
||||
// Insert an ArraySel, except for a few special cases
|
||||
AstUnpackArrayDType* arrayp = nodep->dtypep()->skipRefp()->castUnpackArrayDType();
|
||||
AstUnpackArrayDType* arrayp = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
|
||||
if (!arrayp) { // V3Width should have complained, but...
|
||||
if (!m_assignError) nodep->v3error(nodep->prettyTypeName()<<" is not an unpacked array, but is in an unpacked array context");
|
||||
m_assignError = true;
|
||||
|
|
@ -85,7 +85,7 @@ class SliceVisitor : public AstNVisitor {
|
|||
elements = 1; offset = 0;
|
||||
}
|
||||
AstNode* newp;
|
||||
if (AstInitArray* initp = nodep->castInitArray()) {
|
||||
if (AstInitArray* initp = VN_CAST(nodep, InitArray)) {
|
||||
UINFO(9," cloneInitArray("<<elements<<","<<offset<<") "<<nodep<<endl);
|
||||
AstNode* itemp = initp->initsp();
|
||||
int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset;
|
||||
|
|
@ -98,21 +98,21 @@ class SliceVisitor : public AstNVisitor {
|
|||
}
|
||||
newp = itemp->cloneTree(false);
|
||||
}
|
||||
else if (AstNodeCond* snodep = nodep->castNodeCond()) {
|
||||
else if (AstNodeCond* snodep = VN_CAST(nodep, NodeCond)) {
|
||||
UINFO(9," cloneCond("<<elements<<","<<offset<<") "<<nodep<<endl);
|
||||
return snodep->cloneType(snodep->condp()->cloneTree(false),
|
||||
cloneAndSel(snodep->expr1p(), elements, offset),
|
||||
cloneAndSel(snodep->expr2p(), elements, offset));
|
||||
}
|
||||
else if (AstSliceSel* snodep = nodep->castSliceSel()) {
|
||||
else if (AstSliceSel* snodep = VN_CAST(nodep, SliceSel)) {
|
||||
UINFO(9," cloneSliceSel("<<elements<<","<<offset<<") "<<nodep<<endl);
|
||||
int leOffset = (snodep->declRange().lo()
|
||||
+ (!snodep->declRange().littleEndian() ? snodep->declRange().elements()-1-offset : offset));
|
||||
newp = new AstArraySel(nodep->fileline(), snodep->fromp()->cloneTree(false), leOffset);
|
||||
}
|
||||
else if (nodep->castArraySel()
|
||||
|| nodep->castNodeVarRef()
|
||||
|| nodep->castNodeSel()) {
|
||||
else if (VN_IS(nodep, ArraySel)
|
||||
|| VN_IS(nodep, NodeVarRef)
|
||||
|| VN_IS(nodep, NodeSel)) {
|
||||
UINFO(9," cloneSel("<<elements<<","<<offset<<") "<<nodep<<endl);
|
||||
int leOffset = !arrayp->rangep()->littleEndian() ? arrayp->rangep()->elementsConst()-1-offset : offset;
|
||||
newp = new AstArraySel(nodep->fileline(), nodep->cloneTree(false), leOffset);
|
||||
|
|
@ -128,12 +128,12 @@ class SliceVisitor : public AstNVisitor {
|
|||
virtual void visit(AstNodeAssign* nodep) {
|
||||
// Called recursively on newly created assignments
|
||||
if (!nodep->user1()
|
||||
&& !nodep->castAssignAlias()) {
|
||||
&& !VN_IS(nodep, AssignAlias)) {
|
||||
nodep->user1(true);
|
||||
m_assignError = false;
|
||||
if (debug()>=9) { cout<<endl; nodep->dumpTree(cout," Deslice-In: "); }
|
||||
AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
if (AstUnpackArrayDType* arrayp = dtp->castUnpackArrayDType()) {
|
||||
if (AstUnpackArrayDType* arrayp = VN_CAST(dtp, UnpackArrayDType)) {
|
||||
// Left and right could have different msb/lsbs/endianness, but #elements is common
|
||||
// and all variables are realigned to start at zero
|
||||
// Assign of a little endian'ed slice to a big endian one must reverse the elements
|
||||
|
|
@ -170,17 +170,19 @@ class SliceVisitor : public AstNVisitor {
|
|||
// If it's an unpacked array, blow it up into comparing each element
|
||||
AstNodeDType* fromDtp = nodep->lhsp()->dtypep()->skipRefp();
|
||||
UINFO(9, " Bi-Eq/Neq expansion "<<nodep<<endl);
|
||||
if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) {
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
AstNodeBiop* logp = NULL;
|
||||
for (int index = 0; index < adtypep->rangep()->elementsConst(); ++index) {
|
||||
// EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1])
|
||||
AstNodeBiop* clonep = nodep->cloneType
|
||||
(new AstArraySel(nodep->fileline(),
|
||||
nodep->lhsp()->cloneTree(false),
|
||||
index),
|
||||
new AstArraySel(nodep->fileline(),
|
||||
nodep->rhsp()->cloneTree(false),
|
||||
index))->castNodeBiop();
|
||||
AstNodeBiop* clonep
|
||||
= VN_CAST(nodep->cloneType
|
||||
(new AstArraySel(nodep->fileline(),
|
||||
nodep->lhsp()->cloneTree(false),
|
||||
index),
|
||||
new AstArraySel(nodep->fileline(),
|
||||
nodep->rhsp()->cloneTree(false),
|
||||
index)),
|
||||
NodeBiop);
|
||||
if (!logp) logp = clonep;
|
||||
else {
|
||||
switch (nodep->type()) {
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ private:
|
|||
|
||||
void reorderBlock(AstNode* nodep) {
|
||||
// Reorder statements in the completed graph
|
||||
AstAlways* splitAlwaysp = nodep->backp()->castAlways();
|
||||
AstAlways* splitAlwaysp = VN_CAST(nodep->backp(), Always);
|
||||
|
||||
// Map the rank numbers into nodes they associate with
|
||||
typedef std::multimap<uint32_t,AstNode*> RankNodeMap;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ private:
|
|||
nodep->iterateChildrenConst(*this);
|
||||
if (m_counting && nodep->dtypep()) {
|
||||
if (nodep->isUsedClock()) ++m_statVarClock;
|
||||
if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray;
|
||||
if (VN_IS(nodep->dtypeSkipRefp(), UnpackArrayDType)) ++m_statVarArray;
|
||||
else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
|
||||
if (int(m_statVarWidths.size()) <= nodep->width()) {
|
||||
m_statVarWidths.resize(nodep->width()+5);
|
||||
|
|
@ -123,7 +123,7 @@ private:
|
|||
allNodes(nodep);
|
||||
nodep->iterateChildrenConst(*this);
|
||||
if (m_counting) {
|
||||
if (nodep->varp()->dtypeSkipRefp()->castBasicDType()) {
|
||||
if (VN_IS(nodep->varp()->dtypeSkipRefp(), BasicDType)) {
|
||||
m_statVarScpBytes += nodep->varp()->dtypeSkipRefp()->widthTotalBytes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ private:
|
|||
m_assignStep++;
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
bool hit=false;
|
||||
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) {
|
||||
if (AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
if (isSubstVar(varrefp->varp())) {
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
|
|
@ -281,11 +281,11 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (AstWordSel* wordp = nodep->lhsp()->castWordSel()) {
|
||||
if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) {
|
||||
if (wordp->rhsp()->castConst()
|
||||
else if (AstWordSel* wordp = VN_CAST(nodep->lhsp(), WordSel)) {
|
||||
if (AstVarRef* varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
|
||||
if (VN_IS(wordp->rhsp(), Const)
|
||||
&& isSubstVar(varrefp->varp())) {
|
||||
int word = wordp->rhsp()->castConst()->toUInt();
|
||||
int word = VN_CAST(wordp->rhsp(), Const)->toUInt();
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
if (m_ops > SUBST_MAX_OPS_SUBST) {
|
||||
|
|
@ -315,8 +315,8 @@ private:
|
|||
}
|
||||
virtual void visit(AstWordSel* nodep) {
|
||||
nodep->rhsp()->accept(*this);
|
||||
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
AstVarRef* varrefp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (varrefp && isSubstVar(varrefp->varp())
|
||||
&& !varrefp->lvalue()
|
||||
&& constp) {
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public:
|
|||
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
|
||||
const string& name = it->first;
|
||||
VSymEnt* subSrcp = it->second;
|
||||
AstVar* varp = subSrcp->nodep()->castVar();
|
||||
const AstVar* varp = VN_CAST(subSrcp->nodep(), Var);
|
||||
if (!onlyUnmodportable || (varp && varp->varType() == AstVarType::GPARAM)) {
|
||||
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp);
|
||||
reinsert(name, subSymp);
|
||||
|
|
@ -224,8 +224,8 @@ public:
|
|||
string scopes;
|
||||
for (IdNameMap::iterator it = m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) {
|
||||
AstNode* nodep = it->second->nodep();
|
||||
if (nodep->castCell()
|
||||
|| (nodep->castModule() && nodep->castModule()->isTop())) {
|
||||
if (VN_IS(nodep, Cell)
|
||||
|| (VN_IS(nodep, Module) && VN_CAST(nodep, Module)->isTop())) {
|
||||
if (scopes != "") scopes += ", ";
|
||||
scopes += AstNode::prettyName(it->first);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ private:
|
|||
createOutputAssigns(nodep, stmtsp, indexVscp, chgVscp);
|
||||
|
||||
// Link it in.
|
||||
if (AstAlways* nodeap = nodep->castAlways()) {
|
||||
if (AstAlways* nodeap = VN_CAST(nodep, Always)) {
|
||||
// Keep sensitivity list, but delete all else
|
||||
nodeap->bodysp()->unlinkFrBackWithNext()->deleteTree();
|
||||
nodeap->addStmtp(stmtsp);
|
||||
|
|
@ -328,7 +328,7 @@ private:
|
|||
setp = new AstConst (outnump->fileline(), *outnump);
|
||||
}
|
||||
// Note InitArray requires us to have the values in inValue order
|
||||
m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addValuep(setp);
|
||||
VN_CAST(m_tableVarps[outnum]->varp()->valuep(), InitArray)->addValuep(setp);
|
||||
outnum++;
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ private:
|
|||
if (inValue != inValueNextInitArray++)
|
||||
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
|
||||
AstNode* setp = new AstConst (nodep->fileline(), outputChgMask);
|
||||
chgVscp->varp()->valuep()->castInitArray()->addValuep(setp);
|
||||
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
|
||||
}
|
||||
} // each value
|
||||
}
|
||||
|
|
@ -351,8 +351,8 @@ private:
|
|||
if (var1p->width() == var2p->width()
|
||||
&& (var1p->dtypep()->arrayUnpackedElements()
|
||||
== var2p->dtypep()->arrayUnpackedElements())) {
|
||||
AstNode* init1p = var1p->valuep()->castInitArray();
|
||||
AstNode* init2p = var2p->valuep()->castInitArray();
|
||||
const AstNode* init1p = VN_CAST(var1p->valuep(), InitArray);
|
||||
const AstNode* init2p = VN_CAST(var2p->valuep(), InitArray);
|
||||
if (init1p->sameGateTree(init2p)) {
|
||||
UINFO(8," Duplicate table var "<<vsc2p<<" == "<<vsc1p<<endl);
|
||||
vsc1p->unlinkFrBack()->deleteTree();
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ private:
|
|||
public:
|
||||
// METHODS
|
||||
AstScope* getScope(AstNodeFTask* nodep) {
|
||||
AstScope* scopep = nodep->user3p()->castScope();
|
||||
AstScope* scopep = VN_CAST(nodep->user3p(), Scope);
|
||||
if (!scopep) nodep->v3fatalSrc("No scope for function");
|
||||
return scopep;
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ private:
|
|||
// However, to create variables, we need to track the scopes involved.
|
||||
// Find all var->varscope mappings, for later cleanup
|
||||
for (AstNode* stmtp = nodep->varsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVarScope* vscp = stmtp->castVarScope()) {
|
||||
if (AstVarScope* vscp = VN_CAST(stmtp, VarScope)) {
|
||||
if (vscp->varp()->isFuncLocal()) {
|
||||
UINFO(9," funcvsc "<<vscp<<endl);
|
||||
m_varToScopeMap.insert(std::make_pair(std::make_pair(nodep, vscp->varp()), vscp));
|
||||
|
|
@ -175,7 +175,7 @@ private:
|
|||
}
|
||||
// Likewise, all FTask->scope mappings
|
||||
for (AstNode* stmtp = nodep->blocksp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstNodeFTask* taskp = stmtp->castNodeFTask()) {
|
||||
if (AstNodeFTask* taskp = VN_CAST(stmtp, NodeFTask)) {
|
||||
taskp->user3p(nodep);
|
||||
}
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ private:
|
|||
// Similar code in V3Inline
|
||||
if (nodep->varp()->user2p()) { // It's being converted to a alias.
|
||||
UINFO(9, " relinkVar "<<(void*)nodep->varp()->user2p()<<" "<<nodep<<endl);
|
||||
AstVarScope* newvscp = nodep->varp()->user2p()->castVarScope();
|
||||
AstVarScope* newvscp = VN_CAST(nodep->varp()->user2p(), VarScope);
|
||||
if (!newvscp) nodep->v3fatalSrc("not linked");
|
||||
nodep->varScopep(newvscp);
|
||||
nodep->varp(nodep->varScopep()->varp());
|
||||
|
|
@ -382,14 +382,14 @@ private:
|
|||
pinp->unlinkFrBack(); // Relinked to assignment below
|
||||
argp->unlinkFrBack()->deleteTree(); // Args no longer needed
|
||||
//
|
||||
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
|
||||
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInout()) {
|
||||
// Correct lvalue; see comments below
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
if (AstVarRef* varrefp = pinp->castVarRef()) {
|
||||
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) {
|
||||
// Connect to this exact variable
|
||||
AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope");
|
||||
portp->user2p(localVscp);
|
||||
|
|
@ -439,7 +439,7 @@ private:
|
|||
AstNode* nextstmtp;
|
||||
for (AstNode* stmtp = beginp; stmtp; stmtp=nextstmtp) {
|
||||
nextstmtp = stmtp->nextp();
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
// Any I/O variables that fell out of above loop were already linked
|
||||
if (!portp->user2p()) {
|
||||
// Move it to a new localized variable
|
||||
|
|
@ -487,14 +487,14 @@ private:
|
|||
} else {
|
||||
UINFO(9, " Port "<<portp<<endl);
|
||||
UINFO(9, " pin "<<pinp<<endl);
|
||||
if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) {
|
||||
if ((portp->isInout() || portp->isOutput()) && VN_IS(pinp, Const)) {
|
||||
pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName());
|
||||
}
|
||||
else if (portp->isInout()) {
|
||||
// Correct lvalue; see comments below
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
if (pinp->castVarRef()) {
|
||||
if (VN_IS(pinp, VarRef)) {
|
||||
// Connect to this exact variable
|
||||
} else {
|
||||
pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
|
||||
|
|
@ -541,7 +541,7 @@ private:
|
|||
for (AstNode* pinp = refp->pinsp(); pinp; pinp=nextpinp) {
|
||||
nextpinp = pinp->nextp();
|
||||
// Move pin to the CCall, removing all Arg's
|
||||
AstNode* exprp = pinp->castArg()->exprp();
|
||||
AstNode* exprp = VN_CAST(pinp, Arg)->exprp();
|
||||
exprp->unlinkFrBack();
|
||||
ccallp->addArgsp(exprp);
|
||||
}
|
||||
|
|
@ -564,7 +564,7 @@ private:
|
|||
dpiproto += " "+nodep->cname()+" (";
|
||||
string args;
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (const AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn() && portp!=rtnvarp) {
|
||||
if (args != "") { args+= ", "; dpiproto+= ", "; }
|
||||
args += portp->name(); // Leftover so ,'s look nice
|
||||
|
|
@ -716,7 +716,7 @@ private:
|
|||
args += "("+v3Global.opt.prefix()+"__Syms*)(__Vscopep->symsp())"; // Upcast w/o overhead
|
||||
AstNode* argnodesp = NULL;
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) {
|
||||
// No createDpiTemp; we make a real internal variable instead
|
||||
// SAME CODE BELOW
|
||||
|
|
@ -757,7 +757,7 @@ private:
|
|||
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) {
|
||||
dpip->addStmtsp(createAssignInternalToDpi(portp,false,true,"__Vcvt",""));
|
||||
}
|
||||
|
|
@ -817,7 +817,7 @@ private:
|
|||
void makePortList(AstNodeFTask* nodep, AstVar* rtnvarp, AstCFunc* dpip) {
|
||||
// Copy nodep's list of function I/O to the new dpip c function
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
// Move it to new function
|
||||
AstVar* newPortp = portp->cloneTree(false);
|
||||
|
|
@ -838,8 +838,8 @@ private:
|
|||
// Convert input/inout arguments to DPI types
|
||||
string args;
|
||||
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* portvscp = VN_CAST(portp->user2p(), VarScope); // Remembered when we created it earlier
|
||||
if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp
|
||||
&& portp->name() != "__Vscopep" // Passed to dpiContext, not callee
|
||||
&& portp->name() != "__Vfilenamep"
|
||||
|
|
@ -901,10 +901,10 @@ private:
|
|||
|
||||
// Convert output/inout arguments back to internal type
|
||||
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())
|
||||
&& !portp->isDpiOpenArray()) {
|
||||
AstVarScope* portvscp = portp->user2p()->castVarScope(); // Remembered when we created it earlier
|
||||
AstVarScope* portvscp = VN_CAST(portp->user2p(), VarScope); // Remembered when we created it earlier
|
||||
cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true));
|
||||
}
|
||||
}
|
||||
|
|
@ -918,7 +918,7 @@ private:
|
|||
AstNode::user2ClearTree();
|
||||
AstVar* rtnvarp = NULL;
|
||||
if (nodep->isFunction()) {
|
||||
AstVar* portp = nodep->fvarp()->castVar();
|
||||
AstVar* portp = VN_CAST(nodep->fvarp(), Var);
|
||||
if (!portp) nodep->v3fatalSrc("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.)");
|
||||
|
|
@ -1021,7 +1021,7 @@ private:
|
|||
// Create list of arguments and move to function
|
||||
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
|
||||
nextp = stmtp->nextp();
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
// Move it to new function
|
||||
portp->unlinkFrBack();
|
||||
|
|
@ -1096,7 +1096,7 @@ private:
|
|||
}
|
||||
else if (m_insMode == IM_WHILE_PRECOND) {
|
||||
UINFO(5," IM_While_Precond "<<m_insStmtp);
|
||||
AstWhile* whilep = m_insStmtp->castWhile();
|
||||
AstWhile* whilep = VN_CAST(m_insStmtp, While);
|
||||
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
|
||||
whilep->addPrecondsp(newp);
|
||||
}
|
||||
|
|
@ -1131,13 +1131,13 @@ private:
|
|||
UINFO(4," FTask REF "<<nodep<<endl);
|
||||
if (debug()>=9) { nodep->dumpTree(cout,"-inlfunc:"); }
|
||||
if (!m_scopep) nodep->v3fatalSrc("func ref not under scope");
|
||||
string namePrefix = ((nodep->castFuncRef()?"__Vfunc_":"__Vtask_")
|
||||
string namePrefix = ((VN_IS(nodep, FuncRef) ? "__Vfunc_":"__Vtask_")
|
||||
+nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++));
|
||||
// Create output variable
|
||||
AstVarScope* outvscp = NULL;
|
||||
if (nodep->taskp()->isFunction()) {
|
||||
// Not that it's a FUNCREF, but that we're calling a function (perhaps as a task)
|
||||
outvscp = createVarScope (nodep->taskp()->fvarp()->castVar(),
|
||||
outvscp = createVarScope (VN_CAST(nodep->taskp()->fvarp(), Var),
|
||||
namePrefix+"__Vfuncout");
|
||||
}
|
||||
// Create cloned statements
|
||||
|
|
@ -1149,7 +1149,7 @@ private:
|
|||
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
||||
}
|
||||
// Replace the ref
|
||||
if (nodep->castFuncRef()) {
|
||||
if (VN_IS(nodep, FuncRef)) {
|
||||
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
||||
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
||||
nodep->replaceWith(outrefp);
|
||||
|
|
@ -1197,7 +1197,7 @@ private:
|
|||
// Any variables inside the function still have varscopes pointing to them.
|
||||
// We're going to delete the vars, so delete the varscopes.
|
||||
if (nodep->isFunction()) {
|
||||
if (AstVar* portp = nodep->fvarp()->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(nodep->fvarp(), Var)) {
|
||||
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
UINFO(9," funcremovevsc "<<vscp<<endl);
|
||||
pushDeletep(vscp->unlinkFrBack()); VL_DANGLING(vscp);
|
||||
|
|
@ -1205,7 +1205,7 @@ private:
|
|||
}
|
||||
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
|
||||
nextp = stmtp->nextp();
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp);
|
||||
UINFO(9," funcremovevsc "<<vscp<<endl);
|
||||
pushDeletep(vscp->unlinkFrBack()); VL_DANGLING(vscp);
|
||||
|
|
@ -1282,7 +1282,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
int tpinnum = 0;
|
||||
AstVar* sformatp = NULL;
|
||||
for (AstNode* stmtp = taskStmtsp; stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isIO()) {
|
||||
tconnects.push_back(make_pair(portp, (AstArg*)NULL));
|
||||
nameToIndex.insert(make_pair(portp->name(), tpinnum)); // For name based connections
|
||||
|
|
@ -1301,7 +1301,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
bool reorganize = false;
|
||||
for (AstNode* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
|
||||
nextp = pinp->nextp();
|
||||
AstArg* argp = pinp->castArg(); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
|
||||
AstArg* argp = VN_CAST(pinp, Arg); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference");
|
||||
if (argp->name() != "") {
|
||||
// By name
|
||||
NameToIndex::iterator it = nameToIndex.find(argp->name());
|
||||
|
|
@ -1346,12 +1346,12 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
|||
nodep->v3error("Missing argument on non-defaulted argument '"<<portp->prettyName()
|
||||
<<"' in function call to "<<nodep->taskp()->prettyTypeName());
|
||||
newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0);
|
||||
} else if (!portp->valuep()->castConst()) {
|
||||
} else if (!VN_IS(portp->valuep(), Const)) {
|
||||
// The default value for this port might be a constant
|
||||
// expression that hasn't been folded yet. Try folding it
|
||||
// now; we don't have much to lose if it fails.
|
||||
newvaluep = V3Const::constifyParamsEdit(portp->valuep());
|
||||
if (!newvaluep->castConst()) {
|
||||
if (!VN_IS(newvaluep, Const)) {
|
||||
// Problem otherwise is we might have a varref, task call, or something else that only
|
||||
// makes sense in the domain of the function, not the callee.
|
||||
nodep->v3error("Unsupported: Non-constant default value in missing argument '"<<portp->prettyName()
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ private:
|
|||
if (nodep->valuep() && !vvertexp->duplicatep()) {
|
||||
V3Hashed::iterator dupit = hashed.findDuplicate(nodep->valuep());
|
||||
if (dupit != hashed.end()) {
|
||||
AstTraceInc* dupincp = hashed.iteratorNodep(dupit)->backp()->castTraceInc();
|
||||
AstTraceInc* dupincp = VN_CAST(hashed.iteratorNodep(dupit)->backp(), TraceInc);
|
||||
if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type");
|
||||
TraceTraceVertex* dupvertexp = dynamic_cast<TraceTraceVertex*>(dupincp->user1u().toGraphVertex());
|
||||
UINFO(8," Orig "<<nodep<<endl);
|
||||
|
|
@ -359,10 +359,10 @@ private:
|
|||
}
|
||||
AstCCall* callp = new AstCCall(funcp->fileline(), funcp);
|
||||
callp->argTypes("vlSymsp, vcdp, code");
|
||||
if (callfromp->castCFunc()) {
|
||||
callfromp->castCFunc()->addStmtsp(callp);
|
||||
} else if (callfromp->castIf()) {
|
||||
callfromp->castIf()->addIfsp(callp);
|
||||
if (VN_IS(callfromp, CFunc)) {
|
||||
VN_CAST(callfromp, CFunc)->addStmtsp(callp);
|
||||
} else if (VN_IS(callfromp, If)) {
|
||||
VN_CAST(callfromp, If)->addIfsp(callp);
|
||||
} else {
|
||||
callfromp->v3fatalSrc("Unknown caller node type"); // Where to add it??
|
||||
}
|
||||
|
|
@ -602,7 +602,7 @@ private:
|
|||
// If so, all funcs might share the same activity code
|
||||
TraceActivityVertex* activityVtxp = getActivityVertexp(nodep, nodep->funcp()->slow());
|
||||
for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) {
|
||||
if (AstCCall* ccallp = nextp->castCCall()) {
|
||||
if (AstCCall* ccallp = VN_CAST(nextp, CCall)) {
|
||||
ccallp->user2(true); // Processed
|
||||
UINFO(8," SubCCALL "<<ccallp<<endl);
|
||||
V3GraphVertex* ccallFuncVtxp = getCFuncVertexp(ccallp->funcp());
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ private:
|
|||
if (m_traVscp) {
|
||||
if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) {
|
||||
addIgnore("Wide memory > --trace-max-array ents");
|
||||
} else if (nodep->subDTypep()->skipRefp()->castBasicDType() // Nothing lower than this array
|
||||
} else if (VN_IS(nodep->subDTypep()->skipRefp(), BasicDType) // Nothing lower than this array
|
||||
&& m_traVscp->dtypep()->skipRefp() == nodep) { // Nothing above this array
|
||||
// Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling
|
||||
// This will put "(index)" at end of signal name for us
|
||||
|
|
@ -258,13 +258,13 @@ private:
|
|||
if (!nodep->packed()) {
|
||||
addIgnore("Unsupported: Unpacked struct/union");
|
||||
} else {
|
||||
for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
|
||||
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
|
||||
string oldShowname = m_traShowname;
|
||||
AstNode* oldValuep = m_traValuep;
|
||||
{
|
||||
m_traShowname += string(" ")+itemp->prettyName();
|
||||
if (nodep->castStructDType()) {
|
||||
if (VN_IS(nodep, StructDType)) {
|
||||
m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
|
||||
itemp->lsb(), subtypep->width());
|
||||
subtypep->accept(*this);
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public:
|
|||
virtual ~TristateVertex() {}
|
||||
// ACCESSORS
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstVar* varp() const { return nodep()->castVar(); }
|
||||
AstVar* varp() const { return VN_CAST(nodep(), Var); }
|
||||
virtual string name() const {
|
||||
return ((isTristate() ? "tri\\n"
|
||||
:feedsTri() ? "feed\\n" : "-\\n")
|
||||
|
|
@ -180,7 +180,7 @@ private:
|
|||
// A variable is tristated. Find all of the LHS VARREFs that drive this signal now need tristate drivers
|
||||
for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep=edgep->inNextp()) {
|
||||
TristateVertex* vvertexp = dynamic_cast<TristateVertex*>(edgep->fromp());
|
||||
if (AstVarRef* refp = vvertexp->nodep()->castVarRef()) {
|
||||
if (const AstVarRef* refp = VN_CAST(vvertexp->nodep(), VarRef)) {
|
||||
if (refp->lvalue()
|
||||
// Doesn't hurt to not check if already set, but by doing so when we
|
||||
// print out the debug messages, we'll see this node at level 0 instead.
|
||||
|
|
@ -269,7 +269,7 @@ public:
|
|||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
TristateVertex* vvertexp = static_cast<TristateVertex*>(itp);
|
||||
if (vvertexp->isTristate()) {
|
||||
if (AstVar* nodep = vvertexp->nodep()->castVar()) {
|
||||
if (AstVar* nodep = VN_CAST(vvertexp->nodep(), Var)) {
|
||||
v.push_back(nodep);
|
||||
}
|
||||
}
|
||||
|
|
@ -393,7 +393,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
else m_modp->addStmtp(newp);
|
||||
invarp->user1p(newp); // find envar given invarp
|
||||
}
|
||||
return invarp->user1p()->castVar();
|
||||
return VN_CAST(invarp->user1p(), Var);
|
||||
}
|
||||
|
||||
AstVar* getCreateOutVarp(AstVar* invarp) {
|
||||
|
|
@ -408,7 +408,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
else m_modp->addStmtp(newp);
|
||||
invarp->user4p(newp); // find outvar given invarp
|
||||
}
|
||||
return invarp->user4p()->castVar();
|
||||
return VN_CAST(invarp->user4p(), Var);
|
||||
}
|
||||
|
||||
AstVar* getCreateUnconnVarp(AstNode* fromp, AstNodeDType* dtypep) {
|
||||
|
|
@ -467,10 +467,10 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
nodep->v3error("Unsupported LHS tristate construct: "<<nodep->prettyTypeName());
|
||||
}
|
||||
// Ignore Var's because they end up adjacent to statements
|
||||
if ((nodep->op1p() && nodep->op1p()->user1p() && !nodep->op1p()->castVar())
|
||||
|| (nodep->op2p() && nodep->op2p()->user1p() && !nodep->op1p()->castVar())
|
||||
|| (nodep->op3p() && nodep->op3p()->user1p() && !nodep->op1p()->castVar())
|
||||
|| (nodep->op4p() && nodep->op4p()->user1p() && !nodep->op1p()->castVar())) {
|
||||
if ((nodep->op1p() && nodep->op1p()->user1p() && !VN_IS(nodep->op1p(), Var))
|
||||
|| (nodep->op2p() && nodep->op2p()->user1p() && !VN_IS(nodep->op1p(), Var))
|
||||
|| (nodep->op3p() && nodep->op3p()->user1p() && !VN_IS(nodep->op1p(), Var))
|
||||
|| (nodep->op4p() && nodep->op4p()->user1p() && !VN_IS(nodep->op1p(), Var))) {
|
||||
nodep->v3error("Unsupported tristate construct: "<<nodep->prettyTypeName());
|
||||
}
|
||||
}
|
||||
|
|
@ -546,7 +546,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
outvarp->user3p(invarp->user3p()); // AstPull* propagation
|
||||
if (invarp->user3p()) UINFO(9, "propagate pull to "<<outvarp<<endl);
|
||||
} else if (invarp->user1p()) {
|
||||
envarp = invarp->user1p()->castVar(); // From CASEEQ, foo === 1'bz
|
||||
envarp = VN_CAST(invarp->user1p(), Var); // From CASEEQ, foo === 1'bz
|
||||
}
|
||||
|
||||
AstNode* orp = NULL;
|
||||
|
|
@ -936,13 +936,13 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
// away later when we determine the signal has no tristate
|
||||
nodep->iterateChildren(*this);
|
||||
UINFO(9,dbgState()<<nodep<<endl);
|
||||
AstConst* constp = nodep->lhsp()->castConst(); // Constification always moves const to LHS
|
||||
AstVarRef* varrefp = nodep->rhsp()->castVarRef(); // Input variable
|
||||
const AstConst* constp = VN_CAST(nodep->lhsp(), Const); // Constification always moves const to LHS
|
||||
AstVarRef* varrefp = VN_CAST(nodep->rhsp(), VarRef); // Input variable
|
||||
if (constp && constp->user1p() && varrefp) {
|
||||
// 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in))
|
||||
varrefp->unlinkFrBack();
|
||||
FileLine* fl = nodep->fileline();
|
||||
V3Number oneIfEn = constp->user1p()->castConst()->num(); // visit(AstConst) already split into en/ones
|
||||
V3Number oneIfEn = VN_CAST(constp->user1p(), Const)->num(); // visit(AstConst) already split into en/ones
|
||||
V3Number oneIfEnOne = constp->num();
|
||||
AstVar* envarp = getCreateEnVarp(varrefp->varp());
|
||||
AstNode* newp = new AstLogAnd (fl, new AstEq (fl, new AstConst(fl, oneIfEn),
|
||||
|
|
@ -962,7 +962,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
}
|
||||
}
|
||||
void visitEqNeqWild(AstNodeBiop* nodep) {
|
||||
if (!nodep->rhsp()->castConst()) {
|
||||
if (!VN_IS(nodep->rhsp(), Const)) {
|
||||
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
|
||||
// rhs we want to keep X/Z intact, so otherwise ignore
|
||||
}
|
||||
|
|
@ -985,7 +985,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
virtual void visit(AstPull* nodep) {
|
||||
UINFO(9,dbgState()<<nodep<<endl);
|
||||
if (m_graphing) {
|
||||
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
|
||||
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
lhsp->lvalue(true);
|
||||
m_logicp = nodep;
|
||||
m_tgraph.setTristate(nodep);
|
||||
|
|
@ -1001,7 +1001,7 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
// current limitation of this implementation is that a pullup/down
|
||||
// gets applied to all bits of a bus and a bus cannot have drivers
|
||||
// in opposite directions on indvidual pins.
|
||||
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
|
||||
if (AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
lhsp->lvalue(true);
|
||||
m_tgraph.didProcess(nodep);
|
||||
m_tgraph.didProcess(lhsp->varp());
|
||||
|
|
@ -1159,12 +1159,12 @@ class TristateVisitor : public TristateBaseVisitor {
|
|||
exprrefp = NULL; // Primary input only
|
||||
} else {
|
||||
// pinReconnect should have converted this
|
||||
exprrefp = outpinp->exprp()->castVarRef();
|
||||
exprrefp = VN_CAST(outpinp->exprp(), VarRef);
|
||||
if (!exprrefp) nodep->v3error("Unsupported tristate port expression: "<<nodep->exprp()->prettyTypeName());
|
||||
}
|
||||
} else {
|
||||
// pinReconnect should have converted this
|
||||
exprrefp = outAssignp->rhsp()->castVarRef(); // This should be the same var as the output pin
|
||||
exprrefp = VN_CAST(outAssignp->rhsp(), VarRef); // This should be the same var as the output pin
|
||||
if (!exprrefp) nodep->v3error("Unsupported tristate port expression: "<<nodep->exprp()->prettyTypeName());
|
||||
}
|
||||
if (exprrefp) {
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ private:
|
|||
AstVar* varp = nodep->varp();
|
||||
if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx()
|
||||
&& !m_inBBox // We may have falsely considered a SysIgnore as a driver
|
||||
&& !nodep->castVarXRef() // Xrefs might point at two different instances
|
||||
&& !VN_IS(nodep, VarXRef) // Xrefs might point at two different instances
|
||||
&& !varp->fileline()->warnIsOff(V3ErrorCode::ALWCOMBORDER)) { // Warn only once per variable
|
||||
nodep->v3warn(ALWCOMBORDER, "Always_comb variable driven after use: "<<nodep->prettyName());
|
||||
varp->fileline()->modifyWarnOff(V3ErrorCode::ALWCOMBORDER, true); // Complain just once for any usage
|
||||
|
|
@ -303,8 +303,8 @@ private:
|
|||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstSel* nodep) {
|
||||
AstNodeVarRef* varrefp = nodep->fromp()->castNodeVarRef();
|
||||
AstConst* constp = nodep->lsbp()->castConst();
|
||||
AstNodeVarRef* varrefp = VN_CAST(nodep->fromp(), NodeVarRef);
|
||||
AstConst* constp = VN_CAST(nodep->lsbp(), Const);
|
||||
if (varrefp && constp && !constp->num().isFourState()) {
|
||||
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
||||
UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ private:
|
|||
AstNode* prep = nodep;
|
||||
|
||||
// Scan back to put the condlvalue above all selects (IE top of the lvalue)
|
||||
while (prep->backp()->castNodeSel()
|
||||
|| prep->backp()->castSel()) {
|
||||
while (VN_IS(prep->backp(), NodeSel)
|
||||
|| VN_IS(prep->backp(), Sel)) {
|
||||
prep=prep->backp();
|
||||
}
|
||||
FileLine* fl = nodep->fileline();
|
||||
|
|
@ -113,7 +113,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 = prep->user2p()->castIf()) {
|
||||
if (AstIf* ifp = VN_CAST(prep->user2p(), If)) {
|
||||
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
|
||||
AstNRelinker replaceHandle;
|
||||
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
||||
|
|
@ -179,7 +179,7 @@ private:
|
|||
UINFO(4," N/EQCASE->EQ "<<nodep<<endl);
|
||||
V3Const::constifyEdit(nodep->lhsp()); // lhsp may change
|
||||
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
|
||||
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
|
||||
if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) {
|
||||
// Both sides are constant, node can be constant
|
||||
V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
|
||||
return;
|
||||
|
|
@ -188,14 +188,14 @@ private:
|
|||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* newp;
|
||||
// If we got ==1'bx it can never be true (but 1'bx==1'bx can be!)
|
||||
if (((lhsp->castConst() && lhsp->castConst()->num().isFourState())
|
||||
|| (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) {
|
||||
V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1));
|
||||
if (((VN_IS(lhsp, Const) && VN_CAST(lhsp, Const)->num().isFourState())
|
||||
|| (VN_IS(rhsp, Const) && VN_CAST(rhsp, Const)->num().isFourState()))) {
|
||||
V3Number num (nodep->fileline(), 1, (VN_IS(nodep, EqCase) ? 0:1));
|
||||
newp = new AstConst (nodep->fileline(), num);
|
||||
lhsp->deleteTree(); VL_DANGLING(lhsp);
|
||||
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
||||
} else {
|
||||
if (nodep->castEqCase())
|
||||
if (VN_IS(nodep, EqCase))
|
||||
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
|
||||
else newp = new AstNeq (nodep->fileline(), lhsp, rhsp);
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ private:
|
|||
UINFO(4," N/EQWILD->EQ "<<nodep<<endl);
|
||||
V3Const::constifyEdit(nodep->lhsp()); // lhsp may change
|
||||
V3Const::constifyEdit(nodep->rhsp()); // rhsp may change
|
||||
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
|
||||
if (VN_IS(nodep->lhsp(), Const) && VN_IS(nodep->rhsp(), Const)) {
|
||||
// Both sides are constant, node can be constant
|
||||
V3Const::constifyEdit(nodep); VL_DANGLING(nodep);
|
||||
return;
|
||||
|
|
@ -217,20 +217,20 @@ private:
|
|||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* newp;
|
||||
if (!rhsp->castConst()) {
|
||||
if (!VN_IS(rhsp, Const)) {
|
||||
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
|
||||
// Replace with anything that won't cause more errors
|
||||
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
|
||||
} else {
|
||||
// X or Z's become mask, ala case statements.
|
||||
V3Number nummask (rhsp->fileline(), rhsp->width());
|
||||
nummask.opBitsNonX(rhsp->castConst()->num());
|
||||
nummask.opBitsNonX(VN_CAST(rhsp, Const)->num());
|
||||
V3Number numval (rhsp->fileline(), rhsp->width());
|
||||
numval.opBitsOne (rhsp->castConst()->num());
|
||||
numval.opBitsOne (VN_CAST(rhsp, Const)->num());
|
||||
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
|
||||
new AstConst(nodep->fileline(), nummask));
|
||||
AstNode* and2p = new AstConst(nodep->fileline(), numval);
|
||||
if (nodep->castEqWild())
|
||||
if (VN_IS(nodep, EqWild))
|
||||
newp = new AstEq (nodep->fileline(), and1p, and2p);
|
||||
else newp = new AstNeq (nodep->fileline(), and1p, and2p);
|
||||
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
||||
|
|
@ -333,7 +333,7 @@ private:
|
|||
// Guard against reading/writing past end of bit vector array
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
||||
bool lvalue = false;
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
|
||||
lvalue = varrefp->lvalue();
|
||||
}
|
||||
// Find range of dtype we are selecting from
|
||||
|
|
@ -385,9 +385,9 @@ private:
|
|||
// Guard against reading/writing past end of arrays
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
|
||||
bool lvalue = false;
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||
if (const AstNodeVarRef* varrefp = VN_CAST(basefromp, NodeVarRef)) {
|
||||
lvalue = varrefp->lvalue();
|
||||
} else if (basefromp->castConst()) {
|
||||
} else if (VN_IS(basefromp, Const)) {
|
||||
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
|
||||
} else {
|
||||
nodep->v3fatalSrc("No VarRef or Const under ArraySel");
|
||||
|
|
@ -396,7 +396,7 @@ private:
|
|||
int declElements = -1;
|
||||
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
|
||||
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
declElements = adtypep->elementsConst();
|
||||
} else {
|
||||
nodep->v3error("Select from non-array "<<dtypep->prettyTypeName());
|
||||
|
|
@ -415,7 +415,7 @@ private:
|
|||
condp->deleteTree();
|
||||
}
|
||||
else if (!lvalue
|
||||
&& !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension
|
||||
&& !VN_IS(nodep->backp(), ArraySel)) { // Too complicated and slow if mid-multidimension
|
||||
// ARRAYSEL(...) -> COND(LT(bit<maxbit), ARRAYSEL(...), {width{1'bx}})
|
||||
AstNRelinker replaceHandle;
|
||||
nodep->unlinkFrBack(&replaceHandle);
|
||||
|
|
|
|||
|
|
@ -110,22 +110,22 @@ private:
|
|||
if (incp) UINFO(6, " Inc "<<incp<<endl);
|
||||
|
||||
// Initial value check
|
||||
AstAssign* initAssp = initp->castAssign();
|
||||
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");
|
||||
if (!initAssp->lhsp()->castVarRef()) return cantUnroll(nodep, "no initial assignment to simple variable");
|
||||
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");
|
||||
//
|
||||
// Assignment of next value check
|
||||
AstAssign* incAssp = incp->castAssign();
|
||||
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");
|
||||
|
||||
m_forVarp = initAssp->lhsp()->castVarRef()->varp();
|
||||
m_forVscp = initAssp->lhsp()->castVarRef()->varScopep();
|
||||
if (nodep->castGenFor() && !m_forVarp->isGenVar()) {
|
||||
m_forVarp = VN_CAST(initAssp->lhsp(), VarRef)->varp();
|
||||
m_forVscp = VN_CAST(initAssp->lhsp(), VarRef)->varScopep();
|
||||
if (VN_IS(nodep, GenFor) && !m_forVarp->isGenVar()) {
|
||||
nodep->v3error("Non-genvar used in generate for: "<<m_forVarp->prettyName()<<endl);
|
||||
}
|
||||
if (m_generate) V3Const::constifyParamsEdit(initAssp->rhsp()); // rhsp may change
|
||||
|
|
@ -134,7 +134,7 @@ private:
|
|||
// however, for repeat loops, the loop variable is auto-generated
|
||||
// and the initp statements will reference a variable outside of the initp scope
|
||||
// alas, failing to simulate.
|
||||
AstConst* constInitp = initAssp->rhsp()->castConst();
|
||||
AstConst* constInitp = VN_CAST(initAssp->rhsp(), Const);
|
||||
if (!constInitp) return cantUnroll(nodep, "non-constant initializer");
|
||||
|
||||
//
|
||||
|
|
@ -156,7 +156,7 @@ private:
|
|||
|
||||
|
||||
if (!m_generate) {
|
||||
AstAssign *incpAssign = incp->castAssign();
|
||||
AstAssign *incpAssign = VN_CAST(incp, Assign);
|
||||
if (!canSimulate(incpAssign->rhsp())) return cantUnroll(incp, "Unable to simulate increment");
|
||||
if (!canSimulate(condp)) return cantUnroll(condp, "Unable to simulate condition");
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ private:
|
|||
outLoopsr++;
|
||||
|
||||
// Run inc
|
||||
AstAssign* incpass = incp->castAssign();
|
||||
AstAssign* incpass = VN_CAST(incp, Assign);
|
||||
V3Number newLoopValue = V3Number(initp->fileline());
|
||||
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
|
||||
return false;
|
||||
|
|
@ -287,7 +287,7 @@ private:
|
|||
bodysp->unlinkFrBackWithNext();
|
||||
stmtsp = AstNode::addNextNull(stmtsp, bodysp); // Maybe null if no body
|
||||
}
|
||||
if (incp && !nodep->castGenFor()) { // Generates don't need to increment loop index
|
||||
if (incp && !VN_IS(nodep, GenFor)) { // Generates don't need to increment loop index
|
||||
incp->unlinkFrBackWithNext();
|
||||
stmtsp = AstNode::addNextNull(stmtsp, incp); // Maybe null if no body
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ private:
|
|||
}
|
||||
|
||||
// loopValue += valInc
|
||||
AstAssign *incpass = incp->castAssign();
|
||||
AstAssign *incpass = VN_CAST(incp, Assign);
|
||||
V3Number newLoopValue = V3Number(nodep->fileline());
|
||||
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
|
||||
nodep->v3error("Loop unrolling failed");
|
||||
|
|
|
|||
286
src/V3Width.cpp
286
src/V3Width.cpp
|
|
@ -24,7 +24,7 @@
|
|||
// widthUnsized() = # bits for unsized constant, or 0 if it's sized
|
||||
// widthMin() = Alternative acceptable width for linting, or width() if sized
|
||||
// Determine this subop's width, can be either:
|
||||
// Fixed width X
|
||||
// Fixed width X
|
||||
// Unsized, min width X ('d5 is unsized, min 3 bits.)
|
||||
// Pass up:
|
||||
// width() = # bits this expression generates
|
||||
|
|
@ -38,8 +38,8 @@
|
|||
// If subop larger, add a EXTRACT
|
||||
// If subop smaller, add a EXTEND
|
||||
// Pass size to sub-expressions if required (+/-* etc)
|
||||
// FINAL = true.
|
||||
// Subexpressions lint and extend as needed
|
||||
// FINAL = true.
|
||||
// Subexpressions lint and extend as needed
|
||||
//
|
||||
//*************************************************************************
|
||||
// Signedness depends on:
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
// Else, if any operand unsigned, output unsigned
|
||||
//
|
||||
// Real number rules:
|
||||
// Real numbers are real (duh)
|
||||
// Real numbers are real (duh)
|
||||
// Reals convert to integers by rounding
|
||||
// Reals init to 0.0
|
||||
// Logicals convert compared to zero
|
||||
|
|
@ -393,14 +393,14 @@ private:
|
|||
AstNumeric::UNSIGNED);
|
||||
// Cleanup zero width Verilog2001 {x,{0{foo}}} now,
|
||||
// otherwise having width(0) will cause later assertions to fire
|
||||
if (AstReplicate* repp=nodep->lhsp()->castReplicate()) {
|
||||
if (AstReplicate* repp=VN_CAST(nodep->lhsp(), Replicate)) {
|
||||
if (repp->width()==0) { // Keep rhs
|
||||
nodep->replaceWith(nodep->rhsp()->unlinkFrBack());
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (AstReplicate* repp=nodep->rhsp()->castReplicate()) {
|
||||
if (AstReplicate* repp=VN_CAST(nodep->rhsp(), Replicate)) {
|
||||
if (repp->width()==0) { // Keep lhs
|
||||
nodep->replaceWith(nodep->lhsp()->unlinkFrBack());
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
@ -446,10 +446,10 @@ private:
|
|||
iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH);
|
||||
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
|
||||
uint32_t times = constp->toUInt();
|
||||
if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
|
||||
if (times==0 && !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
|
||||
nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)"); times=1;
|
||||
}
|
||||
if (nodep->lhsp()->isString()) {
|
||||
|
|
@ -477,10 +477,10 @@ private:
|
|||
iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH);
|
||||
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
|
||||
uint32_t times = constp->toUInt();
|
||||
if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
|
||||
if (times==0 && !VN_IS(nodep->backp(), Concat)) { // Concat Visitor will clean it up.
|
||||
nodep->v3error("Replication value of 0 is only legal under a concatenation (IEEE 2012 11.4.12.1)");
|
||||
}
|
||||
nodep->dtypeSetString();
|
||||
|
|
@ -497,8 +497,8 @@ private:
|
|||
iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH);
|
||||
iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
AstBasicDType* basicp = nodep->rhsp()->castBasicDType();
|
||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||
AstBasicDType* basicp = VN_CAST(nodep->rhsp(), BasicDType);
|
||||
if (!constp && !basicp) { nodep->v3error("Slice size isn't a constant or basic data type."); return; }
|
||||
if (basicp) { // Convert data type to a constant size
|
||||
AstConst* newp = new AstConst(basicp->fileline(), basicp->width());
|
||||
|
|
@ -544,8 +544,8 @@ private:
|
|||
int width = nodep->elementsConst();
|
||||
if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<<std::hex<<width);
|
||||
// Note width() not set on range; use elementsConst()
|
||||
if (nodep->littleEndian() && !nodep->backp()->castUnpackArrayDType()
|
||||
&& !nodep->backp()->castCell()) { // For cells we warn in V3Inst
|
||||
if (nodep->littleEndian() && !VN_IS(nodep->backp(), UnpackArrayDType)
|
||||
&& !VN_IS(nodep->backp(), Cell)) { // For cells we warn in V3Inst
|
||||
nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<<nodep->lsbConst()<<":"<<nodep->msbConst());
|
||||
}
|
||||
}
|
||||
|
|
@ -564,14 +564,14 @@ private:
|
|||
iterateCheckSizedSelf(nodep,"Select Width",nodep->widthp(),SELF,BOTH);
|
||||
iterateCheckSizedSelf(nodep,"Select LHS",nodep->lhsp(),SELF,BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change
|
||||
AstConst* widthConstp = nodep->widthp()->castConst();
|
||||
AstConst* widthConstp = VN_CAST(nodep->widthp(), Const);
|
||||
if (!widthConstp) {
|
||||
nodep->v3error("Width of bit extract isn't a constant");
|
||||
nodep->dtypeSetLogicBool(); return;
|
||||
}
|
||||
int width = nodep->widthConst();
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel
|
||||
if (nodep->lsbp()->castConst()
|
||||
if (VN_IS(nodep->lsbp(), Const)
|
||||
&& nodep->msbConst() < nodep->lsbConst()) {
|
||||
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
|
||||
<<nodep->msbConst()<<"<"<<nodep->lsbConst());
|
||||
|
|
@ -617,7 +617,7 @@ private:
|
|||
UINFO(1," Related node: "<<nodep<<endl);
|
||||
}
|
||||
}
|
||||
if (nodep->lsbp()->castConst() && nodep->msbConst() > frommsb) {
|
||||
if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() > frommsb) {
|
||||
// See also warning in V3Const
|
||||
// We need to check here, because the widthCheckSized may silently
|
||||
// add another SEL which will lose the out-of-range check
|
||||
|
|
@ -660,7 +660,7 @@ private:
|
|||
int frommsb;
|
||||
int fromlsb;
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) {
|
||||
if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
frommsb = adtypep->msb();
|
||||
fromlsb = adtypep->lsb();
|
||||
if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; }
|
||||
|
|
@ -692,10 +692,11 @@ private:
|
|||
if (!m_doGenerate) {
|
||||
// Must check bounds before adding a select that truncates the bound
|
||||
// Note we've already subtracted off LSB
|
||||
if (nodep->bitp()->castConst() && (nodep->bitp()->castConst()->toSInt() > (frommsb-fromlsb)
|
||||
|| nodep->bitp()->castConst()->toSInt() < 0)) {
|
||||
if (VN_IS(nodep->bitp(), Const)
|
||||
&& (VN_CAST(nodep->bitp(), Const)->toSInt() > (frommsb-fromlsb)
|
||||
|| VN_CAST(nodep->bitp(), Const)->toSInt() < 0)) {
|
||||
nodep->v3warn(SELRANGE,"Selection index out of range: "
|
||||
<<(nodep->bitp()->castConst()->toSInt()+fromlsb)
|
||||
<<(VN_CAST(nodep->bitp(), Const)->toSInt()+fromlsb)
|
||||
<<" outside "<<frommsb<<":"<<fromlsb);
|
||||
UINFO(1," Related node: "<<nodep<<endl);
|
||||
}
|
||||
|
|
@ -711,7 +712,7 @@ private:
|
|||
//
|
||||
// Array indices are always constant
|
||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||
AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType();
|
||||
AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType);
|
||||
if (!adtypep) {
|
||||
UINFO(1," Related dtype: "<<fromDtp<<endl);
|
||||
nodep->v3fatalSrc("Packed array reference exceeds dimension of array");
|
||||
|
|
@ -923,8 +924,8 @@ private:
|
|||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||
std::pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
|
||||
uint32_t msbdim = dim.first+dim.second;
|
||||
if (!nodep->dimp() || nodep->dimp()->castConst() || msbdim<1) {
|
||||
int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt();
|
||||
if (!nodep->dimp() || VN_IS(nodep->dimp(), Const) || msbdim<1) {
|
||||
int dim = !nodep->dimp() ? 1 : VN_CAST(nodep->dimp(), Const)->toSInt();
|
||||
AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
|
@ -962,7 +963,7 @@ private:
|
|||
// Cleanup array size
|
||||
userIterateAndNext(nodep->rangep(), WidthVP(SELF,BOTH).p());
|
||||
nodep->dtypep(nodep); // The array itself, not subDtype
|
||||
if (nodep->castUnpackArrayDType()) {
|
||||
if (VN_IS(nodep, UnpackArrayDType)) {
|
||||
// Historically array elements have width of the ref type not the full array
|
||||
nodep->widthFromSub(nodep->subDTypep());
|
||||
} else {
|
||||
|
|
@ -1042,7 +1043,7 @@ private:
|
|||
// nodep->dtp could be data type, or a primary_constant
|
||||
// Don't iterate lhsp, will deal with that once convert the type
|
||||
V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change
|
||||
if (AstConst* constp = nodep->dtp()->castConst()) {
|
||||
if (AstConst* constp = VN_CAST(nodep->dtp(), Const)) {
|
||||
constp->unlinkFrBack();
|
||||
AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp);
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -1095,19 +1096,19 @@ 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 (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
|
||||
if (!VN_IS(nodep->rhsp(), Const)) nodep->v3fatalSrc("Unsupported: Non-const cast of size");
|
||||
//if (debug()) nodep->dumpTree(cout," CastSizePre: ");
|
||||
if (m_vup->prelim()) {
|
||||
int width = nodep->rhsp()->castConst()->toSInt();
|
||||
int width = VN_CAST(nodep->rhsp(), Const)->toSInt();
|
||||
if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; }
|
||||
userIterateAndNext(nodep->lhsp(), WidthVP(SELF,PRELIM).p());
|
||||
AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType();
|
||||
AstBasicDType* underDtp = VN_CAST(nodep->lhsp()->dtypep(), BasicDType);
|
||||
if (!underDtp) {
|
||||
underDtp = nodep->lhsp()->dtypep()->basicp();
|
||||
}
|
||||
if (!underDtp) {
|
||||
nodep->v3error("Unsupported: Size-changing cast on non-basic data type");
|
||||
underDtp = nodep->findLogicBoolDType()->castBasicDType();
|
||||
underDtp = VN_CAST(nodep->findLogicBoolDType(), BasicDType);
|
||||
}
|
||||
// A cast propagates its size to the lower expression and is included in the maximum
|
||||
// width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math.
|
||||
|
|
@ -1161,21 +1162,21 @@ private:
|
|||
if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep));
|
||||
nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep()));
|
||||
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var");
|
||||
if (nodep->dtypeSkipRefp()->castUnsizedArrayDType()) {
|
||||
if (VN_IS(nodep->dtypeSkipRefp(), UnsizedArrayDType)) {
|
||||
if (!(m_ftaskp && m_ftaskp->dpiImport())) {
|
||||
nodep->v3error("Unsized/open arrays ('[]') are only supported in DPI imports");
|
||||
}
|
||||
}
|
||||
else if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType()
|
||||
|| nodep->dtypeSkipRefp()->castNodeArrayDType()
|
||||
|| nodep->dtypeSkipRefp()->castNodeClassDType())) {
|
||||
else if (nodep->isIO() && !(VN_IS(nodep->dtypeSkipRefp(), BasicDType)
|
||||
|| VN_IS(nodep->dtypeSkipRefp(), NodeArrayDType)
|
||||
|| VN_IS(nodep->dtypeSkipRefp(), NodeClassDType))) {
|
||||
nodep->v3error("Unsupported: Inputs and outputs must be simple data types");
|
||||
}
|
||||
if (nodep->dtypep()->skipRefToConstp()->castConstDType()) {
|
||||
if (VN_IS(nodep->dtypep()->skipRefToConstp(), ConstDType)) {
|
||||
nodep->isConst(true);
|
||||
}
|
||||
// Parameters if implicit untyped inherit from what they are assigned to
|
||||
AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType();
|
||||
AstBasicDType* bdtypep = VN_CAST(nodep->dtypep(), BasicDType);
|
||||
bool didchk = false;
|
||||
bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit();
|
||||
if (implicitParam) {
|
||||
|
|
@ -1241,7 +1242,7 @@ private:
|
|||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
if (nodep->didWidth()) return;
|
||||
if (!nodep->varp()) {
|
||||
if (m_paramsOnly && nodep->castVarXRef()) {
|
||||
if (m_paramsOnly && VN_IS(nodep, VarXRef)) {
|
||||
checkConstantOrReplace(nodep, "Parameter-resolved constants must not use dotted references: "+nodep->prettyName()); VL_DANGLING(nodep);
|
||||
return;
|
||||
} else {
|
||||
|
|
@ -1255,7 +1256,7 @@ private:
|
|||
//if (debug()>=9) { nodep->dumpTree(cout," VRin "); nodep->varp()->dumpTree(cout," forvar "); }
|
||||
// Note genvar's are also entered as integers
|
||||
nodep->dtypeFrom(nodep->varp());
|
||||
if (nodep->backp()->castNodeAssign() && nodep->lvalue()) { // On LHS
|
||||
if (VN_IS(nodep->backp(), NodeAssign) && nodep->lvalue()) { // On LHS
|
||||
if (!nodep->widthMin()) nodep->v3fatalSrc("LHS var should be size complete");
|
||||
}
|
||||
//if (debug()>=9) nodep->dumpTree(cout," VRout ");
|
||||
|
|
@ -1280,12 +1281,12 @@ private:
|
|||
// Assign missing values
|
||||
V3Number num (nodep->fileline(), nodep->width(), 0);
|
||||
V3Number one (nodep->fileline(), nodep->width(), 1);
|
||||
std::map<V3Number,AstEnumItem*> inits;
|
||||
for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) {
|
||||
std::map<V3Number,AstEnumItem*> inits;
|
||||
for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), EnumItem)) {
|
||||
if (itemp->valuep()) {
|
||||
if (debug()>=9) { UINFO(0,"EnumInit "<<itemp<<endl); itemp->valuep()->dumpTree(cout,"-EnumInit: "); }
|
||||
V3Const::constifyParamsEdit(itemp->valuep()); // itemp may change
|
||||
if (!itemp->valuep()->castConst()) {
|
||||
if (!VN_IS(itemp->valuep(), Const)) {
|
||||
itemp->valuep()->v3error("Enum value isn't a constant");
|
||||
itemp->valuep()->unlinkFrBack()->deleteTree();
|
||||
continue;
|
||||
|
|
@ -1302,7 +1303,7 @@ private:
|
|||
}
|
||||
itemp->valuep(new AstConst(itemp->fileline(), num));
|
||||
}
|
||||
num.opAssign(itemp->valuep()->castConst()->num());
|
||||
num.opAssign(VN_CAST(itemp->valuep(), Const)->num());
|
||||
// Look for duplicates
|
||||
if (inits.find(num) != inits.end()) { // IEEE says illegal
|
||||
itemp->v3error("Overlapping enumeration value: "<<itemp->prettyName()<<endl
|
||||
|
|
@ -1311,7 +1312,7 @@ private:
|
|||
} else {
|
||||
inits.insert(make_pair(num,itemp));
|
||||
}
|
||||
num.opAdd(one, itemp->valuep()->castConst()->num());
|
||||
num.opAdd(one, VN_CAST(itemp->valuep(), Const)->num());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep) {
|
||||
|
|
@ -1333,7 +1334,7 @@ private:
|
|||
AstNode* enump = nodep->itemp();
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef not linked");
|
||||
for (; enump; enump=enump->backp()) {
|
||||
if (enump->castEnumDType()) break;
|
||||
if (VN_IS(enump, EnumDType)) break;
|
||||
}
|
||||
if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum");
|
||||
userIterate(enump, m_vup); VL_DANGLING(enump); // parent's connection to enump may be relinked
|
||||
|
|
@ -1346,7 +1347,7 @@ private:
|
|||
AstNodeDType* vdtypep = m_vup->dtypep();
|
||||
if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor");
|
||||
nodep->dtypep(vdtypep);
|
||||
if (AstNodeArrayDType* arrayp = vdtypep->skipRefp()->castNodeArrayDType()) {
|
||||
if (AstNodeArrayDType* arrayp = VN_CAST(vdtypep->skipRefp(), NodeArrayDType)) {
|
||||
userIterateChildren(nodep, WidthVP(arrayp->subDTypep(),BOTH).p());
|
||||
} else {
|
||||
nodep->v3fatalSrc("InitArray on non-array");
|
||||
|
|
@ -1379,7 +1380,7 @@ private:
|
|||
for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) {
|
||||
nextip = itemp->nextp(); // Will be unlinking
|
||||
AstNode* inewp;
|
||||
if (AstInsideRange* irangep = itemp->castInsideRange()) {
|
||||
if (AstInsideRange* irangep = VN_CAST(itemp, InsideRange)) {
|
||||
// Similar logic in V3Case
|
||||
inewp = new AstAnd(itemp->fileline(),
|
||||
new AstGte(itemp->fileline(),
|
||||
|
|
@ -1431,13 +1432,13 @@ private:
|
|||
nodep->isFourstate(false);
|
||||
// MSB is first, so go backwards
|
||||
AstMemberDType* itemp;
|
||||
for (itemp = nodep->membersp(); itemp && itemp->nextp(); itemp=itemp->nextp()->castMemberDType()) ;
|
||||
for (itemp = nodep->membersp(); itemp && itemp->nextp(); itemp=VN_CAST(itemp->nextp(), MemberDType)) ;
|
||||
for (AstMemberDType* backip; itemp; itemp=backip) {
|
||||
if (nodep->isFourstate()) nodep->isFourstate(true);
|
||||
backip = itemp->backp()->castMemberDType();
|
||||
backip = VN_CAST(itemp->backp(), MemberDType);
|
||||
itemp->lsb(lsb);
|
||||
if (nodep->castUnionDType()) {
|
||||
width = std::max(width, itemp->width());
|
||||
if (VN_IS(nodep, UnionDType)) {
|
||||
width = std::max(width, itemp->width());
|
||||
} else {
|
||||
lsb += itemp->width();
|
||||
width += itemp->width();
|
||||
|
|
@ -1463,14 +1464,14 @@ private:
|
|||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
UINFO(9," from dt "<<fromDtp<<endl);
|
||||
AstMemberDType* memberp = NULL; // NULL=error below
|
||||
if (AstNodeClassDType* adtypep = fromDtp->castNodeClassDType()) {
|
||||
if (AstNodeClassDType* adtypep = VN_CAST(fromDtp, NodeClassDType)) {
|
||||
// No need to width-resolve the class, as it was done when we did the child
|
||||
memberp = adtypep->findMember(nodep->name());
|
||||
if (!memberp) {
|
||||
nodep->v3error("Member '"<<nodep->prettyName()<<"' not found in structure");
|
||||
}
|
||||
}
|
||||
else if (fromDtp->castEnumDType()) {
|
||||
else if (VN_IS(fromDtp, EnumDType)) {
|
||||
// Method call on enum without following parenthesis, e.g. "ENUM.next"
|
||||
// Convert this into a method call, and let that visitor figure out what to do next
|
||||
AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL);
|
||||
|
|
@ -1511,7 +1512,7 @@ private:
|
|||
if (debug()>=9) nodep->dumpTree("-mts-in: ");
|
||||
// Should check types the method requires, but at present we don't do much
|
||||
userIterate(nodep->fromp(), WidthVP(SELF,BOTH).p());
|
||||
for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) {
|
||||
for (AstArg* argp = VN_CAST(nodep->pinsp(), Arg); argp; argp = VN_CAST(argp->nextp(), Arg)) {
|
||||
if (argp->exprp()) userIterate(argp->exprp(), WidthVP(SELF,BOTH).p());
|
||||
}
|
||||
// Find the fromp dtype - should be a class
|
||||
|
|
@ -1519,7 +1520,7 @@ private:
|
|||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
|
||||
AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL;
|
||||
UINFO(9," from dt "<<fromDtp<<endl);
|
||||
if (AstEnumDType* adtypep = fromDtp->castEnumDType()) {
|
||||
if (AstEnumDType* adtypep = VN_CAST(fromDtp, EnumDType)) {
|
||||
// Method call on enum without following parenthesis, e.g. "ENUM.next"
|
||||
// Convert this into a method call, and let that visitor figure out what to do next
|
||||
if (adtypep) {}
|
||||
|
|
@ -1536,12 +1537,12 @@ private:
|
|||
} else if (nodep->name() == "first") {
|
||||
AstEnumItem* itemp = adtypep->itemsp();
|
||||
if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
|
||||
else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
|
||||
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
|
||||
} else if (nodep->name() == "last") {
|
||||
AstEnumItem* itemp = adtypep->itemsp();
|
||||
while (itemp && itemp->nextp()) itemp = itemp->nextp()->castEnumItem();
|
||||
while (itemp && itemp->nextp()) itemp = VN_CAST(itemp->nextp(), EnumItem);
|
||||
if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
|
||||
else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
|
||||
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
|
||||
}
|
||||
if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const");
|
||||
newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables
|
||||
|
|
@ -1559,8 +1560,8 @@ private:
|
|||
|
||||
if (nodep->pinsp() && nodep->name() == "name") {
|
||||
nodep->v3error("Arguments passed to enum.name method, but it does not take arguments");
|
||||
} else if (nodep->pinsp() && !(nodep->pinsp()->castArg()->exprp()->castConst()
|
||||
&& nodep->pinsp()->castArg()->exprp()->castConst()->toUInt()==1
|
||||
} else if (nodep->pinsp() && !(VN_IS(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)
|
||||
&& VN_CAST(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)->toUInt()==1
|
||||
&& !nodep->pinsp()->nextp())) {
|
||||
nodep->v3error("Unsupported: Arguments passed to enum.next method");
|
||||
}
|
||||
|
|
@ -1571,8 +1572,8 @@ private:
|
|||
// a map for when the value is many bits and sparse.
|
||||
uint64_t msbdim = 0;
|
||||
{
|
||||
for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()->castEnumItem()) {
|
||||
AstConst* vconstp = itemp->valuep()->castConst();
|
||||
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");
|
||||
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
|
||||
}
|
||||
|
|
@ -1595,7 +1596,7 @@ private:
|
|||
nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
|
||||
}
|
||||
}
|
||||
else if (AstUnpackArrayDType* arrayType = fromDtp->castUnpackArrayDType()) {
|
||||
else if (AstUnpackArrayDType* arrayType = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||
enum {
|
||||
UNKNOWN = 0,
|
||||
ARRAY_OR,
|
||||
|
|
@ -1666,7 +1667,7 @@ private:
|
|||
UINFO(9," adtypep "<<vdtypep<<endl);
|
||||
nodep->dtypep(vdtypep);
|
||||
// Determine replication count, and replicate initial value as widths need to be individually determined
|
||||
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
|
||||
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
|
||||
int times = visitPatMemberRep(patp);
|
||||
for (int i=1; i<times; i++) {
|
||||
AstNode* newp = patp->cloneTree(false);
|
||||
|
|
@ -1675,7 +1676,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Convert any PatMember with multiple items to multiple PatMembers
|
||||
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
|
||||
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
|
||||
if (patp->lhssp()->nextp()) {
|
||||
// Can't just addNext, as would add to end of all members. So detach, add next and reattach
|
||||
AstNRelinker relinkHandle;
|
||||
|
|
@ -1689,17 +1690,17 @@ private:
|
|||
}
|
||||
}
|
||||
AstPatMember* defaultp = NULL;
|
||||
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
|
||||
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember); patp; patp = VN_CAST(patp->nextp(), PatMember)) {
|
||||
if (patp->isDefault()) {
|
||||
if (defaultp) nodep->v3error("Multiple '{ default: } clauses");
|
||||
defaultp = patp;
|
||||
patp->unlinkFrBack();
|
||||
}
|
||||
}
|
||||
while (AstConstDType* classp = vdtypep->castConstDType()) {
|
||||
while (const AstConstDType* classp = VN_CAST(vdtypep, ConstDType)) {
|
||||
vdtypep = classp->subDTypep()->skipRefp();
|
||||
}
|
||||
if (AstNodeClassDType* classp = vdtypep->castNodeClassDType()) {
|
||||
if (AstNodeClassDType* classp = VN_CAST(vdtypep, NodeClassDType)) {
|
||||
// Due to "default" and tagged patterns, we need to determine
|
||||
// which member each AstPatMember corresponds to before we can
|
||||
// determine the dtypep for that PatMember's value, and then
|
||||
|
|
@ -1708,11 +1709,11 @@ private:
|
|||
PatMap patmap;
|
||||
{
|
||||
AstMemberDType* memp = classp->membersp();
|
||||
AstPatMember* patp = nodep->itemsp()->castPatMember();
|
||||
AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember);
|
||||
for (; memp || patp; ) {
|
||||
if (patp) {
|
||||
if (patp->keyp()) {
|
||||
if (AstText* textp = patp->keyp()->castText()) {
|
||||
if (AstText* textp = VN_CAST(patp->keyp(), Text)) {
|
||||
memp = classp->findMember(textp->text());
|
||||
if (!memp) {
|
||||
patp->keyp()->v3error("Assignment pattern key '"<<textp->text()<<"' not found as member");
|
||||
|
|
@ -1731,16 +1732,16 @@ private:
|
|||
} else {
|
||||
std::pair<PatMap::iterator, bool> ret = patmap.insert(make_pair(memp, patp));
|
||||
if (!ret.second) {
|
||||
patp->v3error("Assignment pattern contains duplicate entry: " << patp->keyp()->castText()->text());
|
||||
patp->v3error("Assignment pattern contains duplicate entry: " << VN_CAST(patp->keyp(), Text)->text());
|
||||
}
|
||||
}
|
||||
// Next
|
||||
if (memp) memp = memp->nextp()->castMemberDType();
|
||||
if (patp) patp = patp->nextp()->castPatMember();
|
||||
if (memp) memp = VN_CAST(memp->nextp(), MemberDType);
|
||||
if (patp) patp = VN_CAST(patp->nextp(), PatMember);
|
||||
}
|
||||
}
|
||||
AstNode* newp = NULL;
|
||||
for (AstMemberDType* memp = classp->membersp(); memp; memp=memp->nextp()->castMemberDType()) {
|
||||
for (AstMemberDType* memp = classp->membersp(); memp; memp=VN_CAST(memp->nextp(), MemberDType)) {
|
||||
PatMap::iterator it = patmap.find(memp);
|
||||
AstPatMember* newpatp = NULL;
|
||||
AstPatMember* patp = NULL;
|
||||
|
|
@ -1750,7 +1751,7 @@ private:
|
|||
patp = newpatp;
|
||||
}
|
||||
else {
|
||||
if (!classp->castUnionDType()) {
|
||||
if (!VN_IS(classp, UnionDType)) {
|
||||
patp->v3error("Assignment pattern missed initializing elements: "<<memp->prettyTypeName());
|
||||
}
|
||||
}
|
||||
|
|
@ -1765,9 +1766,9 @@ private:
|
|||
|
||||
// Convert to concat for now
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
if (VN_IS(valuep, Const)) {
|
||||
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
|
||||
pushDeletep(valuep); VL_DANGLING(valuep);
|
||||
valuep = newp;
|
||||
}
|
||||
|
|
@ -1787,8 +1788,8 @@ private:
|
|||
else nodep->v3error("Assignment pattern with no members");
|
||||
pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present
|
||||
}
|
||||
else if (vdtypep->castNodeArrayDType()) {
|
||||
AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType();
|
||||
else if (VN_IS(vdtypep, NodeArrayDType)) {
|
||||
AstNodeArrayDType* arrayp = VN_CAST(vdtypep, NodeArrayDType);
|
||||
VNumRange range = arrayp->declRange();
|
||||
PatVecMap patmap = patVectorMap(nodep, range);
|
||||
UINFO(9,"ent "<<range.hi()<<" to "<<range.lo()<<endl);
|
||||
|
|
@ -1819,14 +1820,14 @@ private:
|
|||
userIterate(patp, WidthVP(patp->dtypep(),BOTH).p()); // See visit(AstPatMember*
|
||||
// Convert to InitArray or constify immediately
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
if (VN_IS(valuep, Const)) {
|
||||
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
|
||||
pushDeletep(valuep); VL_DANGLING(valuep);
|
||||
valuep = newp;
|
||||
}
|
||||
}
|
||||
if (arrayp->castUnpackArrayDType()) {
|
||||
if (VN_IS(arrayp, UnpackArrayDType)) {
|
||||
if (!newp) {
|
||||
AstInitArray* newap = new AstInitArray(nodep->fileline(), arrayp, NULL);
|
||||
newap->addValuep(valuep);
|
||||
|
|
@ -1834,7 +1835,7 @@ private:
|
|||
} else {
|
||||
// We iterate hi()..lo() as that is what packed needs,
|
||||
// but INITARRAY needs lo() first
|
||||
newp->castInitArray()->addFrontValuep(valuep);
|
||||
VN_CAST(newp, InitArray)->addFrontValuep(valuep);
|
||||
}
|
||||
} else { // Packed. Convert to concat for now.
|
||||
if (!newp) newp = valuep;
|
||||
|
|
@ -1855,9 +1856,9 @@ private:
|
|||
//if (debug()>=9) newp->dumpTree("-apat-out: ");
|
||||
pushDeletep(nodep); VL_DANGLING(nodep); // Deletes defaultp also, if present
|
||||
}
|
||||
else if (vdtypep->castBasicDType()
|
||||
&& vdtypep->castBasicDType()->isRanged()) {
|
||||
AstBasicDType* bdtypep = vdtypep->castBasicDType();
|
||||
else if (VN_IS(vdtypep, BasicDType)
|
||||
&& VN_CAST(vdtypep, BasicDType)->isRanged()) {
|
||||
AstBasicDType* bdtypep = VN_CAST(vdtypep, BasicDType);
|
||||
VNumRange range = bdtypep->declRange();
|
||||
PatVecMap patmap = patVectorMap(nodep, range);
|
||||
UINFO(9,"ent "<<range.hi()<<" to "<<range.lo()<<endl);
|
||||
|
|
@ -1887,9 +1888,9 @@ private:
|
|||
userIterate(patp, WidthVP(patp->dtypep(),BOTH).p());
|
||||
// Convert to InitArray or constify immediately
|
||||
AstNode* valuep = patp->lhssp()->unlinkFrBack();
|
||||
if (valuep->castConst()) {
|
||||
if (VN_IS(valuep, Const)) {
|
||||
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
|
||||
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(VN_CAST(valuep, Const))) {
|
||||
pushDeletep(valuep); VL_DANGLING(valuep);
|
||||
valuep = newp;
|
||||
}
|
||||
|
|
@ -1932,7 +1933,7 @@ private:
|
|||
if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1
|
||||
iterateCheckSizedSelf(nodep,"LHS",nodep->repp(),SELF,BOTH);
|
||||
V3Const::constifyParamsEdit(nodep->repp()); // repp may change
|
||||
AstConst* constp = nodep->repp()->castConst();
|
||||
const AstConst* constp = VN_CAST(nodep->repp(), Const);
|
||||
if (!constp) { nodep->v3error("Replication value isn't a constant."); times=0; }
|
||||
else times = constp->toUInt();
|
||||
if (times==0) { nodep->v3error("Pattern replication value of 0 is not legal."); times=1; }
|
||||
|
|
@ -1962,8 +1963,8 @@ private:
|
|||
assertAtStatement(nodep);
|
||||
userIterateAndNext(nodep->exprp(), WidthVP(CONTEXT,PRELIM).p());
|
||||
for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) {
|
||||
nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced
|
||||
if (!nodep->castGenCase()) userIterateAndNext(itemp->bodysp(), NULL);
|
||||
nextip = VN_CAST(itemp->nextp(), CaseItem); // Prelim may cause the node to get replaced
|
||||
if (!VN_IS(nodep, GenCase)) userIterateAndNext(itemp->bodysp(), NULL);
|
||||
for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) {
|
||||
nextcp = condp->nextp(); // Prelim may cause the node to get replaced
|
||||
userIterate(condp, WidthVP(CONTEXT,PRELIM).p()); VL_DANGLING(condp);
|
||||
|
|
@ -1972,7 +1973,7 @@ private:
|
|||
|
||||
// Take width as maximum across all items, if any is real whole thing is real
|
||||
AstNodeDType* subDTypep = nodep->exprp()->dtypep();
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) {
|
||||
if (condp->dtypep() != subDTypep) {
|
||||
if (condp->dtypep()->isDouble()) {
|
||||
|
|
@ -1988,7 +1989,7 @@ private:
|
|||
}
|
||||
// Apply width
|
||||
iterateCheck(nodep,"Case expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_LHS);
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), CaseItem)) {
|
||||
for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) {
|
||||
nextcp = condp->nextp(); // Final may cause the node to get replaced
|
||||
iterateCheck(nodep,"Case Item",condp,CONTEXT,FINAL,subDTypep,EXTEND_LHS);
|
||||
|
|
@ -1999,7 +2000,7 @@ private:
|
|||
assertAtStatement(nodep);
|
||||
userIterateAndNext(nodep->initsp(), NULL);
|
||||
iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition.
|
||||
if (!nodep->castGenFor()) userIterateAndNext(nodep->bodysp(), NULL);
|
||||
if (!VN_IS(nodep, GenFor)) userIterateAndNext(nodep->bodysp(), NULL);
|
||||
userIterateAndNext(nodep->incsp(), NULL);
|
||||
|
||||
}
|
||||
|
|
@ -2018,7 +2019,7 @@ private:
|
|||
virtual void visit(AstNodeIf* nodep) {
|
||||
assertAtStatement(nodep);
|
||||
//if (debug()) nodep->dumpTree(cout," IfPre: ");
|
||||
if (!nodep->castGenIf()) { // for m_paramsOnly
|
||||
if (!VN_IS(nodep, GenIf)) { // for m_paramsOnly
|
||||
userIterateAndNext(nodep->ifsp(), NULL);
|
||||
userIterateAndNext(nodep->elsesp(), NULL);
|
||||
}
|
||||
|
|
@ -2195,7 +2196,7 @@ private:
|
|||
assertAtStatement(nodep);
|
||||
userIterateAndNext(nodep->filenamep(), WidthVP(SELF,BOTH).p());
|
||||
userIterateAndNext(nodep->memp(), WidthVP(SELF,BOTH).p());
|
||||
if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) {
|
||||
if (!VN_IS(nodep->memp()->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array");
|
||||
}
|
||||
userIterateAndNext(nodep->lsbp(), WidthVP(SELF,BOTH).p());
|
||||
|
|
@ -2281,17 +2282,17 @@ private:
|
|||
// Check if an interface is connected to a non-interface and vice versa
|
||||
AstNodeDType* modDTypep = nodep->modVarp()->dtypep();
|
||||
AstNodeDType* exprDTypep = nodep->exprp()->dtypep();
|
||||
if ((modDTypep->castIfaceRefDType() && !exprDTypep->castIfaceRefDType()) ||
|
||||
(exprDTypep->castIfaceRefDType() && !modDTypep->castIfaceRefDType())) {
|
||||
if ((VN_IS(modDTypep, IfaceRefDType) && !VN_IS(exprDTypep, IfaceRefDType)) ||
|
||||
(VN_IS(exprDTypep, IfaceRefDType) && !VN_IS(modDTypep, IfaceRefDType))) {
|
||||
nodep->v3error("Illegal "<<nodep->prettyOperatorName()<<","
|
||||
<<" mismatch between port which is"<<(modDTypep->castIfaceRefDType()?"":" not")<<" an interface,"
|
||||
<<" and expression which is"<<(exprDTypep->castIfaceRefDType()?"":" not")<<" an interface.");
|
||||
<<" mismatch between port which is"<<(VN_CAST(modDTypep, IfaceRefDType)?"":" not")<<" an interface,"
|
||||
<<" and expression which is"<<(VN_CAST(exprDTypep, IfaceRefDType)?"":" not")<<" an interface.");
|
||||
}
|
||||
|
||||
// TODO Simple dtype checking, should be a more general check
|
||||
AstNodeArrayDType* exprArrayp = exprDTypep->skipRefp()->castUnpackArrayDType();
|
||||
AstNodeArrayDType* modArrayp = modDTypep->skipRefp()->castUnpackArrayDType();
|
||||
if (exprArrayp && modArrayp && exprArrayp->subDTypep()->skipRefp()->castIfaceRefDType()
|
||||
AstNodeArrayDType* exprArrayp = VN_CAST(exprDTypep->skipRefp(), UnpackArrayDType);
|
||||
AstNodeArrayDType* modArrayp = VN_CAST(modDTypep->skipRefp(), UnpackArrayDType);
|
||||
if (exprArrayp && modArrayp && VN_IS(exprArrayp->subDTypep()->skipRefp(), IfaceRefDType)
|
||||
&& exprArrayp->declRange().elements() != modArrayp->declRange().elements()) {
|
||||
int exprSize = exprArrayp->declRange().elements();
|
||||
int modSize = modArrayp->declRange().elements();
|
||||
|
|
@ -2315,7 +2316,7 @@ private:
|
|||
}
|
||||
virtual void visit(AstCell* nodep) {
|
||||
if (!m_paramsOnly) {
|
||||
if (nodep->modp()->castNotFoundModule()) {
|
||||
if (VN_IS(nodep->modp(), NotFoundModule)) {
|
||||
// We've resolved parameters and hit a module that we couldn't resolve. It's
|
||||
// finally time to report it.
|
||||
// Note only here in V3Width as this is first visitor after V3Dead.
|
||||
|
|
@ -2371,7 +2372,7 @@ private:
|
|||
m_ftaskp = nodep;
|
||||
userIterateChildren(nodep, NULL);
|
||||
if (nodep->fvarp()) {
|
||||
m_funcp = nodep->castFunc();
|
||||
m_funcp = VN_CAST(nodep, Func);
|
||||
if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function");
|
||||
nodep->dtypeFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep()
|
||||
}
|
||||
|
|
@ -2404,7 +2405,7 @@ private:
|
|||
}
|
||||
|
||||
virtual void visit(AstFuncRef* nodep) {
|
||||
visit(nodep->castNodeFTaskRef());
|
||||
visit(VN_CAST(nodep, NodeFTaskRef));
|
||||
nodep->dtypeFrom(nodep->taskp());
|
||||
//if (debug()) nodep->dumpTree(cout," FuncOut: ");
|
||||
}
|
||||
|
|
@ -2428,17 +2429,17 @@ private:
|
|||
// Prelim may cause the node to get replaced; we've lost our
|
||||
// pointer, so need to iterate separately later
|
||||
if (portp->attrSFormat()
|
||||
&& (!pinp->castSFormatF() || pinp->nextp())) { // Not already done
|
||||
&& (!VN_IS(pinp, SFormatF) || pinp->nextp())) { // Not already done
|
||||
UINFO(4," sformat via metacomment: "<<nodep<<endl);
|
||||
AstNRelinker handle;
|
||||
argp->unlinkFrBackWithNext(&handle); // Format + additional args, if any
|
||||
AstNode* argsp = NULL;
|
||||
while (AstArg* nextargp = argp->nextp()->castArg()) {
|
||||
while (AstArg* nextargp = VN_CAST(argp->nextp(), Arg)) {
|
||||
argsp = AstNode::addNext(argsp, nextargp->exprp()->unlinkFrBackWithNext()); // Expression goes to SFormatF
|
||||
nextargp->unlinkFrBack()->deleteTree(); // Remove the call's Arg wrapper
|
||||
}
|
||||
string format;
|
||||
if (pinp->castConst()) format = pinp->castConst()->num().toString();
|
||||
if (VN_IS(pinp, Const)) format = VN_CAST(pinp, Const)->num().toString();
|
||||
else pinp->v3error("Format to $display-like function must have constant format string");
|
||||
pushDeletep(argp); VL_DANGLING(argp);
|
||||
AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp);
|
||||
|
|
@ -2450,9 +2451,10 @@ private:
|
|||
goto reloop; // so exit early; next loop will correct it
|
||||
}
|
||||
else if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING
|
||||
&& !pinp->castCvtPackString()
|
||||
&& !pinp->castSFormatF() // Already generates a string
|
||||
&& !(pinp->castVarRef() && pinp->castVarRef()->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) {
|
||||
&& !VN_IS(pinp, CvtPackString)
|
||||
&& !VN_IS(pinp, SFormatF) // Already generates a string
|
||||
&& !(VN_IS(pinp, VarRef)
|
||||
&& VN_CAST(pinp, VarRef)->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) {
|
||||
UINFO(4," Add CvtPackString: "<<pinp<<endl);
|
||||
AstNRelinker handle;
|
||||
pinp->unlinkFrBack(&handle); // No next, that's the next pin
|
||||
|
|
@ -2807,17 +2809,17 @@ private:
|
|||
AstNodeDType* subDTypep = expDTypep;
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
// ShiftRS converts to ShiftR, but not vice-versa
|
||||
if (nodep->castShiftRS()) {
|
||||
if (VN_IS(nodep, ShiftRS)) {
|
||||
if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { VL_DANGLING(nodep);
|
||||
nodep = newp; // Process new node instead
|
||||
}
|
||||
}
|
||||
bool warnOn = true;
|
||||
// No warning if "X = 1'b1<<N"; assume user is doing what they want
|
||||
if (nodep->lhsp()->isOne() && nodep->backp()->castNodeAssign()) warnOn = false;
|
||||
if (nodep->lhsp()->isOne() && VN_IS(nodep->backp(), NodeAssign)) warnOn = false;
|
||||
iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,warnOn);
|
||||
if (nodep->rhsp()->width()>32) {
|
||||
AstConst* shiftp = nodep->rhsp()->castConst();
|
||||
AstConst* shiftp = VN_CAST(nodep->rhsp(), Const);
|
||||
if (shiftp && shiftp->num().mostSetBitP1() <= 32) {
|
||||
// If (number)<<96'h1, then make it into (number)<<32'h1
|
||||
V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num());
|
||||
|
|
@ -2911,10 +2913,10 @@ private:
|
|||
}
|
||||
// Some warning suppressions
|
||||
bool lhsWarn=true; bool rhsWarn = true;
|
||||
if (nodep->castAdd() || nodep->castSub()) {
|
||||
if (VN_IS(nodep, Add) || VN_IS(nodep, Sub)) {
|
||||
if (subDTypep->widthMin() == (nodep->lhsp()->widthMin()+1)) lhsWarn=false; // Warn if user wants extra bit from carry
|
||||
if (subDTypep->widthMin() == (nodep->rhsp()->widthMin()+1)) rhsWarn=false; // Warn if user wants extra bit from carry
|
||||
} else if (nodep->castMul() || nodep->castMulS()) {
|
||||
} else if (VN_IS(nodep, Mul) || VN_IS(nodep, MulS)) {
|
||||
if (subDTypep->widthMin() >= (nodep->lhsp()->widthMin())) lhsWarn=false;
|
||||
if (subDTypep->widthMin() >= (nodep->rhsp()->widthMin())) rhsWarn=false;
|
||||
}
|
||||
|
|
@ -2972,7 +2974,7 @@ private:
|
|||
// for example $unsigned(a)+$signed(b), the SIGNED(B) will be unsigned dtype out
|
||||
UINFO(4," widthExtend_(r="<<extendRule<<") old: "<<nodep<<endl);
|
||||
if (extendRule == EXTEND_OFF) return;
|
||||
AstConst* constp = nodep->castConst();
|
||||
AstConst* constp = VN_CAST(nodep, Const);
|
||||
int expWidth = expDTypep->width();
|
||||
if (constp && !constp->num().isNegative()) {
|
||||
// Save later constant propagation work, just right-size it.
|
||||
|
|
@ -3026,7 +3028,7 @@ private:
|
|||
int expWidth = 1;
|
||||
int expSigned = false;
|
||||
UINFO(4," widthReduce_old: "<<nodep<<endl);
|
||||
AstConst* constp = nodep->castConst();
|
||||
AstConst* constp = VN_CAST(nodep, Const);
|
||||
if (constp) {
|
||||
V3Number num (nodep->fileline(), expWidth);
|
||||
num.opRedOr(constp->num());
|
||||
|
|
@ -3048,7 +3050,7 @@ private:
|
|||
|
||||
bool fixAutoExtend (AstNode*& nodepr, int expWidth) {
|
||||
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
|
||||
if (AstConst* constp = nodepr->castConst()) {
|
||||
if (AstConst* constp = VN_CAST(nodepr, Const)) {
|
||||
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
|
||||
// Make it the proper size. Careful of proper extension of 0's/1's
|
||||
V3Number num (constp->fileline(), expWidth);
|
||||
|
|
@ -3123,8 +3125,8 @@ private:
|
|||
//if (debug()) nodep->dumpTree(cout,"-checkass: ");
|
||||
if (stage != FINAL) nodep->v3fatalSrc("Bad width call");
|
||||
// We iterate and size the RHS based on the result of RHS evaluation
|
||||
bool lhsStream = (nodep->castNodeAssign()
|
||||
&& nodep->castNodeAssign()->lhsp()->castNodeStream());
|
||||
bool lhsStream = (VN_IS(nodep, NodeAssign)
|
||||
&& VN_IS(VN_CAST(nodep, NodeAssign)->lhsp(), NodeStream));
|
||||
rhsp = iterateCheck(nodep,side,rhsp,ASSIGN,FINAL,lhsDTypep,lhsStream?EXTEND_OFF:EXTEND_LHS);
|
||||
//if (debug()) nodep->dumpTree(cout,"-checkout: ");
|
||||
if (rhsp) {} // cppcheck
|
||||
|
|
@ -3257,15 +3259,15 @@ private:
|
|||
underp=NULL; // Changes underp
|
||||
return;
|
||||
}
|
||||
if (underp->castConst() && underp->castConst()->num().isFromString()
|
||||
if (VN_IS(underp, Const) && VN_CAST(underp, Const)->num().isFromString()
|
||||
&& expWidth > underp->width()
|
||||
&& (((expWidth - underp->width()) % 8) == 0)) { // At least it's character sized
|
||||
// reg [31:0] == "foo" we'll consider probably fine.
|
||||
// Maybe this should be a special warning? Not for now.
|
||||
warnOn = false;
|
||||
}
|
||||
if ((nodep->castAdd() && underp->width()==1 && underp->isOne())
|
||||
|| (nodep->castSub() && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) {
|
||||
if ((VN_IS(nodep, Add) && underp->width()==1 && underp->isOne())
|
||||
|| (VN_IS(nodep, Sub) && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) {
|
||||
// "foo + 1'b1", or "foo - 1'b1" are very common, people assume they extend correctly
|
||||
warnOn = false;
|
||||
}
|
||||
|
|
@ -3284,9 +3286,9 @@ private:
|
|||
// If we're in an NodeAssign, don't truncate the RHS if the LHS is
|
||||
// a NodeStream. The streaming operator changes the rules regarding
|
||||
// which bits to truncate.
|
||||
AstNodeAssign* assignp = nodep->castNodeAssign();
|
||||
AstPin* pinp = nodep->castPin();
|
||||
if (assignp && assignp->lhsp()->castNodeStream()) {
|
||||
AstNodeAssign* assignp = VN_CAST(nodep, NodeAssign);
|
||||
AstPin* pinp = VN_CAST(nodep, Pin);
|
||||
if (assignp && VN_IS(assignp->lhsp(), NodeStream)) {
|
||||
} else if (pinp && !pinp->modVarp()->isInput()) { // V3Inst::pinReconnectSimple must deal
|
||||
UINFO(5,"pinInSizeMismatch: "<<pinp);
|
||||
} else {
|
||||
|
|
@ -3517,15 +3519,15 @@ private:
|
|||
for (int i = 1; i <= dim; ++i) {
|
||||
//UINFO(9, " dim at "<<dim<<" "<<dtypep<<endl);
|
||||
declRange = VNumRange(); // ranged() set false
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
declRange = adtypep->declRange();
|
||||
if (i<dim) dtypep = adtypep->subDTypep()->skipRefp();
|
||||
continue;
|
||||
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
|
||||
} else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
|
||||
declRange = adtypep->declRange();
|
||||
if (adtypep) {} // UNUSED
|
||||
break; // Sub elements don't look like arrays and can't iterate into
|
||||
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
} else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
if (adtypep->isRanged()) declRange = adtypep->declRange();
|
||||
break;
|
||||
}
|
||||
|
|
@ -3538,14 +3540,14 @@ private:
|
|||
int bits = 1;
|
||||
while (dtypep) {
|
||||
//UINFO(9, " bits at "<<bits<<" "<<dtypep<<endl);
|
||||
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||
if (AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||
bits *= adtypep->declRange().elements();
|
||||
dtypep = adtypep->subDTypep()->skipRefp();
|
||||
continue;
|
||||
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
|
||||
} else if (AstNodeClassDType* adtypep = VN_CAST(dtypep, NodeClassDType)) {
|
||||
bits *= adtypep->width();
|
||||
break;
|
||||
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
} else if (AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) {
|
||||
bits *= adtypep->width();
|
||||
break;
|
||||
}
|
||||
|
|
@ -3660,10 +3662,10 @@ private:
|
|||
{
|
||||
AstEnumItem* firstp = nodep->itemsp();
|
||||
AstEnumItem* prevp = firstp; // Prev must start with last item
|
||||
while (prevp->nextp()) prevp = prevp->nextp()->castEnumItem();
|
||||
while (prevp->nextp()) prevp = VN_CAST(prevp->nextp(), EnumItem);
|
||||
for (AstEnumItem* itemp = firstp; itemp;) {
|
||||
AstEnumItem* nextp = itemp->nextp()->castEnumItem();
|
||||
AstConst* vconstp = itemp->valuep()->castConst();
|
||||
AstEnumItem* nextp = VN_CAST(itemp->nextp(), EnumItem);
|
||||
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
|
||||
if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
|
||||
uint32_t i = vconstp->toUInt();
|
||||
if (attrType == AstAttrType::ENUM_NAME) {
|
||||
|
|
@ -3692,10 +3694,10 @@ private:
|
|||
PatVecMap patVectorMap(AstPattern* nodep, const VNumRange& range) {
|
||||
PatVecMap patmap;
|
||||
int element = range.left();
|
||||
for (AstPatMember* patp = nodep->itemsp()->castPatMember();
|
||||
patp; patp = patp->nextp()->castPatMember()) {
|
||||
for (AstPatMember* patp = VN_CAST(nodep->itemsp(), PatMember);
|
||||
patp; patp = VN_CAST(patp->nextp(), PatMember)) {
|
||||
if (patp->keyp()) {
|
||||
if (AstConst* constp = patp->keyp()->castConst()) {
|
||||
if (const AstConst* constp = VN_CAST(patp->keyp(), Const)) {
|
||||
element = constp->toSInt();
|
||||
} else {
|
||||
patp->keyp()->v3error("Assignment pattern key not supported/understood: "<<patp->keyp()->prettyTypeName());
|
||||
|
|
@ -3740,7 +3742,7 @@ private:
|
|||
bool markHasOpenArray(AstNodeFTask* nodep) {
|
||||
bool hasOpen = false;
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (AstVar* portp = VN_CAST(stmtp, Var)) {
|
||||
if (portp->isDpiOpenArray() || hasOpenArrayIterateDType(portp->dtypep())) {
|
||||
portp->isDpiOpenArray(true);
|
||||
hasOpen = true;
|
||||
|
|
@ -3751,7 +3753,7 @@ private:
|
|||
}
|
||||
bool hasOpenArrayIterateDType(AstNodeDType* nodep) {
|
||||
// Return true iff this datatype or child has an openarray
|
||||
if (nodep->castUnsizedArrayDType()) return true;
|
||||
if (VN_IS(nodep, UnsizedArrayDType)) return true;
|
||||
if (nodep->subDTypep()) return hasOpenArrayIterateDType(nodep->subDTypep()->skipRefp());
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3767,7 +3769,7 @@ private:
|
|||
void checkConstantOrReplace(AstNode* nodep, const string& message) {
|
||||
// See also V3WidthSel::checkConstantOrReplace
|
||||
// Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us!
|
||||
if (!nodep->castConst()) {
|
||||
if (!VN_IS(nodep, Const)) {
|
||||
nodep->v3error(message);
|
||||
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ private:
|
|||
// Recurse to handle the data type, as may change the size etc of this type
|
||||
if (!nodep->user1()) nodep->accept(*this);
|
||||
// Look for duplicate
|
||||
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
|
||||
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
|
||||
AstBasicDType* newp = nodep->findInsertSameDType(bdtypep);
|
||||
if (newp != bdtypep && debug()>=9) {
|
||||
UINFO(9,"dtype replacement "); nodep->dumpSmall(cout);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ private:
|
|||
void checkConstantOrReplace(AstNode* nodep, const string& message) {
|
||||
// See also V3Width::checkConstantOrReplace
|
||||
// Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us!
|
||||
if (!nodep->castConst()) {
|
||||
if (!VN_IS(nodep, Const)) {
|
||||
nodep->v3error(message);
|
||||
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
|
|
@ -83,8 +83,8 @@ private:
|
|||
UINFO(9," fromData start ddtypep = "<<basefromp<<endl);
|
||||
VNumRange fromRange; // constructs to isRanged(false)
|
||||
while (basefromp) {
|
||||
if (basefromp->castAttrOf()) {
|
||||
basefromp = basefromp->castAttrOf()->fromp();
|
||||
if (VN_IS(basefromp, AttrOf)) {
|
||||
basefromp = VN_CAST(basefromp, AttrOf)->fromp();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
@ -93,17 +93,17 @@ private:
|
|||
AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp();
|
||||
AstNode* errp = ddtypep;
|
||||
UINFO(9," fromData.ddtypep = "<<ddtypep<<endl);
|
||||
if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
|
||||
if (const AstNodeArrayDType* adtypep = VN_CAST(ddtypep, NodeArrayDType)) {
|
||||
fromRange = adtypep->declRange();
|
||||
}
|
||||
else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) {
|
||||
else if (const AstNodeClassDType* adtypep = VN_CAST(ddtypep, NodeClassDType)) {
|
||||
fromRange = adtypep->declRange();
|
||||
}
|
||||
else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
||||
else if (AstBasicDType* adtypep = VN_CAST(ddtypep, BasicDType)) {
|
||||
if (adtypep->isRanged()) {
|
||||
if (adtypep->rangep()
|
||||
&& (!adtypep->rangep()->msbp()->castConst()
|
||||
|| !adtypep->rangep()->lsbp()->castConst()))
|
||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const)))
|
||||
nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||
fromRange = adtypep->declRange();
|
||||
} else {
|
||||
|
|
@ -123,10 +123,10 @@ private:
|
|||
// have to deal with signed math and related 32bit sign extension problems
|
||||
if (rhs == 0) {
|
||||
return lhsp;
|
||||
} else if (lhsp->castConst()) {
|
||||
} else if (VN_IS(lhsp, Const)) {
|
||||
// Optional vs just making add/sub below, but saves constification some work
|
||||
V3Number num (lhsp->fileline(), lhsp->width());
|
||||
num.opSub(lhsp->castConst()->num(), V3Number(lhsp->fileline(), 32, rhs));
|
||||
num.opSub(VN_CAST(lhsp, Const)->num(), V3Number(lhsp->fileline(), 32, rhs));
|
||||
num.isSigned(lhsp->isSigned());
|
||||
AstNode* newp = new AstConst(lhsp->fileline(), num);
|
||||
return newp;
|
||||
|
|
@ -207,7 +207,7 @@ private:
|
|||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
UINFO(6," ddtypep "<<ddtypep<<endl);
|
||||
if (AstUnpackArrayDType* adtypep = ddtypep->castUnpackArrayDType()) {
|
||||
if (AstUnpackArrayDType* adtypep = VN_CAST(ddtypep, UnpackArrayDType)) {
|
||||
// SELBIT(array, index) -> ARRAYSEL(array, index)
|
||||
AstNode* subp = rhsp;
|
||||
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
||||
|
|
@ -219,7 +219,7 @@ private:
|
|||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
|
||||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex)
|
||||
AstNode* subp = rhsp;
|
||||
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
||||
|
|
@ -245,7 +245,7 @@ private:
|
|||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (ddtypep->castBasicDType()) {
|
||||
else if (VN_IS(ddtypep, BasicDType)) {
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel (nodep->fileline(),
|
||||
fromp,
|
||||
|
|
@ -257,7 +257,7 @@ private:
|
|||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (ddtypep->castNodeClassDType()) { // It's packed, so a bit from the packed struct
|
||||
else if (VN_IS(ddtypep, NodeClassDType)) { // It's packed, so a bit from the packed struct
|
||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||
AstSel* newp = new AstSel (nodep->fileline(),
|
||||
fromp,
|
||||
|
|
@ -292,13 +292,13 @@ private:
|
|||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* lsbp = nodep->thsp()->unlinkFrBack();
|
||||
vlsint32_t msb = msbp->castConst()->toSInt();
|
||||
vlsint32_t lsb = lsbp->castConst()->toSInt();
|
||||
vlsint32_t msb = VN_CAST(msbp, Const)->toSInt();
|
||||
vlsint32_t lsb = VN_CAST(lsbp, Const)->toSInt();
|
||||
vlsint32_t elem = (msb>lsb) ? (msb-lsb+1) : (lsb-msb+1);
|
||||
FromData fromdata = fromDataForArray(nodep, fromp, false);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (ddtypep->castUnpackArrayDType()) {
|
||||
if (VN_IS(ddtypep, UnpackArrayDType)) {
|
||||
// Slice extraction
|
||||
if (fromRange.elements() == elem
|
||||
&& fromRange.lo() == lsb) { // Extracting whole of original array
|
||||
|
|
@ -313,7 +313,7 @@ private:
|
|||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
|
||||
else if (AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
// SELEXTRACT(array, msb, lsb) -> SEL(array, lsb*width-of-subindex, width-of-subindex*(msb-lsb))
|
||||
if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0)
|
||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||
|
|
@ -339,7 +339,7 @@ private:
|
|||
if (newp->widthMin()!=(int)newp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (ddtypep->castBasicDType()) {
|
||||
else if (VN_IS(ddtypep, BasicDType)) {
|
||||
if (fromRange.littleEndian()) {
|
||||
// Below code assumes big bit endian; just works out if we swap
|
||||
int x = msb; msb = lsb; lsb = x;
|
||||
|
|
@ -359,7 +359,7 @@ private:
|
|||
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
|
||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
else if (ddtypep->castNodeClassDType()) {
|
||||
else if (VN_IS(ddtypep, NodeClassDType)) {
|
||||
// Classes aren't little endian
|
||||
if (lsb > msb) {
|
||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
|
||||
|
|
@ -402,24 +402,24 @@ private:
|
|||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->thsp()->unlinkFrBack();
|
||||
int width = widthp->castConst()->toSInt();
|
||||
int width = VN_CAST(widthp, Const)->toSInt();
|
||||
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<<widthp->prettyName());
|
||||
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
|
||||
FromData fromdata = fromDataForArray(nodep, fromp, width!=1);
|
||||
AstNodeDType* ddtypep = fromdata.m_dtypep;
|
||||
VNumRange fromRange = fromdata.m_fromRange;
|
||||
if (ddtypep->castBasicDType()
|
||||
|| ddtypep->castPackArrayDType()
|
||||
|| (ddtypep->castNodeClassDType()
|
||||
&& ddtypep->castNodeClassDType()->packedUnsup())) {
|
||||
if (VN_IS(ddtypep, BasicDType)
|
||||
|| VN_IS(ddtypep, PackArrayDType)
|
||||
|| (VN_IS(ddtypep, NodeClassDType)
|
||||
&& VN_CAST(ddtypep, NodeClassDType)->packedUnsup())) {
|
||||
int elwidth = 1;
|
||||
AstNode* newwidthp = widthp;
|
||||
if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) {
|
||||
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||
elwidth = adtypep->width() / fromRange.elements();
|
||||
newwidthp = new AstConst (nodep->fileline(),AstConst::Unsized32(), width * elwidth);
|
||||
}
|
||||
AstNode* newlsbp = NULL;
|
||||
if (nodep->castSelPlus()) {
|
||||
if (VN_IS(nodep, SelPlus)) {
|
||||
if (fromRange.littleEndian()) {
|
||||
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
|
||||
newlsbp = newSubNeg((fromRange.hi()-width+1), rhsp);
|
||||
|
|
@ -427,7 +427,7 @@ private:
|
|||
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
|
||||
newlsbp = newSubNeg(rhsp, fromRange.lo());
|
||||
}
|
||||
} else if (nodep->castSelMinus()) {
|
||||
} else if (VN_IS(nodep, SelMinus)) {
|
||||
if (fromRange.littleEndian()) {
|
||||
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
|
||||
newlsbp = newSubNeg(fromRange.hi(), rhsp);
|
||||
|
|
|
|||
|
|
@ -237,27 +237,45 @@ sub write_visitor {
|
|||
|
||||
sub write_intf {
|
||||
my $fh = open_file(@_);
|
||||
|
||||
print $fh "\n";
|
||||
print $fh " // These for use by VN_IS macro only\n";
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
next if $type eq "Node"; # Special, just a return (this);
|
||||
printf $fh " Ast%-16s cast${type}();\n"
|
||||
,$type."*";
|
||||
print $fh " static bool privateIs",$type,"(const AstNode* nodep);\n";
|
||||
}
|
||||
|
||||
print $fh "\n";
|
||||
print $fh " // These for use by VN_CAST macro only\n";
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
print $fh " static Ast",$type,"* privateCast",$type,"(AstNode* nodep);\n";
|
||||
}
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
print $fh " static const Ast",$type,"* privateConstCast",$type,"(const AstNode* nodep);\n";
|
||||
}
|
||||
|
||||
$fh->close();
|
||||
}
|
||||
|
||||
sub write_impl {
|
||||
my $fh = open_file(@_);
|
||||
|
||||
print $fh "\n";
|
||||
print $fh " // These for use by VN_IS macro only\n";
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
next if $type eq "Node"; # Special, just a return (this);
|
||||
# For performance, prefer static_cast where we can
|
||||
if (children_of($type)) {
|
||||
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast<Ast${type}*>(this)); }\n"
|
||||
,$type."*";
|
||||
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return (bool)(dynamic_cast<const Ast",$type,"*>(nodep)); }\n";
|
||||
} else {
|
||||
printf $fh "inline Ast%-16s AstNode::cast${type}() { return (this && this->type() == AstType::at${type}) ? static_cast<Ast${type}*>(this) : NULL; }\n"
|
||||
,$type."*";
|
||||
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return nodep && nodep->type() == AstType::at",$type,"; }\n";
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
print $fh "inline Ast",$type,"* AstNode::privateCast",$type,"(AstNode* nodep) { return dynamic_cast<Ast",$type,"*>(nodep); }\n";
|
||||
}
|
||||
foreach my $type (sort (keys %Classes)) {
|
||||
print $fh "inline const Ast",$type,"* AstNode::privateConstCast",$type,"(const AstNode* nodep) { return dynamic_cast<const Ast",$type,"*>(nodep); }\n";
|
||||
}
|
||||
|
||||
$fh->close();
|
||||
}
|
||||
|
||||
|
|
@ -405,12 +423,14 @@ sub tree_line {
|
|||
next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs
|
||||
$mif .= " && " if $mif;
|
||||
my $subnodeif = $subnode;
|
||||
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.cast([A-Z][A-Za-z0-9]+)$/VN_IS(nodep->$1(),$2)/g;
|
||||
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g;
|
||||
$subnodeif = add_nodep($subnodeif);
|
||||
$mif .= $subnodeif;
|
||||
}
|
||||
|
||||
my $exec_func = treeop_exec_func($self, $to);
|
||||
while ($exec_func =~ s/([-()a-zA-Z0-9_>]+)->cast([A-Z][A-Za-z0-9]+)\(\)/VN_CAST($1,$2)/) {}
|
||||
|
||||
$self->{treeop}{$type} ||= [];
|
||||
my $n = $#{$self->{treeop}{$type}} + 1;
|
||||
|
|
@ -601,7 +621,7 @@ sub tree_base {
|
|||
" nodep->lhsp()->iterateAndNext(*this);\n",
|
||||
@out_for_type_sc);
|
||||
$self->print(" nodep->rhsp()->iterateAndNext(*this);\n",
|
||||
" AstNodeTriop *tnp = nodep->castNodeTriop();\n",
|
||||
" AstNodeTriop *tnp = VN_CAST(nodep, NodeTriop);\n",
|
||||
" if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n",
|
||||
@out_for_type,
|
||||
" }\n") if ($out_for_type[0]);
|
||||
|
|
|
|||
|
|
@ -1073,11 +1073,11 @@ void V3ParseImp::lexToken() {
|
|||
AstNode* scp = foundp->nodep();
|
||||
yylval.scp = scp;
|
||||
UINFO(7," lexToken: Found "<<scp<<endl);
|
||||
if (scp->castTypedef()) token = yaID__aTYPE;
|
||||
else if (scp->castTypedefFwd()) token = yaID__aTYPE;
|
||||
else if (scp->castPackage()) token = yaID__aPACKAGE;
|
||||
//UNSUP else if (scp->castClass()) token = yaID__aCLASS;
|
||||
//UNSUP else if (scp->castCoverGroup()) token = yaID__aCOVERGROUP;
|
||||
if (VN_IS(scp, Typedef)) token = yaID__aTYPE;
|
||||
else if (VN_IS(scp, TypedefFwd)) token = yaID__aTYPE;
|
||||
else if (VN_IS(scp, Package)) token = yaID__aPACKAGE;
|
||||
//UNSUP else if (VN_IS(scp, NodeClass)) token = yaID__aCLASS;
|
||||
//UNSUP else if (VN_IS(scp, CoverGroup)) token = yaID__aCOVERGROUP;
|
||||
else token = yaID__ETC;
|
||||
} else { // Not found
|
||||
yylval.scp = NULL;
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ public:
|
|||
pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
|
||||
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
|
||||
} else {
|
||||
pkgp = symp->nodep()->castPackage();
|
||||
pkgp = VN_CAST(symp->nodep(), Package);
|
||||
}
|
||||
return pkgp;
|
||||
}
|
||||
|
|
@ -145,12 +145,12 @@ public:
|
|||
rangearraysp = rangesp; // Already a range; everything is an array
|
||||
} else {
|
||||
AstNodeRange* finalp = rangesp;
|
||||
while (finalp->nextp()) finalp=finalp->nextp()->castNodeRange();
|
||||
while (finalp->nextp()) finalp = VN_CAST(finalp->nextp(), Range);
|
||||
if (finalp != rangesp) {
|
||||
finalp->unlinkFrBack();
|
||||
rangearraysp = rangesp;
|
||||
}
|
||||
if (AstRange* finalRangep = finalp->castRange()) { // not an UnsizedRange
|
||||
if (AstRange* finalRangep = VN_CAST(finalp, Range)) { // not an UnsizedRange
|
||||
if (dtypep->implicit()) {
|
||||
// It's no longer implicit but a real logic type
|
||||
AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC,
|
||||
|
|
@ -749,7 +749,7 @@ package_import_itemList<nodep>:
|
|||
|
||||
package_import_item<nodep>: // ==IEEE: package_import_item
|
||||
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
|
||||
{ $$ = new AstPackageImport($<fl>1, $<scp>1->castPackage(), *$3);
|
||||
{ $$ = new AstPackageImport($<fl>1, VN_CAST($<scp>1, Package), *$3);
|
||||
SYMP->importItem($<scp>1,*$3); }
|
||||
;
|
||||
|
||||
|
|
@ -770,7 +770,7 @@ package_export_itemList<nodep>:
|
|||
|
||||
package_export_item<nodep>: // ==IEEE: package_export_item
|
||||
yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
|
||||
{ $$ = new AstPackageExport($<fl>1, $<scp>1->castPackage(), *$3);
|
||||
{ $$ = new AstPackageExport($<fl>1, VN_CAST($<scp>1, Package), *$3);
|
||||
SYMP->exportItem($<scp>1,*$3); }
|
||||
;
|
||||
|
||||
|
|
@ -1497,7 +1497,7 @@ variable_dimensionListE<rangep>: // IEEE: variable_dimension + empty
|
|||
|
||||
variable_dimensionList<rangep>: // IEEE: variable_dimension + empty
|
||||
variable_dimension { $$ = $1; }
|
||||
| variable_dimensionList variable_dimension { $$ = $1->addNext($2)->castNodeRange(); }
|
||||
| variable_dimensionList variable_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
|
||||
;
|
||||
|
||||
variable_dimension<rangep>: // ==IEEE: variable_dimension
|
||||
|
|
@ -1836,7 +1836,7 @@ conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
|
|||
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 = $9->castBegin();
|
||||
AstBegin* lowerBegp = VN_CAST($9, Begin);
|
||||
if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin");
|
||||
if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body
|
||||
AstNode* lowerNoBegp = lowerBegp->stmtsp();
|
||||
|
|
@ -1845,7 +1845,7 @@ loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
|
|||
AstBegin* blkp = new AstBegin($1,lowerBegp->name(),NULL,true);
|
||||
// V3LinkDot detects BEGIN(GENFOR(...)) as a special case
|
||||
AstNode* initp = $3; AstNode* varp = $3;
|
||||
if (varp->castVar()) { // Genvar
|
||||
if (VN_IS(varp, Var)) { // Genvar
|
||||
initp = varp->nextp();
|
||||
initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init
|
||||
blkp->addStmtsp(varp);
|
||||
|
|
@ -2009,7 +2009,7 @@ packed_dimensionListE<rangep>: // IEEE: [{ packed_dimension }]
|
|||
|
||||
packed_dimensionList<rangep>: // IEEE: { packed_dimension }
|
||||
packed_dimension { $$ = $1; }
|
||||
| packed_dimensionList packed_dimension { $$ = $1->addNext($2)->castNodeRange(); }
|
||||
| packed_dimensionList packed_dimension { $$ = VN_CAST($1->addNext($2), NodeRange); }
|
||||
;
|
||||
|
||||
packed_dimension<rangep>: // ==IEEE: packed_dimension
|
||||
|
|
@ -2116,12 +2116,12 @@ cellpinList<pinp>:
|
|||
|
||||
cellparamItList<pinp>: // IEEE: list_of_parameter_assignmente
|
||||
cellparamItemE { $$ = $1; }
|
||||
| cellparamItList ',' cellparamItemE { $$ = $1->addNextNull($3)->castPin(); }
|
||||
| cellparamItList ',' cellparamItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
|
||||
;
|
||||
|
||||
cellpinItList<pinp>: // IEEE: list_of_port_connections
|
||||
cellpinItemE { $$ = $1; }
|
||||
| cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); }
|
||||
| cellpinItList ',' cellpinItemE { $$ = VN_CAST($1->addNextNull($3), Pin); }
|
||||
;
|
||||
|
||||
cellparamItemE<pinp>: // IEEE: named_parameter_assignment + empty
|
||||
|
|
@ -2194,8 +2194,8 @@ event_control<sentreep>: // ==IEEE: event_control
|
|||
|
||||
event_expression<senitemp>: // IEEE: event_expression - split over several
|
||||
senitem { $$ = $1; }
|
||||
| event_expression yOR senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); }
|
||||
| event_expression ',' senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); } /* Verilog 2001 */
|
||||
| event_expression yOR senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
|
||||
| event_expression ',' senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); } /* Verilog 2001 */
|
||||
;
|
||||
|
||||
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
|
||||
|
|
@ -2646,7 +2646,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
|
|||
| yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($<fl>1,$3); }
|
||||
//
|
||||
| yaD_DPI parenE { $$ = new AstTaskRef($<fl>1,*$1,NULL); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList($$->castTaskRef()); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
|
||||
//
|
||||
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
|
||||
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
|
||||
|
|
@ -2691,7 +2691,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
|
|||
| yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2,V3Number($2,"'b0")); } // Unsized 0
|
||||
//
|
||||
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList($$->castFuncRef()); }
|
||||
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); }
|
||||
//
|
||||
| yD_BITS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); }
|
||||
| yD_BITS '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); }
|
||||
|
|
@ -2772,7 +2772,7 @@ exprOrDataType<nodep>: // expr | data_type: combined to prevent conflicts
|
|||
|
||||
list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
|
||||
argsDottedList { $$ = $1; }
|
||||
| argsExprListE { if ($1->castArg() && $1->castArg()->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
|
||||
| argsExprListE { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()'
|
||||
/*cont*/ else $$ = $1; }
|
||||
| argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); }
|
||||
;
|
||||
|
|
@ -3728,7 +3728,7 @@ ps_id_etc: // package_scope + general id
|
|||
ps_type<dtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
|
||||
// Even though we looked up the type and have a AstNode* to it,
|
||||
// we can't fully resolve it because it may have been just a forward definition.
|
||||
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); $$->castRefDType()->packagep($1); }
|
||||
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); VN_CAST($$, RefDType)->packagep($1); }
|
||||
// // Simplify typing - from ps_covergroup_identifier
|
||||
//UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $<fl>$=$<fl>1; $$=$1+$2; }
|
||||
;
|
||||
|
|
@ -3748,7 +3748,7 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
|
|||
yD_UNIT { SYMP->nextId(PARSEP->rootp()); }
|
||||
/*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($<fl>1); }
|
||||
| yaID__aPACKAGE { SYMP->nextId($<scp>1); }
|
||||
/*cont*/ yP_COLONCOLON { $$ = $<scp>1->castPackage(); }
|
||||
/*cont*/ yP_COLONCOLON { $$ = VN_CAST($<scp>1, Package); }
|
||||
//UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
|
||||
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
|
||||
;
|
||||
|
|
@ -3848,26 +3848,26 @@ AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int v
|
|||
AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) {
|
||||
// Remove any UnsizedRange's from list
|
||||
for (AstNodeRange* nodep = nrangep, *nextp; nodep; nodep=nextp) {
|
||||
nextp = nrangep->nextp()->castNodeRange();
|
||||
if (!nodep->castRange()) {
|
||||
nextp = VN_CAST(nrangep->nextp(), NodeRange);
|
||||
if (!VN_IS(nodep, Range)) {
|
||||
nodep->v3error("Unsupported or syntax error: Unsized range in cell or other declaration");
|
||||
nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
return nrangep->castRange();
|
||||
return VN_CAST(nrangep, Range);
|
||||
}
|
||||
|
||||
AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstNodeRange* nrangep, bool isPacked) {
|
||||
// Split RANGE0-RANGE1-RANGE2 into ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3),RANGE),RANGE)
|
||||
AstNodeDType* arrayp = basep;
|
||||
if (nrangep) { // Maybe no range - return unmodified base type
|
||||
while (nrangep->nextp()) nrangep = nrangep->nextp()->castNodeRange();
|
||||
while (nrangep->nextp()) nrangep = VN_CAST(nrangep->nextp(), NodeRange);
|
||||
while (nrangep) {
|
||||
AstNodeRange* prevp = nrangep->backp()->castNodeRange();
|
||||
AstNodeRange* prevp = VN_CAST(nrangep->backp(), NodeRange);
|
||||
if (prevp) nrangep->unlinkFrBack();
|
||||
AstRange* rangep = nrangep->castRange();
|
||||
AstRange* rangep = VN_CAST(nrangep, Range);
|
||||
if (!rangep) {
|
||||
if (!nrangep->castUnsizedRange()) nrangep->v3fatalSrc("Expected range or unsized range");
|
||||
if (!VN_IS(nrangep, UnsizedRange)) nrangep->v3fatalSrc("Expected range or unsized range");
|
||||
arrayp = new AstUnsizedArrayDType(nrangep->fileline(), VFlagChildDType(), arrayp);
|
||||
} else if (isPacked) {
|
||||
arrayp = new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep);
|
||||
|
|
@ -3922,7 +3922,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstNodeR
|
|||
if (GRAMMARP->m_varDecl == AstVarType::SUPPLY1) {
|
||||
nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 1));
|
||||
}
|
||||
if (dtypep->castParseTypeDType()) {
|
||||
if (VN_IS(dtypep, ParseTypeDType)) {
|
||||
// Parser needs to know what is a type
|
||||
AstNode* newp = new AstTypedefFwd(fileline, name);
|
||||
nodep->addNext(newp);
|
||||
|
|
|
|||
Loading…
Reference in New Issue