《数字系统与逻辑设计》课件第10章_第1页
《数字系统与逻辑设计》课件第10章_第2页
《数字系统与逻辑设计》课件第10章_第3页
《数字系统与逻辑设计》课件第10章_第4页
《数字系统与逻辑设计》课件第10章_第5页
已阅读5页,还剩126页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第十章VHDL语言简介10.1

VHDL语言概述10.2

VHDL语言程序的基本结构10.3

VHDL语言的数据类型及运算操作符10.4

VHDL语言的主要描述语句10.5基本逻辑电路设计

10.1

VHDL语言概述

10.1.1VHDL语言的历史

VHDL(VHSICHardwareDescriptionLanguage)是一种标准的硬件描述语言。20世纪70年代末,美国国防部提出了VHSIC(VeryHighSpeedIntegratedCircuit)计划,目的是采用一种新的描述方法来进行新一代集成电路的设计。同时便于管理有关电子电路技术文件,使其遵循统一的设计描述界面,以便将来在有新技术推出时,仍能重复使用原设计。1981年6月,一个工作小组在美国国防部的组织下正式成立,不久提出了一种新的硬件描述语言——VHDL。硬件描述语言(HDL)是一种用形式化方法来描述数字电路和设计数字逻辑系统的语言,可以用来编写设计文件、建立电子系统行为级的模拟模型,在此基础上,可利用计算机的强大能力对用VHDL建模的复杂数字逻辑进行模拟,再利用逻辑综合工具自动生成符合要求且在电路结构上可以实现的数字逻辑网表。根据网表和某种工艺可进一步进行版图设计,生成该工艺条件下电路的延时模型,并经模拟验证无误后用于制造ASIC芯片或者写入CPLD和FPGA器件中。

提出VHDL语言的目标是使电路文本化成为标准,使文本描述的电路设计能够为其他人所理解,同时也可以作为一种模型语言并能采用软件进行仿真。

1986年,IEEE标准化组织开始讨论VHDL语言标准,同时成立了一个VHDL标准化小组。1987年12月,IEEE公布了VHDL的第一个工业标准版本并宣布实施,即IEEE1076标准。1988年,美国军用标准MIL-STD-454规定所有为美国国防部设计的ASIC产品必须采用VHDL来进行描述。1993年,经过几年的修订和扩展,IEEE公布了VHDL的新版本IEEE1164。1996年,IEEE1076.3成为VHDL的综合标准。 10.1.2VHDL系统设计的特点及优势

与其他硬件描述语言相比,VHDL具有以下特点:

(1)功能强大、设计灵活、支持广泛、易于修改。

VHDL具有功能强大的语言结构,可以用简洁明确的源代码来描述复杂的逻辑控制。VHDL支持同步电路、异步电路和随机电路的设计,这是其他硬件描述语言所不能比拟的。VHDL还支持各种设计方法,既支持自底向上的设计,又支持自顶向下的设计;既支持模块化设计,又支持层次化设计。

由于VHDL已经成为IEEE标准所规范的硬件描述语言,因此目前大多数EDA工具几乎都支持VHDL,这为VHDL的进一步推广和广泛应用奠定了基础。在硬件电路设计过程中,主要的设计文件是用VHDL编写的源代码,因为VHDL易读和结构化,所以易于修改设计。

(2)强大的系统硬件描述能力。

VHDL具有多层次的设计描述功能,既可以描述系统级电路,又可以描述门级电路。而描述既可以采用行为描述、寄存器传输描述或结构描述,也可以采用三者混合的混合级描述。另外,VHDL支持惯性延迟和传输延迟,还可以准确地建立硬件电路模型。VHDL支持预定义的和自定义的数据类型,给硬件描述带来了较大的自由度,使设计人员能够方便地创建高层次的系统模型。

(3)独立于器件的设计、与工艺无关。

设计人员用VHDL进行设计时,不需要首先考虑选择完成设计的器件,可以集中精力进行设计的优化。当设计描述完成后,可以用多种不同的器件结构来实现其功能。

(4)很强的移植能力,易于共享和复用。

VHDL是一种标准化的硬件描述语言,同一个设计描述可以被不同的工具所支持,使得设计描述的移植成为可能。

VHDL采用基于库(Library)的设计方法,可以建立各种可再次利用的模块。将这些模块存放到库中,就可以在以后的设计中进行复用,可以使设计成果在设计人员之间进行交流和共享,减少了硬件电路设计的工作量。可见,作为一种IEEE的工业标准,VHDL具有很多其他硬件描述语言所不具有的优点。当然,VHDL也存在着不足之处,主要体现在以下几个方面:

(1)系统级抽象描述能力较差;

(2)某些场合不能准确描述硬件电路;

(3)综合工具的不同将导致综合质量的不同;

(4)不具有描述模拟电路的能力。

10.2

VHDL语言程序的基本结构

10.2.1VHDL语言设计的基本单元及其构成

一个完整的VHDL语言程序通常包含实体(Entity)、结构体(Architecture)、配置(Configuration)、包集合(Package)和库(Library)五个部分。

简单的程序是由实体和结构体两部分组成的。实体用于描述设计系统的外部接口信号,结构体用于描述系统的行为、系统数据的流程或者系统组织结构形式。设计实体是VHDL程序的基本单元,是电子系统的抽象。简单的实体可以是一个门电路,复杂的实体可以是一个微处理器或一个数字电子系统。实体由实体说明和结构体说明两部分组成。

例10-2-1是计数器程序结构模板。由这个抽象的程序可以归纳出VHDL程序的基本结构。

