Skip to content
Steve Julian edited this page Jan 31, 2022 · 43 revisions

Verilog FPGA Pingpong Game Wiki

Introduction

The objective of this project was to design and implement an electronic pingpong game using Verilog and the Basys3 Field Programmable Gate Array (FPGA) kit.

According to the project requirements document provided: “This assignment is to enable the student to extend electrical and electronic knowledge for specialist applications in embedded systems.”

Verilog FPGA Pingpong Game is published under the MIT License.

Digilent Basys 3 FPGA Board

Requirements

The following specification was provided in the project requirements document:

“It is a game of two players; each player has a push button. Either player can start the game by pressing his/her push button. Eight LEDs represent the position of the ball. The ball movement is indicated by the illumination of the LEDs and the opponent player should press his/her push button only, when the ball is at his end. The ball is considered struck if the player presses the push button while the ball is resident on the last LED at the players end. The ball should be flying until any player violates the rule. Once violation happens, then a player gets the point. Scores of the players should be displayed on seven segments LED. The speed of the ball’s movement should increase as the game progresses.”

Research

N/A

Methodology

State Machine Diagram

The requirements specification was transcribed into an overall State Machine Diagram as a method for gaining understanding of what work needed to be done.

Pingpong State Machine Diagram

Game Rules

Starting the Game:

  1. Any player can start a game round by pressing his or her button at which point the “ball” is shown as an illuminated LED heading toward the other player’s side of the board.
  2. When Player 1 starts the game round by pressing their button the “ball” will first appear as the LED LD04 (W18) illuminated and heading toward Player 2’s side of the board.
  3. When Player 2 starts the game round by pressing their button the “ball” will first appear as the LED LD03 (V19) illuminated and heading toward Player 1’s side of the board.

Player One's Turn

Supposing Player 2 has started the game round by pressing their button:

  1. The “ball” is revealed starting with LED LD03 (V19) illuminated.
  2. Next the ball moves to the left toward Player 1 meaning LD03 (V19) is dimmed and LED LD04 (W18) is illuminated.
  3. The ball moves to the left again and so LD04 (W18) is dimmed and LED LD05 (U15) is illuminated.
  4. The ball again moves to the left. LD05 (U15) is dimmed and LED LD06 (U14) is illuminated.
  5. The ball moves to the left once more. LD06 (U14) is dimmed and LED LD07 (V14) is illuminated.
  6. At this point Player 1 must quickly press their button before a timer expires. If the button is not pressed within this time frame then Player 2 wins the round and a point is added to their score.
  7. After a round has been won by a player the next round can be started by either player by pressing their button.

Player Two's Turn

If Player 1 presses their button when the “ball” was on the left-most LED:

  1. The ball moves to the right toward Player 2 meaning LD07 (V14) is dimmed and LED LD06 (U14) is illuminated.
  2. Next the ball moves to the right again and so LD06 (U14) is dimmed and LED LD05 (U15) is illuminated.
  3. The ball again moves to the right. LD05 (U15) is dimmed and LED LD04 (W18) is illuminated.
  4. The ball moves to the right again. LD04 (W18) is dimmed and LED LD03 (V19) is illuminated.
  5. The ball moves to the right again. LD03 (V19) is dimmed and LED LD02 (U19) is illuminated.
  6. The ball moves to the right again. LD02 (U19) is dimmed and LED LD01 (E19) is illuminated.
  7. The ball moves to the right once more. LD01 (E19) is dimmed and LED LD00 (U16) is illuminated.
  8. At this point Player 2 must quickly press their button before a timer expires. If the button is not pressed within this time frame then they lose the round and Player 1 scores a point.

Buttons Either player can start the game by pressing his or her button. The game is considered over once a player has won 10 rounds - making them the overall winner of the game. At this point the player score counters both revert back to zero and the next time a player presses their button the first round of an entirely new game will commence.

Game Speed In regards to the requirements specifying that the game speeds up, this has been interpreted as meaning that the game speed increases at the beginning of each new round. This is as opposed to increasing the game speed throughout the duration of each round in the game.

**Button Player 1 **(Momentary push button) Player 1 is only permitted to press the player one button while LED LD15 is illuminated. Pressing the button at any other time will immediately result in Player 2 winning the round of the game.

