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 (/*AUTOARG*/
8   // Inputs
9   clk
10   );
11   input clk;
12
13   // verilator lint_off COMBDLY
14   // verilator lint_off LATCH
15   // verilator lint_off UNOPT
16   // verilator lint_off UNOPTFLAT
17   // verilator lint_off BLKANDNBLK
18
19   reg         c1_start; initial c1_start = 0;
20   wire [31:0] c1_count;
21   comb_loop c1 (.count(c1_count), .start(c1_start));
22
23   wire        s2_start = c1_start;
24   wire [31:0] s2_count;
25   seq_loop  s2 (.count(s2_count), .start(s2_start));
26
27   wire        c3_start = (s2_count[0]);
28   wire [31:0] c3_count;
29   comb_loop c3 (.count(c3_count), .start(c3_start));
30
31   reg [7:0] cyc; initial cyc = 0;
32   always @ (posedge clk) begin
33      //$write("[%0t] %x  counts %x %x %x\n", $time,cyc,c1_count,s2_count,c3_count);
34      cyc <= cyc + 8'd1;
35      case (cyc)
36        8'd00: begin
37           c1_start <= 1'b0;
38        end
39        8'd01: begin
40           c1_start <= 1'b1;
41        end
42        default: ;
43      endcase
44      case (cyc)
45        8'd02: begin
46           // On Verilator, we expect these comparisons to match exactly,
47           // confirming that our settle loop repeated the exact number of
48           // iterations we expect. No '$stop' should be called here, and we
49           // should reach the normal '$finish' below on the next cycle.
50           if (c1_count!=32'h3) $stop;
51           if (s2_count!=32'h3) $stop;
52           if (c3_count!=32'h5) $stop;
53        end
54        8'd03: begin
55           $write("*-* All Finished *-*\n");
56           $finish;
57        end
58        default: ;
59      endcase
60   end
61endmodule
62
63module comb_loop (/*AUTOARG*/
64   // Outputs
65   count,
66   // Inputs
67   start
68   );
69   input start;
70   output reg [31:0] count; initial count = 0;
71
72   reg [31:0]    runnerm1, runner; initial runner = 0;
73
74   always @ (posedge start) begin
75      runner = 3;
76   end
77
78   always @ (/*AS*/runner) begin
79      runnerm1 = runner - 32'd1;
80   end
81
82   always @ (/*AS*/runnerm1) begin
83      if (runner > 0) begin
84         count = count + 1;
85         runner = runnerm1;
86         $write ("%m count=%d  runner =%x\n",count, runnerm1);
87      end
88   end
89
90endmodule
91
92module seq_loop (/*AUTOARG*/
93   // Outputs
94   count,
95   // Inputs
96   start
97   );
98   input start;
99   output reg [31:0] count; initial count = 0;
100
101   reg [31:0]    runnerm1, runner; initial runner = 0;
102
103   always @ (posedge start) begin
104      runner <= 3;
105   end
106
107   always @ (/*AS*/runner) begin
108      runnerm1 = runner - 32'd1;
109   end
110
111   always @ (/*AS*/runnerm1) begin
112      if (runner > 0) begin
113         count = count + 1;
114         runner <= runnerm1;
115         $write ("%m count=%d  runner<=%x\n",count, runnerm1);
116      end
117   end
118
119endmodule
120