📄 pinball.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 + -