Button Player 2 (Momentary push button) Player 2 is only permitted to press the player one button while LED LD0 is illuminated. Pressing the button at any other time will immediately result in Player 1 winning the round of the game.

Verilog Source Code

The code written for the Basys3 FPGA Board consisted of two files:

  1. The Constraints file (provided in Appendix A)
  2. The Verilog program file (provided in Appendix B)

Cloud Services

N/A

Integrations

N/A

Features Wish List

The attachment of a piezoelectric buzzer or speaker to an output interface of the Basys 3 could be valuable both to testing and to improving the game play experience via audio notifications of game events such as ball hitting and game round points awarding.

Changes Log

N/A

Parts List

Getting Started

Before starting, read the original Project Report to access more complete documentation than this Wiki otherwise provides.

Testing

Initial testing was found to have somewhat unpredictable results. The one change that appeared to remedy this was writing the decimal places on the 7-segment display. Previously the decimal place was ignored however it was found that writing a blank output had the result of the FPGA circuit behaving as described by the State Machine diagram.

A system crash in combination with a development process failure appeared to have been the cause of some data loss which delayed the demonstration of the finished project. Changes to the development process were implemented to prevent this from recurring and the project was successfully completed.

Conclusion

This project proved to be a useful exercise for learning how to design, implement and test an FPGA circuit working with an FPGA development board. The project was completed and functioned correctly as per the provided requirement specifications.

Resources

Additional resources about FPGA for further study:

FPGAs General Talk

https://www.youtube.com/watch?v=gUsHwi4M4xE

Programming FPGA with ISE

https://www.youtube.com/watch?v=eLOLBYxLXcE

BASYS2 using ISE explanation of the board

https://www.youtube.com/watch?v=6_GxkslqbcU

Fabrication of IC Circuits - How an IC is made

https://www.youtube.com/watch?v=35jWSQXku74

Half Adder Example Vivado

https://www.youtube.com/watch?v=aPDT0sPr4jE#t=459.661006

How to Program Basys3

https://reference.digilentinc.com/learn/programmable-logic/tutorials/basys-3-programming-guide/start

Getting Started with Basys3

https://reference.digilentinc.com/learn/programmable-logic/tutorials/basys-3-getting-started/start

List of Figures

All photographs, diagrams and screenshots are by the author unless otherwise indicated.

References

This project was originally completed by Stephen Julian in June 2019 as an Assignment for his Embedded Systems paper during study for a Bachelor of Engineering Technology (Electrical) degree. This GitHub repository delivers on the intention to publish the project work under the MIT Licence.

While this wiki provides a project summary, the complete original documentation is available in Adobe PDF format below:

Julian, Stephen (4/06/2019). Verilog FPGA Pingpong Game - MG7013 Embedded Systems (~3.6 MB PDF, 31 pages)

Appendices

###Appendix A: Verilog Constraints File

