You are on page 1of 36

《可编程逻辑器件与应用专题》

实验讲义
附实验指导书

清华大学电子工程系
2004.8.5
第一章 绪论

§1.1 可编程 ASIC 综述


为特定的产品或应用而设计的芯片被称为专用集成电路 ASIC(Application Specific Integrated
Circuits),除了全定制的专用集成电路外,目前有五种半定制的元件,可实现 ASIC 的要求,它们是:
*可编程逻辑器件(PLD)
*复杂可编程逻辑器件(CPLD)
*现场可编程门阵列(FPGA)
*门阵列(Gate Array)
*标准单元(Standard Cell)
在这些器件中,尤其是前三种器件的出现,使得电子系统的设计工程师利用相应的 EDA 软件,在
办公室或实验室里就可以设计自己的 ASIC 器件,其中近几年发展起来的 CPLD 和 FPGA 格外引人注目。
这三种器件都具有用户可编程性,能实现用户需要的各种专门用途,因此被称作可编程专用集成电路。
半导体制造厂家可按照通用器件的规格大批量生产这种集成电路,作为一种通用集成电路,用户可以从
市场上选购,再通过设计软件编程实现 ASIC 的要求。由于这种方式对厂家和用户都带来了好处而受到
欢迎,因此发展特别迅速,已经成为实现 ASIC 的一种重要手段。
随着半导体技术的迅速发展,从八十年代开始,构造许多电子系统仅仅需要三种标准电路:微处
理器,存储器和可编程 ASIC。电子系统设计的这场革命是从 70 年代开始的,当时存储器已经作为标准
产品进入市场,而 80 年代的微处理器也成为一种标准产品。值得注意的是,微处理器和存储器作为电
子系统的两个主要模块,一直都是可编程的。但是组成电子系统的各种控制逻辑仍然需要大量的中小规
模通用器件。直到近十年来,随着可编程逻辑器件的出现,才给电子系统的控制逻辑提供了可编程的灵
活性。而可编程门阵列作为一种高密度,通用的可编程逻辑器件与它的开发系统一起为更多的电子系统
逻辑设计确定了一种新的工业标准。越来越多的电子系统设计工程师用 CPLD 或 FPGA 作为电子系统
设计的第三个模块来实现一个电子系统。
CMOS 半导体技术的不断发展推动了电子系统逻辑设计的这一变革。人们历来认为 CMOS 速度太
慢,不能满足高性能系统设计的需要,很多设计只能用一次可编程(OTP)的双极型可编程逻辑器件
(PLD)来完成。而现在许多 CMOS 的可编程逻辑器件实际上已达到或超过双极型的性能,同时还具
有低功耗、可编程和高集成度等吸引人的优点。
目前可编程 ASIC 正朝着为设计者提供系统内可再编程(或可再配置)的能力方向发展,即可编程
ASIC 器件不仅要具有可编程和可再编程能力,而且只要把器件插在系统内或电路板上,就能对其进行
编程或再编程,这就为设计者进行电子系统的设计和开发提供了最新的实现手段,而在以前这是不可想
象的。采用系统内可再编程(ISP)技术,使得系统内硬件的功能可以像软件一样被编程来配置,从而
可以实时地进行灵活和方便的更改和开发。这种称为“软”硬件的全新设计概念,使得新一代电子系统
只有极强的灵活性和适应性,它不仅使电子系统的设计和产品性能的改进、扩充变得十分简易和方便,
而且使电子系统只有多功能性的适应能力,从而可以为许多复杂的信号处理技术提供新的思路和方法。
随着可编程器件规模的增加,使器件变得越来越复杂,对器件作全面彻底测试的要求也就越来越
高,而且越来越重要。表面安装的封装和电路板制造技术的进步,使得电路板变小变密,这样一来,传
统的测试方法,例如外探针测试法和“钉床”测试夹具法都难于实现。结果由于电路板简化所节约的成
本,很可能被传统测试方法代价的提高而抵消掉。
20 世纪 80 年代联合测试行动组 JTAG(Joint Test Action Group)开发了 IEEE1149.1-1990 边界扫描
测试技术规范。这个边界扫描测试(BST)结构提供了有效地测试引线间隔致密的电路板上零部件的能
力。
你可以使用 BST 结构测试引脚连接而不必使用物理测试探针,而且可以在器件正常工作时捕获功
能数据。器件的边界扫描单元能够迫使逻辑追踪引脚信号,或是从引脚或器件核心逻辑信号中捕获数据。
强行加入的测试数据串行移入边界扫描单元,捕获的数据串行移出并在器件外部同预期的结果进行比

― 1 ―
较。JTAG 标准提供了板级和芯片级的测试。通过定义输入输出引脚、逻辑控制函数和指令,所有 JTAG
的测试功能部仅需一个四线或五线的接口及相应的软件即能完成。图 1-1 举例说明了边界扫描测试法的
概念。
串行数据输入 串行数据输出

核心 核心
逻辑 逻辑

IC 引脚
JTAG 器件 1 JTAG 器件 2

图 1-1 JTAG 边界扫描测试法


可编程逻辑器件规模的不断发展,使其可以实现电子系统的高度集成,为了快速准确地设计复杂
的电子系统,必须采用计算机自顶向下的设计和综合工具。综合工具一般包括从原理图和高层描述工具、
逻辑仿真器,到底层综合工具的一系列软件包。底层的综合工具对设计进行逻辑描述,并执行逻辑优化、
器件映射、布局布线的网表优化,从而产生最终的设计结果。对于简单的设计,采用原始图输入或布尔
方程输入是比较合适的。但对于复杂系统的设计,这两种输入方法变得繁琐而复杂并容易产生错误,而
必须考虑高层次的设计输入方法。因此很多综合工具支持硬件描述语言(HDL),寄存器转换语言(RTL)
或有限状态机(FSM)。
高层综合工具可以采用高层的行为描述,如 VHDL 或编程语言。行为描述语言不需要说明一个设
计具体采用何种方式实现。高层综合包括选择特定的结构模板,然后执行资源分配,寄存器分配和定时。
所以在高层设计期间,设计者基本是在速度和资源之间所取舍。例如,相同的行为设计,当速度要求不
高时,可以采用完全的流水线方式的逻辑设计来实现。从一个满意的行为描述开始的设计,使设计者能
够有更广泛的选择余地,来找出哪一个最适合特定的实现环境。高层设计方法的另一个主要优点是更容
易理解和维护。
目前,电子设计自动化软件不再是简单的 CAD 或 CAT,已经发展到“电子系统设计自动化(EDA)”,
软件平台也已从小型机覆盖到工作站到高性能微机,一般都包含了符合 IEEE-1076 标准的 VHDL 高层
综合工具,这些都为可编程 ASIC 的设计带来了极大的方便。特别对于中小规模系统的集成,可编程逻
辑器件成为首选的方案。这也是可编程逻辑器件得到广泛应用的原因之一。

§1.2 可编程逻辑器件的分类
可编程逻辑器件包括一个未配置的逻辑单元阵列,此阵列可以编程实现所需的逻辑功能,并通过
可编程互连接到所要求的输入、输出。这些逻辑单元可以是门、反相器、触发器或较大的宏单元,并且
有它自身的可编程局部互连系统。可编程互连是由可编程的开关阵列和连接逻辑单元的固定信号线组
成。可编程逻辑器件有许多不同的分类方法,下面主要介绍四种:
1.2.1 从互连特性上分类
从互连特性上,可编程逻辑器件结构可以分为确定型和统计型两大类。确定型的 PLD 包括 PROM、
PLA、PAL、FPLA、GAL、EPLD 和 EEPLD。它们所提供的互连结构每次都用相同的互连线实现布线。
所以这类可编程逻辑器件的延时特性常常可以从数据手册上直接查到,而不需通过设计软件来确定。
统计型的器件主要是现场可编程门阵列(FPGA) 。FPGA 的设计软件每次完成相同的功能却给出不
同的布线结果,所以称为统计型的结构。因此在电路设计时必须允许设计者限制功能中关键路径的时序
变化,确保它们不超出系统的技术要求。
1.2.2 从可编程特性上分类:
目前为用户提供的编程手段主要有四种:
*一次编程熔丝或逆熔丝;
*EPROM 结构,即紫外线擦除电报编程存储单元(UVEPROM)采用紫外线互补金属氧化半导体

