diff --git a/src/V3Ast.h b/src/V3Ast.h index 80bc45de5..8a77d6450 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -254,7 +254,9 @@ public: // Internal types for mid-steps SCOPEPTR, CHARPTR, // Internal types, eliminated after parsing - LOGIC_IMPLICIT + LOGIC_IMPLICIT, + // Leave last + _ENUM_MAX }; enum en m_e; const char* ascii() const { @@ -264,7 +266,8 @@ public: "real", "shortint", "shortreal", "time", "string", "VerilatedScope*", "char*", - "LOGIC_IMPLICIT" + "LOGIC_IMPLICIT", + " MAX" }; return names[m_e]; }; @@ -275,10 +278,15 @@ public: "double", "short int", "float", "long long", "const char*", "dpiScope", "const char*", - "" + "", + " MAX" }; return names[m_e]; }; + static void test() { + UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"),"Enum array mismatch"); + UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch"); + } inline AstBasicDTypeKwd () : m_e(UNKNOWN) {} inline AstBasicDTypeKwd (en _e) : m_e(_e) {} explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast(_e)) {} @@ -868,7 +876,6 @@ public: void numericFrom(AstNode* fromp) { numeric(fromp->numeric()); } void numeric(AstNumeric flag) { m_numeric = (int)flag; if (flag.isDouble()) width(64,64); } AstNumeric numeric() const { return AstNumeric(m_numeric); } - void isSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } bool isUnsigned() const { return numeric().isUnsigned(); } void didWidth(bool flag) { m_didWidth=flag; } bool didWidth() const { return m_didWidth; } @@ -942,6 +949,7 @@ public: bool isAllOnesV(); // Verilog width rules apply // METHODS - data type changes especially for initial creation + void dtypeChgSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } void dtypeSetBitSized(int widthf, int widthMinf, AstNumeric numericf) { numeric(numericf); width(widthf,widthMinf); } void dtypeSetLogicSized(int widthf, int widthMinf, AstNumeric numericf) { numeric(numericf); width(widthf,widthMinf); } void dtypeSetLogicBool() { numeric(AstNumeric::UNSIGNED); width(1,1); } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index c5b4f82c9..11a600966 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -527,7 +527,7 @@ private: virtual void visit(AstConst* nodep, AstNUser* vup) { // The node got setup with the signed/real state of the node. // However a later operation may have changed the node->signed w/o changing - // the number's sign. So we don't: nodep->isSigned(nodep->num().isSigned()); + // the number's sign. So we don't: nodep->dtypeChgSigned(nodep->num().isSigned()); if (vup && vup->c()->prelim()) { if (nodep->num().sized()) { nodep->width(nodep->num().width(), nodep->num().width()); @@ -575,7 +575,7 @@ private: replaceWithDVersion(nodep); nodep=NULL; } else { AstNodeBiop* newp = shift_final(nodep, vup); nodep=NULL; - newp->isSigned(newp->lhsp()->isSigned()); + newp->dtypeChgSigned(newp->lhsp()->isSigned()); if (newp->isSigned()) { replaceWithUOrSVersion(newp, false); newp=NULL; } @@ -585,7 +585,7 @@ private: // Pow is special, output sign only depends on LHS sign shift_prelim(nodep, vup); AstNodeBiop* newp = shift_final(nodep, vup); nodep=NULL; - newp->isSigned(newp->lhsp()->isSigned()); + newp->dtypeChgSigned(newp->lhsp()->isSigned()); if (!newp->isSigned()) { replaceWithUOrSVersion(newp, true); newp=NULL; } @@ -1448,7 +1448,7 @@ private: nodep = newp; // Process new node instead } } else { - nodep->isSigned(nodep->lhsp()->isSigned()); + nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); // Note there aren't yet uniops that need version changes // So no need to call replaceWithUOrSVersion(nodep, nodep->isSigned()) } @@ -1486,7 +1486,7 @@ private: // Widths: Output width from lhs, rhs<33 bits // Signed: Output signed iff LHS signed; unary operator shift_prelim(nodep,vup); - nodep->isSigned(nodep->lhsp()->isSigned()); + nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); AstNodeBiop* newp = shift_final(nodep,vup); nodep=NULL; if (newp) {} // Ununused } @@ -1538,7 +1538,7 @@ private: int width = max(vup->c()->width(), max(nodep->lhsp()->width(), nodep->rhsp()->width())); int mwidth = max(vup->c()->widthMin(), max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin())); nodep->width(width,mwidth); - nodep->isSigned(nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); + nodep->dtypeChgSigned(nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); if (vup->c()->final()) { // Final call, so make sure children check their sizes nodep->lhsp()->iterateAndNext(*this,WidthVP(width,mwidth,FINAL).p()); @@ -1584,7 +1584,7 @@ private: nodep = newp; // Process new node instead } } else { - nodep->isSigned(nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); + nodep->dtypeChgSigned(nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { nodep=NULL; nodep = newp; // Process new node instead } @@ -1858,11 +1858,11 @@ private: } // To simplify callers, some node types don't need to change switch (nodep->type()) { - case AstType::atEQ: nodep->isSigned(signedFlavorNeeded); return NULL; - case AstType::atNEQ: nodep->isSigned(signedFlavorNeeded); return NULL; - case AstType::atADD: nodep->isSigned(signedFlavorNeeded); return NULL; - case AstType::atSUB: nodep->isSigned(signedFlavorNeeded); return NULL; - case AstType::atSHIFTL: nodep->isSigned(signedFlavorNeeded); return NULL; + case AstType::atEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; + case AstType::atNEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; + case AstType::atADD: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; + case AstType::atSUB: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; + case AstType::atSHIFTL: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; default: break; } FileLine* fl = nodep->fileline(); diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 53d429ea3..b13e28f81 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -656,6 +656,7 @@ int main(int argc, char** argv, char** env) { } // Internal tests (after option parsing as need debug() setting) + AstBasicDTypeKwd::test(); V3Graph::test(); //--FRONTEND------------------