基于VHDL的乒乓球游戏机的设计与实现.docx
《基于VHDL的乒乓球游戏机的设计与实现.docx》由会员分享,可在线阅读,更多相关《基于VHDL的乒乓球游戏机的设计与实现.docx(36页珍藏版)》请在冰豆网上搜索。
基于VHDL的乒乓球游戏机的设计与实现
乒乓球游戏机的设计与实现
摘要:
本文介绍了乒乓球游戏机的设计,并进行了程序仿真,实现一个乒乓球游戏机的规定功能。
设计的乒乓球游戏机能够正确判断与显示乒乓球的位置,并能自动裁判和记分的装置,可应用于实际的乒乓球游戏比赛中。
程序通过调试运行,实现了设计目标。
本论文对系统的功能设计、实现流程及正确使用都做了详细的描述。
系统开发平台为MAX+PLUSII,程序设计语言为VHDL。
关键词:
乒乓球游戏机;设计;实现;VHDL;MAX+PLUSⅡ;
Designandrealizationoftabletennisgameplayer
Abstract:
Thisarticleintroducesthedesignofthetabletennisgameplayer,andcarriedoutsimulationprocedures,implementationoftheprovisionsofatabletennisgamefeatures.Designedtobeabletocorrectlyjudgethetabletennisgametableanddisplaythelocation,andcanautomaticallyappearandscoringdevices,canbeappliedtotheactualgameofTableTennisGame.Proceduredebuggingoperations,implementationofthedesignobjectives.Thisthesisdescribesindetailthefunctionofthesystemdesign,implementationandproperuseofflowaredescribedindetailtodo.SystemdevelopmentplatformfortheMAX+PLUSII,programminglanguageforVHDL.
.Keywords:
tabletennisgameplayer;design;realization;VHDL;MAX+PLUSⅡ
2.2硬件描述语言---VHDL........................................3
1引言
08年奥运,在电视机前欢腾了半个晚上。
看着白色的乒乓球在屏幕中央跳来跳去,心中的喜悦也在不断积累。
又一枚金牌归我中华。
课业繁重,但闲暇时,总喜欢在校园中徜徉,每每看到跳动的乒乓,就有种轻衫衬跳脱的轻松感。
因此,看到这次的论文选题,不禁哑然失笑,两种风牛马不相及的事物,就这样在这里纠结了。
乒乓球作为中国的国球,乒乓人才辈出。
本课程设计就是以乒乓球为背景,利用所学的硬件知识完成一个乒乓球游戏机的设计。
随着科学技术的发展,人类社会已进入到高度发达的信息化社会,信息社会的发展离不开电子产品的进步。
现代电子产品的发展越来越快,各种新型电子元器件和智能化的电子产品已经在国民经济的各个领域和人民生活的各个方面得到了日益广泛的应用。
实现这种进步的主要原因就是生产制造技术和电子设计技术的发展。
其中电子玩具的发展也是在日益成熟。
乒乓球游戏机控制电路是有甲、乙双方参赛,有裁判控制发“球”的三人乒乓球游戏机;它能完成自动裁判和自动计分是一个带数字显示的模拟游戏机。
其结构简单、成本低、易操作,安全性强、无污染。
乒乓球游戏机还能在娱乐的同时提高我们的反应、应变能力。
具有良好的市场发展前景[1]。
1.1课题设计的目的
本文应用状态机,设计了一个乒乓球游戏机的状态机。
状态机的实现是符合人的思维逻辑的,且简单明了[2]。
计算机组成原理课程设计是重要的综合性实践教学环节。
(1)通过该课程设计,结合计算机科学的理论、抽象和设计三种形态,进一步掌握计算机中各功能部件的工作原理和逻辑实现,熟悉乒乓球游戏机的基本工作原理。
(2)通过该课程设计的学习,总结计算机组成原理课程的学习内容,运用所学的数字电路以及计算机组成和状态机的基本原理、基本知识和基本技巧,解决某一个具体的实际问题,培养综合分析和解决问题的能力。
(3)为今后分析、设计、开发以及使用计算机打下坚实的基础。
1.2课题设计的内容
本文设计的是一个乒乓球游戏机的状态机。
利用VHDL,不需要按照传统的设计方法进行烦琐的状态分配、绘制状态、化简状态方程等,就可以简单地根据MDS图直接对状态机进行描述。
乒乓球游戏机可以实现如下功能。
(1)该设计一个由甲、乙双方参赛,有裁判的3人乒乓球游戏机。
(2)用8个(或更多个)LED排成一条直线,以中点为界,两人乒乓游戏机是用8个发光二极管代表乒乓球台,中间两个发光二极管兼做乒乓球网,用点亮的发光二极管按一定方向移动来表示球的运动,在游戏机的两侧个设置发球和击球开关,甲乙双方按乒乓球比赛规则来操作开关。
(3)当“球”(点亮的那只LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。
当甲方按动乒乓球开关时,靠近甲方的第一个发光二极管亮,然后发光二极管由甲方方向依次点亮,代表乒乓球的移动。
当球过网后按照设计者规定的球位乙方就可以击球。
若乙方提前击球或者未击到球,则甲方得分。
然后重新发球进行比赛。
(4)设置自动记分电路,甲、乙双方各用7段译码管进行记分显示,每计满21分为1局,然后记分清零,重新开始新一局比赛。
2EDA、VHDL简介
2.1EDA发展概况
电子设计技术的核心就是EDA技术,EDA是指以计算机为工作台,融合应用电子技术、计算机技术、智能化技术最新成果而研制成的电子CAD通用软件包,主要能辅助进行三方面的设计工作,即IC设计、电子电路设计和PCB设计。
EDA技术已有30年的发展历程,大致可分为三个阶段。
70年代为计算机辅助设计(CAD)阶段,人们开始用进行IC版图编辑、PCB布局布线,取代了手工操作。
80年代为计算机辅助工程(CAE)阶段。
与CAD相比,CAE除了有纯粹的图形绘制功能外,又增加了电路功能设计和结构设计,并且通过电气连接网络表将两者结合在一起,实现了工程设计。
CAE的主要功能是:
原理图输入,逻辑仿真,电路分析,自动布局布线,PCB后分析。
90年代为电子系统设计自动化(EDA)阶段[2]。
硬件描述语言HDL是相对于一般的计算机软件语言,如:
C、PASCAL而言的。
HDL语言使用与设计硬件电子系统的计算机语言,它能描述电子系统的逻辑功能、电路结构和连接方式。
设计者可利用HDL程序来描述所希望的电路系统,规定器件结构特征和电路的行为方式;然后利用综合器和适配器将此程序编程能控制FPGA和CPLD内部结构,并实现相应逻辑功能的的门级或更底层的结构网表文件或下载文件。
目前,就FPGA/CPLD开发来说,比较常用和流行的HDL主要有ABEL-HDL、AHDL和VHDL[3]。
2.2硬件描述语言——VHDL
VHDL的英文全名是Very-High-SpeedIntegratedCircuitHardwareDescriptionLanguage,诞生于1982年。
1987年底,VHDL被IEEE和美国国防部确认为标准硬件描述语言。
自IEEE公布了VHDL的标准版本,IEEE-1076(简称87版)之后,各EDA公司相继推出了自己的VHDL设计环境,或宣布自己的设计工具可以和VHDL接口。
此后VHDL在电子设计领域得到了广泛的接受,并逐步取代了原有的非标准的硬件描述语言。
1993年,IEEE对VHDL进行了修订,从更高的抽象层次和系统描述能力上扩展VHDL的内容,公布了新版本的VHDL,即IEEE标准的1076-1993版本,(简称93版)。
现在,VHDL和Verilog作为IEEE的工业标准硬件描述语言,又得到众多EDA公司的支持,在电子工程领域,已成为事实上的通用硬件描述语言。
专家认为,在新的世纪中,VHDL于Verilog语言将承担起大部分的数字系统设计任务。
VHDL主要用于描述数字系统的结构,行为,功能和接口。
除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。
VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可是部分,及端口)和内部(或称不可视部分),既涉及实体的内部功能和算法完成部分[4]。
在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。
这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。
应用VHDL进行工程设计的优点是多方面的[4]。
(1)与其他的硬件描述语言相比,VHDL具有更强的行为描述能力,从而决定了他成为系统设计领域最佳的硬件描述语言。
强大的行为描述能力是避开具体的器件结构,从逻辑行为上描述和设计大规模电子系统的重要保证。
(2)VHDL丰富的仿真语句和库函数,使得在任何大系统的设计早期就能查验设计系统的功能可行性,随时可对设计进行仿真模拟。
(3)VHDL语句的行为描述能力和程序结构决定了他具有支持大规模设计的分解和已有设计的再利用功能。
符合市场需求的大规模系统高效,高速的完成必须有多人甚至多个代发组共同并行工作才能实现。
(4)对于用VHDL完成的一个确定的设计,可以利用EDA工具进行逻辑综合和优化,并自动的把VHDL描述设计转变成门级网表。
(5)VHDL对设计的描述具有相对独立性,设计者可以不懂硬件的结构,也不必管理最终设计实现的目标器件是什么,而进行独立的设计[4]。
3乒乓球游戏机设计过程
3.1设计规划
根据乒乓球比赛的过程和规则,首先游戏开始,如果一方非正确击球则另一方加分,当分数大于21时获胜,游戏结束,我们把设计流程规定如图3.1所示。
甲乙
否否
NN
YY
图3.1设计流程图
状态机设置了7个状态,分别是“等待发球状态”,“第一盏灯亮状态”,“第八盏灯亮状态”,“球向乙移动状态”,“球向甲移动状态”,“允许甲击球状态”,
“允许乙击球状态”。
这是该程序中起决定作用的七个状态。
开始的时候处于“等待发球状态”,若甲发球则状态转移到“第一盏灯亮状态”,若乙发球则转移到“第八盏灯亮状态”,具体说明以甲球为例。
若发球后乙没有提前击球----规定球移动到对方第一个发光二极管时允许击球,那么状态机从“第一盏灯亮状态”转移到“球向乙移动状态”。
若在“球向乙移动状态”乙仍然没有提前击球,状态就转移到“允许乙击球状态”,在此状态下,如果乙击球了,那么状态就转移到“球向甲移动状态”。
在“第一盏灯亮状态”,“球向乙移动状态”中,如果乙击球了,就算提前击球,这样甲得分,状态转移到“等待发球状态”等待发球,“球向甲移动状态”之后的过程和前面的过程只不过是甲乙角色的调换而已。
状态转移规则都是一样的。
图3.2给出了乒乓球游戏机的原理图。
甲得分乙得分
甲发球乙发球
乙击球甲击球
乙击球甲击球
乙没击球甲没击球
图3.2乒乓球游戏机原理图
3.2乒乓球游戏机实体的设计
该乒乓球游戏机的设计主要包括的模块与内容有:
乒乓球游戏机实体的设计,游戏机编程的实现,记分译码器的设计以及构造体的设计。
直接对状态机进行描述,所有的状态均可表达为CASE_WHEN结构中的一条CASE语句,而状态的转移则通过IF_THEN_ELSE语句实现。
以下我们就详细解析各个板快的设计与实现。
设计该乒乓球游戏机的输入与输出端口。
首先考虑输入端口,一般应该设置一个异步置位端口reset,用于在系统不正常时回到初始状态:
两个发球输入端serve1和serve2,逻辑‘1’分别表示甲方和乙方的发球;两个击球输入端hit1和hit2,逻辑‘1’分别表示甲击球和乙击球;一个开始游戏按钮startbutton,处于逻辑‘1’表示可以游戏;还得有一个时钟输入端口clk。
其次考虑输出端口,芯片应该有8个输出端口来控制8个发光二极管,输出逻辑‘1’即输出一个高电平,可以使发光二极管点亮;另外,要直观地表示双方的得分,就得用到4个七段译码器,每方用到2个,可以表示0到21的数字,每个七段译码器需要芯片的7个输出端口来控制,总共28个输出端口。
实体的设计如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;//引用必要的库函数和包集合
entitypingponggameis--实体名为pingponggame
port(reset:
intstd_logic;
clk:
intstd_logic;
startbutton:
intstd_logic;--开始游戏输入端口
serve:
instd_logic_vector(1to2);--发球输入端口
hit1,hit2:
intstd_logic;--甲和乙的击球输入端口
--控制8个发光二极管的输出端口
light:
outstd_logic_vector(1to8);
score11,score12,score21,score22:
outstd_logic_vector(1to7));--4个用于控制4个7段译码器的输出端口
endpingponggame;
3.3状态机编程实现
状态机设置了7个状态,分别是waitserve,light1on,ballmoveto2,
Allow2hit,light8on,ballmoveto1,和allow1hit它们代表的具体数值依次是0到6。
在波形模拟图中是用数值来表示状态的。
在整个程序中,状态机起的是中央控制器的作用,由它控制的信号来影响整个程序中的其他相关部分,如记分部分,发光二极管部分。
乒乓球游戏机中有两个计数器count1和count2,分别记忆甲和乙的得分,用发光二极管的轮流发光表示球的移动轨迹。
状态机的进程如下:
process(clk)--clk作为敏感信号触发进程
begin--进程开始
ifreset='1'then--异步置位
i<=0;count1<"00000";count2<="00000";
elsifclk'eventandclk='1'then--当处于时钟inclock上升沿时
ifcount1="10101"orcount2="10101"then
i<=0;count1<"00000";count2<="00000";
elsifstartbutton+'0'then
i<=0;count1<"00000";count2<="00000";
else--以下case语句是程序中最关键的状态机部分
casestateis
whenwaitserve=>--进程处于等待发球状态
caseserveis
when"10'=>i<=1;state<=light1on;
when"01'=>i<=8;state<=light8on;
when"i1"=>i<=0;
whenothers=>i<=0;
endcase;
whenlight1on=>--进程处于第一盏灯亮状态
i<=2
ifhit2='1'then
i<=0;
count1<=count1+1;state<=waitserve;
else
state<=ballmoveto2;
endif;
whenlight8on=>--进程处于第八盏灯亮状态
i<=7;
ifhit='1'then
i<=0;
count2<=count2+1;state<=waitserve;
else
state<=ballmoveto1;
endif;
whenballmoveto1=>--进程处于球向乙移动状态
ifhit1='1'then
i<=0;
count2<=count2+1;state<=waitserve;
elsifi=2theni<=1;
state<=allow1hit;
elsei<=i-1;
endif;
whenballmoveto2=>--进程处于球向乙移动状态
ifhit2='1'then
i<=0;
ount1<=count1+1;state<=waitserve;
elsifi=7theni<=8;
state<=allow2hit;
elsei<=i+1;
endif;
whenallow1hit=>--进程处于允许甲击球状态
ifhit1='1'theni<=2;
state<=ballowto2;
elsecount2<=count2+1;i<=0;
state<=waitserve;
endif;
whenallow2hit=>--进程处于允许乙击球状态
ifhit2='1'theni<=7;state<=ballmoveto1;
elsecount1<=count1+1;i<=0;
state<=waitserve;
endif;
endcase;
endif;
endif;
endprocess;
3.4记分译码器的设计
七段译码器是在数学电路设计中经常用到的显示电路。
所谓七段译码器,其实是由7段发光二极管组成的用于显示数字的器件。
记分译码器(mydecoder):
由于记分需要显示出来,所以要使用七段译码器。
而状态机中的记分是由5位二进制码来表示的,即count1和count2。
以下程序就是实现从5位二进制码转换成七段译码显示。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsingned.all;
entitymudecoderis
port(binaryin:
intstd_logic_vector(1to5);
--5位二进制码的输入端口
bcdout1:
outstd_logic_vector(1to7);--七段译码器输出端口
bcdout2:
outstd_logic_vector(1to7)
);
endmydecoder;
architecturemofmydecoderis
signaltembinaryin:
std_logic_vector(1to5);
begin
process(binaryin)
begin
tembinaryin<=binaryin;
casetembinaryinis
--把0到9的5位二进制码转换成七段译码
when"00000"=>bcdout1<="1111110";bcdout2<="1111110";
when"00001"=>bcdout1<="1111110";bcdout2<="0110000";
when"00010"=>bcdout1<="1111110";bcdout2<="1101101";
when"00011"=>bcdout1<="1111110";bcdout2<="1111001";
when"00100"=>bcdout1<="1111110";bcdout2<="0110011";
when"00101"=>bcdout1<="1111110";bcdout2<="1011011";
when"00110"=>bcdout1<="1111110";bcdout2<="1011111";
when"00111"=>bcdout1<="1111110";bcdout2<="1110000";
when"01000"=>bcdout1<="1111110";bcdout2<="1111111";
when"01001"=>bcdout1<="1111110";bcdout2<="1111011";
--把10到19的5位二进制码转换成七段译码
when"01010"=>bcdout1<="0110000";bcdout2<="1111110";
when"01011"=>bcdout1<="0110000";bcdout2<="0110000";
when"00000"=>bcdout1<="0110000";bcdout2<="1101101";
when"01100"=>bcdout1<="0110000";bcdout2<="1111001";
when"01101"=>bcdout1<="0110000";bcdout2<="0110011";
when"01111"=>bcdout1<="0110000";bcdout2<="1011011";
when"10000"=>bcdout1<="0110000";bcdout2<="1011111";
when"10001"=>bcdout1<="0110000";bcdout2<="1110000";
when"10010"=>bcdout1<="0110000";bcdout2<="1111111";
when"10011"=>bcdout1<="0110000";bcdout2<="1111011";
--把20到21的5位二进制码转换成七段译码
when"10100"=>bcdout1<="1101101";bcdout2<="1111110";
when"10101"=>bcdout1<="1101101";bcdout2<="0110000";
--如果5位二进制码不在0到21范围内,那么两个七段译码器都显示0
whenothers=>bcdout1<="1101101";bcdout2<="1111110";
endcase;
endprocess;
endm;
这个记分译马电路是针对乒乓球游戏机的特点进行的特别设计,采用的是全部列举的方法。
3.5构造体的设计
该构造体紧跟在实体设计之后,这样就完成了数字乒乓球游戏机的VHDL源程序编写。
rchitecturegameofpingponggameis
typepingpongis(waitserve,light1on,ballmoveto2,allow2hit,
light8on,ballmoveto1,allow1hit);
---设置7个状态,为枚举数据类型,记为pingpong
signalstate:
pingpong;
signali:
integerrange0to8;
signalcount1,count2:
std_logic_vector(1to5):
="00000";
---内部计数器,是5位二进制变量
componentmydecoderis
port(binaryin:
instd_logic_vector(1to5);
bcdout1:
outstd_logic_