1// DESCRIPTION: Verilator: Verilog Test module 2// This file ONLY is placed into the Public Domain, for any use, 3// without warranty, 2019 by Todd Strader. 4// SPDX-License-Identifier: CC0-1.0 5 6`define DRIVE(sig) \ 7/* Just throw a bunch of bits at the input */ \ 8/* verilator lint_off WIDTH */ \ 9sig``_in <= {8{crc}}; \ 10/* verilator lint_on WIDTH */ 11`define CHECK(sig) \ 12if (cyc > 0 && sig``_in != sig``_out) begin \ 13 $display(`"%%Error (%m) sig``_in (0x%0x) != sig``_out (0x%0x)`", \ 14 sig``_in, sig``_out); \ 15 $stop; \ 16 end 17 18module t #(parameter GATED_CLK = 0) (/*AUTOARG*/ 19 // Inputs 20 clk 21 ); 22 input clk; 23 24 localparam last_cyc = 25`ifdef TEST_BENCHMARK 26 `TEST_BENCHMARK; 27`else 28 10; 29`endif 30 31 genvar x; 32 generate 33 for (x = 0; x < 2; x = x + 1) begin: gen_loop 34 integer cyc = 0; 35 reg [63:0] crc = 64'h5aef0c8d_d70a4497; 36 logic [31:0] accum_in; 37 logic [31:0] accum_out; 38 logic accum_bypass; 39 logic [31:0] accum_bypass_out; 40 logic [31:0] accum_out_expect; 41 logic [31:0] accum_bypass_out_expect; 42 logic s1_in; 43 logic s1_out; 44 logic s1up_in[2]; 45 logic s1up_out[2]; 46 logic [1:0] s2_in; 47 logic [1:0] s2_out; 48 logic [7:0] s8_in; 49 logic [7:0] s8_out; 50 logic [32:0] s33_in; 51 logic [32:0] s33_out; 52 logic [63:0] s64_in; 53 logic [63:0] s64_out; 54 logic [64:0] s65_in; 55 logic [64:0] s65_out; 56 logic [128:0] s129_in; 57 logic [128:0] s129_out; 58 logic [3:0] [31:0] s4x32_in; 59 logic [3:0] [31:0] s4x32_out; 60 /*verilator lint_off LITENDIAN*/ 61 logic [0:15] s6x16up_in[0:1][2:0]; 62 logic [0:15] s6x16up_out[0:1][2:0]; 63 /*verilator lint_on LITENDIAN*/ 64 logic [15:0] s8x16up_in[1:0][0:3]; 65 logic [15:0] s8x16up_out[1:0][0:3]; 66 logic [15:0] s8x16up_3d_in[1:0][0:1][0:1]; 67 logic [15:0] s8x16up_3d_out[1:0][0:1][0:1]; 68 69 wire clk_en = crc[0]; 70 71 secret 72 secret ( 73 .accum_in, 74 .accum_out, 75 .accum_bypass, 76 .accum_bypass_out, 77 .s1_in, 78 .s1_out, 79 .s1up_in, 80 .s1up_out, 81 .s2_in, 82 .s2_out, 83 .s8_in, 84 .s8_out, 85 .s33_in, 86 .s33_out, 87 .s64_in, 88 .s64_out, 89 .s65_in, 90 .s65_out, 91 .s129_in, 92 .s129_out, 93 .s4x32_in, 94 .s4x32_out, 95 .s6x16up_in, 96 .s6x16up_out, 97 .s8x16up_in, 98 .s8x16up_out, 99 .s8x16up_3d_in, 100 .s8x16up_3d_out, 101 .clk_en, 102 .clk); 103 104 always @(posedge clk) begin 105`ifdef TEST_VERBOSE 106 $display("[%0t] x=%0d, cyc=%0d accum_in=%0d accum_out=%0d accum_bypass_out=%0d", 107 $time, x, cyc, accum_in, accum_out, accum_bypass_out); 108`endif 109 cyc <= cyc + 1; 110 crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; 111 accum_in <= accum_in + 5; 112 `DRIVE(s1) 113 `DRIVE(s2) 114 `DRIVE(s8) 115 `DRIVE(s33) 116 `DRIVE(s64) 117 `DRIVE(s65) 118 `DRIVE(s129) 119 `DRIVE(s4x32) 120 {s1up_in[1], s1up_in[0]} <= {^crc, ~(^crc)}; 121 {s6x16up_in[0][0], s6x16up_in[0][1], s6x16up_in[0][2]} <= crc[47:0]; 122 {s6x16up_in[1][0], s6x16up_in[1][1], s6x16up_in[1][2]} <= ~crc[63:16]; 123 {s8x16up_in[0][0], s8x16up_in[0][1], s8x16up_in[0][2], s8x16up_in[0][3]} <= crc; 124 {s8x16up_in[1][0], s8x16up_in[1][1], s8x16up_in[1][2], s8x16up_in[1][3]} <= ~crc; 125 {s8x16up_3d_in[0][0][0], s8x16up_3d_in[0][0][1]} <= ~crc[31:0]; 126 {s8x16up_3d_in[0][1][0], s8x16up_3d_in[0][1][1]} <= ~crc[63:32]; 127 {s8x16up_3d_in[1][0][0], s8x16up_3d_in[1][0][1]} <= crc[31:0]; 128 {s8x16up_3d_in[1][1][0], s8x16up_3d_in[1][1][1]} <= crc[63:32]; 129 if (cyc == 0) begin 130 accum_in <= x*100; 131 accum_bypass <= '0; 132 end else if (cyc > 0) begin 133 if (accum_out_expect != accum_out) begin 134 $display("%%Error: (%m) accum_out expected %0d got %0d", 135 accum_out_expect, accum_out); 136 $stop; 137 end 138 if (accum_bypass_out_expect != accum_bypass_out) begin 139 $display("%%Error: (%m) accum_bypass_out expected %0d got %0d", 140 accum_bypass_out_expect, accum_bypass_out); 141 $stop; 142 end 143 end 144 145 if (cyc == 5) accum_bypass <= '1; 146 147 if (x == 0 && cyc == last_cyc) begin 148 $display("final cycle = %0d", cyc); 149 $write("*-* All Finished *-*\n"); 150 $finish; 151 end 152 end 153 154 logic possibly_gated_clk; 155 if (GATED_CLK != 0) begin: yes_gated_clock 156 logic clk_en_latch /*verilator clock_enable*/; 157 /* verilator lint_off COMBDLY */ 158 /* verilator lint_off LATCH */ 159 always_comb if (clk == '0) clk_en_latch <= clk_en; 160 /* verilator lint_on LATCH */ 161 /* verilator lint_on COMBDLY */ 162 assign possibly_gated_clk = clk & clk_en_latch; 163 end else begin: no_gated_clock 164 assign possibly_gated_clk = clk; 165 end 166 167 always @(posedge possibly_gated_clk) begin 168 // 7 is the secret_value inside the secret module 169 accum_out_expect <= accum_in + accum_out_expect + 7; 170 end 171 172 always @(*) begin 173 // XSim (and maybe all event simulators?) sees the moment where 174 // s1_in has not yet propagated to s1_out, however, they do always 175 // both change at the same time 176 /* verilator lint_off STMTDLY */ 177 #1; 178 /* verilator lint_on STMTDLY */ 179 `CHECK(s1) 180 `CHECK(s1up) 181 `CHECK(s2) 182 `CHECK(s8) 183 `CHECK(s33) 184 `CHECK(s64) 185 `CHECK(s65) 186 `CHECK(s129) 187 `CHECK(s4x32) 188 `CHECK(s6x16up) 189 `CHECK(s8x16up) 190 `CHECK(s8x16up_3d) 191 end 192 193 assign accum_bypass_out_expect = accum_bypass ? accum_in : 194 accum_out_expect; 195 end 196 endgenerate 197 198endmodule 199