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, 2009 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7module t (/*AUTOARG*/
8   // Inputs
9   clk
10   );
11
12   input clk;
13
14   //Simple debug:
15   //wire  [1:1] wir_a [3:3] [2:2]; //11
16   //logic [1:1] log_a [3:3] [2:2]; //12
17   //wire  [3:3] [2:2] [1:1] wir_p; //13
18   //logic [3:3] [2:2] [1:1] log_p; //14
19
20   integer cyc; initial cyc = 0;
21`ifdef IVERILOG
22   reg [7:0] arr [3:0];
23   wire [7:0] arr_w [3:0];
24`else
25   reg [3:0] [7:0] arr;
26   wire [3:0] [7:0] arr_w;
27`endif
28   reg [7:0] sum;
29   reg [7:0] sum_w;
30   integer    i0;
31
32   initial begin
33      for (i0=0; i0<5; i0=i0+1) begin
34	 arr[i0] = 1 << (i0[1:0]*2);
35      end
36   end
37
38   assign arr_w = arr;
39
40   always @ (posedge clk) begin
41      cyc <= cyc + 1;
42      if (cyc==0) begin
43	 // Setup
44	 sum <= 0;
45	 sum_w <= 0;
46      end
47      else if (cyc >= 10 && cyc < 14) begin
48	 sum <= sum + arr[cyc-10];
49
50	 sum_w <= sum_w + arr_w[cyc-10];
51      end
52      else if (cyc==99) begin
53	 $write("[%0t] cyc==%0d sum=%x\n", $time, cyc, sum);
54	 if (sum != 8'h55) $stop;
55	 if (sum != sum_w) $stop;
56	 $write("*-* All Finished *-*\n");
57	 $finish;
58      end
59   end
60
61   // Test ordering of packed dimensions
62   logic             [31:0] data_out;
63   logic             [31:0] data_out2;
64   logic [0:0] [2:0] [31:0] data_in;
65   logic [31:0] data_in2 [0:0] [2:0];
66   assign data_out = data_in[0][0] + data_in[0][1] + data_in[0][2];
67   assign data_out2 = data_in2[0][0] + data_in2[0][1] + data_in2[0][2];
68
69   logic [31:0] last_data_out;
70   always @ (posedge clk) begin
71      if (cyc <= 2) begin
72	 data_in[0][0] <= 0;
73	 data_in[0][1] <= 0;
74	 data_in[0][2] <= 0;
75	 data_in2[0][0] <= 0;
76	 data_in2[0][1] <= 0;
77	 data_in2[0][2] <= 0;
78      end
79      else if (cyc > 2 && cyc < 99) begin
80	 data_in[0][0] <= data_in[0][0] + 1;
81	 data_in[0][1] <= data_in[0][1] + 1;
82	 data_in[0][2] <= data_in[0][2] + 1;
83	 data_in2[0][0] <= data_in2[0][0] + 1;
84	 data_in2[0][1] <= data_in2[0][1] + 1;
85	 data_in2[0][2] <= data_in2[0][2] + 1;
86	 last_data_out <= data_out;
87`ifdef TEST_VERBOSE
88	 $write("data_out %0x %0x\n", data_out, last_data_out);
89`endif
90	 if (cyc > 4 && data_out != last_data_out + 3) $stop;
91	 if (cyc > 4 && data_out != data_out2) $stop;
92      end
93   end
94
95   // Test for mixed implicit/explicit dimensions and all implicit packed
96   bit [3:0][7:0][1:0] vld [1:0][1:0];
97   bit [3:0][7:0][1:0] vld2;
98
99   // There are specific nodes for Or, Xor, Xnor and And
100   logic            vld_or;
101   logic            vld2_or;
102   assign vld_or = |vld[0][0];
103   assign vld2_or = |vld2;
104
105   logic            vld_xor;
106   logic            vld2_xor;
107   assign vld_xor = ^vld[0][0];
108   assign vld2_xor = ^vld2;
109
110   logic            vld_xnor;
111   logic            vld2_xnor;
112   assign vld_xnor = ~^vld[0][0];
113   assign vld2_xnor = ~^vld2;
114
115   logic            vld_and;
116   logic            vld2_and;
117   assign vld_and = &vld[0][0];
118   assign vld2_and = &vld2;
119
120   // Bit reductions should be cloned, other unary operations should clone the
121   // entire assign.
122   bit [3:0][7:0][1:0] not_lhs;
123   bit [3:0][7:0][1:0] not_rhs;
124   assign not_lhs = ~not_rhs;
125
126   // Test an AstNodeUniop that shouldn't be expanded
127   bit [3:0][7:0][1:0] vld2_inv;
128   assign vld2_inv = ~vld2;
129
130   initial begin
131      for (int i=0; i<4; i=i+2) begin
132         for (int j=0; j<8; j=j+2) begin
133	    vld[0][0][i][j] = 2'b00;
134	    vld[0][0][i+1][j+1] = 2'b00;
135	    vld2[i][j] = 2'b00;
136	    vld2[i+1][j+1] = 2'b00;
137	    not_rhs[i][j] = i[1:0];
138	    not_rhs[i+1][j+1] = i[1:0];
139	 end
140      end
141   end
142
143
144   logic [3:0] expect_cyc; initial expect_cyc = 'd15;
145
146   always @(posedge clk) begin
147      expect_cyc <= expect_cyc + 1;
148      for (int i=0; i<4; i=i+1) begin
149         for (int j=0; j<8; j=j+1) begin
150	    vld[0][0][i][j] <= vld[0][0][i][j] + 1;
151	    vld2[i][j] <= vld2[i][j] + 1;
152	    if (not_rhs[i][j] != ~not_lhs[i][j]) $stop;
153	    not_rhs[i][j] <= not_rhs[i][j] + 1;
154	 end
155      end
156      if (cyc % 8 == 0) begin
157	 vld[0][0][0][0] <= vld[0][0][0][0] - 1;
158	 vld2[0][0] <= vld2[0][0] - 1;
159      end
160      if (expect_cyc < 8 && !vld_xor) $stop;
161      else if (expect_cyc > 7 && vld_xor) $stop;
162
163      if (expect_cyc < 8 && vld_xnor) $stop;
164      else if (expect_cyc > 7 && !vld_xnor) $stop;
165
166      if (expect_cyc == 15 && vld_or) $stop;
167      else if (expect_cyc == 11 && vld_or) $stop;
168      else if (expect_cyc != 15 && expect_cyc != 11 && !vld_or) $stop;
169
170      if (expect_cyc == 10 && !vld_and) $stop;
171      else if (expect_cyc == 14 && !vld_and) $stop;
172      else if (expect_cyc != 10 && expect_cyc != 14 && vld_and) $stop;
173
174      if (vld_xor != vld2_xor) $stop;
175      if (vld_xnor != vld2_xnor) $stop;
176      if (vld_or != vld2_or) $stop;
177      if (vld_and != vld2_and) $stop;
178   end
179
180endmodule
181