2009-11-10 1
EDA技术与应用
江国强 编制
桂林电子工业学院
2009-11-10 2


?第 1章 EDA技术概述
?第 2章 EDA工具软件使用方法
?第 3章 VHDL
?第 4章 Veilog HDL
?第 5章 A HDL
?第 6章 常用EDA工具软件
?第 7章 可编程逻辑器件
?第 8章 EDA技术的应用
2009-11-10 3
第 1章 EDA技术概述
? 1.1 EDA技术及发展
? 1.2 EDA设计流程
? 1.3 硬件描述语言 HDL
? 1.4 可编程逻辑器件
? 1.5 常用 EDA工具
2009-11-10 4
第 2章 EDA工具软件的使用方法
? 2.1 MAX+plusII 的安装方法
? 2.2 MAX+plusII原理图输入法
? 2,3 原理图输入的层次设计
2009-11-10 5
第 3章 VHDL
? 3.1 VHDL基础知识
? 3.2 VHDL语言要素
? 3.3VHDL顺序语句
? 3.4 VHDL并行语句
? 3.5 VHDL库和程序包
? 3.6 VHDL设计流程
2009-11-10 6
第 4章 Verilog HDL
? 4.1 Verilog HDL入门
? 4.2 Verilog HDL的词法
? 4.3 Verilog HDL的语句
? 4.4 不同抽象级别的 Verilog HDL模型
? 4.5 Verilog HDL设计流程
2009-11-10 7
第 5章 AHDL
?5.1 基本 AHDL设计结构
?5.2 AHDL的基本元素
?5.3 AHDL的语句
?5.4 AHDL的使用
?5.5 AHDL设计流程
2009-11-10 8
第 6章 常用 EDA工具软件
?6.1 Quartus II
?6.2 ModelSim
?6.3 NCLaunch
2009-11-10 9
第 7章 可编程逻辑器件
? 7.1 可编程逻辑器件的基本原理
? 7.2 可编程逻辑器件的设计技术
? 7.3 可编程逻辑器件的编程与配置
2009-11-10 10
第 8章 EDA技术的应用
? 8.1 组合逻辑电路设计应用
? 8.2 时序逻辑电路设计应用
2009-11-10 11
第 1章 EDA技术概述
1.1 EDA技术及发展
20世纪末,数字电子技术得到飞速发展,有力地推动了社会
生产力的发展和社会信息化的提高。在其推动下,数字电子技
术的应用已经渗透到人类生活的各个方面。从计算机到手机,
从数字电话到数字电视,从家用电器到军用设备,从工业自动
化到航天技术,都尽可能采用数字电子技术。
本章介绍 EDA技术的发展,EDA设计流程以及 EDA技
术涉及的领域。
2009-11-10 12
微电子技术, 即大规模集成电路加工技术的进步
是现代数字电子技术发展的基础 。 目前, 在硅片单
位面积上集成的晶体管数量越来越多, 1978年推出
的 8086微处理器芯片集成的晶体管数是 4万只, 到
2000年推出的 Pentium 4 微处理器芯片的集成度达
4200万只晶体管 。 原来需要成千上万只电子元件组
成的一台计算机主板或彩色电视机电路, 而现在仅
用几片超大规模集成电路就可以代替, 现代集成电
路已经能够实现单片电子系统 SOC( System On a
Chip) 的功能 。
2009-11-10 13
现代电子设计技术的核心是 EDA( Electronic
Design Automation)技术。 EDA技术就是依靠功能
强大的电子计算机,在 EDA工具软件平台上,对以
硬件描述语言 HDL( Hardware Description
Language)为系统逻辑描述手段完成的设计文件,
自动地完成逻辑编译、化简、分割、综合、优化、
仿真,直至下载到可编程逻辑器件 CPLD/FPGA或
专用集成电路 ASIC( Application Specific
Integrated Circuit)芯片中,实现既定的电子电路
设计功能。 EDA技术使得电子电路设计者的工作仅
限于利用硬件描述语言和 EDA软件平台来完成对系
统硬件功能的实现,极大地提高了设计效率,减少
设计周期,节省设计成本。
2009-11-10 14
EDA 是在 20世纪 90年代初从计算机辅助设计
( CAD), 计算机辅助制造 ( CAM), 计算机辅助
测试 ( CAT) 和计算机辅助工程 ( CAE) 的概念发展
而来的 。 一般把 EDA技术的发展分为 CAD,CAE和
EDA三个阶段 。
CAD( Computer Aided Design)是 EDA技术发
展的早期阶段,在这个阶段,人们开始利用计算机取
代手工劳动。但当时的计算机硬件功能有限,软件功
能较弱,人们主要借助计算机对所设计的电路进行一
些模拟和预测,辅助进行集成电路版图编辑、印刷电
路板 PCB( Printed Circuit Board)布局布线等简单
的版图绘制等工作。
2009-11-10 15
CAE( Computer Aided Engineering) 是在 CAD
的工具逐步完善的基础上发展起来的, 尤其是人们
在设计方法学, 设计工具集成化方面取得了长足的
进步, 可以利用计算机作为单点设计工具, 并建立
各种设计单元库, 开始用计算机将许多单点工具集
成在一起使用, 大大提高了工作效率 。
20世纪 90年代以来,微电子工艺有了惊人的发
展,工艺水平已经达到了深亚微米级,在一个芯片
上已经可以集成上百万乃至上亿只晶体管,芯片速
度达到了吉比特 /秒量级,百万门以上的可编程逻辑
器件陆续面世,这样就对电子设计的工具提出了更
高的要求,提供了广阔的发展空间,
2009-11-10 16
促进了 EDA技术的形成 。 特别重要的是世界各 EDA
公司致力推出兼容各种硬件实现方案和支持标准硬件
描述语言的 EDA工具软件, 都有效地将 EDA技术推
向成熟 。
今天,EDA技术已经成为电子设计的重要工具,
无论是设计芯片还是设计系统,如果没有 EDA工具的
支持都将是难以完成的。 EDA工具已经成为现代电路
设计师的重要武器,正在起作越来越重要的作用。
2009-11-10 17
设计准备
设计输入
·原理图
·硬件描述语言
·波形图
功能仿真
设计处理
·优化、综合
·适配、分割
·布局、布线
时序仿真
器件编程 器件测试
设计完成
1.2 EDA设计流程
2009-11-10 18
1.2.1 设计准备
设计准备是指设计者在进行设计之前, 依据任务要求, 确
定系统所要完成的功能及复杂程度, 器件资源的利用, 成本
等所要做的准备工作, 如进行方案论证, 系统设计和器件选
择等 。
1.2.2 设计输入
设计输入 ----将设计的系统或电路以开发软件要求的某
种形式表示出来,并送入计算机的过程。
设计输入形式
文本方式设计输入方式
图形设计输入方式
文本、图形两者混合的设计输入方式。
2009-11-10 19
1,原理图或图形输入方式
这是一种最直接的设计输入方式,它使用软件
系统提供的元器件库及各种符号和连线画出原理图,
形成原理图输入文件。这种方式大多用在对系统及
各部分电路很熟悉的情况,或在系统对时间特性要
求较高的场合。优点是容易实现仿真,便于信号的
观察和电路的调整。
2009-11-10 20
2,硬件描述语言输入方式
硬件描述语言有普通硬件描述语言和行为描述语言,
它们用文本方式描述设计和输入 。 普通硬件描述语言
有 AHDL,CUPL等, 它们支持逻辑方程, 真值表,
状态机等逻辑表达方式 。
行为描述语言是目前常用的高层硬件描述语言,
有 VHDL和 Verilog HDL等,它们具有很强的逻辑描
述和仿真功能,可实现与工艺无关的编程与设计,可
以使设计者在系统设计、逻辑验证阶段便确立方案的
可行性,而且输入效率高,在不同的设计输入库之间
转换也非常方便。运用 VHDL,Verilog HDL硬件描
述语言进行设计已是当前的趋势 。
2009-11-10 21
3,波形输入方式
波形输入主要用于建立和编辑波形设计文件以及输
入仿真向量和功能测试向量 。 波形设计输入适合用于
时序逻辑和有重复性的逻辑函数, 系统软件可以根据
用户定义的输入 /输出波形自动生成逻辑关系 。
波形编辑功能还允许设计者对波形进行拷贝、剪
切、粘贴、重复与伸展。从而可以用内部节点、触发
器和状态机建立设计文件,并将波形进行组合,显示
各种进制的状态值。还可以通过将一组波形重叠到另
一组波形上,对两组仿真结果进行比较。
2009-11-10 22
1.2.3 设计处理
这是 EDA设计中的核心环节 。 在设计处理阶段,
编译软件将对设计输入文件进行逻辑化简, 综合和
优化, 并适当地用一片或多片器件自动地进行适配,
最后产生编程用的编程文件 。 设计处理主要包括设
计编译和检查, 逻辑优化和综合, 适配和分割, 布
局和布线, 生成编程数据文件等过程 。
2009-11-10 23
1,设计编译和检查
设计输入完成之后,立即进行编译。在编译过
程中首先进行语法检验,如检查原理图的信号线有
无漏接,信号有无双重来源,文本输入文件中关键
字有无错误等各种语法错误,并及时标出错误的位
置信息报告,供设计者修改。然后进行设计规则检
验,检查总的设计有无超出器件资源或规定的限制
并将编译报告列出,指明违反规则和潜在不可靠电
路的情况以供设计者纠正,
2009-11-10 24
2,逻辑优化和综合
逻辑优化是化简所有的逻辑方程或用户自建的宏,
使设计所占用的资源最少 。 综合的目的是将多个模块
化设计文件合并为一个网表文件, 并使层次设计平面
化 ( 即展平 ) 。
3,适配和分割
在适配和分割过程, 确定优化以后的逻辑能否与
下载目标器件 CPLD或 FPGA中的宏单元和 I/O单元适
配, 然后将设计分割为多个便于适配的逻辑小块形式
映射到器件相应的宏单元中 。 如果整个设计不能装入
一片器件时, 可以将整个设计自动分割成多块并装入
同一系列的多片器件中去 。
2009-11-10 25
4,布局和布线
布局和布线工作是在设计检验通过以后由软件自动
完成的, 它能以最优的方式对逻辑元件布局, 并准确
地实现元件间的布线互连 。 布局和布线以后,软件会自
动生成布线报告, 提供有关设计中各部分资源的使用
情况等信息 。
5,生成编程数据文件( JED文件)
设计处理的最后一步是产生可供器件编程使用的
数据文件。对 CPLD来说,是产生熔丝图文件,即
JEDEC文件(电子器件工程联合会制定的标准格式,
简称 JED文件);对于 FPGA来说,是生成位流数据
文件 (Bit-stream Generation)。
2009-11-10 26
1.2.4 设计校验
设计校验过程包括功能仿真和时序仿真, 这两项
工作是在设计处理过程中同时进行的 。 功能仿真是在
设计输入完成之后, 选择具体器件进行编译之前进行
的逻辑功能验证, 因此又称为前仿真 。 此时的仿真没
有延时信息或者有由系统添加的微小标准延时, 这对
于初步的功能检测非常方便 。
时序仿真是在选择了具体器件并完成布局, 布线
之后进行的时序关系仿真, 因此又称为后仿真或延时
仿真 。 在设计处理以后, 对系统和各模块进行时序仿
真, 分析其时序关系, 估计设计的性能以及检查和消
除竞争冒险等 。
2009-11-10 27
1.2.5 器件编程
编程是指将设计处理中产生的编程数据文件通过
软件放到具体的可编程逻辑器件中去 。 对 CPLD器件
来说是将 JED文件下载 ( Down Load) 到 CPLD器件
中去, 对 FPGA来说是将位流数据 BG文件配置到
FPGA中去 。
器件编程需要满足一定的条件, 如编程电压, 编
程时序和编程算法等 。 普通的 CPLD器件和一次性编
程的 FPGA需要专用的编程器完成器件的编程工作 。
基于 SRAM的 FPGA可以由 EPROM或其他存储体进
行配置 。 在系统的可编程器件 ( ISP-PLD) 则不需要
专门的编程器, 只要一根与计算机互连的下载编程电
缆就可以了 。
2009-11-10 28
1.2.6 器件测试和设计验证
器件在编程完毕之后, 可以用编译时产生的文件
对器件进行检验, 加密等工作, 或采用边界扫描测
试技术进行功能测试, 测试成功后才完成其设计 。
设计验证可以在 EDA硬件开发平台上进行。
EDA硬件开发平台的核心部件是一片可编程逻辑器
件 FPGA或 CPLD,再附加一些输入输出设备,如按
键、数码显示器、指示灯、喇叭等,还提供时序电
路需要的脉冲源。将设计电路编程下载到 FPGA或
CPLD中后,根据 EDA硬件开发平台的操作模式要求,
进行相应的输入操作,然后检查输出结果,验证设
计电路。
2009-11-10 29
1.3 硬件描述语言
硬件描述语言 HDL是 EDA技术中的重要
组成部分,常用的硬件描述语言有 AHDL、
VHDL和 Verilog HDL,而 VHDL和 Verilog
HDL是当前最流行的并成为 IEEE标准的硬
件描述语言。
2009-11-10 30
VHDL是超高速集成电路硬件描述语言 ( Very-High-
Speed Integrated Circuit Hardware Description
Language) 的缩写 。 VHDL作为 IEEE标准的硬件描述
语言和 EDA的重要组成部分, 经过十几年的发展, 应用
和完善, 以其强大的系统描述能力, 规范的程序设计结
构, 灵活的语言表达风格和多层次的仿真测试手段, 在
电子设计领域受到了普遍的认同和广泛的接受, 成为现
代 EDA领域的首选硬件设计语言 。 专家认为, 在新世纪
中, VHDL与 Verilog语言将承担起几乎全部的数字系统
设计任务 。
1.3.1 VHDL
2009-11-10 31
VHDL的特点
1,VHDL具有强大的功能,覆盖面广,描述能力强。
VHDL支持门级电路的描述,也支持以寄存器、存贮
器、总线及运算单元等构成的寄存器传输级电路的
描述,还支持以行为算法和结构的混合描述为对象
的系统级电路的描述。
2,VHDL有良好的可读性 。 它可以被计算机接受,
也容易被读者理解 。 用 VHDL书写的源文件, 既是
程序又是文档, 既是工程技术人员之间交换信息
的文件, 又可作为合同签约者之间的文件 。
2009-11-10 32
3,VHDL具有良好的可移植性 。 作为一种已被
IEEE承认的工业标准, VHDL事实上已成为通用
的硬件描述语言, 可以在各种不同的设计环境和
系统平台中使用 。
4、使用 VHDL可以延长设计的生命周期。用 VHDL
描述的硬件电路与工艺无关,不会因工艺而是描述
过时。与工艺有关的参数可以通过 VHDL提供的属
性加以描述,工艺改变时,只需要修改相应程序中
属性参数即可。
2009-11-10 33
5,VHDL支持对大规模设计的分解和已有设计的再
利用 。 VHDL可以描述复杂的电路系统, 支持对大
规模设计的分解, 由多人, 多项目组来共同承担和
完成 。 标准化的规则和风格, 为设计的再利用提供
了有力的支持 。
6,VHDL有利于保护知识产权。用 VHDL设计的专
用集成电路( ASIC),在设计文件下载到集成电路
时可以采用一定保密措施,使其不易被破译和窃取。
2009-11-10 34
用 VHDL实现数字电路设计的过程
编辑源程序
编译设计文件
功能仿真
逻辑综合
时序仿真
编程下载
设件调试
目标芯片
2009-11-10 35
1.3.2 Verilog HDL
Verilog HDL也是目前应用最为广泛的硬件描述
语言,并被 IEEE采纳为 IEEE#1064-1995标准。
Verilog HDL可以用来进行各种层次的逻辑设计,也
可以进行数字系统的逻辑综合、仿真验证和时序分
析。 Verilog HDL适合算法级( Algorithm)、寄存器
传输级( RTL)逻辑级( Logic)、门级( Gate)和
版图级( Layout)等各个层次的电路设计和描述。
2009-11-10 36
采用 Verilog HDL进行电路设计的最大优点是其
与工艺无关性,这使得设计者在进行电路设计时可
以不必过多考虑工艺实现的具体细节,只需要根据
系统设计的要求施加不同的约束条件,即可设计出
实际电路。实际上,利用计算机的强大功能,在
EDA工具的支持下,把逻辑验证与具体工艺库相匹
配,将布线及延迟计算分成不同的阶段来实现,从
而减少了设计者的繁重劳动。
2009-11-10 37
Verilog HDL和 VHDL都是用于电路设计的硬件描
述语言,并且都已成为 IEEE标准。 Verilog HDL也具
有与 VHDL类似的特点,稍有不同的是 Verilog HDL早
在 1983年就已经推出,至今已有 20年的应用历史,因
而 Verilog HDL拥有广泛的设计群体,其设计资源比
VHDL丰富。另外 Verilog HDL是在 C语言的基础上演
化而来的,因此只要具有 C语言的编程基础,就很容
易学会并掌握这种语言。
2009-11-10 38
1.3.3 AHDL
AHDL( Altera Hardware Description Language) 是
Altera公司根据自己公司生产的 MAX系列器件和 FLEX
系列器件的特点专门设计的一套完整的硬件描述语言 。
AHDL是一种模块化的硬件描述语言,它完全集成
于 Altera公司的 MAX+plusII的软件开发系统中。 AHDL
特别适合于描述复杂的组合电路、组( group)运算以
及状态机、真值表和参数化的逻辑。用户可以通过
MAX+plusII的软件开发系统对 AHDL源程序进行编辑,
并通过对源文件的编译建立仿真、时域分析和器件编程
的输出文件。
2009-11-10 39
AHDL的语句和元素种类齐全、功能强大,而且易
于应用。用户可以使用 AHDL建立完整层次的工程
设计项目,或者在一个层次的设计中混合其他类型
的设计文件,例如 VHDL设计文件或 Verilog HDL设
计文件。
2009-11-10 40
可编程逻辑器件 PLD( Programmable Logic
Device) 是一种半定制集成电路, 在其内部集成了
大量的门和触发器等基本逻辑电路, 用户通过编程
来改变 PLD内部电路的逻辑关系或连线, 就可以得
到需要的设计电路 。 可编程逻辑器件的出现, 改变
了传统的数字系统设计方法, 其设计方法为采用
EDA技术开创了广阔的发展空间, 并极大地提高电
路设计的效率 。
1.4 可编程逻辑器件
2009-11-10 41
在可编程逻辑器件 PLD没有出现之前,数字系统
的传统设计往往采用, 积木, 式的方法进行,实质上
是对电路板进行设计,通过标准集成电路器件搭建成
电路板来实现系统功能,即先由器件搭成电路板,再
由电路板搭成系统。数字系统的, 积木块, 就是具有
固定功能的标准集成电路器件,如 TTL的 74/54系列、
CMOS的 4000/4500系列芯片和一些固定功能的大规模
集成电路等,用户只能根据需要选择合适的集成电路
器件,并按照此种器件推荐的电路搭成系统并调试成
功。设计中,设计者没有灵活性可言,搭成的系统需
要的芯片种类多且数目大。
2009-11-10 42
PLD的出现,给数字系统的传统设计法带来新的
变革。采用 PLD进行的数字系统设计,是基于芯片的
设计或称之为, 自底向上, ( Bottom-Up)的设计,它
跟传统的积木式设计有本质的不同。它可以直接通过
设计 PLD芯片来实现数字系统功能,将原来由电路板
设计完成的大部分工作放在 PLD芯片的设计中进行。
这种新的设计方法能够由设计者根据实际情况和要求
定义器件的内部逻辑关系和管脚,这样可通过芯片设
计实现多种数字系统功能,同时由于管脚定义的灵活
性,不但大大减轻了系统设计的工作量和难度,提高
了工作效率,而且还可以减少芯片数量,缩小系统体
积,降低能源消耗,提高系统的稳定性和可靠性。
2009-11-10 43
目前, 可编程逻辑器件有许多品种 。 集成度是集成
电路一项很重要的指标, 可编程逻辑器件从集成密度
上可分为低密度可编程逻辑器件 LDPLD和高密度可编
程逻辑器件 HDPLD两类 。
PROM,PLA,PAL和 GAL是早期发展起来的
PLD,其集成密度一般小于 700门(等效门) /片。它
们同属于 LDPLD。
2009-11-10 44
HDPLD包括可擦除可编程逻辑器件 EPLD
( Erasable Programmable Logic Device)、复杂可编
程逻辑器件 CPLD( Complex PLD)和 FPGA三种,其
集成密度大于 700门 /片。随着集成工艺的发展,
HDPLD集成密度不断增加,性能不断提高。如 Altera
公司的 EPM9560,其密度为 12000门 /片,Lattice公司
的 pLSI/ispLSI3320为 14000门 /片等。目前集成度最高
的 HDPLD可达 25万门 /片以上。
2009-11-10 45
目前常用的可编程逻辑器件都是从与或阵列和门阵
列发展起来的, 所以可以从结构上将其分为阵列型
PLD和现场可编程门阵列型 FPGA两大类 。
阵列型 PLD的基本结构由与阵列和或阵列组成 。 简
单 PLD( 如 PROM,PLA,PAL和 GAL等 ), EPLD
和 CPLD都属于阵列型 PLD。
FPGA具有门阵列的结构形式,它有许多可编程
单元(或称逻辑功能块)排成阵列组成,这些逻辑单
元的结构和与或阵列的结构不同,也称之为单元型
PLD。
2009-11-10 46
1.5 常用 EDA工具
用 EDA技术设计电路可以分为不同的技术环节,
每一个环节中必须有对应的软件包或专用的 EDA工
具独立处理。 EDA工具大致可以分为设计输入编辑
器、仿真器,HDL综合器、适配器(或布局布线器)
以及下载器等 5个模块。
2009-11-10 47
1.5.1 设计输入编辑器
通常专业的 EDA工具供应商或各可编程逻辑器件厂
商都提供 EDA开发工具, 在这些 EDA开发工具中都含
有设计输入编辑器, 如 Xilinx公司的 Foundation、
Altera公司的 MAX+plusII等 。
一般的设计输入编辑器都支持图形输入和 HDL文
本输入。图形输入通常包括原理图输入、状态图输入
和波形图输入三种常用方法。原理图输入方式沿用传
统的数字系统设计方式,即根据设计电路的功能和控
制条件,画出设计的原理图或状态图或波形图,然后
在设计输入编辑器的支持下,将这些图形输入到计算
机中,形成图形文件。
2009-11-10 48
1.5.2 仿真器
在 EDA技术中仿真的地位非常重要, 行为模型的表
达, 电子系统的建模, 逻辑电路的验证以及门级系统
的测试, 每一步都离不开仿真器的模拟检测 。 在 EDA
发展的初期, 快速地进行电路逻辑仿真是当时的核心
问题, 即使在现在, 各个环节的仿真仍然是整个 EDA
设计流程中最重要, 最耗时的一个步骤 。 因此, 仿真
器的仿真速度, 仿真的准确性和易用性成为衡量仿真
器的重要指标 。
2009-11-10 49
几乎每个 EDA厂商都提供基于 Verilog/VHDL
的仿真器。常用的仿真器有 Model Technology
公司的 Modelsim,Cadence公司的 Verilog-
XL和 NC-Sim,Aldec公司的 Active HDL,
Synopsys公司的 VCS等。
1.5.3 HDL综合器
硬件描述语言诞生的初衷是用于设计逻辑电
路的建模和仿真, 但直到 Synoposys公司推出了
HDL综合器后, 才可以 HDL直接用于电路设计 。
2009-11-10 50
HDL综合器是一种用 EDA技术实施电路设计中
完成电路化简、算法优化、硬件结构细化的计算机软
件,是将硬件描述语言转化为硬件电路的重要工具。
HDL综合器在把可综合的 HDL( Verilog或 VHDL)
转化为硬件电路时,一般要经过两个步骤。第 1步是
HDL综合器对 Verilog或 VHDL进行处理分析,并将
其转换成电路结构或模块,这时是不考虑实际器件实
现的,即完全与硬件无关,这个过程是一个通用电路
原理图形成的过程。第 2步是对应实际实现目标器件的
结构进行优化,并使之满足各种约束条件,优化关键
路径等。
2009-11-10 51
HDL综合器的输出文件一般是网表文件, 是一种
用于电路设计数据交换和交流的工业标准化格式的文
件, 或是直接用硬件描述语言 HDL表达的标准格式的
网表文件, 或是对应 FPGA/CPLD器件厂商的网表
文件 。
HDL综合器是 EDA设计流程中的一个独立的设
计步骤,它往往被其他 EDA环节调用,完成整个设计
流程。
电路网表 ( 逻辑图 ) 由元件名 N,模型 M,输
入端信号 PI,输出端信号 PO四部分组成, 是唯一确
定电路连接关系的数据结构 。 即,E=( N,M,PI,
PO)
2009-11-10 52
例:一位全加器的电路网表
E1,XOR,( X,Y),S1
E2,XOR,( Cin,S1), Sum
E3,AND,( X,Y),S2
E4,AND,( S1,Cin),S3
E5,OR,( S2,S3),Cout
&
&
≥1
=1
=1
E2
E1
E4
E3
E5
SUM
COUT
S1
S3
S2
CIN
X
Y
2009-11-10 53
第 2章 EDA工具软件的使用方法
?本章概要:本章以 Altera公司的 MAX+plusⅡ 为主, 介绍
EDA工具软件的使用方法 。 读者在具有数字逻辑电路知识
的基础上, 通过本章的学习, 即可初步掌握 EDA软件的使
用方法, 实现电路设计 。
?知识要点:
( 1) EDA技术的原理图输入设计法 。
( 2) 用原理图输入法实现多层次系统电路的设计 。
( 3) MAX+plusⅡ 的宏函数和强函数的使用方法。
2009-11-10 54
2.1 MAX+plusⅡ 的安装方法
1,运行 setup.exe
2,遵守协议
3.授权( LICENSE)文件
复制 CRACK名称为 ALTERA.DAT的
LICENSE文件,到 MAX+plus II的安装目录下
(如 c:\maxplus2)。运行 MAX+plus II,进入
MAX+plus II集成环境,选择 "Option"?"License
Setup"菜单,弹出一个对话框。按 "Browse"按钮,
可以选择,此时选择前面复制时进入的授权文件
即可。
2009-11-10 55
MAX+plusⅡ 软件授权操作提示对话框
2009-11-10 56
2.2 MAX+plusⅡ 原理图输入法
用 MAX+plus II的原理图输入设计法进行数字
系统设计时, 不需要任何硬件描述语言知识, 在掌
握 了 数 字 逻 辑 电 路 的 基 本 知 识 后, 即 可 使 用
MAX+plus II提供 EDA平台, 设计数字电路 。
为了方便电路设计,设计者首先应当在计算机
中建立自己的工程目录。例如,将自己的全部 EDA
设计文件放在 d:\myeda文件夹中,而为图形编辑设
计建立 d:\myeda\mygdf文件夹,为 VHDL文本编辑
设计建立 d:\myeda\myvhdl等。
2009-11-10 57
编辑原理图
编译设计文件
功能仿真
产生元件符号
引脚锁定
时序仿真
硬件调试
编程下载
MAX+plus Ⅱ 原理图输入的基本操作
2009-11-10 58
执行, File‖?―New‖命令,弹出编辑文件类
型对话框,选择, Graphic Editor file‖后按, OK‖