― 2 ―
(UVCMOS) ;
;另
*电擦除和再编程存储单元。一类是 EEPROM,为电擦除式互补金属氧化半导体(EECMOS)
一类是结构与 UVEPROM 类似,但采用电擦除的闪速存储单元(FLASH MEMORY);
*基于静态存储器(SRAM)的编程结构。
所以根据编程能力可以将它们分为两大类,一类是不可以再编程的,确定型的 PAL 和统计型采用
逆熔丝的 FPGA 都是不可再编程的;另一类是可再编程的,确定型的 GAL 和统计型的采用 SRAM 的
FPGA 属于此类。
1.2.3 从器件容量上分类
由于可编程逻辑器件本身结构上和半导体生产工艺的不断改进和提高,器件的密度不断增加,性
能亦不断提高,目前可编程逻辑器件的容量已达到百万门以上。从容量上对可编程逻辑器件的分类是将
复杂的可编程逻辑器件(CPLD)和现场可编程门阵列(FPGA)统称为高容量可编程逻辑器件(HCPLD)。
1.2.4 从结构的复杂程度上分类
从结构上对可编程逻辑进行分类是最常用的方法,而且各类可编程逻辑器件的开发系统都是针对
其结构来设计的,了解和掌握可编程逻辑器件的结构对合理、有效地选用开发软件来设计可编程逻辑器
件就很重要。从结构上可将可编程逻辑器件分为以下三类:
*简单可编程逻辑器件(PLD);
*复杂可编程逻辑器件(CPLD);
*可编程门阵列(FPGA)。

― 3 ―
第二章 可编程逻辑器件的结构和特点

§2.1 概述
可编程逻辑器件(PLD)是一个逻辑电路,可由用户编程来实现特定的逻辑功能。许多 PLD 器件
的功能已经或多或少变成工业标准,即可以像标准 74 系列中小规模器件那样。设计人员可以按照产品
手册,根据速度、功耗、成本进行选择,并能从不同的厂家购买到。而且,PLD 器件还提供了标准 74
系列器件无法提供的可编程功能,用户可以将一些中小规模器件的功能集成到一个或几个 PLD 中,极
大的简化了印制板的设计,因此 PLD 成为最早实现可编程 ASIC 的器件。

§2.2 PLD 的结构


PLD 的主要部分由两个逻辑阵列构成,一个与阵和一个或阵。输入到 PLD 的信号首先通过与阵,
形成输入信号的组合,每组与项称为布尔代数的最小项或乘积项,这些乘积项在或阵中进行逻辑或后由
输出宏单元输出。输入信号的反码由输入缓冲器产生,PLD 的布线由阵列实现,所以只要逻辑功能能
够放进 PLD 器件,布线就能够成功。
PLD 器件的与或阵列结构可以有效地利用硅片的面积,对于逻辑设计也非常方便。因为任何布尔
函数都可以表示为最小项的逻辑表达式,而这正是 PLD 器件的结构。基于与或阵的 PLD 有三种基本类
型,由哪个阵列可编程来区分这三种器件:
• 可编程只读存储器-PROM:与阵固定,或阵可编

• 可编程阵列逻辑-PAL,GAL:与阵可编程,或阵
固定
• 可编程逻辑阵列-PLA:与阵、或阵都可编程

图 2-1 是 PLA 的结构示意图,图中的×表示可编程的


熔丝连接。PROM、PAL 等的结构和 PLA 基本相同,只是
可编程的阵列不同,不同的具体型号的输出结构和输出电平
也略有区别,有的器件具有三态输出、寄存器输出、反馈输
入特性,进一步增强了器件的功能。下表列出了 PAL 器件
的编号方法,具体特性请参考器件手册或相关资料。

图 2-1 是 PLA 的结构示意图

表 2-1 常用 PAL 器件编号方法


结构代码 含义 器件编号
H 高电平输出有效 PAL10H8
L 低电平输出有效 PAL16L8
P 输出电平可编程 PAL16P8
R 带寄存器输出 PAL16R8
V 单元乘积项数目不同或宏单元输出 PAL20V8
例如,编号 PAL16H8 的 PAL 器件表示有最多可以有 16 个输入端,8 个输出端,输入输出端口可
组合编程,输出高电平有效。

§2.3 CPLD 的结构


PLD 器件的共同缺点是逻辑阵列规模小,每个器件仅相当于几十个等效门,不适用于较复杂的逻
辑电路的设计,并且也不能完全杜绝编程数据的非法抄袭。随着集成电路工艺的发展,PLD 的规模越
来越大,已经发展到百万门级的复杂可编程逻辑器件 CPLD(Complex Programmable Logic Device)系

― 4 ―
列,其中可擦除的 CPLD 有称为 EPLD(Erasable PLD)

表 2-2 ALTERA CPLD 主要产品

制造技术 EEPROM EEPROM SRAM EEPROM SRAM


系列 MAX5000 MAX7000 FLEX8000 MAX9000 FLEX10K
等效门 60-3750 60-5K 2.5K-16K 6K-12K 10K-100K
速度(MHz) 125MHz 178.6MHz 125MHz 125MHz 70MHz
最大传输延
10nS 5.0nS 8nS 8nS
迟 tpd(max)
逻辑单元
16-192 32-256 208-1296 320-560 576-4992
GLB
缓存器数 16-192 32-256 208-1500 484-772 720-53920
引脚数 84 164 84-208 168-216 150-406

CPLD 的发展十分快速,各半导体厂都有 CPLD 产品投入研发,如 ALTERA、ATMEL、CYPRESS、


LATTICE 及 XILINX 等。表 2-1 及表 2-2 列出了 ALTERA 及 ATMEL 生产的 CPLD 主要规格,若要详
细了解则可到各家厂商的网站查阅,网址如下:
ALTERA:http://www.altera.com
ATMEL:http://www.atmel.com
CYPRESS:http://www.cypress.com
LATTICE:http://www.latticesemi.com
XILINX:http://www.xilinx.com
表 2-3 ATMEL CPLD 主要产品
制造技术 Flash Flash SRAM SRAM SRAM
产品系列 ATF220V10CC AT6010 AT6005 AT6003 AT6002
等效门数 10K 5K 3K 2K
速度(MHz) 250MHz 250MHz 250MHz 250MHz
最大传输延迟
1.2nS 1.2nS 1.2nS 1.2nS
tpd(max)
逻辑单元 GLB 10 6400 3136 1600 1024
缓存器数 10 6400 3136 1600 1024
I/O 数 20 204 108 120 96

CPLD 不但提高了器件的密度,还改进了阵列宏单元的结构及 I/O 的控制结构。由于 CPLD 的 I/O 引


脚数量和 D 触发器数量大大增加,如果只采用一个与阵列,那么阵列的规模会急剧增大。而实际的设计
中每个与门的输入端常常不是很多,因此与门的利用率较低。此外,庞大的阵列还会增加电路的传输延
迟,降低工作频率。为克服上述缺点,CPLD 采用分区的阵列结构,把整个器件分成若干个区,每个区
都包括若干 I/O 端口,输入端和较小的与或阵列及宏单元,相当于一个小规模的 PLD;有的区只完成某
些特定的逻辑功能。各区之间通过可编程的全局互连总线连接,同一模块的电路一般安排在同一个区内,
因此只有少部分输入和输出使用全局互连总线,从而大大降低了逻辑阵列的规模,减小了电路传输延迟
时间。
由于工艺和生成厂家的不同,不同的 CPLD 的分区结构有较大的差别,这里我们介绍 ALTERA 公司的
灵活逻辑单元阵列结构(FLEX),如图 2-2 所示。它主要由嵌入式阵列块 EAB(Embedded Array Block)、
逻辑阵列块 LAB(Logic Array Block)、逻辑单元 LE(Logic Element)、I/O 单元 IOC(I/O Element)
和快速互连通道构成。

