1// DESCRIPTION: Verilator: Verilog Test module
2//
3// Copyright 2011 by Wilson Snyder. This program is free software; you can
4// redistribute it and/or modify it under the terms of either the GNU
5// Lesser General Public License Version 3 or the Perl Artistic License
6// Version 2.0.
7// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
8
9`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);
10`define is_near_real(a,b)  (( ((a)<(b)) ? (b)-(a) : (a)-(b)) < (((a)/(b))*0.0001))
11
12module t (/*AUTOARG*/
13   // Inputs
14   clk
15   );
16   input clk;
17
18   integer i;
19   reg [63:0] b;
20   reg [47:0] i48;
21   reg signed [47:0] is48;
22   reg [31:0] ci32;
23   reg signed [31:0] cis32;
24   reg [47:0] ci48;
25   reg signed [47:0] cis48;
26   reg [63:0] ci64;
27   reg signed [63:0] cis64;
28   reg [95:0] ci96;
29   reg signed [95:0] cis96;
30   real  r, r2;
31   integer      cyc = 0;
32
33   realtime  uninit;
34   initial if (uninit != 0.0) $stop;
35
36   sub_cast_bug374 sub (.cyc5(cyc[4:0]), .*);
37
38   initial begin
39      if (1_00_0.0_1 != 1000.01) $stop;
40      // rtoi truncates
41      if ($rtoi(36.7) != 36) $stop;
42      if ($rtoi(36.5) != 36) $stop;
43      if ($rtoi(36.4) != 36) $stop;
44      // casting rounds
45      if ((integer '(36.7)) != 37) $stop;
46      if ((integer '(36.5)) != 37) $stop;
47      if ((integer '(36.4)) != 36) $stop;
48      // assignment rounds
49      // verilator lint_off REALCVT
50      i = 36.7; if (i != 37) $stop;
51      i = 36.5; if (i != 37) $stop;
52      i = 36.4; if (i != 36) $stop;
53      r = 10'd38;  if (r!=38.0) $stop;
54      // verilator lint_on REALCVT
55      // operators
56      if ((-(1.5)) != -1.5) $stop;
57      if ((+(1.5)) != 1.5) $stop;
58      if (((1.5)+(1.25)) != 2.75) $stop;
59      if (((1.5)-(1.25)) != 0.25) $stop;
60      if (((1.5)*(1.25)) != 1.875) $stop;
61      if (((1.5)/(1.25)) != 1.2) $stop;
62      //
63      if (((1.5)==(2)) != 1'b0) $stop;  // note 2 becomes real 2.0
64      if (((1.5)!=(2)) != 1'b1) $stop;
65      if (((1.5)> (2)) != 1'b0) $stop;
66      if (((1.5)>=(2)) != 1'b0) $stop;
67      if (((1.5)< (2)) != 1'b1) $stop;
68      if (((1.5)<=(2)) != 1'b1) $stop;
69      if (((1.5)==(1.5)) != 1'b1) $stop;
70      if (((1.5)!=(1.5)) != 1'b0) $stop;
71      if (((1.5)> (1.5)) != 1'b0) $stop;
72      if (((1.5)>=(1.5)) != 1'b1) $stop;
73      if (((1.5)< (1.5)) != 1'b0) $stop;
74      if (((1.5)<=(1.5)) != 1'b1) $stop;
75      if (((1.6)==(1.5)) != 1'b0) $stop;
76      if (((1.6)!=(1.5)) != 1'b1) $stop;
77      if (((1.6)> (1.5)) != 1'b1) $stop;
78      if (((1.6)>=(1.5)) != 1'b1) $stop;
79      if (((1.6)< (1.5)) != 1'b0) $stop;
80      if (((1.6)<=(1.5)) != 1'b0) $stop;
81      //
82      if (((0.0)?(2.0):(1.1)) != 1.1) $stop;
83      if (((1.5)?(2.0):(1.1)) != 2.0) $stop;
84      //
85      if (!1.7) $stop;
86      if (!(!0.0)) $stop;
87      if (1.8 && 0.0) $stop;
88      if (!(1.8 || 0.0)) $stop;
89      //
90      i=0;
91      for (r=1.0; r<2.0; r=r+0.1) i++;
92      if (i!=10) $stop;
93      // bug
94      r = $bitstoreal($realtobits(1.414));
95      if (r != 1.414) $stop;
96      // bug
97      r = 32'bxz000_111;  // 7 accoding to IEEE
98      if (r != 7) $stop;
99      // bug
100      b = 64'h7fe8000000000000;
101      $display("%6.3f", $bitstoreal(b));
102      // bug
103      i48 = 48'hff00_00000000;
104      r = real'(i48);
105      if (r != 280375465082880.0) $stop;
106      r = $itor(i48);
107      if (r != 280375465082880.0) $stop;
108
109      is48 = 48'shff00_00000000;
110      r = real'(is48);
111      if (r != -1099511627776.0) $stop;
112      r = $itor(is48);
113      if (r != -1099511627776.0) $stop;
114
115      r = 0;
116      r = i48;
117      if (r != 280375465082880.0) $stop;
118      r = 0;
119
120      r = $itor(-10);
121      if (r != -10.0) $stop;
122
123      r = real'(4'sb1111);
124      if (r != -1) $stop;
125      r = $itor(4'sb1111);
126      if (r != -1) $stop;
127
128      r = real'(4'b1111);
129      if (r != 15) $stop;
130      r = $itor(4'b1111);
131      if (r != 15) $stop;
132
133      r = real'(96'hf0000000_00000000_00000000);
134      if (r != 74276402357122816493947453440.0) $stop;
135      r = real'(96'shf0000000_00000000_00000000);
136      if (r != -4951760157141521099596496896.0) $stop;
137   end
138
139   // Test loop
140   always @ (posedge clk) begin
141`ifdef TEST_VERBOSE
142      $write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result);
143`endif
144      cyc <= cyc + 1;
145      if (cyc==0) begin
146         // Setup
147         ci48 <= '0;
148         cis48 <= '0;
149         ci96 <= '0;
150         cis96 <= '0;
151      end
152      else if (cyc == 1) begin
153         ci48 <= 48'hff00_00000000;
154         cis48 <= 48'shff00_00000000;
155         ci96 <= 96'hf0000000_00000000_00000000;
156         cis96 <= 96'shf0000000_00000000_00000000;
157      end
158      else if (cyc<80) begin
159         if ($time != {32'h0, $rtoi($realtime)}) $stop;
160         if ($itor(cyc) != cyc) $stop;
161         //Unsup: if ((real `($time)) != $realtime) $stop;
162         r = $itor(cyc*2);
163         i = $rtoi(r);
164         if (i!=cyc*2) $stop;
165         //
166         r = $itor(cyc)/1.5;
167         b = $realtobits(r);
168         r2 = $bitstoreal(b);
169         if (r != r2) $stop;
170         //
171         // Trust the integer math as a comparison
172         r = $itor(cyc);
173         if ($rtoi(-r) != -cyc) $stop;
174         if ($rtoi(+r) != cyc) $stop;
175         if ($rtoi(r+2.0) != (cyc+2)) $stop;
176         if ($rtoi(r-2.0) != (cyc-2)) $stop;
177         if ($rtoi(r*2.0) != (cyc*2)) $stop;
178         if ($rtoi(r/2.0) != (cyc/2)) $stop;
179         r2 = (2.0/(r-60));  // When zero, result indeterminate, but no crash
180         //
181         r2 = $itor(cyc);
182         case (r)
183           (r2-1.0): $stop;
184           r2: ;
185           default: $stop;
186         endcase
187         //
188         r = $itor(cyc);
189         if ((r==50.0) != (cyc==50)) $stop;
190         if ((r!=50.0) != (cyc!=50)) $stop;
191         if ((r> 50.0) != (cyc> 50)) $stop;
192         if ((r>=50.0) != (cyc>=50)) $stop;
193         if ((r< 50.0) != (cyc< 50)) $stop;
194         if ((r<=50.0) != (cyc<=50)) $stop;
195         //
196         if ($rtoi((r-50.0) ? 10.0 : 20.0)
197             !=  (((cyc-50)!=0) ? 10 : 20)) $stop;
198         //
199         if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop;
200         //
201         r = real'(ci48);
202         `checkr(r, 280375465082880.0);
203         r = real'(cis48);
204         `checkr(r, -1099511627776.0);
205         //
206         r = real'(ci96);
207         `checkr(r, 74276402357122816493947453440.0);
208         r = real'(cis96);
209         `checkr(r, -4951760157141521099596496896.0);
210      end
211      else if (cyc==90) begin
212         ci32 <= '0;
213         cis32 <= '0;
214         ci48 <= '0;
215         cis48 <= '0;
216         ci64 <= '0;
217         cis64 <= '0;
218         ci96 <= '0;
219         cis96 <= '0;
220      end
221      else if (cyc==91) begin
222         `checkr(real'(ci32), 0.0);
223         `checkr(real'(cis32), 0.0);
224         `checkr(real'(ci48), 0.0);
225         `checkr(real'(cis48), 0.0);
226         `checkr(real'(ci64), 0.0);
227         `checkr(real'(cis64), 0.0);
228         `checkr(real'(ci96), 0.0);
229         `checkr(real'(cis96), 0.0);
230      end
231      else if (cyc==92) begin
232         ci32 <= 32'b1;
233         cis32 <= 32'b1;
234         ci48 <= 48'b1;
235         cis48 <= 48'b1;
236         ci64 <= 64'b1;
237         cis64 <= 64'b1;
238         ci96 <= 96'b1;
239         cis96 <= 96'b1;
240      end
241      else if (cyc==93) begin
242         `checkr(real'(ci32), 1.0);
243         `checkr(real'(cis32), 1.0);
244         `checkr(real'(ci48), 1.0);
245         `checkr(real'(cis48), 1.0);
246         `checkr(real'(ci64), 1.0);
247         `checkr(real'(cis64), 1.0);
248         `checkr(real'(ci96), 1.0);
249         `checkr(real'(cis96), 1.0);
250      end
251      else if (cyc==94) begin
252         ci32 <= ~ '0;
253         cis32 <= ~ '0;
254         ci48 <= ~ '0;
255         cis48 <= ~ '0;
256         ci64 <= ~ '0;
257         cis64 <= ~ '0;
258         ci96 <= ~ '0;
259         cis96 <= ~ '0;
260      end
261      else if (cyc==95) begin
262         `checkr(real'(ci32), 4294967295.0);
263         `checkr(real'(cis32), -1.0);
264         `checkr(real'(ci48), 281474976710655.0);
265         `checkr(real'(cis48), -1.0);
266         `checkr(real'(ci64), 18446744073709551616.0);
267         `checkr(real'(cis64), -1.0);
268         `checkr(real'(ci96), 79228162514264337593543950336.0);
269         `checkr(real'(cis96), -1.0);
270      end
271      else if (cyc==99) begin
272         $write("*-* All Finished *-*\n");
273         $finish;
274      end
275   end
276endmodule
277
278module sub_cast_bug374(input clk, input [4:0] cyc5);
279    integer i;
280
281    always @(posedge clk) begin
282       i <= integer'(cyc5);
283    end
284endmodule
285