数字电路实验报告.docx
《数字电路实验报告.docx》由会员分享,可在线阅读,更多相关《数字电路实验报告.docx(36页珍藏版)》请在冰豆网上搜索。
数字电路实验报告
北京邮电大学
数字电路与逻辑设计实验
实验报告
实验名称:
足球比赛游戏机
班级:
学号:
姓名
2014年11月8号
一、实验目的
(1)进一步掌握VHDL和Quartus
软件的使用;
(2)理解状态机的工作原理和设计方法;
(3)掌握利用EDA工具进行自顶向下的电子系统设计方法。
二、实验所用仪器及元器件
(1)计算机;
(2)EDA开发板及相应元器件。
三、实验内容
(1)基本内容
1、按下开始键后,点阵显示球场初始状态,黄色点表示球,红、绿点表示甲、乙双方的球员,上下各有四个点表示双方的球门。
2、甲、乙双方各有一组上下左右按键来控制自己的球员,当球员位于足球的上下左右四个点时,按下方向键可带球向对应的方向移动,如果移动方向正前方有对方球员,则球不能移动。
3、在没有球员踢球的时候,足球每秒随机向四个方向移动一格。
4、足球到四周边界线(点阵最外一圈的点)时,再继续向外踢球时,可以球不移动,等待球随机移动;也可以自己设定相关的出界规则。
5、足球进入球门,则胜方自动加1分,每方的分数用2位数码管显示。
6、每场比赛时间为90秒,用数码管倒计时显示时间。
计时到0后,比赛停止,点阵显示胜利方(甲、乙或者平),直到再次按下比赛开始键后重新开始。
(2)提高要求
1、进球和比赛结束后点阵显示动画或者蜂鸣器播放音乐庆祝。
2、自拟其它功能。
四、系统设计
本次试验我把电路分为中心逻辑模块(center)和外围硬件驱动模块(按键keyboard,点阵显示screen,数码管显示digit,倒计时countdown,分频器clkgen)。
各部分把信号送给center,center对信号做出反应。
五.程序设计
(1)点阵模块
点阵分成了两个小块,一部分负责扫描,即通过扫描显示输入图形,一部分负责图像的输入,这样做能简化程序结构,让程序思路更清晰。
扫描模块在1kHz的上升沿,列移位输出
由中心部件传过来的信号shenfu(胜负)为000时未分胜负,则显示甲乙球的对应坐标,否则根据胜负显示结果。
libraryieee;
useieee.std_logic_1164.all;
useieee.numeric_std.all;
entityscreenis
port(
row:
outstd_logic_vector(7downto0);
rcol:
outstd_logic_vector(7downto0);
gcol:
outstd_logic_vector(7downto0);
p0_pos_row:
instd_logic_vector(7downto0);
p0_pos_col:
instd_logic_vector(7downto0);
p1_pos_row:
instd_logic_vector(7downto0);
p1_pos_col:
instd_logic_vector(7downto0);
p2_pos_row:
instd_logic_vector(7downto0);
p2_pos_col:
instd_logic_vector(7downto0);
shenfu:
instd_logic_vector(2downto0);
clock:
instd_logic
);
endentityscreen;
architecturevofscreenis
signalr:
std_logic_vector(7downto0):
="00000001";
signalrc:
std_logic_vector(7downto0);
signalgc:
std_logic_vector(7downto0);
begin
led_SCAN:
process(clock)
begin
ifrising_edge(clock)then
if(r="10000000")then
r<="00000001";
else
r(7downto1)<=r(6downto0);
r(0)<='0';
endif;
endif;
endprocessled_SCAN;
led_out:
process(r,shenfu,p0_pos_row,p0_pos_col,p1_pos_row,p1_pos_col,p2_pos_row,p2_pos_col)
begin
caseshenfuis
when"000"=>
if(r="00000001")then
rc<="00111100";
gc<="00000000";
elsif(r="10000000")then
gc<="00111100";
rc<="00000000";
else
if(r=p2_pos_rowandr=p1_pos_rowandr=p0_pos_row)then
rc<=p1_pos_colorp0_pos_col;
gc<=p2_pos_colorp0_pos_col;
elsif(r=p2_pos_rowandr=p0_pos_row)then
gc<=p2_pos_colorp0_pos_col;
rc<="00000000";
elsif(r=p1_pos_rowandr=p0_pos_row)then
rc<=p1_pos_colorp0_pos_col;
gc<="00000000";
elsif(r=p1_pos_rowandr=p2_pos_row)then
gc<=p2_pos_col;
rc<=p1_pos_col;
elsif(r=p1_pos_row)then
gc<="00000000";
rc<=p1_pos_col;
elsif(r=p2_pos_row)then
rc<="00000000";
gc<=p2_pos_col;
elsif(r=p0_pos_row)then
gc<=p0_pos_col;
rc<=p0_pos_col;
else
gc<="00000000";
rc<="00000000";
endif;
endif;
when"100"=>
gc<=p0_pos_col;
caseris
when"00000001"=>rc<="00010000";
when"00000010"=>rc<="00010000";
when"00000100"=>rc<="00010000";
when"00001000"=>rc<="11111110";
when"00010000"=>rc<="10010010";
when"00100000"=>rc<="11111110";
when"01000000"=>rc<="10010010";
when"10000000"=>rc<="11111110";
whenothers=>rc<="00000000";
endcase;
when"010"=>
gc<=p0_pos_col;
caseris
when"00000001"=>rc<="11111111";
when"00000010"=>rc<="01000000";
when"00000100"=>rc<="00100000";
when"00001000"=>rc<="00010000";
when"00010000"=>rc<="0000100";
when"00100000"=>rc<="00000100";
when"01000000"=>rc<="00000010";
when"10000000"=>rc<="11111111";
whenothers=>rc<="00000000";
endcase;
when"001"=>
gc<=p0_pos_col;
caseris
when"00000001"=>rc<="00010000";
when"00000010"=>rc<="00010000";
when"00000100"=>rc<="00010000";
when"00001000"=>rc<="11111111";
when"00010000"=>rc<="00111000";
when"00100000"=>rc<="01010100";
when"01000000"=>rc<="00111000";
when"10000000"=>rc<="01111100";
whenothers=>rc<="00000000";
endcase;
whenothers=>null;
endcase;
endprocessled_out;
row<=notr;
rcol<=rc;
gcol<=gc;
endarchitecturev;
(2)数码管模块
数码管模块根据输入的数字经过译码显示出来,只和输入的num有关,不会影响程序。
使用digit_translate进行译码,得到的结果在扫描到对应的时间输出
digit_translate由于多次使用,作为component调用,是一个4-7译码器。
libraryieee;
useieee.std_logic_1164.all;
useieee.numeric_std.all;
entitydigitis
port(
cat:
outstd_logic_vector(5downto0);
outdata:
outstd_logic_vector(6downto0);
num5:
instd_logic_vector(3downto0);
num4:
instd_logic_vector(3downto0);
num3:
instd_logic_vector(3downto0);
num2:
instd_logic_vector(3downto0);
num1:
instd_logic_vector(3downto0);
num0:
instd_logic_vector(3downto0);
clock:
instd_logic;
reset:
instd_logic
);
endentitydigit;
architecturedigit_scanofdigitis
COMPONENTdigit_translate
PORT
(
num:
INSTD_LOGIC_VECTOR(3DOWNTO0);
decode:
OUTSTD_LOGIC_VECTOR(6DOWNTO0)
);
ENDCOMPONENT;
signaltemp_cat:
std_logic_vector(5downto0);
signalnum0_decode:
std_logic_vector(6downto0);
signalnum1_decode:
std_logic_vector(6downto0);
signalnum2_decode:
std_logic_vector(6downto0);
signalnum3_decode:
std_logic_vector(6downto0);
signalnum4_decode:
std_logic_vector(6downto0);
signalnum5_decode:
std_logic_vector(6downto0);
signaloutdata_temp:
std_logic_vector(6downto0);
begin
m0:
digit_translateportmap(num0,num0_decode);
m1:
digit_translateportmap(num1,num1_decode);
m2:
digit_translateportmap(num2,num2_decode);
m3:
digit_translateportmap(num3,num3_decode);
m4:
digit_translateportmap(num4,num4_decode);
m5:
digit_translateportmap(num5,num5_decode);
process(clock,reset)is
begin
if(reset='1')then
temp_cat<="000001";
elsifrising_edge(clock)then
if(temp_cat="100000")then
temp_cat<="000001";
else
temp_cat(5downto1)<=temp_cat(4downto0);
temp_cat(0)<='0';
endif;
endif;
endprocess;
process(temp_cat,num0_decode,num1_decode,num2_decode,num3_decode,num4_decode,num5_decode)is
begin
if(temp_cat="000001")then
outdata_temp<=num0_decode;
elsif(temp_cat="000010")then
outdata_temp<=num1_decode;
elsif(temp_cat="000100")then
outdata_temp<=num2_decode;
elsif(temp_cat="001000")then
outdata_temp<=num3_decode;
elsif(temp_cat="010000")then
outdata_temp<=num4_decode;
else
outdata_temp<=num5_decode;
endif;
endprocess;
cat<=nottemp_cat;
outdata<=outdata_temp;
endarchitecturedigit_scan;
(3)倒计时模块
输入1Hz的时钟,start为高时开始倒计时,reset为高时倒计时归为80,时间到0时time_out输出为高
输出分为十位count_10和个位count输出。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycount_downis
port(
clock:
instd_logic;
reset:
instd_logic;
start:
instd_logic;
time_out:
outstd_logic;
count_10:
outstd_logic_vector(3downto0);
count:
outstd_logic_vector(3downto0)
);
endentitycount_down;
architecturemyofcount_downis
signalcount_10_temp:
std_logic_vector(3downto0);
signalcount_temp:
std_logic_vector(3downto0);
begin
process(clock,reset)is
begin
if(reset='1')then
count_10_temp<="1001";
count_temp<="0000";
time_out<='0';
elsifrising_edge(clock)andstart='1'then
if(count_temp="0000"andcount_10_temp="0000")then
time_out<='1';
elsif(count_temp="0000")then
count_temp<="1001";
count_10_temp<=count_10_temp-1;
time_out<='0';
else
count_temp<=count_temp-1;
time_out<='0';
endif;
endif;
endprocess;
count_10<=count_10_temp;
count<=count_temp;
endarchitecturemy;
(4)键盘模块
键盘输出行扫描,输入列信号,
之后防抖、转码输出,屏蔽了多余的接口
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitykeyboardis
port(
col:
outstd_logic_vector(3downto0);
row:
instd_logic_vector(3downto0);
debug_key:
outstd_logic_vector(7downto0);--usedfordebug
p1_key:
outstd_logic_vector(3downto0);--player1(up,left,down,right)
p2_key:
outstd_logic_vector(3downto0);--player2(up,left,down,right)
reset:
instd_logic;
clock:
instd_logic);--1kHz
endentity;
architecturekeyboard_mainofkeyboardis
signaltemp_col:
std_logic_vector(3downto0):
="0001";--col=nottemp_col
signalkeys:
std_logic_vector(7downto0);
signalcatch_row0:
std_logic_vector(3downto0);
signalcatch_row1:
std_logic_vector(3downto0);
signalcatch_row2:
std_logic_vector(3downto0);
signalcatch_row3:
std_logic_vector(3downto0);
signalt0:
integerrange0to99:
=0;
signalt1:
integerrange0to99:
=0;
signalt2:
integerrange0to99:
=0;
signalt3:
integerrange0to99:
=0;
signalp1_key_out:
std_logic_vector(3downto0);
signalp2_key_out:
std_logic_vector(3downto0);
--signalstep:
std_logic_vector(1downto0);
begin
scan:
process(clock)is
begin
ifrising_edge(clock)then
if(temp_col="1000")then
temp_col<="0001";
else
temp_col(3downto1)<=temp_col(2downto0);
temp_col(0)<='0';
endif;
endif;
endprocess;
col<=nottemp_col;
keys(7downto4)<=temp_col;
anti_shake:
process(row,temp_col,clock)is
begin
ifrising_edge(clock)then
iftemp_col="0001"then--row0
if(row="1111")then--ifanykeywasnotpressed
t0<=0;
keys(3downto0)<="0000";
else
ift0=0then
catch_row0<=row;
keys(3downto0)<="0000";
t0<=t0+1;
elsifcatch_row0=rowthen
ift0=24then--0.1sdelay
t0<=0;
keys(3downto0)<=notcatch_row0;
else
t0<=t0+1;
keys(3downto0)<="0000";
endif;
else
catch_row0<=row;
t0<=0;