1// DESCRIPTION: Verilator: Verilog Test module
2//
3// This file ONLY is placed under the Creative Commons Public Domain, for
4// any use, without warranty, 2014 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d:  got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0)
8`define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d:  got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0)
9
10module t (/*AUTOARG*/);
11
12   bit fail;
13
14   localparam signed [3:0] bug737_p1 = 4'b1000;
15
16   wire [3:0] bug737_a = 4'b1010;
17   reg [5:0]  bug737_y;
18   reg signed [3:0] w4_s;
19   reg signed [4:0] w5_s;
20   reg [3:0] w4_u;
21   reg [4:0] w5_u;
22   reg signed [8:0] w9_s;
23   real      r;
24   initial begin
25      // verilator lint_off WIDTH
26      bug737_y = bug737_a + (bug737_p1 + 4'sb0);
27      `checkh(bug737_y, 6'b010010);  //bug737
28
29      //         6u     +[6u]   4s  +[6s] 6s
30      bug737_y = 6'b001010 + (4'sb1000 + 6'sb0);
31      `checkh(bug737_y, 6'b010010);  //bug737, getx 000010
32
33      //         6u     +[6u]   4s  +[6s] 6s
34      bug737_y = 6'b001010 + (4'b1000 + 6'sb0);
35      `checkh(bug737_y, 6'b010010);  //ok
36
37      bug737_y = 6'b001010 + (6'sb111000 + 6'sb0);
38      `checkh(bug737_y, 6'b000010);  //ok
39
40      //                       v--- sign extends to 6-bits
41      bug737_y = 6'sb001010 + (4'sb1000 + 6'sb0);
42      `checkh(bug737_y, 6'b000010);  //ok
43
44      // From t_math_signed_3
45      w4_s = 4'sb1111 - 1'b1;
46      `checkh(w4_s,33'he);
47
48      w4_s = 4'sb1111 - 5'b00001;
49      `checkh(w4_s,33'he);
50
51      w4_s = 4'sb1111 - 1'sb1;
52      `checkh(w4_s,4'h0);
53      w5_s = 4'sb1111 - 1'sb1;
54      `checkh(w5_s,4'h0);
55
56      w4_s = 4'sb1111 - 4'sb1111;
57      `checkh(w4_s,4'h0);
58      w5_s = 4'sb1111 - 4'sb1111;
59      `checkh(w5_s,5'h0);
60
61      // The assign LHS being signed or unsigned does not matter per IEEE
62      // The upper add being signed DOES matter propagating to lower
63      w4_s = 4'sb1111 - (1'sb1 + 4'b0);   //1'sb1 not extended as unsigned add
64      `checkh(w4_s,4'he);
65      w4_s = 4'sb1111 - (1'sb1 + 4'sb0);  //1'sb1 does sign extend
66      `checkh(w4_s,4'h0);
67      w4_s = 4'b1111 - (1'sb1 + 4'sb0);  //1'sb1 does *NOT* sign extend
68      `checkh(w4_s,4'he);  // BUG, Verilator says 'h0
69
70      w5_u = 4'b1111 + 4'b0001;  // Extends to 5 bits due to LHS
71      `checkh(w5_u, 5'b10000);
72      w4_u = 4'b1111 + 4'b0001;  // Normal case
73      `checkh(w4_u, 4'b0000);
74
75      // Another example of promotion, the add is 4 bits wide
76      w4_u = 3'b111 + 3'b010;
77      `checkh(w4_u, 4'b1001);
78      //
79      w4_u = 3'sb111 * 3'sb001; // Signed output, LHS does not matter
80      `checkh(w4_u, 4'sb1111);
81      w4_s = 3'sb111 * 3'sb001; // Signed output
82      `checkh(w4_s, 4'sb1111);
83      w4_s = 3'b111 * 3'sb001;  // Unsigned output
84      `checkh(w4_s, 4'b0111);
85
86      // Conditionals get width from parent; are assignment-like
87      w4_u = 1'b0 ? 4'b0 : (2'b01+2'b11);
88      `checkh(w4_u, 4'b0100);
89      w4_u = 1'b0 ? 4'b0 : (6'b001000+6'b001000);
90      `checkh(w4_u, 4'b0000);
91
92      // If RHS is larger, that larger size is used
93      w4_u = 5'b10000 / 5'b00100;
94      `checkh(w4_u, 4'b0100);
95
96      // bug754
97      w5_u = 4'sb0010 << -2'sd1;  // << 3
98`ifdef VCS
99      `checkh(w5_u, 5'b00000);  // VCS E-2014.03 bug
100`else
101      `checkh(w5_u, 5'b10000);  // VCS E-2014.03 bug
102`endif
103      w5_u = 4'sb1000 << 0;   // Sign extends
104      `checkh(w5_u, 5'b11000);
105
106      // Reals do not propagate to children
107      r = 1.0 + ( 1 + (1 / 2));
108      `checkf(r, 2.0);
109
110      // Self determined sign extension
111      r = $itor(3'sb111);
112      `checkf(r, -1.0);
113
114      // If any part of case is real, all is real
115      case (22)
116	22.0: ;
117	22.1: $stop;
118	default: $stop;
119      endcase
120
121      // bug759
122      w5_u = { -4'sd7 };
123      `checkh(w5_u, 5'b01001);
124      w5_u = {2{ -2'sd1 }};
125      `checkh(w5_u, 5'b01111);
126      // Don't break concats....
127      w5_u = {{0{1'b1}}, -4'sd7 };
128      `checkh(w5_u, 5'b01001);
129      w9_s = { -4'sd7, -4'sd7 };
130      `checkh(w9_s, 9'b010011001);
131      {w5_u, {w4_u}} = 9'b10101_1100;
132      `checkh(w5_u, 5'b10101);
133      `checkh(w4_u, 4'b1100);
134      {w4_u} = 4'b1011;
135      `checkh(w4_u, 4'b1011);
136
137      if (fail) $stop;
138      $write("*-* All Finished *-*\n");
139      $finish;
140   end
141endmodule
142