XilinxFPGA设计基础VHDL版.docx
- 文档编号:26968744
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:17
- 大小:59.96KB
XilinxFPGA设计基础VHDL版.docx
《XilinxFPGA设计基础VHDL版.docx》由会员分享,可在线阅读,更多相关《XilinxFPGA设计基础VHDL版.docx(17页珍藏版)》请在冰豆网上搜索。
XilinxFPGA设计基础VHDL版
第一章开发软件ISE与开发流程
LUT主要适合SRAM工艺生产,因此FPGA都是基于SRAM工艺的,掉电就会丢失。
1.1设计输入
除了常见的文本输入,还可以采用图形输入方式:
单击DesignUtilities->CreatSchematicSymbol,则会在工程文件夹下生成一个MY_AND2.sym文件,同时这个生成的符号被加入到符号库中。
这样可以添加元件。
⏹用户约束文件UCF的编写:
管脚约束:
如NET“
时钟约束:
如NET“
⏹采用图形化方法输入约束文件:
创建ucf文件,选择ucf文件,然后点击Processes->UserConstrains->CreateTimingConstraints添加时序约束;点击Processes->UserConstrains->I/OPinPlanning添加管脚约束。
1.2设计综合(Synthesize)
综合将概念性硬件描述语言HDL的设计定义转换成针对目标器件的逻辑或者物理表示。
XST(XilinxSynthesisTools)就是综合工具,其输出为Xilinx特有的NGC网表文件,NGC包含转化后的逻辑数据和约束信息。
综合是设计流程中的基本步骤,它将概念性硬件描述语言的设计定义转换为针对器件的逻辑或物理表示。
在综合过程中,状态机是单独处理、独立分析的,根据综合的选项,综合器选择状态机在综合过程中选用的实现算法。
综合完成后,综合器会根据综合选项和XCF(XSTConstraintFile,综合约束文件),对综合结果做一些基础的优化。
1.3功能仿真(Simulation->behavioral)
功能仿真可以对工程设计文件进行初步的功能验证。
仿真软件将HDL语言转换为抽象的逻辑电路,忽略信号在逻辑器件和传输线上的延时,并对应各种可能的输入信号仿真得到设计工程的输出信号,检验输出信号是否满足预期的要求。
功能仿真需要创建TestBench文件。
1.4工程实现(Implementation)
工程实现包含以下四个步骤:
⏹Translate—将综合后的网表文件NGC和约束文件UCF融合到同一个Xilinx的设计文件PCF中。
⏹Map—将设计中的功能器件映射到工程设计的目标器件资源中。
⏹PlaceandRoute—对映射后的目标器件资源进行布局和布线,满足时序约束。
⏹GenerateProgrammingFile—生成可以下载到器件中的比特流文件,对器件进行编程配置。
1.5时序仿真(Simulation->PostRoute)
对经过布局布线后的仿真模型加入延时文件进行仿真的过程,他将最基本的门级延时计算在,模拟工程设计在FPGA器件的实现过程。
经过时序仿真后的设计基本上与实际电路是一致的。
时序仿真的基本参数:
⏹时钟周期Period:
最小时钟周期是指信号从一个触发器或锁存器的输入端,经过一系列的组合逻辑单元和信号线,到达下一个同步器件,所用的最长时间。
⏹端口到建立时间(Padtosetuptime):
信号从进入fpga芯片,经过一系列的逻辑元件和连线,到达一个同步器件(触发器、锁存器或存储器)的输入端所用的最长时间。
⏹时钟到端口时间(Clocktopadtime):
数据信号从触发器或锁存器的输入端口,经过逻辑单元和连线时延,到达fpga芯片的输出管脚的最长时间。
这个时间在约束文件中称为OFFSETOUTAFTER约束。
⏹端口到端口时间(Padtopadtime):
数据信号从输入端口进入fpga芯片,经过一系列逻辑元件和连线延时后到达fpga的输出端口的最大时间。
1.6器件配置
利用iMPACT工具将比特流文件编程到fpga中。
第二章VHDL硬件描述语言
2.1基础知识
fpga电路设计的四个层次:
行为层次(Behavioral)、寄存器传输层次(RTL,RegisterTransferLevel)、逻辑门层次(Logic)和布图层次(Layout)。
行为层次主要关注模块的功能描述和仿真验证,寄存器传输层次要关注模块的可综合电路的实现,逻辑门层次考虑如何用门级电路实现给定功能,布图层次考虑如何将电路适配到fpga的资源中。
2.2VHDL基本结构
2.2.1实体与构造体
实体与C++中的类相似。
构造体的行为描述通常采用process进程语句实现。
构造体的数据流描述方式主要使用VHDL语言中的标准布尔函数,将信号之间的布尔代数关系用布尔方程式来表示。
结构体的结构描述主要通过下层模块的声明和调用及端口映射将下层模块相连。
⏹Generic参数声明类似于C++语言中的类属参数声明。
libraryIEEE;
useIEEE.STD_LOGIC_1164.all;
entityCOUNTERis
generic(COUNT_WIDTH:
INTEGER:
=7);
port(RST,SET,CLR:
inSTD_LOGIC;
SETVALUE:
inSTD_LOGIC_VECTOR(COUNT_WIDTHdownto0);
COUNTOUT:
outSTD_LOGIC_VECTOR(COUNT_WIDTHdownto0)
);
endCOUNTER;
2.2.2库
用户自定义库时,先用关键字library说明要引用的库名,然后用use语句打开库中程序包。
在计算机中新建一个文件夹,将文件夹名改为用户自定义“库名”,将编辑的程序包等以文件形式存在该文件下,此时该文件夹即为用户自定义库。
在ise中自定义library时,首先要新建library,然后编写相应的程序包,并将程序包移到(movetolibrary)该library中,然后就可以使用use<库名>之类的语句了。
2.2.3程序包
程序包的作用是收集被多个VHDL实体共享的数据类型、子程序或数据对象,使其适用于更一般的访问和调用围。
2.2.4配置
一个实体可以声明多个构造体,但形成最终电路时,只能使用一种结构体作为功能实现的描述,这时就需要使用配置将实体与结构体连接起来。
配置不是从属单元,可以独立存在。
通常在使用时都会将配置单独写入一个文件中。
1、默认配置语法如下。
当实体选择的结构体中,不包含BLOCK语句和COMPONENT语句时,可采用默认配置为实体选择不同的结构体和对VHDL程序的性能评估。
configuration配置名称of实体名称is
for结构体名称
use
配置项;
endfor
end配置名称;
2、元件配置。
在层次化设计中,应用库中的元件是设计人员经常采用的一种效率比较高的工作方式。
引用元件的方法有两种:
使用元件例化语句;使用元件配置。
元件配置语句的语法结构有两种形式,分别是低层次的配置和实体—结构体对的配置。
低层次的配置语法为:
configuration配置名of实体名is
for选择的结构体名
for例化标号:
元件名useconfiguration库名.元件配置名;
endfor;
...
endfor;
end配置名;
实体—结构体对的配置的语法结构如下:
configuration配置名of实体名is
for选择的结构体名
for例化标号:
元件名useentity库名.实体(结构体);
endfor;
...
endfor;
end配置名;
显然,实体—结构体对比低层次的配置要好。
3、结构体配置。
虽然元件配置语句配置实体具有一定的优势,这种方法易写也易懂;但是书写过于臃肿,于是引出了第三种配置语句—结构体配置语句。
结构体配置语句必须放在所要配置的实体中的结构体中。
其语法如下:
for<元件例化标号>:
<元件名>useentity<库名>:
<实体名(结构体名)>;
【举例】采用结构体配置实现全加器
libraryieee;
useieee.std_logic_1164.all;
entityconfig_exampleis
port(A,B,Cin:
instd_logic;
Co,S:
outstd_logic);
endconfig_example;
architecturestructureofconfig_exampleis
componentadd
port(a:
instd_logic;
b:
instd_logic;
y:
outstd_logic);
endcomponent;
signaltmp1,tmp2,tmp3:
std_logic;
forU1,U2:
adduseentitywork.add(xor_str);
forU3,U4:
adduseentitywork.add(and_str);
forU5:
adduseentitywork.add(or_str);
begin
U1:
addportmap(A,B,tmp1);
U2:
addportmap(tmp1,Cin,S);
U3:
addportmap(tmp1,Cin,tmp2);
U4:
addportmap(A,B,tmp3);
U5:
addportmap(tmp2,tmp3,Co);
endstructure;
2.3语法要素
2.3.1对象类型Port、Constant、Signal、Variable
变量在综合后可以是一个连线(wire),也可以是一个寄存器(register),综合的结果取决于变量在时序电路中是否用于保存信号值。
变量虽然可以赋初始值,但是在综合时,综合器会忽略掉。
信号在声明结构中被赋予的初始值,与变量相同,在综合时也会被忽略。
信号的赋值可以加入延时,如A<=Bafter5ns;但是,延时语句只在行为建模时起作用,而在综合时也会被完全忽略。
2.3.2数据类型
⏹标量类型
1、bit类型是二值系统中的最基本单元,分别表示低电平和高电平。
2、Boolean类型没有数值的含义,也不能进行算术运算,只能作为关系运算的结果,在判断语句中判断使用。
3、Integer类型的数据在底层电路中用一系列二进制位表示。
使用时要指定range围,这样综合器才能综合。
4、real类型的数据很多公司的综合工具不支持。
5、物理类型用于表示一些物理量,完整的物理数据类型包含数值和单位两部分。
定义物理类型时必须先给出一个基准单位。
如VHDL只定义了一个物理类型:
typeTIMEisrange-2147483647to2147483647
units
fs;
ps=1000fs;
ns=1000ps;
us=1000ns;
ms=1000us;
sec=1000ms;
min=60sec;
hr=60min;
endunits
6、符号类型character通常用单引号括起来,如’Z’。
7、标准逻辑类型STD_LOGIC与bit类型相似,也是表示单个数字信号逻辑的,每个STD_LOGIC都有9种不同的状态。
8、枚举类型enumerate在状态机和复杂系统的描述中尤其有用。
9、错误等级severity_level共有四种状态可用:
note、warning、error、failure。
错误等级通常与assert语句配合使用。
⏹复合类型
1、位矢量类型BIT_VECTOR是由多个位型数据组合起来的一组数据。
例子如下:
signalA_WORD:
bit_vector(7downto0);
A_WORD<=X"0101_1100";
2、标准逻辑矢量型STD_LOGIC_VECTOR是由多个标准逻辑数据组合起来的。
3、字符串类型是由多个字符类型的数据组合起来的。
4、数组array是由多个相同类型的数据组成的集合。
VHDL中有两种定义矩阵的方法,一种称为Constrained,另一种称为Unconstrained,两者之间的不同在于定义数组时索引值的围不同。
Constrained在数组定义时就已经确定了索引值的取值围,例如:
typeWORDisARRAY(3downto0)ofSTD_LOGIC;
Unconstrained类型在定义数组时不给定具体的取值围,而是在用数组类型定义一个对象时才给定索引围,例如:
typeBIT_VECTORisARRAY(NATURALrange<>)ofBIT;
typeSTD_LOGIC_VECTORisARRAY(NATURALrange<>)ofSTD_LOGIC;
typeSTRINGisARRAY(POSITIVErange<>)ofCHARACTER;
在工程中,大型的数组一般用变量或常量定义,用信号定义时,会影响仿真速度。
在VHDL做工程仿真时,经常会用ARRAY类型对存储器进行建模。
多维数组没有对应的底层硬件逻辑,因此多用于仿真和建模。
数组的赋值方法为:
signalH_BYTE:
STD_LOGIC_VECTOR(0to7);
H_BYTE<=(7|6|0|1=>'1',2to5=>'0');
5、记录型RECORD
并不是所有综合器都支持记录类型,组成集合的数据至少要有两种以上不同的类型。
2.3.3文件类型(File)
目前常用的文件类型只有TEXT类型,IEEE的TEXTIO包集合中包含了TEXT文件常用的一些读写函数,方便设计者在开发时调用。
综合器不支持,只能用于仿真。
(1).首先需要声明TextIO的包集
useieee.std_logic_textio.all;
usestd.textio.all;
(2).声明输入、输出文件
filestim_a:
textopenread_modeis"stimu1.txt";
fileresp_out:
textopenwrite_modeis"resp_out.txt";
(3).声明读写文件的行变量
variableline_in:
line;
variableline_out:
line;
(4).声明用于保存行变量中值的数据变量
variablea_tmp:
integer;
variablersp_tmp:
integer;
(5).最后进行文件的读写。
读文件时,先从文件中按行读出一行数据,再将行中的数据读到数据变量中。
写文件时,先将数据变量组合成一行,再将行变量中的数据写入文件。
需要注意的是只有variable型才是文件存取类型,不能使用signal型。
TextIO包集中定义了一些常用的文件操作过程:
readline(file_var,line_var);--用于从文件file_var中读取一行数据到line_var
read(line_var,data_var);--用于从line_var中读取数据保存到data_var中
writeline(file_var,line_var);--用于将line_var写入到file_var中
write(line_var,data_var);--用于将data_var写入到line_var中
endfile(file_var);--判断file_var是否已经到文件末尾
2.3.4属性
属性是指实体、结构体、类型及信号的一些表现特征。
大部分信号类属性仅用于仿真,只有两个信号类属性(EVENT和STABLE)是可以综合的。
2.4运算符
类型
符号
支持的数据对象类型
逻辑运算符
AND,OR,NAND,NOR,XOR,XNOR,NOT
BIT,BOOLEAN,STD_LOGIC
关系运算符
=,/=
任何数据类型
<,>,<=,>=
枚举和整数类型以及对应的一维数组
算术运算符
+,-,**,ABS
整数类型
*,/,MOD,REM
整数类型,操作数必须是2的乘方
移位运算符
SLL,SRL,SLA,SRA,ROL,ROR
BIT型一维数组或布尔型一维数组
并置运算符
&,(,,,)
BIT或一维数组
符号运算符
正负:
+,-
整数类型
⏹关系运算符返回值一定是BOOLEAN类型。
关系运算的比较按以下方式进行:
从最左边按位比较,直到发现不相等的元素(位),长数组大于短数组。
如:
"1011">"10101";
"101"<"1010";
⏹IEEE中只定义了SIGNED和UNSIGNED类型的移位运算,其他类型可以换一种写法实现:
Asll2描述为A<=A(5downto0)&"00";
⏹算术运算符中真正能够综合的只有“+”、“-”、和“*”,对于“/”、“mod”、“rem”,在分母为2的乘方次常数时,可以将这些操作用位运算实现,因此是可以综合的。
2.5VHDL的结构体描述方式
⏹行为描述方式是从功能或算法方面对结构体进行描述,不需要包含任何结构信息。
其抽象程度高,主要采用函数、过程、进程语句的形式来表示。
⏹数据流方式源于传统的布尔表达式设计思想,通过逻辑或算术表达式对信号或变量赋值,表示信号在电路中的流动方向。
数据流描述主要建立在并行信号赋值语句基础上。
这种方式对硬件水平要求高,易于综合,但不利于描述复杂逻辑事件。
⏹结构化方式类似于文本方式的原理图设计。
Fpga相对于CPU模式的信号处理,最大的优势在于它能够并行地处理信号,而并发描述语句是实现并行信号处理的主要底层描述方法。
如果信号在多个进程中被赋值,这些驱动器的结果将会被连接在一起,形成多驱动的情况,应避免出现此情况。
Rtl级的VHDL也就是我们常说的可综合的那部分,所谓的rtl级建模,其实也就是用VHDL语言去描述实时电路的行为。
在该层次上,最重要的思想就是“硬件意识”。
2.6VHDL典型语句
2.6.1赋值语句中的延时
在VHDL中存在惯性延时和传输延时两种类型。
惯性延时的特性与信号脉冲持续时间有关,当信号持续时间小于惯性延时,输出信号将忽略该脉冲的存在。
传输延时不是默认的,必须用关键词TRANSPORT明确说明。
传输延时常用于描述总线延时、连接线的延时及ASIC芯片中的路径延时。
不管哪种延时,都是电路固有的特性,与电路的材料、生产工艺、制作温度等相关。
带入语句中的延时子句只能根据这些条件去模拟电路的延迟特性,而不能根据语句中的延时时间参数去综合生成具有指定延迟时间的电路。
换言之,延迟子句是不可综合的,综合器会忽略掉该延时。
如a<=notb,a<=notbafter2ns,a<=transportnotbafter2ns这三条语句最后生成的电路完全一样。
2.6.2顺序语句
1、使用不带else子句的if语句时,电路可能会引入锁存器。
2、Case语句没有优先级,其when后面的选择值可以选择并列数值,如3|5。
3、For…loop循环语句中,循环变量在使用前不需要声明。
循环可以采用递增模式、递减模式以及循环次数围三种方式。
如:
for循环变量inx'RANGEloop
顺序语句;
endloop;
4、Wait语句的综合:
waiton、waitfor和wait语句是不可综合的。
Waituntil语句只有在条件表达式为时钟的边缘时,如waituntilCLOCK=‘1’时,是可综合的,否则也不可综合。
由于在使用waituntil语句时,process没有敏感信号列表,所以它必须是process的第一条语句。
ISE中的XST,不支持任何wait语句的综合。
5、空操作NULL语句类似于计算机汇编语句中的NOP指令,执行该语句不进行任何操作,只是使程序执行下一个操作。
6、变量的综合:
根据变量在程序中的使用情况的不同,变量综合后的结果可能是连线(wire)、锁存器(Latch)或寄存器(Register)。
在时序电路的顺序描述语句中,如果变量在被赋值之前被读取,那么综合后将产生一个寄存器;如果这种情况发生在组合逻辑电路中,那么综合后将会产生一个锁存器。
7、断言语句(ASSERT):
VHDL的断言语句类似于C语言中的断言语句,它是人机对话的一种重要手段。
语法结构为:
assert条件表达式[report字符串信息][severity级别];
assert语句不描述任何硬件逻辑,通常综合器都会将其忽略,或给出一个警告,但它在系统调试时很有用,可以帮助设计者很快找到设计中出现的问题。
2.6.3并发语句
1、进程语句
一个进程语句只允许描述对应于一个时钟信号的同步时序逻辑。
一个进程中只能描述针对于同一时钟的同步时序逻辑,而异步时序逻辑必须由多个进程来表达。
同步电路可由结构体中的多个进程描述,这是因为进程之间的通信可以通过传递信号和共享变量值来实现。
除非使用决断函数,否则在多个进程中,不允许对同一个信号赋值,但在同一个进程中可以对一个信号多次赋值。
进程部是顺序语句,但进程语句本身是并行语句。
2、并行信号赋值语句
每一个信号赋值语句都相当于一条缩写的进程语句,而这条语句的所有输入信号都被隐性地列入此过程的敏感信号表中。
条件式信号代入语句是有优先级的,即使有多个条件为真,也只有第一个满足条件的表达式会被执行。
条件信号赋值语句虽然可以写的很长,实际上是一条语句。
目标信号<=表达式1when条件1else
表达式2when条件2else
表达式n;
选择式信号代入语句,多路信号之间是并行的,没有优先级别。
with选择表达式select
目标信号<=表达式1when选择条件1,
表达式2when选择条件2,
表达式nwhen选择条件n;
3、元件说明和元件例化语句
元件说明语句的功能是将一个现成的设计实体定义或声明为一个元件;元件例化语句,它的功能是将调用的元件或模块的端口信号与结构体中的相应端口信号进行正确的连接,从而达到引用元件的目的。
其中标号名(也称为例化名)相当于电路板中的一个插座名。
4、生成语句
生成语句的典型应用是生成存储器阵列和寄存器阵列。
从软件运行结果来看,for…generate语句的循环变量虽然有顺序性,但最终结果是完全并行的。
5、块语句
块语句主要用于参数定义和信号的映射,包括Generic和GenericMap语句以及Port和PortMap语句。
使用VHDL进行建模时,一般设计者很少使用块语句,尤其是卫式表达式语句,而且很多商用的综合器不支持块语句。
通常情况下,选用进程语句更加高效。
从
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- XilinxFPGA 设计 基础 VHDL
![提示](https://static.bdocx.com/images/bang_tan.gif)