― 5 ―
图 2-2Altera 公司 FLEX10K 系列的 FLEX 结构图
逻辑单元 LE 是 FLEX 结构中最小的逻辑单元,每个 LE 含有一个提供 4 输入组合逻辑函数的查找
表(LUT-Look Up Table)
,能够快速产生 4 输入变量的任意逻辑函数输出。LE 还有一个带同步使能的
可编程寄存器和一个进位链、一个级联链,如图 2-3 所示。

图 2-3 Altera 公司 FLEX10K 系列 CPLD 的 LE 结构图


LE 中的可编程寄存器可以设置成 D、T、J-K 或 RS 触发器,该寄存器的时钟、置位和复位端可
由全局复位、LAB 控制信号 LABCTRL1-4 驱动。如果需要 LE 实现组合逻辑功能,可以将该寄存器旁
路。LE 产生两个输出,其中一个连接到快速互连通道,另一个连接到 LAB 的局部互连通道。这两个输
出可以独立控制。
每 8 个 LE 组成一组,构成一个逻辑阵列块 LAB。每个 LAB 是独立的模块,LAB 中的 LE 有共同
的输入、互连和控制信号。同一模块的逻辑电路一般安排在同一个 LAB 内。
嵌入阵列块 EAB 由 RAM/ROM 和相关的输入、输出寄存器构成,它可以实现大容量的片内存储器,
也可以编程作为复杂逻辑功能查找表,实现乘法器、微控制器、状态机等复杂的逻辑功能。
在 FLEX 结构中,LAB、EAB 排出行和列,构成二维逻辑阵列,内部信号的互连是通过行、列快
速互连通道和 LAB、EAB 内部的局部互连通道实现的。

― 6 ―
第三章 CPLD 实验系统

§3.1 CPLD 实验系统简介


本实验系统由 CPLD 下载板、I/O 实验板、RS-232 接口电路与电源等四部分构成,如图 3-1 所示。

CPLD 或
串口 I/O
FPGA
实验板
下载板

PC

图 3-1 CPLD 实验系统结构图


I/O 实验板是供基础实验用,板上有简单的输入输出器件,包括 LED、七段显示器、米字型显示器、
5×7 点矩阵显示器、DIP 开关、按键及振荡器、脉冲信号等,足以进行所有的基础实验。

七段显示器
16 个 LED 输

米字型 出状态显示

显示器
3 个 40
矩阵 PIN 的下
显示器 载板插座

连续可调
24bits
脉冲输出
DIP 开关

键盘
16 个 LED
脉波输出
输入/输出
按键
状态显示

图 3-2 I/O 实验板


本课程使用的 CPLD 下载板主要由一片 Altera 公司的 FLEX10K10、单片机、RAM、ROM 和 RS-232
接口组成。CPLD 下载板通过 3 个 40PIN 的接插件和 I/O 板相连。通过更换不同类型 CPLD 下载板和 I/O
实验板可以满足各种实验要求。图 3-2 是 CPLD 下载板的实物图。

RS-232 接口

CPLD 芯片

电源

复位
开关

图 3-2 CPLD 下载板的实物图

― 7 ―
电路设计完成后,由计算机通过 RS-232 串行口把数据传送到 CPLD 下载板,再由板上的单片机把
数据下载到 CPLD 内,完成 CPLD 的配置工作。
I/O 实验板上的输入输出器件和 CPLD 下载板上的 CPLD 芯片具有一定的连接关系,可以参考表 3-1。
I/O 实验板上的输入输出器件都有一个以 P 开头的编号,例如第一个输入指示 LED 是 P01,从表中可以
看出它和 CPLD 的第 3 脚相连。
表 3-1 I/O 板和 CPLD 芯片的连接关系
IO 板 P01 P02 P03 P04 P06 P07 P08 P09
CPLD 引脚 03 05 06 07 08 09 10 11
IO 板 P13 P14 P15 P16 P18 P19 P20 P21
CPLD 引脚 16 17 18 19 21 22 23 24
IO 板 P22 P23 P24 P25 P27 P28 P29 P30
CPLD 引脚 25 27 28 29 30 35 36 37
IO 板 P34 P35 P36 P37 P39 P40 P41 P42
CPLD 引脚 38 39 47 48 49 50 51 52
IO 板 P43 P44 P45 P46 P48 P49 P50 P51
CPLD 引脚 25 27 28 29 30 35 36 37
IO 板 P55 P56 P57 P58 P60 P61 P62 P63
CPLD 引脚 53 54 58 59 60 61 62 64
IO 板 P64 P65 P66 P67 P69 P70 P71 P72
CPLD 引脚 65 66 67 69 70 71 72 73
IO 板 P76 P77 P78 P79 P81 P82 P83 P84
CPLD 引脚 78 79 80 81 44 84 83
IO 板 I12 I31 I54 I73
CPLD 引脚 1 2 43 42

§3.2 I/O 实验板


I/O 实验板包括 LED、七段显示器、米字型显示器、5×7 点矩阵显示器、DIP 开关、按键及振荡器、
脉冲信号等输入输出器件,下面分别介绍。

3.2.1 DIP 输入开关


DIP 输入开关位于实验板的右下角,共 3 组 24 个输入开关,它们和 CPLD 的连接关系如表 3-2 所
示。DIP 开关向下时相应 CPLD 引脚接“0”
,反之接“1” 。和 DIP 开关 S1、S2 并联的还有 16 个 LED
(D1-D16)可以这些 DIP 开关的状态。

图 3-3 DIP输入开关配置图

― 8 ―
表 3-2 CPLD引脚与DIP输入开关的对应关系
代 号 S1-1 S1-2 S1-3 S1-4 S1-5 S1-6 S1-7 S1-8
CPLD引脚 03 05 06 07 08 09 10 11
代 号 S2-1 S2-2 S2-3 S2-4 S2-5 S2-6 S2-7 S2-8
CPLD引脚 38 39 47 48 49 50 51 52
代 号S3-1 S3-2 S3-3 S3-4 S3-5 S3-6 S3-7 S3-8
CPLD引脚 25 27 28 29 30 35 36 37

3.2.2 输出指示 LED


16 个输出指示 LED 位于实验板的右上角,它们和 CPLD 的连接关系如表 3-3 所示。这些 LED 完全
用来指示 CPLD 引脚的输出电平,并且是通过 CD40106 缓冲驱动,几乎不会有负载效应。
表 3-3 CPLD 引脚与输出指示 LED 的对应关系
代 号 P55 P56 P57 P58 P60 P61 P62 P63

CPLD引脚 53 54 58 59 60 61 62 64

代 号 P64 P65 P66 P67 P69 P70 P71 P72

CPLD引脚 65 66 67 69 70 71 72 73

3.2.3 七段 LED 显示器


实验板的左上角是 6 个七段 LED 显示器(DP1-DP6),可以接成扫描方式或独立显示方式。本实
验仅需要使用最左面的两个七段 LED 显示器,并且工作在独立显示方式,它们和 CPLD 的连接关系如
下表所示。
表 3-4 CPLD 引脚与七段 LED 显示器的对应关系
代 号 DA1 DB1 DC1 DD1 DE1 DF1 DG1 DP1

名称 DP1 七段显示器

CPLD引脚 16 17 18 19 21 22 23 24

代 号 DA2 DB2 DC2 DD2 DE2 DF2 DG2 DP2

名称 DP2 七段显示器

CPLD引脚 25 27 28 29 30 35 36 37

图3-4 七段显示器段位示意图
注:七段显示器DP2 不能和DIP输入开关S3 同时使用。

