diff --git a/Changes b/Changes index 202700367..036b0fcbd 100644 --- a/Changes +++ b/Changes @@ -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] diff --git a/src/V3Signed.cpp b/src/V3Signed.cpp index daf7917f1..9374ef442 100644 --- a/src/V3Signed.cpp +++ b/src/V3Signed.cpp @@ -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); diff --git a/test_regress/t/t_math_signed.v b/test_regress/t/t_math_signed.v index d973a62e2..cba3253b7 100644 --- a/test_regress/t/t_math_signed.v +++ b/test_regress/t/t_math_signed.v @@ -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 diff --git a/test_regress/t/t_math_signed2.pl b/test_regress/t/t_math_signed2.pl new file mode 100755 index 000000000..7bfdbe852 --- /dev/null +++ b/test_regress/t/t_math_signed2.pl @@ -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; diff --git a/test_regress/t/t_math_signed2.v b/test_regress/t/t_math_signed2.v new file mode 100644 index 000000000..286e6f423 --- /dev/null +++ b/test_regress/t/t_math_signed2.v @@ -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