diff --git a/design/sd/rom_sd.sv b/design/sd/rom_sd.sv index e9d5a62..4c50175 100644 --- a/design/sd/rom_sd.sv +++ b/design/sd/rom_sd.sv @@ -8,6 +8,11 @@ module rom_sd( buffer_interface.driver buffer ); +typedef enum logic [2:0]{ + RESET, DELAY, WRITEBUF, ENDWRITE, 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; @@ -17,16 +22,6 @@ logic rom_enable; logic buffer_half; -always_ff @(posedge clk) begin - if (reset) begin - rom_addr <= 0; - initializing <= 1; - buffer.addra <= 0; - buffer.ena <= 0; - end -end - - // xpm_memory_sprom: Single Port ROM // Xilinx Parameterized Macro, version 2024.2 @@ -67,8 +62,77 @@ xpm_memory_sprom_inst ( // Synchronously resets output port douta to the value specified by // parameter READ_RESET_VALUE_A. ); - // End of xpm_memory_sprom_inst instantiation - + +//next state logic +always_comb +begin + case (current) + RESET: if (reset) next = RESET; + else next = DELAY; + + DELAY: next = WRITEBUF; + + WRITEBUF: if (buffer.addra < 1023) next = WRITEBUF; + else if (buffer.addra == 1023) next = ENDWRITE; + + ENDWRITE: next = WAIT; + + WAIT: if (buffer_half == buffer.address_half) next = WAIT; + else next = DELAY; + + default: next = RESET; + endcase +end + +//sequential output logic +always_ff @(posedge clock) +begin + case (current) + RESET: begin + buffer_half <= 0; + rom_addr <= 0; + rom_enable <= 1; + buffer.addra <= 0; + ready <= 0; + end + + DELAY: rom_addr <= rom_addr + 1; + + WRITEBUF: begin + buffer.ena <= 1; + buffer.dina <= rom_data; + buffer.addra <= buffer.addra + 1; + rom_addr <= rom_addr + 1; + end + + ENDWRITE: begin + buffer.ena <= 1; + buffer.data <= rom_data; + buffer.addra <= buffer.addra + 1; + ready <= 1; + end + + WAIT: buffer.ena <= 0; + + default: begin + buffer_half <= 0; + rom_addr <= 0; + rom_enable <= 0; + buffer.addra <= 0; + buffer.dina <= 0; + ready <= 0; + end + endcase +end + +//sequential clocking block +always_ff @(posedge clock) +begin + if (reset) + current <= RESET; + else + current <= next; +end endmodule