Digital Circuits and Systems/Pong Game

Problem
In this Project is about to develop a pong game and display it on monitor. Carry the project on the FPGA and will sent the video to the monitor via VGA interface. The resolution of the game will be 640x480 and eight colors.

Conceive
The starting point is to understand to generating the VGA into Computer Screen from chapter 19 of IntroToSpartanFPGABook pdf book. For the chapter 19 Professor Foerster Supplied three different Xiling projects, which was previously done. And our goal is to change any one project significant way. I played around with the code to figure out to change the thickness of the grid lines, the different part of the counter both pixel wise and line wise. Also started look online about pong game video on YouTube, that has done previously on Basys™2 Spartan-3E FPGA Board bigger (other) Circuit than Papilio one. The goal is to get an idea from it and then using VGA projects to display and utilize the (VGA) project that had done on previous semester (Fall 14).

Points
No 1

The idea is to create pong game just like in this link: Pong on a FPGA. This link contain information about two player game of “Basys 2” FPGA, where I’m going to make it into “papilio one” just to start for one player pong game. Here is the Circuit Schematic for the Pong Game:

No 4

Pong Game Main Module:

Name: Jesal Mistry Howard Community College Spring 15 ENES-245 This file is part of the Final Project Description: Pong Game Date: 4/27/2015 Current Status: Finished library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity vga_control is    Port ( clk        : in  STD_LOGIC;            start      : in  STD_LOGIC; --TO start Assigning SWITCH#0            reset      : in  STD_LOGIC;            button_l   : IN std_logic;--Left joystick            button_r   : IN std_logic;--Right joystick            rgb        : out  STD_LOGIC_VECTOR (2 downto 0);--assigning all three colors: red, green, blue            h_s        : out  STD_LOGIC;--horizontal syncronize            v_s        : out  STD_LOGIC--vertical syncronize			  ); end vga_control;

architecture Behavioral of vga_control is --/////////////////////////////////////////////////// --Digital Clock Manager: This Component is increase// --the clockspeed from 32MHz to 50 MHz             // --/////////////////////////////////////////////////// COMPONENT DCM32to50 PORT(		CLKIN_IN : IN std_logic;         		CLKFX_OUT : OUT std_logic;		CLKIN_IBUFG_OUT : OUT std_logic;		CLK0_OUT : OUT std_logic		); END COMPONENT;

COMPONENT img_gen PORT( i_clk       : IN std_logic;          x_control  : IN std_logic_vector(9 downto 0);          button_l   : IN std_logic;          button_r   : IN std_logic;          y_control  : IN std_logic_vector(9 downto 0);          video_on   : IN std_logic;                    rgb        : OUT std_logic_vector(2 downto 0) ); END COMPONENT;

COMPONENT sync_mod PORT( i_clk       : IN std_logic;          reset      : IN std_logic;          start      : IN std_logic;                    y_control  : OUT std_logic_vector(9 downto 0);          x_control  : OUT std_logic_vector(9 downto 0);          h_s        : OUT std_logic;          v_s        : OUT std_logic;          video_on   : OUT std_logic ); END COMPONENT;

signal x,y:std_logic_vector(9 downto 0); signal video:std_logic; signal i_clk  : std_logic;

begin

Inst_DCM32to50: DCM32to50 PORT MAP(		CLKIN_IN => clk,		CLKFX_OUT => i_clk,		CLKIN_IBUFG_OUT => open,		CLK0_OUT => open	);

U1: img_gen PORT MAP( i_clk =>i_clk, x_control => x, button_l =>not button_l  , button_r => not button_r, y_control => y,                        video_on =>video , rgb => rgb );

U2: sync_mod PORT MAP( i_clk => i_clk, reset => reset, start => start, y_control => y, x_control =>x, h_s => h_s ,                       v_s => v_s, video_on =>video ); end Behavioral;

No 5

Pong Game Sub Module(Image Generator):

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity img_gen is	Port ( i_clk        : in  STD_LOGIC;			 x_control   : in  STD_LOGIC_VECTOR(9 downto 0);			 button_l    : in STD_LOGIC;			 button_r    : in STD_LOGIC;			 y_control   : in STD_LOGIC_VECTOR(9 downto 0);			 video_on    : in  STD_LOGIC;			 rgb         : out  STD_LOGIC_VECTOR(2 downto 0)); end img_gen;

architecture Behavioral of img_gen is

--wall constant wall_l:integer :=10;--the distance between wall and left side of screen constant wall_t:integer :=10;--the distance between wall and top side of screen constant wall_k:integer :=10;--wall thickness signal wall_on:std_logic; signal rgb_wall:std_logic_vector(2 downto 0); --bar signal  bar_l,bar_l_next:integer :=100; --the distance between bar and left side of screen constant bar_t:integer :=420;--the distance between bar and top side of screen constant bar_k:integer :=10;--bar thickness constant bar_w:integer:=120;--bar width constant bar_v:integer:=10;--velocity of the bar signal bar_on:std_logic; signal rgb_bar:std_logic_vector(2 downto 0); --ball signal ball_l,ball_l_next:integer :=100;--the distance between ball and left side of screen signal ball_t,ball_t_next:integer :=100; --the distance between ball and top side of screen constant ball_w:integer :=20;--ball Height constant ball_u:integer :=20;--ball width constant x_v,y_v:integer:=3;-- horizontal and vertical speeds of the ball signal ball_on:std_logic; signal rgb_ball:std_logic_vector(2 downto 0); --refreshing(1/60) signal refresh_reg,refresh_next:integer; constant refresh_constant:integer:=830000; signal refresh_tick:std_logic; --ball animation signal xv_reg,xv_next:integer:=3;--variable of the horizontal speed signal yv_reg,yv_next:integer:=3;--variable of the vertical speed --x,y pixel cursor signal x,y:integer range 0 to 650; --mux signal vdbt:std_logic_vector(3 downto 0); --buffer signal rgb_reg,rgb_next:std_logic_vector(2 downto 0);

begin

--x,y pixel cursor x <=conv_integer(x_control); y <=conv_integer(y_control );

--refreshing process(i_clk) begin if i_clk'event and i_clk='1' then refresh_reg<=refresh_next; end if; end process; refresh_next<= 0 when refresh_reg= refresh_constant else refresh_reg+1; refresh_tick<= '1' when refresh_reg = 0 else '0';	--register part process(i_clk) begin if i_clk'event and i_clk='1' then ball_l<=ball_l_next; ball_t<=ball_t_next; xv_reg<=xv_next; yv_reg<=yv_next; bar_l<=bar_l_next; end if; end process;

--bar animation process(bar_l,refresh_tick,button_r,button_l) begin bar_l_next<=bar_l; if refresh_tick= '1' then if button_l='1' and bar_l > bar_v then bar_l_next<=bar_l- bar_v; elsif button_r='1' and bar_l < (639- bar_v-bar_w) then bar_l_next<=bar_l+ bar_v; end if; end if; end process;

--ball animation process(refresh_tick,ball_l,ball_t,xv_reg,yv_reg, bar_l) begin ball_l_next <=ball_l; ball_t_next <=ball_t; xv_next<=xv_reg; yv_next<=yv_reg; if refresh_tick = '1' then if ball_t> 400 and ball_l > (bar_l -ball_u) and ball_l < (bar_l +120) then --top bar'a deÄŸdiÄŸi zaman yv_next<= -y_v ; elsif ball_t< 35 then--The ball hits the wall yv_next<= y_v; end if; if ball_l < 10 then --The ball hits the left side of the screen xv_next<= x_v; elsif ball_l> 600 then xv_next<= -x_v ; --The ball hits the right side of the screen end if; ball_l_next <=ball_l +xv_reg; ball_t_next <=ball_t+yv_reg; end if; end process;

--wall object wall_on <= '1' when x > wall_l and x < (640-wall_l) and y> wall_t and y < (wall_t+ wall_k)   else '0'; 	rgb_wall<="000";--Black

--bar object bar_on <= '1' when x > bar_l and x < (bar_l+bar_w) and y> bar_t and y < (bar_t+ bar_k) else '0'; 	rgb_bar<="001";--blue

--ball object ball_on <= '1' when x > ball_l and x < (ball_l+ball_u) and y> ball_t and y < (ball_t+ ball_w) else '0'; 	rgb_ball<="010"; --Green

--buffer process(i_clk) begin if i_clk'event and i_clk='1' then rgb_reg<=rgb_next; end if; end process;

--mux vdbt<=video_on & wall_on & bar_on &ball_on; with vdbt select rgb_next <= "100"    when "1000",--Background of the screen is red rgb_wall when "1100", rgb_wall when "1101", rgb_bar  when "1010", rgb_bar  when "1011", rgb_ball when "1001", "000"    when others; --output rgb<=rgb_reg;

end Behavioral;

No 6

Pong Game Sub Module(Synchronize mode):

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity sync_mod is   Port ( i_clk : in STD_LOGIC;           reset : in STD_LOGIC;           start : in STD_LOGIC;           y_control : out STD_LOGIC_VECTOR (9 downto 0);           x_control : out STD_LOGIC_VECTOR (9 downto 0);           h_s : out STD_LOGIC;           v_s : out STD_LOGIC;           video_on : out STD_LOGIC); end sync_mod;

architecture Behavioral of sync_mod is   -- Video Parameters constant HR:integer:=640;--Horizontal Resolution constant HFP:integer:=16;--Horizontal Front Porch constant HBP:integer:=48;--Horizontal Back Porch constant HRet:integer:=96;--Horizontal retrace constant VR:integer:=480;--Vertical Resolution constant VFP:integer:=10;--Vertical Front Porch constant VBP:integer:=33;--Vertical Back Porch constant VRet:integer:=2;--Vertical Retrace --sync counter signal counter_h,counter_h_next: integer range 0 to 799; signal counter_v,counter_v_next: integer range 0 to 524; --mod 2 counter signal counter_mod2,counter_mod2_next: std_logic:='0'; --State signals signal h_end, v_end:std_logic:='0'; --Output Signals(buffer) signal hs_buffer,hs_buffer_next:std_logic:='0'; signal vs_buffer,vs_buffer_next:std_logic:='0'; --pixel counter signal x_counter, x_counter_next:integer range 0 to 900; signal y_counter, y_counter_next:integer range 0 to 900; --video_on_off signal video:std_logic; begin --i_clk register process(i_clk,reset,start) begin if reset ='1' then counter_h<=0; counter_v<=0; hs_buffer<='0'; hs_buffer<='0'; counter_mod2<='0'; elsif i_clk'event and i_clk='1' then if start='1' then counter_h<=counter_h_next; counter_v<=counter_v_next; x_counter<=x_counter_next; y_counter<=y_counter_next; hs_buffer<=hs_buffer_next; vs_buffer<=vs_buffer_next; counter_mod2<=counter_mod2_next; end if; end if; end process; --video on/off video <= '1' when (counter_v >= VBP) and (counter_v < VBP + VR) and (counter_h >=HBP) and (counter_h < HBP + HR) else '0';

--mod 2 counter counter_mod2_next<=not counter_mod2; --end of Horizontal scanning h_end<= '1' when counter_h=799 else '0';    -- end of Vertical scanning v_end<= '1' when counter_v=524 else '0';     -- Horizontal Counter process(counter_h,counter_mod2,h_end) begin counter_h_next<=counter_h; if counter_mod2= '1' then if h_end='1' then counter_h_next<=0; else counter_h_next<=counter_h+1; end if; end if; end process;

-- Vertical Counter process(counter_v,counter_mod2,h_end,v_end) begin counter_v_next <= counter_v; if counter_mod2= '1' and h_end='1' then if v_end='1' then counter_v_next<=0; else counter_v_next<=counter_v+1; end if; end if; end process;

--pixel x counter process(x_counter,counter_mod2,h_end,video) begin x_counter_next<=x_counter; if video = '1' then if counter_mod2= '1' then if x_counter= 639 then x_counter_next<=0; else x_counter_next<=x_counter + 1; end if; end if; else x_counter_next<=0; end if; end process;

--pixel y counter process(y_counter,counter_mod2,h_end,counter_v) begin y_counter_next<=y_counter; if counter_mod2= '1' and h_end='1' then if counter_v >32 and counter_v <512 then y_counter_next<=y_counter + 1; else y_counter_next<=0; end if; end if; end process;

--buffer hs_buffer_next<= '1' when counter_h < 704 else--(HBP+HGO+HFP) '0';    vs_buffer_next<='1' when counter_v < 523 else--(VBP+VGO+VFP) '0';

--outputs y_control <= conv_std_logic_vector(y_counter,10); x_control <= conv_std_logic_vector(x_counter,10); h_s<= hs_buffer; v_s<= vs_buffer; video_on<=video;

end Behavioral;

No 7

Pong Game (Constraints):

NET "clk" LOC = "P89" | IOSTANDARD = LVCMOS33 ; NET button_l LOC = "P34" | IOSTANDARD=LVTTL; NET button_r LOC = "P36" | IOSTANDARD=LVTTL; NET start LOC = "P91" | IOSTANDARD=LVTTL;

NET rgb(2) LOC = "P71" | IOSTANDARD = LVTTL; NET rgb(1) LOC = "P66" | IOSTANDARD = LVTTL; NET rgb(0) LOC = "P58" | IOSTANDARD = LVTTL;

NET "h_s" LOC = "P83" | IOSTANDARD = LVTTL; NET "v_s" LOC = "P85" | IOSTANDARD = LVTTL;

NET "i_clk" TNM_NET = i_clk; TIMESPEC TS_i_clk = PERIOD "i_clk" 31.25ns HIGH 40%;

Next Steps
1.  Add extra features such that Text to display scores and remaining life (remaining chance to play), blocks right below the top wall so when ball hit the blocks, the block break.

2.  Add Sounds when ball hit the stick or the top wall

3.  Fix some of the bugs as shown in the link: ball still bounce even though it did not hit the stick https://www.youtube.com/watch?v=5WLTa3MJTwM&feature=youtu.be

4.  Make Precise look of the ball(should be round shape), stick, wall etc.

5.  Increasing the Game level: as the level increases, the ball speed increases

6.  Once above all steps will fix then connect another Papilio to make two player game