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   integer 	cyc = 0;
13
14   reg [7:0] crc;
15   genvar g;
16
17   wire [7:0] 	out_p1;
18   wire [15:0] 	out_p2;
19   wire [7:0] 	out_p3;
20   wire [7:0] 	out_p4;
21
22   paramed #(.WIDTH(8),  .MODE(0)) p1 (.in(crc), .out(out_p1));
23   paramed #(.WIDTH(16), .MODE(1)) p2 (.in({crc,crc}), .out(out_p2));
24   paramed #(.WIDTH(8),  .MODE(2)) p3 (.in(crc), .out(out_p3));
25   gencase #(.MODE(3))  	   p4 (.in(crc), .out(out_p4));
26
27   wire [7:0] 	out_ef;
28   enflop  #(.WIDTH(8))            enf (.a(crc), .q(out_ef), .oe_e1(1'b1), .clk(clk));
29
30   always @ (posedge clk) begin
31      //$write("[%0t] cyc==%0d crc=%b %x %x %x %x %x\n", $time, cyc, crc, out_p1, out_p2, out_p3, out_p4, out_ef);
32      cyc <= cyc + 1;
33      crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}};
34      if (cyc==0) begin
35	 // Setup
36	 crc <= 8'hed;
37      end
38      else if (cyc==1) begin
39      end
40      else if (cyc==3) begin
41	 if (out_p1 !== 8'h2d) $stop;
42	 if (out_p2 !== 16'h2d2d) $stop;
43	 if (out_p3 !== 8'h78) $stop;
44	 if (out_p4 !== 8'h44) $stop;
45	 if (out_ef !== 8'hda) $stop;
46      end
47      else if (cyc==9) begin
48	 $write("*-* All Finished *-*\n");
49	 $finish;
50      end
51   end
52
53endmodule
54
55module gencase (/*AUTOARG*/
56   // Outputs
57   out,
58   // Inputs
59   in
60   );
61   parameter MODE = 0;
62   input [7:0] in;
63   output [7:0] out;
64   generate // : genblk1
65      begin
66	 case (MODE)
67	   2:       mbuf mc [7:0] (.q(out[7:0]), .a({in[5:0],in[7:6]}));
68	   default: mbuf mc [7:0] (.q(out[7:0]), .a({in[3:0],in[3:0]}));
69	 endcase
70      end
71   endgenerate
72
73endmodule
74
75module paramed (/*AUTOARG*/
76   // Outputs
77   out,
78   // Inputs
79   in
80   );
81   parameter WIDTH = 1;
82   parameter MODE = 0;
83   input [WIDTH-1:0] in;
84   output [WIDTH-1:0] out;
85
86   generate
87      if (MODE==0) initial $write("Mode=0\n");
88      // No else
89   endgenerate
90
91`ifndef NC  // for(genvar) unsupported
92 `ifndef ATSIM  // for(genvar) unsupported
93   generate
94      // Empty loop body, local genvar
95      for (genvar j=0; j<3; j=j+1) begin end
96      // Ditto to make sure j has new scope
97      for (genvar j=0; j<5; j=j+1) begin end
98   endgenerate
99 `endif
100`endif
101
102   generate
103   endgenerate
104
105   genvar 	      i;
106   generate
107      if (MODE==0) begin
108	 // Flip bitorder, direct assign method
109	 for (i=0; i<WIDTH; i=i+1) begin
110	    assign out[i] = in[WIDTH-i-1];
111	 end
112      end
113      else if (MODE==1) begin
114	 // Flip using instantiation
115	 for (i=0; i<WIDTH; i=i+1) begin
116	    integer from = WIDTH-i-1;
117	    if (i==0) begin	// Test if's within a for
118	       mbuf m0 (.q(out[i]), .a(in[from]));
119	    end
120	    else begin
121	       mbuf ma (.q(out[i]), .a(in[from]));
122	    end
123	 end
124      end
125      else begin
126	 for (i=0; i<WIDTH; i=i+1) begin
127	    mbuf ma (.q(out[i]), .a(in[i^1]));
128	 end
129      end
130   endgenerate
131
132endmodule
133
134module mbuf (
135	   input a,
136	   output q
137	   );
138   assign 	  q = a;
139endmodule
140
141module enflop (clk, oe_e1, a,q);
142   parameter WIDTH=1;
143
144   input     clk;
145   input     oe_e1;
146   input  [WIDTH-1:0] a;
147   output [WIDTH-1:0] q;
148
149   reg [WIDTH-1:0]    oe_r;
150   reg [WIDTH-1:0]    q_r;
151   genvar 	      i;
152
153   generate
154      for (i = 0; i < WIDTH; i = i + 1) begin : datapath_bits
155         enflop_one enflop_one
156	   (.clk        (clk),
157	    .d		(a[i]),
158	    .q_r	(q_r[i]));
159
160	 always @(posedge clk) oe_r[i] <= oe_e1;
161
162         assign q[i] = oe_r[i] ? q_r[i] : 1'bx;
163      end
164   endgenerate
165endmodule
166
167module enflop_one (
168		   input clk,
169		   input d,
170		   output reg q_r
171		   );
172   always @(posedge clk) q_r <= d;
173endmodule
174