Fixed sign error when extracting from signed memory

git-svn-id: file://localhost/svn/verilator/trunk/verilator@978 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2008-01-15 15:00:10 +00:00
parent 87533b13e1
commit 79eac1e6b0
5 changed files with 99 additions and 2 deletions

View File

@ -8,6 +8,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
In such cases, a new {prefix}__Inlines.h file will be built and included.
**** Fixed sign error when extracting from signed memory. [Peter Debacker]
**** Fixed tracing of SystemC w/o SystemPerl. [Bernard Deadman]
* Verilator 3.655 11/27/2007
@ -91,7 +93,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support Verilog 2005 `begin_keywords and `end_keywords.
*** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2008.
*** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005.
*** Add /*verilator public_flat*/. [Eugene Weber]

View File

@ -67,7 +67,6 @@ private:
//========
// Signed: Output unsigned, Operands either
virtual void visit(AstArraySel* nodep, AstNUser*) { signed_Ou_Ix(nodep); } //See backRequiresUnsigned
virtual void visit(AstSel* nodep, AstNUser*) { signed_Ou_Ix(nodep); } //See backRequiresUnsigned
virtual void visit(AstAttrOf* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstCountOnes* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
@ -110,6 +109,10 @@ private:
virtual void visit(AstShiftL* nodep, AstNUser*) { signed_Olhs(nodep); }
virtual void visit(AstShiftR* nodep, AstNUser*) { signed_Olhs(nodep); }
// Signed: Output signed iff LHS signed; binary operator
// Note by contrast, bit extract selects are unsigned
virtual void visit(AstArraySel* nodep, AstNUser*) { signed_Olhs(nodep); } //See backRequiresUnsigned
//=======
// Signed: Output signed iff LHS & RHS signed; binary operator
virtual void visit(AstAnd* nodep, AstNUser*) { signed_OlhsAndRhs(nodep); }
@ -315,6 +318,11 @@ private:
nodep->iterateChildren(*this);
nodep->isSigned(nodep->lhsp()->isSigned());
}
// Signed: Output signed iff LHS signed; select operator
void signed_Olhs(AstSel* nodep) {
nodep->iterateChildren(*this);
nodep->isSigned(nodep->fromp()->isSigned());
}
// Signed: Output signed iff LHS & RHS signed; binary operator
void signed_OlhsAndRhs(AstNodeBiop* nodep) {
nodep->iterateChildren(*this);

View File

@ -78,7 +78,9 @@ module t (/*AUTOARG*/
wire [31:0] ucyc = cyc;
always @ (posedge clk) begin
cyc <= cyc + 1;
`ifdef TEST_VERBOSE
$write("%x %x %x %x %x %x %x\n", cyc, sr,srs,sl,sls, b_s,b_us);
`endif
case (cyc)
0: begin
a <= 16'sh8b1b; b <= 5'sh1f; // -1

View File

@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# 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
# General Public License or the Perl Artistic License.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;

View File

@ -0,0 +1,67 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Peter Debacker.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
reg [10:0] in;
reg signed[7:0] min;
reg signed[7:0] max;
wire signed[7:0] filtered_data;
reg signed[7:0] delay_minmax[31:0];
integer k;
initial begin
in = 11'b10000001000;
for(k=0;k<32;k=k+1)
delay_minmax[k] = 0;
end
assign filtered_data = $signed(in[10:3]);
always @(posedge clk) begin
in = in + 8;
`ifdef TEST_VERBOSE
$write("filtered_data: %d\n", filtered_data);
`endif
// delay line shift
for (k=31;k>0;k=k-1) begin
delay_minmax[k] = delay_minmax[k-1];
end
delay_minmax[0] = filtered_data;
`ifdef TEST_VERBOSE
$write("delay_minmax[0] = %d\n", delay_minmax[0]);
$write("delay_minmax[31] = %d\n", delay_minmax[31]);
`endif
// find min and max
min = 127;
max = -128;
`ifdef TEST_VERBOSE
$write("max init: %d\n", max);
$write("min init: %d\n", min);
`endif
for(k=0;k<32;k=k+1) begin
if ((delay_minmax[k]) > $signed(max))
max = delay_minmax[k];
if ((delay_minmax[k]) < $signed(min))
min = delay_minmax[k];
end
`ifdef TEST_VERBOSE
$write("max: %d\n", max);
$write("min: %d\n", min);
`endif
if (min == 127) begin
$stop;
end
else if (filtered_data >= -61) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule