`include "sdvd_defs.sv" import sdvd_defs::SPEED; module audio_buffer_tb; logic clk, reset; // Control signals logic play, stop; SPEED speed; // Whether the current address being read from is in the upper or lower // half of the 2KiB buffer logic address_half; // Whether the audio buffer is currently playing logic playing; // A 16-bit audio sample to output logic [15:0] sample; // Inputs for the memory buffer logic [10:0] addra; logic [7:0] dina; logic clka, ena; logic [9:0] counter; logic [15:0] test_memory [1023:0]; audio_buffer dut(.*); // The writer's clock should be much faster than the 48khz buffer clock initial clka = 0; always #5 clka = ~clka; // An order of magnitude difference is fine initial clk = 0; always #50 clk = ~clk; // Reader initial begin `ifdef DEBUG $monitor("PLAYING: %b ADDR: 0x%x DATA: 0x%x WILLDELAY: %b", playing, dut.address, dut.doutb,dut.delay); `endif fork //Reader begin play = 0; stop = 0; clk = 0; reset = 0; speed = 1; @(posedge clk) reset = 1; @(posedge clk) reset = 0; play = 1; @(posedge clk) assert (playing == 1) else $error("Audio buffer not playing"); // Wait an extra clock cycle because of the blockmem delay @(posedge clk) // The most basic test we can do here is an incrementing counter, // where the stored sample is the same as the address $display("Running linear test"); for (counter = 0; counter != 1023; counter++) begin #1 assert ({6'b0, counter} === sample) else $error("Invalid sample, expected 0x%x but found 0x%x",counter,sample); @(posedge clk); end @(posedge clk); $display("Running randomized test"); for (counter = 0; counter != 1023; counter++) begin #1 assert (test_memory[counter] === sample) else $error("Invalid sample, expected 0x%x but found 0x%x",test_memory[counter],sample); @(posedge clk); end end // Writer begin ena = 1; for (int i = 0; i<= 1024; i++) begin addra = i*2; dina = i[7:0]; @(posedge clka) addra = i*2+1; dina = i[15:8]; @(posedge clka); end wait (address_half==1); // random test, write to lower half of memory for (int i = 0; i< 512; i++) begin addra = i*2; dina = $urandom; test_memory[i][7:0] = dina; @(posedge clka) addra = i*2+1; dina = $urandom; test_memory[i][15:8] = dina; @(posedge clka); end wait (address_half==0); // random test, write to upper half of memory for (int i = 512; i< 1024; i++) begin addra = i*2; dina = $urandom; test_memory[i][7:0] = dina; @(posedge clka) addra = i*2+1; dina = $urandom; test_memory[i][15:8] = dina; @(posedge clka); end end join $finish; end endmodule