2.2.1 编辑图形设计文件
2009-11-10 59
MAX+plus的图形编辑界面
2009-11-10 60
在原理图编辑窗中的任何一个位置上双击鼠
标的左键,将弹出一个元件选择窗,或者点鼠标右
键,选择输入元件项 Enter Symbol,也可以出现
这个元件选择窗。
由此输入所需要的元件名
用户自己设置的元件库
基本逻辑元件库
老式宏函数元件库
参数可设置的强函数元件库
基本逻辑元件库中的元件
2009-11-10 61
半加器( h_adder.gdf)设计项目示意图
2009-11-10 62
2.2.2 编译设计图形文件
设计好的图形文件一定要通过 MAX+plusII的编
译。在 MAX+plusⅡ 集成环境下,执行, MAX+plus‖
菜单下的, Compiler‖命令,在弹出的编译对话框按
,START‖键,即可对 h_adder.gdf文件进行编译。
在编译中,MAX+plusII自动完成编译网表提取
( Compiler Netlist Extractor)、数据库建立
( Database Builder)、逻辑综合( Logic
Synthesizer)、逻辑分割( Partitioner)、适配
( Fitter)、延时网表提取( Timing SNF Extractor)
和编程文件汇编( Assembler)等操作。
2009-11-10 63
2.2.3 产生元件符号
在 MAXplusII集成环境下,执行, File‖菜单下
的, Create Default Symbol‖命令,将通过编译的
GDF文件产生一个元件符号,并保存在工程目录中。
元件符号可以被其他图形设计文件调用,实现多层次
的系统电路设计。
半加器元件符号
2009-11-10 64
2.2.4 功能仿真设计文件
仿真,也称为模拟( Simulation),是对电路
设计的一种间接的检测方法。对电路设计的逻辑行为
和功能进行模拟检测,可以获得许多设计错误及改进
方面的信息。对于大型系统的设计,能进行可靠、快
速、全面的仿真尤为重要 。
仿真包括编辑波形文件、波形文件存盘和执行仿
真文件等操作。
2009-11-10 65
h_adder的仿真结果
2009-11-10 66
2.2.5 编程下载设计文件
上述的仿真仅是用来检查设计电路的逻辑功能
是否正确,与实际编程下载的目标芯片还没有联系。
为了获得与目标器件对应的、精确的时序仿真文件,
在对文件编译前必须选定设计项目的目标器件,在
Max+plusII环境中主要选 Altera公司的 FPGA或
CPLD。
编程下载包括选择目标芯片、引脚锁定、编译
和编程下载等操作。
完成选择目标芯片、引脚锁定再编译后再进行
的仿真称为时序仿真,此时的仿真是针对具体的目
标芯片进行的。
2009-11-10 67
1,选择 目标芯片
执行,Assign‖的,Device…‖ 命令,选择下载芯片型
号。在,Device Family‖中选择,FLE10K‖,在
Device列表中选择,EPF10KLC84-4‖芯片型号。
2009-11-10 68
2,锁 定 引脚
选择 EDA实验 /开发设备 GW48的 实验结构图 NO.6,
用, 键 7‖和, 键 8‖分别作为 A,B输入按键,接 PIO12和
PIO13 。
用, D8‖和, D7‖作为设计电路的进位 CO与和 SO输出显
示 接 PIO23和 PIO22 ( PIO39/65)。
2009-11-10 69
2.2.6 设计电路硬件调试
按实验板上的, 模式选择, 键,选择模式 NO.6,
执行向 EPF10K10编程下载配置后,按动 GW48实验板
上的高低电平输入键, 键 7‖和, 键 8‖,得到 A,B不同
的输入组合;观察, D8‖和, D7‖发光二极管显示的结
果是否正确。
2009-11-10 70
2.3 原理图输入法的层次化设计
层次化设计也称为, 自底向上, 的设计方法, 即将一
个大的设计项目分解为若干个子项目或若干个层次来
完成 。 先从底层的电路设计开始, 然后在高层次的设
计中逐级调用低层次的设计结果, 直至最后系统电路
的实现 。 对于每个层次的设计结果, 都经过严格的仿
真验证, 尽量减少系统设计中的错误 。
例 4位加法器的设计
4位加法器由 4个 1位全加器构成, 它的底层设计
文件是 1位全加器 。
2009-11-10 71
1位全加器的原理图
全加器元件符号
2009-11-10 72
4位加法器原理图
2009-11-10 73
第 3章 VHDL
?本章概要:本章介绍硬件描述语言 VHDL的语言要素,
程序结构以及描述风格, 并介绍最基本, 最典型的数
字逻辑电路的 VHDL描述, 作为 VHDL工程设计的基
础 。
?知识要点:
( 1) VHDL设计实体的基本结构 。
( 2) VHDL的语言要素 。
( 3) 用 VHDL实现各种类型电路及系统的方法 。
( 4) VHDL设计流程。
2009-11-10 74
3.1 VHDL基本知识
VHDL作为 IEEE标准的硬件描述语言和 EDA
的重要组成部分, 经过十几年的发展, 应用和完善,
以其强大的系统描述能力, 规范的程序设计结构,
灵活的语言表达风格和多层次的仿真测试手段, 在
电子设计领域受到了普遍的认同和广泛的接受, 成
为现代 EDA领域的首选硬件设计语言 。 专家认为,
在新世纪中, VHDL与 Verilog语言将承担起几乎全
部的数字系统设计任务 。
2009-11-10 75
结构体
( ARCHITECTURE)
进程
或其它并行结构
实体( ENTITY)
配置( CONFIGURATION)
库、程序包




3.1.1 VHDL程序设计基本结构
2009-11-10 76
3.1.1 库, 程序包
库 ( LIBRARY) ——存放预先设计好的程序包和
数据的集合体 。
程序包 ( PACKAGE) ——将已定义的数据类型,
元件调用说明及子程序收集在一起, 供 VHDL设计实
体共享和调用, 若干个包则形成库 。
IEEE库包括,STD_LOGIC_1164
STD_LOGIC_ARITH——是 SYNOPSYS公司加
入 IEEE库程序包, 包括:
STD_LOGIC_SIGNED( 有符号数 )
STD_LOGIC_UNSIGNED( 无符号数 )
2009-11-10 77
STD_LOGIC_SMALL_INT(小整型数 )
VHDL‘87版本使用 IEEE STD 1076-1987 语法标准
VHDL‘93版本使用 IEEE STD 1076-1993 语法标准
例,LIBRARY IEEE
USE IEEE.STD_LOGIC_1164.ALL
描述器件的输入, 输出端口数据类型中将要用到的
IEEE的标准库中的 STD_LOGIC_1164程序包 。
2009-11-10 78
3.1.2 实体 ( ENTITY) 说明
格式,ENTITY 实体名 IS
[类属参数说明 ]
[端口说明 ]
END 实体名;
规则,( 1) 类属参数说明必须放在端口说明之前,
用于指定如矢量位数, 延迟时间等参数 。 例如
GENERIC( m,TIME,=1 ns) ; --说明 m是
一个值为 1ns的时间参数
则程序语句,tmp1 <= d0 AND se1 AFTER m; --表
示 d0 AND se1经 1ns延迟后才送到 tem1。
2009-11-10 79
( 2) 端口说明是描述器件的外部接口信号的说
明, 相当于器件的引脚说明 。 其格式为:
PORT( 端口名 {,端口名 }:方向 数据类型名;

端口名 {,端口名 }:方向 数据类型名);
例如,PORT( a,b,IN STD_LOGIC;
s,IN STD_LOGIC;
y,OUT STD_LOGIC) ;
2009-11-10 80
端口方向包括:
IN; --输入,符号:
OUT; --输出,符号:
INOUT; --双向, 符号:
BUFFER;
--具有读功能的输出,符号:
D Q
BUFFER 端口
2009-11-10 81
3.1.3 结构体( ARCHITECTURE)
基本设计单元的实体,用于指明设计基本单元的
行为、元件及内部连接关系,即定义设计单元的功能。
结构体的结构:
ARCHITECTURE 结构体名 OF 实体名 IS
[说明语句 ]; --为内部信号, 常数, 数据类型, 函数
定义
BEGIN
[功能描述语句 ]
END ARCHITECTURE 结构体名;
2009-11-10 82
例如:或门的结构体
ARCHITECTURE or1 OF temp1 IS
SIGNAL y,STD_LOGIC;
BEGIN
y<=a OR b;
END ARCHITECTURE or1;
3.1.4 配置 ( CONFIGURATION) ——把特定的结构
体关联 ( 指定给 ) 一个确定的实体, 为大型系统的设
计提供管理和工程组织 。
2009-11-10 83
【 例 3.1】 或门的描述
LIBRARY IEEE;
USE IEEE.STD LOGIC 1164.ALL
ENTITY or1 IS
PORT( a,b,IN STD_LOGIC;
y,OUT STD LOGIC) ;
END or1;
ARCHITECTURE example1 OF or1 IS
BEGIN
y<=a OR b;
END example1;
3.1.2 基本逻辑器件的描述
2009-11-10 84
【 例 3.2】 半加器的描述
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY h_adder IS
PORT(a,b:IN STD_LOGIC;
so,co:OUT STD_LOGIC);
END h_adder;
ARCHITECTURE example2 OF h_adder IS
BEGIN
so<=a XOR b;
co<=a AND b;
END example2;
a
b
so
co
2009-11-10 85
【 例 3.3】 2选 1数据选择器的描述
LIBRARY IEEE;
USE IEEE.STD LOGIC 1164.ALL
ENTITY mux21 IS
PORT( a,b,IN STD LOGIC;
s,IN STD LOGIC;
y,OUT STD LOGIC) ;
END mux21;
ARCHITECTURE example3 OF mux21 IS
BEGIN
y<=a WHEN s=‘0‘ ELSE
b;
END ARCHITECTURE example3;
a
b
s
y
2009-11-10 86
【 例 3.4】 锁存器的描述
qD Q
ena
d
2009-11-10 87
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY latch1 IS
PORT ( d,IN STD_LOGIC;
ena,IN STD_LOGIC;
q,OUT STD_LOGIC);
END latch1;
ARCHITECTURE example4 OF latch1 IS
SIGNAL sig_save:STD_LOGIC:=?0‘;
2009-11-10 88
BEGIN
PROCESS (d,ena)
BEGIN
IF ena='1' THEN
Sig_save<=D;
END IF;
Q<=sig_save;
END PROCESS;
END example4;
2009-11-10 89
3.2 VHDL语言要素
VHDL具有计算机编程语言的一般特性,其语言
要素是编程语句的基本单元。准确无误地理解和掌
握 VHDL语言要素的基本含义和用法,对正确地完
成 VHDL程序设计十分重要。
2009-11-10 90
1,数字型文字 ——由数字, 小数点和下划线组成
( 1) 整数文字 5,678,156E2,45_234_287(=45234287)
( 2) 实数文字 188.993,88_670_551.453_909
( 3) 以数制基数表示的文字
格式:数制 #数值 #
例如,10#170#
16#FE#
2#11010001#
8#376#
3.2.1 VHDL文字规则
2009-11-10 91
( 4) 物理量文字
例如,60s,100m
2,字符串文字
字符 ——以单引号括起来的数字, 字母和符号
( ASCII码 )
例如,’ 0‘,‘1‘,‘A‘,‘B‘,‘a‘,‘b‘
字符串 ——一维的字符数组,用双引号括起来。
( 1) 文字字符串
例如:, ABC‖,‖ABOY.‖,‖A‖
2009-11-10 92
( 2) 数值字符串 ——矢量
格式:数制基数符号, 数值字符串,
其中,B——二进制基数符号;
O——八进制基数符号;
X——16进制基数符号;
例如,B―111011110‖;矢量数组, 长度为 9
O―15‖;等效 B―001101‖,长度为 6
X―AD0‖;等效 B―101011010000‖,
长度为 12
2009-11-10 93
3,标识符 ——是用户给常量, 变量, 信号, 端口,
子程序或参数定义的名字
规则:以字母开头,后跟若干字母、数字或单个下
划线构成,但最后不能为下划线。
例如,h_adder,mux21,example为合法标识符;
2adder,_mux21,ful__adder,adder_为错误的标识符 。
VHDL‘93标准支持扩展标识符, 以反斜杠来定界, 允
许以数字开头, 允许使用空格以及两个以上的下划号 。
例如,\74LS193\,\A BOY.\等为合法的标识符。
2009-11-10 94
4,下标名 ——数组
格式:标识符 ( 表达式 )
例如,b( 3)
5,段名 ——多个下标名的组合
格式:标识符 ( 表达式 方向 表达式 )
方向,TO——下标序号由低到高
DOWNTO——下标序号由高到低
例如,D( 7 DOWNTO 0) ; 表示数据总线 D7~ D0
D( 0 TO 7 );表示数据总线 D0~ D7
2009-11-10 95
——存放各种类型数据的容器,包括变量、常量和信号
1,变量 ( VARIABLE)
规则:只能在进程 ( PROCESS), 函数
( FUNCTION) 和过程 ( PROCEDURE) 中说明
和使用的局域量
定义格式:
VARIABLE 变量名:数据类型 {,=初始值 }
例如,VARIABLE a,INTEGER
VARIABLE b,INTEGER,=2;
3.2.2 VHDL数据对象
2009-11-10 96
变量赋值语句:
目标变量名,=表达式
例如,VARIABLE x,y,REAL
VARIABLE a,b,BIT VECTOR( 0 TO 7) ;
x,=100.0;
y,=1.5+x;
a,=―1010101‖
a( 3 TO 6), =( ‘ 1‘,‘ 1‘,‘ 0‘,‘ 1‘) ;
a( 0 TO 5),=b( 2 TO 7);
2009-11-10 97
2,信号 ( SIGNAL)
规则:信号是在结构体( ARCHITECTURE)、程
序包( PACKAGE)和实体中说明的全局量。
信号定义格式,SIGNAL 信号名:数据类型,=初值;
例如,SIGNAL temp,STD LOGIC,=?0‘;
SIGNAL flaga,flagb,BIT
SIGNAL data,STD LOOGIC VECTOR
( 15 DOWNTO 0);
2009-11-10 98
信号赋值语句:
目标信号名< =表达式
例如,x< =9;
y< =x;
z< =x AFTER 5ns;
信号与变量的区别:
( 1) 使用场合不同; ( 变量:进程;信号:结构体 )
( 2)变量用“,=‖号赋值,其值被立即使用(无
时间延迟);而信号用“< =‖赋值,其值可以附加
延迟。
2009-11-10 99
3,常数( CONSTANT)
规则:常数在程序前部定义, 且一旦被赋值就不能再
改变 。
常数定义格式:
CONSTANT 常数名:数据类型,=初值;
例如:
CONSTANT fbus,BIT VECTOR,=―010111‖;
CONSTANT Vcc,REAL,=5.0;
CONSTANT dely,TIME,=25ns;
2009-11-10 100
1,标量型( Scalar Type) ——单元素的最基本数
据类型
( 1) 实数类型
( 2) 整数类型
( 3) 枚举类型
( 4) 时间类型
3.2.3 VHDL数据类型
2,复合类型( Composite Type)
( 1)数组型( Array)
( 2)记录型( Record)
2009-11-10 101
3,存取类型( Access Type) ——为数据对象提供
存取方式
4,文件类型( Files Type) ——提供多值存取类

3.2.4 VHDL的预定义数据类型
——在 IEEE库中的标准程序包( STANDARD)中
预先定义的数据类型。
2009-11-10 102
1,布尔( BOOLEAN)数据类型
包 括 逻 辑, 假, ( FALSE ) 和逻辑, 真,
( TRUE), 定义语句:
TYPE BOOLEAN IS( FALSE,TRUE); --以枚
举类型定义
2,位 ( BIT) 数据类型
包括 ‘ 0‘和 ‘ 1‘,定义语句:
TYPE BIT IS(‘ 0‘,‘ 1‘)
2009-11-10 103
3,位矢量( BIT VECTOR)数据类型
位矢量是用双引号括起来的数字序列, 如, 0011‖,
X―00FD‖
定义语句:
TYPE BIT VECTOR IS ARRAY( Natural Range
〈 〉 ) OF BIT; --―〈 〉 ‖表示数据范围未定界
规则:使用位矢量必须注明位宽, 例如:
SIGNAL a,BIT VECTOR( 7 DOWNTO 0); --定
义 a为由 a(7)~ a(0)构成矢量,左为 a(7)右为 a(0);
2009-11-10 104
4,字符( CHARACTER)数据类型
字 符 是 用 单 引 号 括 起 来 的 ASCII 码字符, 如
‘ A‘?a‘?0‘?9‘
定义语句:
TYPE CHARACTER IS( ASCII码字符表中的全部
字符)
5,整数( INTEGER)数据类型
整数包括:正整数, 负整数和零
范围,32位带符号数原码,即 -(231-1)~ +(231-1)
( -2147483647~ +2147483647)
2009-11-10 105
6.自然数 ( NATURAL) 和正整数 ( POSITIVE) 数据类

自然数 ——包括 0和正整数
正整数 ——不包括 0的正整数
7,实数 ( REAL) 数据类型
由正, 负, 小数点和数字组成, 如,-1.0,+2.5,-
1.0E38
范围,-1.0E+38 TO +1.0E+38
2009-11-10 106
8,字符串 ( STRING) 数据类型
字符串是用双引号括起来的字符序列, 也称字符矢
量或字符串数组 。 例如,
,A BOY.‖,,10100011‖
9,时间 ( TIME) 数据类型
时间是物理量数据,由整数数据和单位两部分组成,
定义语句:
2009-11-10 107
TYPE TIME IS RANGE –2147483647 TO
2147483647
units
fs; --飞秒 ( 10-15S) VHDL中的最小时间单位
ps=1000fs; --皮秒
ns=1000ps; --纳秒
us=1000ns; --微秒
ms=1000us; --毫秒
sec=1000ms; --秒
min=60sec; --分
hr=60min; --时
END units;
2009-11-10 108
10.错误等级 ( Severity Level)
错误等级数据用于表征系统的状态,包括,NOTE(注
意),WARNING(警告),ERROR(出错),FAILURE
(失败) 。在仿真过程中,可输出这 4种值来提示被
仿真系统当前的工作状态。其定义如下:
TYPE severity_level IS( note,warning,error,
failure);
2009-11-10 109
3.2.5 IEEE预定义的标准逻辑位和矢量
1,标准逻辑位 ( STD LOGIC) 数据类型
TYPE STD LOGIC IS( ‘ U‘--未初始化的
‘ X‘--强未知的
‘ 0‘--强 0
?1‘--强 1
?Z‘--高阻态
‘ W‘--弱未知的
‘ L‘--弱 0
?H‘--弱 1
?-‘--忽略);
2009-11-10 110
2,标准逻辑矢量 ( STD LOGIC VECTOR) 数据类型
TYPE STD LOGIC VECTOR IS ARRAY( Natural
Range〈〉 ) OF STD LOGIC ; -- 〈〉 表示范围未定
2009-11-10 111
3.2.6 用户自定义数据类型方式
定义格式,TYPE 数据类型名 IS 数据类型定义 OF 基
本数据类型
或,TYPE 数据类型名 IS 数据类型定义;
例如:
TYPE st IS ARRAY( 0 TO 15) OF STD LOGIC;
TYPE week IS ( sun,mon,tue,wed,thu,fri,
sat);
2009-11-10 112
1,枚举类型 ( Enumerated)
定义格式,TYPE 数据类型名 IS 数据类型定义;
例如,TYPE week IS ( sun,mon,tue,wed,thu,
fri,sat);
2,整数类型和实数类型
定义格式,TYPE 数据类型名 IS RANGE 范围;
例如,TYPE num1 IS RANGE 0 TO 100;
2009-11-10 113
3,数组类型
数组 ——是一组具有相同数据类型的元素的组合 。
定义格式,TYPE 数组名 IS ARRAY ( 数据范围 )
OF 数据类型;
例如,TYPE data_bus IS ARRAY (7 DOWNTO 0) OF
STD_LOGIC; --定义数据总线, 下标由高到低, 即 D7位
权值最高, D0位权值最低 。
TYPE data_bus IS ARRAY (0 TO 7) OF STD_LOGIC;
--定义数据总线,下标由低到高,即 D0位权值最高,
D7位权值最低。
2009-11-10 114
4,记录类型 ( Recode)
记录 ——是一组不同数据类型的元素的组合 。
定义格式,TYPE记录类型名 IS RECODE
元素名:元素数据类型;
元素名:元素数据类型;

END RECODE [记录类型名 ]
2009-11-10 115
类型 操作符 功能 操作数数据类型





+ 加 整数
- 减 整数
& 并 一维数组
* 乘 整数和实数
/ 除 整数和实数
MOD 取模 整数
REM 求余 整数
SLL 逻辑左移 BIT或布尔型一维数组
SRL 逻辑右移 BIT或布尔型一维数组
3.2.7 VHDL操作符
2009-11-10 116
类型 操作符 功能 操作数数据类型





SLA 算术左移 BIT或布尔型一维
数组
SRA 算术右移 BIT或布尔型一维
数组
ROL 逻辑循环左

BIT或布尔型一维
数组
ROR 逻辑循环右

BIT或布尔型一维
数组
** 乘方 整数
ABS 取绝对值 整数
2009-11-10 117
类型 操作符 功能 操作数数据类型





= 等于 任何数据类型
/= 不等于 任何数据类型
< 小于 枚举与整数及对
应的一维数组
> 大于 同上
<= 小于等于 同上
>= 大于等于 同上
2009-11-10 118
类型 操作符 功能 操作数数据类型





AND 与 BIT, BOOLEAN,
STD LOGIC
OR 或 同上
NAND 与非 同上
NOR 或非 同上
XOR 异或 同上
NXOR 异或非 同上
NOT 非 同上
2009-11-10 119
类型 操作符 功能 操作数数据类型
符号
操作符
+ 正 整数
- 付 整数
说明,( 1) 操作符的优先级,( ) → ( NOT,
ABS,**) → ( REM,MOD,/,*) → ( +,-)
→ ( 关系运算符 ) → ( 逻辑运算符,XOR,NOR,
NAND,OR,AND)
( 2) 在逻辑运算表达式中若全部运算符相同, 则可
以不加括号;若运算符不同则加括号分隔;
( 3) 并, &‖操作符完成一维数组的位扩展
2009-11-10 120
功能:用于检出时钟边沿, 完成定时检查, 获得未约
束的数据类型的范围等 。
格式:属性测试项目名 ‘ 属性标识符; --S?属性标识符
3.2.8 属性( ATTRIBUTE)描述与定义
语句
2009-11-10 121
例如,TYPE number IS INTEGER RANGE 9
DOWNTO 0;
I,=number?LEFT; --I=9
I,=number?RIGTH; --I=0
I,=number?HIGH; --I=9
I,=number?LOW; --I=0
2009-11-10 122
EVENT——表示对当前的一个极小的时间段内发生事
件的情况进行检测 ( 如时钟的边沿 ) 。
例如,clock?EVENT --检测以 clock为属性测
试项目的事件
clock?EVENT AND clock=?1‘; -- 检测 clock
的上升沿
clock?EVENT AND clock=?0‘; -- 检测 clock
的下降沿
LAST_EVENT——从信号最近一次的发生至今所经
历的时间,常用于检查定时时间、建立时间、保持
时间和脉冲宽度等。
2009-11-10 123
3.3 VHDL顺序语句
顺序语句只能出现在进程( PROCESS)、过程
( PROCEDURE)和函数( FUNCTION)中,其特
点与传统的计算机编程语句类似,是按程序书写的顺
序自上而下、一条一条地执行。利用顺序语句可以描
述数字逻辑系统中的组合逻辑电路和时序逻辑电路。
VHDL的顺序语句有赋值语句、流程控制语句、等待
语句、子程序调用语句、返回语句、空操作语句等六
类。
2009-11-10 124
顺序语句 —— 在进程 ( PROCESS ) 或子程序
( PROCEDURE),函数 ( FUNCTION) 中使用, 按程序
书写的顺序自上而下, 一个一个语句地执行;
并行语句 ——出现在结构体中, 各语句并行 ( 同步 )
执行, 与书写的顺序无关 。
3.3.1 VHDL赋值语句
2009-11-10 125
1,变量赋值语句
格式:目标变量名,=赋值源 ( 表达式 ) ;
例如,x,=5.0;
2,信号赋值语句
格式:目标信号名 <=赋值源 ;
例如,y<=?1‘;
说明:该语句若出现在进程或子程序中则是顺序语
句, 若出现在结构体中则是并行语句 。
2009-11-10 126
3,数组元素赋值
例如:
SIGNAL a,b,STD LOGIC VECTOR( 1 TO 4) ;
a<=―1101‖;
a( 1 TO 2) <=―10‖
a( 1 TO 2) <=b( 2 TO 3);
2009-11-10 127
1,IF语句
格式 1,IF 条件句 Then
顺序语句 ;
END IF;
格式 2,IF 条件句 Then
顺序语句 ;
ELSE
顺序语句 ;
END IF;
3.3.2 流程控制语句
2009-11-10 128
格式 3,IF 条件句 Then
顺序语句 ;
ELSIF 条件句 Then
顺序语句 ;

