// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2018 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; reg rst; // Two phases, random so nothing optimizes away, and focused so get hits logic inval; wire [30:0] wdat = (cyc < 50 ? crc[30:0] : {29'h0, crc[1:0]}); wire [30:0] cdat = (cyc < 50 ? crc[30:0] : {29'h0, crc[1:0]}); wire wdat_val = 1'b1; wire camen = crc[32]; wire ren = crc[33]; wire wen = crc[34]; wire [7:0] rwidx = (cyc < 50 ? crc[63:56] : {6'h0, crc[57:56]}); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic hit_d2r; // From cam of cam.v logic [7:0] hitidx_d1r; // From cam of cam.v logic [255:0] hitvec_d1r; // From cam of cam.v logic [30:0] rdat_d2r; // From cam of cam.v logic rdat_val_d2r; // From cam of cam.v // End of automatics cam cam (/*AUTOINST*/ // Outputs .hitvec_d1r (hitvec_d1r[255:0]), .hitidx_d1r (hitidx_d1r[7:0]), .hit_d2r (hit_d2r), .rdat_d2r (rdat_d2r[30:0]), .rdat_val_d2r (rdat_val_d2r), // Inputs .clk (clk), .rst (rst), .camen (camen), .inval (inval), .cdat (cdat[30:0]), .ren (ren), .wen (wen), .wdat (wdat[30:0]), .wdat_val (wdat_val), .rwidx (rwidx[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {hitvec_d1r[15:0], 15'h0, hit_d2r, rdat_val_d2r, rdat_d2r}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; rst <= 1'b1; end else if (cyc<10) begin sum <= '0; rst <= 1'b0; end else if (cyc==70) begin inval <= 1'b1; end else if (cyc==71) begin inval <= 1'b0; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'h5182640870b07199 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module cam ( input clk, input rst, input camen, input inval, input [30:0] cdat, output logic [255:0] hitvec_d1r, output logic [7:0] hitidx_d1r, output logic hit_d2r, input ren, input wen, input [30:0] wdat, input wdat_val, input [7:0] rwidx, output logic [30:0] rdat_d2r, output logic rdat_val_d2r ); logic [30:0] rdat_d2r; logic camen_d1r; logic inval_d1r; logic ren_d1r; logic wen_d1r; logic [7:0] rwidx_d1r; logic [30:0] cdat_d1r; logic [30:0] wdat_d1r; logic wdat_val_d1r; logic [30:0] wdat; always_ff @(posedge clk) begin camen_d1r <= camen; inval_d1r <= inval; ren_d1r <= ren; wen_d1r <= wen; cdat_d1r <= cdat; rwidx_d1r <= rwidx; wdat_d1r <= wdat; wdat_val_d1r <= wdat_val; end typedef struct packed { logic [30:0] data; logic valid; } entry_t; entry_t [255:0] entries; always_ff @(posedge clk) begin if (camen_d1r) begin for (int i = 0; i < 256; i = i + 1) begin hitvec_d1r[i] <= entries[i].valid & (entries[i].data == cdat_d1r); end end end always_ff @(posedge clk) begin hit_d2r <= | hitvec_d1r; end always_ff @(posedge clk) begin if (rst) begin for (int i = 0; i < 256; i = i + 1) begin entries[i] <= '0; end end else if (wen_d1r) begin entries[rwidx_d1r] <= '{valid:wdat_val_d1r, data:wdat_d1r}; end else if (inval_d1r) begin for (int i = 0; i < 256; i = i + 1) begin entries[i] <= '{valid:'0, data:entries[i].data}; end end end always_ff @(posedge clk) begin if (ren_d1r) begin rdat_d2r <= entries[rwidx_d1r].data; rdat_val_d2r <= entries[rwidx_d1r].valid; end end endmodule