EDA技术与VHDL设计 第6章 VHDL结构与要素
3.1 概述 数字系统设计分为硬件设计和软件设计, 但是随着计算机技术、超大规模集成电路(CPLD、FPGA)的发展和硬件描述语言(HDL, Hardware Description Language)的出现,软、硬件设计之间的界限被打破,数字系统的硬件设计可以完全用软件来实现,只要掌握了HDL语言就可以设计出各种各样的数字逻辑电路。
3.1.1 什么是VHDL及VHDL语言的发展历史 以前很多ASIC制造商都自己开发了HDL语言,存在着很大的差异,工程师一旦选用某种硬件描述语言作为输入工具,就被束缚在这个硬件设计环境之中。因此,硬件设计工程师需要一种强大的、标准化的硬件描述语言,作为可相互交流的设计环境。目前常用硬件描述语言有VHDL、Verilog和ABEL语言,利用硬件描述语言使数字系统设计更加简单和容易。
美国国防部在80年代初提出了VHSIC(Very High Speed Integrated Circuit)计划,其目标之一是为下一代集成电路的生产,实现阶段性的工艺极限以及完成10万门级以上的设计,建立一项新的描述方法。VHDL的英文全名是Very-High-Speed Integrated Circuit Hardware Description Language,诞生于1982年。
1987年底, VHDL被IEEE ( The Institute of Electrical and Electronics Engineers)和美国国防部确认为标准硬件描述语言。自IEEE公布了VHDL的标准版本(IEEE-1076)之后,各EDA公司相继推出了自己的VHDL设计环境,或宣布自己的设计工具可以和VHDL接口。 此后VHDL在电子设计领域得到了广泛的接受,并逐步取代了原有的非标准硬件描述语言。
1993年,IEEE对VHDL进行了修订,从更高的抽象层次和系统描述能力上扩展VHDL的内容,公布了新版本的VHDL,即IEEE标准的1076-1993版本。现在,VHDL和Verilog作为IEEE的工业标准硬件描述语言,又得到众多EDA公司的支持,在电子工程领域,已成为事实上的通用硬件描述语言。有专家认为,在新的世纪中,VHDL与Verilog语言将承担起几乎全部的数字系统设计任务。
3.1.2 VHDL的作用 1.VHDL打破软硬件的界限 传统的数字系统设计方法是硬件设计由硬件设计者承担,软件设计由软件设计者承担,二者没有交流。VHDL语言是用软件的方式设计系统,即使不懂硬件电路也可以设计出一个硬件系统;所以硬件描述语言是现代电子设计者与EDA工具的桥梁,EDA工具及VHDL语言的流行使电子系统向集成化、大规模、高速度等方向发展。
2.VHDL与C、C++的比较 正如用C、C++代替汇编语言设计系统软件那样,用VHDL语言代替原理图、逻辑状态图等。 3.VHDL与原理图描述的比较 VHDL具有较强的抽象描述能力,可进行系统行为级别的描述。描述简洁,效率更高。
VHDL描述与实现工艺无关。而电路原理图描述必须给出完整的具体电路结构图,不能进行抽象描述。描述复杂且效率低。电路原理图描述与实现工艺有关(当功能变时必须重新设计,造成资源浪费,效率低)。
3.1.3 VHDL语言特点 系统硬件描述能力强,设计效率高,具有较高的抽象描述能力。如:一个可置数的16位计数器原理图是一个很庞大的图,一般用一个人一天才能设计出来,而用VHDL语言设计很简单,仅十几条语句,非常间洁, 效率很高。且对电路的修改非常方便。 VHDL语言可读性强,易于修改和发现错误。
VHDL具有丰富的仿真语句和库函数,可对VHDL的源代码进行早期的功能仿真,有利于系统的分析与验证。 移植性好
采用自下而上的设计方法,即:Top-Down和CE(并行工程)设计思想。 上市时间快,成本低。 易于ASIC实现 VHDL有以下描述风格 行为描述、数据流(寄存器传输RTL)描述和结构化描述。
3.1.4 VHDL与其它硬件描述语言的比较 行为级 RTL级 门电路级
VHDL起源于美国国防部的VHSIC,Verilog起源于集成电路的设计,ABEL则来源于可编程逻辑器件的设计。下面从使用方面将三者进行对比。 (1) 逻辑描述层次:一般的硬件描述语言可以在三个层次上进行电路描述,其层次由高到低依次可分为行为级、RTL级和门电路级。VHDL语言是一种高级描述语言,适用于行为级和RTL级的描述,最适于描述电路的行为;Verilog语言和ABEL语言是一种较低级的描述语言,适用于RTL级和门电路级的描述,而ABEL最适于描述门级电路。
(2) 设计要求:VHDL进行电子系统设计时可以不了解电路的结构细节,设计者所做的工作较少;Verilog和ABEL语言进行电子系统设计时需了解电路的结构细节,设计者需做大量的工作。 (3) 综合过程:任何一种语言源程序,最终都要转换成门电路级才能被布线器或适配器所接受。因此,VHDL语言源程序的综合通常要经过行为级→RTL级→门电路级的转化,VHDL几乎不能直接控制门电路的生成。
而Verilog语言和ABEL语言源程序的综合过程要稍简单,即经过RTL级→门电路级的转化,易于控制电路资源。 (4) 对综合器的要求:VHDL描述语言层次较高,不易控制底层电路,因而对综合器的性能要求较高,Verilog和ABEL对综合器的性能要求较低。 (5) 支持的EDA工具:支持VHDL和Verilog的EDA工具很多,但支持ABEL的综合器仅仅Dataio一家。 (6) 国际化程度:VHDL和Verilog已成为IEEE标准,而ABEL正朝国际化标准努力
3.1.5 VHDL的优点 VHDL主要用于描述数字系统的结构、行为、功能和接口。除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法十分类似于一般的计算机高级语言。VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件、一个电路模块或一个系统)分成外部(或称可视部分,即端口)和内部(或称不可视部分),即设计实体的内部功能和算法完成部分。
在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。应用VHDL进行工程设计的优点是多方面的,具体如下: (1) 与其他的硬件描述语言相比,VHDL具有更强的行为描述能力。强大的行为描述能力是避开具体的器件结构,从逻辑行为上描述和设计大规模电子系统的重要保证。
就目前流行的EDA工具和VHDL综合器而言,将基于抽象的行为描述风格的VHDL程序综合成为具体的FPGA和CPLD等目标器件的网表文件已不成问题,只是在综合与优化效率上略有差异。
(3) VHDL语句的行为描述能力和程序结构,决定了它具有支持大规模设计的分解和已有设计的再利用功能。符合市场需求的大规模系统高效、高速的完成必须有多人甚至多个开发组共同并行工作才能实现,VHDL中设计实体的概念、程序包的概念、设计库的概念为设计的分解和并行工作提供了有利的支持。
(4) 用VHDL完成一个确定的设计,可以利用EDA工具进行逻辑综合和优化,并自动把VHDL描述设计转变成门级网表(根据不同的实现芯片)。这种方式突破了门级设计的瓶颈,极大地减少了电路设计的时间和可能发生的错误,降低了开发成本。利用EDA工具的逻辑优化功能,可以自动地把一个综合后的设计变成一个更小、更高速的电路系统。反过来,设计者还可以容易地从综合和优化的电路获得设计信息,返回去更新修改VHDL设计描述,使之更加完善。
3.1.6 VHDL程序设计约定 为了便于程序的阅读和调试,本书对VHDL程序设计特作如下约定: (2) 语句结构描述中方括号“[ ]”内的内容为可选内容。 (3) 对于VHDL的编译器和综合器来说,程序文字的大小写是不加区分的。本书一般使用大写。例外:‘’、“”所括的字符、字符串大小写意义有别。
(3) 程序中的注释使用双横线“--”。在VHDL程序的任何一行中,双横线“--”后的文字都不参加编译和综合。 (4) 为了便于程序的阅读与调试,书写和输入程序时,使用层次缩进格式,同一层次的对齐,低层次比较高层次缩进两个字符。 (5) 考虑到MAX+plusII要求源程序文件的名字与实体名必须一致,因此为了使同一个VHDL源程序文件能适应各个EDA开发软件上的使用要求,建议各个源程序文件的命名均与其实体名一致。
VHDL结构与要素 实体 结构体 VHDL库 VHDL程序包 配置 VHDL文字规则 VHDL数据类型 VHDL操作符 VHDL数据类型 6.1 结构体 6.2 6.3 VHDL库 6.4 VHDL程序包 6.5 配置 VHDL文字规则 6.6 6.7 VHDL数据类型 6.8 VHDL操作符 6.7 VHDL数据类型
先看一个例子:D触发器 library ieee; 库 实体 结构体 use ieee.std_logic_1164.all; entity dff is port(clk,clr,d:in std_logic; q:out std_logic); architecture rtl of dff is begin process(clr,clk) if clr=‘1’ then q<=‘0’; elsif clk’event and clk=‘1’ then q<=d; end if; end process; end rtl; 库 实体 结构体
图 3.1 VHDL程序设计基本结构
6.1 实体 entity 实体名 is [generic(参数名:数据类型);] [port (引脚名:引脚属性 类型; . . . 实体一般格式 entity 实体名 is [generic(参数名:数据类型);] [port (引脚名:引脚属性 类型; . . . 引脚名:引脚属性 类型 );] end entity 实体名;
6.1.1 类属参数说明 generic ( [ 常数名:数据类型[ :设定值] {;常数名:数据类型[:设定值]}); 类属参数是VHDL的一个术语,用以将信息参数传递到实体。 参数传递语句的一般格式如下: generic ( [ 常数名:数据类型[ :设定值] {;常数名:数据类型[:设定值]});
例:在译码器中使用类属语句 entity decoder is generic ( N : positive ; --N表示输入端口的数目 port ( sel : in bit_vector (1 to N ) ; dout : out bit_vector ( 1 to 2**N )); end entity decoder ;
例:使用类属语句表示延迟 entity gate is generic ( delay : time : = 5ns; port ( …); end entity gate ; … out<=in1 and in2 after delay ;
6.1.2 端口说明 port ( 端口名 : 端口模式 数据类型; … 端口名 :端口模式 数据类型); 端口为设计实体和其外部环境提供动态通信的通道,功能相当于外部引脚。 端口说明语句的一般格式如下: port ( 端口名 : 端口模式 数据类型; … 端口名 :端口模式 数据类型); 其中,端口名是设计者为实体的每一个对外通道所取的名字;端口模式是指这些通道上的数据流动方式,如输入或输出等;数据类型是指端口上流动的数据的表达格式。
端口名与端口模式 端口名是每个实体外部引脚的名称,通常用一个或几个英文字母或英文字母加数字命名,如d0、sel、q0等。 端口模式用来定义外部引脚的信号方向,模式有4种:in(输入)、out(输出)、buffer(缓冲器)、inout(双向)。
图6.1 端口模式符号图
6.2 结构体 结构体也叫构造体,描述基本设计单元的结构、行为、元器件及宁内部连接关系。 结构体包括两个组成部分: (1)说明部分:对数据类型、常数、信号、子程序和元器件等要素进行说明。 (2)描述语句部分:包括各种顺序语句和并行语句。
结构体的一般格式 architecture 结构体名 of 实体名 is begin 功能描述(包括并行、进程等)语句; end entity 结构体名;
3.2.2 结构体(ARCHITECTURE) l结构体有三种描述方式 –行为描述(behavioral) –数据流描述(dataflow) –结构化描述(structural) 结构体是用于描述设计实体的内部结构以及实体端口间的逻辑关系。一般地,一个完整的结构体由两个基本层次组成:
● 对数据类型、常数、信号、子程序和元件等元素的说明部分。 ● 描述实体逻辑行为的,以各种不同的描述风格表达的功能描述语句。 结构体将具体实现一个实体。每个实体可以有多个结构体,每个结构体对应着实体不同结构和算法实现方案,其间的各个结构体的地位是同等的,它们完整地实现了实体的行为,但同一结构体不能为不同的实体所拥有。结构体不能单独存在,它必须有一个界面说明,即一个实体。
对于具有多个结构体的实体,必须用CONFIGURATION配置语句指明用于综合的结构体和用于仿真的结构体,即在综合后的可映射于硬件电路的设计实体中,一个实体只对应一个结构体。在电路中,如果实体代表一个器件符号,则结构体描述了这个符号的内部行为。当把这个符号例化成一个实际的器件安装到电路上时,则需配置语句为这个例化的器件指定一个结构体(即指定一种实现方案),或由编译器自动选一个结构体。
6.2.1 结构体的命名 结构体名称由设计者自行定义,指明结构体归属的实体。 结构体的命名有一定规则需要遵循,最好能体现不同的描述方式。 同一实体的结构体不能同名 定义语句中的常数、信号不能与实体中的端口同名
6.2.2 结构体信号定义语句 结构体信号定义必须在architecture和end之间。 结构体中定义的信号应有名称和数据类型,但没有属性,这点与端口不同。 结构体定义的信号只在本结构体有效,对于其它结构体则失去作用。
1. 结构体的一般语句格式如下: ARCHITECTURE 结构体名 OF 实体名 IS [说明语句] 内部信号,常数,数据类型,函数等的定义 BEGIN [功能描述语句] END 结构体名; 其中,实体名必须是所在设计实体的名字,而结构体名可以由设计者自己选择,但当一个实体具有多个结构体时,结构体的取名不可重复。
2.结构体说明语句 结构体中的说明语句是对结构体的功能描述语句中将要用到的信号(SIGNAL)、数据类型(TYPE)、常数(CONSTANT)、元件(COMPONENT)、函数(FUNCTION)和过程(PROCEDURE)等加以说明的语句。但在一个结构体中说明和定义的数据类型、常数、元件、函数和过程只能用于这个结构体中,若希望其能用于其他的实体或结构体中,则需要将其作为程序包来处理。
结构体是实体的一个重要部分,每一个实体都有一个或一个以上的结构体。 例: ENTITY nax IS PORT(a0,a1 : IN BIT; Sel : IN BIT; Sh : OUT BIT); END nax; ARCHITECTURE dataflow OF nax IS BEGIN sh<=(a0 AND sel) OR (NOT sel AND a1); END dataflow;
结构体描述设计实体的具体行为,它包含两类语句: 并行语句 并行语句总是在进程语句(PROCESS)的外部,该语句的执行与书写顺序无关,总是同时被执行 顺序语句 顺序语句总是在进程语句(PROCESS)的内部,从仿真的角度,该语句是顺序执行的 一个结构体包含几个类型的子结构描述,这些描述是: * BLOCK描述(块描述) * PROCESS描述(进程描述)
* SUNPROGRAMS描述(子程序描述) 从前面的设计实例可以看出,一个相对完整的VHDL程序(或称为设计实体)具有如图3.1所示的比较固定的结构。至少应包括三个基本组成部分:库、程序包使用说明,实体说明和实体对应的结构体说明。其中,库、程序包使用说明用于打开(调用)本设计实体将要用到的库、程序包;实体说明用于描述该设计实体与外界的接口信号说明,是可视部分;结构体说明用于描述该设计实体内部工作的逻辑关系,是不可视部分。在一个实体中,可以含有一个或一个以上的结构体,而在每一个结构体中又可以含有一个或多个进程以及其他的语句。根据需要,实体还可以有配置说明语句。
配置说明语句主要用于以层次化的方式对特定的设计实体进行元件例化,或是为实体选定某个特定的结构体。 如何才算一个完整的VHDL程序(设计实体),并没有完全一致的结论,因为不同的程序设计目的可以有不同的程序结构。通常认为,一个完整的设计实体的最低要求应该能为VHDL综合器所接受,并能作为一个独立设计单元,即以元件的形式存在的VHDL程序。这里所谓的元件,既可以被高层次的系统所调用,成为该系统的一部分,也可以作为一个电路功能块而独立存在和独立运行 .
3.功能描述语句结构 如图3.4所示的功能描述语句结构可以含有五种不同类型的,以并行方式工作的语句结构。而在每一语句结构的内部可能含有并行运行的逻辑描述语句或顺序运行的逻辑描述语句。各语句结构的基本组成和功能分别是: (1) 块语句是由一系列并行执行语句构成的组合体,它的功能是将结构体中的并行语句组成一个或多个模块。
(2) 进程语句定义顺序语句模块,用以将从外部获得的信号值,或内部的运算数据向其他的信号进行赋值。 (3) 信号赋值语句将设计实体内的处理结果向定义的信号或界面端口进行赋值。 (4) 子程序调用语句用于调用一个已设计好的子程序。 (5) 元件例化语句对其他的设计实体作元件调用说明,并将此元件的端口与其他的元件、信号或高层次实体的界面端口进行连接。 (CONFIGURATION)
配置可以把特定的结构体指定给一个确定的实体。通常在大而复杂的VHDL工程设计中,配置语句可以为实体指定或配置一个结构体。如可利用配置使仿真器为同一实体配置不同的结构体以使设计者比较不同结构体的仿真差别,或者为例化的各元件实体配置指定的结构体,从而形成一个所希望的例化元件层次构成的设计实体。 VHDL综合器允许将配置规定为一个设计实体中的最高层设计单元,但只支持对最顶层的实体进行配置。一个设计实体的配置可用如图3.5表示
设计实体 结构体2 结构体n 结构体1 结构体3 … 图 3.5 一个设计实体的配置
配置语句的一般格式如下: CONFIGURATION 配置名 OF 实体名 IS 配置说明 END配置名; 配置主要为顶层设计实体指定结构体,或为参与例化的元件实体指定所希望的结构体,以层次方式来对元件例化作结构配置。如前所述,每个实体可以拥有多个不同的结构体,而每个结构体的地位是相同的,在这种情况下,可以利用配置说明为这个实体指定一个结构体。
例3.2.3是一个配置的简单方式应用,即在一个描述与非门NAND的设计实体中会有两个以不同的逻辑描述方式构成的结构体,用配置语句来为特定的结构体需求作配置指定。 【例3.2.3】 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY NAND IS PORT(A:IN STD_LOGIC; B:IN STD_LOGIC; C:OUT STD_LOGIC);
END ENTITY NAND; ARCHITECTURE ART1 OF NAND IS BEGIN C<=NOT (A AND B ); END ARCHITECTURE ART1; ARCHITECTURE ART2 OF NAND IS C<= ‘1’ WHEN (A=‘0’) AND(B=‘0’) ELSE ‘1’ WHEN (A=‘0’) AND(B=‘1’) ELSE ‘1’ WHEN (A=‘1’) AND(B=‘0’) ELSE ‘0’ WHEN (A=‘1’) AND(B=‘1’) ELSE ‘0’;
END ARCHITECTURE ART2; CONFIGURATION FIRST OF NAND IS FOR ART1 END FOR; END FIRST; CONFIGURATION SECOND OF NAND IS FOR ART2 END SECOND;
在本例中若指定配置名为SECOND,则为实体NAND配置的结构体为ART2;若指定配置名为 FIRST,则为实体NAND配置的结构体为ART1。这两种结构的描述方式是不同的,但是有相同的逻辑功能。 如果将例3.2.3中的配置语句全部除去,则可以用此具有两个结构体的实体NAND构成另一个更高层次设计实体中的元件,并由此设计实体中的配置语句来指定元件实体NAND使用哪一个结构体。
6.3 VHDL库 库是经编译后的数据的集合,它存放程序包定义、实体定义、结构体定义和配置定义。 库的好处在于使设计者可以共享已经编译过的设计结果。 在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”程序包的数据时,应说明库和程序包名,然后才可以使用该程序包的数据。例如: LIBRARY IEEE ; USE STD.TEXTIO.ALL ;
3. WORK库 是现行作业库。设计者所描述的VHDL语句不需要任何说明,将都存放在WORK库中。使用该库时无需进行任何说明。 工作库并非文件夹的名称,而是一个逻辑名。综合器将指向该文件夹的路径。
4. 用户自定义库 用于为自身设计需要所开发的共用程序包和实体等,也可汇集在一起定义成一个库。
6.3.2 库的用法 LIBRARY 库名 ; USE 库名. 程序包名.项目名; 例如,需要使用IEEE库中的STD_LOGIC_1164程序包所有项目,则使用语句为: LIBRARY IEEE ; USE IEEE. STD_LOGIC_1164.ALL;
6.4 VHDL程序包 为了使已定义的常数、数据类型、元件调用说明以及子程序等能被更多的其它设计实体方便地访问和共享,可以将它们收集在一个VHDL程序包中。 多个程序包可以并入一个VHDL库中,使之适用于更一般的访问和调用范围。
6.4.1 程序包组成和格式 由两部分组成:程序包首和程序包体。 程序包的一般格式:
6.4.2 VHDL标准程序包 STD_LOGIC_1164:包含一些数据类型、子类型和函数定义。 STD_LOGIC_ARITH:在STD_LOGIC_1164的基础上扩展了三个数据类型UNSIGNED、SIGNED和SMALL_INT,并为其定义了相关的算术运算符和数据类型转换函数。
6.4.2 VHDL标准程序包 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 实体名 IS FOR 选配结构体名 END FOR; END 配置名;
6.6 VHDL文字规则 VHDL语言与其它高级语言一样,除了具有一般文字规则外,对标识符和数据格式等都有详细规定。在编写VHDL程序时必须完全遵守这些规定。 初学者不可能在短时间内记住每一条规定,可以在编译时,由EDA软件指出错误后加以更正。 本节的学习应特别注意理解,而不是死记硬背。
6.6.1 标识符 用来表示常数、变量、信号、端口、子程序或参数的名称。
标识符书写规则 (1)有效的字符必须是小写字母(a-z)、大写字母(A-Z)、数字(0-9)以及下划线。 (2)标识符必须以英文字母开头,最后一个字符不能是下划线。 (3)不区分大小写。 (4)两个划线不能连续出现,若出现则成了注释语句。 (5)VHDL的保留字不能作为标识符使用。 (6)允许包含图形符号(如回车符、换行符等),也允许包含空格符。(93标准,以/来界定)
标识符命名举例 合法: (1)my_counter (2)decoder_1 (3)FFT (4)ram-address 不合法: (3)RYY_RST_:末尾不能是下划线
6.6.2 数字 (1)整数:表示成“进制#数值#指数”五个部分。#起分隔作用,十进制用10表示,十六进制用16表示,八进制用8表示,二进制用2表示。 整数包括:正整数、负整数和零 范围:32位带符号数原码,即-(231-1)~+(231-1) (-2147483647~+2147483647)
(2)实数:实数是十进制的数,由正、负、小数点和数字组成,但须带小数点,如,1.335,99E-2等。 范围:-1.0E+38 TO +1.0E+38 (3)物理量文字:VHDL综合器不接受此类文字,如60s,100m等。
6.6.3 字符串 1. 字符(CHARACTER)数据类型 字符是用单引号括起来的ASCII码字符,如‘A’,‘a’,‘0’,‘9’ 定义语句: TYPE CHARACTER IS(ASCII码字符表中的全部字符) 2、 字符串(STRING)数据类型 字符串是用双引号括起来的字符序列,也称字符矢量或字符串数组。例如, “A BOY.”,“10100011”
6.7 VHDL数据类型 一种分类,四类:标量型、复合型、存取型和文件型。 第二种分类,两类:预定义数据类型和自定义数据类型两个类别。
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. 字符串 字符串是由双引号括起来的一个字符序列,它也称为字符矢量或字符串数组。例如: “integer range” 字符串常用于程序的提示和说明。
8. 时间 时间是一个物理量数据,应包含整数和单位两部分,而且整数和单位之间应至少留一个空格的位置。例如,55 sec,2 min等。 在程序包STANDARD中给出了时间的预定义,其单位为fs,ps,ns,s,ms,sec,min,hr。 在系统仿真时,时间数据特别有用,用它可以表示信号延时,从而使模型系统能更逼近实际系统的运行环境。
9. 错误等级 错误等级类型数据用来表征系统的状态,它共有四种:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)。 在系统仿真过程中可以用这4种状态来提示系统当前的工作情况。这样可以使操作人员随时了解当前系统工作的情况,并根据系统的不同状态采取相应的对策。
10. 大于等于零的整数、正整数 这两类数据是整数的子类。 上述10种数据类型是VHDL语言中标准的数据类型,在编程时可以直接引用。如果用户需要使用这10种以外的数据类型,则必须进行自定义。但是,大多数的CAD厂商已在程序包中对标准数据类型进行了扩展。
关于数据类型 由于VHDL语言属于强类型语言,在仿真过程中,首先要检查赋值语句中的类型和区间,任何一个信号和变量的赋值均须落入给定的约束区间中。例如: INTEGER RANGE 100 DOWNTO 1 BIT_VECTOR( 3 DOWNTO 0 ) REAL RANGE 2.0 TO 30.0 这里的DOWNTO表示下降,而TO表示上升。
6.7.2 自定义数据类型 由用户定义的数据类型的书写格式为: TYPE 数据类型名 数据类型定义; 6.7.2 自定义数据类型 由用户定义的数据类型的书写格式为: TYPE 数据类型名 数据类型定义; 可由用户定义的数据类型有枚举型、整数型、实数型、数组型、存取型、文件型、记录型和时间型。
1. 枚举类型 枚举类型数据的定义格式为: TYPE 数据类型名 IS (元素,元素,); 这类用户定义的数据类型应用相当广泛,例如在程序包“STD_LOGIC”和“STD_LOGIC_1164”中都有此类数据的定义。如: TYPE STD_LOGIC IS (‘U’,‘X’,‘0’,‘1’,‘Z’,‘W’,‘L’,‘H’,‘-’);
2. 整数类型、实数类型 这里所说的是用户所定义的整数类型,实际上可以认为是整数的一个子类。 整数或实数用户定义数据类型的格式为: TYPE 数据类型名 IS 数据类型定义 约束范围;
3. 数组 数组类型属复合类型,是将一组具有相同数据类型的元素集合在一起,作为一个数据对象来处理的数据类型。 VHDL仿真器支持多维数组,但综合器只支持一维数组。 数组定义的书写格式为: TYPE 数据类型名 IS ARRAY (范围) OF 原数据类型名;
4. 时间类型 时间类型是表示时间的数据类型,在仿真时是必不可少的。其书写格式为: TYPE 数据类型名 IS 范围 UNITS 基本单位; END UNITS; 这里的基本单位是“fs”,其1000倍是“ps”。
5. 记录类型 数组是同一类型数据集合起来形成的,而记录则是将不同类型的数据和数据名组织在一起形成的新客体。 记录数据类型的定义格式为: TYPE 数据类型名 IS RECORD 元素名:数据类型名; END RECORD;
6.7.3 用户自定义的子类型 用户定义的子类型是用户对已定义数据类型作一些范围限制而形成的一种新的数据类型。子类型的名称通常采用用户较易理解的名字。 子类型定义的一般格式为: SUBTYPE 子类型名 IS 数据类型名 [范围];
6.7.4 数据类型的转换 在VHDL语言中,数据类型的定义是相当严格的,不同类型的数据是不能进行运算和直接代入的。为了实现正确的代入操作,必须将要代入的数据进行类型变换。 变换函数通常由VHDL语言中的程序包提供。例如“STD_LOGIC_1164”、“STD_LOGIC_ARITH”、“STD_LOGIC_UNSIGNED” 程序包中提供了一些数据类型转换函数。
类型函数的转换
6.8 VHDL操作符 在VHDL语言中共有四类运算操作符: (1)逻辑运算 (2)关系运算 (3)算术运算 (4)并置运算
1. 逻辑操作符 在VHDL语言中逻辑操作符共用七种: NOT取反 AND与 OR或 NAND与非 NOR或非 XOR异或 XNOR同或
2. 关系操作符 功能 符号 等于 = 不等于 /= 大于 > 大于等于 >= 小于 < 小于等于 <=
3. 算术操作符 功能 符号 算术加 + 算术减 - 算术乘 * 算术除 / 取模 MOD 取余 REM 取绝对值 ABS 并置 &
4. 并置操作符 并置操作符“&”用于位的连接。 例如,将4个位用并置操作符连接起来就可以构成一个具有4位长度的位矢量。两个4位的位矢量用并置操作符连接起来就可以构成一个8位长度位矢量。
6.9 数据对象 共有四种对象,分别是常量、变量、信号和文件。 信号对应地代表物理设计中的某一条硬件连接线;常数对应地代表数字电路中的电源和地等。变量对应关系不太直接,通常只代表暂存某些值的载体。文件是传输大量数据的客体,在仿真测试时,测试的输入激励数据和仿真输出常常需要用文件来实现。
6.9.1 常量 常数是一个固定的值。常数的定义和设置主要是为了使程序更容易阅读和修改。常数在使用前需要说明。所谓常数说明是指对某一常数名赋予一个固定的值。通常赋值在程序开始之前进行,该值的数据类型则在说明语句中指明。 常数说明的一般格式如下: CONSTANT 常数名:数据类型:=表达式;
6.9.2 变量 变量只能在进程语句、函数语句和过程语句结构中使用,它是一个局部量。在仿真过程中,它不像信号那样,到了规定的仿真时间才进行赋值,变量的赋值是立即生效的。变量的主要作用是在进程中作为临时性的数据存储单元。 变量定义的一般格式为: VARIABALE 变量名:数据类型:=初始值;
6.9.3 信号 信号是电子电路内部硬件连接的抽象。它除了没有数据流动方向说明以外,其它性质几乎和前面所述的“端口”概念一致。信号通常在结构体、程序包和实体中说明。 信号说明语句的一般格式为: SIGNAL 信号名:数据类型 :=初始值;
6.9.4 文件 对文件进行说明的一般格式为: FILE 文件变量:TEXT IS 方向“文件名”; 其中,方向是指明读或写,读为IN,写为OUT; “文件名”所指的文件必须是ASCII码的文件。当读入时,此文件的扩展名必须为“in”,当读出时,文件的扩展名必须为“out”。