ELSE
顺序语句 ;
END IF;
2009-11-10 129
【 例 3.5】 用 VHDL语言描述下图硬件电路
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY control_stmts IS
PORT(a,b,c:IN BOOLEAN;
y:OUT BOOLEAN);
END control_stmts;
c
a
b
y
2009-11-10 130
ARCHITECTURE example1 OF control_stmts IS
BEGIN
PROCESS(a,b,c)
VARIABLE n:BOOLEAN;
BEGIN
IF a THEN n:=b;
ELSE
n:=c;
END IF;
y<=n;
END PROCESS;
END example1;
2009-11-10 131
【 例 3.6】 8线 -3线优先编码器的设计 (真值表)
输入 输出
a0 a1 a2 a3 a4 a5 a6 a7 y0 y1 y2
x x x x x x x 0 1 1 1
x x x x x x 0 1 0 1 1
x x x x x 0 1 1 1 0 1
x x x x 0 1 1 1 0 0 1
x x x 0 1 1 1 1 1 1 0
x x 0 1 1 1 1 1 0 1 0
x 0 1 1 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0 0 0
2009-11-10 132
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY coder IS
PORT(a:IN STD_LOGIC_VECTOR(0 TO 7);
y:OUT STD_LOGIC_VECTOR(0 TO 2));
END coder;
ARCHITECTURE example2 OF coder IS
BEGIN
2009-11-10 133
PROCESS(a)
BEGIN
IF a(7)='0' THEN y<="111";
ELSIF (a(6)='0') THEN y<="011";
ELSIF (a(5)='0') THEN y<="101";
ELSIF (a(4)='0') THEN y<="001";
ELSIF (a(3)='0') THEN y<="110";
ELSIF (a(2)='0') THEN y<="010";
ELSIF (a(1)='0') THEN y<="100";
ELSE y<="000";
END IF;
END PROCESS;
END example2;
2009-11-10 134
2,CASE语句
格式,CASE 表达式 IS
When 选择值 =>顺序语句;
When 选择值 =>顺序语句;

When OTHERS =>顺序语句;
END CASE;
说明:, =>‖不是运算符, 相当, THEN‖
2009-11-10 135
【 例 3.7】 用 CASE语句描述 4选 1数据选择器





a
s2
zbc
d
s1
2009-11-10 136
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux41 IS
PORT(s1,s2:IN STD_LOGIC;
a,b,c,d:IN STD_LOGIC;
z:OUT STD_LOGIC);
END mux41;
ARCHITECTURE example3 OF mux41 IS
SIGNAL s:STD_LOGIC_VECTOR(1 DOWNTO 0);
2009-11-10 137
BEGIN
s<=s1&s2;
PROCESS(s1,s2,a,b,c,d)
BEGIN
CASE s IS
WHEN "00" => z <= a;
WHEN "01" => z <= b;
WHEN "10" => z <= c;
WHEN "11" => z <= d;
WHEN OTHERS => z <= 'X';
2009-11-10 138
END CASE;
END PROCESS;
END example3;
3,LOOP语句
格式 1:
[标号,]FOR 循环变量 IN 初值 TO 终值 LOOP
顺序语句 ;
END LOOP[标号 ];
2009-11-10 139
【 例 3.8】 8位奇偶校验器的描述
8






a( 0)
z
a( 1)
a( 2)
a( 3)
a( 4)
a( 5)
a( 6)
a( 7)
8






za( 7..0)
2009-11-10 140
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY p_check IS
PORT(a:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
y:OUT STD_LOGIC);
END p_check;
ARCHITECTURE example4 OF p_check IS
BEGIN
2009-11-10 141
PROCESS(a)
VARIABLE temp:STD_LOGIC;
BEGIN
temp:='0';
FOR n IN 7 DOWNTO 0 LOOP
temp:=temp XOR a(n);
END LOOP;
y<=temp;
END PROCESS;
END example4;
2009-11-10 142
4,NEXT语句
格式,NEXT [标号 ][WHEN 条件 ];
功能:
( 1) NEXT——无条件结束本次循环
( 2) NEXT 标号 ——结束本次循环, 从, 标号, 规
定的位置继续循环;
( 3) NEXT WHEN 条件 ——当, 条件, 满足时结
束本次循环, 否则继续循环 。
2009-11-10 143
5,EXIT语句
格式,EXIT [标号 ][WHEN 条件 ];
功能:
( 1) EXIT——无条件跳出循环
( 2) EXIT 标号 ——跳出循环, 从, 标号, 规定的
位置开始循环;
( 3) EXIT WHEN 条件 ——当“条件”满足时跳
出循环,否则继续循环。
2009-11-10 144
格式 1,WAIT ON 敏感信号表;
功能:将运行的程序挂起直至敏感信号表中的任
一信号发生变化时结束挂起, 重新执行程序 。
例如,SIGNAL s1,s2,STD LOGIC;
PROCESS

WAIT ON s1,s2;
END PROCESS;
3.3.3 WAIT语句
2009-11-10 145
注意:含 WAIT语句的进程 PROCESS的括弧中后不
能加敏感信号, 否则是非法的, 例如
PROCESS( s1,s2)
格式 2,WAIT UNTIL 条件表达式;
功能:将运行的程序挂起直至表达式中的敏感信号
发生变化, 而且满足表达式设置的条件时结束挂起,
重新执行程序 。
例如,WAIT UNTIL enable=?1‘;
2009-11-10 146
格式,ASSERT条件表达式 [ REPORT 字 符 串 ][
SEVERITY 错误等级 ]
功能:当条件为, 真, 时, 向下执行另一个语句,
为, 假, 时, 则输出, 字符串, 信息并指出, 错误
等级, 。
用途:用于仿真、调试程序时的人机对话。
3.3.4 断言( ASSERT)语句
2009-11-10 147
例如
ASSERT ( S=?1‘ANDR=?1‘)
REPORT―Both values of S and R are equal ?1‘‖
SEVERITY ERROR;
错误等级,NOTE(注意),WARNING(警告),
ERROR(出错),FAILURE(失败)
2009-11-10 148
3.4 VHDL并行语句
并行语句 ——出现在结构体中,各语句并行(同
步)运行,与书写的顺序无关。
1,并行语句的种类
2009-11-10 149
ARCHITECTURE









































