All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
The audio output is still messed up, but this commit gets everything as ready as it can get. Fixed up all the testbenches and added state machines for everything
145 lines
4.4 KiB
Systemverilog
145 lines
4.4 KiB
Systemverilog
`ifdef VERILATOR
|
|
`include "sdvd_defs.sv"
|
|
`endif
|
|
import sdvd_defs::SPEED;
|
|
|
|
module read_data_tb;
|
|
logic clk, sd_clk, reset;
|
|
|
|
// Control signals
|
|
logic play, stop;
|
|
SPEED speed;
|
|
|
|
// Whether the audio buffer is currently playing
|
|
logic playing;
|
|
|
|
// A 16-bit audio sample to output
|
|
logic [15:0] sample;
|
|
|
|
logic [3:0] sd_data;
|
|
|
|
audio_buffer_interface bufferInterface();
|
|
|
|
logic [10:0] counter;
|
|
|
|
logic [15:0] test_memory [1023:0];
|
|
audio_buffer audioDut(.driver(bufferInterface.receiver), .*);
|
|
read_data readerDut(sd_clk,reset,sd_data,bufferInterface.driver);
|
|
|
|
// The writer's clock should be much faster than the 48khz buffer clock
|
|
initial sd_clk = 0;
|
|
always #5 sd_clk = ~sd_clk;
|
|
|
|
|
|
// An order of magnitude difference is fine
|
|
initial clk = 0;
|
|
always #500 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 < 1024; counter++) begin
|
|
#1
|
|
assert ({5'b0, counter} === sample) else
|
|
$error("Invalid sample, expected 0x%x but found 0x%x",counter,sample);
|
|
@(posedge clk);
|
|
end
|
|
$display("Running randomized test");
|
|
counter = 0;
|
|
while(counter < 1024) begin
|
|
#1
|
|
assert (test_memory[counter[9:0]] === sample) else
|
|
$error("Invalid sample, expected 0x%x but found 0x%x at location 0x%x",test_memory[counter[9:0]],sample,counter);
|
|
@(posedge clk);
|
|
counter++;
|
|
end
|
|
|
|
end
|
|
// Writer
|
|
begin
|
|
for (int i=0; i<1024; i++)
|
|
test_memory[i]=$urandom;
|
|
// Wait til buffer is done resetting
|
|
@(posedge clk);
|
|
@(posedge clk);
|
|
// linear test
|
|
write_linear_sd(0);
|
|
write_linear_sd(256);
|
|
write_linear_sd(512);
|
|
write_linear_sd(256*3);
|
|
wait (bufferInterface.address_half==1);
|
|
// random test, write to lower half of memory
|
|
write_random_sd(0);
|
|
write_random_sd(256);
|
|
wait (bufferInterface.address_half==0);
|
|
// random test, write to upper half of memory
|
|
write_random_sd(512);
|
|
write_random_sd(256*3);
|
|
end
|
|
join
|
|
$finish;
|
|
end
|
|
task automatic write_random_sd(int start);
|
|
@(posedge sd_clk);
|
|
sd_data = '1;
|
|
// send start bit
|
|
@(posedge sd_clk);
|
|
// send 256 data bits
|
|
sd_data = 0;
|
|
for (int i = 0; i < 256; i++) begin
|
|
write_byte(test_memory[start-i-1][7:0]);
|
|
write_byte(test_memory[start-i-1][15:8]);
|
|
end
|
|
// Simulate randomized crc bits and stop bit
|
|
repeat (16*4) @(posedge sd_clk) sd_data=$urandom;
|
|
@(posedge sd_clk) sd_data='1;
|
|
endtask
|
|
task automatic write_linear_sd(int start);
|
|
@(posedge sd_clk);
|
|
sd_data = '1;
|
|
// send start bit
|
|
@(posedge sd_clk);
|
|
// send 256 data bits
|
|
sd_data = 0;
|
|
start += 256;
|
|
for (int i = 0; i < 256; i++) begin
|
|
// NOTE: These are in the wrong order??
|
|
// One of the weird cases where simulation is different
|
|
// than hardware
|
|
write_byte(start[7:0]);
|
|
write_byte(start[15:8]);
|
|
start = start-1;
|
|
end
|
|
// Simulate crc bits and stop bit
|
|
repeat (16*4+1) @(posedge sd_clk) sd_data='1;
|
|
endtask
|
|
task automatic write_byte(logic [7:0] b);
|
|
@(posedge sd_clk) sd_data=b[7:4];
|
|
@(posedge sd_clk) sd_data=b[3:0];
|
|
endtask
|
|
|
|
endmodule
|