― 9 ―
3.2.4 脉冲信号发生器
I/O 实验板的正下方是四个按钮式脉冲信号发生器(SWP1-SWP4),其中 SWP4 不能用,它们和 CPLD
的连接关系如下表所示。SWP1-4 在没有按下时接“0” ,按下时接“1” ,四个按钮都经过了噪声消除
处理,每按一次产生一个高电平脉冲,非常适合作为计数器、缓冲器等调试时的时钟输入使用。

表 3-5 CPLD 引脚与按钮式脉冲信号发生器的对应关系


代 号 SWP1 SWP2 SWP3 SWP4

CPLD引脚 44 84 83

连续脉冲信号发生器由 CD40106 作 RC 振荡器,分两段产生低频和高频时钟,由半可调电位器 F1、


F2 调整输出频率。其中 F1 的调整范围是 1KHz 到 1MHz,F2 的调整范围是 1Hz 到 1KHz。F1 输出接到
CPLD 的第 2 脚,F2 输出接到 CPLD 的第 42 脚。

3.2.5 米字型显示器、矩阵键盘、点阵显示器
本实验未使用,在此不作介绍。请参考相关的使用手册。

― 10 ―
第四章 VHDL 简介

§4.1 VHDL 的特点


随着电子设计计术的高速发展,电路的复杂度越来越高,产品的更新速度越来越快,原理图输入的
方法已经不能满足工业界对设计能力的要求。VHDL(Very High Speed Integrated Circuit Hardware
Description Language)是美国国防部 1983 年提出的一种硬件描述语言,它可以描述硬件的结构和行
为,通过采用 EDA 工具自动综合出电路结构,极大地提高了设计能力。VHDL 设计方法有以下几个优点:
1. 可以直接描述电路的行为,由 EDA 工具综合出电路,设计速度快。
2. 工艺无关性。设计人员不必过多关心具体的工艺,由 EDA 工具自动针对具体的工艺综合出电路。
同时设计具有非常高的可移植性,这是原理图输入法不可比拟的。
3. 设计文件可读性好

§4.2 VHDL 的设计流程


和原理图输入法不同,CPLD/FPGA 的 VHDL 设计流程如下图所示。

行为级/RTL级
VHDL代码

改正错误 综合、布局布线


正确 ?

电路拓扑

仿真


正确 ?

下载到CPLD验证

图 4-1 CPLD/FPGA 设计流程

设计流程主要包括以下几步:
1. 写设计文件。按照自顶向下的方法将系统分解为不同的模块,采用行为描述或结构描述的方法
设计各个模块。
2. 综合、布局布线。由 EDA 工具根据具体的 CPLD 工艺,编译设计文件,产生电路结构,并完成
布局布线,最后产生可下载到 CPLD 的数据文件。
3. 仿真。在计算机上对 EDA 工具产生的电路进行模拟,验证电路的功能、时序是否达到设计要求。
4. 下载到 CPLD 验证。仿真验证了设计的功能正确后,最后下载到 CPLD 芯片中,配合外围电路验
证整个系统的功能。

― 11 ―
§4.3 VHDL 的基本语法
VHDL 语言是一种比较复杂的语言,它可以在不同的抽象层次描述一个电路,在这里仅介绍本实验
所需要的最基本的语法。在 CPLD 设计中,RTL 级(寄存器传输级)模型是最常用的模型,它描述数据
在寄存器之间的流动方式。
4.3.1 VHDL 程序的结构
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

ENTITY counter IS
PORT (
A,B,CLK: in std_logic;
D: out std_logic);
END;

ARCHITECTURE behav OF counter IS


SIGNAL E: std_logic;
BEGIN

--------------------------------------------------
E <= A and B;

--------------------------------------------------
PROCESS (CLK)
BEGIN
IF CLK’event and CLK=’1’ THEN
D <= E;
END IF;
END PROCESS;

END;
图 4-2 一个 VHDL 程序
图 4-2 是一个基本的 VHDL 程序,它包括三个基本部分:
1.库定义。
库类似 C 语言的头文件,在库里定义了一些常用的数据类型、函数等,本实验课程使用如下的库就足
够了:
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
2.实体定义。
实体定义了电路的端口和输入输出信号的名称、类型、宽度等,语法如下:
ENTITY 电路名称 IS
PORT (
信号 1,信号 2: in std_logic;
信号 3,信号 4: in std_logic_vector(7 downto 0);
信号 5,信号 6:out std_logic );
END;
其中 in 或 out 表示该信号是输入还是输出,本实验中信号的类型可以都使用 std_logic 类型,矢
量型信号必须用(n downto m)的方式,例如上例中信号 3 是一个 8 位总线。
3. 结构体
结构体定义了电路的内部结构,包括电路内部的信号,各个模块的结构描述和行为描述,语法如下:
ARCHITECTURE 结构名 OF 实体名 IS
SIGNAL 内部信号 1,2,3: std_logic;
BEGIN
模块 1
模块 2
……
END;

其中结“构体名”可以随便起,一般命名为“behav”;内部信号用 SIGNAL 关键词定义,定义规则


― 12 ―
和端口的定义一样。内部信号只能在 ARCHITECTURE 和 BEGIN 关键词之间定义。图 4-2 中有两个模块,
一个是结构描述类型的与门,一个是行为描述类型的 D 触发器。

4.3.2 数据类型
VHDL 支持多种数据类型,本实验用到的常用类型有:
1.9 值逻辑 std_logic。
它把信号线上的电平描述成“1”, “0”, “X” ,“U” ,
“Z”等,其中“X” ,
“U”表示不定值,
“Z”表
示高阻。
2.矢量类型 std_logic_vector
矢量类型用于方便地描述总线信号,它也是 9 值逻辑,使用时必须指定矢量的宽度,一般从高到低,
例如:
signal x: std_logic_vector(3 downto 0);
表示 x 是一个四位总线,由信号 x(3),x(2),x(1),x(0)构成。
3.整型 integer
整型信号主要用作状态信号、计数信号或数组的下标。整形信号使用时必须指定数值范围,通常是
从小到大,例如:
signal y: integer range 0 to 15;
矢量信号可以通过转换函数 CONV_INTEGER 转换成整形,例如:
y <= CONV_INTEGER(x);
4. 自定义类型
在使用 RAM、ROM 或寄存器堆时需要定义数组,语法如下:
type instr is array (0 to 15)of std_logic_vector(7 downto 0);
signal IRAM: instr;
上例首先定义了 instr 数据类型是一个 8 位的矢量数组,数组容量是 16;然后用该数据类型定义
了信号 IRAM。因此 IRAM 信号实际上是一个容量为 16 的 8 位数组,可以作为 RAM、ROM 或寄存器堆。

4.3.3 数据操作
1.赋值(<=)
相同数据类型的信号可以赋值,结构体内的赋值语句相当于信号线的连接。例如:
signal x: std_logic_vector(3 downto 0);
signal y,z: std_logic;
y <= x(3);
x(3) <= x(2);
y <= z;
y <= ‘1’;
x <= “0010”;
以上三句表示了这些信号线之间的连接关系。
2.逻辑操作(AND、OR、NOT、NAND、NOR、XOR、XNOR)
逻辑操作可以描述信号的逻辑关系,例如:
y <= not (x(1) nand x(2) or x(3));
3.比较操作(=、/=、 <、>、<=、>=)
比较操作常用于条件赋值语句和条件分支语句,将在以后详细介绍。其中/=表示“不等于”。
4. 拼接操作(&)
拼接操作可以把两个信号拼接成一个新的矢量信号,例如:
x(3 downto 2) <= x(1) & x(0);

― 13 ―
4.3.4 并行赋值语句
当赋值语句直接出现在结构体中时表示并行赋值语句,它直接表示了信号的连接关系或描述了一个
电路模块(组合逻辑电路) 。所有的语句在仿真时都是并行执行的。

