go-board-code/simon_game.v

209 lines
5.1 KiB
Verilog

module Simon_Game (
input i_Clk,
input i_Switch_1,
input i_Switch_2,
input i_Switch_3,
input i_Switch_4,
output reg [3:0] o_Score,
output o_LED_1,
output o_LED_2,
output o_LED_3,
output o_LED_4
);
parameter CLKS_PER_SECOND = 25000000;
parameter GAME_LIMIT = 6;
localparam START = 3'd0;
localparam PATTERN_OFF = 3'd1;
localparam PATTERN_SHOW = 3'd2;
localparam WAIT_PLAYER = 3'd3;
localparam INCREMENT_SCORE = 3'd4;
localparam PLAYER_LOST = 3'd5;
localparam PLAYER_WON = 3'd6;
reg [2:0] r_currentState;
// count and toggle results
wire w_IncomingDelay;
reg r_DelayCompleted;
wire w_EnableCounter;
// user input handling
reg r_Switch_1, r_Switch_2, r_Switch_3, r_Switch_4;
reg r_Button_notDown;
reg [1:0] r_currentButtonDown;
// game pattern & construction
reg [1:0] r_LEDPattern [0:10];
wire [21:0] w_LFSR_Data;
reg [$clog2(GAME_LIMIT)-1:0] r_currentLEDPattern;
always @(posedge i_Clk) begin
if (i_Switch_1 & i_Switch_2) begin
r_currentState <= START;
end else begin
case (r_currentState)
START:
begin
if (!i_Switch_1 & !i_Switch_2 & r_Button_notDown) begin
o_Score <= 0;
r_currentLEDPattern <= 0;
r_currentState <= PATTERN_OFF;
end
end
PATTERN_OFF:
begin
if (!w_IncomingDelay & r_DelayCompleted) begin
r_currentState <= PATTERN_SHOW;
end
end
PATTERN_SHOW:
begin
if (!w_IncomingDelay & r_DelayCompleted) begin
// this limits the number of
if (o_Score == r_currentLEDPattern) begin
r_currentLEDPattern <= 0;
r_currentState <= WAIT_PLAYER;
end else begin
r_currentLEDPattern <= r_currentLEDPattern + 1;
r_currentState <= PATTERN_OFF;
end
end
end
WAIT_PLAYER:
begin
if (r_Button_notDown) begin
if (
r_LEDPattern[r_currentLEDPattern] == r_currentButtonDown &&
o_Score == r_currentLEDPattern
) begin
r_currentLEDPattern <= 0;
r_currentState <= INCREMENT_SCORE;
end else if (
r_LEDPattern[r_currentLEDPattern] != r_currentButtonDown
) begin
r_currentState <= PLAYER_LOST;
end else begin
r_currentLEDPattern <= r_currentLEDPattern + 1;
end
end
end
INCREMENT_SCORE:
begin
o_Score <= o_Score + 1;
if (o_Score == GAME_LIMIT - 1) begin
r_currentState <= PLAYER_WON;
end else begin
r_currentState <= PATTERN_OFF;
end
end
PLAYER_WON:
begin
o_Score <= 4'hA;
end
PLAYER_LOST:
begin
o_Score <= 4'hF;
end
default:
begin
r_currentState <= START;
end
endcase
end
end
always @(posedge i_Clk) begin
if (r_currentState == START) begin
r_LEDPattern[0] <= w_LFSR_Data[1:0];
r_LEDPattern[1] <= w_LFSR_Data[3:2];
r_LEDPattern[2] <= w_LFSR_Data[5:4];
r_LEDPattern[3] <= w_LFSR_Data[7:6];
r_LEDPattern[4] <= w_LFSR_Data[9:8];
r_LEDPattern[5] <= w_LFSR_Data[11:10];
r_LEDPattern[6] <= w_LFSR_Data[13:12];
r_LEDPattern[7] <= w_LFSR_Data[15:14];
r_LEDPattern[8] <= w_LFSR_Data[17:16];
r_LEDPattern[9] <= w_LFSR_Data[19:18];
r_LEDPattern[10] <= w_LFSR_Data[21:20];
end
end
assign o_LED_1 = (
(r_currentState == PATTERN_SHOW && r_LEDPattern[r_currentLEDPattern] == 0) ?
1 :
i_Switch_1
);
assign o_LED_2 = (
(r_currentState == PATTERN_SHOW && r_LEDPattern[r_currentLEDPattern] == 1) ?
1 :
i_Switch_2
);
assign o_LED_3 = (
(r_currentState == PATTERN_SHOW && r_LEDPattern[r_currentLEDPattern] == 2) ?
1 :
i_Switch_3
);
assign o_LED_4 = (
(r_currentState == PATTERN_SHOW && r_LEDPattern[r_currentLEDPattern] == 3) ?
1 :
i_Switch_4
);
always @(posedge i_Clk) begin
r_DelayCompleted <= w_IncomingDelay;
r_Switch_1 <= i_Switch_1;
r_Switch_2 <= i_Switch_2;
r_Switch_3 <= i_Switch_3;
r_Switch_4 <= i_Switch_4;
if (r_Switch_1 && !i_Switch_1) begin
r_Button_notDown <= 1;
r_currentButtonDown <= 0;
end else if (r_Switch_2 && !i_Switch_2) begin
r_Button_notDown <= 1;
r_currentButtonDown <= 1;
end else if (r_Switch_3 && !i_Switch_3) begin
r_Button_notDown <= 1;
r_currentButtonDown <= 2;
end else if (r_Switch_4 && !i_Switch_4) begin
r_Button_notDown <= 1;
r_currentButtonDown <= 3;
end else begin
r_Button_notDown <= 0;
r_currentButtonDown <= 0;
end
end
assign w_EnableCounter = (r_currentState == PATTERN_SHOW || r_currentState == PATTERN_OFF);
Count_And_Toggle #(
.COUNT_LIMIT(CLKS_PER_SECOND/4)
) Counter (
.i_Clk(i_Clk),
.i_Enable(w_EnableCounter),
.o_Toggle(w_IncomingDelay)
);
LFSR #(
.SIZE(22)
) MyLFSR (
.i_Clk(i_Clk),
.o_LFSR_Data(w_LFSR_Data),
.o_LFSR_Done()
);
endmodule