Compare commits

...

21 Commits

Author SHA1 Message Date
39894196dd
Add verification section to design.pdf
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-12 20:20:06 -07:00
d4d890f0ea
Update design doc
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-12 20:07:05 -07:00
180857bb39
Add design document
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-11 22:50:03 -07:00
43573f5d8f Added a few more demos and one last attempt
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
at audio fixup. It did nothing of course lol

Reverted back to 16-bit pcm because it sounds marginally better than
8-bit
2025-06-10 14:27:39 -07:00
89131404a3 Merge pull request 'comment_clean_up' (#4) from comment_clean_up into master
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
Reviewed-on: #4
2025-06-10 20:40:39 +00:00
ce217dbbdf Merge branch 'master' into comment_clean_up 2025-06-10 13:32:14 -07:00
f840d27b8e Demo commit
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
The audio output is still messed up, but this commit gets everything as
ready as it can get. Fixed up all the testbenches and added state
machines for everything
2025-06-10 13:26:35 -07:00
9af830daa0 comment clean up 2025-06-10 02:51:18 -07:00
53b48c0bce comment clean up for segment_display folder 2025-06-10 01:38:52 -07:00
a07e811a16 code clean up for playback_controller.sv 2025-06-10 01:30:51 -07:00
fe227d1b61 Broken SD card
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
How tf did it break bro
2025-06-09 15:41:13 -07:00
71eecd18e8 Added modules to read sdcard data and cmd response
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
These were realy headaches but the testbenches are passing. We need to
take a look at the audio_buffer testbench for sure, it is way wrong and
needs reworked to use the interface. Should do a pass through every
module probably.
2025-06-07 21:57:17 -07:00
e32563131f Added command signal driver module
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-06 20:49:18 -07:00
71f08bdf15 Add CRC generation for sd card
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
Works great according to the testbench
2025-06-06 18:13:14 -07:00
35cb264b26 Its working! Demo commit
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
We have something at least, audio is working and sounding dang good
2025-06-06 01:06:20 -07:00
7980424dc8 Lots of changes, trying to get ROM working
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
I think I did some funny math errors so new goal is 8-bit pcm
2025-06-05 18:48:53 -07:00
02e2d77640 header for rom_sd.sv
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-04 14:34:49 -07:00
1beb6cbf5c Implement rom_sd state machine
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-04 13:17:36 -07:00
89558d8313
More fixup on rom_sd
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-03 22:36:57 -07:00
2387fdbe3b
Fixup on rom_sd flowchart
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-03 22:36:01 -07:00
0015a0d7bc Merge pull request 'added headers/ updated old ones' (#3) from header_changes into master
All checks were successful
ci/woodpecker/push/test-workflow Pipeline was successful
Reviewed-on: #3
2025-06-03 00:51:19 +00:00
60 changed files with 774721 additions and 320 deletions

2
.gitignore vendored
View File

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

View File

@ -31,7 +31,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] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict {PACKAGE_PIN H17 IOSTANDARD LVCMOS33} [get_ports {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]
@ -153,14 +153,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 }]; #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]
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]}]
##Accelerometer
#set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports { ACL_MISO }]; #IO_L11P_T1_SRCC_15 Sch=acl_miso
@ -182,8 +182,8 @@ set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports BTNR]
#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 }]; #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
set_property -dict {PACKAGE_PIN A11 IOSTANDARD LVCMOS33} [get_ports AUD_PWM]
set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports 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
@ -216,68 +216,73 @@ set_property -dict {PACKAGE_PIN M17 IOSTANDARD LVCMOS33} [get_ports BTNR]
#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 1 [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 1024 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL 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 6 [get_debug_ports u_ila_0/probe0]
connect_debug_port u_ila_0/probe0 [get_nets [list {seconds_reg[0]} {seconds_reg[1]} {seconds_reg[2]} {seconds_reg[3]} {seconds_reg[4]} {seconds_reg[5]}]]
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 6 [get_debug_ports u_ila_0/probe1]
connect_debug_port u_ila_0/probe1 [get_nets [list {minutes[0]} {minutes[1]} {minutes[2]} {minutes[3]} {minutes[4]} {minutes[5]}]]
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 3 [get_debug_ports u_ila_0/probe2]
connect_debug_port u_ila_0/probe2 [get_nets [list {playbackController/current[0]} {playbackController/current[1]} {playbackController/current[2]}]]
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 {hours_reg[0]} {hours_reg[1]} {hours_reg[2]} {hours_reg[3]} {hours_reg[4]} {hours_reg[5]}]]
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 3 [get_debug_ports u_ila_0/probe4]
connect_debug_port u_ila_0/probe4 [get_nets [list {anodeDriver/mux_select[0]} {anodeDriver/mux_select[1]} {anodeDriver/mux_select[2]}]]
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 8 [get_debug_ports u_ila_0/probe5]
connect_debug_port u_ila_0/probe5 [get_nets [list {AN_OBUF[0]} {AN_OBUF[1]} {AN_OBUF[2]} {AN_OBUF[3]} {AN_OBUF[4]} {AN_OBUF[5]} {AN_OBUF[6]} {AN_OBUF[7]}]]
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 CA_OBUF]]
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 CB_OBUF]]
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 CC_OBUF]]
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 CD_OBUF]]
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 CE_OBUF]]
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 CF_OBUF]]
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 CG_OBUF]]
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]

562
SDVD.xpr
View File