`

clock signal

set_property PACKAGE_PIN W5 [get_ports clock_100Mhz] set_property IOSTANDARD LVCMOS33 [get_ports clock_100Mhz] create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clock_100Mhz]

SWITCHES

game on/off switch

#set_property PACKAGE_PIN V17 [get_ports {sw0}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw0}]

#set_property PACKAGE_PIN V16 [get_ports {sw[1]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]

#set_property PACKAGE_PIN W16 [get_ports {sw[2]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]

#set_property PACKAGE_PIN W17 [get_ports {sw[3]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]

#set_property PACKAGE_PIN W15 [get_ports {sw[4]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[4]}]

#set_property PACKAGE_PIN V15 [get_ports {sw[5]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[5]}]

#set_property PACKAGE_PIN W14 [get_ports {sw[6]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[6]}]

#set_property PACKAGE_PIN W13 [get_ports {sw[7]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[7]}]

#set_property PACKAGE_PIN V2 [get_ports {sw[8]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[8]}]

#set_property PACKAGE_PIN T3 [get_ports {sw[9]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[9]}]

#set_property PACKAGE_PIN T2 [get_ports {sw[10]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[10]}]

#set_property PACKAGE_PIN R3 [get_ports {sw[11]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[11]}]

#set_property PACKAGE_PIN W2 [get_ports {sw[12]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[12]}]

#set_property PACKAGE_PIN U1 [get_ports {sw[13]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[13]}]

#set_property PACKAGE_PIN T1 [get_ports {sw[14]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[14]}]

#set_property PACKAGE_PIN R2 [get_ports {sw[15]}]

set_property IOSTANDARD LVCMOS33 [get_ports {sw[15]}]

set_property PACKAGE_PIN R2 [get_ports {reset}] set_property IOSTANDARD LVCMOS33 [get_ports {reset}]

BUTTONS

player one button = btnL

set_property PACKAGE_PIN W19 [get_ports player1button] set_property IOSTANDARD LVCMOS33 [get_ports player1button]

player two button = btnR

set_property PACKAGE_PIN T17 [get_ports player2button] set_property IOSTANDARD LVCMOS33 [get_ports player2button]

8 x LEDs representing position of ball

led0 is at player 2s end of the board (on right)

led7 is at player 1s end of the board (on left)

set_property PACKAGE_PIN U16 [get_ports {led0}] set_property IOSTANDARD LVCMOS33 [get_ports {led0}] set_property PACKAGE_PIN E19 [get_ports {led1}] set_property IOSTANDARD LVCMOS33 [get_ports {led1}] set_property PACKAGE_PIN U19 [get_ports {led2}] set_property IOSTANDARD LVCMOS33 [get_ports {led2}] set_property PACKAGE_PIN V19 [get_ports {led3}] set_property IOSTANDARD LVCMOS33 [get_ports {led3}] set_property PACKAGE_PIN W18 [get_ports {led4}] set_property IOSTANDARD LVCMOS33 [get_ports {led4}] set_property PACKAGE_PIN U15 [get_ports {led5}] set_property IOSTANDARD LVCMOS33 [get_ports {led5}] set_property PACKAGE_PIN U14 [get_ports {led6}] set_property IOSTANDARD LVCMOS33 [get_ports {led6}] set_property PACKAGE_PIN V14 [get_ports {led7}] set_property IOSTANDARD LVCMOS33 [get_ports {led7}]

8 x unused LEDs

#set_property PACKAGE_PIN V13 [get_ports {led8}]

set_property IOSTANDARD LVCMOS33 [get_ports {led8}]

#set_property PACKAGE_PIN V3 [get_ports {led[9]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]

#set_property PACKAGE_PIN W3 [get_ports {led[10]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]

#set_property PACKAGE_PIN U3 [get_ports {led[11]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]

#set_property PACKAGE_PIN P3 [get_ports {led[12]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]

#set_property PACKAGE_PIN N3 [get_ports {led[13]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]

#set_property PACKAGE_PIN P1 [get_ports {led[14]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}]

#set_property PACKAGE_PIN L1 [get_ports {led[15]}]

set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}]

4-digit 7-segment LED display

#V7 is for the decimal point set_property PACKAGE_PIN V7 [get_ports {dp}] set_property IOSTANDARD LVCMOS33 [get_ports {dp}] set_property PACKAGE_PIN W7 [get_ports {LED_out[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[6]}] set_property PACKAGE_PIN W6 [get_ports {LED_out[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[5]}] set_property PACKAGE_PIN U8 [get_ports {LED_out[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[4]}] set_property PACKAGE_PIN V8 [get_ports {LED_out[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[3]}] set_property PACKAGE_PIN U5 [get_ports {LED_out[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[2]}] set_property PACKAGE_PIN V5 [get_ports {LED_out[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[1]}] set_property PACKAGE_PIN U7 [get_ports {LED_out[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[0]}] set_property PACKAGE_PIN U2 [get_ports {Anode_Activate[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[0]}] set_property PACKAGE_PIN U4 [get_ports {Anode_Activate[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[1]}] set_property PACKAGE_PIN V4 [get_ports {Anode_Activate[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[2]}] set_property PACKAGE_PIN W4 [get_ports {Anode_Activate[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[3]}] `

###Appendix B: Verilog Source Code ` module main_controller( input wire clock_100Mhz, // 100 Mhz clock source on Basys 3 FPGA input wire reset, // reset switch input wire player1button, input wire player2button, output led0, output led1, output led2, output led3, output led4, output led5, output led6, output led7, output reg [3:0] Anode_Activate, // anode signals of the 7-segment LED display output reg [6:0] LED_out, // cathode patterns of the 7-segment LED display output reg dp // decimal point for 7-segment LED display );

