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, 2018 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 reg rst; 17 18 // Two phases, random so nothing optimizes away, and focused so get hits 19 logic inval; 20 wire [30:0] wdat = (cyc < 50 ? crc[30:0] : {29'h0, crc[1:0]}); 21 wire [30:0] cdat = (cyc < 50 ? crc[30:0] : {29'h0, crc[1:0]}); 22 wire wdat_val = 1'b1; 23 wire camen = crc[32]; 24 wire ren = crc[33]; 25 wire wen = crc[34]; 26 wire [7:0] rwidx = (cyc < 50 ? crc[63:56] : {6'h0, crc[57:56]}); 27 28 /*AUTOWIRE*/ 29 // Beginning of automatic wires (for undeclared instantiated-module outputs) 30 logic hit_d2r; // From cam of cam.v 31 logic [7:0] hitidx_d1r; // From cam of cam.v 32 logic [255:0] hitvec_d1r; // From cam of cam.v 33 logic [30:0] rdat_d2r; // From cam of cam.v 34 logic rdat_val_d2r; // From cam of cam.v 35 // End of automatics 36 37 cam cam (/*AUTOINST*/ 38 // Outputs 39 .hitvec_d1r (hitvec_d1r[255:0]), 40 .hitidx_d1r (hitidx_d1r[7:0]), 41 .hit_d2r (hit_d2r), 42 .rdat_d2r (rdat_d2r[30:0]), 43 .rdat_val_d2r (rdat_val_d2r), 44 // Inputs 45 .clk (clk), 46 .rst (rst), 47 .camen (camen), 48 .inval (inval), 49 .cdat (cdat[30:0]), 50 .ren (ren), 51 .wen (wen), 52 .wdat (wdat[30:0]), 53 .wdat_val (wdat_val), 54 .rwidx (rwidx[7:0])); 55 56 // Aggregate outputs into a single result vector 57 wire [63:0] result = {hitvec_d1r[15:0], 15'h0, hit_d2r, rdat_val_d2r, rdat_d2r}; 58 59 // Test loop 60 always @ (posedge clk) begin 61`ifdef TEST_VERBOSE 62 $write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result); 63`endif 64 cyc <= cyc + 1; 65 crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; 66 sum <= result ^ {sum[62:0], sum[63] ^ sum[2] ^ sum[0]}; 67 if (cyc==0) begin 68 // Setup 69 crc <= 64'h5aef0c8d_d70a4497; 70 sum <= '0; 71 rst <= 1'b1; 72 end 73 else if (cyc<10) begin 74 sum <= '0; 75 rst <= 1'b0; 76 end 77 else if (cyc==70) begin 78 inval <= 1'b1; 79 end 80 else if (cyc==71) begin 81 inval <= 1'b0; 82 end 83 else if (cyc==99) begin 84 $write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum); 85 if (crc !== 64'hc77bb9b3784ea091) $stop; 86`define EXPECTED_SUM 64'h5182640870b07199 87 if (sum !== `EXPECTED_SUM) $stop; 88 $write("*-* All Finished *-*\n"); 89 $finish; 90 end 91 end 92 93endmodule 94 95module cam 96 ( 97 input clk, 98 input rst, 99 100 input camen, 101 input inval, 102 input [30:0] cdat, 103 output logic [255:0] hitvec_d1r, 104 output logic [7:0] hitidx_d1r, 105 output logic hit_d2r, 106 107 input ren, 108 input wen, 109 input [30:0] wdat, 110 input wdat_val, 111 input [7:0] rwidx, 112 output logic [30:0] rdat_d2r, 113 output logic rdat_val_d2r 114 ); 115 116 logic camen_d1r; 117 logic inval_d1r; 118 logic ren_d1r; 119 logic wen_d1r; 120 logic [7:0] rwidx_d1r; 121 logic [30:0] cdat_d1r; 122 logic [30:0] wdat_d1r; 123 logic wdat_val_d1r; 124 125 always_ff @(posedge clk) begin 126 camen_d1r <= camen; 127 inval_d1r <= inval; 128 ren_d1r <= ren; 129 wen_d1r <= wen; 130 131 cdat_d1r <= cdat; 132 rwidx_d1r <= rwidx; 133 wdat_d1r <= wdat; 134 wdat_val_d1r <= wdat_val; 135 end 136 137 typedef struct packed { 138 logic [30:0] data; 139 logic valid; 140 } entry_t; 141 entry_t [255:0] entries; 142 143 always_ff @(posedge clk) begin 144 if (camen_d1r) begin 145 for (int i = 0; i < 256; i = i + 1) begin 146 hitvec_d1r[i] <= entries[i].valid & (entries[i].data == cdat_d1r); 147 end 148 end 149 end 150 always_ff @(posedge clk) begin 151 hit_d2r <= | hitvec_d1r; 152 end 153 154 always_ff @(posedge clk) begin 155 if (rst) begin 156 for (int i = 0; i < 256; i = i + 1) begin 157 entries[i] <= '0; 158 end 159 end 160 else if (wen_d1r) begin 161 entries[rwidx_d1r] <= '{valid:wdat_val_d1r, data:wdat_d1r}; 162 end 163 else if (inval_d1r) begin 164 for (int i = 0; i < 256; i = i + 1) begin 165 entries[i] <= '{valid:'0, data:entries[i].data}; 166 end 167 end 168 end 169 170 always_ff @(posedge clk) begin 171 if (ren_d1r) begin 172 rdat_d2r <= entries[rwidx_d1r].data; 173 rdat_val_d2r <= entries[rwidx_d1r].valid; 174 end 175 end 176 177endmodule 178