第6章VHDL结构与要素EDA技术与VHDL设计6.1实体结构体VHDL库配置VHDL程序包VHDL数据类型VHDL文字规则6.26.36.46.56.66.7VHDL结构与要素VHDL操作符6.8VHDL数据类型6.7先看一个例子:D触发器libraryieee;useieee.std_logic_1164.all;entitydffisport(clk,clr,d:instd_logic;q:outstd_logic);architecturertlofdffisbeginprocess(clr,clk)beginifclr=‘1’thenq=‘0’;elsifclk’eventandclk=‘1’thenq=d;endif;endprocess;endrtl;实体结构体库实体一般格式6.1实体entity实体名isport(引脚名:引脚属性类型;...引脚名:引脚属性类型);endentity实体名;类属参数是VHDL的一个术语,用以将信息参数传递到实体。参数传递语句的一般格式如下:6.1.1类属参数说明generic([常数名:数据类型[:设定值]{;常数名:数据类型[:设定值]});例:在译码器中使用类属语句entitydecoderisgeneric(N:positive;--N表示输入端口的数目port(sel:inbit_vector(1toN);dout:outbit_vector(1to2**N));endentitydecoder;例:使用类属语句表示延迟entitygateisgeneric(delay:time:=5ns;port(…);endentitygate;…out=in1andin2afterdelay;端口为设计实体和其外部环境提供动态通信的通道,功能相当于外部引脚。端口说明语句的一般格式如下:6.1.2端口说明port(端口名:端口模式数据类型;…端口名:端口模式数据类型);端口名是每个实体外部引脚的名称,通常用一个或几个英文字母或英文字母加数字命名,如d0、sel、q0等。端口模式用来定义外部引脚的信号方向,模式有4种:in(输入)、out(输出)、buffer(缓冲器)、inout(双向)。端口名与端口模式6.2结构体结构体也叫构造体,描述基本设计单元的结构、行为、元器件及宁内部连接关系。结构体包括两个组成部分:(1)说明部分:对数据类型、常数、信号、子程序和元器件等要素进行说明。(2)描述语句部分:包括各种顺序语句和并行语句。结构体的一般格式architecture结构体名of实体名isbegin功能描述(包括并行、进程等)语句;endentity结构体名;6.2.1结构体的命名结构体名称由设计者自行定义,指明结构体归属的实体。结构体的命名有一定规则需要遵循,最好能体现不同的描述方式。6.2.2结构体信号定义语句结构体信号定义必须在architecture和end之间。结构体中定义的信号应有名称和数据类型,但没有属性,这点与端口不同。结构体定义的信号只在本结构体有效,对于其它结构体则失去作用。6.3VHDL库库是经编译后的数据的集合,它存放程序包定义、实体定义、结构体定义和配置定义。库的好处在于使设计者可以共享已经编译过的设计结果。在VHDL语言中可以存在多个不同的库,但是库与库之间是独立的,不能相互嵌套。6.3.1库的种类当前在VHDL语言中存在的库大致可以归纳为5种:IEEE库、STD库、WORK库和用户自定义的库。1.IEEE库是VHDL设计中最为常用的库,包含有IEEE标准的程序包和其它一些支持工业标准的程序包。IEEE库中的标准程序包主要包括NUMERIC_BIT、STD_LOGIC_1164等程序包。STD_LOGIC_1164是最重要和最常用的程序包。有些公司也提供一些程序包,虽非IEEE标准,但由于其已成为事实上的工业标准,也都并入了IEEE库。如SYNOPSYS的STD_LOGIC_ARITH、STD_LOGIC_SIGNED和STD_LOGIC_UNSIGNED。2.STD库是VHDL的标准库,库中还包含有称作“TEXTIO”的程序包。在使用“TEXTIO”程序包的数据时,应说明库和程序包名,然后才可以使用该程序包的数据。例如:LIBRARYIEEE;USESTD.TEXTIO.ALL;3.WORK库是现行作业库。设计者所描述的VHDL语句不需要任何说明,将都存放在WORK库中。使用该库时无需进行任何说明。工作库并非文件夹的名称,而是一个逻辑名。综合器将指向该文件夹的路径。4.用户自定义库用于为自身设计需要所开发的共用程序包和实体等,也可汇集在一起定义成一个库。6.3.2库的用法LIBRARY库名;USE库名.程序包名.项目名;例如,需要使用IEEE库中的STD_LOGIC_1164程序包所有项目,则使用语句为:LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;6.4VHDL程序包为了使已定义的常数、数据类型、元件调用说明以及子程序等能被更多的其它设计实体方便地访问和共享,可以将它们收集在一个VHDL程序包中。多个程序包可以并入一个VHDL库中,使之适用于更一般的访问和调用范围。6.4.1程序包组成和格式由两部分组成:程序包首和程序包体。程序包的一般格式:6.4.2VHDL标准程序包STD_LOGIC_1164:包含一些数据类型、子类型和函数定义。STD_LOGIC_ARITH:在STD_LOGIC_1164的基础上扩展了三个数据类型UNSIGNED、SIGNED和SMALL_INT,并为其定义了相关的算术运算符和数据类型转换函数。6.4.2VHDL标准程序包STD_LOGIC_UNSIGNED和STD_LOGIC_SIGNED:是SYNOPSYS公司的程序包,重载可用于INTEGER类型及STD_LOGIC和STD_LOGIC_VECTOR类型混合运算的运算符,定义由STD_LOGIC_VECTOR到INTEGER型的转换函数。STANDARD和TEXTIO程序包:STANDARD程序包中定义了许多基本的数据类型、子类型和函数。TEXTIO程序包定义了支持文件操作的许多类型和子程序,主要供仿真器使用。6.5配置配置语句描述层与层之间的连接关系,以及实体与结构体之间的连接关系。设计者可以利用配置语句来选择不同的结构体,使其与要设计的实体相对应。6.5.1默认配置是最简单形式的配置,不含任何块语句和元器件的模块用这种配置。默认配置语句的一般格式如下:CONFIGURATION配置名OF实体名ISFOR选配结构体名ENDFOR;END配置名;6.6VHDL文字规则VHDL语言与其它高级语言一样,除了具有一般文字规则外,对标识符和数据格式等都有详细规定。在编写VHDL程序时必须完全遵守这些规定。初学者不可能在短时间内记住每一条规定,可以在编译时,由EDA软件指出错误后加以更正。本节的学习应特别注意理解,而不是死记硬背。6.6.1标识符用来表示常数、变量、信号、端口、子程序或参数的名称。标识符书写规则(1)有效的字符必须是小写字母(a-z)、大写字母(A-Z)、数字(0-9)以及下划线。(2)标识符必须以英文字母开头,最后一个字符不能是下划线。(3)不区分大小写。(4)两个划线不能连续出现,若出现则成了注视语句。(5)允许包含图形符号(如回车符、换行符等),也允许包含空格符。(6)VHDL的保留字不能作为标识符使用。标识符命名举例合法:(1)my_counter(2)decoder_1(3)FFT(4)ram-address不合法:(1)_decoder_1:起始非英文字母(2)2FFT:起始为数字(3)RYY_RST_:末尾不能是下划线6.6.2数字(1)整数:表示成“进制#数值#指数”五个部分。#起分隔作用,十进制用10表示,十六进制用16表示,八进制用8表示,二进制用2表示。(2)实数:实数是十进制的数,但须带小数点,如,1.335,99E-2等。(3)物理量文字:VHDL综合器不接受此类文字,如60s,100m等。6.7VHDL数据类型一种分类,四类:标量型、复合型、存取型和文件型。第二种分类,两类:预定义数据类型和自定义数据类型两个类别。6.7.1预定义数据类型1.整数代表正整数、负整数和零。整数类型与算术整数相似,可使用预定义的运算符,如加“+”、减“-”、乘“*”、除“/”等进行算术运算,整数的取值范围是-2147483647~+2147483647。在使用整数时,VHDL综合器要求用RANGE子句为所定义的数限定范围,然后根据所限定的范围来决定表示此信号或变量的二进制位数。2.实数类似于数学上的实数,或称浮点数,取值范围-1.0E38~+1.0E38。通常情况下,实数类型仅能在VHDL仿真器中使用,VHDL综合器则不支持实数。因为直接的实数类型的表达和实现相当复杂,目前在电路规模上难以承受。实数有正负数,书写时一定要有小数点,如-1.0,+2.5,-1.0E38。3.位(BIT)位数据类型取值只能是‘0’或者‘1’。位与整数中的0和1不同,前者是逻辑值,后者是整数值。位数据类型可以用来描述数字系统中的总线的值,当然也可以用转换函数进行转换。4.位矢量(BIT_VECTOR)位矢量是用双引号括起来的一组位数据。例如:“001100”,X“00BB”。这里位矢量前面的X表示十六进制,使用位矢量须注明位宽。5.布尔量(BOOLEAN)布尔类型的数据只能取逻辑“真”和“假”两种。布尔量不属于数值,因为不能用于运算,它只能通过关系运算符获得。6.字符字符也是一种数据类型,所定义的字符量通常用单引号括起来,如‘A’。一般情况下,VHDL对大小写不敏感,但是对字符量中的大、小写字符则认为是不一样的。程序包STANDARD中给出了预定义的128个ASCII字符类型,不能打印的用标识符给出。7.字符串字符串是由双引号括起来的一个字符序列,它也称为字符矢量或字符串数组。例如:“integerrange”字符串常用于程序的提示和说明。8.时间时间是一个物理量数据,应包含整数和单位两部分,而且整数和单位之间应至少留一个空格的位置。例如,55sec,2min等。在程序包STANDARD中给出了时间的预定义,其单位为fs,ps,ns,s,ms,sec,min,hr。在系统仿真时,时间数据特别有用,用它可以表示信号延时,从而使模型系统能更逼近实际系统的运行环境。9.错误等级错误等级类型数据用来表征系统的状态,它共有四种:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)。在系统仿真过程中可以用这4种状态来提示系统当前的工作情况。这样可以使操作人员随时了解当前系统工作的情况,并根据系统的不同状态采取相应的对策。10.大于等于零的整数、正整数这两类数据是整数的子类。上述10种数据类型是VHDL语言中标准的数据类型,在编程时可以直接引用。如果用户需要使用这10种以外的数据类型,则必须进行自定义。但是,大多数的CAD厂商已在程序包中对标准数据类型进行了扩展。关于数据类型由于VHDL语言属于强类型语言,在仿真过程中,首先要检查赋值语句中的类型和区间,任何一个信号和变量的赋值均须落入给定的约束区间中。例如:INTEGERRANGE100DOWNTO1BIT_VECTOR(3DOWNTO0)REALRANGE2.0TO30.0这里的DOWNTO表示下降,而TO表示上升。6.7.2自定义数据类型由用户定义的数据类型的书写格式为:TYPE数据类型名数据类型定义;可由用户定义的数据类型有枚举型、整数型、实数型、数组型、存取型、文件型、记录型和时间型。1.枚举类型枚举类型数据的定义格式为:TYPE数据类型名IS(元素,元素,);这类用户定义的数据类型应用相当广泛,例如在程序包“ST