4.3.5 进程语句
进程语句定义了一个电路模块,进程内部是模块的行为描述。语法如下:
PROCESS (信号 1,信号 2,…)
BEGIN
行为描述语句;
END PROCESS;
其中 PROCESS 语句后的信号列表指进程的敏感表,一般情况下把整个 PROCESS 用到的所有输入信号
都列到敏感表中,除非该进程是一个由信号边沿触发的进程。和并行赋值语句不同,在进程内部的行为
描述语句在仿真时都是顺序执行的。这里仅介绍赋值语句、条件分支语句、CASE 语句,它们的语法如下:
条件分支语句语法:
If 条件 then If 条件 then If 条件 1 then
语句; 语句; 语句;
else end if; elsif 条件 2 then
语句; 语句;
end if; else
语句;
end if;
条件分支举例:
If LOAD = ‘0’ then
Q <= Q+1;
else
Q <= QLOAD;
End if;
CASE 分支语句语法:
Case 信号 is
When 值 1 =>
语句;
when 值 2 | 值 3 | … => -- “|” 表示“或”
语句;
when others =>
语句;
End case;
条件分支举例:
case OP is
when “00” =>
Q <= Q+1;
When “01” | “10” => --OP 为“01”或“10”
Q <= QLOAD;
When others =>
Q <= “0000”;
End case;

4.3.6 元件(COMPONENT)
在 VHDL 程序中可以直接使用已经设计好的电路模块,称为“元件”。元件在使用前要在结构体的
ARCHITECTURE 和 BEGIN 关键词之间用 COMPONENT 关键词事先声明(和内部信号的定义类似)
。在下文的
ROM 和 RAM 部分将举例说明。

4.3.7 注释
VHDL 程序的注释行以“--”为开始标志,可以位于程序的任何位置。

§4.4 VHDL 的电路设计技术


任何一个电路都可以分解为很多模块的互连,这些模块可以用 VHDL 语言在同一个结构体中分别用
― 14 ―
并行赋值语句或进程来描述。下面将分别介绍各种电路单元的 VHDL 描述。

4.4.1 组合逻辑电路
简单组合逻辑电路既可以并行赋值语句,也可以用进程描述。简单组合逻辑电路一般可以用一个布
尔方程表示,例如三输入与门:F=A•B•C
并行赋值语句:
F <= A and B and C;
进程:
process(A,B,C)
begin
F <= A and B and C;
End process;
或:
process(A,B,C)
begin
if A=’1’ and B=’1’ and C=’1’ then
F <= ‘1’;
Else
F <=’0’;
End if;
End process;
并行赋值语句适用于可以用简洁的布尔方程表示的组合逻辑电路。如果逻辑关系复杂,难以用布尔
方程表示,则可以用进程实现,在进程中用条件分支语句和 CASE 语句直接描述电路的逻辑功能。
注意:要实现组合逻辑电路,所有的条件分支必须写全。

4.4.2 触发器(D 触发器)


D 触发器的功能可以如下描述:
1.如果有异步复位(置位)端,当复位信号有效时,输出端被复位或置位。复位(置位)端的优
先级比时钟端高。
2.在时钟信号的上升沿(下降沿)把输入数据打到输出端。
3.其它时候输出保持不变。
D 触发器只能用进程实现,在进程的敏感表中只需有异步复位和时钟信号。下面的例子是一个典型
的 D 触发器,它有两个分支分别描述触发器的第 1 个和第 2 个两个功能,在其它情况下 Q 保持不变。
process(RST,CLK)
begin
if RST=’1’ then
Q <= ‘0’;
Elsif CLK’event and CLK=’1’ then --时钟上升沿
Q <= D;
End if;
End process;

4.4.3 锁存器(Latch)
锁存器的功能可以如下描述:
1. 如果使能端有效时,输入信号被输出到输出端。
2.使能端无效时输出保持不变。
锁存器只能用进程实现,在进程的敏感表中应包括所有用到的输入信号。下面的例子是一个典型的
锁存器,它用一个分支描述锁存器的锁存功能,在其它情况下 Q 保持不变。和 D 触发器的区别是,锁存
器没有边沿型的分支。
process(LE,D)
begin
if LE=’1’ then
Q <= D;
End if;
End process;

― 15 ―
4.4.4 寄存器堆
寄存器堆是一组寄存器,由于寄存器堆的速度快,常被 CPU 用来作数据缓冲。下例中的 REG 数组是
一个 8 位的寄存器堆,其功能可以描述为:在写信号 WR 有效时把数据 D 写入到地址为 REG_ADDR 的寄存
器中。
signal REG_ADDR: std_logic_vector(1 downto 0);
signal D:std_logic_vector(7 downto 0);
type com_reg is array(0 to 3) of std_logic_vector(7 downto 0);
signal REG: com_reg;
process(CLK)
begin
if CLK’event and CLK=’1’ then
if WR=’1’ then
REG(CONV_INTEGER(REG_ADDR)) <= D;
End if;
End if;
End process;
本实验要求寄存器堆用 RAM 实现。

4.4.5 RAM
RAM 有很多种类,如同步 RAM、异步 RAM、双端口 RAM、单口 RAM 等。在 CPLD 设计中最常用的是输
入输出数据总线分离的单口同步 RAM。
本实验使用 Altera 公司提供的元件 LPM_RAM_DQ 来实现 RAM 和寄存器堆,它在 we 为高电平时,在
时钟的上升沿把 data 口的数据写入 RAM 的 address 单元,在输出端口 q 输出 address 单元的数据。使
用时首先采用以下方式需要声明。注意,将 lpm_width、q、data 修改为需要的数据宽度,lpm_widthad、
address 修改为需要的地址线宽度。
ARCHITECTURE …….
…….
COMPONENT lpm_ram_dq
GENERIC (
lpm_width : NATURAL := 8;
lpm_widthad : NATURAL := 8;
lpm_indata : STRING := "REGISTERED";
lpm_address_control : STRING :="REGISTERED";
lpm_outdata : STRING :="UNREGISTERED";
lpm_hint : STRING :="USE_EAB=ON"
);
PORT (
address : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
inclock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
we : IN STD_LOGIC
);
END COMPONENT;
…….
BEGIN
……
在结构体的 BEGIN 关键词后用 PORT MAP 关键词将 RAM 连接到内部信号或端口上
BEGIN
……
local_ram_name : lpm_ram_dq --local_ram_name 是为这个 RAM 起的名字
PORT MAP (
address => local_address, --local 开头的信号都是 RAM 连接到的内部信号
inclock => clock,
data => local_data,
we => local_we,
q => local_q
);
……

― 16 ―
4.4.6 ROM
ROM 中的内容是固定不变的,可以用如下的进程实现:
process(OE,ADDR)
begin
if OE = ’1’ then
case ADDR is
when “00” => DOUT <= “00000000”;
when “01” => DOUT <= “00000001”;
when “10” => DOUT <= “00000010”;
when others => DOUT <= “00000100”;
end case;
end if;
End process;

本实验使用 Altera 公司提供的元件 LPM_ROM 来实现 ROM,它在输出端口 q 输出 address 单元的数


据。使用时首先采用以下方式需要声明。注意,将 lpm_width、q 修改为需要的数据宽度,lpm_widthad、
address 修改为需要的地址线宽度。lpm_file 指向 ROM 的初始化文件(以 mif 为后缀) 。
ARCHITECTURE …….
…….
COMPONENT lpm_rom
GENERIC (
lpm_width: positive := 8; -- 数据宽度
lpm_type: string := "lpm_rom";
lpm_widthad: positive := 4; -- 地址宽度
lpm_file: string := "./rom.mif"; -- ROM 内容的初始化文件
lpm_address_control: string := "UNREGISTERED";
lpm_outdata: string := "UNREGISTERED"
);
PORT (
address: IN std_logic_vector(3 downto 0); --地址宽度
q: OUT std_logic_vector(7 downto 0) --数据宽度
);
END COMPONENT;
…….
BEGIN
……
在结构体的 BEGIN 关键词后用 PORT MAP 关键词将 ROM 连接到内部信号或端口上
BEGIN
……
local_rom: lpm_rom --local_rom 是为这个 ROM 起的名字
PORT MAP (
address => local_address, --local 开头的信号都是 ROM 连接到的内部信号
q => local_q
);
……
ROM 初始化文件的格式如下(rom.mif):
depth = 16 数据个数
width = 8 数据宽度
address_radix = hex 地址以十六进制表示
data_radix = bin 数据以二进制表示
content
begin
0: 11001001; 地址:数据内容; (以;结束一行)
1: 10010000;
2: 10000100;
3: 11001001;
4: 10011010;
5: 10011111;
6: 00010000;
7: 11101011;
8: 01000110;
9: 00101111;
a: 11010110;
b: 11000111;

