Commentary: Indicate V3Number width() criticality.

This commit is contained in:
Wilson Snyder 2025-05-04 16:24:36 -04:00
parent d47b88a30c
commit 27ad648c16
6 changed files with 51 additions and 19 deletions

View File

@ -324,7 +324,7 @@ void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int line
// // Commenting out the section below may crash, as the tree state
// // between edits is not always consistent for printing
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// v3Global.rootp()->dumpTree("- treeChange: ");
// if (debug()) v3Global.rootp()->dumpTree("- treeChange: ");
// if (next||1) nodep->dumpTreeAndNext(cout, prefix);
// else nodep->dumpTree(prefix);
// nodep->checkTree();

View File

@ -97,7 +97,7 @@ class ClockVisitor final : public VNVisitor {
}
// VISITORS
void visit(AstCoverToggle* nodep) override {
// nodep->dumpTree("- ct: ");
// if (debug()) nodep->dumpTree("- ct: ");
// COVERTOGGLE(INC, ORIG, CHANGE) ->
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
AstNode* const incp = nodep->incp()->unlinkFrBack();

View File

@ -1706,7 +1706,7 @@ class ConstVisitor final : public VNVisitor {
void replaceAsv(AstNodeBiop* nodep) {
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
// BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
// nodep->dumpTree("- repAsvConst_old: ");
// if (debug()) nodep->dumpTree("- repAsvConst_old: ");
AstNodeExpr* const ap = nodep->lhsp();
AstNodeBiop* const rp = VN_AS(nodep->rhsp(), NodeBiop);
AstNodeExpr* const bp = rp->lhsp();
@ -1720,7 +1720,7 @@ class ConstVisitor final : public VNVisitor {
rp->lhsp(ap);
rp->rhsp(bp);
if (VN_IS(rp->lhsp(), Const) && VN_IS(rp->rhsp(), Const)) replaceConst(rp);
// nodep->dumpTree("- repAsvConst_new: ");
// if (debug()) nodep->dumpTree("- repAsvConst_new: ");
}
void replaceAsvLUp(AstNodeBiop* nodep) {
// BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r))
@ -1732,7 +1732,7 @@ class ConstVisitor final : public VNVisitor {
nodep->rhsp(lp);
lp->lhsp(lrp);
lp->rhsp(rp);
// nodep->dumpTree("- repAsvLUp_new: ");
// if (debug()) nodep->dumpTree("- repAsvLUp_new: ");
}
void replaceAsvRUp(AstNodeBiop* nodep) {
// BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr))
@ -1744,7 +1744,7 @@ class ConstVisitor final : public VNVisitor {
nodep->rhsp(rp);
rp->lhsp(lp);
rp->rhsp(rrp);
// nodep->dumpTree("- repAsvRUp_new: ");
// if (debug()) nodep->dumpTree("- repAsvRUp_new: ");
}
void replaceAndOr(AstNodeBiop* nodep) {
// OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr))
@ -1777,7 +1777,7 @@ class ConstVisitor final : public VNVisitor {
} else {
nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched");
}
// nodep->dumpTree("- repAndOr_new: ");
// if (debug()) nodep->dumpTree("- repAndOr_new: ");
}
void replaceShiftSame(AstNodeBiop* nodep) {
// Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr)
@ -1796,7 +1796,7 @@ class ConstVisitor final : public VNVisitor {
nodep->dtypep(llp->dtypep()); // dtype of Biop is before shift.
VL_DO_DANGLING(pushDeletep(rp), rp);
VL_DO_DANGLING(pushDeletep(rrp), rrp);
// nodep->dumpTree("- repShiftSame_new: ");
// if (debug()) nodep->dumpTree("- repShiftSame_new: ");
}
void replaceConcatSel(AstConcat* nodep) {
// {a[1], a[0]} -> a[1:0]
@ -1981,7 +1981,7 @@ class ConstVisitor final : public VNVisitor {
newp->dtypeFrom(nodep);
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
// newp->dumpTree("- repShiftShift_new: ");
// if (debug()) newp->dumpTree("- repShiftShift_new: ");
iterate(newp); // Further reduce, either node may have more reductions.
}
VL_DO_DANGLING(pushDeletep(lhsp), lhsp);
@ -2024,8 +2024,8 @@ class ConstVisitor final : public VNVisitor {
const bool lsbFirstAssign = (con1p->toUInt() < con2p->toUInt());
UINFO(4, "replaceAssignMultiSel " << nodep << endl);
UINFO(4, " && " << nextp << endl);
// nodep->dumpTree("- comb1: ");
// nextp->dumpTree("- comb2: ");
// if (debug()) nodep->dumpTree("- comb1: ");
// if (debug()) nextp->dumpTree("- comb2: ");
AstNodeExpr* const rhs1p = nodep->rhsp()->unlinkFrBack();
AstNodeExpr* const rhs2p = nextp->rhsp()->unlinkFrBack();
AstNodeAssign* newp;
@ -2038,7 +2038,7 @@ class ConstVisitor final : public VNVisitor {
sel2p->lsbConst(), sel1p->width() + sel2p->width()},
new AstConcat{rhs1p->fileline(), rhs1p, rhs2p});
}
// pnewp->dumpTree("- conew: ");
// if (debug()) pnewp->dumpTree("- conew: ");
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
VL_DO_DANGLING(pushDeletep(nextp->unlinkFrBack()), nextp);
@ -2950,7 +2950,7 @@ class ConstVisitor final : public VNVisitor {
void visit(AstSenTree* nodep) override {
iterateChildren(nodep);
if (m_doExpensive) {
// cout<<endl; nodep->dumpTree("- ssin: ");
// if (debug()) nodep->dumpTree("- ssin: ");
// Optimize ideas for the future:
// SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b))

View File

@ -190,8 +190,8 @@ class LinkResolveVisitor final : public VNVisitor {
if (VN_IS(nodep->backp(), StmtExpr)) {
nodep->v3error("Expected statement, not let substitution " << letp->prettyNameQ());
}
// letp->dumpTree("-let-let ");
// nodep->dumpTree("-let-ref ");
// if (debug()) letp->dumpTree("-let-let ");
// if (debug()) nodep->dumpTree("-let-ref ");
AstStmtExpr* const letStmtp = VN_AS(letp->stmtsp(), StmtExpr);
AstNodeExpr* const newp = letStmtp->exprp()->cloneTree(false);
const V3TaskConnects tconnects = V3Task::taskConnects(nodep, letp->stmtsp());
@ -214,7 +214,7 @@ class LinkResolveVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(refp), refp);
}
});
// newp->dumpTree("-let-new ");
// if (debug()) newp->dumpTree("-let-new ");
nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
// Iterate to expand further now, so we can look for recursions

View File

@ -532,6 +532,7 @@ V3Number& V3Number::setMask(int nbits, int lsb) {
// ACCESSORS - as strings
string V3Number::ascii(bool prefixed, bool cleanVerilog) const VL_MT_STABLE {
// Correct number of zero bits/width matters
std::ostringstream out;
if (is1Step()) {
@ -643,6 +644,7 @@ string V3Number::displayed(AstNode* nodep, const string& vformat) const VL_MT_ST
}
string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STABLE {
// Correct number of zero bits/width matters
auto pos = vformat.cbegin();
UASSERT(pos != vformat.cend() && pos[0] == '%',
"$display-like function with non format argument " << *this);
@ -882,6 +884,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const VL_MT_STAB
}
string V3Number::toDecimalS() const VL_MT_STABLE {
// Correct number of zero bits/width matters
if (isNegative()) {
V3Number lhsNoSign = *this;
lhsNoSign.opNegate(*this);
@ -1082,6 +1085,7 @@ bool V3Number::isEqOne() const {
return true;
}
bool V3Number::isEqAllOnes(int optwidth) const {
// Correct number of zero bits/width matters
if (!optwidth) optwidth = width();
for (int bit = 0; bit < optwidth; bit++) {
if (!bitIs1(bit)) return false;
@ -1145,6 +1149,7 @@ int V3Number::widthToFit() const {
}
uint32_t V3Number::countBits(const V3Number& ctrl) const {
// Correct number of zero bits/width matters
int n = 0;
for (int bit = 0; bit < width(); ++bit) {
switch (ctrl.bitIs(0)) {
@ -1167,6 +1172,7 @@ uint32_t V3Number::countBits(const V3Number& ctrl) const {
uint32_t V3Number::countBits(const V3Number& ctrl1, const V3Number& ctrl2,
const V3Number& ctrl3) const {
// Correct number of zero bits/width matters
int n = countBits(ctrl1);
if (ctrl2.bitIs(0) != ctrl1.bitIs(0)) n += countBits(ctrl2);
if ((ctrl3.bitIs(0) != ctrl1.bitIs(0)) && (ctrl3.bitIs(0) != ctrl2.bitIs(0))) {
@ -1192,6 +1198,7 @@ uint32_t V3Number::mostSetBitP1() const {
//======================================================================
V3Number& V3Number::opBitsNonX(const V3Number& lhs) { // 0/1->1, X/Z->0
// Correct number of zero bits/width matters
// op i, L(lhs) bit return
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
@ -1252,6 +1259,7 @@ V3Number& V3Number::opRedOr(const V3Number& lhs) {
}
V3Number& V3Number::opRedAnd(const V3Number& lhs) {
// Correct number of zero bits/width matters
// op i, 1 bit return
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
@ -1289,6 +1297,7 @@ V3Number& V3Number::opRedXor(const V3Number& lhs) {
V3Number& V3Number::opCountBits(const V3Number& expr, const V3Number& ctrl1, const V3Number& ctrl2,
const V3Number& ctrl3) {
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS4(expr, ctrl1, ctrl2, ctrl3);
NUM_ASSERT_LOGIC_ARGS4(expr, ctrl1, ctrl2, ctrl3);
setZero();
@ -1354,6 +1363,7 @@ last:
}
V3Number& V3Number::opNot(const V3Number& lhs) {
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
// op i, L(lhs) bit return
@ -1420,6 +1430,7 @@ V3Number& V3Number::opXor(const V3Number& lhs, const V3Number& rhs) {
}
V3Number& V3Number::opConcat(const V3Number& lhs, const V3Number& rhs) {
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
setZero();
@ -1834,6 +1845,7 @@ V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
}
V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t lbits) {
// Correct number of zero bits/width matters (hance lbits passed)
// L(lhs) bit return
// The spec says a unsigned >>> still acts as a normal >>.
// We presume it is signed; as that's V3Width's job to convert to opShiftR
@ -1881,6 +1893,7 @@ V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
// Ops - Arithmetic
V3Number& V3Number::opNegate(const V3Number& lhs) {
// Correct number of zero bits/width matters
// op i, L(lhs) bit return
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
@ -1910,6 +1923,7 @@ V3Number& V3Number::opAdd(const V3Number& lhs, const V3Number& rhs) {
return *this;
}
V3Number& V3Number::opSub(const V3Number& lhs, const V3Number& rhs) {
// Correct number of zero bits/width matters
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
@ -1949,6 +1963,7 @@ V3Number& V3Number::opMul(const V3Number& lhs, const V3Number& rhs) {
}
V3Number& V3Number::opMulS(const V3Number& lhs, const V3Number& rhs) {
// Signed multiply
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
@ -1981,6 +1996,7 @@ V3Number& V3Number::opDiv(const V3Number& lhs, const V3Number& rhs) {
}
V3Number& V3Number::opDivS(const V3Number& lhs, const V3Number& rhs) {
// Signed divide
// Correct number of zero bits/width matters
// UINFO(9, ">>divs-start "<<lhs<<" "<<rhs<<endl);
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
@ -2016,6 +2032,7 @@ V3Number& V3Number::opModDiv(const V3Number& lhs, const V3Number& rhs) {
}
V3Number& V3Number::opModDivS(const V3Number& lhs, const V3Number& rhs) {
// Signed moddiv
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
@ -2166,6 +2183,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
}
V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign, bool rsign) {
// Correct number of zero bits/width matters
// L(i) bit return, if any 4-state, 4-state return
NUM_ASSERT_OP_ARGS2(lhs, rhs);
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
@ -2207,12 +2225,15 @@ V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign,
return *this;
}
V3Number& V3Number::opPowSU(const V3Number& lhs, const V3Number& rhs) {
// Correct number of zero bits/width matters
return opPow(lhs, rhs, true, false);
}
V3Number& V3Number::opPowSS(const V3Number& lhs, const V3Number& rhs) {
// Correct number of zero bits/width matters
return opPow(lhs, rhs, true, true);
}
V3Number& V3Number::opPowUS(const V3Number& lhs, const V3Number& rhs) {
// Correct number of zero bits/width matters
return opPow(lhs, rhs, false, true);
}
@ -2362,6 +2383,7 @@ V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) {
// Ops - Floating point
V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
// Correct number of zero bits/width matters
NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_LOGIC_ARGS1(lhs);
// IEEE says we ignore x/z in real conversions

View File

@ -418,6 +418,7 @@ public:
return ((v.m_value & (1UL << (bit & 31))) && !(v.m_valueX & (1UL << (bit & 31))));
}
bool bitIs1Extend(int bit) const {
// Correct number of zero bits/width matters
if (!isNumber()) return false;
if (bit < 0) return false;
if (bit >= m_data.width()) return bitIs1Extend(m_data.width() - 1);
@ -457,7 +458,10 @@ private:
int countZ(int lsb, int nbits) const VL_MT_SAFE;
int words() const VL_MT_SAFE { return ((width() + 31) / 32); }
uint32_t hiWordMask() const VL_MT_SAFE { return VL_MASK_I(width()); }
uint32_t hiWordMask() const VL_MT_SAFE {
// Correct number of zero bits/width matters
return VL_MASK_I(width());
}
V3Number& opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool is_modulus);
@ -615,7 +619,10 @@ public:
return m_data.type() == V3NumberDataType::LOGIC
|| m_data.type() == V3NumberDataType::DOUBLE;
}
bool isNegative() const VL_MT_SAFE { return !isString() && bitIs1(width() - 1); }
bool isNegative() const VL_MT_SAFE {
// Correct number of zero bits/width matters
return !isString() && bitIs1(width() - 1);
}
bool is1Step() const VL_MT_SAFE { return m_data.m_is1Step; }
bool isNull() const VL_MT_SAFE { return m_data.m_isNull; }
bool isFourState() const VL_MT_SAFE;
@ -639,7 +646,10 @@ public:
bool isAnyX() const VL_MT_SAFE;
bool isAnyXZ() const;
bool isAnyZ() const VL_MT_SAFE;
bool isMsbXZ() const { return bitIsXZ(m_data.width() - 1); }
bool isMsbXZ() const {
// Correct number of zero bits/width matters
return bitIsXZ(width() - 1);
}
bool fitsInUInt() const VL_MT_SAFE;
uint32_t toUInt() const VL_MT_SAFE;
int32_t toSInt() const VL_MT_SAFE;