900 likes | 1.32k Views
第三章 VHDL 语法. 3.1 VHDL 语言的基本结构 3.2 VHDL 语言的基本结构 3.3 VHDL 语言结构体的描述方法 3.4 VHDL 语言语言顺序描述语句 3.5 VHDL 语言并行描述语句. 3.1 VHDL 语言的基本结构. 3.1.1 VHDL 数据对象( Data Objects ). 1 、常数( Constant ). 定义格式为: Constant 常数名:数据类型 : = 表达式;. Constant width: integer := 7; Constant Vcc: REAL:=5.0;
E N D
第三章 VHDL语法 3.1 VHDL语言的基本结构 3.2 VHDL语言的基本结构 3.3 VHDL语言结构体的描述方法 3.4 VHDL语言语言顺序描述语句 3.5 VHDL语言并行描述语句
3.1 VHDL语言的基本结构 3.1.1 VHDL数据对象(Data Objects) 1、常数(Constant) 定义格式为: Constant 常数名:数据类型 :=表达式; Constant width: integer := 7; Constant Vcc: REAL:=5.0; Constant D2:Std_Logic_Vector(width Downto 0):= ”0000”; • 不能在程序中改变; • 增强程序的可读性,便于修改程序; • 常量的使用范围取决于其定义位置,可在Library、Entity、Architecture、Process中进行定义,其有效范围也相应限定。
2、信号 信号数据对象,代表电路内部线路,其在元件之间起互连作用,没有方向性,可给它赋值,也可当作输入。 定义格式为: Signal信号名:数据类型[:=设定值]; 如: Signal A : Std_logic_vector(3 Down to 0) := “0000”; 信号赋值语句的语法格式为: 目标信号名<=表达式(设定值); A <= “1010” 注意:设定的初始值在综合时没有用,只是在仿真时在开始设定一个起始值。
3、 变量 变量是一个局部量,用于对中间数据的临时存储,并不一定代表电路的某一硬件,没有物理意义。 定义格式为: Variable 变量名:数据类型[:=设定值]; 如:Variable a: integer := 0; 变量赋值语句的语法格式为: 目标变量名 := 表达式(设定值); 如: a := b and c;
信号、变量、常数对比 一、定义 Signal clk: std_logic; Variable data: std_logic_vector(7 downto 0); Constant width: integer :=7 ; 二、赋值方式 clk <= ‘1’; (非立即) data := “1010”; (立即) 三、定义区域 信号:实体、结构体、程序包 变量:进程、子程序 常数:实体、结构体、程序包、块、进程、子程序
信号、变量、常数对比 四、适用范围 信号:实体、结构体、程序包 变量:定义了变量的进程、子程序的顺序语句中 常数:视其定义的位置而定 若常数定义在实体中,适用范围是实体所对应的所 有结构体。 若常数定义在结构体中,适用范围就是本结构体。
信号和变量赋值区别举例 信号赋值(非立即) 变量赋值(立即) Architecture abc of example is signal tmp:std_logic; Begin process(a,b,c) begin tmp<=a; x<=c and tmp; tmp<=b; y<=c and tmp; end process; End abc; Architecture abc of example is Begin process(a,b,c) variable tmp:std_logic; begin tmp:=a; x<=c and tmp; tmp:=b; y<=c and tmp; end process; End abc; 执行结果:x=c and b y=c and b 执行结果:x=c and a y=c and b
3.1.2 VHDL数据类型 1、逻辑数据类型 (1)布尔代数(Boolean)型 定义位置:在std库的standard程序包中进行定义。 取值:FALSE,TRUE (2)位(Bit) 定义位置:在std库的standard程序包中进行定义。 取值:0,1 (低电平,高电平 )
(3)位矢量(Bit_Vector) 定义位置:在std库的standard程序包中进行定义。 位矢量是基于“位”数据类型的数组 Signal A: bit_vector(0 to 7); Signal B: bit_vector(7 downto 0); A<=“00001010”; B<=“00001010”; A(7)=0 A(6)=1 A(5)=0 A(4)=1 A(3)=0 A(2)=0 A(1)=0 A(0)=0 B(7)=0 B(6)=0 B(5)=0 B(4)=0 B(3)=1 B(2)=0 B(1)=1 B(0)=0
(4)标准逻辑型(Std_Logic ) 定义位置:在IEEE库的std_logic_1164程序包中进行定义 使用这类数据信号,必须包含下面两条声明语句: Library IEEE; Use IEEE.std_logic_1164.all;
该类型能比较全面地包括数字电路中信号的几种状态,比位“bit”信号对于数字逻辑电路的逻辑特性描述更完整、更真实。所以在VHDL的程序里,对于逻辑信号的定义,通常都是采用这个“标准逻辑”信号形式,不再使用“BIT”。该类型能比较全面地包括数字电路中信号的几种状态,比位“bit”信号对于数字逻辑电路的逻辑特性描述更完整、更真实。所以在VHDL的程序里,对于逻辑信号的定义,通常都是采用这个“标准逻辑”信号形式,不再使用“BIT”。
(5)标准逻辑数组类型(Std_Logic_vector) 定义位置:在ieee库的std_logic_1164程序包中进行定义。 Bit_Vector与Std_Logic_vector的区别在于数组的 每一位前者为BIT型(0,1)后者为Std_Logic型 Signal A: STD_LOGIC_VECTOR(0 to 7); Signal B: STD_LOGIC_VECTOR (7 downto 0); A<=“10100000”; B<=“00001010”; A(7)=? B(7)=?
逻辑数据类型赋值举例 1、直接整体赋值 Variable a , b : std_logic; Signal data : std_logic_vector(0 to 3); a: = ‘1’; b: = ‘0’; data<=“1100”; 一位值用单引号 多位值用双引号
逻辑数据类型赋值举例 2. 段赋值 Signal data : std_logic_vector(0 to 3); data(1 to 2) <=“10”; data(0) <=‘1’; 3. 块赋值 Signal a,b,c,d : std_logic; Signal data : std_logic_vector(3 downto 0); data<= “0100” ; (a,b,c,d) <= bus ; 位置关联
数值数据类型 (1)整数(Integer) 定义位置:在std库的standard程序包中进行定义。即数值范围为-231~231。 整数不能用于逻辑运算,只能用于算术运算。 Signal day: integer range 0 to 31; Variable a,b,c: interger; C=a+b;
(2)无符号(Unsigned)和有符号(Signed)类型 定义位置:有符号(Signed)和无符号(Unsigned)逻辑信号定义在库IEEE的程序包std_logic_arith中。 无符号类型数据代表无符号数值,即代表0或正数;最左边的位 为最高位。如:Unsigned(“0110”)代表 ; +6 Unsigned(“1010”)代表 + 10 有符号类型数据代表有符号数值,即可以是正数,0,负数;编 译器将有符号数类型作为一个补码的二进制数,最左边的位为 符号位。 -2。 如:signed(“0110”)代表+6;signed(“1010”)代表
字符(CHARACTER)数据类型 单引号引起来,如:‘A’‘a’ 字符分大小写。’A’不等于’a’ 字符串(STRING)数据类型 双引号引起来字符串数组,一般用于程序的提示和结果说明, VARIABLE string_yin : STRING (1 TO 7 ) ; string_yin := "a b c d" ;
时间(TIME)数据类型(仿真使用,不能综合) TYPE time IS RANGE -2147483647 TO 2147483647 units fs ; -- 飞秒,VHDL中的最小时间单位 ps = 1000 fs ; -- 皮秒 ns = 1000 ps ; -- 纳秒 us = 1000 ns ; -- 微秒 ms = 1000 us ; -- 毫秒 sec = 1000 ms ; -- 秒 min = 60 sec ; -- 分 hr = 60 min ; -- 时 end units ; Q<=a and b or c AFTER 10ns;
用户定义的数据类型 格式: TYPE 数据类型名 数据类型定义 1、枚举类型 格式: TYPE 数据类型名 IS(元素1,元素2,……); 例:TYPE week IS (sun,mon,tue,wed,thu,fri,sat); 2、数组类型 格式: TYPE 数据类型名 IS ARRAY 范围 OF 原数据类型 例:TYPE word IS ARRAY (0 TO 7) OF STD_LOGIC;
用户定义的数据类型 3、记录Record Types • 相同或不同类型的元素组成,类似C中的结构 • 描述总线或功能块 Type iocell is record Enable :bit; Data :bit_vector(7 downto 0); end record; singal bus : iocell; bus.Enable <= ‘1’; bus.Data <= “00110110”;
用户定义的子类型 用户对已定义的数据类型,作一些范围限制而形成新的数据类型 格式: SUBTYPE 子类型名 IS 数据类型名 范围 例:SUBTYPE data IS STD_LOGIC_VECTOR(7 DOWNTO 0); SUBTYPE digit IS INTEGER RANGE 0 TO 9;
3.1.3 VHDL语言的操作符(operator) 一、逻辑操作符 能进行逻辑运算的数据类型: bit、bit_vector、boolean、 std_logic、std_logic_vector
数据类型必须一致 表达式中有多个运算符时一般要加括号,但and、or、xnor除外 signal d1,d2,s : integer; 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 ; ... s<=a and b; -- integer 不能进行逻辑运算 a<=b AND c; -- a、b、c的数据类型同属4位长的位矢量 d<=e OR f OR g ; -- 两个操作符OR相同,不需括号 h<=(i NAND j)NAND k ; -- NAND必须加括号 l<=(m XOR n)AND(o XOR p); -- 操作符不同,必须加括号 h<=i AND j AND k ; -- 两个操作符都是AND,不必加括号 h<=i AND j OR k ; -- 两个操作符不同,未加括号,表达错误 a<=b AND e ; -- 操作数b与e的位矢长度不一致,表达错误 h<=i OR l ; -- 数据类型不同,表达错误。
二、关系运算符 • =和/=的操作对象可以是任何数据类型构成的操作数。 • 其它关系运算符对数据类型有一定的限制。(整数、实数、枚举型、位矢量)
+、-、*可以构成逻辑电路; /、MOD、REM当分母的操作数是2的N次方时,才可过程逻辑电路。 Variabe data: std_logic_vector(3 donto 0) :=“1011”; Data SLL 1; --”0110” Data SRL 3; --”0001” Data ROL 1; --”0111” c<=a&b&c&d; x:=(-y); C<=a*4; A<=d/4
3.2 VHDL语言结构体的描述方法 3.2.1 设计实体 实体语句结构如下: ENTITY 实体名 IS [GENERIC(类属表);] [PORT(端口表);] END ENTITY 实体名; 例: ENTITY or2 IS PORT(a,b:IN STD_LOGIC; C: OUT STD_LOGIC); END ENTITY or2;
注意:实体应以语句“ENTITY 实体名 IS”开始,语句“END ENTITY 实体名;”结束。 在层次化系统设计中,实体说明是整个模块或整个系统的输入输出(I/O)接口;在一个器件级的设计中,实体说明是一个芯片的输入输出(I/O)。 类属参量(GENERIC) 类属参量是实体说明组织中的可选项,放在端口说明之前,其一般格式为: GENERIC [CONSTANT] 名字表:[IN] 子类型标识 [:= 静态表达式],…]
类属参量是一种端口界面常数,常用来规定端口的大小、实体中子元件的数目及实体的定时特性等。它和常数不同,常数只能从设计实体的内部得到赋值且不能改变,而类属参量的值可由设计实体的外部提供。因此设计者可以从外面通过类属参量的重新设定而容易的改变一个设计实体或一个元件的内部电路结构和规模。类属参量是一种端口界面常数,常用来规定端口的大小、实体中子元件的数目及实体的定时特性等。它和常数不同,常数只能从设计实体的内部得到赋值且不能改变,而类属参量的值可由设计实体的外部提供。因此设计者可以从外面通过类属参量的重新设定而容易的改变一个设计实体或一个元件的内部电路结构和规模。
例: GENERIC (trise,tfall:TIME:=1ns; Addrwidth:INTEGER:=16); PORT(a0, a1 : IN STD_LOGIC; Add_bus:OUT STD_LOGIC_VECTOR(addrwidth-1 DOWNTO 0); 这里类属参量中参数trise为上升沿宽度,tfall为下降沿宽度,用于仿真模块的设计;定义地址总线的宽度为Addrwidth位,类属值Addrwidth的改变将使结构体中所有相关的总线定义同时改变,由此使整个设计实体的硬件结构发生变化。
端口说明(PORT) 端口为设计实体和其外部环境提供动态通信的通道,是对基本设计单元与外部接口的描述,其功能相当电路图符号的外部引脚。端口可以被赋值,也可以当做逻辑变量用在逻辑表达式中。 其一般书写格式为: PORT (端口名:端口模式数据类型; 端口名:端口模式数据类型; … …);
其中端口名是设计者为实体的每一个对外通道所取的名字,通常为英文字母加数字,名字的定义有一定的惯例,如clk 表示时钟,D开头的端口名表示数据,A开头的端口名表示地址。 端口模式是指这些通道上的数据流动的方式,如输入或输出等。 端口模式有以下几种类型: 1.输入(IN) 允许信号进入实体,主要用于时钟输入、控制输入(如load、reset、enable、clk)和单向的数据输入(如地址数据信号address)等。
2.输出(OUT) 输出模式只允许信号离开实体,常用于计数输出、单向数据输出、被设计实体产生的控制其他实体的信号等。注意:输出模式不能用于被设计实体的内部反馈,因为输出端口在实体内不能看做是可读的。 3.双向模式(INOUT) 双向模式允许信号双向传输(既可以进入实体,也可以离开实体),双向模式端口允许引入内部反馈。
4.缓冲(BUFFER) 缓冲模式允许信号输出到实体外部,但同时也可以在实体内部引用该端口的信号。缓冲端口既能用于输出也能用于反馈。缓冲模式用于在实体内部建立一个可读的输出端口,例如计数器输出、计数器的现态用来决定计数器的次态。 端口模式可用图下说明,图中方框代表一个设计实体或模块。
Out与Buffer的区别 Entity test1 is port(a: in std_logic; b,c: out std_logic ); end test1; architecture a of test1 is begin b <= not(a); c <= b;-- Error end a; Entity test2 is port(a: in std_logic; b : buffer std_logic; c: out std_logic ); end test2; architecture a of test2 is begin b <= not(a); c <= b; end a;
3.2.2 结构体的一般语言格式 ARCHITECTURE 结构体名 OF 实体名 IS [说明语句] BEGIN [功能描述语句] END 结构体名;
结构体三种描述方法 行为描述(behavioral) 数据流描述(dataflow) 结构化描述(structural)
功能描述语句 进程语句 信号赋值语句 子程序调用语句 元件例化语句
结构体--行为描述 行为描述是高层次描述方式,它只描述输入与输出之间的逻辑转换关系,而不涉及具体逻辑电路结构等信息。 主要用于系统数学模型的仿真或系统工作原理的仿真。故其大量采用的算术运算、关系运算、惯性延时、传输延时等描述方式是难于或不能进行逻辑综合的。
行为描述:一般采用进程语句(PROCESS)描述 Architecture behavioral of eqcomp4 is begin comp: process (a,b) begin if a=b then equal <= ‘1’; else equal <=‘0’; end if; end process comp; end behavioral ; 高层次的功能描述,不必考虑在具体电路是怎样实现的。
结构体--数据流描述 数据流描述:也称寄存器(RTL)描述方式,明确描述了数据信号的流动路径、流动方向和流动结果。 它采用类似于布尔方程的并行信号赋值语句进行描述。可以描述时序电路,也可描述组合电路。是完全能够进行逻辑综合的描述方式。
布尔方程描述 当a和b的宽度发生变化时,需要修改设计,当宽度过大时,设计非常繁琐 Architecture dataflow1 of eqcomp4 is begin equal <= ‘1’ when a=b else ‘0’; end dataflow1; Architecture dataflow2 of eqcomp4 is begin equal <= not(a(0) xor b(0))and not(a(1) xor b(1))and not(a(2) xor b(2))and not(a(3) xor b(3)); end dataflow2;
结构体--结构化描述 结构化描述:复杂数字逻辑系统的层次化设计法。设计中,高层次的设计模块调用低层次的设计模块,或直接用门电设计单元来设计一复杂的逻辑电路。 它采用元件例化语句或生成语句进行设计。
元件例化语句 使用格式: 先声明元件: Component 元件名 [ IS ] [ Port (端口说明)] End Component ; 后元件例化: 例化名: 元件名 Port Map(端口映射)
元件例化时端口映射方式1:位置对应方式 元件标号:元件名Port Map(信号1, 信号2,…); architecture struct of eqcomp4 is COMPONENT XNOR2 PORT(A,B:IN STD_LOGIC; C:OUT STD_LOGIC); END COMPONENT; COMPONENT and4 PORT(a,b,c,d:IN STD_LOGIC; q:OUT STD_LOGIC); END COMPONENT; SIGNAL X:STD_LOGIC_VECTOR(0 TO 3); begin U0:xnor2 port map(a(0),b(0),x(0)); U1:xnor2 port map(a(1),b(1),x(1)); U2:xnor2 port map(a(2),b(2),x(2)); U3:xnor2 port map(a(3),b(3),x(3)); U4:and4 port map(x(0),x(1),x(2),x(3),equal); end struct;
元件例化时端口映射方式1:名字直接对应 元件标号:元件名 Port Map(信号A=>信号A1, 信号B=>信号B1,…); architecture struct of eqcomp4 is COMPONENT XNOR2 PORT(A,B:IN STD_LOGIC; C:OUT STD_LOGIC); END COMPONENT; COMPONENT and4 PORT(a,b,c,d:IN STD_LOGIC; q:OUT STD_LOGIC); END COMPONENT; SIGNAL X:STD_LOGIC_VECTOR(0 TO 3); begin U0:xnor2 port map(A=>a(0),B=>b(0),C=>x(0)); U1:xnor2 port map(B=>b(1),A=>a(1),C=>x(1)); U2:xnor2 port map(A=>a(2),B=>b(2),C=>x(2)); U3:xnor2 port map(A=>a(3),B=>b(3),C=>x(3)); U4:and4 port ap(a=>x(0),b=>x(1),c=>x(2),d=>x(3),q=>equal); end struct;
进程语句(process) Process 语句的格式为: [进程标号:] Process[(敏感信号列表)] [变量声明] Begin 顺序语句; End Process[进程标号]; 敏感表(Sensitivity list)包括进程的一些信号,当敏感表中的某个信号变化时进程才被激活,进程内的顺序语句被执行。当进程结束时,进程内的输出信号值被更新,进程进入等待(睡眠)状态,直到敏感表中的某一信号再次发生变化,进程被再次激活执行。
方案二 • architecture m2 of examle is • begin • A:Process(a,b) • begin • c<=a and b; • end process A; • B:Process(a,b) • begin • d<= a or b; • end process B; • end m2;