Fix power calculation; setAllOnes should not set hidden state bits in V3Number.
This commit is contained in:
parent
5c39420d91
commit
fb4928b2f5
2
Changes
2
Changes
|
|
@ -27,7 +27,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
**** Fix signed extension problems with -Wno-WIDTH, bug729. [Clifford Wolf]
|
||||
|
||||
**** Fix power operator calculation, bug730. [Clifford Wolf]
|
||||
**** Fix power operator calculation, bug730, bug735. [Clifford Wolf]
|
||||
|
||||
**** Fix Mac OS-X test issues. [Holger Waechtler]
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ V3Number::V3Number(VerilogString, FileLine* fileline, const string& str) {
|
|||
}
|
||||
}
|
||||
}
|
||||
opCleanThis();
|
||||
}
|
||||
|
||||
V3Number::V3Number (FileLine* fileline, const char* sourcep) {
|
||||
|
|
@ -252,6 +253,7 @@ V3Number::V3Number (FileLine* fileline, const char* sourcep) {
|
|||
setBit(obit, bitIs(obit-1));
|
||||
obit++;
|
||||
}
|
||||
opCleanThis();
|
||||
|
||||
//printf("Dump \"%s\" CP \"%s\" B '%c' %d W %d\n", sourcep, value_startp, base, width(), m_value[0]);
|
||||
}
|
||||
|
|
@ -276,11 +278,13 @@ V3Number& V3Number::setQuad(vluint64_t value) {
|
|||
for (int i=0; i<words(); i++) m_value[i]=m_valueX[i] = 0;
|
||||
m_value[0] = value & VL_ULL(0xffffffff);
|
||||
m_value[1] = (value>>VL_ULL(32)) & VL_ULL(0xffffffff);
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setLong(uint32_t value) {
|
||||
for (int i=0; i<words(); i++) m_value[i]=m_valueX[i] = 0;
|
||||
m_value[0] = value;
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setLongS(vlsint32_t value) {
|
||||
|
|
@ -288,6 +292,7 @@ V3Number& V3Number::setLongS(vlsint32_t value) {
|
|||
union { uint32_t u; vlsint32_t s; } u;
|
||||
u.s = value;
|
||||
m_value[0] = u.u;
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setDouble(double value) {
|
||||
|
|
@ -314,14 +319,17 @@ V3Number& V3Number::setAllBits0() {
|
|||
}
|
||||
V3Number& V3Number::setAllBits1() {
|
||||
for (int i=0; i<words(); i++) { m_value[i]= ~0; m_valueX[i] = 0; }
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setAllBitsX() {
|
||||
for (int i=0; i<words(); i++) { m_value[i]=m_valueX[i] = ~0; }
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setAllBitsZ() {
|
||||
for (int i=0; i<words(); i++) { m_value[i]=0; m_valueX[i] = ~0; }
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::setMask(int nbits) {
|
||||
|
|
@ -341,6 +349,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
|
|||
if (width()!=64) out<<"%E-bad-width-double";
|
||||
else out<<toDouble();
|
||||
return out.str();
|
||||
} else {
|
||||
if ((m_value[words()-1] | m_valueX[words()-1]) & ~hiWordMask()) out<<"%E-hidden-bits";
|
||||
}
|
||||
if (prefixed) {
|
||||
if (sized()) {
|
||||
|
|
@ -751,6 +761,7 @@ V3Number& V3Number::opCountOnes (const V3Number& lhs) {
|
|||
if (lhs.isFourState()) return setAllBitsX();
|
||||
setZero();
|
||||
m_value[0] = lhs.countOnes();
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::opIsUnknown (const V3Number& lhs) {
|
||||
|
|
@ -1291,6 +1302,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
}
|
||||
UINFO(9, " opmoddiv-1w "<<lhs<<" "<<rhs<<" q="<<*this<<" rem=0x"<<hex<<k<<dec<<endl);
|
||||
if (is_modulus) { setZero(); m_value[0] = k; }
|
||||
opCleanThis();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1373,9 +1385,11 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
|||
m_value[i] = (un[i] >> s) | (shift_mask & (un[i+1] << (32-s)));
|
||||
}
|
||||
for (int i=vw; i<words; i++) m_value[i] = 0;
|
||||
opCleanThis();
|
||||
UINFO(9, " opmoddiv-mod "<<lhs<<" "<<rhs<<" now="<<*this<<endl);
|
||||
return *this;
|
||||
} else { // division
|
||||
opCleanThis();
|
||||
UINFO(9, " opmoddiv-div "<<lhs<<" "<<rhs<<" now="<<*this<<endl);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1457,9 +1471,8 @@ V3Number& V3Number::opClean (const V3Number& lhs, uint32_t bits) {
|
|||
|
||||
void V3Number::opCleanThis() {
|
||||
// Clean in place number
|
||||
if (uint32_t okbits = (width() & 31)) {
|
||||
m_value[words()-1] &= ((1UL<<okbits)-1);
|
||||
}
|
||||
m_value[words()-1] &= hiWordMask();
|
||||
m_valueX[words()-1] &= hiWordMask();
|
||||
}
|
||||
|
||||
V3Number& V3Number::opSel (const V3Number& lhs, const V3Number& msb, const V3Number& lsb) {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ private:
|
|||
}
|
||||
|
||||
int words() const { return ((width()+31)/32); }
|
||||
uint32_t hiWordMask() const { return VL_MASK_I(width()); }
|
||||
|
||||
V3Number& opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool is_modulus);
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ public:
|
|||
// CONSTRUCTORS
|
||||
V3Number(FileLine* fileline) { init(fileline, 1); }
|
||||
V3Number(FileLine* fileline, int width) { init(fileline, width); } // 0=unsized
|
||||
V3Number(FileLine* fileline, int width, uint32_t value) { init(fileline, width); m_value[0]=value; }
|
||||
V3Number(FileLine* fileline, int width, uint32_t value) { init(fileline, width); m_value[0]=value; opCleanThis(); }
|
||||
V3Number(FileLine* fileline, const char* source); // Create from a verilog 32'hxxxx number.
|
||||
V3Number(VerilogString, FileLine* fileline, const string& vvalue);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,68 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2014 by Clifford Wolf.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
|
||||
wire [31:0] y;
|
||||
reg a;
|
||||
test004 sub (/*AUTOINST*/
|
||||
// Outputs
|
||||
.y (y[31:0]),
|
||||
// Inputs
|
||||
.a (a));
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d a=%x y=%x\n",$time, cyc, a, y);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==0) begin
|
||||
a <= 0;
|
||||
end
|
||||
else if (cyc==1) begin
|
||||
a <= 1;
|
||||
if (y != 32'h0) $stop;
|
||||
end
|
||||
else if (cyc==2) begin
|
||||
if (y != 32'h010000ff) $stop;
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test004(a, y);
|
||||
input a;
|
||||
output [31:0] y;
|
||||
|
||||
wire [7:0] y0;
|
||||
wire [7:0] y1;
|
||||
wire [7:0] y2;
|
||||
wire [7:0] y3;
|
||||
assign y = {y0,y1,y2,y3};
|
||||
|
||||
localparam [7:0] v0 = +8'sd1 ** -8'sd2; //'h01
|
||||
localparam [7:0] v1 = +8'sd2 ** -8'sd2; //'h00
|
||||
localparam [7:0] v2 = -8'sd2 ** -8'sd3; //'h00
|
||||
localparam [7:0] v3 = -8'sd1 ** -8'sd3; //'hff
|
||||
localparam [7:0] zero = 0;
|
||||
|
||||
initial $display("v0=%x v1=%x v2=%x v3=%x", v0,v1,v2,v3);
|
||||
|
||||
assign y0 = a ? v0 : zero;
|
||||
assign y1 = a ? v1 : zero;
|
||||
assign y2 = a ? v2 : zero;
|
||||
assign y3 = a ? v3 : zero;
|
||||
endmodule
|
||||
Loading…
Reference in New Issue