forked from github/verilator
Internals: AstRefDType points to type _below_ AstTyperef. No functional change
This commit is contained in:
parent
a39c81c63f
commit
b104ab9491
@ -193,5 +193,5 @@ C<verilator>
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
|
||||
### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree"
|
||||
### End:
|
||||
|
@ -1269,16 +1269,18 @@ private:
|
||||
string m_name; // Name of variable
|
||||
string m_hiername; // Scope converted into name-> for emitting
|
||||
bool m_hierThis; // Hiername points to "this" function
|
||||
void init();
|
||||
public:
|
||||
AstNodeVarRef(FileLine* fl, const string& name, bool lvalue)
|
||||
: AstNodeMath(fl), m_lvalue(lvalue), m_varp(NULL), m_varScopep(NULL),
|
||||
m_packagep(NULL), m_name(name), m_hierThis(false) {
|
||||
init();
|
||||
}
|
||||
AstNodeVarRef(FileLine* fl, const string& name, AstVar* varp, bool lvalue)
|
||||
: AstNodeMath(fl), m_lvalue(lvalue), m_varp(varp), m_varScopep(NULL),
|
||||
m_packagep(NULL), m_name(name), m_hierThis(false) {
|
||||
// May have varp==NULL
|
||||
if (m_varp) widthSignedFrom((AstNode*)m_varp);
|
||||
init();
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeVarRef)
|
||||
virtual bool broken() const;
|
||||
@ -1331,6 +1333,7 @@ struct AstNodeDType : public AstNode {
|
||||
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,...
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
};
|
||||
|
||||
struct AstNodeSel : public AstNodeBiop {
|
||||
@ -1512,4 +1515,6 @@ inline bool AstNode::isOne() { return (this->castConst() && this->castConst
|
||||
inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); }
|
||||
inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); }
|
||||
|
||||
inline void AstNodeVarRef::init() { if (m_varp) widthSignedFrom((AstNode*)m_varp); }
|
||||
|
||||
#endif // Guard
|
||||
|
@ -68,11 +68,11 @@ public:
|
||||
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)) { width(1,0); }
|
||||
,m_num(V3Number(fl,1,0)) { dtypeChgLogicBool(); }
|
||||
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)) { width(1,0); }
|
||||
,m_num(V3Number(fl,1,1)) { dtypeChgLogicBool(); }
|
||||
|
||||
ASTNODE_NODE_FUNCS(Const, CONST)
|
||||
virtual string name() const { return num().ascii(); } // * = Value
|
||||
@ -347,43 +347,43 @@ struct AstConstDType : public AstNodeDType {
|
||||
|
||||
struct AstRefDType : public AstNodeDType {
|
||||
private:
|
||||
AstTypedef* m_defp;
|
||||
string m_name;
|
||||
AstNodeDType* m_defp; // data type pointed to, BELOW the AstTypedef
|
||||
string m_name; // Name of an AstTypedef
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstRefDType(FileLine* fl, const string& name)
|
||||
: AstNodeDType(fl), m_defp(NULL), m_name(name), m_packagep(NULL) {}
|
||||
AstRefDType(FileLine* fl, AstTypedef* defp)
|
||||
: AstNodeDType(fl), m_defp(defp), m_name(defp->name()), m_packagep(NULL) {
|
||||
AstRefDType(FileLine* fl, AstNodeDType* defp)
|
||||
: AstNodeDType(fl), m_defp(defp), m_packagep(NULL) {
|
||||
widthSignedFrom(defp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(RefDType, REFDTYPE)
|
||||
// METHODS
|
||||
virtual bool broken() const { return m_defp && !m_defp->brokeExists(); }
|
||||
virtual void cloneRelink() { if (m_defp && m_defp->clonep()) {
|
||||
m_defp = m_defp->clonep()->castTypedef();
|
||||
m_defp = m_defp->clonep()->castNodeDType();
|
||||
}}
|
||||
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() const { return defp() ? dtypep()->basicp() : NULL; }
|
||||
virtual AstBasicDType* basicp() const { return defp() ? defp()->basicp() : NULL; }
|
||||
virtual AstNodeDType* skipRefp() const {
|
||||
// Skip past both the Ref and the Typedef
|
||||
if (defp()) return defp()->dtypep()->skipRefp();
|
||||
if (defp()) return defp()->skipRefp();
|
||||
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||
}
|
||||
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
|
||||
virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); }
|
||||
virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); }
|
||||
void name(const string& flag) { m_name = flag; }
|
||||
AstNodeDType* dtypep() const {
|
||||
if (defp()) return defp()->dtypep();
|
||||
if (defp()) return defp();
|
||||
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||
}
|
||||
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
|
||||
AstTypedef* defp() const { return m_defp; }
|
||||
void defp(AstTypedef* nodep) { m_defp=nodep; }
|
||||
AstNodeDType* defp() const { return m_defp; }
|
||||
void defp(AstNodeDType* nodep) { m_defp=nodep; }
|
||||
AstPackage* packagep() const { return m_packagep; }
|
||||
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||
};
|
||||
@ -496,7 +496,7 @@ struct AstWordSel : public AstNodeSel {
|
||||
// Select a single word from a multi-word wide value
|
||||
AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeSel(fl, fromp, bitp) {
|
||||
width(VL_WORDSIZE,VL_WORDSIZE); // Always used on, and returns word entities
|
||||
dtypeChgUInt32(); // Always used on IData arrays so returns word entities
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(WordSel, WORDSEL)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; }
|
||||
@ -2363,8 +2363,8 @@ public:
|
||||
ASTNODE_NODE_FUNCS(TraceDecl, TRACEDECL)
|
||||
virtual string name() const { return m_showname; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
string showname() const { return m_showname; } // * = Var name
|
||||
virtual bool same(AstNode* samep) const { return false; }
|
||||
string showname() const { return m_showname; } // * = Var name
|
||||
// Details on what we're tracing
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code=code; }
|
||||
|
@ -677,10 +677,10 @@ class EmitCImp : EmitCStmts {
|
||||
puts(" | (");
|
||||
}
|
||||
changep->lhsp()->iterateAndNext(*this);
|
||||
if (changep->isWide()) puts("["+cvtToStr(word)+"]");
|
||||
if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]");
|
||||
puts(" ^ ");
|
||||
changep->rhsp()->iterateAndNext(*this);
|
||||
if (changep->isWide()) puts("["+cvtToStr(word)+"]");
|
||||
if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]");
|
||||
puts(")");
|
||||
}
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ private:
|
||||
defp = m_curVarsp->findIdUpward(nodep->name())->castTypedef();
|
||||
}
|
||||
if (!defp) { nodep->v3error("Can't find typedef: "<<nodep->prettyName()); }
|
||||
nodep->defp(defp);
|
||||
nodep->defp(defp->dtypep());
|
||||
nodep->packagep(packageFor(defp));
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
|
@ -136,7 +136,7 @@ private:
|
||||
virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); }
|
||||
virtual void visit(AstLogIf* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } // Conversion from real not in IEEE, but a fallout
|
||||
virtual void visit(AstLogIff* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } // Conversion from real not in IEEE, but a fallout
|
||||
|
||||
|
||||
// Widths: 1 bit out, Any width lhs
|
||||
virtual void visit(AstRedAnd* nodep, AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); }
|
||||
virtual void visit(AstRedOr* nodep, AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); }
|
||||
@ -145,7 +145,7 @@ private:
|
||||
virtual void visit(AstIsUnknown* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,true); } // Allow real
|
||||
virtual void visit(AstOneHot* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); }
|
||||
virtual void visit(AstOneHot0* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); }
|
||||
|
||||
|
||||
// These have different node types, as they operate differently
|
||||
// Must add to case statement below,
|
||||
// Widths: 1 bit out, lhs width == rhs width. real if lhs|rhs real
|
||||
@ -199,7 +199,7 @@ private:
|
||||
virtual void visit(AstNegate* nodep, AstNUser* vup) { visit_math_Orus_Dreplace(nodep,vup,true); }
|
||||
// Unary never real
|
||||
virtual void visit(AstNot* nodep, AstNUser* vup) { visit_math_Orus_Dreplace(nodep,vup,false); }
|
||||
|
||||
|
||||
// Real: inputs and output real
|
||||
virtual void visit(AstAddD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); }
|
||||
virtual void visit(AstSubD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); }
|
||||
@ -215,18 +215,18 @@ private:
|
||||
virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
|
||||
virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
|
||||
virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
|
||||
|
||||
// Widths: out signed/unsigned width = lhs width, input un|signed
|
||||
|
||||
// Widths: out signed/unsigned width = lhs width, input un|signed
|
||||
virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::SIGNED); }
|
||||
virtual void visit(AstUnsigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::UNSIGNED); }
|
||||
|
||||
|
||||
// Widths: Output width from lhs, rhs<33 bits
|
||||
// Signed: If lhs signed
|
||||
virtual void visit(AstShiftL* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); }
|
||||
virtual void visit(AstShiftR* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); }
|
||||
// ShiftRS converts to ShiftR, but not vice-versa
|
||||
virtual void visit(AstShiftRS* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); }
|
||||
|
||||
|
||||
//========
|
||||
// Widths: Output real, input integer signed
|
||||
virtual void visit(AstBitsToRealD* nodep, AstNUser* vup) { visit_Or_Lu64(nodep,vup); }
|
||||
@ -235,7 +235,7 @@ private:
|
||||
// Widths: Output integer signed, input real
|
||||
virtual void visit(AstRToIS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); }
|
||||
virtual void visit(AstRToIRoundS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); }
|
||||
|
||||
|
||||
// Widths: Output integer unsigned, input real
|
||||
virtual void visit(AstRealToBits* nodep, AstNUser* vup) { visit_Ou64_Lr(nodep,vup); }
|
||||
|
||||
@ -295,7 +295,7 @@ private:
|
||||
checkCvtUS(nodep->rhsp());
|
||||
nodep->width(nodep->lhsp()->width() + nodep->rhsp()->width(),
|
||||
nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin());
|
||||
nodep->numeric(AstNumeric::UNSIGNED);
|
||||
nodep->numeric(AstNumeric::UNSIGNED);
|
||||
// Cleanup zero width Verilog2001 {x,{0{foo}}} now,
|
||||
// otherwise having width(0) will cause later assertions to fire
|
||||
if (AstReplicate* repp=nodep->lhsp()->castReplicate()) {
|
||||
@ -613,6 +613,7 @@ private:
|
||||
// But also cleanup array size
|
||||
nodep->arrayp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->widthFrom(nodep->dtypep());
|
||||
UINFO(4,"dtWidthed "<<nodep<<endl);
|
||||
}
|
||||
virtual void visit(AstBasicDType* nodep, AstNUser* vup) {
|
||||
if (nodep->rangep()) {
|
||||
@ -621,15 +622,18 @@ private:
|
||||
}
|
||||
// else width in node is correct; it was set based on keyword().width()
|
||||
// at construction time. Ditto signed, so "unsigned byte" etc works right.
|
||||
UINFO(4,"dtWidthed "<<nodep<<endl);
|
||||
}
|
||||
virtual void visit(AstConstDType* nodep, AstNUser* vup) {
|
||||
nodep->iterateChildren(*this, vup);
|
||||
nodep->widthFrom(nodep->dtypep());
|
||||
UINFO(4,"dtWidthed "<<nodep<<endl);
|
||||
}
|
||||
virtual void visit(AstRefDType* nodep, AstNUser* vup) {
|
||||
nodep->iterateChildren(*this, vup);
|
||||
if (nodep->defp()) nodep->defp()->iterate(*this,vup);
|
||||
nodep->widthSignedFrom(nodep->dtypeSkipRefp());
|
||||
UINFO(4,"dtWidthed "<<nodep<<endl);
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep, AstNUser* vup) {
|
||||
nodep->iterateChildren(*this, vup);
|
||||
@ -1365,7 +1369,7 @@ private:
|
||||
// COMPARES
|
||||
// Widths: 1 bit out, lhs width == rhs width
|
||||
// Signed: if RHS&LHS signed, OPERATOR CHANGES to signed flavor
|
||||
// Real: allowed on RHS, if RHS|LHS is real, both become real, and OPERATOR CHANGES
|
||||
// Real: allowed on RHS, if RHS|LHS is real, both become real, and OPERATOR CHANGES
|
||||
if (vup->c()->prelim()) {
|
||||
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());
|
||||
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());
|
||||
|
@ -492,7 +492,7 @@ void process () {
|
||||
// Bits between widthMin() and width() are irrelevant, but may be non zero.
|
||||
v3Global.assertWidthsMatch(false);
|
||||
|
||||
// Make all operations a multiple of 32 bits
|
||||
// Make all math operations either 8, 16, 32 or 64 bits
|
||||
V3Clean::cleanAll(v3Global.rootp());
|
||||
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("clean.tree"));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user