From 2117fe414ec414105cf57683277a618f07252aaf Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 14 Sep 2016 20:27:20 -0400 Subject: [PATCH] Fix error on wide numbers that represent shifts, bug1088. --- Changes | 2 +- src/V3Premit.cpp | 5 +++++ src/V3Width.cpp | 3 --- test_regress/t/t_param_shift.pl | 18 ++++++++++++++++++ test_regress/t/t_param_shift.v | 30 ++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100755 test_regress/t/t_param_shift.pl create mode 100644 test_regress/t/t_param_shift.v diff --git a/Changes b/Changes index dcb0312cd..6f7bb82ee 100644 --- a/Changes +++ b/Changes @@ -12,7 +12,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich] -**** Fix error on wide numbers that represent msb/lsb or shifts, msg1991. [Mandy Xu] +**** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu] **** Improve Verilation performance on internal strings, msg1975. [Johan Bjork] diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index a570764cc..e5e90679a 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -263,6 +263,11 @@ private: // Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s if (!nodep->user2SetOnce()) { UINFO(4," ShiftFix "<rhsp()->castConst(); + if (shiftp && shiftp->num().mostSetBitP1() > 32) { + shiftp->v3error("Unsupported: Shifting of by over 32-bit number isn't supported." + <<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n"); + } if (nodep->widthMin()<=64 // Else we'll use large operators which work right // C operator's width must be < maximum shift which is based on Verilog width && nodep->width() < (1LL<rhsp()->widthMin())) { diff --git a/src/V3Width.cpp b/src/V3Width.cpp index b8b3227e8..7d9e3ecaf 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2632,9 +2632,6 @@ private: AstNode* shiftp = nodep->rhsp(); nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); shiftp->deleteTree(); VL_DANGLING(shiftp); - } else if (!m_paramsOnly) { - nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported." - <<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n"); } } } diff --git a/test_regress/t/t_param_shift.pl b/test_regress/t/t_param_shift.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_param_shift.pl @@ -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; diff --git a/test_regress/t/t_param_shift.v b/test_regress/t/t_param_shift.v new file mode 100644 index 000000000..cc493a10e --- /dev/null +++ b/test_regress/t/t_param_shift.v @@ -0,0 +1,30 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2016 by Mandy Xu. + +module t + #(parameter[95:0] P = 1) + (input clk); + + localparam [32:0] M = 4; + + function [M:0] gen_matrix; + gen_matrix[0] = 1>> M; + endfunction + + reg [95: 0] lfsr = 0; + always @(posedge clk) begin + lfsr <= (1 >> P); + end + + wire [95: 0] lfsr_w = 1 >> P; + + localparam [95: 0] lfsr_p = 1 >> P; + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule