// DESCRIPTION: Verilator: Verilog Test module // // 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. // SPDX-FileCopyrightText: 2011 Wilson Snyder // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // verilog_format: off `define stop $stop `define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); `define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); `define is_near_real(a,b) (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001)) // verilog_format: on module t ( input clk ); integer i; reg [63:0] b; reg [47:0] i48; reg signed [47:0] is48; reg [31:0] ci32; reg signed [31:0] cis32; reg [47:0] ci48; reg signed [47:0] cis48; reg [63:0] ci64; reg signed [63:0] cis64; reg [95:0] ci96; reg signed [95:0] cis96; real r, r2; integer cyc = 0; string s; realtime uninit; initial if (uninit != 0.0) $stop; localparam int TWENTY = 20; localparam real TWENDIV = $ceil((real'(TWENTY) - 14.0) / 2.0); sub_cast_bug374 sub ( .cyc5(cyc[4:0]), .* ); 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 ci64 = $realtobits(1.444); if (ci64 != 64'h3ff71a9fbe76c8b4) $stop; r = $bitstoreal(64'h3ff71a9fbe76c8b4); if (r != 1.444) $stop; r = $bitstoreal($realtobits(1.414)); if (r != 1.414) $stop; // bug r = 32'bxz000_111; // 7 accoding to IEEE if (r != 7) $stop; // bug b = 64'h7fe8000000000000; $display("%6.3f", $bitstoreal(b)); // bug i48 = 48'hff00_00000000; r = real'(i48); if (r != 280375465082880.0) $stop; r = $itor(i48); if (r != 280375465082880.0) $stop; is48 = 48'shff00_00000000; r = real'(is48); if (r != -1099511627776.0) $stop; r = $itor(is48); if (r != -1099511627776.0) $stop; r = 0; r = i48; if (r != 280375465082880.0) $stop; r = 0; r = $itor(-10); if (r != -10.0) $stop; r = real'(4'sb1111); if (r != -1) $stop; r = $itor(4'sb1111); if (r != -1) $stop; r = real'(4'b1111); if (r != 15) $stop; r = $itor(4'b1111); if (r != 15) $stop; r = real'(96'hf0000000_00000000_00000000); if (r != 74276402357122816493947453440.0) $stop; r = real'(96'shf0000000_00000000_00000000); if (r != -4951760157141521099596496896.0) $stop; r = 1.5; if (r++ != 1.5) $stop; if (r != 2.5) $stop; if (r-- != 2.5) $stop; if (r != 1.5) $stop; if (++r != 2.5) $stop; if (r != 2.5) $stop; if (--r != 1.5) $stop; if (r != 1.5) $stop; r = 1.23456; s = $sformatf("%g", r); `checks(s, "1.23456"); r = 1.0 / 0; // inf s = $sformatf("%g", r); `checks(s, "inf"); r = -1.0 / 0; // -inf s = $sformatf("%g", r); `checks(s, "-inf"); r = $sqrt(-1.0); // NaN s = $sformatf("%g", r); if (s == "-nan") s = "nan"; `checks(s, "nan"); r = -$sqrt(-1.0); // NaN s = $sformatf("%g", r); if (s == "-nan") s = "nan"; `checks(s, "nan"); if (real'(TWENTY) != 20.0) $stop; if (TWENDIV != 3.0) $stop; end // Test loop always @(posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d\n", $time, cyc); `endif cyc <= cyc + 1; if (cyc == 0) begin // Setup ci48 <= '0; cis48 <= '0; ci96 <= '0; cis96 <= '0; end else if (cyc == 1) begin ci48 <= 48'hff00_00000000; cis48 <= 48'shff00_00000000; ci96 <= 96'hf0000000_00000000_00000000; cis96 <= 96'shf0000000_00000000_00000000; end else if (cyc < 80) 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; // r = real'(ci48); `checkr(r, 280375465082880.0); r = real'(cis48); `checkr(r, -1099511627776.0); // r = real'(ci96); `checkr(r, 74276402357122816493947453440.0); r = real'(cis96); `checkr(r, -4951760157141521099596496896.0); end else if (cyc == 90) begin ci32 <= '0; cis32 <= '0; ci48 <= '0; cis48 <= '0; ci64 <= '0; cis64 <= '0; ci96 <= '0; cis96 <= '0; end else if (cyc == 91) begin `checkr(real'(ci32), 0.0); `checkr(real'(cis32), 0.0); `checkr(real'(ci48), 0.0); `checkr(real'(cis48), 0.0); `checkr(real'(ci64), 0.0); `checkr(real'(cis64), 0.0); `checkr(real'(ci96), 0.0); `checkr(real'(cis96), 0.0); end else if (cyc == 92) begin ci32 <= 32'b1; cis32 <= 32'b1; ci48 <= 48'b1; cis48 <= 48'b1; ci64 <= 64'b1; cis64 <= 64'b1; ci96 <= 96'b1; cis96 <= 96'b1; end else if (cyc == 93) begin `checkr(real'(ci32), 1.0); `checkr(real'(cis32), 1.0); `checkr(real'(ci48), 1.0); `checkr(real'(cis48), 1.0); `checkr(real'(ci64), 1.0); `checkr(real'(cis64), 1.0); `checkr(real'(ci96), 1.0); `checkr(real'(cis96), 1.0); end else if (cyc == 94) begin ci32 <= ~'0; cis32 <= ~'0; ci48 <= ~'0; cis48 <= ~'0; ci64 <= ~'0; cis64 <= ~'0; ci96 <= ~'0; cis96 <= ~'0; end else if (cyc == 95) begin `checkr(real'(ci32), 4294967295.0); `checkr(real'(cis32), -1.0); `checkr(real'(ci48), 281474976710655.0); `checkr(real'(cis48), -1.0); `checkr(real'(ci64), 18446744073709551616.0); `checkr(real'(cis64), -1.0); `checkr(real'(ci96), 79228162514264337593543950336.0); `checkr(real'(cis96), -1.0); end else if (cyc == 99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub_cast_bug374 ( input clk, input [4:0] cyc5 ); integer i; always @(posedge clk) begin i <= integer'(cyc5); end endmodule