@ -44,7 +44,8 @@
<Option Name="SimulatorGccVersionRiviera" Val="9.3.0"/>
<Option Name="SimulatorGccVersionActiveHdl" Val="9.3.0"/>
<Option Name="BoardPart" Val=""/>
<Option Name="ActiveSimSet" Val="sim_1"/>
<Option Name="SourceMgmtMode" Val="DisplayOnly"/>
<Option Name="ActiveSimSet" Val="read_data_tb"/>
<Option Name="DefaultLib" Val="xil_defaultlib"/>
<Option Name="ProjectType" Val="Default"/>
<Option Name="IPRepoPath" Val="$PPRDIR/../../../fpga/vivado-library"/>
@ -60,7 +61,7 @@
<Option Name="IPStaticSourceDir" Val="$PIPUSERFILESDIR/ipstatic"/>
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSABoardId" Val="nexys-a7-100t"/>
<Option Name="WTXSimLaunchSim" Val="87"/>
<Option Name="WTXSimLaunchSim" Val="237"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
@ -91,6 +92,27 @@
<FileSets Version="1" Minor="32">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1" RelGenDir="$PGENDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/lib/audio_buffer_interface.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/lib/sdvd_defs.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/audio/audio_buffer.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/debouncer.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
@ -119,6 +141,13 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/modular_clock_gen.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/playback_controller.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
@ -126,7 +155,14 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/segment_display/seconds_display.sv">
<File Path="$PPRDIR/design/audio/pwm.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sd/rom_sd.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -140,25 +176,62 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sdvd_defs.sv">
<File Path="$PPRDIR/lib/assertion_error.sv">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/audio/audio_buffer.sv">
<File Path="$PPRDIR/roms/roundabout.mem">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/roms/even_flow_16.mem">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sd/send_command.sv">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/audio/pwm.sv">
<File Path="$PPRDIR/design/sd/crc_gen.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sd/read_command.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sd/read_data.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sd/sd_controller.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/segment_display/sixty_display.sv">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
@ -169,6 +242,7 @@
<Option Name="TopModule" Val="nexys_a7_top"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="VerilogDir" Val="$PPRDIR/design"/>
<Option Name="VerilogDir" Val="$PPRDIR/lib"/>
</Config>
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1" RelGenDir="$PGENDIR/constrs_1">
@ -260,16 +334,15 @@
</FileSet>
<FileSet Name="playback_controller_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/playback_controller_tb" RelGenDir="$PGENDIR/playback_controller_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/playback_controller_tb.sv">
<File Path="$PPRDIR/lib/sdvd_defs.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/design/sdvd_defs.sv">
<File Path="$PPRDIR/verification/playback_controller_tb.sv">
<FileInfo>
<Attr Name="AutoDisabled" Val="1"/>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
@ -320,6 +393,244 @@
<Option Name="xsim.simulate.runtime" Val="10s"/>
</Config>
</FileSet>
<FileSet Name="rom_sd_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/rom_sd_tb" RelGenDir="$PGENDIR/rom_sd_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/roms/testfile.mem">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/sd/rom_sd_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/waveform_configs/rom_sd_waveform.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/roms/consecutive.mem">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="rom_sd_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/rom_sd_waveform.wcfg"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="pwm_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/pwm_tb" RelGenDir="$PGENDIR/pwm_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/audio/pwm_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="pwm_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="crc_gen_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/crc_gen_tb" RelGenDir="$PGENDIR/crc_gen_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/sd/rom_sd_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/sd/crc_gen_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/waveform_configs/crc_gen_tb_behav.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="crc_gen_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/crc_gen_tb_behav.wcfg"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="send_command_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/send_command_tb" RelGenDir="$PGENDIR/send_command_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/sd/send_command_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="send_command_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="read_command_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/read_command_tb" RelGenDir="$PGENDIR/read_command_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/sd/read_command_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/waveform_configs/read_command_tb_behav.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="read_command_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/read_command_tb_behav.wcfg"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="read_data_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/read_data_tb" RelGenDir="$PGENDIR/read_data_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/sd/read_data_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/waveform_configs/read_data_tb_behav.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="read_data_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/read_data_tb_behav.wcfg"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
<FileSet Name="sd_controller_tb" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sd_controller_tb" RelGenDir="$PGENDIR/sd_controller_tb">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/verification/sd/sd_controller_tb.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/verification/waveform_configs/sd_controller_tb_behav.wcfg">
<FileInfo>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="sd_controller_tb"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
<Option Name="SelectedSimModel" Val="rtl"/>
<Option Name="PamDesignTestbench" Val=""/>
<Option Name="PamDutBypassFile" Val="xil_dut_bypass"/>
<Option Name="PamSignalDriverFile" Val="xil_bypass_driver"/>
<Option Name="PamPseudoTop" Val="pseudo_tb"/>
<Option Name="SrcSet" Val="sources_1"/>
<Option Name="XSimWcfgFile" Val="$PPRDIR/verification/waveform_configs/sd_controller_tb_behav.wcfg"/>
<Option Name="CosimPdi" Val=""/>
<Option Name="CosimPlatform" Val=""/>
<Option Name="CosimElf" Val=""/>
<Option Name="xsim.simulate.runtime" Val="1s"/>
</Config>
</FileSet>
</FileSets>
<Simulators>
<Simulator Name="XSim">
@ -345,9 +656,7 @@
<Runs Version="1" Minor="22">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="true" IncrementalCheckpoint="$PSRCDIR/utils_1/imports/synth_1/nexys_a7_top.dcp" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true" IsChild="false" AutoIncrementalDir="$PSRCDIR/utils_1/imports/synth_1" AutoRQSDir="$PSRCDIR/utils_1/imports/synth_1" ParallelReportGen="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2024">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2024"/>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
@ -355,11 +664,9 @@
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" LaunchOptions="-jobs 2 " AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1" ParallelReportGen="true">
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1" LaunchOptions="-jobs 4 " AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1" ParallelReportGen="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
@ -389,58 +696,58 @@
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024" CtrlBit="true">
<ReportConfig DisplayName="Timing Summary - Design Initialization" Name="impl_1_copy_1_init_report_timing_summary_0" Spec="report_timing_summary" RunStep="init_design" ReportFile="nexys_a7_top_timing_summary_init.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Design Initialization" Name="impl_1_copy_1_init_report_timing_summary_0" Spec="report_timing_summary" RunStep="init_design" ReportFile="nexys_a7_top_timing_summary_init_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Opt Design" Name="impl_1_copy_1_opt_report_drc_0" Spec="report_drc" RunStep="opt_design" ReportFile="nexys_a7_top_drc_opted.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="DRC - Opt Design" Name="impl_1_copy_1_opt_report_drc_0" Spec="report_drc" RunStep="opt_design" ReportFile="nexys_a7_top_drc_opted_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Opt Design" Name="impl_1_copy_1_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="opt_design" ReportFile="nexys_a7_top_timing_summary_opted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Opt Design" Name="impl_1_copy_1_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="opt_design" ReportFile="nexys_a7_top_timing_summary_opted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Power Opt Design" Name="impl_1_copy_1_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="power_opt_design" ReportFile="nexys_a7_top_timing_summary_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Power Opt Design" Name="impl_1_copy_1_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="power_opt_design" ReportFile="nexys_a7_top_timing_summary_pwropted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="IO - Place Design" Name="impl_1_copy_1_place_report_io_0" Spec="report_io" RunStep="place_design" ReportFile="nexys_a7_top_io_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="IO - Place Design" Name="impl_1_copy_1_place_report_io_0" Spec="report_io" RunStep="place_design" ReportFile="nexys_a7_top_io_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Utilization - Place Design" Name="impl_1_copy_1_place_report_utilization_0" Spec="report_utilization" RunStep="place_design" ReportFile="nexys_a7_top_utilization_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Utilization - Place Design" Name="impl_1_copy_1_place_report_utilization_0" Spec="report_utilization" RunStep="place_design" ReportFile="nexys_a7_top_utilization_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Control Sets - Place Design" Name="impl_1_copy_1_place_report_control_sets_0" Spec="report_control_sets" RunStep="place_design" ReportFile="nexys_a7_top_control_sets_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Control Sets - Place Design" Name="impl_1_copy_1_place_report_control_sets_0" Spec="report_control_sets" RunStep="place_design" ReportFile="nexys_a7_top_control_sets_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="verbose" Type="" Value="true"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_1_place_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_pre_placed.rpt.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_1_place_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_pre_placed.rpt_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_1_place_report_incremental_reuse_1" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_1_place_report_incremental_reuse_1" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_placed_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Place Design" Name="impl_1_copy_1_place_report_timing_summary_0" Spec="report_timing_summary" RunStep="place_design" ReportFile="nexys_a7_top_timing_summary_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Place Design" Name="impl_1_copy_1_place_report_timing_summary_0" Spec="report_timing_summary" RunStep="place_design" ReportFile="nexys_a7_top_timing_summary_placed_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Power Opt Design" Name="impl_1_copy_1_post_place_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_place_power_opt_design" ReportFile="nexys_a7_top_timing_summary_postplace_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Post-Place Power Opt Design" Name="impl_1_copy_1_post_place_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_place_power_opt_design" ReportFile="nexys_a7_top_timing_summary_postplace_pwropted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Phys Opt Design" Name="impl_1_copy_1_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="phys_opt_design" ReportFile="nexys_a7_top_timing_summary_physopted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Post-Place Phys Opt Design" Name="impl_1_copy_1_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="phys_opt_design" ReportFile="nexys_a7_top_timing_summary_physopted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
@ -449,50 +756,50 @@
<ReportConfig DisplayName="implementation_log" Name="impl_1_copy_1_route_implementation_log_0" Spec="" RunStep="route_design" ReportFile="nexys_a7_top.vdi">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Route Design" Name="impl_1_copy_1_route_report_drc_0" Spec="report_drc" RunStep="route_design" ReportFile="nexys_a7_top_drc_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="DRC - Route Design" Name="impl_1_copy_1_route_report_drc_0" Spec="report_drc" RunStep="route_design" ReportFile="nexys_a7_top_drc_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Methodology - Route Design" Name="impl_1_copy_1_route_report_methodology_0" Spec="report_methodology" RunStep="route_design" ReportFile="nexys_a7_top_methodology_drc_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Methodology - Route Design" Name="impl_1_copy_1_route_report_methodology_0" Spec="report_methodology" RunStep="route_design" ReportFile="nexys_a7_top_methodology_drc_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Power - Route Design" Name="impl_1_copy_1_route_report_power_0" Spec="report_power" RunStep="route_design" ReportFile="nexys_a7_top_power_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Power - Route Design" Name="impl_1_copy_1_route_report_power_0" Spec="report_power" RunStep="route_design" ReportFile="nexys_a7_top_power_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Route Status - Route Design" Name="impl_1_copy_1_route_report_route_status_0" Spec="report_route_status" RunStep="route_design" ReportFile="nexys_a7_top_route_status.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Route Status - Route Design" Name="impl_1_copy_1_route_report_route_status_0" Spec="report_route_status" RunStep="route_design" ReportFile="nexys_a7_top_route_status_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Route Design" Name="impl_1_copy_1_route_report_timing_summary_0" Spec="report_timing_summary" RunStep="route_design" ReportFile="nexys_a7_top_timing_summary_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Timing Summary - Route Design" Name="impl_1_copy_1_route_report_timing_summary_0" Spec="report_timing_summary" RunStep="route_design" ReportFile="nexys_a7_top_timing_summary_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Route Design" Name="impl_1_copy_1_route_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="route_design" ReportFile="nexys_a7_top_incremental_reuse_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Incremental Reuse - Route Design" Name="impl_1_copy_1_route_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="route_design" ReportFile="nexys_a7_top_incremental_reuse_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Clock Utilization - Route Design" Name="impl_1_copy_1_route_report_clock_utilization_0" Spec="report_clock_utilization" RunStep="route_design" ReportFile="nexys_a7_top_clock_utilization_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Clock Utilization - Route Design" Name="impl_1_copy_1_route_report_clock_utilization_0" Spec="report_clock_utilization" RunStep="route_design" ReportFile="nexys_a7_top_clock_utilization_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Route Design" Name="impl_1_copy_1_route_report_bus_skew_0" Spec="report_bus_skew" RunStep="route_design" ReportFile="nexys_a7_top_bus_skew_routed.rpt" Version="1" Minor="1">
<ReportConfig DisplayName="Bus Skew - Route Design" Name="impl_1_copy_1_route_report_bus_skew_0" Spec="report_bus_skew" RunStep="route_design" ReportFile="nexys_a7_top_bus_skew_routed_1.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Route Phys Opt Design" Name="impl_1_copy_1_post_route_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_timing_summary_postroute_physopted.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Timing Summary - Post-Route Phys Opt Design" Name="impl_1_copy_1_post_route_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_timing_summary_postroute_physopted_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Post-Route Phys Opt Design" Name="impl_1_copy_1_post_route_phys_opt_report_bus_skew_0" Spec="report_bus_skew" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_bus_skew_postroute_physopted.rpt" Version="1" Minor="1">
<ReportConfig DisplayName="Bus Skew - Post-Route Phys Opt Design" Name="impl_1_copy_1_post_route_phys_opt_report_bus_skew_0" Spec="report_bus_skew" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_bus_skew_postroute_physopted_1.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
@ -518,58 +825,58 @@
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024" CtrlBit="true">
<ReportConfig DisplayName="Timing Summary - Design Initialization" Name="impl_1_copy_2_init_report_timing_summary_0" Spec="report_timing_summary" RunStep="init_design" ReportFile="nexys_a7_top_timing_summary_init.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Design Initialization" Name="impl_1_copy_2_init_report_timing_summary_0" Spec="report_timing_summary" RunStep="init_design" ReportFile="nexys_a7_top_timing_summary_init_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Opt Design" Name="impl_1_copy_2_opt_report_drc_0" Spec="report_drc" RunStep="opt_design" ReportFile="nexys_a7_top_drc_opted.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="DRC - Opt Design" Name="impl_1_copy_2_opt_report_drc_0" Spec="report_drc" RunStep="opt_design" ReportFile="nexys_a7_top_drc_opted_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Opt Design" Name="impl_1_copy_2_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="opt_design" ReportFile="nexys_a7_top_timing_summary_opted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Opt Design" Name="impl_1_copy_2_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="opt_design" ReportFile="nexys_a7_top_timing_summary_opted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Power Opt Design" Name="impl_1_copy_2_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="power_opt_design" ReportFile="nexys_a7_top_timing_summary_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Power Opt Design" Name="impl_1_copy_2_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="power_opt_design" ReportFile="nexys_a7_top_timing_summary_pwropted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="IO - Place Design" Name="impl_1_copy_2_place_report_io_0" Spec="report_io" RunStep="place_design" ReportFile="nexys_a7_top_io_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="IO - Place Design" Name="impl_1_copy_2_place_report_io_0" Spec="report_io" RunStep="place_design" ReportFile="nexys_a7_top_io_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Utilization - Place Design" Name="impl_1_copy_2_place_report_utilization_0" Spec="report_utilization" RunStep="place_design" ReportFile="nexys_a7_top_utilization_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Utilization - Place Design" Name="impl_1_copy_2_place_report_utilization_0" Spec="report_utilization" RunStep="place_design" ReportFile="nexys_a7_top_utilization_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Control Sets - Place Design" Name="impl_1_copy_2_place_report_control_sets_0" Spec="report_control_sets" RunStep="place_design" ReportFile="nexys_a7_top_control_sets_placed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Control Sets - Place Design" Name="impl_1_copy_2_place_report_control_sets_0" Spec="report_control_sets" RunStep="place_design" ReportFile="nexys_a7_top_control_sets_placed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="verbose" Type="" Value="true"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_2_place_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_pre_placed.rpt.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_2_place_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_pre_placed.rpt_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_2_place_report_incremental_reuse_1" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_2_place_report_incremental_reuse_1" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_placed_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Place Design" Name="impl_1_copy_2_place_report_timing_summary_0" Spec="report_timing_summary" RunStep="place_design" ReportFile="nexys_a7_top_timing_summary_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Place Design" Name="impl_1_copy_2_place_report_timing_summary_0" Spec="report_timing_summary" RunStep="place_design" ReportFile="nexys_a7_top_timing_summary_placed_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Power Opt Design" Name="impl_1_copy_2_post_place_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_place_power_opt_design" ReportFile="nexys_a7_top_timing_summary_postplace_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Post-Place Power Opt Design" Name="impl_1_copy_2_post_place_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_place_power_opt_design" ReportFile="nexys_a7_top_timing_summary_postplace_pwropted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Phys Opt Design" Name="impl_1_copy_2_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="phys_opt_design" ReportFile="nexys_a7_top_timing_summary_physopted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfig DisplayName="Timing Summary - Post-Place Phys Opt Design" Name="impl_1_copy_2_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="phys_opt_design" ReportFile="nexys_a7_top_timing_summary_physopted_1.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
@ -578,50 +885,50 @@
<ReportConfig DisplayName="implementation_log" Name="impl_1_copy_2_route_implementation_log_0" Spec="" RunStep="route_design" ReportFile="nexys_a7_top.vdi">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Route Design" Name="impl_1_copy_2_route_report_drc_0" Spec="report_drc" RunStep="route_design" ReportFile="nexys_a7_top_drc_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="DRC - Route Design" Name="impl_1_copy_2_route_report_drc_0" Spec="report_drc" RunStep="route_design" ReportFile="nexys_a7_top_drc_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Methodology - Route Design" Name="impl_1_copy_2_route_report_methodology_0" Spec="report_methodology" RunStep="route_design" ReportFile="nexys_a7_top_methodology_drc_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Methodology - Route Design" Name="impl_1_copy_2_route_report_methodology_0" Spec="report_methodology" RunStep="route_design" ReportFile="nexys_a7_top_methodology_drc_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Power - Route Design" Name="impl_1_copy_2_route_report_power_0" Spec="report_power" RunStep="route_design" ReportFile="nexys_a7_top_power_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Power - Route Design" Name="impl_1_copy_2_route_report_power_0" Spec="report_power" RunStep="route_design" ReportFile="nexys_a7_top_power_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Route Status - Route Design" Name="impl_1_copy_2_route_report_route_status_0" Spec="report_route_status" RunStep="route_design" ReportFile="nexys_a7_top_route_status.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Route Status - Route Design" Name="impl_1_copy_2_route_report_route_status_0" Spec="report_route_status" RunStep="route_design" ReportFile="nexys_a7_top_route_status_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Route Design" Name="impl_1_copy_2_route_report_timing_summary_0" Spec="report_timing_summary" RunStep="route_design" ReportFile="nexys_a7_top_timing_summary_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Timing Summary - Route Design" Name="impl_1_copy_2_route_report_timing_summary_0" Spec="report_timing_summary" RunStep="route_design" ReportFile="nexys_a7_top_timing_summary_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Route Design" Name="impl_1_copy_2_route_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="route_design" ReportFile="nexys_a7_top_incremental_reuse_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Incremental Reuse - Route Design" Name="impl_1_copy_2_route_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="route_design" ReportFile="nexys_a7_top_incremental_reuse_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Clock Utilization - Route Design" Name="impl_1_copy_2_route_report_clock_utilization_0" Spec="report_clock_utilization" RunStep="route_design" ReportFile="nexys_a7_top_clock_utilization_routed.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Clock Utilization - Route Design" Name="impl_1_copy_2_route_report_clock_utilization_0" Spec="report_clock_utilization" RunStep="route_design" ReportFile="nexys_a7_top_clock_utilization_routed_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Route Design" Name="impl_1_copy_2_route_report_bus_skew_0" Spec="report_bus_skew" RunStep="route_design" ReportFile="nexys_a7_top_bus_skew_routed.rpt" Version="1" Minor="1">
<ReportConfig DisplayName="Bus Skew - Route Design" Name="impl_1_copy_2_route_report_bus_skew_0" Spec="report_bus_skew" RunStep="route_design" ReportFile="nexys_a7_top_bus_skew_routed_1.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Route Phys Opt Design" Name="impl_1_copy_2_post_route_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_timing_summary_postroute_physopted.rpt" Version="1" Minor="0">
<ReportConfig DisplayName="Timing Summary - Post-Route Phys Opt Design" Name="impl_1_copy_2_post_route_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_timing_summary_postroute_physopted_1.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Post-Route Phys Opt Design" Name="impl_1_copy_2_post_route_phys_opt_report_bus_skew_0" Spec="report_bus_skew" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_bus_skew_postroute_physopted.rpt" Version="1" Minor="1">
<ReportConfig DisplayName="Bus Skew - Post-Route Phys Opt Design" Name="impl_1_copy_2_post_route_phys_opt_report_bus_skew_0" Spec="report_bus_skew" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_bus_skew_postroute_physopted_1.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
@ -633,6 +940,135 @@
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
<Run Id="impl_1_copy_3" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" SynthRun="synth_1" IncludeInArchive="true" IsChild="false" GenFullBitstream="true" AutoIncrementalDir="$PSRCDIR/utils_1/imports/impl_1/impl_1_copy_3" AutoRQSDir="$PSRCDIR/utils_1/imports/impl_1/impl_1_copy_3" ParallelReportGen="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
<Step Id="place_design"/>
<Step Id="post_place_power_opt_design"/>
<Step Id="phys_opt_design"/>
<Step Id="route_design"/>
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024" CtrlBit="true">
<ReportConfig DisplayName="Timing Summary - Design Initialization" Name="impl_1_copy_3_init_report_timing_summary_0" Spec="report_timing_summary" RunStep="init_design" ReportFile="nexys_a7_top_timing_summary_init.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Opt Design" Name="impl_1_copy_3_opt_report_drc_0" Spec="report_drc" RunStep="opt_design" ReportFile="nexys_a7_top_drc_opted.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Opt Design" Name="impl_1_copy_3_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="opt_design" ReportFile="nexys_a7_top_timing_summary_opted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Power Opt Design" Name="impl_1_copy_3_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="power_opt_design" ReportFile="nexys_a7_top_timing_summary_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="IO - Place Design" Name="impl_1_copy_3_place_report_io_0" Spec="report_io" RunStep="place_design" ReportFile="nexys_a7_top_io_placed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Utilization - Place Design" Name="impl_1_copy_3_place_report_utilization_0" Spec="report_utilization" RunStep="place_design" ReportFile="nexys_a7_top_utilization_placed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Control Sets - Place Design" Name="impl_1_copy_3_place_report_control_sets_0" Spec="report_control_sets" RunStep="place_design" ReportFile="nexys_a7_top_control_sets_placed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="verbose" Type="" Value="true"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_3_place_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_pre_placed.rpt.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Place Design" Name="impl_1_copy_3_place_report_incremental_reuse_1" Spec="report_incremental_reuse" RunStep="place_design" ReportFile="nexys_a7_top_incremental_reuse_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Place Design" Name="impl_1_copy_3_place_report_timing_summary_0" Spec="report_timing_summary" RunStep="place_design" ReportFile="nexys_a7_top_timing_summary_placed.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Power Opt Design" Name="impl_1_copy_3_post_place_power_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_place_power_opt_design" ReportFile="nexys_a7_top_timing_summary_postplace_pwropted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Place Phys Opt Design" Name="impl_1_copy_3_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="phys_opt_design" ReportFile="nexys_a7_top_timing_summary_physopted.rpt" Version="1" Minor="0" IsDisabled="true">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="implementation_log" Name="impl_1_copy_3_route_implementation_log_0" Spec="" RunStep="route_design" ReportFile="nexys_a7_top.vdi">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="DRC - Route Design" Name="impl_1_copy_3_route_report_drc_0" Spec="report_drc" RunStep="route_design" ReportFile="nexys_a7_top_drc_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Methodology - Route Design" Name="impl_1_copy_3_route_report_methodology_0" Spec="report_methodology" RunStep="route_design" ReportFile="nexys_a7_top_methodology_drc_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Power - Route Design" Name="impl_1_copy_3_route_report_power_0" Spec="report_power" RunStep="route_design" ReportFile="nexys_a7_top_power_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Route Status - Route Design" Name="impl_1_copy_3_route_report_route_status_0" Spec="report_route_status" RunStep="route_design" ReportFile="nexys_a7_top_route_status.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Route Design" Name="impl_1_copy_3_route_report_timing_summary_0" Spec="report_timing_summary" RunStep="route_design" ReportFile="nexys_a7_top_timing_summary_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Incremental Reuse - Route Design" Name="impl_1_copy_3_route_report_incremental_reuse_0" Spec="report_incremental_reuse" RunStep="route_design" ReportFile="nexys_a7_top_incremental_reuse_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Clock Utilization - Route Design" Name="impl_1_copy_3_route_report_clock_utilization_0" Spec="report_clock_utilization" RunStep="route_design" ReportFile="nexys_a7_top_clock_utilization_routed.rpt" Version="1" Minor="0">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Route Design" Name="impl_1_copy_3_route_report_bus_skew_0" Spec="report_bus_skew" RunStep="route_design" ReportFile="nexys_a7_top_bus_skew_routed.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Timing Summary - Post-Route Phys Opt Design" Name="impl_1_copy_3_post_route_phys_opt_report_timing_summary_0" Spec="report_timing_summary" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_timing_summary_postroute_physopted.rpt" Version="1" Minor="0">
<ReportConfigOption Name="max_paths" Type="" Value="10"/>
<ReportConfigOption Name="report_unconstrained" Type="" Value="true"/>
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="Bus Skew - Post-Route Phys Opt Design" Name="impl_1_copy_3_post_route_phys_opt_report_bus_skew_0" Spec="report_bus_skew" RunStep="post_route_phys_opt_design" ReportFile="nexys_a7_top_bus_skew_postroute_physopted.rpt" Version="1" Minor="1">
<ReportConfigOption Name="warn_on_violation" Type="" Value="true"/>
<ReportConfigOutputOption Name="pb" Type="string" Value=""/>
<ReportConfigOutputOption Name="rpx" Type="string" Value=""/>
</ReportConfig>
<ReportConfig DisplayName="implementation_log" Name="impl_1_copy_3_bitstream_implementation_log_0" Spec="" RunStep="write_bitstream" ReportFile="nexys_a7_top.vdi">
<ReportConfigOption Name="dummy_option" Type="string"/>
</ReportConfig>
</ReportStrategy>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/>
</Run>
</Runs>
<Board/>
<DashboardSummary Version="1" Minor="0">

