`timescale 1ns/1ns `define CLK_PERIOD 8 module cache_tb(); localparam ADDR_WIDTH = 30; localparam DATA_WIDTH = 8; localparam LINES = 8; reg clk = 0; always #(`CLK_PERIOD/2) clk = ~clk; reg rst; reg [ADDR_WIDTH-1:0] ra0; reg [ADDR_WIDTH-1:0] ra1; reg [DATA_WIDTH-1:0] dout0; reg [DATA_WIDTH-1:0] dout1; reg hit0; reg hit1; reg [ADDR_WIDTH-1:0] wa; reg [DATA_WIDTH-1:0] din; reg we; bp_cache #( .AWIDTH(ADDR_WIDTH), .DWIDTH(DATA_WIDTH), .LINES(LINES) ) cache ( .clk(clk), .reset(rst), .ra0(ra0), .ra1(ra1), .wa(wa), .din(din), .we(we), .hit0(hit0), .dout0(dout0), .hit1(hit1), .dout1(dout1) ); initial begin `ifndef IVERILOG $vcdpluson; `endif `ifdef IVERILOG $dumpfile("cache_tb.fst"); $dumpvars(0, cache_tb); `endif rst = 1; @(posedge clk); #1; rst = 0; repeat (5) @(negedge clk); // Test read0, compulsory miss ra0 = 30'b0; ra1 = 30'b1; wa = 30'b0; din = 2'b0; we = 1'b0; #(2*`CLK_PERIOD) assert(hit0 == 0) else $display("ERROR: %d", hit0); // Test read1, compulsory miss ra0 = 1; ra1 = 0; wa = 0; din = 0; we = 0; #(2*`CLK_PERIOD) assert(hit1 == 0) else $display("ERROR: %d", hit1); // Test write, read at the same time ra0 = 0; ra1 = 1; wa = 0; din = 1; we = 1; #(4*`CLK_PERIOD) assert(dout0 == 1) else $display("ERROR: %d", dout0); assert(hit0 == 1) else $display("ERROR: %d", hit0); assert(hit1 == 0) else $display("ERROR: %d", hit1); // test read miss and hit on 0 and 1 ra0 = 1; ra1 = 0; wa = 0; din = 0; we = 0; #(2*`CLK_PERIOD) assert(dout1 == 1) else $display("ERROR: %d", dout1); assert(hit0 == 0) else $display("ERROR: %d", hit0); assert(hit1 == 1) else $display("ERROR: %d", hit1); // test cache invalidation rst = 1; @(posedge clk); #1; rst = 0; ra0 = 0; ra1 = 1; wa = 0; din = 0; we = 0; #(2*`CLK_PERIOD) assert(hit0 == 0) else $display("ERROR: %d", hit0); assert(hit1 == 0) else $display("ERROR: %d", hit1); // test cache same index, different tag ra0 = 0; ra1 = 0; wa = 0'b00000000000000000000000000001111; din = 2; we = 1; #(2*`CLK_PERIOD) assert(hit0 == 0) else $display("ERROR: %d", hit0); assert(hit1 == 0) else $display("ERROR: %d", hit1); // same index (111) and different tag (0) ra0 = 0'b00000000000000000000000000000111; ra1 = 0; wa = 0; din = 0; we = 0; #(2*`CLK_PERIOD) assert(hit0 == 0) else $display("ERROR: %d", hit0); // should not hit assert(hit1 == 0) else $display("ERROR: %d", hit1); // same index (111) and different tag (0) ra0 = 0; ra1 = 0'b00000000000000000000000000000111; wa = 0; din = 0; we = 0; #(2*`CLK_PERIOD) assert(hit0 == 0) else $display("ERROR: %d", hit0); // should not hit assert(hit1 == 0) else $display("ERROR: %d", hit1); $display("PASSED!"); $finish(); end endmodule