硬件描述语言VHDL.ppt_第1页
硬件描述语言VHDL.ppt_第2页
硬件描述语言VHDL.ppt_第3页
硬件描述语言VHDL.ppt_第4页
硬件描述语言VHDL.ppt_第5页
已阅读5页,还剩148页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第九章 VHDL程序基础,9.1 VHDL程序结构 9.2 VHDL的语言元素 9.3 VHDL的基本描述语句 9.4 VHDL结构体的三种描述方法 9.5 有限状态机的设计,硬件描述语言VHDL,硬件描述语言VHDL的特点,1、支持自顶向下的设计方法,2、系统硬件描述能力强 行为描述、数据流描述、结构描述。,3、系统仿真能力强,4、工艺无关性,初学者如何学好VHDL,1、掌握时钟的概念。,2、注意VHDL编程与软件编程的差别。,3、语法学习贵精不贵多,靠练不靠背。,4、注意VHDL语句的可综合性。,9.1.1 VHDL程序基本结构,库(Library),包(Package),实体 Entity,结构体 Architecture,配置 Configuration,存放已编译的实体、结构体、包集合和配置,存放各设计模块能共享的数据类型、常数、 子程序等。,定义电路的输入/输出接口,描述电路内部的功能。,决定哪一个结构体被使用。,VHDL程序基本结构,VHDL中常用的资源库为IEEE库。,IEEE库: 常用的资源库。 IEEE库中的三个重要的包集合: STD_LOGIC_1164 STD_LOGIC_ARITH(算术运算库)、STD_LOGIC_UNSIGNED等,库(LIBRARY),库说明语句的语法形式为: LIBRARY 库名; -说明使用什么库 USE 库名.程序包名.项目名;-说明使用库中哪个程序包及 包集合中的项目;,库和程序包的用法,LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;,WORK库:WORK库是现行作业库。设计者所描述的VHDL语句不需要任何说明,将都存放在WORK库中。WORK库对所有设计都是隐含可见的,因此在使用该库时无需进行任何说明。,一点注意:,要求:设计文件不能直接存放在根目录下,必须建立一个英文文件夹,系统自动将其视为work库。,实体的一般格式为: ENTITY 实体名 IS 端口说明; END;,实体名必须与文件名相同。 ENTITY、IS、END是VHDL的关键字(保留字)。 实体名、端口名等均应为符合VHDL命名规则的标识符。 端口:指实体中的每一个I/O信号,其功能对应于电路 图符号的一个引脚。端口说明则是对一个实体的一组端口的定义,即对基本设计实体与外部接口的描述。端口是设计实体和外部环境动态通信的通道。,实体(ENTITY),ENTITY and2 IS END and2;,端口说明的一般格式为: PORT(端口名,端口名:端口模式 数据类型; 端口名,端口名:端口模式 数据类型);,端口模式用来说明数据传输通过该端口的方向。端口模式有以下几类: IN(输入):仅允许数据流进入端口。主要用于时钟输入、控制输入、单向数据输入。 OUT(输出):仅允许数据流由实体内部流出端口。该模式通常用于终端计数一类的输出,不能用于反馈。 BUFFER(缓冲):该模式允许数据流出该实体和作为内部反馈时用,但不允许作为双向端口使用。 INOUT(双向):可以允许数据流入或流出该实体。该模式也允许用于内部反馈。 如果端口模式没有指定,则该端口处于缺省模式为:IN 。 数据类型原则上可以是任何标准的数据类型和用户自定义类型。,补充说明:,在端口说明时,可将几个同样方向、同样数据类型的端口放在同一说明语句里。 最后一条端口说明语句后不加分号;,PORT (a,b : IN STD_LOGIC; y : OUT STD_LOGIC);,ENTITY add4 IS PORT(a, b: IN STD_LOGIC_VECTOR(3 downto 0); Ci: IN STD_LOGIC; Sum: OUT STD_LOGIC_VECTOR(3 downto 0); Co: OUT STD_LOGIC); END add4;,例3: 四位加法器实体说明程序,结构体的一般格式如下: ARCHITECTURE 结构体名 OF 实体名 IS 结构体说明部分; BEGIN 并发处理语句; END 结构体名;,实体名必须与实体声明部分所取的名字相同; 而结构体名可由设计者自由选择;,ARCHITECTURE and2x OF and2 IS BEGIN y=a AND b; END and2x;,结构体(ARCHITECTURE ),结构体的一般格式如下: ARCHITECTURE 结构体名 OF 实体名 IS 结构体说明部分; BEGIN 并发处理语句; END 结构体名;,2) 结构体说明是指对结构体需要使用的信号、常数、数据类 型和函数进行定义和说明。声明语句所声明的内容只能用于该结构体中,若希望在其他的实体或结构体中引用这些定义,则须用包声明(PACKAGE). 3) 并发处理语句位于BEGIN和END之间,这些语句具体地描述了构造体的行为。并发处理语句是功能描述的核心部分,也是变化最丰富的部分。,并发处理语句,块语句(BLOCK),进程语句(PROCESS),信号赋值语句,子程序调用:调用过程(PROCEDURE)和函数(FUNCTION),元件例化语句(COMPONENT),配置的基本格式为: CONFIGURATION 配置名 OF 实体名 IS 配置说明; END 配置名;,配置语句描述了层与层之间的连接关系,以及实体与构造体之间的连接关系。设计者可以利用配置语句选择不同的构造体,使其与要设计的实体相对应;在仿真某一个实体时,可以利用配置选择不同的构造体进行性能对比实验,以得到性能最佳的构造体。,配置(CONFIGURATION),配置语句根据不同情况,其说明语句有简有繁。最简单的缺省配置格式为:,CONFIGURATION 配置名 OF 实体名 IS FOR 选配结构体名 END FOR; END 配置名;,例4:加入了配置的4位等值比较器设计文件 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY comp4 IS PORT(a, b: IN STD_LOGIC_VECTOR(3 downto 0); y: OUT STD_LOGIC); END comp4;,-结构体 1: ARCHITECTURE behavior OF comp4 IS BEGIN Comp: PROCESS(a, b) BEGIN IF a=b THEN y=1; ELSE y=0; END IF; END PROCESS comp; END behavior;,-结构体 2: ARCHITECTURE dataflow OF comp4 IS BEGIN y=1 WHEN(a=b) ELSE 0; END dataflow;,-结构体 3: ARCHITECTURE structural OF comp4 IS COMPONENT xnor2 PORT(in1, in2: IN STD_LOGIC; Out: OUT STD_LOGIC); END COMPONENT; COMPONENT and4 PORT(in1, in2, in3, in4: IN STD_LOGIC; Out: OUT STD-LOGIC); END COMPONENT; SIGNAL s: STD_LOGIC_VECTOR(0 to 3); BEGIN u0: xnor2 PORT MAP(a(0),b(0),s(0); u1: xnor2 PORT MAP(a(1),b(1),s(1); u2: xnor2 PORT MAP(a(2),b(2),s(2); u3: xnor2 PORT MAP(a(3),b(3),s(3); u4: and4 PORT MAP(s(0),s(1),s(2),s(3),y); END structural;,-配置 : CONFIGURATION comp4_con OF comp4 IS FOR behavior END FOR; END comp4_con;,9.2 VHDL的语言元素,9.2.1 标识符,标识符 由英文字母、数字以及下划线字符组成,且: 第一个字符必须是英文字母; 最后一个字符不能是下划线; 不允许连续两个下划线; 在标识符中大、小写字母是等效的。 VHDL中的注释文字一律为2个连续的连接线“-”,可以出现在任一语句后面,也可以出现在独立行; VHDL的保留字(关键字)不能用于标识符;,例如:如下标识符是合法的: tx_clk Three_state_Enable sel7D HIT_1124,如下标识符是非法的: _ tx_clk -标识符必须起始于英文字母 8B10B -标识符必须起始于英文字母 large#number -只能是英文字母、数字、下划线 link_ _bar -不能有连续两个下划线 select -关键字(保留字)不能用于标识符 rx_clk_ -最后字符不能是下划线,9.2.2 数据对象,在VHDL中,数据对象是可以赋予一个值的客体。常用的数据对象为常量、变量和信号,在使用前必须给予定义。, 常量(CONSTANT) 常量是指那些在设计描述中不会变化的值。,常量说明的一般格式如下: CONSTANT 常量名,常量名:数据类型 := 取值;,例如: CONSTANT width: integer : = 8, 变量(VARIABLE) 变量是暂存数据的量。,变量说明的语法格式是: VARIABLE 变量名,变量名:数据类型 :=初始值;,例如:VARIABLE count: INTEGER RANGE 0 TO 99 : =0 变量只用于进程和子程序,它是一个局部量。变量必须在进程或子程序的说明性区域加以说明。 变量的初始值赋值只在仿真时有用,而在综合时无用;,变量赋值语句格式为: 目标变量名 := 表达式;,赋值语句中的表达式必须与目标变量具有相同的数据类型。 变量赋值是立即生效,不存在延时行为。变量常用在实现某种运算的赋值语句中。, 信号(SIGNAL) 信号是电子电路内部硬件实体相互连接的抽象表示。信号能够代表连线,也可内连元件,端口也是信号。,信号说明的语法格式为: SIGNAL 信号名,信号名 :数据类型 :=初始值;,例如: SIGNAL count: BIT_VECTOR(3 downto 0); 信号包括I/O引脚信号以及IC内部缓冲信号,有硬件电路与 之对应,故信号之间的传递有实际的附加延时。 信号通常在构造体、包集合和实体中说明;信号不能在 进程中说明(但可以在进程中使用)。,信号赋值语句格式为: 目标信号名 = 表达式;,赋值语句中的表达式必须与目标信号具有相同的数据类型。,信号和变量的主要区别:,声明形式与赋值符号不同; 有效域不同。信号可在结构体、进程外定义;而变量在进程内定义。即:变量是一个局部量,只能用于进程或子程序中;信号是一个全局量,它可以用来进行进程之间的通信。 信号赋值可以出现在进程中,也可以直接出现在结构体中,但它们的运行含义不同:前者属顺序信号赋值,此时的赋值操作要视进程是否已被启动;后者属并行信号赋值,其赋值操作是各自独立并行发生的。,4. 在进程中变量和信号的赋值形式与操作过程不同: 在变量的赋值语句中,该语句一旦被执行,其值立即被赋予变量。在执行下一条语句时,该变量的值即为上一句新赋的值。 在信号的赋值语句中,该语句即使被执行,其值不会使信号立即发生代入,在下一条语句执行时,仍使用原来的信号值。直到进程结束之后,所有信号赋值的实际代入才顺序进行处理。因此,实际代入过程和赋值语句的执行是分开进行的。如例12所示。,5、可在不同的进程中读取一个信号,但不能在不同的进程中对同一个信号进行赋值。 6、在同一进程中对同一信号进行多次赋值操作时,只有最后一次会生效。,当进程运行时,信号赋值将自上而下顺序执行,但第一项赋值操作并不会发生,这是因为信号赋值是在进程结束时才起作用。因为在进程结束更新时,d的最后一个赋值为c ,因此执行结果为该式。,9.2.3 数据类型,VHDL是一种类型型很强的语言。 VHDL中只有相同数据类型的量, 才能相互之间发生作用。,VHDL预定义数据类型,整数(INTEGER):取值范围为 (2311)(2311)。,variable a: integer range 255 to 255;,布尔量( Boolean ):取值为TURE 、FALSE; 用于逻辑(关系)运算。,位(BIT):只有两种取值,即0和1,可用于描述信号的取值.,位矢量(BIT_VECTOR):是用双引号括起来的一组数据,每位只有两种取值:0 和 1。在其前面可加以数制标记,如X(16进制)、B(2进制、默认)、O(8进制)等。位矢量常用于表示总线的状态。,Data=O“15” Data=B“1101”,SIGNAL a: BIT_VECTOR(0 TO 3); SIGNAL a: BIT_VECTOR(3 DOWNTO 0);,Real(实数)。取值范围为 1.0E+38 +1.0E+38。由于实数运算需要大量的资源,因此综合工具常常并不支持实数类型。,Time(时间)。时间的取值范围从 (2311)到(2311)。时间由整数值、一个以上空格以及时间单位组成。常用的时间单位有:fs、ns、s、ms、s、min、hr等。时间是一个具有量纲的数据,故只能用于指定时间延时和仿真过程,而综合器并不支持。,Natural(自然数)和Positive(正整数)。是整数类型的子类型。自然数取值范围为0 (2311);正整数是大于0的整数。,Severity Level(错误等级)。错误等级分为:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)四级,用于提示系统的错误等级。 只用于仿真。,Character(字符)。是用单引号括起来的一个字母、数字、空格或一些特殊字符(如$、%等)。字符区分大、小写字母。,String(字符串)。是用双引号括起来的一个字符序列。字符串区分大、小写字母。常用于程序的提示和结果说明等。,IEEE预定义标准逻辑位(STD_LOGIC)和矢量(STD_LOGIC_VECTOR),TYPE STD_LOGIC IS U, -未初始化的 X , -不定态 0 , -0 1 , -1 Z , -高阻态 W , -弱信号不定态 L , -弱信号0 H , -弱信号1 _ , -不可能情况(可忽略值),LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL;,2. 用户自定义数据类型 VHDL允许用户自己定义数据类型。,自定义数据类型说明语句的一般格式是: TYPE 数据类型名 ,数据类型名 IS 数据类型定义 of 基本数据类型;,常用的用户自定义数据类型主要有: (1)枚举(Enumerated)类型。 通过列举某类变量所有可能的取值来加以定义。对这些取值,一般使用自然语言中有相应含义的单词或字符序列来代表,以便于阅读和理解。,枚举类型定义的格式为: TYPE 数据类型名 IS (元素1,元素2,);,TYPE m_state IS (s1,s2,s3,s4,s5); SIGNAL present_state, next_state: m_state;,在程序包STD_LOGIC_1164中对STD_LOGIC的定义为 TYPE STD_LOGIC IS ( U ,X ,0 ,1 ,Z ,W ,L ,H ,_ );,(2) 数组(ARRAY)类型。 又称为向量,是多个相同类型的数据集合。它可以是二维的和多维的。,数组类型定义的格式为: TYPE 数组名 IS ARRAY (范围) OF 元素数据类型名;,TYPE m IS ARRAY (7 downto 0) OF STD_LOGIC;,TYPE count1 IS ARRAY ( STD_LOGIC _ DOWNTO U ) OF INTEGER;,(3) 纪录(RECORD)类型: 是多个不同类型的数据集合。,纪录类型定义的格式为: TYPE 数据类型名 IS RECORD 元素名: 数据类型名; 元素名: 数据类型名; END RECORD;,(4)时间(TIME)类型(物理类型)。表示时间的数据类型, 在仿真时是必不可少的。,时间类型定义的一般格式为: TYPE 数据类型名 IS 范围; UNITS 基本单位; 单位; END UNITS;,例如:在STANDARD程序包中定义的时间,如下: TYPE time IS range 1e18 TO 1e18; UNITS fs; ps=1000fs; ns=1000ps; s=1000ns; ms=1000s; set=1000ms; min=60set; hr=60min; END UNITS; 这里的基本单位是“fs”。时间是物理类型的数据,当然对容量、阻抗值也可以做定义。,(5) 子类型(SUBTYPE)。是由type所定义的原数据类型的一个子集。它只是在基本数据类型的基础上作了些约束,但是没有定义新的数据类型。,子类型定义的一般格式为: SUBTYPE 子类型名 IS 基本数据类型名 约束范围;,SUBTYPE digit IS INTEGER range 0 to 9;,SUBTYPE digit2 IS std_logic_vector(0 to 9);,Subtype digit3 is array (0 to 9) of integer;,3. 数据类型的转换 在VHDL程序中,不同类型的对象不能代入,因此要进行类型转换。类型转换的方法有:,(1)类型标记法。用类型名称来实现关系密切的标量类型之间的转换。 例如: VARIABLE x:INTEGER; VARIABLE y:REAL; 使用类型标记(即类型名)实现类型转换时,可采用赋值语句: x :=INTEGER(y); y :=REAL(x)。,(2)类型函数法。,CONV_INTEGER ( ):将STD_LOGIC_VECTOR类型转换成INTEGER类型。 CONV_STD_LOGIC_VECTOR( ):将INTEGER类型、UNSIGNED类型或 SIGNED类型转换成STD_LOGIC_VECTOR类型。 TO_BIT ( ):将STD_LOGIC类型转换成BIT类型。 TO_BIT_VECTOR( ):将STD_LOGIC_VECTOR类型转换BIT_VECTOR 类型。 TO_STD_LOGIC( ):将BIT类型转换成STD_LOGIC类型。 TO_STD_LOGIC_VECTOR( ): 将BIT_VECTOR类型转换成 STD_LOGIC_VECTOR类型。,其中,第1个函数由STD_LOGIC_UNSIGNED程序包定义,第2个函数由 STD_LOGIC_ARITH定义,其余均由STD_LOGIC_1164定义。引用前必须先 打开库和相应的程序包。,例题:用转换函数语句设计一个译码电路。,Entity decoder1 is port( input: in std_logic_vector(0 to 2); output: out std_logic_vector(7 downto 0); End decoder1;,Architecture behave of decoder1 is begin process(input) begin output(conv_integer(input)=1; end process; End behave;,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all;,9.2.4 运算符与操作符,关于括号:表达式中如果一串运算中的算符相同,且是AND,OR,XOR中的一种,则不需使用括号;如果一串运算中的算符不同或有这三种算符之外的算符,则必须使用括号。 操作数的数据类型必须是操作符所规定的数据类型。 严格遵循在基本操作符间操作数是同数据类型的规则。 注意运算符的优先级别;见讲义。,(1)算术运算符,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all;,(2)关系运算符:它包括:= 、/= 、= 、= 。 其作用是将相同数据类型的数据对象进行数值比较或关系排序判断,并将结果以boolean类型表示。 和/=的操作对象可以是任意数据类型;但其余运算符的操作对象则仅限于整数或一维数组。 注意小于等于和赋值符号的区分。 (3)逻辑运算符:包括一元逻辑运算符和二元逻辑运算符。 一元逻辑运算符包括:NOT 。 二元逻辑运算符包括:AND、OR、NAND、NOR、XOR、XNOR。 逻辑运算符的操作对象为boolean,bit,std_logic; 也可以是bit_vector,std_logic_vector,但必须位宽要相同;且数组间的运算必须按位进行; Not的优先级别最高,但其它逻辑运算符的优先级别最低;建议使用括号。,Signal a,b,c: std_logic_vector(3 downto 0); Signal d,e,f,g:std_logic_vector(1 downto 0); Signal h, I,j,k:std_logic; Signal L,m,n,o,p:boolean; a=b and c; d=e or f or g; h=(I nand j) nand k; L=(m xor n) and (o xor p); h=I and j or k; a=b and e; h=I or L;,(4)并置运算符:&(连接),用于将多个位或数组连接成为新的位矢量。 例如:DBUS=D0&D1&D2&D3;即DBUS=(D0,D1,D2,D3)。,例:设计一个4位全加器。ADDER4.VHD,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all;,Entity adder4 is port( cin: in std_logic; a: in std_logic_vector(3 downto 0); b: in std_logic_vector(3 downto 0); s: out std_logic_vector(3 downto 0); co: out std_logic); End adder4;,Architecture behav of adder4 is Signal so: std_logic_vector(4 downto 0); Signal aa,bb: std_logic_vector(4 downto 0); Begin Aa=0 ,VHDL中的操作符主要有以下几种: “=” 赋值符:用于将数据传给信号。 “:=”赋值符:用于将数据传给变量。该赋值符也用于为信号、变量、常量等指定初值。 “=” 符号: 在WHEN语句中出现,其含义是“THEN(则)”。,省略赋值操作符:(others=x),它可以在较多的位赋值中作省略化的赋值。如 Signal d,e : std_logic_vector(7 downto 0); d0); e1,4=1,others=0);,2.2.5 属性(Attributes),属性是指语言中某个项目的特性。预定义属性描述语句是一个预定义函数,其格式为:,属性测试项目名属性标示符,综合器支持的属性有:left, right, high, low, range, reverse_range, length, event, stable.,1、EVENT 例如:CLKEVENT AND CLK=1,2、LEFT, RIGHT, HIGH, LOW 例如:TYPE num IS ARRAY RANGE 7 DOWNTO 0; VARIABLE i1,i2,i3,i4: INTEGER; BEGIN i1:=num LEFT; -i1取得num的左边界值 7 i2:=num RIGHT; -i2取得num的右边界值 0 i3:=num HIGH; -i3取得num的上限值 7 i4:=num LOW; -i4取得num的下限值 0,3、LENGTH 例如:TYPE num IS ARRAY RANGE 7 DOWNTO 0; VARIABLE M: INTEGER; BEGIN M:= num LENGTH;,4、RANGE 和REVERSE_RANGE 例如:SIGNAL S: STD_LOGIC_VECTOR(0 TO 7) FOR I in srange loop 或 FOR I in sreverse_range loop,For I in 0 to 7 loop,For I in 7 downto 0 loop,9.3.2 VHDL结构体的基本子结构,在规模较大的电路设计中,整个电路将被分成若干个相对独立的模块来描述。这样,一个结构体可以用几个子结构,即相对独立的几个模块来构成。VHDL语言有以下3种形式的子结构描述语句:,BLOCK 语句结构 PROCESS 语句结构 SUBPROGRAMS 结构,2.1.2.2 进程( PROCESS ),PROCESS语句是VHDL语言中最重要的语句之一,特点如下: 进程本身是一种并发处理语句,在一个构造体中多个 PROCESS语句可以同时并发运行,但其内部则为顺序语句; 进程只有在特定的时刻才会被激活执行。,进程语句的语法格式1: 进程名: PROCESS (敏感信号表) 进程说明语句; BEGIN 顺序描述语句; END PROCESS 进程名;,进程语句的语法格式2: 进程名: PROCESS 进程说明语句; BEGIN WAIL UNTIL(激活进程的条件); 顺序描述语句; END PROCESS 进程名;,例9 利用PROCESS语句设计与非门电路。 nandx: PROCESS (a, b) BEGIN y=a NAND b; END PROCESS nandx;,进程标号不是必需的; 敏感信号表所标明的信号是用来启动进程的。若无敏感信号时,则通过WAIT语句来实现。WAIT UNTIL 条件表达式; PROCESS语句声明部分定义的量只适用于本进程。最常在此处定义的是变量。因为信号是全局量。 PROCESS内部各语句之间是顺序关系 。在系统仿真时, PROCESS语句是按书写顺序一条一条向下执行的。而不象BLOCK中的语句可以并行执行。,系统上电,进程挂起,敏感信号发生 变化?,敏感信号发生 变化?,顺序语句1,进程挂起,顺序语句1,顺序语句n,顺序语句n,N,N,Y,Y,进程1,进程2,进程的工作原理示意图,进程可用来描述组合逻辑,也可以用来描述时序逻辑。,时钟沿的VHDL描述: CLK: IN STD_LOGIC; 上升沿描述:CLKEVENT AND CLK=1 或者RISING_EDGE(CLK) 下降沿描述:CLKEVENT AND CLK=0 或者falling_edge(CLK),一个进程不可同时对时钟上、下沿敏感。,PROCESS(CLK) BEGIN IF rising_edge(clk) THEN ELSIF falling_edge(clk) THEN ,PROCESS(CLK) BEGIN IF rising_edge(clk) THEN ELSE ,例题:2分频电路(fenpin2.vhd),architecture behav of fenpin2 is signal q: std_logic; begin process(clkin) begin if rising_edge(clkin)then q=not q; end if; end process; clkout=q; end behav;,library ieee; use ieee.std_logic_1164.all;,entity fenpin2 is port(clkin: in std_logic; clkout: out std_logic); end fenpin2;,architecture behav of fenpin2 is begin process(clkin) begin if rising_edge(clkin)then clkout=not clkin; end if; end process; end behav;,例题:计数器(count10.vhd),library ieee; use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all;,entity count10 is port(clk: in std_logic; q: buffer std_logic_vector(0 to 3); end count10;,Architecture behav of count10 is begin process(clk) begin if rising_edge(clk) then if q=“1001“ then q=“0000“; else q=q+1; end if; end if; end process; end behav;,9.3 VHDL的基本描述语句,9.3.1 顺序描述语句 9.3.2 并发描述语句,Vhdl程序设计中两大基本描述语句系列:,9.3.1 顺序描述语句,信号代入语句 变量赋值语句 WAIT语句 IF语句 CASE语句,LOOP语句 NEXT语句 EXIT语句 RETURN语句 NULL语句,顺序语句的特点是:每一条顺序语句的执行顺序是与它们的书写顺序基本一致的。 顺序语句只能出现在进程和子程序中。,变量赋值语句格式为: 目标变量名 := 表达式;,信号赋值语句格式为: 目标信号名 = 表达式;,Library ieee; Use ieee.std_logic_1164.all;,Entity test_signal is Port(clr, clk: in std_logic; q1,q2: out integer range 0 to 9); End test_signal;,1、赋值语句(signal , variable) 将一个值或表达式的运算结果传递给某一数据对象。,Test_signal.vhd,Architecture test of test_signal is Signal A,B: integer range 0 to 9; Begin Process(clk,clr) Variable c: integer range 0 to 9; Begin If clr=1 then A=0; B=2; C:=0;,Elsif rising_edge(clk) then c:=c+1; A=c+1; B=A+2; END IF; END PROCESS; Q1=A; Q2=B; END TEST;,几种赋值形式,1、标识符赋值,Variable a: std_logic; Signal c: std_logic_vector(0 to 3); a:=1; C=“0001”;,2、数组元素赋值:数组名(下标),C(1)=0; C(1 to 2)=“00”; C(3 downto 2)=“10”,在进程(或过程)中,当执行到WAIT 等待语句时,运行程序将被挂起,直到满足此语句的结束挂起条件后,将重新开始执行进程(或过程)中的程序。,WAIT语句有以下四种形式: WAIT -无限等待 WAIT ON 敏感信号表; -敏感信号量变化,进程启动 WAIT UNTIL 条件表达式; -表达式成立时,进程启动 WAIT FOR 时间表达式; -时间到,进程启动,2、WAIT语句,IF语句的语法格式一: IF 条件 THEN 顺序处理语句; END IF;,例:IF(a=1)THEN c=b; END IF;,这种描述经逻辑综合,实际上可以生成D触发器。,3、IF 语句,ARCHITECTURE rtl OF dff IS BEGIN PROCESS (clk) BEGIN IF (clkevent and clk=1) THEN q=d; END IF; END PROCESS ; END rtl;,例2 设计D触发器。,IF语句的语法格式为: IF 条件 THEN 顺序处理语句l; ELSE 顺序处理语句2; END IF;,ARCHITECTURE rtl OF mux2_1 IS BEGIN PROCESS(a,b,sel) BEGIN IF (sel=1) THEN c=a; ELSE c=b; END IF; END PROCESS; END rtl;,例3 设计2选1的数据选择器。,IF语句的语法格式3为: IF 条件1 THEN 顺序处理语句1; ELSIF 条件2 THEN 顺序处理语句2; ELSIF 条件n THEN 顺序处理语句n; ELSE 顺序处理语句n+l; END IF;,例4 设计4选1的多路选择器,ENTITY mux4_1 IS PORT(d : IN STD_LOGIC_VECTOR(3 DOWNTO 0); sel : IN STD_LOGIC_VECTOR(1 DOWNTO 0); y : OUT STD_LOGIC); END mux4_1;,ARCHITECTURE rtl OF mux4_1 IS BEGIN PROCESS (d, sel) BEGIN IF (sel=“00“) THEN y=d(0); ELSIF (sel=“01“) THEN y=d(1); ELSIF (sel=“10“) THEN y=d(2); ELSE y=d(3); END IF; END PROCESS; END rtl;,LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY priencoder IS PORT(input : IN STD_LOGIC_VECTOR(7 DOWNTO 0); y: OUT STD_LOGIC_VECTOR(2 DOWNTO 0); END priencoder;,例5 设计优先编码器,ARCHITECTURE rtl OF priencoder IS BEGIN PROCESS (input) BEGIN IF (input(7)= 0) THEN y= “111“; ELSIF (input(6)= 0) THEN y= “110“; ELSIF (input(5)= 0 ) THEN y= “101“; ELSIF (input(4)= 0) THEN y= “100“; ELSIF (input(3)= 0 ) THEN y= “011“; ELSIF (input(2)= 0) THEN y= “010“; ELSIF (input(1)= 0 ) THEN y= “001“; ELSE y= “000“ ; END IF; END PROCESS; END rtl;,几点注意:,1、if语句可以嵌套使用,但层数不宜太多; 2、用if语句描述异步复位和时钟沿时,只能用if elsif end语句。,Process(clk) Begin If clkevent and clk=1 then S=a; Else s=b; End if; End process;,3、用if 语句描述组合电路时。务必包含所有的情况,否则将引入锁存器;,你能写出74161芯片的vhdl程序吗?,CASE语句的一般格式为: CASE 条件表达式 IS WHEN 条件表达式的值=顺序处理语句; END CASE;,CASE语句中条件表达式的值可以有以下4种不同的表示形式: WHEN 条件表达式的值=顺序处理语句; WHEN 条件表达式的值 | 值 | 值=顺序处理语句; WHEN 条件表达式的值 to 值=顺序处理语句; WHEN OTHERS=顺序处理语句;,4、CASE语句:根据满足的条件直接选择多项顺序语句中的一项执行。,使用case语句必须注意:,1、case语句之间是并行处理的,没有先后顺序: 2、除非所有条件句中的选择值能够涵盖case语句中表达式的所有取值,否则最末一条必须是when others。在使用std_logic时必须注意。 3、case语句中每一条件句中的选择值只能出现一次,不能重复。,例6: 4选1多路选择器(mux4_1.vhd),ARCHITECTURE arch OF mux4_1 IS BEGIN PROCESS (d, sel) BEGIN CASE sel IS WHEN “00“ =yyyyy=x; END CASE; END PROCESS; END arch;,8位数据的4选 1如何实现?,CASE语句与 IF语句的区别 : 在IF语句中,先处理最起始的条件,如果不满足,再处理下一个条件。 在CASE语句中,没有值的顺序号,所有值是并行处理的。因此,在WHEN项中的值不能重复使用。,例7:3-8译码器(decoder3_8.vhd),LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY decode3_8 IS PORT(a,b,c : IN STD_LOGIC; g1,g2a,g2b : IN STD_LOGIC; y : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); END decode3_8;,ARCHITECTURE rtl OF decode3_8 IS SIGNAL ind:STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN indyyyyyyyyy=“XXXXXXXX“; END CASE; ELSE y=“11111111“; END IF; END PROCESS; END rtl;,(b)GB符号,例8:8-3编码器,LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY encoder8_3 I PORT( input : IN STD_LOGIC_VECTOR(7 DOWNTO 0); y :OUT STD_LOGIC_VECTOR(2 DOWNTO 0); END encoder8_3;,ARCHITECTURE rtl OF encoder8_3 IS BEGIN PROCESS (input) BEGIN CASE input IS WHEN “01111111“ =yyyyyyyyy=“XXX“; END CASE; END PROCESS; END rtl;,5、LOOP语句,LOOP语句的书写格式一般有两种:,FOR 循环变量形成的LOOP语句,其一般格式为: 循环标号:FOR 循环变量 IN 循环范围 LOOP 顺序处理语句; END LOOP 循环标号;,循环变量是一个临时变量,属于局部变量。它仅在LOOP语句中有效,因此,不需要事先定义,它由LOOP语句自动定义。 循环变量是一个整数变量,不用事先说明。 其中循环范围是指循环变量在循环中依次取值的范围。,to downto ,例9 奇偶校验电路(parity_check.vhd),ENTITY parity_check IS PORT(a : INSTD_LOGIC_VECTOR(7 downto 0); y : OUT STD_LOGIC); END parity_check;,ARCHITECTURE rtl OF parity_check IS BEGIN y=a(0)xor a(1)xor a(2)xor a(3)xor a(4)xor a(5)xor a(6)xor a(7); END rtl;,ARCHITECTURE rtl OF parity_check IS BEGIN PROCESS(a) VARIABLE tmp : STD_LOGIC; BEGIN tmp:=0; FOR i IN 0 to 7 LOOP tmp:=tmp XOR a(i); END LOOP; y=tmp; END PROCESS; END rtl;,例10 双向移位寄存器(shift.vhd),FOR i IN 7 downto 1 LOOP a(i)=a(i-1);,FOR i IN 0 to 6 LOOP a(i)=a(I+1);,ENTITY shift IS PORT(clr,clk,load,ctr,sr,sl : IN STD_LOGIC; d : IN STD_LOGIC_VECTOR(7 downto 0); q : OUT STD_LOGIC_VECTOR(7 downto 0); END shift;,ARCHITECTURE arc OF shift IS SIGNAL a : STD_LOGIC_VECTOR(7 downto 0); BEGIN q=a; PROCESS(clr,clk) BEGIN IF (clr=0) THEN a=“00000000“;,ELSIF (clkEVENT AND clk=1) THEN IF load=0 THEN a=d; ELSIF (load=1 AND ctr=0) THEN FOR i IN 7 downto 1 LO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论