CPE 447 - University of Bridgeport

CPE 447
Final Project
Two Dimensional Ping-Pong Game
(Submitted on: October 18,1999)
Amit K Singh (# 0316061)
Sudip Pathak (# 0355147)
Instructor: Prof. Stephen Grodzinsky
University of Bridgeport
Table of Contents:
1. Introduction
…………………………………………………………. 3
2. Design Section …….…………………………………………………..
a. Design Specifications ………………………………………………
b. Random Number Generator ………………………………………..
c. Bat Movement ……………………………………………………...
d. VGA Display ………………………………………………………
e. Main Game ……………………………………………………….
f. Inputs and Outputs ………………………………………………….
4
4
4
4
5
5
5
3. Different Modules Implementation:
a. Modules and Assignments ………………………………………….. 6
b. Random Number ……………………………………………………. 6
c. Bat Movement ………………………………………………………. 8
d. Main Game ………………………………………………………….. 10
e. VGA Display …………………………………………………………18
4. Overall Structure ……………………………………………………….. 31
5. Results and conclusion ………………………………………………….. 33
Appendix:
BBBD Diagram
ASM Charts
Proposal Two
2
Introduction:
Ping-pong is a very popular game that is played world wide, sometimes between
two players and sometimes between four players. The game starts with one player serving
first and a person gets a point if his opponent cannot return the ball(serve or hit). The
service is changed after every five points. In our project we had to design the same
pingpong game using VHDL as a programming language and the FPGA as the target
chip. Our design is the implementation of two dimensional pingpong game and is
interfaced to a VGA monitor so that the movement of the bat and the ball and the scores
were displayed on the monitor.
General Outline of the Game:







The game is supposed to be played between two players.
The paddles serve as the two bats and can be moved in either back or front direction.
Any one of the players can start the game, but then serve changes at a total of 5 points
every time.
The player has to hit the ball in the second last position of the ball so that the ball gets
returned when it reaches the end position.
The game ends when either of the players gets 15 points.
The game can be reset any time using the clear button.
The game is displayed on a VGA monitor by supplying appropriate data to the
monitor at appropriate time.
3
Design Section:
First the Bare Bone Block Diagram (BBBD) for the game was designed and then broken
down into sub-blocks (attached in the appendix), namely:
Random Number Generator
Bat movement
VGA display
Main Game
CLR
CLK
Score 1st player
Score 2nd player
P0
P1
Winner
done
VGA display
These four modules were assigned to the team members as follows:
VGA Display - Amit K. Singh
Random Number Generator - Amit K. Singh
Bat movement - Sudip Pathak
Main Game - Sudip Pathak
However the specifications for each module were decided in the Project meeting. Outline
of the specifications for each module is as follows:
Random Number Generator:
Provide two random numbers each time it is asked for. The random numbers are
to be used for the position of the ball.
Bat Movement:
This module will provide the parameters for the movement of the ball. The inputs
are allowed for Reset i.e. to place the bats at the default position. Pulse buttons are
to be used for the movement and switches can be used for changing the direction
of the bat movement.
4
Main Game:
This module should provide the parameters for the ball movement. Keep track of
who serves the ball first and count the number of services. The module should
also count the scores and show the winner. Once the winner is declared stop the
game. The scores should be provided for the display on the VGA monitor.
VGA Display:
This module should allow for displaying the following on the VGA monitor:
 The movement of the ball based on the outer parameters i.e. from Main Game.
 Movement of the Bat based on the parameters from the BAT module.
 Scores for each player, which will be from 0 to 15 only.
The Project Team also decided on the outline of the display. We decided on a
resolution of 640 x 480. The pixel size is to be decided by the module designer.
Then in the following meetings, state diagrams for different modules were presented by
the each designers (provided in appendix). After a careful consideration of all the inputs
and outputs the respective designers were asked to implement their design using VHDL
code.
The various Inputs and Outputs of the program:
CLK: External clock, for the movement of the bats and ball.
Clock: Internal clock of the Altera board to provide the display signals to the monitor at
appropriate time.
CLR:
Global clear switch to reset the game at any time. Always low asserted.
Switch_1 & switch_2:
It is used to change the direction of the two bats.
P1 and P2:
These are used to move the bats(the paddles).
Serve_1 & serve_2:
These are used for the service.
W1 &W2:
These are used to show who the winner is at the end of the game.
Horiz_sync:
This is the pulse that is supplied to the monitor toindicate that the end of a row on
the screen has been reached(while refreshing the screen).
Vert_sync:
This is the pulse that is supplied to the monitor to indicate that the end of the
screen has been reached(while refreshing the screen).
Red: This signal is used to supply the monitor with the data for red color.
Green: This signal is used to supply the monitor with the data for Green color.
Blue: This signal is used to supply the monitor with the data for blue color.
5
The different modules of the project designed by assigned members are:
Bat Movement:
This module was designed based on the specifications generalized during the
project meeting. Since this module works sequentially, i.e. when the Push button is
pressed, the desired direction for the movement of the bat is checked and the bat will be
moved to the desired position, the sequential implementation was chosen for
programming in VHDL.
At first the design was implemented living a room for the mouse implementation.
Later, for some technical reason we chose to go with the two push buttons.1 Then a
switch was provided instead for switching the direction. When a reset button is pressed
the bats will come to a default position, i.e. the center on each side of the board.
Waveform for the Bat Movement Module:
Code for the Bat Movement:
(Bat.vhd)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY bat IS
PORT ( clr, CLK
: IN STD_LOGIC;
--External clock
switch_1, switch_2 : IN STD_LOGIC;
--Direction for the paddle to move
paddle_1, paddle_2 : OUT INTEGER RANGE 0 to 48;
--position of paddle
P1, P2
: IN STD_LOGIC);
-- Pulse switch for players
END bat;
ARCHITECTURE position OF bat IS
BEGIN
PROCESS(CLR,CLK)
1
A game needs two players and we could not implement a game with two mice on a single CPU.
6
VARIABLE pdl_1, pdl_2 : INTEGER RANGE 0 to 48;
BEGIN
IF clr='0' THEN
pdl_1 := 32;
pdl_2 := 32;
-- temporary position
ELSIF CLK'EVENT AND CLK = '1' THEN
--Player 1:
IF switch_1='0' THEN
--forward movement
IF P1 = '0' THEN
--asserted low on board
pdl_1 := pdl_1 + 4;
--forward movement
ELSE
pdl_1 :=pdl_1;
--no movement
END IF;
ELSIF switch_1 ='1' THEN
--backward movement
IF P1 = '0' THEN
--asserted low on board
pdl_1 := pdl_1 - 4;
--backward movement
ELSE
pdl_1 :=pdl_1;
--no movement
END IF;
END IF;
--Player 2:
IF switch_2='0' THEN
IF P2 = '0' THEN
pdl_2 := pdl_2 + 4;
ELSE
pdl_2 :=pdl_2;
END IF;
ELSIF switch_2 ='1' THEN
IF P2 = '0' THEN
pdl_2 := pdl_2 - 4;
ELSE
paddle_2 <=pdl_2;
END IF;
END IF;
END IF;
--End conditions:
--Player 1:
IF pdl_1 >15 AND pdl_1 < 45 THEN
Paddle_1 <=pdl_1;
ELSIF pdl_1 <= 15 THEN
Paddle_1 <= 16;
ELSIF pdl_1 >= 45 THEN
Paddle_1 <= 44;
END IF;
--Player 2:
IF pdl_2 >15 AND pdl_2 < 49 THEN
Paddle_2 <=pdl_2;
ELSIF pdl_2 <= 15 THEN
Paddle_2 <= 16;
ELSIF pdl_2 >= 45 THEN
Paddle_2 <= 44;
END IF;
END PROCESS;
END position;
7
Random.vhd:
This module decides the first movement of the ball at each end of the boundary. This was
later used in the ping.vhd to decide the step of the movement of the ball. This module
constantly generates two positions at each clock pulse, but this position is considered at
only two of the states in the ping.vhd module. In order to generate a better random
number, 8 bit std_logic_vector was used in this program. But since we had limitation in
the position of the of the ball, the random position was then limited to a number between
16 and 44 so as to fit the boundary of the board on display.
Waveform for the Random Number Generator:
Code for the Random Number Generator:
(Random.vhd)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY random IS
PORT ( clk, clr
: IN STD_LOGIC;
POSITION1, POSITION2 : OUT INTEGER RANGE 0 TO 48);
--clock and clear
--random numbers to be
--to be sent for the initial
--position of the ball
END random;
ARCHITECTURE behave OF random IS
SIGNAL ranvar_1 : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL ranvar_2 : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS(clk,clr)
variable PN_1 : STD_LOGIC;
BEGIN
if clr = '0' then
-- reset is low asserted
ranvar_1 <= "01010001";
PN_1 := '0';
8
elsIF clk'event and clk = '1' THEN
PN_1 := ranvar_1(6) XOR ranvar_1(3);
ranvar_1 <= PN_1 & ranvar_1(7 DOWNTO 1);
END IF;
IF conv_integer(ranvar_1)< 32 THEN
POSITION1<=16;
POSITION2<= 16;
ELSIF (conv_integer(ranvar_1) < 64) AND (conv_integer(ranvar_1) > 31) THEN
POSITION1<=20;
POSITION2 <=20;
ELSIF (conv_integer(ranvar_1) < 96) AND (conv_integer(ranvar_1) > 63) THEN
POSITION1<=24;
POSITION2 <=24;
ELSIF (conv_integer(ranvar_1) < 128) AND (conv_integer(ranvar_1) > 97) THEN
POSITION1<=28;
POSITION2 <=28;
ELSIF (conv_integer(ranvar_1) < 160) AND (conv_integer(ranvar_1) > 127) THEN
POSITION1<=32;
POSITION2 <=32;
ELSIF (conv_integer(ranvar_1) < 192) AND (conv_integer(ranvar_1) > 159) THEN
POSITION1<=36;
POSITION2 <=36;
ELSIF (conv_integer(ranvar_1) < 226) AND (conv_integer(ranvar_1) > 191) THEN
POSITION1<=40;
POSITION2 <=40;
ELSIF (conv_integer(ranvar_1) > 226)THEN
POSITION1<=44;
POSITION2 <=44;
END IF;
END PROCESS;
END behave;
9
Ping.vhd:
This was a bit complex module to design. In fact this is the main backbone to the
game. With the given specifications, BBBD was designed to show the inputs and outputs
from this module. After pondering over the problem for some time, it was decided to
implement the module using State Machine design. The handout of the Railway Track
program was really helpful for this part.
The ASM chart was first designed and was modified several times in the
subsequent project meetings to make sure that the other modules would fit properly with
this one upon completion. This was important especially to this module because this was
considered to be the major structure of the project.
The implementation using state machine was not a difficult part but the
limitations with the Altera software while using nested loops really gave a hard time.
Also, it was necessary to limit the resources used thinking that the VGA Display module
would use a lot of the resources too.2
The different states of the ASM chart were numbered in such a way as to draw a
vertical symmetrical line at the middle and distinguish the two parts for each player. This
was very helpful while debugging the program.
The scores were first introduced as integers but the VGA display module
preferred it in a BCD type. Thus the scores were converted into BCD before sending that
to the VGA display.
Waveform for the Main Game (Ping.vhd) module:
2
It was later found out that the VGA display used comparatively less resources.
10
Code for Main Game
(Ping.vhd)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--for using std_logic
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--for addition of std_logic
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY PING IS
PORT( CLK,CLR
: IN STD_LOGIC;
--external clock
SERVE1, SERVE2 : IN STD_LOGIC;
--Services
POSITION1, PADDLE1 : IN INTEGER RANGE 0 TO 48;
POSITION2, PADDLE2 : IN INTEGER RANGE 0 TO 48;
SCORE11,SCORE22 : INOUT INTEGER RANGE 0 TO 15; --scores
ROW, COLUMN
: OUT INTEGER RANGE 0 TO 64; --ball location
OUT1,OUT2
: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --scores for
--VGA display
W1,W2
: OUT STD_LOGIC);
--Winners
END PING;
ARCHITECTURE ALG OF PING IS
TYPE STATE_TYPE IS
(SERVE_DECIDE,STEP_DECIDE_STATE_1,STEP_DECIDE_STATE_2,POSITION_STATE_1,POSITION_S
TATE_2,LOOP_STATE_1,LOOP_STATE_2,SCORE_INC_1,SCORE_INC_2,IDLE_STATE_1,
IDLE_STATE_2);
SIGNAL STATE : STATE_TYPE;
SIGNAL SERVEFLAG : STD_LOGIC;
BEGIN
PROCESS(CLK,CLR)
--process wakes up on CLK or CLR
VARIABLE SCORE1 : INTEGER RANGE 0 TO 15;
--temporary score
VARIABLE SCORE2 : INTEGER RANGE 0 TO 15;
VARIABLE CURRENT_ROW,PREVIOUS_ROW,CURRENT_COLUMN :INTEGER RANGE 0 TO 64;
VARIABLE STEP : INTEGER RANGE 0 TO 32 ;
--for the movement of the ball
BEGIN
IF CLR = '0' THEN
SCORE11 <= 0;
SCORE22 <= 0;
SCORE1 := 1;
SCORE2 := 1;
CURRENT_ROW := 32;
PREVIOUS_ROW := 32;
CURRENT_COLUMN := 32;
STATE <= SERVE_DECIDE;
--the scores reset on CLR
ELSIF CLK'EVENT AND CLK = '1' THEN
CASE STATE IS
WHEN SERVE_DECIDE =>
IF SERVE1 = '1' AND SERVE2 = '0' THEN
SERVEFLAG <= '1';
--player 1 serves
11
STATE <= POSITION_STATE_1;
ELSIF SERVE1 = '0' AND SERVE2 = '1' THEN
--player2serves
SERVEFLAG <= '0';
STATE <= POSITION_STATE_2;
ELSE
STATE <= SERVE_DECIDE;
--rest condition
END IF ;
--PART DEALING WITH THE PLAYER 1
WHEN POSITION_STATE_1 =>
--serving
CURRENT_ROW := PADDLE1;
PREVIOUS_ROW := PADDLE1;
CURRENT_COLUMN := 16;
STATE <= STEP_DECIDE_STATE_1;
WHEN STEP_DECIDE_STATE_1 =>
--deciding the step
CURRENT_ROW := POSITION1;
CURRENT_COLUMN := CURRENT_COLUMN + 4;
IF POSITION1 >= PREVIOUS_ROW THEN
STEP := POSITION1 - PREVIOUS_ROW;
ELSE
STEP := PREVIOUS_ROW - POSITION1;
END IF;
STATE <= LOOP_STATE_1;
WHEN LOOP_STATE_1 =>
--ball moving on the board
--ROW_IF
IF CURRENT_ROW > PREVIOUS_ROW THEN
IF (CURRENT_ROW + STEP) > 48 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := 48;
ELSIF CURRENT_ROW = 48 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW - STEP;
ELSE
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW + STEP;
END IF;
ELSE
IF CURRENT_ROW = 16 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW + STEP;
ELSIF (CURRENT_ROW - STEP) < 16 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := 16;
ELSE
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW - STEP;
END IF;
END IF;
--COLUMN_IF AND NEXT STATE DECISION
IF CURRENT_COLUMN = 44 THEN
12
CURRENT_COLUMN :=
CURRENT_COLUMN + 4;
IF CURRENT_ROW > PREVIOUS_ROW THEN
IF PADDLE2 = (CURRENT_ROW + STEP) THEN
STATE <= POSITION_STATE_2;
ELSE
STATE <= SCORE_INC_1;
END IF;
ELSE
IF PADDLE2 = (CURRENT_ROW - STEP) THEN
STATE <= POSITION_STATE_2;
ELSE
STATE <= SCORE_INC_1;
END IF;
END IF;
ELSE
CURRENT_COLUMN := CURRENT_COLUMN + 4;
STATE <= LOOP_STATE_1;
END IF;
WHEN SCORE_INC_1 =>
SCORE1 := SCORE11 + 1;
SCORE11 <= SCORE1;
--Player P1 gets the point
IF (SERVEFLAG = '1') THEN
IF (SCORE11 + SCORE22) > 3 AND (SCORE11 + SCORE22) < 9
THEN
--This portion decide the serving player
STATE <= IDLE_STATE_2;
ELSIF (SCORE11 + SCORE22) > 13 AND (SCORE11 + SCORE22)
< 19 THEN
STATE <= IDLE_STATE_2;
ELSIF (SCORE11 + SCORE22) > 23 AND (SCORE11 + SCORE22)
< 30 THEN
STATE <= IDLE_STATE_2;
ELSE
STATE <= IDLE_STATE_1;
END IF;
ELSIF (SERVEFLAG = '0') THEN
IF (SCORE11 + SCORE22) > 3 AND (SCORE11 +
SCORE22) < 9 THEN
STATE <= IDLE_STATE_1;
ELSIF (SCORE11 + SCORE22) > 13 AND (SCORE11 + SCORE22)
< 19 THEN
STATE <= IDLE_STATE_1;
ELSIF (SCORE11 + SCORE22) > 23 AND (SCORE11 + SCORE22)
< 30 THEN
STATE <= IDLE_STATE_1;
ELSE
STATE <= IDLE_STATE_2;
END IF;
END IF;
WHEN IDLE_STATE_1 =>
CURRENT_ROW := CURRENT_ROW;
CURRENT_COLUMN := CURRENT_COLUMN;
13
IF SCORE11 = 15 OR SCORE22 = 15 THEN
STATE <= IDLE_STATE_1;
ELSIF SERVE1 = '1' THEN
--Player serves again
STATE <= POSITION_STATE_1;
ELSE
STATE <= IDLE_STATE_1;
--Player is taking a rest!
END IF;
--PART DEALING WITH THE PLAYER 2
WHEN POSITION_STATE_2 =>
CURRENT_ROW := PADDLE2;
PREVIOUS_ROW := PADDLE2;
CURRENT_COLUMN := 48;
STATE <= STEP_DECIDE_STATE_2;
WHEN STEP_DECIDE_STATE_2 =>
CURRENT_ROW := POSITION2;
CURRENT_COLUMN := CURRENT_COLUMN - 4;
IF POSITION2 >= PREVIOUS_ROW THEN
STEP := POSITION2 - PREVIOUS_ROW;
ELSE
STEP := PREVIOUS_ROW - POSITION2;
END IF;
STATE <= LOOP_STATE_2;
WHEN LOOP_STATE_2 =>
--ROW_IF
IF CURRENT_ROW > PREVIOUS_ROW THEN
IF (CURRENT_ROW + STEP) > 48 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := 48;
ELSIF CURRENT_ROW = 48 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW - STEP;
ELSE
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW + STEP;
END IF;
ELSE
IF CURRENT_ROW = 16 THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW + STEP;
ELSIF (CURRENT_ROW - STEP) < 16
THEN
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := 16;
ELSE
PREVIOUS_ROW := CURRENT_ROW;
CURRENT_ROW := CURRENT_ROW - STEP;
END IF;
END IF;
--COLUMN_IF AND NEXT STATE DECISION
14
IF CURRENT_COLUMN = 20 THEN
CURRENT_COLUMN :=
CURRENT_COLUMN - 4;
IF CURRENT_ROW > PREVIOUS_ROW THEN
IF PADDLE1 = (CURRENT_ROW + STEP) THEN
STATE <= POSITION_STATE_1;
ELSE
STATE <= SCORE_INC_2;
END IF;
ELSE
IF PADDLE1 = (CURRENT_ROW - STEP) THEN
STATE <= POSITION_STATE_1;
ELSE
STATE <= SCORE_INC_2;
END IF;
END IF;
ELSE
CURRENT_COLUMN := CURRENT_COLUMN - 4;
STATE <= LOOP_STATE_2;
END IF;
WHEN SCORE_INC_2 =>
SCORE2 := SCORE22 + 1;
SCORE22 <= SCORE2;
IF (SERVEFLAG = '1') THEN
IF (SCORE11 + SCORE22) > 3 AND (SCORE11 + SCORE22) < 9
THEN
STATE <= IDLE_STATE_2;
ELSIF (SCORE11 + SCORE22) > 13 AND (SCORE11 + SCORE22)
< 19 THEN
STATE <= IDLE_STATE_2;
ELSIF (SCORE11 + SCORE22) > 23 AND (SCORE11 + SCORE22)
< 30 THEN
STATE <= IDLE_STATE_2;
ELSE
STATE <= IDLE_STATE_1;
END IF;
ELSIF (SERVEFLAG = '0') THEN
IF (SCORE11 + SCORE22) > 3 AND (SCORE11 +
SCORE22) < 9 THEN
STATE <= IDLE_STATE_1;
ELSIF (SCORE11 + SCORE22) > 13 AND (SCORE11 + SCORE22)
< 19 THEN
STATE <= IDLE_STATE_1;
ELSIF (SCORE11 + SCORE22) > 23 AND
(SCORE11 + SCORE22)
< 30 THEN
STATE <= IDLE_STATE_1;
ELSE
STATE <= IDLE_STATE_2;
END IF;
END IF;
15
WHEN IDLE_STATE_2 =>
CURRENT_ROW := CURRENT_ROW;
CURRENT_COLUMN := CURRENT_COLUMN;
IF SCORE11 = 15 OR SCORE22 = 15 THEN
STATE <= IDLE_STATE_2;
ELSIF SERVE2 = '1' THEN
STATE <= POSITION_STATE_2;
ELSE
STATE <= IDLE_STATE_2;
END IF;
END CASE;
--end of states
END IF;
ROW <= CURRENT_ROW;
COLUMN <= CURRENT_COLUMN;
END PROCESS;
--THE PROCESS TO CONVERT THE SCORE INTO BCD TO BE USED IN VGA
--DISPALY
PROCESS(SCORE11,SCORE22)
BEGIN
--asserted low
CASE SCORE11 IS
--Player 1
WHEN 0 => OUT1 <= "0000001";
WHEN 1 => OUT1 <= "1001111";
WHEN 2 => OUT1 <= "0010010";
WHEN 3 => OUT1 <= "0000110";
WHEN 4 => OUT1 <= "1001100";
WHEN 5 => OUT1 <= "0100100";
WHEN 6 => OUT1 <= "0100000";
WHEN 7 => OUT1 <= "0001111";
WHEN 8 => OUT1 <= "0000000";
WHEN 9 => OUT1 <= "0001100";
WHEN 10=> OUT1 <= "0000010";
WHEN 11=> OUT1 <= "1100000";
WHEN 12=> OUT1 <= "0110001";
WHEN 13=> OUT1 <= "1000010";
WHEN 14=> OUT1 <= "0110000";
WHEN 15=> OUT1 <= "0111000";
END CASE;
-- WINNER IS PLAYER P1
IF SCORE11 = 15 THEN
W1 <= '0';
ELSE
W1 <= '1';
END IF;
CASE SCORE22 IS
WHEN 0 => OUT2 <= "0000001";
WHEN 1 => OUT2 <= "1001111";
--Player 2
16
WHEN 2 => OUT2 <= "0010010";
WHEN 3 => OUT2 <= "0000110";
WHEN 4 => OUT2 <= "1001100";
WHEN 5 => OUT2 <= "0100100";
WHEN 6 => OUT2 <= "0100000";
WHEN 7 => OUT2 <= "0001111";
WHEN 8 => OUT2 <= "0000000";
WHEN 9 => OUT2 <= "0001100";
WHEN 10=> OUT2 <= "0000010";
WHEN 11=> OUT2 <= "1100000";
WHEN 12=> OUT2 <= "0110001";
WHEN 13=> OUT2 <= "1000010";
WHEN 14=> OUT2 <= "0110000";
WHEN 15=> OUT2 <= "0111000";
END CASE;
--Winner is Player 2
IF SCORE22 = 15 THEN
W2 <= '0';
ELSE
W2 <= '1';
END IF;
END PROCESS;
END ALG;
17
Display.vhd(Anew2.vhd):
Display module takes the row and the column addresses of the ball as input and
displays it on the respective location on the screen. Since a single pixel of the screen will
be too small to be seen and we are not concerned about higher resolution at this time, the
screen was mapped into 7 x 5 pixel block each, out of 640 x 480 pixels of the VGA
screen. The board size for the game was determined to be 32 x 32 super pixel. The sizes
of the paddles were determined to be 4 x 1 super pixel and the size of the ball was
determined to be 1 super pixel. Three different colors were chosen for the boundary of
the board, paddles and the ball.
The scores for each of the players were also displayed along the sides of the
board. The numbers are displayed in hexadecimal format. A white color was chosen for
the scores. The score was driven from the module ping.vhd. Since the ping.vhd had used
asserted low convention for the scores (as was required by the Altera board display), the
checking for the display of the scores in this module had to be the same. This issue was
given special attention during the design of this module
The background of the screen was chosen to be black so as to save the power used
by the system.
Code for Display Module
(display.vhd)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY display IS
PORT(Clock
: IN STD_LOGIC;
--internal clock
ROW, COLUMN
: IN INTEGER RANGE 0 TO 64;
--address of ball
PADDLE1,PADDLE2
: IN INTEGER RANGE 0 TO 48; --position of paddles
OUT1,OUT2
: IN STD_LOGIC_VECTOR(6 DOWNTO 0); --scores
Horiz_sync, Vert_sync : OUT STD_LOGIC;-sync signals for screen
RED, GREEN, BLUE
: OUT STD_LOGIC);
--color signals
END display;
ARCHITECTURE NEW1 OF display IS
-- Video Display Signals
signal Horiz_Count,Vert_Count: std_logic_vector(9 Downto 0);
signal R, G, B : std_logic;
--Signals to determine the super pixel and keep track of the position during --screen refresh
signal col_address, row_address: std_logic_vector(7 Downto 0);
signal col_count, row_count: std_logic_vector(2 Downto 0);
constant H_max : std_logic_vector(9 Downto 0) := CONV_STD_LOGIC_VECTOR(799,10);
-- 799 is max horiz count
18
constant V_max : std_logic_vector(9 Downto 0) := CONV_STD_LOGIC_VECTOR(524,10);
-- 524 is max vert count
begin
Red <= R ;
Green <= G;
Blue <= B;
--Generate Horizontal and Vertical Sync Signals for Video Display and
super pixel
--determination of the size of
VIDEO_DISPLAY: Process
Begin
Wait until(Clock'Event and Clock='1');
-- Counting horizontal pixels(640 + extra time for sync signals)
If (Horiz_Count >= H_max) then
Horiz_Count <= To_Stdlogicvector(B"0000000000");
Else
Horiz_Count <= Horiz_Count + To_Stdlogicvector(B"0000000001");
End if;
If (Horiz_Count <= CONV_STD_LOGIC_VECTOR(755,10)) and (Horiz_Count >=
CONV_STD_LOGIC_VECTOR(659,10)) Then
Horiz_Sync <= '0';
ELSE
Horiz_Sync <= '1';
End if;
--Counting vertical pixels (480 + extra time for sync signals)
If (Vert_Count >= V_max) and (Horiz_Count >= CONV_STD_LOGIC_VECTOR(699,10)) then
Vert_Count <= To_Stdlogicvector(B"0000000000");
Else If (Horiz_Count = CONV_STD_LOGIC_VECTOR(699,10)) Then
Vert_Count <= Vert_Count + To_Stdlogicvector(B"0000000001");
End if;
If (Vert_Count <= CONV_STD_LOGIC_VECTOR(494,10)) and (Vert_Count >=
CONV_STD_LOGIC_VECTOR(493,10)) Then
Vert_Sync <= '0';
ELSE
Vert_Sync <= '1';
End if;
-- Generate row and col address for 7 by 5 superpixel to map into 64 by 64 video --memory
if (Horiz_Count <= CONV_STD_LOGIC_VECTOR(639,10)) Then
If col_count < CONV_STD_LOGIC_VECTOR(7,3) Then
col_count <= col_count + '1';
Else
col_count <= "000";
col_address <= col_address + '1';
End if;
ELSE
--end of column count
19
col_count <= "000";
col_address <= "00000000";
End if;
IF(HORIZ_COUNT = CONV_STD_LOGIC_VECTOR(641,10)) Then
row_count <= row_count + '1';
If (row_count = CONV_STD_LOGIC_VECTOR(5,3)) THEN
row_count <= "000";
row_address <= row_address + '1';
End if;
End if;
--end of row count
If (Vert_Count >= CONV_STD_LOGIC_VECTOR(479,10)) Then
row_count <= "000";
row_address <= "00000000";
End if;
end if;
end process VIDEO_DISPLAY;
--Process to determine what colors are to be used and where
RGB:PROCESS
BEGIN
--BOUNDARY OF THE BOARD
IF row_address = CONV_STD_LOGIC_VECTOR(15,8) AND col_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND col_address <= CONV_STD_LOGIC_VECTOR(49,8)
THEN
R <= '1';
G <= '0';
B <= '0';
ELSIF row_address = CONV_STD_LOGIC_VECTOR(49,8) AND col_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND col_address <= CONV_STD_LOGIC_VECTOR(49,8)
THEN
R <= '1';
G <= '0';
B <= '0';
ELSIF col_address = CONV_STD_LOGIC_VECTOR(15,8) AND row_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND row_address <= CONV_STD_LOGIC_VECTOR(49,8)
THEN
R <= '1';
G <= '0';
B <= '0';
ELSIF col_address = CONV_STD_LOGIC_VECTOR(49,8) AND row_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND row_address <= CONV_STD_LOGIC_VECTOR(49,8)
THEN
20
R <= '1';
G <= '0';
B <= '0';
END IF;
--PADDLE1
IF PADDLE1 = 16 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(14,8) OR row_address = CONV_STD_LOGIC_VECTOR(15,8) OR
row_address = CONV_STD_LOGIC_VECTOR(16,8) OR row_address =
CONV_STD_LOGIC_VECTOR(17,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 20 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(18,8) OR row_address = CONV_STD_LOGIC_VECTOR(19,8) OR
row_address = CONV_STD_LOGIC_VECTOR(20,8) OR row_address =
CONV_STD_LOGIC_VECTOR(21,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 24 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(22,8) OR row_address = CONV_STD_LOGIC_VECTOR(23,8) OR
row_address = CONV_STD_LOGIC_VECTOR(24,8) OR row_address =
CONV_STD_LOGIC_VECTOR(25,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 28 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(26,8) OR row_address = CONV_STD_LOGIC_VECTOR(27,8) OR
row_address = CONV_STD_LOGIC_VECTOR(28,8) OR row_address =
21
CONV_STD_LOGIC_VECTOR(29,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 32 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8) OR
row_address = CONV_STD_LOGIC_VECTOR(32,8) OR row_address =
CONV_STD_LOGIC_VECTOR(33,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 36 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(34,8) OR row_address = CONV_STD_LOGIC_VECTOR(35,8) OR
row_address = CONV_STD_LOGIC_VECTOR(36,8) OR row_address =
CONV_STD_LOGIC_VECTOR(37,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 40 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(38,8) OR row_address = CONV_STD_LOGIC_VECTOR(39,8) OR
row_address = CONV_STD_LOGIC_VECTOR(40,8) OR row_address =
CONV_STD_LOGIC_VECTOR(41,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE1 = 44 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(13,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(42,8) OR row_address = CONV_STD_LOGIC_VECTOR(43,8) OR
row_address = CONV_STD_LOGIC_VECTOR(44,8) OR row_address =
CONV_STD_LOGIC_VECTOR(45,8)) THEN
22
R <= '1';
G <= '0';
B <= '1';
END IF;
END IF;
--PADDLE2
IF PADDLE2 = 16 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(14,8) OR row_address = CONV_STD_LOGIC_VECTOR(15,8) OR
row_address = CONV_STD_LOGIC_VECTOR(16,8) OR row_address =
CONV_STD_LOGIC_VECTOR(17,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 20 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(18,8) OR row_address = CONV_STD_LOGIC_VECTOR(19,8) OR
row_address = CONV_STD_LOGIC_VECTOR(20,8) OR row_address =
CONV_STD_LOGIC_VECTOR(21,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 24 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(22,8) OR row_address = CONV_STD_LOGIC_VECTOR(23,8) OR
row_address = CONV_STD_LOGIC_VECTOR(24,8) OR row_address =
CONV_STD_LOGIC_VECTOR(25,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 28 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(26,8) OR row_address = CONV_STD_LOGIC_VECTOR(27,8) OR
row_address = CONV_STD_LOGIC_VECTOR(28,8) OR row_address =
CONV_STD_LOGIC_VECTOR(29,8)) THEN
R <= '1';
G <= '0';
B <= '1';
23
END IF;
ELSIF PADDLE2 = 32 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8) OR
row_address = CONV_STD_LOGIC_VECTOR(32,8) OR row_address =
CONV_STD_LOGIC_VECTOR(33,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 36 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(34,8) OR row_address = CONV_STD_LOGIC_VECTOR(35,8) OR
row_address = CONV_STD_LOGIC_VECTOR(36,8) OR row_address =
CONV_STD_LOGIC_VECTOR(37,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 40 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(38,8) OR row_address = CONV_STD_LOGIC_VECTOR(39,8) OR
row_address = CONV_STD_LOGIC_VECTOR(40,8) OR row_address =
CONV_STD_LOGIC_VECTOR(41,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
ELSIF PADDLE2 = 44 THEN
IF col_address = CONV_STD_LOGIC_VECTOR(51,8) AND (row_address =
CONV_STD_LOGIC_VECTOR(42,8) OR row_address = CONV_STD_LOGIC_VECTOR(43,8) OR
row_address = CONV_STD_LOGIC_VECTOR(44,8) OR row_address =
CONV_STD_LOGIC_VECTOR(45,8)) THEN
R <= '1';
G <= '0';
B <= '1';
END IF;
END IF;
--LOCATION OF THE BALL ON THE MONITOR
IF row_address = CONV_STD_LOGIC_VECTOR(ROW,8) AND col_address =
CONV_STD_LOGIC_VECTOR(COLUMN,8) THEN
24
R <= '1';
G <= '1';
B <= '0';
END IF;
--SCORES
--SCORE OF PLAYER 1
IF OUT1(6) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(29,8) AND (col_address =
CONV_STD_LOGIC_VECTOR(8,8) OR col_address = CONV_STD_LOGIC_VECTOR(9,8) OR
col_address = CONV_STD_LOGIC_VECTOR(10,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(5) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(10,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(4) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(10,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(3) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(33,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(8,8) OR col_address =
CONV_STD_LOGIC_VECTOR(9,8) OR col_address = CONV_STD_LOGIC_VECTOR(10,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(2) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(8,8) AND (row_address
= CONV_STD_LOGIC_VECTOR(31,8) OR row_address = CONV_STD_LOGIC_VECTOR(32,8) OR
row_address = CONV_STD_LOGIC_VECTOR(33,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(1) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(8,8) AND (row_address
= CONV_STD_LOGIC_VECTOR(29,8) OR row_address = CONV_STD_LOGIC_VECTOR(30,8) OR
row_address = CONV_STD_LOGIC_VECTOR(31,8)) THEN
25
R <= '1';
G <='1';
B <= '1';
ELSIF OUT1(0) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(31,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(8,8) OR col_address =
CONV_STD_LOGIC_VECTOR(9,8) OR col_address = CONV_STD_LOGIC_VECTOR(10,8)) THEN
R <= '1';
G <='1';
B <= '1';
END IF;
--SCORE OF PLAYER 2
IF OUT2(6) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(29,8) AND (col_address =
CONV_STD_LOGIC_VECTOR(54,8) OR col_address = CONV_STD_LOGIC_VECTOR(55,8) OR
col_address = CONV_STD_LOGIC_VECTOR(56,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(5) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(56,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(4) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(56,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(3) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(33,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(54,8) OR col_address =
CONV_STD_LOGIC_VECTOR(55,8) OR col_address = CONV_STD_LOGIC_VECTOR(56,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(2) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(54,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)) THEN
26
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(1) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(54,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)) THEN
R <= '1';
G <='1';
B <= '1';
ELSIF OUT2(0) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(31,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(54,8) OR col_address =
CONV_STD_LOGIC_VECTOR(55,8) OR col_address = CONV_STD_LOGIC_VECTOR(56,8)) THEN
R <= '1';
G <='1';
B <= '1';
END IF;
--REST OF THE SCREEN
IF (NOT(row_address = CONV_STD_LOGIC_VECTOR(15,8) AND col_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND col_address <= CONV_STD_LOGIC_VECTOR(49,8))AND
NOT(row_address = CONV_STD_LOGIC_VECTOR(49,8) AND col_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND col_address <= CONV_STD_LOGIC_VECTOR(49,8))AND
NOT(col_address = CONV_STD_LOGIC_VECTOR(15,8) AND row_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND row_address <= CONV_STD_LOGIC_VECTOR(49,8))AND
NOT(col_address = CONV_STD_LOGIC_VECTOR(49,8) AND row_address >=
CONV_STD_LOGIC_VECTOR(15,8) AND row_address <= CONV_STD_LOGIC_VECTOR(49,8))AND
NOT(PADDLE1=16 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(14,8) OR row_address =
CONV_STD_LOGIC_VECTOR(15,8) OR row_address = CONV_STD_LOGIC_VECTOR(16,8) OR
row_address = CONV_STD_LOGIC_VECTOR(17,8)))AND
NOT(PADDLE1=20 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(18,8) OR row_address =
CONV_STD_LOGIC_VECTOR(19,8) OR row_address = CONV_STD_LOGIC_VECTOR(20,8) OR
row_address = CONV_STD_LOGIC_VECTOR(21,8)))AND
NOT(PADDLE1=24 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(22,8) OR row_address =
CONV_STD_LOGIC_VECTOR(23,8) OR row_address = CONV_STD_LOGIC_VECTOR(24,8) OR
row_address = CONV_STD_LOGIC_VECTOR(25,8)))AND
27
NOT(PADDLE1=28 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(26,8) OR row_address =
CONV_STD_LOGIC_VECTOR(27,8) OR row_address = CONV_STD_LOGIC_VECTOR(28,8) OR
row_address = CONV_STD_LOGIC_VECTOR(29,8)))AND
NOT(PADDLE1=32 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(30,8) OR row_address =
CONV_STD_LOGIC_VECTOR(31,8) OR row_address = CONV_STD_LOGIC_VECTOR(32,8) OR
row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(PADDLE1=36 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(34,8) OR row_address =
CONV_STD_LOGIC_VECTOR(35,8) OR row_address = CONV_STD_LOGIC_VECTOR(36,8) OR
row_address = CONV_STD_LOGIC_VECTOR(37,8)))AND
NOT(PADDLE1=40 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(38,8) OR row_address =
CONV_STD_LOGIC_VECTOR(39,8) OR row_address = CONV_STD_LOGIC_VECTOR(40,8) OR
row_address = CONV_STD_LOGIC_VECTOR(41,8)))AND
NOT(PADDLE1=44 AND col_address = CONV_STD_LOGIC_VECTOR(13,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(42,8) OR row_address =
CONV_STD_LOGIC_VECTOR(43,8) OR row_address = CONV_STD_LOGIC_VECTOR(44,8) OR
row_address = CONV_STD_LOGIC_VECTOR(45,8)))AND
NOT(PADDLE2=16 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(14,8) OR row_address =
CONV_STD_LOGIC_VECTOR(15,8) OR row_address = CONV_STD_LOGIC_VECTOR(16,8) OR
row_address = CONV_STD_LOGIC_VECTOR(17,8)))AND
NOT(PADDLE2=20 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(18,8) OR row_address =
CONV_STD_LOGIC_VECTOR(19,8) OR row_address = CONV_STD_LOGIC_VECTOR(20,8) OR
row_address = CONV_STD_LOGIC_VECTOR(21,8)))AND
NOT(PADDLE2=24 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(22,8) OR row_address =
CONV_STD_LOGIC_VECTOR(23,8) OR row_address = CONV_STD_LOGIC_VECTOR(24,8) OR
row_address = CONV_STD_LOGIC_VECTOR(25,8)))AND
NOT(PADDLE2=28 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(26,8) OR row_address =
CONV_STD_LOGIC_VECTOR(27,8) OR row_address = CONV_STD_LOGIC_VECTOR(28,8) OR
row_address = CONV_STD_LOGIC_VECTOR(29,8)))AND
NOT(PADDLE2=32 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(30,8) OR row_address =
CONV_STD_LOGIC_VECTOR(31,8) OR row_address = CONV_STD_LOGIC_VECTOR(32,8) OR
row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(PADDLE2=36 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(34,8) OR row_address =
CONV_STD_LOGIC_VECTOR(35,8) OR row_address = CONV_STD_LOGIC_VECTOR(36,8) OR
28
row_address = CONV_STD_LOGIC_VECTOR(37,8)))AND
NOT(PADDLE2=40 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(38,8) OR row_address =
CONV_STD_LOGIC_VECTOR(39,8) OR row_address = CONV_STD_LOGIC_VECTOR(40,8) OR
row_address = CONV_STD_LOGIC_VECTOR(41,8)))AND
NOT(PADDLE2=44 AND col_address = CONV_STD_LOGIC_VECTOR(51,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(42,8) OR row_address =
CONV_STD_LOGIC_VECTOR(43,8) OR row_address = CONV_STD_LOGIC_VECTOR(44,8) OR
row_address = CONV_STD_LOGIC_VECTOR(45,8)))AND
NOT(row_address = CONV_STD_LOGIC_VECTOR(ROW,8) AND col_address =
CONV_STD_LOGIC_VECTOR(COLUMN,8)) AND
NOT(OUT1(6) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(29,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(8,8) OR col_address =
CONV_STD_LOGIC_VECTOR(9,8) OR col_address = CONV_STD_LOGIC_VECTOR(10,8)))AND
NOT(OUT1(5) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(10,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)))AND
NOT(OUT1(4) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(10,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(OUT1(3) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(33,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(8,8) OR col_address =
CONV_STD_LOGIC_VECTOR(9,8) OR col_address = CONV_STD_LOGIC_VECTOR(10,8)))AND
NOT(OUT1(2) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(8,8) AND (row_address
= CONV_STD_LOGIC_VECTOR(31,8) OR row_address = CONV_STD_LOGIC_VECTOR(32,8) OR
row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(OUT1(1) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(8,8) AND (row_address
= CONV_STD_LOGIC_VECTOR(29,8) OR row_address = CONV_STD_LOGIC_VECTOR(30,8) OR
row_address = CONV_STD_LOGIC_VECTOR(31,8)))AND
NOT(OUT1(0) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(31,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(8,8) OR col_address =
CONV_STD_LOGIC_VECTOR(9,8) OR col_address = CONV_STD_LOGIC_VECTOR(10,8)))AND
NOT(OUT2(6) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(29,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(54,8) OR col_address =
CONV_STD_LOGIC_VECTOR(55,8) OR col_address = CONV_STD_LOGIC_VECTOR(56,8)))AND
NOT(OUT2(5) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(56,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)))AND
NOT(OUT2(4) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(56,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
29
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(OUT2(3) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(33,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(54,8) OR col_address =
CONV_STD_LOGIC_VECTOR(55,8) OR col_address = CONV_STD_LOGIC_VECTOR(56,8)))AND
NOT(OUT2(2) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(54,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(31,8) OR row_address =
CONV_STD_LOGIC_VECTOR(32,8) OR row_address = CONV_STD_LOGIC_VECTOR(33,8)))AND
NOT(OUT2(1) = '0' AND col_address = CONV_STD_LOGIC_VECTOR(54,8) AND
(row_address = CONV_STD_LOGIC_VECTOR(29,8) OR row_address =
CONV_STD_LOGIC_VECTOR(30,8) OR row_address = CONV_STD_LOGIC_VECTOR(31,8)))AND
NOT(OUT2(0) = '0' AND row_address = CONV_STD_LOGIC_VECTOR(31,8) AND
(col_address = CONV_STD_LOGIC_VECTOR(54,8) OR col_address =
CONV_STD_LOGIC_VECTOR(55,8) OR col_address = CONV_STD_LOGIC_VECTOR(56,8)))) THEN
R <= '0';
G <= '0';
B <= '0';
END IF;
END PROCESS RGB;
END NEW1;
30
Combining to form the Overall Structure:
The whole banana was designed and programmed by the team members together.
The prudent plan of the whole design as well as the perspicacious implementation of
various modules was appreciated by both the members of the project team.
A structural format is used to combine the different modules together. The four of
the modules are included as components in the main program and signals, variables and
input outputs are used to interconnect them.
Code for the Overall Structure:
(Final.vhd)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY FINAL IS
PORT(Clock,CLK,CLK : IN STD_LOGIC; --clock signals for VGA
--display and for game movements
switch_1, switch_2 : IN STD_LOGIC;
--used to determine the
-direction of the paddle
P1, P2
: IN STD_LOGIC;
--push buttons for movement of
-- paddles.
SERVE1, SERVE2 : IN STD_LOGIC; --used to serve by the players
W1,W2
: OUT STD_LOGIC; --winners on LED display
Horiz_sync, Vert_sync : OUT STD_LOGIC;--VGA signals to notify end
--of row and column
RED, GREEN, BLUE
: OUT STD_LOGIC); --signals for three
--different colors used.
END FINAL;
ARCHITECTURE NEW1 OF FINAL IS
SIGNAL PADDLE1, PADDLE2
: INTEGER RANGE 0 TO 48;
SIGNAL POSITION1, POSITION2 : INTEGER RANGE 0 TO 48;
SIGNAL SCORE11, SCORE22
: INTEGER RANGE 0 TO 15;
SIGNAL ROW, COLUMN
: INTEGER RANGE 0 TO 64;
SIGNAL OUT1,OUT2
: STD_LOGIC_VECTOR(6 DOWNTO 0);
COMPONENT bat
--component used for movement of bat
PORT ( clr, CLK
: IN STD_LOGIC;
switch_1, switch_2 : IN STD_LOGIC;
paddle_1, paddle_2
: INOUT INTEGER
RANGE 0 to 48;
P1, P2
: IN STD_LOGIC);
END COMPONENT;
COMPONENT random
--component to generate position of
PORT ( clk,clr
: IN STD_LOGIC;-- ball on the boundaries
POSITION1, POSITION2 : OUT INTEGER RANGE 0 TO 48);
END COMPONENT;
COMPONENT PING
PORT( CLK,CLR
: IN STD_LOGIC;
SERVE1, SERVE2
: IN STD_LOGIC;
--The main game
31
POSITION1, PADDLE1 : IN INTEGER RANGE 0 TO 48;
POSITION2, PADDLE2 : IN INTEGER RANGE 0 TO 48;
SCORE11,SCORE22 : INOUT INTEGER RANGE 0 TO 15;
ROW, COLUMN
: OUT INTEGER RANGE 0 TO 64; --gives the
--position of the ball on the VGA monitor
OUT1,OUT2
: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --scores
W1,W2
: OUT STD_LOGIC);
--winners
END COMPONENT;
COMPONENT display
PORT(Clock
: IN STD_LOGIC; --internal clock of board
ROW, COLUMN
: IN INTEGER RANGE 0 TO 64; --position of
-- ball
PADDLE1,PADDLE2
: IN INTEGER RANGE 0 TO 48; --paddleposition
OUT1,OUT2
: IN STD_LOGIC_VECTOR(6 DOWNTO 0);--scores
Horiz_sync, Vert_sync : OUT STD_LOGIC;-sync signals for monitor
RED, GREEN, BLUE : OUT STD_LOGIC);-color signals
END COMPONENT;
BEGIN
U1: bat
PORT MAP(clr,CLK,switch_1,switch_2,PADDLE1,PADDLE2,P1,P2);
U2: random
PORT MAP(CLK,clr,POSITION1,POSITION2);
U3: PING
PORT
MAP(CLK,CLR,SERVE1,SERVE2,POSITION1,PADDLE1,POSITION2,PADDLE2,SCORE11,SCORE22,ROW,COL
UMN,OUT1,OUT2,W1,W2);
U4: display
PORT
MAP(Clock,ROW,COLUMN,PADDLE1,PADDLE2,OUT1,OUT2,Horiz_sync,Vert_sync,RED,GREEN,BLUE);
END NEW1;
32
Results and Conclusion:
This was the second time the project members decided to work together after the
successful implementation of the Slot Machine3 game on the same UP1 Altera board.
Both the team members realized that it was lot easier to work together the second time,
since both had a lot of confidence in each other. Since the beginning both of us had a
sense of confidence in the successful implementation of this game.
However various problems were still encountered but these were related more to
the streamlining of the game. We tried to use the mouse inputs for the game but this was
disregarded later as the game needed two mice, which was not possible to implement
using a single chip.
The second problem arose when we tried to implement several functions like
smashing. This required a separate Clock input for the game. With a variation in the
clock input for the movement of the ball only, this would have been possible. It was
decided not to get into those complexities since we already have the game that is difficult
enough. Also, it was difficult to use the switches and buttons on the UP1 Board. Another
possibility would be to use the Key Board instead of the switches on the UP1 Board. But
this idea came to us quite late and it was decided not to spend more time.
Although it was not discussed earlier, we noticed that the game could be
displayed in a demonstration mode. This was noticed while the project members were
playing the game. If we put a flag on for the demonstration mode and leave the certain
switches on, the game would continue on its own.
The total resources used by the whole project came out to be around 73%.
For the Bat.vhd
Total dedicated input pins used:
6/6
(100%)
Total I/O pins used:
12/183 ( 6%)
Total logic cells used:
60/1152 ( 5%)
Total embedded cells used:
0/48 ( 0%)
Total EABs used:
0/6
( 0%)
Average fan-in:
3.03/4 ( 75%)
Total fan-in:
182/4608 ( 3%)
For Random Number generator:
Total dedicated input pins used:
Total I/O pins used:
Total logic cells used:
2/6
( 33%)
12/183 ( 6%)
38/1152 ( 3%)
3
Slot Machine was implemented for the earlier course CPE 315 (Digital Design using VHDL). However
VGA display was not done for that game. Instead 5x7 LEDs were used to show the wheels movement.
33
Total embedded cells used:
Total EABs used:
Average fan-in:
Total fan-in:
0/48 ( 0%)
0/6
( 0%)
3.02/4 ( 75%)
115/4608 ( 2%)
For VGA display:
** DEVICE SUMMARY **
Chip/
POF
Device
Input Output Bidir Memory Memory
Pins Pins Pins Bits % Utilized LCs % Utilized
display EPF10K20RC240-4 41
User Pins:
41
5
5
0
0
0 % 293
LCs
25 %
0
Total dedicated input pins used:
6/6
(100%)
Total I/O pins used:
40/183 ( 21%)
Total logic cells used:
293/1152 ( 25%)
Total embedded cells used:
0/48 ( 0%)
Total EABs used:
0/6
( 0%)
Average fan-in:
3.49/4 ( 87%)
Total fan-in:
1023/4608 ( 22%)
For Main Game (Ping.vhd)
** DEVICE SUMMARY **
Chip/
POF
ping
Device
Input Output Bidir Memory Memory
Pins Pins Pins Bits % Utilized LCs % Utilized
EPF10K20RC240-4 28
User Pins:
28
30
30
8
0
0 % 458
LCs
39 %
8
Total dedicated input pins used:
6/6
(100%)
Total I/O pins used:
60/183 ( 32%)
Total logic cells used:
458/1152 ( 39%)
Total embedded cells used:
0/48 ( 0%)
Total EABs used:
0/6
( 0%)
Average fan-in:
3.54/4 ( 88%)
Total fan-in:
1624/4608 ( 35%)
34
For the Overall Structure:
** DEVICE SUMMARY **
Chip/
POF
final
Device
Input Output Bidir Memory Memory
Pins Pins Pins Bits % Utilized LCs % Utilized
EPF10K20RC240-4 9
User Pins:
9
7
7
0
0
0 % 848
LCs
73 %
0
Total dedicated input pins used:
6/6
(100%)
Total I/O pins used:
10/183 ( 5%)
Total logic cells used:
848/1152 ( 73%)
Total embedded cells used:
0/48 ( 0%)
Total EABs used:
0/6
( 0%)
Average fan-in:
3.46/4 ( 86%)
Total fan-in:
2936/4608 ( 63%)
The resources used indicate that the project was optimized very well. In the beginning
we were planning to use MIF file for the VGA display. For that we would have to store
the whole file in the memory and that would limit our resources a lot. But later we
managed to implement the VGA display without using MIF files. That probably saved us
a lot of resources.
35