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, 2005 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7module t (clk);
8   input clk;
9
10   reg [0:0] d1;
11   reg [2:0] d3;
12   reg [7:0] d8;
13
14   wire [0:0] q1;
15   wire [2:0] q3;
16   wire [7:0] q8;
17
18   // verilator lint_off UNOPTFLAT
19   reg 	      ena;
20   // verilator lint_on  UNOPTFLAT
21
22   condff #(12) condff
23     (.clk(clk), .sen(1'b0), .ena(ena),
24      .d({d8,d3,d1}),
25      .q({q8,q3,q1}));
26
27   integer cyc; initial cyc=1;
28   always @ (posedge clk) begin
29      if (cyc!=0) begin
30	 //$write("%x %x %x %x\n", cyc, q8, q3, q1);
31	 cyc <= cyc + 1;
32	 if (cyc==1) begin
33	    d1 <= 1'b1; d3<=3'h1; d8<=8'h11;
34	    ena <= 1'b1;
35	 end
36	 if (cyc==2) begin
37	    d1 <= 1'b0; d3<=3'h2; d8<=8'h33;
38	    ena <= 1'b0;
39	 end
40	 if (cyc==3) begin
41	    d1 <= 1'b1; d3<=3'h3; d8<=8'h44;
42	    ena <= 1'b1;
43	    if (q8 != 8'h11) $stop;
44	 end
45	 if (cyc==4) begin
46	    d1 <= 1'b1; d3<=3'h4; d8<=8'h77;
47	    ena <= 1'b1;
48	    if (q8 != 8'h11) $stop;
49	 end
50	 if (cyc==5) begin
51	    d1 <= 1'b1; d3<=3'h0; d8<=8'h88;
52	    ena <= 1'b1;
53	    if (q8 != 8'h44) $stop;
54	 end
55	 if (cyc==6) begin
56	    if (q8 != 8'h77) $stop;
57	 end
58	 if (cyc==7) begin
59	    if (q8 != 8'h88) $stop;
60	 end
61	 //
62	 if (cyc==20) begin
63	    $write("*-* All Finished *-*\n");
64	    $finish;
65	 end
66      end
67   end
68endmodule
69
70module condff (clk, sen, ena, d, q);
71   parameter WIDTH = 1;
72   input     clk;
73
74   input     sen;
75   input     ena;
76   input [WIDTH-1:0] d;
77   output [WIDTH-1:0] q;
78
79   condffimp #(.WIDTH(WIDTH))
80     imp (.clk(clk), .sen(sen), .ena(ena), .d(d), .q(q));
81endmodule
82
83module condffimp (clk, sen, ena, d, q);
84   parameter WIDTH = 1;
85   input     clk;
86   input     sen;
87   input     ena;
88   input [WIDTH-1:0] d;
89   output reg [WIDTH-1:0] q;
90   wire   gatedclk;
91
92   clockgate clockgate (.clk(clk), .sen(sen), .ena(ena), .gatedclk(gatedclk));
93
94   always @(posedge gatedclk) begin
95      if (gatedclk === 1'bX) begin
96	 q <= {WIDTH{1'bX}};
97      end
98      else begin
99	 q <= d;
100      end
101   end
102
103endmodule
104
105module clockgate (clk, sen, ena, gatedclk);
106   input	clk;
107   input	sen;
108   input	ena;
109   output	gatedclk;
110
111   reg		ena_b;
112   wire gatedclk = clk & ena_b;
113
114   // verilator lint_off COMBDLY
115   // verilator lint_off LATCH
116   always @(clk or ena or sen) begin
117      if (~clk) begin
118        ena_b <= ena | sen;
119      end
120      else begin
121	 if ((clk^sen)===1'bX) ena_b <= 1'bX;
122      end
123   end
124   // verilator lint_on LATCH
125   // verilator lint_on COMBDLY
126
127endmodule
128