Fix >>> sign extension based on expression, bug754.
This commit is contained in:
parent
d532a36739
commit
a985a1f9f5
|
|
@ -2232,15 +2232,15 @@ private:
|
|||
AstNodeBiop* iterate_shift_final(AstNodeBiop* nodep, AstNUser* vup) {
|
||||
// Nodep maybe edited
|
||||
if (vup->c()->final()) {
|
||||
AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* subDTypep = expDTypep;
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
// ShiftRS converts to ShiftR, but not vice-versa
|
||||
if (nodep->castShiftRS()) {
|
||||
if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { nodep=NULL;
|
||||
nodep = newp; // Process new node instead
|
||||
}
|
||||
}
|
||||
AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep());
|
||||
AstNodeDType* subDTypep = expDTypep;
|
||||
nodep->dtypeFrom(expDTypep);
|
||||
iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP);
|
||||
if (nodep->rhsp()->width()>32) {
|
||||
AstConst* shiftp = nodep->rhsp()->castConst();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 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.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by Wilson Snyder.
|
||||
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0)
|
||||
`define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0)
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
bit fail;
|
||||
|
||||
reg signed [3:0] w4_s;
|
||||
reg signed [4:0] w5_s;
|
||||
reg [3:0] w4_u;
|
||||
reg [4:0] w5_u;
|
||||
real r;
|
||||
|
||||
reg signed [4:0] bug754_a;
|
||||
|
||||
integer i;
|
||||
|
||||
//verilator lint_off WIDTH
|
||||
wire a = (5'b0 == (5'sb11111 >>> 3'd7));
|
||||
wire b = (5'sb11111 == (5'sb11111 >>> 3'd7));
|
||||
wire c = (1'b0+(5'sb11111 >>> 3'd7));
|
||||
wire d = (1'sb0+(5'sb11111 >>> 3'd7));
|
||||
wire e = (5'b0 == (5'sb11111 / 5'sd3));
|
||||
wire f = (5'sb0 == (5'sb11111 / 5'sd3));
|
||||
wire g = (5'b01010 == (5'b11111 / 5'sd3));
|
||||
initial begin
|
||||
// verilator lint_off STMTDLY
|
||||
#1;
|
||||
`ifdef VCS // I-2014.03
|
||||
`checkh({a, b, c, d, e, f, g}, 7'b1101111);
|
||||
`else
|
||||
`checkh({a, b, c, d, e, f, g}, 7'b1101011);
|
||||
`endif
|
||||
|
||||
//======================================================================
|
||||
|
||||
if ((-1 >>> 3) != -1) $stop; // Decimals are signed
|
||||
|
||||
i = 3'sb111 >>> 3;
|
||||
`checkh(i, -1);
|
||||
i = -1 >>> 3;
|
||||
`checkh(i, -1);
|
||||
|
||||
bug754_a = -1;
|
||||
w4_u = |0 != (bug754_a >>> 3'd7);
|
||||
`checkh(w4_u, 4'b0);
|
||||
|
||||
// Sanity check: -1>>7 == -1
|
||||
w5_u = (5'sb11111 >>> 3'd7);
|
||||
`checkh(w5_u, 5'b11111);
|
||||
|
||||
// bug756
|
||||
w4_u = (5'b0 == (5'sb11111 >>> 3'd7));
|
||||
`checkh(w4_u, 4'b0001);
|
||||
w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); // Exp 0 Vlt 0
|
||||
`checkh(w4_u, 4'b0001);
|
||||
w4_u = ((5'b01111 == (5'sb11111 / 5'sd2))); // Strength-reduces to >>>
|
||||
`ifdef VCS // I-2014.03
|
||||
`checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate
|
||||
`else
|
||||
`checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ...
|
||||
`endif
|
||||
|
||||
// Does == sign propagate from lhs to rhs? Yes, but not in VCS
|
||||
w4_u = ((5'b01010 == (5'sb11111 / 5'sd3))); // Exp 0 Vlt 0 // Must be signed result (-1/3) to make this result zero
|
||||
`ifdef VCS // I-2014.03
|
||||
`checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate
|
||||
`else
|
||||
`checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ...
|
||||
`endif
|
||||
|
||||
w4_u = (1'b0+(5'sb11111 >>> 3'd7)); // Exp 00000 Vlt 000000 Actually the signedness of result does NOT matter
|
||||
`checkh(w4_u, 4'b0000);
|
||||
|
||||
w4_u = (5'sb0 == (5'sb11111 / 5'sd3)); // Must be signed result (-1/3) to make this result zero
|
||||
`checkh(w4_u, 4'b0001);
|
||||
// Does == width propagate from lhs to rhs? Yes
|
||||
w4_u = (3'b100==(3'b111 << 2));
|
||||
`checkh(w4_u, 4'b0001);
|
||||
w4_u = (4'b100==(3'b111 << 2));
|
||||
`checkh(w4_u, 4'b0000);
|
||||
w4_u = (4'b1100==(3'b111 << 2));
|
||||
`checkh(w4_u, 4'b0001);
|
||||
|
||||
// Does >>> sign propagate from input same as for +? Yes
|
||||
w4_u = (1'b0+(5'sb11111 >>> 3'd7));
|
||||
`checkh(w4_u, 4'b0000);
|
||||
w4_u = (1'sb0+(5'sb11111 >>> 3'd7));
|
||||
`checkh(w4_u, 4'b1111);
|
||||
|
||||
// Does << width propagate from input same as for +? Yes
|
||||
w4_u = (3'b0+(3'b111 << 2));
|
||||
`checkh(w4_u, 4'b1100); // width 4 =='s LHS
|
||||
w4_u = (4'b0+(3'b111 << 2));
|
||||
`checkh(w4_u, 4'b1100);
|
||||
|
||||
w4_u = (5'sb11111 == (5'sb11111 >>> 3'd7)); // WHAT? Signedness does propagate across ==?????
|
||||
`checkh(w4_u, 4'b0001);
|
||||
w4_u = ((5'b0 == (5'sb11111 >>> 3'd7)));
|
||||
`checkh(w4_u, 4'b0001);
|
||||
|
||||
if (fail) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue