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