BIN
design.pdf Normal file

Binary file not shown.

View File

@ -6,6 +6,9 @@
* @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
@ -31,22 +34,23 @@ module audio_buffer(
// Inputs for the memory buffer
audio_buffer_interface.receiver driver
);
// Whether the current address being read from is in the upper or lower
// half of the 2KiB buffer
let address_half = driver.address_half;
logic [9:0] address;
// Size of samples, 8bit or 16bit supported
parameter SIZE=16;
(* MARK_DEBUG = "TRUE" *)
logic [11-(SIZE/8):0] address;
// State register
logic enb;
logic [15:0] doutb;
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 address_half = address[9];
assign driver.address_half = address[11-(SIZE/8)];
always_ff @(posedge clk) begin
enb <= 0;
@ -74,10 +78,8 @@ always_ff @(posedge clk) begin
// This will overflow to the correct value always
address <= address + speed;
enb <= 1;
// NOTE: I really don't know a good way to generate the load
// signal. It maybe could be an inverted 48khz clock?
if (delay == 0) begin
sample <= doutb;
sample[15-:SIZE] <= doutb;
end
else begin
sample <= '0;
@ -88,67 +90,69 @@ always_ff @(posedge clk) begin
end
end
//xpm_memory_sdpram #(
// .WRITE_DATA_WIDTH_A(16)
//) buffer ();
//vivado block ram xpm macro
xpm_memory_sdpram #(
.ADDR_WIDTH_A(11), // DECIMAL
.ADDR_WIDTH_B(10), // 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(16), // 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
.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.
.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
.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
.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.
//active high reset
.rstb(reset), // 1-bit input: Reset signal for the final port B output register stage.
.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
.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

