Added modules to read sdcard data and cmd response
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
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.
This commit is contained in:
parent
e32563131f
commit
71eecd18e8
90
SDVD.xpr
90
SDVD.xpr
@ -45,7 +45,7 @@
|
||||
<Option Name="SimulatorGccVersionActiveHdl" Val="9.3.0"/>
|
||||
<Option Name="BoardPart" Val=""/>
|
||||
<Option Name="SourceMgmtMode" Val="DisplayOnly"/>
|
||||
<Option Name="ActiveSimSet" Val="send_command_tb"/>
|
||||
<Option Name="ActiveSimSet" Val="read_data_tb"/>
|
||||
<Option Name="DefaultLib" Val="xil_defaultlib"/>
|
||||
<Option Name="ProjectType" Val="Default"/>
|
||||
<Option Name="IPRepoPath" Val="$PPRDIR/../../../fpga/vivado-library"/>
|
||||
@ -61,7 +61,7 @@
|
||||
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
|
||||
<Option Name="EnableBDX" Val="FALSE"/>
|
||||
<Option Name="DSABoardId" Val="nexys-a7-100t"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="145"/>
|
||||
<Option Name="WTXSimLaunchSim" Val="201"/>
|
||||
<Option Name="WTModelSimLaunchSim" Val="0"/>
|
||||
<Option Name="WTQuestaLaunchSim" Val="0"/>
|
||||
<Option Name="WTIesLaunchSim" Val="0"/>
|
||||
@ -216,6 +216,20 @@
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/design/sd/read_command.sv">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/design/sd/read_data.sv">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="nexys_a7_top"/>
|
||||
@ -509,6 +523,70 @@
|
||||
<Option Name="xsim.simulate.runtime" Val="1s"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="read_command_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/read_command_tb" RelGenDir="$PGENDIR/read_command_tb">
|
||||
<File Path="$PPRDIR/verification/sd/read_command_tb.sv">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/verification/waveform_configs/read_command_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="read_command_tb"/>
|
||||
<Option Name="TopLib" Val="xil_defaultlib"/>
|
||||
<Option Name="TransportPathDelay" Val="0"/>
|
||||
<Option Name="TransportIntDelay" Val="0"/>
|
||||
<Option Name="SelectedSimModel" Val="rtl"/>
|
||||
<Option Name="PamDesignTestbench" Val=""/>
|
||||
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
|
||||
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
|
||||
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
|
||||
<Option Name="SrcSet" Val="sources_1"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/read_command_tb_behav.wcfg"/>
|
||||
<Option Name="CosimPdi" Val=""/>
|
||||
<Option Name="CosimPlatform" Val=""/>
|
||||
<Option Name="CosimElf" Val=""/>
|
||||
<Option Name="xsim.simulate.runtime" Val="1s"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
<FileSet Name="read_data_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/read_data_tb" RelGenDir="$PGENDIR/read_data_tb">
|
||||
<File Path="$PPRDIR/verification/sd/read_data_tb.sv">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="synthesis"/>
|
||||
<Attr Name="UsedIn" Val="implementation"/>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<File Path="$PPRDIR/verification/waveform_configs/read_data_tb_behav.wcfg">
|
||||
<FileInfo>
|
||||
<Attr Name="UsedIn" Val="simulation"/>
|
||||
</FileInfo>
|
||||
</File>
|
||||
<Config>
|
||||
<Option Name="DesignMode" Val="RTL"/>
|
||||
<Option Name="TopModule" Val="read_data_tb"/>
|
||||
<Option Name="TopLib" Val="xil_defaultlib"/>
|
||||
<Option Name="TransportPathDelay" Val="0"/>
|
||||
<Option Name="TransportIntDelay" Val="0"/>
|
||||
<Option Name="SelectedSimModel" Val="rtl"/>
|
||||
<Option Name="PamDesignTestbench" Val=""/>
|
||||
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
|
||||
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
|
||||
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
|
||||
<Option Name="SrcSet" Val="sources_1"/>
|
||||
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/read_data_tb_behav.wcfg"/>
|
||||
<Option Name="CosimPdi" Val=""/>
|
||||
<Option Name="CosimPlatform" Val=""/>
|
||||
<Option Name="CosimElf" Val=""/>
|
||||
<Option Name="xsim.simulate.runtime" Val="1s"/>
|
||||
</Config>
|
||||
</FileSet>
|
||||
</FileSets>
|
||||
<Simulators>
|
||||
<Simulator Name="XSim">
|
||||
@ -534,7 +612,9 @@
|
||||
<Runs Version="1" Minor="22">
|
||||
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" IncrementalCheckpoint="$PSRCDIR/utils_1/imports/synth_1/nexys_a7_top.dcp" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1" ParallelReportGen="true">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2024"/>
|
||||
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2024">
|
||||
<Desc>Vivado Synthesis Defaults</Desc>
|
||||
</StratHandle>
|
||||
<Step Id="synth_design"/>
|
||||
</Strategy>
|
||||
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
|
||||
@ -544,7 +624,9 @@
|
||||
</Run>
|
||||
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" LaunchOptions="-jobs 2 " AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1" ParallelReportGen="true">
|
||||
<Strategy Version="1" Minor="2">
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/>
|
||||
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024">
|
||||
<Desc>Default settings for Implementation.</Desc>
|
||||
</StratHandle>
|
||||
<Step Id="init_design"/>
|
||||
<Step Id="opt_design"/>
|
||||
<Step Id="power_opt_design"/>
|
||||
|
||||
119
design/sd/read_command.sv
Normal file
119
design/sd/read_command.sv
Normal file
@ -0,0 +1,119 @@
|
||||
module read_command(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic listen,
|
||||
// 8 types of responses??? so hard to tell
|
||||
input logic[2:0] response_type,
|
||||
input logic sd_cmd,
|
||||
output logic received,
|
||||
// This has to be large enough to capture each possible response
|
||||
output logic [135:0] out_data
|
||||
);
|
||||
enum logic [2:0] {IDLE,START,LISTEN,RECEIVING,DONE} state, next_state;
|
||||
|
||||
// This should be large enough to capture the largest 136-bit response
|
||||
logic [$clog2(136):0] counter;
|
||||
logic [135:0] data_reg;
|
||||
|
||||
logic [2:0] response_type_reg;
|
||||
|
||||
always_comb begin
|
||||
case (state)
|
||||
IDLE:
|
||||
if (listen)
|
||||
next_state=START;
|
||||
else
|
||||
next_state=IDLE;
|
||||
START:
|
||||
if (sd_cmd == 0)
|
||||
next_state=RECEIVING;
|
||||
else
|
||||
next_state=LISTEN;
|
||||
LISTEN:
|
||||
// check for the start bit
|
||||
if (sd_cmd == 0)
|
||||
next_state=RECEIVING;
|
||||
else
|
||||
next_state=LISTEN;
|
||||
RECEIVING:
|
||||
if (counter == 0)
|
||||
next_state=DONE;
|
||||
else
|
||||
next_state=RECEIVING;
|
||||
DONE:
|
||||
if (listen)
|
||||
next_state=START;
|
||||
else
|
||||
next_state=DONE;
|
||||
default:
|
||||
next_state=IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
case (state)
|
||||
IDLE:
|
||||
begin
|
||||
received <= 0;
|
||||
out_data <= 0;
|
||||
if (listen)
|
||||
response_type_reg <= response_type;
|
||||
end
|
||||
|
||||
START:
|
||||
begin
|
||||
// off-by-one/cycle timing issues accumulated to a counter offset
|
||||
// of 3.
|
||||
counter <= get_bits(response_type_reg) - 3;
|
||||
data_reg <= 0;
|
||||
received <= 0;
|
||||
end
|
||||
|
||||
LISTEN:
|
||||
// This is kinda a hack
|
||||
// I don't fully understand why the receiving state misses two
|
||||
// whole bits, I get why it misses the first but not the second...
|
||||
data_reg[0] <= sd_cmd;
|
||||
|
||||
RECEIVING:
|
||||
begin
|
||||
counter <= counter - 1;
|
||||
data_reg <= {data_reg[134:0],sd_cmd};
|
||||
end
|
||||
|
||||
DONE:
|
||||
begin
|
||||
received <= 1;
|
||||
out_data <= data_reg;
|
||||
if (listen)
|
||||
response_type_reg <= response_type;
|
||||
end
|
||||
|
||||
default: ;
|
||||
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset)
|
||||
state<=IDLE;
|
||||
else
|
||||
state<=next_state;
|
||||
end
|
||||
|
||||
|
||||
function automatic logic [$clog2(136):0] get_bits(logic [2:0] response);
|
||||
case (response)
|
||||
// Response 2 is extra long
|
||||
2:
|
||||
return 136;
|
||||
// Most responses are 48 bits
|
||||
default:
|
||||
return 48;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
64
design/sd/read_data.sv
Normal file
64
design/sd/read_data.sv
Normal file
@ -0,0 +1,64 @@
|
||||
// Whenever we receive a data block, start spitting bytes out into the audio
|
||||
// buffer bram. This could always be clocked at the 25MHz default speed clock,
|
||||
// or it could switch over like the writer has to
|
||||
module read_data(
|
||||
input clk,
|
||||
input reset,
|
||||
input sd_data,
|
||||
audio_buffer_interface.driver buffer
|
||||
);
|
||||
// Block data is a start bit, 512 bytes sent msb first, then a CRC16 and end
|
||||
// bit.
|
||||
|
||||
// NOTE: This doesn't check which side of the buffer the audio player is
|
||||
// reading from, so theoretically it could overwrite audio that's being
|
||||
// played. However, as long as the sd card controller doesn't request extra
|
||||
// blocks this shouldn't be an issue
|
||||
|
||||
localparam BLOCK_SIZE=512*8+16+2;
|
||||
logic [$clog2(BLOCK_SIZE):0] counter;
|
||||
|
||||
logic [7:0] byte_shift;
|
||||
|
||||
logic [3:0] byte_counter;
|
||||
|
||||
assign buffer.clka = clk;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
buffer.ena <= 0;
|
||||
buffer.addra <= '1;
|
||||
buffer.dina <= 0;
|
||||
end
|
||||
else begin
|
||||
// We ignore the lower 17 bits of the block
|
||||
if (counter > 16) begin
|
||||
counter <= counter - 1;
|
||||
byte_shift <= {byte_shift[6:0],sd_data};
|
||||
byte_counter <= byte_counter - 1;
|
||||
|
||||
// Store received byte in audio buffer and reset counter
|
||||
if (byte_counter == 0) begin
|
||||
byte_counter <= 7;
|
||||
buffer.dina <= byte_shift;//{byte_shift[6:0],sd_data};
|
||||
buffer.ena <= 1;
|
||||
end
|
||||
|
||||
// Turn the enable signal off so we don't accidentally write
|
||||
// anything weird
|
||||
if (byte_counter == 4) begin
|
||||
buffer.ena <= 0;
|
||||
buffer.addra <= buffer.addra + 1;
|
||||
end
|
||||
|
||||
end
|
||||
else if (counter != 0)
|
||||
counter<=counter-1;
|
||||
else if (sd_data == 0) begin
|
||||
counter <= BLOCK_SIZE-1;
|
||||
byte_counter <= 8;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@ -30,3 +30,12 @@
|
||||
### command_sender
|
||||
- output ready signal was delay a cycle because it was set by sequential logic,
|
||||
detected in testing, changed it to a combinational output for 1 cycle speedup
|
||||
|
||||
### read_command
|
||||
- response_type was not getting correctly stored/set, breaking the module
|
||||
entirely. Detected in testbench
|
||||
- off-by-one error detected in the counter
|
||||
|
||||
## read_data
|
||||
- audio buffer address to write to was never changing, caught in simulation
|
||||
- some off-by-one errors in the byte shifting were found and corrected
|
||||
|
||||
81
verification/sd/read_command_tb.sv
Normal file
81
verification/sd/read_command_tb.sv
Normal 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
verification/sd/read_data_tb.sv
Normal file
140
verification/sd/read_data_tb.sv
Normal 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
|
||||
67
verification/waveform_configs/read_command_tb_behav.wcfg
Normal file
67
verification/waveform_configs/read_command_tb_behav.wcfg
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="read_command_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="read_command_tb" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="0.000 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="1,370.001 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="330.000 ns"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="533"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="187"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="11" />
|
||||
<wvobject type="logic" fp_name="/read_command_tb/clk">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_command_tb/reset">
|
||||
<obj_property name="ElementShortName">reset</obj_property>
|
||||
<obj_property name="ObjectShortName">reset</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_command_tb/listen">
|
||||
<obj_property name="ElementShortName">listen</obj_property>
|
||||
<obj_property name="ObjectShortName">listen</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_command_tb/sd_cmd">
|
||||
<obj_property name="ElementShortName">sd_cmd</obj_property>
|
||||
<obj_property name="ObjectShortName">sd_cmd</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_command_tb/received">
|
||||
<obj_property name="ElementShortName">received</obj_property>
|
||||
<obj_property name="ObjectShortName">received</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/out_data">
|
||||
<obj_property name="ElementShortName">out_data[39:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">out_data[39:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/dut/state">
|
||||
<obj_property name="ElementShortName">state[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">state[2:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/dut/counter">
|
||||
<obj_property name="ElementShortName">counter[6:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">counter[6:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/dut/data_reg">
|
||||
<obj_property name="ElementShortName">data_reg[39:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">data_reg[39:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/response_type">
|
||||
<obj_property name="ElementShortName">response_type[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">response_type[2:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_command_tb/dut/response_type_reg">
|
||||
<obj_property name="ElementShortName">response_type_reg[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">response_type_reg[2:0]</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
96
verification/waveform_configs/read_data_tb_behav.wcfg
Normal file
96
verification/waveform_configs/read_data_tb_behav.wcfg
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="read_data_tb_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="glbl" />
|
||||
<top_module name="read_data_tb" />
|
||||
<top_module name="sdvd_defs" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="1,438.800 ns"></ZoomStartTime>
|
||||
<ZoomEndTime time="1,718.201 ns"></ZoomEndTime>
|
||||
<Cursor1Time time="618.800 ns"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="533"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="155"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="18" />
|
||||
<wvobject type="logic" fp_name="/read_data_tb/clk">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/sd_clk">
|
||||
<obj_property name="ElementShortName">sd_clk</obj_property>
|
||||
<obj_property name="ObjectShortName">sd_clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/reset">
|
||||
<obj_property name="ElementShortName">reset</obj_property>
|
||||
<obj_property name="ObjectShortName">reset</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/play">
|
||||
<obj_property name="ElementShortName">play</obj_property>
|
||||
<obj_property name="ObjectShortName">play</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/stop">
|
||||
<obj_property name="ElementShortName">stop</obj_property>
|
||||
<obj_property name="ObjectShortName">stop</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/speed">
|
||||
<obj_property name="ElementShortName">speed[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">speed[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/playing">
|
||||
<obj_property name="ElementShortName">playing</obj_property>
|
||||
<obj_property name="ObjectShortName">playing</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/sample">
|
||||
<obj_property name="ElementShortName">sample[15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">sample[15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/counter">
|
||||
<obj_property name="ElementShortName">counter[10:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">counter[10:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/test_memory">
|
||||
<obj_property name="ElementShortName">test_memory[1023:0][15:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">test_memory[1023:0][15:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/bufferInterface/driver/addra">
|
||||
<obj_property name="ElementShortName">addra[10:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">addra[10:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/bufferInterface/driver/dina">
|
||||
<obj_property name="ElementShortName">dina[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dina[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/bufferInterface/driver/ena">
|
||||
<obj_property name="ElementShortName">ena</obj_property>
|
||||
<obj_property name="ObjectShortName">ena</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/bufferInterface/driver/address_half">
|
||||
<obj_property name="ElementShortName">address_half</obj_property>
|
||||
<obj_property name="ObjectShortName">address_half</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/read_data_tb/sd_data">
|
||||
<obj_property name="ElementShortName">sd_data</obj_property>
|
||||
<obj_property name="ObjectShortName">sd_data</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/readerDut/byte_shift">
|
||||
<obj_property name="ElementShortName">byte_shift[7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">byte_shift[7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/readerDut/byte_counter">
|
||||
<obj_property name="ElementShortName">byte_counter[3:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">byte_counter[3:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/read_data_tb/readerDut/counter">
|
||||
<obj_property name="ElementShortName">counter[13:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">counter[13:0]</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
||||
Loading…
x
Reference in New Issue
Block a user