Internals: Cleanups in V3Signed towards reals; no functional change
This commit is contained in:
parent
7f49619875
commit
a9ba4a9fcd
17
src/V3Ast.h
17
src/V3Ast.h
|
|
@ -209,7 +209,7 @@ class AstBasicDTypeKwd {
|
||||||
public:
|
public:
|
||||||
enum en {
|
enum en {
|
||||||
BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT,
|
BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT,
|
||||||
REAL, REALTIME, SHORTINT, SHORTREAL, TIME,
|
REAL, SHORTINT, SHORTREAL, TIME,
|
||||||
// Closer to a class type, but limited usage
|
// Closer to a class type, but limited usage
|
||||||
STRING,
|
STRING,
|
||||||
// Internal types for mid-steps
|
// Internal types for mid-steps
|
||||||
|
|
@ -221,7 +221,7 @@ public:
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
|
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
|
||||||
"real", "realtime", "shortint", "shortreal", "time",
|
"real", "shortint", "shortreal", "time",
|
||||||
"string",
|
"string",
|
||||||
"VerilatedScope*", "char*",
|
"VerilatedScope*", "char*",
|
||||||
"LOGIC_IMPLICIT"
|
"LOGIC_IMPLICIT"
|
||||||
|
|
@ -231,7 +231,7 @@ public:
|
||||||
const char* dpiType() const {
|
const char* dpiType() const {
|
||||||
static const char* names[] = {
|
static const char* names[] = {
|
||||||
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
|
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
|
||||||
"double", "double", "short int", "float", "long long",
|
"double", "short int", "float", "long long",
|
||||||
"const char*",
|
"const char*",
|
||||||
"dpiScope", "const char*",
|
"dpiScope", "const char*",
|
||||||
""
|
""
|
||||||
|
|
@ -251,6 +251,8 @@ public:
|
||||||
case INTEGER: return 32;
|
case INTEGER: return 32;
|
||||||
case LOGIC: return 1;
|
case LOGIC: return 1;
|
||||||
case LONGINT: return 64;
|
case LONGINT: return 64;
|
||||||
|
case REAL: return 64;
|
||||||
|
case SHORTREAL: return 32;
|
||||||
case SHORTINT: return 16;
|
case SHORTINT: return 16;
|
||||||
case TIME: return 64;
|
case TIME: return 64;
|
||||||
case STRING: return 64; // Just the pointer, for today
|
case STRING: return 64; // Just the pointer, for today
|
||||||
|
|
@ -265,7 +267,7 @@ public:
|
||||||
}
|
}
|
||||||
bool isZeroInit() const { // Otherwise initializes to X
|
bool isZeroInit() const { // Otherwise initializes to X
|
||||||
return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT || m_e==LONGINT || m_e==SHORTINT
|
return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT || m_e==LONGINT || m_e==SHORTINT
|
||||||
|| m_e==STRING);
|
|| m_e==STRING || m_e==REAL || m_e==SHORTREAL);
|
||||||
}
|
}
|
||||||
bool isSloppy() const { // Don't be as anal about width warnings
|
bool isSloppy() const { // Don't be as anal about width warnings
|
||||||
return !(m_e==LOGIC || m_e==BIT);
|
return !(m_e==LOGIC || m_e==BIT);
|
||||||
|
|
@ -274,10 +276,13 @@ public:
|
||||||
return (m_e==LOGIC || m_e==BIT);
|
return (m_e==LOGIC || m_e==BIT);
|
||||||
}
|
}
|
||||||
bool isDpiUnsupported() const {
|
bool isDpiUnsupported() const {
|
||||||
return (m_e==LOGIC || m_e==TIME || m_e==REALTIME);
|
return (m_e==LOGIC || m_e==TIME);
|
||||||
}
|
}
|
||||||
bool isOpaque() const { // IE not a simple number we can bit optimize
|
bool isOpaque() const { // IE not a simple number we can bit optimize
|
||||||
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR);
|
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==REAL || m_e==SHORTREAL);
|
||||||
|
}
|
||||||
|
bool isReal() const {
|
||||||
|
return (m_e==REAL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ string AstVar::vlArgType(bool named, bool forReturn) const {
|
||||||
arg += "const char*";
|
arg += "const char*";
|
||||||
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) {
|
||||||
arg += "const VerilatedScope*";
|
arg += "const VerilatedScope*";
|
||||||
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::REAL) {
|
||||||
|
arg += "double";
|
||||||
|
} else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SHORTREAL) {
|
||||||
|
arg += "float";
|
||||||
} else if (strtype) {
|
} else if (strtype) {
|
||||||
if (isInOnly()) arg += "const ";
|
if (isInOnly()) arg += "const ";
|
||||||
arg += "string";
|
arg += "string";
|
||||||
|
|
|
||||||
|
|
@ -1519,7 +1519,7 @@ private:
|
||||||
if (!inPct && ch=='%') {
|
if (!inPct && ch=='%') {
|
||||||
inPct = true;
|
inPct = true;
|
||||||
fmt = ch;
|
fmt = ch;
|
||||||
} else if (inPct && isdigit(ch)) {
|
} else if (inPct && (isdigit(ch) || ch=='.')) {
|
||||||
fmt += ch;
|
fmt += ch;
|
||||||
} else if (inPct) {
|
} else if (inPct) {
|
||||||
inPct = false;
|
inPct = false;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ class SignedVisitor : public AstNVisitor {
|
||||||
private:
|
private:
|
||||||
// NODE STATE/TYPES
|
// NODE STATE/TYPES
|
||||||
// STATE
|
// STATE
|
||||||
int m_taskDepth; // Recursion check
|
|
||||||
bool m_paramsOnly; // Computing parameter value; limit operation
|
bool m_paramsOnly; // Computing parameter value; limit operation
|
||||||
|
|
||||||
// METHODS - special type detection
|
// METHODS - special type detection
|
||||||
|
|
@ -62,8 +61,8 @@ private:
|
||||||
// VISITORS
|
// VISITORS
|
||||||
//========
|
//========
|
||||||
// Signed: Output explicit by user, Lhs either
|
// Signed: Output explicit by user, Lhs either
|
||||||
virtual void visit(AstSigned* nodep, AstNUser*) { signed_Os_Ix(nodep); }
|
|
||||||
virtual void visit(AstUnsigned* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
virtual void visit(AstUnsigned* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
|
||||||
|
virtual void visit(AstSigned* nodep, AstNUser*) { signed_Os_Ix(nodep); }
|
||||||
|
|
||||||
//========
|
//========
|
||||||
// Signed: Output unsigned, Operands either
|
// Signed: Output unsigned, Operands either
|
||||||
|
|
@ -291,6 +290,18 @@ private:
|
||||||
// ShiftRS converts to ShiftR, but not vice-versa
|
// ShiftRS converts to ShiftR, but not vice-versa
|
||||||
virtual void visit(AstShiftRS* nodep, AstNUser*) { checkReplace_Olhs(nodep); }
|
virtual void visit(AstShiftRS* nodep, AstNUser*) { checkReplace_Olhs(nodep); }
|
||||||
|
|
||||||
|
// VISITORS - defaults
|
||||||
|
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
||||||
|
nodep->v3fatalSrc("Visit function missing? Signedness unknown for this node: "<<nodep);
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======
|
||||||
|
// Lower level functions
|
||||||
|
|
||||||
void checkReplace_Ou_FlavLhsAndRhs(AstNodeBiop* nodep) {
|
void checkReplace_Ou_FlavLhsAndRhs(AstNodeBiop* nodep) {
|
||||||
// For compares, the output of the comparison is unsigned.
|
// For compares, the output of the comparison is unsigned.
|
||||||
// However, we need the appropriate type of compare selected by RHS & LHS
|
// However, we need the appropriate type of compare selected by RHS & LHS
|
||||||
|
|
@ -336,15 +347,6 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS - defaults
|
|
||||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
|
||||||
nodep->v3fatalSrc("Visit function missing? Signedness unknown for this node: "<<nodep);
|
|
||||||
nodep->iterateChildren(*this);
|
|
||||||
}
|
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
|
||||||
nodep->iterateChildren(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// COMMON SCHEMES
|
// COMMON SCHEMES
|
||||||
// Signed: Output signed, Lhs/Rhs/etc either
|
// Signed: Output signed, Lhs/Rhs/etc either
|
||||||
void signed_Os_Ix(AstNode* nodep) {
|
void signed_Os_Ix(AstNode* nodep) {
|
||||||
|
|
@ -392,7 +394,6 @@ public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
SignedVisitor(bool paramsOnly) {
|
SignedVisitor(bool paramsOnly) {
|
||||||
m_paramsOnly = paramsOnly;
|
m_paramsOnly = paramsOnly;
|
||||||
m_taskDepth = 0;
|
|
||||||
}
|
}
|
||||||
virtual ~SignedVisitor() {}
|
virtual ~SignedVisitor() {}
|
||||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,14 @@ private:
|
||||||
virtual void visit(AstShiftR* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
virtual void visit(AstShiftR* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
||||||
virtual void visit(AstShiftRS* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
virtual void visit(AstShiftRS* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
||||||
|
|
||||||
|
// Widths: Fixed
|
||||||
|
void width_Ofixed_L(AstNodeUniop* nodep, AstNUser* vup, int width);
|
||||||
|
|
||||||
|
// Widths: Constant, terminal
|
||||||
|
virtual void visit(AstTime* nodep, AstNUser*) { nodep->width(64,64); }
|
||||||
|
virtual void visit(AstTestPlusArgs* nodep, AstNUser*) { nodep->width(32,32); }
|
||||||
|
virtual void visit(AstScopeName* nodep, AstNUser* vup) { nodep->width(64,1); } // A pointer, but not that it matters
|
||||||
|
|
||||||
// Special cases. So many....
|
// Special cases. So many....
|
||||||
virtual void visit(AstNodeCond* nodep, AstNUser* vup) {
|
virtual void visit(AstNodeCond* nodep, AstNUser* vup) {
|
||||||
// op=cond?expr1:expr2 is a Good large example of the propagation mess
|
// op=cond?expr1:expr2 is a Good large example of the propagation mess
|
||||||
|
|
@ -431,9 +439,6 @@ private:
|
||||||
nodep->width(32,32); // Says the spec
|
nodep->width(32,32); // Says the spec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstTime* nodep, AstNUser*) {
|
|
||||||
nodep->width(64,64);
|
|
||||||
}
|
|
||||||
virtual void visit(AstUCFunc* nodep, AstNUser* vup) {
|
virtual void visit(AstUCFunc* nodep, AstNUser* vup) {
|
||||||
// Give it the size the user wants.
|
// Give it the size the user wants.
|
||||||
if (vup && vup->c()->prelim()) {
|
if (vup && vup->c()->prelim()) {
|
||||||
|
|
@ -470,9 +475,6 @@ private:
|
||||||
virtual void visit(AstText* nodep, AstNUser* vup) {
|
virtual void visit(AstText* nodep, AstNUser* vup) {
|
||||||
// Only used in CStmts which don't care....
|
// Only used in CStmts which don't care....
|
||||||
}
|
}
|
||||||
virtual void visit(AstScopeName* nodep, AstNUser* vup) {
|
|
||||||
nodep->width(64,1); // A pointer, but not that it matters
|
|
||||||
}
|
|
||||||
virtual void visit(AstArrayDType* nodep, AstNUser* vup) {
|
virtual void visit(AstArrayDType* nodep, AstNUser* vup) {
|
||||||
// Lower datatype determines the width
|
// Lower datatype determines the width
|
||||||
nodep->dtypep()->iterateAndNext(*this,vup);
|
nodep->dtypep()->iterateAndNext(*this,vup);
|
||||||
|
|
@ -829,9 +831,6 @@ private:
|
||||||
nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
}
|
}
|
||||||
virtual void visit(AstTestPlusArgs* nodep, AstNUser* vup) {
|
|
||||||
nodep->width(32,32);
|
|
||||||
}
|
|
||||||
virtual void visit(AstValuePlusArgs* nodep, AstNUser* vup) {
|
virtual void visit(AstValuePlusArgs* nodep, AstNUser* vup) {
|
||||||
nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
nodep->width(32,32);
|
nodep->width(32,32);
|
||||||
|
|
@ -1305,6 +1304,15 @@ void WidthVisitor::width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WidthVisitor::width_Ofixed_L(AstNodeUniop* nodep, AstNUser* vup, int width) {
|
||||||
|
// Widths: out width = specified width
|
||||||
|
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||||
|
if (vup->c()->prelim()) {
|
||||||
|
nodep->op1p()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
}
|
||||||
|
nodep->width(width,width);
|
||||||
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Olhs_L(AstNodeUniop* nodep, AstNUser* vup) {
|
void WidthVisitor::width_Olhs_L(AstNodeUniop* nodep, AstNUser* vup) {
|
||||||
// Widths: out width = lhs width
|
// Widths: out width = lhs width
|
||||||
// "Interim results shall take the max of operands, including LHS of assignments"
|
// "Interim results shall take the max of operands, including LHS of assignments"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue