forked from github/verilator
Fix cast width propagation (#2597).
This commit is contained in:
parent
6e7b07c794
commit
d78941885b
2
Changes
2
Changes
@ -16,6 +16,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
|||||||
|
|
||||||
**** Fix iteration over mutating list bug in VPI (#2588). [Kaleb Barrett]
|
**** Fix iteration over mutating list bug in VPI (#2588). [Kaleb Barrett]
|
||||||
|
|
||||||
|
**** Fix cast width propagation (#2597). [flex-liu]
|
||||||
|
|
||||||
**** Fix return from callValueCbs (#2589) (#2605). [Marlon James]
|
**** Fix return from callValueCbs (#2589) (#2605). [Marlon James]
|
||||||
|
|
||||||
**** Fix WIDTH warnings on comparisons with nullptr (#2602). [Rupert Swarbrick]
|
**** Fix WIDTH warnings on comparisons with nullptr (#2602). [Rupert Swarbrick]
|
||||||
|
@ -5953,6 +5953,7 @@ public:
|
|||||||
virtual bool cleanLhs() const { return true; }
|
virtual bool cleanLhs() const { return true; }
|
||||||
virtual bool sizeMattersLhs() const { return false; }
|
virtual bool sizeMattersLhs() const { return false; }
|
||||||
AstNode* lhsp() const { return op1p(); }
|
AstNode* lhsp() const { return op1p(); }
|
||||||
|
void lhsp(AstNode* nodep) { setOp1p(nodep); }
|
||||||
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||||
AstNodeDType* childDTypep() const { return VN_CAST(op2p(), NodeDType); }
|
AstNodeDType* childDTypep() const { return VN_CAST(op2p(), NodeDType); }
|
||||||
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
||||||
|
@ -1661,14 +1661,14 @@ private:
|
|||||||
// Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting.
|
// Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting.
|
||||||
AstBasicDType* basicp = nodep->dtypep()->basicp();
|
AstBasicDType* basicp = nodep->dtypep()->basicp();
|
||||||
UASSERT_OBJ(basicp, nodep, "Unimplemented: Casting non-simple data type");
|
UASSERT_OBJ(basicp, nodep, "Unimplemented: Casting non-simple data type");
|
||||||
|
if (m_vup->prelim()) {
|
||||||
|
userIterateAndNext(nodep->lhsp(), WidthVP(SELF, PRELIM).p());
|
||||||
// When implement more complicated types need to convert childDTypep to
|
// When implement more complicated types need to convert childDTypep to
|
||||||
// dtypep() not as a child
|
// dtypep() not as a child
|
||||||
if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) {
|
if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) {
|
||||||
// Note widthCheckSized might modify nodep->lhsp()
|
// Note castSized might modify nodep->lhsp()
|
||||||
AstNodeDType* subDTypep = nodep->findLogicDType(nodep->width(), nodep->width(),
|
int width = nodep->dtypep()->width();
|
||||||
nodep->lhsp()->dtypep()->numeric());
|
castSized(nodep, nodep->lhsp(), width);
|
||||||
iterateCheck(nodep, "value", nodep->lhsp(), CONTEXT, FINAL, subDTypep, EXTEND_EXP,
|
|
||||||
false);
|
|
||||||
} else {
|
} else {
|
||||||
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(),
|
iterateCheck(nodep, "value", nodep->lhsp(), SELF, FINAL, nodep->lhsp()->dtypep(),
|
||||||
EXTEND_EXP, false);
|
EXTEND_EXP, false);
|
||||||
@ -1684,7 +1684,8 @@ private:
|
|||||||
if (basicp->isSigned()) {
|
if (basicp->isSigned()) {
|
||||||
newp = new AstRToIRoundS(nodep->fileline(), newp);
|
newp = new AstRToIRoundS(nodep->fileline(), newp);
|
||||||
} else {
|
} else {
|
||||||
newp = new AstUnsigned(nodep->fileline(), new AstRToIS(nodep->fileline(), newp));
|
newp = new AstUnsigned(nodep->fileline(),
|
||||||
|
new AstRToIS(nodep->fileline(), newp));
|
||||||
}
|
}
|
||||||
} else if (basicp->isSigned() && !newp->isSigned()) {
|
} else if (basicp->isSigned() && !newp->isSigned()) {
|
||||||
newp = new AstSigned(nodep->fileline(), newp);
|
newp = new AstSigned(nodep->fileline(), newp);
|
||||||
@ -1693,9 +1694,14 @@ private:
|
|||||||
} else {
|
} else {
|
||||||
// newp = newp; // Can just remove cast
|
// newp = newp; // Can just remove cast
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->lhsp(newp);
|
||||||
|
// if (debug()) nodep->dumpTree(cout, " CastOut: ");
|
||||||
|
}
|
||||||
|
if (m_vup->final()) {
|
||||||
|
AstNode* underp = nodep->lhsp()->unlinkFrBack();
|
||||||
|
nodep->replaceWith(underp);
|
||||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||||
// if (debug()) newp->dumpTree(cout, " CastOut: ");
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstCastSize* nodep) override {
|
virtual void visit(AstCastSize* nodep) override {
|
||||||
// IEEE: Signedness of result is same as self-determined signedness
|
// IEEE: Signedness of result is same as self-determined signedness
|
||||||
|
@ -9,9 +9,14 @@ module t (/*AUTOARG*/);
|
|||||||
logic in1 = 1;
|
logic in1 = 1;
|
||||||
logic [1:0] in2 = 2'b11;
|
logic [1:0] in2 = 2'b11;
|
||||||
logic [31:0] out;
|
logic [31:0] out;
|
||||||
|
logic [7:0] ones = 8'b11111111;
|
||||||
|
logic [9:0] ones10 = 10'b1111111111;
|
||||||
|
|
||||||
typedef logic [7:0] data_t;
|
typedef logic [7:0] data_t;
|
||||||
|
|
||||||
|
typedef logic [9:0] ten_t;
|
||||||
|
ten_t out10;
|
||||||
|
|
||||||
// verilator lint_off WIDTH
|
// verilator lint_off WIDTH
|
||||||
initial begin
|
initial begin
|
||||||
in1 = 1;
|
in1 = 1;
|
||||||
@ -31,6 +36,28 @@ module t (/*AUTOARG*/);
|
|||||||
out = data_t'(in1 << in2);
|
out = data_t'(in1 << in2);
|
||||||
if (out != 8'b1000) $stop;
|
if (out != 8'b1000) $stop;
|
||||||
|
|
||||||
|
// Check upper bits get cleared when cast
|
||||||
|
in2 = 3;
|
||||||
|
out = data_t'(ones << in2);
|
||||||
|
if (out != 8'b11111000) $stop;
|
||||||
|
|
||||||
|
in2 = 3;
|
||||||
|
out = data_t'(ones10 << in2);
|
||||||
|
if (out != 8'b11111000) $stop;
|
||||||
|
|
||||||
|
// bug2597
|
||||||
|
out = data_t'(10'h208 >> 2);
|
||||||
|
if (out != 8'h82) $stop;
|
||||||
|
|
||||||
|
out = data_t'(10'h208 >> 2);
|
||||||
|
if (out != 8'h82) $stop;
|
||||||
|
|
||||||
|
out = data_t'('h208 >> 2);
|
||||||
|
if (out != 8'h82) $stop;
|
||||||
|
|
||||||
|
out10 = ten_t'('h404 >> 2);
|
||||||
|
if (out10 != 10'h101) $stop;
|
||||||
|
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish();
|
$finish();
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user