-
Notifications
You must be signed in to change notification settings - Fork 0
Home
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.

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.”
N/A
The requirements specification was transcribed into an overall State Machine Diagram as a method for gaining understanding of what work needed to be done.

Starting the Game:
- 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.
- 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.
- 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:
- The “ball” is revealed starting with LED LD03 (V19) illuminated.
- Next the ball moves to the left toward Player 1 meaning LD03 (V19) is dimmed and LED LD04 (W18) is illuminated.
- The ball moves to the left again and so LD04 (W18) is dimmed and LED LD05 (U15) is illuminated.
- The ball again moves to the left. LD05 (U15) is dimmed and LED LD06 (U14) is illuminated.
- The ball moves to the left once more. LD06 (U14) is dimmed and LED LD07 (V14) is illuminated.
- 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.
- 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:
- The ball moves to the right toward Player 2 meaning LD07 (V14) is dimmed and LED LD06 (U14) is illuminated.
- Next the ball moves to the right again and so LD06 (U14) is dimmed and LED LD05 (U15) is illuminated.
- The ball again moves to the right. LD05 (U15) is dimmed and LED LD04 (W18) is illuminated.
- The ball moves to the right again. LD04 (W18) is dimmed and LED LD03 (V19) is illuminated.
- The ball moves to the right again. LD03 (V19) is dimmed and LED LD02 (U19) is illuminated.
- The ball moves to the right again. LD02 (U19) is dimmed and LED LD01 (E19) is illuminated.
- The ball moves to the right once more. LD01 (E19) is dimmed and LED LD00 (U16) is illuminated.
- 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.
The code written for the Basys3 FPGA Board consisted of two files:
- The Constraints file (provided in Appendix A)
- The Verilog program file (provided in Appendix B)
N/A
N/A
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.
N/A
Before starting, read the original Project Report to access more complete documentation than this Wiki otherwise provides.
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.
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.
Additional resources about FPGA for further study:
https://www.youtube.com/watch?v=gUsHwi4M4xE
https://www.youtube.com/watch?v=eLOLBYxLXcE
https://www.youtube.com/watch?v=6_GxkslqbcU
https://www.youtube.com/watch?v=35jWSQXku74
https://www.youtube.com/watch?v=aPDT0sPr4jE#t=459.661006
https://reference.digilentinc.com/learn/programmable-logic/tutorials/basys-3-programming-guide/start
https://reference.digilentinc.com/learn/programmable-logic/tutorials/basys-3-getting-started/start
All photographs, diagrams and screenshots are by the author unless otherwise indicated.
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)
###Appendix A: Verilog Constraints File
`
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]
#set_property PACKAGE_PIN V17 [get_ports {sw0}]
#set_property PACKAGE_PIN V16 [get_ports {sw[1]}]
#set_property PACKAGE_PIN W16 [get_ports {sw[2]}]
#set_property PACKAGE_PIN W17 [get_ports {sw[3]}]
#set_property PACKAGE_PIN W15 [get_ports {sw[4]}]
#set_property PACKAGE_PIN V15 [get_ports {sw[5]}]
#set_property PACKAGE_PIN W14 [get_ports {sw[6]}]
#set_property PACKAGE_PIN W13 [get_ports {sw[7]}]
#set_property PACKAGE_PIN V2 [get_ports {sw[8]}]
#set_property PACKAGE_PIN T3 [get_ports {sw[9]}]
#set_property PACKAGE_PIN T2 [get_ports {sw[10]}]
#set_property PACKAGE_PIN R3 [get_ports {sw[11]}]
#set_property PACKAGE_PIN W2 [get_ports {sw[12]}]
#set_property PACKAGE_PIN U1 [get_ports {sw[13]}]
#set_property PACKAGE_PIN T1 [get_ports {sw[14]}]
#set_property PACKAGE_PIN R2 [get_ports {sw[15]}]
set_property PACKAGE_PIN R2 [get_ports {reset}] set_property IOSTANDARD LVCMOS33 [get_ports {reset}]
set_property PACKAGE_PIN W19 [get_ports player1button] set_property IOSTANDARD LVCMOS33 [get_ports player1button]
set_property PACKAGE_PIN T17 [get_ports player2button] set_property IOSTANDARD LVCMOS33 [get_ports player2button]
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}]
#set_property PACKAGE_PIN V13 [get_ports {led8}]
#set_property PACKAGE_PIN V3 [get_ports {led[9]}]
#set_property PACKAGE_PIN W3 [get_ports {led[10]}]
#set_property PACKAGE_PIN U3 [get_ports {led[11]}]
#set_property PACKAGE_PIN P3 [get_ports {led[12]}]
#set_property PACKAGE_PIN N3 [get_ports {led[13]}]
#set_property PACKAGE_PIN P1 [get_ports {led[14]}]
#set_property PACKAGE_PIN L1 [get_ports {led[15]}]
#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 `