数字电路实验报告
数字电路实验报告
简易的迷宫游戏
信通 16 楚萱 2012210472 班内21
一 实验要求。
1、用 8×8 点阵进行游戏显示。
2、迷宫游戏如图 1 所示,采用双色点阵显示,其中红色LED 为迷宫墙壁,绿色LED 表示人物。通过BTN0~BTN3 四个按键控制迷宫中的人物进行上下左右移动,使人 物从起始点出发,走到迷宫的出口,游戏结束。
3、普通计时模式:通过按键BTN7 启动游戏,必须在30 秒内找到出口,否则游戏失败, 用两个数码管进行倒计时显示。游戏胜利或者失败均要在8×8 点阵上有相应的画面 出现。
4、迷宫中的人物在行走过程中,如果碰到墙壁,保持原地不动。
二 实验设计。
设计思路
1人物显示 ○
通过将点阵每一个点设计坐标表示人物坐标,通过对x y 左边不断的扫描实现人物移动,经过对坐标译码显示在点阵上。
2地图显示 ○
点阵使用共阴极二极管,在扫描列后进行行扫描。即确定哪一列亮之后再确定具体哪一行亮。当接上一个高频时钟后,利用人眼视觉暂留可以实现迷宫地图的显示。此处我使用的时钟初始频率为50M HZ,进行了2000分频后的时钟频率。
3数码管记时显示 ○
设计分频器将50M HZ频率分成1 HZ,设置一个signal 为中间变量不停为8位数码管赋值扫描,实现了计时功能。
主要代码
1防抖时钟 ○
pz:process(go,start)
begin
if(clk3'event and clk3='1')then
if(go='1')then
start
end if;
end if;
end process;
“go”为逻辑型输入信号,引脚为btn7,“start”为逻辑型signal ,clk3分频为12500000分频。每当按下btn7,start 取一次反,即start 起拨码开关作用,当go 逻辑取1后,start 取1,即开关为开状态,游戏开始。
2迷宫显示 ○
p5:process(clk1,start,mord,cnt)
begin
if(start='1')then
if(clk1' event and clk1='1' )then
if(timeout=0)then
case cnt is
when 0=>dzlie
when 1=>dzlie
when 2=>dzlie
when 3=>dzlie
when 4=>dzlie
when 5=>dzlie
when 6=>dzlie
when 7=>dzlie
when 8=>dzlie
end case;
end if;
if(timeout=1)then
case cnt is
when 0=>dzlie
when 1=>dzlie
when 2=>dzlie
when 3=>dzlie
when 4=>dzlie
when 5=>dzlie
when 6=>dzlie
when 7=>dzlie
when 8=>dzlie
end case;
end if;
if(success=1)then
case cnt is
when 0=>dzlie
when 1=>dzlie
when 2=>dzlie
when 3=>dzlie
when 4=>dzlie
when 5=>dzlie
when 6=>dzlie
when 7=>dzlie
when 8=>dzlie
end case;
end if;
end if;
end if;
end process;
cnt 为整型0到8 signal。
dzlie 为逻辑8位输出,控制点阵列,dzhangr ,dzhangg 为逻辑8位输出,分别控制行的红灯与绿灯。
利用时钟控制不停扫描改变cnt 的值,通过视觉暂留与高频时钟,case 语句即可控制点阵上每一点的亮灭以及颜色。其中dzlie 当某一位置“0“时,该列亮,dzhang 当某一位置”1”时,该行亮。
三个case 语句分别画出迷宫,游戏成功后显示画面:绿灯V ,游戏失败后显示画面:红灯L 。 Timeout 判断:首先在显示点阵之前进行一次判断, if (timeout=0),即游戏开始,时间从30秒倒计时,点阵上显示迷宫地图。If (timeout=1)则游戏时间到,游戏结束,点阵显示红灯字母L 。
3时间控制 ○
p6:process(clk2)
begin
if(clk2'event and clk2='1')then
if(start='0')then
secl
sech
else
if(secl=0)then
secl
else
secl
end if;
if(secl=0)then
sech
end if;
if(timeout=1)then
secl
sech
end if;
if(success=1)then
secl
sech
end if;
end if;
end if;
end process;
p7:process(secl)
begin
case secl is
when 0=>q2
when 1=>q2
when 2=>q2
when 3=>q2
when 4=>q2
when 5=>q2
when 6=>q2
when 7=>q2
when 8=>q2
when 9=>q2
end case;
case sech is
when 0=>q3
when 1=>q3
when 2=>q3
when 3=>q3
end case;
end process;
p9:process(clk)
begin
if(clk1'event and clk1='1')then
if(start='1')then
if(cnt5=1)then
cnt5
else
cnt5
end if;
end if;
end if;
end process;
p10:process(cnt5)
begin
case cnt5 is
when 1=>cat1
when 0=>cat1
end case;
end process;
secl 为一个10位整型signal ,表示低位秒表显示,
sech 为一个4位整型signal ,表示高位秒表显示。
q2为逻辑型10位signal ,译码低位显示数字,
q3位逻辑型10为signal ,译码高位显示数字。
Cnt5为2位整型signal 。
q1为10为逻辑型signal ,为数码管输出。
Clk2为50M 分频时钟,控制secl 变化速率为每秒一次,开始时设定sech=3,secl=0,即定时为30秒,随时间变化secl 自减,每当secl 减为0时sech 减1。
cat1选择数码管位码,通过快速变化的cnt5,不断地将q2,q3,cat1赋值,因为视觉暂留的原因,可在数码管上显示连续不断变化的数字倒计时。
4人物控制 ○
p12:process(setx,sety)
begin
case setx is
when 0=>setx1
when 1=>setx1
when 2=>setx1
when 3=>setx1
when 4=>setx1
when 5=>setx1
when 6=>setx1
when 7=>setx1
case sety is
when 0=>sety1
when 1=>sety1
when 2=>sety1
when 3=>sety1
when 4=>sety1
when 5=>sety1
when 6=>sety1
when 7=>sety1
end case;
end process;
setx 逻辑型8位signal ,sety 逻辑型8位signal
setx1为setx 在点阵上的译码,sety1为sety 在点阵上的译码。
通过坐标化可表示人物位置,以绿灯显示。
5人物移动 ○
p13:process(start,S,X,Z,Y)------move
begin
if(start='0')then
setx
sety
else
if(clk3'event and clk3='1')then
if(Z='1')then
if((setx=1 and (sety=7 or sety=6 or sety=1))or(setx=2 and (sety=5 or sety=4))or(setx=6 and (sety=5 or sety=4 or sety=3 or sety=2)))
then
sety
end if;
end if;
if(Y='1')then
if((setx=1 and (sety=0 or sety= 5 or sety=6)) or (setx=2 and (sety=3 or sety=4)) or(setx=6 and (sety=1 or sety=2 or sety=3 or sety=4)))
then
sety
end if;
if(S='1')then
if((sety=1 and (setx=6 or setx=5 or setx=4 or setx=3 or setx=2)) or (sety=3 and (setx=3 or setx=4)) or (sety=5 and (setx=2 or setx=3 or setx=4 or setx=5 or setx=6)))
then
setx
end if;
end if;
if(X='1')then
if((sety=1 and(setx=1 or setx=2 or setx=3 or setx=4 or setx=5)) or (sety=3 and (setx=2 or setx=3)) or (sety=5 and (setx=1 or setx=2 or setx=3 or setx=4 or setx=5)))
then
setx
end if;
end if;
end if;
end if;
end process;
以向左移动为例。
当“Z”被按下时,sety 坐标向左移动,set
遍历点阵中所有可以向左移动的点,即可以实现人物向左移动,而且排除了穿墙的可能性。 向上,向下,向右移动与此类似不一一赘述。
特别的,人物移动分频为迷宫显示时钟分频的两倍,这样做是为了提高按键的灵敏性,可以实现按住按键一步一步连续移动。
仿真波形
引脚设定
共用44个引脚。
三 实验代码。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity migong is
port (clk,go,S,X,Z,Y:in std_logic;
dzlie:out std_logic_vector(7 downto 0);
dzhangr:out std_logic_vector(7 downto 0); dzhangg:out std_logic_vector(7 downto 0); q1:out std_logic_vector(6 downto 0); cat1:out std_logic_vector(5 downto 0)); end migong;
architecture
behave of migong is
signal tmp:integer range 0 to 999; signal clk1:std_logic; signal clk2:std_logic; signal clk3:std_logic; signal start:std_logic; signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
signal
mord:integer range 0 to 4; cnt:integer range 0 to 8; cnt1:integer range 0 to 1; cnt5:integer range 0 to 1; secl:integer range 0 to 9; sech:integer range 0 to 3; secfen:integer range 0 to 24999999; shizhong:integer range 0 to 6249999; q2: std_logic_vector(6 downto 0); q3: std_logic_vector(6 downto 0); timeout:integer range 0 to 1; success:integer range 0 to 1; setx:integer range 0 to 7; sety:integer range 0 to 7; setx1: std_logic_vector(7 downto 0); sety1: std_logic_vector(7 downto 0);
begin
----fenpinqi----
pz:process(go,start)
begin
if(clk3'event and clk3='1')then
if(go='1')then
start
end if;
end if;
end process;
p0:process(clk1)
begin
if(clk'event and clk='1')then
if(tmp=999)then
tmp
else
tmp
end if;
end if;
end process p0;
begin
if(clk1' event and clk1='1')then
if(cnt=8)then
cnt
else
cnt
end if;
end if;
end process;
p2:process(cnt1)
begin
if(clk' event and clk='1')then
if(cnt1=1)then
cnt1
else
cnt1
end if;
end if;
end process;
begin
if(clk'event and clk='1')then
if(secfen=0)then
secfen
else
secfen
end if;
end if;
end process ;
p4:process(clk3)
begin
if(clk'event and clk='1')then
if(shizhong=0)then
shizhong
else
shizhong
end if;
end if;
end process;
------dianzhenxianshi------
p5:process(clk1,start,mord,cnt)
begin
if(start='1')then
if(clk1' event and clk1='1' )then
if(timeout=0)then
case cnt is
when
0=>dzlie
when
1=>dzlie
when
2=>dzlie
when
3=>dzlie
when
4=>dzlie
when
5=>dzlie
when
6=>dzlie
when
7=>dzlie
when 8=>dzlie
end if;
if(timeout=1)then
case cnt is
when
0=>dzlie
1=>dzlie
when
2=>dzlie
when
3=>dzlie
when
4=>dzlie
when
5=>dzlie
when
6=>dzlie
when
7=>dzlie
when
8=>dzlie
end case;
end if;
if(success=1)then
case cnt is
when
0=>dzlie
when
1=>dzlie
when
2=>dzlie
when
3=>dzlie
when
4=>dzlie
5=>dzlie
when
6=>dzlie
when
7=>dzlie
when
8=>dzlie
end case;
end if;
end if;
end if;
end process;
-----jishi-----
p6:process(clk2)
if(clk2'event and clk2='1')then if(start='0')then
secl
sech
else
if(secl=0)then
secl
else
secl
end if;
if(secl=0)then
sech
end if;
if(timeout=1)then secl
sech
end if;
if(success=1)then secl
sech
end if;
end if;
end if;
end process;
p7:process(secl) begin
case secl is
when 0=>q2q2q2q2q2q2q2q2q2q2
end case;
case sech is
when 0=>q3
when 1=>q3
when 2=>q3
when 3=>q3
end case;
end process;
p9:process(clk)
begin
if(clk1'event and clk1='1')then
if(start='1')then
if(cnt5=1)then
cnt5
else
cnt5
end if;
end if;
end process;
p10:process(cnt5)
begin
case cnt5 is
when 1=>cat1
when 0=>cat1
end case;
end process;
p11:process(timeout)
begin
if(secl=0 and sech=0)then
timeout
else
timeout
end if;
end process;
p12:process(setx,sety)
case setx is
when 0=>setx1
when 1=>setx1
when 2=>setx1
when 3=>setx1
when 4=>setx1
when 5=>setx1
when 6=>setx1
when 7=>setx1
end case;
case sety is
when 0=>sety1
when 1=>sety1
when 2=>sety1
when 3=>sety1
when 4=>sety1
when 5=>sety1
when 6=>sety1
when 7=>sety1
end case;
end process;
p13:process(start,S,X,Z,Y)------move
begin
if(start='0')then
setx
sety
else
if(clk3'event and clk3='1')then
if(Z='1')then
if((setx=1 and (sety=7 or sety=6 or sety=1))or(setx=2 and (sety=5 or sety=4))or(setx=6 and (sety=5 or sety=4 or sety=3 or sety=2)))
then
sety
end if;
end if;
if(Y='1')then
if((setx=1 and (sety=0 or sety= 5 or sety=6)) or (setx=2 and (sety=3 or sety=4)) or(setx=6 and (sety=1 or sety=2 or sety=3 or
sety=4)))
then
sety
end if;
end if;
if(S='1')then
if((sety=1 and (setx=6 or setx=5 or setx=4 or setx=3 or setx=2)) or (sety=3 and (setx=3 or setx=4)) or (sety=5 and (setx=2 or setx=3 or setx=4 or setx=5 or setx=6)))
then
setx
end if;
end if;
if(X='1')then
if((sety=1 and(setx=1 or setx=2 or setx=3 or setx=4 or setx=5)) or (sety=3 and (setx=2 or setx=3)) or (sety=5 and (setx=1 or setx=2 or setx=3 or setx=4 or setx=5)))
then
setx
end if;
end if;
end if;
end if;
end process;
p14:process(success)
begin
if(setx=1 and sety=0)then
success
else
success
end if;
end process;
end behave;
四 实验总结。
经过这一个月的数电实验,独立思考完成本次迷宫实验不仅学习到了相关的数电知识,也磨练了我做事情的意志。从开始时不太明太实验要求到最后的一步一步改进迷宫游戏效果。特别是在三个始终选择上花了不少的时间去研究,最终达到了每一个模块不冲突并且更好的同时工作的效果。
本次试验不足在于对于防抖电路的设计以及创新功能的增加,防抖电路设计的还是不够到位,创新部分由于实验开始时考虑不妥最终添加失败,希望在今后的实验中多加改进。