diff --git a/Changes b/Changes index e2d7c5819..0e0b470fc 100644 --- a/Changes +++ b/Changes @@ -10,6 +10,8 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support $rewind and $ungetc. +*** Support shortreal as real, with a SHORTREAL warning. + **** Add -Wpedantic for compliance testing. **** Add error on redefining preprocessor directives. [Piotr Binkowski] diff --git a/bin/verilator b/bin/verilator index fb5853c0f..f259a021d 100755 --- a/bin/verilator +++ b/bin/verilator @@ -4163,6 +4163,17 @@ the access means the access out of bounds will never execute or be used. ... if (seven != 7) out = vec[seven]; // Never will use vec[7] +=item SHORTREAL + +Warns that Verilator does not support "shortreal" and they will be +automatically promoted to "real". The recommendation is to replace any +"shortreal" in the code with "real", as "shortreal" is not widely supported +across industry tools. + +Ignoring this warning may make Verilator simulations differ from other +simulators, if the increased precision of real affects your model or DPI +calls. + =item STMTDLY Warns that you have a statement with a delayed time in front of it, for diff --git a/src/V3Error.h b/src/V3Error.h index 0b865a290..98ce5220f 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -100,6 +100,7 @@ public: REALCVT, // Real conversion REDEFMACRO, // Redefining existing define macro SELRANGE, // Selection index out of range + SHORTREAL, // Shortreal not supported STMTDLY, // Delayed statement SYMRSVDWORD, // Symbol is Reserved Word SYNCASYNCNET, // Mixed sync + async reset @@ -151,7 +152,7 @@ public: "MULTIDRIVEN", "MULTITOP", "PINMISSING", "PINNOCONNECT", "PINCONNECTEMPTY", "PROCASSWIRE", "REALCVT", "REDEFMACRO", - "SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", + "SELRANGE", "SHORTREAL", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS", "UNPACKED", "UNSIGNED", "UNUSED", diff --git a/src/verilog.y b/src/verilog.y index fc380300f..94db470d0 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1425,7 +1425,7 @@ integer_vector_type: // ==IEEE: integer_atom_type non_integer_type: // ==IEEE: non_integer_type yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } | yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } - | ySHORTREAL { BBUNSUP($1, "Unsupported: shortreal (use real instead)"); + | ySHORTREAL { $1->v3warn(SHORTREAL, "Unsupported: shortreal being promoted to real (suggest use real instead)"); $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } ; diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v index a376b7768..ddf6d2b68 100644 --- a/test_regress/t/t_math_real.v +++ b/test_regress/t/t_math_real.v @@ -16,7 +16,7 @@ module t (/*AUTOARG*/ integer i; reg [63:0] b; real r, r2; - integer cyc=0; + integer cyc=0; realtime uninit; initial if (uninit != 0.0) $stop; @@ -90,54 +90,54 @@ module t (/*AUTOARG*/ `endif cyc <= cyc + 1; if (cyc==0) begin - // Setup + // Setup end else if (cyc<90) begin - if ($time != {32'h0, $rtoi($realtime)}) $stop; - if ($itor(cyc) != cyc) $stop; - //Unsup: if ((real `($time)) != $realtime) $stop; - r = $itor(cyc*2); - i = $rtoi(r); - if (i!=cyc*2) $stop; - // - r = $itor(cyc)/1.5; - b = $realtobits(r); - r2 = $bitstoreal(b); - if (r != r2) $stop; - // - // Trust the integer math as a comparison - r = $itor(cyc); - if ($rtoi(-r) != -cyc) $stop; - if ($rtoi(+r) != cyc) $stop; - if ($rtoi(r+2.0) != (cyc+2)) $stop; - if ($rtoi(r-2.0) != (cyc-2)) $stop; - if ($rtoi(r*2.0) != (cyc*2)) $stop; - if ($rtoi(r/2.0) != (cyc/2)) $stop; - r2 = (2.0/(r-60)); // When zero, result indeterminate, but no crash - // - r2 = $itor(cyc); - case (r) - (r2-1.0): $stop; - r2: ; - default: $stop; - endcase - // - r = $itor(cyc); - if ((r==50.0) != (cyc==50)) $stop; - if ((r!=50.0) != (cyc!=50)) $stop; - if ((r> 50.0) != (cyc> 50)) $stop; - if ((r>=50.0) != (cyc>=50)) $stop; - if ((r< 50.0) != (cyc< 50)) $stop; - if ((r<=50.0) != (cyc<=50)) $stop; - // - if ($rtoi((r-50.0) ? 10.0 : 20.0) - != (((cyc-50)!=0) ? 10 : 20)) $stop; - // - if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop; + if ($time != {32'h0, $rtoi($realtime)}) $stop; + if ($itor(cyc) != cyc) $stop; + //Unsup: if ((real `($time)) != $realtime) $stop; + r = $itor(cyc*2); + i = $rtoi(r); + if (i!=cyc*2) $stop; + // + r = $itor(cyc)/1.5; + b = $realtobits(r); + r2 = $bitstoreal(b); + if (r != r2) $stop; + // + // Trust the integer math as a comparison + r = $itor(cyc); + if ($rtoi(-r) != -cyc) $stop; + if ($rtoi(+r) != cyc) $stop; + if ($rtoi(r+2.0) != (cyc+2)) $stop; + if ($rtoi(r-2.0) != (cyc-2)) $stop; + if ($rtoi(r*2.0) != (cyc*2)) $stop; + if ($rtoi(r/2.0) != (cyc/2)) $stop; + r2 = (2.0/(r-60)); // When zero, result indeterminate, but no crash + // + r2 = $itor(cyc); + case (r) + (r2-1.0): $stop; + r2: ; + default: $stop; + endcase + // + r = $itor(cyc); + if ((r==50.0) != (cyc==50)) $stop; + if ((r!=50.0) != (cyc!=50)) $stop; + if ((r> 50.0) != (cyc> 50)) $stop; + if ((r>=50.0) != (cyc>=50)) $stop; + if ((r< 50.0) != (cyc< 50)) $stop; + if ((r<=50.0) != (cyc<=50)) $stop; + // + if ($rtoi((r-50.0) ? 10.0 : 20.0) + != (((cyc-50)!=0) ? 10 : 20)) $stop; + // + if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop; end else if (cyc==99) begin - $write("*-* All Finished *-*\n"); - $finish; + $write("*-* All Finished *-*\n"); + $finish; end end endmodule diff --git a/test_regress/t/t_math_shortreal.pl b/test_regress/t/t_math_shortreal.pl new file mode 100755 index 000000000..89a4e77d9 --- /dev/null +++ b/test_regress/t/t_math_shortreal.pl @@ -0,0 +1,20 @@ +#!/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. + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_shortreal.v b/test_regress/t/t_math_shortreal.v new file mode 100644 index 000000000..146e0463d --- /dev/null +++ b/test_regress/t/t_math_shortreal.v @@ -0,0 +1,142 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2011 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. + +`define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001)) + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + // verilator lint_off SHORTREAL + integer i; + reg [63:0] b; + shortreal r, r2; + integer cyc=0; + + realtime uninit; + initial if (uninit != 0.0) $stop; + + initial begin + if (1_00_0.0_1 != 1000.01) $stop; + // rtoi truncates + if ($rtoi(36.7) != 36) $stop; + if ($rtoi(36.5) != 36) $stop; + if ($rtoi(36.4) != 36) $stop; + // casting rounds + if ((integer '(36.7)) != 37) $stop; + if ((integer '(36.5)) != 37) $stop; + if ((integer '(36.4)) != 36) $stop; + // assignment rounds + // verilator lint_off REALCVT + i = 36.7; if (i != 37) $stop; + i = 36.5; if (i != 37) $stop; + i = 36.4; if (i != 36) $stop; + r = 10'd38; if (r!=38.0) $stop; + // verilator lint_on REALCVT + // operators + if ((-(1.5)) != -1.5) $stop; + if ((+(1.5)) != 1.5) $stop; + if (((1.5)+(1.25)) != 2.75) $stop; + if (((1.5)-(1.25)) != 0.25) $stop; + if (((1.5)*(1.25)) != 1.875) $stop; + if (((1.5)/(1.25)) != 1.2) $stop; + // + if (((1.5)==(2)) != 1'b0) $stop; // note 2 becomes real 2.0 + if (((1.5)!=(2)) != 1'b1) $stop; + if (((1.5)> (2)) != 1'b0) $stop; + if (((1.5)>=(2)) != 1'b0) $stop; + if (((1.5)< (2)) != 1'b1) $stop; + if (((1.5)<=(2)) != 1'b1) $stop; + if (((1.5)==(1.5)) != 1'b1) $stop; + if (((1.5)!=(1.5)) != 1'b0) $stop; + if (((1.5)> (1.5)) != 1'b0) $stop; + if (((1.5)>=(1.5)) != 1'b1) $stop; + if (((1.5)< (1.5)) != 1'b0) $stop; + if (((1.5)<=(1.5)) != 1'b1) $stop; + if (((1.6)==(1.5)) != 1'b0) $stop; + if (((1.6)!=(1.5)) != 1'b1) $stop; + if (((1.6)> (1.5)) != 1'b1) $stop; + if (((1.6)>=(1.5)) != 1'b1) $stop; + if (((1.6)< (1.5)) != 1'b0) $stop; + if (((1.6)<=(1.5)) != 1'b0) $stop; + // + if (((0.0)?(2.0):(1.1)) != 1.1) $stop; + if (((1.5)?(2.0):(1.1)) != 2.0) $stop; + // + if (!1.7) $stop; + if (!(!0.0)) $stop; + if (1.8 && 0.0) $stop; + if (!(1.8 || 0.0)) $stop; + // + i=0; + for (r=1.0; r<2.0; r=r+0.1) i++; + if (i!=10) $stop; + // bug + r = $bitstoreal($realtobits(1.414)); + if (r != 1.414) $stop; + end + + // Test loop + always @ (posedge clk) begin +`ifdef TEST_VERBOSE + $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); +`endif + cyc <= cyc + 1; + if (cyc==0) begin + // Setup + end + else if (cyc<90) begin + if ($time != {32'h0, $rtoi($realtime)}) $stop; + if ($itor(cyc) != cyc) $stop; + //Unsup: if ((real `($time)) != $realtime) $stop; + r = $itor(cyc*2); + i = $rtoi(r); + if (i!=cyc*2) $stop; + // + r = $itor(cyc)/1.5; + b = $realtobits(r); + r2 = $bitstoreal(b); + if (r != r2) $stop; + // + // Trust the integer math as a comparison + r = $itor(cyc); + if ($rtoi(-r) != -cyc) $stop; + if ($rtoi(+r) != cyc) $stop; + if ($rtoi(r+2.0) != (cyc+2)) $stop; + if ($rtoi(r-2.0) != (cyc-2)) $stop; + if ($rtoi(r*2.0) != (cyc*2)) $stop; + if ($rtoi(r/2.0) != (cyc/2)) $stop; + r2 = (2.0/(r-60)); // When zero, result indeterminate, but no crash + // + r2 = $itor(cyc); + case (r) + (r2-1.0): $stop; + r2: ; + default: $stop; + endcase + // + r = $itor(cyc); + if ((r==50.0) != (cyc==50)) $stop; + if ((r!=50.0) != (cyc!=50)) $stop; + if ((r> 50.0) != (cyc> 50)) $stop; + if ((r>=50.0) != (cyc>=50)) $stop; + if ((r< 50.0) != (cyc< 50)) $stop; + if ((r<=50.0) != (cyc<=50)) $stop; + // + if ($rtoi((r-50.0) ? 10.0 : 20.0) + != (((cyc-50)!=0) ? 10 : 20)) $stop; + // + if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop; + end + else if (cyc==99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule diff --git a/test_regress/t/t_math_shortreal_unsup_bad.out b/test_regress/t/t_math_shortreal_unsup_bad.out new file mode 100644 index 000000000..1e9fc1d38 --- /dev/null +++ b/test_regress/t/t_math_shortreal_unsup_bad.out @@ -0,0 +1,5 @@ +%Warning-SHORTREAL: t/t_math_shortreal_unsup_bad.v:8: Unsupported: shortreal being promoted to real (suggest use real instead) + shortreal s; + ^~~~~~~~~ + ... Use "/* verilator lint_off SHORTREAL */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_math_shortreal_unsup_bad.pl b/test_regress/t/t_math_shortreal_unsup_bad.pl new file mode 100755 index 000000000..4ba881869 --- /dev/null +++ b/test_regress/t/t_math_shortreal_unsup_bad.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 2010 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. + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_shortreal_unsup_bad.v b/test_regress/t/t_math_shortreal_unsup_bad.v new file mode 100644 index 000000000..4fa2d5152 --- /dev/null +++ b/test_regress/t/t_math_shortreal_unsup_bad.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2016 by Wilson Snyder. + +module t (/*AUTOARG*/); + + shortreal s; + + initial s = 1.2345; + +endmodule