/*****
 * playback_controller.sv - A finite state machine with states that control
 *                          playback speed. In additon to playing and pausing
 *                          it can fast forward at 2x speed, 4x speed, 8x
 *                          speed and 16x speed.
 *
 * @author: Dilanthi Prentice, Waylon Cude
 * @date: 6/12/25
 *
 * */

`ifdef VERILATOR
    `include "sdvd_defs.sv"
`endif
import sdvd_defs::SPEED;

module playback_controller(
    // This clock should be reasonably slow
    input logic clk,
    input logic reset,

    // Play and pause are the same button
    input logic play,
    input logic ff,

    // Output is 0, 1x, 2x, 4x, 8x or 16x
    output SPEED speed
);

typedef enum logic [2:0] {
    PAUSE, PLAY, FF2, FF4, FF8, FF16
} state_t;

state_t current, next;

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 ffDebouncer (clk,reset,ff,ff_pulse);

//next state logic
always_comb
begin
    unique case (current)
        PAUSE: 
            begin
                if (play_pulse) next = PLAY;
                else if (ff_pulse) next = FF2;
                else next = PAUSE;
            end
        PLAY: 
            begin
                if (play_pulse) next = PAUSE;
                else if (ff_pulse) next = FF2;
                else next = PLAY;
            end
        FF2:
            begin
                if (play_pulse) next = PAUSE;
                else if (ff_pulse) next = FF4;
                else next = FF2;
            end
        FF4:
            begin
                if (play_pulse) next = PAUSE;
                else if (ff_pulse) next = FF8;
                else next = FF4;
            end
        FF8:
            begin
                if (play_pulse) next = PAUSE;
                else if (ff_pulse) next = FF16;
                else next = FF8;
            end
        FF16:
            begin
                if (play_pulse) next = PAUSE;
                else if (ff_pulse) next = FF16;
                else next = FF16;
            end
        default:
            next = PAUSE;
    endcase
end

//output logic
always_comb
begin
    unique case (current)
        PAUSE:  speed = 0; 
        PLAY:   speed = 1;
        FF2:    speed = 2;
        FF4:    speed = 4;
        FF8:    speed = 8;
        FF16:   speed = 16;
        default:speed = 0;
    endcase
end

//sequential logic
always_ff @(posedge clk)
begin    
    if (reset)
        current <= PAUSE;
    else
        current <= next;
end
endmodule



