基于FPGA的乒乓球游戏机设计

摘要

在现代电子设计领域,微电子技术迅猛发展,无论是系统设计、电路设计,还是芯片设计,其设计的复杂度都在增加,传统的手工设计方法已经不能满足设计者的要求,急需新的设计工具来解决。EDA技术的迅速发展顺应了时代的发展,使得电子设计自动化技术有了新的、快的发展,其重要程度日益突出。本文设计了基于FPGA的,用Verilog HDL语言描述的乒乓球游戏机的设计。它由控制模块、数码管的片选信号模块、送数据模块和7段译码器模块组成,连接形成乒乓球游戏机的顶层电路。在QuartusⅡ软件上用Verilog HDL语言分别对每个模块进行描述,然后在软件上进行编译、仿真,最终实现乓乓球比赛的基本过程和规则,并能自动裁判和计分,达到设计的要求。

关键词:EDA ;FPGA ;Verilog HDL Abstract

In the field of modern electronic design, the rapid development of microelectronic

technology,whether the system design, circuit design and chip design, the design is more complex, the traditional manual design methods have been unable to meet the

requirements of designers,in urgent need of new design tools to solve. The rapid

development of EDA technology to the development of the times, the electronic design automation technology has been the development of new, fast, its importance is

outstanding day by day. This paper is designed based on FPGA, the design of table tennis game is described with Verilog HDL language. It consists of control module, chip select signal module, digital tube to send data module and the 7 segment

decoder modules, the top-level circuit connected to form a table tennis game. In the Quartus software by Verilog HDL language for each module are described, and then the compiler, simulation in software, realize the basic process and the rules of table

tennis table tennis competition, and can automatically judge and score, to meet the design requirements.

Keywords: EDA; FPGA; Verilog HDL

第一章 引言

1.1课题研究的背景

随着微电子技术的飞跃发展,无论是系统级设计、电路设计还是芯片设计,它的复杂程度都在不断的增加,而且它的发展速度也越来越快。这时,仅仅依靠传统的电子设计方法已经不能满足需求。EDA技术的兴起与发展给电子设计带来了革命性的变化,推动了微电子技术的迅猛发展,电子学进入一个崭新的时代。

1.2课题研究的目的

EDA技术是现代电子设计领域的一门技术,它提供了基于计算机和信息技术的电路设计方法,不依托其他设计工具,仅以计算机为工具,在EDA软件上完成设计、编译、仿真。EDA技术正以空前的发展速度和规模渗透到各行各业。 在这个快节奏生活的社会,人们外出的休闲娱乐活动越来少,而越来越多的电子游戏解决了这个问题,人们可以在家中玩各种休闲娱乐节目。所以设计了基于FPGA的两人乒乓球游戏机,让人们能在忙碌中有时间体验下体育节目的乐趣。FPGA器件具有高开发周期短,高集成度,现场可修改等特点,因此十分有必要对FPGA进行详细认真的研究。硬件描述语言VHDL功能性强,灵活性高,覆盖面广,用以甚高速集成电路硬件描述语言,具有很好的实用性。总的来说,现代EDA技术的基本特征是采用高级语言(VHDL、Verilog HDL等)描述,具有系统级仿真和综合的能力。它必将成为21世纪不可或缺的电子设计工具,必将影响这个世纪的发展。

2.1EDA基础

2.1.1EDA定义

EDA是Electronics Design Automation(电子设计自动化)的缩写,以计算机为工作平台;在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的定义发展而来的;是利用电子技术基础、计算机技术、智能化技术等多种应用技术而开发成的整套电子CAD软件;是一种帮助从事电子元件产品和系统设计的电子工作者的综合技术。

2.1.2EDA技术的发展历程

集成电路的飞快发展不断给EDA技术提出更高的要求,对EDA技术的发展起了巨大的推动作用。从20世纪60年代中期开始,人们不断地开发出各种计算机辅助设计工具来帮助设计人员进行集成电路和电子系统的设计。经历了计算机辅助设计、计算机辅助工程设计和电子系统设计自动化这3个阶段,如图2.1所示。

图2.1 EDA技术的发展历程

(1)CAD阶段

20世纪70年代,随着中、小规模集成电路的兴起和应用,传统的手工设计印刷电路板和集成电路的方法已经不能满足设计精度和效率的要求,于是电子设计工程师们开始在二维平面图形上进行计算机辅助设计,这样就产生了第一代

EDA工具,设计者从繁杂、机械的、手工布局和布线工作中解放了出来。

(2)CAE阶段

20世纪80年代以后,集成电路的规模越来越大,电子系统设计的复杂也在增加,电子设计自动化的工具逐步完善和发展起来,设计者们尤其在设计方法、设计工具集成化方面取得了很大的进步。为了适应电子产品在规模和制作上的需要,以计算机仿真和自动布线为核心的第二代EDA技术应运而生。其特点是以软件设计工具为核心,通过软件完成产品的开发、设计、分析、生产和测试等工作。

(3)ESDA阶段

20世纪90年代,设计师们逐步从使用硬件转向去设计硬件,从单个电子产品开发转向系统级电子产品开发(及片上系统集成)。因此,这时的EDA工具是以系统级设计为核心,包括结构综合与系统行为级描述,系统仿真与测试验证,系统决策与文件生成,系统划分与指标分配等一整套的电子系统设计工具。这时的EDA工具不仅具有电子系统设计的能力,而且具有独立于生产工艺和厂家的系统级设计能力。第三代EDA工具的出现,极大地提高了电子系统设计的效率,让设计工程师们开始能够以概念来驱动设计工程的梦想。

2.1.3EDA技术的发展趋势

随着微电子技术的不断发展与进步和市场需求的不断增长,EDA技术在21世纪后得到了迅猛的发展,这一发展趋势表现在以下几个方面:

(1)软件IP核在微电子的产业领域、设计应用领域和技术领域得到进一步的巩固与发展。

(2)使支持硬件描述语言仿真和设计的EDA软件不断地强大起来。

(3)EDA使得系统与器件、专用集成电路ASIC与FPGA、模拟与数字、行为与结构、软件与硬件等的界限越来越模糊。

(4) EDA技术保护了设计者的电子设计成果的知识产权。

(5)大规模的电子系统都是以EDA为工具设计的,正以飞快的速度渗透到IP核模块。

(6)更大规模的可编程逻辑器件正在推向市场,使得设计更为广泛与便捷。

2.1.4EDA技术的基本特征

总的来说,现代EDA技术是采用高级程序语言描述,具有系统级仿真和综合的能力。它主要采用并行工程和“自顶向下”的设计方法,使开发人员从一开始就能考虑到产品生成周期的诸多方面,包括质量、成本、开发时间及用户的需求等。然后从系统设计开始,在顶层进行功能方框图的划分和结构的设计,在方框图一级进行仿真、纠错,并用VHDL、Verilog-HDL等硬件描述语言对顶层的系统进行功能和行为上的描述,在系统一级进行验证与仿真。最后,用逻辑综合优化工具生成具体的门级逻辑电路的网表,其对应的物理实现级可以是印刷电路板或者是专用的集成电路。近年来,硬件描述语言等设计数据格式逐步形成一种标准,不同的设计风格和应用要求使得各具特色的EDA工具被集成在相同的设计方法上,EDA技术的设计框架日趋标准化。

2.1.5EDA技术的基本工具

集成电路技术的不断发展对EDA技术提出了更高的要求,促进了EDA技术向更高的层次发展。但实际来说,EDA系统的设计能力一直难以满足集成电路的要求。EDA工具的发展经历了两个阶段,即物理工具阶段和逻辑工具阶段。 现在,人们已经开发了很多计算机辅助设计工具来帮助设计集成电路,常见的EDA工具有编辑器、仿真器、检查/分析工具和优化/综合工具等,如图2.2所示。

图2.2 EDA设计工具的分类

2.1.6EDA技术的基本设计思路

(1)EDA技术的电路级设计

电路级设计工作,首先,应该先确定合适的设计方案,然后选择方便实现该方案的元器件,接着就可根据所选元器件设计符合要求的电路原理图,再接着进行一次仿真。其目的是检验此设计方案在元件模型库支持下的功能方面是否正确,这样,设计工作就进入了轨道。第一次仿真通过后,就开始进行PCB的自动布局布线,此布局布线要根据原理图产生的电路连接网络表来进行。然后,对PCB进行分析,将分析结果反馈给电路图,并再次仿真。这样,PCB板在实际工作中的可行性就一目了然了。综上,EDA的电路级设计可在实际的电子系统产生之前就了解其功能特性,从而降低其设计风险,降低开发成本,缩短其开发周期,使得设计人员能够更好、更方便的设计。电路级设计工作流程如图2.3

图2.3 电路级设计工作流程图

(2)EDA技术的系统级设计

EDA技术的系统级设计方法是采用“自顶向下”的思路来设计的,让开发者一开始就可了解到产品的开发周期、生产成本等。设计者首先从系统方案入手,

进行顶层的划分和结构设计;然后,用VHDL语言等硬件描述语言对系统进行深刻描述;接着就用编辑器将其转换成标准的VHDL文件,再接着验证系统功能设计的正确性;再接着就用逻辑综合优化工具生成具体的门级电路的网络表;其后,进行时序仿真;最后,就到了系统的物理实现级,将其变成FPGA等。EDA技术的系统级设计如图2.4所示。

图2.4 EDA技术的系统级设计

2.1.7 EDA的设计流程

EDA的设计流程是“自顶向下”的设计思路。设计流程如图2.5所示。

图2.5 应用于FPGA/CPLD的EDA开发流程

2.2 FPGA的概念与特点

FPGA(Field-Programmable Gate Array),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。