@ -16,8 +16,12 @@ module pwm(
// 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 [15:0] pulse_counter;
logic [DEPTH-1:0] pulse_counter;
(* MARK_DEBUG = "TRUE" *)
logic [15:0] sample_buffer;
logic should_output;
@ -27,6 +31,7 @@ begin
begin
pulse_counter <= 0;
sample_buffer <= 0;
should_output <= 0;
end
else
@ -36,7 +41,7 @@ begin
pulse_counter <= pulse_counter + 1;
if (pulse_counter < sample_buffer)
if (pulse_counter < sample_buffer[15-:DEPTH])
should_output <= 1;
else
should_output <= 0;

View File

@ -6,7 +6,7 @@
* @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
@ -19,7 +19,7 @@ module low_freq_clock_gen(
output logic clk1k, clk10h, seconds_pulse
);
// Hardcoded to be 1,000,000/4,000
// Hardcoded to be 1,000,000/4,000 (25,000)
// Relying on constant maths makes it the wrong size
localparam num_cycles = 25_000;

View File

@ -0,0 +1,34 @@
/****
* 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

@ -12,8 +12,14 @@ 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 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
@ -21,10 +27,13 @@ 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;
@ -32,18 +41,33 @@ 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;
low_freq_clock_gen clockGen(CLK100MHZ, reset, speed, clk_1khz, clk_10hz, seconds_pulse);
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) begin
always_ff @(posedge seconds_pulse or posedge reset) begin
if (reset) begin
seconds <= 0;
minutes <= 0;
@ -64,16 +88,70 @@ end
display_anode_driver anodeDriver(clk_1khz,reset,AN,segment_mux_select);
seconds_display secondsSegment (seconds, segments[1], segments[0]);
seconds_display minutesSegment (minutes, segments[3], segments[2]);
seconds_display hoursSegment (hours, segments[5], segments[4]);
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

@ -9,6 +9,8 @@
*
* */
//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
@ -35,7 +37,6 @@ 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);