【例10-2-1】计数器程序结构模板。[HT5"SS][ZK(]LIBRARYIEEE;

USEieee.std_logic_1164.all;

ENTITYentity_counterIS

//实体说明

PORT(//端口说明

SIGNAL_data_input_name:ININTEGERRANGE0TO_count_value;

SIGNAL_clk_input_name:INSTD_LOGIC;

SIGNAL_clm_input_name:INSTD_LOGIC;

SIGNAL_ena_input_name:INSTD_LOGIC;

SIGNAL_ld_input_name:INSTD_LOGIC;

SIGNAL_count_output_name:OUTINTEGERRANGE0TO_Count_value;

)

ENDentity_name;

ARCHITECTUREcounterOF_entity_counterIS//结构体说明

SIGNAL_count_signal_name:INTEGERRANGE0TO_count_value;

BEGIN

PROCESS(_clk_input_name,_clrn_input_name)----敏感变量表

BEGIN

IF_clrn_input_name=′0′THEN

_count_signal_name<=0;

ELSIF(_clk_input_name′EVENTAND_clk_input_name=′1′)THEN

IF_ld_input_name=′1′THEN

_count_signal_name<=_data_input_name;

ELSE

IF_ena_input_name=′1′THEN

_count_signal_name<=_count_signal_name+1;

ELSE

_count_signal_name<=_count_signal_name;

ENDIF;

ENDIF;

ENDIF;

ENDPROCESS;

_count_output_name<=_count_signal_name;

ENDcounter;图10-2-1

VHDL程序结构图10-2-2

VHDL程序设计系统模型10.2.2实体

1.实体说明

根据IEEE标准,实体组织的一般格式为

ENTITY实体名IS

[GENERIC(类型表);]——可选项

[PORT(端口表);]——必需项

实体说明部分;——可选项

[BEGIN

实体语句部分;]

END[ENTITY][实体名];

根据上述实体说明的一般书写格式,编写一个8位二进制加法器的VHDL程序设计的实体说明,如例10-2-2所示。【例10-2-2】

8位二进制加法器的实体说明。

LIBRARY

ieee;

USE

ieee.std_logic_1164.all;

ENTITYadd8

IS

PORT(

b:in

std_logic_vector(7

downto

0);

a:in

std_logic_vector(7

downto

0);

Ci:in

std_logic;

Sum:out

std_logic_vector(7downto

0);

Co:out

std_logic;)

ENDadd8;图10-2-3实体add8/8位加法器外部接口实体说明以“ENTITY实体名IS”开始,以“END实体名”结束。大写字母或黑体字都是VHDL关键字。实体说明主要描述一些参数的类型。参数的类型说明必须放在端口说明之前。

在层次化系统设计中,实体说明是整个系统的输入/输出(I/O)。在一个器件级的设计中,实体说明是一个芯片的输入/输出(I/O)。

实体说明在VHDL程序设计中描述一个元件或一个模块与设计系统的其余部分(其余元件、模块)之间的连接关系,可以看做一个电路图的符号。

2.类型说明

类型说明是实体说明中的可选项,放在端口说明之前,其一般书写格式为

GENERIC[CONSTANT]名字表:[IN]子类型标识[:=静态表达式],…]

例如:

GENERIC(m:TIME:=3ns)

这个参数说明是指在VHDL程序中,结构体内的参数m是时间参数,取值为3ns。

3.端口说明

端口说明是对设计实体与外部接口的描述,是设计实体和外部环境动态通信的通道,其功能对应于电路图符号的一个引脚。实体说明中的每一个I/O信号被称为一个端口,一个端口就是一个数据对象。端口可以被赋值,也可以当作变量用在逻辑表达式中。定义实体的一组端口称作端口说明(portdeclaration)。

端口说明的组织结构必须有一个名称、一个通信模式和一个数据类型。端口说明的一般格式为

Port(端口名,端口名:模式数据类型名

端口名,端口名:模式数据类型名);端口名是赋予每个外部引脚的名称,名称的含义要明确,如D开头的端口名表示数据,A开头的端口名表示地址等。端口名通常用几个英文字母或一个英文字母加数字表示。下面是合法的端口名:CLK,RESET,A0,D3。

模式用来说明数据、信号通过该端口的传输方向。端口模式有in、out、buffer、inout。

(1)输入(in)。输入仅允许数据流入端口。输入信号的驱动源在该设计实体的外部。输入模式主要用于时钟输入、控制输入(如Load、Reset、Enable、CLK)和单向的数据输入,如地址信号(address)。不用的输入一般接地,以免浮动引入干扰噪声。

(2)输出(out)。输出仅允许数据流从实体内部输出。端口的驱动源在该设计实体的内部。输出模式不能用于被设计实体的内部反馈,因为输出端口在实体内不能看做可读的。输出模式常用于计数输出、单向数据输出、设计实体产生的控制其他实体的信号等。一般而言,不用的输出端口不能接地,避免造成输出高电平时烧毁被设计实体。

(3)缓冲(buffer)。缓冲模式的端口与输出模式的端口类似,只是缓冲模式允许内部引用该端口的信号。缓冲端口既能用于输出,也能用于反馈。

缓冲端口的驱动源可以是设计实体的内部信号源或者是其他实体的缓冲端口。缓冲不允许多重驱动,不与其他实体的双向端口和输出端口相连。

内部反馈的实现方法有两种,一是通过建立缓冲模式端口来实现,二是通过建立设计实体的内部节点来实现。

缓冲模式用于在实体内部建立一个可读的输出端口,例如计数器输出,计数器的现态被用来决定计数器的次态。实体既需要输出,又需要反馈,这时设计端口模式应为缓冲模式。

(4)双向模式(inout)。双向模式可以代替输入模式、输出模式和缓冲模式。

在设计实体的数据流中,有些数据是双向的,数据可以流入该设计实体,也有数据从设计实体流出,这时需要将端口模式设计为双向端口。双向模式的端口允许引入内部反馈,所以双向模式端口还可以作为缓冲模式用。由此可知,双向端口是一个完备的端口模式。

一般而言,输入信号把端口指派成输入模式,输出信号把端口指派成输出模式,而双向数据信号,如计算机的PCI总线的地址/数据复用总线、DMA控制器数据总线,都选用端口双向模式。这一良好的设计习惯,使得从端口名称、端口模式就可一目了然地知道信号的用途、性质、来源和去向,十分方便。对一个大型设计任务,大家应协同工作,从而不至于引起歧义。类型说明和端口说明是实体说明的组成部分,用于说明设计实体和外部通信的通道。利用外部通信通道和参数的类型说明为设计实体提供信息。参数的类型用来规定端口的大小、I/O引脚的指派、实体中子元件的数目和实体的定时特性等信息。

4.数据类型(types)

数据类型端口说明除了定义端口标识名称、端口定义外,还要标明出入端口的数据类型。VHDL语言的IEEE1706/93标准规定,EDA综合工具支持的数据类型为布尔型(boolean)、位型(bit)、位矢量型(bitvector)和整数型(integer)。

由IEEEstd_logic_1164所约定,并由EDA工具支持和提供的数据类型为标准逻辑(standardlogic)类型。标准逻辑类型也分为布尔型、位型、位矢量型和整数型。为了使EDA工具的仿真、综合软件能够处理这些逻辑类型,这些标准库必须在实体中声明或在USE语句中调用。

10.2.3结构体

1.结构体说明

结构体定义实体功能的一种实现。结构体的结构为

architecture结构体名of实体名is

{块说明项}

begin

{并行语句}

end结构体名;

块说明项(或定义语句)处于architecture与begin之间,对结构体内部使用的信号、常数、数据类型和函数进行说明,包括使用语句、子程序说明、子程序体、类型说明、子类型说明、常数说明、信号说明和元件说明。

并行语句处于begin与end之间,描述结构体的行为与连接关系。

结构体的组织如图10-2-4所示。图10-2-4结构体的组织

2.结构体的子结构描述

1)块(block)语句结构

块语句结构为

块结构名:

block

begin

{并行语句}

endblock块结构名;

2)进程(process)语句结构

进程语句结构为

[进程名]:process(信号1,信号2,……)

{说明内部变量}

begin

{顺序语句}

endprocess;

进程的组织如图10-2-5所示。图10-2-5进程的组织一般地,一个可综合的、完整的VHDL程序有比较固定的结构。设计实体中,一般首先出现的是各类库及其程序包的使用声明,包括未以显式表达的工作库WORK库的使用声明,接着是实体描述,接着是结构体描述,而在结构体中可以含有不同的逻辑表达语句结构。这里将一个相对完整的VHDL程序设计构建称为设计实体。

3.process进程语句和顺序语句

由process引导的语句称为进程语句。在VHDL中,所有合法的顺序描述的语句都必须放在进程语句中(并非所有语句都能放在进程语句中)。

process(a,b,c)称为进程的敏感信号表,通常要求将进程中所有的输入信号都放在敏感信号表中。由于process语句的执行依赖于敏感信号的变化,当某一敏感信号(如a)从原来的“1”跳变到“0”,或者从原来的“0”跳变到“1”时,就将启动此进程语句,而在执行一遍整个进程的顺序语句后,便进入等待状态,直到下一次敏感信号表中某一信号的跳变才再次进入“启动—运行”状态。在一个结构体中可以包含任意个进程语句,所有的进程语句都是并行语句,而由任一进程process引导的语句结构属于顺序语句。10.2.4寄存器的VHDL描述

与其他硬件描述语言相比,在时序电路的描述上,VHDL具有许多独特之处,最明显的是VHDL主要通过对时序器件功能和逻辑行为的描述,而非结构上的描述即能由计算机综合出符合要求的时序电路,从而充分体现了VHDL电路系统行为描述的强大功能。

以D触发器为例,其语言描述包含了VHDL对时序电路的最基本和典型的表达方式,同时也包含了VHDL中许多最具特色的语言现象。例10-2-3是对D触发器元件图10-2-6的VHDL描述。图10-2-6

D触发器【例10-2-3】

D触发器的VHDL描述。

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYDFF1IS

PORT(CLK:[WBY]INSTD_LOGIC;

D:[DW)]INSTD_LOGIC;

Q:[DW)]OUTSTD_LOGIC);

END;

ARCHITECTUREbhvOFDFF1IS

SIGNALQ1:STD_LOGIC;

BEGIN

PROCESS(CLK)

BEGIN

IFCLK′EVENTANDCLK=′1′

THENQ1<=D;

ENDIF;

ENDPROCESS;

Q<=Q1;

ENDbhv;

1.标准逻辑位数据类型STD_LOGIC

从例10-2-3中可见,D触发器的3个信号端口CLK、D和Q的数据类型都被定义为STD_LOGIC。就数字系统设计来说,类型STD_LOGIC比BIT包含的内容丰富和完整得多。试比较STD_LOGIC和BIT两种数据类型的程序包定义表达式(其中TYPE是数据类型定义语句):

BIT数据类型定义:

TYPEBITIS(′0′,′1′);

STD_LOGIC数据类型定义:

TYPESTD_LOGICIS(′U′,′X′,′0′,′1′,′Z′,′W′,′L′,′H′,′-′);以上定义的9种数据的含义是:′U′——未初始化的;′X′——强未知的;′0′——强逻辑0;′1′——强逻辑1;′Z′——高阻态;′W′——弱未知的;′L′——弱逻辑0;′H′——弱逻辑1;′-′——忽略。它们较完整地概括了数字系统中所有可能的数据表现形式。STD_LOGIC类型比BIT类型的数据具有更宽的取值范围,从而实际电路有更好的适应性。