信号 信号 信号 信号 信号 信号
END ARCHITECTURE
2009-11-10 150
2,并行语句的使用结构
ARCHITECTURE 结构体名 OF 实体名 IS
说明语句
BEGIN
并行语句
END ARCHITECTURE 结构体名
2009-11-10 151
进程语句属于并行语句,它在 VHDL中使用最频繁、
最能体现 VHDL风格。
进程语句格式:
[进程标号,]PROCESS [( 敏感信号参数表 ) ] [IS]
[进程说明部分 ]
BEGIN
顺序描述语句
END PROCESS [进程标号 ];
3.4.1 进程语句
2009-11-10 152
【 例 3.9】 异步清除十进制加法计数器的描述
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY cnt10y IS
PORT(clr:IN STD_LOGIC;
clk:IN STD_LOGIC;
cnt:BUFFER INTEGER RANGE 9 DOWNTO 0);
END cnt10y;
ARCHITECTURE example9 OF cnt10y IS
2009-11-10 153
BEGIN
PROCESS(clr,clk)
BEGIN
IF clr='0' THEN cnt<=0;
ELSIF clk'EVENT AND clk='1' THEN
IF (cnt=9) THEN
cnt<=0;
ELSE
cnt<=cnt+1;
END IF;
END IF;
END PROCESS;
END example9;
2009-11-10 154
功能:将一个大系统程序分解为若干子系统(块)
编写,便于程序的编写、调试和查错。
格式:块名,BLOCK
[说明部分 ]
BEGIN
… --以并行语句构成的块体
END BLOCK 块名
3.4.2 块语句
2009-11-10 155
【 例 3.10】 假设 CPU芯片由算术逻辑运算单元 ALU
和寄存器组 REG8组成, REG8又由 8个 REG1、
REG2,… 子块构成, 其程序结构为:
LIBRARY IEEE;
USE IEEE.STD LOGIC 1164.ALL
ENTITY CPU IS
PORT( clk,RESET,IN STD LOGIC;
ADDERS,OUT STD LOGIC_VECTOR( 31DOWNTO 0) ;
DATA,INOUT STD LOGIC VECTOR( 7DOWNTO 0) ;
END CPU ;
2009-11-10 156
ARCHITECTURE CPU_ALU_REG8 OF CPU IS
SIGANL ibus,dbus:STD_LOGIC_VECTOR(31 DOWNTO 0);
--定义全局量
BEGIN
ALU,BLOCK
SIGNAL Qbus, STD_LOGIC_VECTOR(31DOWNTO 0); --定义局域量
BEGIN
--ALU块行为描述语句
END ALU;
2009-11-10 157
REG8,BLOCK
SIGNALZbus, STD_LOGIC_VECTOR(31
DOWNTO 0); --定义局域量
BEGIN
REG1,BLOCK
SIGNAL Zbus1,STD_LOGIC_VECTOR(31
DOWNTO 0); --定义子局域量
BEGIN
--REG1子块行为描述语句
END REG1
2009-11-10 158

END REG8
END CPU_ALU_REG8
说明:在结构体中定义的全局量可以在各块结构中
使用;块结构中定义局域量只能在本块及所属的子
块中使用;子块中定义子局域量只能在子块中使用。
2009-11-10 159
1,简单信号赋值语句
格式:赋值目标 <=表达式 ;
例如,output1<=a AND b;
规则:赋值目标必须是信号,而且出现在结构体或
块语句中
3.4.3 并行信号赋值语句
2009-11-10 160
2,条件信号赋值语句
格式:
赋值目标 <=表达式 WHEN 赋值条件 ELSE
表达式 WHEN 赋值条件 ELSE

表达式;
2009-11-10 161
例如:对 4选 1多路选择器的描述

z<=a WHEN s=‖00‖ ELSE
b WHEN s=‖01‖ ELSE
c WHEN s=‖10‖ ELSE
d;

2009-11-10 162
3,选择信号赋值语句
格式:
WITH 选择表达式 SELECT
赋值目标信号 <=表达式 WHEN 选择值,
--以,,, 号分

表达式 WHEN 选择值,

表达式 WHEN 选择值;
--以“;”号结

2009-11-10 163
例如,WITH sel SELECT
q<=i0 AFTER 10 ns WHEN 0,
i1 AFTER 10 ns WHEN 1,
i2 AFTER 10 ns WHEN 2,
i3 AFTER 10 ns WHEN 3,
‘ X‘AFTER 10 ns WHEN OTHERS;
3.4.4,子程序和并行过程调用语句
VHDL中的子程序( SUBPROGRAM)有两种类
型:过程( PROCEDURE)和函数
( FUNCTION)。
2009-11-10 164
1,过程 ( PROCEDURE) 语句
过程调用前需要将过程的实质内容装入程序包
( Package) 中, 过程分为过程首和过程体两部分 。 过
程首是过程的索引, 相当于一本书目录, 便于快速地
检索到相应过程体的内容 。 过程首的语句格式为:
PROCEDURE 过程名 ( 参数表 ) ;
过程体是放在程序包的包体 ( Package Body) 中, 过
程体的格式为:
PROCEDURE 过程名 ( 参数表 ) IS
[声明部分 ]
2009-11-10 165
BEGIN
顺序语句 ;
END PROCEDURE 过程名 ;
例如
PROCEDURE adder(SIGANL a, b,INSTD_LOGIC_VECTOR;
Sum,OUT STD_LOGIC ); --过程首
PROCEDURE adder(SIGANL a, b,INSTD_LOGIC_VECTOR;
Sum,OUT STD_LOGIC ) IS --过程体
BEGIN
… ;
END adder;
2009-11-10 166
2,过程调用语句
格式:过程名 ( 关联参数表 ) ;
例如,adder( a1,b1,sum1) ;
规则,( 1) 若过程在进程 ( PROCESS) 中调用, 则
是顺序语句;
( 2)若过程调用出现在结构体( ARCHITECTURE)
或块( BLOCK)中,则属于并行语句,相当一个进
程,而且每调用一次过程,就相当插入一个元件。
2009-11-10 167
3,函数 ( FUNCTION) 语句
格式,FUNCTION 函数名 ( 参数表 )
RETURN 数据类型 IS
[说明部分 ]
BEGIN
[顺序处理语句 ]
RETURN [返回变量名 ];
END [函数名 ];
2009-11-10 168
说明:函数程序通常是放在程序包 ( PACKAGE) 中 。
【 例 3.11】 求最大值的函数:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE bpac1 IS
FUNCTION max(a,b:IN STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR;
--声明函数首
END ;
2009-11-10 169
PACKAGE BODY bpac IS
FUNCTION max(a,b,IN
STD_LOGIC_VECTOR) --声明函数体
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF (a>b) THEN RETURN a;
ELSE RETURN b;
END IF;
END max;
END ;
2009-11-10 170
4,函数调用语句
格式:函数名 ( 关联参数表 ) ;
规则:函数调用是出现在结构体的语句中 。 例如,
peak<=max(data,peak);
2009-11-10 171
3.4.5 元件例化 ( COMPONENT) 语句
格式:
COMPONENT 元件名
GENERIC 说明; --参数说明
PORT 说明; --端口说明
END COMPONENT;
例化名:元件名 PORT MAP(信号,… ); --元
件例化
元件定义
2009-11-10 172
说明:
( 1) COMPONENT语句可以在结构体
( ARCHITECTURE)、程序包( PACKAGE)和
块( BLOCK)的说明中使用; GENERIC用于该
元件的可变参数的代入和赋值; PORT则说明该元
件的输入输出端口的信号规定;
(2) COMPONENT语句分为“元件定义”和“元
件例化”两部分;“元件定义”完成元件的“封
装”,“元件例化”完成电路板上的元件“插座”
的定义,“例化名”(标号名)相当于“插座名”
是不可缺少的;
2009-11-10 173
( 3) ( 信号, … ) 部分完成, 元件, 引脚与
,插座, 引脚的连接 ——―关联,
关联方法,① 位置影射法 ——上层元件端口说明
语句中的信号名与 PORT MAP( ) 中的信号名书
写顺序和位置一一对应 。 例如,
u1,and1( a1,b1,y1);
② 名称映射法 ——用, =>‖号将上层元件端口说
明语句中的信号名与 PORT MAP( ) 中的信号名
关联起来 。 例如,
u1,and1( a=>a1,b=>b1,y=>y1);
2009-11-10 174
【 例 3.12】 利用 2输入端与非门元件,设计 4输入端的或电路。
a
b c
a1
b1
c1
d1
z1
u1
u2
u3X
Y
2009-11-10 175
第一步:设计 2输入端与非门
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY nd2 IS
PORT (a,b,IN STD_LOGIC;
c,OUT STD_LOGIC);
END nd2;
ARCHITECTURE nd2behv OF nd2 IS
BEGIN
c<=a NAND b;
END nd2behv;
2009-11-10 176
第二步:将设计的元件声明装入 my_pkg程序包中,
包含 2输入端与非门元件的 my_pkg程序包的 VHDL源
程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE my_pkg IS
Component nd2 --元件声明
PORT (a,b,IN STD_LOGIC;
c,OUT STD_LOGIC);
END Component;
END my_pkg;
2009-11-10 177
第三步:用元件例化产生电路:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE work.my_pkg.ALL; --打开程序包
ENTITY ord41 IS
PORT (a1,b1,c1,d1,IN STD_LOGIC;
z1,OUT STD_LOGIC);
END ord41;
ARCHITECTURE ord41behv OF ord41 IS --元件
例化
2009-11-10 178
SIGNAL x,y,STD_LOGIC;
BEGIN
u1:nd2 PORT MAP(a1,b1,x); --位置关联方式
u2:nd2 PORT MAP(a=>c1,b=>d1,c=>y); --名字
关联方式
u3:nd2 PORT MAP(x,y,c=>z1); --混合
关联方式
END ord41behv;
2009-11-10 179
3.4.6 生成语句
功能:复制一组完全相同的并行元件或设计单元电
路结构。
格式 1, [标 号,]FOR 循 环变量 IN 取值范围
GENERATE
[说明部分 ]
BEGIN
[并行语句 ]; --元件例化语句, 以重复产生并行元件 。
END GENERATE [标号 ];
2009-11-10 180
格式 2,[标号,]IF 条件 GENERATE
[说明部分 ]
BEGIN
[并行语句 ]
END GENERATE [标号 ];
( 【 例 3.13】 供读者参考)
2009-11-10 181
3.5 VHDL的库和程序包
根据 VHDL语法规则,在 VHDL程序中使用的
文字、数据对象、数据类型都需要预先定义。为了
方便用 VHDL编程和提高设计效率,可以将预先定义
好的数据类型、元件调用说明以及一些常用子程序
汇集在一起,形成程序包,供 VHDL设计实体供调用,
若干个程序包则形成库。
2009-11-10 182
3.5.1,VHDL库
常用 VHDL库有 IEEE标准库, STD库和 WORK库 。
IEEE 标准库包括 STD_LOGIC_1164 程 序 包 和
STD_LOGIC_ARITH 程序包 。 其中,
STD_LOGIC_ARITH程序包是 SYNOPSYS公司加入
IEEE标准库的程序包, 它包括 STD_LOGIC_SIGNED
( 有符号数 ) 程序包, STD_LOGIC_UNSIGNED( 无
符号数 ) 程序包和 STD_LOGIC_SMALL_INT( 小整
型数 ) 程序包 。 其中 STD_LOGIC_1164是最重要和最
常用的程序包, 大部分数字系统设计都是以此程序包
设定的标准为基础 。
2009-11-10 183
因此, 在每个设计实体开始都有打开 IEEE标准
库和该程序包的语句
LIBRARY IEEE;
USE IEEE STD_LOGIC_1164.ALL;
STD库包含 STANDARD和 TEXTIO程序包, 它
们是文件输入 /输出程序包, 在 VHDL的编译和综合过
程中, 系统都能自动调用这两个程序包中的任何内容 。
用户在进行电路设计时, 可以不必如 IEEE库那样打开
该库以及它的程序包 。
2009-11-10 184
WORK库是用户设计的现行工作库, 用于存放用户
自己设计的工程项目 。 在 PC机或工作站利用 VHDL进
行项目设计, 不允许在根目录下进行, 必须在根目录
下为设计建立一个工程目录 ( 即文件夹 ), VHDL综
合器将此目录默认为 WORK库 。 但, WORK‖不是设
计项目的目录名, 而是一个逻辑名 。 VHDL标准规定
WORK库总是可见的, 因此在程序设计时不需要明确
指定 。
2009-11-10 185
3.5.2 VHDL程序包
在设计实体中定义的数据类型, 子程序或数据对
象对于其他设计实体是不可再利用的 。 为了使已定义
的数据类型, 子程序, 元件能被其他设计实体调用或
共享, 可以把它们汇集在程序包中 。
VHDL程序包必须经过定义后才能使用,程序包
的结构中包含 Type Declaration(类型定义)、
Subtype Declaration(子类型定义),Constant
Declaration(常量定义),Signal Declaration(信号
定义),Component Declaration(元件定义)、
Subprogram Declaration和(子程序定义)等内容,
2009-11-10 186
程序包定义的格式为
PACKAGE 程序包名 IS
Type Declaration( 类型定义 )
Subtype Declaration( 子类型定义 )
Constant Declaration( 常量定义 )
Signal Declaration( 信号定义 )
Component Declaration( 元件定义 )
Subprogram Declaration( 子程序定义 )
END 程序包名 ;
2009-11-10 187
例如, 定义 my_pkg程序包的结构中, 包含 2输入端与
非门 nd2元件说明, 1位锁存器 Latch1元件说明和求最
大值函数 max的函数首说明以及它的函数体说明 。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE my_pkg IS
Component nd2
PORT (a,b,IN STD_LOGIC;
c,OUT STD_LOGIC);
END Component;
2009-11-10 188
Component latch1
PORT ( d:IN STD_LOGIC;
ena:IN STD_LOGIC;
q:OUT STD_LOGIC);
END Component;
FUNCTION max(a,b:IN STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR;
END ; --函数首定义
2009-11-10 189
PACKAGE BODY my_pkg IS --函数体定义
FUNCTION max(a,b,IN STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF (a>b) THEN RETURN a;
ELSE RETURN B;
END IF;
END max;
END my_pkg;
2009-11-10 190
由于程序包也是用 VHDL语言编写的, 所以其源程
序也需要以,vhd文件类型保存, my_pkg的源程序名为
my_pkg.vhd。 为了使用 my_pkg程序包中定义内容,
在设计实体的开始, 需要将其打开, 打开 my_pkg程
序包的语句是
USE work,my_pkg.ALL;
2009-11-10 191
3.6 VHDL设计流程
设计举例:计数显示译码电路的设计
计数显示译码电路的设计包括 Cnt4e.vhd、
Dec7s.vhd和 TOP.gdf三个模块,其中 Cnt4e.vhd和
Dec7s.vhd是用 VHDL编写的 4位二进制计数器和
共阴极 7段显示译码器源程序,TOP,gdf则是以原
理图输入法设计的顶层文件。在 TOP,gdf原理图
中以 Cnt4e.vhd和 Dec7s.vhd作为元件,设计一个 8
位计数显示译码电路。
(注:本节内容应结合实际操作讲述。)
2009-11-10 192
编辑 VHDL源文件
编译设计文件
编辑顶层设计文件
编译顶层设计文件
仿真顶层设计文件
锁定引脚
硬件调试
编程下载
设计流程
2009-11-10 193
3.6.1 编辑 VHDL源文件
执行,File‖ → ―New…‖ 命令菜单或按“新建”
按钮出现,New‖对话框,选择,Text Editor file‖,
按,OK‖
2009-11-10 194
编辑四位二进制计数器的源程序 Cnt4.vhd 。
2009-11-10 195
七段数码显示译码器的源程序 Decl7s.vhd 。
2009-11-10 196
2009-11-10 197
3.6.2 创建源文件 TOP.GDF
计数显示译码电路设计需要的元件
2009-11-10 198
TOP顶层设计结果图
2009-11-10 199
3.6.3 编译顶层设计文件
执行, MAX+plus‖的, Compiler‖命令,可对
顶层设计文件进行编译。在编译中,自动完成编译
网表提取( Compiler Netlist Extractor)、数据库
建立( Database Builder)、逻辑综合( Logic
Synthesizer)、逻辑分割( Partitioner)、适配
( Fitter)、延时网表提取( Timing SNF Extractor)
和编程文件汇编( Assembler)等操作。
在完成对图形编辑文件的编译后,系统并没有
为设计文件自动生成元件符号,若要生成元件符号,
则还要执行, File‖菜单下的, Create Default
Symbol‖命令。
2009-11-10 200
3.6.4 仿真顶层设计文件
8位计数显示译码电路的仿真波形
2009-11-10 201
3.6.5 引脚锁定
首先在,Device Family‖中选择,FLE10K‖,
在 Device列表中选择,EPF10KLC84-4‖芯片型号。
然后在,Assign‖的,Pin/Location/Chip…‖ 的
对话框中设置引脚。
2009-11-10 202
3.6.6 编程下载
执行,MAX+plus Ⅱ ‖的,Programmer‖命令
2009-11-10 203
第 4章 Verilog HDL
?本章概要:本章介绍硬件描述语言 Verilog HDL的语言规则,
数据类型和语句结构, 并介绍最基本, 最典型的数字逻辑电
路的 Verilog HDL描述, 作为 Verilog HDL工程设计的基础 。
?知识要点:
( 1) Verilog HDL设计模块的基本结构 。
( 2) Verilog HDL的语言规则 。
( 3) 用 Verilog HDL实现各种类型电路及系统设计的方法 。
( 4) Verilog HDL设计流程。
2009-11-10 204
4.1 Verilog HDL入门
4.1.1 Verilog HDL程序模块结构




模块端口定义
I/O说明
功能描述
模块内容
信号类型说明
2009-11-10 205
4.1.1 模块端口定义
模块端口定义用来声明设计电路模块的输入输出
端口, 端口定义格式如下
module 模块名 ( 端口 1,端口 2,端口 3,… ) ;
在端口定义的圆括弧中, 是设计电路模块与外界联系
的全部输入输出端口信号或引脚, 它是设计实体对外
的一个通信界面, 是外界可以看到的部分 ( 不包含电
源和接地端 ), 多个端口名之间用,,, 分隔 。 例如,
module adder( sum,cont,ina,inb,cin) ;
2009-11-10 206
4.1.2 模块内容
模块内容包括 I/O说明, 信号类型声明和功能描述 。
1,模块的 I/O说明
模块的 I/O说明用来声明模块端口定义中各端口数据流动方向
包括输入 ( input), 输出 ( output) 和双向 ( inout) 。 I/O说
明格式如下
input 端口 1,端口 2,端口 3,… ;
output 端口 1,端口 2,端口 3,… ;
例如
input ina,inb,cin;
output sum,cont;
2009-11-10 207
2,信号类型声明
信号类型声明用来说明设计电路的功能描述中,所
用的信号的数据类型以及函数声明。
信号的数据类型主要有连线( wire)、寄存器
( reg)、整型( integer)、实型( real)和时间
( time)等类型。
2009-11-10 208
3,功能描述
功能描述是 Verilog HDL程序设计中最主要的部
分,用来描述设计模块的内部结构和模块端口间的
逻辑关系,在电路上相当于器件的内部电路结构。
功能描述可以用 assign语句、元件例化
( instantiate),always块语句,initial块语句等方
法来实现,通常把确定这些设计模块描述的方法称
为建模。
2009-11-10 209
( 1) 用 assign语句建模
用 assign语句建模的方法很简单, 只需要在, assign‖
后面再加一个表达式即可 。 assign语句一般适合对组合逻辑
进行赋值, 称为连续赋值方式 。
【 例 4.1】 1位全加器的设计 。
ina
inb
cin
Adder1 sum
cout
2009-11-10 210
Verilog HDL源程序如下
module adder1(sum,cout,ina,inb,cin);
input ina,inb,cin;
output sum,cout;
assign {cout,sum} = ina+inb+cin;
endmodule
2009-11-10 211
( 2) 用元件例化 ( instantiate) 方式建模
元件例化方式建模是利用 Verilog HDL提供的元
件库实现的 。
例如, 用与门例化元件定义一个 3输入端与门可以
写为
and myand3(y,a,b,c);
2009-11-10 212
( 3) 用 always块语句建模
always块语句可以产生各种逻辑, 常用于时序逻辑
的功能描述 。 一个程序设计模块中, 可以包含一个
或多个 always语句 。 程序运行中, 在某种条件满足
时, 就重复执行一遍 always结构中的语句 。
【 例 4.2】 8位二进制加法计数器的设计。
2009-11-10 213
8位二进制加法计数器的 Verilog HDL源程序:
module cnt8(out,cout,data,load,cin,clk,clr);
input [7:0] data;
input load,cin,clk,clr;
output [7:0] out;
output cout;
reg [7:0] out;
2009-11-10 214
always @(posedge clk)
begin
if (load) out = data;
else if (clr) out ='b00000000;
else if (cin) out = out+1;
end
assign cout = &out;
endmodule
2009-11-10 215
( 4) 用 initial块语句建模
initial块语句预 always语句类似,不过在程序中它
只执行 1次就结束了。
Verilog HDL程序设计模块的基本结构小结:
① Verilog HDL程序是由模块构成的 。 每个模块的
内容都是嵌在 module和 endmodule两语句之间, 每
个模块实现特定的功能, 模块是可以进行层次嵌套
的 。
② 每个模块首先要进行端口定义,并说明输入
( input)、输出( output)或双向( inout),然
后对模块的功能进行逻辑描述。
2009-11-10 216
③ Verilog HDL程序的书写格式自由, 一行可以一
条或多条语句, 一条语句也可以分为多行写 。
④ 除了 end或含 end( 如 endmodule) 语句外, 每
条语句后必须要有分号, ;, 。
⑤ 可以用 /*…… */或 //…… 对 Verilog HDL程序的
任何部分作注释。一个完整的源程序都应当加上
需要的注释,以加强程序的可读性。
2009-11-10 217
4.2 Verilog HDL的词法
4.2.1 空白符和注释
Verilog HDL的空白符包括空格, tab符号,
换行和换页 。 空白符如果不是出现在字符串中,
编译源程序时将被忽略 。
注释分为行注释和块注释两种方式。行注
释用符号 //(两个斜杠)开始,注释到本行结束。
块注释用 /*开始,用 */结束。块注释可以跨越多
行,但它们不能嵌套。
2009-11-10 218
4.2.2 常数
Verilog HDL的常数包括数字, 未知 x和高阻 z三种 。
数字可以用二进制, 十进制, 八进制和十六进制等 4
种不同数制来表示, 完整的数字格式为
<位宽 >‘<进制符号 ><数字 >
其中, 位宽表示数字对应的二进制数的位数宽度;
进制符号包括 b或 B( 表示二进制数 ), d或 D( 表示
十进制数 ), h或 H( 表示十六进制数 ), o或 O( 表
示八进制数 ) 。
2009-11-10 219
例如
8‘b10110001 //表示位宽为 8位的二进制数
8‘hf5 //表示位宽为 8位的十六进制数
十进制数的位宽和进制符号可以缺省, 例如
125//表示十进制数 125
8‘b1111xxxx //等价 8‘hfx
8‘b1101zzzz //等价 8‘hdz
2009-11-10 220
4.2.3 字符串
字符串是用双引号括起来的可打印字符序列, 它必须
包含在同一行中 。 例如,
” ABC‖,” ABOY.‖,” A‖,” 1234‖
都是字符串 。
2009-11-10 221
4.2.4 标识符
标识符是用户编程时为常量, 变量, 模块, 寄存器,
端口, 连线, 示例和 begin-end块等元素定义的名称 。
标识符可以是字母, 数字和下划线, _‖等符号组成的
任意序列 。 定义标识符时应遵循如下规则
① 首字符不能是数字 。
② 字符数不能多于 1024个 。
③ 大小写字母是不同的 。
④ 不要与关键字同名。
2009-11-10 222
4.2.5 关键字
关键字是 Verilog HDL预先定义的单词,它们
在程序中有不同的使用目的。例如,module和
endmodule来指出源程序模块的开始和结束;用
assign来描述一个逻辑表达式等。
Verilog HDL的关键字有 97个(见表 4.1所示)。
2009-11-10 223
4.2.6 操作符
操作符也称为运算符,是 Verilog HDL预定义的
函数名字,这些函数对被操作的对象(即操作数)
进行规定的运算,得到一个结果。
操作符通常由 1~ 3个字符组成,例如,,+‖表
示加操作,,==‖(两个 =字符)表示逻辑等操作,
,===‖( 3个 =字符)表示全等操作。有些操作符的
操作数只有 1个,称为单目操作;有些操作符的操作
数有 2个,称为双目操作;有些操作符的操作数有 3
个,称为三目操作。
2009-11-10 224
1,算术操作符( Arithmetic operators)
常用的算术操作符:
+( 加 ), -( 减 ), *( 乘 ), /( 除 ), %( 求余 ) 。
其中 %是求余操作符,在两个整数相除的基础上, 取
出其余数 。 例如, 5 % 6的值为 5; 13 % 5的值是 3。
2009-11-10 225
2,逻辑操作符( Logical operators )
逻辑操作符包括:
&&( 逻辑与 ), ||( 逻辑或 ), ! ( 逻辑非 )
3,位运算( Bitwise operators)
位运算是将两个操作数按对应位进行逻辑操作 。 位运
算操作符包括,~( 按位取反 ), &( 按位与 ), |( 按
位或 ), ^( 按位异或 ), ^~或 ~^( 按位同或 ) 。
在进行位运算时, 当两个操作数的位宽不同时, 计算
机会自动将两个操作数按右端对齐, 位数少的操作数
会在高位用 0补齐 。
2009-11-10 226
4,关系操作符( Pelational operators)
关系操作符有:
<( 小于 ), <=( 小于等于 ), >( 大于 ), >=( 大
于等于 ) 。
其中, <=也是赋值运算的赋值符号 。
关系运算的结果是 1位逻辑值。在进行关系运算
时,如果关系是真,则计算结果为 1;如果关系是假,
则计算结果为 0;如果某个操作数的值不定,则计算
结果不定(未知),表示结果是模糊的。
2009-11-10 227
5,等式操作符( Equality operators)
等值操作符包括:
==( 等于 ), ! =( 不等于 ), ===( 全等 ),
! ==( 不全等 ) 4种 。
等值运算的结果也是 1位逻辑值,当运算结果为
真时,返回值 1;为假则返回值 0。相等操作符( ==)
与全等操作符( ===)的区别是:当进行相等运算时,
两个操作数必须逐位相等,其比较结果的值才为 1
(真),如果某些位是不定或高阻状态,其相等比较
的结果就会是不定值;而进行全等运算时,对不定或
高阻状态位也进行比较,当两个操作数完全一致时,其结果的值才为 1(真),否则结果为 0(假)。
2009-11-10 228
6,缩减操作符( Reduction operators)
缩减操作符包括:
&(与),~&(与非),|(或),~|(或非)、
^(异或),^~或 ~^(同或)。
缩减操作运算法则与逻辑运算操作相同,但操作
的运算对象只有一个。在进行缩减操作运算时,对操
作数进行与、与非、或、或非、异或、同或等缩减操
作运算,运算结果有 1位 1或 0。例如,设 A=
8‘b11010001,则 & A = 0(在与缩减运算中,只有 A中
的数字全为 1时,结果才为 1); |A= 1(在或缩减运
算中,只有 A中的数字全为 0时,结果才为 0)。
2009-11-10 229
7,转移操作符( Shift operators)
转移操作符包括:
>>( 右移 ), <<( 左移 )
操作数 >> n ; //将操作数的内容右移 n位,
同时从左边开始用 0来填补移出的位数 。
操作数 << n; //将操作数的内容左移 n位, 同时从
右边开始用 0来填补移出的位数 。
例如,设 A= 8‘b11010001,则 A>> 4的结果是 A =
8‘b00001101;而 A<< 4的结果是 A= 8‘b00010000。
2009-11-10 230
8,条件操作符 (Conditional operators)
条件操作符为,?,
条件操作符的操作数有 3个, 其使用格式为
操作数 = 条件? 表达式 1:表达式 2;
即当条件为真(条件结果值为 1)时,操作数 = 表达
式 1;为假(条件结果值为 0)时,操作数 = 表达式 2。
【 例 4.3】 用 Verilog HDL语言描述下图所示的电路。
c
a
b
out
2009-11-10 231
源程序如下
module example_4_3(out,a,b,c);
input a,b,c;
output out;
assign out = a? b:c;
endmodule
2009-11-10 232
9,位并接操作符( Concatenation operators)
并接操作符为,{ }
并接操作符的使用格式为
{ 操作数 1的某些位, 操作数 2的某些位, …, 操作数 n
的某些位 } ;
即将操作数 1的某些位与操作数 2的某些位与 … 与
操作数 n的某些位并接在一起 。 例如, 将 1位全加器进
位 cont与和 sum并接在一起使用, 它们的结果由两个
加数 ina,inb及低位进位 cin相加决定的表达式为
{ cont,sum} = ina+inb+cin;
2009-11-10 233
4.2.7 Verilog HDL数据对象
Verilog HDL数据对象是指用来存放各种类型数据的
容器,包括常量和变量。
1,常量
常量是一个恒定不变的值数, 一般在程序前部定义 。
常量定义格式为
parameter常量名 1 = 表达式, 常量名 2 = 表达式, …, 常量名 n = 表达式;
parameter是常量定义关键字, 常量名是用户定义的标
识符, 表达式是为常量赋的值 。 例如
parameter Vcc = 5,fbus = 8‘b11010001;
2009-11-10 234
2,变量
变量是在程序运行时其值可以改变的量。在 Verilog
HDL中,变量分为网络型( nets type)和寄存器型
( register type)两种。
( 1) 网络型变量 ( nets type)
nets型变量是输出值始终根据输入变化而更新的变量,
它一般 用来定义硬件 电路中的各种 物理连线 。
Verilog HDL提供的 nets型变量如下 。
2009-11-10 235
类 型 功能说明
wire,tri 连线类型(两者功能完全相同)
wor,trior 具有线或特性的连线(两者功能一致)
wand,triand 具有线与特性的连线(两者功能一致)
tri1,tri0 分别为上拉电阻和下拉电阻
supply1、
supply0
分别为电源(逻辑 1)和地(逻辑 0)
2009-11-10 236
( 2) 寄存器型变量 ( register type)
register型变量是一种数值容器,不仅可以容纳当
前值,也可以保持历史值,这一属性与触发器或寄存
器的记忆功能有很好的对应关系。
register型变量也是一种连接线,可以作为设计
模块中各器件间的信息传送通道。 register型变量与
wire型变量的根本区别在于 register型变量需要被明确
地赋值,并且在被重新赋值前一直保持原值。 register
型变量是在 always,initial等过程语句中定义,并通过
过程语句赋值。
2009-11-10 237
类 型 功 能 说 明
reg 常用的寄存器型变量
integer 32位带符号整数型变量
real 64位带符号实数型变量
time 无符号时间型变量
常用的 register型变量及说明
2009-11-10 238
integer,real和 time等 3种寄存器型变量都是纯数
学的抽象描述, 不对应任何具体的硬件电路, 但它们
可以描述与模拟有关的计算 。 例如, 可以利用 time型
变量控制经过特定的时间后关闭显示等 。
reg型变量是数字系统中存储设备的抽象,常用于
的具体的硬件描述,因此是最常用的寄存器型变量。
reg型变量定义的关键字是 reg,定义格式如下
reg [位宽 ] 变量 1,变量 2,…, 变量 n;
用 reg定义的变量有一个范围选项 ( 即位宽 ), 默认的位宽是 1。
位宽为 1位的变量称为标量, 位宽超过 1位的变量称为向量 。 标
量的定义不需要加位宽选项, 例如
reg a,b; //定义两个 reg型变量 a,b
2009-11-10 239
向量定义时需要位宽选项, 例如
reg[7,0] data; //定义 1个 8位寄存器型
变量, 最高有效位是 7,最低有效位是 0
reg[0,7] data; //定义 1个 8位寄存器型
变量, 最高有效位是 0,最低有效位是 7
向量定义后可以采有多种使用形式(即赋值)
data=8‘b00000000;
data[5:3]=3‘B111;
data[7]=1;
2009-11-10 240
( 3) 数组
若干个相同宽度的向量构成数组 。 在数字系统中,
reg型数组变量即为 memory( 存储器 ) 型变量 。
存储器型可以用如下语句定义
reg[7,0] mymemory[1023,0];
上述语句定义了一个 1024个字存储器变量 mymemory,
每个字的字长为 8位 。 在表达式中可以用下面的语句
来使用存储器:
mymemory[7] = 75; //存储器 mymemory的第 7个字
被赋值 75
2009-11-10 241
4.3 Verilog HDL的语句
语句是构成 Verilog HDL程序不可缺少的部分。
Verilog HDL的语句包括赋值语句、条件语句、循
环语句、结构说明语句和编译预处理语句等类型,
每一类语句又包括几种不同的语句。在这些语句中,
有些语句属于顺序执行语句,有些语句属于并行执
行语句。
2009-11-10 242
4.3.1 赋值语句
1,门基元赋值语句
格式
基本逻辑门关键字 ( 门输出, 门输入 1,门输入 2,…, 门输入 n) ;
基本逻辑门关键字是 Verilog HDL预定义的逻辑门,
包括 and,or,not,xor,nand,nor等;圆括弧
中内容是被描述门的输出和输入信号 。 例如, 具有 a、
b,c,d四个输入和 y为输出与非门的门基元赋值语
句为
nand( y,a,b,c,d) ;
该语句与 y = ~( a & b & c & d) 等效
2009-11-10 243
2,连续赋值语句
格式
assign 赋值变量 = 表达式;
例如
assign y = ~( a & b & c & d) ;
连续赋值语句的, =‖号两边的变量都应该是
wire型变量。在执行中,输出 y的变化跟随输入 a,b、
c,d的变化而变化,反映了信息传送的连续性。
2009-11-10 244
【 例 4.4】 4输入端与非门的 Verilog HDL源程序 。
module example_4_4(y,a,b,c,d);
output y;
input a,b,c,d;
assign #1 y = ~(a&b&c&d);
endmodule
#1——表示该门的输出与输入信号之间具有 1个
单位的时间延迟。
2009-11-10 245
3,过程赋值语句
过程赋值语句出现在 initial和 always块语句中,
赋值符号是, =‖,格式为
赋值变量 = 表达式;
在过程赋值语句中,赋值号, =‖左边的赋值变
量必须是 reg(寄存器)型变量,其值在该语句结束
即可得到。如果一个块语句中包含若干条过程赋值语
句,那么这些过程赋值语句是按照语句编写的顺序由
上至下一条一条地执行,前面的语句没有完成,后面
的语句就不能执行,就象被阻塞了一样。因此,过程
赋值语句也称为阻塞赋值语句。
2009-11-10 246
4,非阻塞赋值语句
非阻塞赋值语句也是出现在 initial和 always块语句中,
赋值符号是, <=‖,格式为
赋值变量 <= 表达式;
在非阻塞赋值语句中,赋值号, <=‖左边的赋值
变量也必须是 reg型变量,其值不象在过程赋值语句
那样,语句结束时即刻得到,而在该块语句结束才可
得到。
2009-11-10 247
例如, 在下面的块语句中包含 4条赋值语句
always @(posedge clock)
m = 3;
n = 75;
n <= m;
r = n;
语句执行结束后,r的值是 75,而不是 3,因为第 3行是非阻
塞赋值语句,n <= m”,该语句要等到本块语句结束时,n的
值才能改变。块语句中的,@(posedge clock)”是定时控制
敏感函数,表示时钟信号 clock的上升沿到来的敏感时刻。
2009-11-10 248
【 例 4.5】 上升沿触发的 D触发器的的源程序 。
module D_FF(q,d,clock);
input d,clock;
output q;
reg q;
always @(posedge clock)
q <= d;
endmodule
q是触发器的输出,属于 reg型变量; d和 clock是输
入,属于 wire型变量(由隐含规则定义)。
2009-11-10 249
4.3.2 条件语句
条件语句包含 if语句和 case语句, 它们都是顺
序语句, 应放在 always块中 。
1,if语句
完整的 Verilog HDL的 if语句结构如下:
if (表达式 ) begin 语句 ; end
else if (表达式 ) begin 语句 ; end
else begin 语句 ; end
2009-11-10 250
【 例 4.6】 8线 -3线优先编码器的设计
输入 输出
a0 a1 a2 a3 a4 a5 a6 a7 y2 y1 y0
x x x x x x x 0 1 1 1
x x x x x x 0 1 1 1 0
x x x x x 0 1 1 1 0 1
x x x x 0 1 1 1 1 0 0
x x x 0 1 1 1 1 0 1 1
x x 0 1 1 1 1 1 0 1 0
x 0 1 1 1 1 1 1 0 0 1
0 1 1 1 1 1 1 1 0 0 0
2009-11-10 251
Verilog HDL源代码如下
module example_4_6(y,a);
input[7:0] a;
output[2:0] y;
reg[2:0] y;
always @(a)
begin
if(~a[7]) y<=3'b111;
else if(~a[6]) y<=3'b110;
2009-11-10 252
else if(~a[5]) y<=3'b101;
else if(~a[4]) y<=3'b100;
else if(~a[3]) y<=3'b011;
else if(~a[2]) y<=3'b010;
else if(~a[1]) y<=3'b001;
else y<=3'b000;
end
endmodule
2009-11-10 253
2,case语句
case语句是一种多分支的条件语句, 完整的 case
语句的格式为
case (表达式 )
选择值 1, 语句 1;
选择值 2, 语句 2;

选择值 n, 语句 n;
default, 语句 n+1;
endcase
2009-11-10 254
【 例 4.7】 用 case语句描述 4选 1数据选择器 。
a
b
c
d
s1
s2





z
module example_4_7(z,a,b,c,d,s1,s2);
input s1,s2;
input a,b,c,d;
output z;
reg z;
always @(s1,s2)
begin
2009-11-10 255
case ({s1,s2})
2'b00,z=a;
2'b01,z=b;
2'b10,z=c;
2'b11,z=d;
endcase
end
endmodule
2009-11-10 256
case语句还有两种变体语句形式,即 casez
和 casex语句。 casez和 casex语句与 case语句的
格式完全相同,它们的区别是:在 casez语句中,
如果分支表达式某些位的值为高阻 z,那么对这些
位的比较就不予以考虑,只关注其他位的比较结果。
在 casex语句中,把不予以考虑的位扩展到未知 x,
即不考虑值为高阻 z和未知 x的那些位,只关注其他
位的比较结果。
2009-11-10 257
4.3.3 循环语句
循环语句包含 for语句, repeat语句, while语句
和 forever语句 4种 。
1,for语句
for语句的语法格式为
for (循环指针 = 初值 ; 循环指针 < 终值 ; 循环指针
= 循环指针 + 步长值 )
begin
语句 ;
end
2009-11-10 258
【 例 4.8】 8位奇偶校验器的描述。
module example_4_8(a,out);
input[7:0] a;
output out;
reg out;
integer n;
always @(a)
begin
out = 0;
for (n = 0; n < 8; n = n + 1) out =out ^ a[n];
end
endmodule
2009-11-10 259
2,repeat语句
语法格式
repeat( 循环次数表达式 ) 语句;
用 repeat语句实现 8位奇偶校验器
module example_4_8_1(a,out);
parameter size = 7;
input[7:0] a;
output out;
reg out;
integer n;
always @(a)
2009-11-10 260
begin
out = 0;
n = 0;
repeat(size)
begin
out =out ^ a[n];
n = n+1;
end
end
endmodule
注意,MAX+plusII软件不支持 repeat语句,但
synplify软件支持。
2009-11-10 261
4.3.4 结构声明语句
Verilog HDL的任何过程模块都是放在结构声
明语句中, 结构声明语句包括 always,initial、
task和 function等 4种结构 。
1,always块语句
在一个 Verilog HDL模块 ( module) 中,
always块语句的使用次数是不受限制的, 块内的语
句也是不断重复执行的 。 always块语句的语法结构

2009-11-10 262
always @(敏感信号表达式 )
begin
// 过程赋值语句 ;
// if语句, case语句 ;
// for语句, while语句, repeat语句 ;
// tast语句, function语句 ;
end
2009-11-10 263
在 always 块语句中, 敏感信号表达式
( event-expression) 应该列出影响块内取值的
所有信号 ( 一般指设计电路的输入信号 ), 多个信
号之间用, or‖连接 。 当表达式中任何信号发生变
化时, 就会执行一遍块内的语句 。 块内语句可以包
括:过程赋值, if,case,for,while,repeat、
tast和 function等语句 。
敏感信号表达式中用, posedge‖和
,negedge‖这两个关键字来声明事件是由时钟的
上升沿或下降沿触发。
always @( posedge clk)表示事件由 clk的
上升沿触发; always @( negedge clk)表示事件
由 clk的下降沿触发。
2009-11-10 264
2,initial语句
initial语句的语法格式为
initial
begin
语句 1;
语句 2;

end
initial语句的使用次数也是不受限制的,但块
内的语句仅执行一次,因此 initial语句常用于仿真
中的初始化。
2009-11-10 265
3,task语句
task语句用来定义任务 。 任务类似高级语言中的
子程序, 用来单独完成某项具体任务, 并可以被模
块或其他任务调用 。 利用任务可以把一个大的程序
模块分解成为若干小的任务, 使程序清晰易懂, 而
且便于调试 。
可以被调用的任务必须事先用 task语句定义, 定义
格式如下
2009-11-10 266
task 任务名 ;
端口声明语句 ;
类型声明语句 ;
begin
语句 ;
end
endtask
2009-11-10 267
例如, 8位加法器任务的定义如下
task adder8;
output[7:0] sum;
output cout;
input[7:0] ina,inb;
input cin;
assign {cout,sum}=ina+inb+cin;
endtask
2009-11-10 268
任务调用的格式如下
任务名 ( 端口名列表 ) ;
例如, 8位加法器任务调用
adder8( tsum,tcout,tina,tinb,cin );
2009-11-10 269
4,function语句
function语句用来定义函数,函数定义格式如下
function [最高有效位,最低有效位 ] 函数名 ;
端口声明语句 ;
类型声明语句 ;
begin
语句 ;
end
endfunction
2009-11-10 270
【 例 4.9】 求最大值的函数 。
function [7:0] max;
input[7:0] a,b;
begin
if (a>=b) max=a;
else max=b;
end
endfunction
2009-11-10 271
函数调用的格式如下
函数名 ( 关联参数表 ) ;
函数调用一般是出现在模块, 任务或函数语句中 。
通过函数的调用来完成某些数据的运算或转换 。 例
如, 调用例 4.9编制的求最大值的函数
peak<=max(data,peak);
其中,data和 peak是与函数定义的两个参数 a,b
关联的关联参数。通过函数的调用,求出 data和
peak中的最大值,并用函数名 max返回。
2009-11-10 272
4.4 不同抽象级别的 Verilog HDL模型
Verilog HDL是一种用于逻辑电路设计的硬件描
述语言 。 用 Verilog HDL描述的电路称为该设计电路
的 Verilog HDL模型 。
Verilog HDL具有行为描述和结构描述功能 。 行
为描述是对设计电路的逻辑功能的描述, 并不用关
心设计电路使用那些元件以及这些元件之间的连接
关系 。 行为描述属于高层次的描述方法, 在 Verilog
HDL中, 行为描述包括系统级 ( System Level),
算法级 ( Algorithm Level) 和寄存器传输级 ( RTL:
Register Transfer Level) 等 3种抽象级别 。
2009-11-10 273
结构描述是对设计电路的结构进行描述, 即
描述设计电路使用的元件及这些元件之间的连接
关系 。 结构描述属于低层次的描述方法, 在
Verilog HDL,结构描述包括门级 ( Gate Level)
和开关级 ( Switch Level) 2种抽象级别 。
在 Verilog HDL的学习中,应重点掌握高层次
描述方法,但门级描述在一些电路设计中也有一
定的实际意义。
2009-11-10 274
4.4.1 Verilog HDL门级描述
用于门级描述关键字包括,not( 非门 ), and
( 与门 ), nand( 与非门 ), or( 或门 ), nor( 或
非门 ), xor( 异或门 ), xnor( 异或非门 ), buf
( 缓冲器 ) 以及 bufif1,bufif0,notif1,notif0等各
种三态门 。
门级描述语句格式为
门类型关键字 <例化门的名称 >( 端口列表 ) ;
其中,,例化门的名称, 是用户定义的标识符,属
于可选项;端口列表按:(输出,输入,使能控制
端)的顺序列出。
2009-11-10 275
例如
nand nand2(y,a,b); //2输入端与非门
xor myxor(y,a,b); //异或门
bufif0 mybuf(y,a,en); //低电平使能的三态缓冲器
【 例 4.11】 采用结构描述方式描述下图所示的硬件电
路 。
S2
S3
S1
2009-11-10 276
module example_4_11(y,a,b,c);
input a,b,c;
output y;
wire s1,s2,s3;
not (s1,a);
nand (s2,c,s1);
nand (s3,a,b);
nand (y,s2,s3);
endmodule
2009-11-10 277
4.4.2 Verilog HDL的行为级描述
Verilog HDL的行为级描述是最能体现 EDA风
格的硬件描述方式,它既可以描述简单的逻辑门,
也可以描述复杂的数字系统乃至微处理器;既可
以描述组合逻辑电路,也可以描述时序逻辑电路。
【 例 4.12】 3线 -8线译码器的设计。
2009-11-10 278
module example_4_12(a,b,c,y,en);
input a,b,c,en;
output[7:0] y;
reg[7:0] y;
always @(en or a or b or c)
begin
if (en) y = 8'b11111111;
else
begin
2009-11-10 279
case({c,b,a})
3'b000,y<=8'b11111110;
3'b001,y<=8'b11111101;
3'b010,y<=8'b11111011;
3'b011,y<=8'b11110111;
3'b100,y<=8'b11101111;
3'b101,y<=8'b11011111;
3'b110,y<=8'b10111111;
3'b111,y<=8'b01111111;
endcase
end
end
endmodule
2009-11-10 280
【 例 4.13】 8D锁存器的设计。
module example_4_13(d,q,en);
input en;
input[7:0] d;
output[7:0] q;
reg[7:0] q;
always @(en or d)
begin
if (en)q = 8'bzzzzzzzz;
else
q=d;
end
endmodule
2009-11-10 281
【 例 4.14】 异步清除十进制加法计数器的设计。
module example_4_14(clr,clk,cnt,out);
input clr,clk;
output[3:0] out;
output cnt;
reg[3:0] out;
reg cnt;
always @(posedge clk or posedge clr)
begin
if (clr)
begin out=4'b0000; cnt=0; end
else if (out==4'b1001)
begin out=4'b0000; cnt=1; end
else begin cnt=0;out=out+1; end
end
endmodule
2009-11-10 282
4.4.3 用结构描述实现电路系统设计
任何用 Verilog HDL描述的电路设计模块 ( module), 均可
用模块例化语句, 例化一个元件, 来实现电路系统的设计 。
模块例化语句格式与逻辑门例化语句格式相同, 具体为
设计模块名 <例化电路名 >( 端口列表 ) ;
其中,, 例化电路名, 是用户为系统设计定义的标识符, 相
当系统电路板上为插入设计模块元件的插座, 而端口列表相
当插座上引脚名表, 应与设计模块的输入 /输出端口一一对应 。
【 例 4.15】 用模块例化方式设计 8位计数译码器电路系统 。
第一步:设计一个 4位二进制加法计数器 cnt4e模块和一个 7
段数码显示器的译码器 dec7s模块
2009-11-10 283
Cnt4e的 Verilog HDL源程序如下:
module cnt4e(clk,clr,ena,cout,q);
input clk,clr,ena;
output [3:0] q;
output cout;
reg [3:0] q;
always @(posedge clr or posedge clk)
begin
if (clr) q = 'b0000;
else if (ena) q = q+1;
end
assign cout = &q;
endmodule
2009-11-10 284
Dec7s的 Verilog HDL源程序如下:
module Dec7s(a,q);
input [3:0] a;
output [7:0] q;
reg [7:0] q;
always @(a)
begin
case(a)
0:q=8'b00111111; 1:q=8'b00000110;
2:q=8'b01011011; 3:q=8'b01001111;
2009-11-10 285
4:q=8'b01100110; 5:q=8'b01101101;
6:q=8'b01111101; 7:q=8'b00000111;
8:q=8'b01111111; 9:q=8'b01101111;
10:q=8'b01110111; 11:q=8'b01111100;
12:q=8'b00111001; 13:q=8'b01011110;
14:q=8'b01111001; 15:q=8'b01110001;
endcase
end
endmodule
2009-11-10 286
第二步:设计计数译码系统电路。计数译码系统电路的结
构图如图 4.13所示,其中 u1和 u2是两个 cnt4e元件的例化
模块名,相当 cnt4e系统电路板上的插座; u3和 u4是 dec7s
元件的例化模块名,相当 dec7s在系统电路板上的插座。 x、
q1,q2是电路中的连线。
图 4.13 计数译码系统电路的结构图
u1
u2
u3
u4
x
q1
q2
2009-11-10 287
cnt_dec7s的源程序如下:
module cnt_Dec_v(clk,clr,ena,cout,q);
input clk,clr,ena;
output[15:0] q;
output cout;
reg [15:0] q;
wire [3:0] q1,q2;
wire x;
cnt4e u1(clk,clr,ena,x,q1); //模块例化
cnt4e u2(clk,clr,x,cout,q2);
dec7s u3(q1,q[7:0]);
dec7s u4(q2,q[15:8]);
endmodule
2009-11-10 288
4.5 Verilog HDL设计流程
Verilog HDL设计流程与第 3章叙述的 VHDL设计
流程基本相同,这里不再重复。
2009-11-10 289
第 5章 AHDL
?本章概要:本章介绍 AHDL设计结构, 基本元素, 数据类型
和语句结构, 并通过最基本, 最典型的数字逻辑电路的 AHDL
描述介绍, 作为 AHDL工程设计的基础 。
?知识要点:
( 1) 基本 AHDL设计结构 。
( 2) AHDL基本元素, 数据类型和语句结构 。
( 3) 用 AHDL实现各种类型电路及系统设计的方法 。
( 4) AHDL设计流程。
2009-11-10 290
5.1 基本 AHDL设计结构
变量段( VARIABLE)
逻辑段
子设计段( SUBDESIGN)
基本 AHDL设计结构图
2009-11-10 291
5.1.1 子设计段( Subdesign Section)
子设计段用于描述设计电路的输入, 输出和双
向端口 。 子设计段的语法规则如下
SUBDESIGN 子设计名称
( 信号名 1,信号名 2,…, 信号名 n:端口类型;
信号名 1,信号名 2,…, 信号名 n:端口类型; )
例如, 半加器 h_adder的子设计段为
SUBDESIGN h_adder
( a,b,INPUT; --半加器的输入端口
so,co:OUTPUT;) --半加器的输出端口
2009-11-10 292
5.1.2 变量段( Variable Section)
可选的变量段用于声明和产生用在逻辑段的任
何变量 。 在 AHDL中, 变量一般用来代表设计电路内
部连接线或节点 ( NODE), 触发器或寄存器, 状态
机等, 完成信号的传送, 存储和表示状态变化 。
变量段的语法规则如下
VARIABLE
变量名 1,变量名 1,…, 变量名 n:变量类型;
变量名 1,变量名 1,…,变量名 m,变量类型;
2009-11-10 293
变 量 类 型 可 以 是 NODE ( 节点 ),
TRI_STATE_NODE( 三态节点 ), Primitive( 原
语 ), megafunction( 强函数 ), macrofunction
( 宏函数 ) 或 state machine declaration( 状态机
声明 ) 。
变量段可以包括一个或多实例声明、节点声明、
寄存器声明、状态机声明、状态机别名声明语句。应
该注意,变量段也可以包括 If Generate语句,可以
用它产生实例、节点、寄存器,状态机和状态机别名
声明。
2009-11-10 294
1,Instance(实例)声明
在变量段里, 可以声明一个具有某种独立应用的, 实
际的逻辑函数, 称为实例声明 。 当一个变量带有一个
实例声明时, 在它被声明之后, 用户就可以在逻辑段
内使用这个逻辑函数的输入和输出端口 。
例如, 如果用户希望把 ff函数合并到用户的当前 TDF
文件里, 变量段里应做以下实例声明
VARIABLE
ff, TFF;
2009-11-10 295
这个变量声明指出变量 ff是函数 TFF( T触发器函数 )
的实例 。 TFF函数有 t,clk,cler,prn等输入端和 q
输出端 。 因此, 用户在当前逻辑段中可以用 ff.t表示 T
触发器的输入端 t,用 ff.clk表示时钟输入端 clk,用
ff.cler表示复位输入端 cler,用 ff.prn表示置位输入
端 prn,用 ff.q表示输出端 q。 并且可以在当前逻辑段
中, 用表达式表示设计电路的连接关系 。 例如用表
达式
ff.t=t;
表示实际设计电路的 t输入端口,与 AHDL中预先定
义好的 T触发器函数实例 TFF的 t输入端 t连接。
2009-11-10 296
2,NODE(节点)声明
AHDL 支持 NODE ( 节点 ) 和 TRI_STATE_NODE
( 三态节点 ) 两种类型的节点 。 两种类型是全局的变
量类型, 它们用于存储在子设计段和别处变量段内没
有被声明过的信号, 每一种变量可以被用在一个等式
的左边或右边 。 节点和三态节点相当设计电路内部的
连接线, 完成内部信号的传输 。 例如
VARIABLE
b, NODE;
t, TRl_STATE_NODE;
一般用 NODE类型节点来声明不存在高阻状态
的信号线,用 TRI_STATE_NODE类型节点来声明包
括高、低电平和高阻状态的信号线节点。
2009-11-10 297
3,Register(寄存器)声明
寄存器声明包括 D,T,JK,SR触发器 ( 即
DFF, DFFE, TFF, TFFE,JKFF, JKFFE,
SRFF和 SRFFE) 和锁存器 ( LATCH) 的声明 。 这
些寄存器是 AHDL预先定义好的函数, 称为原语函
数 。 通过变量声明后, 寄存器的输入和输出就可以
在当前的逻辑段中使用 。 例如
VARIABLE
ff, DFF;
这个寄存器变量声明 ff是 D触发器 。 在完成寄
存 器 变 量 声 明 后, 用 户 可 以 按 照, instance
name.port name‖格式来描述 D触发器的输入和输
出端口 。 例如
2009-11-10 298
ff.d --表示 D触发器的输入端 d
ff.clk --表示 D触发器的时钟输入端 clk
ff.cler --表示 D触发器的复位输入端 cler
ff.prn--表示 D触发器的置位输入端 prn
ff.q --表示 D触发器的输出端 q
由于所有的原语都只有一个输出,用户想使用
它的输出端,可以不带附加端口名。例如,ff和 ff.q
都可以用来表示 D触发器的输出端口名。
2009-11-10 299
4,State Machine(状态机)声明
状态机一般用来实现时序逻辑电路的描述, 反映触发
器, 计数器, 状态机的状态位数和状态 。 因此, 用户
创建一个状态机时, 必须在变量段内声明状态机的名
称, 状态, 根据需要还可以设置状态位 。
状态机声明的语法规则:
状态名,MACHINE
OF BITS( 状态位组 )
WITH STATES(状态)
2009-11-10 300
例如
VARIABLE
ss, MACHINE
OF BITS(q1,q2,q3) --位组
WITH STATES( --状态
s1= B‖000‖,
s2= B‖010‖,
s3= B‖111‖);
上述状态机声明定义了状态名是 ss,状态机位
q1,q2和 q3,表示是 3位状态机,状态机的状态是 s1、
s2和 s3,每个状态机都给状态位 q1,q2和 q3赋予一
个具体的状态值。例如,在 s1状态,q1,q2和 q3的
值都是 0。
2009-11-10 301
5,Machine Alias(状态机别名)声明
用户可以在变量段中用状态机别名声明语句为状态
机起一个临时名字 。 这样, 用户既可以在建立状态
机的文件中使用状态机别名, 也可以在 MACHINE
INPUT端口引入状态机的文件中使用状态机别名,
然后就可以用这个别名代替原来的状态机的名字 。
状态机别名声明的语法格式如下
状态机别名, MACHINE;
2009-11-10 302
5.1.3 逻辑段( Logic Section)
在设计结构中, 逻辑段完成设计电路逻辑操作
和逻辑功能的描述, 是 TDF文件的主体, 是必需的段 。
在逻辑段里可以使用 Boolean Equations( 布尔等
式 ), Boolean Control Equations( 布尔控制等
式 ), Case Statement( 情况语句 ), Defaults
Statement ( 默认语句 ), if Then 语句, if
Generate语句, For Generate语句, Truth Table
Statement( 真值表语句 ) 和 Assert Statement
( 断言语句 ) 等各种语句和表达式来完成实际设计
电路的功能描述 。
逻辑段以 BEGIN关键字开始, 以 END和一个分
号结束, 逻辑段中的一条语句或表达式都以分号结
束 。
2009-11-10 303
【 例 5.1】 半加器的 AHDL描述 。
a,b是半加器输入信号, so,co是输出信号 。
用 AHDL语法规则推导出输出信号与输入信号之间的
逻辑表达式为
so = a $ b; --$ 是逻辑异或运算符
co = a & b; --&是逻辑与运算符
2009-11-10 304
半加器的 AHDL描述如下
SUBDESIGN h_adder --子设计段
( a,b,INPUT;
so,c,OUTPUT;)
BEGIN --逻辑段
so = a $ b;
co = a & b;
END;
2009-11-10 305
5.2 AHDL的基本元素
5.2.1 保留关键字和保留标识符
保 留 关 键 字 ( Reserved Keywords ) 是
AHDL预先定义的单词, 它们在程序中有不同的使
用目的, 在 AHDL语句的开始, 结尾和中间过程都
要用保留关键字, 并且为了预定义常数值 ( 如 GND
和 VCC) 也要用保留关键字 。
保留关键字同保留标识符有区别。当保留关键
字被括在单引号内时可以被当作符号名使用,而保
留标识符则不能。但是保留关键字和保留标识符都
能在注释中任意使用。
2009-11-10 306
5.2.2 空白符和注释
AHDL的空白符包括空格, tab符号, 换行和换
页 。 空白符用来分隔各种不同的词法符号, 合理地使
用空白符可以使源程序具有一定的可读性和编程风格 。
空白符如果不是出现在字符串中, 编译源程序时将被
忽略 。
注释分为行注释和块注释两种方式。行注释用
符号 --(两个减号)开始,注释到本行结束。块注释
用 %符号开始,也用 %符号结束。块注释可以跨越多
行,但它们不能嵌套。
2009-11-10 307
5.2.3 标识符
标识符是用户编程时为常量, 变量, 状态, 实例,
参数, 存储程序段, 端口, 节点, 组, 命名的运算
和子设计名等元素定义的名称 。 标识符可以是字母,
数字, 斜线, /‖和下划线, _‖等符号组成的任意序列 。
定义标识符时应遵循如下规则
① 首字符允许使用字母, 数字, 斜线, /‖和下
划线, _‖等符号 。 子设计名可以由全部数字组成,
如 74138,但其他标识符不能用全部数字组成 。
② 字符数不能多于 32个。
2009-11-10 308
③ 用于子设计名的标识符不能以斜线, /‖作为
首字符 。
④ 不要与保留关键字和保留标识符同名 。
标识符有带引号和不带引号两种标准 。 带引号
的标识符被包括引在单引号内;不带引号标识符不能
括在单引号内 。 带引号的标识符允许全部数字组成 。
例如, 合法的不带引号和带引号的符号名称如下
a / a1 74LS00 _table
?74138‘
2009-11-10 309
5.2.4 操作符
操作符也称为运算符, 是 AHDL预定义的函数
名字, 这些函数对被操作的对象 ( 即操作数 ) 进行规
定的运算, 得到一个结果 。 操作符通常由 1~ 2个字符
组成, 例如,, +‖表示加操作,, = =‖( 两个 =字符 )
表示数字或字符串相等操作 。 有些操作符的操作数只
有 1个, 称为一元操作;有些操作符的操作数有 2个,
称为二元操作;有些操作符的操作数有 3个, 称为三
元操作 。
AHDL的操作符分为符号操作符、算术操作符、
逻辑操作符、关系操作符和条件操作符等类型。
2009-11-10 310
1 1,符号操作符
符号操作符包括 +( 正号 ) 和 -( 负号 ) 两个 。 符号
操作符属于一元操作符, 用来改变常数和变量的符
号 。 例如,-5, -a
2,算术操作符
常用的算术操作符有,+( 加 ), -( 减 ), *
( 乘 ), DIV( 除 ), ^( 乘方 ), MOD( 求余 ),
LOG2( 以 2为底的对数 ) 。 除 LOG2属于一元操作
符以外, 算术操作符是二元操作符, 例如
2+3, a+b,15 MOD 3,LOG2( a)
2009-11-10 311
3,关系操作符
关系操作符用来对两个操作数进行比较 。 关系操作
符有,<( 小于 ), <=( 小于等于 ), >( 大于 ),
>=( 大于等于 ), =( 等于 ), !=( 不等于 ), = =
( 数字或字符串相等 )
4,逻辑操作符
逻辑操作符包括,&或 AND( 逻辑与 ), #或 OR( 逻
辑或 ), ! ( 逻辑非 ), $或 XOR( 异或 ), ! &或
NAND( 与非 ), !#或 NOR( 或非 ), !$或 NXOR
( 异或非 ) 。 除 ! ( 非 ) 属于一元操作符以外, 逻
辑操作符是二元操作符, 例如,a & b,!a
2009-11-10 312
5,条件操作符
条件操作符为,?
条件操作符的操作数有 3个, 其使用格式为
( 条件 )? 表达式 1:表达式 2;
即当条件为真时, 操作结果为表达式 1的值;为假时,
操作结果为 表达式 2的值 。 例如
( a<b)? a:b
在这个表达式中,如果( a<b)则表达式的值为 a;
为假时,表达式的值为 b。
2009-11-10 313
5.2.5 组
在布尔表达式和布尔等式中,相同类型的符号
名和端口名称可以当作组来声明和应用。一个组最
多可包括 256个成员(或位)。它可以当作许多节点
的集合,并且被当作一个整体来操作。在 TDF文件的
逻辑段或变量段中,组可由许多节点组成。在布尔
表达式和布尔等式中,一个节点和常量 GND和 VCC
可以被复制成一个组 。
2009-11-10 314
1,组的标记( Group Notations)
组能用单值域组名称, 双值域组名称和有序组名称三种
记法声明 。
( 1) 单值域组名称
一个单值域组名称由一个符号名称或端口名称后
跟一个括在方括号内的单值数域组成,例如 a[4..1]。符
号名和端口名加上在区域内最长的数字的总长度不能超
过 32位字符。一个组被定义之后,利用 [ ]指定输入范
围是一种速记方法。例如,a[4..1]也可以用 a[ ]表示。
也能把一个单个的数放在方括号内。例如 a[5]。但是,
这种标记符号是一种单个符号名称而不是一个组的名称,
并且与 a5的意义相同。
2009-11-10 315
( 2) 双值域组名称
双值域组名称由一个符号名或端口名后跟包括在方括
号中的两个值域组成, 例如 d[6..0][2..0]。 符号名或端
口名加上在每一个值域中最长的数值不能超过 32个字
符 。 在一个组已经被定义之后, 利用 [ ][ ]指定双值域
的速记方法 。 例如, b[6..][3..2]也能用 b[ ][ ]标记 。
在组内一个单独的节点能当作 name[Y][Z]或 name
Y_Z考虑,这里的 Y和 Z是组域内的 数值。
2009-11-10 316
( 3) 一个有序组名称
一个有顺序组的名称是由一组符号名, 端口名
或者数字组成, 它们之间用逗号分隔, 并且被包括在
圆括号中, 例如, (a,b,c)。 单值域和双值域组的
名称也可以被列人圆括号中 。 例如, ( a,b,c[5..1])
就是一个合法的组名 。 这种记法对于指定端口名是非
常有用的 。 例如, DFF类型的变量 reg,其输入和端
口能被写作 reg.(d,clk,clrn,prn)。
下面的例子给出相同组的不同记法的规定
b[5..0]
(b5,b4,b3,b2,b1,b0)
b[ ]
2009-11-10 317
2,组域和组的子域( Group ranges & sub ranges)
单值域或双值域的域组名称可由数字或算术表
达式组成, 在它们中间用二个断续点,,.‖ 隔开,
并且被包括在方括号内 。 例如
a[4..1] --表示一个具有成员 a4,a3,a2和 a1的
组 。
d[B‖10‖..B‖00‖] --表示一个具有成员 d2,d1和
d0的组 。
不管域的界限是一个数值还是一个算术表达式,
经过编译器后生成的界限均是一个十进制整数值。
2009-11-10 318
组的子域是指所定义的组中节点的子集, 并且
能采用不同的方法来表示 。 逗点在组内可以分隔子节
点, 也可以用来保留一个未分配组成员的位置 。 例如,
如果用户定义了组 c[5..1],那么就能采用下述的这些
组的子域
c[3..1],c[4..2],c4,c[5],(c2,,c4)。
在子域 (c2,,c4)里, 一个逗号被用来保留一
个未分配组成员 c3的位置 。
域一般按降序排列。为了按升序或是以升序和
降序混合排列,就必须用 Options语句指定 BIT0的位
置,否则就会在编译时产生警告信息。在二元域组名
中 BIT0的选择影响两个域。
2009-11-10 319
5.2.6 AHDL的数字
在 AHDL中能够按任意组合方式使用十进制, 二进制,
八进制和十六进制数字 。 除十进制数外, 其他数制的格式为
数制符号, 数值, 。
数制符号包括 B( 二进制数 ), O或 Q( 八进制数 ),
X或 H( 十六进制数 ) 。 二进制数的取值范围有 0,1,X( X
表示无关项或未知项 ) 和 Z( 高阻态 ) ;八进制数的取值范围
是 0~ 7;十六进制数的取值范围是 0~ 9,A~ F。 例如
1225 --十进制数
B‖1101XXXX‖ --二进制数
Q‖765‖ --八进制数
H‖FD6‖ --十六进制数
2009-11-10 320
5.2.7 表达式
表达式是用各种运算符连接起来的式子, 在
AHDL有算术表达式和布尔表达式两类 。
1,算术表达式
算术表达式是由算术运算操作符分隔的各种运
算组成的表达式, 用于定义语句中的计算函数, 常量
语句中的常量, 并且还能作为组域的域界 。 例如
CONSTANT po=6+45 DIV 3+LOG2( 256) ;
a[4..c-4];
2009-11-10 321
2,布尔表达式
由逻辑操作符, 算术运算符和比较符分隔的各
种运算组成布尔表达式 。 表达式用在布尔方程中以及
Case和 If Then等其他语句中 。 例如
(a>b) (!a & b)
( 1) 布尔等式 (Boolean Equations)
在 TDF文件的逻辑段内, 布尔等式用来表示节点连接,
输入和输出引脚, 原语, 强函数, 宏函数和状态机的
输人信号流和输出信号流 。
布尔等式的语法规则如下
标识符 = 表达式;
例如, a = c& b#e;
2009-11-10 322
(2) 布尔控制等式 (Boolean Control Equations)
布尔控制等式是在逻辑段建立状态机时钟 ( clk), 复
位 ( reset) 和时钟使能 ( ena) 信号采用的布尔等式 。 布尔
控制等式的法规则如下
状态机名,clk = 表达式;
状态机名,reset = 表达式;
状态机名,ena = 表达式;
例如, ss.clk = clk;, 表示状态机的时钟 clk与设计电
路的输入端 clk连接(即控制),而且是时钟的上升沿有效;
而, ss.clk = ! clk;, 表示状态机的时钟 clk受输入端 clk的
控制,下降沿有效。
2009-11-10 323
5.2.8 原语( Primitive)
原语是指 MAX+plusII为 ALTERA公司生产的可
编程逻辑器件提供的一套关于设计电路的原语函数 。
这些原语函数的图形文件 GDF( 即,gdf文件对应的元
件符号 ), 可以在 MAX+plusII的图形编辑软件中被
调出来使用, 其函数名也可以在 AHDL程序设计调用,
完成某个具体电路的功能 。
2009-11-10 324
AHDL中的原语包括缓冲器、触发器和锁存器
三种类型。缓冲器原语有 CARRY(进位缓冲器)、
CASCADE(级联缓冲器),EXP(扩展缓冲器)、
GLOBAL(全局缓冲器),LCELL(逻辑单元缓冲
器),OPNDRN(漏极开路缓冲器),SOFF(软
缓冲器)和 TRI(三态缓冲器。触发器原语有 DFF
( D触发器),DFFE(具有使能控制的 D触发器)、
TFF( T触发器),TFFE(具有使能控制的 T触发
器),JKFF( JK触发器),JKFFE(具有使能控
制的 JK触发器),SRFF( SR触发器)和 SRFFE
(具有使能控制的 SR触发器)。锁存器的原语是
LATCH。 AHDL原语定义的所有触发器都是在时钟
的上升沿触发的,而锁存器是电平触发的。
2009-11-10 325
全部原语只有一个输出端, 根据需要, 不同的
原语函数有不同的输入端 。 一般用函数原型来声明原
语的输入和输出端 。 例如, DFF原语的函数原型为
FUNCTION DFF( d,clk,clrn,prn)
RETURNS ( q) ;
该函数原型声明 D触发器的原语函数名是 DFF,
输入端有 d,clk,clrn,prn,输出端是 d。表 5.2列
出了触发器和锁存器的原语函数。
除三态缓冲器外,其他缓冲器都只有一个输入
端 in和一个输出端 out;三态缓冲器有两个输入端 in
和 oe,oe是三态控制输入端,当 oe为高电平时,三态
缓冲器工作,out=in;当 oe为低电平时,三态缓冲器
输出为高阻态。
2009-11-10 326
原语可以在变量段中被声明, 也可以作为函数在逻辑
段中被调用 。 原语函数调用的格式如下
变量名 = 原语函数名 ( 输入项表 ) ;
其中, 输入项表中的输入项由原语函数的输入组成,
输入项之间用逗号分隔, 不需要的原语输入项可以用
一个逗号省略 。 例如
dff_out = DFF( io,clk,,);
2009-11-10 327
【 例 5.3】 设计一个具有三态、双向(输入 /输出)端
口的 D触发器。
2009-11-10 328
用 AHDL描述的源程序如下
SUBDESIGN example_5_3
( clk,oe,INPUT;
io,BIDIR;)
VARIABLE
dff_out,node;
BEGIN
dff_out = DFF(io,clk,,);
io = TRI(dff_out,oe);
END;
2009-11-10 329
5.3 AHDL的语句
5.3.1 文本编辑语句
文本编辑语句包括 Title(标题)语句、
Include(包含)语句,Constant(常量)语句、
Define(定义)语句,Parameters(参数)语句、
Function Prototype(函数原型)语句,Options
(选择)语句,Assert(断言)语句
包括用于文本编辑的语句和用于电路设计的语句两类
2009-11-10 330
1,Title(标题)语句
标题语句允许用户为编译器产生报告文件
(,rpt) 提供文档注释 ( 文档的标题 ) 。 标题语句的
语法规则如下
TITLE―标题字符串, ;
例如
TITLE "__your_title";
注:一个 TDF文件内只能使用一次 标题语句,
而且 必须放在所有其他 AHDL段之外 。
2009-11-10 331
1,Include(包含)语句
包含语句允许用户将一个包含文件 (,inc) 引
入到当前文件输入文本, 包含文件可以由用户编写
的 TDF文件生成, 也可以直接引用 AHDL库中的强函
数或宏函数的包含文件 。 用包含语句引入包含文件
后, 该包含文件描述的函数就可以在逻辑段中使用,
完成电路设计 。 包含语句的语法规则如下
INCLUDE "包含文件名,inc";
例如
INCLUDE "__include_filename.inc";
2009-11-10 332
3,Constant(常量)语句
常量语句允许用户用一个有意义的符号名代替一
个数或一个算术表达式 。 这个符号名可 以简单地表示
被定义的那个数 。
常量语句的语法规则如下
CONSTANT 常量名 = 常量值 ;
例如
CDNSTANT UPPER_LIMIT=130;
CONSTANT BAR=I+2DIV3+LOG2(256);
2009-11-10 333
4,Define(定义)语句
定义语句允许用户定义一个运算函数, 这个
运算函数是根据选择的自变量产生一个值的数学函
数 。 定义语句的语法规则如下
DEFINE 计算函数名 (变量, 变量 ) = 表达式 ;
例如
DEFINE MAX(a,b) = (a>b)?a,b;
2009-11-10 334
5,Parameters(参数)语句
参数语句允许用户声明一个或多个参数, 这些
参数控制一个参数化的强函数或宏函数的执行 。 参
数语句的语法规则如下
PARAMETERS
( 参数名 1 = 参数默认值,
参数名 2,参数名 3) ;
例如:
PARAMETERS
( WIDTH,
AD_WIDITH = 8 );
2009-11-10 335
6,Function Prototype(函数原型)语句
函数原型语句分为参数化函数原型语句和非参数
化函数原型语句两种 。
参数化函数原型语句的语法规则如下
FUNCTION 函数名 (输入端口名, MACHINE 状
态机名 )
WITH (参数名, 参数名 )
RETURNS (输出端口名,双向端口名,
MACHINE 状态机名 );
2009-11-10 336
非参数化函数原型语句的语法规则如下
FUNCTION 函数名 (输入端口名, MACHINE 状态机
名 )
RETURNS ( 输出端口名, 双向端口名,
MACHINE 状态机名 );
例如,用函数原型语句调用例 5.3函数 example_5_3,
实现具有双向、三态输出的 8D触发器的 TDF源程序
bidir8_D.tdf如下
2009-11-10 337
FUNCTION example_5_3 (clk,oe) RETURNS (io);
SUBDESIGN bidir8_D
( clk,oe,INPUT;
io[7..0],BIDIR;)
BEGIN
io0 = example_5_3(clk,oe);
io1 = example_5_3(clk,oe);
io2 = example_5_3(clk,oe);
io3 = example_5_3(clk,oe);
io4 = example_5_3(clk,oe);
io5 = example_5_3(clk,oe);
io6 = example_5_3(clk,oe);
io7 = example_5_3(clk,oe);
END;
2009-11-10 338
7,Options(选择)语句
选择语句的作用是对 BIT0选项进行设置, 以指
定组的最低数字位是最高有效位 (MSB) 还是最低有效
位 (LSB)或其他位 。 选择语句的语法规则如下
OPTIONS BIT0 = 选择值 ;
其中, 选择值包括 ANY( 任意 ), LSB( 最低 )
和 MSB( 最高 ) 。 例如
OPTIONS BIT0 = MSB;
2009-11-10 339
8,Assert(断言)语句
断言语句在仿真器中使用, 用于在仿真, 调试
程序时的人机对话, 指出错误等级, 表征系统的状
态以及编译源程序时的提示 。 断言语句的语法规则
如下
ASSERT运算表达式
REPORT 报告字符串 报告参数,报告
参数
SEVERITY 等级度 ;
2009-11-10 340
ASSERT语句的功能是:当运算表达式的结果为真
时, 向下执行另一个语句;为假时, 则输出, 报告
字符串, 信息并指出, ( 错误 ) 等级度, 。 例如
ASSERT (S=‘1‘ AND R=‘1‘)
REPORT ‖Both values of S and R are
equal ‘1‘ ‖
SEVERITY ERROR;
语句中的错误等级包括,WARNING,ERROR和
INFO。
2009-11-10 341
5.3.2 程序设计语句
程序设计语句一般变量段和逻辑段中使用,
用来描述设计电路的功能。程序设计语包括 If
Then 语句,If Generate 语句,Case语句,For
Generate语句,Truth Table语句和 Defaults语句。
2009-11-10 342
1,Boolean Equation(布尔等式)
在 AHDL的逻辑段中, 布尔等式 ( Boolean
Equation) 完成对节点, 输入和输出引脚, 原语,
强函数, 宏函数的赋值操作 。 布尔等式的语句规则
如下
节点名 = 节点名 操作符 节点名;
例如
a = b AND C;
out[ ] = a[ ] XOR b[ ];
2009-11-10 343
2,if Then语句
在 If Then语句中可以有一个或多个布尔表达式 。
如果其中某表达式结果为真, 那么该表达式后面的行
为语句将被执行 。 完整的 If Then语句的语法规则如下
IF 表达式 THEN
语句;
语句;
ELSIF 表达式 THEN
语句;
语句;
ELSE
语句;
语句;
END IF;
2009-11-10 344
if语句和它的变化形式属于条件语句, 在程序
中用来改变控制流程 。
【 例 5.4】 8线 -3线优先编码器的设计 。
输入 输出
In0 in1 in2 in3 in4 in5 in6 in7 Out0 out1 out2
x x x x x x x 0
x x x x x x 0 1
x x x x x 0 1 1
x x x x 0 1 1 1
x x x 0 1 1 1 1
x x 0 1 1 1 1 1
x 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
1 1 1
0 1 1
1 0 1
0 0 1
1 1 0
0 1 0
1 0 0
0 0 0
2009-11-10 345
AHDL源代码如下
SUBDESIGN example_5_4
( in[7..0],INPUT;
out[2..0],output;)
BEGIN
IF in[7] THEN out=7;
ELSIF in[6] THEN out=6;
ELSIF in[5] THEN out=5;
ELSIF in[4] THEN out=4;
ELSIF in[3] THEN out=3;
ELSIF in[2] THEN out=2;
ELSIF in[1] THEN out=1;
ELSE out=0;
END IF;
END;
2009-11-10 346
3,If Generate 语句
If Generate 与 If Then都属于条件语句, 完成不同条件的控制
操作 。 If Generate 与 If Then语句不同之处在于 If Generate
语句可以在变量段和逻辑段中使用, 而 If Then语句只能在逻
辑段中使用 。
If Generate语句的语法规则如下
IF 条件表达式 EGENERAT
语句;
语句;
ELSE GENERATE
语句;
语句;
END RGENEATE;
2009-11-10 347
4,Case语句
Case语句列出了几种可能执行的操作, 至于执
行什么操作, 决定于跟在 Case关键字后面的变量,
组或表达式的值 。 情况语句的语法规则如下
CASE 表达式 IS
WHEN 常量值 => 选择语句;
选择语句;
WHEN常量值 => 选择语句;
选择语句;
WHEN OTHERS => 选择语句;
选择语句;
END CASE;
2009-11-10 348
【 例 5.5】 用 case语句描述 4选 1数据选择器。
4选 1数据
选择器
a
b
c
d
s1
s2
y
2009-11-10 349
4选 1数据选择器 AHDL描述如下
SUBDESIGN example_5_5
( a,b,c,d,INPUT;
s1,s2,INPUT;
y,OUTPUT;)
VARIABLE
ss[1..0],NODE;
BEGIN
ss[1]=s1;
ss[0]=s2;
2009-11-10 350
CASE ss[] IS
WHEN 0 => y=a;
WHEN 1 => y=b;
WHEN 2 => y=c;
WHEN 3 => y=d;
WHEN OTHERS => y=x;
END CASE;
END;
2009-11-10 351
5,For Generate语句
AHDL的 For Generate语句程序设计中的循环
操作 。 For Generate语句的语法规则如下
FOR 指针变量 IN初置 TO 终值 GENERATE
逻辑语句;
逻辑语句;
END GENERATE;
2009-11-10 352
【 例 5.6】 8位加法器的设计 。
SUBDESIGN example_5_6
( a[7..0],b[7..0],cin,INPUT;
c[7..0],cout,OUTPUT;)
VARIABLE
carryout[8..0], NODE;
BEGIN
carryout[0]=cin;
FOR i IN 0 TO 7 GENERATE
c[i] = a[i]$b[i]$carryout[i];
carryout[i+1]=a[i]&b[i]#carryout[i]&(a[i]$b[i]);
END GENERATE;
cout = carryout[8];
END;
2009-11-10 353
6,Truth Table语句
真值表语句的语法规则如下
TABLE
输入节点名,输入节点名 => 输出节点名,输出节点名;
输入值,输入值 => 输出值,输出值;
输入值,输入值 => 输出值,输出值;
输入值,输入值 => 输出值,输出值;
ND TABLE;
2009-11-10 354
【 例 5.7】 用 Truth Table语句设计 SR触发器 。
SUBDESIGN example_5_7
( s,r,INPUT;
q,nq,OUTPUT;)
BEGIN
TABLE
s,r,q => q,nq;
0,0,0 => 0,1;
0,0,1 => 1,0;
0,1,0 => 0,1;
0,1,1 => 0,1;
1,0,0 => 1,0;
1,0,1 => 1,0;
1,1,0 => x,x;
1,1,1 => x,x;
END TABLE;
END;
2009-11-10 355
7,Defaults语句
在 AHDL中, Defaults( 默认 ) 语句用来为变量指定默认值 。
由于高电平有效的信号总是被自动地默认为 GND( 即低电
平 ), 所以只对低电平有效的信号才需要默认语句 。 默认语句
的语法规则如下
DEFAULTS
节点名 = 常量值;
END DEFAULTS;
例如
DEFAULTS
a = VCC;
END DEFAULTS;
2009-11-10 356
8,In-Line Logic Function Reference(内部逻辑函数
直接引用)
内部逻辑函数直接引用使用在逻辑段中, 利
用 —个布尔等式调用 AHDL的内部逻辑函数, 来实现
某种逻辑功, 使用时不需要作变量声明 。
逻辑函数内部直接引用由三种语法规则 。
语法规则一:
(节点名, 节点名 ) = 函数名 (节点名, 节点名 );
节点名 = 参数名 (节点名,节点名 );
2009-11-10 357
语法规则二:
(节点名, 节点名 ) = 函数名 (节点名, 节点名 )
WITH (参数名 = 参数植;
参数名 = 参数值 );
语法规则三:
(节点名, 节点名 ) = 函数名
(端口名 = 节点名, 端口名 = 节点名 )
RETURNS (.端口名,,端口名 );
节点名 = 参数名
(.端口名 = 节点名,.端口名 = 节点名 );
2009-11-10 358
例如, 已知 bus_reg2是一个已经设计好的双向, 三态输出总
线寄存器的 TDF文件名 ( 也是函数名 ), clk和 oe是函数的输
入, io是函数的输出 ( 双向, 三态 ), 利用 bus_reg2函数以
及使用内部逻辑函数直接引用语句, 可以实现的 4位双向, 三
态输出总线寄存器 。 TDF文件如下:
FUNCTION bus_reg2 (clk,oe) RETURNS (io);
SUBDESIGN bidir1
( clk,oe,INPUT;
io[3..0],BIDIR; )
BEGIN
io0 = bus_reg2(clk,oe);
io1 = bus_reg2(clk,oe);
io2 = bus_reg2(clk,oe);
io3 = bus_reg2(clk,oe);
END;
2009-11-10 359
5.4 AHDL的使用
一个完整的 AHDL设计结构含程序头部, 子设
计段, 变量段和逻辑段 4个组成部分 。
程序头部分由 Title( 标题 ) 语句, Include( 包
含 ) 语句, Constant( 常量 ) 语句, Define( 定义 )
语句, Parameters ( 参数 ) 语句, Function
Prototype( 函数原型 ) 语句, Options( 选择 ) 语
句和 Assert( 断言 ) 语句组成, 这些语句都是可选项,
如果要使用它们, 必须放在子设计段前部 。
2009-11-10 360
设计结构的第 2部分是子设计段, 这是 TDF文件
不可缺少的部分 。 子设计段用于定义设计电路的输入,
输出和双向端口 。
设计结构的第 3部分是变量段,变量段包括 If
Generate(条件)语句,Node(节点)声明、
Instance(包含)声明,Register(寄存器)声明、
State Machine(状态机)声明,Machine Alias(状
态机别名)声明和 Assert(断言)语句,这些语句或
声明是可选项。
2009-11-10 361
设计结构的第 4部分是逻辑段,也是 TDF文件不
可缺少的部分。逻辑段包括 Defaults(默认)语句、
Boolean Equation(布尔表达式),Case 语句、
For Generate语句,If Generate语句,If Then语句、
In-Line Logic Function Reference语句,Truth
Table语句和 Assert(断言)语句。
默认语句是可选项,当一个逻辑段中包含默认
语句时,必须把它放在段的最前部,其他语句出现的
顺序可以自由选择。
2009-11-10 362
5.4.1 Include(包含)语句的使用
AHDL为数字系统提供了丰富的设计资源,包
括门电路、触发器、组合逻辑部件、时序逻辑部件以
及存储器和微处理器等基本器件。这些设计资源以原
语、函数和图形的形式存放在 MAX+plusII元件库中,
设计者可以采用不同的方法将它们调出来,供系统设
计使用。使用包含语句就是其中的一种 TDF文本设计
调用的方法。
2009-11-10 363
【 例 5.8】 用包含语句将 4位计数器, 4counter‖与 4
线 -16线译码器, 16dmux‖连接,构成带译码器的计
数器电路。
4counter( 4位二进制加法计数器) 和 16dmux
( 4线 -16线译码器)都是 AHDL的宏函数,它们的元
件符号分别如图所示。
2009-11-10 364
这些元件符号可以用图形编辑方式调出,通过连线将
它们组成带译码器的计数器电路;也可以用包含语句将它们
调出来,以 TDF文本方式形成设计电路。
2009-11-10 365
带译码器的计数器电路的 TDF源程序如下
INCLUDE "4count"; --4count包含文件的引用
INCLUDE "16dmux";--16dmux包含文件的引用
SUBDESIGN example_5_8
( a,b,c,d:INPUT; --设计电路的输入端口
clk,ldn,cin,dnup,setn,clrn:INPUT;
out[15..0]:OUTPUT;) --设计电路的输出端口
VARIABLE
counter:4count; --4count的实例声明
decoder:16dmux; --16dmux的实例声明
2009-11-10 366
BEGIN
counter.(d,c,b,a)=(d,c,b,a);
--设计电路输入端口与 4count输入连接
counter.clk=clk;
counter.dnup=dnup;
counter.clk=ldn;
counter.clk=setn;
counter.clk=clrn;
decoder.(d,c,b,a)= counter.(qd,qc,qb,qa);
--4count输出与 16dmux输入的连接
OUT[15..0] = DECODER.q[15..0];
--16dmux输出与设计电路输出端口连接
END;
2009-11-10 367
5.4.2 Constant(常量)语句的使用
常量语句允许用户用一个有意义的符号名代替
一个数或一个算术表达式。在电路设计的 TDF文件中,
常量一般被用来代替总线的位宽和组的域宽,为以后
同类型电路的设计带来方便。例如,对于例 5.6设计
的 8位加法器的 TDF文件,用一个常量
WIDTH_OF_BIT代替文中的常数 8,则可以利用这个
文件设计 16位或其他位宽的加法器,设计时只需要修
改常量定义语句即可。
2009-11-10 368
5.4.3 Function Prototype(函数原型)语句的
使用
在 AHDL中没有函数语句,实际上每一个 TDF
文件都可以作为一个函数,供其他 TDF文件来调用。
需要调用的函数必须在子设计段的前部用函数原型语
句声明,然后才能在逻辑段中用内部逻辑函数直接引
用语句来使用这个函数。
2009-11-10 369
【 例 5.9】 设计一个 D触发器, 以 mydff1.tdf作为 TDF
文件名, 然后使用 mydff1函数原型语句设计一个 8D
触发器的 TDF文件, 并命名为 mydff8.tdf。
D触发器的 TDF文件 mydff1.tdf设计如下
SUBDESIGN mydff1
( clk,reset,ena,d,INPUT;
q,output;)
VARIABLE
ss, MACHINE WITH STATES(s0,s1);
2009-11-10 370
BEGIN
ss.clk=clk;
ss.reset=reset;
ss.ena=ena;
CASE ss IS
WHEN s0 =>q = GND;
IF (d) THEN ss = s1;
END IF;
END CASE;
CASE ss IS
WHEN s1 =>
q = VCC;
IF (!d) THEN ss = s0;
END IF;
END CASE;
END;
2009-11-10 371
8D触发器的 TDF文件 mydff8.tdf如下
CONSTANT WIDTH_OF_BIT = 8;
FUNCTION mydff1 (clk,reset,ena,d) RETURNS (q);
-- mydff1函数原形
SUBDESIGN MYDFF8
( clk,reset,ena,d[WIDTH_OF_BIT-1..0],INPUT;
q[WIDTH_OF_BIT-1..0],output;)
BEGIN
FOR i IN 0 TO WIDTH_OF_BIT-1 GENERATE
q[i] = mydff1 (clk,reset,ena,d[i]);
END GENERATE;
END;
2009-11-10 372
8D触发器的元件符号
8D触发器的仿真波形
2009-11-10 373
5.4.4 Register( 寄存器 ) 声明的使用
为了方便电路设计,AHDL预先把常用的触发
器(即 DFF,DFFE,TFF,TFFE,JKFF,JKFFE、
SRFF和 SRFFE)和锁存器( LATCH)设计好,并
产生各种设计文件,包括文本文件(,tdf)、图形文
件(,gdf)、包含文件(,inc)以及函数原语,这些
文件可以通过不同的方式调用触发器和锁存器的设
计结果。在 AHDL的 TDF设计文本中,也可以通过寄
存器变量声明,然后在逻辑段中使用这些器件,完
成电路设计。
2009-11-10 374
【 例 5.10】 用 DFF寄存器变量声明方式,实现 4位右
移位寄存器的设计。
4位右移位寄存器的电路结构图
2009-11-10 375
TDF设计文件如下:
SUBDESIGN myshift_4
( clk,prn,clrn,din,INPUT;
dout,output;)
VARIABLE
ff[3..0], dff;
BEGIN
ff[].clk=clk;
ff[].prn=prn;
ff[].clrn=clrn;
ff[0].d=din;
ff[1].d=ff[0].q;
ff[2].d=ff[1].q;
ff[3].d=ff[2].q;
dout=ff[3].q;
END;
2009-11-10 376
5.4.5 State Machine(状态机)声明的使用
AHDL的状态机一般用来实现时序逻辑电路的
描述,反映触发器、计数器、状态机的状态位数和状
态。状态机( State Machine)实际也是 AHDL中预
先设计好的函数,它有一个时钟输入端 clk、一个使
能控制端 ena、一个复位输入端 reset以及由参数定义
的状态位和状态。在 AHDL的 TDF文件中,可以通过
状态机声明来完成时序逻辑电路的设计。
2009-11-10 377
【 例 5.11】 用状态机声明方式实现十进制加法计数器
的设计。
计数器的状态转换图
S0 S1 S2 S3 S4
S5S6S7S8S9
/1
/0 /0 /0 /0
/0 /0 /0 /0
/0
2009-11-10 378
十进制加法计数器的 AHDL的 TDF源程序如下:
SUBDESIGN cnt4e
( clk,reset,ena,INPUT;
q[3..0],cout,output;)
VARIABLE
ss, MACHINE
OF BITS(q[3..0])
WITH STATES(s0=0,s1=1,s2=2,s3=3,
s4=4,s5=5,s6=6,s7=7,s8=8,s9=9);
BEGIN
ss.clk=clk;
ss.reset=reset;
ss.ena=ena;
q[]=ss.q[];
2009-11-10 379
TABLE
ss => ss,cout;
s0 => s1,0;
s1 => s2,0;
s2 => s3,0;
s3 => s4,0;
s4 => s5,0;
s5 => s6,0;
s6 => s7,0;
s7 => s8,0;
s8 => s9,0;
s9 => s0,1;
END TABLE;
END;
2009-11-10 380
十进制加法计数器的仿真波形图
2009-11-10 381
5.5 AHDL设计流程
AHDL设计流程与第 3章叙述的 VHDL设计流程基
本相同,这里不再重复。
2009-11-10 382
第 6章 常用 EDA工具软件
?本章概要:本章介绍几种目前世界上最流行和实用的 EDA工
具软件, 包括 Altera公司的 Quartus II,Mentor Graphics的
子公司 Model Technology的 ModelSim和 Cadence公司的
NCLaunch,以适应不同读者的需要 。 这些软件主要是基于
PC机平台的, 面向 FPGA和 CPLD或 ASIC设计, 比较适合学
校教学, 项目开发和相关的科研 。
?知识要点:
( 1) Quartus II工具软件的使用方法 。
( 2) ModelSim工具软件的使用方法 。
( 3) NCLaunch工具软件的使用方法。
2009-11-10 383
6.1 Quartus II
Quartus II是 Altera公司近几年推出的新一代,
功能强大的可编程逻辑器件设计环境 。 Quartus II支
持 Altera公司最新器件, 如 ACEX 1K,APEX 20K、
APEX 20KC,APEX 20KE,APEX II,ARM-based
Excalibur,FLEX 6000,FLEX 10KE,MAX 3000A、
MAX 7000AE,MAX 7000B,Mercury和 Stratix器
件 。
Quartus II支持多种编辑输入法,包括图形编辑
输入法,VHDL,Verilog HDL和 AHDL的文本编辑输
入法,符号编辑输入法,以及内存编辑输入法。
2009-11-10 384
6.1.1 Quartus II的图形编辑输入法
在 Quartus II平台上,使用图形编辑输入法设计
电路的操作流程包括编辑、编译、仿真和编程下载等
基本过程。用 Quartus II图形编辑方式生成的图形文
件的扩展名为,gdf或,bdf。为了方便电路设计,设计
者首先应当在计算机中建立自己的工程目录,例如用
\myeda\mybdf\文件夹存放设计,bdf文件,用
\myeda\myvhdl\文件夹存放设计,vhd文件等。
2009-11-10 385
1,编辑设计文件
Quartus II主窗口界面










































































仿








2009-11-10 386
填入项目所在的
文件夹名
填入顶层项目名
填入底层项目名
建立新的项目对话框
(1)建立设计项目( Project)。 执行, File‖?―New
Project Wizard‖命令,
2009-11-10 387
(2)进入图形编辑方式。 执行, File‖?―New‖命令,选择
,Block Diagram/Schematic File ‖ (模块 /原理图文件)方
式。
编辑文件类型对话框
2009-11-10 388
( 3)选择元件。 在原理图编辑窗中的任何一个位置
上双击鼠标的左键将跳出一个元件选择窗。
图 2.6 半加器逻辑图
=
1
&
SO
CO
A
B
基本逻辑元件库
参数可设置的强函数元件库
基本逻辑元件库中的元件
由此输入所需要的元件名
MAX+plus库
2009-11-10 389
一位全加器的图形编辑文件
( 4)编辑图形文件
2009-11-10 390
2,编译设计文件
在编译设计文件前,应先选择下载的目标芯片,
否则系统将以默认的目标芯片为基础完成设计文件
的编译。在 Quartus II集成环境下,执行
,Assignments‖菜单下的, Device‖命令,在弹出
器件选择对话框的, Family:, 栏目中选择目标芯
片系列名,如, FLEX10K‖,然后在, Available
devices:‖栏目中用鼠标点黑选择的目标芯片型号,
如, EPF10KLC84-4‖,选择结束按, OK‖键。
执行, Pricessing‖→ ―Start Compilation‖命
令,或者按, 开始编译, 按键,即可进行编译,编
译过程中的相关信息将在, 消息窗口, 中出现。
2009-11-10 391
目标芯片选择对话框
2009-11-10 392
3,仿真设计文件
仿真一般需要经过建立波形文件、输入信号节
点、设置波形参量、编辑输入信号、波形文件存
盘、运行仿真器和分析仿真波形等过程。
( 1)建立波形文件
执行, File‖?―New‖命令,在弹出编辑文件类型
对话框,选择, Other Files‖中的, Vector
Waveform File ‖方式 K‖,或者直接按主窗口上
的, 创建新的波形文件, 按键,
2009-11-10 393
波形文件编辑界面
2009-11-10 394
( 2) 输入信号节点
在波形编辑方式下,执行, Edit‖的, Insert Node or
Bus…‖ 命令,或在波形文件编辑窗口的, Name‖栏中点鼠标
右键,在弹出的菜单中选择, Insert Node or Bus…‖ 命令,
即可弹出插入节点或总线( Insert Node or Bus… )对话框。
插入信号节点对话框
2009-11-10 395
节点发现者对话框
2009-11-10 396
( 3) 设置波形参量
Quartus II默认的仿真时间域是 100ns,如果需要更长
时间观察仿真结果,可执行, Edit‖命令菜单中的, End
Time…‖ 选项,在弹出的, End Time‖选择窗中,选择适当的
仿真时间域。
设置仿真时间域对话框
2009-11-10 397
( 4) 编辑输入信号
为输入信号 a,b和 cin编辑测试电平的方法及相
关操作域 MAX+plusII基本相同 。
( 5) 波形文件存盘
执行, File‖选项的, Save‖命令,在弹出的
,Save as‖对话框中直接按, OK‖键即可完成波形
文件的存盘。在波形文件存盘操中,系统自动将波形
文件名设置设计文件名同名,但文件类型是,vwf。例
如,全加器设计电路的波形文件名为
,adder_1.vwf‖。
2009-11-10 398
( 6) 运行仿真器
执行, Processing‖中的, Start Simulation‖
命令,或点击, Start Simulation‖按键,即可对全
加器设计电路进行仿真。
全加器的仿真波形
2009-11-10 399
4,编程下载设计文件
编程下载设计文件包括引脚锁定和编程下载两
个部分 。
( 1) 引脚锁定
在目标芯片引脚锁定前,需要确定使用的 EDA
硬件开发平台及相应的工作模式。然后确定了设计
电路的输入和输出端与目标芯片引脚的连接关系,
再进行引脚锁定。(此项操作可参考第 2章中的相关
叙述。)
2009-11-10 400
① 执行, Assignments‖项中的赋值编辑, Assignments
Editor‖命令或者直接按, Assignments Editor‖按键,在弹
出的赋值编辑对话框的, Category‖栏目选择, Pin‖项。
赋值编辑对话框
2009-11-10 401
② 用鼠标双击, Name‖栏目下的 <<new>>,在其
下拉菜单中列出了设计电路的全部输入和输出端口
名, 例如全加器的 a,b,cin,cout和 sum端口等 。
用鼠标选择其中的一个端口后, 再用鼠标双击
,Location‖栏目下的 <<new>>,在其下拉菜单中
列出了目标芯片全部可使用的 I/O端口, 然后用鼠标
选择其中的一个 I/O端口 。 例如, 全加器的 a,b、
cin,cout和 sum端口, 分别选择 Pin_23, Pin_22、
Pin_21,Pin_37和 Pin_36。 赋值编辑操作结束后,
存盘并关闭此窗口, 完成引脚锁定 。
③ 锁定引脚后还需要对设计文件重新编译,产生设
计电路的下载文件(,sof)。
2009-11-10 402
( 2) 编程下载设计文件
在编程下载设计文件之前, 需要将硬件测试系统 ( 如
GW48实验系统 ), 通过计算机的并行打印机接口与计算机连
接好, 打开电源 。
首先设定编程方式。选择, Tools‖的编程器
,Programmer‖命令或者直接按, Programmer‖键,弹出置
编程方式窗口。用鼠标点击下载方式窗口左边的, Add File‖
(添加文件)按键,在弹出的, Select Programming File‖
(选择编程文件)的对话框中,选择全加器设计工程目录下的
下载文件, Adder_1.sof‖。
2009-11-10 403
开始编程按键
添加文件按键
选择器件按键
设置编程方式窗口
2009-11-10 404
( 1)选择下载文件
用鼠标点击下载方式窗口左边的, Add File‖(添加文
件)按键,在弹出的, Select Programming File‖(选择编
程文件)的对话框中,选择全加器设计工程目录下的下载文
件, Adder_1.sof‖。
选择下载文件对话框
2009-11-10 405
( 2)设置硬件
用鼠标点击,Hardware… ‖(硬件设置)按键,在弹出
的,Hardware Setup‖硬件设置对话框中按下,Add
Hardware‖按键,在弹出的添加硬件对话框中选择
ByteBlasterMV编程方式后按,OK‖键 。
硬件设置对话框
2009-11-10 406
添加硬件对话框
( 3)编程下载
执行, Processing‖的, Stare
Programming‖命令或者直接按, Start
Programming‖按键,即可实现设计电路到目标芯
片的编程下载。
2009-11-10 407
6.1.2 Quartus II的文本编辑输入法
Quartus II的文本编辑输入法与图形输入法的设计步
骤基本相同 。 在设计电路时, 首先要建立设计项目,
然后在 Quartus II集成环境下, 执行, File‖?―New‖
命令, 在 弹 出 的 编 辑 文 件 类 型 对 话 框, 选择
,VHDL File‖或, Verilog HDL File‖,或者直接按
主窗口上的, 创建新的文本文件, 按键, 进入
Quartus II文本编辑方式,
在文本编辑窗口中,完成 VHDL或 Verilog HDL
设计文件的编辑,然后再对设计文件进行编译、仿
真和下载操作。
2009-11-10 408
文本编辑窗口
2009-11-10 409
6.2 ModelSim
ModelSim是一种快速而又方便的 HDL编译型仿真工具,
支持 VHDL和 Verilog HDL的编辑, 编译和仿真 。
ModelSim有一系列产品,它们可以在 Unix平台和
Windows平台上工作,目前主要分为 MoelSim/VHDL(或
ModelSim/Verilog-OEM),MoelSim/LNL (支持 VHDL或
Verilog的版本,但不同时支持 VHDL和 Verilog)、
ModelSim/PLUS(支持 VHDL和 Verilog的版本,包括混合仿
真)和 ModelSim/SE(主要版本,功能比 ModelSim/Plus更
强大)等不同版本。
2009-11-10 410
6.2.1 ModelSim的安装
ModelSim的安装分为软件安装和许可文件安装两个过
程。
1,ModelSim软件安装
插入 ModelSim光盘后,执行, setup‖安装命令,根据屏
幕提示完成 ModelSim的安装。安装结束后,将 License.dat拷
贝到 Modeltech_5.6安装目录下,并将附在光盘上的
lmgr326b.dll文件拷贝到 \ Modeltech_5.6\WIN32\ 目录下替
换原文件,重新启动计算机。
2009-11-10 411
2,ModelSim许可文件安装
计算机的, 开始, 菜单的, 程序, 选项中, 选择, ModelSim
XE II Eval 5.6e‖中的, Licening Wizard‖命令, 在弹出的许可文件安装
的对话框中点击, Continue‖按钮, 然后在弹出许可文件位置 ( License
File Location) 对话框中输入, C:\Modeltech_xe\license.dat‖许可文
件后按, OK‖。
许可文件安装对话框
2009-11-10 412
6.2.2 ModelSim的使用方法
ModelSim是 Unix下的 QuickHDL发展来,
Windows版本的 ModelSim保留了部分 Unix风格,
可以使用键盘完成所有操作,但也提供了用户图形界
面接口。 ModelSim有交互命令方式(即在
ModelSim的主窗口通过输入命令实现编辑、编译和
仿真操作)、图形用户交互方式(即通过菜单进行交
互)和批处理方式(类似 DOS批处理或 Unix的 shell
工作方式)等三种执行方式。
2009-11-10 413
ModelSim启动后,首先呈现出的主窗口( Main
Windows)界面,主窗口中包括命令窗口( Transcript)、
工作区( Workspace)和工具栏。在命令窗口中可以输入
ModeSim的命令,并获得执行信息;在工作区中用树状列表
( Tree List)的形式来观察库( Library)、项目源文件
( Project)和设计仿真的结构。
ModeSim的主窗口界面
工作区 命令窗口
工具栏
2009-11-10 414
在使用 ModelSim之前,应事先建立用户自己的工程文
件夹,用于存放各种设计文件和仿真文件,然后还要建立
work库。在 VHDL中 work是默认的工作库,因此 ModelSim中
必须首先建立一个 work库。
建立新项目对话框
2009-11-10 415
1,ModelSim编辑方法
在 ModelSim的主窗口界面,执行
,File‖→ ―New‖→ ―Source‖→ ―VHDL‖命令,进入 ModelSim
的 VHDL(或 Verilog HDL)编辑方式。在 ModelSim的编辑方
式( source)界面输入十进制加法计数器的 VHDL源程序,并
用 cnt4m.vhd为文件名,存入用户自己的工程文件夹中。
进入 ModelSim编辑方式的界面
2009-11-10 416
ModelSim编辑方式的界面
2009-11-10 417
2,ModelSim编译方法
完成源程序的编辑后,在 ModelSim编辑方式窗口执行
,Tools‖→ ―Compile‖命令,在弹出的编译 HDL源文件
( Compile HDL Source File)对话框中,按, Compile‖按
钮,即可对源程序进行编译,编译成功后,cnt10m的设计实
体就会出现在 work库中。
ModelSim的编译方式界面
2009-11-10 418
3,ModelSim仿真方法
ModelSim仿真包括装载设计文件, 设置激励信号和仿真等操
作过程 。
( 1) 装载设计文件
执行, Simulate‖→ ―Simulate…‖ 命令,在弹出的仿真
文件装载对话框中,用鼠标将 work库中的 cnt10m点黑选中,
然后按, Add‖键,再按, Load‖键,即可完成设计文件的装
载,此时工作区会出现, Sim‖标签,表示装载成功。
2009-11-10 419
设计文件装载对话框
2009-11-10 420
( 2) 设置仿真激励信号
执行, View‖→ ―Signals‖命令,打开信号( Signals)
窗口,经过装载的十进制加法计数器设计电路的复位输入端
clr、时钟输入端 clk和输出端 cnt已在窗口内。
ModelSim的信号窗口
2009-11-10 421
将 ModelSim信号( Signal)窗口中的复位输入信号 clr
用鼠标点亮选中后,执行, Edit‖→ ―force…‖ 命令,在弹出的
被选信号激励( Force Selected Signal)对话框中将
,Value:‖中的数值改写为 1,则为 clr当前赋 1值。另外,
,Delay For:‖中的值是信号赋值前的延迟时间,,Cancei
After:‖中的值是仿真取消后的值,这两个参数一般可以不填。
被选激励信号的值确定后,按, OK‖键结束 Force赋值操作。
为 clr赋值的对话框
2009-11-10 422
将 ModelSim的 Signal窗口中的时钟输入信号 clk用鼠标点亮选中
后,执行, Edit‖→ ―Clock…‖ 命令,在弹出的定义时钟( Define Clock)
对话框中,时钟信号的主要参数基本设置好,其中, Period‖参数是时钟
的周期,已经预先设置为 100标准单位;, Duty‖参数是时钟波形的高电
平持续时间,已经预先设置为 50个标准单位,表示预先设置的 Clock的占
空比为 50%,即方波。另外,,offset‖参数是补偿时间,,Cancel‖参数
是取消时间。 Clock设置完毕后按, OK‖键确定。
定义时钟对话框
2009-11-10 423
当全部激励信号设置完毕后,将 ModelSim的 Signal
窗口中全部端口信号用鼠标点亮选中,然后执行
,Add‖→ ―Wave‖→ ―Selected Signals‖命令,即可将选中
的端口信号加入到 ModelSim的波形( Wave)窗口中。
选择端口信号操作示意图
2009-11-10 424
( 3) 仿真设计文件
执行, View‖→ ―Signals‖命令,打开波形( Wave)窗
口。在 Wave窗口的工具栏中,各主要按键的功能如图所示。























2x


2x
波形窗口
2009-11-10 425
按动 ModelSim的波形窗口上的, 运行, 按键,仿真波
形将按照按一次键输出一个时钟周期的方式对设计电路进行
仿真。在仿真期间,可以用 ModelSim的 Signal窗口,改变复
位信号 clr的值,来验证复位信号的功能。
十进制加法计数器 cnt10m的仿真波形
2009-11-10 426
6.2.3 ModelSim与 MAX+plusII的接口
ModelSim是一种快速仿真工具,但对设计文
件的输入编辑与编译不如 MAX+plusII那样方便快捷。
因此,在 EDA设计过程中,设计者常用 MAX+plusII
来完成 HDL设计文件的输入编辑与编译,再用
ModelSim对设计文件进行仿真。由于 ModelSim是
编译型仿真器,使用编译后的 HDL库进行仿真,因
此在进行仿真前,必须编译所以待仿真的 HDL文件
成为仿真库,在编译时获得优化,提高仿真速度。
2009-11-10 427
编译时执行,Compile‖→― Compile… ‖命令,在弹出
的在弹出的,Compile HDL Source File‖对话框的“查找范
围:”栏目输入或选择 MAX+plusII设计文件夹,则该文件中
的 HDL源文件将全部出现在对话框中,然后用鼠标将选中的
源文件点黑选中,或者直接把选中的源文件名输入“文件名”
栏目中,按,Compile‖按钮,即可对源程序进行编译。编译
成功后,选中源文件的设计实体就会出现在 work库中。
ModelSim的编译方式界面
2009-11-10 428
ModelSim仿真属于功能仿真, 输出波形没有延迟 。
为了对设计文件进行门级时序仿真, 必须用 MAX+plusII对
设计文件进行综合和适配, 再把适配后的网表文件导入到
ModelSim仿真环境中进行门级时序仿真 。
MAX+plusII支持多种 VHDL和 Verilog HDL网表格式,
不同的网表格式 ModelSim仿真处理不同,因此在
MAX+plusII中还必须进行设置。在 MAX+plusII对设计文件
进行编译时,可以执行, Interface‖→ ―VHDL Netlist
Writer Settings…‖ 命令,对 VHDL的网表格式进行设置;执
行, Interface‖→ ―Verilog Netlist Writer Settings…‖ 命令,
对 Verilog HDL的网表格式进行设置。在 MAX+plusII中已将
VHDL的网表格式默认设置为, VHDL Output File[.vho]‖文
件,将 Verilog HDL的网表格式默认设置为, Verilog
Output File[.vo]‖文件。
2009-11-10 429
在对 VHDL或 Verilog HDL设计文件进行编译前,打开
MAX+plusII 的, Interface‖界面,将, VHDL Netlist Writer‖
和, Verilog Netlist Writer‖选项前加上, √,,如图所示,
则在对设计文件进行编译后,生成 VHDL网表文件,vho,或者
Verilog HDL的网表文件,vo。
在 MAX+plus中进行设置的示意图
2009-11-10 430
6.2.4 ModelSim交互命令方式仿真
ModelSim交互命令方式, 是在 ModelSim的
主窗口的命令窗口上, 通过输入命令来实现的, 具
有更好的调试和交互功能 。 ModelSim提供了多种指
令, 既可以单步, 也可以构成批处理文件, 用来控
制编辑, 编译和仿真流程 。
ModelSim用于仿真的主要指令包括 Run、
Force,View等指令,其他指令可参考 ModelSim说
明书或帮助。
2009-11-10 431
1,Run指令
指令格式,Run [<timesteps>][<time_unit>]
其中, 参数 timesteps( 时间步长 ) 和 time_unit( 时间单位 )
是可选项, time_unit可以是 fs( 10- 15秒 ), ps( 10- 12秒 )
ns( 10- 9秒 ) ms( 10- 6秒 ), sec( 秒 ) 这几种 。
指令功能:运行 ( 仿真 ) 并指定时间及单元 。
例如,,run‖表示运行;, run 1000‖表示运行 1000个默认
的时间单元( ps);, run 2500 ns‖表示运行 2500ns;
,run –continue‖表示继续运行;, run –all‖表示运行全程。
2009-11-10 432
2,force指令
指令格式,force <item_name> <value>
[<time>],[<value>] [<time>]
其中, 参数 item_name 不能缺省, 它可以是端口信号, 也可
以是内部信号, 且还支持通配符号, 但只能匹配一个; value
也不能缺省, 其类型必须与 item_name 一致; time是可选项,
支持时间单元 。
例如,,force clr 1‖表示为 clr赋值 1;, force clr 1 100‖表
示经历 100个默认时间单元延迟后为 clr赋值 1;, force clr
1,0 1000‖表示为 clr赋值 1后经历 1000默认时间单元延迟后为
clr赋值 0。
2009-11-10 433
3,force –repeat指令
指令格式,force <开始时间 > <开始电平值 >,<结束电平值 >
<忽略时间 >–repeat <周期 >
指令功能:每隔一定的周期 ( period) 重复一定的 force命令 。
该指令常用来产生时钟信号 。
例如,,force clk 0 0,1 30 -repeat 100‖表示强制 clk从 0时
间单元开始,起始电平为 0,结束电平为 1,忽略时间(即 0电
平保持时间)为 30个默认时间单元,周期为 100个默认时间
单元,占空比为( 100-30) /100=70%。
2009-11-10 434
4,force –cancel指令
指令格式,force–cancel < period>
指令功能:执行 period周期时间后取消 force命令 。
例如,, force clk 0 0,1 30 -repeat 60 -cancel 1000‖
强制 clk从 0时间单元开始,直到 1000个时间单元结束。
5,View指令
指令格式,view <窗口名
指令功能:打开 ModelSim的窗口 。
例如,,view souce‖是打开源代码窗口;, view
wave‖是打开波形窗口;, view list‖是打开列表窗口;
,view variables‖是打开变量窗口;, view signals‖是打开
信号窗口;, view all‖是打开所有窗口。
2009-11-10 435
6.2.5 ModelSim批处理工作方式
ModelSim提供个简化方式, 即可以把一批命令存盘,
形 成 一 个 批 处 理 文 件, 采用 GUI 方式从菜单
,Macro‖→― Save‖,回答文件名即可, 当然用户也可以自己
编辑或生成该文件 。
例如上面所讨论指令可以采用记事本等文本编辑工具产
生一个 dff.do文件, 输入下列几行代码:
add wave -r /*
force -freeze /dff/clk 0 -repeat 20
force -freeze /dff/clk 1 10 -repeat 20
force -freeze /dff/enable 1
force -freeze /dff/d 0,1 15,0 49
run 100
2009-11-10 436
批处理文件存盘后在 ModelSim中输入
>>vsim dff &
vsim 1>do dff.do
用这两行命令就可以取代一批命令。
2009-11-10 437
6.3 NCLaunch
Cadence是目前全球最大的 EDA工具软件开发公司,
NCLaunch是该公司开发的 EDA工具之一 。
6.3.1 NCLaunch的安装
安装 NCLaunch软件时必须先安装, License‖,系统
会自动运行一个安装界面,此时可以选择第二个选项目
,Install Cadence License Manager‖。安装 License时应注
意,在输入 Hostid时候必须与你申请到的 License一致。在安
装好第二个选择项目后,则可以安装 LDV软件包,在安装过程
中系统会询问相关 License的端口号,注意此时 License必须
与你的 License申请时候,对方所给予的代号一致。
2009-11-10 438
6.3.2 第一次使用 NCLaunch
第一次使用 NCLaunch,必须建立一个新的设计目录和
一个, CDS‖,CDS包含物理库路径信息。
执行主菜单, File‖的, Create New Directory‖命令,
在弹出的, New Directory‖对话框中输入自己的工程目录。
设置新的工程目录示意图
2009-11-10 439
新的工程目录建立后执行,File‖的,Set Design Directory‖
命令,在弹出的,Set Design Directory‖(设置设计目录)
对话框的,Design Directory‖栏目中选择刚建立的目录
( d:\myeda),然后用鼠标点击,Create cds.lib File‖按
钮在弹出对话框中输入 cds,确定后按“” OK键。
设置设计目录对话框
2009-11-10 440
设计目录设置结束后,在 NCLaunch主窗口界面的左边
将显示工程目录下的各种库名以及设计文件名,右边显示
,cds‖库包含的内容,而下面是用于显示编译、仿真过程中
相关信息。
NCLaunch的主窗口界面
V
H
D
L



Ve
ril
og











仿



2009-11-10 441
6.3.3 NCLaunch的设计流程
NCLaunch的设计流程包括编写 HDL源代码、编译
HDL源代码、产生仿真快照和仿真快照等操作。
1,编写 HDL源代码
执行主菜单, File‖的, Edit New File…‖ 命令,弹出
,Edit a new file‖(编辑新文件)对话框,在对话框的, 保
存在( I), 栏目内选择设计项目的文件夹,如, myeda‖,
然后在, 文件名( N), 栏目中填入设计的文本文件名,如
,cnt4.vhd‖。文件名的后缀表示不同类型的文本文件,例如
用,,vhd‖表示 VHDL文本文件,用,,v‖表示 Verilog VHD文
本文件。
2009-11-10 442
编辑新文件对话框
设计文件名输入结束后按, 保存( S), 键存盘,此时
将弹出写字板(或记事本),用写字板对设计文件进行编辑。
2009-11-10 443
写字板编辑窗口
2009-11-10 444
2,编译 HDL代码
用鼠标将需要编译的 HDL源文件点黑选中,然后按工
具栏上的 VHDL编译按键,则开始对对 VHDL源文件
,cnt4.vhd‖进行编译。编译结果的信息将出现在底部的信
息窗口中,如果有错误,将用红色文字把出错信息显示出来。
3,产生仿真快照
源文件编译完成后,主窗口右边的, cds‖库中的
worklib左边将会有一个, +‖符号出现,单击, +‖符号将出现
下级提示, cnt4‖,再度点击 cnt4左边的, +‖符号,将出现
,entity‖和, one‖。, entity‖是 cnt4的设计实体,,one‖是
设计实体中的结构体名。用鼠标将, entity‖或, one‖点黑选
中,然后按主窗口工具栏上的, 产生快照, 按键,则系统将产
生一个仿真快照,
2009-11-10 445
操作结束时,库管理窗口处的, Snapshots‖将出现
一个, +‖符号。单击, +‖符号将出现, worklib.cnt4.one‖
图标(见图 6.38所示),表示 cnt4的仿真快照已经形成,接
下来可以对设计电路进行仿真验证。
产生快照操作示意图
2009-11-10 446
4,仿真
用鼠标将库管理窗口 Snapshots目录下的 test_cnt4仿
真快照文件,worklib.test_cnt4.one‖点黑,然后点击主窗口
上的“开始仿真”按键,在弹出的仿真器对话窗口中执行
,Select‖菜单下的,Signals‖命令,选中设计实体的全部信
号和端口,然后执行,Windows‖菜单下的,Waveform‖命
令,完成仿真信号节点的选择,同时弹出仿真波形窗口。
执行仿真器窗口, Run‖菜单下的, Run‖命令,或者
直接按, 开始 /停止仿真, 按键,则仿真器开始对设计电路仿
真,4位二进制计数器的仿真波形见图 6.42所示。
2009-11-10 447
图 6.42 4位二进制计数器的仿真波形
2009-11-10 448
第 7章 可编程逻辑器件
?本章概要:本章介绍 PLA,PAL,GAL,CPLD,EPLD和
FPGA等各种类型可编程逻辑器件的电路结构, 工作原理和
使用方法, 并介绍可编程逻辑器件的编程方法 。
?知识要点:
( 1) 可编程逻辑器件的分类 。
( 2) 可编程逻辑器件的结构及特性 。
( 3)可编程逻辑器件的编程方法。
2009-11-10 449
7.1 可编程逻辑器件的基本原理
PROM是始于 1970年出现第一块可编程逻辑器件 PLD
( Programmable Logic Device), 随后可编程逻辑器件又
陆续出现了 PLA,PAL,GAL,EPLD及现阶段的 CPLD和
FPGA等 。 可编程逻辑器件的出现, 不仅改变了传统的数字系
统设计方法, 而且促进了 EDA技术的高速发展 。 EDA技术是以
计算机为工具, 代替人去完成数字系统设计中各种复杂的逻辑
综合, 布局布线和设计仿真等工作 。 设计者只需用硬件描述语
言完成对系统功能的描述, 就可以由计算机软件自行完成处理,
得到设计结果 。 利用 EDA工具进行设计, 可以极大地提高设计
的效率 。
2009-11-10 450
7.1.1 可编程逻辑器件的分类
可编程逻辑器件的密度分类
低密度可编程逻辑
器件 (LDPLD)
高密度可编程逻辑
器件 (HDPLD)
可编程逻辑器件
(PLD)
PROM PLA PAL GAL EPLD CPLD FPGA
2009-11-10 451
1,按集成密度分类
可编程逻辑器件从集成密度上可分为低密度可编程逻辑
器件 LDPLD和高密度可编程逻辑器件 HDPLD两类。
LDPLD 通常是指早期发展起来的、集成密度小于 700
门 /片左右的 PLD如 ROM,PLA,PAL和 GAL等 。
HDPLD包括可擦除可编程逻辑器件 EPLD( Erasable
Programmable Logic Device)、复杂可编程逻辑器件
CPLD( Complex PLD)和 FPGA三种,其集成密度大于 700
门 /片。如 Altera公司的 EPM9560,其密度为 12000门 /片,
Lattice公司的 pLSI/ispLSI3320为 14000门 /片等。目前集成度
最高的 HDPLD可达 25万门 /片以上。
2009-11-10 452
2,按编程方式分类
可编程逻辑器件的编程方式分为两类:一次性编程
OTP( One Time Programmable)器件和可多次编程 MTP
( Many Time Programmable)器件。
OTP器件是属于一次性使用的器件,只允许用户对器
件编程一次,编程后不能修改,其优点是可靠性与集成度高,
抗干扰性强。
MTP器件是属于可多次重复使用的器件,允许用户对
其进行多次编程、修改或设计,特别适合于系统样机的研制
和初级设计者的使用。
2009-11-10 453
根据各种可编程元件的结构及编程方式, 可编程逻辑器
件通常又可以分为四类:
① 采用一次性编程的熔丝 ( Fuse) 或反熔丝 ( Antifuse) 元
件的可编程器件, 如 PROM,PAL和 EPLD等 。
② 采用紫外线擦除, 电可编程元件, 即采用 EPROM、
UVCMOS工艺结构的可多次编程器件 。
③ 采用电擦除, 电可编程元件 。 其中一种是 E2PROM,另一
种是采用快闪存储器单元 ( Flash Memory) 结构的可多次编
程器件 。
④ 基于静态存储器 SRAM结构的可多次编程器件 。 目前多数
FPGA是基于 SRAM结构的可编程器件 。
2009-11-10 454
3,按结构特点分类
PLD按结构特点分为阵列型 PLD和现场可编程门阵列型
FPGA两大类。
阵列型 PLD的基本结构由与阵列和或阵列组成 。 简单
PLD( 如 PROM,PLA,PAL和 GAL等 ), EPLD和 CPLD都属于阵列
型 PLD。
现场可编程门阵列型 FPGA具有门阵列的结构形式, 它
有许多可编程单元 ( 或称逻辑功能块 ) 排成阵列组成, 称为
单元型 PLD。
2009-11-10 455
7.2 可编程逻辑器件的设计技术
7.2.1 概 述
在 PLD没有出现之前,数字系统的传统设计往往采用
,积木, 式的方法进行,实质上是对电路板进行设计,通
过标准集成电路器件搭建成电路板来实现系统功能,即先
由器件搭成电路板,再由电路板搭成系统。数字系统的
,积木块, 就是具有固定功能的标准集成电路器件,如
TTL的 74/54系列,CMOS的 4000/4500系列芯片和一些固
定功能的大规模集成电路等,用户只能根据需要选择合适
的集成电路器件,并按照此种器件推荐的电路搭成系统并
调试成功。设计中,设计者没有灵活性可言,搭成的系统
需要的芯片种类多且数目大 。
2009-11-10 456
PLD的出现,给数字系统的传统设计法带来新的变革。
采用 PLD进行的数字系统设计,是基于芯片的设计或称之为
,自底向上, ( Bottom-Up)的设计,它跟传统的积木式
设计有本质的不同。它可以直接通过设计 PLD芯片来实现数
字系统功能,将原来由电路板设计完成的大部分工作放在
PLD芯片的设计中进行。这种新的设计方法能够由设计者根
据实际情况和要求定义器件的内部逻辑关系和管脚,这样可
通过芯片设计实现多种数字系统功能,同时由于管脚定义的
灵活性,不但大大减轻了系统设计的工作量和难度,提高了
工作效率,而且还可以减少芯片数量,缩小系统体积,降低
能源消耗,提高系统的稳定性和可靠性。
2009-11-10 457
IEEE标准的 HDL(如 VHDL 和 Verilog HDL)给 PLD
和数字系统的设计带来了更新的设计方法和理念,产生了目
前最常用的并称之为, 自顶向下, ( Top-Down)的设计法。
自顶向下的设计采用功能分割的方法从顶向下逐次将设计内
容进行分块和细化。在设计过程中采用层次化和模块化将使
系统设计变得简洁和方便,其基本设计思想如图 7.15所示。
层次化设计是分层次、分模块地进行设计描述。描述器件总
功能的模块放在最上层,称为顶层设计;描述器件某一部分
功能的模块放在下层,称为底层设计;底层模块还可以再向
下分层,直至最后完成硬件电子系统电路的整体设计。
2009-11-10 458
系统设计
模块 A 模块 B 模块 C

块A
1

块A
2

块A
3

块B
1

块B
2

块B
3

块C
1

块C
2

块C
3
图 7.15,自顶向下, 设计法示意图
2009-11-10 459
7.2.2 可编程逻辑器件的设计流程
可编程逻辑器件 的设计流程包括设计准备、
设计输入、设计处理和器件编程四个步骤以及相应
的功能仿真、时序仿真和器件测试三个设计验证过
程。这个设计流程与第 1章 1.2节中叙述的 EDA设计
流程基本相同,这里不再重复。
2009-11-10 460
7.2.3 在系统可编程技术
在系统可编程( In-System Programmable,
简称 ISP)技术是 20世纪 80年代末 Lattice公司首先
提出的一种先进的编程技术。在系统可编程是指对
器件、电路板或整个电子系统的逻辑功能可随时进
行修改或重构的能力。支持 ISP技术的可编程逻辑器
件称为在系统可编程器件( ISP-PLD),例如
Lattice公司生产的 ispLSI1000~ ispLSI8000系列器
件属于 ISP-PLD。
2009-11-10 461
7.2.4 边界扫描技术
边界扫描测试 BST( Boundary-Scan Testing)
是针对器件密度及 I/O口数增加,信号注入和测取难
度越来越大而提出的一种新的测试技术。它是由联
合测试活动组织 JTAG提出来的,而后 IEEE对此制
定了测试标准,称为 IEEE 1149.1 标准。边界扫描
测试技术主要解决芯片的测试问题。
2009-11-10 462
7.3 可编程逻辑器件的编程与配置
由于可编程逻辑器件具有在系统下载或重新配
置功能,因此在电路设计之前就可以把其焊接在印刷
电路板上,并通过电缆与计算机连接。在设计过程中,
以下载编程或配置方式来改变可编程逻辑器件的内部
逻辑关系,达到设计逻辑电路目的。
目前常见的可编程逻辑器件的编程和配置工艺
包括基于电可擦存储单元的 E2PROM或 Flash技术的编程
工艺, 基于 SRAM查找表的编程单元的编程工艺和基于
反熔丝编程单元的编程工艺三种 。
2009-11-10 463
7.3.1 CPLD的 ISP方式编程
ISP方式是当系统上电并正常工作时, 计算机就
可以通过 CPLD器件拥有的 ISP接口直接对其进行编程,
器件被编程后立即进入正常工作状态 。
CPLD的编程和 FPGA的配置可以使用专用的编
程设备,也可以使用下载电缆。例如用 Altera公司的
ByteBlaster( MV)并行下载电缆,将 PC机的并行打
印口与需要编程或配置的器件连接起来,在
MAX+plusII工具软件的控制下,就可以对 Altera公司
的多种 CPLD和 FPGA进行编程或配置。
2009-11-10 464
JTAG接口本来是用作边界扫描测试 ( BST)
的, 把它用作编程接口则可以省去专用的编程接口,
减少系统的引出线 。
采用 JATG模式对 CPLD编程下载的连线如图
7.22所示 。 这种连线方式既可以对 CPLD进行测试,
也可以进行编程下载 。
2009-11-10 465
图 7.22 CPLD编程下载连线图
TCK
TDO
TMS
TDI
Altera
MAX
7000
系列
器件
GND
VCC
2
4
10
1
3
5
9
1k? 1k?
1k?
2009-11-10 466
由于 ISP器件具有串行编程方式,即菊花链结
构,其特点是各片共用一套 ISP编程接口,每片的
SDI输入端与前一片的 SDO输出端相连,最前面一
片的 SDI端和最后一片的 SDO端与 ISP编程口相连,
构成一个类似移位寄存器的链形结构。因此采用
JTAG模式可以对多个 CPLD器件进行 ISP在系统编
程,多 CPLD芯片 ISP编程下载的连线如图 7.23所示。
2009-11-10 467
GND
图 7.23 多 CPLD编程下载连线图
VCC
2
4
10
1
3
5
9
1k? 1k?
1k?
TDO TDI
TCK TMS
TDO TDI
TCK TMS
TDO TDI
TCK TMS
Altera的 MAX7000系列器件或其他 JTAG器件
2009-11-10 468
7.3.2 使用 PC机的并口配置 FPGA
基于 SRAM LUT结构的 FPGA不属于 ISP器件,它
是以在线可重配置方式 ICR( In Circuit
Reconfigurability)改变芯片内部的结构来进行硬件验
证。利用 FPGA进行电路设计时,可以通过下载电缆与
PC机的并口连接,将设计文件编程下载到 FPGA中。
使用 PC机的并口通过 ByteBlaster下载电缆对多个
FPGA器件进行配置的电路连接如图 7.24所示。
2009-11-10 469
图 7.24 多 FPGA芯片配置连线图
VCC
2
4
10
1
3
5
9
1k?
1k?
CONF_DONE
nSTATUS
DCLK
nCEO
MSEL1
MSEL2
nCE
DATA0
nCONFIG
CONF_DONE
nSTATUS
DCLK
nCEO
MSEL1
MSEL2
nCE
DATA0
nCONFIG
1k?
1k?
1k?
2009-11-10 470
第 8章 EDA技术的应用
?本章概要:本章通过用硬件描述语言 VHDL和 Verilog
HDL实现的设计实例, 进一步介绍 EDA技术在组合逻辑, 时
序逻辑电路设计以及在测量仪器, 通信系统和自动控制等技
术领域的综合应用 。 本章列出的全部 HDL源程序均通过
MAX+plusII或 ModelSim工具软件的编译 。
?知识要点:
( 1) VHDL的组合逻辑, 时序逻辑以及综合应用实例 。
( 2) Verilog HDL的组合逻辑, 时序逻辑以及综合应用的实
例 。
( 3) VHDL和 Verilog HDL实现系统设计的实例 。
2009-11-10 471
8.1 组合逻辑电路设计应用
8.1.1 8位乘法器的设计
8位乘法器的元件符号如图 8.1所示,a[7..0]
和 b[7..0]是被乘数和乘数输入端,q[15..0]是乘积
输出端。
图 8.1 8位乘法器元件符号
2009-11-10 472
用 VHDL描述的 8位乘法器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mul IS
PORT( a,b,IN integer range 0 to 255;
q,OUT integer range 0 to 65535);
END mul;
ARCHITECTURE one OF mul IS
BEGIN
q<=a *b;
END one;
2009-11-10 473
用 Verilog HDL描述的 8位乘法器源程序如下:
module mul8v (a,b,q);
input[7:0] a,b;
output[15:0] q;
assign q = a * b;
endmodule
2009-11-10 474
8.1.2 十六进制编码键盘设计
十六进制编码键盘的结构如图 8.3所示,它是一个 4× 4
矩阵结构,用 x3~ x0和 y3~ y0等 8条信号线接收 16个按键的信
息,相应的编码器元件符号如图 8.4所示。
x0
x1
x2
x3
y0 y1 y2 y3
3210
7654
BA98
FEDC
图 8.3 图 8.4
2009-11-10 475
VHDL描述源程序如下
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY hcoder IS
PORT(x,y:INSTD_LOGIC_VECTOR(3 DOWNTO 0);
S, OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END hcoder;
ARCHITECTURE struc OF hcoder IS
BEGIN
2009-11-10 476
PROCESS (x,y)
VARIABLE xy:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
xy:=(X & y);
CASE xy IS
WHEN B"11101110" => S <= B"0000";
WHEN B"11101101" => S <= B"0001";
WHEN B"11101011" => S <= B"0010";
WHEN B"11100111" => S <= B"0011";
WHEN B"11011110" => S <= B"0100";
WHEN B"11011101" => S <= B"0101";
WHEN B"11011011" => S <= B"0110";
2009-11-10 477
WHEN B"11010111" => S <= B"0111";
WHEN B"10111110" => S <= B"1000";
WHEN B"10111101" => S <= B"1001";
WHEN B"10111011" => S <= B"1010";
WHEN B"10110111" => S <= B"1011";
WHEN B"01111110" => S <= B"1100";
WHEN B"01111101" => S <= B"1101";
WHEN B"01111011" => S <= B"1110";
WHEN B"01110111" => S <= B"1111";
WHEN OTHERS => S <= B"0000";
END CASE;
END PROCESS ;
END struc;
2009-11-10 478
Verilog HDL描述如下,
Module hcoder(x,y,s);
input[3:0] x,y;
output[3:0] s;
reg[3:0] s;
always
begin
case ({x,y})
8'b11101110,s=0;
8'b11101101,s=1;
8'b11101011,s=2;
8'b11100111,s=3;
8'b11011110,s=4;
2009-11-10 479
8'b11011101,s=5;
8'b11011011,s=6;
8'b11010111,s=7;
8'b10111110,s=8;
8'b10111101,s=9;
8'b10111011,s=10;
8'b10110111,s=11;
8'b01111110,s=12;
8'b01111101,s=13;
8'b01111011,s=14;
8'b01110111,s=15;
default, s=0;
endcase
end
endmodule
2009-11-10 480
8.1.3 译码器设计
3线 -8线译码器的元件符号如图 8.6所示,ENA是译码
器的使能控制输入端,当 ENA=1时,译码器不能工作,8线
输出 Y[7..0]=11111111(译码器的输出有效电平为低电平);
当 ENA=0时,译码器工作。 C,B,A是 3线数据输入端,译
码器处于工作状态时,当 CBA=000时,Y[7..0]=11111110
(即 Y[0]=0);当 CBA=001时,Y[7..0]=11111101(即
Y[1]=0);依此类推。
图 8.6 3线 -8线译码器的元件符号
2009-11-10 481
用 VHDL描述的源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Decoder IS
PORT(a,b,c,ena:IN BIT;
y:OUT BIT_VECTOR(7 DOWNTO 0));
END Decoder;
ARCHITECTURE one OF Decoder IS
BEGIN
PROCESS(a,b,c,ena)
VARIABLE cba:BIT_VECTOR(2 DOWNTO 0);
BEGIN
cba:=(c & b & a);
2009-11-10 482
IF (ena='1') THEN y <= "11111111";
ELSE CASE (cba) IS
WHEN "000" => y <= "11111110";
WHEN "001" => y <= "11111101";
WHEN "010" => y <= "11111011";
WHEN "011" => y <= "11110111";
WHEN "100" => y <= "11101111";
WHEN "101" => y <= "11011111";
WHEN "110" => y <= "10111111";
WHEN "111" => y <= "01111111";
WHEN OTHERS=>NULL;
END CASE;
END IF;
END PROCESS;
END one;
2009-11-10 483
用 Verilog HDL描述的 3线 -8线译码器源程序如下:
module decoder(a,b,c,ena,y);
input a,b,c,ena;
output[7:0] y;
reg[7:0] y;
always
begin
if (ena==1) y = 'b11111111;
else
case ({c,b,a})
'b000,y= 'b11111110;
'b001,y= 'b11111101;
2009-11-10 484
'b010,y= 'b11111011;
'b011,y= 'b11110111;
'b100,y= 'b11101111;
'b101,y= 'b11011111;
'b110,y= 'b10111111;
'b111,y= 'b01111111;
default, y= 'b11111111;
endcase
end
endmodule
2009-11-10 485
8.1.4 16选 1数据选择器设计
16选 1数据选择器的元件符号如图 8.8所示, ENA是使
能控制输入端, 当 ENA=1时, 电路不能工作, 输出 Y=0;
ENA=0时, 电路处于工作状态 。 A[15..0]是数据输入端, S3、
S2,S1和 S0是数据选择控制端, 当电路处于工作状态时
( ENA=0), 若 S3S2S1S0=0000,则输入 A[0]被选中, 输出
Y=A[0];若 S3S2S1S0=0001,则输入 A[1]被选中, 输出
Y=A[1];依此类推 。
图 8.8 16选 1数据选择器元件符号
2009-11-10 486
用 VHDL描述的 16选 1数据选择器 源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux16_1 IS
PORT (s0,s1,s2,s3,ena,IN STD_LOGIC;
a,IN STD_LOGIC_VECTOR(15 DOWNTO 0);
y,OUT STD_LOGIC);
END mux16_1;
ARCHITECTURE one OF mux16_1 IS
SIGNAL s,STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
s<=s0&s1&s2&s3; --将 s0,s1,s2和 s3并为 s
2009-11-10 487
PROCESS(s0,s1,s2,s3,ena)
BEGIN
IF ena='1' THEN y<='0';
ELSE
CASE s IS
WHEN "0000" => y <=a(0);
WHEN "0001" => y <=a(1);
WHEN "0010" => y <=a(2);
WHEN "0011" => y <=a(3);
WHEN "0100" => y <=a(4);
WHEN "0101" => y <=a(5);
WHEN "0110" => y <=a(6);
WHEN "0111" => y <=a(7);
2009-11-10 488
WHEN "1000" => y <=a(8);
WHEN "1001" => y <=a(9);
WHEN "1010" => y <=a(10);
WHEN "1011" => y <=a(11);
WHEN "1100" => y <=a(12);
WHEN "1101" => y <=a(13);
WHEN "1110" => y <=a(14);
WHEN "1111" => y <=a(15);
WHEN OTHERS => y <='X';
END CASE;
END IF;
END PROCESS;
END one;
2009-11-10 489
用 Verilog HDL描述 16选 1数据选择器的源程序如下:
module mux16_1(a,s3,s2,s1,s0,ena,y);
input s3,s2,s1,s0,ena;
input[15:0] a;
output y;
reg y;
always
begin
if (ena==1) y = 0;
else
case ({s3,s2,s1,s0})
'b0000,y= a[0]; 'b0001,y= a[1];
2009-11-10 490
'b0010,y= a[2]; 'b0011,y= a[3];
'b0100,y= a[4]; 'b0101,y= a[5];
'b0110,y= a[6]; 'b0111,y= a[7];
'b1000,y= a[8]; 'b1001,y= a[9];
'b1010,y= a[10]; 'b1011,y= a[11];
'b1100,y= a[12]; 'b1101,y= a[13];
'b1110,y= a[14]; 'b1111,y= a[15];
default, y= 0;
endcase
end
endmodule
2009-11-10 491
8.1.5 8位二进制数据比较器设计
8位二进制数据比较器电路的元件符号如图 8.8所示,
A[7..0]和 B[7..0]是两个数据输入端, FA是, 大于, 输出端,
FB是, 小于, 输出端, FE是, 等于, 输出端 。 当 A[7..0]大于
B[7..0]时, FA=1;当 A[7..0]小于 B[7..0]时, FB=1;当 A[7..0]
等于 B[7..0]时, FE=1。
图 8.8 8位数据比较器元件符号
2009-11-10 492
用 VHDL描述的 8位二进制数据比较器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY comp8 IS
PORT (a,b, IN STD_LOGIC_VECTOR(7 DOWNTO 0);
fa,fb,fe, OUT STD_LOGIC);
END comp8;
ARCHITECTURE one OF comp8 IS
BEGIN
PROCESS(a,b)
BEGIN
2009-11-10 493
IF a > b THEN fa <= '1';
fb <= '0';
fe <= '0';
ELSIF a < b THEN fa <= '0';
fb <= '1';
fe <= '0';
ELSIF a = b THEN fa <= '0';
fb <= '0';
fe <= '1';
END IF;
END PROCESS;
END one;
2009-11-10 494
用 Verilog HDL描述 8位二进制数据比较器的源程序如下:
module comp8v(a,b,fa,fb,fe);
input[7:0] a,b;
output fa,fb,fe;
reg[7:0] fa,fb,fe;
always
begin
if (a > b) begin fa = 1; fb = 0; fe = 0; end
else if (a < b) begin fa = 0; fb = 1; fe = 0; end
else if (a == b) begin fa = 0; fb = 0; fe = 1; end
end
endmodule
2009-11-10 495
8.1.6 ROM的设计
对于容量不大的 ROM,可以用 VHDL的 case语句来实现。下
面是用 case语句实现 8× 8位 ROM的源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY from_rom IS
PORT(addr, IN INTEGER RANGE 0 TO 7;
ena, IN STD_LOGIC;
q,OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END from_rom;
ARCHITECTURE a OF from_rom IS
BEGIN
2009-11-10 496
PROCESS (ena,addr)
BEGIN
IF (ena='1') THEN q<="ZZZZZZZZ";ELSE
CASE addr IS
WHEN 0 => q<="01000001";
WHEN 1 => q<="01000010";
WHEN 2 => q<="01000011";
WHEN 3 => q<="01000100";
WHEN 4 => q<="01000101";
WHEN 5 => q<="01000110";
WHEN 6 => q<="01000111";
WHEN 7 => q<="01001000";
END CASE;
2009-11-10 497
END IF;
END PROCESS ;
END a;
由 VHDL源代码生成的 8× 8位 ROM的元件符号如图 8.9所示,
其中 ADDR[3..0]是地址输入端,ENA是使能控制输入端,当
ENA=1时,ROM不能工作,输出 Q[7..0]为高阻态,ENA=0时,
ROM工作,其输出的数据由输入地址决定。
图 8.9 8× 8位 ROM的元件符号
2009-11-10 498
用 Veilog HDL实现 8× 8位 ROM的源程序如下:
module from_rom(addr,ena,q);
input [2:0] addr;
input ena;
output [7:0] q;
reg [7:0] q;
always @(ena or addr)
begin
if (ena) q = 'bzzzzzzzz;else
case (addr)
0,q = 'b01000001;
1,q = 'b01000010;
2009-11-10 499
2,q = 'b01000011;
3,q = 'b01000100;
4,q = 'b01000101;
5,q = 'b01000110;
6,q = 'b01000111;
7,q = 'b01001000;
default, q = 'bzzzzzzzz;
endcase
end
endmodule
2009-11-10 500
8.2 时序逻辑电路设计应用
8.2.1 JK触发器设计
JK触发器的元件符号如图 8.14所示, 其中 J,K是数据输入端,
CLR是复位控制输入端, 当 CLR=0时, 触发器的状态被置为
0态; CLK是时钟输入端; Q和 QN是触发器的两个互补输出端 。
图 8.14 JK触发器的元件符号
2009-11-10 501
用 VHDL描述的 JK触发器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY myjkff IS
PORT(j,k,clr:IN STD_LOGIC;
clk:IN STD_LOGIC;
q,qn:BUFFER STD_LOGIC);
END myjkff;
ARCHITECTURE one OF myjkff IS
BEGIN
PROCESS(j,k,clr,clk)
VARIABLE jk:STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
2009-11-10 502
jk:=(j & k);
IF clr='0' THEN q<='0'; qn<='1';
ELSIF clk'EVENT AND clk='0' THEN
CASE jk IS
WHEN "00" => q <=q; qn <= qn;
WHEN "01" => q <= '0'; qn <= '1';
WHEN "10" => q <= '1'; qn <= '0';
WHEN "11" => q <= NOT q; qn <= NOT qn;
WHEN OTHERS => NULL;
END CASE ;
END IF;
END PROCESS;
END one;
2009-11-10 503
用 Verilog HDL描述的 JK触发器源程序如下:
module myjkff(j,k,clr,clk,q,qn);
input j,k,clr,clk;
output q,qn;
reg q,qn;
always @(negedge clr or negedge clk)
begin
if (~clr) begin q = 0; qn = 1; end
else
case ({j,k})
'b00,begin q = q; qn = qn; end
'b01,begin q = 0; qn = 1; end
2009-11-10 504
'b10,begin q = 1; qn = 0; end
'b11,begin q = ~q; qn = ~qn; end
default begin q = 0; qn = 1;end
endcase
end
endmodule
2009-11-10 505
8.2.2 8D锁存器设计
具有三态输出的 8D锁存器元件符号如图 8.16所示。 CLR是复
位控制输入端,当 CLR=0时,8位数据输出
Q[7..0]=00000000。 ENA是使能控制输入端,当 ENA=1时,
锁存器处于工作状态,输出 Q[7..0]= D[7..0]; ENA=0时,锁
存器的状态保持不变。 OE是三态输出控制端,当 OE=1时,
输出为高阻态; OE=0时,锁存器为正常输出状态。
图 8.16 8D锁存器元件符号
2009-11-10 506
用 VHDL描述的 8D锁存器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY latch8 IS
PORT(clr,clk,ena,oe:IN STD_LOGIC;
d:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
q:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0));
END latch8;
ARCHITECTURE one OF latch8 IS
SIGNAL q_temp:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
2009-11-10 507
u1:PROCESS(clk,clr,ena,oe)
BEGIN
IF clr='0' THEN q_temp <= "00000000";
ELSIF clk'EVENT AND clk='1' THEN
IF (ena='1') THEN
q_temp <= d;
END IF;
END IF;
IF oe='1' THEN q <= "ZZZZZZZZ";
ELSE q <= q_temp;
END IF;
END PROCESS u1;
END one;
2009-11-10 508
用 Verilog HDL描述三态输出 8D锁存器的源程序如下:
module latch8v(clk,clr,ena,oe,q,d);
input [7:0] d;
input clk,clr,ena,oe;
output [7:0] q;
reg [7:0] q,q_temp;
always @(posedge clk)
begin
if (~clr) q_temp = 0;
else if (ena) q_temp = d;
else q_temp = q;
if (oe) q = 8'bzzzzzzzz; else q = q_temp;
end
endmodule
2009-11-10 509
8.2.3 8位双向移位寄存器设计
8位双向移位寄存器电路的元件符号如图 8.18所示, 其中 CLR
是复位控制输入端; LOD是预置控制输入端; S是移位方向控
制输入端, 当 S=1时, 是右移移位寄存器, S=0时, 是左移移
位寄存器; DIR是右移串入输入信号; DIL是左移串入输入信
号 。
图 8.18 8位双向移位寄存器元件符号
2009-11-10 510
用 VHDL描述的 8位双向移位寄存器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY rlshift IS
PORT(clr,lod,clk,s,dir,dil:IN BIT;
d:IN BIT_VECTOR(7 DOWNTO 0);
q:BUFFER BIT_VECTOR(7 DOWNTO 0));
END rlshift;
ARCHITECTURE one OF rlshift IS
SIGNAL q_temp:BIT_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS(clr,clk,lod,s,dir,dil)
BEGIN
2009-11-10 511
IF clr='0' THEN q_temp <= "00000000";
ELSIF clk'EVENT AND clk='1' THEN
IF (lod='1') THEN
q_temp <= d;
ELSIF (S='1') THEN
FOR i IN 7 downto 1 LOOP --实现右移操作
q_temp(i-1) <= q(i);
END LOOP ;
q_temp(7) <= dir;
ELSE
2009-11-10 512
FOR i IN 0 TO 6 LOOP --实现左移操作
q_temp(i+1) <= q(i);
END LOOP ;
q_temp(0) <= dil;
END IF;
END IF;
q <= q_temp;
END PROCESS;
END one;
2009-11-10 513
用 Verilog HDL描述 8位双向移位寄存器的源程序如下:
module rlshift8(q,d,lod,clk,clr,s,dir,dil);
input [7:0] d;
input lod,clk,clr,s,dir,dil;
output [7:0] q;
reg [7:0] q;
always @(posedge clk)
begin
if (~clr) q = 'b00000000;
else if (lod) q = d;
else if (s) begin
q = q >> 1; --实现右移操作
q[7] = dir; end
2009-11-10 514
else begin
q = q << 1; --实现左移操作
q[0] = dil; end
end
endmodule
2009-11-10 515
8.2.4 8位二进制加减计数器设计
8位二进制加减计数器的元件符号如图 8.20所示, CLR是复位
控制输入端; ENA是使能控制输入端; LOAD是预置控制输入
端; D[7..0]是 8位并行数据输入端; UPDOWN是加减控制输
入端, 当 UPDOWN=0时, 计数器作加法操作, UPDOWN=1
时, 计数器作减法操作; COUT是进 /借位输出端 。
图 8.20 8位二进制加减计数器元件符号
2009-11-10 516
用 VHDL描述的 8位二进制加减计数器源程序如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY updowncnt8 IS
PORT(clr,clk,ena,load,updown:IN STD_LOGIC;
d:IN INTEGER RANGE 0 TO 255;
cout:OUT STD_LOGIC;
q:BUFFER INTEGER RANGE 0 TO 255);
END updowncnt8;
ARCHITECTURE one OF updowncnt8 IS
BEGIN
PROCESS(clk,ena,clr,d,load,updown)
2009-11-10 517
BEGIN
IF CLR='0' THENq <= 0;
ELSIF clk'EVENT AND clk='1' THEN
IF load = '1' THEN q <= d;
ELSIF ena='1' THEN
IF updown = '0' THEN q <= q+1;
IF q = 255 THEN COUT <= '1'; END IF;
ELSE q <= q-1;
IF q = 0 THEN COUT <= '0'; END IF;
END IF;
END IF;
END IF;
END PROCESS;
END one;
2009-11-10 518
用 Verilog HDL描述 8位二进制加减计数器的源程序如下:
module pdowncnt8(q,cout,d,load,ena,clk,clr,updown);
input [7:0] d;
input load,ena,clk,clr,updown;
output [7:0] q;
output cout;
reg [7:0] q;
always @(posedge clk)
begin
if (~clr) q = 'b00000000;
else if (load) q = d;
2009-11-10 519
else if (ena)
if (~updown) q = q+1;
else q = q-1;
end
assign cout = (~updown)? &q:|q;
endmodule
2009-11-10 520
再见!