― 17 ―
c: 11000110;
d: 11010000;
e: 11110100;
f: 11110100;
end

参考资料

1. 《CPLD 系统设计技术入门与应用》,黄正谨等,电子工业出版社。
2. 《VHDL 硬件描述语言与数字逻辑电路设计》,侯伯亨等,西安电子科技大学出版社。
3. 《可编程 ASIC 设计及应用》,李广军,孟宪元,电子科技大学出版社。
4. 《可编程器件应用导论》,曾繁泰等,清华大学出版社。
5. 《XILINX 数字系统现场集成技术》,乐明程,东南大学出版社。
6. 《CPLD 技术及其应用》,宋万杰等,西安电子科技大学出版社。
7. 清华大学图书馆,检索关键词“微处理器”,“微处理机”等。

― 18 ―
实验一 四位同步二进制计数器设计
一、实验目的
熟悉使用 MAXPLUS II 的图形输入工具和 VHDL 语言设计时序电路的基本操作。
二、实验内容
1. 采用图形输入工具设计四位同步二进制计数器。
2. 绘制激励波形
3. 功能仿真
4. 采用 VHDL 语言重新设计计数器,重复 2、3 步骤

实验二 用 VHDL 语言设计七段译码器


一、实验目的
使用 VHDL 语言设计七段译码器,掌握组合逻辑电路的设计方法。
二、实验内容
1.设计七段译码器,输入为 4 位 BCD 码,输出 7 段译码器电路的输入输
出端口如附图所示。
2.绘制激励波形
3.功能仿真

实验三 综合下载实验
一、实验目的
使用 VHDL 语言进行较完整的设计,验证功能后,下载到可编程逻辑实验板。
二、实验内容
1. 结合实验 1 和实验 2,把 4 位计数器的结果用七段显示器显示。
2.绘制激励波形
3.功能仿真
4.下载到 CPLD 板,用 7 段 LED 显示器显示计数结果

实验四 秒表

设计要求:
1. 设计一个秒表,可以从 0-59 计数或倒计数。
2. 可以用一个键启动计数和暂停计数;一个键控制加计数或减计数;一个键清零
3.功能仿真
4.下载到 CPLD 板,用两位 7 段 LED 显示器显示。

― 19 ―
实验五 简单微处理器的设计与实现

一、设计任务和技术指标
运用在“数字电路与逻辑设计”课程中学过的基本理论知识,设计并用可编程逻辑器件实现一个简
单的八位操作数的微处理器。完成微处理器硬件系统设计和指令系统设计两方面的任务,使微处理器能
够实现两个不带符号位的八位二进制数原码相乘等功能。

二、简单微处理器介绍
1.微处理器硬件系统及原理
微处理器硬件系统包括运算器、控制器、存储器以及其它必要的逻辑部件。图 4-1 是一个微处理器
的参考原理框图,具体说明如下:
(1) 程序计数器 PC:存放将要执行指令的地址。
(2) 指令存储器 IROM,存放程序指令,每条指令的长度为 W,指令的个数为 L。
(3) 指令寄存器 IR:存放被执行指令的操作码,直接供运算控制器。
(4) 控制器 CON:产生一系列时序逻辑信号,控制微处理器各个部件协调一致地完成每条指令
相应的操作,实现两个操作数的运算。
(5) 通用寄存器堆 R0-R7:用来临时存放运算过程中读出和写入的数据。
(6) 缓冲寄存器 RS 和 RD:用于存放 ALU 的两个输入操作数。
(7) 运算器 ALU 和进位寄存器 C:运算器 ALU 对两个操作数 RS 和 RD 进行加、减或逻辑运算
处理,在进行加减运算时还接受控制器的进位输入信号 CI,ALU 的运算结果送给通用寄存
器或特殊寄存器。ALU 还根据运算结果设置进位标志 C 和零标志 Z。
(8) 运算结果显示送七段数码管显示,用十六进制显示。

PC R0…R7
Rin1,Rin2
程序计数器 通用寄存器堆
特殊寄存器 输入
4 8 (输入)
Log2L
8
IROM(L×W)
指令存储器 RS RD

W
Rout
8 8 特殊寄存器 输出
(输出)
IR
ALU
指令寄存器
CI 运算器
W

CON C Z
控制器

图 4-1 简单微处理器框图

2.处理器指令系统及功能
处理器的基本指令字长为 W 位,指令的每一位从高到低用 DW、DW-1、…D1、D0 表示,有些微处
理器的一条指令包括多个指令字长,即每条指令的长度不一样,例如 Intel 的 80386 等。本实验为了简
化设计,规定所有的指令都是单指令字的指令,即所有指令的长度都是 W。基本的指令系统一般包括

― 20 ―
三类指令:数据传送指令、算术逻辑运算指令和转移指令。每条指令又有多种对操作数的寻址方式。
本实验只要求掌握立即数寻址和直接寻址方式。例如下表中 OP 表示要进行的操作,立即数表示操作
数为常数,D、S 是直接寻址的地址,表示要寻址的通用寄存器的地址, ADDR 表示要跳转到的地址。
OP 字段的长度主要由指令种类的数量决定,但不同类型的指令的 OP 字段的长度也可以不同。D、
S 字段的长度主要由寄存器的个数决定。ADDR 的长度主要由容许的程序最大长度决定。
表 4-1 指令格式
立即数寻址指令 OP D 立即数
直接寻址指令 OP D S
转移指令 OP ADDR

2.1 数据传送指令
数据传送指令在两个通用寄存器或者通用寄存器和特殊寄存器直接传送数据,或者为通用寄存器装
载一个常数,常用的指令可以用以下助记符表示:
MOV Dest_Reg, Source_Reg 将 Source_Reg 的内容传送到 Dest_Reg
MOV Dest_Reg, #Constant 将常数 Constant 装载到 Dest_Reg

2.2 算术逻辑运算指令
这类指令控制 ALU 执行两个寄存器之间的运算操作。通常微处理器还具有一些状态寄存器,它们
由 ALU 的运算结果设置。在表 4-1 的指令格式里,S 和 D 字段指定了两个寄存器。OP 字段规定了在 S
和 D 之间执行的操作种类,并将结果保存到 D 寄存器。
ALU 还根据运算结果设置进位标志 C 和零标志 Z。即如果运算结果有进位,则设置进位标志 C=1,
如果运算结果为零,则设置零标志 Z=1。
常用的指令可以用以下助记符表示:
表 4-2 算术逻辑运算指令助记符
助记符 功能
ADD D = S+D
ADDC D = S+D+C
INC D = D+1
DEC D = D-1
SUB D = D–S
SUBB D=D–S–1
AND D = D and S
OR D = D or S
XOR D = D xor S

假设微处理器共有 64 条不同的指令,定义 OP 字段长 6 位,分配给 ADD 指令的 OP 是 100111,D、S


字段都是 4 位,那么指令字长就是 14 位。
对于指令 ADD R3, R6,
它的指令码应该是“100111-0011-0110”。

2.2 转移指令
转移指令分为无条件转移和条件转移指令。条件转移指令可以根据进位标志 C、零标志 Z 的状态
控制程序的流程,常用的指令助记符如下:

表 4-3 转移指令助记符
助记符 说明
JMP 无条件跳转到(ADDR)

― 21 ―
JC 如果 C=1 就跳转到(ADDR)执行,否则继续执行
JNC 如果 C=0 就跳转到(ADDR)执行,否则继续执行
JZ 如果 Z=1 就跳转到(ADDR)执行,否则继续执行
JNZ 如果 Z=0 就跳转到(ADDR)执行,否则继续执行