在仿真和综合中,将信号或其他数据对象定义为STD_LOGIC数据类型是非常重要的,它可以使设计者精确地模拟一些未知的和具有高阻态的线路情况。但就目前的综合器而言,STD_LOGIC型数据能够在数字器件中实现的只有其中的四种值,即′X′(或′-′)、′0′、′1′和′Z′。

2.设计库和标准程序包

如上所述,定义数据类型BIT的函数包含于标准库STD的STANDARD标准程序包中。一般地,为了使用STD_LOGIC数据类型,应该在如例10-2-1的程序上面增加如下两句说明语句:

LIBRARYSTD;

USESTD.STANDARD.ALL;第一句中的LIBRARY是关键词,LIBRARYSTD表示打开STD库;第二句的USE和ALL是关键词,USESTD.STANDARD.ALL表示允许使用STD库中STANDARD程序包中的所有内容,如类型定义、函数、过程、常量等。另一方面,要求VHDL设计文件存盘在某一文件夹中,如D:\VHDL_FILE中,并被指定为工程PROJECT文件所在的目录,VHDL工具将此路径指定的文件夹默认为工作库(WORKLIBRARY)。在VHDL程序前面还应该增加“LIBRARYWORK;”语句,VHDL工具才能调用相关的元件和程序包。但是,由于VHDL标准中规定标准库STD和工作库WORK都是默认打开的,因此可以像例10-2-1那样,不必将上述库和程序包的使用语句以显式表达在VHDL程序中。除非如例10-2-3那样,需要使用一些特殊的程序包。使用库和程序包的一般定义表达式是:

LIBRARY<设计库名>;

USE<设计库名>.<程序包名>.ALL;

STD_LOGIC的类型定义在被称为STD_LOGIC_1164的程序包中,此包由IEEE定义,而且此程序包所在的程序库的库名也称为IEEE。由于IEEE库不属于VHDL标准库,所以在使用其库中内容前,必须事先给予声明,如例10-2-3最上面的两句语句:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

3.SIGNAL信号定义和数据对象

例10-2-3中的语句“SIGNALQ1:STD_LOGIC;”表示在描述的器件DFF内部定义标识符Q1的数据对象为信号SIGNAL,其数据类型为STD_LOGIC。由于Q1被定义为器件的内部接点信号,数据的进出不像端口信号那样受限制,所以不必定义其端口模式(如IN、OUT等)。

语句“SIGNALQ1:STD_LOGIC;”中的SIGNAL是定义某标识符为信号的关键词。在VHDL中,数据对象(DataObjects)类似于一种容器,它接受不同数据类型的赋值。数据对象有三类,即信号(SIGNAL)、变量(VARIABLE)和常量(CONSTANT)。VHDL中,被定义的标识符必须确定为某类数据对象,同时还必须被定义为某种数据类型,如例10-2-3中的Q1,对它规定的数据对象是信号,数据类型是STD_LOGIC(规定Q1的取值范围),前者规定了Q1的行为方式和功能特点,后者限定了Q1的取值范围。根据VHDL规定,Q1作为信号,它可以如同一根连线那样在整个结构体中传递信息,也可以根据程序的功能描述构成一个时序元件;但Q1传递或存储的数据的类型只能包含在STD_LOGIC的定义中。需要注意的是,语句“SIGNALQ1:STD_LOGIC;”仅规定了Q1的属性特征,而其功能定位需要由结构体中的语句描述具体确定。

4.上升沿检测表式和信号属性函数EVENT

例10-2-3中的条件语句的判断表达式“CLK′EVENTANDCLK=′1′”是用于检测时钟信号CLK的上升沿的,即如果检测到CLK的上升沿,此表达式将输出“TRUE”。

关键词EVENT是信号属性,VHDL通过表达式“<信号名>′EVENT”来测定该信号的跳变边沿。短语“clock′EVENT”就是对clock标识符的信号在当前的一个极小的时间段δ内发生事件的情况进行检测。所谓发生事件,就是clock的电平发生变化,从一种电平方式转变到另一种电平方式。如果clock的数据类型定义为STD_LOGIC,则在δ时间段内,clock从其数据类型允许的9种值中的任何一个值向另一个值跳变,如由′0′变成′1′、由′1′变成′0′或由′Z′变成′0′,都认为发生了事件,于是此表达式将输出一个布尔值TRUE,否则为FALSE。如果将“clock′EVENT”改成语句“clock′EVENTANDclock=′1′”,则一旦“clock′EVENT”在δ时间内测得clock有一个跳变,而小时间段δ之后又测得clock为高电平′1′,从而满足此语句右侧的“clock=′1′”的条件,而两者相与(AND)后返回TRUE,由此便可以从当前的“clock=′1′”推断在此前的δ时间段内,clock必为0(假设clock的数据类型为BIT)。因此,以上的表达式可以用来对信号clock的上升沿进行检测。

5.不完整条件语句与时序电路

下面分析例10-2-3中对D触发器功能的描述。

