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, 2003 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7module t (clk);
8   input clk;
9
10   tpub p1 (.clk(clk), .i(32'd1));
11   tpub p2 (.clk(clk), .i(32'd2));
12
13   integer cyc; initial cyc=1;
14   always @ (posedge clk) begin
15      if (cyc!=0) begin
16	 cyc <= cyc + 1;
17	 if (cyc==1) begin
18`ifdef verilator
19	    $c("this->publicTop();");
20`endif
21	 end
22	 if (cyc==20) begin
23	    $write("*-* All Finished *-*\n");
24	    $finish;
25	 end
26      end
27   end
28
29   task publicTop;
30      // verilator public
31      // We have different optimizations if only one of something, so try it out.
32      $write("Hello in publicTop\n");
33   endtask
34
35endmodule
36
37module tpub (
38	     input clk,
39	     input [31:0] i);
40
41   reg [23:0] var_long;
42   reg [59:0] var_quad;
43   reg [71:0] var_wide;
44   reg 	      var_bool;
45
46   // verilator lint_off BLKANDNBLK
47   reg [11:0] var_flop;
48   // verilator lint_on  BLKANDNBLK
49
50   reg [23:0] got_long /*verilator public*/;
51   reg [59:0] got_quad /*verilator public*/;
52   reg [71:0] got_wide /*verilator public*/;
53   reg        got_bool /*verilator public*/;
54
55   integer cyc; initial cyc=1;
56   always @ (posedge clk) begin
57      if (cyc!=0) begin
58	 cyc <= cyc + 1;
59	 // cyc==1 is in top level
60	 if (cyc==2) begin
61	    publicNoArgs;
62	    publicSetBool(1'b1);
63	    publicSetLong(24'habca);
64	    publicSetQuad(60'h4444_3333_2222);
65	    publicSetWide(72'h12_5678_9123_1245_2352);
66	    var_flop <= 12'habe;
67	 end
68	 if (cyc==3) begin
69	    if (1'b1 != publicGetSetBool(1'b0)) $stop;
70	    if (24'habca != publicGetSetLong(24'h1234)) $stop;
71	    if (60'h4444_3333_2222 != publicGetSetQuad(60'h123_4567_89ab)) $stop;
72	    if (72'h12_5678_9123_1245_2352 != publicGetSetWide(72'hac_abca_aaaa_bbbb_1234)) $stop;
73	 end
74	 if (cyc==4) begin
75	    publicGetBool(got_bool);
76	    if (1'b0 != got_bool) $stop;
77	    publicGetLong(got_long);
78	    if (24'h1234 != got_long) $stop;
79	    publicGetQuad(got_quad);
80	    if (60'h123_4567_89ab != got_quad) $stop;
81	    publicGetWide(got_wide);
82	    if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop;
83	 end
84	 //
85`ifdef VERILATOR_PUBLIC_TASKS
86	 if (cyc==11) begin
87	    $c("this->publicNoArgs();");
88	    $c("this->publicSetBool(true);");
89	    $c("this->publicSetLong(0x11bca);");
90	    $c("this->publicSetQuad(0x66655554444ULL);");
91	    $c("this->publicSetFlop(0x321);");
92	    //Unsupported: $c("WData w[3] = {0x12, 0x5678_9123, 0x1245_2352}; publicSetWide(w);");
93	 end
94	 if (cyc==12) begin
95	    $c("this->got_bool = this->publicGetSetBool(true);");
96	    $c("this->got_long = this->publicGetSetLong(0x11bca);");
97	    $c("this->got_quad = this->publicGetSetQuad(0xaaaabbbbccccULL);");
98	 end
99	 if (cyc==13) begin
100	    $c("{ bool gb; this->publicGetBool(gb); this->got_bool=gb; }");
101	    if (1'b1 != got_bool) $stop;
102	    $c("this->publicGetLong(this->got_long);");
103	    if (24'h11bca != got_long) $stop;
104	    $c("{ vluint64_t qq; this->publicGetQuad(qq); this->got_quad=qq; }");
105	    if (60'haaaa_bbbb_cccc != got_quad) $stop;
106	    $c("{ WData gw[3]; this->publicGetWide(gw); VL_ASSIGN_W(72,this->got_wide,gw); }");
107	    if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop;
108	    //Below doesn't work, because we're calling it inside the loop that sets var_flop
109	    // if (12'h321 != var_flop) $stop;
110	 end
111	 if (cyc==14) begin
112	    if ($c32("this->publicInstNum()") != i) $stop;
113	 end
114`endif
115      end
116   end
117
118   task publicEmpty;
119      // verilator public
120      begin end
121   endtask
122
123   task publicNoArgs;
124      // verilator public
125      $write("Hello in publicNoArgs\n");
126   endtask
127
128   task publicSetBool;
129      // verilator public
130      input in_bool;
131      var_bool = in_bool;
132   endtask
133
134   task publicSetLong;
135      // verilator public
136      input [23:0] in_long;
137      reg [23:0]   not_long;
138      begin
139	 not_long = ~in_long;	// Test that we can have local variables
140	 var_long = ~not_long;
141      end
142   endtask
143
144   task publicSetQuad;
145      // verilator public
146      input [59:0] in_quad;
147      var_quad = in_quad;
148   endtask
149
150   task publicSetFlop;
151      // verilator public
152      input [11:0] in_flop;
153      var_flop = in_flop;
154   endtask
155
156   task publicSetWide;
157      // verilator public
158      input [71:0] in_wide;
159      var_wide = in_wide;
160   endtask
161
162   task publicGetBool;
163      // verilator public
164      output out_bool;
165      out_bool = var_bool;
166   endtask
167
168   task publicGetLong;
169      // verilator public
170      output [23:0] out_long;
171      out_long = var_long;
172   endtask
173
174   task publicGetQuad;
175      // verilator public
176      output [59:0] out_quad;
177      out_quad = var_quad;
178   endtask
179
180   task publicGetWide;
181      // verilator public
182      output [71:0] out_wide;
183      out_wide = var_wide;
184   endtask
185
186   function publicGetSetBool;
187      // verilator public
188      input in_bool;
189      begin
190	 publicGetSetBool = var_bool;
191	 var_bool = in_bool;
192      end
193   endfunction
194
195   function [23:0] publicGetSetLong;
196      // verilator public
197      input [23:0] in_long;
198      begin
199	 publicGetSetLong = var_long;
200	 var_long = in_long;
201      end
202   endfunction
203
204   function [59:0] publicGetSetQuad;
205      // verilator public
206      input [59:0] in_quad;
207      begin
208	 publicGetSetQuad = var_quad;
209	 var_quad = in_quad;
210      end
211   endfunction
212
213   function [71:0] publicGetSetWide;
214      // Can't be public, as no wide return types in C++
215      input [71:0] in_wide;
216      begin
217	 publicGetSetWide = var_wide;
218	 var_wide = in_wide;
219      end
220   endfunction
221
222`ifdef VERILATOR_PUBLIC_TASKS
223   function [31:0] publicInstNum;
224      // verilator public
225      publicInstNum = i;
226   endfunction
227`endif
228
229endmodule
230