3. NOP 指令
空操作指令,不执行任何动作。

4.处理器的设计
为实现上述处理器的功能,每条指令运行需要若干个时钟周期,称为机器周期。通常周期“0”为
“取指令”阶段,其余周期为“执行”阶段,例如可以安排周期“1”取 S 操作数,周期“2”取 D 操
作数并运算,周期“3”将运算结果保存回 D。

三、实验要求:
1. 参考并修改图 4-1 的框图设计能够处理八位操作数的微处理器系统,画出必要的电路结构示意图、
状态转移图。设计微处理器的指令系统(指令助记符、指令编码方式) ,至少包括数据传送指令、
算术运算指令、逻辑运算指令和转移指令的每一类指令中的一条或若干条。确定每条指令执行所需
的指令周期数,合理分配各个指令周期。

2. 要求 IROM 和寄存器堆(R0…R7)用 LPM 实现。

3. 合理安排系统应有的输入、输出开关,下面是建议使用的开关。
①“复位”开关——用于系统复位和清除 PC,并从零地址开始执行程序。
③“单步/连续”开关——为了能够调试检查处理器的运行情况,用这个开关来选择连续脉冲时钟
或单脉冲时钟。
④“单脉冲”按钮——单步工作时,产生时钟单脉冲。
⑤“数据输入”开关——8 位开关,用于输入 8 位数据。
⑥“数据显示”——七段显示器,显示指令执行的结果。
⑦“PC”显示——七段显示器,显示 PC 的内容。
⑧“指令码显示”——八个发光管,显示指令码,方便调试。

4. 参考下表编写乘法程序测试你的系统。
为验证处理器的功能,编写一个两个无符号位的八位二进制数相乘的程序,乘积为 16 位,将程序
保存于指令存储器(IROM)中。在运行程序时注意:
A. 为输入乘数或被乘数,应该首先将输入开关 S7-S0 置为乘数或被乘数,然后按下输入键,使程
序读入数据。
B. 由于输入键按下的持续时间一般大于指令周期,因此必须由硬件或软件对输入键进行处理,以
免将按下一次输入键误识为按下多次输入键。

表 4-7 乘法程序
PC 程序
指令码 操作 说明
显示 地址
0 000000 SUB R3,R3 R3 ← 0
1 000001 P0: MOV R1,Rin1 R1 ← Rin1,输入乘数
2 000010 MOV R2,Rin2 R2 ← Rin2,检测按下输入键
3 … SUB R2, R3 R2 ← R2 - 0
4 … 如果 R2 等于 0(没有按下输入键),跳转到 P0
JZ P0
执行,等待按下输入键
5 P1: MOV R4,Rin1 R4 ← Rin1,输入被乘数
6 MOV R2,Rin2 R2 ← Rin2,检测按下输入键
7 SUB R2, R3 R2 ← R2 - 0

― 22 ―
8 如果 R2 等于 0(没有按下输入键),跳转到 P1
JZ P1
执行,等待按下输入键
9 R1 =乘数,R4 =被乘数,下面进行乘法计算。
… … … … …

5. 在微机上完成功能仿真,正确后,在实验板上完成逻辑设计下载。

6. 认真写好实验报告,应包括如下内容:
① 实验目的。
② 处理器设计方案、指令系统、各部分工作原理说明及框图。
③ 关键的仿真波形及分析
④ 实验课总结、体会及意见。

实验六 小组合作实验
一、实验目的
本实验可以由 2-5 人合作完成。在实验五的基础上修改指令集,使之能够运行相对复杂的程序。
二、设计要求
1. 修改指令集,使之能够支持更多、更复杂的指令。
2. 自行编写程序,四则运算或其它复杂运算。
3. 合作完成实验报告。

― 23 ―
附件 1:

Max Plus II 软件使用介绍(VHDL)


一、设计流程
Max Plus II 是 Altera 公司为其 CPLD 芯片设计的集成化专用开发工具,适用于 Classic,MAX3000,
MAX7000,MAX9000,FLEX6000,FLEX8000,FLEX10K,ACEX1K 系列芯片的开发。Maxplus 支持
多种设计输入方法:原理图输入、VHDL、Verilog 和 OrCAD、SYNOPSYS 等多种第三方 EDA 工具的
网单,集成了编译、仿真、时序分析和对器件编程多种功能。下面将结合一个 4 位计数器的设计简单介
绍 MaxPlus II 的使用,详细的使用说明请参考 Altera 公司的使用手册。
Maxplus II 的设计流程如下图:

设计输入

修改设计

编译设计

功能仿真

时序仿真

器件编程

系统内仿真

完成

二、VHDL 设计举例(4 位计数器)


设计内容:
用 VHDL 设计实现一个可预置的同步加减 4 位计数器,计数范围 0-15;
输入: DataIn : 计数器预置值
CLK : 时钟
CLEAR : 同步清零信号
CS : 片选信号
LOAD : 设置计数器初值信号
UpDown : 设置计数方向(加,减)
输出: DataOut : 计数器输出值

1.双击桌面上 Max Plus II 图标,进入 Maxplus 使用界面:

― 24 ―
层次化浏览器 编程器

编译器 仿真器 时序分析

2.选择 FILE-> New 菜单,弹出下图所示对话框,选择 Text Editor file, 点击 OK。

3.在文本编辑窗口中输入下列 VHDL 代码
LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY counter IS
PORT (
DataIn : IN INTEGER RANGE 0 TO 15;
CLK,CLEAR,CS,LOAD,UpDown: IN STD_LOGIC;
DataOut : OUT INTEGER RANGE 0 TO 15 );
END counter;

ARCHITECTURE behavior OF counter IS