首先当时钟信号CLK发生变化时,PROCESS语句被启动,IF语句将测定条件表达式“CLK′EVENTANDCLK=′1′”是否满足条件(即CLK的上升沿是否到来),如果为“TRUE”,则执行语句Q1<=D,即将D的数据向内部信号Q1赋值,并结束IF语句,最后将Q1的值向端口信号Q输出,即执行Q<=Q1。如果CLK没有发生变化,或是非上升沿方式的变化,IF语句都不满足条件,即条件表达式给出“FALSE”,于是将跳过赋值表达式Q1<=D结束IF语句的执行。由于在此IF语句中没有利用ELSE明确指出当IF语句不满足条件时作何操作,显然这是一种不完整的条件语句(即在条件语句中,没有将所有可能发生的条件给出对应的处理方式),对于这种语言现象,VHDL综合器将“理解”为当不满足条件时,不能执行语句Q1<=D,即应保持Q1的原值不变。这就意味着必须引进时序元件来保存Q1中的原值,直到满足IF语句的判断条件后才能更新Q1中的值。将这种不完整的条件语句的描述引进寄存器元件,从而构成时序电路的方式是VHDL描述时序电路最重要的途径。通常,完整的条件语句只能构成组合逻辑电路,例如,IF_THEN_ELSE语句可以指明全部可能的条件下的赋值操作,从而构成多路选择器组合电路模块。

然而必须注意的是,虽然在构成时序电路方面,不完整的条件语句具有独特的功能,但在利用条件语句进行纯组合电路设计时,如果没有充分考虑电路中所有可能出现的问题,即没有列全所有的条件,将导致不完整的条件语句的描述,从而产生设计者不希望的组合与时序电路的混合体。10.3

VHDL语言的数据类型及运算操作符

10.3.1VHDL的数据类型

VHDL中的数据类型用来描述目标量的属性,有三种数据类型:

(1)常量(constant):命名数据类型的一种特殊值。

(2)变量(variable):变量对象位于进程和子程序中,主要用于局部计算结果的暂存。

(3)信号(signal):是连接实体(或进程)的主要机制,用信号在实体(或进程)之间传送信息。

1.常量[HT](constant)

格式:

constant常数名:数据类型[:=初始值];

例如:

constantVOFF:real:=0.8;

constantdelay:Time:=10ns;

常数赋值后不能变,赋的值要与数据类型一致,常数有和信号一样的可视性规则,在程序包中说明的常数为全局量;在实体说明部分的常数可以被该实体中任何结构体引用,在结构体中的常数能被其结构体内部任何语句采用,包括被进程语句采用;在进程说明中说明的常量只能在进程中使用。

2.变量(variable)

格式:

variable变量名:数据类型[约束条件][:=表达式];

例如:

variablex,y:integer;

variablecount:integerrange0to255:=10;

变量只能在进程、函数或过程中使用,用做局部的数据存储,为局部量,赋值立即生效。

3.信号[HT](signal)

格式:

signal变量名:数据类型[约束条件][:=初始值];

即在关键词signal后跟一个或者多个信号名,每个信号名将建一个新信号,用冒号“:”把信号名和信号的数据类型分隔开,信号数据类型规定信号包含的数据类型信息,最后信号还可包含初始化信号指定的初值。

例如:

signalground:bit:=′0′;

signalen:std_logic_vector(7downto0);

信号是实体间动态数据交换的手段,信号赋值有附加延迟,信号为全局量,可实现进程之间的通信,程序中赋值采用<=。

4.常量、变量与信号的区别

常量的作用范围取决于它被定义的位置,允许用在实体、结构体、程序包、块、进程、子程序中。

变量是一个局部量,只作用于在定义了变量的process和子程序的顺序语句里面,而且变量的数据传输没有延时行为。变量的主要作用是在进程中作为临时的数据存储单元(当前)。信号的定义和使用的范围为entity、architecture和package,而不能用在process和subprogram的顺序语句中。而且在没有作特殊设置时,信号也有一个最小传输延时,它的硬件特征更为明显,类似于连接线,可以作为设计实体并行语句模块间的信息交流通道,它既可以保存当前值也可以保存历史值,和触发器的记忆功能有很好的对应关系,只是不必关注信号上的数据流动方向。信号的初始值的设定和variable一样,由于电路上电后的随机性,因此综合器并不支持设置初始值。由于process的敏感列表里可以有信号,因此信号就能把process外部的信息引入或传出,在process中,当多个同名信号被赋值后,只执行最后一个,因为当遇到endprocess的时候才对signal赋值。但是在并行语句中却不允许同一信号有多个驱动源。在进程中向信号赋值的时刻和信号得到该值的时刻之间有一隐含延迟,称Δ延迟,Δ延迟是一个无穷小的时间量。一般信号赋值在进程中仅当碰到wait语句或进程结束赋值时才生效。

进程只对信号敏感,而对变量不敏感。信号除当前值外还有许多相关信息,而变量只有当前值。信号是全局量,变量为局部量。信号在电路中的功能是保存变化的数值和连接子元件;变量在电路中无类似的对应关系,仅用于计算。

从硬件电路系统上来看,变量和信号相当于电路系统中的连线和连线上传输的信号,常量相当于电路中的恒定电平,如GND和VCC。10.3.2VHDL语言的运算操作符

VHDL支持的运算有逻辑运算(logical)、关系运算(relational)、算术运算(arithmetic)和并置(连接)(concatenation)运算。

1.逻辑运算符

逻辑运算符有not、and、or、nand、nor、xor等6种。其操作数类型有std_logic、bit、std_logic_vector、bit_vector及boolean。表达式中,操作数必须同类型,数组操作数必须同长度,作用于两个数组操作数的逻辑运算符就是作用在两数组相应的元素对上,运算结果为同长度数组。表达式左右无优先级差别,必要时加括号。当表达式中仅有“and”、“or”、“xor”运算符时,可省略括号,“not”的优先级最高。

2.算术运算符

算术运算符有+、-、*、/、mod、rem、+、-、**、abs等10种。

