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;
8   reg [2:0] value;
9   reg [31:0] rglobal;
10   reg [31:0] vec [1:0];
11   reg [31:0] n;
12
13   initial begin
14      rglobal = 1;
15      value = 2;
16      if (add(value) != 3'd3) $stop;
17      if (rglobal != 2) $stop;
18      if (add(add(3'd1)) != 3'd3) $stop;
19      if (rglobal != 4) $stop;
20      if (munge4(4'b0010) != 4'b1011) $stop;
21      if (toint(2) != 3) $stop;
22      if (rglobal != 5) $stop;
23      setit;
24      incr(rglobal,rglobal,32'h10);
25      if (rglobal != 32'h17) $stop;
26      nop(32'h11);
27      empty;
28      empty();
29
30      rglobal = 32'h00000001;
31      flipupperbit(rglobal,4'd4);
32      flipupperbit(rglobal,4'd12);
33      if (rglobal !== 32'h10100001) $stop;
34
35      if (nil_func(32'h12,32'h12) != 32'h24) $stop;
36      nil_task(32'h012,32'h112,rglobal);
37      if (rglobal !== 32'h124) $stop;
38
39      vec[0] = 32'h333;
40      vec[1] = 32'habc;
41      incr(vec[1],vec[0],vec[1]);
42      if (vec[0] != 32'h333) $stop;
43      if (vec[1] != 32'hdef) $stop;
44
45      // verilator lint_off SELRANGE
46      incr(vec[2],vec[0],vec[2]);  // Reading/Writing past end of vector!
47      // verilator lint_on SELRANGE
48
49      n=1;
50      nil();
51      if (n !== 10) $stop;
52
53      // Functions called as tasks
54      // verilator lint_off IGNOREDRETURN
55      rglobal = 32'h4;
56      if (inc_and_return(32'h2) != 32'h6) $stop;
57      if (rglobal !== 32'h6) $stop;
58      rglobal = 32'h6;
59
60      inc_and_return(32'h3);
61      if (rglobal !== 32'h9) $stop;
62      // verilator lint_on IGNOREDRETURN
63
64      $write("*-* All Finished *-*\n");
65      $finish;
66   end
67
68   function [2:0] add;
69      input [2:0] fromv;
70      begin
71	 add = fromv + 3'd1;
72	 begin : named
73	    reg [31:0] flocal;
74	    flocal = 1;
75	    rglobal = rglobal + flocal;
76	 end : named	// SystemVerilog end labels
77      end
78   endfunction
79
80   function [3:0] munge4;
81      input [3:0] fromv; // Different fromv than the 'fromv' signal above
82      reg one;
83      begin : named
84	 reg [1:0] flocal;
85	 // Function calling a function
86	 one = 1'b1;
87	 munge4 = {one, add(fromv[2:0])};
88      end
89   endfunction
90
91   task setit;
92      reg [31:0] temp;
93      begin
94	 temp = rglobal + 32'h1;
95	 rglobal = temp + 32'h1;
96      end
97   endtask
98
99   task incr (
100	      // Check a V2K style input/output list
101    output [31:0] z,
102    input [31:0]  a, inc
103	      );
104      z = a + inc;
105   endtask
106
107   task nop;
108      input  [31:0] a;
109      begin
110      end
111   endtask
112
113   task empty;
114   endtask
115
116   task flipupperbit;
117      inout [31:0] vector;
118      input [3:0] bitnum;
119      reg [4:0]   bitnum2;
120      begin
121	 bitnum2 = {1'b1, bitnum};	// A little math to test constant propagation
122	 vector[bitnum2] = vector[bitnum2] ^ 1'b1;
123      end
124   endtask
125
126   task nil_task;
127      input [31:0] a;
128      input [31:0] b;
129      output [31:0] q;
130      // verilator no_inline_task
131      q = nil_func(a, b);
132   endtask
133
134   function void nil;
135      n = 10;
136   endfunction
137
138   function [31:0] nil_func;
139      input [31:0] fa;
140      input [31:0] fb;
141      // verilator no_inline_task
142      nil_func = fa + fb;
143   endfunction
144
145   function integer toint;
146      input integer fa;
147      toint = fa + 32'h1;
148   endfunction
149
150   function [31:0] inc_and_return;
151      input [31:0] inc;
152      rglobal = rglobal + inc;
153      return rglobal;
154   endfunction
155
156endmodule
157