47
design/sd/crc_gen.sv Normal file
View File

@ -0,0 +1,47 @@
/***
* 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

138
design/sd/read_command.sv Normal file
View File

@ -0,0 +1,138 @@
/****
* 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

76
design/sd/read_data.sv Normal file
View File

@ -0,0 +1,76 @@
/***
* 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,59 +1,30 @@
// A dummy sdcard module for testing the audio port
module sd(
/****
* 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 audio_buffer
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 initializing;
logic [16:0] rom_address;
logic [18:0] rom_addr;
logic [7:0] rom_data;
logic rom_enable;
// Keep track of pipeline delay so we don't write garbage into the buffer
logic delay;
// Keep track of if we are caught up to the buffer or not
logic waiting;
//TODO: This probably could be an assign, not sure
assign ready = '1;
always_ff @(posedge clk) begin
if (reset) begin
delay <= 1;
rom_address <= 0;
initializing <= 1;
audio_buffer.addra <= 0;
audio_buffer.ena <= 0;
end
else if (initializing) begin
rom_enable <= 1;
case (delay)
1: delay <= 0;
0: begin
rom_address <= 1;
delay <= 0;
initializing <= 0;
end
endcase
end
else begin
if (!waiting) begin
audio_buffer.ena <= 1;
audio_buffer.dina <= rom_data;
audio_buffer.addra <= audio_buffer.addra + 1;
end
end
end
logic buffer_half;
// xpm_memory_sprom: Single Port ROM
@ -62,42 +33,140 @@ end
// 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(17), // 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("roundabout.mem"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("auto"), // String
.MEMORY_SIZE(131072*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
.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_address), // 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
.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.
.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

445
design/sd/sd_controller.sv Normal file
View File

@ -0,0 +1,445 @@
/****
* 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

113
design/sd/send_command.sv Normal file
View File

@ -0,0 +1,113 @@
/***
* 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

View File

@ -17,11 +17,15 @@ module display_anode_driver(
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]};

View File

@ -1,30 +0,0 @@
/***
* seconds_display.sv - converts a five bit seconds counter to its seven segement display equivalent.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25
*
*/
module seconds_display
(
input [$clog2(60)-1:0] seconds,
output [6:0] display_tens,
output [6:0] display_ones
);
logic [4:0] ones_digit;
logic [4:0] tens_digit;
always_comb
begin
ones_digit = seconds % 10;
tens_digit = seconds / 10;
end
//instantiate the display_converter to convert the counter
//to a seven segment display number
display_converter ones (ones_digit, display_ones);
display_converter tens (tens_digit, display_tens);
endmodule