一元运算(“+”取正,“-”取负)操作数为任何类型,类型要相同;乘除操作数可同为整型或实型,也可以是物理量;求模和取余的操作数必须为整型;指数运算的左操作数可为整型或实型,而右操作数为整型只有“+”、“-”、“*”才能综合;对“STD_LOGIC_VECTOR”类型做加减运算时,操作数位长应相同。

3.关系运算符

关系运算符有=、/=、<、<=、>、>=等6种,比较同类型的两个操作数,返回一个BOOLEAN值。

“=”和“/=”适用于各种类型,对数组和记录类型,比较操作数的对应元素,运算顺序从算式左边开始,关系运算符<、<=、>、>=适用于INTEGER、REAL、STD_LOGIC、[JP]STD_LOGIC_VECTOR和枚举类型,关系运算两边的数据类型必须相同,但位长可以不同。

4.并置(连接)运算符

并置(连接)运算符用于一维数组的连接,右边内容接在左边内容之后形成新数组,操作数是数组或数组的元素。

例如:

signalA,D:BIT_VECTOR(3downto0);

signalB,C,G:BIT_VECTOR(1downto0);

signalE:BIT_VECTOR(2downto0);

signalF,H,I:BIT;

A<=notB¬C;--数组连接数组

D<=notE¬F;--数组连接元素

G<=notH¬I;--元素连接元素用集合体方法进行位的连接(将“&”换成“,”),例如:

temp<=(en,en,en,en);

temp<=(3=>en,2=>en,1=>en,0=>en);

temp<=(3downto0=>en);

temp<=(2=>′0′,others=>en);

各种运算符号之间的关系如表10-3-1所示。表10-3-1运算操作符优先级顺序10.4

VHDL语言的主要描述语句

10.4.1顺序描述语句

1.wait语句

WAIT语句用于多种不同的目的,常用于为综合工具指定时钟输入。另一用途是将进程的执行延时一段时间或者是为了动态地修改进程的敏感表。

WAIT语句的执行会暂停进程的执行,直到信号敏感表发生变化或某种条件满足为止。若进程中含信号敏感表,则必须紧跟在procees之后,这等价于该进程最后一个语句为waiton语句,此时不能用显式的wait语句。

2.断言(assert)语句

assert语句在运行过程中报告指定的错误信息,用于仿真和调试。

基本格式:

assert条件[report报告信息][severity出错级别];

报告信息:字符串;出错级别:note,warning,error,failure。执行此语句时,如果条件为真,则向下执行;反之,则输出错误信息和出错级别。

3.赋值语句

赋值语句将一个值赋给变量或信号。

基本格式:

标识符:=表达式;变量赋值

标识符<=表达式;信号赋值

标识符为接受表达式值的变量或信号(或变量或信号的一部分),表达式必须求值得到与目标相同的数据类型。

标识符为信号或变量,对数组类型数组的所有元素都要赋值,数组的序号表达式必须计算成该数组序号类型的值且在界内,但无需是可计算的。

信号赋值语句有三种类型:基本型、条件型和选择型。其中条件型和选择型赋值语句为并发语句。基本型信号赋值语句举例如下:

a<=b;

a<=bafter10ns;为赋值引入非零延时值

条件型信号赋值语句格式为:

信号<=敏感信号表达式;

例如:

z<=anot(bnadc);

条件型信号赋值语句信号赋值不立即生效,若在一个进程中有若干值赋给一个信号,则最后一个赋值生效;若干进程赋值给一个信号,电路可能失效。

4.if语句

格式:

(1)if条件then

<顺序处理语句>;

endif;

【例10-4-1】一个D触发器的实现。

entityuregis

generic(size:integer:=2);

port(

clk,reset,load:instd_logic;

d:inunsigned(size-1downto0);

q:bufferunsigned(size-1downto0));

endureg;

architecturearchuregofuregis

begin

p1:process(reset,clk)

begin

if

reset=′1′then

q<=(others=>′0′);

elsif(clk′eventandclk=′1′)then

if

load=′1′then

q<=d;

end

if;

endif;

end

process;

end

archureg;

(2)if条件then

<顺序处理语句>;

else

<顺序处理语句>;

endif;

例如,两输入与门,在所有条件下都赋给信号一个值:

if(PHI=′1′)then

TEMP<=A;

else

TEMP<=′0′;

endif;

(3)if条件then

<顺序处理语句>;

elsif条件then

<顺序处理语句>;

elsif条件then

<顺序处理语句>;

else

<顺序处理语句>;

endif;

if语句中的每个条件必须是布尔表达式,每个if分支都包括一个或几个顺序语句,每个条件按顺序计算。如果没有一个条件满足且else语句存在,则执行else语句;如果没有一个条件满足且else语句不存在,则什么语句也不执行。【例10-4-2】

4选1数据选择器的实现。

entity

mux4is

port(

input:instd_logic_vector(3downto0);

sel:instd_logic_vector(1downto0);

y:outinstd_logic);

endmux4;

architecturertlofmux4is

begin

process(input,sel)

begin

if(sel=″00″)then

y<=input(0);

elsif(sel=″01″)then

y<=input(1);

elsif(sel=″10″)then

y<=input(2);

elsif

y<=input(3);

endif;

end

process;

endrtl;

if

load=′1′then

q<=d;

end

if;

end

if;

end

process;

end

archureg;

5.case语句

格式:

case表达式is

when选择=>顺序处理语句;

end

case;

选择的计算结果必须是整型、枚举型或枚举型数组;选择为静态表达式或动态范围,最终的选择可以是“others”,选择不能重叠;若无“others”选择,那么选择必须覆盖表达式的所有可能值。【例10-4-3】

case语句。

port(A,B,I0,I1,I2,I3:instd_logic;

Q:outstd_logic);

endMUX4;

architectureMUX4ofMUX4is

signalsel:INTEGERrange0to3;

begin

process(A,B,I0,I1,I2,I3)

caseselis

when0=>Q<=I0;

when1=>Q<=I1;

when2=>Q<=I2;

when3=>Q<=I3;

endcase;

endprocess;

endmux4;

6.loop语句

要重复地执行顺序语句时,可利用for…loop和while…loop两种语句来实现。

1)for…loop

该语句用于循环执行一系列语句,迭代次数为一整数,对该范围内的每一个值,循环执行一次。当迭代范围中的最后一个值迭代完成后,跳出循环,继续执行循环后的下一个语句。

格式:

[标号]:for循环变量in范围loop

<顺序处理语句>;

end

loop[标号名];【例10-4-4】loop语句的应用。

asum:foriin1to9loop

sum:=i+sum;

endloopasum;

2)while…loop

该语句也用于循环执行一系列语句,只要满足迭代条件,就重复执行下去。如果迭代条件求值为“真”,则封闭的语句就执行一次。然后迭代条件重新求值。如果迭代仍为“真”,则循环重复执行;否则,跳出循环,继续执行循环后的下一个语句。

格式:

[标号]:while条件loop

<顺序处理语句>;

endloop[标号名];

语句中的条件为布尔表达式。【例10-4-5】

while…loop语句的应用。

i:=1;

sum:=0;

sbcd:while(i<10)loop

sum:=i+sum;

i:=i+1;

endloopsbcd;

7.next语句

next语句用于停止本次迭代,转入下一次迭代。

格式:

next[标号][when条件];

[标号]表明下一次迭代的起始位置;若既无[标号]也无[when条件],则执行到该语句就立即跳出本次循环,再从loop的起始位置进行下次迭代。

例如:signalA,B,COPY_ENABLE:BIT_VECTOR(1to8);

A<=″00000000″;

for

I

in

1

to

8

loop

nextwhenCOPY_ENABLE(I)=′0′;

A(I)<=B(I);

end

loop;

8.exit语句

exit语句用于循环体内部,有条件或无条件地结束当前的迭代和循环。

格式:

exit[loop标号][when条件];

当条件满足时,结束循环,继续后继的语句。

嵌套循环中有以下三种形式:

(1)若无[loop标号],则执行exit时,程序仅从当前所属的loop循环中跳出。

(2)若exit后接[loop标号],则执行exit时,程序跳到说明的标号处。

(3)若exit后接[when条件],则执行exit时,只有当条件为“真”时才跳出循环。【例10-4-6】

exit语句。

signalA,B:BIT_VECTOR(1downto

8);

signalA_LESS_THAN_B:boolean;

A_LESS_THAN_B<=FALSE;

forIin1downto

0

loop

if(A(I)=′1′andB(I)=′0′)then

A_LESS_THAN_B<=FALSE;

exit;

elsif(A(I)=′0′andB(I)=′1′)then

A_LESS_THAN_B<=TRUE;

exit;

else

null;

end

if;

end

loop;

9.exit与next语句的比较

exit与next语句两者格式相同,都是跳出循环的剩余语句,但exit是终止循环,而next是继续下一次循环。10.4.2并行描述语句

VHDL的并行语句有进程(process)语句、并行信号赋值(concurrentsignalassignment)语句、条件信号赋值(conditionalsignalassignment)语句、选择信号赋值(selectivesignalassignment)语句、块(block)语句等。

1.进程(process)语句

进程语句在一个结构体中的所有进程中并行运行,每个进程中的所有语句都顺序执行,进程之间的通信靠信号来传递。

2.并发信号赋值[HT](concurrentsignalassignment)语句

并发信号赋值语句在结构体的进程之外使用,等价于包含顺序赋值语句的进程,并发信号赋值语句在仿真时同时运行。

3.条件信号赋值(conditionalsignalassignment)语句

格式:

目标<=表达式1when条件1else

表达式2when条件2else

表达式n;

“目标”为接受表达式值的信号,所使用的表达式是“条件”为真的第一个(按顺序)。如果没有条件为真,则将最后一个表达式赋给目标,若多个条件为真,则仅第一个有效,如同if语句的第一个条件为真的分支一样。…例如:

z<=Awhenassign_A=′1′else

Bwhenassign_B=′1′else

C;

与此等价的if语句如下:

process(A,ssign_A,B,assign_B,C)

begin

ifasign_A=′1′then

Z<=A;

elsifasign_B=′1′then

Z<=B;

else

Z<=C;

endif;

endprocess;

条件信号赋值语句与if语句的区别如下:

(1)if语句只能在进程内使用,而条件赋值语句可在进程外使用。

(2)if语句可以没有else,而条件赋值语句一定要有else。

(3)if语句可以嵌套,而条件赋值语句不能进行嵌套。

(4)if语句可以生成锁存电路,而条件赋值语句不能生成锁存电路。

4.选择信号赋值(selectivesignalassignment)语句

格式:

with选择表达式select

目标<=表达式1when条件1

表达式2when条件2

表达式nwhen条件n;…当选择表达式的值满足条件1时,表达式1的值赋给目标,满足条件2时,表达式2的值赋给目标,依此类推。选择表达式中的每一个值都必须由一个条件所覆盖;最后的选择可以是others。各条件不能重叠;若无others,则选择表达式的所有可能值都必须被条件集合所覆盖。【例10-4-7】选择语句。

siganlA,B,C,D,Z:BIT

signalCONTROL:bit_vector(1downto0);

withCONTROLselect

Z<=A

when″00″,

Bwhen″01″,

Cwhen″10″,

Dwhen″11″,