SIGNAL nCount: INTEGER RANGE 0 TO 15;
BEGIN
PROCESS (CLK, CLEAR)
BEGIN
IF CLEAR= '0' THEN
nCount<= 0;
ELSIF (CLK'EVENT AND CLK= '1') THEN
IF LOAD= '1' THEN
nCount<= DataIn;
ELSE
IF CS= '1' THEN
IF UpDown = '1' THEN
nCount<= nCount + 1;
ELSE
nCount<= nCount - 1;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
DataOut<= nCount;
END behavior;

4.选择 FILE -> Save 菜单, 在 File Name 中输入 counter.vhd(文件名必须和 VHDL 代码中的实体名称
― 25 ―
一致,以 vhd 为后缀),选择适当的目录(Directories)
,点击 OK。

5. 选择 FILE -> Project -> Set Project To Current File 菜单,把 counter 设置为当前项目,这样我们就完
成了设计的输入。

6. 选择 Assign -> Device 菜单,选择芯片


根据实际应用的需要选择芯片的类型和型号。如果不选择芯片,MAXPLUS II 将自动根据设计的大
小选择最合适的芯片。本实验 Device Family 选择 FLEX10K,Devices 应选择 EPF10K10LC84-3。

7. 选择 MAX+plus II -> Compiler 菜单,点击 Start,检查、编译设计。如果设计文件有错误,返回第 3


步修改设计。

8. 选择 Max+Plus II -> Waveform Editor 菜单,绘制激励波形图为仿真作准备。

― 26 ―
9.选择 Node -> Enter Node From SNF…菜单,点击对话框中的 List 按钮,以选择需要在波形编辑器中
出现的信号名称。选择信号 UpDown(I), LOAD(I), CS(I), CLK(I), CLEAR(I), DataIn(I), DataOut(O)到右边
的列表框内,点击 OK。

11.选择 Option -> Grid Size 菜单,将格点(即半个时钟周期)设为 100.0 ns。

改为 100.0 ns

12.设定各个输入信号的波形,如下图所示。
设定输入信号波形的方法如下:首先用鼠标左键按下并拖拉以选定需要改变的信号的范围,然后选
择窗口左边的快捷按钮,设定信号为 0、1、X 或 Z。本实验需要设置 CS 和 CLEAR 为 1,CLK 为
时钟。

― 27 ―
按下左键 拖拉至此
看完整的 释放左键
波形

设为 0,1,X,Z

设为时钟

13.如果需要,可选择 File -> End Time …菜单改变仿真时间长度。

14.选择 File -> Save 菜单,保存波形图,文件名必须以 scf 为后缀。


15.选择 Maxplus II->Simulator 菜单,点击 Start 开始仿真。

要仿真的波形文件名

不要选择这些选项

16.观察输出波形,检查电路功能是否正确。返回第 12 步修改激励波形重新仿真,直到验证电路功能
正确。

17.选择 Assign->Pin/Location/Chip 菜单,为输入、输出信号指定芯片引腿


根据实际应用的需要为输入、输出信号指定芯片引腿,如果不指定,MAXPLUS II 将自动为输入、
输出信号指定芯片引腿。可以直接在 Node Name 栏输入指定信号名称,也可以按“Search”按钮弹
出右边的对话框,按“List”按钮显示并选择合适的信号,最后在左边对话框的“Pin”下拉列表里
选择相应的引腿并按“Add”按钮完成。

― 28 ―
18.重复步骤 7,再次编译一遍。

19.性能分析
选择 Maxplus+II->Timing Analyzer,在 Analysis 菜单中可以选择“Delay Matrix”,“Setup/Hold

Matrix”“Registered Performance”
,进行延时分析、建立保持时间分析和工作频率分析。

20.下载
MAXPLUS 编译通过后会产生一个以 hex 为后缀的文件,这个文件就是用来下载的数据文件。本次
实验使用的是装载有 EPF10K10 芯片的 CPLD 下载板,不能用 MAXPLUSII 自带的下载工具将数据下载
到这种开发板上,而要使用另一种专用的下载程序 DNLD102.EXE,在电工电子中心计算机的桌面上可
以找到这个下载工具。下图是该程序的界面。具体使用步骤如下:
(1) 选择 Option->Com Port 菜单,设置使用计算机的串口 1 或串口 2 和 CPLD 下载板通信。
(2) 选择 Option->Reset Com 菜单,复位串口。
(3) 按左边列表框下面的“Dir”按钮,如果设置正确,列表框中会有一些文字出现;否则请检查电
缆、电源和串口的设置是否正确,并按下载板上的复位按钮。
(4) 在右边的列表框里选择设计文件所在的目录。
(5) 在中间的列表框里选择需要下载的数据文件,按“Config”按钮下载。
(6) 在 I/O 实验板上设置相应的输入信号,检查输出是否符合设计要求。

― 29 ―
附件 2:

Max Plus II 图形输入法设计 4 位二进制全加器


1.全加器功能说明:
输入端:
A3、A2、A1、A0 和 B3、B2、B1、B0 分别代表两个四位二进制数(由高位到低位排列)。C0
为进位输入端。
输出端:
S3、S2、S1、S0 为和的四位输出(由高位到低位排列) 。C 为进位输出端。
2.全加器的仿真步骤:
1) 双击桌面上 Max Plus II 图标,进入 MAX+plus II Manager 管理器。

2) 单击 FILE 菜单,选择 New 选项,弹出新建对话框,如下图所示。选中 Graphic Editor file(图


形编辑文件)单选框。其后是文件保存后缀,有两种:一种是 gdf,另一种是 sch,前者是 Max
Plus II 的图表文件格式,后者是 OrCAD 的图表文件格式,这样做的目的是为了方便与 OrCAD
的兼容。然后单击 OK 按钮。

― 30 ―
3) 在下面图示中图形编辑窗口中可以直接绘制原理图。

插入元件有如下几种方式:
a) 选择 Symbol 菜单下的 Enter Symbol 选项;

b) 在图形编辑窗口中双击鼠标左键;
c) 在图形编辑窗口中单击鼠标右键,在弹出的菜单中选择 Enter Symbol 选项。

― 31 ―
这几种方式都可以进入 Enter Symbol 对话框:

在 Symbol Libraries
(元件库)中选择 d:\maxplus2\max2lib\prim,并双击,
这时在左下侧的 Symbol Files
中出现元件列表。从中选择所需的元件,然后单击 OK 按钮,或者直接在元件上双击即可。

下面是插入一个异或门的例子:

按照设计好的原理图,将元件逐一输入。在图形编辑窗口的左侧列有一排图形编辑的辅助按钮,可
以用来连线,输入文本,以及画曲线、圆等图形,还可以放大或者缩小视图。

下面是完成的原理图输入:

― 32 ―
在插入 Input 输入端的 Symbol 时,会出现如下图形:

左侧的 PIN_NAME 是引脚名称,双击 PIN_NAME 可以修改引脚名称。这里把输入的两组引脚分


别取为 A0、A1、A2、A3 和 B0、B1、B2、B3,还有一个进位输入端取为 C0。对输出端 Output 也做同
样的处理。输入输出端图形右下方的 VCC 是指该输入端的默认值。
4) 单击 FILE 菜单 下的 Save 选项,弹出下面的保存对话框:

在 File Name(文件名) 中输入 adder.gdf;


选择适当的 Directories(目录);将 Automatic Extension 设为.gdf;单击 OK 按钮。
5) 单击 FILE 菜单下的 Project 选项,选择 Set Project To Current File 命令。原理图输入部分完成。
下面绘制波形图,以仿真加法器设计。
6) 指定芯片、编译、仿真、性能分析
同附件 1 的步骤 6-20。

― 33 ―
附件 3:

实验中的常见问题
1. 上机时请在 E 盘的根目录建立一个子目录,用学号作为目录名,所有的设计数据必须放在这个目
录里。否则在编译设计文件时会出现“无法写 WORK 目录”的错误。每天下机前用 WINZIP 把所
有的设计文件压缩后用 EMAIL 发送到自己的信箱。

2. WIN2000 操作系统的下载程序 DLND102 在桌面上。

3. VHDL 程序保存时文件名必须和实体名称一致,文件名的后缀必须是“vhd”

4. 问题:仿真时提示“无法打开 SCF 文件”


原因:没有画激励波形或画好了激励波形,但没有保存成*.SCF 文件。如果 SCF 文件名和 VHDL
文件名不同,可以在仿真的“simulator”对话框里双击“Simulation Input:”来修改输入波形文件。

5. 问题:画激励波形时不能从“node”菜单添加信号
原因:没有对设计编译

6. 问题:VHDL 程序编译错误“can not read port … of a mode OUT”


原因:端口信号是“out”类型,但在 process 中使用该端口作为输入。
解决方法:端口信号改为“buffer”类型

7. 问题:原理图输入时,产生编译错误“几个节点连在一起了”
原因:元器件之间的连线必须画在绿色的虚线边框之外,否则有可能被认为连在一起了。

8. 如何在波形窗口里看完整的波形
解决方法:按波形窗口左上方第三个按钮。

9. VHDL 编译错误: “00xx… choice not specified”


原因:case 语句没有写 when others 分支。

10. VHDL 编译错误: “found extra ; …”


原因:case 语句没有写 when others 分支。

11. VHDL 编译错误: “illegal use case statement …”


原因:case 语句只能在进程内使用

12. VHDL 编译错误:“generate statement must be labeled”


原因:if 语句只能在进程内使用

13. VHDL 编译错误: “can not interpret subprogram call”


原因 1:没有写 use ieee.std_logic_unsigned.all;
原因 2:赋值语句或 IF 或 CASE 语句中信号的类型不对,例如 A 是 std_logic 类型,但使用了 A<=1;
或 if A=1 then …错误的类型赋值、比较语句。

14. 编译错误:“…missing source…”

― 34 ―
原因: 没有对输出端口赋值,整个电路没有输出。

15. 定义了 integer range 0-9,加法时为什么会超过 9?


原因: MAXPLUSII 软件并不会自动检查整数的范围,在编译是它会用 4 位矢量类型来代替这个
整数类型,因此实际能够表示的范围是从 0-15。在代码设计时需要自行处理数据超出范围的情
况。

― 35 ―

You might also like