integer roundtimer;
integer roundtimeratlastevent;
integer cyclesperround;
integer cyclesperrounddecrement;
integer pauseduration;
integer nextstate;
integer state;
integer i;
integer lastwinningplayer;

reg int_led0;
reg int_led1;
reg int_led2;
reg int_led3;
reg int_led4;
reg int_led5;
reg int_led6;
reg int_led7;
reg [3:0] bcd_player1score; // BCD
reg [3:0] bcd_player2score; // BCD
reg [3:0] LED_BCD;
reg [19:0] refresh_counter; // 20-bit for creating 10.5ms refresh period or 380Hz refresh rate
         // the first 2 MSB bits for creating 4 LED-activating signals with 2.6ms digit period
wire [1:0] LED_activating_counter; 

always@ (negedge clock_100Mhz or negedge reset) begin // this part is always done

	if(reset == 1) begin
		int_led0 = 0;
		int_led1 = 0;
		int_led2 = 0;
		int_led3 = 0;
		int_led4 = 0;
		int_led5 = 0;
		int_led6 = 0;
		int_led7 = 0;
		bcd_player1score = 4'b0000;
		bcd_player2score = 4'b0000;
		roundtimer = 0;
		roundtimeratlastevent = 0;
		cyclesperround = 100000000;
		cyclesperrounddecrement = 1000000;
		pauseduration = 25000000;
		nextstate = 0;
		state = 0;
		i = 0;
		lastwinningplayer = 0;
		
	end else begin
		case (state) 
			0: begin
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				cyclesperround = 100000000;
				cyclesperrounddecrement = 1000000;
				if(lastwinningplayer == 1) begin
					bcd_player1score = bcd_player1score + 1;
					lastwinningplayer = 0;
				end else if(lastwinningplayer == 2) begin
					bcd_player2score = bcd_player2score + 1;
					lastwinningplayer = 0;
				end
						
				if(roundtimer > (roundtimeratlastevent + pauseduration)) begin
					if(player1button) begin 
						// player 1 starts game so ball will head toward player 2
						nextstate = 9;
						roundtimer = 0;
						roundtimeratlastevent = 0;
					end else if(player2button) begin 
						// player 2 starts game so ball will head toward player 1
						nextstate = 2;
						roundtimer = 0;
						roundtimeratlastevent = 0;
					end else if(!player1button && !player2button) begin
						if(i>cyclesperround) begin
							if(nextstate != state) begin
								i = 0;
								roundtimeratlastevent = roundtimer;
								state = nextstate;
							end
						end
					end
				end
				
			end
			1: begin 
				// ball is at player 2
				int_led0 = 1;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 hit the ball
					nextstate = 2;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin 
						// player 2 failed to hit the ball so player 1 wins round
						if(nextstate == state) begin
							lastwinningplayer = 1;
							nextstate = 0;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end 
			2: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 1;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 3;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end 
			3: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 1;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 4;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			4: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 1;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 5;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			5: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 1;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 6;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			6: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 1;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 7;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			7: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 1;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 8;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			8: begin 
				// ball is at player 1;
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 1;
				if(player1button) begin 
					// player 1 hit the ball
					nextstate = 9;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin 
						// player 1 failed to hit the ball so player 2 wins round
						if(nextstate == state) begin
							lastwinningplayer = 2;
							nextstate = 0;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			9: begin 
				// ball is moving toward player 2
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 1;
				int_led7 = 0;
				if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 10;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			10: begin 
				// ball is moving toward player 2
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 1;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 11;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			11: begin 
				// ball is moving toward player 2
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 1;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 12;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			12: begin 
				// ball is moving toward player 2
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 1;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 13;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			13: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 1;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 14;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			14: begin 
				// ball is moving toward player 1
				int_led0 = 0;
				int_led1 = 1;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				if(player1button) begin 
					// player 1 violated rule so player 2 wins round
					lastwinningplayer = 2;
					roundtimer = 0;
					nextstate = 0;
				end else if(player2button) begin 
					// player 2 violated rule so player 1 wins round
					lastwinningplayer = 1;
					roundtimer = 0;
					nextstate = 0;
				end else if(!player1button && !player2button) begin
					if(i>cyclesperround) begin
						if(nextstate == state) begin
							nextstate = 1;
						end
						i = 0;
						cyclesperround = cyclesperround - cyclesperrounddecrement;
						roundtimeratlastevent = roundtimer;
						state = nextstate;
					end
				end
			end
			default: begin 
				// reset variables and send game to an idle state 
				// to wait for a player to start a new round 
				// by pressing their button
				int_led0 = 0;
				int_led1 = 0;
				int_led2 = 0;
				int_led3 = 0;
				int_led4 = 0;
				int_led5 = 0;
				int_led6 = 0;
				int_led7 = 0;
				bcd_player1score = 4'b0000;
				bcd_player2score = 4'b0000;
				roundtimer = 0;
				roundtimeratlastevent = 0;
				cyclesperround = 100000000;
				cyclesperrounddecrement = 1000000;
				pauseduration = 25000000;
				i = 0;
				lastwinningplayer = 0;
				nextstate = 0;
				state = 0;
			end
		endcase 

		if(bcd_player1score > 4'b1001) begin 
			// player 1 wins entire game if score > 9
			bcd_player1score = 4'b0000;
			bcd_player2score = 4'b0000;
			nextstate = 0;
			i = 0;
			roundtimeratlastevent = 0;
			roundtimer = 0;
			lastwinningplayer = 0;
			state = nextstate;
		end else if(bcd_player2score > 4'b1001) begin 
			// player 2 wins entire game if score > 9
			bcd_player1score = 4'b0000;
			bcd_player2score = 4'b0000;
			nextstate = 0;
			i = 0;
			roundtimeratlastevent = 0;
			roundtimer = 0;
			lastwinningplayer = 0;
			state = nextstate;
		end else begin
			roundtimer = roundtimer + 1;
			i = i + 1;
		end
		
	end
end


always @(posedge clock_100Mhz or posedge reset) begin 
    if(reset == 1)
        refresh_counter <= 0;
    else
        refresh_counter <= refresh_counter + 1;
end 

assign LED_activating_counter = refresh_counter[19:18];

// anode activating signals for 4 LEDs, digit period of 2.6ms
// decoder to generate anode signals 
always @(*) begin
	if(reset == 1) begin
		Anode_Activate = 4'b1011; 
		LED_BCD = 4'b1111;
	end else begin
		case(LED_activating_counter)
		2'b00: begin
			Anode_Activate = 4'b0111;
			LED_BCD = bcd_player1score;
			end
		2'b01: begin
			Anode_Activate = 4'b1011; 
			LED_BCD = 4'b1111;
			end
		2'b10: begin
			Anode_Activate = 4'b1101; 
			LED_BCD = 4'b1111;
			end
		2'b11: begin
			Anode_Activate = 4'b1110; 
			LED_BCD = bcd_player2score; 
			end
		default: begin
			Anode_Activate = 4'b1011; 
			LED_BCD = 4'b1111;
			end
		endcase
	end
end

always @(*) begin
	if(reset == 1) begin
		LED_out = 7'b1111111; // " "
		dp = 1'b1; // output blank decimal point
	end else begin
		case(LED_BCD)
			4'b0000: LED_out = 7'b0000001; // "0"     
			4'b0001: LED_out = 7'b1001111; // "1" 
			4'b0010: LED_out = 7'b0010010; // "2" 
			4'b0011: LED_out = 7'b0000110; // "3" 
			4'b0100: LED_out = 7'b1001100; // "4" 
			4'b0101: LED_out = 7'b0100100; // "5" 
			4'b0110: LED_out = 7'b0100000; // "6" 
			4'b0111: LED_out = 7'b0001111; // "7" 
			4'b1000: LED_out = 7'b0000000; // "8"     
			4'b1001: LED_out = 7'b0000100; // "9" 
			4'b1111: LED_out = 7'b1111111; // " " 
			default: LED_out = 7'b1111111; // " "
		endcase
		dp = 1'b1; // output blank decimal point
	end
end

assign led0 = int_led0;
assign led1 = int_led1;
assign led2 = int_led2;
assign led3 = int_led3;
assign led4 = int_led4;
assign led5 = int_led5;
assign led6 = int_led6;
assign led7 = int_led7;

endmodule `