⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pong_cntrl.vhd

📁 Pong is a mixed schematic, VHDL, Verilog project featuring the PS2 and VGA monitor connections of
💻 VHD
字号:
------------------------------------------------------------------

-- Copyright (c) 1995-2004 Xilinx, Inc.

-- All Right Reserved.

------------------------------------------------------------------

--   ____  ____ 

--  /   /\/   / 

-- /___/  \  /    Vendor: Xilinx 

-- \   \   \/     Version : 7.1i

--  \   \         Application : 

--  /   /         Filename : pong_cntrl.vhd

-- /___/   /\     Timestamp : 10/27/2004 11:01:05

-- \   \  /  \ 

--  \___\/\___\ 

--

-- This module displays the title, PONG, on the four seven segment LEDs of the Spartan3 Demo Board
--   

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

entity cntrl is Port (
	CLK : 	in std_logic;
	RESET: 	in std_logic;
	left_dir:		in std_logic_vector(1 downto 0);
	right_dir:	in std_logic_vector(1 downto 0);
	SERVE:	in std_logic;
--	WRITE: 	out std_logic;
	HSYNCH:  out std_logic;
	VSYNCH:	out std_logic;
	COLOR:	out std_logic_vector( 1 downto 0 )
	);
end cntrl;

architecture static_display of cntrl is

component vgacore is Port ( 
	CLK : 	in std_logic;
	RESET: 	in std_logic;
	HSYNCH:  out std_logic;
	VSYNCH:	out std_logic;
	VBLANK: 	out std_logic;
	HBLANK: 	out std_logic;
	LINE: 	out std_logic_vector(5 downto 0);
	PIXEL: 	out std_logic_vector(6 downto 0)
	);
end component;

component testram is Port ( 
	clk: 		in std_logic;
	address: in std_logic_vector( 6 downto 0 );
	data: 	out std_logic_vector( 3 downto 0 )
	);
end component;

signal	number_data: std_logic_vector( 3 downto 0 );
signal   number_address: std_logic_vector( 6 downto 0 );
signal	enable: std_logic;

signal	LINE:	 	std_logic_vector( 5 downto 0 );
signal	PIXEL: 	std_logic_vector( 6 downto 0 );
signal	VBLANK: 	std_logic;
signal	HBLANK: 	std_logic;

signal	next_HSYNCH:	std_logic;
signal	next_VSYNCH:	std_logic;
signal	VCLK: std_logic;
signal   next_COLOR: 	std_logic_vector( 1 downto 0 );

constant ball_height: integer := 1;
constant ball_width: integer := 2;

constant paddle_height: integer := 8;
constant paddle_heighta: integer := 4;	-- defines top 1/4 of paddle
constant paddle_heightb: integer := 6;	-- defines middle 1/2 of paddle
constant paddle_heightc: integer := 8;	-- defines bottom 1/4 of paddle
constant paddle_width: integer := 2;	-- defines width of paddle

constant wall_height: integer := 1;
constant wall_top: integer := 9;
constant wall_bottom: integer := 58;
constant right_wall: integer := 77;
constant left_wall: integer := 2;

constant right_score_x: integer:= 64;
constant right_score_y: integer:= 4;
constant left_score_x: integer:= 16;
constant left_score_y: integer:= 4;
constant score_width: integer := 4;
constant score_height: integer := 4;

constant right_x: integer := 72;
constant left_x: integer := 8;

signal ball_xdir, ball_ydir: std_logic;
signal ball_x: integer range 0 to 80;
signal ball_y: integer range 0 to 60 := 30;
signal ball_yrate: integer range 0 to 3;

signal left_y: std_logic_vector(5 downto 0);
signal right_y: std_logic_vector(5 downto 0);
signal nextleft_y: std_logic_vector(5 downto 0);
signal nextright_y: std_logic_vector(5 downto 0);

signal delay: std_logic_vector(2 downto 0);		-- Delay vector is used to slow down the speed of the ball

signal lscore, rscore: integer range 0 to 9 := 0;

begin


-- VGA CORE Instantiation
VGA1: vgacore port map (
	CLK => CLK,
	RESET=> RESET,
	HSYNCH=> next_HSYNCH,
	VSYNCH=> next_VSYNCH,
	VBLANK=> VBLANK,
	HBLANK=> HBLANK,
	LINE=> LINE,
	PIXEL=> PIXEL
	);

-- Character generator memory instantiation
CGEN1: testram port map ( 
	clk		=> clk,
	address	=> number_address ,
	data		=> number_data
	);

