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, 2020 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   // Take CRC data and apply to testblock inputs
18   wire [31:0] in = crc[31:0];
19
20   /*AUTOWIRE*/
21   // Beginning of automatic wires (for undeclared instantiated-module outputs)
22   wire [31:0]          rd0;                    // From test of Test.v
23   wire [31:0]          rd1;                    // From test of Test.v
24   // End of automatics
25
26   wire                 rden0 = crc[0];
27   wire                 rden1 = crc[1];
28   wire [4:0]           raddr0 = crc[20:16];
29   wire [4:0]           raddr1 = crc[28:24];
30
31   Test test(/*AUTOINST*/
32             // Outputs
33             .rd0                       (rd0[31:0]),
34             .rd1                       (rd1[31:0]),
35             // Inputs
36             .clk                       (clk),
37             .raddr0                    (raddr0[4:0]),
38             .raddr1                    (raddr1[4:0]),
39             .rden0                     (rden0),
40             .rden1                     (rden1));
41
42   // Aggregate outputs into a single result vector
43   wire [63:0] result = {rd1, rd0};
44
45   // Test loop
46   always @ (posedge clk) begin
47`ifdef TEST_VERBOSE
48      $write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result);
49`endif
50      cyc <= cyc + 1;
51      crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]};
52      sum <= result ^ {sum[62:0], sum[63] ^ sum[2] ^ sum[0]};
53      if (cyc == 0) begin
54         // Setup
55         crc <= 64'h5aef0c8d_d70a4497;
56         sum <= '0;
57      end
58      else if (cyc < 10) begin
59         sum <= '0;
60      end
61      else if (cyc == 99) begin
62         $write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
63         if (crc !== 64'hc77bb9b3784ea091) $stop;
64         // What checksum will we end up with (above print should match)
65`define EXPECTED_SUM 64'hdc97b141ac5d6d7d
66         if (sum !== `EXPECTED_SUM) $stop;
67         $write("*-* All Finished *-*\n");
68         $finish;
69      end
70   end
71
72endmodule
73
74module Test(/*AUTOARG*/
75   // Outputs
76   rd0, rd1,
77   // Inputs
78   clk, raddr0, raddr1, rden0, rden1
79   );
80
81   input clk;
82   input [4:0]  raddr0;
83   input [4:0]  raddr1;
84   input        rden0;
85   input        rden1;
86
87   output reg [31:0] rd0;
88   output reg [31:0] rd1;
89
90   reg [31:0] gpr [31:1];
91
92   initial begin
93      for (int j=1; j<32; j++ )  begin
94         gpr[j] = {8'(j), 8'(j), 8'(j), 8'(j)};
95      end
96   end
97
98   always_comb begin
99      rd0[31:0] = 32'b0;
100      rd1[31:0] = 32'b0;
101      // Future optimization:
102      // Multiple assignments to same variable with OR between them
103      // ASSIGN(a, OR(a, aq)), ASSIGN(a, OR(a, bq)) -> ASSIGN(a, OR(a, OR(aq, bq))
104      // Skip if we're not const'ing an entire module (IE doing only one assign, etc)
105      for (int j=1; j<32; j++ )  begin
106         rd0[31:0] |= ({32{rden0 & (raddr0[4:0]== 5'(j))}} & gpr[j][31:0]);
107         rd1[31:0] |= ({32{rden1 & (raddr1[4:0]== 5'(j))}} & gpr[j][31:0]);
108      end
109   end
110
111endmodule
112