I moved around where packages are. I couldn't find any evidence of where other people put them, but for now they are in the `lib/` folder. Other infrastructure changes are that all the weird includes we need to make the linter happy are gated behind ifdefs, so they don't mess with vivado. I kinda can't believe concurrent assertions work because there's so little info about them, good to ssee they actually do something
125 lines
3.6 KiB
Systemverilog
125 lines
3.6 KiB
Systemverilog
`ifdef VERILATOR
|
|
`include "sdvd_defs.sv"
|
|
`endif
|
|
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
|