-- Pipeline the control signals to account for Game Delay
pipeline: process ( clk, pixel, line)
begin
	if ( clk = '1' and clk'event) then
		VSYNCH <= next_VSYNCH;
		VCLK <= next_VSYNCH;
		HSYNCH <= next_HSYNCH;
--		WRITE <= VBLANK;
		if ( HBLANK = '1' ) then
			color <= "00";
		else
			color <= next_COLOR;
		end if;
	end if;
end process;

-- Code to display the ball and paddles
display: process (clk, line, pixel)
begin

	number_address(2 downto 0) <= line(2 downto 0);
	
	-- Display Background Color
	next_COLOR <= "00";

	-- Display the playing field top bar
		if ( line = wall_top  ) then
				next_COLOR <= "11";
		end if;

	-- Display the playing field bottom bar
		if ( line = wall_bottom ) then
				next_COLOR <= "11";
		end if;

	-- Display the left Paddle:
		if (( pixel = left_x -1)  ) then
			if ( (line >= left_y ) and (line <= (left_y + paddle_height)) ) then
				next_COLOR <= "11";
			end if;
		end if;
		
	-- Display the right Paddle:
		if ( pixel = right_x + 1 ) then
			if ( (line >= right_y) and (line <= (right_y + paddle_height)) ) then
				next_COLOR <= "11";
			end if;
		end if;

	-- Display the Ball:
		if ( (pixel = ball_x) ) then
			if ( line = ball_y ) then
				next_COLOR <= "11";
			end if;
		end if;
	
	-- Display the Left Score ( Using Std_Logic_Vectors instead of integers )
		if ( (pixel >= "0001000" ) and ( pixel <= "0001011" ) ) then
			if ( (line >= "000000" ) and (line <= "000111" ) ) then
				number_address(6 downto 3) <= CONV_STD_LOGIC_VECTOR(lscore,4); 

 			   case pixel( 1 downto 0 ) is
					when "00" =>
						if ( number_data(3) = '1' ) then
							next_COLOR <= "10";
						end if;
					when "01" =>
						if ( number_data(2) = '1' ) then
							next_COLOR <= "10";
						end if;
					when "10" =>
						if ( number_data(1) = '1' ) then
							next_COLOR <= "10";
						end if;
					when "11" =>
						if ( number_data(0) = '1' ) then
							next_COLOR <= "10";
						end if;
					when others =>
						next_COLOR <= "00";
				end case;				
			end if;
		end if;

	-- Display the Right Score
		if ( (pixel >= "01000000" ) and ( pixel <= "01000011" ) ) then
			if ( (line >= "000000" ) and (line <= "000111" ) ) then
				number_address(6 downto 3) <= CONV_STD_LOGIC_VECTOR(rscore,4); 
 			   case pixel(1 downto 0) is
					when "00" =>
						if (number_data(3) = '1') then
							next_COLOR <= "10";
						end if;
					when "01" =>
						if (number_data(2) = '1') then
							next_COLOR <= "10";
						end if;
					when "10" =>
						if (number_data(1) = '1') then
							next_COLOR <= "10";
						end if;
					when "11" =>
						if (number_data(0) = '1') then
							next_COLOR <= "10";
						end if;
					when others =>
						next_COLOR <= "00";
				end case;				
			end if;
		end if;

end process;

-- Game play logic
moving_paddles: process (VCLK, reset)
  begin
	if (reset = '1') then
		left_y <= "001001";
		right_y <= "001001";
		nextleft_y <= "001001";
		nextright_y <= "001001";
	elsif (VCLK = '1' and VCLK'event) then
 		
		if (left_dir = "10") then
			nextleft_y <= nextleft_y + 1;	 -- move up
		elsif (left_dir = "01") then
			nextleft_y <= nextleft_y - 1;	 -- move down
		else
			nextleft_y <= nextleft_y;	 	 -- don't move
		end if;
		
		if (right_dir = "10") then
			nextright_y <= nextright_y + 1;	-- move up
		elsif (right_dir = "01") then		
			nextright_y <= nextright_y - 1;	-- move down
		else 											
			nextright_y <= nextright_y;		-- don't move
		end if;
		
		if (nextleft_y < 9) then 
			left_y <= "001001";				   -- stop at top of screen
			nextleft_y <= "001001";		 	 
		elsif(nextleft_y > 50) then		 
			left_y <= "110010";				   -- stop at bottom of screen
			nextleft_y <= "110010";
		else
			left_y <= nextleft_y;
		end if;

		if ( nextright_y < 9 ) then
			right_y <= "001001";					-- stop at top of screen
			nextright_y <= "001001";
		elsif( nextright_y > 50 ) then
			right_y <= "110010";					-- stop at bottom of screen
			nextright_y <= "110010";
		else
			right_y <= nextright_y;
		end if;
	 end if;
end process;

moving_ball: process (VCLK, ball_xdir, ball_ydir, ball_x, ball_y, reset)
begin
 
	if (reset = '1') then
		ball_x <= left_wall;
		ball_y <= 32;
		ball_yrate <= 1;
		lscore <= 0;
		rscore <= 0;
		enable <= '0';
		delay <= "000";
	elsif (VCLK = '1' and VCLK'event) then
	   if (delay >= "100") then	--This value may be increased or decreased to adjust the speed of the ball
		  delay <= "000";
			if (SERVE = '1') then
				if (enable = '0' ) then
					ball_yrate <= 0;
				  	ball_y <= 16;
				end if;
				ball_y <= 32;
				enable <= '1';
			end if;

			if (ball_xdir = '1') then				 -- Horizontal Movement ( 1 = right )
				if (enable = '1') then
					ball_x <= ball_x + 1;
				end if;

				-- check for hit on upper 1/4 of right paddle
				if  ((ball_x = right_x) and ( ball_y >= right_y - ball_height ) and ( ball_y < right_y + paddle_heighta) ) then
					ball_xdir <= '0';
					-- if ball is going down
					if ( ball_ydir = '0' ) then 
						if ( ball_yrate > 0 ) then
							ball_yrate <= ball_yrate - 1;
						else
							ball_yrate <= 1;
							ball_ydir <= '1';
						end if;

					-- if ball is going up
				  	else
						if ( ball_yrate < 2 ) then
							ball_yrate <= ball_yrate + 1;
						else
							ball_yrate <= 2;
						end if;
					end if;

				elsif  ((ball_x = right_x) and ( ball_y >= right_y + paddle_heighta) and ( ball_y < right_y + paddle_heightb) ) then
					ball_xdir <= '0';

				-- check for hit on lower half of right paddle
				elsif  ((ball_x = right_x) and ( ball_y >= right_y + paddle_heightb) and ( ball_y <= right_y + paddle_heightc) ) then
						ball_xdir <= '0';
					-- if ball is going down
					if (ball_ydir = '0') then 
						if (ball_yrate < 2) then
							ball_yrate <= ball_yrate + 1;
						else
							ball_yrate <= 2;
						end if;
					-- if ball is going up
				  	else
						if (ball_yrate > 0) then
							ball_yrate <= ball_yrate - 1;
						else
							ball_ydir <= '0';
							ball_yrate <= 1;
						end if;
					end if;
					
				-- Score for left team
				else
					if (ball_x = right_wall) then			
						ball_xdir <= '0';	
						if (enable = '1') then
							if (lscore = 9) then
								lscore <= 0;
							else 
								lscore <= lscore + 1;
							end if;
						end if;
						enable <= '0';
					end if;
				end if;

			-- Ball going left
			else 
				-- in middle of playing field
				if ( enable = '1' ) then
					ball_x <= ball_x - 1;
				end if;

				if ( ball_x = left_x ) then

				-- upper portion of paddle
					if (( ball_y >= left_y ) and ( ball_y < left_y + paddle_heighta )) then
						ball_xdir <= '1';
						-- if ball is going down
						if ( ball_ydir = '0' ) then 
							if ( ball_yrate > 0 ) then
								ball_yrate <= ball_yrate - 1;
							else
								ball_ydir <= '1';
								ball_yrate <= 1;
							end if;
						-- if ball is going up
					  	else
							if ( ball_yrate < 2 ) then
								ball_yrate <= ball_yrate + 1;
							else
								ball_yrate <= 2;
							end if;
						end if;

					-- lower portion of paddle
					elsif  ( ( ball_y >= left_y + paddle_heightb) and ( ball_y <= left_y + paddle_heightc) ) then
						ball_xdir <= '1';
						-- if ball is going down
						if ( ball_ydir = '0' ) then 
							if ( ball_yrate < 2 ) then
								ball_yrate <= ball_yrate + 1;
							else
								ball_yrate <= 2;
							end if;
						-- if ball is going up
					  	else
							if ( ball_yrate > 0 ) then
								ball_yrate <= ball_yrate - 1;
							else
								ball_ydir <= '0';
								ball_yrate <= 1;
							end if;
						end if;				
					elsif (( ball_y >= left_y + paddle_heighta) and ( ball_y < left_y + paddle_heightb)) then
						ball_xdir <= '1';				
					end if;

				-- Score for right team
				else
					if ( ball_x = left_wall ) then	
						ball_xdir <= '1';		
						if ( enable = '1' ) then
							if ( rscore = 9 ) then
								rscore <= 0;
							else
								rscore <= rscore + 1;
							end if;
						end if;
					enable <= '0';
					end if;
				end if;
			end if;

			-- Vertical Movement ( 1 = up )
			if ( ball_ydir = '1' ) then
				if (ball_y <= wall_top) then
					ball_ydir <= '0';
				else
					ball_y <= ball_y - ball_yrate;
				end if;
			else 
				if (ball_y >= wall_bottom) then
					ball_ydir <= '1';
				else
					ball_y <= ball_y + ball_yrate;
				end if;
			end if;
	  else 
	  		delay <= delay + '1';
			ball_y <= ball_y;
			ball_yrate <= ball_yrate;
			ball_x <= ball_x;
			ball_ydir <= ball_ydir;
			ball_xdir <= ball_xdir;
	  end if;
  end if;
end process;

end static_display;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -