Internals: Make consistent left/right/lo/hi accessors to ranges.
Change order of Range to store always left:right. XML output changes to now show left:right (previously info was lost), no other change intended.
This commit is contained in:
parent
b32d530000
commit
cd248f6bd7
105
src/V3Ast.h
105
src/V3Ast.h
|
|
@ -981,61 +981,53 @@ inline std::ostream& operator<<(std::ostream& os, const VParseRefExp& rhs) {
|
||||||
|
|
||||||
class VNumRange final {
|
class VNumRange final {
|
||||||
public:
|
public:
|
||||||
int m_hi = 0; // HI part, HI always >= LO
|
int m_left = 0;
|
||||||
int m_lo = 0; // LO
|
int m_right = 0;
|
||||||
union {
|
bool m_ranged = false; // Has a range
|
||||||
int mu_flags;
|
|
||||||
struct {
|
|
||||||
bool m_ranged : 1; // Has a range
|
|
||||||
bool m_littleEndian : 1; // Bit vector is little endian
|
|
||||||
};
|
|
||||||
};
|
|
||||||
bool operator==(const VNumRange& rhs) const {
|
bool operator==(const VNumRange& rhs) const {
|
||||||
return m_hi == rhs.m_hi && m_lo == rhs.m_lo && mu_flags == rhs.mu_flags;
|
return m_left == rhs.m_left && m_right == rhs.m_right && m_ranged == rhs.m_ranged;
|
||||||
}
|
}
|
||||||
bool operator<(const VNumRange& rhs) const {
|
bool operator<(const VNumRange& rhs) const {
|
||||||
if ((m_hi < rhs.m_hi)) return true;
|
if ((m_left < rhs.m_left)) return true;
|
||||||
if (!(m_hi == rhs.m_hi)) return false; // lhs > rhs
|
if (!(m_left == rhs.m_left)) return false; // lhs > rhs
|
||||||
if ((m_lo < rhs.m_lo)) return true;
|
if ((m_right < rhs.m_right)) return true;
|
||||||
if (!(m_lo == rhs.m_lo)) return false; // lhs > rhs
|
if (!(m_right == rhs.m_right)) return false; // lhs > rhs
|
||||||
if ((mu_flags < rhs.mu_flags)) return true;
|
if ((m_ranged < rhs.m_ranged)) return true;
|
||||||
if (!(mu_flags == rhs.mu_flags)) return false; // lhs > rhs
|
if (!(m_ranged == rhs.m_ranged)) return false; // lhs > rhs
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
class LeftRight {};
|
VNumRange() {}
|
||||||
VNumRange()
|
VNumRange(int hi, int lo, bool littleEndian) { init(hi, lo, littleEndian); }
|
||||||
: mu_flags{0} {}
|
VNumRange(int left, int right)
|
||||||
VNumRange(int hi, int lo, bool littleEndian)
|
: m_left{left}
|
||||||
: mu_flags{0} {
|
, m_right{right}
|
||||||
init(hi, lo, littleEndian);
|
, m_ranged{true} {}
|
||||||
}
|
|
||||||
VNumRange(LeftRight, int left, int right)
|
|
||||||
: mu_flags{0} {
|
|
||||||
init((right > left) ? right : left, (right > left) ? left : right, (right > left));
|
|
||||||
}
|
|
||||||
~VNumRange() = default;
|
~VNumRange() = default;
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
void init(int hi, int lo, bool littleEndian) {
|
void init(int hi, int lo, bool littleEndian) {
|
||||||
m_hi = hi;
|
if (lo > hi) {
|
||||||
m_lo = lo;
|
int t = hi;
|
||||||
mu_flags = 0;
|
hi = lo;
|
||||||
|
lo = t;
|
||||||
|
}
|
||||||
|
m_left = littleEndian ? lo : hi;
|
||||||
|
m_right = littleEndian ? hi : lo;
|
||||||
m_ranged = true;
|
m_ranged = true;
|
||||||
m_littleEndian = littleEndian;
|
|
||||||
}
|
}
|
||||||
int hi() const { return m_hi; }
|
int left() const { return m_left; }
|
||||||
int lo() const { return m_lo; }
|
int right() const { return m_right; }
|
||||||
int left() const { return littleEndian() ? lo() : hi(); } // How to show a declaration
|
int hi() const { return m_left > m_right ? m_left : m_right; } // How to show a declaration
|
||||||
int right() const { return littleEndian() ? hi() : lo(); }
|
int lo() const { return m_left > m_right ? m_right : m_left; } // How to show a declaration
|
||||||
int leftToRightInc() const { return littleEndian() ? 1 : -1; }
|
int leftToRightInc() const { return littleEndian() ? 1 : -1; }
|
||||||
int elements() const { return hi() - lo() + 1; }
|
int elements() const { return hi() - lo() + 1; }
|
||||||
bool ranged() const { return m_ranged; }
|
bool ranged() const { return m_ranged; }
|
||||||
bool littleEndian() const { return m_littleEndian; }
|
bool littleEndian() const { return m_left < m_right; }
|
||||||
int hiMaxSelect() const {
|
int hiMaxSelect() const {
|
||||||
return (lo() < 0 ? hi() - lo() : hi());
|
return (lo() < 0 ? hi() - lo() : hi());
|
||||||
} // Maximum value a [] select may index
|
} // Maximum value a [] select may index
|
||||||
bool representableByWidth() const { // Could be represented by just width=1, or [width-1:0]
|
bool representableByWidth() const { // Could be represented by just width=1, or [width-1:0]
|
||||||
return (!m_ranged || (m_lo == 0 && m_hi >= 1 && !m_littleEndian));
|
return (!m_ranged || (m_right == 0 && m_left >= 1));
|
||||||
}
|
}
|
||||||
void dump(std::ostream& str) const {
|
void dump(std::ostream& str) const {
|
||||||
if (ranged()) {
|
if (ranged()) {
|
||||||
|
|
@ -2491,12 +2483,11 @@ public:
|
||||||
virtual void dump(std::ostream& str) const override;
|
virtual void dump(std::ostream& str) const override;
|
||||||
// For basicp() we reuse the size to indicate a "fake" basic type of same size
|
// For basicp() we reuse the size to indicate a "fake" basic type of same size
|
||||||
virtual AstBasicDType* basicp() const override {
|
virtual AstBasicDType* basicp() const override {
|
||||||
return (isFourstate() ? VN_CAST(
|
return (isFourstate()
|
||||||
findLogicRangeDType(VNumRange(width() - 1, 0, false), width(), numeric()),
|
? VN_CAST(findLogicRangeDType(VNumRange{width() - 1, 0}, width(), numeric()),
|
||||||
BasicDType)
|
BasicDType)
|
||||||
: VN_CAST(findBitRangeDType(VNumRange(width() - 1, 0, false),
|
: VN_CAST(findBitRangeDType(VNumRange{width() - 1, 0}, width(), numeric()),
|
||||||
width(), numeric()),
|
BasicDType));
|
||||||
BasicDType));
|
|
||||||
}
|
}
|
||||||
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
||||||
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
||||||
|
|
@ -2526,9 +2517,9 @@ public:
|
||||||
const auto it = m_members.find(name);
|
const auto it = m_members.find(name);
|
||||||
return (it == m_members.end()) ? nullptr : it->second;
|
return (it == m_members.end()) ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
static int lsb() { return 0; }
|
static int lo() { return 0; }
|
||||||
int msb() const { return dtypep()->width() - 1; } // Packed classes look like arrays
|
int hi() const { return dtypep()->width() - 1; } // Packed classes look like arrays
|
||||||
VNumRange declRange() const { return VNumRange(msb(), lsb(), false); }
|
VNumRange declRange() const { return VNumRange{hi(), lo()}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
|
class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
|
||||||
|
|
@ -2554,17 +2545,17 @@ public:
|
||||||
}
|
}
|
||||||
virtual bool same(const AstNode* samep) const override {
|
virtual bool same(const AstNode* samep) const override {
|
||||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||||
return (msb() == asamep->msb() && subDTypep() == asamep->subDTypep()
|
return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep()
|
||||||
&& rangenp()->sameTree(asamep->rangenp()));
|
&& rangenp()->sameTree(asamep->rangenp()));
|
||||||
} // HashedDT doesn't recurse, so need to check children
|
} // HashedDT doesn't recurse, so need to check children
|
||||||
virtual bool similarDType(AstNodeDType* samep) const override {
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
||||||
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
|
||||||
return (asamep && type() == samep->type() && msb() == asamep->msb()
|
return (asamep && type() == samep->type() && hi() == asamep->hi()
|
||||||
&& rangenp()->sameTree(asamep->rangenp())
|
&& rangenp()->sameTree(asamep->rangenp())
|
||||||
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
||||||
}
|
}
|
||||||
virtual V3Hash sameHash() const override {
|
virtual V3Hash sameHash() const override {
|
||||||
return V3Hash(V3Hash(m_refDTypep), V3Hash(msb()), V3Hash(lsb()));
|
return V3Hash(V3Hash(m_refDTypep), V3Hash(hi()), V3Hash(lo()));
|
||||||
}
|
}
|
||||||
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||||
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); }
|
AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); }
|
||||||
|
|
@ -2588,8 +2579,10 @@ public:
|
||||||
virtual int widthTotalBytes() const override {
|
virtual int widthTotalBytes() const override {
|
||||||
return elementsConst() * subDTypep()->widthTotalBytes();
|
return elementsConst() * subDTypep()->widthTotalBytes();
|
||||||
}
|
}
|
||||||
int msb() const;
|
int left() const;
|
||||||
int lsb() const;
|
int right() const;
|
||||||
|
int hi() const;
|
||||||
|
int lo() const;
|
||||||
int elementsConst() const;
|
int elementsConst() const;
|
||||||
VNumRange declRange() const;
|
VNumRange declRange() const;
|
||||||
};
|
};
|
||||||
|
|
@ -3004,12 +2997,12 @@ inline void AstNodeVarRef::varp(AstVar* varp) {
|
||||||
inline bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); }
|
inline bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); }
|
||||||
|
|
||||||
inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
||||||
inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); }
|
inline int AstNodeArrayDType::left() const { return rangep()->leftConst(); }
|
||||||
inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); }
|
inline int AstNodeArrayDType::right() const { return rangep()->rightConst(); }
|
||||||
|
inline int AstNodeArrayDType::hi() const { return rangep()->hiConst(); }
|
||||||
|
inline int AstNodeArrayDType::lo() const { return rangep()->loConst(); }
|
||||||
inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); }
|
inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); }
|
||||||
inline VNumRange AstNodeArrayDType::declRange() const {
|
inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right()}; }
|
||||||
return VNumRange(msb(), lsb(), rangep()->littleEndian());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* AstNodeFTaskRef::broken() const {
|
inline const char* AstNodeFTaskRef::broken() const {
|
||||||
BROKEN_RTN(m_taskp && !m_taskp->brokeExists());
|
BROKEN_RTN(m_taskp && !m_taskp->brokeExists());
|
||||||
|
|
|
||||||
|
|
@ -185,46 +185,25 @@ public:
|
||||||
|
|
||||||
class AstRange final : public AstNodeRange {
|
class AstRange final : public AstNodeRange {
|
||||||
// Range specification, for use under variables and cells
|
// Range specification, for use under variables and cells
|
||||||
private:
|
|
||||||
bool m_littleEndian : 1; // Bit vector is little endian
|
|
||||||
public:
|
public:
|
||||||
AstRange(FileLine* fl, AstNode* msbp, AstNode* lsbp)
|
AstRange(FileLine* fl, AstNode* leftp, AstNode* rightp)
|
||||||
: ASTGEN_SUPER(fl) {
|
: ASTGEN_SUPER(fl) {
|
||||||
m_littleEndian = false;
|
setOp2p(leftp);
|
||||||
setOp2p(msbp);
|
setOp3p(rightp);
|
||||||
setOp3p(lsbp);
|
|
||||||
}
|
}
|
||||||
AstRange(FileLine* fl, int msb, int lsb)
|
AstRange(FileLine* fl, int left, int right)
|
||||||
: ASTGEN_SUPER(fl) {
|
: ASTGEN_SUPER(fl) {
|
||||||
m_littleEndian = false;
|
setOp2p(new AstConst(fl, left));
|
||||||
setOp2p(new AstConst(fl, msb));
|
setOp3p(new AstConst(fl, right));
|
||||||
setOp3p(new AstConst(fl, lsb));
|
|
||||||
}
|
}
|
||||||
AstRange(FileLine* fl, const VNumRange& range)
|
AstRange(FileLine* fl, const VNumRange& range)
|
||||||
: ASTGEN_SUPER(fl) {
|
: ASTGEN_SUPER(fl) {
|
||||||
m_littleEndian = range.littleEndian();
|
setOp2p(new AstConst(fl, range.left()));
|
||||||
setOp2p(new AstConst(fl, range.hi()));
|
setOp3p(new AstConst(fl, range.right()));
|
||||||
setOp3p(new AstConst(fl, range.lo()));
|
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Range)
|
ASTNODE_NODE_FUNCS(Range)
|
||||||
AstNode* msbp() const { return op2p(); } // op2 = Msb expression
|
AstNode* leftp() const { return op2p(); }
|
||||||
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
|
AstNode* rightp() const { return op3p(); }
|
||||||
AstNode* leftp() const {
|
|
||||||
return littleEndian() ? lsbp() : msbp();
|
|
||||||
} // How to show a declaration
|
|
||||||
AstNode* rightp() const { return littleEndian() ? msbp() : lsbp(); }
|
|
||||||
int msbConst() const {
|
|
||||||
AstConst* constp = VN_CAST(msbp(), Const);
|
|
||||||
return (constp ? constp->toSInt() : 0);
|
|
||||||
}
|
|
||||||
int lsbConst() const {
|
|
||||||
AstConst* constp = VN_CAST(lsbp(), Const);
|
|
||||||
return (constp ? constp->toSInt() : 0);
|
|
||||||
}
|
|
||||||
int elementsConst() const {
|
|
||||||
return (msbConst() > lsbConst()) ? msbConst() - lsbConst() + 1
|
|
||||||
: lsbConst() - msbConst() + 1;
|
|
||||||
}
|
|
||||||
int leftConst() const {
|
int leftConst() const {
|
||||||
AstConst* constp = VN_CAST(leftp(), Const);
|
AstConst* constp = VN_CAST(leftp(), Const);
|
||||||
return (constp ? constp->toSInt() : 0);
|
return (constp ? constp->toSInt() : 0);
|
||||||
|
|
@ -233,9 +212,18 @@ public:
|
||||||
AstConst* constp = VN_CAST(rightp(), Const);
|
AstConst* constp = VN_CAST(rightp(), Const);
|
||||||
return (constp ? constp->toSInt() : 0);
|
return (constp ? constp->toSInt() : 0);
|
||||||
}
|
}
|
||||||
int leftToRightInc() const { return littleEndian() ? 1 : -1; }
|
int hiConst() const {
|
||||||
bool littleEndian() const { return m_littleEndian; }
|
int l = leftConst();
|
||||||
void littleEndian(bool flag) { m_littleEndian = flag; }
|
int r = rightConst();
|
||||||
|
return l > r ? l : r;
|
||||||
|
}
|
||||||
|
int loConst() const {
|
||||||
|
int l = leftConst();
|
||||||
|
int r = rightConst();
|
||||||
|
return l > r ? r : l;
|
||||||
|
}
|
||||||
|
int elementsConst() const { return hiConst() - loConst() + 1; }
|
||||||
|
bool littleEndian() const { return leftConst() < rightConst(); }
|
||||||
virtual void dump(std::ostream& str) const override;
|
virtual void dump(std::ostream& str) const override;
|
||||||
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
||||||
virtual V3Hash sameHash() const override { return V3Hash(); }
|
virtual V3Hash sameHash() const override { return V3Hash(); }
|
||||||
|
|
@ -924,22 +912,20 @@ public:
|
||||||
bool isDpiPrimitive() const { // DPI uses a primitive type
|
bool isDpiPrimitive() const { // DPI uses a primitive type
|
||||||
return !isDpiBitVec() && !isDpiLogicVec();
|
return !isDpiBitVec() && !isDpiLogicVec();
|
||||||
}
|
}
|
||||||
// Generally the msb/lsb/etc funcs should be used instead
|
// Generally the lo/hi/left/right funcs should be used instead of nrange()
|
||||||
const VNumRange& nrange() const { return m.m_nrange; }
|
const VNumRange& nrange() const { return m.m_nrange; }
|
||||||
int msb() const { return (rangep() ? rangep()->msbConst() : m.m_nrange.hi()); }
|
int hi() const { return (rangep() ? rangep()->hiConst() : m.m_nrange.hi()); }
|
||||||
int lsb() const { return (rangep() ? rangep()->lsbConst() : m.m_nrange.lo()); }
|
int lo() const { return (rangep() ? rangep()->loConst() : m.m_nrange.lo()); }
|
||||||
int left() const { return littleEndian() ? lsb() : msb(); } // How to show a declaration
|
int left() const { return littleEndian() ? lo() : hi(); } // How to show a declaration
|
||||||
int right() const { return littleEndian() ? msb() : lsb(); }
|
int right() const { return littleEndian() ? hi() : lo(); }
|
||||||
bool littleEndian() const {
|
bool littleEndian() const {
|
||||||
return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian());
|
return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian());
|
||||||
}
|
}
|
||||||
bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; }
|
bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; }
|
||||||
VNumRange declRange() const {
|
VNumRange declRange() const { return isRanged() ? VNumRange{left(), right()} : VNumRange{}; }
|
||||||
return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange();
|
|
||||||
}
|
|
||||||
void cvtRangeConst() { // Convert to smaller representation
|
void cvtRangeConst() { // Convert to smaller representation
|
||||||
if (rangep() && VN_IS(rangep()->msbp(), Const) && VN_IS(rangep()->lsbp(), Const)) {
|
if (rangep() && VN_IS(rangep()->leftp(), Const) && VN_IS(rangep()->rightp(), Const)) {
|
||||||
m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(), rangep()->littleEndian());
|
m.m_nrange = VNumRange{rangep()->leftConst(), rangep()->rightConst()};
|
||||||
rangep()->unlinkFrBackWithNext()->deleteTree();
|
rangep()->unlinkFrBackWithNext()->deleteTree();
|
||||||
rangep(nullptr);
|
rangep(nullptr);
|
||||||
}
|
}
|
||||||
|
|
@ -1658,8 +1644,8 @@ public:
|
||||||
AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp)
|
AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp)
|
||||||
: ASTGEN_SUPER(fl, fromp, msbp, lsbp) {}
|
: ASTGEN_SUPER(fl, fromp, msbp, lsbp) {}
|
||||||
ASTNODE_NODE_FUNCS(SelExtract)
|
ASTNODE_NODE_FUNCS(SelExtract)
|
||||||
AstNode* msbp() const { return rhsp(); }
|
AstNode* leftp() const { return rhsp(); }
|
||||||
AstNode* lsbp() const { return thsp(); }
|
AstNode* rightp() const { return thsp(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AstSelBit final : public AstNodePreSel {
|
class AstSelBit final : public AstNodePreSel {
|
||||||
|
|
|
||||||
|
|
@ -310,9 +310,9 @@ private:
|
||||||
const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant
|
const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant
|
||||||
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
|
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
|
||||||
if (bdtypep->isRanged()) {
|
if (bdtypep->isRanged()) {
|
||||||
for (int index_docs = bdtypep->lsb(); index_docs < bdtypep->msb() + 1;
|
for (int index_docs = bdtypep->lo(); index_docs < bdtypep->hi() + 1;
|
||||||
index_docs++) {
|
++index_docs) {
|
||||||
int index_code = index_docs - bdtypep->lsb();
|
int index_code = index_docs - bdtypep->lo();
|
||||||
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
||||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||||
index_code, 1),
|
index_code, 1),
|
||||||
|
|
@ -325,8 +325,8 @@ private:
|
||||||
toggleVarBottom(above, varp);
|
toggleVarBottom(above, varp);
|
||||||
}
|
}
|
||||||
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||||
for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) {
|
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
|
||||||
int index_code = index_docs - adtypep->lsb();
|
int index_code = index_docs - adtypep->lo();
|
||||||
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
||||||
new AstArraySel(varp->fileline(),
|
new AstArraySel(varp->fileline(),
|
||||||
above.m_varRefp->cloneTree(true), index_code),
|
above.m_varRefp->cloneTree(true), index_code),
|
||||||
|
|
@ -337,9 +337,9 @@ private:
|
||||||
newent.cleanup();
|
newent.cleanup();
|
||||||
}
|
}
|
||||||
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
|
||||||
for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) {
|
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
|
||||||
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
|
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
|
||||||
int index_code = index_docs - adtypep->lsb();
|
int index_code = index_docs - adtypep->lo();
|
||||||
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
|
||||||
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
|
||||||
index_code * subtypep->width(), subtypep->width()),
|
index_code * subtypep->width(), subtypep->width()),
|
||||||
|
|
|
||||||
|
|
@ -631,7 +631,7 @@ public:
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
// Need real storage width
|
// Need real storage width
|
||||||
puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin()));
|
puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin()));
|
||||||
uint32_t array_lsb = 0;
|
uint32_t array_lo = 0;
|
||||||
{
|
{
|
||||||
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||||
if (!varrefp) {
|
if (!varrefp) {
|
||||||
|
|
@ -642,9 +642,9 @@ public:
|
||||||
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
|
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
|
||||||
array_lsb = adtypep->lsb();
|
array_lo = adtypep->lo();
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
puts(cvtToStr(array_lsb));
|
puts(cvtToStr(array_lo));
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error(nodep->verilogKwd()
|
nodep->v3error(nodep->verilogKwd()
|
||||||
<< " loading other than unpacked/associative-array variable");
|
<< " loading other than unpacked/associative-array variable");
|
||||||
|
|
@ -658,7 +658,7 @@ public:
|
||||||
if (nodep->lsbp()) {
|
if (nodep->lsbp()) {
|
||||||
iterateAndNextNull(nodep->lsbp());
|
iterateAndNextNull(nodep->lsbp());
|
||||||
} else {
|
} else {
|
||||||
puts(cvtToStr(array_lsb));
|
puts(cvtToStr(array_lo));
|
||||||
}
|
}
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
if (nodep->msbp()) {
|
if (nodep->msbp()) {
|
||||||
|
|
@ -710,7 +710,7 @@ public:
|
||||||
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
||||||
putbs(",");
|
putbs(",");
|
||||||
bool memory = false;
|
bool memory = false;
|
||||||
uint32_t array_lsb = 0;
|
uint32_t array_lo = 0;
|
||||||
uint32_t array_size = 0;
|
uint32_t array_size = 0;
|
||||||
{
|
{
|
||||||
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef);
|
||||||
|
|
@ -720,14 +720,14 @@ public:
|
||||||
} else if (const AstUnpackArrayDType* adtypep
|
} else if (const AstUnpackArrayDType* adtypep
|
||||||
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
|
||||||
memory = true;
|
memory = true;
|
||||||
array_lsb = adtypep->lsb();
|
array_lo = adtypep->lo();
|
||||||
array_size = adtypep->elementsConst();
|
array_size = adtypep->elementsConst();
|
||||||
} else {
|
} else {
|
||||||
nodep->v3error(nodep->verilogKwd()
|
nodep->v3error(nodep->verilogKwd()
|
||||||
<< " loading other than unpacked-array variable");
|
<< " loading other than unpacked-array variable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
puts(cvtToStr(array_lsb));
|
puts(cvtToStr(array_lo));
|
||||||
putbs(",");
|
putbs(",");
|
||||||
puts(cvtToStr(array_size));
|
puts(cvtToStr(array_size));
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
|
|
@ -740,7 +740,7 @@ public:
|
||||||
if (nodep->startp()) {
|
if (nodep->startp()) {
|
||||||
iterateAndNextNull(nodep->startp());
|
iterateAndNextNull(nodep->startp());
|
||||||
} else {
|
} else {
|
||||||
puts(cvtToStr(array_lsb));
|
puts(cvtToStr(array_lo));
|
||||||
}
|
}
|
||||||
putbs(", ");
|
putbs(", ");
|
||||||
if (nodep->countp()) {
|
if (nodep->countp()) {
|
||||||
|
|
@ -1789,7 +1789,7 @@ class EmitCImp final : EmitCStmts {
|
||||||
return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1,
|
return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1,
|
||||||
".atDefault()" + cvtarray);
|
".atDefault()" + cvtarray);
|
||||||
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
|
||||||
UASSERT_OBJ(adtypep->msb() >= adtypep->lsb(), varp,
|
UASSERT_OBJ(adtypep->hi() >= adtypep->lo(), varp,
|
||||||
"Should have swapped msb & lsb earlier.");
|
"Should have swapped msb & lsb earlier.");
|
||||||
string ivar = string("__Vi") + cvtToStr(depth);
|
string ivar = string("__Vi") + cvtToStr(depth);
|
||||||
string pre = ("for (int " + ivar + "=" + cvtToStr(0) + "; " + ivar + "<"
|
string pre = ("for (int " + ivar + "=" + cvtToStr(0) + "; " + ivar + "<"
|
||||||
|
|
@ -1921,7 +1921,7 @@ void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) {
|
||||||
emitDeclArrayBrackets(nodep);
|
emitDeclArrayBrackets(nodep);
|
||||||
// If it's a packed struct/array then nodep->width is the whole
|
// If it's a packed struct/array then nodep->width is the whole
|
||||||
// thing, msb/lsb is just lowest dimension
|
// thing, msb/lsb is just lowest dimension
|
||||||
puts("," + cvtToStr(basicp->lsb() + nodep->width() - 1) + "," + cvtToStr(basicp->lsb()));
|
puts("," + cvtToStr(basicp->lo() + nodep->width() - 1) + "," + cvtToStr(basicp->lo()));
|
||||||
if (nodep->isWide()) puts("," + cvtToStr(nodep->widthWords()));
|
if (nodep->isWide()) puts("," + cvtToStr(nodep->widthWords()));
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2600,7 +2600,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
|
||||||
for (AstUnpackArrayDType* arrayp = VN_CAST(elementp, UnpackArrayDType);
|
for (AstUnpackArrayDType* arrayp = VN_CAST(elementp, UnpackArrayDType);
|
||||||
arrayp; arrayp = VN_CAST(elementp, UnpackArrayDType)) {
|
arrayp; arrayp = VN_CAST(elementp, UnpackArrayDType)) {
|
||||||
int vecnum = vects++;
|
int vecnum = vects++;
|
||||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
UASSERT_OBJ(arrayp->hi() >= arrayp->lo(), varp,
|
||||||
"Should have swapped msb & lsb earlier.");
|
"Should have swapped msb & lsb earlier.");
|
||||||
string ivar = string("__Vi") + cvtToStr(vecnum);
|
string ivar = string("__Vi") + cvtToStr(vecnum);
|
||||||
puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(0));
|
puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(0));
|
||||||
|
|
@ -2687,11 +2687,11 @@ void EmitCImp::emitSensitives() {
|
||||||
arrayp;
|
arrayp;
|
||||||
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) {
|
||||||
int vecnum = vects++;
|
int vecnum = vects++;
|
||||||
UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp,
|
UASSERT_OBJ(arrayp->hi() >= arrayp->lo(), varp,
|
||||||
"Should have swapped msb & lsb earlier.");
|
"Should have swapped msb & lsb earlier.");
|
||||||
string ivar = string("__Vi") + cvtToStr(vecnum);
|
string ivar = string("__Vi") + cvtToStr(vecnum);
|
||||||
puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(arrayp->lsb()));
|
puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(arrayp->lo()));
|
||||||
puts("; " + ivar + "<=" + cvtToStr(arrayp->msb()));
|
puts("; " + ivar + "<=" + cvtToStr(arrayp->hi()));
|
||||||
puts("; ++" + ivar + ") {\n");
|
puts("; ++" + ivar + ") {\n");
|
||||||
}
|
}
|
||||||
puts("sensitive << " + varp->nameProtect());
|
puts("sensitive << " + varp->nameProtect());
|
||||||
|
|
|
||||||
|
|
@ -752,9 +752,9 @@ void EmitCSyms::emitSymImp() {
|
||||||
// Range is always first, it's not in "C" order
|
// Range is always first, it's not in "C" order
|
||||||
if (basicp->isRanged()) {
|
if (basicp->isRanged()) {
|
||||||
bounds += " ,";
|
bounds += " ,";
|
||||||
bounds += cvtToStr(basicp->msb());
|
bounds += cvtToStr(basicp->hi());
|
||||||
bounds += ",";
|
bounds += ",";
|
||||||
bounds += cvtToStr(basicp->lsb());
|
bounds += cvtToStr(basicp->lo());
|
||||||
pdim++;
|
pdim++;
|
||||||
}
|
}
|
||||||
for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) {
|
for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) {
|
||||||
|
|
@ -762,9 +762,9 @@ void EmitCSyms::emitSymImp() {
|
||||||
= dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
= dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||||
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) {
|
||||||
bounds += " ,";
|
bounds += " ,";
|
||||||
bounds += cvtToStr(adtypep->msb());
|
bounds += cvtToStr(adtypep->hi());
|
||||||
bounds += ",";
|
bounds += ",";
|
||||||
bounds += cvtToStr(adtypep->lsb());
|
bounds += cvtToStr(adtypep->lo());
|
||||||
if (VN_IS(dtypep, PackArrayDType)) {
|
if (VN_IS(dtypep, PackArrayDType)) {
|
||||||
pdim++;
|
pdim++;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -513,11 +513,11 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||||
}
|
}
|
||||||
virtual void visit(AstRange* nodep) override {
|
virtual void visit(AstRange* nodep) override {
|
||||||
puts("[");
|
puts("[");
|
||||||
if (VN_IS(nodep->msbp(), Const) && VN_IS(nodep->lsbp(), Const)) {
|
if (VN_IS(nodep->leftp(), Const) && VN_IS(nodep->rightp(), Const)) {
|
||||||
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
|
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
|
||||||
puts(cvtToStr(VN_CAST(nodep->leftp(), Const)->toSInt()));
|
puts(cvtToStr(nodep->leftConst()));
|
||||||
puts(":");
|
puts(":");
|
||||||
puts(cvtToStr(VN_CAST(nodep->rightp(), Const)->toSInt()));
|
puts(cvtToStr(nodep->rightConst()));
|
||||||
puts("]");
|
puts("]");
|
||||||
} else {
|
} else {
|
||||||
iterateAndNextNull(nodep->leftp());
|
iterateAndNextNull(nodep->leftp());
|
||||||
|
|
@ -570,7 +570,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
||||||
puts(" ");
|
puts(" ");
|
||||||
} else if (nodep->isRanged()) {
|
} else if (nodep->isRanged()) {
|
||||||
puts(" [");
|
puts(" [");
|
||||||
puts(cvtToStr(nodep->msb()));
|
puts(cvtToStr(nodep->hi()));
|
||||||
puts(":0] ");
|
puts(":0] ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ private:
|
||||||
UINFO(8, " dv-vec-VAR " << nodep << endl);
|
UINFO(8, " dv-vec-VAR " << nodep << endl);
|
||||||
AstUnpackArrayDType* arrdtype = VN_CAST(nodep->dtypep(), UnpackArrayDType);
|
AstUnpackArrayDType* arrdtype = VN_CAST(nodep->dtypep(), UnpackArrayDType);
|
||||||
AstNode* prevp = nullptr;
|
AstNode* prevp = nullptr;
|
||||||
for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) {
|
for (int i = arrdtype->lo(); i <= arrdtype->hi(); ++i) {
|
||||||
string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||||
UINFO(8, "VAR name insert " << varNewName << " " << nodep << endl);
|
UINFO(8, "VAR name insert " << varNewName << " " << nodep << endl);
|
||||||
if (!m_deModVars.find(varNewName)) {
|
if (!m_deModVars.find(varNewName)) {
|
||||||
|
|
@ -255,7 +255,7 @@ private:
|
||||||
for (int i = 0; i < m_cellRangep->elementsConst(); i++) {
|
for (int i = 0; i < m_cellRangep->elementsConst(); i++) {
|
||||||
m_instSelNum
|
m_instSelNum
|
||||||
= m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i;
|
= m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i;
|
||||||
int instNum = m_cellRangep->lsbConst() + i;
|
int instNum = m_cellRangep->loConst() + i;
|
||||||
|
|
||||||
AstCell* newp = nodep->cloneTree(false);
|
AstCell* newp = nodep->cloneTree(false);
|
||||||
nodep->addNextHere(newp);
|
nodep->addNextHere(newp);
|
||||||
|
|
@ -341,10 +341,11 @@ private:
|
||||||
// Arrayed instants: one bit for each of the instants (each
|
// Arrayed instants: one bit for each of the instants (each
|
||||||
// assign is 1 pinwidth wide)
|
// assign is 1 pinwidth wide)
|
||||||
if (m_cellRangep->littleEndian()) {
|
if (m_cellRangep->littleEndian()) {
|
||||||
nodep->exprp()->v3warn(LITENDIAN, "Little endian cell range connecting to "
|
nodep->exprp()->v3warn(
|
||||||
"vector: left < right of cell range: ["
|
LITENDIAN,
|
||||||
<< m_cellRangep->leftConst() << ":"
|
"Little endian cell range connecting to vector: left < right of cell range: ["
|
||||||
<< m_cellRangep->rightConst() << "]");
|
<< m_cellRangep->leftConst() << ":" << m_cellRangep->rightConst()
|
||||||
|
<< "]");
|
||||||
}
|
}
|
||||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||||
bool inputPin = nodep->modVarp()->isNonOutput();
|
bool inputPin = nodep->modVarp()->isNonOutput();
|
||||||
|
|
@ -396,7 +397,7 @@ private:
|
||||||
AstNode* prevPinp = nullptr;
|
AstNode* prevPinp = nullptr;
|
||||||
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
||||||
// Clone pin varp:
|
// Clone pin varp:
|
||||||
for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) {
|
for (int i = pinArrp->lo(); i <= pinArrp->hi(); ++i) {
|
||||||
string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||||
AstVar* varNewp = nullptr;
|
AstVar* varNewp = nullptr;
|
||||||
|
|
||||||
|
|
@ -529,7 +530,7 @@ public:
|
||||||
&& connectXRefp->varp()->isIfaceRef()) {
|
&& connectXRefp->varp()->isIfaceRef()) {
|
||||||
} else if (!alwaysCvt && connBasicp && pinBasicp
|
} else if (!alwaysCvt && connBasicp && pinBasicp
|
||||||
&& connBasicp->width() == pinBasicp->width()
|
&& connBasicp->width() == pinBasicp->width()
|
||||||
&& connBasicp->lsb() == pinBasicp->lsb()
|
&& connBasicp->lo() == pinBasicp->lo()
|
||||||
&& !connectRefp->varp()
|
&& !connectRefp->varp()
|
||||||
->isSc() // Need the signal as a 'shell' to convert types
|
->isSc() // Need the signal as a 'shell' to convert types
|
||||||
&& connBasicp->width() == pinVarp->width()) {
|
&& connBasicp->width() == pinVarp->width()) {
|
||||||
|
|
|
||||||
|
|
@ -151,16 +151,16 @@ private:
|
||||||
cleanFileline(nodep);
|
cleanFileline(nodep);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (nodep->rangep()) {
|
if (nodep->rangep()) {
|
||||||
if (!VN_IS(nodep->rangep()->msbp(), Const) //
|
if (!VN_IS(nodep->rangep()->leftp(), Const) //
|
||||||
|| !VN_IS(nodep->rangep()->lsbp(), Const)) {
|
|| !VN_IS(nodep->rangep()->rightp(), Const)) {
|
||||||
nodep->v3error("Enum ranges must be integral, per spec");
|
nodep->v3error("Enum ranges must be integral, per spec");
|
||||||
}
|
}
|
||||||
int msb = nodep->rangep()->msbConst();
|
int left = nodep->rangep()->leftConst();
|
||||||
int lsb = nodep->rangep()->lsbConst();
|
int right = nodep->rangep()->rightConst();
|
||||||
int increment = (msb > lsb) ? -1 : 1;
|
int increment = (left > right) ? -1 : 1;
|
||||||
int offset_from_init = 0;
|
int offset_from_init = 0;
|
||||||
AstNode* addp = nullptr;
|
AstNode* addp = nullptr;
|
||||||
for (int i = msb; i != (lsb + increment); i += increment, offset_from_init++) {
|
for (int i = left; i != (right + increment); i += increment, offset_from_init++) {
|
||||||
string name = nodep->name() + cvtToStr(i);
|
string name = nodep->name() + cvtToStr(i);
|
||||||
AstNode* valuep = nullptr;
|
AstNode* valuep = nullptr;
|
||||||
if (nodep->valuep()) {
|
if (nodep->valuep()) {
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ private:
|
||||||
int msb = lsb + width - 1;
|
int msb = lsb + width - 1;
|
||||||
V3Number fieldNum(nump, width);
|
V3Number fieldNum(nump, width);
|
||||||
fieldNum.opSel(*nump, msb, lsb);
|
fieldNum.opSel(*nump, msb, lsb);
|
||||||
int arrayElem = arrayp->lsb() + element;
|
int arrayElem = arrayp->lo() + element;
|
||||||
out << arrayElem << " = " << prettyNumber(&fieldNum, childTypep);
|
out << arrayElem << " = " << prettyNumber(&fieldNum, childTypep);
|
||||||
if (element < arrayElements - 1) out << ", ";
|
if (element < arrayElements - 1) out << ", ";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -405,7 +405,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
static int outerMostSizeOfUnpackedArray(AstVar* nodep) {
|
static int outerMostSizeOfUnpackedArray(AstVar* nodep) {
|
||||||
AstUnpackArrayDType* dtypep = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
|
AstUnpackArrayDType* dtypep = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType);
|
||||||
UASSERT_OBJ(dtypep, nodep, "Must be unapcked array");
|
UASSERT_OBJ(dtypep, nodep, "Must be unapcked array");
|
||||||
return dtypep->msb() - dtypep->lsb() + 1;
|
return dtypep->elementsConst();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setContextAndIterateChildren(AstNode* nodep) {
|
void setContextAndIterateChildren(AstNode* nodep) {
|
||||||
|
|
@ -585,7 +585,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
const VNumRange selRange{nodep->declRange().hi() + dtypep->declRange().lo(),
|
const VNumRange selRange{nodep->declRange().hi() + dtypep->declRange().lo(),
|
||||||
nodep->declRange().lo() + dtypep->declRange().lo(),
|
nodep->declRange().lo() + dtypep->declRange().lo(),
|
||||||
nodep->declRange().littleEndian()};
|
nodep->declRange().littleEndian()};
|
||||||
UASSERT_OBJ(dtypep->lsb() <= selRange.lo() && selRange.hi() <= dtypep->msb(), nodep,
|
UASSERT_OBJ(dtypep->lo() <= selRange.lo() && selRange.hi() <= dtypep->hi(), nodep,
|
||||||
"Range check for AstSliceSel must have been finished in V3Width.cpp");
|
"Range check for AstSliceSel must have been finished in V3Width.cpp");
|
||||||
UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n");
|
UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n");
|
||||||
m_refs.tryAdd(m_contextp, refp, nodep, nodep->declRange().hi(),
|
m_refs.tryAdd(m_contextp, refp, nodep, nodep->declRange().hi(),
|
||||||
|
|
@ -614,12 +614,12 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
AstVar* varp = newVar(nodep->fileline(), AstVarType::VAR, name, dtypep);
|
AstVar* varp = newVar(nodep->fileline(), AstVarType::VAR, name, dtypep);
|
||||||
// Variable will be registered in the caller side.
|
// Variable will be registered in the caller side.
|
||||||
UINFO(3, varp->prettyNameQ()
|
UINFO(3, varp->prettyNameQ()
|
||||||
<< " is created lsb:" << dtypep->lsb() << " msb:" << dtypep->msb() << "\n");
|
<< " is created lsb:" << dtypep->lo() << " msb:" << dtypep->hi() << "\n");
|
||||||
// Use AstAssign if true, otherwise AstAssignW
|
// Use AstAssign if true, otherwise AstAssignW
|
||||||
const bool use_simple_assign
|
const bool use_simple_assign
|
||||||
= (context && VN_IS(context, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign));
|
= (context && VN_IS(context, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign));
|
||||||
|
|
||||||
for (int i = 0; i <= dtypep->msb() - dtypep->lsb(); ++i) {
|
for (int i = 0; i < dtypep->elementsConst(); ++i) {
|
||||||
AstNode* lhsp = newVarRef(nodep->fileline(), vars.at(start_idx + i),
|
AstNode* lhsp = newVarRef(nodep->fileline(), vars.at(start_idx + i),
|
||||||
lvalue ? VAccess::WRITE : VAccess::READ);
|
lvalue ? VAccess::WRITE : VAccess::READ);
|
||||||
AstNode* rhsp = new AstArraySel(
|
AstNode* rhsp = new AstArraySel(
|
||||||
|
|
@ -689,10 +689,10 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
const bool needNext = VN_IS(subTypep, UnpackArrayDType); // Still unpacked array.
|
const bool needNext = VN_IS(subTypep, UnpackArrayDType); // Still unpacked array.
|
||||||
std::vector<AstVar*> vars;
|
std::vector<AstVar*> vars;
|
||||||
// Add the split variables
|
// Add the split variables
|
||||||
for (vlsint32_t i = 0; i <= dtypep->msb() - dtypep->lsb(); ++i) {
|
for (vlsint32_t i = 0; i < dtypep->elementsConst(); ++i) {
|
||||||
// Unpacked array is traced as var(idx), not var[idx].
|
// Unpacked array is traced as var(idx), not var[idx].
|
||||||
const std::string name
|
const std::string name
|
||||||
= varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lsb()) + ')');
|
= varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lo()) + ')');
|
||||||
AstVar* newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep);
|
AstVar* newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep);
|
||||||
newp->propagateAttrFrom(varp);
|
newp->propagateAttrFrom(varp);
|
||||||
// If varp is an IO, varp will remain and will be traced.
|
// If varp is an IO, varp will remain and will be traced.
|
||||||
|
|
@ -722,7 +722,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
refp = VN_CAST(selp->fromp(), VarRef);
|
refp = VN_CAST(selp->fromp(), VarRef);
|
||||||
UASSERT_OBJ(refp, selp, "Unexpected op is registered");
|
UASSERT_OBJ(refp, selp, "Unexpected op is registered");
|
||||||
adtypep = VN_CAST(selp->dtypep()->skipRefp(), UnpackArrayDType);
|
adtypep = VN_CAST(selp->dtypep()->skipRefp(), UnpackArrayDType);
|
||||||
lsb = adtypep->lsb();
|
lsb = adtypep->lo();
|
||||||
}
|
}
|
||||||
AstVarRef* newrefp = createTempVar(sit->context(), refp, adtypep, varp->name(),
|
AstVarRef* newrefp = createTempVar(sit->context(), refp, adtypep, varp->name(),
|
||||||
vars, lsb, refp->access(), sit->ftask());
|
vars, lsb, refp->access(), sit->ftask());
|
||||||
|
|
@ -922,8 +922,8 @@ public:
|
||||||
points.emplace_back(std::make_pair(it->msb() + 1, true)); // End of a region
|
points.emplace_back(std::make_pair(it->msb() + 1, true)); // End of a region
|
||||||
}
|
}
|
||||||
if (skipUnused && !m_rhs.empty()) { // Range to be read must be kept, so add points here
|
if (skipUnused && !m_rhs.empty()) { // Range to be read must be kept, so add points here
|
||||||
int lsb = m_basicp->msb() + 1;
|
int lsb = m_basicp->hi() + 1;
|
||||||
int msb = m_basicp->lsb() - 1;
|
int msb = m_basicp->lo() - 1;
|
||||||
for (size_t i = 0; i < m_rhs.size(); ++i) {
|
for (size_t i = 0; i < m_rhs.size(); ++i) {
|
||||||
lsb = std::min(lsb, m_rhs[i].lsb());
|
lsb = std::min(lsb, m_rhs[i].lsb());
|
||||||
msb = std::max(msb, m_rhs[i].msb());
|
msb = std::max(msb, m_rhs[i].msb());
|
||||||
|
|
@ -933,8 +933,8 @@ public:
|
||||||
points.emplace_back(std::make_pair(msb + 1, true));
|
points.emplace_back(std::make_pair(msb + 1, true));
|
||||||
}
|
}
|
||||||
if (!skipUnused) { // All bits are necessary
|
if (!skipUnused) { // All bits are necessary
|
||||||
points.emplace_back(std::make_pair(m_basicp->lsb(), false));
|
points.emplace_back(std::make_pair(m_basicp->lo(), false));
|
||||||
points.emplace_back(std::make_pair(m_basicp->msb() + 1, true));
|
points.emplace_back(std::make_pair(m_basicp->hi() + 1, true));
|
||||||
}
|
}
|
||||||
std::sort(points.begin(), points.end(), SortByFirst());
|
std::sort(points.begin(), points.end(), SortByFirst());
|
||||||
|
|
||||||
|
|
@ -985,10 +985,10 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
UASSERT_OBJ(!nodep->classOrPackagep(), nodep,
|
UASSERT_OBJ(!nodep->classOrPackagep(), nodep,
|
||||||
"variable in package must have been dropped beforehand.");
|
"variable in package must have been dropped beforehand.");
|
||||||
const AstBasicDType* basicp = refit->second.basicp();
|
const AstBasicDType* basicp = refit->second.basicp();
|
||||||
refit->second.append(PackedVarRefEntry(nodep, basicp->lsb(), varp->width()),
|
refit->second.append(PackedVarRefEntry(nodep, basicp->lo(), varp->width()),
|
||||||
nodep->access());
|
nodep->access());
|
||||||
UINFO(5, varp->prettyName()
|
UINFO(5, varp->prettyName()
|
||||||
<< " Entire bit of [" << basicp->lsb() << ":+" << varp->width() << "] \n");
|
<< " Entire bit of [" << basicp->lo() << "+:" << varp->width() << "] \n");
|
||||||
}
|
}
|
||||||
virtual void visit(AstSel* nodep) override {
|
virtual void visit(AstSel* nodep) override {
|
||||||
AstVarRef* vrefp = VN_CAST(nodep->fromp(), VarRef);
|
AstVarRef* vrefp = VN_CAST(nodep->fromp(), VarRef);
|
||||||
|
|
@ -1010,12 +1010,12 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}}
|
VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}}
|
||||||
if (consts[0] && consts[1]) { // OK
|
if (consts[0] && consts[1]) { // OK
|
||||||
refit->second.append(
|
refit->second.append(
|
||||||
PackedVarRefEntry(nodep, consts[0]->toSInt() + refit->second.basicp()->lsb(),
|
PackedVarRefEntry(nodep, consts[0]->toSInt() + refit->second.basicp()->lo(),
|
||||||
consts[1]->toUInt()),
|
consts[1]->toUInt()),
|
||||||
vrefp->access());
|
vrefp->access());
|
||||||
UINFO(5, varp->prettyName()
|
UINFO(5, varp->prettyName()
|
||||||
<< " [" << consts[0]->toSInt() << ":+" << consts[1]->toSInt()
|
<< " [" << consts[0]->toSInt() << ":+" << consts[1]->toSInt()
|
||||||
<< "] lsb:" << refit->second.basicp()->lsb() << "\n");
|
<< "] lsb:" << refit->second.basicp()->lo() << "\n");
|
||||||
} else {
|
} else {
|
||||||
nodep->v3warn(SPLITVAR, vrefp->prettyNameQ()
|
nodep->v3warn(SPLITVAR, vrefp->prettyNameQ()
|
||||||
<< notSplitMsg
|
<< notSplitMsg
|
||||||
|
|
@ -1081,7 +1081,8 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
void createVars(AstVar* varp, const AstBasicDType* basicp, std::vector<SplitNewVar>& vars) {
|
void createVars(AstVar* varp, const AstBasicDType* basicp, std::vector<SplitNewVar>& vars) {
|
||||||
for (size_t i = 0; i < vars.size(); ++i) {
|
for (size_t i = 0; i < vars.size(); ++i) {
|
||||||
SplitNewVar* newvarp = &vars[i];
|
SplitNewVar* newvarp = &vars[i];
|
||||||
int left = newvarp->msb(), right = newvarp->lsb();
|
int left = newvarp->msb();
|
||||||
|
int right = newvarp->lsb();
|
||||||
if (basicp->littleEndian()) std::swap(left, right);
|
if (basicp->littleEndian()) std::swap(left, right);
|
||||||
const std::string name
|
const std::string name
|
||||||
= (left == right)
|
= (left == right)
|
||||||
|
|
@ -1101,8 +1102,8 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
|
||||||
break;
|
break;
|
||||||
default: UASSERT_OBJ(false, basicp, "Only bit and logic are allowed");
|
default: UASSERT_OBJ(false, basicp, "Only bit and logic are allowed");
|
||||||
}
|
}
|
||||||
dtypep->rangep(new AstRange(varp->fileline(), newvarp->msb(), newvarp->lsb()));
|
dtypep->rangep(new AstRange{varp->fileline(), VNumRange{newvarp->msb(), newvarp->lsb(),
|
||||||
dtypep->rangep()->littleEndian(basicp->littleEndian());
|
basicp->littleEndian()}});
|
||||||
newvarp->varp(new AstVar(varp->fileline(), AstVarType::VAR, name, dtypep));
|
newvarp->varp(new AstVar(varp->fileline(), AstVarType::VAR, name, dtypep));
|
||||||
newvarp->varp()->propagateAttrFrom(varp);
|
newvarp->varp()->propagateAttrFrom(varp);
|
||||||
newvarp->varp()->funcLocal(varp->isFuncLocal() || varp->isFuncReturn());
|
newvarp->varp()->funcLocal(varp->isFuncLocal() || varp->isFuncReturn());
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,8 @@ private:
|
||||||
FileLine* const flp = m_topScopep->fileline();
|
FileLine* const flp = m_topScopep->fileline();
|
||||||
AstNodeDType* const newScalarDtp = new AstBasicDType(flp, VFlagLogicPacked(), 1);
|
AstNodeDType* const newScalarDtp = new AstBasicDType(flp, VFlagLogicPacked(), 1);
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp);
|
v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp);
|
||||||
AstRange* const newArange = new AstRange(flp, VNumRange(m_activityNumber - 1, 0, false));
|
AstRange* const newArange
|
||||||
|
= new AstRange{flp, VNumRange{static_cast<int>(m_activityNumber) - 1, 0}};
|
||||||
AstNodeDType* const newArrDtp = new AstUnpackArrayDType(flp, newScalarDtp, newArange);
|
AstNodeDType* const newArrDtp = new AstUnpackArrayDType(flp, newScalarDtp, newArange);
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(newArrDtp);
|
v3Global.rootp()->typeTablep()->addTypesp(newArrDtp);
|
||||||
AstVar* const newvarp
|
AstVar* const newvarp
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ private:
|
||||||
// misreflects one element
|
// misreflects one element
|
||||||
VNumRange bitRange;
|
VNumRange bitRange;
|
||||||
if (widthOverride) {
|
if (widthOverride) {
|
||||||
bitRange = VNumRange(widthOverride - 1, 0, false);
|
bitRange = VNumRange{widthOverride - 1, 0};
|
||||||
} else if (const AstBasicDType* const bdtypep = m_traValuep->dtypep()->basicp()) {
|
} else if (const AstBasicDType* const bdtypep = m_traValuep->dtypep()->basicp()) {
|
||||||
bitRange = bdtypep->nrange();
|
bitRange = bdtypep->nrange();
|
||||||
}
|
}
|
||||||
|
|
@ -238,13 +238,13 @@ private:
|
||||||
} else {
|
} else {
|
||||||
// Unroll now, as have no other method to get right signal names
|
// Unroll now, as have no other method to get right signal names
|
||||||
AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump();
|
AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump();
|
||||||
for (int i = nodep->lsb(); i <= nodep->msb(); ++i) {
|
for (int i = nodep->lo(); i <= nodep->hi(); ++i) {
|
||||||
VL_RESTORER(m_traShowname);
|
VL_RESTORER(m_traShowname);
|
||||||
VL_RESTORER(m_traValuep);
|
VL_RESTORER(m_traValuep);
|
||||||
{
|
{
|
||||||
m_traShowname += string("(") + cvtToStr(i) + string(")");
|
m_traShowname += string("(") + cvtToStr(i) + string(")");
|
||||||
m_traValuep = new AstArraySel(
|
m_traValuep = new AstArraySel(
|
||||||
nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb());
|
nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lo());
|
||||||
|
|
||||||
m_traValuep->dtypep(subtypep);
|
m_traValuep->dtypep(subtypep);
|
||||||
iterate(subtypep);
|
iterate(subtypep);
|
||||||
|
|
@ -263,14 +263,14 @@ private:
|
||||||
addTraceDecl(VNumRange(), nodep->width());
|
addTraceDecl(VNumRange(), nodep->width());
|
||||||
} else {
|
} else {
|
||||||
AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump();
|
AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump();
|
||||||
for (int i = nodep->lsb(); i <= nodep->msb(); ++i) {
|
for (int i = nodep->lo(); i <= nodep->hi(); ++i) {
|
||||||
VL_RESTORER(m_traShowname);
|
VL_RESTORER(m_traShowname);
|
||||||
VL_RESTORER(m_traValuep);
|
VL_RESTORER(m_traValuep);
|
||||||
{
|
{
|
||||||
m_traShowname += string("(") + cvtToStr(i) + string(")");
|
m_traShowname += string("(") + cvtToStr(i) + string(")");
|
||||||
m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
|
m_traValuep
|
||||||
(i - nodep->lsb()) * subtypep->width(),
|
= new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
|
||||||
subtypep->width());
|
(i - nodep->lo()) * subtypep->width(), subtypep->width());
|
||||||
m_traValuep->dtypep(subtypep);
|
m_traValuep->dtypep(subtypep);
|
||||||
iterate(subtypep);
|
iterate(subtypep);
|
||||||
VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = nullptr);
|
VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -90,14 +90,14 @@ private:
|
||||||
int lsb = bit + 1;
|
int lsb = bit + 1;
|
||||||
if (bits != "") bits += ",";
|
if (bits != "") bits += ",";
|
||||||
if (lsb == msb) {
|
if (lsb == msb) {
|
||||||
bits += cvtToStr(lsb + bdtypep->lsb());
|
bits += cvtToStr(lsb + bdtypep->lo());
|
||||||
} else {
|
} else {
|
||||||
if (bdtypep->littleEndian()) {
|
if (bdtypep->littleEndian()) {
|
||||||
bits += cvtToStr(lsb + bdtypep->lsb()) + ":"
|
bits
|
||||||
+ cvtToStr(msb + bdtypep->lsb());
|
+= cvtToStr(lsb + bdtypep->lo()) + ":" + cvtToStr(msb + bdtypep->lo());
|
||||||
} else {
|
} else {
|
||||||
bits += cvtToStr(msb + bdtypep->lsb()) + ":"
|
bits
|
||||||
+ cvtToStr(lsb + bdtypep->lsb());
|
+= cvtToStr(msb + bdtypep->lo()) + ":" + cvtToStr(lsb + bdtypep->lo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev = false;
|
prev = false;
|
||||||
|
|
|
||||||
|
|
@ -752,21 +752,10 @@ private:
|
||||||
// Signed: unsigned output, input either
|
// Signed: unsigned output, input either
|
||||||
// Convert all range values to constants
|
// Convert all range values to constants
|
||||||
UINFO(6, "RANGE " << nodep << endl);
|
UINFO(6, "RANGE " << nodep << endl);
|
||||||
V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node
|
V3Const::constifyParamsEdit(nodep->leftp()); // May relink pointed to node
|
||||||
V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node
|
V3Const::constifyParamsEdit(nodep->rightp()); // May relink pointed to node
|
||||||
checkConstantOrReplace(nodep->msbp(), "MSB of bit range isn't a constant");
|
checkConstantOrReplace(nodep->leftp(), "left side of bit range isn't a constant");
|
||||||
checkConstantOrReplace(nodep->lsbp(), "LSB of bit range isn't a constant");
|
checkConstantOrReplace(nodep->rightp(), "right side of bit range isn't a constant");
|
||||||
int msb = nodep->msbConst();
|
|
||||||
int lsb = nodep->lsbConst();
|
|
||||||
if (msb < lsb) {
|
|
||||||
// Little endian bits are legal, just remember to swap
|
|
||||||
// Warning is in V3Width to avoid false warnings when in "off" generate if's
|
|
||||||
nodep->littleEndian(!nodep->littleEndian());
|
|
||||||
// Internally we'll always have msb() be the greater number
|
|
||||||
// We only need to correct when doing [] AstSel extraction,
|
|
||||||
// and when tracing the vector.
|
|
||||||
nodep->msbp()->swapWith(nodep->lsbp());
|
|
||||||
}
|
|
||||||
if (m_vup->prelim()) {
|
if (m_vup->prelim()) {
|
||||||
// Don't need to iterate because V3Const already constified
|
// Don't need to iterate because V3Const already constified
|
||||||
int width = nodep->elementsConst();
|
int width = nodep->elementsConst();
|
||||||
|
|
@ -807,7 +796,7 @@ private:
|
||||||
int width = nodep->widthConst();
|
int width = nodep->widthConst();
|
||||||
UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel
|
UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel
|
||||||
if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() < nodep->lsbConst()) {
|
if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() < nodep->lsbConst()) {
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: MSB < LSB of bit extract: "
|
nodep->v3warn(E_UNSUPPORTED, "Unsupported: left < right of bit extract: "
|
||||||
<< nodep->msbConst() << "<" << nodep->lsbConst());
|
<< nodep->msbConst() << "<" << nodep->lsbConst());
|
||||||
width = (nodep->lsbConst() - nodep->msbConst() + 1);
|
width = (nodep->lsbConst() - nodep->msbConst() + 1);
|
||||||
nodep->dtypeSetLogicSized(width, VSigning::UNSIGNED);
|
nodep->dtypeSetLogicSized(width, VSigning::UNSIGNED);
|
||||||
|
|
@ -903,8 +892,8 @@ private:
|
||||||
int fromlsb;
|
int fromlsb;
|
||||||
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
|
||||||
if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
|
||||||
frommsb = adtypep->msb();
|
frommsb = adtypep->hi();
|
||||||
fromlsb = adtypep->lsb();
|
fromlsb = adtypep->lo();
|
||||||
if (fromlsb > frommsb) {
|
if (fromlsb > frommsb) {
|
||||||
int t = frommsb;
|
int t = frommsb;
|
||||||
frommsb = fromlsb;
|
frommsb = fromlsb;
|
||||||
|
|
@ -1929,7 +1918,7 @@ private:
|
||||||
// "foo[0]" from a parameter but not a wire
|
// "foo[0]" from a parameter but not a wire
|
||||||
nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(),
|
nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(),
|
||||||
VSigning::fromBool(issigned));
|
VSigning::fromBool(issigned));
|
||||||
nodep->dtypep(nodep->findLogicRangeDType(VNumRange(0, 0, false),
|
nodep->dtypep(nodep->findLogicRangeDType(VNumRange{0, 0},
|
||||||
nodep->valuep()->widthMin(),
|
nodep->valuep()->widthMin(),
|
||||||
VSigning::fromBool(issigned)));
|
VSigning::fromBool(issigned)));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ private:
|
||||||
} else if (adtypep->isRanged()) {
|
} else if (adtypep->isRanged()) {
|
||||||
UASSERT_OBJ(
|
UASSERT_OBJ(
|
||||||
!(adtypep->rangep()
|
!(adtypep->rangep()
|
||||||
&& (!VN_IS(adtypep->rangep()->msbp(), Const)
|
&& (!VN_IS(adtypep->rangep()->leftp(), Const)
|
||||||
|| !VN_IS(adtypep->rangep()->lsbp(), Const))),
|
|| !VN_IS(adtypep->rangep()->rightp(), Const))),
|
||||||
nodep,
|
nodep,
|
||||||
"Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
"Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep)
|
||||||
fromRange = adtypep->declRange();
|
fromRange = adtypep->declRange();
|
||||||
|
|
@ -324,12 +324,12 @@ private:
|
||||||
UINFO(6, "SELEXTRACT " << nodep << endl);
|
UINFO(6, "SELEXTRACT " << nodep << endl);
|
||||||
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX0: ");
|
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX0: ");
|
||||||
// Below 2 lines may change nodep->widthp()
|
// Below 2 lines may change nodep->widthp()
|
||||||
V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node
|
V3Const::constifyParamsEdit(nodep->leftp()); // May relink pointed to node
|
||||||
V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node
|
V3Const::constifyParamsEdit(nodep->rightp()); // May relink pointed to node
|
||||||
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX3: ");
|
// if (debug() >= 9) nodep->dumpTree(cout, "--SELEX3: ");
|
||||||
checkConstantOrReplace(nodep->lsbp(),
|
checkConstantOrReplace(nodep->leftp(),
|
||||||
"First value of [a:b] isn't a constant, maybe you want +: or -:");
|
"First value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||||
checkConstantOrReplace(nodep->msbp(),
|
checkConstantOrReplace(nodep->rightp(),
|
||||||
"Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
"Second value of [a:b] isn't a constant, maybe you want +: or -:");
|
||||||
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
AstNode* fromp = nodep->lhsp()->unlinkFrBack();
|
||||||
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
|
AstNode* msbp = nodep->rhsp()->unlinkFrBack();
|
||||||
|
|
@ -351,9 +351,9 @@ private:
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
} else { // Slice
|
} else { // Slice
|
||||||
AstSliceSel* newp = new AstSliceSel(
|
AstSliceSel* newp
|
||||||
nodep->fileline(), fromp,
|
= new AstSliceSel{nodep->fileline(), fromp,
|
||||||
VNumRange(VNumRange::LeftRight(), msb - fromRange.lo(), lsb - fromRange.lo()));
|
VNumRange{msb - fromRange.lo(), lsb - fromRange.lo()}};
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,8 @@
|
||||||
<refdtype fl="d31" loc="d,31,4,31,13" id="16" name="my_struct" sub_dtype_id="2"/>
|
<refdtype fl="d31" loc="d,31,4,31,13" id="16" name="my_struct" sub_dtype_id="2"/>
|
||||||
<unpackarraydtype fl="d31" loc="d,31,26,31,27" id="4" sub_dtype_id="2">
|
<unpackarraydtype fl="d31" loc="d,31,26,31,27" id="4" sub_dtype_id="2">
|
||||||
<range fl="d31" loc="d,31,26,31,27">
|
<range fl="d31" loc="d,31,26,31,27">
|
||||||
<const fl="d31" loc="d,31,27,31,28" name="32'h1" dtype_id="5"/>
|
|
||||||
<const fl="d31" loc="d,31,27,31,28" name="32'h0" dtype_id="5"/>
|
<const fl="d31" loc="d,31,27,31,28" name="32'h0" dtype_id="5"/>
|
||||||
|
<const fl="d31" loc="d,31,27,31,28" name="32'h1" dtype_id="5"/>
|
||||||
</range>
|
</range>
|
||||||
</unpackarraydtype>
|
</unpackarraydtype>
|
||||||
<basicdtype fl="d35" loc="d,35,21,35,27" id="7" name="string"/>
|
<basicdtype fl="d35" loc="d,35,21,35,27" id="7" name="string"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue