📄 ballgame.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ballgame is
port(start,reset,left,right,clk:in std_logic;
r,g,b,hs,vs:out std_logic);
end ballgame;
architecture game of ballgame is
-------------------------------------------------------------------------------------------------------
constant board_x0:std_logic_vector(9 downto 0):="0001101100";
constant board_y0:std_logic_vector(9 downto 0):="0110101110"; --board's position
constant pl:integer:=40;
constant ph:integer:=10; --board's lenth and high
-------------------------------------------------------------------------------------------------------
constant ballx0:std_logic_vector(9 downto 0):="0001101100";
constant bally0:std_logic_vector(9 downto 0):="0110011110"; --ball's position
constant ballc:integer:=16; --ball's diameter
type bitmap is array(15 downto 0,15 downto 0) of std_logic;
constant ballmap:bitmap :=("0000000000000000",
"0000011111100000",
"0001111111111000",
"0011111100011100",
"0011111111001100",
"0111111111100110",
"0111111111100110",
"0111111111100110",
"0111111111100110",
"0111111111111110",
"0111111111111110",
"0011111111111100",
"0011111111111100",
"0001111111111000",
"0000011111100000",
"0000000000000000"); --ball's bitmap
-------------------------------------------------------------------------------------------------------
constant brickx0:std_logic_vector(9 downto 0):="0001011001";
constant bricky0:std_logic_vector(9 downto 0):="0001100100"; --brick1's position
constant brickx1:std_logic_vector(9 downto 0):="0100001110";
constant bricky1:std_logic_vector(9 downto 0):="0001100100"; --brick2's position
constant brickx2:std_logic_vector(9 downto 0):="0111000011";
constant bricky2:std_logic_vector(9 downto 0):="0001100100"; --brick3's position
constant brickl:integer:=100;
constant brickh:integer:=35; --brick's lenth and high
-------------------------------------------------------------------------------------------------------
constant board_step:integer:=2; --board's move step
-------------------------------------------------------------------------------------------------------
signal hloc,vloc:std_logic_vector(9 downto 0); --vga h&s location
signal hsyncb,vsyncb:std_logic; --hs & vs
signal ballx,bally,board_x,board_y:std_logic_vector(9 downto 0); --ball & board's position
signal ball_cnt_x,ball_cnt_y:integer range 0 to 15; --ball's bitmap x&y
signal ball_color,border_color,brick_color,brick_color_x,brick_color_y:std_logic;
signal board_color_x,board_color_y,board_color:std_logic; --color flag
signal border_up,border_down,border_left,border_right:std_logic; --border color check
signal update,enable:std_logic;
signal sysclk:std_logic; --clock 25m
signal i,j:integer range -1 to 1; --ball's move step
-------------------------------------------------------------------------------------------------------
component vga_sig --vga_sig 25m
port(clock: in std_logic;reset:in std_logic;
hsyncb,vsyncb:out std_logic;
enable:out std_logic;
xaddr,yaddr:out std_logic_vector(9 downto 0));
end component;
-------------------------------------------------------------------------------------------------------
function intval(val:in std_logic_vector) return integer is --Hex to Dec function
variable valv:std_logic_vector(val'length-1 downto 0);
variable sum:integer:=0;
begin
valv:=val;
for i in valv'low to valv'high loop
if valv(i)='1' then
sum:=sum+(2**i);
else null;
end if;
end loop;
return sum;
end intval;
-------------------------------------------------------------------------------------------------------
begin
-------------------------------------------------------------------------------------------------------
uut_a:vga_sig port map(clock=>sysclk,reset=>reset,
hsyncb=>hsyncb,vsyncb=>vsyncb,
enable=>enable,xaddr=>hloc,yaddr=>vloc); --component vga_sig
-------------------------------------------------------------------------------------------------------
divclk: process(clk,reset) --divide clock from 50m to 25m
begin
if reset='1' then
sysclk<='0';
elsif clk'event and clk='1' then
sysclk<=not sysclk;
end if;
end process;
-------------------------------------------------------------------------------------------------------
ball_cnt_x<=intval(hloc-ballx) when hloc>=ballx and hloc<=ballx+ballc else 0;
ball_cnt_y<=intval(vloc-bally) when vloc>=bally and vloc<=bally+ballc else 0;
ball_color<=ballmap(ball_cnt_x,ball_cnt_y); --read ball's bitmap
brick_color_x <='1' when (hloc>=brickx0 and hloc<=brickx0+brickl)
or (hloc>=brickx1 and hloc<=brickx1+brickl)
or (hloc>=brickx2 and hloc<=brickx2+brickl)
else '0';
brick_color_y <='1' when (vloc>=bricky0 and vloc<=bricky0+brickh)
else '0';
brick_color <= brick_color_x and brick_color_y; --brick's color
board_color_x<='1' when hloc>=board_x and hloc<=board_x+pl else '0';
board_color_y<='1' when vloc>=board_y and vloc<=board_y+ph else '0';
board_color<=board_color_x and board_color_y; --board's color
border_up <='1' when hloc(9 downto 3)="0000000" else '0';
border_down <='1' when hloc(9 downto 3)="1001111" else '0';
border_left <='1' when vloc(9 downto 3)="0000000" else '0';
border_right <='1' when vloc(9 downto 3)="0111011" else '0';
border_color<=border_up or border_down or border_left or border_right; --border's color
-------------------------------------------------------------------------------------------------------
hs<=hsyncb;
vs<=vsyncb;
r<=enable and (border_color or board_color or brick_color);
g<=enable and (border_color or board_color or ball_color);
b<=enable and (border_color or board_color or ball_color); --output vga signal
-------------------------------------------------------------------------------------------------------
update<='1' when hloc="00000000001" and vloc="0000000001" else '0'; --screen update flag
-------------------------------------------------------------------------------------------------------
ball_collision:process(sysclk,reset,start) --ball collision
begin
if reset='1' then
j<=0;
i<=0;
elsif sysclk'event and sysclk='1' then
if start='1' then
i<=1;
j<=-1;
elsif ballx="0000000111"
or (ballx=board_x+pl and bally<board_y+ph and bally>board_y-ballc)
or (ballx=brickx0+brickl and bally<bricky0+brickh and bally>bricky0-ballc)
or (ballx=brickx1+brickl and bally<bricky0+brickh and bally>bricky0-ballc)
or (ballx=brickx2+brickl and bally<bricky0+brickh and bally>bricky0-ballc)
then
i<=1;
elsif ballx="1001101000"
or (ballx=board_x-ballc and bally<board_y+ph and bally>board_y-ballc)
or (ballx=brickx0-ballc and bally<bricky0+brickh and bally>bricky0-ballc)
or (ballx=brickx1-ballc and bally<bricky0+brickh and bally>bricky0-ballc)
or (ballx=brickx2-ballc and bally<bricky0+brickh and bally>bricky0-ballc)
then
i<=-1;
elsif bally="0000000111"
or (bally=bricky0+brickh
and ((ballx>=brickx0-ballc and ballx<=brickx0+brickl)
or (ballx>=brickx1-ballc and ballx<=brickx1+brickl)
or (ballx>=brickx2-ballc and ballx<=brickx2+brickl)))
then
j<=1;
elsif (bally=board_y0-ballc and ballx>=board_x-ballc
and ballx<=board_x+pl and (i=1 or i=-1) )
or (bally=bricky0-ballc
and ((ballx>=brickx0-ballc and ballx<=brickx0+brickl)
or (ballx>=brickx1-ballc and ballx<=brickx1+brickl)
or (ballx>=brickx2-ballc and ballx<=brickx2+brickl)))
then
j<=-1;
elsif bally>="0111011000" then
i<=0;
j<=0;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------------------
board_control:process(sysclk,reset) --control
begin
if reset='1' then
ballx<=ballx0;
bally<=bally0;
board_x<=board_x0;
board_y<=board_y0;
elsif sysclk'event and sysclk='1' then
if start='1' then
board_x<=board_x0;
board_y<=board_y0;
ballx<=ballx0;
bally<=bally0;
end if;
if update='1' then
if left='1' and board_x>"0000000111" then
board_x<=board_x-board_step;
end if;
if right='1' and board_x<"1001010000" then
board_x<=board_x+board_step;
end if;
ballx<=ballx+i;
bally<=bally+j;
end if;
end if;
end process;
-------------------------------------------------------------------------------------------------------
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -