Compare commits

..

No commits in common. "master" and "wcude" have entirely different histories.

68 changed files with 86 additions and 872053 deletions

2
.gitignore vendored
View File

@ -2,6 +2,4 @@
*.log
xsim.dir
SDVD.*
.Xil/
vivado_pid*
!SDVD.xpr

View File

@ -5,11 +5,8 @@
## Note: As the Nexys 4 DDR was rebranded to the Nexys A7 with no substantial changes, this XDC file will also work for the Nexys 4 DDR.
## Clock signal
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports CLK100MHZ]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports CLK100MHZ]
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
#set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
#create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}];
##Switches
@ -31,7 +28,7 @@ set_property CONFIG_VOLTAGE 3.3 [current_design]
#set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { SW[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
## LEDs
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {LED[0]}]
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
#set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
@ -57,31 +54,31 @@ set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {LED[0]}]
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { LED17_R }]; #IO_L11N_T1_SRCC_14 Sch=led17_r
##7 segment display
set_property -dict {PACKAGE_PIN T10 IOSTANDARD LVCMOS33} [get_ports CA]
set_property -dict {PACKAGE_PIN R10 IOSTANDARD LVCMOS33} [get_ports CB]
set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33} [get_ports CC]
set_property -dict {PACKAGE_PIN K13 IOSTANDARD LVCMOS33} [get_ports CD]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports CE]
set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports CF]
set_property -dict {PACKAGE_PIN L18 IOSTANDARD LVCMOS33} [get_ports CG]
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { CA }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { CB }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { CC }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { CD }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { CE }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { CF }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { CG }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
set_property -dict {PACKAGE_PIN J17 IOSTANDARD LVCMOS33} [get_ports {AN[0]}]
set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS33} [get_ports {AN[1]}]
set_property -dict {PACKAGE_PIN T9 IOSTANDARD LVCMOS33} [get_ports {AN[2]}]
set_property -dict {PACKAGE_PIN J14 IOSTANDARD LVCMOS33} [get_ports {AN[3]}]
set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports {AN[4]}]
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {AN[5]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {AN[6]}]
set_property -dict {PACKAGE_PIN U13 IOSTANDARD LVCMOS33} [get_ports {AN[7]}]
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
##CPU Reset Button
set_property -dict {PACKAGE_PIN C12 IOSTANDARD LVCMOS33} [get_ports CPU_RESETN]
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { CPU_RESETN }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
##Buttons
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports BTNC]
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports BTNR]
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
@ -153,14 +150,14 @@ set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports BTNR]
#set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##Micro SD Connector
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports SD_RESET]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports SD_CD]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports SD_SCK]
set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports SD_CMD]
set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports {SD_DAT[0]}]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {SD_DAT[1]}]
set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {SD_DAT[2]}]
set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {SD_DAT[3]}]
#set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports { SD_RESET }]; #IO_L14P_T2_SRCC_35 Sch=sd_reset
#set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports { SD_CD }]; #IO_L9N_T1_DQS_AD7N_35 Sch=sd_cd
#set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports { SD_SCK }]; #IO_L9P_T1_DQS_AD7P_35 Sch=sd_sck
#set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports { SD_CMD }]; #IO_L16N_T2_35 Sch=sd_cmd
#set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[0] }]; #IO_L16P_T2_35 Sch=sd_dat[0]
#set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[1] }]; #IO_L18N_T2_35 Sch=sd_dat[1]
#set_property -dict { PACKAGE_PIN F1 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[2] }]; #IO_L18P_T2_35 Sch=sd_dat[2]
#set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports { SD_DAT[3] }]; #IO_L14N_T2_SRCC_35 Sch=sd_dat[3]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
@ -182,8 +179,8 @@ set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {SD_DAT[3]}]
#set_property -dict { PACKAGE_PIN F5 IOSTANDARD LVCMOS33 } [get_ports { M_LRSEL }]; #IO_0_35 Sch=m_lrsel
##PWM Audio Amplifier
set_property -dict {PACKAGE_PIN A11 IOSTANDARD LVCMOS33} [get_ports AUD_PWM]
set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports AUD_SD]
#set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { AUD_PWM }]; #IO_L4N_T0_15 Sch=aud_pwm
#set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { AUD_SD }]; #IO_L6P_T0_15 Sch=aud_sd
##USB-RS232 Interface
#set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD_IN }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
@ -215,75 +212,3 @@ set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports AUD_SD]
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[2] }]; #IO_L2P_T0_D02_14 Sch=qspi_dq[2]
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { QSPI_DQ[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_dq[3]
#set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { QSPI_CSN }]; #IO_L6P_T0_FCS_B_14 Sch=qspi_csn
create_debug_core u_ila_0 ila
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU_CNT 2 [get_debug_cores u_ila_0]
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
set_property C_DATA_DEPTH 16384 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
set_property port_width 1 [get_debug_ports u_ila_0/clk]
connect_debug_port u_ila_0/clk [get_nets [list CLK100MHZ_IBUF_BUFG]]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
set_property port_width 48 [get_debug_ports u_ila_0/probe0]
connect_debug_port u_ila_0/probe0 [get_nets [list {realSdPlayer/slowSender/to_send[0]} {realSdPlayer/slowSender/to_send[1]} {realSdPlayer/slowSender/to_send[2]} {realSdPlayer/slowSender/to_send[3]} {realSdPlayer/slowSender/to_send[4]} {realSdPlayer/slowSender/to_send[5]} {realSdPlayer/slowSender/to_send[6]} {realSdPlayer/slowSender/to_send[7]} {realSdPlayer/slowSender/to_send[8]} {realSdPlayer/slowSender/to_send[9]} {realSdPlayer/slowSender/to_send[10]} {realSdPlayer/slowSender/to_send[11]} {realSdPlayer/slowSender/to_send[12]} {realSdPlayer/slowSender/to_send[13]} {realSdPlayer/slowSender/to_send[14]} {realSdPlayer/slowSender/to_send[15]} {realSdPlayer/slowSender/to_send[16]} {realSdPlayer/slowSender/to_send[17]} {realSdPlayer/slowSender/to_send[18]} {realSdPlayer/slowSender/to_send[19]} {realSdPlayer/slowSender/to_send[20]} {realSdPlayer/slowSender/to_send[21]} {realSdPlayer/slowSender/to_send[22]} {realSdPlayer/slowSender/to_send[23]} {realSdPlayer/slowSender/to_send[24]} {realSdPlayer/slowSender/to_send[25]} {realSdPlayer/slowSender/to_send[26]} {realSdPlayer/slowSender/to_send[27]} {realSdPlayer/slowSender/to_send[28]} {realSdPlayer/slowSender/to_send[29]} {realSdPlayer/slowSender/to_send[30]} {realSdPlayer/slowSender/to_send[31]} {realSdPlayer/slowSender/to_send[32]} {realSdPlayer/slowSender/to_send[33]} {realSdPlayer/slowSender/to_send[34]} {realSdPlayer/slowSender/to_send[35]} {realSdPlayer/slowSender/to_send[36]} {realSdPlayer/slowSender/to_send[37]} {realSdPlayer/slowSender/to_send[38]} {realSdPlayer/slowSender/to_send[39]} {realSdPlayer/slowSender/to_send[40]} {realSdPlayer/slowSender/to_send[41]} {realSdPlayer/slowSender/to_send[42]} {realSdPlayer/slowSender/to_send[43]} {realSdPlayer/slowSender/to_send[44]} {realSdPlayer/slowSender/to_send[45]} {realSdPlayer/slowSender/to_send[46]} {realSdPlayer/slowSender/to_send[47]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1]
set_property port_width 48 [get_debug_ports u_ila_0/probe1]
connect_debug_port u_ila_0/probe1 [get_nets [list {realSdPlayer/received_data[0]} {realSdPlayer/received_data[1]} {realSdPlayer/received_data[2]} {realSdPlayer/received_data[3]} {realSdPlayer/received_data[4]} {realSdPlayer/received_data[5]} {realSdPlayer/received_data[6]} {realSdPlayer/received_data[7]} {realSdPlayer/received_data[8]} {realSdPlayer/received_data[9]} {realSdPlayer/received_data[10]} {realSdPlayer/received_data[11]} {realSdPlayer/received_data[12]} {realSdPlayer/received_data[13]} {realSdPlayer/received_data[14]} {realSdPlayer/received_data[15]} {realSdPlayer/received_data[16]} {realSdPlayer/received_data[17]} {realSdPlayer/received_data[18]} {realSdPlayer/received_data[19]} {realSdPlayer/received_data[20]} {realSdPlayer/received_data[21]} {realSdPlayer/received_data[22]} {realSdPlayer/received_data[23]} {realSdPlayer/received_data[24]} {realSdPlayer/received_data[25]} {realSdPlayer/received_data[26]} {realSdPlayer/received_data[27]} {realSdPlayer/received_data[28]} {realSdPlayer/received_data[29]} {realSdPlayer/received_data[30]} {realSdPlayer/received_data[31]} {realSdPlayer/received_data[32]} {realSdPlayer/received_data[33]} {realSdPlayer/received_data[34]} {realSdPlayer/received_data[35]} {realSdPlayer/received_data[36]} {realSdPlayer/received_data[37]} {realSdPlayer/received_data[38]} {realSdPlayer/received_data[39]} {realSdPlayer/received_data[40]} {realSdPlayer/received_data[41]} {realSdPlayer/received_data[42]} {realSdPlayer/received_data[43]} {realSdPlayer/received_data[44]} {realSdPlayer/received_data[45]} {realSdPlayer/received_data[46]} {realSdPlayer/received_data[47]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2]
set_property port_width 4 [get_debug_ports u_ila_0/probe2]
connect_debug_port u_ila_0/probe2 [get_nets [list {realSdPlayer/sd_data[0]} {realSdPlayer/sd_data[1]} {realSdPlayer/sd_data[2]} {realSdPlayer/sd_data[3]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3]
set_property port_width 6 [get_debug_ports u_ila_0/probe3]
connect_debug_port u_ila_0/probe3 [get_nets [list {realSdPlayer/cmd[0]} {realSdPlayer/cmd[1]} {realSdPlayer/cmd[2]} {realSdPlayer/cmd[3]} {realSdPlayer/cmd[4]} {realSdPlayer/cmd[5]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4]
set_property port_width 16 [get_debug_ports u_ila_0/probe4]
connect_debug_port u_ila_0/probe4 [get_nets [list {audioOutput/sample_buffer[0]} {audioOutput/sample_buffer[1]} {audioOutput/sample_buffer[2]} {audioOutput/sample_buffer[3]} {audioOutput/sample_buffer[4]} {audioOutput/sample_buffer[5]} {audioOutput/sample_buffer[6]} {audioOutput/sample_buffer[7]} {audioOutput/sample_buffer[8]} {audioOutput/sample_buffer[9]} {audioOutput/sample_buffer[10]} {audioOutput/sample_buffer[11]} {audioOutput/sample_buffer[12]} {audioOutput/sample_buffer[13]} {audioOutput/sample_buffer[14]} {audioOutput/sample_buffer[15]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5]
set_property port_width 10 [get_debug_ports u_ila_0/probe5]
connect_debug_port u_ila_0/probe5 [get_nets [list {audioBuffer/address[0]} {audioBuffer/address[1]} {audioBuffer/address[2]} {audioBuffer/address[3]} {audioBuffer/address[4]} {audioBuffer/address[5]} {audioBuffer/address[6]} {audioBuffer/address[7]} {audioBuffer/address[8]} {audioBuffer/address[9]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6]
set_property port_width 1 [get_debug_ports u_ila_0/probe6]
connect_debug_port u_ila_0/probe6 [get_nets [list realSdPlayer/fast_clk]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7]
set_property port_width 1 [get_debug_ports u_ila_0/probe7]
connect_debug_port u_ila_0/probe7 [get_nets [list realSdPlayer/read_command_listen]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8]
set_property port_width 1 [get_debug_ports u_ila_0/probe8]
connect_debug_port u_ila_0/probe8 [get_nets [list realSdPlayer/read_command_received]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9]
set_property port_width 1 [get_debug_ports u_ila_0/probe9]
connect_debug_port u_ila_0/probe9 [get_nets [list realSdPlayer/send_command_ready]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10]
set_property port_width 1 [get_debug_ports u_ila_0/probe10]
connect_debug_port u_ila_0/probe10 [get_nets [list realSdPlayer/send_command_start]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11]
set_property port_width 1 [get_debug_ports u_ila_0/probe11]
connect_debug_port u_ila_0/probe11 [get_nets [list realSdPlayer/slowSender/send_sd_cmd]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12]
set_property port_width 1 [get_debug_ports u_ila_0/probe12]
connect_debug_port u_ila_0/probe12 [get_nets [list realSdPlayer/slow_clk]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13]
set_property port_width 1 [get_debug_ports u_ila_0/probe13]
connect_debug_port u_ila_0/probe13 [get_nets [list realSdPlayer/stored_sd_cmd]]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets CLK100MHZ_IBUF_BUFG]

899
SDVD.xpr

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,158 +0,0 @@
/****
* audio_buffer.sv - holds a 2KiB audio buffer of 16-bit pcm audio
* samples (with pcm being the audio format we are using)
*
* @author: Waylon Cude, Dilanthi
* @date: 6/12/2025
*
* */
//define used here because verilator needs it but vivado is smart enough
//not to.
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
//this interfaces with block ram
module audio_buffer(
// The clock should be at 48khz
input logic clk, reset,
// Control signals
input logic play, stop,
input SPEED speed,
// Whether the audio buffer is currently playing
output logic playing,
// A 16-bit audio sample to output
output logic [15:0] sample,
// Inputs for the memory buffer
audio_buffer_interface.receiver driver
);
// Size of samples, 8bit or 16bit supported
parameter SIZE=16;
(* MARK_DEBUG = "TRUE" *)
logic [11-(SIZE/8):0] address;
// State register
logic enb;
logic [(SIZE-1):0] doutb;
// A single bit counter, to avoid feeding samples given the 1 cycle read delay
logic delay;
// Whether the current address being read from is in the upper or lower
// half of the 2KiB buffer
//
// The MSB of the address == higher/lower half address
assign driver.address_half = address[11-(SIZE/8)];
always_ff @(posedge clk) begin
enb <= 0;
if (reset) begin
playing <= 0;
address <= 0;
sample <= 0;
delay <= '1;
end
else if (!playing) begin
if (play) begin
playing <= 1;
delay <= '1;
end
end
else begin
if (stop) begin
playing <= 0;
// If playback "Stops" then reset the address to a known value, 0
address <= 0;
delay <= '1;
end
else begin
// This will overflow to the correct value always
address <= address + speed;
enb <= 1;
if (delay == 0) begin
sample[15-:SIZE] <= doutb;
end
else begin
sample <= '0;
delay <= '0;
end
end
end
end
//vivado block ram xpm macro
xpm_memory_sdpram #(
.ADDR_WIDTH_A(11), // DECIMAL
.ADDR_WIDTH_B(12-(SIZE/8)), // DECIMAL
.AUTO_SLEEP_TIME(0), // DECIMAL
.BYTE_WRITE_WIDTH_A(8), // DECIMAL
.CASCADE_HEIGHT(0), // DECIMAL
.CLOCKING_MODE("independent_clock"), // String
.ECC_BIT_RANGE("7:0"), // String
.ECC_MODE("no_ecc"), // String
.ECC_TYPE("none"), // String
.IGNORE_INIT_SYNTH(0), // DECIMAL
.MEMORY_INIT_FILE("none"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("auto"), // String
.MEMORY_SIZE(16*1024), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.RAM_DECOMP("auto"), // String
.READ_DATA_WIDTH_B(SIZE), // DECIMAL
.READ_LATENCY_B(1), // DECIMAL
.READ_RESET_VALUE_B("0"), // String
.RST_MODE_A("SYNC"), // String
.RST_MODE_B("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_EMBEDDED_CONSTRAINT(0), // DECIMAL
.USE_MEM_INIT(1), // DECIMAL
.USE_MEM_INIT_MMI(0), // DECIMAL
.WAKEUP_TIME("disable_sleep"), // String
.WRITE_DATA_WIDTH_A(8), // DECIMAL
.WRITE_MODE_B("no_change"), // String
.WRITE_PROTECT(1) // DECIMAL
)
buffer (
.doutb(doutb), // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
.addra(driver.addra), // ADDR_WIDTH_A-bit input: Address for port A write operations.
.addrb(address), // ADDR_WIDTH_B-bit input: Address for port B read operations.
.clka(driver.clka), // 1-bit input: Clock signal for port A. Also clocks port B when
// parameter CLOCKING_MODE is "common_clock".
.clkb(clk), // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
// "independent_clock". Unused when parameter CLOCKING_MODE is
// "common_clock".
.dina(driver.dina), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
.ena(driver.ena), // 1-bit input: Memory enable signal for port A. Must be high on clock
// cycles when write operations are initiated. Pipelined internally.
.enb(enb), // 1-bit input: Memory enable signal for port B. Must be high on clock
// cycles when read operations are initiated. Pipelined internally.
.rstb(reset), // 1-bit input: Reset signal for the final port B output register stage.
// Synchronously resets output port doutb to the value specified by
// parameter READ_RESET_VALUE_B.
.wea(driver.ena), // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
// for port A input data port dina. 1 bit wide when word-wide writes are
// used. In byte-wide write configurations, each bit controls the
// writing one byte of dina to address addra. For example, to
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
// is 32, wea would be 4'b0010.
.sleep(0), // The XPM macros say these can be removed, but when I did this the
.injectsbiterra(0), // entire block memory got optimized out. These were readded in later
.injectdbiterra(0),
.regceb(enb)
);
endmodule

View File

@ -1,55 +0,0 @@
/****
* pwm.sv - drives the pwm audio output on the FPGA given a single 16-bit
* sample.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6-12-2025
*
*
* */
module pwm(
input logic clk, reset,
// Load control signal, if this is high we should load a new sample
input logic load,
// The audio sample to play back
input logic [15:0] sample,
// The audio output pin
output wire pwm_pin
);
// This can't be 16 or we are slowing the audio rate down by a factor of
// 2^5=32
parameter DEPTH=11;
logic [DEPTH-1:0] pulse_counter;
(* MARK_DEBUG = "TRUE" *)
logic [15:0] sample_buffer;
logic should_output;
always_ff @(posedge clk)
begin
if (reset)
begin
pulse_counter <= 0;
sample_buffer <= 0;
should_output <= 0;
end
else
begin
if (load)
sample_buffer <= sample;
pulse_counter <= pulse_counter + 1;
if (pulse_counter < sample_buffer[15-:DEPTH])
should_output <= 1;
else
should_output <= 0;
end
end
assign pwm_pin = should_output ? 'z : '0;
endmodule

View File

@ -1,30 +1,23 @@
/***
* debouncer.sv - generates a debounced button press and turns it into
* a single pulse.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6-12-25
*
* */
//NOTE: you should drive this with a slow clock to actually debounce input
module debouncer(input logic clk, input reset, input source, output logic out);
module debouncer(input logic clk, input reset, input source, output wire out);
logic pressed;
assign out = pressed;
always_ff @(posedge clk) begin
if (reset)
pressed <= 0;
if (!source) begin
else if (!pressed && source)
pressed <= 1;
else if (pressed && !source)
pressed <= 0;
out <= 0;
end
else
if (pressed)
out <= 0;
else begin
pressed <= 1;
out <= 1;
end
end
//always_ff (@posedge clk) begin
//
//end
endmodule

View File

@ -1,67 +0,0 @@
/****
* low_freq_clock_gen.sv - Generates different clock frequencies to drive
* different state machines and different parts of
* the design.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
* */
//Define used because verilator needs it but vivado is samrt enough not to
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
// Takes in a 100MHz clock and generates the very low freq signals needed
// for driving the control logic
module low_freq_clock_gen(
input logic clk, reset,
input SPEED speed,
output logic clk1k, clk10h, seconds_pulse
);
// Hardcoded to be 1,000,000/4,000 (25,000)
// Relying on constant maths makes it the wrong size
localparam num_cycles = 25_000;
logic [$clog2(num_cycles):0] counter;
logic [$clog2(4000):0] seconds_counter;
logic [$clog2(4000):0] clock_divider_counter;
always_ff @(posedge clk) begin
if (reset) begin
counter <= num_cycles;
clk1k <= 0;
clk10h <= 0;
seconds_pulse <= 0;
seconds_counter <= 0;
clock_divider_counter <= 0;
end
// At 4khz increment the seconds counter and output clocks
else if (counter == 0) begin
counter <= num_cycles;
seconds_counter <= seconds_counter + {9'b0, speed};
clock_divider_counter <= clock_divider_counter + 1;
if (seconds_counter >= 4000) begin
seconds_counter <= seconds_counter-4000;
// Should we flop it or pulse at 100MHz?
seconds_pulse <= 1;
end
else
seconds_pulse <= 0;
if (clock_divider_counter == 4000)
clock_divider_counter <= 0;
// Generate output clocks
if (clock_divider_counter % 4 == 0)
clk1k <= ~clk1k;
if (clock_divider_counter % 400 == 0)
clk10h <= ~clk10h;
end
else
counter <= counter - 1;
end
endmodule

View File

@ -1,34 +0,0 @@
/****
* modular_clock_gen.sv - parameterizable clock divider.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* */
module modular_clock_gen(
input clk, reset,
output logic oclk
);
//parameter has no default because the user should always set it
parameter DIVISOR;
logic [$clog2(DIVISOR)-1:0] counter;
logic set;
always_ff @(posedge clk) begin
// modular clock has to keep ticking through reset
// so everything with a synchronous reset actually works
if (reset && !set) begin
counter <= DIVISOR-1;
set <= 1;
end
else if (counter == 0)
counter <= DIVISOR-1;
else
counter <= counter - 1;
oclk <= counter < (DIVISOR/2);
end
endmodule

View File

@ -1,157 +0,0 @@
/***
* nexys_a7_top.sv - top level design module specific to Nexys A7100T.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* **/
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
module nexys_a7_top(
input logic CLK100MHZ, CPU_RESETN,
input logic BTNC, BTNR,
output logic AUD_PWM, AUD_SD,
output logic CA,CB,CC,CD,CE,CF,CG,
output logic [7:0] AN,
output wire LED[0:0],
output wire SD_RESET,SD_SCK,
inout wire [3:0] SD_DAT,
inout wire SD_CMD,
input wire SD_CD
);
// Active high reset
wire reset;
assign reset = ~CPU_RESETN;
logic clk_1khz, clk_10hz;
logic clk_48khz, clk_1mhz;
logic seconds_pulse;
SPEED speed;
audio_buffer_interface audio_interface();
// Map C{A-G} to an array of 7-segment displays
wire [6:0] segments [7:0];
wire [2:0] segment_mux_select;
// These segments are currently unused
assign segments[7] = 0;
assign segments[6] = 0;
// These are the ones we're using
assign {CA,CB,CC,CD,CE,CF,CG} = ~segments[segment_mux_select];
logic [$clog2(60)-1:0] seconds;
logic [$clog2(60)-1:0] minutes;
logic [$clog2(60)-1:0] hours;
logic [15:0] audio_sample;
logic sd_ready;
logic playing;
assign LED[0] = playing;
assign AUD_SD = playing;
low_freq_clock_gen clockGen(CLK100MHZ, reset, speed, 'z, clk_10hz, seconds_pulse);
modular_clock_gen #(100_000) anodeClock(CLK100MHZ, reset, clk_1khz);
// Create a clock with a divisor of 2083, making ~48khz
modular_clock_gen #(2083) audioClock(CLK100MHZ, reset, clk_48khz);
modular_clock_gen #(100) pwmClock(CLK100MHZ, reset, clk_1mhz);
// Count the number on seconds, hours, and minutes elapsed
// If the speed is faster this will pulse more often than once a second
// but will still theoretically be a second of video time
always_ff @(posedge seconds_pulse or posedge reset) begin
if (reset) begin
seconds <= 0;
minutes <= 0;
hours <= 0;
end
else if (seconds == 59) begin
seconds <= 0;
if (minutes == 59) begin
minutes <= 0;
hours <= hours + 1;
end
else
minutes <= minutes + 1;
end
else
seconds <= seconds + 1;
end
display_anode_driver anodeDriver(clk_1khz,reset,AN,segment_mux_select);
sixty_display secondsSegment (seconds, segments[1], segments[0]);
sixty_display minutesSegment (minutes, segments[3], segments[2]);
sixty_display hoursSegment (hours, segments[5], segments[4]);
// Run the playback speed state machine at a lower rate
// Gets rid of button bouncing
playback_controller playbackController (clk_10hz,reset,BTNC, BTNR, speed);
`ifdef ROM
rom_sd #("even_flow_16.mem") romSdPlayer(clk_1mhz,reset,sd_ready,audio_interface.driver);
assign {SD_RESET,SD_DAT,SD_CMD,SD_SCK} = 'z;
audio_buffer audioBuffer(
clk_48khz,
reset,
sd_ready,
'0, // stop signal not used right now
speed,
playing,
audio_sample,
audio_interface.receiver
);
pwm audioOutput(CLK100MHZ, reset, clk_48khz, audio_sample, AUD_PWM);
`else
// Power the sd slot
assign SD_RESET = 0;
// We don't use more than one dat line
logic clk_100khz;
logic clk_25mhz;
// We can clock this at around 200khz before things start breaking
// Even at 200khz sometimes things break
modular_clock_gen #(500) slowSdClock(CLK100MHZ, reset, clk_100khz);
// Try clocking this slower than max speed
// To see if that makes it actually work
//
// NOTE: It did not make it work
modular_clock_gen #(400) fastSdClock(CLK100MHZ, reset, clk_25mhz);
sd_controller realSdPlayer(
clk_100khz,
clk_25mhz,
CLK100MHZ,
clk_1mhz,
reset,
SD_DAT,
SD_CMD,
sd_ready,
SD_SCK,
audio_interface.driver
);
audio_buffer #(.SIZE(16)) audioBuffer(
clk_48khz,
reset,
sd_ready,
'0, // stop signal not used right now
speed,
playing,
audio_sample,
audio_interface.receiver
);
pwm #(11) audioOutput(CLK100MHZ, reset, clk_48khz, audio_sample, AUD_PWM);
`endif
endmodule

View File

@ -1,22 +1,4 @@
/*****
* playback_controller.sv - A finite state machine with states that control
* playback speed. In additon to playing and pausing
* it can fast forward at 2x speed, 4x speed, 8x
* speed and 16x speed.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25
*
* */
//VERILATOR define used here because verilator needs it to find the package
//while vivado is smart enough not to.
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
module playback_controller(
module Playback_Controller(
// This clock should be reasonably slow
input logic clk,
input logic reset,
@ -25,89 +7,14 @@ module playback_controller(
input logic play,
input logic ff,
// Output is 0, 1x, 2x, 4x, 8x or 16x
output SPEED speed
// Output is 0, 1x, 2x, 4x, or 8x
output wire [3:0] speed
);
typedef enum logic [2:0] {
PAUSE, PLAY, FF2, FF4, FF8, FF16
} state_t;
state_t current, next;
wire play_pulse,ff_pulse;
// NOTE: These might need to be hooked to an even lower clock? Not sure
debouncer playDebouncer (clk,reset,play,play_pulse);
debouncer ffDebouncer (clk,reset,ff,ff_pulse);
//next state logic
always_comb
begin
unique case (current)
PAUSE:
begin
if (play_pulse) next = PLAY;
else if (ff_pulse) next = FF2;
else next = PAUSE;
end
PLAY:
begin
if (play_pulse) next = PAUSE;
else if (ff_pulse) next = FF2;
else next = PLAY;
end
FF2:
begin
if (play_pulse) next = PAUSE;
else if (ff_pulse) next = FF4;
else next = FF2;
end
FF4:
begin
if (play_pulse) next = PAUSE;
else if (ff_pulse) next = FF8;
else next = FF4;
end
FF8:
begin
if (play_pulse) next = PAUSE;
else if (ff_pulse) next = FF16;
else next = FF8;
end
FF16:
begin
if (play_pulse) next = PAUSE;
else if (ff_pulse) next = FF16;
else next = FF16;
end
default:
next = PAUSE;
endcase
end
//output logic
always_comb
begin
unique case (current)
PAUSE: speed = 0;
PLAY: speed = 1;
FF2: speed = 2;
FF4: speed = 4;
FF8: speed = 8;
FF16: speed = 16;
default:speed = 0;
endcase
end
//sequential logic
always_ff @(posedge clk)
begin
if (reset)
current <= PAUSE;
else
current <= next;
end
endmodule

View File

@ -1,47 +0,0 @@
/***
* crc_gen.sv - paramerizable sequential crc generator. This could probably be
* combinational logic too (but it would be way slower)
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* */
module crc_gen #(
parameter CRCBITS=7,
parameter COMMANDLEN=40,
parameter POLYNOMIAL='h89
) (
input clk,
input reset,
input start,
input [COMMANDLEN-1:0] num,
output logic ready,
output logic [CRCBITS-1:0] crc
);
logic [$clog2(COMMANDLEN):0] counter;
logic [COMMANDLEN+CRCBITS-1:0] div_reg;
always_ff @(posedge clk) begin
if (reset) begin
counter <= 0;
crc <= 0;
end
else if (start) begin
counter <= COMMANDLEN;
div_reg <= {num, {CRCBITS{1'b0}}};
ready <= 0;
end
else if (counter != 0) begin
if (div_reg[counter+CRCBITS-1] == 1) begin
div_reg <= div_reg ^ (POLYNOMIAL << (counter-1));
end
counter <= counter - 1;
end
else begin
ready <= 1;
crc <= div_reg[CRCBITS-1:0];
end
end
endmodule

View File

@ -1,138 +0,0 @@
/****
* read_command.sv - reads the sd command line and listens for sd command
* responses.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* **/
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 received_reg;
logic [2:0] response_type_reg;
// recevied was set a cycle before the data was actually ready
// and if it's just a register it holds for too long
// use both for maximum reactivity
assign received = received_reg && !listen;
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
// This defaulted to 1 ... oops
received_reg <= 0;
out_data <= 0;
if (listen)
response_type_reg <= response_type;
end
START:
begin
received_reg <= 0;
// off-by-one/cycle timing issues accumulated to a counter offset
// of 3.
// 3 in simulation, 2 in reality????
counter <= get_bits(response_type_reg) - 2;
data_reg <= 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
out_data <= data_reg;
received_reg <= 1;
if (listen) begin
received_reg <= 0;
response_type_reg <= response_type;
end
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

View File

@ -1,76 +0,0 @@
/***
* read_data.sv - whenever we receive a data block, start spitting bytes out
* into the audio buffer block ram. This could be clocked at
* 25MHz default speed clock, or it could swtich over like the
* writer has to.
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
***/
module read_data(
input clk,
input mem_clk,
input reset,
input [3:0] 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*2+16*4+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;
// Start negative so adding bytes will get us to the right address
buffer.addra <= 0 - 512;
buffer.dina <= 0;
end
else begin
// We ignore the lower 16*4+1 bits of the block
// CRC is apparently sent on each line, back to back
if (counter > 16*4) begin
counter <= counter - 1;
byte_shift <= {byte_shift[3:0],sd_data};
byte_counter <= byte_counter - 1;
// Store received byte in audio buffer and reset counter
if (byte_counter == 0) begin
byte_counter <= 1;
buffer.dina <= {byte_shift[3:0],sd_data};
buffer.ena <= 1;
end
// Turn the enable signal off so we don't accidentally write
// anything weird
if (byte_counter == 1) begin
buffer.addra <= buffer.addra - 1;
end
end
else if (counter != 0) begin
counter<=counter-1;
buffer.ena <= 0;
end
else if (sd_data == 0) begin
// In wide bus mode we read bytes in a descending order
buffer.addra <= buffer.addra + 1024;
counter <= BLOCK_SIZE;
byte_counter <= 3;
end
end
end
endmodule

View File

@ -1,172 +0,0 @@
/****
* rom_sd.sv - reads audio data off a rom and feeds it to the audio buffer
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25
*
* **/
module rom_sd(
input logic clk,
input logic reset,
output logic ready,
audio_buffer_interface.driver buffer
);
parameter MEM_FILE = "roundabout.mem";
typedef enum logic [3:0]{
RESET, DELAY1, DELAY2, DELAY3, WRITEBUF, ENDWRITE1, ENDWRITE2, ENDWRITE3, WAIT
} state_t;
state_t current, next;
// First we write 2048B into the memory buffer, then signal to play it and
// wait for half signal to avoid overwriting memory
logic [18:0] rom_addr;
logic [7:0] rom_data;
logic rom_enable;
logic buffer_half;
// xpm_memory_sprom: Single Port ROM
// Xilinx Parameterized Macro, version 2024.2
// The ROM has 17 address bits and 8 data bits to store 128KiB, more than
// enough for one second of 48khz audio
xpm_memory_sprom #(
.ADDR_WIDTH_A(19), // DECIMAL
.AUTO_SLEEP_TIME(0), // DECIMAL
.CASCADE_HEIGHT(0), // DECIMAL
.ECC_BIT_RANGE("7:0"), // String
.ECC_MODE("no_ecc"), // String
.ECC_TYPE("none"), // String
.IGNORE_INIT_SYNTH(0), // DECIMAL
.MEMORY_INIT_FILE(MEM_FILE), // String
.MEMORY_INIT_PARAM(""), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("auto"), // String
.MEMORY_SIZE((1<<19)*8), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.RAM_DECOMP("auto"), // String
.READ_DATA_WIDTH_A(8), // DECIMAL
.READ_LATENCY_A(2), // DECIMAL
.READ_RESET_VALUE_A("0"), // String
.RST_MODE_A("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_MEM_INIT(1), // DECIMAL
.USE_MEM_INIT_MMI(0), // DECIMAL
.WAKEUP_TIME("disable_sleep") // String
)
xpm_memory_sprom_inst (
.douta(rom_data), // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
.addra(rom_addr), // ADDR_WIDTH_A-bit input: Address for port A read operations.
.clka(clk), // 1-bit input: Clock signal for port A.
.ena(rom_enable), // 1-bit input: Memory enable signal for port A. Must be high on clock
// cycles when read operations are initiated. Pipelined internally.
.rsta(reset), // 1-bit input: Reset signal for the final port A output register stage.
// Synchronously resets output port douta to the value specified by
// parameter READ_RESET_VALUE_A.
// These are required I think? The ROM gets optimized out without them
.sleep(0),
// Should this have a separate control signal? What happens if it gets
// turned on early like I'm doing now?
.regcea(rom_enable),
.injectsbiterra(0),
.injectdbiterra(0)
);
// End of xpm_memory_sprom_inst instantiation
assign buffer_half = buffer.addra[10];
// The audio buffer memory is clocked at the same speed as this module
assign buffer.clka = clk;
//next state logic
always_comb
begin
case (current)
RESET: if (reset) next = RESET;
else next = DELAY1;
DELAY1: next = DELAY2;
DELAY2: next = DELAY3;
DELAY3: next = WRITEBUF;
WRITEBUF: if (buffer.addra[9:0] < 1020) next = WRITEBUF;
else next = ENDWRITE1;
ENDWRITE1: next = ENDWRITE2;
ENDWRITE2: next = ENDWRITE3;
ENDWRITE3: next = WAIT;
WAIT: if (buffer_half == buffer.address_half) next = WAIT;
else next = DELAY1;
default: next = RESET;
endcase
end
//sequential output logic
always_ff @(posedge clk)
begin
case (current)
RESET: begin
rom_addr <= 0;
rom_enable <= 1;
buffer.addra <= 0;
buffer.ena <= 0;
ready <= 0;
end
DELAY1: rom_addr <= rom_addr + 1;
DELAY2: rom_addr <= rom_addr + 1;
DELAY3: begin
rom_addr <= rom_addr + 1;
buffer.dina <= rom_data;
buffer.ena <= 1;
end
WRITEBUF: begin
buffer.ena <= 1;
buffer.dina <= rom_data;
buffer.addra <= buffer.addra + 1;
rom_addr <= rom_addr + 1;
end
ENDWRITE1, ENDWRITE2:
begin
buffer.ena <= 1;
buffer.dina <= rom_data;
buffer.addra <= buffer.addra + 1;
end
ENDWRITE3: begin
buffer.ena <= 0;
buffer.dina <= rom_data;
buffer.addra <= buffer.addra + 1;
ready <= 1;
end
WAIT: ;
default: begin
rom_addr <= 0;
rom_enable <= 0;
buffer.addra <= 0;
buffer.dina <= 0;
buffer.ena <= 0;
ready <= 0;
end
endcase
end
//sequential clocking block
always_ff @(posedge clk)
begin
if (reset)
current <= RESET;
else
current <= next;
end
endmodule

View File

@ -1,445 +0,0 @@
/****
* sd_controller.sv - Initializes and reads data off an sd card, feeding it
* into the audio buffer
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/25
*
* **/
module sd_controller(
(* MARK_DEBUG = "TRUE" *)
input logic slow_clk,
(* MARK_DEBUG = "TRUE" *)
input logic fast_clk,
input logic crc_clk,
input logic mem_clk,
input logic reset,
(* MARK_DEBUG = "TRUE" *)
input logic [3:0] sd_data,
inout logic sd_cmd,
output logic ready,
output wire clk,
audio_buffer_interface.driver buffer
);
// NOTE: this gets encoded as one-hot, even if in here I set it as a logic[5:0]
enum logic [5:0] {
INIT,WAIT,SEND_CMD0,WAIT_CMD0,DELAY_CMD0, // last 4
SEND_CMD8,WAIT_CMD8,LISTEN_RESPONSE_CMD8,WAIT_RESPONSE_CMD8, // last 8
SEND_CMD55,WAIT_CMD55,LISTEN_RESPONSE_CMD55,WAIT_RESPONSE_CMD55, // last 12
SEND_ACMD41,WAIT_ACMD41,LISTEN_RESPONSE_ACMD41,WAIT_RESPONSE_ACMD41,ACMD41_DELAY, //17
SEND_CMD2,WAIT_CMD2,LISTEN_RESPONSE_CMD2,WAIT_RESPONSE_CMD2, //21
SEND_CMD3,WAIT_CMD3,LISTEN_RESPONSE_CMD3,WAIT_RESPONSE_CMD3, //25
SEND_CMD7,WAIT_CMD7,LISTEN_RESPONSE_CMD7,WAIT_RESPONSE_CMD7, //29
SEND2_CMD55,WAIT2_CMD55,LISTEN_RESPONSE2_CMD55,WAIT_RESPONSE2_CMD55,
SEND_ACMD6,WAIT_ACMD6,LISTEN_RESPONSE_ACMD6,WAIT_RESPONSE_ACMD6,
READY_TO_TRANSMIT,
DELAY_CLOCK_SWITCH,
TRANSMIT,WAIT_TRANSMIT,WAIT_END,FINISH_TRANSMIT,
TRANSMIT2,WAIT_TRANSMIT2,WAIT_END2,FINISH_TRANSMIT2,
WAIT_FOR_BUFFER
} state, next_state;
logic fast_clk_enable;
assign clk = fast_clk_enable ? fast_clk : slow_clk;
logic [$clog2(4114):0] counter;
logic sd_buffer_half;
logic [31:0] address;
(* MARK_DEBUG = "TRUE" *)
logic send_command_start;//, send_command_start_fast;
(* MARK_DEBUG = "TRUE" *)
logic [5:0] cmd;
logic [31:0] arg;
(* MARK_DEBUG = "TRUE" *)
wire send_command_ready;//, send_command_ready_fast;
(* MARK_DEBUG = "TRUE" *)
logic stored_sd_cmd;
// This needs to swap speeds
send_command slowSender(
clk,
crc_clk,
reset,
send_command_start,
cmd,
arg,
send_command_ready,
sd_cmd);
//send_command fastSender(
// fast_clk,
// crc_clk,
// reset,
// send_command_start_fast,
// cmd,
// arg,
// send_command_ready_fast,
// sd_cmd);
(* MARK_DEBUG = "TRUE" *)
logic read_command_listen;
logic [2:0] response_type;
(* MARK_DEBUG = "TRUE" *)
wire read_command_received;
wire [135:0] out_data;
// Hopefully this doesn't get optimized out...
(* MARK_DEBUG = "TRUE" *)
logic [47:0] received_data;
assign received_data = out_data[47:0];
// This doesn't need to swap speeds as we ignore responses to CMD17
read_command slowReader(
slow_clk,
reset,
read_command_listen,
response_type,
sd_cmd,
read_command_received,
out_data
);
// The data line is only ever used at fast_clk speeds
read_data dataHandler(
fast_clk,
mem_clk,
reset,
sd_data,
buffer
);
//always_ff @(posedge crc_clk) begin
// stored_sd_cmd <= sd_cmd;
//end
// Next state logic
always_comb begin
case (state)
INIT: next_state=WAIT;
WAIT:
if (counter==0)
next_state=SEND_CMD0;
else
next_state=WAIT;
SEND_CMD0:
next_state=WAIT_CMD0;
WAIT_CMD0:
if (send_command_ready)
next_state=DELAY_CMD0;
else
next_state=WAIT_CMD0;
DELAY_CMD0:
if (counter == 0)
next_state=SEND_CMD8;
else
next_state=DELAY_CMD0;
// These state transitions are all very similar, this probably could
// be a macro
SEND_CMD8:
next_state=WAIT_CMD8;
WAIT_CMD8:
if (send_command_ready)
next_state=LISTEN_RESPONSE_CMD8;
else
next_state=WAIT_CMD8;
LISTEN_RESPONSE_CMD8:
next_state=WAIT_RESPONSE_CMD8;
WAIT_RESPONSE_CMD8:
if (read_command_received)
next_state=SEND_CMD55;
else
next_state=WAIT_RESPONSE_CMD8;
SEND_CMD2:
next_state=WAIT_CMD2;
WAIT_CMD2:
if (send_command_ready)
next_state=LISTEN_RESPONSE_CMD2;
else
next_state=WAIT_CMD2;
LISTEN_RESPONSE_CMD2:
next_state=WAIT_RESPONSE_CMD2;
WAIT_RESPONSE_CMD2:
if (read_command_received)
next_state=SEND_CMD3;
else
next_state=WAIT_RESPONSE_CMD2;
SEND_CMD3:
next_state=WAIT_CMD3;
WAIT_CMD3:
if (send_command_ready)
next_state=LISTEN_RESPONSE_CMD3;
else
next_state=WAIT_CMD3;
LISTEN_RESPONSE_CMD3:
next_state=WAIT_RESPONSE_CMD3;
WAIT_RESPONSE_CMD3:
if (read_command_received)
next_state=SEND_CMD7;
else
next_state=WAIT_RESPONSE_CMD3;
SEND_CMD7:
next_state=WAIT_CMD7;
WAIT_CMD7:
if (send_command_ready)
next_state=LISTEN_RESPONSE_CMD7;
else
next_state=WAIT_CMD7;
LISTEN_RESPONSE_CMD7:
next_state=WAIT_RESPONSE_CMD7;
WAIT_RESPONSE_CMD7:
if (read_command_received)
next_state=SEND2_CMD55;
else
next_state=WAIT_RESPONSE_CMD7;
SEND_CMD55:
next_state=WAIT_CMD55;
WAIT_CMD55:
if (send_command_ready)
next_state=LISTEN_RESPONSE_CMD55;
else
next_state=WAIT_CMD55;
LISTEN_RESPONSE_CMD55:
next_state=WAIT_RESPONSE_CMD55;
WAIT_RESPONSE_CMD55:
if (read_command_received)
next_state=SEND_ACMD41;
else
next_state=WAIT_RESPONSE_CMD55;
SEND_ACMD41:
next_state=WAIT_ACMD41;
WAIT_ACMD41:
if (send_command_ready)
next_state=LISTEN_RESPONSE_ACMD41;
else
next_state=WAIT_ACMD41;
LISTEN_RESPONSE_ACMD41:
next_state=WAIT_RESPONSE_ACMD41;
WAIT_RESPONSE_ACMD41:
if (read_command_received && !out_data[39])
next_state=ACMD41_DELAY;
else if (read_command_received && out_data[39])
next_state=SEND_CMD2;
else
next_state=WAIT_RESPONSE_ACMD41;
ACMD41_DELAY:
if (counter == 0)
next_state=SEND_CMD55;
else
next_state=ACMD41_DELAY;
SEND2_CMD55:
next_state=WAIT2_CMD55;
WAIT2_CMD55:
if (send_command_ready)
next_state=LISTEN_RESPONSE2_CMD55;
else
next_state=WAIT2_CMD55;
LISTEN_RESPONSE2_CMD55:
next_state=WAIT_RESPONSE2_CMD55;
WAIT_RESPONSE2_CMD55:
if (read_command_received)
next_state=SEND_ACMD6;
else
next_state=WAIT_RESPONSE2_CMD55;
SEND_ACMD6:
next_state=WAIT_ACMD6;
WAIT_ACMD6:
if (send_command_ready)
next_state=LISTEN_RESPONSE_ACMD6;
else
next_state=WAIT_ACMD6;
LISTEN_RESPONSE_ACMD6:
next_state=WAIT_RESPONSE_ACMD6;
WAIT_RESPONSE_ACMD6:
if (read_command_received)
next_state=READY_TO_TRANSMIT;
else
next_state=WAIT_RESPONSE_ACMD6;
READY_TO_TRANSMIT:
next_state=DELAY_CLOCK_SWITCH;
DELAY_CLOCK_SWITCH:
if (counter == 0)
next_state = TRANSMIT;
else
next_state = DELAY_CLOCK_SWITCH;
TRANSMIT:
next_state=WAIT_TRANSMIT;
WAIT_TRANSMIT:
if (sd_data==0)
next_state=WAIT_END;
else
next_state=WAIT_TRANSMIT;
WAIT_END:
if (counter==0)
next_state=FINISH_TRANSMIT;
else
next_state=WAIT_END;
FINISH_TRANSMIT:
next_state=TRANSMIT2;
TRANSMIT2:
next_state=WAIT_TRANSMIT2;
WAIT_TRANSMIT2:
if (sd_data==0)
next_state=WAIT_END2;
else
next_state=WAIT_TRANSMIT2;
WAIT_END2:
if (counter==0)
next_state=FINISH_TRANSMIT2;
else
next_state=WAIT_END2;
FINISH_TRANSMIT2:
next_state=WAIT_FOR_BUFFER;
WAIT_FOR_BUFFER:
if (sd_buffer_half==buffer.address_half)
next_state=WAIT_FOR_BUFFER;
else
next_state=TRANSMIT;
default:
next_state=INIT;
endcase
end
// This could mostly swap speeds ... however detecting the data line going low
// would not work
always_ff @(posedge clk) begin
stored_sd_cmd <= sd_cmd;
// Transition states
if (reset)
state <= INIT;
else
state <= next_state;
// Sequential outputs/logic
case (state)
INIT: begin
counter <= 80;
fast_clk_enable <= 0;
end
SEND_CMD0: begin
cmd<=0;
arg<=0;
send_command_start <= 1;
end
WAIT_CMD0: begin
counter<=20;
send_command_start<=0;
end
SEND_CMD8: begin
cmd <=8;
arg <='h1AA;
send_command_start <=1;
end
LISTEN_RESPONSE_CMD8: begin
response_type <= 7;
read_command_listen <= 1;
end
SEND_CMD55: begin
cmd <= 55;
arg <= 0;
send_command_start <=1;
end
SEND2_CMD55: begin
cmd <= 55;
// the arg should be the same as the preceding command
// and otherwise we'll lose the RCA bits
//arg <= 0;
send_command_start <=1;
end
LISTEN_RESPONSE_CMD55,LISTEN_RESPONSE2_CMD55: begin
response_type <= 1;
read_command_listen <= 1;
end
SEND_ACMD41: begin
cmd <= 41;
arg <= 'h40100000;
send_command_start <=1;
end
LISTEN_RESPONSE_ACMD41: begin
response_type <= 3;
read_command_listen <= 1;
end
WAIT_RESPONSE_ACMD41: begin
read_command_listen<=0;
counter<=100;
end
SEND_ACMD6: begin
cmd <= 6;
arg <= 'b10;
send_command_start <=1;
end
LISTEN_RESPONSE_ACMD6: begin
response_type <= 1;
read_command_listen <= 1;
end
SEND_CMD2: begin
cmd <= 2;
arg <= 0;
send_command_start <=1;
end
LISTEN_RESPONSE_CMD2: begin
response_type <= 2;
read_command_listen <= 1;
end
SEND_CMD3: begin
cmd <= 3;
arg <= 0;
send_command_start <=1;
end
LISTEN_RESPONSE_CMD3: begin
response_type <= 6;
read_command_listen <= 1;
end
SEND_CMD7: begin
cmd <= 7;
arg <= {out_data[39:24],16'h0000};
send_command_start <=1;
end
LISTEN_RESPONSE_CMD7: begin
response_type <= 1;
read_command_listen <= 1;
end
READY_TO_TRANSMIT: begin
fast_clk_enable <= 1;
address <= 0;
sd_buffer_half <= 0;
// Wait to actually transmit until clock is running and stable
counter <= 100;
end
TRANSMIT, TRANSMIT2: begin
cmd <= 17;
arg <= address;
send_command_start <= 1;
end
WAIT_TRANSMIT, WAIT_TRANSMIT2: begin
send_command_start <= 0;
counter <= 512*2+16+1;
end
FINISH_TRANSMIT:
address <= address +1;
FINISH_TRANSMIT2: begin
address <= address +1;
sd_buffer_half <= ~sd_buffer_half;
end
WAIT_FOR_BUFFER:
ready <= 1;
// The logic is simple enough in these to group them
WAIT, DELAY_CMD0, ACMD41_DELAY, WAIT_END, WAIT_END2, DELAY_CLOCK_SWITCH:
counter <= counter - 1;
WAIT_CMD8,WAIT_CMD55,WAIT_ACMD41,WAIT2_CMD55,WAIT_ACMD6,WAIT_CMD2,WAIT_CMD3,WAIT_CMD7:
send_command_start<=0;
WAIT_RESPONSE_CMD8,WAIT_RESPONSE_CMD55,WAIT_RESPONSE2_CMD55,WAIT_RESPONSE_ACMD6,
WAIT_RESPONSE_CMD2,WAIT_RESPONSE_CMD3,WAIT_RESPONSE_CMD7:
read_command_listen<=0;
default: ;
endcase
end
endmodule

View File

@ -1,113 +0,0 @@
/***
* send_command.sv - sends sd card commands. It takes in a command and an
* argument and will figure out the necessary crc.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* */
module send_command(
input clk,
// The crc should be clocked way faster than the sender
input crc_clk,
input reset,
input start,
input [5:0] command,
input [31:0] arguments,
output logic ready,
output wire sd_cmd
);
(* MARK_DEBUG = "TRUE" *)
logic [47:0] to_send;
logic crc_start;
wire crc_ready;
logic [6:0] crc;
logic [$clog2(48):0] counter;
(* MARK_DEBUG = "TRUE" *)
logic send_sd_cmd;
enum logic [2:0] {READY, SEND_CRC, DELAY, WAIT_CRC, SEND_DATA} cur_state, next_state;
// We theoretically could speed up sd card initialization by hardcoding the
// CRCs for it, but wasting an extra couple of cycles at 400khz shouldn't
// really matter
crc_gen crcGen(crc_clk,reset,crc_start,to_send[47-:40],crc_ready,crc);
// State transitions
always_comb begin
case (cur_state)
READY:
if (start)
next_state = SEND_CRC;
else
next_state = READY;
SEND_CRC:
next_state = DELAY;
DELAY:
next_state = WAIT_CRC;
WAIT_CRC:
if (crc_ready)
next_state = SEND_DATA;
else
next_state = WAIT_CRC;
SEND_DATA:
if (counter != 1)
next_state = SEND_DATA;
else
next_state = READY;
default:
next_state = READY;
endcase
end
assign sd_cmd = send_sd_cmd ? 'z : 0;
// BUG SPOTTED: Too slow, make the output more reactive
// Added start input check to achieve this
assign ready = (cur_state == READY && !start);
// Sequential logic
always_ff @(posedge clk) begin
// Default to high-z
send_sd_cmd <= 1;
case (cur_state)
READY:
begin
counter <= 48;
end
SEND_CRC:
begin
to_send <= {1'b0, 1'b1, command, arguments, 8'b1};
crc_start <= 1;
end
DELAY:
crc_start <= 0;
WAIT_CRC:
to_send[7:1] <= crc;
SEND_DATA:
begin
counter <= counter - 1;
send_sd_cmd <= to_send[counter-1];
end
default: ;
endcase
end
always_ff @(posedge clk) begin
if (reset) begin
cur_state <= READY;
end
else begin
cur_state <= next_state;
end
end
endmodule

10
design/seconds_display.sv Normal file
View File

@ -0,0 +1,10 @@
module seconds_display(
input logic clk,
input logic reset,
input [$clog2(60)-1:0] counter,
output [7:0] display_tens,
output [7:0] display_ones
);
endmodule

View File

@ -1,36 +0,0 @@
/***
* display_anode_driver.sv - Turns on a single anode of a single digit at a time,
* rapidly rotating through all of them, generating
* a solid-looking display even though only one digit
* is on at a time.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6-12-2025
*
* */
// NOTE: This expects to be driven with a 100khz clock but can be altered in
// the nexys_a7_top.sv file.
module display_anode_driver(
input logic clk,
input logic reset,
output logic [7:0] AN,
output logic [2:0] mux_select);
// Initialize this once, it can be free-running after
logic started;
// This is just a shift register that drives each anode individually
always_ff @(posedge clk) begin
if (reset) begin
AN <= '1 - 1;
mux_select <= 0;
started <= 1;
end
else begin
AN <= {AN[6:0], AN[7]};
// Letting this overflow will automatically reset it
mux_select <= mux_select + 1;
end
end
endmodule

View File

@ -1,62 +0,0 @@
/**
* display_converter.sv - decodes a 5 bit digit input into its seven segment
* display equivalent using a lookup table. Display can
* do 0 - 9, A - F, individual segments and special
* characters.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25
*
****/
module display_converter(
input logic [4:0] digit,
output logic [6:0] segment
);
localparam ROM_SIZE=32;
//ROM lookup table for seven segment display
//blanks are unused space we could add characters to.
localparam logic [6:0] segment_rom [0:ROM_SIZE-1] = '{
7'b1111110, //0
7'b0000110, //1
7'b1101101, //2
7'b1111001, //3
7'b0110011, //4
7'b1011011, //5
7'b1011111, //6
7'b1110000, //7
7'b1111111, //8
7'b1111011, //9
7'b1110111, //A
7'b0011111, //B
7'b1001110, //C
7'b0111101, //D
7'b1001111, //E
7'b1000111, //F
7'b1000000, //segment a
7'b0100000, //segment b
7'b0010000, //segment c
7'b0001000, //segment d
7'b0000100, //segment e
7'b0000001, //segment f
7'b0110111, //H
7'b0001110, //L
7'b1110111, //R
7'b0000110, //l
7'b0000101, //r
7'b0000000, //blank
7'b0000000, //blank
7'b0000000, //blank
7'b0000000, //blank
7'b0000000 //blank
};
//use digit input to index segment_rom lookup table.
assign segment = segment_rom[digit];
endmodule

View File

@ -1,32 +0,0 @@
/***
* sixty_display.sv - converts a binary digit from zero to fifty-nine to its
* ones and tens digits and then gets the seven segment
* display equivalents of them.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25
*
*/
module sixty_display
(
input [$clog2(60)-1:0] number,
output [6:0] display_tens,
output [6:0] display_ones
);
logic [4:0] ones_digit;
logic [4:0] tens_digit;
//convert digit to ones and tens places
always_comb
begin
ones_digit = number % 10;
tens_digit = number / 10;
end
//convert both ones and tens place digits to their seven segement equivalent
display_converter ones (ones_digit, display_ones);
display_converter tens (tens_digit, display_tens);
endmodule

View File

@ -1,49 +0,0 @@
## Bugs I Found
### Audio Buffer
- Forgot to assign to a delay counter
### Debouncer
- Logic was fundamentally wrong
- Found multiple logic bugs with testbench and then assertions
### Display Converter
- Found a typo in a single digit
### Low Freq Clock Gen
- Was initially trying to do modulo at max clock speed, failing timing
### sd_rom
- ROM was getting totally optimized out and was doing nothing in simulation, and
didn't show up in synthesized design
- Timing issues, ROM was one cycle slower than expected, latching takes an extra
cycle too, had to rework state machines, there are a bonus 2 delay states when
starting and ending writes
### PWM
- major design problems
- clocked too slow
- initial goal of 16-bit audio isn't feasible because 100MHz isn't fast enough
to pwm based on a 16-bit counter, would give a sample rate of 1.5khz
### 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
- counter was being set in multiple blocks, caught by synthesis
- output phase too long, caught in hw
### 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
### modular_clock
- stopped ticking on reset
- meant that every module using these clocks w/ a synchronous reset would get
stuck and never reset
- found during hw debugging

View File

@ -1,22 +0,0 @@
digraph playback_controller {
PAUSE [shape="doublecircle",label="PAUSE\nspeed=0"];
node [shape="ellipse"]
PLAY [label="PLAY\nspeed=1"];
FF2 [label="FF2\nspeed=2"];
FF4 [label="FF4\nspeed=4"];
FF8 [label="FF8\nspeed=8"];
FF16 [label="FF16\nspeed=16"];
PAUSE -> PLAY [label="play_pulse"]
PLAY -> PAUSE [label="play_pulse"]
PLAY -> FF2 [label="ff_pulse"]
FF2 -> FF4 [label="ff_pulse"]
FF4 -> FF8 [label="ff_pulse"]
FF8 -> FF16 [label="ff_pulse"]
FF2 -> PAUSE [label="play_pulse"];
FF4 -> PAUSE [label="play_pulse"];
FF8 -> PAUSE [label="play_pulse"];
FF16 -> PAUSE [label="play_pulse"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

View File

@ -1,24 +0,0 @@
digraph read_command {
IDLE [shape="doublecircle",label="IDLE\nreceived_reg=0\nout_data=0\nresponse_type_reg=response_type"]
node [shape="ellipse"]
START [label="START\nrecevied_reg=0\ncounter=get_bits(response_type_reg) - 2\ndata_reg=0"]
LISTEN [label="LISTEN\ndata_reg[0]=sd_cmd"]
RECEIVING [label="RECEIVING\ncounter--\ndata_reg={data_reg[134:0],sd_cmd}"]
DONE [label="DONE\nout_data=data_reg\nreceived_reg=1\nreponse_type_reg=response_type"]
IDLE -> IDLE [label="!listen"]
IDLE -> START [label="listen"]
START -> RECEIVING [label="sd_cmd==0"]
START -> LISTEN [label="sd_cmd!=0"]
LISTEN -> LISTEN [label="sd_cmd!=0"]
LISTEN -> RECEIVING [label="sd_cmd==0"]
RECEIVING -> DONE [label="counter==0"]
RECEIVING -> RECEIVING [label="counter!=0"]
DONE -> START [label="listen"]
DONE -> DONE [label="!listen"]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

View File

@ -1,30 +0,0 @@
digraph rom_sd {
Reset [shape = doublecircle, label = "RESET\nbuffer_half = 0\nrom_addr = 0\nrom_enable = 1\nbuffer.addra=0\nready=0"];
node [shape = circle];
Delay1 [label="DELAY1\nrom_addr++"];
Delay2 [label="DELAY2\nrom_addr++"];
Delay3 [label="DELAY3\nrom_addr++\nbuffer.dina=rom_data\nbuffer.ena=1"];
WriteBuf [label="WRITEBUF\nbuffer.ena=1\nbuffer.dina=rom_data\nbuffer.addra++\nrom_addr++"];
EndWrite1 [label="ENDWRITE1\nbuffer.ena=1\nbuffer.data=rom_data\nbuffer.addra++"];
EndWrite2 [label="ENDWRITE2\nbuffer.ena=1\nbuffer.data=rom_data\nbuffer.addra++"];
EndWrite3 [label="ENDWRITE3\nbuffer.ena=0\nbuffer.data=rom_data\nbuffer.addra++\nready=1"];
Wait [label = "WAIT"];
Reset -> Reset [label="reset"];
Reset -> Delay1 [label="!reset"];
Delay1 -> Delay2;
Delay2 -> Delay3;
Delay3 -> WriteBuf;
WriteBuf -> WriteBuf [label="buffer.addra < 1023"]
WriteBuf -> EndWrite1 [label="buffer.addra == 1023"]
EndWrite1 -> EndWrite2;
EndWrite2 -> EndWrite3;
EndWrite3 -> Wait;
Wait -> Wait [label = "buffer_half == buffer.address_half"]
Wait -> Delay1 [label = "buffer_half != buffer.address_half"]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

View File

@ -1,161 +0,0 @@
digraph sd_controller {
// Rough steps
INIT [shape=doublecircle, label="INIT\ncounter=80\nclk_source=slow"];
node [shape=ellipse]
// Tick at slow speed (100khz? 400khz?) for 80 ticks
WAIT [label="WAIT\ncounter--"];
// Send CMD0 with arg 0
SEND_CMD0 [label="SEND_CMD0\ncmd=0\narg=0\nstart=1"];
// There is no response to CMD0, so tick for 20 more cycles then send CMD8
WAIT_CMD0 [label="WAIT_CMD0\ncounter=20\nstart=0"];
DELAY_CMD0 [label="DELAY_CMD0\ncounter--"];
// Send CMD8
SEND_CMD8 [label="SEND_CMD8\ncmd=8\narg=0x1AA\nstart=1"];
WAIT_CMD8 [label="WAIT_CMD8\nstart=0"];
LISTEN_RESPONSE_CMD8 [label="LISTEN_RESPONSE_CMD8\nresponse_type=7\nread_command.listen=1"]
WAIT_RESPONSE_CMD8 [label="WAIT_RESPONSE_CMD8\nread_command.listen=0"];
INIT -> WAIT;
WAIT -> WAIT [label="counter!=0"];
WAIT -> SEND_CMD0 [label="counter==0"];
SEND_CMD0 -> WAIT_CMD0;
WAIT_CMD0 -> DELAY_CMD0 [label="send_command.ready"];
WAIT_CMD0 -> WAIT_CMD0 [label="!send_command.ready"]
DELAY_CMD0 -> DELAY_CMD0 [label="counter!=0"];
DELAY_CMD0 -> SEND_CMD8 [label="counter==0"]
SEND_CMD8 -> WAIT_CMD8;
WAIT_CMD8 -> WAIT_CMD8 [label="!send_command.ready"]
WAIT_CMD8 -> LISTEN_RESPONSE_CMD8 [label="send_command.ready"]
LISTEN_RESPONSE_CMD8 -> WAIT_RESPONSE_CMD8;
WAIT_RESPONSE_CMD8 -> WAIT_RESPONSE_CMD8 [label="!read_command.received"]
// Send CMD55+CMD41 with arg 40100000 until card is ready
SEND_CMD55 [label="SEND_CMD55\ncmd=55\narg=0\nstart=1"];
WAIT_CMD55 [label="WAIT_CMD55\nstart=0"];
LISTEN_RESPONSE_CMD55 [label="LISTEN_RESPONSE_CMD55\nresponse_type=1\nread_command.listen=1"]
WAIT_RESPONSE_CMD55 [label="WAIT_RESPONSE_CMD55\nread_command.listen=0"]
SEND_ACMD41 [label="SEND_ACMD41\ncmd=41\narg=0x40100000\nstart=1"];
WAIT_ACMD41 [label="WAIT_ACMD41\nstart=0"];
LISTEN_RESPONSE_ACMD41 [label="LISTEN_RESPONSE_ACMD41\nresponse_type=3\nread_command.listen=1"]
WAIT_RESPONSE_ACMD41 [label="WAIT_RESPONSE_ACMD41\nread_command.listen=0\ncounter=100"];
// Delay trying this again
ACMD41_DELAY [label="ACMD41_DELAY\ncounter--"];
// Card is ready when bit31 is high
WAIT_RESPONSE_CMD8 -> SEND_CMD55 [label="read_command.received"]
SEND_CMD55 -> WAIT_CMD55;
WAIT_CMD55 -> WAIT_CMD55 [label="!send_command.ready"];
WAIT_CMD55 -> LISTEN_RESPONSE_CMD55 [label="send_command.ready"];
LISTEN_RESPONSE_CMD55 -> WAIT_RESPONSE_CMD55;
WAIT_RESPONSE_CMD55 -> WAIT_RESPONSE_CMD55 [label="!read_command.received"]
WAIT_RESPONSE_CMD55 -> SEND_ACMD41 [label="read_command.received"]
SEND_ACMD41 -> WAIT_ACMD41
WAIT_ACMD41 -> WAIT_ACMD41 [label="!send_command.ready"]
WAIT_ACMD41 -> LISTEN_RESPONSE_ACMD41[label="send_command.ready"]
LISTEN_RESPONSE_ACMD41 -> WAIT_RESPONSE_ACMD41
WAIT_RESPONSE_ACMD41 -> WAIT_RESPONSE_ACMD41 [label="!read_command.received"]
WAIT_RESPONSE_ACMD41 -> ACMD41_DELAY [label="read_command.received && !out_data[39]"]
ACMD41_DELAY -> ACMD41_DELAY [label="counter!=0"]
ACMD41_DELAY -> SEND_CMD55 [label="counter==0"]
// CMD2 with argument 0, dont need response
SEND_CMD2 [label="SEND_CMD2\ncmd=2\narg=0\nsend_command.start=1"];
WAIT_CMD2 [label="WAIT_CMD2\nsend_command.start=0"];
LISTEN_RESPONSE_CMD2 [label="LISTEN_RESPONSE_CMD2\nresponse_type=2\nread_command.listen=1"];
WAIT_RESPONSE_CMD2 [label="WAIT_RESPONSE_CMD2\nread_command.listen=0"];
WAIT_RESPONSE_ACMD41 -> SEND_CMD2 [label="read_command.received && out_data[39]"]
SEND_CMD2 -> WAIT_CMD2;
WAIT_CMD2 -> WAIT_CMD2 [label="!send_command.ready"]
WAIT_CMD2 -> LISTEN_RESPONSE_CMD2 [label="send_command.ready"]
LISTEN_RESPONSE_CMD2 -> WAIT_RESPONSE_CMD2;
WAIT_RESPONSE_CMD2 -> WAIT_RESPONSE_CMD2 [label="!read_command.received"]
// CMD3 with argument 0 to get RCA
SEND_CMD3 [label="SEND_CMD3\ncmd=3\narg=0\nsend_command.start=1"];
WAIT_CMD3 [label="WAIT_CMD3\nsend_command.start=0"];
LISTEN_RESPONSE_CMD3 [label="LISTEN_RESPONSE_CMD3\nresponse_type=6\nread_command.listen=1"];
WAIT_RESPONSE_CMD3 [label="WAIT_RESPONSE_CMD3\nread_command.listen=0"];
WAIT_RESPONSE_CMD2 -> SEND_CMD3 [label="read_command.received"]
SEND_CMD3 -> WAIT_CMD3
WAIT_CMD3 -> WAIT_CMD3 [label="!send_command.ready"]
WAIT_CMD3 -> LISTEN_RESPONSE_CMD3 [label="send_command.ready"]
LISTEN_RESPONSE_CMD3 -> WAIT_RESPONSE_CMD3;
WAIT_RESPONSE_CMD3 -> WAIT_RESPONSE_CMD3 [label="!read_command.received"]
// CMD7 to select the correct card given the RCA
SEND_CMD7 [label="SEND_CMD7\ncmd=7\narg={out_data[39:24],16'h0000}\nsend_command.start=1"];
WAIT_CMD7 [label="WAIT_CMD7\nsend_command.start=0"];
LISTEN_RESPONSE_CMD7 [label="LISTEN_RESPONSE_CMD7\nresponse_type=1\nread_command.listen=1"];
WAIT_RESPONSE_CMD7 [label="WAIT_RESPONSE_CMD7\nread_command.listen=0"];
WAIT_RESPONSE_CMD3 -> SEND_CMD7[label="read_command.received"]
SEND_CMD7 -> WAIT_CMD7;
WAIT_CMD7 -> WAIT_CMD7 [label="!send_command.ready"]
WAIT_CMD7 -> LISTEN_RESPONSE_CMD7 [label="send_command.ready"]
LISTEN_RESPONSE_CMD7 -> WAIT_RESPONSE_CMD7;
WAIT_RESPONSE_CMD7 -> WAIT_RESPONSE_CMD7 [label="!read_command.ready"]
// Send CMD55+CMD41 with arg 40100000 until card is ready
SEND2_CMD55 [label="SEND2_CMD55\ncmd=55\nstart=1"];
WAIT2_CMD55 [label="WAIT2_CMD55\nstart=0"];
LISTEN_RESPONSE2_CMD55 [label="LISTEN_RESPONSE2_CMD55\nresponse_type=1\nread_command.listen=1"]
WAIT_RESPONSE2_CMD55 [label="WAIT_RESPONSE2_CMD55\nread_command.listen=0"]
SEND_ACMD6[label="SEND_ACMD6\ncmd=6\narg=0x00000002\nstart=1"];
WAIT_ACMD6 [label="WAIT_ACMD6\nstart=0"];
LISTEN_RESPONSE_ACMD6 [label="LISTEN_RESPONSE_ACMD6\nresponse_type=1\nread_command.listen=1"]
WAIT_RESPONSE_ACMD6 [label="WAIT_RESPONSE_ACMD6\nread_command.listen=0\ncounter=100"];
WAIT_RESPONSE_CMD7 -> SEND2_CMD55 [label="read_command.received"]
SEND2_CMD55 -> WAIT2_CMD55;
WAIT2_CMD55 -> WAIT2_CMD55 [label="!send_command.ready"];
WAIT2_CMD55 -> LISTEN_RESPONSE2_CMD55 [label="send_command.ready"];
LISTEN_RESPONSE2_CMD55 -> WAIT_RESPONSE2_CMD55;
WAIT_RESPONSE2_CMD55 -> WAIT_RESPONSE2_CMD55 [label="!read_command.received"]
WAIT_RESPONSE2_CMD55 -> SEND_ACMD6 [label="read_command.received"]
SEND_ACMD6 -> WAIT_ACMD6
WAIT_ACMD6 -> WAIT_ACMD6 [label="!send_command.ready"]
WAIT_ACMD6 -> LISTEN_RESPONSE_ACMD6[label="send_command.ready"]
LISTEN_RESPONSE_ACMD6 -> WAIT_RESPONSE_ACMD6
WAIT_RESPONSE_ACMD6 -> WAIT_RESPONSE_ACMD6 [label="!read_command.received"]
// Now we can finally read blocks with CMD17
// Swap over to the fast clock
READY_TO_TRANSMIT [label="READY_TO_TRANSMIT\nclk_source=fast\naddress=0\nbuffer_half=0\ncounter=100"];
DELAY_CLOCK_SWITCH [label="DELAY_CLOCK_SWITCH\ncounter--"]
// There are two sets of states because we need to read two blocks at once
TRANSMIT [label="TRANSMIT\ncmd=17\narg=address\nsend_command.start=1"];
WAIT_TRANSMIT [label="WAIT_TRANSMIT\nsend_command.start=0\ncounter=4114"];
WAIT_END [label="WAIT_END\ncounter--"];
FINISH_TRANSMIT [label="FINISH_TRANSMIT\naddress++"]
TRANSMIT2 [label="TRANSMIT2\ncmd=17\narg=address\nsend_command.start=1"];
WAIT_TRANSMIT2 [label="WAIT_TRANSMIT2\nsend_command.start=0\ncounter=4114"];
WAIT_END2 [label="WAIT_END2\ncounter--"];
FINISH_TRANSMIT2 [label="FINISH_TRANSMIT2\naddress++\nsd_buffer_half=!sd_buffer_half"]
// Wait for the buffer to be free, then go back to TRANSMIT
WAIT_FOR_BUFFER [label="WAIT_FOR_BUFFER\nready=1"];
WAIT_RESPONSE_ACMD6 -> READY_TO_TRANSMIT [label="read_command.ready"]
READY_TO_TRANSMIT -> DELAY_CLOCK_SWITCH;
DELAY_CLOCK_SWITCH -> TRANSMIT [label="counter==0"];
DELAY_CLOCK_SWITCH -> DELAY_CLOCK_SWITCH [label="counter!=0"];
TRANSMIT -> WAIT_TRANSMIT;
WAIT_TRANSMIT -> WAIT_TRANSMIT [label="sd_data==1"]
WAIT_TRANSMIT -> WAIT_END [label="sd_data==0"]
WAIT_END -> WAIT_END [label="counter!=0"]
WAIT_END -> FINISH_TRANSMIT [label="counter==0"]
FINISH_TRANSMIT -> TRANSMIT2;
TRANSMIT2 -> WAIT_TRANSMIT2;
WAIT_TRANSMIT2 -> WAIT_TRANSMIT2 [label="sd_data==1"]
WAIT_TRANSMIT2 -> WAIT_END2 [label="sd_data==0"]
WAIT_END2 -> WAIT_END2 [label="counter!=0"]
WAIT_END2 -> FINISH_TRANSMIT2 [label="counter==0"]
FINISH_TRANSMIT2 -> WAIT_FOR_BUFFER;
WAIT_FOR_BUFFER -> WAIT_FOR_BUFFER [label="sd_buffer_half==audio_buffer.address_half"];
WAIT_FOR_BUFFER -> TRANSMIT [label="sd_buffer_half!=audio_buffer.address_half"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 KiB

View File

@ -1,905 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 12.2.1 (0)
-->
<!-- Title: sd_controller Pages: 1 -->
<svg width="880pt" height="5892pt"
viewBox="0.00 0.00 879.78 5891.99" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 5887.99)">
<title>sd_controller</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-5887.99 875.78,-5887.99 875.78,4 -4,4"/>
<!-- INIT -->
<g id="node1" class="node">
<title>INIT</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5803.45" rx="76.54" ry="76.54"/>
<ellipse fill="none" stroke="black" cx="595" cy="-5803.45" rx="80.54" ry="80.54"/>
<text text-anchor="middle" x="595" y="-5814.9" font-family="Times,serif" font-size="14.00">INIT</text>
<text text-anchor="middle" x="595" y="-5798.4" font-family="Times,serif" font-size="14.00">counter=80</text>
<text text-anchor="middle" x="595" y="-5781.9" font-family="Times,serif" font-size="14.00">clk_source=slow</text>
</g>
<!-- WAIT -->
<g id="node2" class="node">
<title>WAIT</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5656.91" rx="46.32" ry="28.99"/>
<text text-anchor="middle" x="595" y="-5660.11" font-family="Times,serif" font-size="14.00">WAIT</text>
<text text-anchor="middle" x="595" y="-5643.61" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- INIT&#45;&gt;WAIT -->
<g id="edge1" class="edge">
<title>INIT&#45;&gt;WAIT</title>
<path fill="none" stroke="black" d="M595,-5722.57C595,-5713.9 595,-5705.37 595,-5697.51"/>
<polygon fill="black" stroke="black" points="598.5,-5697.65 595,-5687.65 591.5,-5697.65 598.5,-5697.65"/>
</g>
<!-- WAIT&#45;&gt;WAIT -->
<g id="edge2" class="edge">
<title>WAIT&#45;&gt;WAIT</title>
<path fill="none" stroke="black" d="M639.49,-5665.71C650.81,-5665.13 659.32,-5662.2 659.32,-5656.91 659.32,-5653.61 655.99,-5651.22 650.74,-5649.76"/>
<polygon fill="black" stroke="black" points="651.39,-5646.31 640.98,-5648.33 650.37,-5653.24 651.39,-5646.31"/>
<text text-anchor="middle" x="689.32" y="-5651.86" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- SEND_CMD0 -->
<g id="node3" class="node">
<title>SEND_CMD0</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5523.09" rx="68.06" ry="52.33"/>
<text text-anchor="middle" x="595" y="-5542.79" font-family="Times,serif" font-size="14.00">SEND_CMD0</text>
<text text-anchor="middle" x="595" y="-5526.29" font-family="Times,serif" font-size="14.00">cmd=0</text>
<text text-anchor="middle" x="595" y="-5509.79" font-family="Times,serif" font-size="14.00">arg=0</text>
<text text-anchor="middle" x="595" y="-5493.29" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- WAIT&#45;&gt;SEND_CMD0 -->
<g id="edge3" class="edge">
<title>WAIT&#45;&gt;SEND_CMD0</title>
<path fill="none" stroke="black" d="M595,-5627.63C595,-5615.69 595,-5601.28 595,-5587.05"/>
<polygon fill="black" stroke="black" points="598.5,-5587.24 595,-5577.24 591.5,-5587.24 598.5,-5587.24"/>
<text text-anchor="middle" x="626.88" y="-5596.62" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- WAIT_CMD0 -->
<g id="node4" class="node">
<title>WAIT_CMD0</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5393.11" rx="67.53" ry="40.66"/>
<text text-anchor="middle" x="595" y="-5404.56" font-family="Times,serif" font-size="14.00">WAIT_CMD0</text>
<text text-anchor="middle" x="595" y="-5388.06" font-family="Times,serif" font-size="14.00">counter=20</text>
<text text-anchor="middle" x="595" y="-5371.56" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND_CMD0&#45;&gt;WAIT_CMD0 -->
<g id="edge4" class="edge">
<title>SEND_CMD0&#45;&gt;WAIT_CMD0</title>
<path fill="none" stroke="black" d="M595,-5470.41C595,-5462.2 595,-5453.72 595,-5445.52"/>
<polygon fill="black" stroke="black" points="598.5,-5445.69 595,-5435.69 591.5,-5445.69 598.5,-5445.69"/>
</g>
<!-- WAIT_CMD0&#45;&gt;WAIT_CMD0 -->
<g id="edge6" class="edge">
<title>WAIT_CMD0&#45;&gt;WAIT_CMD0</title>
<path fill="none" stroke="black" d="M660.62,-5403.55C672.34,-5402.19 680.53,-5398.71 680.53,-5393.11 680.53,-5389.52 677.17,-5386.8 671.67,-5384.95"/>
<polygon fill="black" stroke="black" points="672.61,-5381.57 662.11,-5382.97 671.19,-5388.43 672.61,-5381.57"/>
<text text-anchor="middle" x="742.78" y="-5388.06" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- DELAY_CMD0 -->
<g id="node5" class="node">
<title>DELAY_CMD0</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5270.96" rx="75.48" ry="28.99"/>
<text text-anchor="middle" x="595" y="-5274.16" font-family="Times,serif" font-size="14.00">DELAY_CMD0</text>
<text text-anchor="middle" x="595" y="-5257.66" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- WAIT_CMD0&#45;&gt;DELAY_CMD0 -->
<g id="edge5" class="edge">
<title>WAIT_CMD0&#45;&gt;DELAY_CMD0</title>
<path fill="none" stroke="black" d="M595,-5352.1C595,-5339.14 595,-5324.77 595,-5311.82"/>
<polygon fill="black" stroke="black" points="598.5,-5311.92 595,-5301.92 591.5,-5311.92 598.5,-5311.92"/>
<text text-anchor="middle" x="655" y="-5321.15" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- DELAY_CMD0&#45;&gt;DELAY_CMD0 -->
<g id="edge7" class="edge">
<title>DELAY_CMD0&#45;&gt;DELAY_CMD0</title>
<path fill="none" stroke="black" d="M666.33,-5280.75C679.35,-5279.51 688.48,-5276.24 688.48,-5270.96 688.48,-5267.32 684.17,-5264.65 677.24,-5262.92"/>
<polygon fill="black" stroke="black" points="678.25,-5259.54 667.82,-5261.41 677.14,-5266.45 678.25,-5259.54"/>
<text text-anchor="middle" x="718.48" y="-5265.91" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- SEND_CMD8 -->
<g id="node6" class="node">
<title>SEND_CMD8</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5137.14" rx="68.06" ry="52.33"/>
<text text-anchor="middle" x="595" y="-5156.84" font-family="Times,serif" font-size="14.00">SEND_CMD8</text>
<text text-anchor="middle" x="595" y="-5140.34" font-family="Times,serif" font-size="14.00">cmd=8</text>
<text text-anchor="middle" x="595" y="-5123.84" font-family="Times,serif" font-size="14.00">arg=0x1AA</text>
<text text-anchor="middle" x="595" y="-5107.34" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- DELAY_CMD0&#45;&gt;SEND_CMD8 -->
<g id="edge8" class="edge">
<title>DELAY_CMD0&#45;&gt;SEND_CMD8</title>
<path fill="none" stroke="black" d="M595,-5241.68C595,-5229.74 595,-5215.33 595,-5201.09"/>
<polygon fill="black" stroke="black" points="598.5,-5201.29 595,-5191.29 591.5,-5201.29 598.5,-5201.29"/>
<text text-anchor="middle" x="626.88" y="-5210.67" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- WAIT_CMD8 -->
<g id="node7" class="node">
<title>WAIT_CMD8</title>
<ellipse fill="none" stroke="black" cx="595" cy="-5018.82" rx="67.53" ry="28.99"/>
<text text-anchor="middle" x="595" y="-5022.02" font-family="Times,serif" font-size="14.00">WAIT_CMD8</text>
<text text-anchor="middle" x="595" y="-5005.52" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND_CMD8&#45;&gt;WAIT_CMD8 -->
<g id="edge9" class="edge">
<title>SEND_CMD8&#45;&gt;WAIT_CMD8</title>
<path fill="none" stroke="black" d="M595,-5084.45C595,-5076.05 595,-5067.47 595,-5059.42"/>
<polygon fill="black" stroke="black" points="598.5,-5059.6 595,-5049.6 591.5,-5059.6 598.5,-5059.6"/>
</g>
<!-- WAIT_CMD8&#45;&gt;WAIT_CMD8 -->
<g id="edge10" class="edge">
<title>WAIT_CMD8&#45;&gt;WAIT_CMD8</title>
<path fill="none" stroke="black" d="M659.89,-5027.27C672,-5026.23 680.53,-5023.42 680.53,-5018.82 680.53,-5015.81 676.86,-5013.56 670.91,-5012.08"/>
<polygon fill="black" stroke="black" points="671.81,-5008.68 661.39,-5010.61 670.74,-5015.59 671.81,-5008.68"/>
<text text-anchor="middle" x="742.78" y="-5013.77" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_CMD8 -->
<g id="node8" class="node">
<title>LISTEN_RESPONSE_CMD8</title>
<ellipse fill="none" stroke="black" cx="595" cy="-4896.67" rx="128.52" ry="40.66"/>
<text text-anchor="middle" x="595" y="-4908.12" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_CMD8</text>
<text text-anchor="middle" x="595" y="-4891.62" font-family="Times,serif" font-size="14.00">response_type=7</text>
<text text-anchor="middle" x="595" y="-4875.12" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_CMD8&#45;&gt;LISTEN_RESPONSE_CMD8 -->
<g id="edge11" class="edge">
<title>WAIT_CMD8&#45;&gt;LISTEN_RESPONSE_CMD8</title>
<path fill="none" stroke="black" d="M595,-4989.35C595,-4977.31 595,-4962.91 595,-4949.13"/>
<polygon fill="black" stroke="black" points="598.5,-4949.28 595,-4939.28 591.5,-4949.28 598.5,-4949.28"/>
<text text-anchor="middle" x="655" y="-4958.53" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_CMD8 -->
<g id="node9" class="node">
<title>WAIT_RESPONSE_CMD8</title>
<ellipse fill="none" stroke="black" cx="595" cy="-4790.02" rx="120.03" ry="28.99"/>
<text text-anchor="middle" x="595" y="-4793.22" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_CMD8</text>
<text text-anchor="middle" x="595" y="-4776.72" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE_CMD8&#45;&gt;WAIT_RESPONSE_CMD8 -->
<g id="edge12" class="edge">
<title>LISTEN_RESPONSE_CMD8&#45;&gt;WAIT_RESPONSE_CMD8</title>
<path fill="none" stroke="black" d="M595,-4855.81C595,-4847.57 595,-4838.88 595,-4830.65"/>
<polygon fill="black" stroke="black" points="598.5,-4830.91 595,-4820.91 591.5,-4830.91 598.5,-4830.91"/>
</g>
<!-- WAIT_RESPONSE_CMD8&#45;&gt;WAIT_RESPONSE_CMD8 -->
<g id="edge13" class="edge">
<title>WAIT_RESPONSE_CMD8&#45;&gt;WAIT_RESPONSE_CMD8</title>
<path fill="none" stroke="black" d="M711.31,-4797.57C724.49,-4796.16 733.03,-4793.64 733.03,-4790.02 733.03,-4787.59 729.18,-4785.66 722.65,-4784.22"/>
<polygon fill="black" stroke="black" points="723.22,-4780.77 712.8,-4782.71 722.15,-4787.69 723.22,-4780.77"/>
<text text-anchor="middle" x="802.41" y="-4784.97" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- SEND_CMD55 -->
<g id="node10" class="node">
<title>SEND_CMD55</title>
<ellipse fill="none" stroke="black" cx="595" cy="-4656.21" rx="72.83" ry="52.33"/>
<text text-anchor="middle" x="595" y="-4675.91" font-family="Times,serif" font-size="14.00">SEND_CMD55</text>
<text text-anchor="middle" x="595" y="-4659.41" font-family="Times,serif" font-size="14.00">cmd=55</text>
<text text-anchor="middle" x="595" y="-4642.91" font-family="Times,serif" font-size="14.00">arg=0</text>
<text text-anchor="middle" x="595" y="-4626.41" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- WAIT_RESPONSE_CMD8&#45;&gt;SEND_CMD55 -->
<g id="edge14" class="edge">
<title>WAIT_RESPONSE_CMD8&#45;&gt;SEND_CMD55</title>
<path fill="none" stroke="black" d="M595,-4760.75C595,-4748.81 595,-4734.39 595,-4720.16"/>
<polygon fill="black" stroke="black" points="598.5,-4720.35 595,-4710.35 591.5,-4720.35 598.5,-4720.35"/>
<text text-anchor="middle" x="662.13" y="-4729.73" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT_CMD55 -->
<g id="node11" class="node">
<title>WAIT_CMD55</title>
<ellipse fill="none" stroke="black" cx="470" cy="-4537.89" rx="72.3" ry="28.99"/>
<text text-anchor="middle" x="470" y="-4541.09" font-family="Times,serif" font-size="14.00">WAIT_CMD55</text>
<text text-anchor="middle" x="470" y="-4524.59" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND_CMD55&#45;&gt;WAIT_CMD55 -->
<g id="edge15" class="edge">
<title>SEND_CMD55&#45;&gt;WAIT_CMD55</title>
<path fill="none" stroke="black" d="M550.93,-4614.2C536.38,-4600.66 520.36,-4585.75 506.44,-4572.8"/>
<polygon fill="black" stroke="black" points="508.9,-4570.3 499.19,-4566.05 504.13,-4575.43 508.9,-4570.3"/>
</g>
<!-- WAIT_CMD55&#45;&gt;WAIT_CMD55 -->
<g id="edge16" class="edge">
<title>WAIT_CMD55&#45;&gt;WAIT_CMD55</title>
<path fill="none" stroke="black" d="M539.67,-4546.24C551.84,-4545.12 560.3,-4542.34 560.3,-4537.89 560.3,-4534.97 556.66,-4532.76 550.71,-4531.28"/>
<polygon fill="black" stroke="black" points="551.58,-4527.88 541.16,-4529.78 550.5,-4534.79 551.58,-4527.88"/>
<text text-anchor="middle" x="622.55" y="-4532.84" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_CMD55 -->
<g id="node12" class="node">
<title>LISTEN_RESPONSE_CMD55</title>
<ellipse fill="none" stroke="black" cx="445" cy="-4415.74" rx="133.29" ry="40.66"/>
<text text-anchor="middle" x="445" y="-4427.19" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_CMD55</text>
<text text-anchor="middle" x="445" y="-4410.69" font-family="Times,serif" font-size="14.00">response_type=1</text>
<text text-anchor="middle" x="445" y="-4394.19" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_CMD55&#45;&gt;LISTEN_RESPONSE_CMD55 -->
<g id="edge17" class="edge">
<title>WAIT_CMD55&#45;&gt;LISTEN_RESPONSE_CMD55</title>
<path fill="none" stroke="black" d="M464.14,-4508.72C461.59,-4496.46 458.52,-4481.7 455.59,-4467.63"/>
<polygon fill="black" stroke="black" points="459.06,-4467.12 453.59,-4458.04 452.2,-4468.54 459.06,-4467.12"/>
<text text-anchor="middle" x="519.74" y="-4477.6" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_CMD55 -->
<g id="node13" class="node">
<title>WAIT_RESPONSE_CMD55</title>
<ellipse fill="none" stroke="black" cx="407" cy="-4309.09" rx="124.8" ry="28.99"/>
<text text-anchor="middle" x="407" y="-4312.29" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_CMD55</text>
<text text-anchor="middle" x="407" y="-4295.79" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE_CMD55&#45;&gt;WAIT_RESPONSE_CMD55 -->
<g id="edge18" class="edge">
<title>LISTEN_RESPONSE_CMD55&#45;&gt;WAIT_RESPONSE_CMD55</title>
<path fill="none" stroke="black" d="M430.53,-4374.88C427.46,-4366.44 424.23,-4357.55 421.18,-4349.15"/>
<polygon fill="black" stroke="black" points="424.52,-4348.09 417.82,-4339.88 417.94,-4350.48 424.52,-4348.09"/>
</g>
<!-- WAIT_RESPONSE_CMD55&#45;&gt;WAIT_RESPONSE_CMD55 -->
<g id="edge19" class="edge">
<title>WAIT_RESPONSE_CMD55&#45;&gt;WAIT_RESPONSE_CMD55</title>
<path fill="none" stroke="black" d="M528.11,-4316.55C541.3,-4315.12 549.8,-4312.64 549.8,-4309.09 549.8,-4306.71 545.97,-4304.8 539.45,-4303.37"/>
<polygon fill="black" stroke="black" points="540.02,-4299.92 529.61,-4301.86 538.96,-4306.84 540.02,-4299.92"/>
<text text-anchor="middle" x="619.18" y="-4304.04" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- SEND_ACMD41 -->
<g id="node14" class="node">
<title>SEND_ACMD41</title>
<ellipse fill="none" stroke="black" cx="407" cy="-4175.27" rx="79.73" ry="52.33"/>
<text text-anchor="middle" x="407" y="-4194.97" font-family="Times,serif" font-size="14.00">SEND_ACMD41</text>
<text text-anchor="middle" x="407" y="-4178.47" font-family="Times,serif" font-size="14.00">cmd=41</text>
<text text-anchor="middle" x="407" y="-4161.97" font-family="Times,serif" font-size="14.00">arg=0x40100000</text>
<text text-anchor="middle" x="407" y="-4145.47" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- WAIT_RESPONSE_CMD55&#45;&gt;SEND_ACMD41 -->
<g id="edge20" class="edge">
<title>WAIT_RESPONSE_CMD55&#45;&gt;SEND_ACMD41</title>
<path fill="none" stroke="black" d="M407,-4279.81C407,-4267.87 407,-4253.46 407,-4239.23"/>
<polygon fill="black" stroke="black" points="410.5,-4239.42 407,-4229.42 403.5,-4239.42 410.5,-4239.42"/>
<text text-anchor="middle" x="474.13" y="-4248.8" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT_ACMD41 -->
<g id="node15" class="node">
<title>WAIT_ACMD41</title>
<ellipse fill="none" stroke="black" cx="407" cy="-4056.95" rx="79.2" ry="28.99"/>
<text text-anchor="middle" x="407" y="-4060.15" font-family="Times,serif" font-size="14.00">WAIT_ACMD41</text>
<text text-anchor="middle" x="407" y="-4043.65" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND_ACMD41&#45;&gt;WAIT_ACMD41 -->
<g id="edge21" class="edge">
<title>SEND_ACMD41&#45;&gt;WAIT_ACMD41</title>
<path fill="none" stroke="black" d="M407,-4122.58C407,-4114.18 407,-4105.6 407,-4097.55"/>
<polygon fill="black" stroke="black" points="410.5,-4097.73 407,-4087.73 403.5,-4097.73 410.5,-4097.73"/>
</g>
<!-- WAIT_ACMD41&#45;&gt;WAIT_ACMD41 -->
<g id="edge22" class="edge">
<title>WAIT_ACMD41&#45;&gt;WAIT_ACMD41</title>
<path fill="none" stroke="black" d="M483.2,-4065.19C495.64,-4064.01 504.2,-4061.27 504.2,-4056.95 504.2,-4054.12 500.51,-4051.97 494.46,-4050.49"/>
<polygon fill="black" stroke="black" points="495.12,-4047.05 484.7,-4048.95 494.03,-4053.96 495.12,-4047.05"/>
<text text-anchor="middle" x="566.45" y="-4051.9" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_ACMD41 -->
<g id="node16" class="node">
<title>LISTEN_RESPONSE_ACMD41</title>
<ellipse fill="none" stroke="black" cx="405" cy="-3934.8" rx="140.18" ry="40.66"/>
<text text-anchor="middle" x="405" y="-3946.25" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_ACMD41</text>
<text text-anchor="middle" x="405" y="-3929.75" font-family="Times,serif" font-size="14.00">response_type=3</text>
<text text-anchor="middle" x="405" y="-3913.25" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_ACMD41&#45;&gt;LISTEN_RESPONSE_ACMD41 -->
<g id="edge23" class="edge">
<title>WAIT_ACMD41&#45;&gt;LISTEN_RESPONSE_ACMD41</title>
<path fill="none" stroke="black" d="M406.53,-4027.48C406.33,-4015.44 406.09,-4001.04 405.86,-3987.26"/>
<polygon fill="black" stroke="black" points="409.36,-3987.35 405.69,-3977.41 402.36,-3987.46 409.36,-3987.35"/>
<text text-anchor="middle" x="466.18" y="-3996.66" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_ACMD41 -->
<g id="node17" class="node">
<title>WAIT_RESPONSE_ACMD41</title>
<ellipse fill="none" stroke="black" cx="401" cy="-3816.49" rx="131.7" ry="40.66"/>
<text text-anchor="middle" x="401" y="-3827.94" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_ACMD41</text>
<text text-anchor="middle" x="401" y="-3811.44" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
<text text-anchor="middle" x="401" y="-3794.94" font-family="Times,serif" font-size="14.00">counter=100</text>
</g>
<!-- LISTEN_RESPONSE_ACMD41&#45;&gt;WAIT_RESPONSE_ACMD41 -->
<g id="edge24" class="edge">
<title>LISTEN_RESPONSE_ACMD41&#45;&gt;WAIT_RESPONSE_ACMD41</title>
<path fill="none" stroke="black" d="M403.62,-3893.77C403.35,-3885.73 403.05,-3877.18 402.77,-3868.81"/>
<polygon fill="black" stroke="black" points="406.27,-3868.98 402.43,-3859.1 399.28,-3869.22 406.27,-3868.98"/>
</g>
<!-- WAIT_RESPONSE_ACMD41&#45;&gt;WAIT_RESPONSE_ACMD41 -->
<g id="edge25" class="edge">
<title>WAIT_RESPONSE_ACMD41&#45;&gt;WAIT_RESPONSE_ACMD41</title>
<path fill="none" stroke="black" d="M529.82,-3825.53C542.58,-3823.72 550.7,-3820.7 550.7,-3816.49 550.7,-3813.65 547.04,-3811.36 540.76,-3809.62"/>
<polygon fill="black" stroke="black" points="541.8,-3806.25 531.31,-3807.74 540.44,-3813.12 541.8,-3806.25"/>
<text text-anchor="middle" x="620.07" y="-3811.44" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- ACMD41_DELAY -->
<g id="node18" class="node">
<title>ACMD41_DELAY</title>
<ellipse fill="none" stroke="black" cx="590" cy="-3671" rx="87.15" ry="28.99"/>
<text text-anchor="middle" x="590" y="-3674.2" font-family="Times,serif" font-size="14.00">ACMD41_DELAY</text>
<text text-anchor="middle" x="590" y="-3657.7" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- WAIT_RESPONSE_ACMD41&#45;&gt;ACMD41_DELAY -->
<g id="edge26" class="edge">
<title>WAIT_RESPONSE_ACMD41&#45;&gt;ACMD41_DELAY</title>
<path fill="none" stroke="black" d="M430.37,-3776.49C440.6,-3764.37 452.69,-3751.53 465.25,-3741.33 484.68,-3725.55 508.19,-3711.43 529.55,-3700.12"/>
<polygon fill="black" stroke="black" points="530.9,-3703.36 538.16,-3695.66 527.68,-3697.15 530.9,-3703.36"/>
<text text-anchor="middle" x="584.13" y="-3744.53" font-family="Times,serif" font-size="14.00">read_command.received &amp;&amp; !out_data[39]</text>
</g>
<!-- SEND_CMD2 -->
<g id="node19" class="node">
<title>SEND_CMD2</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3671" rx="102" ry="52.33"/>
<text text-anchor="middle" x="208" y="-3690.7" font-family="Times,serif" font-size="14.00">SEND_CMD2</text>
<text text-anchor="middle" x="208" y="-3674.2" font-family="Times,serif" font-size="14.00">cmd=2</text>
<text text-anchor="middle" x="208" y="-3657.7" font-family="Times,serif" font-size="14.00">arg=0</text>
<text text-anchor="middle" x="208" y="-3641.2" font-family="Times,serif" font-size="14.00">send_command.start=1</text>
</g>
<!-- WAIT_RESPONSE_ACMD41&#45;&gt;SEND_CMD2 -->
<g id="edge29" class="edge">
<title>WAIT_RESPONSE_ACMD41&#45;&gt;SEND_CMD2</title>
<path fill="none" stroke="black" d="M277.39,-3802.37C251.18,-3793.67 226.42,-3779.79 209.75,-3757.83 204.67,-3751.14 201.74,-3743.23 200.27,-3734.97"/>
<polygon fill="black" stroke="black" points="203.75,-3734.65 199.24,-3725.07 196.79,-3735.37 203.75,-3734.65"/>
<text text-anchor="middle" x="326.38" y="-3744.53" font-family="Times,serif" font-size="14.00">read_command.received &amp;&amp; out_data[39]</text>
</g>
<!-- ACMD41_DELAY&#45;&gt;SEND_CMD55 -->
<g id="edge28" class="edge">
<title>ACMD41_DELAY&#45;&gt;SEND_CMD55</title>
<path fill="none" stroke="black" d="M644.9,-3693.9C666.16,-3705.04 688.76,-3720.67 703,-3741.33 722.04,-3768.94 717,-3781.95 717,-3815.49 717,-4538.89 717,-4538.89 717,-4538.89 717,-4572.94 691.8,-4600.06 664.31,-4619.53"/>
<polygon fill="black" stroke="black" points="662.53,-4616.5 656.18,-4624.99 666.44,-4622.31 662.53,-4616.5"/>
<text text-anchor="middle" x="748.88" y="-4170.22" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- ACMD41_DELAY&#45;&gt;ACMD41_DELAY -->
<g id="edge27" class="edge">
<title>ACMD41_DELAY&#45;&gt;ACMD41_DELAY</title>
<path fill="none" stroke="black" d="M668.87,-3683.69C684.24,-3682.22 695.15,-3677.99 695.15,-3671 695.15,-3665.87 689.27,-3662.23 680.05,-3660.07"/>
<polygon fill="black" stroke="black" points="680.79,-3656.64 670.37,-3658.55 679.7,-3663.56 680.79,-3656.64"/>
<text text-anchor="middle" x="725.15" y="-3665.95" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- WAIT_CMD2 -->
<g id="node20" class="node">
<title>WAIT_CMD2</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3552.69" rx="102" ry="28.99"/>
<text text-anchor="middle" x="208" y="-3555.89" font-family="Times,serif" font-size="14.00">WAIT_CMD2</text>
<text text-anchor="middle" x="208" y="-3539.39" font-family="Times,serif" font-size="14.00">send_command.start=0</text>
</g>
<!-- SEND_CMD2&#45;&gt;WAIT_CMD2 -->
<g id="edge30" class="edge">
<title>SEND_CMD2&#45;&gt;WAIT_CMD2</title>
<path fill="none" stroke="black" d="M208,-3618.31C208,-3609.91 208,-3601.33 208,-3593.28"/>
<polygon fill="black" stroke="black" points="211.5,-3593.46 208,-3583.46 204.5,-3593.46 211.5,-3593.46"/>
</g>
<!-- WAIT_CMD2&#45;&gt;WAIT_CMD2 -->
<g id="edge31" class="edge">
<title>WAIT_CMD2&#45;&gt;WAIT_CMD2</title>
<path fill="none" stroke="black" d="M306.4,-3560.54C319.39,-3559.2 328,-3556.58 328,-3552.69 328,-3550.07 324.11,-3548.03 317.62,-3546.56"/>
<polygon fill="black" stroke="black" points="318.31,-3543.13 307.9,-3545.06 317.25,-3550.05 318.31,-3543.13"/>
<text text-anchor="middle" x="390.25" y="-3547.64" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_CMD2 -->
<g id="node21" class="node">
<title>LISTEN_RESPONSE_CMD2</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3430.54" rx="128.52" ry="40.66"/>
<text text-anchor="middle" x="208" y="-3441.99" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_CMD2</text>
<text text-anchor="middle" x="208" y="-3425.49" font-family="Times,serif" font-size="14.00">response_type=2</text>
<text text-anchor="middle" x="208" y="-3408.99" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_CMD2&#45;&gt;LISTEN_RESPONSE_CMD2 -->
<g id="edge32" class="edge">
<title>WAIT_CMD2&#45;&gt;LISTEN_RESPONSE_CMD2</title>
<path fill="none" stroke="black" d="M208,-3523.21C208,-3511.18 208,-3496.77 208,-3482.99"/>
<polygon fill="black" stroke="black" points="211.5,-3483.14 208,-3473.14 204.5,-3483.14 211.5,-3483.14"/>
<text text-anchor="middle" x="268" y="-3492.39" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_CMD2 -->
<g id="node22" class="node">
<title>WAIT_RESPONSE_CMD2</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3323.89" rx="120.03" ry="28.99"/>
<text text-anchor="middle" x="208" y="-3327.09" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_CMD2</text>
<text text-anchor="middle" x="208" y="-3310.59" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE_CMD2&#45;&gt;WAIT_RESPONSE_CMD2 -->
<g id="edge33" class="edge">
<title>LISTEN_RESPONSE_CMD2&#45;&gt;WAIT_RESPONSE_CMD2</title>
<path fill="none" stroke="black" d="M208,-3389.67C208,-3381.43 208,-3372.75 208,-3364.51"/>
<polygon fill="black" stroke="black" points="211.5,-3364.77 208,-3354.77 204.5,-3364.77 211.5,-3364.77"/>
</g>
<!-- WAIT_RESPONSE_CMD2&#45;&gt;WAIT_RESPONSE_CMD2 -->
<g id="edge34" class="edge">
<title>WAIT_RESPONSE_CMD2&#45;&gt;WAIT_RESPONSE_CMD2</title>
<path fill="none" stroke="black" d="M324.31,-3331.43C337.49,-3330.02 346.03,-3327.5 346.03,-3323.89 346.03,-3321.45 342.18,-3319.52 335.65,-3318.09"/>
<polygon fill="black" stroke="black" points="336.22,-3314.63 325.8,-3316.57 335.15,-3321.55 336.22,-3314.63"/>
<text text-anchor="middle" x="415.41" y="-3318.84" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- SEND_CMD3 -->
<g id="node23" class="node">
<title>SEND_CMD3</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3190.07" rx="102" ry="52.33"/>
<text text-anchor="middle" x="208" y="-3209.77" font-family="Times,serif" font-size="14.00">SEND_CMD3</text>
<text text-anchor="middle" x="208" y="-3193.27" font-family="Times,serif" font-size="14.00">cmd=3</text>
<text text-anchor="middle" x="208" y="-3176.77" font-family="Times,serif" font-size="14.00">arg=0</text>
<text text-anchor="middle" x="208" y="-3160.27" font-family="Times,serif" font-size="14.00">send_command.start=1</text>
</g>
<!-- WAIT_RESPONSE_CMD2&#45;&gt;SEND_CMD3 -->
<g id="edge35" class="edge">
<title>WAIT_RESPONSE_CMD2&#45;&gt;SEND_CMD3</title>
<path fill="none" stroke="black" d="M208,-3294.61C208,-3282.67 208,-3268.25 208,-3254.02"/>
<polygon fill="black" stroke="black" points="211.5,-3254.21 208,-3244.21 204.5,-3254.21 211.5,-3254.21"/>
<text text-anchor="middle" x="275.13" y="-3263.59" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT_CMD3 -->
<g id="node24" class="node">
<title>WAIT_CMD3</title>
<ellipse fill="none" stroke="black" cx="208" cy="-3071.75" rx="102" ry="28.99"/>
<text text-anchor="middle" x="208" y="-3074.95" font-family="Times,serif" font-size="14.00">WAIT_CMD3</text>
<text text-anchor="middle" x="208" y="-3058.45" font-family="Times,serif" font-size="14.00">send_command.start=0</text>
</g>
<!-- SEND_CMD3&#45;&gt;WAIT_CMD3 -->
<g id="edge36" class="edge">
<title>SEND_CMD3&#45;&gt;WAIT_CMD3</title>
<path fill="none" stroke="black" d="M208,-3137.37C208,-3128.97 208,-3120.39 208,-3112.34"/>
<polygon fill="black" stroke="black" points="211.5,-3112.53 208,-3102.53 204.5,-3112.53 211.5,-3112.53"/>
</g>
<!-- WAIT_CMD3&#45;&gt;WAIT_CMD3 -->
<g id="edge37" class="edge">
<title>WAIT_CMD3&#45;&gt;WAIT_CMD3</title>
<path fill="none" stroke="black" d="M306.4,-3079.6C319.39,-3078.26 328,-3075.65 328,-3071.75 328,-3069.13 324.11,-3067.09 317.62,-3065.63"/>
<polygon fill="black" stroke="black" points="318.31,-3062.19 307.9,-3064.13 317.25,-3069.11 318.31,-3062.19"/>
<text text-anchor="middle" x="390.25" y="-3066.7" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_CMD3 -->
<g id="node25" class="node">
<title>LISTEN_RESPONSE_CMD3</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2949.6" rx="128.52" ry="40.66"/>
<text text-anchor="middle" x="208" y="-2961.05" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_CMD3</text>
<text text-anchor="middle" x="208" y="-2944.55" font-family="Times,serif" font-size="14.00">response_type=6</text>
<text text-anchor="middle" x="208" y="-2928.05" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_CMD3&#45;&gt;LISTEN_RESPONSE_CMD3 -->
<g id="edge38" class="edge">
<title>WAIT_CMD3&#45;&gt;LISTEN_RESPONSE_CMD3</title>
<path fill="none" stroke="black" d="M208,-3042.28C208,-3030.24 208,-3015.84 208,-3002.06"/>
<polygon fill="black" stroke="black" points="211.5,-3002.2 208,-2992.2 204.5,-3002.2 211.5,-3002.2"/>
<text text-anchor="middle" x="268" y="-3011.46" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_CMD3 -->
<g id="node26" class="node">
<title>WAIT_RESPONSE_CMD3</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2842.95" rx="120.03" ry="28.99"/>
<text text-anchor="middle" x="208" y="-2846.15" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_CMD3</text>
<text text-anchor="middle" x="208" y="-2829.65" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE_CMD3&#45;&gt;WAIT_RESPONSE_CMD3 -->
<g id="edge39" class="edge">
<title>LISTEN_RESPONSE_CMD3&#45;&gt;WAIT_RESPONSE_CMD3</title>
<path fill="none" stroke="black" d="M208,-2908.74C208,-2900.49 208,-2891.81 208,-2883.57"/>
<polygon fill="black" stroke="black" points="211.5,-2883.83 208,-2873.83 204.5,-2883.83 211.5,-2883.83"/>
</g>
<!-- WAIT_RESPONSE_CMD3&#45;&gt;WAIT_RESPONSE_CMD3 -->
<g id="edge40" class="edge">
<title>WAIT_RESPONSE_CMD3&#45;&gt;WAIT_RESPONSE_CMD3</title>
<path fill="none" stroke="black" d="M324.31,-2850.5C337.49,-2849.08 346.03,-2846.57 346.03,-2842.95 346.03,-2840.52 342.18,-2838.59 335.65,-2837.15"/>
<polygon fill="black" stroke="black" points="336.22,-2833.7 325.8,-2835.64 335.15,-2840.62 336.22,-2833.7"/>
<text text-anchor="middle" x="415.41" y="-2837.9" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- SEND_CMD7 -->
<g id="node27" class="node">
<title>SEND_CMD7</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2709.13" rx="137.53" ry="52.33"/>
<text text-anchor="middle" x="208" y="-2728.83" font-family="Times,serif" font-size="14.00">SEND_CMD7</text>
<text text-anchor="middle" x="208" y="-2712.33" font-family="Times,serif" font-size="14.00">cmd=7</text>
<text text-anchor="middle" x="208" y="-2695.83" font-family="Times,serif" font-size="14.00">arg={out_data[39:24],16&#39;h0000}</text>
<text text-anchor="middle" x="208" y="-2679.33" font-family="Times,serif" font-size="14.00">send_command.start=1</text>
</g>
<!-- WAIT_RESPONSE_CMD3&#45;&gt;SEND_CMD7 -->
<g id="edge41" class="edge">
<title>WAIT_RESPONSE_CMD3&#45;&gt;SEND_CMD7</title>
<path fill="none" stroke="black" d="M208,-2813.67C208,-2801.73 208,-2787.32 208,-2773.09"/>
<polygon fill="black" stroke="black" points="211.5,-2773.28 208,-2763.28 204.5,-2773.28 211.5,-2773.28"/>
<text text-anchor="middle" x="275.13" y="-2782.66" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT_CMD7 -->
<g id="node28" class="node">
<title>WAIT_CMD7</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2590.82" rx="102" ry="28.99"/>
<text text-anchor="middle" x="208" y="-2594.02" font-family="Times,serif" font-size="14.00">WAIT_CMD7</text>
<text text-anchor="middle" x="208" y="-2577.52" font-family="Times,serif" font-size="14.00">send_command.start=0</text>
</g>
<!-- SEND_CMD7&#45;&gt;WAIT_CMD7 -->
<g id="edge42" class="edge">
<title>SEND_CMD7&#45;&gt;WAIT_CMD7</title>
<path fill="none" stroke="black" d="M208,-2656.44C208,-2648.04 208,-2639.46 208,-2631.41"/>
<polygon fill="black" stroke="black" points="211.5,-2631.59 208,-2621.59 204.5,-2631.59 211.5,-2631.59"/>
</g>
<!-- WAIT_CMD7&#45;&gt;WAIT_CMD7 -->
<g id="edge43" class="edge">
<title>WAIT_CMD7&#45;&gt;WAIT_CMD7</title>
<path fill="none" stroke="black" d="M306.4,-2598.67C319.39,-2597.33 328,-2594.71 328,-2590.82 328,-2588.2 324.11,-2586.16 317.62,-2584.69"/>
<polygon fill="black" stroke="black" points="318.31,-2581.26 307.9,-2583.19 317.25,-2588.18 318.31,-2581.26"/>
<text text-anchor="middle" x="390.25" y="-2585.77" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_CMD7 -->
<g id="node29" class="node">
<title>LISTEN_RESPONSE_CMD7</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2468.67" rx="128.52" ry="40.66"/>
<text text-anchor="middle" x="208" y="-2480.12" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_CMD7</text>
<text text-anchor="middle" x="208" y="-2463.62" font-family="Times,serif" font-size="14.00">response_type=1</text>
<text text-anchor="middle" x="208" y="-2447.12" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_CMD7&#45;&gt;LISTEN_RESPONSE_CMD7 -->
<g id="edge44" class="edge">
<title>WAIT_CMD7&#45;&gt;LISTEN_RESPONSE_CMD7</title>
<path fill="none" stroke="black" d="M208,-2561.34C208,-2549.31 208,-2534.91 208,-2521.12"/>
<polygon fill="black" stroke="black" points="211.5,-2521.27 208,-2511.27 204.5,-2521.27 211.5,-2521.27"/>
<text text-anchor="middle" x="268" y="-2530.52" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_CMD7 -->
<g id="node30" class="node">
<title>WAIT_RESPONSE_CMD7</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2362.02" rx="120.03" ry="28.99"/>
<text text-anchor="middle" x="208" y="-2365.22" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_CMD7</text>
<text text-anchor="middle" x="208" y="-2348.72" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE_CMD7&#45;&gt;WAIT_RESPONSE_CMD7 -->
<g id="edge45" class="edge">
<title>LISTEN_RESPONSE_CMD7&#45;&gt;WAIT_RESPONSE_CMD7</title>
<path fill="none" stroke="black" d="M208,-2427.8C208,-2419.56 208,-2410.88 208,-2402.64"/>
<polygon fill="black" stroke="black" points="211.5,-2402.9 208,-2392.9 204.5,-2402.9 211.5,-2402.9"/>
</g>
<!-- WAIT_RESPONSE_CMD7&#45;&gt;WAIT_RESPONSE_CMD7 -->
<g id="edge46" class="edge">
<title>WAIT_RESPONSE_CMD7&#45;&gt;WAIT_RESPONSE_CMD7</title>
<path fill="none" stroke="black" d="M324.31,-2369.56C337.49,-2368.15 346.03,-2365.63 346.03,-2362.02 346.03,-2359.59 342.18,-2357.65 335.65,-2356.22"/>
<polygon fill="black" stroke="black" points="336.22,-2352.76 325.8,-2354.7 335.15,-2359.68 336.22,-2352.76"/>
<text text-anchor="middle" x="407.53" y="-2356.97" font-family="Times,serif" font-size="14.00">!read_command.ready</text>
</g>
<!-- SEND2_CMD55 -->
<g id="node31" class="node">
<title>SEND2_CMD55</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2239.87" rx="77.6" ry="40.66"/>
<text text-anchor="middle" x="208" y="-2251.32" font-family="Times,serif" font-size="14.00">SEND2_CMD55</text>
<text text-anchor="middle" x="208" y="-2234.82" font-family="Times,serif" font-size="14.00">cmd=55</text>
<text text-anchor="middle" x="208" y="-2218.32" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- WAIT_RESPONSE_CMD7&#45;&gt;SEND2_CMD55 -->
<g id="edge47" class="edge">
<title>WAIT_RESPONSE_CMD7&#45;&gt;SEND2_CMD55</title>
<path fill="none" stroke="black" d="M208,-2332.54C208,-2320.51 208,-2306.11 208,-2292.32"/>
<polygon fill="black" stroke="black" points="211.5,-2292.47 208,-2282.47 204.5,-2292.47 211.5,-2292.47"/>
<text text-anchor="middle" x="275.13" y="-2301.72" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT2_CMD55 -->
<g id="node32" class="node">
<title>WAIT2_CMD55</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2133.22" rx="77.07" ry="28.99"/>
<text text-anchor="middle" x="208" y="-2136.42" font-family="Times,serif" font-size="14.00">WAIT2_CMD55</text>
<text text-anchor="middle" x="208" y="-2119.92" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND2_CMD55&#45;&gt;WAIT2_CMD55 -->
<g id="edge48" class="edge">
<title>SEND2_CMD55&#45;&gt;WAIT2_CMD55</title>
<path fill="none" stroke="black" d="M208,-2199C208,-2190.76 208,-2182.08 208,-2173.84"/>
<polygon fill="black" stroke="black" points="211.5,-2174.1 208,-2164.1 204.5,-2174.1 211.5,-2174.1"/>
</g>
<!-- WAIT2_CMD55&#45;&gt;WAIT2_CMD55 -->
<g id="edge49" class="edge">
<title>WAIT2_CMD55&#45;&gt;WAIT2_CMD55</title>
<path fill="none" stroke="black" d="M282.14,-2141.49C294.53,-2140.33 303.07,-2137.58 303.07,-2133.22 303.07,-2130.36 299.39,-2128.18 293.36,-2126.7"/>
<polygon fill="black" stroke="black" points="294.06,-2123.27 283.64,-2125.17 292.98,-2130.18 294.06,-2123.27"/>
<text text-anchor="middle" x="365.32" y="-2128.17" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE2_CMD55 -->
<g id="node33" class="node">
<title>LISTEN_RESPONSE2_CMD55</title>
<ellipse fill="none" stroke="black" cx="208" cy="-2011.07" rx="138.06" ry="40.66"/>
<text text-anchor="middle" x="208" y="-2022.52" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE2_CMD55</text>
<text text-anchor="middle" x="208" y="-2006.02" font-family="Times,serif" font-size="14.00">response_type=1</text>
<text text-anchor="middle" x="208" y="-1989.52" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT2_CMD55&#45;&gt;LISTEN_RESPONSE2_CMD55 -->
<g id="edge50" class="edge">
<title>WAIT2_CMD55&#45;&gt;LISTEN_RESPONSE2_CMD55</title>
<path fill="none" stroke="black" d="M208,-2103.74C208,-2091.71 208,-2077.31 208,-2063.52"/>
<polygon fill="black" stroke="black" points="211.5,-2063.67 208,-2053.67 204.5,-2063.67 211.5,-2063.67"/>
<text text-anchor="middle" x="268" y="-2072.92" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE2_CMD55 -->
<g id="node34" class="node">
<title>WAIT_RESPONSE2_CMD55</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1904.42" rx="129.58" ry="28.99"/>
<text text-anchor="middle" x="208" y="-1907.62" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE2_CMD55</text>
<text text-anchor="middle" x="208" y="-1891.12" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
</g>
<!-- LISTEN_RESPONSE2_CMD55&#45;&gt;WAIT_RESPONSE2_CMD55 -->
<g id="edge51" class="edge">
<title>LISTEN_RESPONSE2_CMD55&#45;&gt;WAIT_RESPONSE2_CMD55</title>
<path fill="none" stroke="black" d="M208,-1970.2C208,-1961.96 208,-1953.28 208,-1945.04"/>
<polygon fill="black" stroke="black" points="211.5,-1945.3 208,-1935.3 204.5,-1945.3 211.5,-1945.3"/>
</g>
<!-- WAIT_RESPONSE2_CMD55&#45;&gt;WAIT_RESPONSE2_CMD55 -->
<g id="edge52" class="edge">
<title>WAIT_RESPONSE2_CMD55&#45;&gt;WAIT_RESPONSE2_CMD55</title>
<path fill="none" stroke="black" d="M333.69,-1911.82C347.02,-1910.39 355.58,-1907.92 355.58,-1904.42 355.58,-1902.01 351.53,-1900.09 344.67,-1898.66"/>
<polygon fill="black" stroke="black" points="345.6,-1895.26 335.19,-1897.23 344.56,-1902.18 345.6,-1895.26"/>
<text text-anchor="middle" x="424.95" y="-1899.37" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- SEND_ACMD6 -->
<g id="node35" class="node">
<title>SEND_ACMD6</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1770.6" rx="77.07" ry="52.33"/>
<text text-anchor="middle" x="208" y="-1790.3" font-family="Times,serif" font-size="14.00">SEND_ACMD6</text>
<text text-anchor="middle" x="208" y="-1773.8" font-family="Times,serif" font-size="14.00">cmd=6</text>
<text text-anchor="middle" x="208" y="-1757.3" font-family="Times,serif" font-size="14.00">arg=0x00000002</text>
<text text-anchor="middle" x="208" y="-1740.8" font-family="Times,serif" font-size="14.00">start=1</text>
</g>
<!-- WAIT_RESPONSE2_CMD55&#45;&gt;SEND_ACMD6 -->
<g id="edge53" class="edge">
<title>WAIT_RESPONSE2_CMD55&#45;&gt;SEND_ACMD6</title>
<path fill="none" stroke="black" d="M208,-1875.14C208,-1863.2 208,-1848.78 208,-1834.55"/>
<polygon fill="black" stroke="black" points="211.5,-1834.74 208,-1824.74 204.5,-1834.74 211.5,-1834.74"/>
<text text-anchor="middle" x="275.13" y="-1844.12" font-family="Times,serif" font-size="14.00">read_command.received</text>
</g>
<!-- WAIT_ACMD6 -->
<g id="node36" class="node">
<title>WAIT_ACMD6</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1652.28" rx="74.42" ry="28.99"/>
<text text-anchor="middle" x="208" y="-1655.48" font-family="Times,serif" font-size="14.00">WAIT_ACMD6</text>
<text text-anchor="middle" x="208" y="-1638.98" font-family="Times,serif" font-size="14.00">start=0</text>
</g>
<!-- SEND_ACMD6&#45;&gt;WAIT_ACMD6 -->
<g id="edge54" class="edge">
<title>SEND_ACMD6&#45;&gt;WAIT_ACMD6</title>
<path fill="none" stroke="black" d="M208,-1717.9C208,-1709.51 208,-1700.93 208,-1692.88"/>
<polygon fill="black" stroke="black" points="211.5,-1693.06 208,-1683.06 204.5,-1693.06 211.5,-1693.06"/>
</g>
<!-- WAIT_ACMD6&#45;&gt;WAIT_ACMD6 -->
<g id="edge55" class="edge">
<title>WAIT_ACMD6&#45;&gt;WAIT_ACMD6</title>
<path fill="none" stroke="black" d="M279.69,-1660.59C291.94,-1659.46 300.42,-1656.69 300.42,-1652.28 300.42,-1649.39 296.77,-1647.2 290.8,-1645.72"/>
<polygon fill="black" stroke="black" points="291.61,-1642.3 281.19,-1644.2 290.52,-1649.22 291.61,-1642.3"/>
<text text-anchor="middle" x="362.67" y="-1647.23" font-family="Times,serif" font-size="14.00">!send_command.ready</text>
</g>
<!-- LISTEN_RESPONSE_ACMD6 -->
<g id="node37" class="node">
<title>LISTEN_RESPONSE_ACMD6</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1530.13" rx="135.41" ry="40.66"/>
<text text-anchor="middle" x="208" y="-1541.58" font-family="Times,serif" font-size="14.00">LISTEN_RESPONSE_ACMD6</text>
<text text-anchor="middle" x="208" y="-1525.08" font-family="Times,serif" font-size="14.00">response_type=1</text>
<text text-anchor="middle" x="208" y="-1508.58" font-family="Times,serif" font-size="14.00">read_command.listen=1</text>
</g>
<!-- WAIT_ACMD6&#45;&gt;LISTEN_RESPONSE_ACMD6 -->
<g id="edge56" class="edge">
<title>WAIT_ACMD6&#45;&gt;LISTEN_RESPONSE_ACMD6</title>
<path fill="none" stroke="black" d="M208,-1622.81C208,-1610.77 208,-1596.37 208,-1582.59"/>
<polygon fill="black" stroke="black" points="211.5,-1582.73 208,-1572.73 204.5,-1582.73 211.5,-1582.73"/>
<text text-anchor="middle" x="268" y="-1591.99" font-family="Times,serif" font-size="14.00">send_command.ready</text>
</g>
<!-- WAIT_RESPONSE_ACMD6 -->
<g id="node38" class="node">
<title>WAIT_RESPONSE_ACMD6</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1411.81" rx="126.93" ry="40.66"/>
<text text-anchor="middle" x="208" y="-1423.26" font-family="Times,serif" font-size="14.00">WAIT_RESPONSE_ACMD6</text>
<text text-anchor="middle" x="208" y="-1406.76" font-family="Times,serif" font-size="14.00">read_command.listen=0</text>
<text text-anchor="middle" x="208" y="-1390.26" font-family="Times,serif" font-size="14.00">counter=100</text>
</g>
<!-- LISTEN_RESPONSE_ACMD6&#45;&gt;WAIT_RESPONSE_ACMD6 -->
<g id="edge57" class="edge">
<title>LISTEN_RESPONSE_ACMD6&#45;&gt;WAIT_RESPONSE_ACMD6</title>
<path fill="none" stroke="black" d="M208,-1489.1C208,-1481.15 208,-1472.7 208,-1464.42"/>
<polygon fill="black" stroke="black" points="211.5,-1464.43 208,-1454.43 204.5,-1464.43 211.5,-1464.43"/>
</g>
<!-- WAIT_RESPONSE_ACMD6&#45;&gt;WAIT_RESPONSE_ACMD6 -->
<g id="edge58" class="edge">
<title>WAIT_RESPONSE_ACMD6&#45;&gt;WAIT_RESPONSE_ACMD6</title>
<path fill="none" stroke="black" d="M332.21,-1420.93C344.85,-1419.13 352.93,-1416.09 352.93,-1411.81 352.93,-1409.01 349.45,-1406.74 343.48,-1404.99"/>
<polygon fill="black" stroke="black" points="344.19,-1401.57 333.69,-1403 342.79,-1408.42 344.19,-1401.57"/>
<text text-anchor="middle" x="422.3" y="-1406.76" font-family="Times,serif" font-size="14.00">!read_command.received</text>
</g>
<!-- READY_TO_TRANSMIT -->
<g id="node39" class="node">
<title>READY_TO_TRANSMIT</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1254.66" rx="115.79" ry="63.99"/>
<text text-anchor="middle" x="208" y="-1282.61" font-family="Times,serif" font-size="14.00">READY_TO_TRANSMIT</text>
<text text-anchor="middle" x="208" y="-1266.11" font-family="Times,serif" font-size="14.00">clk_source=fast</text>
<text text-anchor="middle" x="208" y="-1249.61" font-family="Times,serif" font-size="14.00">address=0</text>
<text text-anchor="middle" x="208" y="-1233.11" font-family="Times,serif" font-size="14.00">buffer_half=0</text>
<text text-anchor="middle" x="208" y="-1216.61" font-family="Times,serif" font-size="14.00">counter=100</text>
</g>
<!-- WAIT_RESPONSE_ACMD6&#45;&gt;READY_TO_TRANSMIT -->
<g id="edge59" class="edge">
<title>WAIT_RESPONSE_ACMD6&#45;&gt;READY_TO_TRANSMIT</title>
<path fill="none" stroke="black" d="M208,-1370.86C208,-1358.39 208,-1344.21 208,-1330.16"/>
<polygon fill="black" stroke="black" points="211.5,-1330.48 208,-1320.48 204.5,-1330.48 211.5,-1330.48"/>
<text text-anchor="middle" x="267.25" y="-1339.86" font-family="Times,serif" font-size="14.00">read_command.ready</text>
</g>
<!-- DELAY_CLOCK_SWITCH -->
<g id="node40" class="node">
<title>DELAY_CLOCK_SWITCH</title>
<ellipse fill="none" stroke="black" cx="208" cy="-1124.68" rx="122.68" ry="28.99"/>
<text text-anchor="middle" x="208" y="-1127.88" font-family="Times,serif" font-size="14.00">DELAY_CLOCK_SWITCH</text>
<text text-anchor="middle" x="208" y="-1111.38" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- READY_TO_TRANSMIT&#45;&gt;DELAY_CLOCK_SWITCH -->
<g id="edge60" class="edge">
<title>READY_TO_TRANSMIT&#45;&gt;DELAY_CLOCK_SWITCH</title>
<path fill="none" stroke="black" d="M208,-1190.42C208,-1181.97 208,-1173.51 208,-1165.61"/>
<polygon fill="black" stroke="black" points="211.5,-1165.66 208,-1155.66 204.5,-1165.66 211.5,-1165.66"/>
</g>
<!-- DELAY_CLOCK_SWITCH&#45;&gt;DELAY_CLOCK_SWITCH -->
<g id="edge62" class="edge">
<title>DELAY_CLOCK_SWITCH&#45;&gt;DELAY_CLOCK_SWITCH</title>
<path fill="none" stroke="black" d="M327.06,-1132.17C340.2,-1130.75 348.68,-1128.25 348.68,-1124.68 348.68,-1122.28 344.85,-1120.36 338.35,-1118.93"/>
<polygon fill="black" stroke="black" points="338.97,-1115.49 328.55,-1117.42 337.9,-1122.41 338.97,-1115.49"/>
<text text-anchor="middle" x="378.68" y="-1119.63" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- TRANSMIT -->
<g id="node41" class="node">
<title>TRANSMIT</title>
<ellipse fill="none" stroke="black" cx="208" cy="-990.86" rx="102" ry="52.33"/>
<text text-anchor="middle" x="208" y="-1010.56" font-family="Times,serif" font-size="14.00">TRANSMIT</text>
<text text-anchor="middle" x="208" y="-994.06" font-family="Times,serif" font-size="14.00">cmd=17</text>
<text text-anchor="middle" x="208" y="-977.56" font-family="Times,serif" font-size="14.00">arg=address</text>
<text text-anchor="middle" x="208" y="-961.06" font-family="Times,serif" font-size="14.00">send_command.start=1</text>
</g>
<!-- DELAY_CLOCK_SWITCH&#45;&gt;TRANSMIT -->
<g id="edge61" class="edge">
<title>DELAY_CLOCK_SWITCH&#45;&gt;TRANSMIT</title>
<path fill="none" stroke="black" d="M208,-1095.4C208,-1083.46 208,-1069.05 208,-1054.81"/>
<polygon fill="black" stroke="black" points="211.5,-1055 208,-1045 204.5,-1055 211.5,-1055"/>
<text text-anchor="middle" x="239.88" y="-1064.39" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- WAIT_TRANSMIT -->
<g id="node42" class="node">
<title>WAIT_TRANSMIT</title>
<ellipse fill="none" stroke="black" cx="102" cy="-860.88" rx="102" ry="40.66"/>
<text text-anchor="middle" x="102" y="-872.33" font-family="Times,serif" font-size="14.00">WAIT_TRANSMIT</text>
<text text-anchor="middle" x="102" y="-855.83" font-family="Times,serif" font-size="14.00">send_command.start=0</text>
<text text-anchor="middle" x="102" y="-839.33" font-family="Times,serif" font-size="14.00">counter=4114</text>
</g>
<!-- TRANSMIT&#45;&gt;WAIT_TRANSMIT -->
<g id="edge63" class="edge">
<title>TRANSMIT&#45;&gt;WAIT_TRANSMIT</title>
<path fill="none" stroke="black" d="M168.53,-942.2C159.43,-931.21 149.75,-919.53 140.68,-908.58"/>
<polygon fill="black" stroke="black" points="143.6,-906.62 134.53,-901.15 138.21,-911.08 143.6,-906.62"/>
</g>
<!-- WAIT_TRANSMIT&#45;&gt;WAIT_TRANSMIT -->
<g id="edge64" class="edge">
<title>WAIT_TRANSMIT&#45;&gt;WAIT_TRANSMIT</title>
<path fill="none" stroke="black" d="M201.32,-870.54C213.79,-868.83 222,-865.61 222,-860.88 222,-857.77 218.47,-855.31 212.51,-853.51"/>
<polygon fill="black" stroke="black" points="213.3,-850.1 202.8,-851.52 211.9,-856.96 213.3,-850.1"/>
<text text-anchor="middle" x="254.25" y="-855.83" font-family="Times,serif" font-size="14.00">sd_data==1</text>
</g>
<!-- WAIT_END -->
<g id="node43" class="node">
<title>WAIT_END</title>
<ellipse fill="none" stroke="black" cx="102" cy="-738.73" rx="60.1" ry="28.99"/>
<text text-anchor="middle" x="102" y="-741.93" font-family="Times,serif" font-size="14.00">WAIT_END</text>
<text text-anchor="middle" x="102" y="-725.43" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- WAIT_TRANSMIT&#45;&gt;WAIT_END -->
<g id="edge65" class="edge">
<title>WAIT_TRANSMIT&#45;&gt;WAIT_END</title>
<path fill="none" stroke="black" d="M102,-819.87C102,-806.91 102,-792.54 102,-779.59"/>
<polygon fill="black" stroke="black" points="105.5,-779.68 102,-769.68 98.5,-779.68 105.5,-779.68"/>
<text text-anchor="middle" x="134.25" y="-788.92" font-family="Times,serif" font-size="14.00">sd_data==0</text>
</g>
<!-- WAIT_END&#45;&gt;WAIT_END -->
<g id="edge66" class="edge">
<title>WAIT_END&#45;&gt;WAIT_END</title>
<path fill="none" stroke="black" d="M158.87,-748.78C171.18,-747.79 180.1,-744.44 180.1,-738.73 180.1,-734.97 176.26,-732.24 170.14,-730.53"/>
<polygon fill="black" stroke="black" points="170.8,-727.09 160.36,-728.92 169.66,-734 170.8,-727.09"/>
<text text-anchor="middle" x="210.1" y="-733.68" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- FINISH_TRANSMIT -->
<g id="node44" class="node">
<title>FINISH_TRANSMIT</title>
<ellipse fill="none" stroke="black" cx="102" cy="-628.24" rx="96.17" ry="28.99"/>
<text text-anchor="middle" x="102" y="-631.44" font-family="Times,serif" font-size="14.00">FINISH_TRANSMIT</text>
<text text-anchor="middle" x="102" y="-614.94" font-family="Times,serif" font-size="14.00">address++</text>
</g>
<!-- WAIT_END&#45;&gt;FINISH_TRANSMIT -->
<g id="edge67" class="edge">
<title>WAIT_END&#45;&gt;FINISH_TRANSMIT</title>
<path fill="none" stroke="black" d="M102,-709.51C102,-697.17 102,-682.49 102,-669.07"/>
<polygon fill="black" stroke="black" points="105.5,-669.21 102,-659.21 98.5,-669.21 105.5,-669.21"/>
<text text-anchor="middle" x="133.88" y="-678.43" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- TRANSMIT2 -->
<g id="node45" class="node">
<title>TRANSMIT2</title>
<ellipse fill="none" stroke="black" cx="102" cy="-509.93" rx="102" ry="52.33"/>
<text text-anchor="middle" x="102" y="-529.63" font-family="Times,serif" font-size="14.00">TRANSMIT2</text>
<text text-anchor="middle" x="102" y="-513.13" font-family="Times,serif" font-size="14.00">cmd=17</text>
<text text-anchor="middle" x="102" y="-496.63" font-family="Times,serif" font-size="14.00">arg=address</text>
<text text-anchor="middle" x="102" y="-480.13" font-family="Times,serif" font-size="14.00">send_command.start=1</text>
</g>
<!-- FINISH_TRANSMIT&#45;&gt;TRANSMIT2 -->
<g id="edge68" class="edge">
<title>FINISH_TRANSMIT&#45;&gt;TRANSMIT2</title>
<path fill="none" stroke="black" d="M102,-598.79C102,-591.21 102,-582.72 102,-574.07"/>
<polygon fill="black" stroke="black" points="105.5,-574.21 102,-564.21 98.5,-574.21 105.5,-574.21"/>
</g>
<!-- WAIT_TRANSMIT2 -->
<g id="node46" class="node">
<title>WAIT_TRANSMIT2</title>
<ellipse fill="none" stroke="black" cx="102" cy="-379.94" rx="102" ry="40.66"/>
<text text-anchor="middle" x="102" y="-391.39" font-family="Times,serif" font-size="14.00">WAIT_TRANSMIT2</text>
<text text-anchor="middle" x="102" y="-374.89" font-family="Times,serif" font-size="14.00">send_command.start=0</text>
<text text-anchor="middle" x="102" y="-358.39" font-family="Times,serif" font-size="14.00">counter=4114</text>
</g>
<!-- TRANSMIT2&#45;&gt;WAIT_TRANSMIT2 -->
<g id="edge69" class="edge">
<title>TRANSMIT2&#45;&gt;WAIT_TRANSMIT2</title>
<path fill="none" stroke="black" d="M102,-457.24C102,-449.03 102,-440.55 102,-432.35"/>
<polygon fill="black" stroke="black" points="105.5,-432.52 102,-422.52 98.5,-432.52 105.5,-432.52"/>
</g>
<!-- WAIT_TRANSMIT2&#45;&gt;WAIT_TRANSMIT2 -->
<g id="edge70" class="edge">
<title>WAIT_TRANSMIT2&#45;&gt;WAIT_TRANSMIT2</title>
<path fill="none" stroke="black" d="M201.32,-389.6C213.79,-387.9 222,-384.68 222,-379.94 222,-376.83 218.47,-374.38 212.51,-372.58"/>
<polygon fill="black" stroke="black" points="213.3,-369.16 202.8,-370.59 211.9,-376.02 213.3,-369.16"/>
<text text-anchor="middle" x="254.25" y="-374.89" font-family="Times,serif" font-size="14.00">sd_data==1</text>
</g>
<!-- WAIT_END2 -->
<g id="node47" class="node">
<title>WAIT_END2</title>
<ellipse fill="none" stroke="black" cx="111" cy="-257.79" rx="64.88" ry="28.99"/>
<text text-anchor="middle" x="111" y="-260.99" font-family="Times,serif" font-size="14.00">WAIT_END2</text>
<text text-anchor="middle" x="111" y="-244.49" font-family="Times,serif" font-size="14.00">counter&#45;&#45;</text>
</g>
<!-- WAIT_TRANSMIT2&#45;&gt;WAIT_END2 -->
<g id="edge71" class="edge">
<title>WAIT_TRANSMIT2&#45;&gt;WAIT_END2</title>
<path fill="none" stroke="black" d="M105,-338.93C105.97,-325.97 107.04,-311.6 108.01,-298.65"/>
<polygon fill="black" stroke="black" points="111.5,-298.98 108.76,-288.75 104.52,-298.46 111.5,-298.98"/>
<text text-anchor="middle" x="139.56" y="-307.98" font-family="Times,serif" font-size="14.00">sd_data==0</text>
</g>
<!-- WAIT_END2&#45;&gt;WAIT_END2 -->
<g id="edge72" class="edge">
<title>WAIT_END2&#45;&gt;WAIT_END2</title>
<path fill="none" stroke="black" d="M172.44,-267.75C184.93,-266.67 193.88,-263.35 193.88,-257.79 193.88,-254.06 189.84,-251.33 183.4,-249.62"/>
<polygon fill="black" stroke="black" points="184.37,-246.23 173.94,-248.07 183.24,-253.14 184.37,-246.23"/>
<text text-anchor="middle" x="223.88" y="-252.74" font-family="Times,serif" font-size="14.00">counter!=0</text>
</g>
<!-- FINISH_TRANSMIT2 -->
<g id="node48" class="node">
<title>FINISH_TRANSMIT2</title>
<ellipse fill="none" stroke="black" cx="150" cy="-135.64" rx="132.76" ry="40.66"/>
<text text-anchor="middle" x="150" y="-147.09" font-family="Times,serif" font-size="14.00">FINISH_TRANSMIT2</text>
<text text-anchor="middle" x="150" y="-130.59" font-family="Times,serif" font-size="14.00">address++</text>
<text text-anchor="middle" x="150" y="-114.09" font-family="Times,serif" font-size="14.00">sd_buffer_half=!sd_buffer_half</text>
</g>
<!-- WAIT_END2&#45;&gt;FINISH_TRANSMIT2 -->
<g id="edge73" class="edge">
<title>WAIT_END2&#45;&gt;FINISH_TRANSMIT2</title>
<path fill="none" stroke="black" d="M120.14,-228.62C124.16,-216.24 129.01,-201.31 133.62,-187.12"/>
<polygon fill="black" stroke="black" points="136.85,-188.49 136.61,-177.9 130.19,-186.33 136.85,-188.49"/>
<text text-anchor="middle" x="162.38" y="-197.5" font-family="Times,serif" font-size="14.00">counter==0</text>
</g>
<!-- WAIT_FOR_BUFFER -->
<g id="node49" class="node">
<title>WAIT_FOR_BUFFER</title>
<ellipse fill="none" stroke="black" cx="309" cy="-28.99" rx="99.88" ry="28.99"/>
<text text-anchor="middle" x="309" y="-32.19" font-family="Times,serif" font-size="14.00">WAIT_FOR_BUFFER</text>
<text text-anchor="middle" x="309" y="-15.69" font-family="Times,serif" font-size="14.00">ready=1</text>
</g>
<!-- FINISH_TRANSMIT2&#45;&gt;WAIT_FOR_BUFFER -->
<g id="edge74" class="edge">
<title>FINISH_TRANSMIT2&#45;&gt;WAIT_FOR_BUFFER</title>
<path fill="none" stroke="black" d="M205.16,-98.33C223.02,-86.58 242.7,-73.63 260.07,-62.19"/>
<polygon fill="black" stroke="black" points="261.77,-65.27 268.2,-56.85 257.92,-59.42 261.77,-65.27"/>
</g>
<!-- WAIT_FOR_BUFFER&#45;&gt;TRANSMIT -->
<g id="edge76" class="edge">
<title>WAIT_FOR_BUFFER&#45;&gt;TRANSMIT</title>
<path fill="none" stroke="black" d="M311.51,-58.39C313.15,-79.43 315,-108.8 315,-134.64 315,-861.88 315,-861.88 315,-861.88 315,-892.18 297.13,-919.09 275.99,-940.32"/>
<polygon fill="black" stroke="black" points="273.67,-937.7 268.85,-947.13 278.5,-942.76 273.67,-937.7"/>
<text text-anchor="middle" x="431.63" y="-504.88" font-family="Times,serif" font-size="14.00">sd_buffer_half!=audio_buffer.address_half</text>
</g>
<!-- WAIT_FOR_BUFFER&#45;&gt;WAIT_FOR_BUFFER -->
<g id="edge75" class="edge">
<title>WAIT_FOR_BUFFER&#45;&gt;WAIT_FOR_BUFFER</title>
<path fill="none" stroke="black" d="M405.66,-36.84C418.42,-35.5 426.88,-32.89 426.88,-28.99 426.88,-26.37 423.06,-24.33 416.68,-22.87"/>
<polygon fill="black" stroke="black" points="417.58,-19.47 407.16,-21.37 416.49,-26.38 417.58,-19.47"/>
<text text-anchor="middle" x="545.38" y="-23.94" font-family="Times,serif" font-size="14.00">sd_buffer_half==audio_buffer.address_half</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 56 KiB

View File

@ -1,23 +0,0 @@
digraph send_command {
READY [shape="doublecircle",label="READY\ncounter=48\nready"]
node [shape="ellipse"]
SEND_CRC [label="SEND_CRC\n!ready\ncrc_start=1\nto_send={2'b01,command,arguments,8'b1}"]
DELAY [label="DELAY\ncrc_start=0"]
WAIT_CRC [label="WAIT_CRC\nto_send[7:1]=crc"]
SEND_DATA [label="SEND_DATA\ncounter--\nsend_sd_cmd=to_send[counter-1]"]
READY -> READY [label="!start"]
READY -> SEND_CRC [label="start"]
SEND_CRC -> DELAY;
DELAY -> WAIT_CRC;
WAIT_CRC -> WAIT_CRC [label="!crc_ready"]
WAIT_CRC -> SEND_DATA [label="crc_ready"]
SEND_DATA -> SEND_DATA [label="counter!=1"]
SEND_DATA -> READY [label="counter==0"]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -1,5 +0,0 @@
// A global error counter, useful for when we're tracking error counts from
// assertions
package assertion_error;
int errors;
endpackage : assertion_error

View File

@ -1,18 +0,0 @@
interface audio_buffer_interface;
logic [10:0] addra;
logic [7:0] dina;
logic clka;
logic ena;
logic address_half;
modport driver (
output addra, dina, clka, ena,
input address_half
);
modport receiver (
input addra, dina, clka, ena,
output address_half
);
endinterface

View File

@ -1,7 +0,0 @@
`ifndef SDVD_DEFS
`define SDVD_DEFS
package sdvd_defs;
// Playback speed type
typedef logic [4:0] SPEED;
endpackage
`endif

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +0,0 @@
for i in range(1,256):
print(hex(i))
for i in range(0,10):
for i in range(0,256):
print(hex(i))

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +0,0 @@
`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 audio buffer is currently playing
logic playing;
// A 16-bit audio sample to output
logic [15:0] sample;
logic [9:0] counter;
logic [15:0] test_memory [1023:0];
audio_buffer_interface buffer();
audio_buffer dut(.driver(buffer),.*);
// The writer's clock should be much faster than the 48khz buffer clock
initial buffer.clka = 0;
always #5 buffer.clka = ~buffer.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
buffer.ena = 1;
for (int i = 0; i<= 1024; i++) begin
buffer.addra = i*2;
buffer.dina = i[7:0];
@(posedge buffer.clka)
buffer.addra = i*2+1;
buffer.dina = i[15:8];
@(posedge buffer.clka);
end
wait (buffer.address_half==1);
// random test, write to lower half of memory
for (int i = 0; i< 512; i++) begin
buffer.addra = i*2;
buffer.dina = $urandom;
test_memory[i][7:0] = buffer.dina;
@(posedge buffer.clka)
buffer.addra = i*2+1;
buffer.dina = $urandom;
test_memory[i][15:8] = buffer.dina;
@(posedge buffer.clka);
end
wait (buffer.address_half==0);
// random test, write to upper half of memory
for (int i = 512; i< 1024; i++) begin
buffer.addra = i*2;
buffer.dina = $urandom;
test_memory[i][7:0] = buffer.dina;
@(posedge buffer.clka)
buffer.addra = i*2+1;
buffer.dina = $urandom;
test_memory[i][15:8] = buffer.dina;
@(posedge buffer.clka);
end
end
join
$finish;
end
endmodule

View File

@ -1,57 +0,0 @@
/*****
* pwm_tb.sv - testbench for the pwm.sv module.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/2025
* */
module pwm_tb;
bit clk, reset;
logic load;
wire pwm_pin;
logic [15:0] sample;
pwm #(16) dut (.*);
initial forever #10 clk = ~clk;
initial begin
reset = 1;
@(posedge clk);
@(posedge clk);
reset = 0;
load = 1;
sample = 0;
for (int i=0; i < (1<<16)-1; i++) begin
@(posedge clk) assert (pwm_pin === 0)
else $error("Should be low at %d",i);
end
reset = 0;
load = 1;
sample = '1;
@(posedge clk)
for (int i=0; i < (1<<16)-1; i++) begin
@(posedge clk) assert (pwm_pin === 'z)
else $error("Should be high at %d",i);
end
reset = 0;
load = 1;
// Should be about half on
sample = 1<<15;
@(posedge clk)
for (int i=0; i < (1<<15); i++) begin
@(posedge clk) assert (pwm_pin === 'z)
else $error("Should be high at %d",i);
end
sample = 1<<15;
for (int i = (1 << 15); i < (1<<16)-1; i++) begin
@(posedge clk) assert (pwm_pin === 0)
else $error("Should be low at %d",i);
end
$finish;
end
endmodule

View File

@ -1,34 +0,0 @@
`ifdef VERILATOR
`include "assertion_error.sv"
`endif
module debouncer_assertions(input logic clk, reset,source, out);
// Check that no matter how long the button is held down, output will only be
// high once
property only_one_per_press_p;
(source && out) |=> (source |-> ((!out) throughout (source[+])));
endproperty
only_one_per_press_a: assert property (@(posedge clk) only_one_per_press_p)
else assertion_error::errors++;
// Check that the output is never high two cycles in a row
property out_not_high_consecutively_p;
out |=> !out;
endproperty
out_not_high_consecutively_a: assert property (@(posedge clk) out_not_high_consecutively_p)
else assertion_error::errors++;
// Check that the output always turns off if the button is depressed
property off_if_depressed_p;
!source |-> !out;
endproperty
off_if_depressed_a: assert property (@(posedge clk) off_if_depressed_p)
else assertion_error::errors++;
// Check that the output activates if the button is pressed
property on_if_pressed_p;
!source |=> (source |-> out);
endproperty
on_if_pressed_a: assert property (@(posedge clk) on_if_pressed_p);
endmodule

View File

@ -1,80 +1,8 @@
`timescale 1ns / 1ps
`ifdef VERILATOR
`include "assertion_error.sv"
`endif
import assertion_error::errors;
module debouncer_tb;
parameter TESTCYCLES=1000;
logic clk,reset,source;
wire out;
debouncer Dut (.*);
bind debouncer debouncer_assertions AssertDut (.*);
initial begin
clk = 0;
forever #10 clk = ~clk;
end
initial begin
// Turn assertions off during reset
$assertoff;
$display("Testing debouncer");
reset = 1;
source = 0;
@(posedge clk);
@(posedge clk);
reset = 0;
$asserton;
@(posedge clk);
source = 1;
#1;
assert (out == 1) else begin
$error("Output not brought high during first press");
errors++;
end
@(posedge clk);
#1;
assert (out == 0) else begin
$error("Output not brought low after first press");
errors++;
end
@(posedge clk);
source = 0;
@(posedge clk);
source = 1;
#1;
assert (out == 1) else begin
$error("Output not brought high during second press");
errors++;
end
@(posedge clk);
source = 0;
@(posedge clk);
#1;
assert (out == 0) else begin
$error("Output not brought low after second press");
errors++;
end
@(posedge clk);
@(posedge clk);
$display("Generating random input to test assertions");
for (int i=0; i<TESTCYCLES; i++) begin
source = $urandom;
@(posedge clk);
end
if (errors == 0)
$display("Found no errors while testing debouncer");
else
$display("ERROR: Found %0d errors while testing debouncer", errors);
$finish;
end
endmodule

View File

@ -1,108 +0,0 @@
/****
* playback_controller_tb.sv - a testbench for the playback_controller.sv
* module.
*
* @author: Dilanthi Prentice
* @date: [unsure of due date]
*
* */
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;
module playback_controller_tb;
logic clk, reset;
logic play, ff;
SPEED speed;
int errors;
//instatiate the dut
playback_controller dut(clk, reset, play, ff, speed);
//clock generation
initial clk = 0;
always #5 clk = ~clk;
//play button press
task press_play();
play = 1;
@(posedge clk);
play = 0;
@(posedge clk);
endtask
//ff button press
task press_ff();
ff = 1;
@(posedge clk);
ff = 0;
@(posedge clk);
endtask
initial
begin
@(posedge clk);
play = 0;
ff = 0;
reset = 1;
@(posedge clk);
reset = 0;
@(posedge clk);
assert (speed === 0) else
begin
$error("Speed not zero after reset");
errors++;
end
@(posedge clk);
press_play();
assert (speed === 1) else
begin
$error("Play not working");
errors++;
end
press_play();
assert (speed === 0) else
begin
$error("Pause not working");
errors++;
end
press_ff();
assert (speed === 2) else
begin
$error("Not in FF2 after ff btn pressed once");
errors++;
end
press_ff();
assert (speed === 4) else
begin
$error("Not in FF4 after ff btn pressed twice");
errors++;
end
press_ff();
assert (speed === 8) else
begin
$error("Not in FF8 after ff btn pressed thrice");
errors++;
end
press_play();
assert (speed === 0) else
begin
$error("Unsuccessful return to pause after play btn pressed from a FF state");
errors++;
end
if (errors === 0)
$display("No errors detected in playback_controller");
$finish;
end
endmodule

View File

@ -1,49 +0,0 @@
module crc_gen_tb;
parameter CRCBITS=7;
parameter COMMANDLEN=40;
parameter POLYNOMIAL='h89;
logic clk, reset, start, ready;
logic [COMMANDLEN-1:0] num;
logic [CRCBITS-1:0] crc;
logic [CRCBITS-1:0] test_cases [logic [COMMANDLEN-1:0]];
crc_gen #(CRCBITS,COMMANDLEN,POLYNOMIAL) dut (.*);
initial begin
clk = 0;
forever #10 clk = ~clk;
end
initial begin
test_cases = '{
'h1234567890: 'h10,
'hBEEFB05535: 'h05,
'h5544992211: 'h17,
'0: '0
};
reset = 1;
start = 0;
repeat (2) @(posedge clk);
reset = 0;
@(posedge clk);
foreach (test_cases[key]) begin
wait (ready);
num = key;
@(posedge clk);
start = 1;
@(posedge clk);
start = 0;
@(posedge clk);
wait(ready);
assert (crc === test_cases[key])
else $error("Invalid crc, found 0x%x but expected 0x%x",crc,test_cases[key]);
end
$finish;
end
endmodule

View File

@ -1,81 +0,0 @@
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

View File

@ -1,144 +0,0 @@
`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

View File

@ -1,155 +0,0 @@
`ifdef VERILATOR
`include "sdvd_defs.sv"
`endif
module rom_sd_tb;
bit clk,reset;
wire ready;
int errors;
logic [10:0] i;
audio_buffer_interface buffer();
rom_sd #("consecutive.mem") dut (clk,reset,ready,buffer.driver);
initial forever #10 clk = ~clk;
initial begin
reset = 1;
buffer.address_half = 0;
@(posedge clk);
reset = 0;
// Audio data should not be flowing yet
#1 assert (buffer.dina == 0)
else begin
errors++;
$error("Data not zero after reset, found 0x%x",buffer.dina);
end
repeat (3) @(posedge clk);
for (i = 0; i < 1024;) begin
@(posedge clk);
#1
assert (buffer.addra === i)
else begin
errors++;
$error("Incorrect address, expected %x found %x",i,buffer.addra);
end
assert (buffer.dina === ((i + 1) % 256))
else begin
errors++;
$error("Incorrect data, expected 0x%x but found 0x%x",i[7:0],buffer.dina);
end
assert (i == 0 || buffer.ena === 1)
else begin
$error("Enable not high");
errors++;
end
assert (buffer.address_half == 0)
else begin
errors++;
$error("Incorrect address half, expected 0 but found %d",buffer.address_half);
end
i = i + 1;
end
// Wait a cycle for the buffer to catch up
@(posedge clk);
// Make sure that we start waiting and that we signal that the buffer
// is ready
#1 assert(buffer.ena === 0)
else begin
errors++;
$error("Buffer did not wait after first full cycle");
end
assert(ready === 1)
else begin
errors++;
$error("Buffer did not signal ready");
end
assert(dut.buffer_half === 1)
else begin
errors++;
$error("Buffer half did not correctly change to 1");
end
// Set the address half high so we can test waiting/catching up to the
// buffer
buffer.address_half = 1;
repeat (100) @(posedge clk);
#1 assert(buffer.ena === 0)
else begin
errors++;
$error("Buffer did not wait after first full cycle");
end
buffer.address_half = 0;
repeat (3) @(posedge clk);
// Check that sending into the upper half of the buffer works as
// expected
while (i != 0) begin
@(posedge clk);
#1
assert (buffer.addra === i)
else begin
errors++;
$error("Incorrect address, expected %x found %x",i,buffer.addra);
end
assert (buffer.dina === ((i + 1) % 256))
else begin
errors++;
$error("Incorrect data, expected 0x%x but found 0x%x",i[7:0],buffer.dina);
end
assert (i == 0 || buffer.ena === 1)
else begin
$error("Enable not high");
errors++;
end
assert (buffer.address_half == 0)
else begin
errors++;
$error("Incorrect address half, expected 0 but found %d",buffer.address_half);
end
i = i + 1;
end
// Wait a cycle for the buffer to catch up
@(posedge clk);
// Make sure that we start waiting
#1 assert(buffer.ena === 0)
else begin
errors++;
$error("Buffer did not wait after second full cycle");
end
assert(ready === 1)
else begin
errors++;
$error("Buffer did not signal ready");
end
assert(dut.buffer_half === 0)
else begin
errors++;
$error("Buffer half did not correctly change to 0");
end
$display("Found %0d errors while testing rom_sd",errors);
$finish;
end
endmodule

View File

@ -1,45 +0,0 @@
module sd_controller_tb;
bit slow_clk,fast_clk,crc_clk;
logic reset,sd_data;
wire sd_cmd;
wire ready;
wire clk;
audio_buffer_interface buffer ();
sd_controller dut (.buffer(buffer.driver), .*);
bit sd_write;
assign sd_cmd = sd_write ? 'z : 0;
initial forever #100 slow_clk = ~slow_clk;
initial forever #1 crc_clk = ~crc_clk;
initial forever #10 fast_clk = ~fast_clk;
initial begin
sd_write = 1;
reset = 1;
repeat (2) @(posedge slow_clk);
reset = 0;
repeat (200) @(posedge slow_clk);
send_response();
repeat (100) @(posedge slow_clk);
send_response();
repeat (100) @(posedge slow_clk);
$finish;
end
task automatic send_response();
for(int i=0;i<47;i++)
@(posedge slow_clk) sd_write = 0;
@(posedge slow_clk) sd_write = 1;
endtask
endmodule

View File

@ -1,66 +0,0 @@
module send_command_tb;
bit clk;
// The crc should be clocked way faster than the sender
bit crc_clk;
logic reset;
logic start;
logic [5:0] command;
logic [31:0] arguments;
wire ready;
wire sd_cmd;
logic [47:0] fill_me;
int counter;
logic sd_cmd_real;
assign sd_cmd_real = (sd_cmd === 'z) ? 1 : 0;
send_command dut(.*);
initial forever #100 clk = ~clk;
initial forever #20 crc_clk = ~crc_clk;
initial begin
reset = 1;
start = 0;
repeat (2) @(posedge clk);
reset = 0;
@(posedge clk);
start = 1;
command = 8;
arguments = 'h1AA;
counter = 48;
@(posedge clk);
start = 0;
// Try receiving the CMD8
while (counter != 0) begin
// Check for the start bit, or that we're receiving a message
if (sd_cmd_real != 1 || counter != 48) begin
fill_me = {fill_me[46:0], sd_cmd_real};
counter--;
end
@(posedge clk);
end
assert (fill_me === {2'b01, 6'd8, 32'h1AA, 8'h87})
else $error("Received wrong command, got 0x%x",fill_me);
repeat (1) @(posedge clk);
assert (ready)
else $error("SD command sender not ready");
repeat (10) @(posedge clk);
$finish;
end
endmodule

View File

@ -1,12 +1,3 @@
/****
* seconds_display_tb.sv - testbench for the seconds_display module.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* */
`timescale 1ns / 1ps
module seconds_display_tb;
int errors = 0;
logic [5:0] seconds;
@ -16,7 +7,7 @@ wire [6:0] display_ones;
logic [6:0] expected_tens;
logic [6:0] expected_ones;
sixty_display Dut(.number(seconds),.*);
seconds_display Dut(.*);
initial begin
$display("Testing seconds_display");
for (seconds=0; seconds<60; seconds++) begin
@ -25,16 +16,14 @@ initial begin
#1
if (display_ones !== expected_ones) begin
errors++;
$error("Failed ones test case, seconds = %d, displayed = %b, expected = %b",
seconds,
$display("Failed ones test case, displayed = %b, expected = %b",
display_ones,
expected_ones);
end
else
if (display_tens !== expected_tens) begin
errors++;
$error("Failed tens test case, seconds = %d, displayed = %b, expected = %b",
seconds,
$display("Failed tens test case, displayed = %b, expected = %b",
display_tens,
expected_tens);
end

View File

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="crc_gen_tb_behav.wdb" id="1">
<top_modules>
<top_module name="crc_gen_tb" />
<top_module name="glbl" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="609.789 ns"></ZoomStartTime>
<ZoomEndTime time="1,276.290 ns"></ZoomEndTime>
<Cursor1Time time="209.703 ns"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="533"></NameColumnWidth>
<ValueColumnWidth column_width="219"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="10" />
<wvobject type="logic" fp_name="/crc_gen_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/crc_gen_tb/reset">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/crc_gen_tb/start">
<obj_property name="ElementShortName">start</obj_property>
<obj_property name="ObjectShortName">start</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/crc_gen_tb/ready">
<obj_property name="ElementShortName">ready</obj_property>
<obj_property name="ObjectShortName">ready</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/num">
<obj_property name="ElementShortName">num[39:0]</obj_property>
<obj_property name="ObjectShortName">num[39:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/crc">
<obj_property name="ElementShortName">crc[6:0]</obj_property>
<obj_property name="ObjectShortName">crc[6:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/CRCBITS">
<obj_property name="ElementShortName">CRCBITS[31:0]</obj_property>
<obj_property name="ObjectShortName">CRCBITS[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/COMMANDLEN">
<obj_property name="ElementShortName">COMMANDLEN[31:0]</obj_property>
<obj_property name="ObjectShortName">COMMANDLEN[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/POLYNOMIAL">
<obj_property name="ElementShortName">POLYNOMIAL[31:0]</obj_property>
<obj_property name="ObjectShortName">POLYNOMIAL[31:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/crc_gen_tb/dut/counter">
<obj_property name="ElementShortName">counter[6:0]</obj_property>
<obj_property name="ObjectShortName">counter[6:0]</obj_property>
</wvobject>
</wave_config>

View File

@ -1,67 +0,0 @@
<?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>

View File

@ -1,96 +0,0 @@
<?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>

View File

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="rom_sd_tb_behav.wdb" id="1">
<top_modules>
<top_module name="glbl" />
<top_module name="rom_sd_tb" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="0.000 ns"></ZoomStartTime>
<ZoomEndTime time="143.201 ns"></ZoomEndTime>
<Cursor1Time time="0.000 ns"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="453"></NameColumnWidth>
<ValueColumnWidth column_width="200"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="10" />
<wvobject type="logic" fp_name="/rom_sd_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/rom_sd_tb/reset">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/rom_sd_tb/ready">
<obj_property name="ElementShortName">ready</obj_property>
<obj_property name="ObjectShortName">ready</obj_property>
</wvobject>
<wvobject type="array" fp_name="/rom_sd_tb/dut/rom_data">
<obj_property name="ElementShortName">rom_data[7:0]</obj_property>
<obj_property name="ObjectShortName">rom_data[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/rom_sd_tb/dut/current">
<obj_property name="ElementShortName">current[2:0]</obj_property>
<obj_property name="ObjectShortName">current[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/rom_sd_tb/dut/rom_addr">
<obj_property name="ElementShortName">rom_addr[16:0]</obj_property>
<obj_property name="ObjectShortName">rom_addr[16:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/rom_sd_tb/dut/rom_enable">
<obj_property name="ElementShortName">rom_enable</obj_property>
<obj_property name="ObjectShortName">rom_enable</obj_property>
</wvobject>
<wvobject type="array" fp_name="/rom_sd_tb/buffer/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="/rom_sd_tb/buffer/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="/rom_sd_tb/buffer/ena">
<obj_property name="ElementShortName">ena</obj_property>
<obj_property name="ObjectShortName">ena</obj_property>
</wvobject>
</wave_config>

View File

@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="sd_controller_tb_behav.wdb" id="1">
<top_modules>
<top_module name="glbl" />
<top_module name="sd_controller_tb" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="41,685.336 ns"></ZoomStartTime>
<ZoomEndTime time="44,957.696 ns"></ZoomEndTime>
<Cursor1Time time="0.000 ns"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="469"></NameColumnWidth>
<ValueColumnWidth column_width="172"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="11" />
<wvobject type="logic" fp_name="/sd_controller_tb/slow_clk">
<obj_property name="ElementShortName">slow_clk</obj_property>
<obj_property name="ObjectShortName">slow_clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/fast_clk">
<obj_property name="ElementShortName">fast_clk</obj_property>
<obj_property name="ObjectShortName">fast_clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/crc_clk">
<obj_property name="ElementShortName">crc_clk</obj_property>
<obj_property name="ObjectShortName">crc_clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/reset">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/sd_data">
<obj_property name="ElementShortName">sd_data</obj_property>
<obj_property name="ObjectShortName">sd_data</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_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="/sd_controller_tb/ready">
<obj_property name="ElementShortName">ready</obj_property>
<obj_property name="ObjectShortName">ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="array" fp_name="/sd_controller_tb/dut/state">
<obj_property name="ElementShortName">state[5:0]</obj_property>
<obj_property name="ObjectShortName">state[5:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/dut/sender/ready">
<obj_property name="ElementShortName">ready</obj_property>
<obj_property name="ObjectShortName">ready</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/sd_controller_tb/dut/reader/received">
<obj_property name="ElementShortName">received</obj_property>
<obj_property name="ObjectShortName">received</obj_property>
</wvobject>
</wave_config>