第3章ⅤHDL入门 实践表明,ⅤHDL入门的最有效的方法是通过具体电路实例引出对应的ⅤHDL表述, 通过这些有针对性的表述进而学习相关的语句语法,再通过多个类似实例的学习,逐步完 备VHDL的基本语法知识和提高电路的描述和设计能力。据此,全章通过数个简单、完整 而典型的ⅤHDL设计示例,使读者初步了解用VHDL表达和设计电路的方法,并对由此而 引出的ⅤHDL语言现象和语句规则能逐步趋向系统的了解 由于用硬件描述语言来对电子线路的表达和设计是EDA建模和实现技术中最基本和 最重要的方法,其它的许多方法都是建筑在这一基础之上的,如使用 MATLAB/DSP Builder 的设计方案、图形方式的状态机输入法、原理图输入法等等。因此ⅤHDL的学习在EDA 技术的掌握中具有十分重要的地位。 3.1简单组合电路的ⅤHDL描述 2选1多路选择器是典型的组合电路,本章以此电路的DL表述与设计为例,引出 相关的ⅤHDL结构、语句表述、数据规则和语法特点,并加以详细说明。 3.1.1多路选择器的VHDL描述 2选1多路选择器的电路模型,或元件图如图3-1所示。例3-1是其HDL的完整描述,即 可使用ⅤHDL综合器直接综合出实现即定功能的逻辑电路,对应的逻辑电路如图3-2所示,因 而可以认为是此多路选择器的内部电路结构 mux21a b 图3-1mux2la实体 图3-2mu21a结构体 注意,电路的功能可以是唯一的,但其电路的结构方式不是唯一的,它决定于综合器的基 本元件库的来源、优化方向和约束的选择、目标器件(指 FPGA/CPLD)的结构特点等等 图中,a和b分别为两个数据输入端的端口名,s为通道选择控制信号输入端的端口名,y 为输出端的端口名。“mux2la”是设计者为此器件取的名称(好的名称应该体现器件的基
第 3 章 VHDL 入门 实践表明,VHDL 入门的最有效的方法是通过具体电路实例引出对应的 VHDL 表述, 通过这些有针对性的表述进而学习相关的语句语法,再通过多个类似实例的学习,逐步完 备 VHDL 的基本语法知识和提高电路的描述和设计能力。据此,全章通过数个简单、完整 而典型的 VHDL 设计示例,使读者初步了解用 VHDL 表达和设计电路的方法,并对由此而 引出的 VHDL 语言现象和语句规则能逐步趋向系统的了解。 由于用硬件描述语言来对电子线路的表达和设计是 EDA 建模和实现技术中最基本和 最重要的方法,其它的许多方法都是建筑在这一基础之上的,如使用 MATLAB/DSP Builder 的设计方案、图形方式的状态机输入法、原理图输入法等等。因此 VHDL 的学习在 EDA 技术的掌握中具有十分重要的地位。 3.1 简单组合电路的 VHDL 描述 2 选 1 多路选择器是典型的组合电路,本章以此电路的 VHDL 表述与设计为例,引出 相关的 VHDL 结构、语句表述、数据规则和语法特点,并加以详细说明。 3.1.1 多路选择器的 VHDL 描述 2 选 1 多路选择器的电路模型,或元件图如图3-1所示。例3-1 是其 VHDL的完整描述,即 可使用 VHDL 综合器直接综合出实现即定功能的逻辑电路,对应的逻辑电路如图 3-2 所示,因 而可以认为是此多路选择器的内部电路结构。 图 3-1 mux21a 实体 图 3-2 mux21a 结构体 注意,电路的功能可以是唯一的,但其电路的结构方式不是唯一的,它决定于综合器的基 本元件库的来源、优化方向和约束的选择、目标器件(指 FPGA/CPLD)的结构特点等等。 图中,a和 b 分别为两个数据输入端的端口名,s 为通道选择控制信号输入端的端口名,y 为输出端的端口名。“mux21a”是设计者为此器件取的名称(好的名称应该体现器件的基
第3章VHDL入门 本功能特点)。 【例3-1】 ENTITY mux 21a PORt(a, b s:工NB工乎 y: OUT BIT END ENTITY mux21a ARCHITECTURE one oF mux21a Is BEGIN END ARCHITECTURE one 由例3-1可见,此电路的ⅤHDL描述由两大部分组成: (1)以关键词 ENTITY引导, END ENTITY mux21a结尾的语句部分,称为实体 VHDL的实体描述了电路器件的外部情况及各信号端口的基本性质,如信号流动的方向,流 动在其上的信号结构方式和数据类型等。图3-1可以认为是实体的图形表达 (2)以关键词 ARCHITECTURE引导, END ARCHITECTURE one结尾的语句部分 称为结构体。结构体负责描述电路器件的内部逻辑功能和电路结构。图3-2是此结构体的 某种可能的电路原理图表达。 在VHDL结构体中用于描述逻辑功能和电路结构的语句分为顺序语句和并行语句两部 分。顺序语句的执行方式类似于普通软件语言的程序执行方式,是按照语句的前后排列方 式逐条顺序执行的。而在结构体中的并行语句,无论有多少行语句,都是同时执行的,与 语句的前后次序无关(姑且暂时这样认为,以后将给予详细说明)。 例3-1中的逻辑描述是用 WHEN ELSE结构的并行语句表达的。它的含义是,当满足 条件s=0,即s为低电平时,a输入端的信号传送至y,否则即s为高电平时为输入端的 信号传送至y 也可以用其他的语句形式来描述以上相同的逻辑行为。例3-2中的功能描述语句都用 了并行语句,是用布尔方程的表达式来描述的。其中的“AND”、“OR”、“NOT”分别是“与”、 “或”、“非”的逻辑操作符号。 例3-3则给出了用顺序语句 IF THEN ELSE表达的功能描述 以上3例用不同的表达方式描述了相同的逻辑功能,其电路功能可以从图3-3的时序 波形( Quartus仿真波形)中看出,分别向a和b端输入两个不同频率的信号fa和fb(a> fb),当s为高电平时,y输出t,而当s为低电平时,y输出fa。显然,图3-3的波型证实 了ⅤHDL逻辑设计的正确性 注意,以上各例的实体和结构体分别是以“ END ENTITY XXX”和“END ARCHITECTUREⅹx”语句结尾的,这是符合VHDL的 IEEE STD10761993版的语法要 求的。若根据ⅤHDL87版本,即 IEEE STD10761987的语法要求,这两条结尾语句只需 写成“END,”或“ END XX”。但考虑到目前绝大多数常用的EDA工具中的ⅤHDL综合器 都兼容两种ⅤHDL版本的语法规则,且许多最新的VHDL方面的资料,仍然使用ⅤHDL87 版本语言规则,因此,出于实用的目的,对于以后出现的示例,不再特意指出VHDL两种 版本的语法差异处。但对于不同的EDA工具,仍需根据设计程序不同的ⅤDL版本表述
第 3 章 VHDL 入门 71 本功能特点)。 【例3-1】 ENTITY mux21a IS PORT ( a, b : IN BIT; s : IN BIT; y : OUT BIT ); END ENTITY mux21a; ARCHITECTURE one OF mux21a IS BEGIN y fb),当 s 为高电平时,y 输出 fb,而当 s 为低电平时,y 输出 fa。显然,图 3-3 的波型证实 了 VHDL 逻辑设计的正确性。 注意,以上各例的实体和结构体分别是以“ END ENTITY xxx ”和“ END ARCHITECTURE xx ”语句结尾的,这是符合 VHDL 的 IEEE STD 1076_1993 版的语法要 求的。若根据 VHDL’87 版本,即 IEEE STD 1076_1987 的语法要求,这两条结尾语句只需 写成“END;”或“END xx”。但考虑到目前绝大多数常用的 EDA 工具中的 VHDL 综合器 都兼容两种 VHDL 版本的语法规则,且许多最新的 VHDL 方面的资料,仍然使用 VHDL’87 版本语言规则,因此,出于实用的目的,对于以后出现的示例,不再特意指出 VHDL 两种 版本的语法差异处。但对于不同的 EDA 工具,仍需根据设计程序不同的 VHDL 版本表述
EDA技术与VHDL 在综合前作相应的设置。 【例3-2】 ENTITY mux21a IS PORt( a, b: IN BIT; s:工NB工乎 y: OUT BIT END ENTITY mux21 ARCHITECTURE one oF mux21a IS SIGNAL dr e: BIT BEGIN d < a AND (NOT S) y < d or e 【例3-3】 ENTITY mux21a I PORT( a, b, s: IN BIT y: OUT BIT END ENTITY mux21a ARCHITECTURE one oF mux21a Is BEGIN PROCESS(a,b, s) BEGIN IFs="0′THEN y < a ElSE <=b END IF; END PROCESS END ARCHITECTURE one p51m104m15第209m2m Ha酯e -B1puL000100LU10000001L0LU00u00100LU0D0U00 ULUL B1 pouooooL moon FUoODUDLUOOUDUOUn 图3-3mu21a功能时序波形 3.1.2相关语句结构和语法说明 以下将对例3-1至例3-3中出现的相关语句结构和语法含义作出说明 1.实体表达 VHDL完整的、可综合的程序结构必须能完整地表达一片专用集成电路ASIC器件的 端口结构和电路功能,即无论是一片74LS138还是一片CPU,都必须包含实体和结构体两
72 EDA 技术与 VHDL 在综合前作相应的设置。 【例 3-2】 ENTITY mux21a IS PORT ( a, b : IN BIT; s : IN BIT; y : OUT BIT ); END ENTITY mux21a; ARCHITECTURE one OF mux21a IS SIGNAL d,e : BIT; BEGIN d <= a AND (NOT S) ; e <= b AND s ; y <= d OR e ; END ARCHITECTURE one ; 【例 3-3】 ENTITY mux21a IS PORT ( a, b, s: IN BIT; y : OUT BIT ); END ENTITY mux21a; ARCHITECTURE one OF mux21a IS BEGIN PROCESS (a,b,s) BEGIN IF s = '0' THEN y <= a ; ELSE y <= b ; END IF; END PROCESS; END ARCHITECTURE one ; 图3-3 mux21a功能时序波形 3.1.2 相关语句结构和语法说明 以下将对例 3-1 至例 3-3 中出现的相关语句结构和语法含义作出说明: 1. 实体表达 VHDL 完整的、可综合的程序结构必须能完整地表达一片专用集成电路 ASIC 器件的 端口结构和电路功能,即无论是一片 74LS138 还是一片 CPU,都必须包含实体和结构体两
第3章VHDL入门 个最基本的语言结构。这里将含有完整程序结构(包含实体和结构体)的VHDL表述称为设 计实体。如前所述,实体描述的是电路器件的端口构成和信号属性,它的最简表式如下 【例3-4】 ENTITY e name Is poRt(p name port m data type p namei: port mi data type END ENTITY e name; 上式中, ENTITY、IS、PORT和 END ENTITY都是描述实体的关键词,在实体描述 中必须包含这些关键词。在编辑中,关键词不分大写和小写。 2.实体名 例3-4中的 e name是实体名,是标识符,具体取名由设计者自定。由于实体名实际上 表达的应该设计电路的器件名,所以最好根据相应电路的功能来确定,如4位二进制计数 器,实体名可取为 counter4b;8位二进制加法器,实体名可取为ader8b,等等。但应注意, 不应用数字或中文定义实体名,也不应用与EDA工具库中已定义好的元件名作为实体名 如or2、 latch等,且不能用数字起头的实体名,如74LSx 3.端口语句和端口信号名 描述电路的端口及其端口信号必须用端口语句PORT(別导,并在语句结尾处加分号 “;"。例3-4中的 p name是端口信号名,如例3-1中的端口信号名分别是a、b、s和y 4.端口模式 在例3-1的实体描述中,用IN和oU分别定义端口a、b和s为信号输入端口,y为信号 输出端口。一般,可综合的端口模式有四种,它们分别是“IN”、“oUr”、“ INOUT” 和“ BUFFER”,用于定义端口上数据的流动方向和方式: κIN:输入端口,定义的通道为单向只读模式。规定数据只能由此端口被读入实体。 κeOUI:输出端口,定义的通道为单向输出模式。规定数据只能通过此端口从实体 向外流出,或者说可以将实体中的数据向此端口赋值 κε INOUT:定义的通道确定为输入输出双向端口。即从端口的内部看,可以对此端 口进行赋值,或通过此端口读入外部的数据信息;而从端口的外部看,信号既可 由此端口流出,也可向此端口输入信号。如RAM的数据口,单片机的O口等 BUFFer:缓冲端口,其功能与 INOUT类似,区别在于当需要输入数据时,只允 许内部回读输出的信号,即允许反馈。如计数器设计,可将计数器输出的计数信 号回读,以作下一计数值的初值。与 INOUT模式相比, BUFFER回读的信号不是 由外部输入的,而是由内部产生,向外输出的信号 5.数据类型 例3-4中的data_type是数据类型名。例3-1中,端口信号a、b、s和y的数据类型都 定义为BIT。由于VHDL中任何一种数据对象的应用都必须严格限定其取值范围和数值类
第 3 章 VHDL 入门 73 个最基本的语言结构。这里将含有完整程序结构(包含实体和结构体)的 VHDL 表述称为设 计实体。如前所述,实体描述的是电路器件的端口构成和信号属性,它的最简表式如下: 【例 3-4】 ENTITY e_name IS PORT ( p_name : port_m data_type; ... p_namei : port_mi data_type ); END ENTITY e_name; 上式中,ENTITY、IS、PORT 和 END ENTITY 都是描述实体的关键词,在实体描述 中必须包含这些关键词。在编辑中,关键词不分大写和小写。 2. 实体名 例 3-4 中的 e_name 是实体名,是标识符,具体取名由设计者自定。由于实体名实际上 表达的应该设计电路的器件名,所以最好根据相应电路的功能来确定,如 4 位二进制计数 器,实体名可取为 counter4b;8 位二进制加法器,实体名可取为 adder8b,等等。但应注意, 不应用数字或中文定义实体名,也不应用与 EDA 工具库中已定义好的元件名作为实体名, 如 or2、latch 等,且不能用数字起头的实体名,如 74LSxx。 3. 端口语句和端口信号名 描述电路的端口及其端口信号必须用端口语句 PORT( )引导,并在语句结尾处加分号 “;”。例 3-4 中的 p_name 是端口信号名,如例 3-1 中的端口信号名分别是 a、b、s 和 y。 4. 端口模式 在例3-1的实体描述中,用IN和OUT分别定义端口a、b和s为信号输入端口,y为信号 输出端口。一般,可综合的端口模式有四种,它们分别是“IN”、“OUT”、“INOUT” 和“BUFFER”,用于定义端口上数据的流动方向和方式: ?? IN:输入端口,定义的通道为单向只读模式。规定数据只能由此端口被读入实体。 ?? OUT:输出端口,定义的通道为单向输出模式。规定数据只能通过此端口从实体 向外流出,或者说可以将实体中的数据向此端口赋值。 ?? INOUT:定义的通道确定为输入输出双向端口。即从端口的内部看,可以对此端 口进行赋值,或通过此端口读入外部的数据信息;而从端口的外部看,信号既可 由此端口流出,也可向此端口输入信号。如 RAM 的数据口,单片机的 I/O 口等。 ?? BUFFER:缓冲端口,其功能与 INOUT 类似,区别在于当需要输入数据时,只允 许内部回读输出的信号,即允许反馈。如计数器设计,可将计数器输出的计数信 号回读,以作下一计数值的初值。与 INOUT 模式相比,BUFFER 回读的信号不是 由外部输入的,而是由内部产生,向外输出的信号。 5. 数据类型 例 3-4 中的 data_type 是数据类型名。例 3-1 中,端口信号 a、b、s 和 y 的数据类型都 定义为 BIT。由于 VHDL 中任何一种数据对象的应用都必须严格限定其取值范围和数值类
EDA技术与ⅤHDL 型,即对其传输或存储的数据的类型要作明确的界定,因此,在ⅤHIDL设计中,必须预先 定义好要使用的数据类型,这对于大规模电路描述的排错是十分有益的。相关的数据类型 有 INTEGER类型、 BOOLEAN类型、 STD LOGIC类型和BIT类型等 BIT数据类型的信号规定的取值范围是逻辑位和0。在ⅤHDL中,逻辑位0和1的 表达必须加单引号,否则HDL综合器将0和1解释为整数数据类型 INTEGER BIT数据类型可以参与逻辑运算或算术运算,其结果仍是位的数据类型。ⅤHDL综合 器用一个二进制位表示BIl将例3-1中的端口信号a、b、s和y的数据类型都定义为BIr 表示:a、b、s和y的取值范围,或者说数据范围都被限定在逻辑位"l'和o的二值范围内 6.结构体表达 结构体的一般表达如例3-5所示。 【例3-5】 ARCHITECTURE arch name oF e name I [说明语句] BEGIN 功能描述语句) END ARCHITECTURE arch name 上式中, ARCHITECTURE、OF、IS、 BEGIN和 END ARCHITECTURE都是描述结构 体的关键词,在描述中必须包含它们。 arch name是结构体名,是标识符 说明语句]包括在结构体中,用以说明和定义数据对象、数据类型、元件调用声明等 等。[说明语句]并非是必须的,(功能描述语句)则不同,结构体中必须给出相应的电路功能 描述语句,可以是并行语句,顺序语句或它们的混合 般地,一个可综合的,完整的VHDL程序有比较固定的结构。设计实体中,一般首 先出现的是各类库及其程序包的使用声明,包括未以显式表达的工作库WORK库的使用声 明,然后是实体描述,最后是结构体描述,而在结构体中可以含有不同的逻辑表达语句结 构。如前所述,在此把一个完整的可综合的ⅤHDL程序设计构建为设计实体(独立的电路 功能结构),而其程序代码常被称为ⅵHIDL的RTL描述 7.赋值符号和数据比较符号 例3-1中的表达式y<=a表示输入端口a的数据向输出端口y传输;但也可以解释为信 号a向信号y赋值。在HDL仿真中赋值操作y<=a并非立即发生的,而是要经历一个模 拟器的最小分辨时间?后,才将a的值赋予y。在此不妨将?看成是实际电路存在的固有 延时量。ⅤHDL要求赋值符“<=”两边的信号的数据类型必须一致 例3-1中,条件判断语句 WHEN ELSE通过测定表式s=0的比较结果,以确定由 哪一端口向y赋值。条件语句 WHEN ELSE的判定依据是表式s=0′输出的结果。表式 中的等号“=”没有赋值的含义,只是一种数据比较符号。其表式输出结果的数据类型是布 尔数据类型 BOOLEAN。 BOOLEAN类型的取值分别是:true(真)和 false(伪)。即当s 为高电平时,表式s=0输出“ false”当s为低电平时,表式s=0输出“true”。 在ⅦHD综合器或仿真器中分别用1·和'0表达txue和 false。布尔数据不是数值,只
74 EDA 技术与 VHDL 型,即对其传输或存储的数据的类型要作明确的界定,因此,在 VHDL 设计中,必须预先 定义好要使用的数据类型,这对于大规模电路描述的排错是十分有益的。相关的数据类型 有 INTEGER 类型、BOOLEAN 类型、STD_LOGIC 类型和 BIT 类型等。 BIT 数据类型的信号规定的取值范围是逻辑位'1'和'0'。在 VHDL 中,逻辑位 0 和 1 的 表达必须加单引号,否则 VHDL 综合器将 0 和 1 解释为整数数据类型 INTEGER。 BIT 数据类型可以参与逻辑运算或算术运算,其结果仍是位的数据类型。VHDL 综合 器用一个二进制位表示 BIT。将例 3-1 中的端口信号 a、b、s 和 y 的数据类型都定义为 BIT 表示:a、b、s 和 y 的取值范围,或者说数据范围都被限定在逻辑位'1'和'0'的二值范围内。 6. 结构体表达 结构体的一般表达如例 3-5 所示。 【例 3-5】 ARCHITECTURE arch_name OF e_name IS [说明语句] BEGIN (功能描述语句) END ARCHITECTURE arch_name ; 上式中,ARCHITECTURE、OF、IS、BEGIN 和 END ARCHITECTURE 都是描述结构 体的关键词,在描述中必须包含它们。arch_name 是结构体名,是标识符。 [说明语句]包括在结构体中,用以说明和定义数据对象、数据类型、元件调用声明等 等。[说明语句]并非是必须的,(功能描述语句)则不同,结构体中必须给出相应的电路功能 描述语句,可以是并行语句,顺序语句或它们的混合。 一般地,一个可综合的,完整的 VHDL 程序有比较固定的结构。设计实体中,一般首 先出现的是各类库及其程序包的使用声明,包括未以显式表达的工作库 WORK 库的使用声 明,然后是实体描述,最后是结构体描述,而在结构体中可以含有不同的逻辑表达语句结 构。如前所述,在此把一个完整的可综合的 VHDL 程序设计构建为设计实体(独立的电路 功能结构),而其程序代码常被称为 VHDL 的 RTL 描述。 7. 赋值符号和数据比较符号 例 3-1 中的表达式 y<= a 表示输入端口 a 的数据向输出端口 y 传输;但也可以解释为信 号 a 向信号 y 赋值。在 VHDL 仿真中赋值操作 y<= a并非立即发生的,而是要经历一个模 拟器的最小分辨时间?后,才将 a 的值赋予 y 。在此不妨将? 看成是实际电路存在的固有 延时量。VHDL 要求赋值符“<=”两边的信号的数据类型必须一致。 例 3-1 中,条件判断语句 WHEN_ELSE 通过测定表式 s='0' 的比较结果,以确定由 哪一端口向 y 赋值。条件语句 WHEN_ELSE 的判定依据是表式 s='0' 输出的结果。表式 中的等号“=”没有赋值的含义,只是一种数据比较符号。其表式输出结果的数据类型是布 尔数据类型 BOOLEAN。BOOLEAN 类型的取值分别是:true(真)和 false(伪)。即当 s 为高电平时,表式 s='0' 输出“false”;当 s 为低电平时,表式 s ='0'输出“true”。 在 VHDL 综合器或仿真器中分别用'1'和'0'表达 true 和 false。布尔数据不是数值,只
第3章VHDL入门 能用于逻辑操作或条件判断。 用于条件语句的判断表达式可以是一个值,也可以是更复杂的逻辑或运算表达式,如: IF a THEN 注意,a的数据类型必须是 boole IF (s1=0)AND(s2=1)OR(C<b+1) THEN 8.逻辑操作符 例3-2中出现的文字AND、OR和NOT是逻辑操作符号。ⅵHDL共有7种基本逻辑操 作符,它们是AND(与)、OR(或)、NAND(与非)、NOR(或非)、XOR(异或)、XNOR(同或) 和NOT(取反)。信号在这些操作符的作用下可构成组合逻辑。逻辑操作符所要求的操作数 (操作对象)的数据类型有3种,即BT、 BOOLEAN和 STD LOGIO 注意,与其他HDL用某种符号表达逻辑操作符不同,VHDL中直接用对应的英语文字 表达逻辑操作符号,这更明确显示了VHDL作为硬件行为描述语言的特征 9.条件语句 例3-3利用 IF THEN ELSE表达的vDL顺序语句的方式,同样描述了一个多路选择 器的电路行为。其结构体中的IF语句的执行顺序类似于软件语言,首先判断如果s为低电 平,则执行y<=a语句,否则(当s为高电平),则执行语句y<=b。由此可见ⅤHDL的顺序 语句同样能描述并行运行的组合电路。注意,IF语句必须以语句“ END IF:”结束。 10. WHEN ELSE条件信号赋值语句 例3-1中出现的是条件信号赋值语句,这是一种并行赋值语句,其表达方式如下: 赋值目标<=表达式WHEN赋值条件ELSE 表达式WHEN赋值条件ELSE 表达式 在结构体中的条件信号赋值语句的功能与在进程中的IF语句相同,在执行条件信号语 句时,每一“赋值条件”是按书写的先后关系逐项测定的,一旦发现(赋值条件=tnue),立 即将“表达式”的值赋给“赋值目标”信号。 注意,由于条件测试的顺序性,条件信号赋值语句中的第一子句具有最高赋值优先级, 第二句其次,如此类推。例如在以下程序中,如果当pl和p同时为时,z获得的赋值是 a而不可能是b。还应该注意,相对于在同一结构体中的其它语句,此类赋值语句作为一 个完整的语句,属于并行语句。 z <=a WHEN P1 =1EL b WHEN P2 =1 ELS 11.进程语句和顺序语句 由例3-3可见,顺序语句“ IF THEN ELSE END IF;”是放在由“ PROCESS. END PROCESS”引导的语句中的。由 PROCESS引导的语句称为进程语句。在ⅤHDL中,所有
第 3 章 VHDL 入门 75 能用于逻辑操作或条件判断。 用于条件语句的判断表达式可以是一个值,也可以是更复杂的逻辑或运算表达式,如: IF a THEN ... -- 注意,a 的数据类型必须是 boolean IF (s1='0')AND(s2='1')OR(c<b+1) THEN .. 8. 逻辑操作符 例 3-2 中出现的文字 AND、OR 和 NOT 是逻辑操作符号。VHDL 共有 7 种基本逻辑操 作符,它们是 AND(与)、OR(或)、NAND(与非)、NOR(或非)、XOR(异或)、XNOR(同或) 和 NOT(取反)。信号在这些操作符的作用下可构成组合逻辑。逻辑操作符所要求的操作数 (操作对象)的数据类型有 3 种,即 BIT、BOOLEAN 和 STD_LOGIC。 注意,与其他 HDL 用某种符号表达逻辑操作符不同,VHDL 中直接用对应的英语文字 表达逻辑操作符号,这更明确显示了 VHDL 作为硬件行为描述语言的特征。 9. 条件语句 例 3-3 利用 IF_THEN_ELSE 表达的 VHDL 顺序语句的方式,同样描述了一个多路选择 器的电路行为。其结构体中的 IF 语句的执行顺序类似于软件语言,首先判断如果 s 为低电 平,则执行 y<=a 语句,否则(当 s 为高电平),则执行语句 y<=b。由此可见 VHDL 的顺序 语句同样能描述并行运行的组合电路。注意,IF 语句必须以语句“END IF;”结束。 10. WHEN_ELSE 条件信号赋值语句 例 3-1 中出现的是条件信号赋值语句,这是一种并行赋值语句,其表达方式如下: 赋值目标 <= 表达式 WHEN 赋值条件 ELSE 表达式 WHEN 赋值条件 ELSE ... 表达式 ; 在结构体中的条件信号赋值语句的功能与在进程中的 IF 语句相同,在执行条件信号语 句时,每一“赋值条件”是按书写的先后关系逐项测定的,一旦发现(赋值条件= true),立 即将“表达式”的值赋给“赋值目标”信号。 注意,由于条件测试的顺序性,条件信号赋值语句中的第一子句具有最高赋值优先级, 第二句其次,如此类推。例如在以下程序中,如果当 p1 和 p2 同时为'1'时,z 获得的赋值是 a 而不可能是 b 。还应该注意,相对于在同一结构体中的其它语句,此类赋值语句作为一 个完整的语句,属于并行语句。 z <= a WHEN p1 = '1' ELSE b WHEN p2 = '1' ELSE c ; 11. 进程语句和顺序语句 由例 3-3 可见,顺序语句“IF_THEN_ELSE_END IF;”是放在由“PROCESS... END PROCESS”引导的语句中的。由 PROCESS 引导的语句称为进程语句。在 VHDL 中,所有
EDA技术与ⅤHDL 合法的顺序描述语句都必须放在进程语句中 PROCESS旁的(a,b,s)称为进程的敏感信号表,通常要求将进程中所有的输入信号都 放在敏感信号表中。例如,例3-3中的输入信号是a、b和s,所以将它们全部列入敏感信 号表中。由于 PROCESS语句的执行依赖于敏感信号的变化(或称发生事件),当某一敏感 信号(如a)从原来的跳变到0,或者从原来的跳变到时,就将启动此进程语句,于是 此 PROCESS至 END PROCESS引导的语句(包括其中的顺序语句)被执行一遍,然后返 回进程的起始端,进入等待状态,直到下一次敏感信号表中某一信号或某些信号发生事件 才再次进入“启动一运行”状态 在一个结构体中可以包含任意个进程语句,所有的进程语句都是并行语句,而由任一 进程 PROCESS引导的语句(包含在其中的语句)结构属于顺序语句 2.文件取名和存盘 如果用 Quartus提供的ⅤHDL文本编辑器编辑VHDL代码文件,在保存文件时,必 须赋给一个正确的文件名。一般地,文件名可以由设计者任意给定,但文件后缀扩展名必 须是“vhd”,如 adder ivd。但考虑到某些EDA软件的限制和ⅤHDL程序的特点,以及 调用的方便性,因此建议程序的文件名尽可能与该程序的实体名一致,如例3-1的文件名 应该是:mux2 l. vhd。原则上文件名不分大小写,但推荐使用小写,特别是后缀。 3.2简单时序电路的ⅥHDL描述 与其他硬件描述语言相比,在时序电路的描述上,ⅤHDL具有许多独特之处。最明显 的是VHDL主要通过对时序器件功能和逻辑行为的描述,而非结构上的描述使得计算机综 合出符合要求的时序电路,从而充分体现了ⅤHDL电路系统行为描述的强大功能。 以下将对一个典型的时序元件D触发器的HDL描述进行详细分析,从而得出时序电 路描述的一般规律和设计方法。 321D触发器 最简单、最常用,并最具代表性的时序电路是D触发器,它是现代数字系统设计中最 基本的时序单元和底层元件。D触发器的描述包含了VHDL对时序电路的最基本和典型的 表达方式,同时也包含了VHDL中许多最具特色的语言现象。例3-6是对D触发器元件图 3-4的描述。从DL的描述上看,与例3-3相比,例3-6多了4个部分 (1)由 LIBRARY引导的库的说明部分 (2)使用了另一种数据类型: STD LOGIC。 (3)定义了一个内部节点信号: SIGNAL (4)使用了一种新的条件判断表式:CLKEⅤ ENT AND CLK=l
76 EDA 技术与 VHDL 合法的顺序描述语句都必须放在进程语句中。 PROCESS 旁的(a,b,s)称为进程的敏感信号表,通常要求将进程中所有的输入信号都 放在敏感信号表中。例如,例 3-3 中的输入信号是 a、b 和 s,所以将它们全部列入敏感信 号表中。由于 PROCESS 语句的执行依赖于敏感信号的变化(或称发生事件),当某一敏感 信号(如 a)从原来的'1'跳变到'0',或者从原来的'0'跳变到'1'时,就将启动此进程语句,于是 此 PROCESS 至 END PROCESS 引导的语句(包括其中的顺序语句)被执行一遍,然后返 回进程的起始端,进入等待状态,直到下一次敏感信号表中某一信号或某些信号发生事件 才再次进入“启动-运行”状态。 在一个结构体中可以包含任意个进程语句,所有的进程语句都是并行语句,而由任一 进程 PROCESS 引导的语句(包含在其中的语句)结构属于顺序语句。 12. 文件取名和存盘 如果用 QuartusII 提供的 VHDL 文本编辑器编辑 VHDL 代码文件,在保存文件时,必 须赋给一个正确的文件名。一般地,文件名可以由设计者任意给定,但文件后缀扩展名必 须是“.vhd”,如 adder_f.vhd。但考虑到某些 EDA 软件的限制和 VHDL 程序的特点,以及 调用的方便性,因此建议程序的文件名尽可能与该程序的实体名一致,如例 3-1 的文件名 应该是:mux21a.vhd。原则上文件名不分大小写,但推荐使用小写,特别是后缀。 3.2 简单时序电路的 VHDL 描述 与其他硬件描述语言相比,在时序电路的描述上,VHDL 具有许多独特之处。最明显 的是 VHDL 主要通过对时序器件功能和逻辑行为的描述,而非结构上的描述使得计算机综 合出符合要求的时序电路,从而充分体现了 VHDL 电路系统行为描述的强大功能。 以下将对一个典型的时序元件 D 触发器的 VHDL 描述进行详细分析,从而得出时序电 路描述的一般规律和设计方法。 3.2.1 D 触发器 最简单、最常用,并最具代表性的时序电路是 D 触发器,它是现代数字系统设计中最 基本的时序单元和底层元件。D 触发器的描述包含了 VHDL 对时序电路的最基本和典型的 表达方式,同时也包含了 VHDL 中许多最具特色的语言现象。例 3-6 是对 D 触发器元件图 3-4 的描述。从 VHDL 的描述上看,与例 3-3 相比,例 3-6 多了 4 个部分: (1) 由 LIBRARY 引导的库的说明部分。 (2) 使用了另一种数据类型:STD_LOGIC。 (3) 定义了一个内部节点信号:SIGNAL。 (4) 使用了一种新的条件判断表式:CLK'EVENT AND CLK = '1
第3章VHDL入门 除此之外,虽然例3-3描述的是组合电路,而例3-6描述的是时序电路,如果不详细 分析其中的表述含义,二例在语句结构和语言应用上没有明显的差异,也不存在如其他硬 件描述语言(如ABEL、AHDL)那样包含用于表示时序或组合逻辑的特征语句,更没有与特 定的软件或硬件相关的特征属性语句。这也充分表明了ⅤHDL电路描述与设计平台和硬件 实现对象无关性的优秀特点。 【例3-6】 L工 BRARY IEEE USE IEEE STD LOGIC 1164.ALL ENTITY DEF1 IS PORT (CLK IN STD LOGIC DFF 1 D: IN STD LOGIC i 图3-4D触发器 END architecture bhy OF DEF1 IS SIGNAL Q1: STD LOGIC 类似于在芯片内部定义一个数据的暂存节点 BEGIN BEGIN IE CLK EVENT AND CLK =1 THEN Q1<= D ND IE END PROCESS 将内部的暂存数据向端口输出(双横线--是注释符号) END bhy 3.2.2D触发器VHDL描述的语言现象说明 以下对例3-6中出现的新的语句语言现象作出说明 1.标准逻辑位数据类型 STD LOGIO 从例3-6可见,D触发器的3个信号端口CLK、D和Q的数据类型都被定义为 STD LOGIC(例3-1中,端口信号的数据类型被定义为BIT)。就数字系统设计来说,类型 STD LOGIC比BT包含的内容丰富和完整得多,当然也包含了BIT类型。试比较以下 STD LOGIC和BT两种数据类型的程序包定义表式(其中TYPE是数据类型定义语句)。 IT数据类型定义: TYPE BIT IS(0,1 只有两种取值 STD LOGIO数据类型定义 TYPE STD LOGIC Is (U,x,0,1,'Z,'W,'L,'H,-) STD LOGIC所定义的9种数据的含义是:U表示未初始化的:X表示强未知的;"O 表示强逻辑0:"1表示强逻辑1:Z表示高阻态;W表示弱未知的:"L表示弱逻辑0;"H 表示弱逻辑1;"-表示忽略
第 3 章 VHDL 入门 77 除此之外,虽然例 3-3 描述的是组合电路,而例 3-6 描述的是时序电路,如果不详细 分析其中的表述含义,二例在语句结构和语言应用上没有明显的差异,也不存在如其他硬 件描述语言(如 ABEL、AHDL)那样包含用于表示时序或组合逻辑的特征语句,更没有与特 定的软件或硬件相关的特征属性语句。这也充分表明了 VHDL 电路描述与设计平台和硬件 实现对象无关性的优秀特点。 【例 3-6】 LIBRARY IEEE ; USE IEEE.STD_LOGIC_1164.ALL ; ENTITY DFF1 IS PORT (CLK : IN STD_LOGIC ; D : IN STD_LOGIC ; Q : OUT STD_LOGIC ); END ; ARCHITECTURE bhv OF DFF1 IS SIGNAL Q1 : STD_LOGIC ; --类似于在芯片内部定义一个数据的暂存节点 BEGIN PROCESS (CLK,Q1) BEGIN IF CLK'EVENT AND CLK = '1' THEN Q1 <= D ; END IF; END PROCESS ; Q <= Q1 ; --将内部的暂存数据向端口输出(双横线--是注释符号) END bhv; 3.2.2 D 触发器 VHDL 描述的语言现象说明 以下对例 3-6 中出现的新的语句语言现象作出说明。 1. 标准逻辑位数据类型 STD_LOGIC 从例 3-6 可见,D 触发器的 3 个信号端口 CLK、D 和 Q 的数据类型都被定义为 STD_LOGIC(例 3-1 中,端口信号的数据类型被定义为 BIT)。就数字系统设计来说,类型 STD_LOGIC 比 BIT 包含的内容丰富和完整得多,当然也包含了 BIT 类型。试比较以下 STD_LOGIC 和 BIT 两种数据类型的程序包定义表式(其中 TYPE 是数据类型定义语句)。 BIT 数据类型定义: TYPE BIT IS('0','1'); --只有两种取值 STD_LOGIC 数据类型定义: TYPE STD_LOGIC IS ('U','X','0','1','Z','W','L','H','-'); STD_LOGIC 所定义的 9 种数据的含义是:'U'表示未初始化的;'X'表示强未知的;'0' 表示强逻辑 0;'1'表示强逻辑 1;'Z'表示高阻态;'W' 表示弱未知的;'L'表示弱逻辑 0;'H' 表示弱逻辑 1;'-'表示忽略。 图 3-4 D 触发器
EDA技术与ⅤHDL 它们完整地概括了数字系统中所有可能的数据表现形式,所以例3-6中的CLK、D和 Q比例3-1中的a、b、s具有更宽的取值范围,因而其描述和实际电路有更好的适应性 在仿真和综合中,将信号或其他数据对象定义为 STD LOGIC数据类型是非常重要的, 它可以使设计者精确地模拟一些未知的和具有高阻态的线路情况。对于综合器,高阻态Z 和-忽略态(有的综合器用X")可用于三态的描述。 STD LOGIO型数据在数字器件中实现的 只有其中的4到5种值,即X(或/和-)、0、"1和Z,其他类型通常不可综合 注意,此例中给出的 STD LOGIC数据类型的定义主要是借以学习一种新的语法现象, 而非D触发器等时序电路必须使用此类数据类型。 2.设计库和标准程序包 有许多数据类型的说明,及类似的函数是预先仿在ⅤHDL综合器附带的设计库和程序 包中的。如BIT数据类型的定义是包含在VHDL标准程序包 STANDARD中的,而程序包 STANDARD包含于ⅤHDL标准库STD中。一般,为了使用BIT数据类型,应该在例3-1 的程序上面增加如下3句说明语句: LIBRARY WORK LIBRARY STD i USE STD STANDARD. ALL 第2句中的 LIBRARY是关键词, LIBRARY STD表示打开STD库:第3句的USE和 ALL是关键词,全句表示允许使用sTD库中 STANDARD程序包中的所有内容(.ALL),如 类型定义、函数、过程、常量等。 此外,由于要求VHDL设计文件保存在某一文件夹,如d:\ myfile中,并指定为工 程 PROJECT的文件所在的目录,VHDL工具就将此路径指定的文件夹默认工作库(WORK 工工 BRARY),于是在VHDL程序前面还应该增加“ LIBRARY WORK:”语句,VHDL工具才 能调用此路径中相关的元件和程序包 但是,由于ⅤHDL标准中规定标准库STD和工作库WORK都是默认打开的,因此就 可以像例3-1那样,不必将上述库和程序包的使用语句以显式表达在VDL程序中。除非 如例3-6那样,需要使用一些特殊的程序包 使用库和程序包的一般定义表式是: LIBRARY.ALL STD LOGIC数据类型定义在被称为 STD LOGIC1164的程序包中,此包由IEEE定 义,而且此程序包所在的程序库的库名被取名为IEEE。由于IEE库不属于ⅤHDL标准库 所以在使用其库中内容前,必须事先给予声明。即如例3-6最上的两句语句 LIBRARY IEEE USE IEEE STD LOGIC 1164.ALL 正是出于需要定义端口信号的数据类型为 STD LOGIC的目的,当然也可以定义为BIT 类型或其他数据类型,但一般应用中推荐定义 STD LOGIO类型
78 EDA 技术与 VHDL 它们完整地概括了数字系统中所有可能的数据表现形式,所以例 3-6 中的 CLK、D 和 Q 比例 3-1 中的 a、b、s 具有更宽的取值范围,因而其描述和实际电路有更好的适应性。 在仿真和综合中,将信号或其他数据对象定义为 STD_LOGIC 数据类型是非常重要的, 它可以使设计者精确地模拟一些未知的和具有高阻态的线路情况。对于综合器,高阻态'Z' 和'-'忽略态(有的综合器用'X')可用于三态的描述。STD_LOGIC 型数据在数字器件中实现的 只有其中的 4 到 5 种值,即'X' (或/和'-')、'0'、'1'和'Z',其他类型通常不可综合。 注意,此例中给出的 STD_LOGIC 数据类型的定义主要是借以学习一种新的语法现象, 而非 D 触发器等时序电路必须使用此类数据类型。 2. 设计库和标准程序包 有许多数据类型的说明,及类似的函数是预先仿在 VHDL 综合器附带的设计库和程序 包中的。如 BIT 数据类型的定义是包含在 VHDL 标准程序包 STANDARD 中的,而程序包 STANDARD 包含于 VHDL 标准库 STD 中。一般,为了使用 BIT 数据类型,应该在例 3-1 的程序上面增加如下 3 句说明语句: LIBRARY WORK ; LIBRARY STD ; USE STD.STANDARD.ALL ; 第 2 句中的 LIBRARY 是关键词,LIBRARY STD 表示打开 STD 库;第 3 句的 USE 和 ALL 是关键词,全句表示允许使用 STD 库中 STANDARD 程序包中的所有内容(.ALL),如 类型定义、函数、过程、常量等。 此外,由于要求 VHDL 设计文件保存在某一文件夹,如 d:\myfile 中,并指定为工 程 PROJECT 的文件所在的目录,VHDL 工具就将此路径指定的文件夹默认工作库(WORK LIBRARY),于是在 VHDL 程序前面还应该增加“LIBRARY WORK;”语句,VHDL 工具才 能调用此路径中相关的元件和程序包。 但是,由于 VHDL 标准中规定标准库 STD 和工作库 WORK 都是默认打开的,因此就 可以像例 3-1 那样,不必将上述库和程序包的使用语句以显式表达在 VHDL 程序中。除非 如例 3-6 那样,需要使用一些特殊的程序包。 使用库和程序包的一般定义表式是: LIBRARY ; USE ..ALL ; STD_LOGIC 数据类型定义在被称为 STD_LOGIC_1164 的程序包中,此包由 IEEE 定 义,而且此程序包所在的程序库的库名被取名为 IEEE。由于 IEEE 库不属于 VHDL 标准库, 所以在使用其库中内容前,必须事先给予声明。即如例 3-6 最上的两句语句: LIBRARY IEEE ; USE IEEE.STD_LOGIC_1164.ALL ; 正是出于需要定义端口信号的数据类型为 STD_LOGIC的目的,当然也可以定义为 BIT 类型或其他数据类型,但一般应用中推荐定义 STD_LOGIC 类型
第3章VHDL入门 3.信号定义和数据对象 例3-6中的语句“ SIGNAL Q1: STD LOGIC:”表示在描述的器件DFF1内部定义标 识符Q1的数据对象为信号 SIGNAL,其数据类型为 STD LOGIC。由于Q1被定义为器件 的内部节点信号,数据的进出不像端口信号那样受限制,所以不必定义其端口模式(如IN、 OUT等)。定义Q1的目的是为了在设计更大的电路时使用由此引入的时序电路的信号,这 是一种常用的时序电路设计的方式。事实上,如果在例3-6中不作Q1的定义,其结构体如 将其中的赋值语句Ql" EVENT 短语“ clockEVENT”就是对 clock标识符的信号在当前的一个极小的时间段?内发 生事件的情况进行检测。所谓发生事件,就是 clock在其数据类型的取值范围内发生变化, 从一种取值转变到另一种取值(或电平方式)。如果 clock的数据类型定义为 STD LOGIC, 则在?时间段内, clock从其数据类型允许的9种值中的任何一个值向另一值跳变,如由Oy 变成'1、由1变成0或由Z变成0,都认为发生了事件,于是此表式将输出一个布尔值true, 否则为 false. 如果将以上短语c1ck' EVENT改成语句:c1ock' EVENT AND clock=11,则表 示一旦“c1ock' EVENT”在?时间内测得c1ock有一个跳变,而此小时间段?之后又测 得c1ock为高电平·1’,即满足此语句右侧的c1ock=1·的条件,于是两者相与(AND) 后返回值为true,由此便可以从当前的c1ock='1推断在此前的?时间段内,c1ock 必为'0’(设c1ock的数据类型是B工T)。因此,以上的表达式就可以用来对信号c1ock
第 3 章 VHDL 入门 79 3. 信号定义和数据对象 例 3-6 中的语句“SIGNAL Q1:STD_LOGIC;”表示在描述的器件 DFF1 内部定义标 识符 Q1 的数据对象为信号 SIGNAL,其数据类型为 STD_LOGIC。由于 Q1 被定义为器件 的内部节点信号,数据的进出不像端口信号那样受限制,所以不必定义其端口模式(如 IN、 OUT 等)。定义 Q1 的目的是为了在设计更大的电路时使用由此引入的时序电路的信号,这 是一种常用的时序电路设计的方式。事实上,如果在例 3-6 中不作 Q1 的定义,其结构体(如 将其中的赋值语句 Q1 'EVENT 短语“clock'EVENT”就是对 clock 标识符的信号在当前的一个极小的时间段 ? 内发 生事件的情况进行检测。所谓发生事件,就是 clock 在其数据类型的取值范围内发生变化, 从一种取值转变到另一种取值(或电平方式)。如果 clock 的数据类型定义为 STD_LOGIC, 则在? 时间段内,clock 从其数据类型允许的 9 种值中的任何一个值向另一值跳变,如由'0' 变成'1'、由'1'变成'0'或由'Z'变成'0',都认为发生了事件,于是此表式将输出一个布尔值 true, 否则为 false。 如果将以上短语 clock'EVENT 改成语句:clock'EVENT AND clock='1',则表 示一旦“clock'EVENT”在? 时间内测得 clock 有一个跳变,而此小时间段 ? 之后又测 得 clock 为高电平'1',即满足此语句右侧的 clock ='1'的条件,于是两者相与(AND) 后返回值为 true,由此便可以从当前的 clock ='1'推断在此前的? 时间段内,clock 必为'0' (设 clock 的数据类型是 BIT)。因此,以上的表达式就可以用来对信号 clock