Compare commits
2 Commits
a07e811a16
...
9af830daa0
| Author | SHA1 | Date | |
|---|---|---|---|
| 9af830daa0 | |||
| 53b48c0bce |
@ -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
|
||||||
@ -72,8 +75,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 <= doutb;
|
sample <= doutb;
|
||||||
end
|
end
|
||||||
@ -86,9 +87,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(10), // DECIMAL
|
.ADDR_WIDTH_B(10), // DECIMAL
|
||||||
@ -137,7 +136,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.
|
||||||
@ -147,11 +145,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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -118,11 +118,13 @@ audio_buffer audioBuffer(
|
|||||||
assign SD_DAT[3:1] = 'z;
|
assign SD_DAT[3:1] = 'z;
|
||||||
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
|
||||||
// 200khz is slightly unstable??????
|
// Even at 200khz sometimes things break
|
||||||
modular_clock_gen #(1000) slowSdClock(CLK100MHZ, reset, clk_100khz);
|
modular_clock_gen #(1000) 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
|
||||||
|
//
|
||||||
|
// NOTE: It did not make it work
|
||||||
modular_clock_gen #(1000) fastSdClock(CLK100MHZ, reset, clk_25mhz);
|
modular_clock_gen #(1000) fastSdClock(CLK100MHZ, reset, clk_25mhz);
|
||||||
sd_controller realSdPlayer(
|
sd_controller realSdPlayer(
|
||||||
clk_100khz,
|
clk_100khz,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,12 @@
|
|||||||
// 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 reset,
|
input reset,
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
/***
|
/***
|
||||||
* seconds_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 seconds_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 = seconds % 10;
|
ones_digit = seconds % 10;
|
||||||
tens_digit = seconds / 10;
|
tens_digit = seconds / 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);
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user