SDVD/design/playback_controller.sv
Waylon Cude a50efdc6c6 Fixed up debouncer and added some assertions
I moved around where packages are. I couldn't find any evidence of where
other people put them, but for now they are in the `lib/` folder. Other
infrastructure changes are that all the weird includes we need to make
the linter happy are gated behind ifdefs, so they don't mess with
vivado.

I kinda can't believe concurrent assertions work because there's so
little info about them, good to ssee they actually do something
2025-05-30 13:56:52 -07:00

113 lines
2.5 KiB
Systemverilog

/*****
* 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