9 Commits

Author SHA1 Message Date
uelen 39894196dd Add verification section to design.pdf
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-12 20:20:06 -07:00
uelen d4d890f0ea Update design doc
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-12 20:07:05 -07:00
uelen 180857bb39 Add design document
ci/woodpecker/push/test-workflow Pipeline was successful
2025-06-11 22:50:03 -07:00
uelen 43573f5d8f Added a few more demos and one last attempt
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
uelen 89131404a3 Merge pull request 'comment_clean_up' (#4) from comment_clean_up into master
ci/woodpecker/push/test-workflow Pipeline was successful
Reviewed-on: #4
2025-06-10 20:40:39 +00:00
uelen ce217dbbdf Merge branch 'master' into comment_clean_up 2025-06-10 13:32:14 -07:00
Dilanthi 9af830daa0 comment clean up 2025-06-10 02:51:18 -07:00
Dilanthi 53b48c0bce comment clean up for segment_display folder 2025-06-10 01:38:52 -07:00
Dilanthi a07e811a16 code clean up for playback_controller.sv 2025-06-10 01:30:51 -07:00
17 changed files with 111 additions and 72 deletions
+2 -2
View File
@@ -249,8 +249,8 @@ 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]}]] 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 create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5]
set_property port_width 11 [get_debug_ports u_ila_0/probe5] set_property port_width 10 [get_debug_ports u_ila_0/probe5]
connect_debug_port u_ila_0/probe5 [get_nets [list {audioBuffer/address[0]} {audioBuffer/address[1]} {audioBuffer/address[2]} {audioBuffer/address[3]} {audioBuffer/address[4]} {audioBuffer/address[5]} {audioBuffer/address[6]} {audioBuffer/address[7]} {audioBuffer/address[8]} {audioBuffer/address[9]} {audioBuffer/address[10]}]] 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 create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] 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] set_property port_width 1 [get_debug_ports u_ila_0/probe6]
+2 -1
View File
@@ -664,7 +664,7 @@
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/> <RQSFiles/>
</Run> </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" 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"> <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"> <Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/> <StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2024"/>
<Step Id="init_design"/> <Step Id="init_design"/>
@@ -677,6 +677,7 @@
<Step Id="post_route_phys_opt_design"/> <Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/> <Step Id="write_bitstream"/>
</Strategy> </Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024"/> <ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2024"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/> <Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
<RQSFiles/> <RQSFiles/>
BIN
View File
Binary file not shown.
+7 -10
View File
@@ -6,6 +6,9 @@
* @date: 6/12/2025 * @date: 6/12/2025
* *
* */ * */
//define used here because verilator needs it but vivado is smart enough
//not to.
`ifdef VERILATOR `ifdef VERILATOR
`include "sdvd_defs.sv" `include "sdvd_defs.sv"
`endif `endif
@@ -75,8 +78,6 @@ always_ff @(posedge clk) begin
// This will overflow to the correct value always // This will overflow to the correct value always
address <= address + speed; address <= address + speed;
enb <= 1; 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 if (delay == 0) begin
sample[15-:SIZE] <= doutb; sample[15-:SIZE] <= doutb;
end end
@@ -89,9 +90,7 @@ always_ff @(posedge clk) begin
end end
end end
//xpm_memory_sdpram #( //vivado block ram xpm macro
// .WRITE_DATA_WIDTH_A(16)
//) buffer ();
xpm_memory_sdpram #( xpm_memory_sdpram #(
.ADDR_WIDTH_A(11), // DECIMAL .ADDR_WIDTH_A(11), // DECIMAL
.ADDR_WIDTH_B(12-(SIZE/8)), // DECIMAL .ADDR_WIDTH_B(12-(SIZE/8)), // DECIMAL
@@ -140,7 +139,6 @@ buffer (
.enb(enb), // 1-bit input: Memory enable signal for port B. Must be high on clock .enb(enb), // 1-bit input: Memory enable signal for port B. Must be high on clock
// cycles when read operations are initiated. Pipelined internally. // 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 // Synchronously resets output port doutb to the value specified by
// parameter READ_RESET_VALUE_B. // parameter READ_RESET_VALUE_B.
@@ -150,11 +148,10 @@ buffer (
// writing one byte of dina to address addra. For example, to // writing one byte of dina to address addra. For example, to
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A // synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
// is 32, wea would be 4'b0010. // is 32, wea would be 4'b0010.
// Extra inputs that I guess I need
.sleep(0), .sleep(0), // The XPM macros say these can be removed, but when I did this the
.injectsbiterra(0), .injectsbiterra(0), // entire block memory got optimized out. These were readded in later
.injectdbiterra(0), .injectdbiterra(0),
// With a latency of 1 this surely does not matter
.regceb(enb) .regceb(enb)
); );
+2 -2
View File
@@ -6,7 +6,7 @@
* @author: Waylon Cude, Dilanthi Prentice * @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025 * @date: 6/12/2025
* */ * */
//Define used because verilator needs it but vivado is samrt enough not to
`ifdef VERILATOR `ifdef VERILATOR
`include "sdvd_defs.sv" `include "sdvd_defs.sv"
`endif `endif
@@ -19,7 +19,7 @@ module low_freq_clock_gen(
output logic clk1k, clk10h, seconds_pulse 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 // Relying on constant maths makes it the wrong size
localparam num_cycles = 25_000; localparam num_cycles = 25_000;
+8 -5
View File
@@ -1,18 +1,21 @@
/****
* modular_clock_gen.sv - parameterizable clock divider.
*
* @author: Waylon Cude, Dilanthi Prentice
* @date: 6/12/2025
*
* */
module modular_clock_gen( module modular_clock_gen(
input clk, reset, input clk, reset,
output logic oclk output logic oclk
); );
//parameter has no default because the user should always set it
parameter DIVISOR; parameter DIVISOR;
logic [$clog2(DIVISOR)-1:0] counter; logic [$clog2(DIVISOR)-1:0] counter;
logic set; logic set;
// clock will be high for about half of the cycle, depending on integer
// rounding
// OOPS this makes it combinational
//assign oclk = counter < (DIVISOR/2);
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
// modular clock has to keep ticking through reset // modular clock has to keep ticking through reset
// so everything with a synchronous reset actually works // so everything with a synchronous reset actually works
+9 -5
View File
@@ -117,16 +117,20 @@ playback_controller playbackController (clk_10hz,reset,BTNC, BTNR, speed);
// We don't use more than one dat line // We don't use more than one dat line
logic clk_100khz; logic clk_100khz;
logic clk_25mhz; logic clk_25mhz;
// Actually 200khz now // 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); modular_clock_gen #(500) slowSdClock(CLK100MHZ, reset, clk_100khz);
// Try clocking this slower than max speed // Try clocking this slower than max speed
// To see if that makes it actually work ... // To see if that makes it actually work
// If these are different speeds bad things happen :) oops //
// NOTE: It did not make it work
modular_clock_gen #(400) fastSdClock(CLK100MHZ, reset, clk_25mhz); modular_clock_gen #(400) fastSdClock(CLK100MHZ, reset, clk_25mhz);
sd_controller realSdPlayer( sd_controller realSdPlayer(
clk_100khz, clk_100khz,
clk_25mhz, clk_25mhz,
CLK100MHZ, CLK100MHZ,
clk_1mhz,
reset, reset,
SD_DAT, SD_DAT,
SD_CMD, SD_CMD,
@@ -135,7 +139,7 @@ playback_controller playbackController (clk_10hz,reset,BTNC, BTNR, speed);
audio_interface.driver audio_interface.driver
); );
audio_buffer #(.SIZE(8)) audioBuffer( audio_buffer #(.SIZE(16)) audioBuffer(
clk_48khz, clk_48khz,
reset, reset,
sd_ready, sd_ready,
@@ -145,7 +149,7 @@ playback_controller playbackController (clk_10hz,reset,BTNC, BTNR, speed);
audio_sample, audio_sample,
audio_interface.receiver audio_interface.receiver
); );
pwm #(8) audioOutput(CLK100MHZ, reset, clk_48khz, audio_sample, AUD_PWM); pwm #(11) audioOutput(CLK100MHZ, reset, clk_48khz, audio_sample, AUD_PWM);
`endif `endif
+2 -1
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 `ifdef VERILATOR
`include "sdvd_defs.sv" `include "sdvd_defs.sv"
`endif `endif
@@ -35,7 +37,6 @@ state_t current, next;
wire play_pulse,ff_pulse; 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 playDebouncer (clk,reset,play,play_pulse);
debouncer ffDebouncer (clk,reset,ff,ff_pulse); debouncer ffDebouncer (clk,reset,ff,ff_pulse);
+8 -2
View File
@@ -1,5 +1,11 @@
// parameterizable sequential crc generator /***
// This probably could be combinational logic too, though it would be way slow * 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 #( module crc_gen #(
parameter CRCBITS=7, parameter CRCBITS=7,
parameter COMMANDLEN=40, parameter COMMANDLEN=40,
+10 -2
View File
@@ -1,3 +1,11 @@
/****
* 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( module read_command(
input logic clk, input logic clk,
input logic reset, input logic reset,
@@ -19,8 +27,8 @@ logic received_reg;
logic [2:0] response_type_reg; logic [2:0] response_type_reg;
// oops this was set a cycle before the data was actually ready // recevied was set a cycle before the data was actually ready
// and if it's just a reg it holds for too long // and if it's just a register it holds for too long
// use both for maximum reactivity // use both for maximum reactivity
assign received = received_reg && !listen; assign received = received_reg && !listen;
+10 -3
View File
@@ -1,8 +1,15 @@
// Whenever we receive a data block, start spitting bytes out into the audio /***
// buffer bram. This could always be clocked at the 25MHz default speed clock, * read_data.sv - whenever we receive a data block, start spitting bytes out
// or it could switch over like the writer has to * 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( module read_data(
input clk, input clk,
input mem_clk,
input reset, input reset,
input [3:0] sd_data, input [3:0] sd_data,
audio_buffer_interface.driver buffer audio_buffer_interface.driver buffer
+2
View File
@@ -12,6 +12,7 @@ module sd_controller(
(* MARK_DEBUG = "TRUE" *) (* MARK_DEBUG = "TRUE" *)
input logic fast_clk, input logic fast_clk,
input logic crc_clk, input logic crc_clk,
input logic mem_clk,
input logic reset, input logic reset,
(* MARK_DEBUG = "TRUE" *) (* MARK_DEBUG = "TRUE" *)
input logic [3:0] sd_data, input logic [3:0] sd_data,
@@ -104,6 +105,7 @@ read_command slowReader(
// The data line is only ever used at fast_clk speeds // The data line is only ever used at fast_clk speeds
read_data dataHandler( read_data dataHandler(
fast_clk, fast_clk,
mem_clk,
reset, reset,
sd_data, sd_data,
buffer buffer
+8
View File
@@ -1,3 +1,11 @@
/***
* 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( module send_command(
input clk, input clk,
// The crc should be clocked way faster than the sender // The crc should be clocked way faster than the sender
+5 -3
View File
@@ -1,5 +1,7 @@
/*** /***
* sixty_display.sv - converts a five bit seconds counter to its seven segement display equivalent. * 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 * @author: Dilanthi Prentice, Waylon Cude
* @date: 6/12/25 * @date: 6/12/25
@@ -16,14 +18,14 @@ module sixty_display
logic [4:0] ones_digit; logic [4:0] ones_digit;
logic [4:0] tens_digit; logic [4:0] tens_digit;
//convert digit to ones and tens places
always_comb always_comb
begin begin
ones_digit = number % 10; ones_digit = number % 10;
tens_digit = number / 10; tens_digit = number / 10;
end end
//instantiate the display_converter to convert the counter //convert both ones and tens place digits to their seven segement equivalent
//to a seven segment display number
display_converter ones (ones_digit, display_ones); display_converter ones (ones_digit, display_ones);
display_converter tens (tens_digit, display_tens); display_converter tens (tens_digit, display_tens);
+1 -1
View File
@@ -38,7 +38,7 @@
entirely. Detected in testbench entirely. Detected in testbench
- off-by-one error detected in the counter - off-by-one error detected in the counter
## read_data ### read_data
- audio buffer address to write to was never changing, caught in simulation - 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 - some off-by-one errors in the byte shifting were found and corrected
Binary file not shown.
Binary file not shown.