目前以硬件描述语言(Verilog 或 VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至 FPGA 上进行测试,是现代 IC 设计验证的技术主流。这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(Flip-flop)或者其他更加完整的记忆块。

系统设计师可以根据需要通过可编辑的连接把FPGA内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。一个出厂后的成品FPGA的逻辑块和连接可以按照设计者而改变,所以FPGA可以完成所需要的逻辑功能。

FPGA一般来说比ASIC(专用集成芯片)的速度要慢,无法完成复杂的设计,而且消耗更多的电能。但是他们也有很多的优点比如可以快速成品,可以被修改来改正程序中的错误和更便宜的造价。厂商也可能会提供便宜的但是编辑能力差的FPGA。因为这些芯片有比较差的可编辑能力,所以这些设计的开发是在普通的FPGA上完成的,然后将设计转移到一个类似于ASIC的芯片上。另外一种方法是用CPLD(复杂可编程逻辑器件备)。

早在1980年代中期,FPGA已经在PLD设备中扎根。CPLD和FPGA包括了一些相对大数量的可以编辑逻辑单元。CPLD逻辑门的密度在几千到几万个逻辑单元之间,而FPGA通常是在几万到几百万。

CPLD和FPGA的主要区别是他们的系统结构。CPLD是一个有点限制性的结构。这个结构由一个或者多个可编辑的结果之和的逻辑组列和一些相对少量的锁定的寄存器。这样的结果是缺乏编辑灵活性,但是却有可以预计的延迟时间和逻辑单元对连接单元高比率的优点。而FPGA却是有很多的连接单元,这样虽然让它可以更加灵活的编辑,但是结构却复杂的多。

CPLD和FPGA另外一个区别是大多数的FPGA含有高层次的内置模块(比如加法器和乘法器)和内置的记忆体。一个因此有关的重要区别是很多新的FPGA支持完全的或者部分的系统内重新配置。允许他们的设计随着系统升级或者动态重新配置而改变。一些FPGA可以让设备的一部分重新编辑而其他部分继续正常运行。

FPGA采用了逻辑单元阵列LCA(Logic Cell Array)这样一个概念,内部包括可配置逻辑模块CLB(Configurable Logic Block)、输出输入模块IOB(Input Output Block)和内部连线(Interconnect)三个部分。FPGA的基本特点主要有:

1)采用FPGA设计ASIC电路,用户不需要投片生产,就能得到合用的芯片。

2)FPGA可做其它全定制或半定制ASIC电路的中试样片。

3)FPGA内部有丰富的触发器和I/O引脚。

4)FPGA是ASIC电路中设计周期最短、开发费用最低、风险最小的器件之一。

5) FPGA采用高速CHMOS工艺,功耗低,可以与CMOS、TTL电平兼容。 可以说,FPGA芯片是小批量系统提高系统集成度、可靠性的最佳选择之一。

FPGA是由存放在片内RAM中的程序来设置其工作状态的,因此,工作时需要对片内的RAM进行编程。用户可以根据不同的配置模式,采用不同的编程方式。加电时,FPGA芯片将EPROM中数据读入片内编程RAM中,配置完成后,FPGA进入工作状态。掉电后,FPGA恢复成白片,内部逻辑关系消失,因此,FPGA能够反复使用。FPGA的编程无须专用的FPGA编程器,只须用通用的EPROM、PROM编程器即可。当需要修改FPGA功能时,只需换一片EPROM即可。这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。因此,FPGA的使用非常灵活。

Verilog HDL语言简介

Verilog HDL和VHDL是目前世界上最流行的两种硬件描述语言(HDL:Hardware Description Language),均为IEEE标准,被广泛地应用于基于可编程逻辑器件的项目开发。二者都是在20世纪80年代中期开发出来的,前者由Gateway Design Automation公司(该公司于1989年被Cadence公司收购)开发,后者由美国军方研发。

HDL语言以文本形式来描述数字系统硬件结构和行为,是一种用形式化方法来描述数字电路和系统的语言,可以从上层到下层来逐层描述自己的设计思想。即用一系列分层次的模块来表示复杂的数字系统,并逐层进行验证仿真,再把具体

的模块组合由综合工具转化成门级网表,接下去再利用布局布线工具把网表转化为具体电路结构的实现。目前,这种自顶向下的方法已被广泛使用。概括地讲,HDL语言包含以下主要特征:

Verilog HDL语言既包含一些高级程序设计语言的结构形式,同时也兼顾描述硬件线路连接的具体结构。

通过使用结构级行为描述,可以在不同的抽象层次描述设计。Verilog HDL语言采用自顶向下的数字电路设计方法,主要包括3个领域5个抽象层次。

Verilog HDL语言是并行处理的,具有同一时刻执行多任务的能力。这和一般高级设计语言(例如C语言等)串行执行的特征是不同的。

Verilog HDL语言具有时序的概念。一般的高级编程语言是没有时序概念的,但在硬件电路中从输入到输出总是有延时存在的,为了描述这一特征,需要引入时延的概念。HDL语言不仅可以描述硬件电路的功能,还可以描述电路的时序。

2.1.1 Verilog HDL语言的历史 1983年,Gateway Design Automation(GDA)硬件描述语言公司的Philip Moorby首创了Verilog HDL。后来Moorby成为Verilog HDL-XL的主要设计者和Cadence公司的第一合伙人。1984至1986年,Moorby设计出第一个关于Verilog HDL的仿真器,并提出了用于快速门级仿真的XL算法,使Verilog HDL语言得到迅速发展。1987年Synonsys公司开始使用Verilog HDL行为语言作为综合工具的输入。1989年Cadence公司收购了Gateway公司,Verilog HDL成为Cadence公司的私有财产。1990年初,Cadence公司把Verilog HDL和Verilog HDL-XL分开,并公开发布了Verilog HDL。随后成立的OVI(Open Verilog HDL International)组织负责Verilog HDL的发展并制定有关标准,OVI由Verilog HDL的使用者和CAE供应商组成。1993年,几乎所有ASIC厂商都开始支持Verilog HDL,并且认为Verilog HDL-XL是最好的仿真器。同时,OVI推出2.0版本的Verilong HDL规范,IEEE则将OVI的Verilog HDL2.0作为IEEE标准的提案。1995年12月,IEEE制定了Verilog HDL的标准IEEE1364-1995。目前,最新的Verilog语言版本是2000年IEEE公布的Verilog 2001标准,其大幅度地提高了系统级和可综合性能。

Verilog HDL的主要能力

Verilog HDL既是一种行为描述语言,也是一种结构描述语言。如果按照一定的规则和风格编写代码,就可以将功能行为模块通过工具自动转化为门级互连的结构模块。这意味着利用Verilog语言所提供的功能,就可以构造一个模块间的清晰结构来描述复杂的大型设计,并对所需的逻辑电路进行严格的设计。 下面列出的是Verilog语言的主要功能:

1.可描述顺序执行或并行执行的程序结构;

2.用延迟表示式或事件表达式来明确地控制过程的启动时间;

3.通过命名的事件来触发其他过程里的激活行为或停止行为;

4.提供了条件和循环等程序结构;

5.提供了可带参数且非零延续时间的任务程序结构;

6.提供了可定义新的操作符的函数结构;

7.提供了用于建立表达式的算术运算符、逻辑运算符和位运算符;

8.提供了一套完整的表示组合逻辑基本元件的原语;

9.提供了双向通路和电阻器件的描述;

10.可建立MOS器件的电荷分享和衰减模型;

11.可以通过构造性语句精确地建立信号模型;

此外,Verilog HDL语言还有一个重要特征就是:和C语言风格有很多的相似之处,学习起来比较容易。

Verilog HDL和VHDL的区别

Verilog HDL和VHDL都是用于逻辑设计的硬件描述语言。VHDL在1987年成为IEEE标准,Verilog HDL则在1995年才成为IEEE标准,这是因为前者是美国军方组织开发的,而后者则是从民间公司转化而来,要成为国际标准就必须放弃专利。相比而言,Verilog HDL具有更强的生命力。

Verilog HDL和VHDL的相同点在于:都能形式化地抽象表示电路的行为和结构;支持逻辑设计中层次与范围的描述;可以简化电路行为的描述;具有电路仿真和验证机制;支持电路描述由高层到低层的综合转换;与实现工艺无关;便于管理和设计重用。

但Verilog HDL和VHDL又有各自的特点,由于Verilog HDL推出较早,因而拥有更广泛的客户群体、更丰富的资源。Verilog HDL还有一个优点就是容易掌握,如果具有C语言学习的基础,很快就能够掌握。而VHDL需要Ada编程语言基础,一般需要半年以上的专业培训才能够掌握。传统观点认为Verilog HDL在系统级抽象方面较弱,不太适合特大型的系统。但经过Verilog 2001标准的补充之后,系统级表述性能和可综合性能有了大幅度提高。当然,这两种语言也仍处于不断完善的过程中,都在朝着更高级描述语言的方向前进。

Verilog HDL设计方法

1. 自下而上的设计方法

自下而上的设计是传统的设计方法,是从基本单元出发,对设计进行逐层划分的过程。这种设计方法与用电子元件在模拟实现板上建立一个系统的步骤有密切的关系。优、缺点分别如下:

优点 :

设计人员对这种设计方法比较熟悉;实现各个子模块所需的时间较短。 缺点 :

对系统的整体功能把握不足;由于必须先对多个子模块进行设计,因此实现整个系统的功能所需的时间长;另外,对设计人员之间相互协作也有较高的要求。

2.自上而下的设计方法

自上而下的设计是从系统级开始,把系统划分为基本单元,然后再把基本单元划分为下一层次的基本单元,直到可用EDA元件实现为止。这种方法的优、缺点如下。

优点:

在设计周期开始就做好了系统分析;由于设计的主要仿真和调试过程是在高层完成的,所以能够早期发现结构设计上的错误,避免了设计工作的浪费,方便了系统的划分和整个项目的管理,可减少设计人员劳动,避免了重复设计。 缺点 :

得到的最小单元不标准,且制造成本高。

3.混合的设计方法

复杂数字逻辑电路和系统设计过程,通常是以上两种设计方法的结合。设计时需要考虑多个目标的综合平衡。在高层系统用自上而下的设计方法实现,而使用自下而上的方法从库元件或以往设计库中调用已有的设计单元。混合设计方法兼有以上两种方法的优点,并且可使用先进的矢量测试方法。

第二章 设计思想

1.基本原理

