第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<设计库名 UsE<设计库名>.<程序包名>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<=D改为Q<D)同样能综合出相同的结果,但不推荐这种设计方式。 语句“ SIGNAL Q1: STD LOGIC:”中的 SIGNAL是定义某标识符为信号的关键词。 在VHDL中,数据对象( Data objects)类似于一种容器,它接受不同数据类型的赋 值。数据对象有3类,即信号( SIGNAL)、变量( VARIABLE)和常量( CONSTANT)。在VHDL 中,被定义的标识符必须确定为某类数据对象,同时还必须被定义为某种数据类型。如例 3-6中的Q1,对它规定的数据对象是信号,而数据类型是 STD LOGIC,前者规定了Q1的 行为方式和功能特点,后者限定了Q1的取值范围。VHDL规定,Q1作为信号,它可以如 同一根连线那样在整个结构体中传递信息,也可以根据程序的功能描述构成一个时序元件 但Q1传递或存储的数据的类型只能包含在 STD LOGIO的定义中 需要注意的是,语句“ SIGNAL QI: STD LOGIC:”仅规定了Ql的属性特征,而其功能 定位需要由结枃体中的语句描述具体确定。如果将Q1比喻为一瓶葡萄酒,则其特定形状 的酒瓶就是其数据对象,瓶中的葡萄酒(而非其他酒)就是其数据类型,而这瓶酒的用处(功 能)只能由拥有这酒的人来确定,即结构体中的具体描述。 4.上升沿检测表式和信号属性函数 EVENT 例3-6中的条件语句的判断表式“CLK' EVENT AND CLK=·1”是用于检测时钟信号 CLK的上升沿的,即如果检测到CLK的上升沿,此表达式将输出“true” 关键词 EVENT是信号属性函数,用来获得信号行为信息的函数称为信号属性函数 VHDL通过以下表式来测定某信号的跳变情况: 信号名>" 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 <= D 改为 Q <= D)同样能综合出相同的结果,但不推荐这种设计方式。 语句“SIGNAL Q1:STD_LOGIC;”中的 SIGNAL 是定义某标识符为信号的关键词。 在 VHDL 中,数据对象(Data Objects)类似于一种容器,它接受不同数据类型的赋 值。数据对象有 3 类,即信号(SIGNAL)、变量(VARIABLE)和常量(CONSTANT)。在 VHDL 中,被定义的标识符必须确定为某类数据对象,同时还必须被定义为某种数据类型。如例 3-6 中的 Q1,对它规定的数据对象是信号,而数据类型是 STD_LOGIC,前者规定了 Q1 的 行为方式和功能特点,后者限定了 Q1 的取值范围。VHDL 规定,Q1 作为信号,它可以如 同一根连线那样在整个结构体中传递信息,也可以根据程序的功能描述构成一个时序元件; 但 Q1 传递或存储的数据的类型只能包含在 STD_LOGIC 的定义中。 需要注意的是,语句“SIGNAL Q1:STD_LOGIC;”仅规定了 Q1 的属性特征,而其功能 定位需要由结构体中的语句描述具体确定。如果将 Q1 比喻为一瓶葡萄酒,则其特定形状 的酒瓶就是其数据对象,瓶中的葡萄酒(而非其他酒)就是其数据类型,而这瓶酒的用处(功 能)只能由拥有这酒的人来确定,即结构体中的具体描述。 4. 上升沿检测表式和信号属性函数 EVENT 例 3-6 中的条件语句的判断表式“CLK'EVENT AND CLK='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'EVENT AND clock='1',则表 示一旦“clock'EVENT”在? 时间内测得 clock 有一个跳变,而此小时间段 ? 之后又测 得 clock 为高电平'1',即满足此语句右侧的 clock ='1'的条件,于是两者相与(AND) 后返回值为 true,由此便可以从当前的 clock ='1'推断在此前的? 时间段内,clock 必为'0' (设 clock 的数据类型是 BIT)。因此,以上的表达式就可以用来对信号 clock