mirror of
https://github.com/verilator/verilator.git
synced 2025-04-25 10:06:54 +00:00
Internals: Remove AstVar methods in preference of going via dtype
This commit is contained in:
parent
fd38216eda
commit
8e6846d9da
@ -1197,8 +1197,8 @@ struct AstNodeDType : public AstNode {
|
||||
AstNodeDType(FileLine* fl) : AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeDType)
|
||||
// Accessors
|
||||
virtual AstBasicDType* basicp() = 0; // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() = 0; // recurses over typedefs to next non-typeref type
|
||||
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type
|
||||
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
};
|
||||
|
@ -153,8 +153,8 @@ struct AstArrayDType : public AstNodeDType {
|
||||
AstRange* arrayp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||
void arrayp(AstRange* nodep) { setOp2p(nodep); }
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() { return this; }
|
||||
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||
virtual int widthTotalBytes() const { return elementsConst() * dtypep()->widthTotalBytes(); }
|
||||
int msb() const { return arrayp()->msbConst(); }
|
||||
@ -203,6 +203,9 @@ private:
|
||||
public:
|
||||
ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE)
|
||||
virtual void dump(ostream& str);
|
||||
virtual V3Hash sameHash() const { return V3Hash(keyword()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return samep->castBasicDType()->keyword() == keyword(); }
|
||||
virtual string name() const {
|
||||
if (rangep()) return string(m_keyword.ascii())+"[]";
|
||||
else return m_keyword.ascii();
|
||||
@ -213,8 +216,8 @@ public:
|
||||
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
|
||||
}
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() { return this; } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() { return this; }
|
||||
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
bool isBitLogic() const { return keyword().isBitLogic(); }
|
||||
@ -247,10 +250,13 @@ public:
|
||||
virtual void cloneRelink() { if (m_defp && m_defp->clonep()) {
|
||||
m_defp = m_defp->clonep()->castTypedef();
|
||||
}}
|
||||
virtual V3Hash sameHash() const { return V3Hash(skipRefp()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return skipRefp()->sameTree(samep->castRefDType()->skipRefp()); }
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; }
|
||||
virtual AstBasicDType* basicp() { return defp() ? dtypep()->basicp() : NULL; }
|
||||
virtual AstNodeDType* skipRefp() {
|
||||
virtual AstBasicDType* basicp() const { return defp() ? dtypep()->basicp() : NULL; }
|
||||
virtual AstNodeDType* skipRefp() const {
|
||||
// Skip past both the Ref and the Typedef
|
||||
if (defp()) return defp()->dtypep();
|
||||
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||
@ -436,7 +442,9 @@ public:
|
||||
, m_name(name) {
|
||||
init();
|
||||
combineType(type); setOp1p(dtypep);
|
||||
width(msb()-lsb()+1,0);
|
||||
if (dtypep && dtypep->basicp()) {
|
||||
width(dtypep->basicp()->width(), 0);
|
||||
} else width(1, 0);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstLogicPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
@ -468,14 +476,15 @@ public:
|
||||
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
||||
void combineType(AstVarType type);
|
||||
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
|
||||
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
|
||||
AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
|
||||
AstNodeDType* dtypeDimensionp(int depth) const;
|
||||
AstNode* initp() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const)
|
||||
void initp(AstNode* nodep) { setOp3p(nodep); }
|
||||
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
||||
AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse
|
||||
bool hasSimpleInit() const { return (op3p() && !op3p()->castInitArray()); }
|
||||
void dtypep(AstRange* nodep) { setOp1p(nodep); }
|
||||
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
||||
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
||||
void attrScClocked(bool flag) { m_scClocked = flag; }
|
||||
@ -493,7 +502,6 @@ public:
|
||||
void funcReturn(bool flag) { m_funcReturn = flag; }
|
||||
void trace(bool flag) { m_trace=flag; }
|
||||
// METHODS
|
||||
AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual void name(const string& name) { m_name = name; }
|
||||
bool isInput() const { return m_input; }
|
||||
bool isOutput() const { return m_output; }
|
||||
@ -536,11 +544,6 @@ public:
|
||||
bool attrFileDescr() const { return m_fileDescr; }
|
||||
bool attrScClocked() const { return m_scClocked; }
|
||||
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||
int msb() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msb() : 0; }
|
||||
int lsb() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->lsb() : 0; }
|
||||
int msbEndianed() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msbEndianed() : 0; }
|
||||
int lsbEndianed() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->lsbEndianed() : 0; }
|
||||
int msbMaxSelect() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msbMaxSelect() : 0; }
|
||||
uint32_t arrayElements() const; // 1, or total multiplication of all dimensions
|
||||
virtual string verilogKwd() const;
|
||||
void propagateAttrFrom(AstVar* fromp) {
|
||||
@ -1780,7 +1783,9 @@ public:
|
||||
widthSignedFrom(varp);
|
||||
m_code = 0;
|
||||
m_codeInc = varp->arrayElements() * varp->widthWords();
|
||||
m_lsb = varp->lsbEndianed(); m_msb = varp->msbEndianed();
|
||||
AstBasicDType* bdtypep = varp->basicp();
|
||||
m_msb = bdtypep ? bdtypep->msbEndianed() : 0;
|
||||
m_lsb = bdtypep ? bdtypep->lsbEndianed() : 0;
|
||||
if (AstArrayDType* adtypep = varp->dtypeSkipRefp()->castArrayDType()) {
|
||||
m_arrayLsb = adtypep->arrayp()->lsbConst();
|
||||
m_arrayMsb = adtypep->arrayp()->msbConst();
|
||||
|
@ -310,10 +310,11 @@ private:
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||
AstVar* varp = varrefp->varp();
|
||||
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
|
||||
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
|
||||
if (m_warn
|
||||
&& nodep->lsbp()->castConst()
|
||||
&& nodep->widthp()->castConst()
|
||||
&& (!varp->basicp()->rangep() || varp->msb())) { // else it's non-resolvable parameterized
|
||||
&& (!bdtypep->rangep() || bdtypep->msb())) { // else it's non-resolvable parameterized
|
||||
if (nodep->lsbp()->castConst()->num().isFourState()
|
||||
|| nodep->widthp()->castConst()->num().isFourState()) {
|
||||
nodep->v3error("Selection index is constantly unknown or tristated: "
|
||||
@ -321,14 +322,14 @@ private:
|
||||
// Replacing nodep will make a mess above, so we replace the offender
|
||||
replaceZero(nodep->lsbp());
|
||||
}
|
||||
else if ((nodep->msbConst() > varp->msbMaxSelect())
|
||||
|| (nodep->lsbConst() > varp->msbMaxSelect())) {
|
||||
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|
||||
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
|
||||
// See also warning in V3Width
|
||||
nodep->v3error("Selection index out of range: "
|
||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
||||
<<" outside "<<varp->msbMaxSelect()<<":0"
|
||||
<<(varp->lsb()>=0 ? ""
|
||||
:" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)"));
|
||||
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
|
||||
<<(bdtypep->lsb()>=0 ? ""
|
||||
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
|
||||
// Don't replace with zero, we'll do it later
|
||||
}
|
||||
}
|
||||
|
@ -755,6 +755,7 @@ public:
|
||||
// Internal EmitCStmts
|
||||
|
||||
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
@ -786,12 +787,12 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
|
||||
if (!nodep->isWide())
|
||||
puts("("+nodep->name()
|
||||
+","+cvtToStr(nodep->msb())
|
||||
+","+cvtToStr(nodep->lsb()));
|
||||
+","+cvtToStr(basicp->msb())
|
||||
+","+cvtToStr(basicp->lsb()));
|
||||
else puts("W("+nodep->name()
|
||||
+","+cvtToStr(nodep->msb())
|
||||
+","+cvtToStr(nodep->lsb())
|
||||
+","+cvtToStr(nodep->widthWords()));
|
||||
+","+cvtToStr(basicp->msb())
|
||||
+","+cvtToStr(basicp->lsb())
|
||||
+","+cvtToStr(basicp->widthWords()));
|
||||
puts(");\n");
|
||||
}
|
||||
} else {
|
||||
@ -818,8 +819,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
puts(","+cvtToStr(nodep->msb())+","+cvtToStr(nodep->lsb()));
|
||||
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
|
||||
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb()));
|
||||
if (basicp->isWide()) puts(","+cvtToStr(basicp->widthWords()));
|
||||
puts(");\n");
|
||||
}
|
||||
}
|
||||
|
@ -238,12 +238,21 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* mod
|
||||
// Note this module calles cloneTree() via new AstVar
|
||||
AstVar* pinVarp = pinp->modVarp();
|
||||
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
|
||||
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
|
||||
AstBasicDType* connBasicp = NULL;
|
||||
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
|
||||
//
|
||||
if (connectRefp
|
||||
&& connectRefp->width() == pinVarp->width()
|
||||
&& connectRefp->varp()->lsb() == pinVarp->lsb()
|
||||
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
|
||||
&& pinp->width() == pinVarp->width()
|
||||
&& 1) {
|
||||
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
|
||||
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
|
||||
// Done. Same data type
|
||||
} else if (connBasicp
|
||||
&& pinBasicp
|
||||
&& connBasicp->width() == pinBasicp->width()
|
||||
&& connBasicp->lsb() == pinBasicp->lsb()
|
||||
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
|
||||
&& pinp->width() == pinVarp->width()
|
||||
&& 1) {
|
||||
// Done. One to one interconnect won't need a temporary variable.
|
||||
} else if (pinp->exprp()->castConst()) {
|
||||
// Done. Constant.
|
||||
|
@ -301,8 +301,8 @@ private:
|
||||
int fromlsb = 0;
|
||||
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
|
||||
if (varrp && varrp->varp()->basicp()->rangep()) { // Selecting a bit from a multibit register
|
||||
frommsb = varrp->varp()->msbMaxSelect(); // Corrected for negative lsb
|
||||
fromlsb = varrp->varp()->lsb();
|
||||
frommsb = varrp->varp()->basicp()->msbMaxSelect(); // Corrected for negative lsb
|
||||
fromlsb = varrp->varp()->basicp()->lsb();
|
||||
}
|
||||
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
|
||||
nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,FINAL).p());
|
||||
|
@ -149,11 +149,11 @@ private:
|
||||
varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp)
|
||||
if (varp->basicp()->rangep()->littleEndian()) {
|
||||
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
|
||||
AstNode* newp = newSubNeg(varp->msb(), underp);
|
||||
AstNode* newp = newSubNeg(varp->basicp()->msb(), underp);
|
||||
return newp;
|
||||
} else {
|
||||
// reg [3:1] needs a SUB(under,1)
|
||||
AstNode* newp = newSubNeg(underp, varp->lsb());
|
||||
AstNode* newp = newSubNeg(underp, varp->basicp()->lsb());
|
||||
return newp;
|
||||
}
|
||||
}
|
||||
@ -287,19 +287,18 @@ private:
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* widthp = nodep->thsp()->unlinkFrBack();
|
||||
int width = widthp->castConst()->toSInt();
|
||||
AstVar* varp = varFromBasefrom(basefromp);
|
||||
//AstVar* varp = varFromBasefrom(basefromp);
|
||||
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<<widthp->prettyName());
|
||||
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
|
||||
AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, width!=1);
|
||||
if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
||||
if (adtypep) {} // Unused
|
||||
AstSel* newp = NULL;
|
||||
if (nodep->castSelPlus()) {
|
||||
if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
|
||||
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
|
||||
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
|
||||
newp = new AstSel (nodep->fileline(),
|
||||
fromp,
|
||||
newSubNeg((varp->msb()-width+1), rhsp),
|
||||
newSubNeg((adtypep->msb()-width+1), rhsp),
|
||||
widthp);
|
||||
} else {
|
||||
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
|
||||
@ -309,17 +308,17 @@ private:
|
||||
widthp);
|
||||
}
|
||||
} else if (nodep->castSelMinus()) {
|
||||
if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
|
||||
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
|
||||
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
|
||||
newp = new AstSel (nodep->fileline(),
|
||||
fromp,
|
||||
newSubNeg(varp->msb(), rhsp),
|
||||
newSubNeg(adtypep->msb(), rhsp),
|
||||
widthp);
|
||||
} else {
|
||||
// SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#)
|
||||
newp = new AstSel (nodep->fileline(),
|
||||
fromp,
|
||||
newSubNeg(rhsp, varp->lsb()+(width-1)),
|
||||
newSubNeg(rhsp, adtypep->lsb()+(width-1)),
|
||||
widthp);
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user