810 likes | 1.15k Views
第 4 ç« VHDL 设计入门. 基本知识:. ç†è§£ Quartusâ…¡ çš„ HDL 输入法 ç†è§£ VHDL 程åºçš„基本结构 ç†è§£ VHDL 程åºçš„顺åºç»“æž„ ç†è§£ VHDL 程åºçš„并行结构 ç†è§£ VHDL 程åºçš„è¯è¨€è¦ç´ . Quartusâ…¡ 软件的æ“作顺åºï¼š. 编写 VHDL 程åºï¼ˆä½¿ç”¨ Text Editor ) 编译 VHDL 程åºï¼ˆä½¿ç”¨ Complier ) ä»¿çœŸéªŒè¯ VHDL 程åºï¼ˆä½¿ç”¨ Waveform Editor 〠Simulator ) 进行芯片的时åºåˆ†æžï¼ˆä½¿ç”¨ Timing Analyzer )
E N D
基本知识: • 理解QuartusⅡ的HDL输入法 • 理解VHDL程序的基本结构 • 理解VHDL程序的顺序结构 • 理解VHDL程序的并行结构 • 理解VHDL程序的语言要素
QuartusⅡ软件的操作顺序: • 编写VHDL程序(使用Text Editor) • 编译VHDL程序(使用Complier) • 仿真验证VHDL程序(使用Waveform Editor、Simulator) • 进行芯片的时序分析(使用Timing Analyzer) • 安排芯片脚位(使用Floorplan Editor) • 下载程序至芯片(使用Programmer)
§4.1 QuartusⅡ的HDL输入法 • 常用的输入法有三种:AHDL、VHDL、Verilog HDL。 • 以7段数码显示译码器设计为例介绍QuartusⅡ的VHDL文件的输入编辑和编译仿真方法。 • 一、输入编辑VHDL文件 • 建立工程项目 • 执行File-New Project Wizard…命令,建立工程,项目名称DECL7S
一、输入编辑VHDL文件 2. 新建VHDL文件 执行File-New…命令,弹出图4-8对话框选择VHDL File。然后保存文本文件File-save as… 图4-9 图4-8
一、输入编辑VHDL文件 3. 编辑VHDL文件
二、编译仿真VHDL文件 1.编译VHDL文件 执行Processing-Start Complication,进行编译,如有错误进行修改保存后再编译直到编译成功。 2.仿真VHDL文件 新建波形文件File-New…,如同仿真原理图一样步骤 先装载引脚d和led;然后设置仿真结束时间Edit-End Time和网格大小Edit-Grid Size;编辑波形后保存,最后进行波形仿真Processing-Start Simulation.
二、编译仿真VHDL文件 图4-26 仿真结果
§4.2 VHDL的程序基本结构117 定义使用哪些自定义元件库 定义元件库 1.USE定义区 描述电路内部的功能,说明电路执行什么动作或功能 2.PACKAGE定义区 定义电路实体的外观;I/O接口的规格 3.ENTITY定义区 4.ARCHITECTURE定义区 Component定义区 信号定义 Behavior Process描述 Data Flow描述 Structure描述 决定哪一个architecture被使用 5.CONFIGURATION定义区
IEEE库 STD库 ASIC矢量库 WORK库 用户自定义库 VHDL基本程序结构: 常用库: 由于VHDL已是IEEE规定的标准,所以只要是CPLD、FPGA等芯片公司,它们都会提供这个标准的定义库(Library IEEE),而且由于这里面写了许许多多的定义与参数,初学者一时之间也不容易全部了解,所以全部写上以减轻负担。 1)USE定义区和标准定义库包括: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;
1)USE定义区和标准定义库包括 • 程序包(PACKAGE)是预先定义或设计好的数据类型、子程序和各种设计实体的集合; • 库(LIBRARY)则是用来存储已经完成的程序包等VHDL设计与数据的仓库。 • 一般情况下,库和程序包的引用声明放在设计文件的最前面。
库与程序包的使用 除WORK、STD库外,其他库与程序包使用前首先要声明。格式如下: LIBRARY 库名; USE 库名.程序包名.项目名; USE 库名.程序包名.ALL; 例:LIBRARY altera; USE altera.maxplus2.ALL; LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL;
附程序包的定义: PACKAGE 程序包名 IS 程序包首说明语句; END [PACKAGE] 程序包名; PACKAGE BODY 程序包名 IS 程序包体说明语句; END [PACKAGE BODY] 包集合名; 提示:程序包体为可选项,程序包首与程序包体名字应相同。
2)实体(ENTITY)命令格式: ENTITY 芯片电路名称 is PORT( 管脚名称1:输出输入状态 资料类型; 管脚名称2:输出输入状态 资料类型; : 管脚名称n:输出输入状态 资料类型 ); END 芯片电路名称; ※注意两点:a.芯片电路名称是对你所编辑的电路功能的描述,比如半加器、全加器、D出发器及一些复杂的编程电路;b.对每个管脚的描述完成后要打分号,但是最后一个管脚描述完成后不用分号,而是在括上反括号后打分号。
端口方向: • IN(输入),只能读,用于时钟输入、控制输入(装入、复位、使能)、单向数据输入; • OUT(输出),只能被赋值,用于不能反馈的输出; • BUFFER(缓冲),类似于输出,但可以读,读的值是被赋值,用做内部反馈用,不能作为双向端口使用。 ENTITY and_n IS GENERIC(n:POSITIVE:=8); PORT(a:IN BIT_VECTOR((N-1) DOWNTO 0); f:OUT BIT); END and_n;
3)Architecture定义区的命令格式: ARCHITECTURE 结构名称 OF 芯片电路名称(实体名) IS BEGIN : (电路内部的描述) END 结构名称; ※ 这里的结构名称是可以根据用户的习惯定义,但是需要和芯片电路名称相区别。
例: ENTITY adder IS PORT(op1,op2 : IN UNSIGNED(7 DOWNTO 0); Result: OUT INTEGER); END adder; ARCHITECTURE maxpld OF adder IS BEGIN result<=CONV_INTEGER(op1+op2); END ARCHITECTURE maxpld;
4)CONFIGURATION配置的命令格式: 一个实体可以有几个结构体,就好像一个电路可以有几个不同的实现方案一样。配置是在一个实体有几个结构体时,用来为实体指定在特定的情况下使用哪个特定的结构体。在仿真时可以利用配置为实体选择不同的结构体。 CONFIGURATION 配置名 OF 实体名 IS FOR 结构体名 END FOR; END[CONFIGURATION] 配置名;
例: CONFIGURATION MY_CONFIG OF COUNTER3 IS FOR MY_ARCH END FOR; END MY_CONFIG;
Pin48 Pin7 以一个芯片内部俯视图为例: 试用VHDL编写程序 实际上这只是将输入脚Pin48直接引一条线至输出脚Pin7。 图4-5-1芯片内部俯视图
程序如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CH1_1_1 IS PORT( PIN48: IN STD_LOGIC; PIN7: OUT STD_LOGIC ); END CH1_1_1; ARCHITECTURE A OF CH1_1_1 IS BEGIN PIN7<=PIN48; END A;
§4.5 VHDL程序的语言要素总结 基本数据类型:逻辑信号、数值信号 布尔代数(Boolean) 逻辑信号 位(Bit) 标准逻辑(Std_Logic) 信号 正整数(Positive) 整数(Integer Unsigned) 自然数(Natural) 数值信号 实数(Real)
一、逻辑信号 1.布尔代数(Boolean) Type Boolean is (False,True) 一个布尔量具有两个状态:“真”或“假”。布尔量不属于数值,因此不能用于运算,它只能通过关系运算符获得。一般这一类型的数据初始值总为FALSE. 2.位(Bit) Type Bit is(‘0’, ‘1’) 可视为数字电路里的低电位,高电位 Eg.要设置一个定义为Bit的Result管脚信号为高电位输出,则 Entity中 Result: out Bit; Architecture中 Result<=‘1’;
3.标准逻辑(Std_Logic) Type STD_LOGIC is (‘X’,--Forcing Unknown ; 浮接不定 ‘0’,--Forcing 0; 低电位 ‘1’,--Forcing1;高电位 ‘Z’,--High Impedance;高阻抗 ‘W’,--Weak Unknown;浮弱接 ‘L’,--Weak 0;弱低电位 ‘H’,--Weak 1;弱高电位 ‘-’,--Don’t care;不必理会 ); “标准逻辑”信号定义,远较“Bit”信号对于的数字逻辑电路的逻辑特性描述更完整、更真实。对逻辑信号的定义,通常都采用
Address 4 8 ROM CE 4.逻辑序列信号 以数字电路而言,有许多时候都是将几个信号合成一组代表特定功能的序列信号,例如:数据总线(Data Bus)、地址总线(Address Bus)等。实际上从电路的观点上,CLK信号看成一条线上的信号,而Data是8条线合成的排线信号。 Data 图5-1-1 序列信号在电路上的表示意义
针对这种序列信号的表示,提供以下功能: Bit_Vector :位序列 Std_Logic_Vector :标准逻辑序列 Signal Data : Std_logic_vector(7 Downto 0);--Data output Signal Address:Std_logic_vector(0 to 3);--Address Signal CE:Std_logic --chip enable 对序列信号的表示,除了序列的范围大小须注意外,还须特别留意序列的编号顺序。
B(0) B(1) B(2) B(3) A(3) A(2) A(1) A(0) ARCHITECURE m of test is Signal A : Std_logic_vector(3 Downto 0); Signal B :Std_logic_vector(0 to 3); Begin B<=A; --A序列信号传递至B序列信号 End m; 图5-1-2 A、B序列信号的传递
B(0) B(1) B(2) B(3) A(3) A(2) A(1) A(0) C(0) D(1) C(1) D(0) 1 5、序列信号的分解与合并 在信号的处理上,VHDL的语法是接受分解与合并的,如图5-1-3“&”符号代表执行信号合并的动作。 图5-1-3序列信号的分解与合并
程序为: ARCHITECTURE M OF TEST IS Signal A :Std_logic_vector(3 downto 0); Signal B :Std_logic_vector(0 to 3); Signal C :Std_logic_vector(0 to 1); Signal D :Std_logic_vector(1 downto 0); BEGIN C<=A(2 DOWNTO 1); --分解:A(2~1)序列信号传至D B<=A(3) & D & ‘1’; --合并;A(3)、D、要“1”信号传递至D END M;
6、逻辑信号的运算 配合逻辑信号的基本运算符,通常包含有两种: 逻辑运算、关系运算 1)逻辑运算符(6种) NOT(非) OR(或) AND(与) NOR(或非) NAND(与非) XOR(异或) 2)关系运算符 =(等于) /=(不等于) <(小于) <=(小于等于) >(大于) >=(大于等于)
例2: ENTITY CH2_1_2 IS PORT( A: IN Std_logic_vector(3 downto 0); B: IN Std_logic_vector(3 downto 0); C: OUT Std_logic_vector(7 downto 0) ); END CH2_1_2; ARCHITECTURE M OF CH2_1_2 IS BEGIN C(0)<=NOT A(0); C(2 DOWNTO 1)<=A(2 DOWNTO 1) AND B(2 DOWNTO 1); C(3)<='1' XOR A(3); C(7 downto 4)<="1111" when(A/=B)ELSE "0000"; END M;
二、数值信号 在VHDL的程序中,将信号定义成数值,是为了方便作数值方面的运算,如“加6计数器”、“10分频器”,为后续作加减乘等运算就相对容易许多。 1、整数(Integer) Type INTEGER is range -2147483648 to 2147483647 实际上一个整数是由32位的BIT_VECTOR所构成,所以数值范围也可以看成是-231 ~231-1 ①正整数 Subtype POSITIVE is range 0 to INTEGER’High ②自然数 Subtype NATRAL is range 1 to INTEGER’High
数值范围的限制方法,是以Range…To 命令来达成。 Signal A : INTEGER; --32位整数的定义 Signal B : Integer range 0 to 7; --3位整数的定义 Signal C : Integer range -1 to 1; --2位整数的定义 上面的A、B、C信号的定义,原本都是32位的整数,但经Range…To的限制结果,将有效控制B、C的位长度。
2、无符号整数 和前面的“标准逻辑”序列(Std_logic_vector)信号相似,定义时必须指明这个无符号整数的位数,例如下面的定义: Signal A : Unsigned(3 Downto 0); --4位无符号整数定义 Signal B : Unsigned(7 Downto 0); --8位无符号整数定义 Usigned信号类型除了具有数值运算的好处外,它还具有与“标准逻辑”序列信号相似的逻辑运算特性。 通过一个实例来理解无符号整数与标准逻辑序列的异同: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--**************************************************** ENTITY CH2_1_3 IS PORT( A:IN STD_LOGIC_VECTOR(1 DOWNTO 0); B:IN UNSIGNED(1 DOWNTO 0); C:OUT UNSIGNED(7 DOWNTO 0); D:OUT STD_LOGIC_VECTOR(1 DOWNTO 0) ); END CH2_1_3; --***************************************************** ARCHITECTURE M OF CH2_1_3 IS SIGNAL E,F,G:UNSIGNED(1 DOWNTO 0); SIGNAL H :UNSIGNED(7 DOWNTO 0); BEGIN E<=UNSIGNED(A); F<=B; H(1 DOWNTO 0)<=E+F; H(3 DOWNTO 2)<=E-F; H(7 DOWNTO 4)<=E*F; G(0)<=E(0) AND F(0); G(1)<=E(1) OR F(1); C<=H; D<=STD_LOGIC_VECTOR(G); END M;
※注意: 1、由上述的范例可以了解,Unsigned(无符号整数)与Std_logic_vector(标准逻辑)信号之间是可以作转换的。 2、Unsigned(无符号整数)信号的序列编号是由高至低,所以一定要使用Downto的序列形式定义。
3、实数(Real) 实数信号的定义形式为: Type REAL is range -1.7E38 to 1.7E38 必须表示成“带小数点”或科学计数的表示方式。 ARCHITECTURE m OF TEST IS Signal A,B,C,D : REAL; BEGIN A<=1.5; --带小数点 B<=5.0; C<=3.0E8; --科学计数 D<=-4.9E-9; END m;
数据对象的定义 • VHDL语言的标识符 • 数据对象的定义 常数(Constant) 信号(Signal) 变量(Variable)
VHDL语言的标识符 • VHDL中的标识符可以是常数、变量、信号、端口、子程序或参数的名字。使用标识符要遵守如下法则: • 标识符由字母(A…Z;a…z)、数字和下划线字符组成。 • 任何标识符必须以英文字母开头。 • 末字符不能为下划线。 • 不允许出现两个连续下划线。 • 标识符中不区分大小写字母。 • VHDL定义的保留子或称关键字,不能用作标识符。 • VHDL中的注释由两个连续的短线(--)开始,直到行尾。
以下是非法标识符: -Decoder —起始不能为非英文字母 3DOP —起始不能为数字 Large#number —“#”不能成为标识符的构成符号 Data__bus —不能有双下划线 Copper_ —最后字符不能为下划线 On —关键字不能用作标识符。 注:在AHDL语言中标识符要区分大小写,但在VHDL语言中不区分大小写。所以写程序时,一定要养成良好的书写习惯,应用关键字时用大写,自己定义的标识符用小写。
标识符表示的几种数据对象的详细说明如下: • 1) 常数(Constant ) • 常数是一个固定的值,主要是为了使设计实体中的常数更容易阅读和修改。常数一被赋值就不能在改变。一般格式: • CONSTANT 常数名:数据类型:=表达式; • 例:CONSTANT Vcc: REAL: =5.0; • —设计实体的电源电压指定 • 常数所赋得值应与定义的数据类型一致。 • 常量的使用范围取决于它被定义的位置。程序包中定义的常量具有最大的全局化特性,可以用在调用此程序包的所有设计实体中;设计实体中某一结构体中定义的常量只能用于此结构体;结构体中某一单元定义的常量,如一个进程中,这个常量只能用在这一进程中。
例如:定义一个4位(Nibble)长的常数零和一个8位(Byte)长的常数零,可分别写成:例如:定义一个4位(Nibble)长的常数零和一个8位(Byte)长的常数零,可分别写成: Constant Zero_4:Std_logic_vector(3 downto 0):=“0000”; Constant Zero_8:Std_logic_vector(7 downto 0):=“00000000”; 常数名称的命令规则如标志符规则,数据类型如上一节所提Bit、Unsigned、Std_logic_vector。设置值必须要,而且定义完成后,就不能再更改。
2)变量(Variable) • 变量是一个局部变量,它只能在进程语句、函数语句和进程语句结构中使用。用作局部数据存储。在仿真过程中。它不像信号那样,到了规定的仿真时间才进行赋值,变量的赋值是立即生效的。变量常用在实现某种算法的赋值语句中。 • 一般格式: • VARIABLE 变量名 数据类型 约束条件:=表达式; • 例:VARIABLE x, y: INTEGER; —定义x, y为整数变量 • VARIABLE count: INTEGER RANGE0 TO255:=10; —定义计数变量范围 • 变量的适用范围仅限于定义了变量的进程或子程序中。若将变量用于进程之外,必须该值赋给一个相同的类型的信号,即进程之间传递数据靠的信号。 • 变量赋值语句的语法格式如下: • 目标变量:=表达式; • 变量赋值符号是“:=”。赋值语句右方的表达式必须是一个与目标变量有相同数据类型的数值。变量不能用于硬件连线和存储元件。
3)信号(Signal) 信号是描述硬件系统的基本数据对象,它类似于连接线,也可内连元件。端口也是信号。事实上,端口能够专门被定义为信号。它除了没有数据流动方向说明以外,其它性质与实体的端口(Port)概念一致。变量的值可以传递给信号,而信号的值不能传递给变量。信号通常在构造体、包集合和实体中说明。信号说明格式为: SIGNAL 信号名: 数据类型; 信号初始值的设置不是必需的,而且初始值仅在VHDL的行为仿真中有效。 信号除了没有方向的概念以外几乎和端口概念一致。 例:SIGNAL sys_clk: BIT:=’0’; SIGNAL ground: BIT:=’0’ 在程序中,信号值输入信号时采用代入符”<=”,而不是赋值符 “:=”,同时信号可以附加延时。 信号传送语句: s1<=s2 AFTER 10ns 信号是一个全局量,可以用来进行进程之间的通信
信号与变量的区别: • 信号赋值可以有延迟时间,变量赋值无时间延迟; • 信号除当前值外还有许多相关值,如历史信息等,变量只有当前值; • 进程对信号敏感,对变量不敏感; • 信号可以是多个进程的全局信号,但变量只在定义它之后的顺序域可见; • 信号可以看作硬件的一根连线,但变量无此对应关系。
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CH2_2_2A IS PORT( IP:IN STD_LOGIC; CP:IN STD_LOGIC; OP:OUT STD_LOGIC ); END CH2_2_2A; ARCHITECTURE M OF CH2_2_2B IS BEGIN PROCESS(CP,IP) VARIABLE D:STD_LOGIC; BEGIN IF CP'EVENT AND CP='1' THEN D:=IP; OP<=D; END IF; END PROCESS; END M; ARCHITECTURE M OF CH2_2_2A IS SIGNAL D:STD_LOGIC; BEGIN PROCESS(CP,IP) BEGIN IF CP'EVENT AND CP='1' THEN D<=IP; OP<=D; END IF; END PROCESS; END M;
VHDL程序的顺序结构 • 顺序语句: 每一条语句在行为仿真时的执行顺序都是按照它们的书写顺序。 • 并行语句: 各个并行语句在行为仿真时执行是同步进行的,其执行顺序与它们的书写顺序无关。
§4.2 顺序语句(一) • 进程(Process) • If-Else(判断比较) • Wait(等待) 注意: “顺序语句命令”与下一节所提“并行同时”命令的最大不同点是,顺序语句命令类似一般的程序语言,如C、Basic等的执行方式,是一次一个命令,且依书写方式由上而下的执行。 但“并行同时”命令的执行方式,就像是电路板的动作方式,不论几个命令,是一次同时执行,产生结果。
1、进程(Process) 语法格式: [过程名称:] Process [(感测信号1,感测信号2,……)] [定义区] Begin : End Process[过程名称]; 说明: 1)中括号表示可以省略的,包括过程名称、感测信号; 2)“感测信号”代表这个信号有任何变化时,将促使这个过程所包含的顺序语句立刻执行一次; 3)在Architecture中,可存放多个Process,允许它们同时执行。
2、If-Else(判断比较) 语法格式1: If 条件 Then 顺序语句; Else 顺序语句; End If;