Added modules to read sdcard data and cmd response
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.
This commit is contained in:
2025-06-07 21:57:17 -07:00
parent e32563131f
commit 71eecd18e8
8 changed files with 662 additions and 4 deletions
+81
View File
@@ -0,0 +1,81 @@
module read_command_tb;
bit clk;
logic reset;
logic listen;
logic [2:0] response_type;
logic sd_cmd;
wire received;
wire [135:0] out_data;
read_command dut (.*);
initial forever #10 clk = ~clk;
initial begin
$display("Testing read_command module");
sd_cmd = 1;
response_type = 0;
reset = 1;
listen = 0;
repeat (2) @(posedge clk);
reset = 0;
listen = 1;
response_type = 2;
@(posedge clk);
listen = 0;
response_type = 0;
repeat (5) @(posedge clk);
send_byte('h01);
for (int i=0; i<15; i++)
send_byte('hAA);
send_byte('h01);
@(posedge clk);
// NOTE: the received signal takes an extra cycle to propogate because
// it is loaded into a register
@(posedge clk);
#1;
assert (received === 1)
else $error("received signal not high");
assert (out_data === 'h01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01)
else $error("out_dat incorrect, found 0x%x but expected 0x01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01",out_data);
repeat (7) @(posedge clk);
listen = 1;
response_type = 3;
@(posedge clk);
listen = 0;
response_type = 0;
send_byte('h00);
send_byte('hAB);
send_byte('hCD);
send_byte('hEF);
send_byte('h12);
send_byte('h01);
// Return sd_cmd to inactive state
@(posedge clk) sd_cmd = 1;
@(posedge clk);
#1;
assert (received === 1)
else $error("received signal not high");
assert (out_data === 136'h00ABCDEF1201)
else $error("out_dat incorrect, found %b but expected 0x00ABCDEF1201",out_data);
@(posedge clk);
$finish;
end
task automatic send_byte(logic [7:0] b);
for (int i = 8; i != 0; i--) begin
@(posedge clk) sd_cmd = b[i-1];
end
endtask
endmodule
+140
View File
@@ -0,0 +1,140 @@
`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