Internals: Move width internals to inside class; move WidthCommit. No functional change
This commit is contained in:
parent
1b3d252bfe
commit
4fa1e45d45
120
src/V3Width.cpp
120
src/V3Width.cpp
|
|
@ -57,6 +57,10 @@
|
||||||
#include "V3Const.h"
|
#include "V3Const.h"
|
||||||
#include "V3Task.h"
|
#include "V3Task.h"
|
||||||
|
|
||||||
|
// More code; this file was getting too large; see actions there
|
||||||
|
#define _V3WIDTH_CPP_
|
||||||
|
#include "V3WidthCommit.h"
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Width state, as a visitor of each AstNode
|
// Width state, as a visitor of each AstNode
|
||||||
|
|
||||||
|
|
@ -99,19 +103,16 @@ private:
|
||||||
// VISITORS
|
// VISITORS
|
||||||
// Naming: width_{output size rule}_{lhs rule}_{rhs rule}
|
// Naming: width_{output size rule}_{lhs rule}_{rhs rule}
|
||||||
// Widths: 1 bit out, lhs 1 bit
|
// Widths: 1 bit out, lhs 1 bit
|
||||||
void width_O1_L1(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstLogNot* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); }
|
virtual void visit(AstLogNot* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); }
|
||||||
virtual void visit(AstPslBool* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); }
|
virtual void visit(AstPslBool* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); }
|
||||||
|
|
||||||
// Widths: 1 bit out, lhs 1 bit, rhs 1 bit
|
// Widths: 1 bit out, lhs 1 bit, rhs 1 bit
|
||||||
void width_O1_L1_R1(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstLogAnd* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
virtual void visit(AstLogAnd* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
||||||
virtual void visit(AstLogOr* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
virtual void visit(AstLogOr* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
||||||
virtual void visit(AstLogIf* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
virtual void visit(AstLogIf* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
||||||
virtual void visit(AstLogIff* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
virtual void visit(AstLogIff* nodep, AstNUser* vup) { width_O1_L1_R1(nodep,vup); }
|
||||||
|
|
||||||
// Widths: 1 bit out, Any width lhs
|
// Widths: 1 bit out, Any width lhs
|
||||||
void width_O1_L(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstRedAnd* nodep, AstNUser* vup) { width_O1_L(nodep,vup); }
|
virtual void visit(AstRedAnd* nodep, AstNUser* vup) { width_O1_L(nodep,vup); }
|
||||||
virtual void visit(AstRedOr* nodep, AstNUser* vup) { width_O1_L(nodep,vup); }
|
virtual void visit(AstRedOr* nodep, AstNUser* vup) { width_O1_L(nodep,vup); }
|
||||||
virtual void visit(AstRedXnor* nodep, AstNUser* vup){ width_O1_L(nodep,vup); }
|
virtual void visit(AstRedXnor* nodep, AstNUser* vup){ width_O1_L(nodep,vup); }
|
||||||
|
|
@ -121,7 +122,6 @@ private:
|
||||||
virtual void visit(AstOneHot0* nodep,AstNUser* vup) { width_O1_L(nodep,vup); }
|
virtual void visit(AstOneHot0* nodep,AstNUser* vup) { width_O1_L(nodep,vup); }
|
||||||
|
|
||||||
// Widths: 1 bit out, lhs width == rhs width
|
// Widths: 1 bit out, lhs width == rhs width
|
||||||
void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
||||||
virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
||||||
virtual void visit(AstEqWild* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
virtual void visit(AstEqWild* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
|
||||||
|
|
@ -138,7 +138,6 @@ private:
|
||||||
virtual void visit(AstNeqWild* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
|
virtual void visit(AstNeqWild* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
|
||||||
|
|
||||||
// Widths: out width = lhs width = rhs width
|
// Widths: out width = lhs width = rhs width
|
||||||
void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstAnd* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
virtual void visit(AstAnd* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
||||||
virtual void visit(AstOr* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
virtual void visit(AstOr* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
||||||
virtual void visit(AstXnor* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
virtual void visit(AstXnor* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
||||||
|
|
@ -156,26 +155,20 @@ private:
|
||||||
virtual void visit(AstMulS* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
virtual void visit(AstMulS* nodep, AstNUser* vup) { width_Omax_L_Rlhs(nodep,vup); }
|
||||||
|
|
||||||
// Widths: out width = lhs width, but upper matters
|
// Widths: out width = lhs width, but upper matters
|
||||||
void width_Olhs_L(AstNodeUniop* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstNot* nodep, AstNUser* vup) { width_Olhs_L(nodep,vup); }
|
virtual void visit(AstNot* nodep, AstNUser* vup) { width_Olhs_L(nodep,vup); }
|
||||||
virtual void visit(AstUnaryMin* nodep, AstNUser* vup) { width_Olhs_L(nodep,vup); }
|
virtual void visit(AstUnaryMin* nodep, AstNUser* vup) { width_Olhs_L(nodep,vup); }
|
||||||
|
|
||||||
// Widths: out width = lhs width, upper doesn't matter
|
// Widths: out width = lhs width, upper doesn't matter
|
||||||
void width_Olhs_Lforce(AstNodeUniop* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstSigned* nodep, AstNUser* vup) { width_Olhs_Lforce(nodep,vup); }
|
virtual void visit(AstSigned* nodep, AstNUser* vup) { width_Olhs_Lforce(nodep,vup); }
|
||||||
virtual void visit(AstUnsigned* nodep, AstNUser* vup) { width_Olhs_Lforce(nodep,vup); }
|
virtual void visit(AstUnsigned* nodep, AstNUser* vup) { width_Olhs_Lforce(nodep,vup); }
|
||||||
|
|
||||||
// Widths: Output width from lhs, rhs<33 bits
|
// Widths: Output width from lhs, rhs<33 bits
|
||||||
void width_Olhs_L_R32(AstNode* nodep, AstNUser* vup);
|
|
||||||
virtual void visit(AstPow* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
virtual void visit(AstPow* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
||||||
virtual void visit(AstPowS* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
virtual void visit(AstPowS* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
||||||
virtual void visit(AstShiftL* nodep, AstNUser* vup) { width_Olhs_L_R32(nodep,vup); }
|
virtual void visit(AstShiftL* 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(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
|
// Widths: Constant, terminal
|
||||||
virtual void visit(AstTime* nodep, AstNUser*) { nodep->width(64,64); }
|
virtual void visit(AstTime* nodep, AstNUser*) { nodep->width(64,64); }
|
||||||
virtual void visit(AstTestPlusArgs* nodep, AstNUser*) { nodep->width(32,32); }
|
virtual void visit(AstTestPlusArgs* nodep, AstNUser*) { nodep->width(32,32); }
|
||||||
|
|
@ -1047,38 +1040,10 @@ private:
|
||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// METHODS
|
|
||||||
bool widthBad (AstNode* nodep, int expWidth, int expWidthMin);
|
|
||||||
void widthCheck (AstNode* nodep, const char* side,
|
|
||||||
AstNode* underp, int expWidth, int expWidthMin,
|
|
||||||
bool ignoreWarn=false);
|
|
||||||
void widthCheckReduce (AstNode* nodep, const char* side,
|
|
||||||
AstNode* underp, int expWidth, int expWidthMin,
|
|
||||||
bool ignoreWarn=false);
|
|
||||||
void widthCheckPin (AstNode* nodep, AstNode* underp, int expWidth, bool inputPin);
|
|
||||||
bool fixAutoExtend (AstNode*& nodepr, int expWidth);
|
|
||||||
void fixWidthExtend (AstNode* nodep, int expWidth);
|
|
||||||
void fixWidthReduce (AstNode* nodep, int expWidth);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// CONSTUCTORS
|
|
||||||
WidthVisitor(bool paramsOnly) {
|
|
||||||
m_paramsOnly = paramsOnly;
|
|
||||||
m_taskDepth = 0;
|
|
||||||
m_cellRangep = NULL;
|
|
||||||
m_casep = NULL;
|
|
||||||
m_funcp = NULL;
|
|
||||||
}
|
|
||||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
|
||||||
return nodep->acceptSubtreeReturnEdits(*this, WidthVP(ANYSIZE,0,BOTH).p());
|
|
||||||
}
|
|
||||||
virtual ~WidthVisitor() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// METHODs
|
// METHODs
|
||||||
|
|
||||||
bool WidthVisitor::widthBad (AstNode* nodep, int expWidth, int expWidthMin) {
|
bool widthBad (AstNode* nodep, int expWidth, int expWidthMin) {
|
||||||
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
|
if (nodep->width()==0) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
|
||||||
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
|
if (expWidth==0) nodep->v3fatalSrc("Node "<<nodep->prettyTypeName()<<" has no expected width?? Missing Visitor func?");
|
||||||
if (expWidthMin==0) expWidthMin = expWidth;
|
if (expWidthMin==0) expWidthMin = expWidth;
|
||||||
|
|
@ -1087,7 +1052,7 @@ bool WidthVisitor::widthBad (AstNode* nodep, int expWidth, int expWidthMin) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::fixWidthExtend (AstNode* nodep, int expWidth) {
|
void fixWidthExtend (AstNode* nodep, int expWidth) {
|
||||||
// Fix the width mismatch by extending or truncating bits
|
// Fix the width mismatch by extending or truncating bits
|
||||||
// Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312;
|
// Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312;
|
||||||
// A(CONSTwide)+B becomes A(CONSTwidened)+B
|
// A(CONSTwide)+B becomes A(CONSTwidened)+B
|
||||||
|
|
@ -1125,7 +1090,7 @@ void WidthVisitor::fixWidthExtend (AstNode* nodep, int expWidth) {
|
||||||
UINFO(4," _new: "<<nodep<<endl);
|
UINFO(4," _new: "<<nodep<<endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::fixWidthReduce (AstNode* nodep, int expWidth) {
|
void fixWidthReduce (AstNode* nodep, int expWidth) {
|
||||||
// Fix the width mismatch by adding a reduction OR operator
|
// Fix the width mismatch by adding a reduction OR operator
|
||||||
// IF (A(CONSTwide)) becomes IF (A(CONSTreduced))
|
// IF (A(CONSTwide)) becomes IF (A(CONSTreduced))
|
||||||
// IF (A(somewide)) becomes IF (A(REDOR(somewide)))
|
// IF (A(somewide)) becomes IF (A(REDOR(somewide)))
|
||||||
|
|
@ -1150,7 +1115,7 @@ void WidthVisitor::fixWidthReduce (AstNode* nodep, int expWidth) {
|
||||||
UINFO(4," _new: "<<nodep<<endl);
|
UINFO(4," _new: "<<nodep<<endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WidthVisitor::fixAutoExtend (AstNode*& nodepr, int expWidth) {
|
bool fixAutoExtend (AstNode*& nodepr, int expWidth) {
|
||||||
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
|
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
|
||||||
if (AstConst* constp = nodepr->castConst()) {
|
if (AstConst* constp = nodepr->castConst()) {
|
||||||
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
|
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
|
||||||
|
|
@ -1171,9 +1136,9 @@ bool WidthVisitor::fixAutoExtend (AstNode*& nodepr, int expWidth) {
|
||||||
return false; // No change
|
return false; // No change
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::widthCheck (AstNode* nodep, const char* side,
|
void widthCheck (AstNode* nodep, const char* side,
|
||||||
AstNode* underp, int expWidth, int expWidthMin,
|
AstNode* underp, int expWidth, int expWidthMin,
|
||||||
bool ignoreWarn) {
|
bool ignoreWarn=false) {
|
||||||
//UINFO(9,"wchk "<<side<<endl<<" "<<nodep<<endl<<" "<<underp<<endl<<" e"<<expWidth<<" m"<<expWidthMin<<" i"<<ignoreWarn<<endl);
|
//UINFO(9,"wchk "<<side<<endl<<" "<<nodep<<endl<<" "<<underp<<endl<<" e"<<expWidth<<" m"<<expWidthMin<<" i"<<ignoreWarn<<endl);
|
||||||
if (expWidthMin==0) expWidthMin = expWidth;
|
if (expWidthMin==0) expWidthMin = expWidth;
|
||||||
bool bad = widthBad(underp,expWidth,expWidthMin);
|
bool bad = widthBad(underp,expWidth,expWidthMin);
|
||||||
|
|
@ -1207,9 +1172,9 @@ void WidthVisitor::widthCheck (AstNode* nodep, const char* side,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::widthCheckReduce (AstNode* nodep, const char* side,
|
void widthCheckReduce (AstNode* nodep, const char* side,
|
||||||
AstNode* underp, int expWidth, int expWidthMin,
|
AstNode* underp, int expWidth, int expWidthMin,
|
||||||
bool ignoreWarn) {
|
bool ignoreWarn=false) {
|
||||||
// Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately
|
// Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately
|
||||||
if (expWidthMin==0) expWidthMin = expWidth;
|
if (expWidthMin==0) expWidthMin = expWidth;
|
||||||
if (expWidth!=1) nodep->v3fatalSrc("Only for binary functions");
|
if (expWidth!=1) nodep->v3fatalSrc("Only for binary functions");
|
||||||
|
|
@ -1228,7 +1193,7 @@ void WidthVisitor::widthCheckReduce (AstNode* nodep, const char* side,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::widthCheckPin (AstNode* nodep, AstNode* underp, int expWidth, bool inputPin) {
|
void widthCheckPin (AstNode* nodep, AstNode* underp, int expWidth, bool inputPin) {
|
||||||
// Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately
|
// Before calling this, iterate into underp with FINAL state, so numbers get resized appropriately
|
||||||
bool bad = widthBad(underp,expWidth,expWidth);
|
bool bad = widthBad(underp,expWidth,expWidth);
|
||||||
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp
|
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp
|
||||||
|
|
@ -1248,7 +1213,7 @@ void WidthVisitor::widthCheckPin (AstNode* nodep, AstNode* underp, int expWidth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_O1_L1(AstNode* nodep, AstNUser* vup) {
|
void width_O1_L1(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: 1 bit out, lhs 1 bit
|
// Widths: 1 bit out, lhs 1 bit
|
||||||
// We calculate the width of the UNDER expression.
|
// We calculate the width of the UNDER expression.
|
||||||
// We then check its width to see if it's legal, and edit if not
|
// We then check its width to see if it's legal, and edit if not
|
||||||
|
|
@ -1263,7 +1228,7 @@ void WidthVisitor::width_O1_L1(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_O1_L1_R1(AstNode* nodep, AstNUser* vup) {
|
void width_O1_L1_R1(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: 1 bit out, lhs 1 bit, rhs 1 bit
|
// Widths: 1 bit out, lhs 1 bit, rhs 1 bit
|
||||||
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
||||||
if (vup->c()->prelim()) {
|
if (vup->c()->prelim()) {
|
||||||
|
|
@ -1277,7 +1242,7 @@ void WidthVisitor::width_O1_L1_R1(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_O1_L(AstNode* nodep, AstNUser* vup) {
|
void width_O1_L(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: 1 bit out, Any width lhs
|
// Widths: 1 bit out, Any width lhs
|
||||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||||
if (vup->c()->prelim()) {
|
if (vup->c()->prelim()) {
|
||||||
|
|
@ -1286,7 +1251,7 @@ void WidthVisitor::width_O1_L(AstNode* nodep, AstNUser* vup) {
|
||||||
nodep->width(1,1);
|
nodep->width(1,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: 1 bit out, lhs width == rhs width
|
// Widths: 1 bit out, lhs width == rhs width
|
||||||
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
||||||
if (vup->c()->prelim()) {
|
if (vup->c()->prelim()) {
|
||||||
|
|
@ -1304,7 +1269,7 @@ void WidthVisitor::width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Ofixed_L(AstNodeUniop* nodep, AstNUser* vup, int width) {
|
void width_Ofixed_L(AstNodeUniop* nodep, AstNUser* vup, int width) {
|
||||||
// Widths: out width = specified width
|
// Widths: out width = specified width
|
||||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||||
if (vup->c()->prelim()) {
|
if (vup->c()->prelim()) {
|
||||||
|
|
@ -1313,7 +1278,7 @@ void WidthVisitor::width_Ofixed_L(AstNodeUniop* nodep, AstNUser* vup, int width)
|
||||||
nodep->width(width,width);
|
nodep->width(width,width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Olhs_L(AstNodeUniop* nodep, AstNUser* vup) {
|
void 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"
|
||||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||||
|
|
@ -1329,7 +1294,7 @@ void WidthVisitor::width_Olhs_L(AstNodeUniop* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Olhs_Lforce(AstNodeUniop* nodep, AstNUser* vup) {
|
void width_Olhs_Lforce(AstNodeUniop* nodep, AstNUser* vup) {
|
||||||
// Widths: out width = lhs width
|
// Widths: out width = lhs width
|
||||||
// It always comes exactly from LHS; ignores any upper operand
|
// It always comes exactly from LHS; ignores any upper operand
|
||||||
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!");
|
||||||
|
|
@ -1346,7 +1311,7 @@ void WidthVisitor::width_Olhs_Lforce(AstNodeUniop* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Olhs_L_R32(AstNode* nodep, AstNUser* vup) {
|
void width_Olhs_L_R32(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: Output width from lhs, rhs<33 bits
|
// Widths: Output width from lhs, rhs<33 bits
|
||||||
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
||||||
if (vup->c()->prelim()) {
|
if (vup->c()->prelim()) {
|
||||||
|
|
@ -1365,7 +1330,7 @@ void WidthVisitor::width_Olhs_L_R32(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidthVisitor::width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
||||||
// Widths: out width = lhs width = rhs width
|
// Widths: out width = lhs width = rhs width
|
||||||
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
if (!nodep->op2p()) nodep->v3fatalSrc("For binary ops only!");
|
||||||
// If errors are off, we need to follow the spec; thus we really need to do the max()
|
// If errors are off, we need to follow the spec; thus we really need to do the max()
|
||||||
|
|
@ -1398,40 +1363,19 @@ void WidthVisitor::width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
|
||||||
|
|
||||||
class WidthCommitVisitor : public AstNVisitor {
|
|
||||||
// Now that all widthing is complete,
|
|
||||||
// Copy all width() to widthMin(). V3Const expects this
|
|
||||||
private:
|
|
||||||
// VISITORS
|
|
||||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
|
||||||
nodep->width(nodep->width(),nodep->width());
|
|
||||||
if ((nodep->width() != nodep->num().width()) || !nodep->num().sized()) {
|
|
||||||
V3Number num (nodep->fileline(), nodep->width());
|
|
||||||
num.opAssign(nodep->num());
|
|
||||||
num.isSigned(nodep->isSigned());
|
|
||||||
AstNode* newp = new AstConst(nodep->fileline(), num);
|
|
||||||
nodep->replaceWith(newp);
|
|
||||||
//if (debug()>4) nodep->dumpTree(cout," fixConstSize_old: ");
|
|
||||||
//if (debug()>4) newp->dumpTree(cout," _new: ");
|
|
||||||
pushDeletep(nodep); nodep=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
|
||||||
nodep->width(nodep->width(),nodep->width());
|
|
||||||
nodep->iterateChildren(*this);
|
|
||||||
}
|
|
||||||
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
|
|
||||||
// This check could go anywhere after V3Param
|
|
||||||
nodep->v3fatalSrc("Presels should have been removed before this point");
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
// CONSTUCTORS
|
// CONSTUCTORS
|
||||||
WidthCommitVisitor(AstNetlist* nodep) {
|
WidthVisitor(bool paramsOnly) {
|
||||||
nodep->accept(*this);
|
m_paramsOnly = paramsOnly;
|
||||||
|
m_taskDepth = 0;
|
||||||
|
m_cellRangep = NULL;
|
||||||
|
m_casep = NULL;
|
||||||
|
m_funcp = NULL;
|
||||||
}
|
}
|
||||||
virtual ~WidthCommitVisitor() {}
|
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||||
|
return nodep->acceptSubtreeReturnEdits(*this, WidthVP(ANYSIZE,0,BOTH).p());
|
||||||
|
}
|
||||||
|
virtual ~WidthVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
//*************************************************************************
|
||||||
|
// DESCRIPTION: Verilator: Cleanup stage in V3Width
|
||||||
|
//
|
||||||
|
// Code available from: http://www.veripool.org/verilator
|
||||||
|
//
|
||||||
|
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
// Version 2.0.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
#ifndef _V3WIDTHCOMMIT_H_
|
||||||
|
#define _V3WIDTHCOMMIT_H_ 1
|
||||||
|
#include "config_build.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
|
#include "V3Error.h"
|
||||||
|
#include "V3Ast.h"
|
||||||
|
|
||||||
|
#ifndef _V3WIDTH_CPP_
|
||||||
|
# error "V3WidthCommit for V3Width internal use only"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
class WidthCommitVisitor : public AstNVisitor {
|
||||||
|
// Now that all widthing is complete,
|
||||||
|
// Copy all width() to widthMin(). V3Const expects this
|
||||||
|
private:
|
||||||
|
// VISITORS
|
||||||
|
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||||
|
nodep->width(nodep->width(),nodep->width());
|
||||||
|
if ((nodep->width() != nodep->num().width()) || !nodep->num().sized()) {
|
||||||
|
V3Number num (nodep->fileline(), nodep->width());
|
||||||
|
num.opAssign(nodep->num());
|
||||||
|
num.isSigned(nodep->isSigned());
|
||||||
|
AstNode* newp = new AstConst(nodep->fileline(), num);
|
||||||
|
nodep->replaceWith(newp);
|
||||||
|
//if (debug()>4) nodep->dumpTree(cout," fixConstSize_old: ");
|
||||||
|
//if (debug()>4) newp->dumpTree(cout," _new: ");
|
||||||
|
pushDeletep(nodep); nodep=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
|
nodep->width(nodep->width(),nodep->width());
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
}
|
||||||
|
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
|
||||||
|
// This check could go anywhere after V3Param
|
||||||
|
nodep->v3fatalSrc("Presels should have been removed before this point");
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
// CONSTUCTORS
|
||||||
|
WidthCommitVisitor(AstNetlist* nodep) {
|
||||||
|
nodep->accept(*this);
|
||||||
|
}
|
||||||
|
virtual ~WidthCommitVisitor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
|
#endif // Guard
|
||||||
Loading…
Reference in New Issue