View File

@ -0,0 +1,32 @@
/***
* 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

@ -12,3 +12,38 @@
### 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

@ -0,0 +1,22 @@
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"];
}

BIN
doc/playback_controller.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

24
doc/read_command.gv Normal file
View File

@ -0,0 +1,24 @@
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"]
}

BIN
doc/read_command.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@ -1,23 +1,30 @@
digraph rom_sd {
Reset [shape = doublecircle, label = "RESET\nbuffer_half = 0\nrom_address = 0\nrom_enable = 1\nbuf.addr=0\nready=0"];
Reset [shape = doublecircle, label = "RESET\nbuffer_half = 0\nrom_addr = 0\nrom_enable = 1\nbuffer.addra=0\nready=0"];
node [shape = circle];
Delay [label="DELAY\nrom_address++"];
WriteBuf [label="WRITEBUF\nbuf.ena=1\nbuf.data=rom_data\nbuf.addr++\nrom_addr++"];
EndWrite [label="ENDWRITE\nbuf.ena=1\nbuf.data=rom_data\nbuf.addr++\nready=1"];
Wait [label = "WAIT\nbuf.ena=0"];
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 -> Delay [label="!reset"];
Reset -> Delay1 [label="!reset"];
Delay -> WriteBuf;
Delay1 -> Delay2;
Delay2 -> Delay3;
Delay3 -> WriteBuf;
WriteBuf -> WriteBuf [label="buf.addr < 1023"]
WriteBuf -> EndWrite [label="buf.addr == 1023"]
WriteBuf -> WriteBuf [label="buffer.addra < 1023"]
WriteBuf -> EndWrite1 [label="buffer.addra == 1023"]
EndWrite -> Wait;
Wait -> Wait [label = "buffer_half == buf.address_half"]
Wait -> Delay [label = "buffer_half != buf.address_half"]
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: 107 KiB

After

Width:  |  Height:  |  Size: 177 KiB

161
doc/sd_controller.gv Normal file
View File

@ -0,0 +1,161 @@
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"];
}

BIN
doc/sd_controller.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

905
doc/sd_controller.svg Normal file
View File

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

After

Width:  |  Height:  |  Size: 56 KiB

23
doc/send_command.gv Normal file
View File

@ -0,0 +1,23 @@
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"]
}

BIN
doc/send_command.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

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

BIN
roms/birds_16_full.raw Normal file

Binary file not shown.

1
roms/birds_8_full.raw Normal file

File diff suppressed because one or more lines are too long

2815
roms/consecutive.mem Normal file

File diff suppressed because it is too large Load Diff

192000
roms/even_flow.mem Normal file

File diff suppressed because it is too large Load Diff

1
roms/even_flow.raw Normal file

File diff suppressed because one or more lines are too long

384000
roms/even_flow_16.mem Normal file

File diff suppressed because it is too large Load Diff

BIN
roms/even_flow_16.raw Normal file

Binary file not shown.

BIN
roms/even_flow_16_full.raw Normal file

Binary file not shown.

5
roms/gen_consecutive.py Normal file
View File

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

BIN
roms/hampster_dance.raw Normal file

Binary file not shown.

96000
roms/testfile.mem Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,29 +10,22 @@ module audio_buffer_tb;
logic play, stop;
SPEED speed;
// Whether the current address being read from is in the upper or lower
// half of the 2KiB buffer
logic address_half;
// Whether the audio buffer is currently playing
logic playing;
// A 16-bit audio sample to output
logic [15:0] sample;
// Inputs for the memory buffer
logic [10:0] addra;
logic [7:0] dina;
logic clka, ena;
logic [9:0] counter;
logic [15:0] test_memory [1023:0];
audio_buffer dut(.*);
audio_buffer_interface buffer();
audio_buffer dut(.driver(buffer),.*);
// The writer's clock should be much faster than the 48khz buffer clock
initial clka = 0;
always #5 clka = ~clka;
initial buffer.clka = 0;
always #5 buffer.clka = ~buffer.clka;
// An order of magnitude difference is fine
@ -83,38 +76,38 @@ module audio_buffer_tb;
end
// Writer
begin
ena = 1;
buffer.ena = 1;
for (int i = 0; i<= 1024; i++) begin
addra = i*2;
dina = i[7:0];
@(posedge clka)
addra = i*2+1;
dina = i[15:8];
@(posedge clka);
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 (address_half==1);
wait (buffer.address_half==1);
// random test, write to lower half of memory
for (int i = 0; i< 512; i++) begin
addra = i*2;
dina = $urandom;
test_memory[i][7:0] = dina;
@(posedge clka)
addra = i*2+1;
dina = $urandom;
test_memory[i][15:8] = dina;
@(posedge clka);
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 (address_half==0);
wait (buffer.address_half==0);
// random test, write to upper half of memory
for (int i = 512; i< 1024; i++) begin
addra = i*2;
dina = $urandom;
test_memory[i][7:0] = dina;
@(posedge clka)
addra = i*2+1;
dina = $urandom;
test_memory[i][15:8] = dina;
@(posedge clka);
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

View File

@ -0,0 +1,57 @@
/*****
* 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,6 +0,0 @@
/*****
* pwn_tb.sv - testbench for the pwn.sv module.
*
* @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/2025
* */

