Internals: Replace unnecessary AstSel::widthp() child node with const in node (#6117)

This commit is contained in:
Geza Lore 2025-06-24 16:59:09 +01:00 committed by GitHub
parent a9e9ab50bd
commit 916d473eff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 276 additions and 354 deletions

View File

@ -3415,6 +3415,65 @@ public:
int instrCount() const override { return widthInstrs() * 2; }
bool stringFlavor() const override { return true; }
};
class AstSel final : public AstNodeBiop {
// *Resolved* (tyep checked) multiple bit range extraction. Always const width
// @astgen alias op1 := fromp
// @astgen alias op2 := lsbp
VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid
int m_declElWidth; // If a packed array, the number of bits per element
// Selection width (!= this->width() from V3Clean onwards, != this->widthMin() in V3Width)
int m_widthConst;
public:
AstSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* lsbp, int bitwidth)
: ASTGEN_SUPER_Sel(fl, fromp, lsbp)
, m_declElWidth{1}
, m_widthConst{bitwidth} {
dtypeSetLogicSized(bitwidth, VSigning::UNSIGNED);
}
AstSel(FileLine* fl, AstNodeExpr* fromp, int lsb, int bitwidth)
: ASTGEN_SUPER_Sel(fl, fromp, new AstConst(fl, lsb)) // Need () constructor
, m_declElWidth{1}
, m_widthConst{bitwidth} {
dtypeSetLogicSized(bitwidth, VSigning::UNSIGNED);
}
ASTGEN_MEMBERS_AstSel;
AstNodeExpr* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override {
return new AstSel{fileline(), lhsp, rhsp, widthConst()};
}
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) override {
out.opSel(from, bit.toUInt() + widthConst() - 1, bit.toUInt());
}
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override {
return widthConst() == 1 ? "VL_BITSEL_%nq%lq%rqI(%lw, %P, %li, %ri)"
: isWide() ? "VL_SEL_%nq%lq%rqI(%nw, %lw, %P, %li, %ri, %nw)"
: "VL_SEL_%nq%lq%rqI(%lw, %P, %li, %ri, %nw)";
}
string emitSMT() const override { return "((_ extract %t %r) %l)"; }
bool cleanOut() const override { return false; }
bool cleanLhs() const override { return true; }
bool cleanRhs() const override { return true; }
bool sizeMattersLhs() const override { return false; }
bool sizeMattersRhs() const override { return false; }
bool sameNode(const AstNode* otherp) const override {
return widthConst() == VN_DBG_AS(otherp, Sel)->widthConst();
}
int instrCount() const override {
return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10) + 1;
}
int widthConst() const { return m_widthConst; }
void widthConst(int value) { m_widthConst = value; }
int lsbConst() const { return VN_AS(lsbp(), Const)->toSInt(); }
int msbConst() const { return lsbConst() + widthConst() - 1; }
VNumRange& declRange() VL_MT_STABLE { return m_declRange; }
const VNumRange& declRange() const VL_MT_STABLE { return m_declRange; }
void declRange(const VNumRange& flag) { m_declRange = flag; }
int declElWidth() const { return m_declElWidth; }
void declElWidth(int flag) { m_declElWidth = flag; }
};
class AstShiftL final : public AstNodeBiop {
public:
AstShiftL(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp, int setwidth = 0)
@ -4693,59 +4752,6 @@ public:
bool sizeMattersRhs() const override { return false; }
bool sizeMattersThs() const override { return false; }
};
class AstSel final : public AstNodeTriop {
// Multiple bit range extraction
// @astgen alias op1 := fromp
// @astgen alias op2 := lsbp
// @astgen alias op3 := widthp
VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid
int m_declElWidth; // If a packed array, the number of bits per element
public:
AstSel(FileLine* fl, AstNodeExpr* fromp, AstNodeExpr* lsbp, AstNodeExpr* widthp)
: ASTGEN_SUPER_Sel(fl, fromp, lsbp, widthp)
, m_declElWidth{1} {
if (VN_IS(widthp, Const)) {
dtypeSetLogicSized(VN_AS(widthp, Const)->toUInt(), VSigning::UNSIGNED);
}
}
AstSel(FileLine* fl, AstNodeExpr* fromp, int lsb, int bitwidth)
: ASTGEN_SUPER_Sel(fl, fromp, new AstConst(fl, lsb), // Need () constructor
new AstConst(fl, bitwidth)) // Need () constructor
, m_declElWidth{1} {
dtypeSetLogicSized(bitwidth, VSigning::UNSIGNED);
}
ASTGEN_MEMBERS_AstSel;
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit,
const V3Number& width) override {
out.opSel(from, bit.toUInt() + width.toUInt() - 1, bit.toUInt());
}
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override {
return widthp()->isOne() ? "VL_BITSEL_%nq%lq%rq%tq(%lw, %P, %li, %ri)"
: isWide() ? "VL_SEL_%nq%lq%rq%tq(%nw,%lw, %P, %li, %ri, %ti)"
: "VL_SEL_%nq%lq%rq%tq(%lw, %P, %li, %ri, %ti)";
}
string emitSMT() const override { return "((_ extract %t %r) %l)"; }
bool cleanOut() const override { return false; }
bool cleanLhs() const override { return true; }
bool cleanRhs() const override { return true; }
bool cleanThs() const override { return true; }
bool sizeMattersLhs() const override { return false; }
bool sizeMattersRhs() const override { return false; }
bool sizeMattersThs() const override { return false; }
bool sameNode(const AstNode*) const override { return true; }
int instrCount() const override { return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10); }
int widthConst() const { return VN_AS(widthp(), Const)->toSInt(); }
int lsbConst() const { return VN_AS(lsbp(), Const)->toSInt(); }
int msbConst() const { return lsbConst() + widthConst() - 1; }
VNumRange& declRange() VL_MT_STABLE { return m_declRange; }
const VNumRange& declRange() const VL_MT_STABLE { return m_declRange; }
void declRange(const VNumRange& flag) { m_declRange = flag; }
int declElWidth() const { return m_declElWidth; }
void declElWidth(int flag) { m_declElWidth = flag; }
};
class AstSliceSel final : public AstNodeTriop {
// Multiple array element extraction
// @astgen alias op1 := fromp

View File

@ -2358,13 +2358,15 @@ void AstPatMember::dumpJson(std::ostream& str) const {
void AstNodeTriop::dump(std::ostream& str) const { this->AstNodeExpr::dump(str); }
void AstNodeTriop::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
void AstSel::dump(std::ostream& str) const {
this->AstNodeTriop::dump(str);
this->AstNodeBiop::dump(str);
str << " widthConst=" << this->widthConst();
if (declRange().ranged()) {
str << " decl" << declRange() << "]";
if (declElWidth() != 1) str << "/" << declElWidth();
}
}
void AstSel::dumpJson(std::ostream& str) const {
dumpJsonNumFunc(str, widthConst);
if (declRange().ranged()) {
dumpJsonStr(str, "declRange", cvtToStr(declRange()));
dumpJsonNumFunc(str, declElWidth);

View File

@ -233,7 +233,7 @@ class CleanVisitor final : public VNVisitor {
setClean(nodep, true);
}
void visit(AstSel* nodep) override {
operandTriop(nodep);
operandBiop(nodep);
setClean(nodep, nodep->cleanOut());
}
void visit(AstUCFunc* nodep) override {

View File

@ -1310,8 +1310,7 @@ class ConstVisitor final : public VNVisitor {
>= VN_AS(nodep->fromp(), NodeVarRef)->varp()->widthWords()));
}
bool operandSelFull(const AstSel* nodep) {
return (VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
&& nodep->lsbConst() == 0
return (VN_IS(nodep->lsbp(), Const) && nodep->lsbConst() == 0
&& static_cast<int>(nodep->widthConst()) == nodep->fromp()->width());
}
bool operandSelExtend(AstSel* nodep) {
@ -1319,8 +1318,7 @@ class ConstVisitor final : public VNVisitor {
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
// Since select's return unsigned, this is always an extend
AstExtend* const extendp = VN_CAST(nodep->fromp(), Extend);
if (!(m_doV && extendp && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
&& nodep->lsbConst() == 0
if (!(m_doV && extendp && VN_IS(nodep->lsbp(), Const) && nodep->lsbConst() == 0
&& static_cast<int>(nodep->widthConst()) == extendp->lhsp()->width()))
return false;
VL_DO_DANGLING(replaceWChild(nodep, extendp->lhsp()), nodep);
@ -1330,9 +1328,7 @@ class ConstVisitor final : public VNVisitor {
// SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b))
// Add or any operation which doesn't care if we discard top bits
AstNodeBiop* const bip = VN_CAST(nodep->fromp(), NodeBiop);
if (!(m_doV && bip && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const)
&& nodep->lsbConst() == 0))
return false;
if (!(m_doV && bip && VN_IS(nodep->lsbp(), Const) && nodep->lsbConst() == 0)) return false;
if (debug() >= 9) nodep->dumpTree("- SEL(BI)-in: ");
AstNodeExpr* const bilhsp = bip->lhsp()->unlinkFrBack();
AstNodeExpr* const birhsp = bip->rhsp()->unlinkFrBack();
@ -1347,8 +1343,7 @@ class ConstVisitor final : public VNVisitor {
// becomes thought other optimizations
// SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width})
AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR);
if (!(m_doV && shiftp && VN_IS(shiftp->rhsp(), Const) && VN_IS(nodep->lsbp(), Const)
&& VN_IS(nodep->widthp(), Const))) {
if (!(m_doV && shiftp && VN_IS(shiftp->rhsp(), Const) && VN_IS(nodep->lsbp(), Const))) {
return false;
}
AstNodeExpr* const ap = shiftp->lhsp();
@ -1420,14 +1415,13 @@ class ConstVisitor final : public VNVisitor {
// Find range of dtype we are selecting from
// Similar code in V3Unknown::AstSel
const bool doit = true;
if (m_warn && VN_IS(nodep->lsbp(), Const) && VN_IS(nodep->widthp(), Const) && doit) {
if (m_warn && VN_IS(nodep->lsbp(), Const) && doit) {
const int maxDeclBit = nodep->declRange().hiMaxSelect() * nodep->declElWidth()
+ (nodep->declElWidth() - 1);
if (VN_AS(nodep->lsbp(), Const)->num().isFourState()
|| VN_AS(nodep->widthp(), Const)->num().isFourState()) {
if (VN_AS(nodep->lsbp(), Const)->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="
<< nodep->lsbp()->name() << " width=" << nodep->widthp()->name());
<< nodep->lsbp()->name() << " width=" << nodep->widthConst());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
} else if (nodep->declRange().ranged()
@ -1510,10 +1504,8 @@ class ConstVisitor final : public VNVisitor {
if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false;
const AstConst* const lstart = VN_CAST(lhsp->lsbp(), Const);
const AstConst* const rstart = VN_CAST(rhsp->lsbp(), Const);
const AstConst* const lwidth = VN_CAST(lhsp->widthp(), Const);
const AstConst* const rwidth = VN_CAST(rhsp->widthp(), Const);
if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated
const int rend = (rstart->toSInt() + rwidth->toSInt());
if (!lstart || !rstart) return false; // too complicated
const int rend = (rstart->toSInt() + rhsp->widthConst());
return (rend == lstart->toSInt());
}
bool ifMergeAdjacent(AstNodeExpr* lhsp, AstNodeExpr* rhsp) {
@ -1543,10 +1535,8 @@ class ConstVisitor final : public VNVisitor {
if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false;
AstConst* const lstart = VN_CAST(lselp->lsbp(), Const);
AstConst* const rstart = VN_CAST(rselp->lsbp(), Const);
AstConst* const lwidth = VN_CAST(lselp->widthp(), Const);
AstConst* const rwidth = VN_CAST(rselp->widthp(), Const);
if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated
const int rend = (rstart->toSInt() + rwidth->toSInt());
if (!lstart || !rstart) return false; // too complicated
const int rend = (rstart->toSInt() + rselp->widthConst());
// a[i:j] a[j-1:k]
if (rend == lstart->toSInt()) return true;
// a[i:0] a[msb:j]
@ -2566,7 +2556,6 @@ class ConstVisitor final : public VNVisitor {
// SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d)
AstSel* const belowp = VN_AS(nodep->fromp(), Sel);
AstNodeExpr* const fromp = belowp->fromp()->unlinkFrBack();
AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
AstNodeExpr* const lsb1p = nodep->lsbp()->unlinkFrBack();
AstNodeExpr* const lsb2p = belowp->lsbp()->unlinkFrBack();
// Eliminate lower range
@ -2594,7 +2583,7 @@ class ConstVisitor final : public VNVisitor {
newlsbp = new AstAdd{lsb1p->fileline(), lhsp, rhsp};
newlsbp->dtypeFrom(widep);
}
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, widthp};
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, nodep->widthConst()};
nodep->replaceWithKeepDType(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
@ -2636,8 +2625,6 @@ class ConstVisitor final : public VNVisitor {
AstNodeExpr* const fromp = repp->srcp();
AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const);
if (!lsbp) return false;
AstNodeExpr* const widthp = nodep->widthp();
if (!VN_IS(widthp, Const)) return false;
UASSERT_OBJ(fromp->width(), nodep, "Not widthed");
if ((lsbp->toUInt() / fromp->width())
!= ((lsbp->toUInt() + nodep->width() - 1) / fromp->width())) {
@ -2645,10 +2632,9 @@ class ConstVisitor final : public VNVisitor {
}
//
fromp->unlinkFrBack();
widthp->unlinkFrBack();
AstSel* const newp
= new AstSel{nodep->fileline(), fromp,
new AstConst{lsbp->fileline(), lsbp->toUInt() % fromp->width()}, widthp};
AstSel* const newp = new AstSel{
nodep->fileline(), fromp,
new AstConst{lsbp->fileline(), lsbp->toUInt() % fromp->width()}, nodep->widthConst()};
nodep->replaceWithKeepDType(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return true;
@ -2705,14 +2691,13 @@ class ConstVisitor final : public VNVisitor {
AstNodeBiop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeBiop);
UASSERT_OBJ(fromp, nodep, "Called on non biop");
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
//
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
AstNodeExpr* const birhsp = fromp->rhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel{nodep->fileline(), bilhsp, lsbp->cloneTreePure(true),
widthp->cloneTreePure(true)});
fromp->rhsp(new AstSel{nodep->fileline(), birhsp, lsbp, widthp});
fromp->lhsp(
new AstSel{nodep->fileline(), bilhsp, lsbp->cloneTreePure(true), nodep->widthConst()});
fromp->rhsp(new AstSel{nodep->fileline(), birhsp, lsbp, nodep->widthConst()});
nodep->replaceWithKeepDType(fromp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
@ -2721,11 +2706,10 @@ class ConstVisitor final : public VNVisitor {
AstNodeUniop* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeUniop);
UASSERT_OBJ(fromp, nodep, "Called on non biop");
AstNodeExpr* const lsbp = nodep->lsbp()->unlinkFrBack();
AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack();
//
AstNodeExpr* const bilhsp = fromp->lhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel{nodep->fileline(), bilhsp, lsbp, widthp});
fromp->lhsp(new AstSel{nodep->fileline(), bilhsp, lsbp, nodep->widthConst()});
nodep->replaceWithKeepDType(fromp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
@ -3771,9 +3755,9 @@ class ConstVisitor final : public VNVisitor {
TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castShiftR, operandSelShiftLower(nodep)}", "DONE");
TREEOPA("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.castConst, operandSelReplicate(nodep) }", "DONE");
TREEOPA("AstSel{$fromp.castConst, $lsbp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, operandSelReplicate(nodep) }", "DONE");
// V3Tristate requires selects below BufIf1.
// Also do additional operators that are bit-independent, but only definite
// win if bit select is a constant (otherwise we may need to compute bit index several times)

View File

@ -931,13 +931,11 @@ class CoverageVisitor final : public VNVisitor {
const int width = lhsp->dtypep()->width();
const size_t expected = std::is_same<T_Oper, AstXor>::value ? 0x1 << width : width + 1;
if (checkMaxExprs(expected)) return;
AstNodeExpr* unrolledp = new AstSel{fl, lhsp->cloneTree(false),
new AstConst{fl, static_cast<uint32_t>(width - 1)},
new AstConst{fl, 1}};
AstNodeExpr* unrolledp = new AstSel{
fl, lhsp->cloneTree(false), new AstConst{fl, static_cast<uint32_t>(width - 1)}, 1};
for (int bit = width - 2; bit >= 0; bit--) {
AstSel* const selp = new AstSel{fl, lhsp->cloneTree(false),
new AstConst{fl, static_cast<uint32_t>(bit)},
new AstConst{fl, 1}};
new AstConst{fl, static_cast<uint32_t>(bit)}, 1};
unrolledp = new T_Oper{fl, selp, unrolledp};
}
iterate(unrolledp);

View File

@ -358,7 +358,7 @@ class DelayedVisitor final : public VNVisitor {
// Insert new statements before 'insertp'.
// Returns a read reference to the temporary variable.
AstVarRef* createWidened(FileLine* flp, AstScope* scopep, AstNodeDType* dtypep,
AstNodeExpr* sLsbp, AstNodeExpr* sWidthp, const std::string& name,
AstNodeExpr* sLsbp, int sWidth, const std::string& name,
AstNodeExpr* valuep, AstNode* insertp) {
// Create temporary variable.
AstVarScope* const tp = createTemp(flp, scopep, name, dtypep);
@ -369,7 +369,7 @@ class DelayedVisitor final : public VNVisitor {
new AstAssign{flp, new AstVarRef{flp, tp, VAccess::WRITE}, zerop});
// Set the selected bits to 'valuep'
AstSel* const selp = new AstSel{flp, new AstVarRef{flp, tp, VAccess::WRITE},
sLsbp->cloneTreePure(true), sWidthp->cloneTreePure(true)};
sLsbp->cloneTreePure(true), sWidth};
insertp->addHereThisAsNext(new AstAssign{flp, selp, valuep});
// This is the expression to get the value of the temporary
return new AstVarRef{flp, tp, VAccess::READ};
@ -633,22 +633,21 @@ class DelayedVisitor final : public VNVisitor {
// Need to create a mask and widen the value to element size.
lhsNodep = lSelp->fromp();
AstNodeExpr* const sLsbp = lSelp->lsbp();
AstConst* const sWidthp = VN_AS(lSelp->widthp(), Const);
const int sWidth = lSelp->widthConst();
// Create mask value
maskp = [&]() -> AstNodeExpr* {
// Constant mask we can compute here
if (AstConst* const cLsbp = VN_CAST(sLsbp, Const)) {
AstConst* const cp = new AstConst{flp, AstConst::DTyped{}, eDTypep};
cp->num().setMask(sWidthp->toSInt(), cLsbp->toSInt());
cp->num().setMask(sWidth, cLsbp->toSInt());
return cp;
}
// A non-constant mask we must compute at run-time.
AstConst* const onesp
= new AstConst{flp, AstConst::WidthedValue{}, sWidthp->toSInt(), 0};
AstConst* const onesp = new AstConst{flp, AstConst::WidthedValue{}, sWidth, 0};
onesp->num().setAllBits1();
return createWidened(flp, scopep, eDTypep, sLsbp, sWidthp,
return createWidened(flp, scopep, eDTypep, sLsbp, sWidth,
"__VdlyMask" + baseName, onesp, nodep);
}();
@ -659,14 +658,13 @@ class DelayedVisitor final : public VNVisitor {
if (AstConst* const cLsbp = VN_CAST(sLsbp, Const)) {
AstConst* const cp = new AstConst{flp, AstConst::DTyped{}, eDTypep};
cp->num().setAllBits0();
cp->num().opSelInto(cValuep->num(), cLsbp->toSInt(),
sWidthp->toSInt());
cp->num().opSelInto(cValuep->num(), cLsbp->toSInt(), sWidth);
return cp;
}
}
// A non-constant value we must adjust.
return createWidened(flp, scopep, eDTypep, sLsbp, sWidthp, //
return createWidened(flp, scopep, eDTypep, sLsbp, sWidth, //
"__VdlyElem" + baseName, valuep, nodep);
}();
} else {

View File

@ -172,7 +172,7 @@ class AstToDfgVisitor final : public VNVisitor {
if (AstSel* const selp = VN_CAST(nodep, Sel)) {
AstVarRef* const vrefp = VN_CAST(selp->fromp(), VarRef);
const AstConst* const lsbp = VN_CAST(selp->lsbp(), Const);
if (!vrefp || !lsbp || !VN_IS(selp->widthp(), Const)) {
if (!vrefp || !lsbp) {
++m_ctx.m_nonRepLhs;
return false;
}
@ -555,11 +555,7 @@ class AstToDfgVisitor final : public VNVisitor {
void visit(AstSel* nodep) override {
UASSERT_OBJ(!nodep->user1p(), nodep, "Already has Dfg vertex");
if (unhandled(nodep)) return;
if (!VN_IS(nodep->widthp(), Const)) { // This should never be taken, but paranoia
m_foundUnhandled = true;
++m_ctx.m_nonRepNode;
return;
}
iterate(nodep->fromp());
if (m_foundUnhandled) return;

View File

@ -173,8 +173,8 @@ class DfgToAstVisitor final : DfgVisitor {
FileLine* const flp = dfgVarp->driverFileLine(idx);
AstVarRef* const refp = new AstVarRef{flp, dfgVarp->varp(), VAccess::WRITE};
AstConst* const lsbp = new AstConst{flp, dfgVarp->driverLsb(idx)};
AstConst* const widthp = new AstConst{flp, edge.sourcep()->width()};
AstSel* const lhsp = new AstSel{flp, refp, lsbp, widthp};
const int width = static_cast<int>(edge.sourcep()->width());
AstSel* const lhsp = new AstSel{flp, refp, lsbp, width};
// Add assignment of the value to the selected bits
addResultEquation(flp, lhsp, rhsp);
});
@ -218,16 +218,14 @@ class DfgToAstVisitor final : DfgVisitor {
FileLine* const flp = vtxp->fileline();
AstNodeExpr* const fromp = convertDfgVertexToAstNodeExpr(vtxp->fromp());
AstConst* const lsbp = new AstConst{flp, vtxp->lsb()};
AstConst* const widthp = new AstConst{flp, vtxp->width()};
m_resultp = new AstSel{flp, fromp, lsbp, widthp};
m_resultp = new AstSel{flp, fromp, lsbp, static_cast<int>(vtxp->width())};
}
void visit(DfgMux* vtxp) override {
FileLine* const flp = vtxp->fileline();
AstNodeExpr* const fromp = convertDfgVertexToAstNodeExpr(vtxp->fromp());
AstNodeExpr* const lsbp = convertDfgVertexToAstNodeExpr(vtxp->lsbp());
AstConst* const widthp = new AstConst{flp, vtxp->width()};
m_resultp = new AstSel{flp, fromp, lsbp, widthp};
m_resultp = new AstSel{flp, fromp, lsbp, static_cast<int>(vtxp->width())};
}
// The rest of the 'visit' methods are generated by 'astgen'

View File

@ -421,6 +421,7 @@ public:
bool decind = false;
bool rhs = true;
if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
UASSERT_OBJ(selp->widthMin() == selp->widthConst(), selp, "Width mismatch");
if (selp->widthMin() == 1) {
putnbs(nodep, "VL_ASSIGNBIT_");
emitIQW(selp->fromp());
@ -1260,7 +1261,8 @@ public:
}
void visit(AstSel* nodep) override {
// Note ASSIGN checks for this on a LHS
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->widthp());
UASSERT_OBJ(nodep->widthMin() == nodep->widthConst(), nodep, "Width mismatch");
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nullptr);
}
void visit(AstReplicate* nodep) override {
if (nodep->srcp()->widthMin() == 1 && !nodep->isWide()) {

View File

@ -642,11 +642,11 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
}
puts("[");
if (VN_IS(nodep->lsbp(), Const)) {
if (nodep->widthp()->isOne()) {
if (nodep->widthConst() == 1) {
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt() + offset));
} else {
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt()
+ VN_AS(nodep->widthp(), Const)->toSInt() + offset - 1));
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt() + nodep->widthConst() + offset
- 1));
puts(":");
puts(cvtToStr(VN_AS(nodep->lsbp(), Const)->toSInt() + offset));
}
@ -657,7 +657,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst {
puts(cvtToStr(offset));
}
putfs(nodep, "+:");
iterateAndNextConstNull(nodep->widthp());
puts(cvtToStr(nodep->widthConst()));
puts("]");
}
puts("]");

View File

@ -255,6 +255,11 @@ class EmitXmlFileVisitor final : public VNVisitorConst {
putsQuoted(nodep->funcp() ? nodep->funcp()->name() : nodep->name());
outputChildrenEnd(nodep, "");
}
void visit(AstSel* nodep) override {
outputTag(nodep, "");
puts(" widthConst=\"" + cvtToStr(nodep->widthConst()) + "\"");
outputChildrenEnd(nodep, "");
}
// Data types
void visit(AstBasicDType* nodep) override {

View File

@ -457,7 +457,7 @@ class GateClkDecomp final {
// RHS
if (const AstSel* const rselp = VN_CAST(rhsp, Sel)) {
if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) {
if (VN_IS(rselp->lsbp(), Const)) {
if (clkOffset < rselp->lsbConst() || clkOffset > rselp->msbConst()) return;
clkOffset -= rselp->lsbConst();
} else {
@ -473,7 +473,7 @@ class GateClkDecomp final {
// LHS
if (const AstSel* const lselp = VN_CAST(lhsp, Sel)) {
if (VN_IS(lselp->lsbp(), Const) && VN_IS(lselp->widthp(), Const)) {
if (VN_IS(lselp->lsbp(), Const)) {
clkOffset += lselp->lsbConst();
} else {
return;
@ -1248,10 +1248,8 @@ class GateMergeAssignments final {
if (!pRefp || !cRefp || !cRefp->sameNode(pRefp)) return nullptr; // not the same var
const AstConst* const pstart = VN_CAST(prevSelp->lsbp(), Const);
const AstConst* const pwidth = VN_CAST(prevSelp->widthp(), Const);
const AstConst* const cstart = VN_CAST(currSelp->lsbp(), Const);
const AstConst* const cwidth = VN_CAST(currSelp->widthp(), Const);
if (!pstart || !pwidth || !cstart || !cwidth) return nullptr; // too complicated
if (!pstart || !cstart) return nullptr; // too complicated
if (currSelp->msbConst() + 1 == prevSelp->lsbConst()) {
return new AstSel{cRefp->fileline(), cRefp->cloneTree(false), currSelp->lsbConst(),

View File

@ -215,6 +215,11 @@ class HasherVisitor final : public VNVisitorConst {
void visit(AstNodeExpr* nodep) override {
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, []() {});
}
void visit(AstSel* nodep) override {
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [this, nodep]() { //
m_hash += nodep->widthConst();
});
}
void visit(AstConst* nodep) override {
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [this, nodep]() { //
m_hash += nodep->num().toHash();

View File

@ -140,7 +140,6 @@ private:
// the fromp() node which could be disproportionately large.
const VisitBase vb{this, nodep};
iterateAndNextConstNull(nodep->lsbp());
iterateAndNextConstNull(nodep->widthp());
}
void visit(AstConcat* nodep) override {
if (m_ignoreRemaining) return;

View File

@ -270,7 +270,6 @@ class LinkLValueVisitor final : public VNVisitor {
// Only set lvalues on the from
m_setRefLvalue = VAccess::NOCHANGE;
iterateAndNextNull(nodep->lsbp());
iterateAndNextNull(nodep->widthp());
}
void visit(AstNodeSel* nodep) override {
VL_RESTORER(m_setRefLvalue);

View File

@ -503,9 +503,15 @@ class ConstraintExprVisitor final : public VNVisitor {
UASSERT_OBJ(smtExpr != "", nodep,
"Node needs randomization constraint, but no emitSMT: " << nodep);
if (lhsp) lhsp = VN_AS(iterateSubtreeReturnEdits(lhsp->unlinkFrBack()), NodeExpr);
if (rhsp) rhsp = VN_AS(iterateSubtreeReturnEdits(rhsp->unlinkFrBack()), NodeExpr);
if (thsp) thsp = VN_AS(iterateSubtreeReturnEdits(thsp->unlinkFrBack()), NodeExpr);
if (lhsp)
lhsp = VN_AS(iterateSubtreeReturnEdits(lhsp->backp() ? lhsp->unlinkFrBack() : lhsp),
NodeExpr);
if (rhsp)
rhsp = VN_AS(iterateSubtreeReturnEdits(rhsp->backp() ? rhsp->unlinkFrBack() : rhsp),
NodeExpr);
if (thsp)
thsp = VN_AS(iterateSubtreeReturnEdits(thsp->backp() ? thsp->unlinkFrBack() : thsp),
NodeExpr);
AstNodeExpr* argsp = nullptr;
for (string::iterator pos = smtExpr.begin(); pos != smtExpr.end(); ++pos) {
@ -704,13 +710,11 @@ class ConstraintExprVisitor final : public VNVisitor {
void visit(AstSel* nodep) override {
if (editFormat(nodep)) return;
VNRelinker handle;
AstNodeExpr* const widthp = nodep->widthp()->unlinkFrBack(&handle);
FileLine* const fl = nodep->fileline();
AstNodeExpr* const msbp
= new AstSFormatF{fl, "%1d", false,
new AstAdd{fl, nodep->lsbp()->cloneTreePure(false),
new AstSub{fl, widthp, new AstConst{fl, 1}}}};
handle.relink(msbp);
AstNodeExpr* const msbp = new AstSFormatF{
fl, "%1d", false,
new AstAdd{fl, nodep->lsbp()->cloneTreePure(false),
new AstConst{fl, static_cast<uint32_t>(nodep->widthConst() - 1)}}};
AstNodeExpr* const lsbp
= new AstSFormatF{fl, "%1d", false, nodep->lsbp()->unlinkFrBack(&handle)};
handle.relink(lsbp);
@ -1562,9 +1566,7 @@ class RandomizeVisitor final : public VNVisitor {
fl,
new AstSub{fl, tempRefp,
new AstConst{fl, static_cast<uint32_t>(aryDTypep->lo())}},
new AstConst{fl, 0},
new AstConst{
fl, static_cast<uint32_t>(V3Number::log2b(aryDTypep->hi()) + 1)}}};
new AstConst{fl, 0}, V3Number::log2b(aryDTypep->hi()) + 1}};
} else if (VN_IS(tempDTypep, AssocArrayDType))
tempElementp = new AstAssocSel{fl, tempExprp, tempRefp};
else if (VN_IS(tempDTypep, QueueDType))

View File

@ -581,23 +581,13 @@ private:
}
}
void visit(AstNodeBiop* nodep) override {
if (!optimizable()) return; // Accelerate
checkNodeInfo(nodep);
iterateChildrenConst(nodep);
if (!m_checkOnly && optimizable()) {
nodep->numberOperate(newConst(nodep)->num(), fetchConst(nodep->lhsp())->num(),
fetchConst(nodep->rhsp())->num());
}
}
void visit(AstNodeTriop* nodep) override {
if (!optimizable()) return; // Accelerate
checkNodeInfo(nodep);
iterateChildrenConst(nodep);
if (!m_checkOnly && optimizable()) {
AstConst* const valuep = newConst(nodep);
nodep->numberOperate(newConst(nodep)->num(), fetchConst(nodep->lhsp())->num(),
fetchConst(nodep->rhsp())->num(),
fetchConst(nodep->thsp())->num());
fetchConst(nodep->rhsp())->num());
// See #5490. 'numberOperate' on partially out of range select yields 'x' bits,
// but in reality it would yield '0's without V3Table, so force 'x' bits to '0',
// to ensure the result is the same with and without V3Table.
@ -607,6 +597,16 @@ private:
}
}
}
void visit(AstNodeTriop* nodep) override {
if (!optimizable()) return; // Accelerate
checkNodeInfo(nodep);
iterateChildrenConst(nodep);
if (!m_checkOnly && optimizable()) {
nodep->numberOperate(newConst(nodep)->num(), fetchConst(nodep->lhsp())->num(),
fetchConst(nodep->rhsp())->num(),
fetchConst(nodep->thsp())->num());
}
}
void visit(AstNodeQuadop* nodep) override {
if (!optimizable()) return; // Accelerate
checkNodeInfo(nodep);

View File

@ -381,8 +381,6 @@ public:
m_refs.erase(refp);
} else if (AstVarRef* const refp = VN_CAST(selp->lsbp(), VarRef)) {
m_refs.erase(refp);
} else if (AstVarRef* const refp = VN_CAST(selp->widthp(), VarRef)) {
m_refs.erase(refp);
}
UASSERT_OBJ(reinterpret_cast<uintptr_t>(selp->op1p()) != 1, selp, "stale");
visitor->iterate(selp);
@ -1010,28 +1008,19 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
}
UASSERT_OBJ(varp->attrSplitVar() || varp->user2(), varp, "must be a split candidate");
const std::array<AstConst*, 2> consts
= {{VN_CAST(nodep->lsbp(), Const),
VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}}
if (consts[0] && consts[1]) { // OK
if (AstConst* const lsbConstp = VN_CAST(nodep->lsbp(), Const)) { // OK
refit->second.append(
PackedVarRefEntry(nodep, consts[0]->toSInt() + refit->second.basicp()->lo(),
consts[1]->toUInt()),
PackedVarRefEntry(nodep, lsbConstp->toSInt() + refit->second.basicp()->lo(),
nodep->widthConst()),
vrefp->access());
UINFO(5, varp->prettyName()
<< " [" << consts[0]->toSInt() << ":+" << consts[1]->toSInt()
<< " [" << lsbConstp->toSInt() << ":+" << nodep->widthConst()
<< "] lsb:" << refit->second.basicp()->lo());
} else {
if (varp->attrSplitVar()) {
warnNoSplit(vrefp->varp(), nodep, "its bit range cannot be determined statically");
varp->attrSplitVar(false);
}
if (!consts[0]) {
UINFO(4, "LSB " << nodep->lsbp() << " is expected to be constant, but not");
}
if (!consts[1]) {
UINFO(4, "WIDTH " << nodep->widthp() << " is expected to be constant, but not");
}
m_refs.erase(varp);
iterateChildren(nodep);
}
@ -1261,15 +1250,10 @@ class SplitPackedVarVisitor final : public VNVisitor, public SplitVarImpl {
info.ineligible = true;
continue;
}
AstConst* const widthConstp = VN_CAST(selp->widthp(), Const);
if (!widthConstp) {
info.ineligible = true;
continue;
}
// All good, record the selection range
const int32_t lsb = lsbConstp->toSInt();
const int32_t msb = lsb + widthConstp->toSInt() - 1;
const int32_t msb = lsb + selp->widthConst() - 1;
info.ranges.emplace_back(lsb, msb);
}

View File

@ -1160,7 +1160,7 @@ class TristateVisitor final : public TristateBaseVisitor {
AstNodeExpr* const en1p = getEnp(nodep->fromp());
AstNodeExpr* const enp
= new AstSel{nodep->fileline(), en1p, nodep->lsbp()->cloneTreePure(true),
nodep->widthp()->cloneTree(true)};
nodep->widthConst()};
UINFO(9, " newsel " << enp);
nodep->user1p(enp); // propagate up SEL(fromp->enable, value)
m_tgraph.didProcess(nodep);

View File

@ -972,16 +972,7 @@ class WidthVisitor final : public VNVisitor {
userIterateAndNext(nodep->fromp(), WidthVP{CONTEXT_DET, PRELIM}.p());
userIterateAndNext(nodep->lsbp(), WidthVP{SELF, PRELIM}.p());
checkCvtUS(nodep->fromp());
iterateCheckSizedSelf(nodep, "Select Width", nodep->widthp(), SELF, BOTH);
iterateCheckSizedSelf(nodep, "Select LHS", nodep->fromp(), SELF, BOTH);
V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change
const AstConst* const widthConstp = VN_CAST(nodep->widthp(), Const);
if (!widthConstp) {
nodep->v3error(
"Width of bit extract isn't a constant"); // Impossible? // LCOV_EXCL_LINE
nodep->dtypeSetBit();
return;
}
int width = nodep->widthConst();
if (width <= 0) {
nodep->v3error("Width of bit extract must be positive (IEEE 1800-2023 11.5.1)");
@ -997,8 +988,7 @@ class WidthVisitor final : public VNVisitor {
<< nodep->msbConst() << "<" << nodep->lsbConst());
width = (nodep->lsbConst() - nodep->msbConst() + 1);
nodep->dtypeSetLogicSized(width, VSigning::UNSIGNED);
pushDeletep(nodep->widthp());
nodep->widthp()->replaceWith(new AstConst(nodep->widthp()->fileline(), width));
nodep->widthConst(width);
pushDeletep(nodep->lsbp());
nodep->lsbp()->replaceWith(new AstConst{nodep->lsbp()->fileline(), 0});
}

View File

@ -262,8 +262,7 @@ class WidthSelVisitor final : public VNVisitor {
// cppcheck-suppress zerodivcond
const int elwidth = adtypep->width() / fromRange.elements();
AstSel* const newp = new AstSel{
nodep->fileline(), fromp, newMulConst(nodep->fileline(), elwidth, subp),
new AstConst(nodep->fileline(), AstConst::Unsized32{}, elwidth)};
nodep->fileline(), fromp, newMulConst(nodep->fileline(), elwidth, subp), elwidth};
newp->declRange(fromRange);
newp->declElWidth(elwidth);
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
@ -333,9 +332,7 @@ class WidthSelVisitor final : public VNVisitor {
} else if (VN_IS(ddtypep, BasicDType)) {
// SELBIT(range, index) -> SEL(array, index, 1)
AstSel* const newp
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
// Unsized so width from user
new AstConst{nodep->fileline(), AstConst::Unsized32{}, 1}};
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange), 1};
newp->declRange(fromRange);
UINFO(6, " new " << newp);
if (debug() >= 9) newp->dumpTree("- SELBTn: ");
@ -344,9 +341,7 @@ class WidthSelVisitor final : public VNVisitor {
} else if (VN_IS(ddtypep, NodeUOrStructDType)) { // A bit from the packed struct
// SELBIT(range, index) -> SEL(array, index, 1)
AstSel* const newp
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange),
// Unsized so width from user
new AstConst{nodep->fileline(), AstConst::Unsized32{}, 1}};
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange), 1};
newp->declRange(fromRange);
UINFO(6, " new " << newp);
if (debug() >= 9) newp->dumpTree("- SELBTn: ");
@ -449,10 +444,10 @@ class WidthSelVisitor final : public VNVisitor {
lsb = x;
}
const int elwidth = adtypep->width() / fromRange.elements();
AstSel* const newp = new AstSel{
nodep->fileline(), fromp,
newMulConst(nodep->fileline(), elwidth, newSubLsbOf(lsbp, fromRange)),
new AstConst(nodep->fileline(), AstConst::Unsized32{}, (msb - lsb + 1) * elwidth)};
AstSel* const newp
= new AstSel{nodep->fileline(), fromp,
newMulConst(nodep->fileline(), elwidth, newSubLsbOf(lsbp, fromRange)),
(msb - lsb + 1) * elwidth};
newp->declRange(fromRange);
newp->declElWidth(elwidth);
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
@ -477,11 +472,8 @@ class WidthSelVisitor final : public VNVisitor {
msb = lsb;
lsb = x;
}
AstNodeExpr* const widthp = new AstConst(
msbp->fileline(), AstConst::Unsized32{}, // Unsized so width from user
msb + 1 - lsb);
AstSel* const newp
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp};
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange),
msb + 1 - lsb};
newp->declRange(fromRange);
UINFO(6, " new " << newp);
// if (debug() >= 9) newp->dumpTree("- SELEXnew: ");
@ -499,11 +491,8 @@ class WidthSelVisitor final : public VNVisitor {
msb = lsb;
lsb = x;
}
AstNodeExpr* const widthp = new AstConst(
msbp->fileline(), AstConst::Unsized32{}, // Unsized so width from user
msb + 1 - lsb);
AstSel* const newp
= new AstSel{nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp};
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange),
msb + 1 - lsb};
newp->declRange(fromRange);
UINFO(6, " new " << newp);
// if (debug() >= 9) newp->dumpTree("- SELEXnew: ");
@ -581,11 +570,10 @@ class WidthSelVisitor final : public VNVisitor {
|| (VN_IS(ddtypep, NodeUOrStructDType)
&& VN_AS(ddtypep, NodeUOrStructDType)->packedUnsup())) {
int elwidth = 1;
AstNodeExpr* newwidthp = widthp;
int newwidth = width;
if (const AstPackArrayDType* const adtypep = VN_CAST(ddtypep, PackArrayDType)) {
elwidth = adtypep->width() / fromRange.elements();
newwidthp
= new AstConst(nodep->fileline(), AstConst::Unsized32{}, width * elwidth);
newwidth = width * elwidth;
}
AstNodeExpr* newlsbp = nullptr;
if (VN_IS(nodep, SelPlus)) {
@ -608,7 +596,7 @@ class WidthSelVisitor final : public VNVisitor {
nodep->v3fatalSrc("Bad Case");
}
if (elwidth != 1) newlsbp = newMulConst(nodep->fileline(), elwidth, newlsbp);
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, newwidthp};
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, newwidth};
newp->declRange(fromRange);
newp->declElWidth(elwidth);
UINFO(6, " new " << newp);

View File

@ -206,15 +206,15 @@
if (0 == 1) begin
for (int loop_var = 0; loop_var < 1; loop_var++) begin
%000000 if (cyc[loop_var] && t2) $write("");
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(t2==0) => 0 hier=top.t
end
end
// stop at the first layer even if there's more to find
%000007 if ((cyc[3+32'(t1 && t2)+:2] == cyc[5+32'(t3 || t4)+:2]) || cyc[31]) $write("");
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==1) => 1 hier=top.t
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==1) => 1 hier=top.t
-000000 point: comment=(cyc[31]==1) => 1 hier=top.t
// impossible branches and redundant terms
%000005 if ((t1 && t2) && ~(t1 && t3) && (t1 || t4)) $write("");
@ -233,12 +233,12 @@
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
// demonstrate current limitations of term matching scheme
%000005 if ((cyc[0] && cyc[1]) && ~(cyc[1-1] && cyc[2]) && (cyc[2-2] || cyc[3])) $write("");
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==0 && cyc[3]==0) => 0 hier=top.t
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==0 && cyc[3]==0) => 0 hier=top.t
-000004 point: comment=(cyc[0]==0) => 0 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[3]==1) => 1 hier=top.t
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
//verilator coverage_off

View File

@ -206,15 +206,15 @@
if (0 == 1) begin
for (int loop_var = 0; loop_var < 1; loop_var++) begin
%000000 if (cyc[loop_var] && t2) $write("");
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(t2==0) => 0 hier=top.t
end
end
// stop at the first layer even if there's more to find
%000007 if ((cyc[3+32'(t1 && t2)+:2] == cyc[5+32'(t3 || t4)+:2]) || cyc[31]) $write("");
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==1) => 1 hier=top.t
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==1) => 1 hier=top.t
-000000 point: comment=(cyc[31]==1) => 1 hier=top.t
// impossible branches and redundant terms
%000005 if ((t1 && t2) && ~(t1 && t3) && (t1 || t4)) $write("");
@ -233,12 +233,12 @@
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
// demonstrate current limitations of term matching scheme
%000005 if ((cyc[0] && cyc[1]) && ~(cyc[1-1] && cyc[2]) && (cyc[2-2] || cyc[3])) $write("");
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==0 && cyc[3]==0) => 0 hier=top.t
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==0 && cyc[3]==0) => 0 hier=top.t
-000004 point: comment=(cyc[0]==0) => 0 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[3]==1) => 1 hier=top.t
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
//verilator coverage_off

View File

@ -206,15 +206,15 @@
if (0 == 1) begin
for (int loop_var = 0; loop_var < 1; loop_var++) begin
%000000 if (cyc[loop_var] && t2) $write("");
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(t2==0) => 0 hier=top.t
end
end
// stop at the first layer even if there's more to find
%000007 if ((cyc[3+32'(t1 && t2)+:2] == cyc[5+32'(t3 || t4)+:2]) || cyc[31]) $write("");
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==1) => 1 hier=top.t
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==1) => 1 hier=top.t
-000000 point: comment=(cyc[31]==1) => 1 hier=top.t
// impossible branches and redundant terms
%000005 if ((t1 && t2) && ~(t1 && t3) && (t1 || t4)) $write("");
@ -233,12 +233,12 @@
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
// demonstrate current limitations of term matching scheme
%000005 if ((cyc[0] && cyc[1]) && ~(cyc[1-1] && cyc[2]) && (cyc[2-2] || cyc[3])) $write("");
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==0 && cyc[3]==0) => 0 hier=top.t
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==0 && cyc[3]==0) => 0 hier=top.t
-000004 point: comment=(cyc[0]==0) => 0 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[3]==1) => 1 hier=top.t
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
//verilator coverage_off

View File

@ -282,16 +282,16 @@
%000000 if (cyc[loop_var] && t2) $write("");
-000000 point: comment=if hier=top.t
-000000 point: comment=else hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:32'h1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==0) => 0 hier=top.t
-000000 point: comment=(cyc[loop_var[4:0]+:1]]==1 && t2==1) => 1 hier=top.t
-000000 point: comment=(t2==0) => 0 hier=top.t
end
end
// stop at the first layer even if there's more to find
%000007 if ((cyc[3+32'(t1 && t2)+:2] == cyc[5+32'(t3 || t4)+:2]) || cyc[31]) $write("");
-000002 point: comment=else hier=top.t
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:32'sh2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:32'sh2]])==1) => 1 hier=top.t
-000002 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==0 && cyc[31]==0) => 0 hier=top.t
-000007 point: comment=((cyc[(32'sh3 + (t1 && t2))[4:0]+:2]] == cyc[(32'sh5 + (t3 || t4))[4:0]+:2]])==1) => 1 hier=top.t
-000000 point: comment=(cyc[31]==1) => 1 hier=top.t
-000007 point: comment=if hier=top.t
// impossible branches and redundant terms
@ -316,12 +316,12 @@
// demonstrate current limitations of term matching scheme
%000008 if ((cyc[0] && cyc[1]) && ~(cyc[1-1] && cyc[2]) && (cyc[2-2] || cyc[3])) $write("");
-000008 point: comment=else hier=top.t
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==0 && cyc[3]==0) => 0 hier=top.t
-000002 point: comment=(cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==1 && cyc[2]==1) => 0 hier=top.t
-000003 point: comment=(cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==0 && cyc[3]==0) => 0 hier=top.t
-000004 point: comment=(cyc[0]==0) => 0 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:32'h1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:32'h1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[(32'sh1 - 32'sh1)[4:0]+:1]]==0 && cyc[3]==1) => 1 hier=top.t
-000001 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[(32'sh2 - 32'sh2)[4:0]+:1]]==1) => 1 hier=top.t
-000000 point: comment=(cyc[0]==1 && cyc[1]==1 && cyc[2]==0 && cyc[3]==1) => 1 hier=top.t
-000005 point: comment=(cyc[1]==0) => 0 hier=top.t
-000001 point: comment=if hier=top.t

