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

📄 pinball.vhd

📁 实现了16*16点阵上的三色显示的弹球游戏
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity Pinball is
	port (	clkIn:in std_logic;
			scnClk,sysClk:buffer std_logic;
			reset:in std_logic;
			yesIn,leftIn,rightIn:in std_logic;
			lifeOut,gradeOut:out std_logic_vector(6 downto 0);
			rowScan:out std_logic_vector(0 to 15);
			rowParallel1:out std_logic_vector(15 downto 0);
			rowParallel2:out std_logic_vector(15 downto 0);
			m:buffer std_logic_vector(0 to 8);
			change0,change1:buffer integer range 0 to 8;
			newdir,dir:buffer integer range 0 to 7);
end Pinball;

architecture main of Pinball is

	component input
	port(keyIn:in std_logic;
		clk:in std_logic;
		keyOut:out std_logic);
	end component;
	
	component freqDivision
	port(clk:in std_logic;
		scanClk:out std_logic;
		systemClk:out std_logic);
	end component;
	
	component seg7dec
	port(bcdin:in integer range 0 to 9;
		segout:out std_logic_vector(6 downto 0));
	end component;
	
	component state5
	port(clk:in std_logic;
		statein5:in bit_vector(1 downto 0);
		dir:in integer range 0 to 5;
		m:in std_logic_vector(0 to 8);
		rightIn,leftIn:in std_logic;
		px:in integer range 0 to 15;
		py:in integer range 0 to 15;
		change0:out integer range 0 to 8;
		change1:out integer range 0 to 8;
		dirout:out integer range 0 to 5;
		fail:out bit;
		move:out bit_vector(1 downto 0));
	end component;
	
	constant MAX:integer:=16;			--16*16 
	subtype size is integer range 0 to 15;
	type steps is array (0 to 5) of integer range -1 to 1;
	type memory is array (0 to MAX-1) of std_logic_vector(MAX-1 downto 0);
	type romType is array (0 to 7) of memory;
	constant stepx:steps:=(1,0,-1,-1,0,1);
	constant stepy:steps:=(-1,-1,-1,1,1,1);
	constant rom:romType:=  ((("0000000000000000"),
							  ("0000011111100000"),
							  ("0000100000010000"),
							  ("0001000000001000"),
							  ("0010000000000100"),
							  ("0100000000000010"),
							  ("0100010000100010"),
							  ("0100000000000010"),
							  ("0100000000000010"),
							  ("0100000000000010"),
							  ("0100010000100010"),
							  ("0010001111000100"),
							  ("0001000000001000"),
							  ("0000100000010000"),
							  ("0000011111100000"),
							  ("0000000000000000")),
							
						     (("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0001000000001000"),
							  ("0011111001111100"),
							  ("0111111001111110"),
							  ("0011111001111100"),
							  ("0001000000001000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000")),
							
						     (("0000000000000000"),
							  ("0011111111111100"),
							  ("0001111111111000"),
							  ("0011111111111100"),
							  ("0001111111111000"),
							  ("0011111111111100"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000001111000000")),
							
					          (("0000000000000000"),
							  ("0010101010101000"),
							  ("0001111111111100"),
							  ("0011111111111000"),
							  ("0001111111111100"),
							  ("0011111111111000"),
							  ("0001010101010100"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000001111000000")),
							
						     (("0000000000000000"),
							  ("0011111111111100"),
							  ("0011000000001100"),
							  ("0011011111101100"),
							  ("0011011111101100"),
							  ("0011000000001100"),
							  ("0011111111111100"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000001110000000")),
							
						     (("0000000110000000"),
							  ("0000011001100000"),
							  ("0001110110111000"),
							  ("0011101001011100"),
							  ("0110010110100110"),
							  ("0011101111011100"),
							  ("0001110000111000"),
							  ("0000011111100000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000000000000"),
							  ("0000000110000000")),
							
						     (("0000000000000000"),--win
							  ("0010000010011100"),
							  ("0010000010001000"),
							  ("0010010010001000"),
							  ("0010010010001000"),
							  ("0011010110001000"),
							  ("0001111100001000"),
							  ("0001101100011100"),
							  ("0000000000000000"),
							  ("0000010001000000"),
							  ("0000011001000000"),
							  ("0000010101000000"),
							  ("0000010101000000"),
							  ("0000010011000000"),
							  ("0000010001000000"),
							  ("0000000000000000")),
							
						     (("0000000000000000"),--fall
							  ("0011110000010000"),
							  ("0010000000101000"),
							  ("0010000000101000"),
							  ("0011110001000100"),
							  ("0010000001000100"),
							  ("0010000001111100"),
							  ("0010000001000100"),
							  ("0000000000000000"),
							  ("0011100010000000"),
							  ("0001000010000000"),
							  ("0001000010000000"),
							  ("0001000010000000"),
							  ("0001000010000000"),
							  ("0011100011100000"),
							  ("0000000000000000")));
							
	--signal scnClk,sysClk:std_logic;
	signal px,py: size;					--define the position of the ball
	--signal newdir,dir:integer range 0 to 7;	--define the direction index of the ball
	signal life,grade:integer range 0 to 3;	--define the number of life for the players
	signal yes,left,right,anotherl,anotherr,anothery:std_logic;		--define the inputs
	signal matrix:memory;				--this is what to be show
	signal state,nextState: bit_vector(2 downto 0):="001";		--to describe the state of the system
	signal scan:std_logic_vector(0 to MAX-1);
	signal r:size:=0;
	signal rowOut1:std_logic_vector(MAX-1 downto 0);
	signal rowOut2:std_logic_vector(MAX-1 downto 0);
	--signal m:std_logic_vector(0 to 8);
	--signal change0,change1:integer range 0 to 8;
	signal move:bit_vector(1 downto 0);
	signal fail:bit;
	signal statein5:bit_vector(1 downto 0);--用于状态5中分布实现功能
	begin
		u1:input port map (yesIn,sysClk,yes);
		u2:input port map (leftIn,sysClk,left);
		u3:input port map (rightIn,sysClk,right);
		u4:freqDivision port map(clkIn,scnClk,sysClk);
		u5:seg7dec port map(grade,gradeOut);
		u6:seg7dec port map(life,lifeOut);
		core: state5 port map(sysClk,statein5,dir,m,rightIn,leftIn,px,py,change0,change1,newdir,fail,move);
		
		rowScan<=scan;
		rowParallel1<=rowOut1;
		rowParallel2<=rowOut2;
		
		process(scnClk)
			begin
				if(rising_edge(scnClk)) then
					if(r=MAX-1) then 
						scan<="1111111111111110"; 
						r<=0;
					else
						scan<=scan(MAX-1)& scan(0 to MAX-2);
						r<= r+1;
					end if;
					if(r=MAX-1)and((state="101")or(state="100")or((state="000")and(nextstate="101"))) then
						rowOut1<=not matrix(MAX-1);
						rowOut2<=not matrix(MAX-1);                  --注意修改最低一行
					else
						rowOut1<=not matrix(r);
						rowOut2<=(others => '1');
					end if;
					if(r=py)and((state="101")or(state="100")or((state="000")and(nextstate="101"))) then
						rowOut2(px)<='0';
					end if;	
				end if;
			end process;
		
		state1:process(sysClk)								--a state to show the welcome screen
			variable bool:bit;
			begin										--and initiate some signals
				if (rising_edge(sysClk)) then
					if(reset='1')then state<="001";end if;
					case state is	
					when "000" => 
						if(yes='1')then
							state<=nextState;
						end if;	
					when "001" =>
						grade<=0;
						matrix<=rom(0);
						if(yes='1') then 
							nextState<="010";
							state<="000"; 
						end if;
						
					when "010" =>			--a state for the user to set the grade of the game
						matrix<=rom(1);
						if(right='1') then
							if(grade<3) then
								grade<=grade+1;
							end if;
						end if;
						if(left='1') then 
							if(grade>0) then
								grade<=grade-1;
							end if;
						end if;
						if(yes='1') then
							state<="100";
							matrix<=rom(2+grade);
							life<=2;
						end if;
						
					when "011" =>
						if(yes='1') then
							state<=nextState;
						end if;
					
					when "100" =>						--initiate while waiting to launch
						px<=MAX/2;								--the position of the ball
						py<=MAX-2;
						dir<=1;
						matrix(MAX-1)<=rom(2+grade)(MAX-1);
						if(yes='1') then
							state<="101";
							statein5<="10";
						end if;
						
					when "110" =>
						matrix<=rom(6);
						if(yes='1') then
							grade<=grade+1;
							life<=2;
							matrix<=rom(3+grade);
							state<="100";
						end if;
						
					when "111" =>
						matrix<=rom(7);
						if(yes='1') then
							life<=2;
							matrix<=rom(2+grade);
							state<="100";
						end if;
						
					when "101" =>
						case statein5 is
						when "10" =>
							if(yes='1') then anothery<='1'; end if;
							if(rightIn='0') then anotherr<='0'; end if;
							if(leftIn='0') then anotherl<='0'; end if;
							
						
							--Test whether have finish the assignment
							bool:='1';
							loop1:
							for i in 0 to MAX/2 loop
								if(matrix(i)/=x"0") then
									bool:='0';
								end if;
							end loop loop1;
							if(bool='1') then
								state<="110";
							end if;
							--test whether have finish the assignment
							
						
							if(px=MAX-1)or(py=0)then m(0)<='0'; else m(0)<=matrix(py-1)(px+1); end if;
							if(py=0)then m(1)<='0';  else m(1)<=matrix(py-1)(px); end if;
							if(px=0) or (py=0)then m(2)<='0';  else m(2)<=matrix(py-1)(px-1); end if;
							if(px=MAX-1)then m(3)<='0';  else m(3)<=matrix(py)(px+1); end if;
							if(px=0)then m(5)<='0';  else m(5)<=matrix(py)(px-1); end if;
							if(px=MAX-1)or(py=MAX-1)then m(6)<='0';  else m(6)<=matrix(py+1)(px+1); end if;
							if(py=MAX-1)then m(7)<='0';  else m(7)<=matrix(py+1)(px); end if;
							if(px=0) or (py=MAX-1)then m(8)<='0';  else m(8)<=matrix(py+1)(px-1); end if;
							statein5<="00";
							
						when "00" =>
							if(yes='1') then anothery<='1'; end if;
							if(rightIn='0') then anotherr<='0'; end if;
							if(leftIn='0') then anotherl<='0'; end if;
							
							case change0 is
							when 0 => matrix(py-1)(px+1)<='0';
							when 1 => matrix(py-1)(px)<='0';
							when 2 => matrix(py-1)(px-1)<='0';
							when 3 => matrix(py)(px+1)<='0';
							when 4 => matrix(py)(px)<='0';
							when 5 => matrix(py)(px-1)<='0';
							when 6 => matrix(py+1)(px+1)<='0';
							when 7 => matrix(py+1)(px)<='0';
							when 8 => matrix(py+1)(px-1)<='0';
							end case;
							
							case change1 is
							when 0 => matrix(py-1)(px+1)<='0';
							when 1 => matrix(py-1)(px)<='0';
							when 2 => matrix(py-1)(px-1)<='0';
							when 3 => matrix(py)(px+1)<='0';
							when 4 => matrix(py)(px)<='0';
							when 5 => matrix(py)(px-1)<='0';
							when 6 => matrix(py+1)(px+1)<='0';
							when 7 => matrix(py+1)(px)<='0';
							when 8 => matrix(py+1)(px-1)<='0';
							end case;
							
							dir<=newdir;
							statein5<="01";
								
						when "01" =>
							if((rightIn='0')or(anotherr='0'))and(matrix(MAX-1)(0)='0')then
								matrix(MAX-1)<=matrix(MAX-1)(0)&matrix(MAX-1)(MAX-1 downto 1);
							end if;
							
							if((leftIn='0')or(anotherl='0'))and (matrix(MAX-1)(MAX-1)='0')then
								matrix(MAX-1)<=matrix(MAX-1)(MAX-2 downto 0)&matrix(MAX-1)(MAX-1);
							end if;
							
							if(yes='1')or(anothery='1')then
								nextState<="101";
								state<="000";
							end if;
							anothery<='0';
							anotherr<='1';
							anotherl<='1';
										
							px<=px+stepx(dir);
							py<=py+stepy(dir);
							
							if(fail='1')then
							if(life>0) then
								life<=life-1;
								state<="100";
							else 
								state<="111";	--fail the game
							end if;
							end if;
							
							if(move="01") then
								if (px>1)then px<=px+stepx(dir)-1; end if;
							elsif(move="10") then
								if (px<14) then px<=px+stepx(dir)+1; end if;
							end if;
							statein5<="10";
						when "11" => null;
						end case;
						
					end case;
				end if;
			end process;
	end main;

⌨️ 快捷键说明

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