View File

@ -60,6 +60,9 @@ initial begin
errors++;
end
@(posedge clk);
@(posedge clk);
$display("Generating random input to test assertions");
for (int i=0; i<TESTCYCLES; i++) begin
source = $urandom;

View File

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

@ -0,0 +1,81 @@
module read_command_tb;
bit clk;
logic reset;
logic listen;
logic [2:0] response_type;
logic sd_cmd;
wire received;
wire [135:0] out_data;
read_command dut (.*);
initial forever #10 clk = ~clk;
initial begin
$display("Testing read_command module");
sd_cmd = 1;
response_type = 0;
reset = 1;
listen = 0;
repeat (2) @(posedge clk);
reset = 0;
listen = 1;
response_type = 2;
@(posedge clk);
listen = 0;
response_type = 0;
repeat (5) @(posedge clk);
send_byte('h01);
for (int i=0; i<15; i++)
send_byte('hAA);
send_byte('h01);
@(posedge clk);
// NOTE: the received signal takes an extra cycle to propogate because
// it is loaded into a register
@(posedge clk);
#1;
assert (received === 1)
else $error("received signal not high");
assert (out_data === 'h01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01)
else $error("out_dat incorrect, found 0x%x but expected 0x01AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA01",out_data);
repeat (7) @(posedge clk);
listen = 1;
response_type = 3;
@(posedge clk);
listen = 0;
response_type = 0;
send_byte('h00);
send_byte('hAB);
send_byte('hCD);
send_byte('hEF);
send_byte('h12);
send_byte('h01);
// Return sd_cmd to inactive state
@(posedge clk) sd_cmd = 1;
@(posedge clk);
#1;
assert (received === 1)
else $error("received signal not high");
assert (out_data === 136'h00ABCDEF1201)
else $error("out_dat incorrect, found %b but expected 0x00ABCDEF1201",out_data);
@(posedge clk);
$finish;
end
task automatic send_byte(logic [7:0] b);
for (int i = 8; i != 0; i--) begin
@(posedge clk) sd_cmd = b[i-1];
end
endtask
endmodule

View File

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

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

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

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

@ -16,7 +16,7 @@ wire [6:0] display_ones;
logic [6:0] expected_tens;
logic [6:0] expected_ones;
seconds_display Dut(.*);
sixty_display Dut(.number(seconds),.*);
initial begin
$display("Testing seconds_display");
for (seconds=0; seconds<60; seconds++) begin

View File

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

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="read_command_tb_behav.wdb" id="1">
<top_modules>
<top_module name="glbl" />
<top_module name="read_command_tb" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="0.000 ns"></ZoomStartTime>
<ZoomEndTime time="1,370.001 ns"></ZoomEndTime>
<Cursor1Time time="330.000 ns"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="533"></NameColumnWidth>
<ValueColumnWidth column_width="187"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="11" />
<wvobject type="logic" fp_name="/read_command_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_command_tb/reset">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_command_tb/listen">
<obj_property name="ElementShortName">listen</obj_property>
<obj_property name="ObjectShortName">listen</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_command_tb/sd_cmd">
<obj_property name="ElementShortName">sd_cmd</obj_property>
<obj_property name="ObjectShortName">sd_cmd</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_command_tb/received">
<obj_property name="ElementShortName">received</obj_property>
<obj_property name="ObjectShortName">received</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/out_data">
<obj_property name="ElementShortName">out_data[39:0]</obj_property>
<obj_property name="ObjectShortName">out_data[39:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/dut/state">
<obj_property name="ElementShortName">state[2:0]</obj_property>
<obj_property name="ObjectShortName">state[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/dut/counter">
<obj_property name="ElementShortName">counter[6:0]</obj_property>
<obj_property name="ObjectShortName">counter[6:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/dut/data_reg">
<obj_property name="ElementShortName">data_reg[39:0]</obj_property>
<obj_property name="ObjectShortName">data_reg[39:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/response_type">
<obj_property name="ElementShortName">response_type[2:0]</obj_property>
<obj_property name="ObjectShortName">response_type[2:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_command_tb/dut/response_type_reg">
<obj_property name="ElementShortName">response_type_reg[2:0]</obj_property>
<obj_property name="ObjectShortName">response_type_reg[2:0]</obj_property>
</wvobject>
</wave_config>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="read_data_tb_behav.wdb" id="1">
<top_modules>
<top_module name="glbl" />
<top_module name="read_data_tb" />
<top_module name="sdvd_defs" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1,438.800 ns"></ZoomStartTime>
<ZoomEndTime time="1,718.201 ns"></ZoomEndTime>
<Cursor1Time time="618.800 ns"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="533"></NameColumnWidth>
<ValueColumnWidth column_width="155"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="18" />
<wvobject type="logic" fp_name="/read_data_tb/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/sd_clk">
<obj_property name="ElementShortName">sd_clk</obj_property>
<obj_property name="ObjectShortName">sd_clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/reset">
<obj_property name="ElementShortName">reset</obj_property>
<obj_property name="ObjectShortName">reset</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/play">
<obj_property name="ElementShortName">play</obj_property>
<obj_property name="ObjectShortName">play</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/stop">
<obj_property name="ElementShortName">stop</obj_property>
<obj_property name="ObjectShortName">stop</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/speed">
<obj_property name="ElementShortName">speed[3:0]</obj_property>
<obj_property name="ObjectShortName">speed[3:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/playing">
<obj_property name="ElementShortName">playing</obj_property>
<obj_property name="ObjectShortName">playing</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/sample">
<obj_property name="ElementShortName">sample[15:0]</obj_property>
<obj_property name="ObjectShortName">sample[15:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/counter">
<obj_property name="ElementShortName">counter[10:0]</obj_property>
<obj_property name="ObjectShortName">counter[10:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/test_memory">
<obj_property name="ElementShortName">test_memory[1023:0][15:0]</obj_property>
<obj_property name="ObjectShortName">test_memory[1023:0][15:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/bufferInterface/driver/addra">
<obj_property name="ElementShortName">addra[10:0]</obj_property>
<obj_property name="ObjectShortName">addra[10:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/bufferInterface/driver/dina">
<obj_property name="ElementShortName">dina[7:0]</obj_property>
<obj_property name="ObjectShortName">dina[7:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/bufferInterface/driver/ena">
<obj_property name="ElementShortName">ena</obj_property>
<obj_property name="ObjectShortName">ena</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/bufferInterface/driver/address_half">
<obj_property name="ElementShortName">address_half</obj_property>
<obj_property name="ObjectShortName">address_half</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/read_data_tb/sd_data">
<obj_property name="ElementShortName">sd_data</obj_property>
<obj_property name="ObjectShortName">sd_data</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/readerDut/byte_shift">
<obj_property name="ElementShortName">byte_shift[7:0]</obj_property>
<obj_property name="ObjectShortName">byte_shift[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/readerDut/byte_counter">
<obj_property name="ElementShortName">byte_counter[3:0]</obj_property>
<obj_property name="ObjectShortName">byte_counter[3:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/read_data_tb/readerDut/counter">
<obj_property name="ElementShortName">counter[13:0]</obj_property>
<obj_property name="ObjectShortName">counter[13:0]</obj_property>
</wvobject>
</wave_config>

View File

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

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