设计中心 电子设计自动化技术 教师:李平教授(博导) Email: pli@uestc.edu.cn Tel: 83201794 2004年 5月 设计中心 电子设计自动化技术 第四章 VHDL中的语言要素 设计中心 本章要点 ? VHDL与其他软件编程语言一样,对标志 符和数据格式等具有详细的规定。 ? 在编写VHDL程序时必须完全遵守这些规 定。 ? 对于初学者不可能在短时间内完全记住 每一条规定,可以在编译时,由EDA工具 指出错误后,加以更改。 ? 本章的学习应特别注重 “理解” ,而不要 死记硬背。 设计中心 VHDL中的语言要素 ? 标识符 ? 操作符 ? 数据类型 ? 数据对象 ? 对象的申明 设计中心 基本标识符的书写规则 ? 有效的字符是小写字母(a …z),大写字母 (A …Z),数字(0 …9)以及划线 “-”。 ? 标识符必须以英文字母开头,最后一个字不能是下 划线。 ? 不区分大小写。 ? 两个划线不能连续出现。若出现则成了注释语句。 举例: drive-bus const32-59 r2d2 ram_address 设计中心 操作符 ? 逻辑运算符 :逻辑运算(Logical) ? 算术运算符 :算术运算(Arithmetic) ? 关系运算符 :关系运算(Relational) ? 并置运算符 :并置运算(Concatenation) 需要注意 A. 被操作符所操作的对象是操作数,且操作数 的类型应该和操作符所要求的类型相一致。 B. 运算操作符是有优先级的,例如逻辑运算符 NOT,在所有操作符中其优先级最高。表4-1 示出了所有操作符的优先次序。 设计中心 设计中心 逻辑运算符 在VHDL中逻辑运算符共有6种,它们分别是 : ? NOT——取反; ? AND——与; ? OR——或; ? NAND——与非; ? NOR——或非; ? XOR——异或。 设计中心 逻辑运算符 ? 必须注意,运算符的左边和右边,以及代入的 信号的数据类型必须是相同的。 ? 当一个语句中存在两个以上的逻辑表达式时, 在VHDL中,左右没有优先级差别。 X<=(a AND b)OR (NOT c AND d);--必须要括号 ? 如果逻辑表达式中只有“ AND”,“ OR”,“ XOR”运算 符,那么改变运算顺序不会导致逻辑变化。 a<=b AND c AND d AND e ; a<=b XOR c XOR d XOR e ; 设计中心 算术运算符 VHDL有10种算术运算符,它们分别是: ? + ——加; ? - ——减; ? *——乘; ? / ——除; ? MOD——求模; ? REM——取余; ? + ——正;(一元运算) ? - ——负(一元运算) ? ** ——指数; ? ABS——取绝对值。 设计中心 算术运算符(续) ? 实际上能够真正综合逻辑电路的算术运算符只 有“ +”、“ -” 、“ *”。 ? 在数据位较长的情况下,在使用算术运算符进 行运算,特别是使用乘法运算符“ *”时,应特别 慎重。因为对于16位的乘法运算,综合时逻辑 门电路会超过2000个门。 ? 对于算术运算符“ /”、“ MOD”、“ REM”,分母的操作 数为2乘方的常数时,逻辑电路综合是可能的。 设计中心 关系运算符 VHDL中有6种关系运算符,它们分别是: ? = ——等于; ? /= ——不等于; ? < ——小于; ? <= ——小于等于; ? > ——大于; ? >= ——大于等于。 设计中心 关系运算符(续) ? 等号 “=”和不等号 “/=”可以适用所有类型的数据。 ? 其它关系运算符则可使用于整数(INTEGER)和这数 (REAL)、位(STD_LOGIC)等枚举类型以及位矢量 (STD_LOGIC_VECTOR)等数组类型的关系运算。 ? 在进行关系运算时,左右两边的操作数的数据类型 必须相同,但是位长度不一定相同,当然也有例外 的情况。 注意: 在关系运算符中小于等于符 “<= ”和代入符 “<= ” 是相同的,在读VHDL的语句时,应按照上下文关系 来判断此符号到底是关系还是代入符。 设计中心 并置运算符 并置运算符“& ”用于位的连接。 例如: ? 将4个“位”用并置运算符“& ”连接起来就 可以构成一个具有4位长度的位矢量。 ? 两个4位的位矢量用并置运算符“& ”连接 起来就可以构成8位长度的位矢量。 设计中心 数据类型 ? 在VHDL 中,一个对象可以保存一个或几个数, 同时这一个或这几个数可以是某一种或几种类型 的数值。数据类型是对象的这一重要属性的表征。 用一个标识符代表某个或某些个指定类型的数值 的有限或无限集合,则称为一个 数据类型。某个 对象具有某数据类型,就表示该对象可以保存的 数值应该在数据类型所限定的某种类型数的指定 范围中。数据类型由 type语句定义。 ? 根据数据类型所能保存数的个数, 数据类型分纯 量类型、复合类型、存取类型和文件类型。 设计中心 纯量类型 ?纯量类型的对象只能保存一个数。纯量类型的 数据类型 可以包含某一类型数的连续范围或若干离散数。 ?纯量类型又包括以下几种类型: 1. 整数类型(int eger):最大范围是 –2147483647 到 2147483647。 2. 实数类型(Real):定义的范围为– 1.0E+38到 +1.0E+38。实数有正负之分,书写时一定要加小数点。 例如:-3.2,+4.0,-1.0E36。 3. 位类型(Bit):用 “0”和 “1”中的一个来代表二进制的 值。 4. 布尔类型(Boolean):包括False和True 设计中心 纯量类型(续) 5. 枚举类型:此类型是我们可以自定义的类型。 我们可以通过枚举某种类型的所有可能值来定 义一个枚举类型,其定义的基本格式为: type 〈类型名称〉is〈元素1,元素2, ……〉; 例如:TYPE color IS (blue,red,yellow); 6. 时间类型(time):这是一个物理量的数据, 它包括整数和单位两部分,而且整数和单位之 间至少应留有一个空格。例如:35 sec, 2 min。 设计中心 复合类型 复合类型包括数组类型和记录类型: ? 数组类型用于定义同一类型值的集合 ? 记录类型用于定义可能不同类型的集合 设计中心 数组类型 数组类型 是一种复合数据类型,一个数组由若干同 一种数据类型的元素组成,所用数组元素可作一 维或多维排列 ,即数组元素可有一个或多个下标。 定义数组类型的数据类型,应用关键字array说 明是数组类型,并说明数组下标范围和数组元素 的数据类型。如: ? type word is array (15 downto 0) of Bit; ? 此例表示,数据word被定义为数组类型的数据, 该数组包含16个元素,即下标范围从15往下数到 0,该数组元素的类型被定义为了Bit数据类型, BIT类型只能取二进制的0或1。 设计中心 数组类型(续) 下标范围也可以定义为不定,即数组规模也就是数 组中的元素个数不定,此类型的数组可以如下定 义: type Bit_vector is array (Natural range <>) of Bit; 此例中,Bit_vector也是被定义为以数据类型Bit 为 元素组成的数组类型。在下标定义中使用range<> 表示该数组类型的下标范围不定,但下标的数据 类型为Natural, 这是一个已定义过的数值为自然数 的数据类型。也就是说这个数组的元素的下标只 要是自然数就行了,数据类型Bit_vector和Natural 也是VHDL 中的预定义的数据类型。 设计中心 记录类型 记录也是一种复合类型,上面讲到由同一类的数据组 织在一起而形成的新的数据类型叫数组类型,而由 不同类型的数据组织在一起而形成的数据类型叫记 录类型。 记录类型的规范书写格式为: TYPE 数据类型 IS RECORD 元素名: 数据类型名; 元素名: 数据类型名; ┆ END RECORD; 设计中心 记录类型定义示例 TYPE pic_bus IS RECORD ADDR: STD_LOGIC_VECTOR (31 DOWNTO 0); DATA: STD_LOGIC_VECTOR (31 DOWNTO 0); END RECORD; 这里 pic_bus被定义为记录类型,其中 ADDR和 DATA 是其中的两个元素,这两个元素都是位矢量。 设计中心 存取类型 存取类型类似于C语言中的指针类型,它被用来 在对象之间建立联系,或者给新对象分配或 释放存储空间。在IEEE std_1076的程序包 TEXTIO 中,有1个预定义的存取类型 Line (系统工程师也可以定义自己的存取类型); TYPE line IS ACCESS string; 这表示类型为line 的变量是指向字符串值的指 针。只有变量才可以是存取类型,例如: VARIABLE line_buffer : line ; 设计中心 文件类型 ?文件类型用于在主系统环境中定义代表文件的对象, 文件对象的值是主系统文件中值的序列。 ?在IEEE Std_1076的程序包TEXTIO中,有1个预定义 的文件类型Text (系统工程师也可以定义自己的文 件类型): TYPE Text IS FILE OF string; -- TEXTIO程序包中预定义的文件类型 TYPE input_type IS FILE OF character ; --系统工程师自定义的文件类型 设计中心 数据对象 ?VHDL程序中数值的载体称为对象( object)。 ?VHDL中有四种对象:常量(constant )、变 量( variable)信号( signal)和文件 (file)。其 中文件类型是 VHDL 的93 标准中更新通过的。 ?常量、变量和文件的定义与高级语言中的定义 是一样的,在这里用来描述电路的行为。信号 可以看作是电路中的信号线,文件是传输大量 数据的客体,在仿真测试时,测试的输入激励 数据和仿真输出常常需要用文件来实现。 设计中心 请注意三点: 1. 常量只能进行一次赋值,变量和信号则可多次赋值。 2. 信号相当于硬件中的连线(信号线),因 此信号的 赋值必须经一段时间延迟才能生效;而变量的赋值 是立即生效。 3. 常量是全局量,即其值始终不变。在结构体描述, 包集合说明,实体说明,过程说明,函数调用说明 和进程说明中使用。变量是局部量,在进程说明, 函数调用说明,过程说明中使用。信号是全局量, 在结构体描述,包集合说明,实体说明中使用。 设计中心 【例4-1 】变量与信号赋值语句 (1 ) a_variable := x * y ; (2 ) b_variable := a_variable + z ; (3 ) a_signal <= x * y ; (4 ) b_signal <= a_signal + z ; ? 语句( 1)和语句( 2)的变量赋值是立即生效的, 相邻语句的变量值可以传递; ? 语句( 3)和语句( 4)的信号赋值受△延时作用, 其赋值过程特殊,相邻语句的信号值不可以传递。 设计中心 对象的声明 在VHDL中,所使用的对象要预先声明,对象的声明包 括对象的类型和它的数据类型,有时也可给出 其初值。 对象声明的一般形式为: 〈 对象类型〉〈对象名〉:〈数据类型〉:=〈初值〉; 一个特定对象的声明要求指明它的对象类型(常量、 变量、信号)和数据类型。 例如 : SIGNAL clk: BIT; clk被声明为了一个信号(S IGNAL) ,并且clk的数据 类型属于BIT类型。 一个数值也可以被选择定义为信号、常量或变量。 对于一个文件,声明中需要有如何打开这个文件的信息。 设计中心 常量声明 常量声明一般格式为: CONSTANT 常量名 : 数据类型 := 表达式 ; 例如: CONSTANT rise_time : TIME :=10ns ; CONSTANT bus_width : INTEGER :=8 ; 第一行声明了对象rise_time,它的数值的类型是TIME 型的(TIME 是语言中预先定义的),它在仿真开始 时的值设定为10ns。 第二行声明了常量bus_width,它为整数类型的数值8。 设计中心 以下进一步举例说明常量的声明: CONSTANT a : BIT_VECTOR (0 TO 3) ; 对象a被定义为常量,数据类型为位向 量BIT_VECTOR。在 定义对象a时确定了其下标范围,从0到3。 在定义常量a时,也可同时进行赋值,以枚举形式给出它 的各个元素的数值,如: CONSTANT a : BIT_VECTOR := (‘0’,’0’,’1’,’0’) ; 这是按位向量下标顺序列出a (0:3)的值的。也可不按顺 序,但要标明下标值。如下面两式均与上式等价: CONSTANT a : BIT_VECTOR :=(0=>’0’,1=>’0’,2=>’1’,3=>’0’); CONSTANT a : BIT_VECTOR :=(2=>’1’,OTHERS=>’0’); 由于BIT_VECTOR是位向量,故可用位串 表示其值,如a可 等价地定义为: CONSTANT a : BIT_VECTOR := ”0010”; 设计中心 变量声明 变量声明一般格式为: VARIABLE 变量名:数据类型、约束条件:=表达式 ; 例如: VARIABLE ctrl_status:BIT_VECTOR(10 DOWNTO 0); VARIABLE sum:INTEGER RANGE 0 TO 100:=10; 第一行声明对象 ctrl_status为有 11个元素的数列,每 个数列元素的类型是 BIT。 设计中心 信号声明 信号声明一般格式为: SIGNAL 信号名:数据类型、约束条件:=表达式; 例如: SIGNAL sys_clk: BIT := ’0’ ; SIGNAL sys_busy : BIT :=’1’ ; SIGNAL count : BIT_VECTOR (7 DOWNTO 0) ; 有关信号的使用规则如下: “:=” 表示直接赋值,可用于信号赋初始值 (无延时 )。 “<=” 表示代入赋值,用于信号的传递,允许延时。 例如: t1<= t2 AFTER 20ns ; 上式表明信号 t2的值在延时 20ns后赋予 t1。 设计中心 文件声明 对文件进行说明的格式是: FILE 文件变量:TEXT IS 方向 “文件名 ”; 其中的“ 方向” 是指明读还是写,读为IN,写为OUT。 “文 件名” 所指的文件必须是ASCII 码的文件。当读入时, 此文件的扩展名必须为 “in”,当读出时,扩展名必须 为“ out”。 例如: FILE fi :TEXT IS IN “test.in”; 上面一条语句说明 fi被定义为文件变量,它指向文件 名为 test.in的文件。 设计中心 从文件中读出一行的格式是: READLINE (文件变量,行变量); 例如: VARIABLE li:LINE; READLINE (fi ,li); 首先定义li为行变量(即LINE),然后从前一例定 义的文件变量fi所指的文件(即test.in)中读出一 行数据,赋值给行变量li。 从文件中读出一行后,还可以依次读出一行中的 每个数据,放到指定的数据变量或信号中,其格式为: READ(行变量,数据变量); 例如(接上面的例子): READ(li,clk); READ(li,dout); 设计中心 作业