Initial work on rom_sd #2
@ -12,9 +12,6 @@ module audio_buffer(
|
||||
input logic play, stop,
|
||||
input SPEED speed,
|
||||
|
||||
// Whether the current address being read from is in the upper or lower
|
||||
// half of the 2KiB buffer
|
||||
output logic address_half,
|
||||
|
||||
// Whether the audio buffer is currently playing
|
||||
output logic playing,
|
||||
@ -23,11 +20,13 @@ module audio_buffer(
|
||||
output logic [15:0] sample,
|
||||
|
||||
// Inputs for the memory buffer
|
||||
input logic [10:0] addra,
|
||||
input logic [7:0] dina,
|
||||
input logic clka, ena
|
||||
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;
|
||||
|
||||
// State register
|
||||
@ -117,16 +116,16 @@ xpm_memory_sdpram #(
|
||||
)
|
||||
buffer (
|
||||
.doutb(doutb), // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
|
||||
.addra(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(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(dina), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
|
||||
.ena(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
|
||||
@ -135,7 +134,7 @@ buffer (
|
||||
.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(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
|
||||
|
||||
103
design/sd/rom_sd.sv
Normal file
103
design/sd/rom_sd.sv
Normal file
@ -0,0 +1,103 @@
|
||||
// A dummy sdcard module for testing the audio port
|
||||
|
||||
module sd(
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
output logic ready,
|
||||
|
||||
audio_buffer_interface.driver audio_buffer
|
||||
);
|
||||
|
||||
// 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 [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
|
||||
|
||||
|
||||
// xpm_memory_sprom: Single Port ROM
|
||||
// Xilinx Parameterized Macro, version 2024.2
|
||||
|
||||
// The ROM has 17 address bits and 8 data bits to store 128KiB, more than
|
||||
// enough for one second of 48khz audio
|
||||
xpm_memory_sprom #(
|
||||
.ADDR_WIDTH_A(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
|
||||
)
|
||||
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
|
||||
// cycles when read operations are initiated. Pipelined internally.
|
||||
|
||||
.rsta(reset) // 1-bit input: Reset signal for the final port A output register stage.
|
||||
// Synchronously resets output port douta to the value specified by
|
||||
// parameter READ_RESET_VALUE_A.
|
||||
);
|
||||
|
||||
// End of xpm_memory_sprom_inst instantiation
|
||||
|
||||
|
||||
endmodule
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
### Debouncer
|
||||
- Logic was fundamentally wrong
|
||||
- Found multiple logic bugs with testbench and then assertions
|
||||
|
||||
### Display Converter
|
||||
- Found a typo in a single digit
|
||||
23
doc/rom_sd.gv
Normal file
23
doc/rom_sd.gv
Normal file
@ -0,0 +1,23 @@
|
||||
digraph rom_sd {
|
||||
Reset [shape = doublecircle, label = "RESET\nbuffer_half = 0\nrom_address = 0\nrom_enable = 1\nbuf.addr=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"];
|
||||
|
||||
Reset -> Reset [label="reset"];
|
||||
Reset -> Delay [label="!reset"];
|
||||
|
||||
Delay -> WriteBuf;
|
||||
|
||||
WriteBuf -> WriteBuf [label="buf.addr < 1023"]
|
||||
WriteBuf -> EndWrite [label="buf.addr == 1023"]
|
||||
|
||||
EndWrite -> Wait;
|
||||
|
||||
Wait -> Wait [label = "buffer_half == buf.address_half"]
|
||||
Wait -> Delay [label = "buffer_half != buf.address_half"]
|
||||
|
||||
|
||||
}
|
||||
BIN
doc/rom_sd.png
Normal file
BIN
doc/rom_sd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
18
lib/audio_buffer_interface.sv
Normal file
18
lib/audio_buffer_interface.sv
Normal file
@ -0,0 +1,18 @@
|
||||
interface audio_buffer_interface;
|
||||
logic [10:0] addra;
|
||||
logic [7:0] dina;
|
||||
logic clka;
|
||||
logic ena;
|
||||
logic address_half;
|
||||
|
||||
modport driver (
|
||||
output addra, dina, clka, ena,
|
||||
input address_half
|
||||
);
|
||||
|
||||
modport receiver (
|
||||
input addra, dina, clka, ena,
|
||||
output address_half
|
||||
);
|
||||
|
||||
endinterface
|
||||
96000
roms/roundabout.mem
Normal file
96000
roms/roundabout.mem
Normal file
File diff suppressed because it is too large
Load Diff
BIN
roms/roundabout.raw
Normal file
BIN
roms/roundabout.raw
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user