′X′whenothers;等价的case语句:

process(CONTROL,A,B,C,D)

begin

caseCONTROLis

when0=>Z<=A;

when1=>Z<=B;

when2=>Z<=C;

when3=>Z<=D;

endcase;

endprocess;

5.块(block)语句

块语句允许设计者合理分组一个模型的区域,即把类似的部分由块语句保持在一起,是VHDL中具有的一种划分机制。例如设计CPU时,将ALU划分为一个块,寄存器堆划分为一个块,而移位寄存器是另一个块。每块表示模块中的一个自包容区域,分别描述局部信号、数据类型和常量等,任何能在结构体说明部分说明的对象都能在块说明部分说明。

block为并行语句,其所包含的语句也是并行语句。 10.5基本逻辑电路设计

10.5.1组合逻辑电路设计

组合逻辑电路包括简单门电路、与非门、或非门、非门、异或门、编译码器与选择器、加法器、求补器、三态门、总线缓冲器等。

1.简单门电路

【例10-5-1】

3输入与非门电路。

libraryieee;

useieee.std_logic_1164.all;

entitynand_3is

port(a,b,c:instd_logic;

y:outstd_logic);

endnand_3;

architecturebeh_nand_3ofnand_3is

begin

y<=not(aandbandc);

endbeh_nand_3;【例10-5-2】

2输入异或门电路。

libraryieee;

useieee.std_logic_1164.all;

entityxor2isport(

a:instd_logic;

b:instd_logic;

y:outstd_logic);

endxor2;

architecturebeh_xor2ofxor2is

begin

y<=axorb;

endbeh_xor2;

2.编码器、译码器与数据选择器

【例10-5-3】3线-8线译码器。要求输入“a,b,c”,输出“y0~y7”,使能输入“g1,g2,g3”,仅当g1=1,g2=0,g3=0时,译码器工作,否则输出为高电平。

libraryieee;

useieee.std_logic_1164.all;

entitydecoder_3_to_8is

port(a,b,c,g1,g2,g3:instd_logic;

y:outstd_logic_vector(7downto0));

enddecoder_3_to_8;

architecturertlofdecoder_3_to_8is

signalindata:std_logic_vector(2downto0);

begin

indata<=c&b&a;

process(indata,g1,g2,g3)

begin

if(g1=′1′andg2=′0′andg3=′0′)then

caseindatais

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″

endcase;

else

y<=″11111111″;

endif;

endprocess;

endrtl;【例10-5-4】

3线-8线优先级编码器。

library

ieee;

useieee.std_logic_1164.all;

entity

priorityencoder

is

port(input:instd_logic_vector(7downto

0);

y:out

std_logic_vector(2downto

0));

end

priorityencoder;

architecture

rtl

of

priorityencoderis

begin

process(input)

begin

if(input(0)=″0″)then

y<=″111″;

elsif(input(1)=″0″)then

y<=″110″;

elsif(input(2)=″0″)then

y<=″101″;

elsif(input(3)=″0″)then

y<=″100″;

elsif(input(4)=″0″)then

y<=″011″;

elsif(input(5)=″0″)then

y<=″010″;

elsif(input(6)=″0″)then

y<=″001″;

else

y<=″000″;

end

if;

end

process;

end

rtl;【例10-5-5】4选1数据选择器。

library

ieee;

useieee.std_logic_1164.all;

entitymux4is

port(input:instd_logic_vector(3downto0);

a,b:instd_logic;

y:outstd_logic);

endmux4;

architecturertlofmux4is

signalsel:std_logic_vector(1downto0);

begin

sel<=a&b;

process(input,sel)

begin

if(sel=″00″)then

y<=input(0);

elsif(sel=″01″)then

y<=input(1);

elsif(sel=″10″)then

y<=input(2);

else

y<=input(3);

endif;

endprocess;

endrtl;

3.加法器

【例10-5-6】半加器。

Library

ieee;

use

ieee.std_logic_1164.all;

entity

half_adder

is

port(a,b:instd_logic;

s,co:outstd_logic);

end

half_adder;

architecture

half1of

half_adder

is

begin

c<=a

or

b;

d<=a

nand

b;

co<=not

d;

s<=c

and

d;

end

half1;【例10-5-7】全加器。由两个半加器构成一个全加器。

libraryieee;

useieee.std_logic_1164.all;

entityfull_adderis

port(a,b,cin:instd_logic;

s,co:outstd_logic);

endfull_adder;

architectureful1offull_adderis

componenthalf_adder

port(a,b:instd_logic;

s,co:outstd_logic);

endcomponent;

signalu0_co,u0_s,u1_co:std_logic;

begin

u0:half_adderportmap(a,b,u0_s,u0_co);

u1:half_adderportmap(u0_s,cin,s,u1_co);

co<=u0_cooru1_co;

endfull;

4.三态门与总线缓冲器

【例10-5-8】三态门。

libraryieee;

use

ieee.std_logic_1164.all;

entity

tri_gateis

port(din,en:instd_logic;

dout:outstd_logic);

end

tri_gate;

architecturezasoftri_gateis

begin

tri_gate:process(din,en)

begin

if(en=′1′)then

dout<=din;

else

dout<=′Z′;

end

if;

endprocess;

endzas;

【例10-5-9】单向总线缓冲器,由多个三态门组成,来驱动地址总线和控制总线。

libraryieee;

useieee.std_logic_1164.all;

entitytri_buf8is

port(din:instd_logic_vector(7downto0);

dout:outstd_logic_vector(7downto0);

en:instd_logic;);

endtri_buf8;

architecturezasoftri_buf8is

begin

tri_buff:process(din,en)

begin

if(en=′1′)then

dout<=din;

else

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论