用8个(或更多个)LED排成一条直线,以中点为界,两边各代表参赛双方的位置,其中一只点亮的LED指示球的当前位置,点亮的LED依此从左到右,或从右到左,其移动的速度应能调节。当“球”(点亮的那只LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。若击中,则球向相反方向移动;若未击中,则对方得1分。一方得分时,电路自动响铃3秒,这期间发球无效,等铃声停止后方能继续比赛。设置自动记分电路,甲、乙双方各用2位数码管进行记分显示,每计满21分为1局。甲、乙双方各设一个发光二极管,表示拥有发球权,每隔5次自动交换发球权,拥有发球权的一方发球才有效。根据乒乓球比赛的过程和规则,首先游戏开始,如果一方非正确击球则另一方加分,当分数大于21时获胜,游戏结束,我们把设计流程规定如图1.1所示。状态机设置了7个状态,分别是“等待发球状态”,“第一盏灯亮状态”,“第八盏灯亮状态”,“球向乙移动状态”,“ 球向甲移动状态”,“允许甲击球状态”,“允许乙击球状态”。这是该程序中起决定作用的七个状态。开始的时候处于“等待发球状态”,若甲发球则状态转移到“第一盏灯亮状态”,若乙发球则转移到“第八盏灯亮状态”,具体说明以甲球为例。

若发球后乙没有提前击球——规定球移动到对方第一个发光二极管时允许击球,那么状态机从“第一盏灯亮状态”转移到“球向乙移动状态”。若在“球向乙移动状态”乙仍然没有提前击球,状态就转移到“允许乙击球状态”,在此状态下,如果乙击球了,那么状态就转移到“ 球向甲移动状态”。在“第一盏灯

亮状态”, “球向乙移动状态”中,如果乙击球了 ,就算提前击球,这样甲得分,状态转移到“等待发球状态”等待发球,“ 球向甲移动状态”之后的过程和前面的过程只不过是甲乙角色的调换而已。

2.设计框图

图1流程图

图2 基本原理

第三章 设计步骤和调试过程

1、模块设计和相应模块代码

(1)发球选择模块的设计

游戏开始时,必须先决定发球权在哪一方。同时,在游戏进行的过程中,必须能够正确交换甲乙双方发球权。相应的代码如下:

module Permissions(clk,res,in1,in2,out1,out2,en_jia,en_yi);

input clk,res,in1,in2;

output out1,out2,en_jia,en_yi;

reg out1,out2,en_jia,en_yi;

wire w1,w2,a,b;

or u2(w1,in1,in2);

add4 u1(.res(res),.c(w1),.cnt(w2));

select u3(.cnt(w2),.a(a),.b(b));

parameter[1:0] s0=1'b00,s1=1'b01;

reg[1:0] current_state,next_current;

always@(posedge clk or negedge res)

begin

if(!res)

current_state

else

current_state

end

always@(current_state or next_current)

begin

case(current_state)

s0:

begin

out1

en_jia

en_yi

out2

if(a==1)

next_current

else

next_current

end

s1:

begin

out1

en_jia

en_yi

out2

if(b==1)

next_current

else

next_current

end

endcase

end

endmodule

(2)状态机编程实现

状态机设置了7个状态,它们代表的具体数值依次是0到6。在波形模拟图中是用数值来表示状态的。

在整个程序中,状态机起的是中央控制器的作用,由它控制的信号来影响整个程序中的其他相关部分,如记分部分,发光二极管部分。乒乓球游戏机中有两个计数器,分别记忆甲和乙的得分,用发光二极管的轮流发光表示球的移动轨迹。状态机的进程如下:

module state_machine (clk,res,key1,key2,led,jia,yi,en_jia,

en_yi,win,t1,t2);

input clk,res,key1,key2,en_jia,en_yi,win,t1;

output jia,yi,t2;

reg jia,yi,t2;

output[7:0] led;

reg[7:0] led;

parameter[7:0]

s0=8'b0000_0001,s1=8'b0000_0010,s2=8'b0000_0100,s3=8'b0000_1000,

s4=8'b0001_0000,s5=8'b0010_0000,s6=8'b0100_0000,s7=8'b1000_0000; reg[7:0] current_state,next_current;

/*--------------------每个时钟沿转跳一次逻辑状态

--------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

current_state

else

current_state

end

/*--------------------产生下一状态的组合逻辑

-----------------------*/

always@(current_state)

begin

case(current_state)

s0:

if((key1==1)&&(en_jia==1)) next_current

else

if((key2==1)&&(en_yi==1)) next_current

else next_current

s1:

if(led==8'b0000_0001) next_current

else next_current

s2:

if(led==8'b1000_0000) next_current

else next_current

s3:

if((t1==1)&&(key2==1)) next_current

else next_current

s4:

if((t1==1)&&(key1==1)) next_current

else next_current

s5:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

s6:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

endcase

end

/*--------------------状态机输出的组合逻辑

-------------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

begin

led

t2

jia

yi

end

else

begin

case(current_state)

s0:

led

s1:

begin

led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

s2:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

end

s3:

begin

led

t2

end

s4:

begin

led

t2

end

s5:

jia

s6:

yi

s7:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

endcase

end

end

endmodule

(3)得分判断模块的设计

在一方并没有击球成功时,需要进行判定,并且鸣响蜂鸣器来提示这个球某一方没有击中,而另一方得分。于是编写相应程序。

module goal(res,buzz,jia,yi,en);

input res,jia,yi;

output buzz,en;

reg buzz,en;

reg[12:0] q;

wire w;

or u1(w,jia,yi);

always@(posedge w or negedge res)

begin

if(~res)

begin

q

en

buzz

end

else

begin

if(q==2999)

begin

en

q

buzz

end

else

begin

q

en

buzz

end

end

end

endmodule

(4)记分译码器的设计

七段译码器是在数学电路设计中经常用到的显示电路。所谓七段译码器,其实是由7段发光二极管组成的用于显示数字的器件。记分译码器(encoder):由于记分需要显示出来,所以要使用七段译码器。而状态机中的记分是由2个4位二进制码来表示的。以下程序就是实现从4位二进制码转换成七段译码显示。 module encoder(in1,in2,out1,out2);

input[3:0] in1,in2;

output[7:0] out1,out2;

reg[7:0] out1,out2;

always@(*)

case(in1) //共阳数码管编码

8'b0000:out1=8'b1100_0000; //0

8'b0001:out1=8'b1111_1001; //1

8'b0010:out1=8'b1010_0100; //2

8'b0011:out1=8'b1011_0000; //3

8'b0100:out1=8'b1001_1001; //4

8'b0101:out1=8'b1001_0010; //5

8'b0110:out1=8'b1000_0010; //6

8'b0111:out1=8'b1111_1000; //7

8'b1000:out1=8'b1000_0000; //8

8'b1001:out1=8'b1001_0000; //9

default:out1=8'b1100_0000;

endcase

always@(*)

case(in2)

8'b0000:out2=8'b1100_0000; //0

8'b0001:out2=8'b1111_1001; //1

8'b0010:out2=8'b1010_0100; //2

8'b0011:out2=8'b1011_0000; //3

8'b0100:out2=8'b1001_1001; //4

8'b0101:out2=8'b1001_0010; //5

8'b0110:out2=8'b1000_0010; //6

8'b0111:out2=8'b1111_1000; //7

8'b1000:out2=8'b1000_0000; //8

8'b1001:out2=8'b1001_0000; //9

default:out2=8'b1100_0000;

endcase

endmodule

这个记分译马电路是针对乒乓球游戏机的特点进行的特别设计,采用的是全部列举的方法。

(4)顶层的设计

顶层综合各个模块设计,这样就完成了数字乒乓球游戏机的VHDL源程序编写。 module table_tennis(clk,res,key1,key2,led,smg1,smg2,smg3,smg4,buzz, jia_led,yi_led);

input clk,res,key1,key2;

output buzz,jia_led,yi_led;

output[7:0] led,smg1,smg2,smg3,smg4;

wire[7:0] smg1,smg2,smg3,smg4,led;

wire

w1,w2,w3,w4,w5,jia_led,yi_led,buzz,win,win1,win2,en,en_jia,en_yi,t1,t2;

and D1(w3,w5,en_jia);

and D2(w4,w5,en_yi);

or D3(win,win1,win2);

state_machine

u0(.clk(clk),.res(res),.jia(w1),.yi(w2),.en_jia(w3),.en_yi(w4),.key1(key1),

.key2(key2),.led(led),.win(win),.t1(t1),.t2(t2));

score1

u1(.res(res),.jia(w1),.s1(smg1),.s2(smg2),.win(win1));

score2

u2(.res(res),.yi(w2),.s1(smg3),.s2(smg4),.win(win2));

Permissions

u3(.clk(clk),.res(res),.in1(w1),.in2(w2),.out1(jia_led),.out2(yi_led),.en_jia(en_jia),.en_yi(en_yi));

goal u4(.res(res),.jia(w1),.yi(w2),.en(w5),.buzz(buzz)); timer u5(.t1(t1),.t2(t2));

endmodule

从顶层设计中可以看到,控制整个乒乓球游戏机运转的就是状态机进程,它队各个外围部分起控制作用。它是整个程序的核心,起到一个中心控制器的作用。而外围的部分,比如分数显示,球的轨迹,都是通过它传出的信号来控制。状态机中的信号变化同时就可以影响到外围的显示部分——发光二极管和七段译码器,从而表示出当时的乒乓球位置和双方分数情况。

第四章 顶层电路、仿真及调试

1.顶层电路图

根据程序所画的顶层电路图如图3

图3

2.仿真

编译完成后仿真如图

图4

A方先发球,B方在恰当的时刻击球成功,当球回到A方时,A方没有及时接到

球的仿真波形

图5

A方两次成功发球后B方都没有接到球,A方得2分的仿真波形图

图6

B方成功发球后,A方在恰当的时刻成功接到球,而B方没有接到球的情况

3、实验调试结果

通过调试我们可以观察到,8个LED排成一条直线,以中点为界,两边各代表参赛双方的位置,其中一只点亮的LED指示球的当前位置,点亮的LED依此从左到右,或从右到左,其移动的速度应能调节。当“球”(点亮的那只LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。若击中,则球向相反方向移动;若未击中,则对方得1分。一方得分时,电路自动响铃3秒,这期间发球无效,等铃声停止后方能继续比赛。设置自动记分电路,甲、乙双方各用2位数码管进行记分显示,每计满21分为1局。甲、乙双方各设一个发光二极管,表示拥有发球权,每隔5次自动交换发球权,拥有发球权的一方发球有效。

第五章

结论

采用Verilog HDL语言编程,基于FPGA成功设计了一款乒乓球比赛的游戏机,通过仿真验证可知,结果满足了设计的要求。系统能够模拟两人乒乓球比赛的基本过程和规则,并能自动裁判和计分,能有效模拟实际的乒乓球比赛。该系统可进一步改进,改进思路为:改用人体感应器官来采集击球信号,采用FPGA产生视频信号送到电视机,更直观地展示乒乓球运动轨迹,从而真正实现人机互动,优化虚拟效果。

参考文献:

[1]朱正伟.EDA技术及应用[M].清华大学出版社,2005年10月第一版.

[2]刘昌华.EDA技术与应用—基于QuartusⅡ和VHDL[M].北京航空航天大学出版社,2012年8月第一版.

[3]潘松 黄继业.EDA技术实用教程[M].科学出版社,2002年10月第一版.

[4]包明.EDA技术与可编程器件的应用[M].北京航空航天大学出版社,2007年10月第一版.

[5]江国强.EDA技术与应用[M].电子工业出版社,2004年8月第一版.

[6]张文爱.EDA技术与FPGA应用设计[M].电子工业出版社,2012年1月第一版.

[7]谭慧生 张昌凡.EDA技术与应用[M].西安电子科技大学出版社,2001年9月第一版.

[8]汉泽西.EDA技术及其应用[M].北京航空航天大学出版社,2004年5月第一版.

[9]王振红.VHDL数字电路设计与应用教程[M].机械工业出版社,2003.

[10]付家才.EDA技术与FPGA应用设计[M].电子工业出版社,2012,(01).

[11]赖杰.VHDL与数字电路设计[M].科学出版社,2001.

[12]李慧.PLD与数字系统设计[M].西安电子科技大学出版社,2005.

[13]王行.EDA技术入门与提高[M].西安:西安电子科技大学出版社,2005.

[14]田耘.Xilinx FPGA开发实用教程[M].清华大学出版社,2008.

[15]杨跃.FPGA应用开发实战技巧精粹[M].人民邮电出版社,2005.

附录:

Verilog HDL语言源程序:

module table_tennis(clk,res,key1,key2,led,smg1,smg2,smg3,smg4,buzz, jia_led,yi_led);

input clk,res,key1,key2;

output buzz,jia_led,yi_led;

output[7:0] led,smg1,smg2,smg3,smg4;

wire[7:0] smg1,smg2,smg3,smg4,led;

wire

w1,w2,w3,w4,w5,jia_led,yi_led,buzz,win,win1,win2,en,en_jia,en_yi,t1,t2;

and D1(w3,w5,en_jia);

and D2(w4,w5,en_yi);

or D3(win,win1,win2);

state_machine

u0(.clk(clk),.res(res),.jia(w1),.yi(w2),.en_jia(w3),.en_yi(w4),.key1(key1),

.key2(key2),.led(led),.win(win),.t1(t1),.t2(t2));

score1

u1(.res(res),.jia(w1),.s1(smg1),.s2(smg2),.win(win1));

score2

u2(.res(res),.yi(w2),.s1(smg3),.s2(smg4),.win(win2));

Permissions

u3(.clk(clk),.res(res),.in1(w1),.in2(w2),.out1(jia_led),.out2(yi_led),.en_jia(en_jia),.en_yi(en_yi));

goal

u4(.res(res),.jia(w1),.yi(w2),.en(w5),.buzz(buzz));

timer u5(.t1(t1),.t2(t2));

endmodule

module

state_machine(clk,res,key1,key2,led,jia,yi,en_jia,en_yi,win,t1,t2); //

input clk,res,key1,key2,en_jia,en_yi,win,t1; output jia,yi,t2;

reg jia,yi,t2;

output[7:0] led;

reg[7:0] led;

parameter[7:0]

s0=8'b0000_0001,s1=8'b0000_0010,s2=8'b0000_0100,s3=8'b0000_1000,

s4=8'b0001_0000,s5=8'b0010_0000,s6=8'b0100_0000,s7=8'b1000_0000; reg[7:0] current_state,next_current;

/*--------------------每个时钟沿转跳一次逻辑状态

--------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

current_state

else

current_state

end

/*--------------------产生下一状态的组合逻辑

-----------------------*/

always@(current_state)

begin

case(current_state)

s0:

if((key1==1)&&(en_jia==1)) next_current

else

if((key2==1)&&(en_yi==1)) next_current

else next_current

s1:

if(led==8'b0000_0001) next_current

else next_current

s2:

if(led==8'b1000_0000) next_current

else next_current

s3:

if((t1==1)&&(key2==1)) next_current

else next_current

if((t1==1)&&(key1==1)) next_current

else next_current

s5:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

s6:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

endcase

end

/*--------------------状态机输出的组合逻辑

-------------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

begin

led

t2

jia

yi

end

else

begin

case(current_state)

s0:

led

s1:

begin

led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001; end

s2:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000; end

s3:

begin

led

t2

end

s4:

begin

led

t2

end

s5:

jia

s6:

yi

s7:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

endcase

end

end

endmodule

module score1(res,jia,s1,s2,win);

input res,jia;

output win;

output[7:0] s1,s2;

wire[7:0] s1,s2;

wire[3:0] w1,w2;

add21

u1(.in(jia),.res(res),.win(win),.out1(w1),.out2(w2));

encoder u2(.in1(w1),.in2(w2),.out1(s1),.out2(s2));

endmodule

module score2(clk,res,yi,s1,s2,win);

input clk,res,yi;

output win;

output[7:0] s1,s2;

wire[7:0] s1,s2;

wire[3:0] w1,w2;

add21

u1(.in(yi),.res(res),.win(win),.out1(w1),.out2(w2));

encoder u2(.in1(w1),.in2(w2),.out1(s1),.out2(s2));

endmodule

module add21(in,res,win,out1,out2);

input in,res;

output win;

output[3:0] out1,out2;

reg[3:0] out1,out2;

reg cin,win;

always@(posedge in or negedge res)

begin

if(~res)

begin

out1

end

else

if(in)

if(out1==9)

begin

out1

cin

end

else

begin

out1

cin

end

end

always@(posedge cin or negedge res)

begin

if(~res)

out2

else

if(cin)

if(out2==9)

out2

else

out2

end

always@(*)

begin

if((out1==1)&&(out2==2))

win

else

win

end

endmodule

module encoder(in1,in2,out1,out2);

input[3:0] in1,in2;

output[7:0] out1,out2;

reg[7:0] out1,out2;

always@(*)

case(in1) //共阳数码管编码 8'b0000:out1=8'b1100_0000; //0

8'b0001:out1=8'b1111_1001; //1

8'b0010:out1=8'b1010_0100; //2

8'b0011:out1=8'b1011_0000; //3

8'b0100:out1=8'b1001_1001; //4

8'b0101:out1=8'b1001_0010; //5

8'b0110:out1=8'b1000_0010; //6

8'b0111:out1=8'b1111_1000; //7

8'b1000:out1=8'b1000_0000; //8

8'b1001:out1=8'b1001_0000; //9

default:out1=8'b1100_0000;

endcase

always@(*)

case(in2)

8'b0000:out2=8'b1100_0000; //0

8'b0001:out2=8'b1111_1001; //1

8'b0010:out2=8'b1010_0100; //2

8'b0011:out2=8'b1011_0000; //3

8'b0100:out2=8'b1001_1001; //4

8'b0101:out2=8'b1001_0010; //5

8'b0110:out2=8'b1000_0010; //6

8'b0111:out2=8'b1111_1000; //7

8'b1000:out2=8'b1000_0000; //8

8'b1001:out2=8'b1001_0000; //9

default:out2=8'b1100_0000;

endcase

endmodule

module Permissions(clk,res,in1,in2,out1,out2,en_jia,en_yi); input clk,res,in1,in2;

output out1,out2,en_jia,en_yi;

reg out1,out2,en_jia,en_yi;

wire w1,w2,a,b;

or u2(w1,in1,in2);

add4 u1(.res(res),.c(w1),.cnt(w2));

select u3(.cnt(w2),.a(a),.b(b));

parameter[1:0] s0=1'b00,s1=1'b01;

reg[1:0] current_state,next_current;

always@(posedge clk or negedge res)

begin

if(!res)

current_state

current_state

end

always@(current_state or next_current) begin

case(current_state)

s0:

begin

out1

en_jia

en_yi

out2

if(a==1)

next_current

next_current

s1:

begin

out1

en_jia

en_yi

out2

if(b==1)

next_current

next_current

endcase

end

endmodule

module add4(res,c,cnt);

input res,c;

output cnt;

reg cnt;

reg[2:0] q;

always@(posedge c or negedge res) begin

if(~res)

begin

q

cnt

end

else

begin

if(q==4)

begin

cnt

q

end

else

begin

q

cnt

end

end

end

endmodule

module select(cnt,a,b);

input cnt;

output a,b;

reg a,b;

always@(cnt)

begin

if(cnt==1)

begin

a

b

end

else

begin

a

b

end

end

endmodule

module goal(res,buzz,jia,yi,en); input res,jia,yi; output buzz,en;

reg buzz,en; reg[12:0] q;

wire w;

or u1(w,jia,yi);

always@(posedge w or negedge res) begin

if(~res)

begin

q

en

buzz

end

else

begin

if(q==2999)

begin

en

q

buzz

end

else

begin

q

en

buzz

end

end

end

endmodule

module timer(t1,t2);

input t2;

output t1;

reg t1;

reg[8:0] cnt;

always@(posedge t2)

begin

if(cnt==499)

begin

cnt

t1

cnt

endmodule

摘要

在现代电子设计领域,微电子技术迅猛发展,无论是系统设计、电路设计,还是芯片设计,其设计的复杂度都在增加,传统的手工设计方法已经不能满足设计者的要求,急需新的设计工具来解决。EDA技术的迅速发展顺应了时代的发展,使得电子设计自动化技术有了新的、快的发展,其重要程度日益突出。本文设计了基于FPGA的,用Verilog HDL语言描述的乒乓球游戏机的设计。它由控制模块、数码管的片选信号模块、送数据模块和7段译码器模块组成,连接形成乒乓球游戏机的顶层电路。在QuartusⅡ软件上用Verilog HDL语言分别对每个模块进行描述,然后在软件上进行编译、仿真,最终实现乓乓球比赛的基本过程和规则,并能自动裁判和计分,达到设计的要求。

关键词:EDA ;FPGA ;Verilog HDL Abstract

In the field of modern electronic design, the rapid development of microelectronic

technology,whether the system design, circuit design and chip design, the design is more complex, the traditional manual design methods have been unable to meet the

requirements of designers,in urgent need of new design tools to solve. The rapid

development of EDA technology to the development of the times, the electronic design automation technology has been the development of new, fast, its importance is

outstanding day by day. This paper is designed based on FPGA, the design of table tennis game is described with Verilog HDL language. It consists of control module, chip select signal module, digital tube to send data module and the 7 segment

decoder modules, the top-level circuit connected to form a table tennis game. In the Quartus software by Verilog HDL language for each module are described, and then the compiler, simulation in software, realize the basic process and the rules of table

tennis table tennis competition, and can automatically judge and score, to meet the design requirements.

Keywords: EDA; FPGA; Verilog HDL

第一章 引言

1.1课题研究的背景

随着微电子技术的飞跃发展,无论是系统级设计、电路设计还是芯片设计,它的复杂程度都在不断的增加,而且它的发展速度也越来越快。这时,仅仅依靠传统的电子设计方法已经不能满足需求。EDA技术的兴起与发展给电子设计带来了革命性的变化,推动了微电子技术的迅猛发展,电子学进入一个崭新的时代。

1.2课题研究的目的

EDA技术是现代电子设计领域的一门技术,它提供了基于计算机和信息技术的电路设计方法,不依托其他设计工具,仅以计算机为工具,在EDA软件上完成设计、编译、仿真。EDA技术正以空前的发展速度和规模渗透到各行各业。 在这个快节奏生活的社会,人们外出的休闲娱乐活动越来少,而越来越多的电子游戏解决了这个问题,人们可以在家中玩各种休闲娱乐节目。所以设计了基于FPGA的两人乒乓球游戏机,让人们能在忙碌中有时间体验下体育节目的乐趣。FPGA器件具有高开发周期短,高集成度,现场可修改等特点,因此十分有必要对FPGA进行详细认真的研究。硬件描述语言VHDL功能性强,灵活性高,覆盖面广,用以甚高速集成电路硬件描述语言,具有很好的实用性。总的来说,现代EDA技术的基本特征是采用高级语言(VHDL、Verilog HDL等)描述,具有系统级仿真和综合的能力。它必将成为21世纪不可或缺的电子设计工具,必将影响这个世纪的发展。

2.1EDA基础

2.1.1EDA定义

EDA是Electronics Design Automation(电子设计自动化)的缩写,以计算机为工作平台;在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的定义发展而来的;是利用电子技术基础、计算机技术、智能化技术等多种应用技术而开发成的整套电子CAD软件;是一种帮助从事电子元件产品和系统设计的电子工作者的综合技术。

2.1.2EDA技术的发展历程

集成电路的飞快发展不断给EDA技术提出更高的要求,对EDA技术的发展起了巨大的推动作用。从20世纪60年代中期开始,人们不断地开发出各种计算机辅助设计工具来帮助设计人员进行集成电路和电子系统的设计。经历了计算机辅助设计、计算机辅助工程设计和电子系统设计自动化这3个阶段,如图2.1所示。

图2.1 EDA技术的发展历程

(1)CAD阶段

20世纪70年代,随着中、小规模集成电路的兴起和应用,传统的手工设计印刷电路板和集成电路的方法已经不能满足设计精度和效率的要求,于是电子设计工程师们开始在二维平面图形上进行计算机辅助设计,这样就产生了第一代

EDA工具,设计者从繁杂、机械的、手工布局和布线工作中解放了出来。

(2)CAE阶段

20世纪80年代以后,集成电路的规模越来越大,电子系统设计的复杂也在增加,电子设计自动化的工具逐步完善和发展起来,设计者们尤其在设计方法、设计工具集成化方面取得了很大的进步。为了适应电子产品在规模和制作上的需要,以计算机仿真和自动布线为核心的第二代EDA技术应运而生。其特点是以软件设计工具为核心,通过软件完成产品的开发、设计、分析、生产和测试等工作。

(3)ESDA阶段

20世纪90年代,设计师们逐步从使用硬件转向去设计硬件,从单个电子产品开发转向系统级电子产品开发(及片上系统集成)。因此,这时的EDA工具是以系统级设计为核心,包括结构综合与系统行为级描述,系统仿真与测试验证,系统决策与文件生成,系统划分与指标分配等一整套的电子系统设计工具。这时的EDA工具不仅具有电子系统设计的能力,而且具有独立于生产工艺和厂家的系统级设计能力。第三代EDA工具的出现,极大地提高了电子系统设计的效率,让设计工程师们开始能够以概念来驱动设计工程的梦想。

2.1.3EDA技术的发展趋势

随着微电子技术的不断发展与进步和市场需求的不断增长,EDA技术在21世纪后得到了迅猛的发展,这一发展趋势表现在以下几个方面:

(1)软件IP核在微电子的产业领域、设计应用领域和技术领域得到进一步的巩固与发展。

(2)使支持硬件描述语言仿真和设计的EDA软件不断地强大起来。

(3)EDA使得系统与器件、专用集成电路ASIC与FPGA、模拟与数字、行为与结构、软件与硬件等的界限越来越模糊。

(4) EDA技术保护了设计者的电子设计成果的知识产权。

(5)大规模的电子系统都是以EDA为工具设计的,正以飞快的速度渗透到IP核模块。

(6)更大规模的可编程逻辑器件正在推向市场,使得设计更为广泛与便捷。

2.1.4EDA技术的基本特征

总的来说,现代EDA技术是采用高级程序语言描述,具有系统级仿真和综合的能力。它主要采用并行工程和“自顶向下”的设计方法,使开发人员从一开始就能考虑到产品生成周期的诸多方面,包括质量、成本、开发时间及用户的需求等。然后从系统设计开始,在顶层进行功能方框图的划分和结构的设计,在方框图一级进行仿真、纠错,并用VHDL、Verilog-HDL等硬件描述语言对顶层的系统进行功能和行为上的描述,在系统一级进行验证与仿真。最后,用逻辑综合优化工具生成具体的门级逻辑电路的网表,其对应的物理实现级可以是印刷电路板或者是专用的集成电路。近年来,硬件描述语言等设计数据格式逐步形成一种标准,不同的设计风格和应用要求使得各具特色的EDA工具被集成在相同的设计方法上,EDA技术的设计框架日趋标准化。

2.1.5EDA技术的基本工具

集成电路技术的不断发展对EDA技术提出了更高的要求,促进了EDA技术向更高的层次发展。但实际来说,EDA系统的设计能力一直难以满足集成电路的要求。EDA工具的发展经历了两个阶段,即物理工具阶段和逻辑工具阶段。 现在,人们已经开发了很多计算机辅助设计工具来帮助设计集成电路,常见的EDA工具有编辑器、仿真器、检查/分析工具和优化/综合工具等,如图2.2所示。

图2.2 EDA设计工具的分类

2.1.6EDA技术的基本设计思路

(1)EDA技术的电路级设计

电路级设计工作,首先,应该先确定合适的设计方案,然后选择方便实现该方案的元器件,接着就可根据所选元器件设计符合要求的电路原理图,再接着进行一次仿真。其目的是检验此设计方案在元件模型库支持下的功能方面是否正确,这样,设计工作就进入了轨道。第一次仿真通过后,就开始进行PCB的自动布局布线,此布局布线要根据原理图产生的电路连接网络表来进行。然后,对PCB进行分析,将分析结果反馈给电路图,并再次仿真。这样,PCB板在实际工作中的可行性就一目了然了。综上,EDA的电路级设计可在实际的电子系统产生之前就了解其功能特性,从而降低其设计风险,降低开发成本,缩短其开发周期,使得设计人员能够更好、更方便的设计。电路级设计工作流程如图2.3

图2.3 电路级设计工作流程图

(2)EDA技术的系统级设计

EDA技术的系统级设计方法是采用“自顶向下”的思路来设计的,让开发者一开始就可了解到产品的开发周期、生产成本等。设计者首先从系统方案入手,

进行顶层的划分和结构设计;然后,用VHDL语言等硬件描述语言对系统进行深刻描述;接着就用编辑器将其转换成标准的VHDL文件,再接着验证系统功能设计的正确性;再接着就用逻辑综合优化工具生成具体的门级电路的网络表;其后,进行时序仿真;最后,就到了系统的物理实现级,将其变成FPGA等。EDA技术的系统级设计如图2.4所示。

图2.4 EDA技术的系统级设计

2.1.7 EDA的设计流程

EDA的设计流程是“自顶向下”的设计思路。设计流程如图2.5所示。

图2.5 应用于FPGA/CPLD的EDA开发流程

2.2 FPGA的概念与特点

FPGA(Field-Programmable Gate Array),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。

目前以硬件描述语言(Verilog 或 VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至 FPGA 上进行测试,是现代 IC 设计验证的技术主流。这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(Flip-flop)或者其他更加完整的记忆块。

系统设计师可以根据需要通过可编辑的连接把FPGA内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。一个出厂后的成品FPGA的逻辑块和连接可以按照设计者而改变,所以FPGA可以完成所需要的逻辑功能。

FPGA一般来说比ASIC(专用集成芯片)的速度要慢,无法完成复杂的设计,而且消耗更多的电能。但是他们也有很多的优点比如可以快速成品,可以被修改来改正程序中的错误和更便宜的造价。厂商也可能会提供便宜的但是编辑能力差的FPGA。因为这些芯片有比较差的可编辑能力,所以这些设计的开发是在普通的FPGA上完成的,然后将设计转移到一个类似于ASIC的芯片上。另外一种方法是用CPLD(复杂可编程逻辑器件备)。

早在1980年代中期,FPGA已经在PLD设备中扎根。CPLD和FPGA包括了一些相对大数量的可以编辑逻辑单元。CPLD逻辑门的密度在几千到几万个逻辑单元之间,而FPGA通常是在几万到几百万。

CPLD和FPGA的主要区别是他们的系统结构。CPLD是一个有点限制性的结构。这个结构由一个或者多个可编辑的结果之和的逻辑组列和一些相对少量的锁定的寄存器。这样的结果是缺乏编辑灵活性,但是却有可以预计的延迟时间和逻辑单元对连接单元高比率的优点。而FPGA却是有很多的连接单元,这样虽然让它可以更加灵活的编辑,但是结构却复杂的多。

CPLD和FPGA另外一个区别是大多数的FPGA含有高层次的内置模块(比如加法器和乘法器)和内置的记忆体。一个因此有关的重要区别是很多新的FPGA支持完全的或者部分的系统内重新配置。允许他们的设计随着系统升级或者动态重新配置而改变。一些FPGA可以让设备的一部分重新编辑而其他部分继续正常运行。

FPGA采用了逻辑单元阵列LCA(Logic Cell Array)这样一个概念,内部包括可配置逻辑模块CLB(Configurable Logic Block)、输出输入模块IOB(Input Output Block)和内部连线(Interconnect)三个部分。FPGA的基本特点主要有:

1)采用FPGA设计ASIC电路,用户不需要投片生产,就能得到合用的芯片。

2)FPGA可做其它全定制或半定制ASIC电路的中试样片。

3)FPGA内部有丰富的触发器和I/O引脚。

4)FPGA是ASIC电路中设计周期最短、开发费用最低、风险最小的器件之一。

5) FPGA采用高速CHMOS工艺,功耗低,可以与CMOS、TTL电平兼容。 可以说,FPGA芯片是小批量系统提高系统集成度、可靠性的最佳选择之一。

FPGA是由存放在片内RAM中的程序来设置其工作状态的,因此,工作时需要对片内的RAM进行编程。用户可以根据不同的配置模式,采用不同的编程方式。加电时,FPGA芯片将EPROM中数据读入片内编程RAM中,配置完成后,FPGA进入工作状态。掉电后,FPGA恢复成白片,内部逻辑关系消失,因此,FPGA能够反复使用。FPGA的编程无须专用的FPGA编程器,只须用通用的EPROM、PROM编程器即可。当需要修改FPGA功能时,只需换一片EPROM即可。这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。因此,FPGA的使用非常灵活。

Verilog HDL语言简介

Verilog HDL和VHDL是目前世界上最流行的两种硬件描述语言(HDL:Hardware Description Language),均为IEEE标准,被广泛地应用于基于可编程逻辑器件的项目开发。二者都是在20世纪80年代中期开发出来的,前者由Gateway Design Automation公司(该公司于1989年被Cadence公司收购)开发,后者由美国军方研发。

HDL语言以文本形式来描述数字系统硬件结构和行为,是一种用形式化方法来描述数字电路和系统的语言,可以从上层到下层来逐层描述自己的设计思想。即用一系列分层次的模块来表示复杂的数字系统,并逐层进行验证仿真,再把具体

的模块组合由综合工具转化成门级网表,接下去再利用布局布线工具把网表转化为具体电路结构的实现。目前,这种自顶向下的方法已被广泛使用。概括地讲,HDL语言包含以下主要特征:

Verilog HDL语言既包含一些高级程序设计语言的结构形式,同时也兼顾描述硬件线路连接的具体结构。

通过使用结构级行为描述,可以在不同的抽象层次描述设计。Verilog HDL语言采用自顶向下的数字电路设计方法,主要包括3个领域5个抽象层次。

Verilog HDL语言是并行处理的,具有同一时刻执行多任务的能力。这和一般高级设计语言(例如C语言等)串行执行的特征是不同的。

Verilog HDL语言具有时序的概念。一般的高级编程语言是没有时序概念的,但在硬件电路中从输入到输出总是有延时存在的,为了描述这一特征,需要引入时延的概念。HDL语言不仅可以描述硬件电路的功能,还可以描述电路的时序。

2.1.1 Verilog HDL语言的历史 1983年,Gateway Design Automation(GDA)硬件描述语言公司的Philip Moorby首创了Verilog HDL。后来Moorby成为Verilog HDL-XL的主要设计者和Cadence公司的第一合伙人。1984至1986年,Moorby设计出第一个关于Verilog HDL的仿真器,并提出了用于快速门级仿真的XL算法,使Verilog HDL语言得到迅速发展。1987年Synonsys公司开始使用Verilog HDL行为语言作为综合工具的输入。1989年Cadence公司收购了Gateway公司,Verilog HDL成为Cadence公司的私有财产。1990年初,Cadence公司把Verilog HDL和Verilog HDL-XL分开,并公开发布了Verilog HDL。随后成立的OVI(Open Verilog HDL International)组织负责Verilog HDL的发展并制定有关标准,OVI由Verilog HDL的使用者和CAE供应商组成。1993年,几乎所有ASIC厂商都开始支持Verilog HDL,并且认为Verilog HDL-XL是最好的仿真器。同时,OVI推出2.0版本的Verilong HDL规范,IEEE则将OVI的Verilog HDL2.0作为IEEE标准的提案。1995年12月,IEEE制定了Verilog HDL的标准IEEE1364-1995。目前,最新的Verilog语言版本是2000年IEEE公布的Verilog 2001标准,其大幅度地提高了系统级和可综合性能。

Verilog HDL的主要能力

Verilog HDL既是一种行为描述语言,也是一种结构描述语言。如果按照一定的规则和风格编写代码,就可以将功能行为模块通过工具自动转化为门级互连的结构模块。这意味着利用Verilog语言所提供的功能,就可以构造一个模块间的清晰结构来描述复杂的大型设计,并对所需的逻辑电路进行严格的设计。 下面列出的是Verilog语言的主要功能:

1.可描述顺序执行或并行执行的程序结构;

2.用延迟表示式或事件表达式来明确地控制过程的启动时间;

3.通过命名的事件来触发其他过程里的激活行为或停止行为;

4.提供了条件和循环等程序结构;

5.提供了可带参数且非零延续时间的任务程序结构;

6.提供了可定义新的操作符的函数结构;

7.提供了用于建立表达式的算术运算符、逻辑运算符和位运算符;

8.提供了一套完整的表示组合逻辑基本元件的原语;

9.提供了双向通路和电阻器件的描述;

10.可建立MOS器件的电荷分享和衰减模型;

11.可以通过构造性语句精确地建立信号模型;

此外,Verilog HDL语言还有一个重要特征就是:和C语言风格有很多的相似之处,学习起来比较容易。

Verilog HDL和VHDL的区别

Verilog HDL和VHDL都是用于逻辑设计的硬件描述语言。VHDL在1987年成为IEEE标准,Verilog HDL则在1995年才成为IEEE标准,这是因为前者是美国军方组织开发的,而后者则是从民间公司转化而来,要成为国际标准就必须放弃专利。相比而言,Verilog HDL具有更强的生命力。

Verilog HDL和VHDL的相同点在于:都能形式化地抽象表示电路的行为和结构;支持逻辑设计中层次与范围的描述;可以简化电路行为的描述;具有电路仿真和验证机制;支持电路描述由高层到低层的综合转换;与实现工艺无关;便于管理和设计重用。

但Verilog HDL和VHDL又有各自的特点,由于Verilog HDL推出较早,因而拥有更广泛的客户群体、更丰富的资源。Verilog HDL还有一个优点就是容易掌握,如果具有C语言学习的基础,很快就能够掌握。而VHDL需要Ada编程语言基础,一般需要半年以上的专业培训才能够掌握。传统观点认为Verilog HDL在系统级抽象方面较弱,不太适合特大型的系统。但经过Verilog 2001标准的补充之后,系统级表述性能和可综合性能有了大幅度提高。当然,这两种语言也仍处于不断完善的过程中,都在朝着更高级描述语言的方向前进。

Verilog HDL设计方法

1. 自下而上的设计方法

自下而上的设计是传统的设计方法,是从基本单元出发,对设计进行逐层划分的过程。这种设计方法与用电子元件在模拟实现板上建立一个系统的步骤有密切的关系。优、缺点分别如下:

优点 :

设计人员对这种设计方法比较熟悉;实现各个子模块所需的时间较短。 缺点 :

对系统的整体功能把握不足;由于必须先对多个子模块进行设计,因此实现整个系统的功能所需的时间长;另外,对设计人员之间相互协作也有较高的要求。

2.自上而下的设计方法

自上而下的设计是从系统级开始,把系统划分为基本单元,然后再把基本单元划分为下一层次的基本单元,直到可用EDA元件实现为止。这种方法的优、缺点如下。

优点:

在设计周期开始就做好了系统分析;由于设计的主要仿真和调试过程是在高层完成的,所以能够早期发现结构设计上的错误,避免了设计工作的浪费,方便了系统的划分和整个项目的管理,可减少设计人员劳动,避免了重复设计。 缺点 :

得到的最小单元不标准,且制造成本高。

3.混合的设计方法

复杂数字逻辑电路和系统设计过程,通常是以上两种设计方法的结合。设计时需要考虑多个目标的综合平衡。在高层系统用自上而下的设计方法实现,而使用自下而上的方法从库元件或以往设计库中调用已有的设计单元。混合设计方法兼有以上两种方法的优点,并且可使用先进的矢量测试方法。

第二章 设计思想

1.基本原理

用8个(或更多个)LED排成一条直线,以中点为界,两边各代表参赛双方的位置,其中一只点亮的LED指示球的当前位置,点亮的LED依此从左到右,或从右到左,其移动的速度应能调节。当“球”(点亮的那只LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。若击中,则球向相反方向移动;若未击中,则对方得1分。一方得分时,电路自动响铃3秒,这期间发球无效,等铃声停止后方能继续比赛。设置自动记分电路,甲、乙双方各用2位数码管进行记分显示,每计满21分为1局。甲、乙双方各设一个发光二极管,表示拥有发球权,每隔5次自动交换发球权,拥有发球权的一方发球才有效。根据乒乓球比赛的过程和规则,首先游戏开始,如果一方非正确击球则另一方加分,当分数大于21时获胜,游戏结束,我们把设计流程规定如图1.1所示。状态机设置了7个状态,分别是“等待发球状态”,“第一盏灯亮状态”,“第八盏灯亮状态”,“球向乙移动状态”,“ 球向甲移动状态”,“允许甲击球状态”,“允许乙击球状态”。这是该程序中起决定作用的七个状态。开始的时候处于“等待发球状态”,若甲发球则状态转移到“第一盏灯亮状态”,若乙发球则转移到“第八盏灯亮状态”,具体说明以甲球为例。

若发球后乙没有提前击球——规定球移动到对方第一个发光二极管时允许击球,那么状态机从“第一盏灯亮状态”转移到“球向乙移动状态”。若在“球向乙移动状态”乙仍然没有提前击球,状态就转移到“允许乙击球状态”,在此状态下,如果乙击球了,那么状态就转移到“ 球向甲移动状态”。在“第一盏灯

亮状态”, “球向乙移动状态”中,如果乙击球了 ,就算提前击球,这样甲得分,状态转移到“等待发球状态”等待发球,“ 球向甲移动状态”之后的过程和前面的过程只不过是甲乙角色的调换而已。

2.设计框图

图1流程图

图2 基本原理

第三章 设计步骤和调试过程

1、模块设计和相应模块代码

(1)发球选择模块的设计

游戏开始时,必须先决定发球权在哪一方。同时,在游戏进行的过程中,必须能够正确交换甲乙双方发球权。相应的代码如下:

module Permissions(clk,res,in1,in2,out1,out2,en_jia,en_yi);

input clk,res,in1,in2;

output out1,out2,en_jia,en_yi;

reg out1,out2,en_jia,en_yi;

wire w1,w2,a,b;

or u2(w1,in1,in2);

add4 u1(.res(res),.c(w1),.cnt(w2));

select u3(.cnt(w2),.a(a),.b(b));

parameter[1:0] s0=1'b00,s1=1'b01;

reg[1:0] current_state,next_current;

always@(posedge clk or negedge res)

begin

if(!res)

current_state

else

current_state

end

always@(current_state or next_current)

begin

case(current_state)

s0:

begin

out1

en_jia

en_yi

out2

if(a==1)

next_current

else

next_current

end

s1:

begin

out1

en_jia

en_yi

out2

if(b==1)

next_current

else

next_current

end

endcase

end

endmodule

(2)状态机编程实现

状态机设置了7个状态,它们代表的具体数值依次是0到6。在波形模拟图中是用数值来表示状态的。

在整个程序中,状态机起的是中央控制器的作用,由它控制的信号来影响整个程序中的其他相关部分,如记分部分,发光二极管部分。乒乓球游戏机中有两个计数器,分别记忆甲和乙的得分,用发光二极管的轮流发光表示球的移动轨迹。状态机的进程如下:

module state_machine (clk,res,key1,key2,led,jia,yi,en_jia,

en_yi,win,t1,t2);

input clk,res,key1,key2,en_jia,en_yi,win,t1;

output jia,yi,t2;

reg jia,yi,t2;

output[7:0] led;

reg[7:0] led;

parameter[7:0]

s0=8'b0000_0001,s1=8'b0000_0010,s2=8'b0000_0100,s3=8'b0000_1000,

s4=8'b0001_0000,s5=8'b0010_0000,s6=8'b0100_0000,s7=8'b1000_0000; reg[7:0] current_state,next_current;

/*--------------------每个时钟沿转跳一次逻辑状态

--------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

current_state

else

current_state

end

/*--------------------产生下一状态的组合逻辑

-----------------------*/

always@(current_state)

begin

case(current_state)

s0:

if((key1==1)&&(en_jia==1)) next_current

else

if((key2==1)&&(en_yi==1)) next_current

else next_current

s1:

if(led==8'b0000_0001) next_current

else next_current

s2:

if(led==8'b1000_0000) next_current

else next_current

s3:

if((t1==1)&&(key2==1)) next_current

else next_current

s4:

if((t1==1)&&(key1==1)) next_current

else next_current

s5:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

s6:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

endcase

end

/*--------------------状态机输出的组合逻辑

-------------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

begin

led

t2

jia

yi

end

else

begin

case(current_state)

s0:

led

s1:

begin

led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

s2:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

end

s3:

begin

led

t2

end

s4:

begin

led

t2

end

s5:

jia

s6:

yi

s7:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

endcase

end

end

endmodule

(3)得分判断模块的设计

在一方并没有击球成功时,需要进行判定,并且鸣响蜂鸣器来提示这个球某一方没有击中,而另一方得分。于是编写相应程序。

module goal(res,buzz,jia,yi,en);

input res,jia,yi;

output buzz,en;

reg buzz,en;

reg[12:0] q;

wire w;

or u1(w,jia,yi);

always@(posedge w or negedge res)

begin

if(~res)

begin

q

en

buzz

end

else

begin

if(q==2999)

begin

en

q

buzz

end

else

begin

q

en

buzz

end

end

end

endmodule

(4)记分译码器的设计

七段译码器是在数学电路设计中经常用到的显示电路。所谓七段译码器,其实是由7段发光二极管组成的用于显示数字的器件。记分译码器(encoder):由于记分需要显示出来,所以要使用七段译码器。而状态机中的记分是由2个4位二进制码来表示的。以下程序就是实现从4位二进制码转换成七段译码显示。 module encoder(in1,in2,out1,out2);

input[3:0] in1,in2;

output[7:0] out1,out2;

reg[7:0] out1,out2;

always@(*)

case(in1) //共阳数码管编码

8'b0000:out1=8'b1100_0000; //0

8'b0001:out1=8'b1111_1001; //1

8'b0010:out1=8'b1010_0100; //2

8'b0011:out1=8'b1011_0000; //3

8'b0100:out1=8'b1001_1001; //4

8'b0101:out1=8'b1001_0010; //5

8'b0110:out1=8'b1000_0010; //6

8'b0111:out1=8'b1111_1000; //7

8'b1000:out1=8'b1000_0000; //8

8'b1001:out1=8'b1001_0000; //9

default:out1=8'b1100_0000;

endcase

always@(*)

case(in2)

8'b0000:out2=8'b1100_0000; //0

8'b0001:out2=8'b1111_1001; //1

8'b0010:out2=8'b1010_0100; //2

8'b0011:out2=8'b1011_0000; //3

8'b0100:out2=8'b1001_1001; //4

8'b0101:out2=8'b1001_0010; //5

8'b0110:out2=8'b1000_0010; //6

8'b0111:out2=8'b1111_1000; //7

8'b1000:out2=8'b1000_0000; //8

8'b1001:out2=8'b1001_0000; //9

default:out2=8'b1100_0000;

endcase

endmodule

这个记分译马电路是针对乒乓球游戏机的特点进行的特别设计,采用的是全部列举的方法。

(4)顶层的设计

顶层综合各个模块设计,这样就完成了数字乒乓球游戏机的VHDL源程序编写。 module table_tennis(clk,res,key1,key2,led,smg1,smg2,smg3,smg4,buzz, jia_led,yi_led);

input clk,res,key1,key2;

output buzz,jia_led,yi_led;

output[7:0] led,smg1,smg2,smg3,smg4;

wire[7:0] smg1,smg2,smg3,smg4,led;

wire

w1,w2,w3,w4,w5,jia_led,yi_led,buzz,win,win1,win2,en,en_jia,en_yi,t1,t2;

and D1(w3,w5,en_jia);

and D2(w4,w5,en_yi);

or D3(win,win1,win2);

state_machine

u0(.clk(clk),.res(res),.jia(w1),.yi(w2),.en_jia(w3),.en_yi(w4),.key1(key1),

.key2(key2),.led(led),.win(win),.t1(t1),.t2(t2));

score1

u1(.res(res),.jia(w1),.s1(smg1),.s2(smg2),.win(win1));

score2

u2(.res(res),.yi(w2),.s1(smg3),.s2(smg4),.win(win2));

Permissions

u3(.clk(clk),.res(res),.in1(w1),.in2(w2),.out1(jia_led),.out2(yi_led),.en_jia(en_jia),.en_yi(en_yi));

goal u4(.res(res),.jia(w1),.yi(w2),.en(w5),.buzz(buzz)); timer u5(.t1(t1),.t2(t2));

endmodule

从顶层设计中可以看到,控制整个乒乓球游戏机运转的就是状态机进程,它队各个外围部分起控制作用。它是整个程序的核心,起到一个中心控制器的作用。而外围的部分,比如分数显示,球的轨迹,都是通过它传出的信号来控制。状态机中的信号变化同时就可以影响到外围的显示部分——发光二极管和七段译码器,从而表示出当时的乒乓球位置和双方分数情况。

第四章 顶层电路、仿真及调试

1.顶层电路图

根据程序所画的顶层电路图如图3

图3

2.仿真

编译完成后仿真如图

图4

A方先发球,B方在恰当的时刻击球成功,当球回到A方时,A方没有及时接到

球的仿真波形

图5

A方两次成功发球后B方都没有接到球,A方得2分的仿真波形图

图6

B方成功发球后,A方在恰当的时刻成功接到球,而B方没有接到球的情况

3、实验调试结果

通过调试我们可以观察到,8个LED排成一条直线,以中点为界,两边各代表参赛双方的位置,其中一只点亮的LED指示球的当前位置,点亮的LED依此从左到右,或从右到左,其移动的速度应能调节。当“球”(点亮的那只LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。若击中,则球向相反方向移动;若未击中,则对方得1分。一方得分时,电路自动响铃3秒,这期间发球无效,等铃声停止后方能继续比赛。设置自动记分电路,甲、乙双方各用2位数码管进行记分显示,每计满21分为1局。甲、乙双方各设一个发光二极管,表示拥有发球权,每隔5次自动交换发球权,拥有发球权的一方发球有效。

第五章

结论

采用Verilog HDL语言编程,基于FPGA成功设计了一款乒乓球比赛的游戏机,通过仿真验证可知,结果满足了设计的要求。系统能够模拟两人乒乓球比赛的基本过程和规则,并能自动裁判和计分,能有效模拟实际的乒乓球比赛。该系统可进一步改进,改进思路为:改用人体感应器官来采集击球信号,采用FPGA产生视频信号送到电视机,更直观地展示乒乓球运动轨迹,从而真正实现人机互动,优化虚拟效果。

参考文献:

[1]朱正伟.EDA技术及应用[M].清华大学出版社,2005年10月第一版.

[2]刘昌华.EDA技术与应用—基于QuartusⅡ和VHDL[M].北京航空航天大学出版社,2012年8月第一版.

[3]潘松 黄继业.EDA技术实用教程[M].科学出版社,2002年10月第一版.

[4]包明.EDA技术与可编程器件的应用[M].北京航空航天大学出版社,2007年10月第一版.

[5]江国强.EDA技术与应用[M].电子工业出版社,2004年8月第一版.

[6]张文爱.EDA技术与FPGA应用设计[M].电子工业出版社,2012年1月第一版.

[7]谭慧生 张昌凡.EDA技术与应用[M].西安电子科技大学出版社,2001年9月第一版.

[8]汉泽西.EDA技术及其应用[M].北京航空航天大学出版社,2004年5月第一版.

[9]王振红.VHDL数字电路设计与应用教程[M].机械工业出版社,2003.

[10]付家才.EDA技术与FPGA应用设计[M].电子工业出版社,2012,(01).

[11]赖杰.VHDL与数字电路设计[M].科学出版社,2001.

[12]李慧.PLD与数字系统设计[M].西安电子科技大学出版社,2005.

[13]王行.EDA技术入门与提高[M].西安:西安电子科技大学出版社,2005.

[14]田耘.Xilinx FPGA开发实用教程[M].清华大学出版社,2008.

[15]杨跃.FPGA应用开发实战技巧精粹[M].人民邮电出版社,2005.

附录:

Verilog HDL语言源程序:

module table_tennis(clk,res,key1,key2,led,smg1,smg2,smg3,smg4,buzz, jia_led,yi_led);

input clk,res,key1,key2;

output buzz,jia_led,yi_led;

output[7:0] led,smg1,smg2,smg3,smg4;

wire[7:0] smg1,smg2,smg3,smg4,led;

wire

w1,w2,w3,w4,w5,jia_led,yi_led,buzz,win,win1,win2,en,en_jia,en_yi,t1,t2;

and D1(w3,w5,en_jia);

and D2(w4,w5,en_yi);

or D3(win,win1,win2);

state_machine

u0(.clk(clk),.res(res),.jia(w1),.yi(w2),.en_jia(w3),.en_yi(w4),.key1(key1),

.key2(key2),.led(led),.win(win),.t1(t1),.t2(t2));

score1

u1(.res(res),.jia(w1),.s1(smg1),.s2(smg2),.win(win1));

score2

u2(.res(res),.yi(w2),.s1(smg3),.s2(smg4),.win(win2));

Permissions

u3(.clk(clk),.res(res),.in1(w1),.in2(w2),.out1(jia_led),.out2(yi_led),.en_jia(en_jia),.en_yi(en_yi));

goal

u4(.res(res),.jia(w1),.yi(w2),.en(w5),.buzz(buzz));

timer u5(.t1(t1),.t2(t2));

endmodule

module

state_machine(clk,res,key1,key2,led,jia,yi,en_jia,en_yi,win,t1,t2); //

input clk,res,key1,key2,en_jia,en_yi,win,t1; output jia,yi,t2;

reg jia,yi,t2;

output[7:0] led;

reg[7:0] led;

parameter[7:0]

s0=8'b0000_0001,s1=8'b0000_0010,s2=8'b0000_0100,s3=8'b0000_1000,

s4=8'b0001_0000,s5=8'b0010_0000,s6=8'b0100_0000,s7=8'b1000_0000; reg[7:0] current_state,next_current;

/*--------------------每个时钟沿转跳一次逻辑状态

--------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

current_state

else

current_state

end

/*--------------------产生下一状态的组合逻辑

-----------------------*/

always@(current_state)

begin

case(current_state)

s0:

if((key1==1)&&(en_jia==1)) next_current

else

if((key2==1)&&(en_yi==1)) next_current

else next_current

s1:

if(led==8'b0000_0001) next_current

else next_current

s2:

if(led==8'b1000_0000) next_current

else next_current

s3:

if((t1==1)&&(key2==1)) next_current

else next_current

if((t1==1)&&(key1==1)) next_current

else next_current

s5:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

else next_current

s6:

if(win==1) next_current

else

if((en_jia==1)||(en_yi==1)) next_current

endcase

end

/*--------------------状态机输出的组合逻辑

-------------------------*/

always@(posedge clk or negedge res)

begin

if(~res)

begin

led

t2

jia

yi

end

else

begin

case(current_state)

s0:

led

s1:

begin

led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001; end

s2:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000; end

s3:

begin

led

t2

end

s4:

begin

led

t2

end

s5:

jia

s6:

yi

s7:

begin

led=8'b0000_0001;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_1000;

#1000 led=8'b0001_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b1000_0000;

#1000 led=8'b0100_0000;

#1000 led=8'b0010_0000;

#1000 led=8'b0001_0000;

#1000 led=8'b0000_1000;

#1000 led=8'b0000_0100;

#1000 led=8'b0000_0010;

#1000 led=8'b0000_0001;

end

endcase

end

end

endmodule

module score1(res,jia,s1,s2,win);

input res,jia;

output win;

output[7:0] s1,s2;

wire[7:0] s1,s2;

wire[3:0] w1,w2;

add21

u1(.in(jia),.res(res),.win(win),.out1(w1),.out2(w2));

encoder u2(.in1(w1),.in2(w2),.out1(s1),.out2(s2));

endmodule

module score2(clk,res,yi,s1,s2,win);

input clk,res,yi;

output win;

output[7:0] s1,s2;

wire[7:0] s1,s2;

wire[3:0] w1,w2;

add21

u1(.in(yi),.res(res),.win(win),.out1(w1),.out2(w2));

encoder u2(.in1(w1),.in2(w2),.out1(s1),.out2(s2));

endmodule

module add21(in,res,win,out1,out2);

input in,res;

output win;

output[3:0] out1,out2;

reg[3:0] out1,out2;

reg cin,win;

always@(posedge in or negedge res)

begin

if(~res)

begin

out1

end

else

if(in)

if(out1==9)

begin

out1

cin

end

else

begin

out1

cin

end

end

always@(posedge cin or negedge res)

begin

if(~res)

out2

else

if(cin)

if(out2==9)

out2

else

out2

end

always@(*)

begin

if((out1==1)&&(out2==2))

win

else

win

end

endmodule

module encoder(in1,in2,out1,out2);

input[3:0] in1,in2;

output[7:0] out1,out2;

reg[7:0] out1,out2;

always@(*)

case(in1) //共阳数码管编码 8'b0000:out1=8'b1100_0000; //0

8'b0001:out1=8'b1111_1001; //1

8'b0010:out1=8'b1010_0100; //2

8'b0011:out1=8'b1011_0000; //3

8'b0100:out1=8'b1001_1001; //4

8'b0101:out1=8'b1001_0010; //5

8'b0110:out1=8'b1000_0010; //6

8'b0111:out1=8'b1111_1000; //7

8'b1000:out1=8'b1000_0000; //8

8'b1001:out1=8'b1001_0000; //9

default:out1=8'b1100_0000;

endcase

always@(*)

case(in2)

8'b0000:out2=8'b1100_0000; //0

8'b0001:out2=8'b1111_1001; //1

8'b0010:out2=8'b1010_0100; //2

8'b0011:out2=8'b1011_0000; //3

8'b0100:out2=8'b1001_1001; //4

8'b0101:out2=8'b1001_0010; //5

8'b0110:out2=8'b1000_0010; //6

8'b0111:out2=8'b1111_1000; //7

8'b1000:out2=8'b1000_0000; //8

8'b1001:out2=8'b1001_0000; //9

default:out2=8'b1100_0000;

endcase

endmodule

module Permissions(clk,res,in1,in2,out1,out2,en_jia,en_yi); input clk,res,in1,in2;

output out1,out2,en_jia,en_yi;

reg out1,out2,en_jia,en_yi;

wire w1,w2,a,b;

or u2(w1,in1,in2);

add4 u1(.res(res),.c(w1),.cnt(w2));

select u3(.cnt(w2),.a(a),.b(b));

parameter[1:0] s0=1'b00,s1=1'b01;

reg[1:0] current_state,next_current;

always@(posedge clk or negedge res)

begin

if(!res)

current_state

current_state

end

always@(current_state or next_current) begin

case(current_state)

s0:

begin

out1

en_jia

en_yi

out2

if(a==1)

next_current

next_current

s1:

begin

out1

en_jia

en_yi

out2

if(b==1)

next_current

next_current

endcase

end

endmodule

module add4(res,c,cnt);

input res,c;

output cnt;

reg cnt;

reg[2:0] q;

always@(posedge c or negedge res) begin

if(~res)

begin

q

cnt

end

else

begin

if(q==4)

begin

cnt

q

end

else

begin

q

cnt

end

end

end

endmodule

module select(cnt,a,b);

input cnt;

output a,b;

reg a,b;

always@(cnt)

begin

if(cnt==1)

begin

a

b

end

else

begin

a

b

end

end

endmodule

module goal(res,buzz,jia,yi,en); input res,jia,yi; output buzz,en;

reg buzz,en; reg[12:0] q;

wire w;

or u1(w,jia,yi);

always@(posedge w or negedge res) begin

if(~res)

begin

q

en

buzz

end

else

begin

if(q==2999)

begin

en

q

buzz

end

else

begin

q

en

buzz

end

end

end

endmodule

module timer(t1,t2);

input t2;

output t1;

reg t1;

reg[8:0] cnt;

always@(posedge t2)

begin

if(cnt==499)

begin

cnt

t1

cnt

endmodule


相关内容

  • 电子综合课程设计题目
  • 电子综合课程设计题目汇总 1. 水温控制系统设计 任务:设计并制作一个水温自动控制系统,控制对象为1升净水,容器为搪瓷器皿.水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动控制,以保持设定的温度基本不变. 要求: 1)基本要求 (1)温度设定范围为40-90℃,最小区分度为1℃,标定温度 ...

  • 基于FPGA的视频图像采集系统的设计与实现
  • 第29卷第4期增刊 2008年4月 仪 器 仪表学 报 V01.29No.4Apr.2008 ChineseJournalofScientificInstrument 基于FPGA的视频图像采集系统的设计与实现木 刘泽伟 解梅 (电子科技大学电子工程学院成都610054) 摘要提出并实现了一种基于A ...

  • 单片机题目毕业设计
  • mcu002 ARM硬件电路板设计之外围接口电路研究mcu003 CDMA通信系统中的接入信道部分进行仿真与分析[doc格式+45页+毕业论文1.6万] mcu004 CDMA通信系统中的接入信道部分进行仿真与分析[论文+45页+1.7万+doc] mcu005 CDMA系统的研究与MATLAB仿真 ...

  • 乒乓球比赛游戏机的设计
  • 湖南涉外经济学院 课程设计报告 课程名称:EDA技术与应用 报告题目:乒乓球比赛游戏机的设计 学生姓名: 所在学院: 专业班级: 学生学号: 指导教师: 2014年12月30日 课程设计任务书 乒乓球游戏电路是一个对输入信号.输入时机正确与否的16个LED表示乒乓球球台和乒乓球,用数码管模拟显示器, ...

  • 乒乓球游戏电路课程设计最终完成版
  • 电子课程设计 --基于Verilog的乒乓游戏设计电路 学院: 专业.班级: 姓名: 学号: 指导教师: 2014年12月 引言 可编程器件的广泛应用,为数字系统的设计带来了极大的灵活性.可编程器件可以通过软件编程对硬件的结构和工作方式进行重构,使得硬件的设计可以如同软件设计那样快捷方便.高速发展的 ...

  • 科技文献检索_课程论文
  • 09物理学 汪筠(0908410043) 关于"基于FPGA技术设计电子钟表电路"的科技文 献检索 [摘要] 本文从科研及毕业论文的角度,首先阐述了文献检索的概念及重要意义,然后通过对有关"基于FPGA技术设计电子钟表电路"的科技文献的检索,并对检索过程.结果 ...

  • 识别系统中的特征参数提取过程研究[1]
  • 第5卷第4期2009年10月 沈阳工程学院学报(自然科学版) JournalofShenyangInstituteofEngineering(NaturalScience) VOI.5No.4 Oct.2009 语音识别系统中的特征参数提取过程研究 孟祥斌,尹常永,包妍 (沈阳工程学院自动控制工程系 ...

  • 基于加减交替法除法器的FPGA设计与实现
  • r:''-.?-''.-_-_--_--_-__-___-_--___----__1一 鬯的论文得到两院院士关注}PLD CPLD FPGA应用 文章编号:1008--0570(2008)09-2-0141-03 基于加减交替法除法器的FPGA设计与实现 FPGADesignandImplement ...

  • 电气专业的一些毕业设计题目
  • 电气专业的一些毕业设计题目 电子类: 1.红外遥控照明灯(电路+程序+论文) 2.基于单片机的多功能智能小车设计论文(电路+程序+论文) 3.基于数字信号处理器(DSP)的异步电机直接转矩控制研究(硕士)(论文+上位机下位机软件+程序) 4.简单温度控制系统(仅论文) 5.漏电保护器(电路+程序+论 ...