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, 2008 by Wilson Snyder.
5// SPDX-License-Identifier: CC0-1.0
6
7module t (/*AUTOARG*/
8   // Inputs
9   clk
10   );
11   input clk;
12
13   integer 	cyc = 0;
14   reg [63:0] 	crc;
15   reg [63:0] 	sum;
16
17   wire [31:0]  inp = crc[31:0];
18   wire		reset = (cyc < 5);
19
20   /*AUTOWIRE*/
21   // Beginning of automatic wires (for undeclared instantiated-module outputs)
22   wire [31:0]		outp;			// From test of Test.v
23   // End of automatics
24
25   Test test (/*AUTOINST*/
26	      // Outputs
27	      .outp			(outp[31:0]),
28	      // Inputs
29	      .reset			(reset),
30	      .clk			(clk),
31	      .inp			(inp[31:0]));
32
33   // Aggregate outputs into a single result vector
34   wire [63:0] result = {32'h0, outp};
35
36   // What checksum will we end up with
37`define EXPECTED_SUM 64'ha7f0a34f9cf56ccb
38
39   // Test loop
40   always @ (posedge clk) begin
41`ifdef TEST_VERBOSE
42      $write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result);
43`endif
44      cyc <= cyc + 1;
45      crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]};
46      sum <= result ^ {sum[62:0], sum[63] ^ sum[2] ^ sum[0]};
47      if (cyc==0) begin
48	 // Setup
49	 crc <= 64'h5aef0c8d_d70a4497;
50      end
51      else if (cyc<10) begin
52	 sum <= 64'h0;
53      end
54      else if (cyc<90) begin
55      end
56      else if (cyc==99) begin
57	 $write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
58	 if (crc !== 64'hc77bb9b3784ea091) $stop;
59	 if (sum !== `EXPECTED_SUM) $stop;
60	 $write("*-* All Finished *-*\n");
61	 $finish;
62      end
63   end
64
65endmodule
66
67module Test (/*AUTOARG*/
68   // Outputs
69   outp,
70   // Inputs
71   reset, clk, inp
72   );
73
74   input		  reset;
75   input		  clk;
76   input [31:0] 	  inp;
77   output [31:0] 	  outp;
78
79   function [31:0] no_inline_function;
80      input [31:0] 	  var1;
81      input [31:0] 	  var2;
82      /*verilator no_inline_task*/
83      reg [31*2:0] 	  product1 ;
84      reg [31*2:0] 	  product2 ;
85      integer 		  i;
86      reg [31:0] 	  tmp;
87
88      begin
89	 product2 = {(31*2+1){1'b0}};
90
91	 for (i = 0; i < 32; i = i + 1)
92	   if (var2[i]) begin
93	      product1 = { {31*2+1-32{1'b0}}, var1} << i;
94	      product2 = product2 ^ product1;
95	   end
96	 no_inline_function = 0;
97
98	 for (i= 0; i < 31; i = i + 1 )
99	   no_inline_function[i+1] = no_inline_function[i] ^ product2[i] ^ var1[i];
100      end
101   endfunction
102
103   reg [31:0] outp;
104   reg [31:0] inp_d;
105
106   always @( posedge clk ) begin
107      if( reset ) begin
108	 outp <= 0;
109      end
110      else begin
111	 inp_d <= inp;
112	 outp <= no_inline_function(inp, inp_d);
113      end
114   end
115
116endmodule
117