View File

@ -59,7 +59,7 @@ module Vt_debug_emitv_t;
$write("");
end
if (downto_32[(ident('sh21) - 'h20)[5:0] + 32
+:'h1]]) begin
+:1]]) begin
$write("");
end
if ((| downto_32[48:40])) begin

View File

@ -103,12 +103,12 @@
{"type":"CONST","name":"2'h0","addr":"(WC)","loc":"d,19:34,19:39","dtypep":"(XC)"}
],
"rhsp": [
{"type":"SEL","name":"","addr":"(YC)","loc":"d,19:20,19:21","dtypep":"(XC)","declRange":"[15:0]","declElWidth":1,
{"type":"SEL","name":"","addr":"(YC)","loc":"d,19:20,19:21","dtypep":"(XC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__val","addr":"(ZC)","loc":"d,19:17,19:20","dtypep":"(H)","access":"RD","varp":"(CB)","varScopep":"(BB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"SEL","name":"","addr":"(AD)","loc":"d,19:22,19:23","dtypep":"(BD)",
{"type":"SEL","name":"","addr":"(AD)","loc":"d,19:22,19:23","dtypep":"(BD)","widthConst":4,
"fromp": [
{"type":"MULS","name":"","addr":"(CD)","loc":"d,19:22,19:23","dtypep":"(NC)",
"lhsp": [
@ -120,188 +120,164 @@
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(FD)","loc":"d,19:22,19:23","dtypep":"(GD)"}
],
"widthp": [
{"type":"CONST","name":"32'h4","addr":"(HD)","loc":"d,19:22,19:23","dtypep":"(GD)"}
]}
],
"widthp": [
{"type":"CONST","name":"32'sh2","addr":"(ID)","loc":"d,19:28,19:29","dtypep":"(NC)"}
]}
]}
],
"lhsp": [
{"type":"SEL","name":"","addr":"(JD)","loc":"d,19:10,19:11","dtypep":"(RC)","declRange":"[6:0]","declElWidth":1,
{"type":"SEL","name":"","addr":"(HD)","loc":"d,19:10,19:11","dtypep":"(RC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(KD)","loc":"d,19:7,19:10","dtypep":"(K)","access":"WR","varp":"(EB)","varScopep":"(DB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(ID)","loc":"d,19:7,19:10","dtypep":"(K)","access":"WR","varp":"(EB)","varScopep":"(DB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"SEL","name":"","addr":"(LD)","loc":"d,19:11,19:12","dtypep":"(MD)",
{"type":"SEL","name":"","addr":"(JD)","loc":"d,19:11,19:12","dtypep":"(KD)","widthConst":3,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(ND)","loc":"d,19:11,19:12","dtypep":"(GB)","access":"RD","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(LD)","loc":"d,19:11,19:12","dtypep":"(GB)","access":"RD","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(OD)","loc":"d,19:11,19:12","dtypep":"(GD)"}
],
"widthp": [
{"type":"CONST","name":"32'h3","addr":"(PD)","loc":"d,19:11,19:12","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(MD)","loc":"d,19:11,19:12","dtypep":"(GD)"}
]}
],
"widthp": [
{"type":"CONST","name":"32'h1","addr":"(QD)","loc":"d,19:10,19:11","dtypep":"(GD)"}
]}
],"timingControlp": []}
],
"incsp": [
{"type":"ASSIGN","name":"","addr":"(RD)","loc":"d,18:24,18:26","dtypep":"(GB)",
{"type":"ASSIGN","name":"","addr":"(ND)","loc":"d,18:24,18:26","dtypep":"(GB)",
"rhsp": [
{"type":"ADD","name":"","addr":"(SD)","loc":"d,18:24,18:26","dtypep":"(GD)",
{"type":"ADD","name":"","addr":"(OD)","loc":"d,18:24,18:26","dtypep":"(GD)",
"lhsp": [
{"type":"CONST","name":"32'h1","addr":"(TD)","loc":"d,18:24,18:26","dtypep":"(GD)"}
{"type":"CONST","name":"32'h1","addr":"(PD)","loc":"d,18:24,18:26","dtypep":"(GD)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(UD)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"RD","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(QD)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"RD","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
]}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(VD)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"WR","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__i","addr":"(RD)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"WR","varp":"(HB)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
]},
{"type":"ASSIGN","name":"","addr":"(WD)","loc":"d,21:5,21:11","dtypep":"(K)",
{"type":"ASSIGN","name":"","addr":"(SD)","loc":"d,21:5,21:11","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(XD)","loc":"d,21:12,21:15","dtypep":"(K)","access":"RD","varp":"(EB)","varScopep":"(DB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__ret","addr":"(TD)","loc":"d,21:12,21:15","dtypep":"(K)","access":"RD","varp":"(EB)","varScopep":"(DB)","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(YD)","loc":"d,21:5,21:11","dtypep":"(K)","access":"WR","varp":"(AB)","varScopep":"(Z)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(UD)","loc":"d,21:5,21:11","dtypep":"(K)","access":"WR","varp":"(AB)","varScopep":"(Z)","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"ASSIGN","name":"","addr":"(ZD)","loc":"d,24:14,24:15","dtypep":"(K)",
{"type":"ASSIGN","name":"","addr":"(VD)","loc":"d,24:14,24:15","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(AE)","loc":"d,24:16,24:19","dtypep":"(K)","access":"RD","varp":"(AB)","varScopep":"(Z)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__0__Vfuncout","addr":"(WD)","loc":"d,24:16,24:19","dtypep":"(K)","access":"RD","varp":"(AB)","varScopep":"(Z)","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"o_a","addr":"(BE)","loc":"d,24:10,24:13","dtypep":"(K)","access":"WR","varp":"(J)","varScopep":"(T)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"o_a","addr":"(XD)","loc":"d,24:10,24:13","dtypep":"(K)","access":"WR","varp":"(J)","varScopep":"(T)","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
]},
{"type":"ALWAYS","name":"","addr":"(CE)","loc":"d,25:14,25:15","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
{"type":"ALWAYS","name":"","addr":"(YD)","loc":"d,25:14,25:15","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [],
"stmtsp": [
{"type":"COMMENT","name":"Function: foo","addr":"(DE)","loc":"d,25:16,25:19"},
{"type":"ASSIGN","name":"","addr":"(EE)","loc":"d,25:20,25:23","dtypep":"(H)",
{"type":"COMMENT","name":"Function: foo","addr":"(ZD)","loc":"d,25:16,25:19"},
{"type":"ASSIGN","name":"","addr":"(AE)","loc":"d,25:20,25:23","dtypep":"(H)",
"rhsp": [
{"type":"VARREF","name":"i_b","addr":"(FE)","loc":"d,25:20,25:23","dtypep":"(H)","access":"RD","varp":"(I)","varScopep":"(S)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"i_b","addr":"(BE)","loc":"d,25:20,25:23","dtypep":"(H)","access":"RD","varp":"(I)","varScopep":"(S)","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(GE)","loc":"d,15:57,15:60","dtypep":"(H)","access":"WR","varp":"(LB)","varScopep":"(KB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(CE)","loc":"d,15:57,15:60","dtypep":"(H)","access":"WR","varp":"(LB)","varScopep":"(KB)","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"CRESET","name":"","addr":"(HE)","loc":"d,16:17,16:20","constructing":false,
{"type":"CRESET","name":"","addr":"(DE)","loc":"d,16:17,16:20","constructing":false,
"varrefp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(IE)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(EE)","loc":"d,16:17,16:20","dtypep":"(K)","access":"WR","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
]},
{"type":"CRESET","name":"","addr":"(JE)","loc":"d,17:13,17:14","constructing":false,
{"type":"CRESET","name":"","addr":"(FE)","loc":"d,17:13,17:14","constructing":false,
"varrefp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(KE)","loc":"d,17:13,17:14","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(GE)","loc":"d,17:13,17:14","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
]},
{"type":"ASSIGN","name":"","addr":"(LE)","loc":"d,18:11,18:12","dtypep":"(GB)",
{"type":"ASSIGN","name":"","addr":"(HE)","loc":"d,18:11,18:12","dtypep":"(GB)",
"rhsp": [
{"type":"CONST","name":"32'sh0","addr":"(ME)","loc":"d,18:12,18:13","dtypep":"(NC)"}
{"type":"CONST","name":"32'sh0","addr":"(IE)","loc":"d,18:12,18:13","dtypep":"(NC)"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(NE)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(JE)","loc":"d,18:10,18:11","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"WHILE","name":"","addr":"(OE)","loc":"d,18:5,18:8","precondsp": [],
{"type":"WHILE","name":"","addr":"(KE)","loc":"d,18:5,18:8","precondsp": [],
"condp": [
{"type":"GTS","name":"","addr":"(PE)","loc":"d,18:18,18:19","dtypep":"(RC)",
{"type":"GTS","name":"","addr":"(LE)","loc":"d,18:18,18:19","dtypep":"(RC)",
"lhsp": [
{"type":"CONST","name":"32'sh7","addr":"(QE)","loc":"d,18:20,18:21","dtypep":"(NC)"}
{"type":"CONST","name":"32'sh7","addr":"(ME)","loc":"d,18:20,18:21","dtypep":"(NC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(RE)","loc":"d,18:16,18:17","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(NE)","loc":"d,18:16,18:17","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
]}
],
"stmtsp": [
{"type":"ASSIGN","name":"","addr":"(SE)","loc":"d,19:14,19:15","dtypep":"(RC)",
{"type":"ASSIGN","name":"","addr":"(OE)","loc":"d,19:14,19:15","dtypep":"(RC)",
"rhsp": [
{"type":"EQ","name":"","addr":"(TE)","loc":"d,19:31,19:33","dtypep":"(RC)",
{"type":"EQ","name":"","addr":"(PE)","loc":"d,19:31,19:33","dtypep":"(RC)",
"lhsp": [
{"type":"CONST","name":"2'h0","addr":"(UE)","loc":"d,19:34,19:39","dtypep":"(XC)"}
{"type":"CONST","name":"2'h0","addr":"(QE)","loc":"d,19:34,19:39","dtypep":"(XC)"}
],
"rhsp": [
{"type":"SEL","name":"","addr":"(VE)","loc":"d,19:20,19:21","dtypep":"(XC)","declRange":"[15:0]","declElWidth":1,
{"type":"SEL","name":"","addr":"(RE)","loc":"d,19:20,19:21","dtypep":"(XC)","widthConst":2,"declRange":"[15:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(WE)","loc":"d,19:17,19:20","dtypep":"(H)","access":"RD","varp":"(LB)","varScopep":"(KB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__val","addr":"(SE)","loc":"d,19:17,19:20","dtypep":"(H)","access":"RD","varp":"(LB)","varScopep":"(KB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"SEL","name":"","addr":"(XE)","loc":"d,19:22,19:23","dtypep":"(BD)",
{"type":"SEL","name":"","addr":"(TE)","loc":"d,19:22,19:23","dtypep":"(BD)","widthConst":4,
"fromp": [
{"type":"MULS","name":"","addr":"(YE)","loc":"d,19:22,19:23","dtypep":"(NC)",
{"type":"MULS","name":"","addr":"(UE)","loc":"d,19:22,19:23","dtypep":"(NC)",
"lhsp": [
{"type":"CONST","name":"32'sh2","addr":"(ZE)","loc":"d,19:23,19:24","dtypep":"(NC)"}
{"type":"CONST","name":"32'sh2","addr":"(VE)","loc":"d,19:23,19:24","dtypep":"(NC)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(AF)","loc":"d,19:21,19:22","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(WE)","loc":"d,19:21,19:22","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
]}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(BF)","loc":"d,19:22,19:23","dtypep":"(GD)"}
],
"widthp": [
{"type":"CONST","name":"32'h4","addr":"(CF)","loc":"d,19:22,19:23","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(XE)","loc":"d,19:22,19:23","dtypep":"(GD)"}
]}
],
"widthp": [
{"type":"CONST","name":"32'sh2","addr":"(DF)","loc":"d,19:28,19:29","dtypep":"(NC)"}
]}
]}
],
"lhsp": [
{"type":"SEL","name":"","addr":"(EF)","loc":"d,19:10,19:11","dtypep":"(RC)","declRange":"[6:0]","declElWidth":1,
{"type":"SEL","name":"","addr":"(YE)","loc":"d,19:10,19:11","dtypep":"(RC)","widthConst":1,"declRange":"[6:0]","declElWidth":1,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(FF)","loc":"d,19:7,19:10","dtypep":"(K)","access":"WR","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(ZE)","loc":"d,19:7,19:10","dtypep":"(K)","access":"WR","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"SEL","name":"","addr":"(GF)","loc":"d,19:11,19:12","dtypep":"(MD)",
{"type":"SEL","name":"","addr":"(AF)","loc":"d,19:11,19:12","dtypep":"(KD)","widthConst":3,
"fromp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(HF)","loc":"d,19:11,19:12","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(BF)","loc":"d,19:11,19:12","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
],
"lsbp": [
{"type":"CONST","name":"32'h0","addr":"(IF)","loc":"d,19:11,19:12","dtypep":"(GD)"}
],
"widthp": [
{"type":"CONST","name":"32'h3","addr":"(JF)","loc":"d,19:11,19:12","dtypep":"(GD)"}
{"type":"CONST","name":"32'h0","addr":"(CF)","loc":"d,19:11,19:12","dtypep":"(GD)"}
]}
],
"widthp": [
{"type":"CONST","name":"32'h1","addr":"(KF)","loc":"d,19:10,19:11","dtypep":"(GD)"}
]}
],"timingControlp": []}
],
"incsp": [
{"type":"ASSIGN","name":"","addr":"(LF)","loc":"d,18:24,18:26","dtypep":"(GB)",
{"type":"ASSIGN","name":"","addr":"(DF)","loc":"d,18:24,18:26","dtypep":"(GB)",
"rhsp": [
{"type":"ADD","name":"","addr":"(MF)","loc":"d,18:24,18:26","dtypep":"(GD)",
{"type":"ADD","name":"","addr":"(EF)","loc":"d,18:24,18:26","dtypep":"(GD)",
"lhsp": [
{"type":"CONST","name":"32'h1","addr":"(NF)","loc":"d,18:24,18:26","dtypep":"(GD)"}
{"type":"CONST","name":"32'h1","addr":"(FF)","loc":"d,18:24,18:26","dtypep":"(GD)"}
],
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(OF)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(GF)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"RD","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
]}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(PF)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(HF)","loc":"d,18:23,18:24","dtypep":"(GB)","access":"WR","varp":"(PB)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
]},
{"type":"ASSIGN","name":"","addr":"(QF)","loc":"d,21:5,21:11","dtypep":"(K)",
{"type":"ASSIGN","name":"","addr":"(IF)","loc":"d,21:5,21:11","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(RF)","loc":"d,21:12,21:15","dtypep":"(K)","access":"RD","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__ret","addr":"(JF)","loc":"d,21:12,21:15","dtypep":"(K)","access":"RD","varp":"(NB)","varScopep":"(MB)","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(SF)","loc":"d,21:5,21:11","dtypep":"(K)","access":"WR","varp":"(JB)","varScopep":"(IB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(KF)","loc":"d,21:5,21:11","dtypep":"(K)","access":"WR","varp":"(JB)","varScopep":"(IB)","classOrPackagep":"UNLINKED"}
],"timingControlp": []},
{"type":"ASSIGN","name":"","addr":"(TF)","loc":"d,25:14,25:15","dtypep":"(K)",
{"type":"ASSIGN","name":"","addr":"(LF)","loc":"d,25:14,25:15","dtypep":"(K)",
"rhsp": [
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(UF)","loc":"d,25:16,25:19","dtypep":"(K)","access":"RD","varp":"(JB)","varScopep":"(IB)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"__Vfunc_vlvbound_test.foo__1__Vfuncout","addr":"(MF)","loc":"d,25:16,25:19","dtypep":"(K)","access":"RD","varp":"(JB)","varScopep":"(IB)","classOrPackagep":"UNLINKED"}
],
"lhsp": [
{"type":"VARREF","name":"o_b","addr":"(VF)","loc":"d,25:10,25:13","dtypep":"(K)","access":"WR","varp":"(L)","varScopep":"(U)","classOrPackagep":"UNLINKED"}
{"type":"VARREF","name":"o_b","addr":"(NF)","loc":"d,25:10,25:13","dtypep":"(K)","access":"WR","varp":"(L)","varScopep":"(U)","classOrPackagep":"UNLINKED"}
],"timingControlp": []}
]}
],"inlinesp": []}
@ -324,16 +300,16 @@
{"type":"BASICDTYPE","name":"logic","addr":"(H)","loc":"d,9:11,9:16","dtypep":"(H)","keyword":"logic","range":"15:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(K)","loc":"d,11:12,11:17","dtypep":"(K)","keyword":"logic","range":"6:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"integer","addr":"(GB)","loc":"d,17:5,17:12","dtypep":"(GB)","keyword":"integer","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(MD)","loc":"d,19:10,19:11","dtypep":"(MD)","keyword":"logic","range":"2:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(KD)","loc":"d,19:10,19:11","dtypep":"(KD)","keyword":"logic","range":"2:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(GD)","loc":"d,19:11,19:12","dtypep":"(GD)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(BD)","loc":"d,19:20,19:21","dtypep":"(BD)","keyword":"logic","range":"3:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(NC)","loc":"d,18:12,18:13","dtypep":"(NC)","keyword":"logic","range":"31:0","generic":true,"rangep": []}
]},
{"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0",
"modulep": [
{"type":"MODULE","name":"@CONST-POOL@","addr":"(WF)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [],
{"type":"MODULE","name":"@CONST-POOL@","addr":"(OF)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [],
"stmtsp": [
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(XF)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(WF)","varsp": [],"blocksp": [],"inlinesp": []}
{"type":"SCOPE","name":"@CONST-POOL@","addr":"(PF)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(OF)","varsp": [],"blocksp": [],"inlinesp": []}
],"activesp": []}
]}
]}

View File

@ -86,27 +86,23 @@
<assign loc="d,19,14,19,15" dtype_id="5">
<eq loc="d,19,31,19,33" dtype_id="5">
<const loc="d,19,34,19,39" name="2&apos;h0" dtype_id="6"/>
<sel loc="d,19,20,19,21" dtype_id="6">
<sel loc="d,19,20,19,21" dtype_id="6" widthConst="2">
<varref loc="d,19,17,19,20" name="__Vfunc_vlvbound_test.foo__0__val" dtype_id="1"/>
<sel loc="d,19,22,19,23" dtype_id="7">
<sel loc="d,19,22,19,23" dtype_id="7" widthConst="4">
<muls loc="d,19,22,19,23" dtype_id="4">
<const loc="d,19,23,19,24" name="32&apos;sh2" dtype_id="4"/>
<varref loc="d,19,21,19,22" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
</muls>
<const loc="d,19,22,19,23" name="32&apos;h0" dtype_id="8"/>
<const loc="d,19,22,19,23" name="32&apos;h4" dtype_id="8"/>
</sel>
<const loc="d,19,28,19,29" name="32&apos;sh2" dtype_id="4"/>
</sel>
</eq>
<sel loc="d,19,10,19,11" dtype_id="5">
<sel loc="d,19,10,19,11" dtype_id="5" widthConst="1">
<varref loc="d,19,7,19,10" name="__Vfunc_vlvbound_test.foo__0__ret" dtype_id="2"/>
<sel loc="d,19,11,19,12" dtype_id="9">
<sel loc="d,19,11,19,12" dtype_id="9" widthConst="3">
<varref loc="d,19,11,19,12" name="__Vfunc_vlvbound_test.foo__0__i" dtype_id="3"/>
<const loc="d,19,11,19,12" name="32&apos;h0" dtype_id="8"/>
<const loc="d,19,11,19,12" name="32&apos;h3" dtype_id="8"/>
</sel>
<const loc="d,19,10,19,11" name="32&apos;h1" dtype_id="8"/>
</sel>
</assign>
</begin>
@ -158,27 +154,23 @@
<assign loc="d,19,14,19,15" dtype_id="5">
<eq loc="d,19,31,19,33" dtype_id="5">
<const loc="d,19,34,19,39" name="2&apos;h0" dtype_id="6"/>
<sel loc="d,19,20,19,21" dtype_id="6">
<sel loc="d,19,20,19,21" dtype_id="6" widthConst="2">
<varref loc="d,19,17,19,20" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1"/>
<sel loc="d,19,22,19,23" dtype_id="7">
<sel loc="d,19,22,19,23" dtype_id="7" widthConst="4">
<muls loc="d,19,22,19,23" dtype_id="4">
<const loc="d,19,23,19,24" name="32&apos;sh2" dtype_id="4"/>
<varref loc="d,19,21,19,22" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
</muls>
<const loc="d,19,22,19,23" name="32&apos;h0" dtype_id="8"/>
<const loc="d,19,22,19,23" name="32&apos;h4" dtype_id="8"/>
</sel>
<const loc="d,19,28,19,29" name="32&apos;sh2" dtype_id="4"/>
</sel>
</eq>
<sel loc="d,19,10,19,11" dtype_id="5">
<sel loc="d,19,10,19,11" dtype_id="5" widthConst="1">
<varref loc="d,19,7,19,10" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2"/>
<sel loc="d,19,11,19,12" dtype_id="9">
<sel loc="d,19,11,19,12" dtype_id="9" widthConst="3">
<varref loc="d,19,11,19,12" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
<const loc="d,19,11,19,12" name="32&apos;h0" dtype_id="8"/>
<const loc="d,19,11,19,12" name="32&apos;h3" dtype_id="8"/>
</sel>
<const loc="d,19,10,19,11" name="32&apos;h1" dtype_id="8"/>
</sel>
</assign>
</begin>