Fix constant propagation of post-expand stages (#5983).
This commit is contained in:
parent
a3662cc3f5
commit
69eb76ad66
2
Changes
2
Changes
|
@ -17,7 +17,7 @@ Verilator 5.037 devel
|
|||
* Add PROCINITASSIGN on initial assignments to process variables (#2481). [Niraj Menon]
|
||||
* Fix filename backslash escapes in C code (#5947).
|
||||
* Fix C++ widths in V3Expand (#5953) (#5975). [Geza Lore]
|
||||
* Fix constant propagation of post-expand stages (#5955) (#5963) (#5969) (#5972).
|
||||
* Fix constant propagation of post-expand stages (#5955) (#5963) (#5969) (#5972) (#5983).
|
||||
* Fix sign extension of signed compared with unsigned case items (#5968).
|
||||
* Fix always processes ignoring $finish (#5971). [Hennadii Chernyshchyk]
|
||||
* Fix streaming to/from packed arrays (#5976). [Geza Lore]
|
||||
|
|
|
@ -1903,7 +1903,7 @@ find what made a <e#*#*> line in the tree dumps):
|
|||
|
||||
::
|
||||
|
||||
watch AstNode::s_editCntGbl==####
|
||||
watch AstNode::s_editCntGbl=####
|
||||
|
||||
Then, when the watch fires, to break at every following change to that
|
||||
node:
|
||||
|
|
|
@ -1022,7 +1022,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
if (ccastp) {
|
||||
andp->replaceWith(ccastp);
|
||||
andp->replaceWithKeepDType(ccastp);
|
||||
VL_DO_DANGLING(pushDeletep(andp), andp);
|
||||
return true;
|
||||
}
|
||||
|
@ -1128,16 +1128,16 @@ class ConstVisitor final : public VNVisitor {
|
|||
const bool orRIsRedundant = checkBottomClear(orp->rhsp());
|
||||
|
||||
if (orLIsRedundant && orRIsRedundant) {
|
||||
nodep->replaceWith(
|
||||
nodep->replaceWithKeepDType(
|
||||
new AstConst{nodep->fileline(), AstConst::DTyped{}, nodep->dtypep()});
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
return true;
|
||||
} else if (orLIsRedundant) {
|
||||
orp->replaceWith(orp->rhsp()->unlinkFrBack());
|
||||
orp->replaceWithKeepDType(orp->rhsp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(orp), orp);
|
||||
return false; // input node is still valid, keep going
|
||||
} else if (orRIsRedundant) {
|
||||
orp->replaceWith(orp->lhsp()->unlinkFrBack());
|
||||
orp->replaceWithKeepDType(orp->lhsp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(orp), orp);
|
||||
return false; // input node is still valid, keep going
|
||||
} else {
|
||||
|
@ -1204,8 +1204,8 @@ class ConstVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
if (newp) {
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
UINFO(4, "Transformed leaf of bit tree to " << newp << std::endl);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
|
@ -1657,7 +1657,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
AstNode* const newp = new AstConst{oldp->fileline(), AstConst::String{}, num};
|
||||
if (debug() > 5) oldp->dumpTree("- const_old: ");
|
||||
if (debug() > 5) newp->dumpTree("- _new: ");
|
||||
oldp->replaceWith(newp);
|
||||
oldp->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(oldp), oldp);
|
||||
}
|
||||
//----------------------------------------
|
||||
|
@ -1676,9 +1676,9 @@ class ConstVisitor final : public VNVisitor {
|
|||
// NODE(..., CHILD(...)) -> REDOR(CHILD(...))
|
||||
childp->unlinkFrBack();
|
||||
if (childp->width1()) {
|
||||
nodep->replaceWith(childp);
|
||||
nodep->replaceWithKeepDType(childp);
|
||||
} else {
|
||||
nodep->replaceWith(new AstRedOr{childp->fileline(), childp});
|
||||
nodep->replaceWithKeepDType(new AstRedOr{childp->fileline(), childp});
|
||||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
@ -1767,7 +1767,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop);
|
||||
AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack();
|
||||
nodep->replaceWith(lp);
|
||||
nodep->replaceWithKeepDType(lp);
|
||||
if (operandsSame(llp, rlp)) {
|
||||
lp->lhsp(llp);
|
||||
lp->rhsp(nodep);
|
||||
|
@ -1798,7 +1798,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
AstNodeBiop* const rp = VN_AS(nodep->rhsp()->unlinkFrBack(), NodeBiop);
|
||||
AstNodeExpr* const rlp = rp->lhsp()->unlinkFrBack();
|
||||
AstNodeExpr* const rrp = rp->rhsp()->unlinkFrBack();
|
||||
nodep->replaceWith(lp);
|
||||
nodep->replaceWithKeepDType(lp);
|
||||
lp->lhsp(nodep);
|
||||
lp->rhsp(lrp);
|
||||
nodep->lhsp(llp);
|
||||
|
@ -1824,7 +1824,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
UINFO(5, "merged two adjacent sel " << lselp << " and " << rselp << " to one " << newselp
|
||||
<< endl);
|
||||
|
||||
nodep->replaceWith(newselp);
|
||||
nodep->replaceWithKeepDType(newselp);
|
||||
VL_DO_DANGLING(pushDeletep(lselp), lselp);
|
||||
VL_DO_DANGLING(pushDeletep(rselp), rselp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
@ -1850,7 +1850,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), VSigning::UNSIGNED);
|
||||
UINFO(5, "merged " << nodep << endl);
|
||||
VL_DO_DANGLING(pushDeletep(rp->unlinkFrBack()), rp);
|
||||
nodep->replaceWith(lp->unlinkFrBack());
|
||||
nodep->replaceWithKeepDType(lp->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
iterate(lp->lhsp());
|
||||
iterate(lp->rhsp());
|
||||
|
@ -2043,7 +2043,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
new AstConcat{rhs1p->fileline(), rhs1p, rhs2p});
|
||||
}
|
||||
// if (debug()) pnewp->dumpTree("- conew: ");
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWith(newp); // dypep intentionally changing
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
VL_DO_DANGLING(pushDeletep(nextp->unlinkFrBack()), nextp);
|
||||
return true;
|
||||
|
@ -2562,7 +2562,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
newlsbp->dtypeFrom(widep);
|
||||
}
|
||||
AstSel* const newp = new AstSel{nodep->fileline(), fromp, newlsbp, widthp};
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
|
@ -2576,12 +2576,12 @@ class ConstVisitor final : public VNVisitor {
|
|||
AstSel* const newp
|
||||
= new AstSel{nodep->fileline(), conLhsp, nodep->lsbConst() - conRhsp->width(),
|
||||
nodep->widthConst()};
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
} else if (static_cast<int>(nodep->msbConst()) < conRhsp->width()) {
|
||||
conRhsp->unlinkFrBack();
|
||||
AstSel* const newp
|
||||
= new AstSel{nodep->fileline(), conRhsp, nodep->lsbConst(), nodep->widthConst()};
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
} else {
|
||||
// Yuk, split between the two
|
||||
conRhsp->unlinkFrBack();
|
||||
|
@ -2592,7 +2592,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
nodep->msbConst() - conRhsp->width() + 1},
|
||||
new AstSel{nodep->fileline(), conRhsp, nodep->lsbConst(),
|
||||
conRhsp->width() - nodep->lsbConst()}};
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
@ -2718,7 +2718,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
nodep->v3error("Illegal assignment of constant to unpacked array");
|
||||
} else {
|
||||
AstNode* const fromp = nodep->fromp()->unlinkFrBack();
|
||||
nodep->replaceWith(fromp);
|
||||
nodep->replaceWithKeepDType(fromp);
|
||||
if (VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) {
|
||||
// Strip off array to find what array references
|
||||
fromp->dtypeFrom(
|
||||
|
@ -2771,12 +2771,12 @@ class ConstVisitor final : public VNVisitor {
|
|||
// This exception is fairly fragile, i.e. doesn't
|
||||
// support arrays of arrays or other stuff
|
||||
AstNode* const newp = valuep->cloneTree(false);
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
did = true;
|
||||
} else if (nodep->varp()->isParam() && VN_IS(valuep, Unbounded)) {
|
||||
AstNode* const newp = valuep->cloneTree(false);
|
||||
nodep->replaceWith(newp);
|
||||
nodep->replaceWithKeepDType(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
did = true;
|
||||
}
|
||||
|
|
|
@ -445,7 +445,6 @@ class ExpandVisitor final : public VNVisitor {
|
|||
midp = new AstCond{
|
||||
nfl,
|
||||
// lsb % VL_EDATASIZE == 0 ?
|
||||
|
||||
new AstEq{nfl, new AstConst{nfl, 0}, newSelBitBit(nodep->lsbp())},
|
||||
// 0 :
|
||||
new AstConst{nfl, zero},
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
one 'd=-1 'b=1
|
||||
ort 'd=-1 'b=1
|
||||
tmp 'd= -1 'b=11111111
|
||||
out63 'd= 1 'b=000000000000000000000001
|
||||
out63 'd= 1 'b=000000000000000000000001
|
||||
*-* All Finished *-*
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
test.compile(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute(expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
|
@ -0,0 +1,92 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define stop $stop
|
||||
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
|
||||
module sub (
|
||||
input wire clock_4,
|
||||
input wire clock_8,
|
||||
output wire [28:5] out63
|
||||
);
|
||||
|
||||
reg [28:0] reg_12;
|
||||
reg [28:22] reg_24;
|
||||
|
||||
wire _0558_ = | reg_24[26:25]; // reg_24 = 0 or 1100110 ---> _0558_ == 0
|
||||
wire [28:0] _0670_ = _0558_ ? reg_12 : 29'h00000f93; // _0558_ == 0 ---> _0670_ == 29'h00000f93
|
||||
wire [28:0] _0399_= - _0670_; // _0670_ == 29'h00000f93 ---> _0399_ = 29'b11111111111111111000001101101
|
||||
wire _0085_ = ~ _0399_[2]; // _0399_[2] == 1 ---> _0085_ == 0
|
||||
wire [28:0] _0769_;
|
||||
assign { _0769_[28:3], _0769_[1:0] } = { _0399_[28:3], _0399_[1:0] }; // _0769_ != 0
|
||||
assign _0769_[2] = _0085_;
|
||||
|
||||
// verilator lint_off WIDTH
|
||||
wire _0305_ = ! _0769_; // _0769_ != 0 ---> _0305_ == 0
|
||||
wire [23:0] _0306_ = ! _0305_; // _0305_ == 0 ---> _0306_ == 1
|
||||
// verilator lint_on WIDTH
|
||||
|
||||
assign out63 = _0306_; // out63 == 1
|
||||
|
||||
always @(posedge clock_4, posedge clock_8)
|
||||
if (clock_8) reg_12 <= 29'h00000066;
|
||||
else reg_12 <= { reg_12[28:27], 25'h0000001, reg_12[1:0] };
|
||||
|
||||
always @(posedge clock_4, posedge clock_8)
|
||||
if (clock_8) reg_24 <= 7'h66;
|
||||
else reg_24 <= reg_24;
|
||||
|
||||
endmodule
|
||||
|
||||
module t;
|
||||
reg clock_4;
|
||||
reg clock_8;
|
||||
wire signed [28:5] out63;
|
||||
reg signed [7:0] tmp = -1;
|
||||
reg signed [0:0] one = 1;
|
||||
reg signed [0:0] onert = 1;
|
||||
|
||||
sub sub (
|
||||
.clock_4 (clock_4),
|
||||
.clock_8 (clock_8),
|
||||
.out63 (out63)
|
||||
);
|
||||
|
||||
|
||||
initial begin
|
||||
// All simulators agree: 1'sb1 really shows as decimal -1
|
||||
$display("one 'd=%d 'b=%b", one, one);
|
||||
`ifdef VERILATOR
|
||||
onert = $c(1);
|
||||
`endif
|
||||
$display("ort 'd=%d 'b=%b", onert, onert);
|
||||
|
||||
$display("tmp 'd=%d 'b=%b", tmp, tmp);
|
||||
|
||||
clock_4 = 0;
|
||||
clock_8 = 0;
|
||||
#2000;
|
||||
|
||||
sub.reg_24 = 0;
|
||||
sub.reg_12 = 0;
|
||||
#2000;
|
||||
|
||||
clock_4 = 0;
|
||||
clock_8 = 0;
|
||||
#10;
|
||||
$display("out63 'd=%d 'b=%b", out63, out63);
|
||||
|
||||
#2000;
|
||||
clock_4 = 1;
|
||||
clock_8 = 1;
|
||||
#10;
|
||||
$display("out63 'd=%d 'b=%b", out63, out63);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue