基于VHDL的数字密码器的设计

更新时间:2024-05-05 21:12:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

基于VHDL的数字密码器的设计

【摘 要】 本论文介绍了一种利用 EDA技术 和VHDL 语言,通过自顶向下的设计方法对数字

密码器进行设计,并在FPGA芯片EPF10K10LC84-4上实现。用FPGA 器件构造系统, 所有算法完全由硬件电路来实现, 使得系统的工作可靠性大为提高。由于FPGA 具有ISP (在系统可编程)功能, 当设计需要更改时, 只需更改FPGA 中的控制和接口电路, 利用EDA 工具将更新后的设计下载到FPGA 中即可, 无需更改外部电路的设计, 大大提高了设计的效率。因此, 采用FPGA 开发的数字系统, 不仅具有很高的工作可靠性, 其升级与改进也极其方便。本文设计的密码器采用6位密码, 比一般的四位密码锁具有更高的安全可靠性, 应用前景十分良好。

摘要 ······················································································································································································1 1 EDA技术概述 ······························································································································································3

1.1 现代电子设计方法—EDA技术 ················································································································· 3

1.1.1 EDA技术的发展历程 ························································································································· 3 1.1.2 EDA技术的基本特征 ························································································································· 3 1.1.3 EDA技术的发展趋势 ····························································································································· 4 1.2 硬件描述语言(VHDL)简介 ························································································································· 5 1.2.1 VHDL的产生与发展 ································································································································ 5 1.2.2 VHDL的基本特征 ···································································································································· 5 1.2.3 VHDL的设计流程 ···································································································································· 6 1.3 可编程逻辑器件(PLD)简介······················································································································· 7 1.3.1 PLD的发展历程 ······································································································································ 7 1.3.2 FPGA/CPLD简介 ······································································································································ 8 1.3.3用FPGA/CPLD进行开发的优点 ············································································································· 8

2 数字密码器的VHDL设计 ·······································································································································8

2.1 数字密码器的总体方案设计 ························································································································· 8 2.1.1 数字密码器的功能描述 ························································································································ 8 2.1.2 数字密码器的内部结构及模块划分 ··································································································· 9 2.1.3 数字密码器的工作过程 ······················································································································ 10 2.2 数字密码器的顶层设计 ·························································································································· 11 2.2.1 顶层模块的输入输出 ·························································································································· 11 2.2.1模块描述 ················································································································································ 11 2.2.2 VHDL设计 ·············································································································································· 12 2.3 数字密码器的底层设计 ······························································································································· 12 2.3.1 分频模块 ··············································································································································· 12 2.3.2 消抖同步模块 ······································································································································· 13 2.3.3 使能电路模块 ······································································································································· 14 2.3.4 密码预置输出模块 ······························································································································· 14 2.3.5 编码模块 ··············································································································································· 15 2.3.6 比较模块 ··············································································································································· 16 2.3.7 计数器选择模块 ··································································································································· 16 2.3.8 数码管显示译码模块 ·························································································································· 17 2.3.9 数码管扫描模块 ··································································································································· 17 2.3.10 指示电路模块 ····································································································································· 18

1

2.3.11 误码模块 ············································································································································· 19 2.3.12 控制器模块 ········································································································································· 19

3 数字密码器的VHDL程序的编译、综合、仿真、验证 ········································································ 22

3.1 编译、综合 ···················································································································································· 22 3.2 模块仿真 ························································································································································ 22 3.2.1 顶层模块仿真 ······································································································································· 22 3.2.2 编码模块仿真 ······································································································································· 23 3.3 FPGA验证 ······················································································································································· 24

4 结束语 ········································································································································································· 24 致谢辞 ············································································································································· 错误!未定义书签。 参考文献 ········································································································································ 错误!未定义书签。 附录 程序清单 ····························································································································································· 24

2

1 EDA技术概述

电子技术的发展,特别是专用集成电路(ASIC)设计技术的日趋进步和完善,推动了数字系统的迅猛发展。传统的“固定功能集成块+连线”的设计方法已不能满足实际需求,根据系统功能要求利用现代电子设计方法—EDA技术,采用自上而下的设计方式,设计出速度快、体积小、重量轻、功耗低的集成电路已成为必然趋势。

1.1 现代电子设计方法—EDA技术

EDA(Electronic Design Automation)即电子设计自动化,它的定义是指利用计算机来完成电子系统的设计。EDA技术就是指以计算机为工作平台、以EDA软件工具为开发环境、以硬件描述语言为设计

[1]

语言、以可编程逻辑器件为实验载体、以ASIC和SoC为设计目标、以电子系统设计为应用方向的电子产品自动化设计过程。在现代电子设计技术领域中,EDA技术已成为主要的设计手段。采用EDA技术可以缩短电系统设计的开发周期,极大地提高了工作效率。

1.1.1 EDA技术的发展历程

EDA 技术不是某一学科的分支,或某种新的技能技术,应该是一门综合性学科。它融合多学科于一体,打破了软件和硬件间的壁垒,使计算机的软件技术与硬件实现、设计效率和产品性能合二为一,它代表了电子设计技术和应用技术的发展方向。就过去近30年的电子技术的发展历程,可大致将EDA技术的发展分为三个阶段。

第一阶段 20世纪70年代,集成电路制作方面,MOS工艺已得到广泛的应用。 可编程逻辑技术及其器件已经问世,计算机作为一种运算工具已在科研领域得到广泛的应用。而在后期,CAD的概念已见雏形。这一阶段人们开始利用计算机取代手工劳动,辅助进行集成电路版图编辑、PCB布局布线等工作。

第二阶段 20世纪80年代,集成电路设计进入了CMOS(互补场效应管)时代。 复杂可编程逻辑器件已进入商业应用,相应的辅助设计软件也已投入使用,而在80年代末,出现了FPGA,CAE和CAD技术的应用更为广泛,它们在PCB设计方面的原理图输入、自动布局布线及PCB分析,以及逻辑设计、逻辑仿真、布尔方程综合和化简等方面担任了重要的角色,特别是各种硬件描述语言的出现、应用和标准化方面的重大进步,为电子设计自动化必须解决的电路建模、标准文档及仿真测试奠定了基础。

第三阶段 进入20世纪90年代,随着硬件描述语言的标准化得到进一步的确立,计算机辅助工程、辅助分析和辅助设计在电子技术领域获得更加广泛的应用,与此同时电子技术在通信、计算机及家电产品生产中的市场需求和技术需求,极大地推动了全新的电子设计自动化技术的应用和发展。特别是集成电路设计工艺步入了超深亚微米阶段,百万门以上的大规模ASIC设计技术的应用,促进了EDA技术的形成。更为重要的是各EDA公司致力于兼容各种硬件实现方案和支持标准硬件描述语言的EDA工具软件的研究,都有效地将EDA技术推向成熟。

[2]

1.1.2 EDA技术的基本特征

EDA代表了当今电子设计技术的最新发展方向,它的基本特征是:设计人员按照“自顶向下”的设

3

计方法,对整个系统进行方案设计和功能划分,系统的关键电路用一片或几片专用集成电路(ASIC)实现,然后采用硬件描述语言(HDL)完成系统行为级设计,最后通过综合器和适配器生成最终的目标器

[3]

件,这样的设计方法被称为高层次的电子设计方法。下面介绍与EDA基本特征有关的几个概念。

1、 〝自顶向下〞的设计方法

“自顶向下”的设计方法首先从系统级设计入手,在顶层进行功能方框图的划分和结构设计;在方框图级进行仿真、纠错,并用硬件描述语言对高层次的系统行为进行描述;在功能级进行验证,然后用逻辑综合优化工具生成具体的门级逻辑电路的网表,其对应的物理实现级可以是印刷电路板或专用集成电路。“Top-down”设计方法有利于在早期发现结构设计中的错误,提高设计的一次成功率,因而在现代EDA系统中被广泛采用。

2、 硬件描述语言(HDL)

用硬件描述语言进行电路与系统的设计是当前EDA技术的一个重要特征。与传统的原理图输入设计方法相比较,硬件描述语言更适合于规模日益增大的电子系统,它还是进行逻辑综合优化的重要工具。硬件描述语言使得设计者在比较抽象的层次上描述设计的结构和内部特征。它的突出优点是:语言的公开可利用性;设计与工艺的无关性;宽范围的描述能力;便于组织大规模系统的设计;便于设计的复用和继承等。目前最常用的硬件描述语言有VHDL和Verilog-HDL,它们都已经成为IEEE标准。

3、 逻辑综合优化

逻辑综合功能将高层次的系统行为设计自动翻译成门级逻辑的电路描述,做到了设计与工艺的独立。优化则是对于上述综合生成的电路网表,根据布尔方程功能等效的原则,用更小更快的综合结果替代一些复杂的逻辑电路单元,根据指定的目标库映射成新的网表。

4、 开放性和标准化

框架是一种软件平台结构,它为EDA工具提供了操作环境。框架的关键在于提供与硬件平台无关的图形用户界面以及工具之间的通信、设计数据和设计流程的管理等,此外还应包括各种与数据库相关的服务项目。任何一个EDA系统只要建立了一个符合标准的开放式框架结构,就可以接纳其他厂商的EDA工具一起进行设计工作。这样,框架作为一套使用和配置EDA软件包的规范,就可以实现各种EDA工具间的优化组合,并集成在一个易于管理的统一的环境之下,实现资源共享。

5、ASIC设计

现代电子产品的复杂度日益提高,一个电子系统可能由数万个中小规模集成电路构成,这就带来了体积大、功耗大、可靠性差的问题。解决这一问题的有效方法就是采用ASIC芯片进行设计。ASIC按照设计方法的不同可分为全定制ASIC、半定制ASC和可编程ASIC(也称为可编程逻辑器件)。

设计全定制ASIC芯片时,设计师要定义芯片上所有晶体管的几何图形和工艺规则,最后将设计结果交由m厂家去进行格模制造,做出产品。这种设计方法的优点是芯片可以获得最优的性能,即面积利用率高、速度快、功耗低,而缺点是开发周期长,费用高,只适合大批量产品开发。

半定制ASIC芯片的版图设计方法分为门阵列设计法和标准单元设计法,这两种方法都是约束性的设计方法,其主要目的就是简化设计,以牺牲芯片性能为代价来缩短开发时间。

可编程逻辑芯片与上述掩模ASIC的不同之处在于:设计人员完成版图设计后,在实验室内就可以烧制出自己的芯片,无须IC厂家的参与,大大缩短了开发周期。

可编程逻辑器件自70年代以来,经历了PAL、GAL、CPLD、FPGA几个发展阶段,其中CPLD/FPGA高密度可编程逻辑器件,目前集成度已高达200万门/片,它将格模ASC集成度高的优点和可编程逻辑器件设计生产方便的特点结合在一起,特别适合于样品研制或小批量产品开发,使产品能以最快的速度上市,而当市场扩大时,它可以很容易地转由掩模ASIC实现,因此开发风险也大为降低。

上述ASIC芯片,尤其是CPLD/FPGA器件,已成为现代高层次电子设计方法的实现载体。

1.1.3 EDA技术的发展趋势

随着大规模集成电路技术和计算机技术的不断发展,在涉及工业自动化、计算机应用、仪器仪表等领域的电子系统设计工作中,EDA技术的含量正以惊人的速度上升,电子类的高新技术项目的开发也日

[4]

益依赖于EDA技术的应用。即使是普通的电子产品的开发,EDA技术常常使一些原来的技术瓶颈得以

4

轻松突破,从而使产品的开发周期大为缩短、性能价格比大幅度提高。所以EDA技术将成为电子设计领域中的极其重要的组成部分。电子设计专家认为,单片机时代己经结束,未来将是EDA的时代。随着微电子技术的飞速进步,电子学进入了一个崭新的时代。其特征是电子技术的应用以空前规模和速度渗透到各行各业。各行业对自己专用集成电路(ASIC)的设计要求日趋迫切,可编程器件的广泛应用,为各行业的电子系统设计工程师自行开发本行业专用的ASIC提供了技术和物质条件。与单片机系统开发相比,利用EDA技术对FPGA/CPLD的开发,通常是一种借助于软件的纯硬件开发,可以通过这种途径进行专用ASIC开发,而最终的ASIC芯片,可以是FPGA/CPLD,也可以是专制的门阵列掩模芯片,FPGA/CPLD起到了硬件仿真ASIC芯片的作用。

1.2 硬件描述语言(VHDL)简介

EDA技术的设计语言是硬件描述语言HDL,它采用软件编程的方式来描述电子系统的逻辑功能、电路结构和连接方式等。利用这种语言,数字电路系统的设计可以从上层到下层(从抽象到具体)逐层描述自己的设计思想,用一系列分层次的模块来表示极其复杂的数字系统。然后,利用电子设计自动化(EDA)工具,逐层进行仿真验证,再把其中需要变为实际电路的模块组合,经过自动综合工具转换到门级电路网表。接下去,再用专用集成电路ASIC或现场可编程门阵列FPGA自动布局布线工具,把网表转换为要实现的具体电路布线结构。

1.2.1 VHDL的产生与发展

美国于1981年提出了一种新的、标准化的HDL,称之为VHSIC(Very High Speed Integrated Circuit) Hardware Description Language,简称VHDL。这是一种用形式化方法来描述数字电路和设计数字逻辑系统的语言。设计者可以利用这种语言来描述自己的设计思想,然后利用电子设计自动化工具进行仿真,再自动综合到门级电路,最后用PLD实现其功能。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语言将承担起大部分的数字系统设计任务。

1.2.2 VHDL的基本特征

与其它的硬件描述语言相比,VHDL具有更强的行为描述能力,能够避开具体的器件结构,从行为功能上对数字电路系统设计进行描述。VHDL具有如下的基本特征:

1、设计功能强、方法灵活、支持广泛。VHDL语言可以支持自上而下的设计方法,它具有功能强大的语言结构,可用简洁明确的代码描述来进行复杂控制逻辑的设计,可硕士学位论文绪论以支持同步电路、异步电路、以及其他随机电路的设计。其范围之广是其他HDL语言所不能比拟的。此外,VHDL语言可以自定义数据类型,这也给编程人员带来了较大的自由和方便。

2、系统硬件描述能力强。VHDL语言具有多层次的设计描述功能,可以从系统的数字模型直到门级电路,支持设计库和可重复使用的元件生成,它支持阶层设计且提供模块设计的创建。VHDL语言能进行系统级的硬件描述是它的一个最突出的优点。

3、可以进行与工艺无关编程。VHDL语言设计系统硬件时,没有嵌入描述与工艺相关的信息,不会因为工艺变化而使描述过时。与工艺技术有关的参数可通过VHDL提高的类属加以描述,工艺改变时,只需修改相应程序中的类属参数即可。

4、VHDL语言标准、规范,易于共享和复用。VHDL既是IEEE承认的标准,故VHDL的描述可以被不同的EDA设计工具所支持。从一个仿真工具移植到另一个仿真工具,从一个综合工具移植到另一个综合

5

工具,从一个工作平台移植到另一个工作平台去执行。这意味着同一个VHDL设计描述可以在不同的设计项目中采用,方便了设计成果的设计和交流。另外,VHDL语言的语法比较规范,从而其可读性比较好,给阅读和使用都带来了极大的好处。

5、方便向ASIC移植。VHDL语言的效率之一,就是如果设计是被综合到一个CPLD或FPGA,则可以设计的产品以最快速度上市。当产品的产量达到相当的数量时,采用VHDL进行的设计可以很容易转成用专用集成电路来实现,仅仅需要更换不同的库重新进行综合。由于VHDL是一个成熟的定义型语言,可以确保ASIC厂商交付优良品质的器件产品。此外,由于工艺技术的进步,需要采用更先进的工艺时,仍可以采用原来的VHDL代码。

1.2.3 VHDL的设计流程

利用VHDL语言进行设计可分为以下几个步骤:

1、设计要求的定义。在从事设计进行编程VHDL代码之前,必须先对你的设计目的和要求有一个明确的认识.对所需的信号建立时间、时钟/输出时间、最大系统工作频率、关键的路径等这些要求,要有一个明确的定义,这将有助于你的设计,然后再选择适当的设计方式和相应的器件结构,进行设计的综合。

2、用VHDL语言进行设计描述。(l)应决定设计方式,设计方式一般说来有三种:自顶向下设计,自底向上设计,平坦式设计。前两种方式包括设计阶层的生成,而后一种方式将描述的电路当作单模块电路来进行的。自顶向下的处理方式要求将你的设计分成不同的功能元件,每个元件具有专门定义的输入和输出,并执行专门的逻辑功能.首先生成一个由各功能元件相互连接形成的顶层块来做成一个网表,然后再设计其中的各个元件。而自底向上的处理方法正好相反。平坦式设计则是指所有功能元件均在同一层和同一图中详细进行的。(2)编写设计代码。编写VHDL语言的代码与编写其他计算机科技大学硕士学位论文绪论程序语言的代码有很大的不同。必须清醒地认识到正在设计硬件,编写的VHDL代码必须能够综合到采用可编程逻辑器件来实现的数字逻辑中。懂得EDA工具中仿真软件和综合软件的大致工作过程,将有助于编写出优秀的代码。

3、用VHDL仿真器对VHDL原代码进行功能仿真。对于大型设计,采用VHDL仿真软件对其进行仿真可以节省时间,可以在设计的早期阶段检测到设计中的错误,从而进行修正,以便尽可能地减少对设计日程计划的影响。因为对于小型设计,其综合优化、配置花费的时间不多,而且在综合优化之后,往往会发现为了实现性能目标,将需要修改设计。在这种情况下,用户事先在原代码仿真时所花费的时间是毫无意义的,因为一旦改变设计,还必须重新再做仿真。

4、利用VHDL综合优化软件对VHDL原代码进行综合优化处理。选择目标器件、输入约束条件后,VHDL综合优化软件工具将对VHDL原代码进行处理,产生一个优化了的网络表,并可以进行粗略的时序仿真。

5、配置将综合优化处理后得到的优化了的网络表,安放到前面选定的CPLD或PPGA目标器件之中,这一过程成为配置。再优化了的网络表配置到目标器件后,从完成的版图上可以得到连线长短、宽窄的信息,把它们反注到原来的网络表,为再次进行时序做准备。

6、配置后的时序仿真。这时的时序仿真将检查诸如信号建立时间、时钟到输出、寄存器到寄存器的时延是否满足要求。因为已经得到实际连线引起的时延数据,所以仿真结果能比较精确地未来芯片的实际性能。如果时延仿真结果不能满足设计的要求,就需要重新对VHDL原代码进行综合优化,并重新装配于新的器件之中,或选择不同速度品质的器件。同时,也可以重新观察和分析VHDL原代码,以确认描述是正确有效的。只有这样,取得的综合优化和配置的结果才符合实际要求。

7、器件编程。在成功地完成了设计描述、综合优化、配置和配置后的时序仿真之后,则可以对器件编程和继续进行系统设计的其他工作。

[5]

1.3 可编程逻辑器件(PLD)简介

PLD(可编程逻辑器件)是与ISP(在系统可编程)技术和EDA(电子设计自动化)工具紧密结合、同时进行的。它代表了数字电信领域的最高水平,给数字电路的设计带来了革命性的变化。从70 年代

6

第一片可编程逻辑器件PROM的诞生到现在的CPLD/FPGA,数字系统的设计发生了本质的变化。从传统的对电路板的设计到现在的基于芯片的设计,使得数字系统设计的效率大大提高,产品更新速度大大加快,设计周期大大变短。

1.3.1 PLD的发展历程

最早的可编程逻辑器件出现在20世纪70年代,主要是可编程只读存储器(PROM)和编程逻辑阵列(PLA)。20世纪70年代末出现了可编程逻辑阵列(PAL-Programmable Array Logic)器件。20世纪

[6]

80年代初期,美国Lattice公司推出了一种新型的PLD器件,称为通用阵列逻辑(GAL-Generic Array Logic),一般认为它是第二代PLD器件。随着技术的进步,生产工艺的不断改进,器件规模不断扩大,逻辑功能不断增强,各种可编程逻辑器件如雨后春笋般涌现,如PROM、EPROM等。在EPROM基础上出现的高密度可编程逻辑器件称为EPLD或CPLD。现在一般把超过某一集成度的PLD器件都称为CPLD。在20世纪80年代中期,美国Xilinx公司首先推出了现场可编程门阵列(FPGA)。FPGA器件采用逻辑单元阵列结构和静态随机存取存储器工艺,设计灵活,集成度高,可无限次反复编程,并可现场模拟调试验证。在20世纪90年代初,Lattice公司又推出了在系统可编程大规模集成电路(ispLSI)。

1.3.2 FPGA/CPLD简介

FPGA/CPLD都是高密度现场可编程逻辑芯片,都能够将大量的逻辑功能集成于一个单片集成电路中,其集成度己发展到现在的几百万门。复杂可编程逻辑CPLD是由PAL或GAL发展而来的。它采用全局金属互连导线,因而具有较大的延时可预测性,易于控制时序逻辑,但功耗比较大。现场可编程门阵列(FPGA)是由掩膜可编程门阵列和可编程逻辑器件二者演变而来的,并将它们的特性结合在一起。因此FPGA既具有门阵列的高逻辑密度和通用性,又有可编程特性。FPGA通常由布线资源分割的可编程逻辑单元(或宏单元)构成阵列,又有可编程UO单元围绕阵列构成整个芯片。其内部资源是分段互联的因而

[7]

延时不可预测,只有编程完毕后才能实际测量。CPLD和FPGA建立内部可编程逻辑连接关系的编程技术有三种:基于反熔丝技术的器件只允许对器件编程一次,编程后不能修改。其优点是集成度、工作频率和可靠性都很高,适用于电磁辐射干扰较强的恶劣环境。基于EEPROM存储器技术的可编程逻辑芯片能够重复编程100次以上,系统掉电后编程信息也不会丢失。编程方法分为在编程器上编程和用下载电缆编程。用下载电缆编程的器件,只要先将器件装焊在电路板上,通过PC、SUN工作站、就能产生编程所有的标准5V、3.3V或2.5V逻辑电平信号,也称为ISP方式编程,其调试和维修也很方便。基于SRAM技术的器件编程数据存储于器件的RAM区中,使之具有用户设计的功能。在系统不加电时,编程数据存储在EPROM、硬或软盘中。系统加电时将这些编程数据即时写入可编程器件,从而实现板级或系统级的动态配置。

1.3.3 用FPGA/CPLD进行开发的优点

基于EDA技术的FPGA/CPLD器件的开发应用可以从根本上解决MCU所遇到的问题。与MCU相比,

[8]

FPGA/CPLD的优势是多方面的和根本性的:

1、编程方式简便、先进。FPGA/CPLD产品越来越多地采用了先进的IEEE1149.1边界扫描测试(BST)技术和ISP。在+5V工作电平下可随时对正在工作的系统上的FPGA/CPLD进行全部或部分地在系统编程,并可进行所谓菊花链式多芯片串行编程,对于SRAM结构的FPGA,其下载编程次数没有限制。

2、高速。FPGA/CPLD的时钟延迟可达纳秒级,结合其并行工作方式,在超高速应用领域和实时测控方面有非常广阔的应用前景。

3、高可靠性。在高可靠应用领域,MCU的缺憾为FPGA/CPLD的应用留下了很大的用武之地。除了不存在MCU所特有的复位不可靠与PC可能跑飞等固有缺陷外,FPGA/CPLD的高可靠性还表现在几乎可将整个系统下载于同一芯片中,从而大大缩小了体积,易于管理和屏蔽。

4、开发工具和设计语言标准化,开发周期短。由于FPGA/CPLD的集成规模非常大,集成度可达数百万门。因此,FPGA/CPLD的设计开发必须利用功能强大的EDA工具,通过符合国际标准的硬件描述语言(如VHDL)来进行电子系统设计和产品的和开发。由于开发工具的通用性、设计语言的标准化以及设

7

计过程几乎与所有的FPGA/CPLD器件结构没有关系,所以设计成功的各类逻辑功能块软件有很好的兼容性和可移植性,它几乎可用于任何型号的FPGA/CPLD中由此还可以知识产权的方式得到确认,并被注册成为所谓的IP芯核从而使得片上系统的产品设计效率大幅度提高。由于相应的EDA软件功能完善而强大,仿真方式便捷而实时,开发过程形象而直观,兼之硬件因素涉及甚少,因此可以在很短时间内完成十分复杂的系统设计,这正是产品快速进入市场的最宝贵的特征。EDA专家预言,未来的大系统的FPG刀CPLD设计仅仅是各类再应用逻辑与IP芯核的拼装,其设计周期最少仅数分钟。

5、功能强大,应用广阔。目前,FPGA/CPLD可供选择范围很大,可根据不同的应用选用不同容量的芯片。利用它们可实现几乎任何形式的数字电路或数字系统的设计。随着这类器件的广泛应用和成本的大幅度下降,FPGA/CPLD周期系统中的直接应用率正直逼ASIC的开发。

2 数字密码器的VHDL设计

本次设计的数字密码器将实现一般数字密码器的基本功能,并且能够预置任意位密码,比一般的四位密码锁具有更高的安全可靠性。本次设计将利用EDA技术自顶向下的设计方法,采用VHDL语言进行设计输入,并在MAX+PLUSⅡ开发软件上进行编译、仿真、编程、下载,最后在ALTERA公司开发的FPGA芯片EPF10K10LC84-4上实现。

2.1 数字密码器的总体方案设计 2.1.1 数字密码器的功能描述

一个简单的数字密码器是由密码器主体以及附加的外围指示电路组成的,其中密码器主体的作用是用来接受密码并进行密码的验证操作;附加的外围指示电路的主要作用是用来显示输入的密码和根据密码验证的结果来给出不同的指示灯显示或者启动报警装置,而报警装置则通常采用扬声器。

[9]

下面给出数字密码器的系统结构图,如图2-1所示。

WAIT_T SETUP READY OPEN_T A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 GND 数 字 密 码 器 LED_G LED_R ALERT 扬声器

A B 7 C D E F G E D F G C 绿灯 红灯 A B 外部时钟CLK 图2-1 数字密码器的系统结构图

8

在本设计中,数字密码器的功能描述如下所示:

1、密码器的工作时钟由外部晶振来提供,时钟频率为300Hz;

2、密码预先在内部设置,可以设置任意位密码,这里采用6位十进制数字作为密码;

3、密码输入正确后,密码器将启动开启装置。这里密码器只接受前6位密码输入,并以按键音提 示,多余位数的密码输入将不起作用;

4、采用6位7段LED对输入的密码进行动态扫描显示;

5、允许密码输入错误的最大次数为三次, 口令错误次数超过三次则进入死锁状态, 并发出警报; 6、报警后,内部人员可以通过按键SETUP使密码器回到初始等待状态;

7、开启装置开启后,操作人员可以通过按键WAIT_T使密码器回到初始等待状态; 8、密码器具有外接键盘,可以用来输入密码和操作指令;

9、内部按键SETUP不由外接键盘提供,需要放在外部人员不能进入的地方。

2.1.2 数字密码器的内部结构及模块划分

在数字电路设计中,自顶向下的设计方法的主要思想是对数字系统进行模块划分,这样可以将复杂的设计简化成相对简单的模块设计,不同的模块用来完成数字系统中某一部分的具体功能。可见,划分模块是设计过程中一个非常重要的步骤。在这一步,必须花费一定的时间,从而保证模块划分的最优化,这样可以大大减小后面VHDL程序编写的工作量。

[10]

9

指示电路模块

绿灯 LED_G 红灯 LED_R WAIT_T SETUP READY OPEN_T 消 抖 同 步 电 路 C11 C22 C33 C44 WAIT_L S_LG RS RS 控 制 器S_LR ALERT NOTC 密码错误次数达到3次 计数器2 ANC DEP FULL EN DUS CNP RESET DATA_IN 计数器满 计数器1 S0 S1 S2 4位六选一数据选择器 A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 使 能 电 路 A00 A10 A20 A30 A40 A50 A60 A70 A80 A90 消抖同步电路 A01 A11 A21 A31 A41 A51 A61 A71 A81 A91 编 码 器 E1 E2 E3 E4 B1 B2 B3 B4 比较器 IN1 IN2 IN3 IN4 IN5 IN6 数 码 管 扫 描 模 块 DATA 数码管显示译码… 1 6 a - g … CLK 分频模块CLK_DIV1 CLK_DIV2 图2-2 数字密码器的模块划分图

SEL[2..0] 数码管选择信号 根据本次设计的数字密码器的功能描述,可以进一步将它划分为如图2-2所示的结构框图。由图可知,整个数字密码器系统主要包括分频模块、消抖同步模块、使能电路模块、密码预置模块、编码模块、比较模块、计数器选择模块、数码管显示译码模块、指示电路模块、数码管扫描模块、误码模块和控制器模块12部分。

2.1.3 数字密码器的工作过程

10

根据图2-2所示的模块划分图,下面介绍一下密码器的具体工作过程。

首先,密码器通过外接键盘输入数字密码,然后密码需要经过10线至4线编码器变成BCD码;接下来通过4位比较器与存储在系统中的预置密码进行比较,同时将输入的密码通过数码管扫描模块和数码管显示译码模块显示出来;最后将比较的结果DEP送到控制器模块中。

本次设计中的密码是串行输入的,每次分别与一个预置码比较。可见,6个十进制的密码分别有24个端口送入,因此需要使用一个数据选择器来进行选择。这里,数据选择器是一个4位的六选一数据选择器,它的两位选择信号是由一个模6的计数器来给出的,计数器的控制信号是由控制信号RESET和时钟信号CNP是由控制模块来提供的。外接键盘每送一个密码数字,计数器的计数值加1。如果计数器的数值计到6时,那么表示6个密码已经输入完毕。接下来计数器应向控制器发出反馈信号FULL,这表示控制器已经可以进入到启动状态。

计数器2用来记录输入密码错误次数,当密码输入错误时,密码器将发出警报,并提示用户还可以输入密码的次数。当密码输入错误的达到次数三次时,计数器2应向控制器反馈信号NOTC, 密码器将进入死锁状态, 并发出警报。这时只能通过内部按键SETUP使密码器回到初始状态。

2.2 数字密码器的顶层设计

密码器的顶层设计由各个子模块构成。其中各个模块是以元件的形式给出的,首先必须进行元件的说明,然后进行元件的例化调用就可以构成顶层模块。顶层设计的模块图如图2-3所示。

图2-3 顶层设计模块图

2.2.1 顶层模块的输入输出

由上图可以给出数字密码器的对外接口信号,即输入和输出信号。 1、 数字按键输入信号A0~A9,用来进行密码的输入操作; 2、 外部时钟信号CLK,用来作为内部操作时钟和驱动蜂鸣器; 3、 按键输入信号READY,用来设置密码器的准备操作状态; 4、 按键输入信号WAIT_T,用来建立密码器的等待状态; 5、 按键输入信号SETUP,用来恢复密码器的等待状态; 6、 按键输入信号OPEN_T, 用来设置密码器进入到启动状态; 7、 绿灯指示驱动信号LED_G,驱动绿灯显示; 8、 红灯指示驱动信号LED_R,驱动红灯显示; 9、 蜂鸣器驱动信号ALERT,驱动报警蜂鸣器; 10、数码管显示译码输出A,B,C,D,E,F,G。

2.2.2 模块描述

11

根据数字密码器的功能描述和模块划分,下面给出密码器输入电路和输出电路功能的具体描述。 1、给密码器上电后按下READY键,表示密码器准备就绪,可以接收外部输入的密码数字;这时用来指示密码器工作状态的指示灯和扬声器都处于不工作状态。

2、通过A0~A9按键输入6位数字密码后按下OPEN_T键:如果密码输入正确并且按键正确,这时密码器将启动开启装置,同时密码器的绿灯亮;如果输入的密码错误,扬声器将发出警告,同时还将提示密码器还可以输入的次数。密码器允许密码输入错误的最大次数为三次, 口令错误次数超过三次则进入死锁状态, 并发出警报。

3、密码器只接受前6位密码输入,并以按键音提示,多余位数的密码输入将不起作用。

4、密码器开启结束后,密码器将进入到下一次开启等待状态。这时,输入电路中需要设置一个WAIT_T按键,目的是使密码器重新进入到等待状态。

5、密码器出于死锁状态时,READY按键和 WAIT_T按键是不起任何作用的。在这种情况下,密码器必须由内部人员通过按键SETUP来对密码器进行重新设置,目的是使其重新回到等待状态。为了密码器的安全起见,按键需放在内部人员办公室或其他外部人员不能进入的地方。

6、如果发现输入的6位密码有错误,这时操作人员可以在按下OPEN_T按键之前按下READY键重新回到密码器准备就绪状态。因此,密码器需要含有一个输入数字密码的显示电路,这里采用6个7段LED对输入的密码进行动态显示。

2.2.3 VHDL设计

本模块设计的VHDL程序为cipher_top.vhd。在该程序中,其中密码器顶层设计的各个模块是以元件的形式给出的,必须进行元件的说明,然后才能进行元件的例化调用。另外,结构体的说明部分还定义了许多中间信号,它们的作用是用来在模块之间传递信息。这里,假设上述调用的元件存放在WORK库的程序包cipher_example中。

2.3 数字密码器的底层设计

前面描述了数字密码器的顶层设计和相应的VHDL程序,下面将介绍密码器系统中各个模块的具体实现和相应的VHDL程序。数字密码器划分为分频模块、消抖同步模块、使能电路模块、密码预置模块、编码模块、比较模块、计数器选择模块、数码管显示译码模块、指示电路模块、数码管扫描模块、误码模块和控制器模块12个部分,顶层设计中各个模块是作为元件来引用的,因此这里需要将各个模块设计成独立设计实体的具体形式,这样便可以在顶层设计来引用这些模块了。

2.3.1 分频模块

1、分频模块的输入、输出

图2-4 分频模块图

分频模块的模块图如图2-4所示,可以定义输入、输出信号如下: CLK: 系统输入时钟,300Hz。

CLK_DIV1、CLK_DIV2: 分频输出时钟信号,分别为10Hz、1Hz。 2、模块描述

在数字密码器中,它的外部时钟信号CLK是由外部晶振来提供的,时钟频率为300Hz。对CLK进行分频输出两路时钟CLK_DIV1 和CLK_DIV2,其中CLK_DIV1作为按键检测消抖时钟和控制器模块时钟,而CLK_DIV2作为密码错误次数计数模块的时钟。CLK时钟信号还作为蜂鸣器启动信号和LED显示扫描时钟信号。CLK_DIV1设为CLK的30分频,为10Hz。再将CLK_DIV1进行10分频可以得到CLK_DIV2时钟,为1HZ。因此,分频模块可以采用10分频和30分频电路来构成,如图2-5所示。

12

CLK 30分频电路 CLK_DIV1 CLK_DIV1 10分频电路 CLK_DIV2 图2-5

3、VHDL设计

由图2-5可知,分频模块内部含有两个单元电路:30分频电路和10分频电路。首先需要进行30分频和10分频这两个单元电路的VHDL设计,这两个单元电路的设计可以采用计数的方法来完成。而对于分频模块的设计,可以通过对两个单元电路元件的例化调用来实现。其中30分频电路和10分频电路的VHDL程序分别为clk_div30.vhd,clk_div10.vhd;分频模块的VHDL程序为clkdiv_model.vhd。

2.3.2 消抖同步模块

1、消抖同步模块的输入、输出信号定义

图2-6 消抖同步模块图

消抖同步模块的模块图如图2-6所示,由图可以得到输入、输出信号定义: 1)输入信号

C1、C2、C3、C4:分别由WAIT_T、SETUP、READY、OPEN_T操作指令得到; AOO~A90:由使能模块提供;

CLK:由分频模块输出的CLK_DIV1(10Hz)来提供; 2)输出信号

C11、C22、C33、C44: 由WAIT_T、SETUP、READY、OPEN_T经过消抖后产生; A01~A91:有AOO~A90经过消抖后产生。 2、模块描述

在数字密码器中,由按键方式产生的数字密码A0~A9、READY、OPEN_T、WAIT_T、SETUP的产生时刻和持续长短是随机不定的,同时存在因开关簧片反弹而引起的电平抖动现象,因此必须添加消抖同步模块,目的是保证系统能捕捉到输入脉冲,同时保证每按一键只形成一个宽度为系统时钟周期的脉冲。

3、VHDL设计

[11]

在数字电路中,消抖同步电路的设计方案较多,本设计采用的是一种应用较为广泛的消抖同步

13

电路。如图2-7所示。因为采用与非门构成的触发器使用底电平触发,因此按键输入的数字或者操作指令要设计成低电平有效。

输入 & D Q D Q CP QCP Q& CLK 图2-7

根据图2-7可以看出消抖同步电路含有两个与非门、一个与门和两个D触发器的VHDL设计,然后构成消抖同步电路的VHDL设计,最后通过元件例化调用完成消抖同步模块的VHDL设计。其中,D触发器的VHDL程序为dff_1.vhd, 消抖同步电路的消抖同步模块的VHDL程序为keysync_model.vhd。

2.3.3 使能电路模块

1、使能电路模块的输入、输出信号定义

图2-8 使能电路模块图

使能电路模块的模块图如图2-8所示,模块的输入、输出信号定义如下:1)输入信号

A0~A9:由按键0~9提供; EN :由控制器模块提供。 2)输出信号

A00~A90:当其为低电平0时,表示对应的A0~A9有信号输入。该输出用于提供给消抖同步模块。2、模块描述 在数字密码器中,数字密码A0~A9的按键输入信号是通过控制器模块给出的使能信号制的:当使能信号有效(高电平)时,输入的信号A0~A9有效;否则输出为高电平。3、VHDL设计

使能电路模块的VHDL程序为enable_model.vhd。

2.3.4 密码预置输出模块

14

& 输出

所以首先必须进行程序为key_sync.vhd,EN来进行控

D触发器。VHDL 1、输入输出定义信号定义

图2-9密码预置输出模块图

密码预置输出模块的模块图如图2-9所示,模块的输入、输出信号定义如下: 1)输入信号

S0、S1、S2:由计数器选择模块提供。 2)输出信号

E1、E2、E3、E4:密码预置信号。 2、模块描述

该模块用来预置密码器的密码,用于与输入的数字密码进行比较操作。密码器的密码可以设置成任意位,这里设为6位,为“654321”。它的输入有三个,分别为s2、s1、s0,由计数器选择模块提供;输出有为4位的2进制密码。

3、VHDL设计

密码预置输出模块的VHDL程序为mux4_model.vhd。

2.3.5 编码模块

1、输入输出信号定义

图2-10 密码预置输出模块图

密码预置输出模块的模块图如图2-10所示,模块的输入、输出定义如下: 1)输入信号

A01~A91:由消抖同步模块提供,对应于数字按键0~9; RESET :由控制器模块提供;

DUS :由控制器模块提供,用于检测是否有按键输入; 2)输出信号

B1~B4:由按键信号转换成4位BCD码,用来提供给比较模块;

DATA_IN:当其为高电平是,表示有密码输入,用来提供给控制器模块; DI :按键音信号,用来提供给指示模块,以驱动扬声器。

IN1~IN6:用于按顺序存储密码,其中IN1用于存储第一位密码,IN6用于存储第六位密码。该信号提供给数码管扫描信号,用于动态显示输入的密码。

15

2、模块描述

编码模块为子模块中的第二大模块,该模块用于将输入的按键信号转换成4位BCD码B1~B4送入到比较器中,这一步将通过10线至4线编码器来完成。除此以外,该模块还将输入的按键信号通过移位寄存器按照按键的顺序存储到6个4位BCD码输出信号in1~in6中,用于提供给数码管扫描模块的输入信号。同时还将输出di信号提供给指示电路模块用于产生按键音。对于编码器的输出来说,B4是MSB,B1是LSB。

3、VHDL设计

编码模块的VHDL程序为encoder_model.vhd。

2.3.6 比较模块

1、输入输出信号定义

图2-11 比较模块图

比较模块的模块图如图2-11所示,模块的输入、输出信号定义如下: 1)输入信号

B1、B2、B3、B4:由编码模块提供,用于与密码预置模块输出的预置密码信号进行比较; E1、E2、E3、E4:密码预置信号,由密码预置模块提供。 2)输出信号

DEP :该信号用于反馈给控制器模块,用于说明比较的结果。 2、模块描述

在数字密码器中,比较模块的主要功能是对编码模块的输出B1~B4这4位数据和密码预置输出模块的输出E1~E4这4位数据进行比较,然后将比较的结果送入控制器模块的DEP端口上。比较器的具体工作原理是:当比较结果相等是,DEP的输出为1;当比较结果不相等时,DEP的输出为0。

3、VHDL设计

比较模块的VHDL程序为comparator_model.vhd。

2.3.7 计数器选择模块

1、输入输出信号定义

计数器选择模块的模块图如图2-12所示,模块的输入、输出信号定义如下: 1)输入信号

RESET:计数器的复位信号。

CNP :计数器的输入脉冲信号,上升沿有效。 2)输出信号

S0、S1、S2:提供给密码预置输出模块的地址选择信号。

FULL: 提供给密码预置输出模块,用于表示6位密码是否输入完毕。

16

图2-12 计数器选择模块图

2、模块描述

在密码器中,计数器选择模块的功能是用来给出密码预置输出模块的地址选择信号S0、S1和S2,它的控制信号RESET和时钟信号CNP是由控制器模块来提供的;另外还有一个输出信号FULL,它表示6个密码已经输入完毕,控制器可以进入到启动状态。

3、VHDL设计

计数器选择模块的VHDL程序为counter_model.vhd。

2.3.8 数码管显示译码模块

1、输入输出信号定义

图2-13 数码管显示译码模块图

数码管显示译码模块的模块图如图2-13所示,模块的输入、输出信号定义如下: 1)输入信号

DATA :4位的BCD码输入信号,由数码管扫描模块提供。 2)输出信号

A、B、C、D、E、F、G:分别对应7段LED的7个输入端口。 2、模块描述

在密码器中,显示设备由8个7段LED组成。前6个LED将显示输入的6个密码,后2个LED在用来在误码状态下显示还可以输入的密码次数。由于采用动态扫描显示,只须输出一个LED所须的驱动信号即可。这里采用共阴极LED,所以输出A~G高电平有效。

3、VHDL设计

数码管显示译码模块的VHDL程序为decoder_model.vhd。

2.3.9 数码管扫描模块

1、输入输出信号定义

数码管扫描模块的模块图如图2-14所示,模块的输入、输出信号定义如下: 1)输入信号

CLKSCAN:数码管扫描频率,来源于系统时钟输入CLK。 RESET:数码管复位信号,由控制器模块提供。

IN1~IN6:数字密码显示输入信号,由编码模块提供。

IN7、IN8:剩余密码输入次数显示输入信号,由密码错误次数计数模块提供。 2)输出信号

DATA:用于提供给数码管显示译码模块的数据输入。

17

SEL: 3位的2进制数码管选择信号,当其为111 ~010时,选择前6位数码管,用于显示输入的密码数字;当其为001~000时,选择后2位数码管,用于显示剩余密码输入次数。

图2-14 数码管扫描模块图

2、模块描述

在密码器中,输入的数字密码需显示在LED上,由于输入由6位,所以至少应采用6个LED进行显示。若采用传统静态显示的方法,不仅需要消耗更大的芯片资源和管脚资源,而且还会在电路中会产生一个比较大的电流,很容易造成电路烧坏。通过动态扫描电路可以解决这一问题,通过产生一个扫描信号SEL(000) - SEL(111) 来控制8 个七段显示器,依次点亮8个七段显示器,也就是每次只点亮一个七段显示器。只要扫描信号SEL(000) - SEL(111) 的频率超过人的眼睛视觉暂留频率24Hz 以上,就可以达到尽管每次点亮单个七段显示器,却能具有8 个同时显示的视觉效果,而且显示也不致闪烁抖动。这里数码管扫描频率采用密码器时钟输入CLK,为300Hz。

3、VHDL设计

数码管扫描模块的VHDL程序为keyscan_model.vhd。

2.3.10 指示电路模块

1、输入输出信号定义

图2-15 指示电路模块图

指示电路模块的模块图如图2-15所示,模块的输入、输出信号定义如下: 1)输入信号

WAIT_L、S_LG、S_LR:由控制器模块提供的红绿灯驱动信号。 DI: 由编码模块提供的按键音信号;

BJY:由密码错误次数计数模块的警告音信号。 CLK_DIV1:用于报警状态下的扬声器驱动信号。 2)输出信号

LED_G:绿灯驱动信号,高电平有效。 LED_R:红灯驱动信号,高电平有效。 ALERT: 扬声器驱动信号,高电平有效。 2、模块描述

18

在密码器中,指示电路模块的功能是用来产生红灯指示LED_R、绿灯指示LED_G和蜂鸣装置ALERT。根据图2-2的模块划分图可以看出,绿灯指示LED_G是由控制器模块提供的置位信号S_LG和按下WAIT_T键时提供的WAIT_L信号通过RS触发器来共同控制的;红灯是由控制器模块提供的置位信号S_LR、信号WAIT_L和BJY来来共同控制的;蜂鸣装置ALERT是由由控制器模块提供的置位信号S_LR、信号WAIT_L、单频信号CLK_DIV1、DI和BJY来共同控制的。

3、VHDL设计

指示电路模块的主要元件是RS触发器,控制器提供的置位和复位信号都应该是低电平有效。所以首先应该进行RS触发器的VHDL设计,然后才能构成指示电路模块的VHDL设计。其中RS触发器的VHDL程序为rs_dff.vhd,指示电路模块的VHDL程序为indicator_model.vhd。

2.3.11 误码模块

1、输入输出信号定义

图2-16 误码模块图

误码模块的模块图如图2-16所示,模块的输入、输出信号定义如下: 1)输入信号

ANC:由控制器模块来提供,表示密码输入错误。

DS :由控制器模块来提供,作为延时和报警的脉冲信号。

CLK:计数脉冲输入,当其计为4时,延时结束,这是如果密码次数还不到3次,则可以再次输入密码。

RET:复位信号,有控制器提供。 2)输出信号

IN7、IN8:用于显示还可以输入的密码次数。

NOTC :当密码错误次数达到3次时有效,为1,它将反馈给控制器模块。 DSW :表示延时结束,这是密码器可以由警告状态进入到密码输入状态。 BJY :警告状态下的红灯和蜂鸣器驱动信号。 2、模块描述

该模块用于对密码输入错误次数进行计数,当密码输入错误次数不达3次时,密码器将进入到警告状态,这时红灯和蜂鸣器会有相应的指示,大约持续4秒后,可以继续输入密码。当密码器的密码错误次数达到3次时,密码器将进入到死锁状态。

3、VHDL设计

根据前面对该模块的描述,可以给出其VHDL程序,为wrong3_model.vhd。

2.3.12 控制器模块

1、输入输出信号定义

控制器模块的模块图如图2-17所示,模块的输入、输出信号定义如下:

19

图2-17 控制器模块图

1)输入信号

C11、C22、C33、C44:由消抖模块提供,分别对应键WAIT_T、SETUP、READY、OPEN_T。 DATA_IN:由编码模块提供,表示有密码输入。

DEP :由比较模块提供,当它为1时,表示输入的数字与预置密码相等。

DSW :由密码错误次数计数器提供,当它为1时,表示定时(4S)完,可以进入到下一个状态。 FULL :由计数选择模块提供,当它为1时,表示已经输入了6位的正确密码,可以进入到启动状态。

NOTC :由密码错误次数计数模块提供,当它为1时,表示密码错误次数已经达到3次。这时将进入到报警状态。

CLK :输入时钟,有分频模块提供,与消抖模块的输入时钟同步。 2)输出信号

EN :输入到使能模块的使能信号。 DUS :输入到编码模块的读数脉冲信号。

ANC :输入到密码错误次数计数模块的密码错误次数计数脉冲。 CNP :输入到计数器选择模块的输入密码位数计数脉冲。

RESET:输入到编码模块、计数器选择模块和数码管扫描模块的复位信号。 DS :输入到密码错误次数计数模块的定时信号。

RET :输入到密码错误次数计数模块的密码错误次数复位信号。

WAIT_L、S_LG、S_LR:输入到指示电路模块的红绿灯和蜂鸣器驱动信号。 2、模块描述

控制器模块为数字密码器的核心部分,它在密码器系统中占有重要的地位,要编好这一部分的程序,必须先对该模块的工作原理有清晰的认识。

控制器模块的工作原理如下所示: 1)建立等待状态

建立等待状态是指密码器处于上电、启动或者报警后的状态,这是密码器并没有进入到正常的等待状态,因此密码器不会接受除WAIT_T信号外的任何输入信号。当操作人员按下WAIT_T键后,密码器将会进入到等待状态,这时用来指示密码器工作情况的指示灯和蜂鸣器都处于不工作状态,同时它还将密码错误次数计数器复位为0。

2)准备就绪状态

准备就绪状态是指密码器在被按下WAIT_T键后处于的一种状态。这时如果操作人员按下READY键,密码器将会进入到第3种状态,等待密码数字的输入。在这种情况下,RESET将被置1,DS信号将被置0。

3)密码输入状态

密码输入状态是控制器模块的第3个状态,这是密码器将进入到密码输入的操作状态。当处于这种状态时,控制器模块的EN输出信号将变为有效,它意味着此时允许数字密码A0~A9的按键输入。在这

20

种情况下,密码器每收到一个按键信号后,控制器模块应该判断出该按键输入是数字密码还是OPEN_T信号。

如果判断出按键输入OPEN_T信号,那么这是就不符合启动程序,这是密码器将转移到报警状态,同时还向密码错误次数计数模块发出ANC时钟,作为密码错误次数计数输入脉冲。是如果判断出是数字按键输入,则提供DUS时钟给编码模块作为密码输入位数计数脉冲信号,同时如果判断出该按键输入为正确密码,则向计数器选择模块发出CNP时钟信号,目的是选出对应的预置密码与输入的密码进行比较。对于比较模块来说,如果DEP的输出为0,那么控制器模块应该转移到密码错误状态;如果DEP的输出为0,那么这时检查计数器选择模块的输出FULL是否有效。如果FULL有效,那么表示已经接收了6个正确的数字密码,控制器模块将转移到启动状态,否则将返回本状态继续接收密码。

4)启动状态

启动状态是控制器模块的第4个状态,这时控制器将判断按键输入的具体信号:如果判断出按键输入是OPEN_T信号,那么将发出S_LG信号;如果判断出是数字按键输入,那么仍向编码模块发出DUS时钟。

5)误码状态

当控制器处于这个状态时,如果按下READY键,那么控制器将发出复位信号RESET,并使控制器返回到密码输入状态:如果按下OPEN_T键,那么控制器将向误码模块发出ANC时钟,同时转移到报警状态;如果判断出是数字按键输入,那么向编码模块发出DUS时钟。

6)报警状态

当控制器处于这个状态时,这时控制器将判断NOTC信号是否有效,如果该信号有效,则表示密码输入错误次数已经达到3次,这时密码器将进入到死锁状态,同时控制器将转移到报警返回状态;如果NOTC信号无效,则向密码错误计数模块发出定时信号,这时指示设备将发出警告信号,这时任何按键输入都将不被响应;如果定时结束(4s)则,密码器将再次进入到准备就绪状态,这时允许再次输入密码。

7)报警返回状态

报警返回状态是控制器模块的最后一个状态,这是密码器将判断输入的具体信号:如果按下SETUP信号,那么控制器模块将返回到密码建立等待状态;如果按下其他键,那么状态将不会发生变化。

根据上面对控制器模块的工作原理的描述,可以画出该模块的状态图,如图2-18所示。其中QA、QB、QC、QD、QE、QF、QG分别对应控制器的建立等待状态、准备就绪状态、密码输入状态、启动状态、误码状态、报警状态、报警返回状态这7个状态。

WAIT_T QA WAIT_T FULL READY QB READY QC READY DSW OPEN_T DEP QG NOTC SETUP 图2-18 控制器模块的状态图 QF OPEN_T QE READY OPEN_T QD SETUP

3、VHDL设计

通过前面对控制器模块的详细介绍,可以给出控制器模块的VHDL描述,其VHDL程序为control_model.vhd。

21

3 数字密码器的VHDL程序的编译、综合、仿真、验证

本课题中设计的所有模块均采用VHDL硬件描述语言进行描述,在Altera公司的MAX+PLUSⅡ开发环境下进行程序的编译、逻辑综合和优化、功能仿真、布局布线以及时序仿真,由Altera公司的FPGA产品FLEX10K系列产品EPF10K10LC84-4实现验证。

3.1 编译、综合

Altera公司的MAX+PLUSⅡ开发环境,由于其目的是形成可下载到可编程逻辑器件(FPGA或CPLD)中的文件,因此,编译、综合过程是一起的。

逻辑综合就是将较高抽象层次的描述自动转换到较低抽象层次描述的一种方法,就设计而言,既将RTL级的描述转换成网表的过程,编译的最终目的是为了生成可以进行仿真、定时分析及下载到可编程逻辑器件的相关文件,如*.cnf,*.rPt,*.snf,*.pof等。由于芯片的资源有限,为了优化输出和工艺映射,就要有相应的约束条件加以控制。以FPGA为目标器件时,设计实体中有的电路要尽量压缩面积而忽略性能要求;而有的电路为了满足关键信号及性能的要求,则要忽略面积占用。所以,速度和面

[12]

积优化的选择在多数情况下是矛盾的,这就要求设计者视具体情况选择,采用一定的优化设计方法。

3.2 模块仿真

下面给出主要模块的仿真波形图。

3.2.1 顶层模块仿真

1、密码输入错误

图3-1 密码输入错误状态的仿真波形图

密码输入错误状态的波形仿真图如图3-1所示,从图中可以看出:输入的密码为854321,而正确密码为654321,所以在按下OPEN_T键后,控制器进入了报警状态(QF),符合控制器工作流程。

2、密码输入正确

密码输入正确下的仿真波形图如图3-2所示。从图中可以看出,当密码输入654321后,控制器进入到了启动状态(QD)。在按下OPEN_T键后,控制器又返回了建立等待状态,同时发出LED_G绿灯驱动信号。这完全符合控制器工作流程,满足设计要求。

22

图3-2 密码输入正确下的仿真波形图

3.2.2 编码模块仿真

编码模块的仿真波形图如图3-3所示,从图中可以看出:当检测到有数字按键输入是,DATA_IN将输出一个时钟周期的高电平,同时该按键信号所代表的数值将通过B4~B1和IN1~IN6存储起来。

图3-3 编码模块的仿真波形图

至此完成了系统软件上的仿真。由于仿真激励文件的不完善,所以时序仿真的通过并不代表加载到FPGA片上的成功,只是通过了FPGA的硬件调试,才是系统设计的真正成功。

由于输入延时及仿真频率的选择问题,输出带有一定的延时,所以应该考虑到输出的延时问题,才能正确的对输入进行设置,从而得到意想的结果。

23

3.3 FPGA验证

FPGA验证就是将编译、综合生成的下载文件下载到指定的芯片上,本设计采用的是EDA—V型实验开发系统。本实验器由主板和下载板组成。下载板由ALTERA公司生产的FPGA(EPF10K10LC84—4)芯片及单片机系统组成,还包括EEPROM等。可以完成FPGA设计资料的下载,存储,显示等功能,可以和主板配合完成CPLD的各种开发及实验。

本设计通过在MAX+PLUSⅡ软件上进行编译、综合,最后下载到FPGA(EPF10K10LC84—4)芯片并在实验开发系统上进行验证,实际测试表明系统的各项功能要求均得到满足并且系统工作良好。

4 结束语

本文设计的密码锁克服了基于单片机的密码锁的可靠性较差的缺点高效的进行功能扩展和产品升级。本设计还突破了一般密码锁只能设置四位密码的限制任意位密码, 具有使用灵活、 性能可靠、 同时本文还通过数字密码器的设计展现出了现代电子设计方法—式的优点。VHDL语言具有很强的电路描述和建模能力而大大简化了硬件设计任务,提高了设计效率和可靠性。用其功能的实现,而不需要对不影响功能的与工艺相关的因素花费过多的时间和精力。它必将是现代电子的重要设计手段和发展方向。

附录1、 顶层模块(cipher_top.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_arith.ALL; USE IEEE.std_logic_unsigned.ALL; USE WORK.cipher_example.ALL; ENTITY cipher_top IS

PORT(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9 : IN std_logic; wait_t : IN std_logic; ready : IN std_logic; setup : IN std_logic; open_t : IN std_logic; clk : IN std_logic;

led_g,led_r,alert : OUT std_logic; a,b,c,d,e,f,g : OUT std_logic;

sel : OUT std_logic_vector(2 DOWNTO 0)); END cipher_top;

ARCHITECTURE cipher_top_arch OF cipher_top IS COMPONENT keysync_model

PORT(c1,c2,c3,c4: IN std_logic;

a00,a10,a20,a30,a40,a50,a60,a70,a80,a90: IN std_logic; clk: IN std_logic;

c11,c22,c33,c44: OUT std_logic;

a01,a11,a21,a31,a41,a51,a61,a71,a81,a91: OUT std_logic); END COMPONENT;

, 利用了FPGA 的ISP 功能可, 可方便的设置, 将有十分良好的应用前景。

EDA 技术的灵活性,层次化设计方

[13]

,能从多个层次对数字系统进行建模和描述,从VHDL 语言实现电路设计者可以专心致力于程序清单

24

安全保密性强等优点 COMPONENT enable_model

PORT(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9: IN std_logic; en: IN std_logic;

a00,a10,a20,a30,a40,a50,a60,a70,a80,a90: OUT std_logic); END COMPONENT;

COMPONENT mux4_model

PORT(s0,s1,s2 : IN std_logic; e1,e2,e3,e4 : OUT std_logic); END COMPONENT;

COMPONENT encoder_model

PORT(a01,a11,a21,a31,a41,a51,a61,a71,a81,a91 : IN std_logic; reset,dus : IN std_logic; b1,b2,b3,b4 : OUT std_logic; data_in,di : OUT std_logic;

in1,in2,in3,in4,in5,in6 : OUT std_logic_vector(3 DOWNTO 0)); END COMPONENT;

COMPONENT comparator_model

PORT(b1,b2,b3,b4: IN std_logic; e1,e2,e3,e4: IN std_logic; dep : OUT std_logic); END COMPONENT;

COMPONENT counter_model

PORT(reset : IN std_logic; cnp : IN std_logic; s0,s1,s2 : OUT std_logic; full : OUT std_logic); END COMPONENT;

COMPONENT decoder_model

PORT(data : IN std_logic_vector(3 DOWNTO 0); a,b,c,d,e,f,g: OUT std_logic); END COMPONENT;

COMPONENT indicator_model

PORT(wait_l : IN std_logic; s_lg : IN std_logic; s_lr : IN std_logic; di,bjy : IN std_logic; clk_div1 : IN std_logic;

led_g,led_r,alert: OUT std_logic); END COMPONENT;

COMPONENT control_model

PORT(c11,c22,c33,c44 : IN std_logic; data_in : IN std_logic; dep,dsw : IN std_logic; full,notc : IN std_logic; clk : IN std_logic; en,dus,anc: OUT std_logic;

25

cnp,reset : OUT std_logic; ds,ret : OUT std_logic;

s_lr,s_lg,wait_l: OUT std_logic); END COMPONENT;

COMPONENT clkdiv_model

PORT(clk : IN std_logic;

clk_div1 : OUT std_logic; clk_div2 : OUT std_logic); END COMPONENT;

COMPONENT keyscan_model

PORT(clkscan,reset : IN std_logic; in1,in2,in3,in4,

in5,in6,in7,in8 : IN std_logic_vector(3 DOWNTO 0); data : OUT std_logic_vector(3 DOWNTO 0); sel : OUT std_logic_vector(2 DOWNTO 0)); END COMPONENT;

COMPONENT wrong3_model

PORT(anc,ds : IN std_logic; clk,ret: IN std_logic;

in7,in8: OUT std_logic_vector(3 DOWNTO 0); notc,dsw : OUT std_logic; bjy : OUT std_logic); END COMPONENT;

SIGNAL e1,e2,e3,e4 : std_logic; SIGNAL b1,b2,b3,b4 : std_logic; SIGNAL dus,di,bjy : std_logic; SIGNAL anc,ds,ret : std_logic; SIGNAL notc,dsw : std_logic; SIGNAL c11,c22,c33,c44 : std_logic;

SIGNAL a00,a10,a20,a30,a40,a50,a60,a70,a80,a90 : std_logic; SIGNAL a01,a11,a21,a31,a41,a51,a61,a71,a81,a91 : std_logic; SIGNAL en,data_in : std_logic;

SIGNAL wait_l,s_lg,s_lr : std_logic; SIGNAL reset,cnp : std_logic; SIGNAL full,dep : std_logic; SIGNAL s0,s1,s2 : std_logic;

SIGNAL clk_div1,clk_div2 : std_logic;

SIGNAL data : std_logic_vector(3 DOWNTO 0);

SIGNAL in1,in2,in3,in4,in5,in6,in7,in8 : std_logic_vector(3 DOWNTO 0); BEGIN

U1: keysync_model

PORT MAP(wait_t,setup,ready,open_t,a00,a10,a20,a30,a40,a50,a60,a70,a80,a90, clk_div1,c11,c22,c33,c44,a01,a11,a21,a31,a41,a51,a61,a71, a81,a91); U2: enable_model

PORT MAP(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,en,a00,a10,

26

a20,a30,a40,a50,a60,a70,a80,a90); U3: mux4_model

PORT MAP(s0,s1,s2,e1,e2,e3,e4); U4: encoder_model

PORT MAP(a01,a11,a21,a31,a41,a51,a61,a71,a81,a91,reset,dus,b1, b2,b3,b4,data_in,di,in1,in2,in3,in4,in5,in6); U5: comparator_model

PORT MAP(b1,b2,b3,b4,e1,e2,e3,e4,dep); U6: counter_model

PORT MAP(reset,cnp,s0,s1,s2,full); U7: decoder_model

PORT MAP(data,a,b,c,d,e,f,g); U8: indicator_model

PORT MAP(wait_l,s_lg,s_lr,di,bjy,clk,led_g,led_r,alert); U9:control_model

PORT MAP(c11,c22,c33,c44,data_in,dep,dsw,full,notc,clk_div1,en,dus,anc,cnp,reset, ds,ret,s_lr,s_lg,wait_l); U10:clkdiv_model

PORT MAP(clk,clk_div1,clk_div2); U11:keyscan_model

PORT MAP(clk,reset,in1,in2,in3,in4,in5,in6,in7,in8,data, sel);

U12:wrong3_model

PORT MAP(anc,ds,clk_div2,ret,in7,in8,notc,dsw,bjy); END cipher_top_arch;

2、 30分频单元电路(clk_div30.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY clk_div30 IS

PORT(clk : IN std_logic;

clk_div : OUT std_logic); END clk_div30;

ARCHITECTURE behave OF clk_div30 IS BEGIN

PROCESS(clk)

VARIABLE count:std_logic_vector(3 DOWNTO 0); VARIABLE clk_tmp: std_logic; BEGIN

IF(clk'event AND clk='1') THEN IF(count=\

count := (OTHERS => '0'); clk_tmp := NOT clk_tmp; ELSE

count := count+1;

27

END IF; END IF;

clk_div <= clk_tmp; END PROCESS; END behave;

3、 10分频单元电路(clk_div10.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY clk_div10 IS

PORT(clk : IN std_logic;

clk_div : OUT std_logic); END clk_div10;

ARCHITECTURE behave OF clk_div10 IS BEGIN

PROCESS(clk)

VARIABLE count:std_logic_vector(2 DOWNTO 0); VARIABLE clk_tmp: std_logic; BEGIN

IF(clk'event AND clk='1') THEN IF(count=\

count := (OTHERS => '0'); clk_tmp := NOT clk_tmp; ELSE

count := count+1; END IF; END IF;

clk_div <= clk_tmp; END PROCESS; END behave;

4、 分频模块(clkdiv_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY clkdiv_model IS

PORT(clk : IN std_logic;

clk_div1 : OUT std_logic; clk_div2 : OUT std_logic); END clkdiv_model;

ARCHITECTURE clkdiv_model_arch OF clkdiv_model IS COMPONENT clk_div30

PORT(clk : IN std_logic; clk_div : OUT std_logic); END COMPONENT;

28

COMPONENT clk_div10

PORT(clk : IN std_logic; clk_div : OUT std_logic); END COMPONENT;

SIGNAL tmp1 : std_logic; BEGIN

U1 : clk_div30

PORT MAP(clk,tmp1); U2 : clk_div10

PORT MAP(tmp1,clk_div2); clk_div1 <= tmp1; END clkdiv_model_arch;

5、 D触发器模块(dff_1.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY dff_1 IS

PORT(d,clk :IN std_logic; q,qb :OUT std_logic); END dff_1;

ARCHITECTURE rtl OF dff_1 IS BEGIN

PROCESS(clk) BEGIN

IF(clk'event AND clk='1') THEN q <=d;

qb<= NOT d; END IF; END PROCESS; END rtl;

6、 消抖同步电路(key_sync.vhd ) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY key_sync IS PORT(

key_in : IN STD_LOGIC; clk : IN STD_LOGIC; key_out : OUT STD_LOGIC); END key_sync;

ARCHITECTURE a OF key_sync IS COMPONENT dff_1 PORT(

d,clk :IN STD_LOGIC; q,qb :OUT STD_LOGIC); END COMPONENT;

29

SIGNAL tmp1,tmp2,tmp3,tmp4,tmp5,tmp6 :std_logic; BEGIN

tmp2 <=key_in NAND tmp1; tmp1 <=tmp3 NAND tmp2; key_out <= tmp4 AND tmp5; U1:dff_1

PORT MAP(tmp2,clk,tmp4,tmp3); U2:dff_1

PORT MAP(tmp4,clk,tmp6,tmp5); END a;

7、 消抖同步模块LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY keyscan_model IS

PORT(clkscan,reset : IN std_logic; in1,in2,in3,in4,

in5,in6,in7,in8 : IN std_logic_vector(3 DOWNTO 0); data : OUT std_logic_vector(3 DOWNTO 0); sel : OUT std_logic_vector(2 DOWNTO 0)); END keyscan_model;

ARCHITECTURE rtl OF keyscan_model IS

SIGNAL count: std_logic_vector(2 DOWNTO 0); BEGIN

PROCESS(clkscan,reset) BEGIN

IF(reset='1') THEN count <= \

ELSIF(clkscan'event AND clkscan='1') THEN IF(count=\

count <=\ ELSE

count <= count+1; END IF; END IF;

END PROCESS; PROCESS(count) BEGIN

CASE count IS

WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \

(keysync_model.vhd ) 30

WHEN \ WHEN \ WHEN OTHERS => data <= \ END CASE; END PROCESS; sel <= count; END rtl;

8、 使能电路模块(enable_model.vhd ) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY enable_model IS

PORT(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9: IN std_logic; en: IN std_logic;

a00,a10,a20,a30,a40,a50,a60,a70,a80,a90: OUT std_logic); END enable_model;

ARCHITECTURE enable_model_arch OF enable_model IS BEGIN

PROCESS(en,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9) BEGIN

IF(en='1') THEN a00 <= a0; a10 <= a1; a20 <= a2; a30 <= a3; a40 <= a4; a50 <= a5; a60 <= a6; a70 <= a7; a80 <= a8; a90 <= a9; ELSE

a00 <= '1'; a10 <= '1'; a20 <= '1'; a30 <= '1'; a40 <= '1'; a50 <= '1'; a60 <= '1'; a70 <= '1'; a80 <= '1'; a90 <= '1'; END IF; END PROCESS; END enable_model_arch;

31

9、 密码预置输出模块(mux4_model.vhd ) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY mux4_model IS

PORT(s0,s1,s2 : IN std_logic;

e1,e2,e3,e4 : OUT std_logic); END mux4_model;

ARCHITECTURE mux4_model_arch OF mux4_model IS SIGNAL comb : std_logic_vector(2 DOWNTO 0); BEGIN

comb <= s2&s1&s0; PROCESS(comb) BEGIN

IF(comb=\

e1 <= '0'; e2 <='1'; e3 <='1'; e4 <='0'; ELSIF(comb=\

e1 <= '1'; e2 <='0'; e3 <='1'; e4 <='0'; ELSIF(comb=\

e1 <= '0'; e2 <='0'; e3 <='1'; e4 <='0'; ELSIF(comb=\

e1 <= '1'; e2 <='1'; e3 <='0'; e4 <='0'; ELSIF(comb=\

e1 <= '0'; e2 <='1'; e3 <='0'; e4 <='0'; ELSIF(comb=\

e1 <= '1'; e2 <='0'; e3 <='0'; e4 <='0'; ELSE

e1 <= '1'; e2 <='1'; e3 <='1'; e4 <='1'; END IF; END PROCESS; END mux4_model_arch;

10、编码模块(encoder_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY encoder_model IS

PORT(a01,a11,a21,a31,a41,a51,a61,a71,a81,a91 : IN std_logic; reset,dus : IN std_logic; b1,b2,b3,b4 : OUT std_logic; data_in,di : OUT std_logic;

in1,in2,in3,in4,in5,in6 : OUT std_logic_vector(3 DOWNTO 0)); END encoder_model;

ARCHITECTURE encoder_model_arch OF encoder_model IS SIGNAL count : integer RANGE 0 TO 7; SIGNAL duw,d_in: std_logic;

SIGNAL data_tmp,io1,io2,io3,io4,io5,io6 : std_logic_vector(3 DOWNTO 0);

32

BEGIN

PROCESS(a01,a11,a21,a31,a41,a51,a61,a71,a81,a91) BEGIN

IF(a01='1') THEN

data_tmp <= \

b1 <= '0'; b2 <='0'; b3 <='0'; b4 <='0'; d_in <='1';

ELSIF(a11='1') THEN data_tmp <= \

b1 <= '1'; b2 <='0'; b3 <='0'; b4 <='0'; d_in <='1';

ELSIF(a21='1') THEN data_tmp <= \

b1 <= '0'; b2 <='1'; b3 <='0'; b4 <='0'; d_in <='1';

ELSIF(a31='1') THEN data_tmp <= \

b1 <= '1'; b2 <='1'; b3 <='0'; b4 <='0'; d_in <='1';

ELSIF(a41='1') THEN data_tmp <= \

b1 <= '0'; b2 <='0'; b3 <='1'; b4 <='0'; d_in <='1';

ELSIF(a51='1') THEN data_tmp <= \

b1 <= '1'; b2 <='0'; b3 <='1'; b4 <='0'; d_in <='1';

ELSIF(a61='1') THEN data_tmp <= \

b1 <= '0'; b2 <='1'; b3 <='1'; b4 <='0'; d_in <='1';

ELSIF(a71='1') THEN data_tmp <= \

b1 <= '1'; b2 <='1'; b3 <='1'; b4 <='0'; d_in <='1';

ELSIF(a81='1') THEN data_tmp <= \

b1 <= '0'; b2 <='0'; b3 <='0'; b4 <='1'; d_in <='1';

ELSIF(a91='1') THEN data_tmp <= \

b1 <= '1'; b2 <='0'; b3 <='0'; b4 <='1'; d_in <='1'; ELSE

b1 <= '1'; b2 <='1'; b3 <='1'; b4 <='1'; d_in <='0';

33

END IF;

END PROCESS;

PROCESS(d_in,reset) BEGIN

IF(reset='1') THEN di <= '0';

ELSIF(duw = '1') THEN di <= '0';

ELSIF(d_in='1') THEN di <= '1'; ELSE

di <= '0'; END IF;

END PROCESS;

PROCESS(dus,reset) BEGIN

IF(reset='1') THEN

count <= 0; duw <= '0';

ELSIF(dus'event AND dus='1') THEN IF(count>=5) THEN duw <= '1'; count <= 6; ELSE

count <= count+1; END IF; END IF;

END PROCESS;

PROCESS(count,dus) BEGIN

IF(count=0) THEN io1 <= \ io2 <= \ io3 <= \ io4 <= \ io5 <= \ io6 <= \

ELSIF(dus'event AND dus='0') THEN io6 <= data_tmp; io5 <= io6; io4 <= io5; io3 <= io4; io2 <= io3;

io1 <= io2; END IF;

END PROCESS; data_in <= d_in;

34

in1 <= io1; in2 <= io2; in3 <= io3; in4 <= io4; in5 <= io5; in6 <= io6;

END encoder_model_arch;

11、比较模块(comparator_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY comparator_model IS

PORT(b1,b2,b3,b4: IN std_logic; e1,e2,e3,e4: IN std_logic; dep : OUT std_logic); END comparator_model;

ARCHITECTURE comparator_model_arch OF comparator_model IS BEGIN

PROCESS(b1,b2,b3,b4,e1,e2,e3,e4) BEGIN

IF(b1=e1 AND b2=e2 AND b3=e3 AND b4=e4) THEN dep <= '1'; ELSE

dep <= '0'; END IF; END PROCESS;

END comparator_model_arch;

12、计数器选择模块LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY counter_model IS

PORT(reset : IN std_logic; cnp : IN std_logic; s0,s1,s2 : OUT std_logic; full : OUT std_logic); END counter_model;

ARCHITECTURE counter_model_arch OF counter_model IS BEGIN

PROCESS(reset,cnp)

VARIABLE count: std_logic_vector(2 DOWNTO 0); BEGIN

IF (reset ='1') THEN count := \ full <= '0';

(counter_model.vhd) 35

ELSIF(cnp'event AND cnp='1') THEN IF(count =\ count := count+1; full <= '1'; ELSE

count := count+1; END IF; END IF;

s0 <= count(0); s1 <= count(1); s2 <= count(2); END PROCESS; END counter_model_arch;

13、数码管显示译码模块LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY decoder_model IS

PORT(data: IN std_logic_vector(3 DOWNTO 0); a,b,c,d,e,f,g: OUT std_logic); END decoder_model;

ARCHITECTURE decoder_model_arch OF decoder_model IS SIGNAL data_tmp: std_logic_vector(6 DOWNTO 0); BEGIN

PROCESS(data) BEGIN

CASE data IS

WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN OTHERS => data_tmp <=\ END CASE; END PROCESS; a<=data_tmp(0); b<=data_tmp(1); c<=data_tmp(2); d<=data_tmp(3); e<=data_tmp(4);

(decoder_model.vhd) 36

f<=data_tmp(5); g<=data_tmp(6); END decoder_model_arch;

14、数码管扫描模块(keyscan_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY keyscan_model IS

PORT(clkscan,reset : IN std_logic; in1,in2,in3,in4,

in5,in6,in7,in8 : IN std_logic_vector(3 DOWNTO 0); data : OUT std_logic_vector(3 DOWNTO 0); sel : OUT std_logic_vector(2 DOWNTO 0)); END keyscan_model;

ARCHITECTURE rtl OF keyscan_model IS

SIGNAL count: std_logic_vector(2 DOWNTO 0); BEGIN

PROCESS(clkscan,reset) BEGIN

IF(reset='1') THEN count <= \

ELSIF(clkscan'event AND clkscan='1') THEN IF(count=\

count <=\ ELSE

count <= count+1; END IF; END IF;

END PROCESS; PROCESS(count) BEGIN

CASE count IS

WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN \ WHEN OTHERS => data <= \ END CASE; END PROCESS; sel <= count; END rtl;

37

15、RS触发器单元电路(rs_dff.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY rs_dff IS

PORT(r,s : IN std_logic; q : OUT std_logic); END rs_dff;

ARCHITECTURE rtl OF rs_dff IS SIGNAL tmp1,tmp2 : std_logic; BEGIN

tmp2 <= r NAND tmp1; tmp1 <= tmp2 NAND s; q <= tmp1; END rtl;

16、指示电路模块(indicator_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY indicator_model IS

PORT(wait_l : IN std_logic; s_lg : IN std_logic; s_lr : IN std_logic; di,bjy : IN std_logic; clk_div1 : IN std_logic;

led_g,led_r,alert: OUT std_logic); END indicator_model;

ARCHITECTURE indicator_model_arch OF indicator_model IS COMPONENT rs_dff

PORT(r,s : IN std_logic; q : OUT std_logic); END COMPONENT;

SIGNAL tmp1 : std_logic; BEGIN

U1: rs_dff

PORT MAP(wait_l,s_lg,led_g); U2: rs_dff

PORT MAP(wait_l,s_lr,tmp1);

alert <= ((tmp1 AND clk_div1) OR di) OR bjy ; led_r <= tmp1 OR bjy; END indicator_model_arch;

17、误码模块(wrong3_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL;

38

USE IEEE.std_logic_unsigned.ALL; ENTITY wrong3_model IS

PORT(anc,ds : IN std_logic; clk,ret: IN std_logic;

in7,in8 : OUT std_logic_vector(3 DOWNTO 0); notc,dsw : OUT std_logic; bjy : OUT std_logic); END wrong3_model;

ARCHITECTURE behave OF wrong3_model IS SIGNAL count : integer RANGE 0 TO 3; SIGNAL xs : std_logic; BEGIN

PROCESS(ret,anc) BEGIN

IF(ret='1') THEN

notc <= '0'; count <= 0;

ELSIF(anc'event AND anc='1') THEN IF(count=2) THEN

count <= 3; notc <= '1'; ELSE

count <= count+1; END IF; END IF;

END PROCESS;

PROCESS(count,xs) BEGIN

IF(count=1) THEN IF(xs = '1') THEN

in7 <= \ ELSE

in7 <= \ END IF;

ELSIF(count=2) THEN IF(xs = '1') THEN

in7 <= \ ELSE

in7 <= \ END IF; ELSE

in7 <= \ END IF;

END PROCESS; PROCESS(ds,clk)

VARIABLE cnt : integer RANGE 0 TO 5; BEGIN

IF(ds='0') THEN

39

cnt := 0; xs <= '0'; dsw <= '0'; ELSIF(clk'event AND clk='1') THEN IF(cnt=4) THEN

dsw <= '1'; xs <= '0'; ELSE

cnt := cnt+1; xs <= '1'; END IF; END IF;

END PROCESS;

bjy <= clk AND xs; END behave;

18、控制器模块(control_model.vhd) LIBRARY IEEE;

USE IEEE.std_logic_1164.ALL; ENTITY control_model IS

PORT(c11,c22,c33,c44 : IN std_logic; data_in : IN std_logic; dep,dsw : IN std_logic; full,notc : IN std_logic; clk : IN std_logic; en,dus,anc: OUT std_logic; cnp,reset : OUT std_logic; ds,ret : OUT std_logic;

s_lr,s_lg,wait_l: OUT std_logic); END control_model;

ARCHITECTURE control_model_arch OF control_model IS TYPE state IS (QA,QB,QC,QD,QE,QF,QG); SIGNAL current_state :state := QA; BEGIN

PROCESS BEGIN

WAIT UNTIL clk'event AND clk ='1'; CASE current_state IS WHEN QA => en<='0';

IF (c11='0') THEN

current_state <= QA; ELSE

current_state <= QB; wait_l <= '0'; s_lg <= '1'; s_lr <= '1'; ret <= '1'; END IF;

WHEN QB => wait_l <= '1'; en<= '0'; ret <= '0';

40

本文来源:https://www.bwwdw.com/article/bx2g.html

Top