All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
These were realy headaches but the testbenches are passing. We need to take a look at the audio_buffer testbench for sure, it is way wrong and needs reworked to use the interface. Should do a pass through every module probably.
141 lines
4.2 KiB
Systemverilog
141 lines
4.2 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 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][7:0]);
|
|
write_byte(test_memory[start+i][15:8]);
|
|
end
|
|
// Simulate randomized crc bits and stop bit
|
|
repeat (16) @(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;
|
|
for (int i = 0; i < 256; i++) begin
|
|
write_byte(start[7:0]);
|
|
write_byte(start[15:8]);
|
|
start = start+1;
|
|
end
|
|
// Simulate crc bits and stop bit
|
|
repeat (17) @(posedge sd_clk) sd_data=1;
|
|
endtask
|
|
task automatic write_byte(logic [7:0] b);
|
|
for (int i=0; i<8; i++)
|
|
@(posedge sd_clk) sd_data=b[7-i];
|
|
endtask
|
|
|
|
endmodule
|