📄 top.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity VGA is
port
(
kb_data : IN std_logic;--p194
kb_clk : IN std_logic; --p202
ori_clkin : in std_logic ; --外部时钟输入(32MHz)
-- push_reset : in std_logic; --系统重新启动
-- up : in std_logic; --向上移动按键
-- down : in std_logic; --向下移动按键
-- left : in std_logic; --向左移动按键
-- right : in std_logic; --向右移动按键
-- start : in std_logic;
led : out std_logic_vector(6 downto 0); --秒计时个位七段译码输出
led2 : out std_logic_vector(6 downto 0); --秒计时十位七段译码输出
led3 : out std_logic_vector(6 downto 0); --分计时个位七段译码输出
led4 : out std_logic_vector(6 downto 0); --分计时十位七段译码输出
hsync : inout std_logic; --VGA行频
vsync : out std_logic; --VGA场频
rgbout : out std_logic_vector(2 downto 0) --VGA色信号
);
end VGA;
architecture VGA_arch of VGA is
signal ori_clk : std_logic; --原始输入时钟
signal count : std_logic_vector(3 downto 0); --显示器分频计数
signal count_sec : std_logic_vector(26 downto 0);--分频计数
signal clk : std_logic; --显示器扫描时钟
signal clk_for : std_logic; --按键捕获时钟
signal hcnt : std_logic_vector(8 downto 0); --显示器纵坐标
signal vcnt : std_logic_vector(9 downto 0); --显示器横坐标
signal rgb : std_logic_vector(2 downto 0) := "000"; --显示器输出颜色
signal win_sign : std_logic:='0'; --胜利标志
signal life_sign : std_logic:='0'; --生命标志
signal rst : std_logic; --重新开始游戏
signal dout : std_logic_vector(3 downto 0); --计数器秒个位
signal dout2 : std_logic_vector(3 downto 0); --计数器秒十位
signal dout3 : std_logic_vector(3 downto 0); --计数器分个位
signal dout4 : std_logic_vector(3 downto 0); --计数器分十位
signal clkin : std_logic; --计数器秒个位时钟
signal clkin2 : std_logic; --计数器分个位时钟
signal clk6 : std_logic; --计数器秒十位时钟
signal clk62 : std_logic; --计数器分十位时钟
signal box1_x : std_logic_vector(7 downto 0) := "00011111"; --BOX1位置
signal box1_y : std_logic_vector(8 downto 0) :="011000001";
signal box2_x : std_logic_vector(7 downto 0) := "00101110"; --BOX2位置
signal box2_y : std_logic_vector(8 downto 0) :="100000001";
signal boy_x : std_logic_vector(7 downto 0) := "00111101";
signal boy_y : std_logic_vector(8 downto 0) :="001000001";
signal brick1_x : std_logic_vector(7 downto 0) := "00111101"; --BRICK1位置
signal brick1_y : std_logic_vector(8 downto 0) :="010000001";
signal brick2_x : std_logic_vector(7 downto 0) := "00101110"; --BRICK2位置
signal brick2_y : std_logic_vector(8 downto 0) :="011000001";
signal brick3_x : std_logic_vector(7 downto 0) := "00111101"; --BRICK3位置
signal brick3_y : std_logic_vector(8 downto 0) :="011000001";
signal pos1_x : std_logic_vector(7 downto 0) := "00010000"; --POS1位置
signal pos1_y : std_logic_vector(8 downto 0) :="101000001";
signal pos2_x : std_logic_vector(7 downto 0) := "00101110"; --POS2位置
signal pos2_y : std_logic_vector(8 downto 0) :="101000001";
signal data_in : std_logic_vector(7 downto 0);
signal data_ready : std_logic;
signal start : std_logic;
signal push_reset : std_logic;
constant clbrick : std_logic_vector(2 downto 0) :="100"; --RED OK
constant clpos : std_logic_vector(2 downto 0) :="010"; --GREEN OK
constant clboy : std_logic_vector(2 downto 0) :="001"; --BLUE
constant clbox : std_logic_vector(2 downto 0) :="110"; --YELLOW
constant clback : std_logic_vector(2 downto 0) :="000"; --SKY
constant clgrid : std_logic_vector(2 downto 0) :="101"; --pink-purple
constant clin : std_logic_vector(2 downto 0) :="011"; --pink-blue
component cnt10 --系统10进制计数器
port( Q : out std_logic_vector(3 downto 0);
clk : in std_logic;
aclr : in std_logic
);
end component;
component cnt6 --系统6进制计数器
port( Q : out std_logic_vector(2 downto 0);
clk : in std_logic;
aclr : in std_logic
);
end component;
component hex2led --七段译码器子模块
port( hex : in std_logic_vector(3 downto 0);
led : out std_logic_vector(6 downto 0));
end component;
component keyboard
port(
kb_data : in std_logic; --数据信号
kb_clk : in std_logic; --时钟信号
clk : in std_logic; --32M时钟
reset : in std_logic; --重启
data : buffer std_logic_vector(7 downto 0); --从键盘读入的八位串行数据
data_ready : out std_logic --数据有效信号
-- rs : out std_logic_vector(6 downto 0) --数码管显示(检验用)
);
end component;
begin
U1: cnt10 --映射计数器秒个位
port map(Q=>dout,
clk=>clkin,
aclr=>rst);
U2: cnt6 --映射计数器秒十位
port map(Q=>dout2(2 downto 0),
clk=>clk6,
aclr=>rst);
U3: cnt10 --映射计数器分个位
port map(Q=>dout3,
clk=>clkin2,
aclr=>rst);
U4: cnt6 --映射计数器分十位
port map(Q=>dout4(2 downto 0),
clk=>clk62,
aclr=>rst);
U5: hex2led --映射七段译码器秒个位
port map(hex=>dout,
led=>led);
U6: hex2led --映射七段译码器秒十位
port map(hex=>dout2,
led=>led2);
U7: hex2led --映射七段译码器分个位
port map(hex=>dout3,
led=>led3);
U8: hex2led --映射七段译码器分十位
port map(hex=>dout4,
led=>led4);
U9: keyboard
port map(
kb_data => kb_data,
kb_clk => kb_clk,
clk => clk,
reset =>push_reset,
data => data_in,
data_ready =>data_ready
-- rs => rs
);
dout2(3)<='0'; --6进制计数器高位清零
dout4(3)<='0'; --6进制计数器高位清零
rst<=not (start and push_reset); --重启键电平转换
process(clk)
begin
if data_ready='1' then
case data_in is
when X"5A" => --Enter start
start<='0';
when X"2D" => --R(eset)
push_reset<='0';
when others=>
null;
end case;
else
start<='1';
push_reset<='1';
end if;
end process;
process(clk) --用户对BOY位置控制权开关
variable num : integer range 0 to 1000000000;
begin
if life_sign='0' then --胜利或失败时用户失去对青蛙的操控权
clkin<='0';
elsif clk'event and clk ='1' then --用户可以操控青蛙时对按键处理的时钟分频
if num=2000000 then num:=0; clkin<=not clkin;
else num:=num+1;
end if;
end if;
end process;
process(dout) --计数器秒个位进位指示(秒十位的时钟)
begin
if dout=9 then clk6<='0';
else clk6<='1';
end if;
end process;
process(dout2) --计数器秒十位进位指示(分个位的时钟)
begin
if dout2=5 then clkin2<='0';
else clkin2<='1';
end if;
end process;
process(dout3) --计数器分个位进位指示(分十位的时钟)
begin
if dout3=9 then clk62<='0';
else clk62<='1';
end if;
end process;
process(ori_clk,count) --对原始时钟进行分频,得到场刷新信号
begin
if(ori_clk'event and ori_clk='0') then
count<=count+1;
count_sec<=count_sec+1;
end if;
if(count=4) then
clk<=not(clk);
count<="0000";
end if;
end process;
clk_for<=count_sec(21);--得到按键刷新脉冲
rgbout(2)<=rgb(2);
rgbout(1)<=rgb(1);
rgbout(0)<=rgb(0);
process (hsync,push_reset)--场频刷新
begin
if push_reset = '0' then
vsync<='1';
vcnt<="0000000000";
elsif hsync'event and hsync='1' then
if vcnt<526 then
vcnt<=vcnt+1;
else
vcnt<="0000000000";
end if;
if vcnt>=524 and vcnt<526 then--场扫描逆程
vsync<='0';
else
vsync<='1'; --场扫描正程
end if;
end if;
end process;
process (clk, push_reset )--行频刷新
begin
if push_reset = '0' then
hcnt<="000000000";
hsync<='1';
elsif clk'event and clk='1' then
if hcnt<126 then
hcnt<=hcnt+1;
else
hcnt<="000000000";
end if;
if hcnt>116 and hcnt<126 then --行扫描正程
hsync<='0';
else
hsync<='1'; --行扫描逆程
end if;
end if;
end process;
process (clk,hcnt,vcnt)--画出显示器的各个部分
begin
if CLK'EVENT and CLK='1' then
if (hcnt>=16 and hcnt<=91 and vcnt>=63 and vcnt<=385) then
if life_sign='1' then
if hcnt=16 or hcnt=31 or hcnt = 46 or hcnt=61 or hcnt = 76 or hcnt = 91
or vcnt=64 or vcnt=128 or vcnt=192 or vcnt=256 or vcnt=320 or vcnt = 384
or vcnt=65 or vcnt=129 or vcnt=193 or vcnt=257 or vcnt=321 or vcnt = 385 then
rgb<=clgrid; --grid
elsif hcnt>boy_x+1 and hcnt<boy_x+14 and vcnt>boy_y+8 and vcnt<boy_y+51 then
rgb<=clboy; --画出boy
elsif hcnt>box1_x+1 and hcnt<box1_x+14 and vcnt>box1_y+8 and vcnt<box1_y+51 then
rgb<=clbox; --画出box1
elsif hcnt>box2_x+1 and hcnt<box2_x+14 and vcnt>box2_y+8 and vcnt<box2_y+51 then
rgb<=clbox; --画出box2
elsif hcnt>pos1_x+2 and hcnt<pos1_x+12and vcnt>pos1_y+15 and vcnt<pos1_y+40 then
rgb<=clpos; --画出pos1
elsif hcnt>pos2_x+2 and hcnt<pos2_x+12 and vcnt>pos2_y+15 and vcnt<pos2_y+40 then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -