基于VHDL的乒乓游戏机的设计与实现文档格式.docx
《基于VHDL的乒乓游戏机的设计与实现文档格式.docx》由会员分享,可在线阅读,更多相关《基于VHDL的乒乓游戏机的设计与实现文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
VHDL是VeryhighspeedintegratedcircuitHardwareDescriptionLanguage的缩写,即“甚高速集成电路硬件描述语言”,最初由美国国防部和INTER、IBM、TI公司联合开发,1987年成为IEEE标准,即IEEE1076标准(俗称87版VHDL)[1]。
此后,美国国防部要求官方与高速集成电路设计的所有文档必须用VHDL描述,因为VHDL在电子设计领域得到了广泛的应用,渐渐成为工业界的标准。
1993年,IEEE对VHDL进行了修订,公布了新的VHDL标准,即IEEE1076-1993版(俗称93版VHDL)[3]。
2.1VHDL的特点及优点
VHDL具有以下特点[4]:
(1)支持“自顶向下”的设计方法:
设计可按层次分解,采用结构化开发手段,可实现多人、多任务的并行工作方式,使系统的设计效力大幅提高。
(2)系统硬件描述能力强:
可以同时支持“行为描述”、“数字流描述”和“结构描述”3种描述方式,并可混用[5]。
其中,强大的“行为描述”能力使设计者可以避开具体的器件结构,从逻辑行为上描述和设计大规模电子系统。
这一特点使VHDL成为系统设计领域中最佳的硬件描述语言。
(3)系统仿真能力强:
VHDL最初是作为一种仿真标准问世的,因此VHDL具有仿真语句和库函数。
另外,VHDL强大的“行为描述”能力也使其十分适用于系统级仿真。
(4)工艺无关性[6]:
在使用VHDL设计系统硬件时,没有嵌入与工艺相关的信息。
正因为VHDL的硬件描述与具体工艺无关,因而其程序的硬件实现目标器件有广阔的选择范围,其中包括各种CPLD、FPGA及ASIC等。
同时,VHDL具有以下优点[7]:
(1)与其他的硬件描述语言相比,VHDL具有更强的行为描述能力。
强大的行为描述能力是避开具体的器件结构,从逻辑行为上描述和设计大规模电子系统的重要保证。
就目前流行EDA工具和VHDL综合器而言,将基于抽象的行为描述风格的VHDL程序综合成为具体FPGA和CPLD等目标器件的网表文件已不成问题,只是在综合与优化效率上略有差异。
(2)VHDL具有丰富的仿真语句和库函数,使得在任何大系统的设计早期,就能查验设计系统的功能可行性,随时可对系统进行仿真模拟,使设计者对整个工程的结构和功能可行性做出判断。
(3)VHDL语句的行为描述能力和程序结构,决定了它具有支持大规模设计的分解和已有设计的再利用功能。
高效、高速完成符号市场需求的大规模系统设计必须有多人甚至多个开发组共同并行工作才能实现。
VHDL中设计实体的概念、程序包的概念、设计库的概念为设计的分解和并行工作提供了有利的支持。
(4)用VHDL完成一个确定的设计,可以利用EDA工具进行逻辑综合和优化,并自动把VHDL描述设计转变成门级网表(根据不同的芯片)。
这种方式突破了门级设计的瓶颈,极大地减少电路设计的时间和可能发生的错误,降低了开发成本。
利用EDA工具的逻辑优化功能,可以自动地把一个综合后的设计变成一个更小、更高速的电路系统。
反过来,设计者还可以容易地从综合和优化的电路获得设计信息,返回去修改VHDL设计描述,使之更加完善。
(5)VHDL对设计的描述具有相对独立性。
设计者可以不懂硬件的结构,也不必管最终设计的目标器件是什么,而进行独立的设计。
正因为VHDL的硬件描述与具体的工艺技术和硬件结构无关,所以VHDL设计程序的硬件实现目标器件有广阔的选择范围,其中包括各种系列的CPLD、FPGA及各种门阵列器件。
(6)VHDL具有类属描述语句和子程序调用等功能,对于完成的设计,在不改变源程序的条件下,只需改变类属参量或函数,就能轻易地改变设计的规模和结构。
正因为VHDL有如此多的特点和优点,所以本设计运用VHDL进行乒乓球游戏机软设计。
2.2设计流图
设计流程图如图1所示。
这一流程图基本可使用任何基本硬件描述语言的设计。
下面对这个流程中的步骤进行说明[1]:
(1)系统层次划分/画出系统框图(Hierarchy/BlockDiagram):
按照“自顶向下”的设计方法对系统进行划分(确定系统由哪些模块构成,各个模块又由哪些子模块构成)。
(2)编码:
写出VHDL代码,大多数集成开发环境(如MAX+plus2等)都集成了针对VHDL的编辑。
这些编辑器一般都具有VHDL关键词的亮点显示等特点,有的还内嵌了常用的VHDL程序模块。
图1VHDL的设计流程图
(3)编译(Compilation):
编译器会对VHDL程序进行语法检查,还会产生用于仿真的一些内部信息。
这一步骤通常由编译器自动完成,无须我们干预。
如果VHDL语言有错误,编译无法通过,则需要修改程序,即回到第
(2)步。
事实上,VHDL设计过程中,常常根据需要往后退一步,甚至更多。
(4)功能仿真(FunctionalSimulation):
VHDL仿真器允许定义输入并应用到设计中,不必生成实际电路就可以观察输出。
此仿真主要用于检验系统功能设计的正确性,不涉及具体器件的硬件特性。
(5)综合(Synthesis):
利用综合器对VHDL代码进行综合优化处理,生成门级描述的网表文件,这是将VHDL语言描述转化为硬件电路的关键步骤。
这一步通常由综合器自动完成,但设计者可以设定一些技术上的约束条件(如限定逻辑层次的最大数等)来“帮助”综合器。
(6)适配(Fitting):
利用适配器将综合后的网表文件针对某一具体的目标器件进行逻辑映射操作,包括底层器件配置、逻辑分割、逻辑优化、布局布线等。
此步骤将产生多项设计结果:
①适配报告,包括芯片内部资源的利用情况、设计的布尔方程描述情况等;
②适配后的仿真模型;
③器件编程文件。
(7)时序仿真(TimingSimulation):
根据适配后的仿真模型,可以进行时序仿真。
因为这时已经得到目标器件的实际硬件特性(如时延特性等),所以仿真结果能比较精确的预期芯片的实际性能。
如果仿真结果达不到设计要求,就需要修改VHDL源代码或选择不同的目标器件,甚至要重构整个系统,图1就是所设计者极力避免出现的情况。
(8)下载CPLD/FPGA(Programming):
如果时序仿真通过,就可将“适配”时产生的器件编程文件下载到CPLD或FPGA中(FPGA的编程通过被称为“配置”)。
虽然流程图中未标出从此步“往回走”的箭头,但事实上,实际的结果有可能与仿真结果有差异(可能是设计时未考虑到外部硬件的实际情况;
也可能是由于仿真时测试的条件不够多,没有发现其中隐藏的错误),这时,必须回头重新找出问题所在。
3模块设计
乒乓游戏机的组成示意图如图2所示。
图2乒乓游戏机的组成示意图
本设计中的乒乓游戏机是由5个发光二极管代表乒乓球台,中间的发光二极管兼作球网,用点亮的发光二极管按一定方向移动来表示球的运动。
在游戏机的两侧各设置两个开关,一个是发球开关STARTA、STARTB;
另一个是击球开关HITA、HITB。
甲乙二人按乒乓球比赛规则来操作开关。
当甲方按动发球开关STARTA时,靠近甲方的第一个发光二极管亮,然后发光二极管由甲向乙依次点亮,代表乒乓球的移动。
当球过网后按设计者规定的球位,乙方就可以击球。
若乙方提前击球或没有击中球,则判乙方失分,甲方的记分牌自动加一分。
然后重新发球,比赛继续进行。
比赛一直要进行到一方记分牌达到21分,该局才结束。
本设计由译码显示器、按键去抖、状态机/球台控制器和记分器等部分所组成。
本系统的逻辑分框图如图3所示。
图3系统逻辑分框图
3.1七段数码管显示译码器
七段数码是纯组合电路,通常的小规模专用IC,如74或4000系列的器件只能作十进制BCD码译码,然而数字系统中的数据处理和运算都是2进制的,所以输出表达都是16进制的,为了满足16进制数的译码显示,最方便的方法就是利用VHDL译码程序在FPGA或CPLD中实现。
七段数码管分为共阴极和共阳极两种[8]。
简而言之,对共阴极来说,公共引脚要接地,想要点亮某段数码管,就在相应的引脚加上高电平;
对共阴极来说刚好相反,公共引脚提高电平,想要点亮某段数码管,就在相应的引脚加上低电平[9]。
七段BCD码译码器的设计,输出信号LED7S的7位分别接如图4所示数码管的七个段,高位在左,低位在右[9]。
例如当LED7S输出为“1101101”时,数码管的7个段:
g、f、e、d、c、b、a分别接1、1、0、1、1、0、1,接有高电平的段发亮,于是数码管显示“5”。
带使能信号EN的译码电路的VHDL程序中,EN为高电平时,译码器正常工作;
EN为低电平时,译码器输出0000000,表示数码管无显示。
用选择信号赋值语句描述,将综合成组合逻辑电路。
图4共阴数码管及电路
图5多模块共同控制七段数码管译码电路示意图
带使能信号EN的译码电路的VHDL程序如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYDISPLAYIS
PORT
(EN:
INSTD_LOGIC;
NUM:
ININTEGERRANGE0TO15;
DISPLAY:
OUTSTD_LOGIC_VECTOR(0TO6));
END;
ARCHITECTUREDECODEROFDISPLAYIS
BEGIN
PROCESS(EN,NUM)
IFEN=’1’THEN--使能信号EN为1时,译码器正常工作
CASENUMIS
WHEN0=>
DISPLAY<
=”1111110”;
WHEN1=>
=”0110000”;
WHEN2=>
=”1101101”;
WHEN3=>
=”1111001”;
WHEN4=>
=”0110011”;
WHEN5=>
=”1011011”;
WHEN6=>
=”0011111”;
WHEN7=>
=”1110000”;
WHEN8=>
=”1111111”;
WHENOTHERS=>
=”0000000”;
ENDCASE;
ELSE
DISPLAY<
--EN为0,数码管无显示
ENDIF;
ENDPROCESS;
值得注意的是,本程序是组合逻辑电路,PROCESS的敏感信号参数表中一定要有NUM;
否则编译时会提示如下出错信息:
“ElseClausefollowingaClockedgemustholdthestateofsignal‘Display’”。
出现此提示信息的原因是:
综合器将EN误判为时钟信号,并试图将程序综合成时序逻辑电路,但该程序的格式又不符合综合器对时钟信号描述的要求,因此无法综合。
3.2按键去抖电路
键盘的按键闭合与释放瞬间,输入的信号会有毛刺。
如果不进行消抖处理,系统会将这些毛刺误以为是用户的另一次输入,导致系统的误操作。
防抖电路有很多种,最简单、最容易理解的就是计数法。
其原理是对键值进行计数,当某一键值保持一段时间不改变时(计数器达到一定值后),才确认它为有效值;
否则将其判为无效键值,重新对键值进行计算[2]。
下面是基于计数法的防抖电路程序:
ENTUTYANTITWITTERIS
(CLOCK:
NUMIN:
NUMOUT:
OUTINTEGERRANGE0TO15);
ARCHITECTUREBEHAVIOROFANTITWITTERIS
SIGNALTEMPNUM:
INTEGERRANGE0TO15;
SIGNALCOUNTER:
INTEGERRANGE0TO31;
SIGNALSTART:
STD_LOGIC;
PROCESS(CLOCK)
IFRISING_EDGE(CLOCK)THEN
IFSTART=‘0’THEN--上电后立即对输出的键值赋予无效值
TEMPNUM<
=15;
--此处沿将15作为无效值
NUMOUT<
--此无效值务必随实际情况改变
START<
=‘1’;
ELSE
IFNUMIN<
=TEMPNUMTHEN--上一键值与此键值不同
TENPNUM<
=NUMIN;
--记录此键值
COUNTER<
=‘0’;
--并对计数器清0,准备对此键值计时
ELSE
IFCOUNTER31THEN;
--当键值保持31个时钟周期不变时
--即确定为有效键值,并输出
COUNTER<
=COUNTER+1;
ENDIF;
ENDIF;
3.3状态机设计
3.3.1状态机的6种状态及状态转移
本状态机有6种状态,分别是WAITSTATE、ATOB、BTOA、ASCORE、BSCORE和FINALRESULT,其含义如表1所示。
表1状态机的6种状态及含义
状态
含义
WAITSTATE
等待状态,等待A或B方开球
ATOB
球从A向B方移动
BTOA
球从B向A方移动
ASCORE
A得一分
BSCORE
B得一分
FINALRESULT
比赛结束(最终判分),在此状态下需要按复位键,才能开始下一轮比赛
结合表1,从图6中很清楚地看出乒乓游戏机比赛过程中球的移动情况,及加分方法,还可以初步了解到本状态机设计的基本思路。
图6乒乓游戏机状态转移图
3.3.2状态机/球台控制程序
状态机是种很重要的时序电路,也是本设计的核心部件。
状态机属于时序电路范畴,实现一个控制功能更为方便,并提高了控制速度[10]。
本次设计中状态机的符号如图7所示。
图7状态机符号
在本设计中,状态机用两个信号表示状态:
STATE表示当前状态,TABLESTATE表示下一个状态。
此状态机由两个进程构成,状态机的输入/输出引脚的作用如表2所示。
其中SCOREAL[3..0]、SCOREAH[3..0]、SCOREBL[3..0]、SCOREBH[3..0]用七段BCD码译码器显示得分情况,而SCOREA、SCOREB用二进制进行加分,由记分器反馈回来。
表2输入/输出引脚的作用
引脚
作用
CLK
10Hz的时钟,可由系统时钟分频得到。
此时时钟决定了球移动的速度,可根据实际需要调整。
RESET
复位键,比赛重新开始,记分器清0
STARTA、STARTB
A和B双方的开始的开球键
HITA、HITB
A和B双方的击球键(可以将其与开球键合并)
CLEAR
将记分器清0(给记分器的控制信号)
INCREASEA、INCREASEB
分别为A、B双方的加分信号(给记分器的控制信号)
SCOREAL[3..0]SCOREAH[3..0]
SCOREBL[3..0]SCOREBH[3..0]
SCOREA、SCOREB
A、B双方的分数(由记分器给出)
LIGHT[4..0]
接5个发光二极管
AWIN、BWIN
分别接发光二极管,表示A或B方胜出
状态机的程序如下:
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYSTATEMACHINEIS
PORT(CLK:
RESET:
STARTA,HITA,STARTB,HITB:
SCOREA,SCOREB:
ININTEGERRANGE0TO21;
CLEAR,INCREASEA,INCREASEB:
OUTSTD_LOGIC;
TABLELIGHT:
OUTSTD_LOGIC_VECTOR(0TO4);
AWIN,BWIN:
OUTSTD_LOGIC);
ARCHITECTUREBEHAVIOROFSTATEMACHINEIS
TYPESTATE_TYPEIS(WAITSTATE,ATOB,BTOA,ASCORE,BSCORE,FINALRESULT);
SIGNALSTATE:
STATE_TYPE;
SIGNALTABLESTATE:
INTEGERRANGE0TO4;
PROCESS(CLK,RESET)
IFRESET='
1'
THEN--按下复位键,比赛开始
STATE<
=WAITSTATE;
--进入等待状态
CLEAR<
='
;
--记分器清零
AWIN<
0'
BWIN<
ELSIFRISING_EDGE(CLK)THEN
CASESTATEIS
WHENWAITSTATE=>
INCREASEA<
INCREASEB<
IF((SCOREA=21)OR(SCOREB=21))THEN--如果一方先得到21分
STATE<
=FINALRESULT;
--比赛结束
IFSTARTA='
THEN--如果A开球
STATE<
=ATOB;
--球从A向B方移动
TABLESTATE<
=0;
--A方第一个灯点亮
IFSTARTB='
THEN--如果B开球(A、B开球有
--定的优先级区别
=BTOA;
--球从B向A方移动
TABLESTATE<
=4;
--B方第一个灯亮
ELSE
WHENATOB=>
--球从A向B移动的过程
IFHITB='
THEN--如果检测到B方击球
IFTABLESTATE<
=2THEN--若未过网提前击球
=ASCORE;
--判为A胜
ELSE
--若过了网击球,球从B
--向A移动
ELSE--若未检测到B方击球
IFTABLESTATE=4THEN--如果离B方最近的灯
--已经亮
--判为A胜
=TABLESTATE+1;
--否则球继续移动
WHENBTOA=>
--球从B向A移动的过程
IFHITA='
THEN--如果检测A方击球
IFTABLESTATE