资源描述
VHDL与数字电路设计,主讲:崔 刚 北京工业大学电控学院电工电子中心 2005年9月1,目录,概述 第一章 VHDL的程序结构和软件操作 第二章 数据类型与数据对象的定义 第三章 并行赋值语句 第四章 顺序赋值语句 第五章 组合逻辑电路的设计 第六章 时序逻辑电路的设计 第七章 子程序、库和程序包 第八章 CPLD和FPGA的结构与工作原理 第九章 数字钟电路的设计,本节主要内容,传统数字电路设计方法 EDA设计方法 PLD器件 PLD器件设计流程 文本设计输入VHDL程序设计,数字电子技术的基本知识回顾,组合逻辑电路 编码器、译码器、数据选择器、加法器、数值比较器等 时序逻辑电路 同步时序逻辑电路 异步时序逻辑电路 寄存器、移位寄存器、计数器、序列信号发生器,一、传统设计方法,(1)首先确定可用的元器件; (2)根据这些器件进行逻辑设计,完成各模块; (3)将各模块进行连接,最后形成系统; (4)而后经调试、测量观察整个系统是否达到规定的性能指标。,传统的设计方法是基于中小规模集成电路器件进行设计(如74系列及其改进系列、CC4000系列、74HC系列等都属于通用型数字集成电路),而且是采用自底向上进行设计:,EDA(Electronics Design Automation)即电子设计自动化技术,是利用计算机工作平台,从事电子系统和电路设计的一项技术。 EDA技术为电子系统设计带来了这样的变化: (1)设计效率提高,设计周期缩短; (2)设计质量提高; (3)设计成本降低; (4)能更充分地发挥设计人员的创造性; (5)设计成果的重用性大大提高,省去了不必要的重复劳动。,二、EDA设计方法,自顶向下的设计方法,数字电路的EDA设计是基于PLD进行设计的,支持自顶向下的设计方法: (1)首先从系统设计入手,在顶层进行功能划分和结构设计; (2)然后再逐级设计底层的结构; (3)并在系统级采用仿真手段验证设计的正确性; (4)最后完成整个系统的设计,实现从设计、仿真、测试一体化。,传统设计方法 vs EDA设计方法,三、PLD器件 (一)出现的背景,如果能把所设计的数字系统做成一片大规模集成电路,则不仅能减小电路的体积、重量、功耗,而且会使电路的可靠性大为提高。 为某种专门用途而设计的集成电路叫做专用集成电路,即所谓的ASIC(Application Specific Integrated Circuit的缩写)。 在用量不大的情况下,设计和制造这样的专用集成电路成本很高,而且设计、制造的周期也较长。 可编程逻辑器件的研制成功为解决上述问题提供了比较理想的途径。,(二)PLD概述,PLD是可编程逻辑器件(Programmable Logic Device)的英文缩写。 可编程逻辑器件是一种数字集成电路的半成品,在其芯片上按一定排列方式集成了大量的逻辑门和触发器等基本逻辑元件。通过编程可以设置其逻辑功能。 PLD编程: 利用开发工具对PLD进行加工,即按设计要求将这些片内的元件连接起来,使之完成某个逻辑电路或系统的功能,成为一个专用集成电路(ASICApplication Specific Integrated Circuit)。,PLD开发系统,PLD开发系统包括硬件和软件两部分。 硬件部分:计算机、下载电缆或编程器; 软件部分:集成开发系统。 Altera公司:Maxplus 、 Quartus Xilinx公司:Foundation、 ISE Lattice公司:Synario System、ispEXPERT System,四、PLD设计流程,设计准备,设计输入,设计处理,器件编程,功能仿真,时序仿真,器件测试,PLD设计准备,在设计之前,首先要进行方案论证和器件选择等设计准备工作。 设计者首先要根据任务要求,判断系统的可行性。系统的可行性要受到逻辑要求合理性、成本、开发条件、器件供应等方面的约束。 若系统可行,则根据系统所完成的功能及复杂程度,对器件本身的资源和成本、工作速度及连线的可布性等方面进行权衡,选择合适的设计方案和合适的器件类型。,设计输入,将所设计的电路的逻辑功能按照开发系统要求的形式表达出来的过程称为设计输入。 通常,设计输入有如下三种方式: (1)原理图输入方式 适用于对系统及各部分电路很熟悉的场合。 (2)硬件描述语言输入方式 硬件描述语言是用文本方式描述设计,硬件描述语言有ABEL、AHDL、VHDL、Verilog等,其中VHDL和Verilog已成为IEEE标准。 (3)波形输入方式,设计处理,逻辑优化 把逻辑描述转变为最适合在器件中实现的形式,优化使设计所占用的资源最少。 逻辑综合 根据设计描述,对给定的硬件结构组件,最终获得门级电路甚至更底层的电路描述文件,即将多个模块化设计文件合并为一个网表文件。 适配 确定优化后的逻辑能否与器件中的宏单元和I/O单元适配。 分割 将大的设计分割为多个便于器件内部资源实现的逻辑小块的形式。,设计校验,设计校验过程包括功能仿真和时序仿真。 功能仿真 时序仿真,器件编程,器件编程就是将开发系统生成的目标文件下载到可编程逻辑器件中,来定义内部模块的逻辑功能以及它们的相互连接关系。 两种编程方式: 编程器 下载电缆,PLD开发系统,PLD开发系统包括硬件和软件两部分。 硬件部分:计算机、下载电缆或编程器; 软件部分:集成开发系统。 Altera公司:Maxplus 、 Quartus Xilinx公司:Foundation、 ISE Lattice公司:Synario System、ispEXPERT System,设计举例,设计内容: 十进制计数器电路设计。,PLD器件:ACEX1K系列的EP1K30QC208。 开发系统:MAX+plus系统。 编程方式:下载电缆。,实验下载板,14:34:11,设计过程,1、设计输入 VHDL 演示1 2、逻辑验证 演示2 3、设计处理 引脚设定 演示3 4、器件编程 连接下载电缆 演示4,三、PLD电路设计的特点,1、设计简单,方便; 2、电路系统可以集成在一片芯片上; 3、电路设计不依赖于器件进行设计; 4、电路系统很容易完善和升级。,器件选择:(1)电路系统所完成的功能及复杂程度; (2)器件本身的资源和成本、性能参数、 器件编程工艺等方面进行权衡。,VHDL是非常高速集成电路硬件描述语言 (Very High speed Integrated Circuit Hardware Description Language)的英文缩写。,五、文本设计输入VHDL程序设计,语法和风格: (1)类似与现代高级编程语言,如C语言。 (2)VHDL描述的是硬件,它包含许多硬件特有的结构。,VHDL设计 VS 电路图设计,VHDL与电路图设计电路的方式不同,和电路图设计方式相比: (1)易于修改; (2)设计能力更强; (3)VHDL语言很方便:独立于器件设计;相同的程序代码可以用于不同厂家生产的器件。,VHDL程序的基本结构,include “stdio.h”; include “math.h”; int main(void) int a,b,c; a=8; b=9; c=a+b; return c; ,Library std; Use std.standard.all; Entity and2 is Port( a,b : in bit; c : out bit); End and2; Architecture a1 of and2 is Begin c = a and b; End a1;,VHDL程序,C程序,VHDL程序的基本结构,(1)LIBRARY和PACHAGE声明区; (2)ENTITY定义区; (3)ARCHITECTURE定义区;,Library(库)是用于存放预先编译好的Package(程序包)。 Package (程序包)中定义了基本的常数,数据类型,元件及子程序等。 作用:声明在实体和结构体定义中将用到的 数据类型、元件或子程序等。 声明格式: Library 库名; Use 库名. PACKAGE名.All;,(1)LIBRARY和PACKAGE声明区,作用: ENTITY(实体)用于定义电路的外观,即I/O端口的类型和数量。 定义格式: Entity 实体名 is Port( a : in bit; b : in bit; c : out bit); End 实体名;,(2)ENTITY定义区,端口名,数据类型,端口模式,端口模式(MODE)有以下几种类型: IN ;OUT;INOUT ;BUFFER 端口模式可用下图说明:(黑框代表一个设计或模块) IN OUT BUFFER INOUT,(2)ENTITY定义区,(3)ARCHITECTURE定义区,实体的实现。即说明电路执行什么动作或实现功能。 定义格式: Architecture 结构体名 of 实体名 is 声明语句;(内部信号、变量、常数,元件,子程序声明) Begin 并行描述语句; End 结构体名;,二输入与门电路设计范例,电路真值表,二输入与门电路设计范例,Library std; Use std.standard.all; Entity and2 is Port( a : in bit; b : in bit; c : out bit); End and2; -实体定义结束。,双减号-为VHDL程序的注释符,类似C语言中的/注释符。,二输入与门电路设计范例,Architecture Na of and2 is Begin c =0 when a=0 and b = 0 else 0 when a=1 and b = 0 else 0 when a=0 and b = 1 else 1; 符号=为信号直接赋值符。 End Na; -结构体Na Architecture Nb of and2 is Begin c = a and b; -and 为逻辑与操作 End Nb; -结构体Nb,第一章 VHDL的程序结构和软件操作,1-1 VHDL程序的基本结构 1-2 Max+plus的操作,1-1 VHDL程序的基本结构,include “stdio.h”; include “math.h”; int main(void) int a,b,c; a=8; b=9; c=a+b; return c; ,Library std; Use std.standard.all; Entity and2 is Port( a,b : in bit; c : out bit); End and2; Architecture a1 of and2 is Begin c = a and b; End a1;,VHDL程序,C程序,1-1 VHDL程序的基本结构,(1)LIBRARY和PACHAGE声明区; (2)ENTITY定义区; (3)ARCHITECTURE定义区; (4)CONFIGURATION定义区。,Library(库)是用于存放预先编译好的Package(程序包)。 Package (程序包)中定义了基本的常数,数据类型,元件及子程序等。 作用:声明在实体和结构体定义中将用到的 数据类型、元件或子程序等。 声明格式: Library 库名; Use 库名. PACKAGE名.All;,(1)LIBRARY和PACKAGE声明区,作用: ENTITY(实体)用于定义电路的外观,即I/O端口的类型和数量。 定义格式: Entity 实体名 is Port( a : in bit; b : in bit; c : out bit); End 实体名;,(2)ENTITY定义区,端口名,数据类型,端口模式,(2)ENTITY定义区,标识符的定义原则: (1)标识符由字母、数字和下划线组成,a7_; (2)在标识符不区分大小写,ab和AB是一样的; (3)第一个字符必须是字母,即a666; (4)不允许有两个连续的下划线,a_b错误; (5)末尾不能是下划线,mname_错误; (6)标识符不能和关键字相同,如Entity,is等。,端口模式(MODE)有以下几种类型: IN ;OUT;INOUT ;BUFFER 端口模式可用下图说明:(黑框代表一个设计或模块) IN OUT BUFFER INOUT,(2)ENTITY定义区,(3)ARCHITECTURE定义区,定义了实体的实现。即电路的具体描述,说明电路执行什么动作或实现功能。 定义格式: Architecture 结构体名 of 实体名 is 声明语句;(内部信号、变量、常数,元件,子程序声明) Begin 并行描述语句; End 结构体名;,(4)CONFIGURATION定义区,一个完整VHDL电路设计必须有一个实体和对应的结构体,即实体和结构体对构成一个完整的VHDL设计。 一个实体可对应一个结构体或多个结构体,即一个实体可以有不同的描述方式。 作用:当实体有多个结构体时,系统默认实体选用最后一个结构体,利用CONFIGURATION语句可以任意选择采用哪一个结构体。,(4)CONFIGURATION定义区,定义格式: Configuration 配置名 of 实体名 is for 选用的结构体名 end for; end configuration 配置名 ;,二输入与门电路设计范例,电路真值表,二输入与门电路设计范例,Library std; Use std.standard.all; Entity and2 is Port( a : in bit; b : in bit; c : out bit); End and2; -实体定义结束。,双减号-为VHDL程序的注释符,类似C语言中的/注释符。,二输入与门电路设计范例,Architecture Na of and2 is Begin c =0 when a=0 and b = 0 else 0 when a=1 and b = 0 else 0 when a=0 and b = 1 else 1; 符号=为信号直接赋值符。 End Na; -结构体Na Architecture Nb of and2 is Begin c = a and b; -and 为逻辑与操作 End Nb; -结构体Nb,二输入与门电路设计范例,Configuration s1 of and2 is for na end for; end configuration s1; -结构体配置结束。,1-2 Max+plus系统的操作,Max+plus开发工具是美国Altera公司自行设计的一种软件工具,其全称为Multiple Array Matrix and Programmable Logic User System。 它具有原理图输入和文本输入(采用硬件描述语言)两种输入手段,利用该工具所配备的编辑、编译、仿真、时序分析、芯片编程等功能,将设计电路图或电路描述程序变成基本的逻辑单元写入到可编程的芯片中(如CPLD或FPGA芯片),作成ASIC芯片。它是EDA设计中不可缺少的一种工具。,下面我们介绍利用Max+plus 系统如何实现如下操作: (1)如何编写VHDL程序(使用Text Editor); (2)如何编译VHDL程序(使用Compiler); (3)如何仿真验证VHDL程序(使用Waveform Editor,Simulator); (4)如何进行芯片的时序分析(使用Timing Analyzer); (5)如何安排芯片脚位(使用Floorplan Editor); (6)如何下载程序至芯片(使用Programmer)。,1-2 Max+plus系统的操作,(1)如何编写VHDL程序,a. 打开文本编辑器;File/new/Text editor file b. 编写VHDL程序; c. 保存文件,文件名和定义的实体名必须相同,文件扩展名为VHD,文件存盘的目录不应是根目录或桌面,建议存放在Max2work或Maxplus2目录,或其子目录 。,(2)如何编译VHDL程序,a. 打开需要编译的文件; b.设置工程到目前打开的文件 ; File/Project/Set Project to Current File, c.打开编译器; 点击主菜单MAX+plus/Compiler选项。 d. 选定VHDL源文件的版本 ; Interfaces/VHDL Netlist Reader Settings e. 打开编译器进行编译。,(3)如何仿真验证VHDL程序,a. 打开波形编辑器(Waveform Editor ) ; b. 确定仿真持续时间(File/End Time); c. 将输入输出端口名选入波形编辑器; d. 编辑输入信号波形 ; e. 保存仿真波形文件 ; f. 打开仿真器MAX+plusSimulator进行仿真。在仿真结束后打开仿真波形文件(点击右下角的Open SCF按钮)即可以显示仿真结果。,(4)如何进行芯片的时序分析,a. 选择要下载的器件型号 ; 点击主菜单的Assign/Device项得到Device对话框。在Device Family框中选择芯片系列,在Devices选择框下选择具体的芯片名,最后点击OK按钮 。 b. 再编译一次; c. 打开时序分析器(Timing Analyzer ); d. 点击Start进行时序分析。,(5)如何安排芯片脚位,a.打开芯片脚位设置窗口;点击主菜单Assign/ Pin/Location/Chip,出现脚位设置对话框; ; b.将实体定义的端口名字和下载芯片的管脚进行具体对应;在Node Name框中输入我们定义的实体端口名字,然后在Pin列表选项框中输入下载芯片的管脚序号,再点击对话框右下角的Add按钮,将所有端口设置完成以后,点击Ok按钮,则实现实体端口和下载芯片的管脚的对应; c. 再编译一次,将生成可以下载的文件(And2.Sof)。,(6)如何下载程序至芯片,a. 将下载电缆与计算机并口相连,然后给芯片通电 ; b. 打开编程器Programmer ; Options/Hardware Setup,在Hardware Type选择ByteBlaster(MV)方式,则在Parallel Port处显示LPT1,单击OK钮返回Programmer窗口。 c.下载方式选择 ; d. 选择下载的芯片类型和要下载的文件(选择JTAG/Muti Devic JTAG Chain Setup)。 e. 点击Configure进行下载,将程序写入芯片中 。,第二章 数据类型与数据对象的定义,2-1 数据类型 2-2 数据对象的定义 2-3 信号运算符 2-4 信号属性,2-1 数据类型,在VHDL程序中,我们经常会遇到这样的语句: Signal A : std_logic; Variable B : std_logic_vector(7 downto 0); Constant C : integer;,数据对象类型,数据类型,数据对象名,2-1-1 逻辑数据类型,(1)布尔代数(Boolean)型 ; (2)位(Bit); (3)位数组类型(Bit_Vector),在std库的standard 程序包中进行定义。,type BIT_VECTOR is array (NATURAL range ) of BIT;,type BIT is (0, 1);,type BOOLEAN is (FALSE, TRUE) ;,(4)标准逻辑型(Std_Logic); Type STD_LOGIC is (U, -Uninialized;未初始化 X, -Forcing unknown;浮接不定 0, - Forcing 0;低电位 1, - Forcing 1;高电位 Z, - High Impedance;高阻抗 W, - Weak Unknown;弱浮接 L, - Weak 0;弱低电位 H, - Weak 1;弱高电位 -, - Dont care;不必理会 ); (5)标准逻辑数组类型(Std_Logic_vector);,在ieee库的std_logic_1164程序包中定义。,TYPE std_logic_vector IS ARRAY ( NATURAL RANGE ) OF std_logic;,2-1-2 数值数据类型,(1)整数(Integer); a. 正整数(POSITIVE) b. 自然数(NATURAL),在std库的standard 程序包中进行定义。,subtype POSITIVE is range 1 to INTEGERHigh;,Type INTEGER is range 2147483648 to 2147483647;,subtype NATURAL is range 0 to INTEGERHigh;,(2)实数(Real) (3)有符号数(Signed) 无符号数(Unsigned),在ieee库的std_logic_arith程序包中定义。,type REAL is range 1.7E38 to 1.7E38;,type UNSIGNED is array (NATURAL range ) of STD_LOGIC; type SIGNED is array (NATURAL range ) of STD_LOGIC;,SIGNED 的最高位为符号位,其余位为数值位,数值位为补码形式。如:符号数”1001”表示-7。,library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity data is port(a,b: in unsigned(3 downto 0); -a,b: in signed(3 downto 0); c: out std_logic); end data; architecture m1 of data is begin c=1 when ab else 0; end m1;,当定义成无符号类型时,若a=”1000”,b=0001, 即a=8,b=1则结果c=0; 当定义成有符号类型时,若a=”1000”,b=0001, 则a=-8,b=1,则结果c=1。,2-1-3 列举和数组数据类型,(1)列举数据类型(Enumerated Types) 定义格式: Type 列举名称 is (元素1,元素2,); (2)数组数据类型(Array Types) 定义格式: Type 数组名称 is Array(range ) of 数据类型;,2-1-4 数据类型的转换,在VHDL语言里,不同类型的数据信号之间不能互相赋值。当需要不同类型数据之间传递信息时,就需要类型转换函数将其中的一种类型数据转换为另一中数据类型后,再进行信号的传递。 例如:Signal Y : Std_logic_vector(7 downto 0); Signal X : Integer range 0 to 255; Y= CONV_STD_LOGIC_VECTOR(X,8); 转换函数有两个参数,被转换的对象和转换后的位数。,常用的数据类型转换函数,CONV_INTEGER 将数据类型 UNSIGNED, SIGNED转换为INTEGER 类型. CONV_UNSIGNED 将数据类型INTEGER, SIGNED转换为UNSIGNED 类型. CONV_SIGNED 将数据类型INTEGER, UNSIGNED转换为SIGNED类型. CONV_STD_LOGIC_VECTOR 将数据类型INTEGER, UNSIGNED, SIGNED, STD_LOGIC转换为STD_LOGIC_VECTOR 类型.,在库ieee的程序包 std_logic_arith中定义,2-2 数据对象的定义,常用的数据对象有三种: 常数(Constant) 信号(Signal) 变量(Variable),2-2-1 常数的定义,(1)将数据对象定义为常数,一方面希望该数据对象的值不会被改变;另一方面,为了提高程序的可读性。 (2)常数为全局量。 (3)常数在程序包说明、实体说明、结构体描述、过程说明、函数调用中使用。 (4)常数的定义格式: Constant 常数名:数据类型 :=常数值; 如:Constant D1: Integer := 3; 注意!常数定义的同时进行赋初值。,常数的应用示例,library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -必需定义+ entity exam1 is port (ip : in std_logic_vector(3 downto 0); op : out std_logic_vector(3 downto 0); end exam1; architecture m1 of exam1 is constant num : integer := 6; begin op = ip + num; end m1;,2-2-2 信号的定义,(1)“信号”数据对象,代表电路内部信号或连接线路,其在元件之间起互连作用。,注意!信号定义的时候尽管可以直接赋初值,但系统往往忽略。 建议信号对象定义后再进行赋值。,(2)信号为全局量。,(3)在实体说明、结构体描述和程序包说明中使用。,(4)信号的定义格式: Signal 信号名:数据类型 ;,(5)信号赋值的语法格式为:信号名 = 表达式; 如:Signal S1 : Std_logic_vector(3 Downto 0); S1 = “0000”;,2-2-3 变量的定义,(1)“变量”数据对象,它用于对中间数据的临时存储,并不一定代表电路的某一组件。,注意!变量定义的时候尽管可以直接赋初值,但系统往往忽略。 建议变量对象定义后再进行赋值。,(2)变量为局部量。,(3)仅限于进程(Process)或子程序中使用。,(4)变量的定义格式: Variable 变量名:数据类型 ;,(5)变量赋值的语法格式为:目标信号值:=表达式; 如:Variable S1 : Std_logic_vector(3 Downto 0); S1 := “0000”;,library ieee; use ieee.std_logic_1164.all; entity bcv is port (a,b,c : in std_logic; x,y : out std_logic); end bcv;,architecture m2 of bcv is begin process(a,b,c) variable d:std_logic; begin d:=a; x=c xor d; d:=b; y=c xor d; end process; end m2;,例一,结果:x=c xor b, y=c xor b,x=c xor a, y=c xor b,architecture m1 of bcv is signal d:std_logic; begin process(a,b,c) begin d=a; -ignored x=c xor d; d=b; y=c xor d; end process; end m1;,library ieee; use ieee.std_logic_1164.all; Entity cmp is port( cp,ip : in std_logic; -cp为时钟脉冲 op,oq: out std_logic); -ip为输入信号 end cmp; Architecture m1 of cmp is signal d:std_logic; begin process(cp) variable e:std_logic; begin if cpevent and cp=1 then d = ip; op = d; e := ip; oq = e ; end if; end process; end m1;,例二 D触发器,在进程中,信号赋值只有在过程结束时起作用,而变量赋值是立即进行的。,2-2-4 信号和变量的比较,(1)信号和变量的对应关系不同:信号代表电路内部信号或连接线路;而变量则不是。,(2)信号和变量声明的位置不同:信号声明在子程序、进程的外部;而变量声明在子程序、进程的内部。,(3)信号为全局量,而变量只在定义它的域中才可见。因此,变量不能在两个进程之间传递信息。,(4)在一个进程中多次为一个信号赋值时,只有最后一个值会起作用;而变量则不同,每次赋值都会改变它的值。,(5)赋值不同。在进程中,信号赋值只有在进程结束时起作用,而变量赋值是立即进行的。而且赋值符号不同:信号赋值为“=”,变量赋值为“:=”。,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all;,一位BCD码的加法器,Entity bcdadder is Port( a,b : in std_logic_vector(3 downto 0); result : out std_logic_vector(4 downto 0); End bcdadder;,Architecture Na of bcdadder is constant adjnum : integer:=6; -常数定义 signal binadd : std_logic_vector(4 downto 0); -信号 Begin binadd9 then tmp:=adjnum; else tmp:=0; end if; result= binadd+tmp; end process; End Na;,2-3 信号运算符,VHDL提供了四种类型运算符号: 逻辑运算符 关系运算符 算术运算符 连接运算符,VHDL运算符逻辑运算符,and 逻辑与or逻辑或nand与非nor 或非xor 异或xnor同或not 逻辑非,上述逻辑运算在库ieee的程序包std_logic_1164中定义。,VHDL运算符关系运算符,=等于/=不等于大于=大于或等于 注:其中=操作符也用于表示信号的赋值操作。 上述运算在库ieee的程序包std_logic_arith中定义。,VHDL运算符算术运算符,+加-减*乘/除*乘方mod求模 rem求余 abs求绝对值 在库ieee的程序包std_logic_arith中定义。,VHDL运算符连接运算符, Signal B : std_logic_vector(0 to 3); 则这两个信号的属性值分别为: Aleft=7; Aright=0; Alow=0; Ahigh=7; Alength=8; Bleft=0; Bright=3; Blow=0; Bhigh=3; Blength=4;,left表示数组的左边界; right表示数组的右边界; low表示数组的下边界; high表示数组的上边界; length表示数组的长度。,(2)event属性: event属性,它的值为布尔型,如果刚好有事件发生在该属性所附着的信号上(即信号有变化),则其取值为Ture,否则为False。 利用此属性可决定时钟信号的变化情况,即时钟是否发生。,2-4 数据对象属性,(2)Event属性: 例如:时钟边沿表示 signal clk : in std_logic;则clkevent and clk=1表示时钟的上升沿。即时钟变化了,且其值为1。 clkevent and clk=0表示时钟的下降沿。即时钟变化了,且其值为0。 此外,还可利用两个函数来表示时钟的边沿。rising_edge(clk) 表示时钟的上升沿falling_edge(clk) 表示时钟的下降沿 这两个函数分别在库ieee的程序包Std_logic_1164中定义。,2-4 数据对象属性,并行语句一般处于进程(PROCESS)的外部。所有并行语句都是并行执行的,即与它们出现的先后次序无关。 并行语句有三个特点: a. 所有语句的执行是并行的; b. 每条语句的执行和其所在的位置无关; c. 并行语句的输出仅仅依赖于输入,没有其它的限制条件。,第三章 并行赋值语句,第三章 并行赋值语句,(1)直接赋值语句:= 赋值运算符 (2)条件式信号设置语句:When-Else (3)选择式信号设置语句:With-Select-When (4) Process(进程)语句 (5) Block(块)语句 (6) 函数调用语句(后面章节讲) (7) Component(元件)例化语句 (8)For-Generate语句 Generic的使用,(1)直接赋值语句:=,直接赋值语句的格式:Signal_name0); 结果信号A的每一位的值都为0。 B0); 信号对象的位数很多时,采用others来赋值很方便。,=示例,library ieee; use ieee.std_logic_1164.all; Entity test1 Is Port ( a, b : in std_logic; c, d : out std_logic); end test1; architecture test1_body of test1 is begin 同时执行 d = a or b; c = a and b; end test1_body;,输出仅仅依赖于输入, 没有其它的限制条件。,每条语句的执行和 其所在的位置无关。,(2) When-Else条件式信号设置语句,它的语法格式为: label: Signal_name= expression1 When logic_expression1 Else expression2 When logic_expression2 Else expressionn; 例如:f=1 when x1=x2 else 0;,When-Else语句示例,Library ieee; Use ieee.std_logic_1164.all; Entity xor2 is Port(x,y : in std_logic; z : out std_logic); End xor2; Architecture a of xor2 is Begin z= 1 when(x= 0 and y= 1 ) else 1 when(x= 1 and y= 0 ) else 0; End a;,(3) With-Select-When选择式信号设置语句,label: With expression Select Signal_name=expression When constant_value , expression When constant_value ;,With-Select-When示例,Library ieee; Use ieee.std_logic_1164.all; Entity xor2 is Port(x,y : in std_logic; z : out std_logic); End xor2; Architecture a of xor2 is signal tmp : std_logic_vector(1 downto 0); Begin tmp=x,When-else和With-select-When语句的区别,(1)With-select-When语句中When后的constant_value必须是互不相同的; (2)而When-else语句中When后的logic_expression则不需要这样的严格条件; (3)When-else语句中When后的logic_expression的优先权次序为由先到后排列。,优先编码器示例,Library ieee; Use ieee.std_logic_1164.all; Entity priority is Port(r1,r2,r3 : in std_logic; f : out std_logic_vector(1 downto 0); End priority; Architecture a of priority is Begin f= 01 when(r1= 1 ) else 10 when(r2= 1 ) else 11 when(r3= 1 ) else 00; End a;,If r1=1,f=”01”; If r2=1 and r1/=1,f=”10”; If r3=1 and r1/=1 and r2/=1, f=”11”; 如果三个输入都为0,f=”00”。,(4) Process语句,(1)一个结构体当中可以有多个Process 语句,Process 语句是同时执行的并行语句。 (2)Process内的语句却是顺序执行的顺序语句。 (3)多进程之间的信息通过信号对象来传递。 Process 语句的格式为: Process label: Process(Sensitivity list) Variable declarations Begin 顺序语句; End Process Process label;,(4) Process语句,敏感表(Sensitivity list)包括进程的一些信号,当敏感表中的某个信号变化时进程才被激活,进程内的顺序语句被执行。 当进程结束时,进程内的输出信号值被更新,进程进入等待(睡眠)状态,直到敏感表中的某一信号发生变化,进程被再次激活。 对于上述电路,我们同样可以采用Process语句来进行描述。,Process语句示例,architecture m2 of exam1 is Signal tmp: std_logic; begin process begin tmp=a and b; end process; d=tmp; process begin e= tmp or c ; end process; end m2;,(5) Block(块)语句,当我们设计一个比较复杂的电路时,为了使设计简单化,可以将其分为几个部分分别进行设计,每个部分设计完成后,再将其组合成我们需要的电路。这种方法称为模块化设计方法。这样,使得整个设计工作更加容易实现,同时程序代码的维护性、纠错性都能得到提高。 采用模块化设计时,当设计一个模块时,我们就要用到Block语句。,语法格式: Block Label : Block 数据对象定义部分 Begin End Block;,(5) Block(块)语句,library ieee; use ieee.std_logic_1164.all; entity exam1 is port (a,b,c : in std_logic; d,e : out std_logic); end exam1; architecture m1 of exam1 is begin Block_1: Block Begin d=a and b; end block; Block_2: Block Begin e=(a and b) or c ; end block; end m1;,Block语句示例,Component(元件)例化语句,(1)Block语句可以使VHDL程序更加模块化、功能化。但这样的做法要求在同一程序中,若是重复使用时,必须重写一次。 Block语句解决了这样的重复编写问题。 (2)元件也是完整的VHDL设计,作为底层设计,通过元件声明,使之可在其他模块中被调用。 (3)元件声明可放在程序包中,也可在某个设计的结构体中声明。,语法格式: Component 元件名 Port (端口定义) ; -同元件实现时的实体的port部分 End Component; 元件例化指元件的调用,它的语法格式为: Label : 元件名 Port Map(端口映射);,Component(元件)例化语句,元件例化时端口映射或关联有两种方式: a.位置对应方式 直接由输入信号和元件信号的对应位置进行映射。即: 元件标号:元件名 Port Map(信号A1, 信号B1,); b.名字直接对应 我们使用=映射符号进行输入信号和元件信号之间的映射,那么位置可以不对应。即: 元件标号:元件名 Port Map(元件信号A=信号A1,元件信号B=信号B1,); 注意!元件标号是必需的。,Component例化语句,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Entity fulladder is Port(Ci : in std_logic; a,b : in std_logic; s : out std_logic; Co : out std_logic); End fulladder; Architecture m1 of fulladder is Signal tmp: std_logic_vector(1 downto 0); Begin tmp=(0 ,一位全加器,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Entity adder is Port(Cin : in std_logic; x,y : in std_logic_vector(3 downto 0); sum : out std_logic_vector(3 downto 0); Cout : out std_logic); End adder;,四位加法器,Architecture a of adder is Signal c: std_logic_vector(0 to 4); Component fulladder Port(ci,a,b : in std_logic; s,co : out std_logic); end component; Begin c(0)c(0),a=x(0),b=y(0), s=sum(0),co=c(1); U2: fulladder Port map(c(1),x(1),y(1),sum(1),c(2); U3: fulladder Port map(c(2),x(2),y(2),sum(2),c(3); U4: fulladder Port map(c(3),x(3),y(3),sum(3),c(4); Cout=c(4); End a;,Component例化示例,For-Generate语句,For-Generate语句用于生成一组信号赋值或元件例化语句。 语法格式: generate_label: -必须的 for index_variable In range generate statement; statement; end generate;,则上面的四位加法器可以这样来实现: 其它相同,上面四条赋值语句可以这样来代替: Generate_label: For i In 0 to 3 Generate Bitadder: fulladder Port map(c(i),x(i),y(i),sum(i),c(i+1); End generate;,For-Generate语句,Generic语句,通过引入一个参数n使得我们设计的加法器更加具有通用性,参数n代表加法器中相加的位数,在VHDL中,这样的参数称为Generic(类属)。 通常定义在实体描述和元件声明中。 定义格式: Generic(参数名 : 数据类型 := 表达式 ); 例如:Generic( m : integer:=7);,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Entity adder is Generic(n:integer:=4); Port(Cin : in std_logic; x,y : in std_logic_vector(n-1 downto 0); sum : out std_logic_vector(n-1 downto 0); Cout : out std_logic); End adder;,Generic语句示例N位全加器,Architecture a of adder is Signal c: std_logic_vector(0 to n); Component fulladder Port(ci,a,b : in std_logic; s,co : out std_logic); End component; Begin c(0)=cin; Generate_label: For i In 0 to n-1 Generate Bitadder: fulladder Port map(c(i),x(i),y(i),sum(i),c(i+1); End generate; Cout=c(n); End a;,Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_unsigned.all; Entity nadder is Port(Cin1 : in std_logic; x1,y1 : in std_logic_vector(7 downto 0); Sum1 : out std_logic_vector(7 downto 0); Cout1 : out std_logic); End nadder;,带Generic的元件例化N位全加器,Architecture a of nadder is Component adder Generic(n:integer); -也可在此进行影射Generic(n:integer:=8); Port(cin : in std_logic; x,y : in std_logic_vector(n-1 downto 0); sum : out std_logic_vector(n-1 downto 0); cout: out std_logic); end component; Begin Nadder: adder Generic map(n=8) Port map(cin1,x1,
展开阅读全文