1.29k likes | 1.64k Views
第 10 章 VHDL 程序结构与规则. 本章内容. VHDL 实体 VHDL 结构体 VHDL 子程序 VHDL 库 VHDL 程序包 VHDL 配置 VHDL 文字规则 VHDL 数据类型 VHDL 操作符. 10.1 VHDL 实体. 10.1.1 实体语句结构. ENTITY 实体名 IS [GENERIC ( 参数名:数据类型 );] [PORT ( 端口表 );] END ENTITY 实体名 ;. 10.1 VHDL 实体. 10.1.2 参数传递说明语句.
E N D
第10章 VHDL程序结构与规则
本章内容 • VHDL实体 • VHDL结构体 • VHDL子程序 • VHDL库 • VHDL程序包 • VHDL配置 • VHDL文字规则 • VHDL数据类型 • VHDL操作符
10.1 VHDL实体 10.1.1 实体语句结构 ENTITY 实体名 IS [GENERIC ( 参数名:数据类型 );] [PORT ( 端口表 );] END ENTITY 实体名;
10.1 VHDL实体 10.1.2 参数传递说明语句 GENERIC([ 常数名 : 数据类型 [ : =设定值 ] { ;常数名 : 数据类型 [ : =设定值 ] } ) ; GENERIC(m:TIME:=1ns) … q<=tmp AFTER m;
10.1 VHDL实体 10.1.2 参数传递说明语句 【例10-1】 … ENTITY andn IS GENERIC ( n : INTEGER ); --定义类属参量及其数据类型 PORT(a : IN STD_LOGIC_VECTOR(n-1 DOWNTO 0);--用类属参量限制矢量长度 c : OUT STD_LOGIC); END; ARCHITECTURE behav OF andn IS BEGIN PROCESS (a) VARIABLE int : STD_LOGIC; BEGIN int := '1'; FOR i IN a'LENGTH - 1 DOWNTO 0 LOOP --循环语句 IF a(i)='0' THEN int := '0'; END IF; END LOOP; c <=int ; END PROCESS; END;
10.1 VHDL实体 10.1.2 参数传递说明语句 【例10-2】 … ENTITY exn IS PORT(d1,d2,d3,d4,d5,d6,d7 : IN STD_LOGIC; q1,q2 : OUT STD_LOGIC); END; ARCHITECTURE exn_behav OF exn IS COMPONENT andn --调用例10-1的元件调用声明 GENERIC ( n : INTEGER); PORT(a : IN STD_LOGIC_VECTOR(n-1 DOWNTO 0); C : OUT STD_LOGIC); END COMPONENT ; BEGIN u1: andn GENERIC MAP (n =>2) -- 参数传递映射语句,定义类属变量,n赋值为2 PORT MAP (a(0)=>d1,a(1)=>d2,c=>q1); u2: andn GENERIC MAP (n =>5) -- 定义类属变量,n赋值为5 PORT MAP (a(0)=>d3,a(1)=>d4,a(2)=>d5, a(3)=>d6,a(4)=>d7, c=>q2); END;
10.1 VHDL实体 10.1.3 参数传递映射语句 GENERIC MAP(类属表) 【例10-3】 LIBRARY IEEE; --待例化元件 USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_arith.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; ENTITY addern IS PORT (a, b: IN STD_LOGIC_VECTOR; result: out STD_LOGIC_VECTOR); END addern; ARCHITECTURE behave OF addern IS BEGIN result <= a + b; END; 不建议采用10-3与10-4方式进行编程
10.1 VHDL实体 10.1.3 参数传递映射语句 【例10-4】 LIBRARY IEEE; --顶层设计 USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_arith.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; ENTITY adders IS GENERIC(msb_operand: INTEGER := 15; msb_sum: INTEGER :=15); PORT(b: IN STD_LOGIC_VECTOR (msb_operand DOWNTO 0); result: OUT STD_LOGIC_VECTOR (msb_sum DOWNTO 0)); END adders; ARCHITECTURE behave OF adders IS COMPONENT addern PORT ( a, b: IN STD_LOGIC_VECTOR; result: OUT STD_LOGIC_VECTOR); END COMPONENT; SIGNAL a: STD_LOGIC_VECTOR (msb_sum /2 DOWNTO 0); SIGNAL twoa: STD_LOGIC_VECTOR (msb_operand DOWNTO 0); BEGIN twoa <= a & a; U1: addern PORT MAP (a => twoa, b => b, result => result); U2: addern PORT MAP (a=>b(msb_operand downto msb_operand/2 +1), b=>b(msb_operand/2 downto 0), result => a); END behave;
10.1 VHDL实体 10.1.3 参数传递映射语句 图10-1 例10-4的RTL电路图(Synplify综合)
10.1 VHDL实体 10.1.4 端口说明语句 PORT ( 端口名 : 端口模式 数据类型 ; { 端口名 : 端口模式 数据类型} ) ;
10.2 VHDL结构体 1. 结构体的一般语言格式 ARCHITECTURE 结构体名OF 实体名IS [说明语句] BEGIN [功能描述语句] END ARCHITECTURE 结构体名;
10.2 VHDL结构体 2. 结构体说明语句 数据类型,信号,常数,元件,函数,过程 3. 功能描述语句结构 进程语句 信号赋值语句 子程序调用语句 元件例化语句
10.4 VHDL库 10.4.1 库的种类 1.IEEE库 2.STD库 3.WORK库 4.VITAL库
10.4 VHDL库 10.4.2 库的用法 USE 库名.程序包名.项目名; USE 库名.程序包名.ALL ; LIBRARY IEEE ; USE IEEE.STD_LOGIC_1164.STD_ULOGIC ; USE IEEE.STD_LOGIC_1164.RISING_EDGE ; USE WORK.std_logic_1164.ALL;
10.5 VHDL程序包 定义程序包的一般语句结构如下: PACKAGE 程序包名IS -- 程序包首 程序包首说明部分 END 程序包名; PACKAGE BODY 程序包名IS -- 程序包体 程序包体说明部分以及包体内 END 程序包名; 程序包结构中,程序包体并非总是必须的,程序包首可以独立定义和使用
10.5 VHDL程序包 【例10-16】 PACKAGE pacl IS -- 程序包首开始 TYPE byte IS RANGE 0 TO 255 ; -- 定义数据类型byte SUBTYPE nibble IS byte RANGE 0 TO 15 ; -- 定义子类型nibble CONSTANT byte_ff : byte := 255 ; -- 定义常数byte_ff SIGNAL addend : nibble ; -- 定义信号addend COMPONENT byte_adder -- 定义元件 PORT( a, b : IN byte ; c : OUT byte ; overflow : OUT BOOLEAN ) ; END COMPONENT ; FUNCTION my_function (a : IN byte) Return byte ; -- 定义函数 END pacl ; -- 程序包首结束
【例10-17】 PACKAGE seven IS SUBTYPE segments is BIT_VECTOR(0 TO 6) ; TYPE bcd IS RANGE 0 TO 9 ; END seven ; USE WORK.seven.ALL; -- WORK库默认是打开的, ENTITY decoder IS PORT (input: bcd; drive : out segments) ; END decoder ; ARCHITECTURE simple OF decoder IS BEGIN WITH input SELECT drive <= B"1111110" WHEN 0 , B"0110000" WHEN 1 , B"1101101" WHEN 2 , B"1111001" WHEN 3 , B"0110011" WHEN 4 , B"1011011" WHEN 5 , B"1011111" WHEN 6 , B"1110000" WHEN 7 , B"1111111" WHEN 8 , B"1111011" WHEN 9 , B"0000000" WHEN OTHERS ; END simple ;
10.5 VHDL程序包 常用的程序包有: (1) STD_LOGIC_1164程序包。 (2) STD_LOGIC_ARITH程序包。 (3) STD_LOGIC_UNSIGNED和STD_LOGIC_SIGNED程序包。 (4) STANDARD和TEXTIO程序包。
10.3 VHDL子程序 FUNCTION 函数 PROCEDURE 过程块
10.3 VHDL子程序 10.3.1 VHDL函数 FUNCTION 函数名(参数表) RETURN 数据类型 --函数首 FUNCTION 函数名(参数表)RETURN 数据类型 IS -- 函数体 [ 说明部分 ] BEGIN 顺序语句 ; END FUNCTION 函数名; 一般函数定义由两部分组成,即函数首和函数体,在进程或结构体中不必定义函数首,而在程序包中使用必须定义函数首。
【例10-5】 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; PACKAGE packexp IS --定义程序包 FUNCTION max( a,b : IN STD_LOGIC_VECTOR) --定义函数首 RETURN STD_LOGIC_VECTOR ; FUNCTION func1 ( a,b,c : REAL ) --定义函数首 RETURN REAL ; FUNCTION "*" ( a ,b : INTEGER ) --定义函数首 RETURN INTEGER ; FUNCTION as2 (SIGNAL in1 ,in2 : REAL ) --定义函数首 RETURN REAL ; END ; PACKAGE BODY packexp IS FUNCTION max( a,b : IN STD_LOGIC_VECTOR)--定义函数体 RETURN STD_LOGIC_VECTOR IS BEGIN IF a > b THEN RETURN a; ELSE RETURN b; END IF; END FUNCTION max; --结束FUNCTION语句 END; --结束PACKAGE BODY语句
LIBRARY IEEE; -- 函数应用实例 USE IEEE.STD_LOGIC_1164.ALL; USE WORK.packexp.ALL ; ENTITY axamp IS PORT(dat1,dat2 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); dat3,dat4 : IN STD_LOGIC_VECTOR(3 DOWNTO 0); out1,out2 : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) ); END; ARCHITECTURE bhv OF axamp IS BEGIN out1 <= max(dat1,dat2); --用在结构体中的并行函数调用语句 PROCESS(dat3,dat4) BEGIN out2 <= max(dat3,dat4); --顺序函数调用语句,用在进程中 END PROCESS; END;
10.3 VHDL子程序 10.3.1 VHDL函数 图10-2 例10-5的逻辑电路图
10.3 VHDL子程序 10.3.1 VHDL函数 【例10-6】 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL ; ENTITY func IS PORT ( a : IN STD_LOGIC_VECTOR (0 to 2 ) ; m : OUT STD_LOGIC_VECTOR (0 to 2 ) ); END ENTITY func ; ARCHITECTURE demo OF func IS FUNCTION sam(x ,y ,z : STD_LOGIC) RETURN STD_LOGIC IS BEGIN RETURN ( x AND y ) OR z ; END FUNCTION sam ;--没有函数首,只有函数体 BEGIN PROCESS ( a ) BEGIN m(0) = sam( a(0), a(1), a(2) ) ; m(1) = sam( a(2), a(0), a(1) ) ; m(2) = sam( a(1), a(2), a(0) ) ; END PROCESS ; END ARCHITECTURE demo ;
10.3 VHDL子程序 10.3.2 VHDL重载函数 VHDL允许以相同的函数名定义函数,但要求函数中定义的操作数具有不同的数据类型,以便调用时用以分辨不同功能的同名函数
10.3 VHDL子程序 10.3.2 VHDL重载函数 【例10-7】 LIBRARY IEEE ; USE IEEE.STD_LOGIC_1164.ALL ; PACKAGE packexp IS --定义程序包 FUNCTION max( a,b :IN STD_LOGIC_VECTOR) --定义函数首 RETURN STD_LOGIC_VECTOR ; FUNCTION max( a,b :IN BIT_VECTOR) --定义函数首 RETURN BIT_VECTOR ; FUNCTION max( a,b :IN INTEGER ) --定义函数首 RETURN INTEGER ; END;
10.3 VHDL子程序 10.3.3 VHDL转换函数 VHDL是一种强数据类型语言,当数据类型不一致时,须转换一致后才能给信号赋值或完成各种运算操作。
函数名 功能 程序包: STD_LOGIC_1164 to_stdlogicvector(A) 由bit_vector类型的A转换为std_logic_vector to_bitvector(A) 由std_logic _vector转换为bit_vector to_stdlogic (A) 由bit转换成std_logic to_bit(A) 由std_logic转换成bit 程序包: STD_LOGIC_ARITH conv_std_logic_vector(A, 位长) 将整数integer转换成std_logic_vector类型,A是整数 conv_integer(A) 将std_logic_vector转换成整数integer 程序包: STD_LOGIC_UNSIGNED conv_integer(A) 由std_logic_vector转换成integer 10.3 VHDL子程序 10.3.3 VHDL转换函数 表10-1 IEEE库类型转换函数表
10.3 VHDL子程序 10.3.3 VHDL转换函数 【例10-9】 LIBRARY IEEE; USE IEEE. std_logic_1164.ALL; ENTITY exg IS PORT (a,b : in bit_vector(3 downto 0); q : out std_logic_vector(3 downto 0)); end ; architecture rtl of exg is begin q<= to_stdlogicvector(a and b);--将位矢量数据类型转换成标准逻辑位矢量数据 end;
10.3 VHDL子程序 10.3.3 VHDL转换函数 【例10-10】 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL;--注意使用了此程序包 ENTITY axamp IS PORT(a,b,c : IN integer range 0 to 15 ; q : OUT std_logic_vector(3 downto 0) ); END; ARCHITECTURE bhv OF axamp IS BEGIN q<= conv_std_logic_vector(a,4) when c=8 else conv_std_logic_vector(b,4) ; END;
【例10-11】 自定义转换函数 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; PACKAGE n_pack IS SUBTYPE nat IS Integer range 0 to 255; --定义一个Integer的子类型 TYPE Bit8 IS array (7 downto 0) OF std_logic;-- 定义一个数据类型 FUNCTION nat_to_Bit8 (s: nat) RETURN Bit8; End n_pack; PACKAGE BODY n_pack IS FUNCTION nat_to_Bit8 (s: nat) RETURN Bit8 IS VARIABLE Din: Integer range 255 downto 0; VARIABLE Rut: Bit8; VARIABLE Rig: Integer :=2**7; BEGIN Din := s; FOR I in 7 downto 0 LOOP IF Din/Rig > 1 THEN Rut(i) := '1'; Din := Din-Rig; ELSE Rut (i):= '0'; END IF; Rig := Rig / 2; END LOOP; RETURN Rut; END nat_to_Bit8; END n_pack;
接上页 LIBRARY IEEE; -- 用户定义转换函数应用实例 USE IEEE.STD_LOGIC_1164.ALL; USE WORK.n_pack.ALL ; ENTITY axamp IS PORT(dat : IN nat; --注意数据类型的定义 ou : OUT Bit8); --注意数据类型的定义 END; ARCHITECTURE bhv OF axamp IS BEGIN ou <= nat_to_Bit8(dat); END;
10.3 VHDL子程序 10.3.4 VHDL决断函数 决断函数输入一般是单一变量,多个驱动源的信号值组成非限定数组,如2个信号驱动源,其信号值组成的数组是2个元素长度;3个信号驱动源信号值组成的数组是3个元素长度,多个信号驱动源信号值组成的未限定数组可依次类推。但决断函数调用后返回的是单一信号值,称断信号值。
小结 函数 • VHDL函数 • 重载函数(OVERLOADED FUNCTION) • 转换函数 • 决断函数
10.3 VHDL子程序 10.3.5 VHDL过程 PROCEDURE 过程名(参数表) -- 过程首 PROCEDURE 过程名(参数表) IS [说明部分] BIGIN -- 过程体 顺序语句; END PROCEDURE 过程名 与函数一样,过程也由过程首和过程体构成,过程首在程序包中必须使用,在进程或结构体中不必定义过程首。
10.3 VHDL子程序 10.3.5 VHDL过程 参数表可以对常数、变量和信号3类数据对象做出说明,并用关键词IN OUT INOUT定义这些参数的工作模式,如果没有指定模式,则默认为IN。 PROCEDURE pro1 (VARIABLE a, b : INOUT REAL) ; PROCEDURE pro2 (CONSTANT a1 : IN INTEGER ; VARIABLE b1 : OUT INTEGER ) ; PROCEDURE pro3 (SIGNAL sig : INOUT BIT) ;
10.3 VHDL子程序 10.3.5 VHDL过程 【例10-12】 PROCEDURE prg1(VARIABLE value:INOUT BIT_VECTOR(0 TO 7)) IS BEGIN CASE value IS WHEN "0000" => value: "0101" ; WHEN "0101" => value: "0000" ; WHEN OTHERS => value: "1111" ; END CASE ; END PROCEDURE prg1 ;
【例10-14】 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; PACKAGE axamp IS 过程首定义 PROCEDURE nand4a (SIGNAL a,b,c,d : IN STD_LOGIC ; SIGNAL y : OUT STD_LOGIC ); END axamp; PACKAGE BODY axamp IS --过程体定义 PROCEDURE nand4a (SIGNAL a,b,c,d : IN STD_LOGIC ; SIGNAL y : OUT STD_LOGIC ) IS BEGIN y<= NOT(a AND b AND c AND d); RETURN; END nand4a; END axamp; LIBRARY IEEE; --主程序 USE IEEE.STD_LOGIC_1164.ALL; USE WORK.axamp.ALL; ENTITY EX IS PORT( e,f,g,h : IN STD_LOGIC ; x : OUT STD_LOGIC ); END; ARCHITECTURE bhv OF EX IS BEGIN nand4a(e,f,g,h,x) ; 并行调用过程 END;
10.3 VHDL子程序 10.3.6 VHDL重载过程 【例10-15】 PROCEDURE calcu ( v1, v2 : IN REAL ; SIGNAL out1 : INOUT INTEGER) ; PROCEDURE calcu ( v1, v2 : IN INTEGER ; SIGNAL out1 : INOUT REAL) ; ... calcu (20.15, 1.42, signl) ; -- 调用第一个重载过程calcu calcu (23,320,sign2 ) ;-- 调用第二个重载过程calcu ...
过程与函数的差异 1 函数所有参数都是输入信号,其输出信号只有一个,即,返回值。所以,在函数声明中,参数的输入输出状态不必写明。 2 过程的参数有可能是输入信号,有可能是输出信号,INOUT 信号,所以在其声明中必须要标清楚。 3 function只返回一个值(用return),且不改变其它值。 procedure可返回多个值(无return),或不返回值,可改变其它值。
10.6 VHDL配置 当一个VHDL程序有多个构造体时,可以通过配置语句对构造体进行选择。 配置语句的一般格式如下: CONFIGURATION 配置名 OF 实体名 IS for 选配构造体名 end for; END 配置名;
实例 entity counter is port(…. …..); end counter; Architecture count_255 of counter is Begin …… end ardff; Architecture count_64k of counter is Begin ….. End srdff; Configuration small_count of counter is for connt_255; end for; end cfg_dff;
10.7 VHDL文字规则 10.7.1 数字 整数: 5, 678, 0, 156E2(=15600), 45_234_287 (=45234287) 实数: 1.335,88_670_551.453_909(=88670551.453909),1.0,44.99E-2(=0.4499) 以数制基数表示的文字: SIGNAL d1,d2,d3,d4,d5, : INTEGER RANGE 0 TO 255; d1 <= 10#170# ; -- (十进制表示,等于170) d2 <= 16#FE# ; -- (十六进制表示,等于254) d3 <= 2#1111_1110#; -- (二进制表示,等于254) d4 <= 8#376# ; -- (八进制表示,等于254) d5 <= 16#E#E1 ; -- (十六进制表示,等于2#1110000#,等于224) 物理量文字(VHDL综合器不接受此类文字) 60s (60秒),100m (100米),k (千欧姆),177A (177安培)
10.7 VHDL文字规则 10.7.2 字符串 (1) 文字字符串 "ERROR" ,"Both S and Q equal to 1" ,"X" ,"BB$CC" (2) 数位字符串 了解 B:二进制基数符号,表示二进制位0或1,在字符串中的每位表示一个Bit。 O:八进制基数符号,在字符串中的每一个数代表一个八进制数,即代表一个3位(BIT)的二进制数。 X:十六进制基数符号(0~F),代表一个十六进制数,即一个4位的二进制数。 data1 <= B"1_1101_1110" -- 二进制数数组,位矢数组长度是9 data2 <= O"15" -- 八进制数数组,位矢数组长度是6 data3 <= X"AD0" -- 十六进制数数组,位矢数组长度是12 data4 <= B"101_010_101_010" -- 二进制数数组,位矢数组长度是12 data5 <= "101_010_101_010" --表达错误,缺B。 data6 <= "0AD0" --表达错误,缺X。
10.7 VHDL文字规则 10.7.4 下标名 标识符(表达式) SIGNAL a,b : BIT_VECTOR (0 TO 3) ; SIGNAL m : INTEGER RANGE 0 TO 3 ; SIGNAL y,z : BIT ; z <= b(3) ; -- 可计算型下标表示
命名规则 • 名字的最前面应该是英文字母 • 能使用的字符只有英文字母、数字和‘_’; • 不能连续使用‘_’,在名字的最后也不能使用‘_’,中间不能使用空格。 • Signal a_bus: std_logic_vector(7 downto 0); • Signal 302_bus: • Signal b_@bus: • Signal a_ _bus: • Signal b_bus_: • Signal b bus: -- 注释符号
10.8 VHDL数据类型 • 在VHDL语言中信号、变量、常数都要指定数据类型,为此,VHDL语言提供了多种标准的数据类型。另外,为使用户设计方便,还可以由用户自定义数据类型。 • VHDL语言的数据类型的定义相当严格,不同类型之间的数据不能直接代入,而且,即使数据类型相同,而位长不同时也不能直接代入。 • 预定义数据类型 • IEEE定义标准逻辑位与矢量 • 其他预定义数据类型
整数(Integer) • 整数与数学中的定义相同。在VHDL中,整数的表示范围为-2 147 483 647 ~ 2 147 483 647,既-(231-1) ~ (231-1) 。 • 注意千万不要把一个实数赋予一个整数变量,因为VHDL是一个强类型语言。 • 对整数不能用逻辑操作符,当需要进行位操作时,可以用转换函数,将整数转转成位矢量。
实数(Real) • 在进行算法研究或者实验时,做为对硬件的抽象手段,常常采用实数四则运算,实数的定义值范围为-1.0e+38 ~ +1.0e+38 ,实数有正有负,书写时要有小数点,例如: -1.0,+2.5,-1.0e38 • 注意实数类型不能综合