Lots of changes, trying to get ROM working
ci/woodpecker/push/test-workflow Pipeline was successful

I think I did some funny math errors so new goal is 8-bit pcm
This commit is contained in:
2025-06-05 18:48:53 -07:00
parent 02e2d77640
commit 7980424dc8
18 changed files with 387489 additions and 134 deletions
+52 -23
View File
@@ -10,17 +10,17 @@ module rom_sd(
input logic reset,
output logic ready,
buffer_interface.driver buffer
audio_buffer_interface.driver buffer
);
parameter MEM_FILE = "roundabout.mem";
typedef enum logic [2:0]{
RESET, DELAY, WRITEBUF, ENDWRITE, WAIT
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_addr;
logic [7:0] rom_data;
logic rom_enable;
@@ -40,8 +40,8 @@ xpm_memory_sprom #(
.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_INIT_FILE(MEM_FILE), // String
.MEMORY_INIT_PARAM(""), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("auto"), // String
.MEMORY_SIZE(131072*8), // DECIMAL
@@ -63,46 +63,67 @@ xpm_memory_sprom_inst (
.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 = DELAY;
else next = DELAY1;
DELAY1: next = DELAY2;
DELAY2: next = DELAY3;
DELAY3: next = WRITEBUF;
DELAY: next = WRITEBUF;
WRITEBUF: if (buffer.addra[9:0] < 1020) next = WRITEBUF;
else next = ENDWRITE1;
WRITEBUF: if (buffer.addra < 1023) next = WRITEBUF;
else if (buffer.addra == 1023) next = ENDWRITE;
ENDWRITE: next = WAIT;
ENDWRITE1: next = ENDWRITE2;
ENDWRITE2: next = ENDWRITE3;
ENDWRITE3: next = WAIT;
WAIT: if (buffer_half == buffer.address_half) next = WAIT;
else next = DELAY;
else next = DELAY1;
default: next = RESET;
endcase
end
//sequential output logic
always_ff @(posedge clock)
always_ff @(posedge clk)
begin
case (current)
RESET: begin
buffer_half <= 0;
rom_addr <= 0;
rom_enable <= 1;
buffer.addra <= 0;
buffer.ena <= 0;
ready <= 0;
end
DELAY: rom_addr <= rom_addr + 1;
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;
@@ -110,29 +131,37 @@ begin
buffer.addra <= buffer.addra + 1;
rom_addr <= rom_addr + 1;
end
ENDWRITE: begin
ENDWRITE1, ENDWRITE2:
begin
buffer.ena <= 1;
buffer.data <= rom_data;
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: buffer.ena <= 0;
WAIT: ;
default: begin
buffer_half <= 0;
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 clock)
always_ff @(posedge clk)
begin
if (reset)
current <= RESET;