From eac345864779b6a3c6e31bc055ef73e9cce8ebde Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 9 May 2019 20:03:19 -0400 Subject: [PATCH] Internals: V3Number tracks node information, part of bug1305. Signed-off-by: Wilson Snyder --- src/V3Ast.h | 14 ++-- src/V3AstNodes.cpp | 5 ++ src/V3AstNodes.h | 100 +++++++++++++++--------- src/V3CCtors.cpp | 6 +- src/V3Case.cpp | 20 ++--- src/V3Clean.cpp | 6 +- src/V3Const.cpp | 71 ++++++++--------- src/V3Delayed.cpp | 6 +- src/V3EmitC.cpp | 2 +- src/V3Expand.cpp | 38 ++++----- src/V3LinkDot.cpp | 13 ++-- src/V3LinkJump.cpp | 6 +- src/V3Number.cpp | 186 +++++++++++++++++++++++++------------------- src/V3Number.h | 53 +++++++++---- src/V3Param.cpp | 18 +++-- src/V3ParseImp.h | 6 +- src/V3Premit.cpp | 8 +- src/V3Simulate.h | 78 ++++++++++--------- src/V3Table.cpp | 18 ++--- src/V3Trace.cpp | 3 +- src/V3Tristate.cpp | 35 +++++---- src/V3Unknown.cpp | 48 ++++++------ src/V3Unroll.cpp | 38 ++++----- src/V3Width.cpp | 36 ++++----- src/V3WidthCommit.h | 6 +- src/V3WidthSel.cpp | 6 +- src/verilog.y | 25 +++--- 27 files changed, 469 insertions(+), 382 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index 935c76a01..0ecc0093a 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1628,19 +1628,19 @@ public: else if (expr2p) dtypeFrom(expr2p); } ASTNODE_BASE_FUNCS(NodeCond) - virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) { - if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); } - AstNode* condp() const { return op1p(); } // op1 = Condition - AstNode* expr1p() const { return op2p(); } // op2 = If true... - AstNode* expr2p() const { return op3p(); } // op3 = If false... + virtual void numberOperate(V3Number& out, const V3Number& lhs, + const V3Number& rhs, const V3Number& ths); + AstNode* condp() const { return op1p(); } // op1 = Condition + AstNode* expr1p() const { return op2p(); } // op2 = If true... + AstNode* expr2p() const { return op3p(); } // op3 = If false... virtual string emitVerilog() { return "%k(%l %f? %r %k: %t)"; } virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; } - virtual bool cleanOut() { return false; } // clean if e1 & e2 clean + virtual bool cleanOut() { return false; } // clean if e1 & e2 clean virtual bool cleanLhs() { return true; } virtual bool cleanRhs() { return false; } virtual bool cleanThs() { return false; } // Propagates up virtual bool sizeMattersLhs() { return false; } virtual bool sizeMattersRhs() { return false; } virtual bool sizeMattersThs() { return false; } - virtual int instrCount() const { return instrCountBranch(); } + virtual int instrCount() const { return instrCountBranch(); } virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) = 0; }; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index eb78ca28c..f44f61b55 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -84,6 +84,11 @@ const char* AstNodeClassDType::broken() const { return NULL; } +void AstNodeCond::numberOperate(V3Number& out, const V3Number& lhs, + const V3Number& rhs, const V3Number& ths) { + if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); +} + int AstBasicDType::widthAlignBytes() const { if (width()<=8) return 1; else if (width()<=16) return 2; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index d68660da6..d7fd9d351 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -48,56 +48,82 @@ class AstConst : public AstNodeMath { // A constant private: - V3Number m_num; // Constant value -public: - AstConst(FileLine* fl, const V3Number& num) - :AstNodeMath(fl) - ,m_num(num) { - if (m_num.isDouble()) { - dtypeSetDouble(); + V3Number m_num; // Constant value + void initWithNumber() { + if (m_num.isDouble()) { + dtypeSetDouble(); } else if (m_num.isString()) { - dtypeSetString(); - } else { - dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(), + dtypeSetString(); + } else { + dtypeSetLogicSized(m_num.width(), (m_num.sized() ? 0 : m_num.widthMin()), m_num.isSigned() ? AstNumeric::SIGNED - : AstNumeric::UNSIGNED); + : AstNumeric::UNSIGNED); } } +public: + AstConst(FileLine* fl, const V3Number& num) + : AstNodeMath(fl) + , m_num(num) { + initWithNumber(); + } + class WidthedValue {}; // for creator type-overload selection + AstConst(FileLine* fl, WidthedValue, int width, uint32_t value) + : AstNodeMath(fl) + , m_num(this, width, value) { + initWithNumber(); + } + class StringToParse {}; // for creator type-overload selection + AstConst(FileLine* fl, StringToParse, const char* sourcep) + : AstNodeMath(fl) + , m_num(this, sourcep) { + initWithNumber(); + } + class VerilogStringLiteral {}; // for creator type-overload selection + AstConst(FileLine* fl, VerilogStringLiteral, const string& str) + : AstNodeMath(fl) + , m_num(V3Number::VerilogStringLiteral(), this, str) { + initWithNumber(); + } AstConst(FileLine* fl, uint32_t num) - :AstNodeMath(fl) - ,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(), - m_num.sized()?0:m_num.widthMin(), - AstNumeric::UNSIGNED); } + : AstNodeMath(fl) + , m_num(V3Number(this, 32, num)) { + dtypeSetLogicSized(m_num.width(), + m_num.sized() ? 0 : m_num.widthMin(), + AstNumeric::UNSIGNED); + } class Unsized32 {}; // for creator type-overload selection AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value - :AstNodeMath(fl) - ,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(), - AstNumeric::UNSIGNED); } - class Signed32 {}; // for creator type-overload selection + : AstNodeMath(fl) + , m_num(V3Number(this, 32, num)) { + m_num.width(32,false); + dtypeSetLogicSized(32, m_num.widthMin(), AstNumeric::UNSIGNED); + } + class Signed32 {}; // for creator type-overload selection AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value - :AstNodeMath(fl) - ,m_num(V3Number(fl,32,num)) { m_num.width(32,32); dtypeSetLogicSized(32,m_num.widthMin(), - AstNumeric::SIGNED); } - class RealDouble {}; // for creator type-overload selection + : AstNodeMath(fl) + , m_num(V3Number(this, 32, num)) { + m_num.width(32,32); + dtypeSetLogicSized(32, m_num.widthMin(), AstNumeric::SIGNED); + } + class RealDouble {}; // for creator type-overload selection AstConst(FileLine* fl, RealDouble, double num) - :AstNodeMath(fl) - ,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); } - class String {}; // for creator type-overload selection + : AstNodeMath(fl) + , m_num(V3Number(this, 64)) { m_num.setDouble(num); dtypeSetDouble(); } + class String {}; // for creator type-overload selection AstConst(FileLine* fl, String, const string& num) - :AstNodeMath(fl) - ,m_num(V3Number(V3Number::String(), fl, num)) { dtypeSetString(); } + : AstNodeMath(fl) + , m_num(V3Number(V3Number::String(), this, num)) { dtypeSetString(); } class LogicFalse {}; - AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1 - :AstNodeMath(fl) - ,m_num(V3Number(fl,1,0)) { dtypeSetLogicBool(); } + AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, dtype should be a logic of size 1 + : AstNodeMath(fl) + , m_num(V3Number(this, 1, 0)) { dtypeSetLogicBool(); } class LogicTrue {}; - AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, know the dtype should be a logic of size 1 - :AstNodeMath(fl) - ,m_num(V3Number(fl,1,1)) { dtypeSetLogicBool(); } - + AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, dtype should be a logic of size 1 + : AstNodeMath(fl) + , m_num(V3Number(this, 1, 1)) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Const) - virtual string name() const { return num().ascii(); } // * = Value - virtual const V3Number& num() const { return m_num; } // * = Value + virtual string name() const { return num().ascii(); } // * = Value + virtual const V3Number& num() const { return m_num; } // * = Value uint32_t toUInt() const { return num().toUInt(); } vlsint32_t toSInt() const { return num().toSInt(); } vluint64_t toUQuad() const { return num().toUQuad(); } diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index ad70d2ffa..20bb2b9d3 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -125,9 +125,9 @@ void V3CCtors::evalAsserts() { newp = new AstWordSel(varp->fileline(), newp, new AstConst(varp->fileline(), varp->widthWords()-1)); } - uint64_t value = VL_MASK_Q(storedWidth) & ~VL_MASK_Q(lastWordWidth); - V3Number num (varp->fileline(), storedWidth, value); - newp = new AstAnd(varp->fileline(), newp, + uint64_t value = VL_MASK_Q(storedWidth) & ~VL_MASK_Q(lastWordWidth); + V3Number num (varp, storedWidth, value); + newp = new AstAnd(varp->fileline(), newp, new AstConst(varp->fileline(), num)); AstNodeIf* ifp = new AstIf(varp->fileline(), newp, new AstCStmt(varp->fileline(), diff --git a/src/V3Case.cpp b/src/V3Case.cpp index a68c206fa..bbc6594ca 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -170,10 +170,10 @@ private: if (neverItem(nodep, iconstp)) { // X in casez can't ever be executed } else { - V3Number nummask (itemp->fileline(), iconstp->width()); - nummask.opBitsNonX(iconstp->num()); - uint32_t mask = nummask.toUInt(); - V3Number numval (itemp->fileline(), iconstp->width()); + V3Number nummask (itemp, iconstp->width()); + nummask.opBitsNonX(iconstp->num()); + uint32_t mask = nummask.toUInt(); + V3Number numval (itemp, iconstp->width()); numval.opBitsOne(iconstp->num()); uint32_t val = numval.toUInt(); for (uint32_t i=0; i<(1UL<user3()) tree0p = tree0p->cloneTree(true); if (tree1p && !tree1p->user3()) tree1p = tree1p->cloneTree(true); - // Alternate scheme if we ever do multiple bits at a time: - //V3Number nummask (cexprp->fileline(), cexprp->width(), (1UL<fileline(), cexprp->cloneTree(false), + // Alternate scheme if we ever do multiple bits at a time: + //V3Number nummask (cexprp, cexprp->width(), (1UL<fileline(), cexprp->cloneTree(false), // new AstConst(cexprp->fileline(), nummask)); AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false), msb, 1); @@ -334,9 +334,9 @@ private: condp = new AstAnd(itemp->fileline(), ap, bp); } else if (iconstp && iconstp->num().isFourState() && (nodep->casex() || nodep->casez() || nodep->caseInside())) { - V3Number nummask (itemp->fileline(), iconstp->width()); - nummask.opBitsNonX(iconstp->num()); - V3Number numval (itemp->fileline(), iconstp->width()); + V3Number nummask (itemp, iconstp->width()); + nummask.opBitsNonX(iconstp->num()); + V3Number numval (itemp, iconstp->width()); numval.opBitsOne(iconstp->num()); AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false), new AstConst(itemp->fileline(), nummask)); diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 656f3395f..f24e203f4 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -119,9 +119,9 @@ private: AstNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); // - computeCppWidth(nodep); - V3Number mask (nodep->fileline(), cppWidth(nodep)); - mask.setMask(nodep->widthMin()); + computeCppWidth(nodep); + V3Number mask (nodep, cppWidth(nodep)); + mask.setMask(nodep->widthMin()); AstNode* cleanp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), mask), nodep); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 48e146f18..64e35d35e 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -385,9 +385,9 @@ private: extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp. nodep->rhsp(smallerp); - constp->unlinkFrBack(); - V3Number num (constp->fileline(), subsize); - num.opAssign(constp->num()); + constp->unlinkFrBack(); + V3Number num (constp, subsize); + num.opAssign(constp->num()); nodep->lhsp(new AstConst(constp->fileline(), num)); constp->deleteTree(); VL_DANGLING(constp); if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:"); @@ -597,8 +597,8 @@ private: oldp->deleteTree(); VL_DANGLING(oldp); } void replaceNum(AstNode* nodep, uint32_t val) { - V3Number num (nodep->fileline(), nodep->width(), val); - replaceNum(nodep, num); VL_DANGLING(nodep); + V3Number num (nodep, nodep->width(), val); + replaceNum(nodep, num); VL_DANGLING(nodep); } void replaceNumSigned(AstNodeBiop* nodep, uint32_t val) { // We allow both sides to be constant, as one may have come from parameter propagation, etc. @@ -631,24 +631,24 @@ private: } } void replaceAllOnes(AstNode* nodep) { - V3Number ones (nodep->fileline(), nodep->width(), 0); - ones.setMask(nodep->width()); - replaceNum(nodep, ones); VL_DANGLING(nodep); + V3Number ones (nodep, nodep->width(), 0); + ones.setMask(nodep->width()); + replaceNum(nodep, ones); VL_DANGLING(nodep); } void replaceConst(AstNodeUniop* nodep) { - V3Number num (nodep->fileline(), nodep->width()); + V3Number num (nodep, nodep->width()); nodep->numberOperate(num, VN_CAST(nodep->lhsp(), Const)->num()); - UINFO(4,"UNICONST -> "< "<fileline(), nodep->width()); + V3Number num (nodep, nodep->width()); nodep->numberOperate(num, VN_CAST(nodep->lhsp(), Const)->num(), VN_CAST(nodep->rhsp(), Const)->num()); - UINFO(4,"BICONST -> "< "<fileline(), nodep->width()); + V3Number num (nodep, nodep->width()); nodep->numberOperate(num, VN_CAST(nodep->lhsp(), Const)->num(), VN_CAST(nodep->rhsp(), Const)->num(), VN_CAST(nodep->thsp(), Const)->num()); @@ -915,20 +915,20 @@ private: shift1p->deleteTree(); VL_DANGLING(shift1p); shift2p->deleteTree(); VL_DANGLING(shift2p); AstNode* newp; - V3Number mask1 (nodep->fileline(), nodep->width()); - V3Number ones (nodep->fileline(), nodep->width()); - ones.setMask(nodep->width()); - if (shift1<0) { - mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1)); - } else { - mask1.opShiftL(ones,V3Number(nodep->fileline(),VL_WORDSIZE,shift1)); - } - V3Number mask (nodep->fileline(), nodep->width()); - if (shift2<0) { - mask.opShiftR(mask1,V3Number(nodep->fileline(),VL_WORDSIZE,-shift2)); - } else { - mask.opShiftL(mask1,V3Number(nodep->fileline(),VL_WORDSIZE,shift2)); - } + V3Number mask1 (nodep, nodep->width()); + V3Number ones (nodep, nodep->width()); + ones.setMask(nodep->width()); + if (shift1<0) { + mask1.opShiftR(ones, V3Number(nodep, VL_WORDSIZE, -shift1)); + } else { + mask1.opShiftL(ones, V3Number(nodep, VL_WORDSIZE, shift1)); + } + V3Number mask (nodep, nodep->width()); + if (shift2<0) { + mask.opShiftR(mask1, V3Number(nodep, VL_WORDSIZE, -shift2)); + } else { + mask.opShiftL(mask1, V3Number(nodep, VL_WORDSIZE, shift2)); + } if (newshift<0) { newp = new AstShiftR(nodep->fileline(), ap, new AstConst(nodep->fileline(), -newshift)); @@ -1194,9 +1194,9 @@ private: AstConst* andConstp = VN_CAST(VN_CAST(nodep, And)->lhsp(), Const); AstNode* fromp = VN_CAST(VN_CAST(nodep, And)->rhsp(), ShiftR)->lhsp()->unlinkFrBack(); AstConst* shiftConstp = VN_CAST(VN_CAST(VN_CAST(nodep, And)->rhsp(), ShiftR)->rhsp(), Const); - V3Number val (andConstp->fileline(), andConstp->width()); - val.opShiftL(andConstp->num(), shiftConstp->num()); - AstAnd* newp = new AstAnd(nodep->fileline(), + V3Number val (andConstp, andConstp->width()); + val.opShiftL(andConstp->num(), shiftConstp->num()); + AstAnd* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), val), fromp); // widthMin no longer applicable if different C-expanded width @@ -2002,9 +2002,10 @@ private: if (argp) { AstNode* nextp=argp->nextp(); if (argp && VN_IS(argp, Const)) { // Convert it - string out = VN_CAST(argp, Const)->num().displayed(nodep->fileline(), fmt); - UINFO(9," DispConst: "< "<num().displayed(nodep, fmt); + UINFO(9," DispConst: "< "<unlinkFrBack()->deleteTree(); VL_DANGLING(argp); } diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index d96400160..0dea2804a 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -280,9 +280,9 @@ private: = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, true), new AstConst(nodep->fileline(), - V3Number(nodep->fileline(),1,true))); - nodep->addNextHere(setassignp); - } + V3Number(nodep, 1, true))); + nodep->addNextHere(setassignp); + } if (m_nextDlyp) { // Tell next assigndly it can share the variable m_nextDlyp->user3p(setvscp); } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 2d243685c..64e87fe1b 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -2979,7 +2979,7 @@ class EmitCTrace : EmitCStmts { itemp=VN_CAST(itemp->nextp(), EnumItem)) { AstConst* constp = VN_CAST(itemp->valuep(), Const); if (++nvals > 1) puts(", "); - putbs("\""+constp->num().displayed(nodep->fileline(), "%0b")+"\""); + putbs("\""+constp->num().displayed(nodep, "%0b")+"\""); } puts("};\n"); puts("vcdp->declDTypeEnum("+cvtToStr(enumNum) diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index ef0d8ef58..9e1726b53 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -59,13 +59,13 @@ private: return (nodep->width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1); } V3Number notWideMask(AstNode* nodep) { - return V3Number(nodep->fileline(), VL_WORDSIZE, ~VL_MASK_I(nodep->widthMin())); + return V3Number(nodep, VL_WORDSIZE, ~VL_MASK_I(nodep->widthMin())); } V3Number wordMask(AstNode* nodep) { - if (nodep->isWide()) { - return V3Number(nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin())); - } else { - V3Number mask (nodep->fileline(), longOrQuadWidth(nodep)); + if (nodep->isWide()) { + return V3Number(nodep, VL_WORDSIZE, VL_MASK_I(nodep->widthMin())); + } else { + V3Number mask (nodep, longOrQuadWidth(nodep)); mask.setMask(nodep->widthMin()); return mask; } @@ -222,8 +222,8 @@ private: if (rhsp->num().isFourState()) { rhsp->v3error("Unsupported: 4-state numbers in this context"); } - for (int w=0; wwidthWords(); w++) { - V3Number num (nodep->fileline(), VL_WORDSIZE, rhsp->num().dataWord(w)); + for (int w=0; wwidthWords(); w++) { + V3Number num (nodep, VL_WORDSIZE, rhsp->num().dataWord(w)); addWordAssign(nodep, w, new AstConst(nodep->fileline(), num)); } return true; @@ -368,9 +368,9 @@ private: newSelBitBit(nodep->lsbp()), nodep->width()); // If > 1 bit, we might be crossing the word boundary - AstNode* midp=NULL; - V3Number zero (nodep->fileline(), longOrQuadWidth(nodep)); - if (nodep->widthConst() > 1) { + AstNode* midp=NULL; + V3Number zero (nodep, longOrQuadWidth(nodep)); + if (nodep->widthConst() > 1) { AstNode* midwordp = // SEL(from,[1+wordnum]) new AstWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), @@ -475,9 +475,9 @@ private: lowwordp, newSelBitBit(rhsp->lsbp()), VL_WORDSIZE); - // Upper bits - V3Number zero (nodep->fileline(), VL_WORDSIZE, 0); - AstNode* midwordp = // SEL(from,[1+wordnum]) + // Upper bits + V3Number zero (nodep, VL_WORDSIZE, 0); + AstNode* midwordp = // SEL(from,[1+wordnum]) new AstWordSel(rhsp->fromp()->fileline(), rhsp->fromp()->cloneTree(true), newSelBitWord(rhsp->lsbp(), w+1)); @@ -517,9 +517,9 @@ private: AstNode* destp = lhsp->fromp()->unlinkFrBack(); int lsb = lhsp->lsbConst(); int msb = lhsp->msbConst(); - V3Number maskset (nodep->fileline(), destp->widthMin()); - for (int bit=lsb; bit<(msb+1); bit++) maskset.setBit(bit,1); - V3Number maskold (nodep->fileline(), destp->widthMin()); maskold.opNot(maskset); + V3Number maskset (nodep, destp->widthMin()); + for (int bit=lsb; bit<(msb+1); bit++) maskset.setBit(bit, 1); + V3Number maskold (nodep, destp->widthMin()); maskold.opNot(maskset); if (destwide) { UINFO(8," ASSIGNSEL(const,wide) "<widthWords(); w++) { @@ -624,7 +624,7 @@ private: AstNode* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); - V3Number maskwidth (nodep->fileline(), destp->widthMin()); + V3Number maskwidth (nodep, destp->widthMin()); for (int bit=0; bit < lhsp->widthConst(); bit++) maskwidth.setBit(bit,1); if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); @@ -811,8 +811,8 @@ private: replaceWithDelete(nodep,newp); VL_DANGLING(nodep); } else { UINFO(8," REDOR->EQ "<lhsp()->unlinkFrBack(); - V3Number zero (nodep->fileline(), longOrQuadWidth(nodep)); + AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); + V3Number zero (nodep, longOrQuadWidth(nodep)); AstNode* newp = new AstNeq(nodep->fileline(), new AstConst(nodep->fileline(), zero), lhsp); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 8fc822c3c..6bf71a797 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -609,8 +609,7 @@ class LinkDotFindVisitor : public AstNVisitor { if (literal[0] == '"') { // This is a string string v = literal.substr(1, literal.find('"', 1) - 1); - V3Number n(V3Number::VerilogStringLiteral(), fl, v); - return new AstConst(fl,n); + return new AstConst(fl, AstConst::VerilogStringLiteral(), v); } else if ((literal.find('.') != string::npos) || (literal.find('e') != string::npos)) { // This may be a real @@ -629,12 +628,10 @@ class LinkDotFindVisitor : public AstNVisitor { // the Verilog literal parser. char* endp; int v = strtol(literal.c_str(), &endp, 0); - if ((v != 0) && (endp[0] == 0)) { // C literal - V3Number n(fl, 32, v); - return new AstConst(fl, n); - } else { // Try a Verilog literal (fatals if not) - V3Number n(fl, literal.c_str()); - return new AstConst(fl, n); + if ((v != 0) && (endp[0] == 0)) { // C literal + return new AstConst(fl, AstConst::WidthedValue(), 32, v); + } else { // Try a Verilog literal (fatals if not) + return new AstConst(fl, AstConst::StringToParse(), literal.c_str()); } } return NULL; diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index b96e5e2ac..5c1d86f0f 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -141,9 +141,9 @@ private: countp); AstNode* decp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false), - new AstConst(nodep->fileline(), 1))); - V3Number zero (nodep->fileline(), 32, 0); zero.isSigned(true); - AstNode* zerosp = new AstConst(nodep->fileline(), zero); + new AstConst(nodep->fileline(), 1))); + V3Number zero (nodep, 32, 0); zero.isSigned(true); + AstNode* zerosp = new AstConst(nodep->fileline(), zero); AstNode* condp = new AstGtS(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false), zerosp); AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext(); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 8c06f473a..2661db490 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -23,6 +23,7 @@ #include "V3Global.h" #include "V3Number.h" +#include "V3Ast.h" #include #include @@ -31,15 +32,24 @@ #define MAX_SPRINTF_DOUBLE_SIZE 100 // Maximum characters with a sprintf %e/%f/%g (probably < 30) -//###################################################################### +//====================================================================== +// Errors + +void V3Number::v3errorEnd(std::ostringstream& str) { + std::ostringstream nsstr; + nsstr<v3errorEnd(nsstr); +} + +//====================================================================== // Read class functions // CREATION -V3Number::V3Number(VerilogStringLiteral, FileLine* fileline, const string& str) { +V3Number::V3Number(VerilogStringLiteral, AstNode* nodep, const string& str) { // Create a number using a verilog string as the value, thus 8 bits per character. // cppcheck bug - doesn't see init() resets these // cppcheck: Member variable 'm_sized/m_width' is not initialized in the constructor - init(fileline, str.length()*8); + init(nodep, str.length()*8); m_fromString = true; for (unsigned pos=0; posopAdd(product,addend); - if (product.bitsValue(width(), 4)) { // Overflowed - m_fileline->v3error("Too many digits for "<v3error("As that number was unsized ('d...) it is limited to 32 bits (IEEE 2017 5.7.1)"); - } - } + V3Number product (this, width()+4); // +4 for overflow detection + V3Number ten (this, width()+4, 10); + V3Number addend (this, width(), (*cp-'0')); + product.opMul(*this,ten); + this->opAdd(product, addend); + if (product.bitsValue(width(), 4)) { // Overflowed + v3error("Too many digits for "<v3error("Illegal character in decimal constant: "<<*cp); - break; - } - } - } - obit = width(); - if ((got_01+got_x+got_z)>1) m_fileline->v3error("Mixing X/Z/? with digits not legal in decimal constant: "< 1) { + v3error("Mixing X/Z/? with digits not legal in decimal constant: "<= value_startp; cp--) { - if (*cp!='_' && *cp!='0' && obit>=width()) { - m_fileline->v3error("Too many digits for "<=width()) { + v3error("Too many digits for "<v3error("Illegal character in binary constant: "<<*cp); - } - break; - } + v3error("Illegal character in binary constant: "<<*cp); + } + break; + } case 'o': case 'c': { @@ -213,10 +227,10 @@ V3Number::V3Number(FileLine* fileline, const char* sourcep) { setBit(obit++, 'x'); setBit(obit++, 'x'); setBit(obit++, 'x'); break; case '_': break; default: - m_fileline->v3error("Illegal character in octal constant"); - } - break; - } + v3error("Illegal character in octal constant"); + } + break; + } case 'h': { switch(tolower(*cp)) { @@ -242,14 +256,14 @@ V3Number::V3Number(FileLine* fileline, const char* sourcep) { setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); break; case '_': break; default: - m_fileline->v3error("Illegal character in hex constant: "<<*cp); - } - break; - } - default: - m_fileline->v3error("Illegal base character: "<fileline(); +} + //====================================================================== // Global @@ -302,7 +321,7 @@ V3Number& V3Number::setLongS(vlsint32_t value) { } V3Number& V3Number::setDouble(double value) { if (VL_UNLIKELY(width()!=64)) { - m_fileline->v3fatalSrc("Real operation on wrong sized number"); + v3fatalSrc("Real operation on wrong sized number"); } m_double = true; union { double d; uint32_t u[2]; } u; @@ -400,12 +419,12 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { if (binary) { out<<"b"; - out<fileline(), vformat); +} string V3Number::displayed(FileLine*fl, const string& vformat) const { string::const_iterator pos = vformat.begin(); @@ -504,9 +526,9 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const { return str; } case 'c': { - if (this->width()>8) fl->v3warn(WIDTH,"$display-like format of %c format of > 8 bit value"); - unsigned int v = bitsValue(0, 8); - char strc[2]; strc[0] = v&0xff; strc[1] = '\0'; + if (width()>8) fl->v3warn(WIDTH, "$display-like format of %c format of > 8 bit value"); + unsigned int v = bitsValue(0, 8); + char strc[2]; strc[0] = v&0xff; strc[1] = '\0'; str = strc; return str; } @@ -603,8 +625,8 @@ string V3Number::displayed(FileLine*fl, const string& vformat) const { return toString(); } default: - fl->v3fatalSrc("Unknown $display-like format code for number: %"<v3fatalSrc("Unknown $display-like format code for number: %"<v3fatalSrc("Real conversion on non-real number"); + v3fatalSrc("Real conversion on non-real number"); } if (VL_UNLIKELY(width()!=64)) { - m_fileline->v3fatalSrc("Real operation on wrong sized number"); + v3fatalSrc("Real operation on wrong sized number"); } union { double d; uint32_t u[2]; } u; u.u[0] = m_value[0]; u.u[1] = m_value[1]; @@ -1020,7 +1042,7 @@ V3Number& V3Number::opConcat(const V3Number& lhs, const V3Number& rhs) { setZero(); // See also error in V3Width if (!lhs.sized() || !rhs.sized()) { - m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); + v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } int obit = 0; for(int bit=0; bitv3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); + if (!lhs.sized()) { + v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); + } return opRepl(lhs, rhs.toUInt()); } V3Number& V3Number::opRepl(const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate // i op repl, L(i)*value(rhs) bit return setZero(); - if (rhsval>8192) m_fileline->v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "< 8192) { + v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "<v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); + v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } // Slice size should never exceed the lhs width int ssize = std::min(rhs.toUInt(), static_cast(lhs.width())); @@ -1351,9 +1377,9 @@ V3Number& V3Number::opAbsS(const V3Number& lhs) { V3Number& V3Number::opNegate(const V3Number& lhs) { // op i, L(lhs) bit return if (lhs.isFourState()) return setAllBitsX(); - V3Number notlhs (lhs.m_fileline, width()); + V3Number notlhs (&lhs, width()); notlhs.opNot(lhs); - V3Number one (lhs.m_fileline, width(), 1); + V3Number one (&lhs, width(), 1); opAdd(notlhs,one); return *this; } @@ -1375,7 +1401,7 @@ V3Number& V3Number::opAdd(const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opSub(const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); - V3Number negrhs (rhs.m_fileline, rhs.width()); + V3Number negrhs (&rhs, rhs.width()); negrhs.opNegate(rhs); return opAdd(lhs, negrhs); } @@ -1611,14 +1637,14 @@ V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign, if (lhs.isEqZero()) return setZero(); setZero(); m_value[0] = 1; - V3Number power (lhs.m_fileline, width()); power.opAssign(lhs); + V3Number power (&lhs, width()); power.opAssign(lhs); for (int bit=0; bit0) { // power = power*power - V3Number lastPower (lhs.m_fileline, width()); lastPower.opAssign(power); - power.opMul(lastPower, lastPower); - } - if (rhs.bitIs1(bit)) { // out *= power - V3Number lastOut (lhs.m_fileline, width()); lastOut.opAssign(*this); + if (bit>0) { // power = power*power + V3Number lastPower (&lhs, width()); lastPower.opAssign(power); + power.opMul(lastPower, lastPower); + } + if (rhs.bitIs1(bit)) { // out *= power + V3Number lastOut (&lhs, width()); lastOut.opAssign(*this); this->opMul(lastOut, power); //UINFO(0, "pow "<opAssign(if0s); } @@ -1767,7 +1793,7 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) { V3Number& V3Number::opRealToBits(const V3Number& lhs) { // Conveniently our internal format is identical so we can copy bits... if (lhs.width()!=64 || this->width()!=64) { - m_fileline->v3fatalSrc("Real operation on wrong sized number"); + v3fatalSrc("Real operation on wrong sized number"); } opAssign(lhs); m_double = false; @@ -1776,7 +1802,7 @@ V3Number& V3Number::opRealToBits(const V3Number& lhs) { V3Number& V3Number::opBitsToRealD(const V3Number& lhs) { // Conveniently our internal format is identical so we can copy bits... if (lhs.width()!=64 || this->width()!=64) { - m_fileline->v3fatalSrc("Real operation on wrong sized number"); + v3fatalSrc("Real operation on wrong sized number"); } opAssign(lhs); m_double = true; diff --git a/src/V3Number.h b/src/V3Number.h index 909297c5c..d8fa51332 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -25,12 +25,13 @@ #include "verilatedos.h" #include "V3Error.h" -#include "V3FileLine.h" #include //============================================================================ +class AstNode; + class V3Number { // Large 4-state number handling int m_width; // Width as specified/calculated. @@ -39,8 +40,8 @@ class V3Number { bool m_double:1; // True if double real value bool m_isString:1; // True if string bool m_fromString:1; // True if from string literal - bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width - FileLine* m_fileline; + bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width + FileLine* m_fileline; std::vector m_value; // The Value, with bit 0 being in bit 0 of this vector (unless X/Z) std::vector m_valueX; // Each bit is true if it's X or Z, 10=z, 11=x string m_stringVal; // If isString, the value of the string @@ -49,8 +50,8 @@ class V3Number { V3Number& setString(const string& str) { m_isString=true; m_stringVal=str; return *this; } void opCleanThis(bool warnOnTruncation = false); public: - FileLine* fileline() const { return m_fileline; } - void fileline(FileLine* fl) { m_fileline=fl; } + void nodep(AstNode* nodep) { setNames(nodep); } + FileLine* fileline() const { return m_fileline; }; V3Number& setZero(); V3Number& setQuad(vluint64_t value); V3Number& setLong(uint32_t value); @@ -131,18 +132,34 @@ private: public: // CONSTRUCTORS - explicit V3Number(FileLine* fileline) { init(fileline, 1); } - V3Number(FileLine* fileline, int width) { init(fileline, width); } // 0=unsized - V3Number(FileLine* fileline, int width, uint32_t value) { init(fileline, width); m_value[0]=value; opCleanThis(); } - V3Number(FileLine* fileline, const char* sourcep); // Create from a verilog 32'hxxxx number. + explicit V3Number(AstNode* nodep) { init(nodep, 1); } + V3Number(AstNode* nodep, int width) { init(nodep, width); } // 0=unsized + V3Number(AstNode* nodep, int width, uint32_t value) { + init(nodep, width); m_value[0]=value; opCleanThis(); + } + // Create from a verilog 32'hxxxx number. + V3Number(AstNode* nodep, const char* sourcep) { V3NumberCreate(nodep, sourcep, NULL); } + class FileLined {}; // Fileline based errors, for parsing only, otherwise pass nodep + V3Number(FileLined, FileLine* fl, const char* sourcep) { V3NumberCreate(NULL, sourcep, fl); } class VerilogStringLiteral {}; // For creator type-overload selection - V3Number(VerilogStringLiteral, FileLine* fileline, const string& str); + V3Number(VerilogStringLiteral, AstNode* nodep, const string& str); class String {}; - V3Number(String, FileLine* fileline, const string& value) { init(fileline, 0); setString(value); } + V3Number(String, AstNode* nodep, const string& value) { init(nodep, 0); setString(value); } + V3Number(const V3Number* nump, int width = 1) { + init(NULL, width); + m_fileline = nump->fileline(); + } + V3Number(const V3Number* nump, int width, uint32_t value) { + init(NULL, width); + m_value[0]=value; + opCleanThis(); + m_fileline = nump->fileline(); + } private: - void init(FileLine* fileline, int swidth) { - m_fileline = fileline; + void V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl); + void init(AstNode* nodep, int swidth) { + setNames(nodep); m_signed = false; m_double = false; m_isString = false; @@ -151,7 +168,13 @@ private: width(swidth); for (int i=0; iisDefault()) { for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) { if (const AstConst* ccondp = VN_CAST(ep, Const)) { - V3Number match (nodep->fileline(), 1); - match.opEq(ccondp->num(), exprp->num()); - if (!keepp && match.isNeqZero()) { + V3Number match (nodep, 1); + match.opEq(ccondp->num(), exprp->num()); + if (!keepp && match.isNeqZero()) { keepp = itemp->bodysp(); } } else { @@ -575,11 +575,13 @@ void ParamVisitor::visitCell(AstCell* nodep) { } else { 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 "<name()<<" of "<prettyName()); - pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0))); - } else if (origp && exprp->sameTree(origp)) { + if (!exprp) { + //if (debug()) pinp->dumpTree(cout,"error:"); + pinp->v3error("Can't convert defparam value to constant: Param " + <name()<<" of "<prettyName()); + pinp->exprp()->replaceWith( + new AstConst(pinp->fileline(), V3Number(pinp, modvarp->width(), 0))); + } else if (origp && exprp->sameTree(origp)) { // Setting parameter to its default value. Just ignore it. // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 4cbd0ed44..648801749 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -183,9 +183,9 @@ public: return strp; } V3Number* newNumber(FileLine* fl, const char* text) { - V3Number* nump = new V3Number(fl, text); - m_numberps.push_back(nump); - return nump; + V3Number* nump = new V3Number(V3Number::FileLined(), fl, text); + m_numberps.push_back(nump); + return nump; } // Return next token, for bison, since bison isn't class based, use a global THIS diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index fb76c9fd6..754ea434f 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -284,12 +284,12 @@ private: m1value), nodep->width())); } else { - V3Number zeronum (nodep->fileline(), nodep->width(), 0); - constzerop = new AstConst(nodep->fileline(), zeronum); - } + V3Number zeronum (nodep, nodep->width(), 0); + constzerop = new AstConst(nodep->fileline(), zeronum); + } constzerop->dtypeFrom(nodep); // unsigned - V3Number widthnum (nodep->fileline(), nodep->rhsp()->widthMin(), m1value); + V3Number widthnum (nodep, nodep->rhsp()->widthMin(), m1value); AstNode* constwidthp = new AstConst(nodep->fileline(), widthnum); constwidthp->dtypeFrom(nodep->rhsp()); // unsigned AstCond* newp = diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 0445a519b..51658b9b5 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -127,9 +127,9 @@ private: 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; - V3Number fieldNum = V3Number(nump->fileline(), width); - fieldNum.opSel(*nump, msb, lsb); + int msb = lsb + width - 1; + V3Number fieldNum = V3Number(nump, width); + fieldNum.opSel(*nump, msb, lsb); out<name()<<": "; if (AstNodeDType * childTypep = itemp->subDTypep()) { out<width(); int lsb = width * element; - int msb = lsb + width - 1; - V3Number fieldNum = V3Number(nump->fileline(), width); - fieldNum.opSel(*nump, msb, lsb); + int msb = lsb + width - 1; + V3Number fieldNum = V3Number(nump, width); + fieldNum.opSel(*nump, msb, lsb); int arrayElem = arrayp->lsb() + element; out<width()<width(nodep->width()); - nump->fileline(nodep->fileline()); - nump->setLong(value); // We do support more than 32 bit numbers, just valuep=0 in that case - } else { - //UINFO(7,"Num New "<width()<fileline(), nodep->width(), value); + nump->nodep(nodep); + nump->setLong(value); + } else { + //UINFO(7,"Num New "<width()<width(), value); m_numAllps.push_back(nump); } nump->isDouble(nodep->isDouble()); @@ -520,9 +520,9 @@ private: } else { iterate(nodep->lhsp()); if (optimizable()) { - if (fetchNumber(nodep->lhsp())->isEqZero()) { - newNumber(nodep, V3Number(nodep->fileline(), 1, 1)); // a one - } else { + if (fetchNumber(nodep->lhsp())->isEqZero()) { + newNumber(nodep, V3Number(nodep, 1, 1)); // a one + } else { iterate(nodep->rhsp()); newNumber(nodep, *fetchNumber(nodep->rhsp())); } @@ -552,19 +552,21 @@ private: void handleAssignSel(AstNodeAssign* nodep, AstSel* selp) { AstVarRef* varrefp = NULL; - V3Number lsb = V3Number(nodep->fileline()); + V3Number lsb = V3Number(nodep); iterateAndNextNull(nodep->rhsp()); // Value to assign - handleAssignSelRecurse(nodep, selp, varrefp/*ref*/, lsb/*ref*/, 0); - if (!m_checkOnly && optimizable()) { - if (!varrefp) nodep->v3fatalSrc("Indicated optimizable, but no variable found on RHS of select"); - AstNode* vscp = varOrScope(varrefp); - V3Number outnum = V3Number(nodep->fileline()); - if (V3Number* vscpnump = fetchOutNumberNull(vscp)) { - outnum = *vscpnump; - } else if (V3Number* vscpnump = fetchNumberNull(vscp)) { - outnum = *vscpnump; - } else { // Assignment to unassigned variable, all bits are X or 0 - outnum = V3Number(nodep->fileline(), varrefp->varp()->widthMin()); + handleAssignSelRecurse(nodep, selp, varrefp/*ref*/, lsb/*ref*/, 0); + if (!m_checkOnly && optimizable()) { + if (!varrefp) { + nodep->v3fatalSrc("Indicated optimizable, but no variable found on RHS of select"); + } + AstNode* vscp = varOrScope(varrefp); + V3Number outnum = V3Number(nodep); + if (V3Number* vscpnump = fetchOutNumberNull(vscp)) { + outnum = *vscpnump; + } else if (V3Number* vscpnump = fetchNumberNull(vscp)) { + outnum = *vscpnump; + } else { // Assignment to unassigned variable, all bits are X or 0 + outnum = V3Number(nodep, varrefp->varp()->widthMin()); if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) { outnum.setAllBits0(); } else { @@ -588,9 +590,9 @@ private: lsbRef = *fetchNumber(selp->lsbp()); return; // And presumably still optimizable() } else if (AstSel* subselp = VN_CAST(selp->lhsp(), Sel)) { - V3Number sublsb = V3Number(nodep->fileline()); - handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb/*ref*/, depth+1); - if (optimizable()) { + V3Number sublsb = V3Number(nodep); + handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb/*ref*/, depth+1); + if (optimizable()) { lsbRef = sublsb; lsbRef.opAdd(sublsb, *fetchNumber(selp->lsbp())); } @@ -648,9 +650,9 @@ private: for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) { if (hit) break; iterateAndNextNull(ep); - if (optimizable()) { - V3Number match (nodep->fileline(), 1); - match.opEq(*fetchNumber(nodep->exprp()), *fetchNumber(ep)); + if (optimizable()) { + V3Number match (nodep, 1); + match.opEq(*fetchNumber(nodep->exprp()), *fetchNumber(ep)); if (match.isNeqZero()) { iterateAndNextNull(itemp->bodysp()); hit = true; @@ -853,9 +855,9 @@ private: clearOptimizable(nodep, "Argument for $display like statement is not constant"); break; } - string format = string("%") + pos[0]; - result += nump->displayed(nodep->fileline(), format); - } else { + string format = string("%") + pos[0]; + result += nump->displayed(nodep, format); + } else { switch (tolower(pos[0])) { case '%': result += "%"; @@ -872,9 +874,9 @@ private: } } - V3Number* resultNump = new V3Number(V3Number::String(), nodep->fileline(), result); - setNumber(nodep, resultNump); - m_stringNumbersp.push_back(resultNump); + V3Number* resultNump = new V3Number(V3Number::String(), nodep, result); + setNumber(nodep, resultNump); + m_stringNumbersp.push_back(resultNump); } } diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 873be188a..61d4d09b7 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -300,7 +300,7 @@ private: AstVarScope* invscp = *it; // LSB is first variable, so extract it that way simvis.newNumber(invscp, - V3Number(invscp->fileline(), invscp->width(), + V3Number(invscp, invscp->width(), VL_MASK_I(invscp->width()) & (inValue>>shift))); shift += invscp->width(); // We're just using32 bit arithmetic, because there's no way the input table can be 2^32 bytes! @@ -316,8 +316,8 @@ private: } // If a output changed, add it to table - int outnum = 0; - V3Number outputChgMask (nodep->fileline(), m_outVarps.size(), 0); + int outnum = 0; + V3Number outputChgMask (nodep, m_outVarps.size(), 0); for (std::deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { AstVarScope* outvscp = *it; V3Number* outnump = simvis.fetchOutNumberNull(outvscp); @@ -327,9 +327,9 @@ private: m_outNotSet[outnum] = true; // Value in table is arbitrary, but we need something setp = new AstConst(outvscp->fileline(), - V3Number(outvscp->fileline(), outvscp->width(), 0)); - } else { - UINFO(8," Output "<name()<<" = "<<*outnump<width(), 0)); + } else { + UINFO(8," Output "<name()<<" = "<<*outnump<fileline(), m_outVarps.size(), 0); - outputChgMask.setBit(outnum,1); + if (m_outNotSet[outnum]) { + V3Number outputChgMask (nodep, m_outVarps.size(), 0); + outputChgMask.setBit(outnum, 1); outsetp = new AstIf(nodep->fileline(), new AstAnd(nodep->fileline(), new AstArraySel(nodep->fileline(), diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 7e5c0b5a2..0d5305541 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -511,7 +511,8 @@ private: } } else { AstNode* clrp = new AstAssign(fl, new AstVarRef(fl, m_activityVscp, true), - new AstConst(fl, V3Number(fl, m_activityVscp->width(), 0))); + new AstConst(fl, AstConst::WidthedValue(), + m_activityVscp->width(), 0)); m_fullFuncp->addFinalsp(clrp->cloneTree(true)); m_chgFuncp->addFinalsp(clrp); } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 400b7dc0c..556cb7f4a 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -365,9 +365,9 @@ class TristateVisitor : public TristateBaseVisitor { AstNode* getEnp(AstNode* nodep) { // checks if user1p() is null, and if so, adds a constant output // enable driver of all 1's. Otherwise returns the user1p() data. - if (!nodep->user1p()) { - V3Number num(nodep->fileline(), nodep->width()); - num.setAllBits1(); + if (!nodep->user1p()) { + V3Number num(nodep, nodep->width()); + num.setAllBits1(); AstNode* enp = new AstConst(nodep->fileline(), num); nodep->user1p(enp); } @@ -479,9 +479,9 @@ class TristateVisitor : public TristateBaseVisitor { VarMap::iterator it = m_lhsmap.find(varp); if (it == m_lhsmap.end()) { // set output enable to always be off on this assign statement so that this var is floating - UINFO(8," Adding driver to var "<fileline(), varp->width()); - zeros.setAllBits0(); + UINFO(8," Adding driver to var "<width()); + zeros.setAllBits0(); AstConst* constp = new AstConst(varp->fileline(), zeros); AstVarRef* varrefp = new AstVarRef(varp->fileline(), varp, true); AstNode* newp = new AstAssignW(varp->fileline(), varrefp, constp); @@ -592,13 +592,13 @@ class TristateVisitor : public TristateBaseVisitor { : new AstAnd(refp->fileline(), tmp, undrivenp)); } if (!undrivenp) { // No drivers on the bus - V3Number ones(invarp->fileline(), lhsp->width()); ones.setAllBits1(); - undrivenp = new AstConst(invarp->fileline(), ones); - } - if (!outvarp) { - // This is the final resolution of the tristate, so we apply - // the pull direction to any undriven pins. - V3Number pull(invarp->fileline(), lhsp->width()); + V3Number ones(invarp, lhsp->width()); ones.setAllBits1(); + undrivenp = new AstConst(invarp->fileline(), ones); + } + if (!outvarp) { + // This is the final resolution of the tristate, so we apply + // the pull direction to any undriven pins. + V3Number pull(invarp, lhsp->width()); AstPull* pullp = static_cast(lhsp->user3p()); if (pullp && pullp->direction() == 1) { pull.setAllBits1(); @@ -654,9 +654,12 @@ class TristateVisitor : public TristateBaseVisitor { else if (m_tgraph.isTristate(nodep)) { m_tgraph.didProcess(nodep); FileLine* fl = nodep->fileline(); - V3Number numz (fl,nodep->width()); numz.opBitsZ(nodep->num()); //Z->1, else 0 - V3Number numz0(fl,nodep->width()); numz0.opNot(numz); // Z->0, else 1 - V3Number num1 (fl,nodep->width()); num1.opAnd(nodep->num(),numz0); // 01X->01X, Z->0 + V3Number numz (nodep, nodep->width()); + numz.opBitsZ(nodep->num()); // Z->1, else 0 + V3Number numz0(nodep, nodep->width()); + numz0.opNot(numz); // Z->0, else 1 + V3Number num1 (nodep, nodep->width()); + num1.opAnd(nodep->num(), numz0); // 01X->01X, Z->0 AstConst* newconstp = new AstConst(fl, num1); AstConst* enp = new AstConst(fl, numz0); nodep->replaceWith(newconstp); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 7e02a8456..085c89205 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -185,7 +185,7 @@ private: // If we got ==1'bx it can never be true (but 1'bx==1'bx can be!) 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)); + V3Number num(nodep, 1, (VN_IS(nodep, EqCase) ? 0:1)); newp = new AstConst(nodep->fileline(), num); lhsp->deleteTree(); VL_DANGLING(lhsp); rhsp->deleteTree(); VL_DANGLING(rhsp); @@ -218,9 +218,9 @@ private: newp = new AstEq(nodep->fileline(), lhsp, rhsp); } else { // X or Z's become mask, ala case statements. - V3Number nummask (rhsp->fileline(), rhsp->width()); + V3Number nummask (rhsp, rhsp->width()); nummask.opBitsNonX(VN_CAST(rhsp, Const)->num()); - V3Number numval (rhsp->fileline(), rhsp->width()); + V3Number numval (rhsp, rhsp->width()); numval.opBitsOne(VN_CAST(rhsp, Const)->num()); AstNode* and1p = new AstAnd(nodep->fileline(), lhsp, new AstConst(nodep->fileline(), nummask)); @@ -252,8 +252,8 @@ private: virtual void visit(AstIsUnknown* nodep) { iterateChildren(nodep); // Ahh, we're two state, so this is easy - UINFO(4," ISUNKNOWN->0 "<fileline(), 1, 0); + UINFO(4," ISUNKNOWN->0 "<fileline(), zero); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); @@ -266,13 +266,13 @@ private: // CONST(num) -> VARREF(newvarp) // -> VAR(newvarp) // -> INITIAL(VARREF(newvarp, OR(num_No_Xs,AND(random,num_1s_Where_X)) - V3Number numb1 (nodep->fileline(), nodep->width()); - numb1.opBitsOne(nodep->num()); - V3Number numbx (nodep->fileline(), nodep->width()); - numbx.opBitsXZ(nodep->num()); - if (v3Global.opt.xAssign()!="unique") { - // All X bits just become 0; fastest simulation, but not nice - V3Number numnew (nodep->fileline(), numb1.width()); + V3Number numb1 (nodep, nodep->width()); + numb1.opBitsOne(nodep->num()); + V3Number numbx (nodep, nodep->width()); + numbx.opBitsXZ(nodep->num()); + if (v3Global.opt.xAssign()!="unique") { + // All X bits just become 0; fastest simulation, but not nice + V3Number numnew (nodep, numb1.width()); if (v3Global.opt.xAssign()=="1") { numnew.opOr(numb1, numbx); } else { @@ -334,8 +334,8 @@ private: // Find range of dtype we are selecting from // Similar code in V3Const::warnSelect int maxmsb = nodep->fromp()->dtypep()->width()-1; - if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); - V3Number maxmsbnum (nodep->fileline(), nodep->lsbp()->width(), maxmsb); + if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); + V3Number maxmsbnum (nodep, nodep->lsbp()->width(), maxmsb); // If (maxmsb >= selected), we're in bound AstNode* condp = new AstGte(nodep->fileline(), @@ -351,9 +351,9 @@ private: else if (!lvalue) { // SEL(...) -> COND(LTE(bit<=maxmsb), ARRAYSEL(...), {width{1'bx}}) AstNRelinker replaceHandle; - nodep->unlinkFrBack(&replaceHandle); - V3Number xnum (nodep->fileline(), nodep->width()); - xnum.setAllBitsX(); + nodep->unlinkFrBack(&replaceHandle); + V3Number xnum (nodep, nodep->width()); + xnum.setAllBitsX(); AstNode* newp = new AstCondBound(nodep->fileline(), condp, nodep, @@ -396,8 +396,8 @@ private: } else { nodep->v3error("Select from non-array "<prettyTypeName()); } - if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: "); - V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1); + if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: "); + V3Number widthnum (nodep, nodep->bitp()->width(), declElements-1); // See if the condition is constant true AstNode* condp = new AstGte(nodep->fileline(), @@ -414,9 +414,9 @@ private: // ARRAYSEL(...) -> COND(LT(bitunlinkFrBack(&replaceHandle); - V3Number xnum (nodep->fileline(), nodep->width()); - if (nodep->isString()) { - xnum = V3Number(V3Number::String(), nodep->fileline(), ""); + V3Number xnum (nodep, nodep->width()); + if (nodep->isString()) { + xnum = V3Number(V3Number::String(), nodep, ""); } else { xnum.setAllBitsX(); } @@ -432,8 +432,8 @@ private: else if (!lvalue) { // Mid-multidimension read, just use zero // ARRAYSEL(...) -> ARRAYSEL(COND(LT(bitbitp()->unlinkFrBack(&replaceHandle); - V3Number zeronum (nodep->fileline(), bitp->width(), 0); + AstNode* bitp = nodep->bitp()->unlinkFrBack(&replaceHandle); + V3Number zeronum (nodep, bitp->width(), 0); AstNode* newp = new AstCondBound(bitp->fileline(), condp, bitp, new AstConst(bitp->fileline(), zeronum)); diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index f7e9be2cc..dfc3a2ead 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -231,12 +231,12 @@ private: bool countLoops(AstAssign *initp, AstNode *condp, AstNode *incp, int max, int &outLoopsr) { outLoopsr = 0; - V3Number loopValue = V3Number(initp->fileline()); - if (!simulateTree(initp->rhsp(), NULL, initp, loopValue)) { - return false; - } - while (1) { - V3Number res = V3Number(initp->fileline()); + V3Number loopValue = V3Number(initp); + if (!simulateTree(initp->rhsp(), NULL, initp, loopValue)) { + return false; + } + while (1) { + V3Number res = V3Number(initp); if (!simulateTree(condp, &loopValue, NULL, res)) { return false; } @@ -248,10 +248,10 @@ private: // Run inc AstAssign* incpass = VN_CAST(incp, Assign); - V3Number newLoopValue = V3Number(initp->fileline()); - if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { - return false; - } + V3Number newLoopValue = V3Number(initp); + if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { + return false; + } loopValue.opAssign(newLoopValue); if (outLoopsr > max) { return false; @@ -265,9 +265,9 @@ private: AstNode* condp, AstNode* precondsp, AstNode* incp, AstNode* bodysp) { - UINFO(9, "forUnroller "<fileline()); - if (!simulateTree(initp->rhsp(), NULL, initp, loopValue)) { + UINFO(9, "forUnroller "<rhsp(), NULL, initp, loopValue)) { return false; } AstNode* stmtsp = NULL; @@ -295,9 +295,9 @@ private: if (stmtsp) { int times = 0; while (1) { - UINFO(8," Looping "<fileline()); - if (!simulateTree(condp, &loopValue, NULL, res)) { + UINFO(8," Looping "<v3error("Loop unrolling failed."); return false; } @@ -337,9 +337,9 @@ private: // loopValue += valInc AstAssign *incpass = VN_CAST(incp, Assign); - V3Number newLoopValue = V3Number(nodep->fileline()); - if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { - nodep->v3error("Loop unrolling failed"); + V3Number newLoopValue = V3Number(nodep); + if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { + nodep->v3error("Loop unrolling failed"); return false; } loopValue.opAssign(newLoopValue); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 4301539c2..2fafc6af8 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1321,8 +1321,8 @@ private: // Assign widths userIterateAndNext(nodep->itemsp(), WidthVP(nodep->dtypep(),BOTH).p()); // Assign missing values - V3Number num (nodep->fileline(), nodep->width(), 0); - V3Number one (nodep->fileline(), nodep->width(), 1); + V3Number num (nodep, nodep->width(), 0); + V3Number one (nodep, nodep->width(), 1); std::map inits; for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=VN_CAST(itemp->nextp(), EnumItem)) { if (itemp->valuep()) { @@ -2923,9 +2923,9 @@ private: if (nodep->rhsp()->width()>32) { 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()); - AstNode* shiftp = nodep->rhsp(); + // If (number)<<96'h1, then make it into (number)<<32'h1 + V3Number num (shiftp, 32, 0); num.opAssign(shiftp->num()); + AstNode* shiftp = nodep->rhsp(); nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); shiftp->deleteTree(); VL_DANGLING(shiftp); } @@ -3082,9 +3082,9 @@ private: AstConst* constp = VN_CAST(nodep, Const); int expWidth = expDTypep->width(); if (constp && !constp->num().isNegative()) { - // Save later constant propagation work, just right-size it. - V3Number num (nodep->fileline(), expWidth); - num.opAssign(constp->num()); + // Save later constant propagation work, just right-size it. + V3Number num (nodep, expWidth); + num.opAssign(constp->num()); num.isSigned(false); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); @@ -3134,9 +3134,9 @@ private: int expSigned = false; UINFO(4," widthReduce_old: "<fileline(), expWidth); - num.opRedOr(constp->num()); + if (constp) { + V3Number num (nodep, expWidth); + num.opRedOr(constp->num()); num.isSigned(expSigned); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); @@ -3157,9 +3157,9 @@ private: // For SystemVerilog '0,'1,'x,'z, autoextend and don't warn 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); - num.opRepl(constp->num(), expWidth); // {width{'1}} + // Make it the proper size. Careful of proper extension of 0's/1's + V3Number num (constp, expWidth); + num.opRepl(constp->num(), expWidth); // {width{'1}} AstNode* newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width if (debug()>4) constp->dumpTree(cout," fixAutoExtend_old: "); @@ -3176,7 +3176,7 @@ private: && expWidth > 32 && constp->num().isMsbXZ()) { constp->v3warn(WIDTH, "Unsized constant being X/Z extended to " <prettyName()); - V3Number num (constp->fileline(), expWidth); + V3Number num (constp, expWidth); num.opExtendXZ(constp->num(), constp->width()); AstNode* newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width @@ -3802,9 +3802,9 @@ private: if (attrType == AstAttrType::ENUM_NAME) { initp->defaultp(new AstConst(nodep->fileline(), AstConst::String(), "")); } else if (attrType == AstAttrType::ENUM_NEXT - || attrType == AstAttrType::ENUM_PREV) { - initp->defaultp(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0))); - } else { + || attrType == AstAttrType::ENUM_PREV) { + initp->defaultp(new AstConst(nodep->fileline(), V3Number(nodep, nodep->width(), 0))); + } else { nodep->v3fatalSrc("Bad case"); } diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h index 9fc62864a..cc5a7f306 100644 --- a/src/V3WidthCommit.h +++ b/src/V3WidthCommit.h @@ -77,9 +77,9 @@ public: static AstConst* newIfConstCommitSize(AstConst* nodep) { if (((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized()) - && !nodep->num().isString()) { // Need to force the number from unsized to sized - V3Number num (nodep->fileline(), nodep->dtypep()->width()); - num.opAssign(nodep->num()); + && !nodep->num().isString()) { // Need to force the number from unsized to sized + V3Number num (nodep, nodep->dtypep()->width()); + num.opAssign(nodep->num()); num.isSigned(nodep->isSigned()); AstConst* newp = new AstConst(nodep->fileline(), num); newp->dtypeFrom(nodep); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 38d406d63..4228c08fb 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -120,9 +120,9 @@ private: return lhsp; } 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(VN_CAST(lhsp, Const)->num(), V3Number(lhsp->fileline(), 32, rhs)); - num.isSigned(lhsp->isSigned()); + V3Number num (lhsp, lhsp->width()); + num.opSub(VN_CAST(lhsp, Const)->num(), V3Number(lhsp, 32, rhs)); + num.isSigned(lhsp->isSigned()); AstNode* newp = new AstConst(lhsp->fileline(), num); return newp; } else if (rhs > 0) { diff --git a/src/verilog.y b/src/verilog.y index 4f131abec..6ba6c1e97 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1936,10 +1936,10 @@ genvar_iteration: // ==IEEE: genvar_iteration | varRefBase yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); } // // inc_or_dec_operator // When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstNodeMathStmt? - | yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } - | yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } - | varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } - | varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } + | yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true), new AstConst($1, AstConst::StringToParse(), "'b1"))); } + | yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true), new AstConst($1, AstConst::StringToParse(), "'b1"))); } + | varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true), new AstConst($2, AstConst::StringToParse(), "'b1"))); } + | varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true), new AstConst($2, AstConst::StringToParse(), "'b1"))); } ; case_generate_itemListE: // IEEE: [{ case_generate_itemList }] @@ -2520,10 +2520,10 @@ foperator_assignment: // IEEE: operator_assignment (for first part of exp finc_or_dec_expression: // ==IEEE: inc_or_dec_expression //UNSUP: Generic scopes in incrementes - fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } - | fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } - | yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } - | yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } + fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); } + | fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); } + | yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); } + | yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); } ; //************************************************ @@ -2798,8 +2798,8 @@ system_t_call: // IEEE: system_tf_call (as task) ; system_f_call: // IEEE: system_tf_call (as func) - yaD_IGNORE parenE { $$ = new AstConst($1,V3Number($1,"'b0")); } // Unsized 0 - | yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2,V3Number($2,"'b0")); } // Unsized 0 + yaD_IGNORE parenE { $$ = new AstConst($1, AstConst::StringToParse(), "'b0"); } // Unsized 0 + | yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2, AstConst::StringToParse(), "'b0"); } // Unsized 0 // | yaD_DPI parenE { $$ = new AstFuncRef($1,*$1,NULL); } | yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); } @@ -3781,7 +3781,7 @@ str: // yaSTRING but with \{escapes} need decoded ; strAsInt: - yaSTRING { $$ = new AstConst($1,V3Number(V3Number::VerilogStringLiteral(),$1,GRAMMARP->deQuote($1,*$1)));} + yaSTRING { $$ = new AstConst($1, AstConst::VerilogStringLiteral(), GRAMMARP->deQuote($1, *$1));} ; strAsIntIgnore: // strAsInt, but never matches for when expr shouldn't parse strings @@ -3988,7 +3988,8 @@ void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) { AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) { return new AstAssignW(fileline, new AstVarRef(fileline, name, true), - new AstConst(fileline, V3Number(fileline, (value ? "'1" : "'0")))); + new AstConst(fileline, AstConst::StringToParse(), + (value ? "'1" : "'0"))); } AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) {