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, 2010 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7interface counter_if;
8   logic [3:0] value;
9   logic       reset;
10   modport counter_mp (input reset, output value);
11   modport core_mp (output reset, input value);
12endinterface
13
14// Check can have inst module before top module
15module counter_ansi
16  (
17   input clkm,
18   counter_if c_data,
19   input logic [3:0] i_value
20   );
21
22   always @ (posedge clkm) begin
23      c_data.value <= c_data.reset ? i_value : c_data.value + 1;
24   end
25endmodule : counter_ansi
26
27module t (/*AUTOARG*/
28   // Inputs
29   clk
30   );
31
32   input clk;
33   integer cyc=1;
34
35   counter_if c1_data();
36   counter_if c2_data();
37   counter_if c3_data();
38   counter_if c4_data();
39
40   counter_ansi    c1 (.clkm(clk),
41		       .c_data(c1_data.counter_mp),
42		       .i_value(4'h1));
43`ifdef VERILATOR counter_ansi `else counter_nansi `endif
44   /**/            c2 (.clkm(clk),
45		       .c_data(c2_data.counter_mp),
46		       .i_value(4'h2));
47   counter_ansi_m  c3 (.clkm(clk),
48		       .c_data(c3_data),
49		       .i_value(4'h3));
50`ifdef VERILATOR counter_ansi_m `else counter_nansi_m `endif
51   /**/            c4 (.clkm(clk),
52		       .c_data(c4_data),
53		       .i_value(4'h4));
54
55   initial begin
56      c1_data.value = 4'h4;
57      c2_data.value = 4'h5;
58      c3_data.value = 4'h6;
59      c4_data.value = 4'h7;
60   end
61
62   always @ (posedge clk) begin
63      cyc <= cyc + 1;
64      if (cyc<2) begin
65	 c1_data.reset <= 1;
66	 c2_data.reset <= 1;
67	 c3_data.reset <= 1;
68	 c4_data.reset <= 1;
69      end
70      if (cyc==2) begin
71	 c1_data.reset <= 0;
72	 c2_data.reset <= 0;
73	 c3_data.reset <= 0;
74	 c4_data.reset <= 0;
75      end
76      if (cyc==20) begin
77	 $write("[%0t] cyc%0d: c1 %0x %0x  c2 %0x %0x  c3 %0x %0x  c4 %0x %0x\n", $time, cyc,
78		c1_data.value, c1_data.reset,
79		c2_data.value, c2_data.reset,
80		c3_data.value, c3_data.reset,
81		c4_data.value, c4_data.reset);
82	 if (c1_data.value != 2) $stop;
83	 if (c2_data.value != 3) $stop;
84	 if (c3_data.value != 4) $stop;
85	 if (c4_data.value != 5) $stop;
86	 $write("*-* All Finished *-*\n");
87	 $finish;
88      end
89   end
90endmodule
91
92`ifndef VERILATOR
93// non-ansi modports not seen in the wild yet.  Verilog-Perl needs parser improvement too.
94module counter_nansi
95  (clkm, c_data, i_value);
96
97   input clkm;
98   counter_if c_data;
99   input logic [3:0] i_value;
100
101   always @ (posedge clkm) begin
102      c_data.value <= c_data.reset ? i_value : c_data.value + 1;
103   end
104endmodule : counter_nansi
105`endif
106
107module counter_ansi_m
108  (
109   input clkm,
110   counter_if.counter_mp c_data,
111   input logic [3:0] i_value
112   );
113
114   always @ (posedge clkm) begin
115      c_data.value <= c_data.reset ? i_value : c_data.value + 1;
116   end
117endmodule : counter_ansi_m
118
119`ifndef VERILATOR
120// non-ansi modports not seen in the wild yet.  Verilog-Perl needs parser improvement too.
121module counter_nansi_m
122  (clkm, c_data, i_value);
123
124   input clkm;
125   counter_if.counter_mp c_data;
126   input logic [3:0] i_value;
127
128   always @ (posedge clkm) begin
129      c_data.value <= c_data.reset ? i_value : c_data.value + 1;
130   end
131endmodule : counter_nansi_m
132`endif
133