第4节 约束文件的编写
4.4.1 约束文件的基本操作
1.约束文件的概念
FPGA设计中的约束文件有3类:用户设计文件(.UCF文件)、网表约束文件(.NCF文件)以及物理约束文件(.PCF文件),可以完成时序约束、管脚约束以及区域约束。3类约束文件的关系为:用户在设计输入阶段编写UCF文件,然后UCF文件和设计综合后生成NCF文件,最后再经过实现后生成PCF文件。本节主要介绍UCF文件的使用方法。
UCF文件是ASC 2码文件,描述了逻辑设计的约束,可以用文本编辑器和Xilinx约束文件编辑器进行编辑。NCF约束文件的语法和UCF文件相同,二者的区别在于:UCF文件由用户输入,NCF文件由综合工具自动生成,当二者发生冲突时,以UCF文件为准,这是因为UCF的优先级最高。PCF文件可以分为两个部分:一部分是映射产生的物理约束,另一部分是用户输入的约束,同样用户约束输入的优先级最高。一般情况下,用户约束都应在UCF文件中完成,不建议直接修改NCF文件和PCF文件。
2.创建约束文件
约束文件的后缀是.ucf,所以一般也被称为UCF文件。创建约束文件有两种方法,一种是通过新建方式,另一种则是利用过程管理器来完成。
第一种方法:新建一个源文件,在代码类型中选取“Implementation Constrains File”,在“File Name”中输入“one2two_ucf”。单击“Next”按键进入模块选择对
话框,选择模块“one2two”,然后单击“Next”进入下一页,再单击“Finish”按键完成约束文件的创建。
第二种方法:在工程管理区中,将“Source for”设置为“Synthesis/Implementation”。“Constrains Editor”是一个专用的约束文件编辑器,双击过程管理区中“User Constrains”下的“Create Timing Constrains”就可以打开“Constrains Editor”,其界面如图4-73所示:
图4-73启动Constrains Editor引脚约束编辑
在“Ports”选项卡中可以看到,所有的端口都已经罗列出来了,如果要修改端口和FPGA管脚的对应关系,只需要在每个端口的“Location”列中填入管脚的编号即可。例如在UCF文件中描述管脚分配的语法为:
NET “端口名称” LOC = 引脚编号;
需要注意的是,UCF文件是大小敏感的,端口名称必须和源代码中的名字一致,且端口名字不能和关键字一样。但是关键字NET是不区分大小写的。
3.编辑约束文件
在工程管理区中,将“Source for”设置为“Synthesis/Implementation”,然后双击过程管理区中“User Constrains”下的“Edit Constraints (Text)”就可以打开约束文件编辑器,如图4-73所示,就会新建当前工程的约束文件。
图4-73 用户约束管理窗口
4.4.2 UCF文件的语法说明
1.语法
UCF文件的语法为:
{NET|INST|PIN} \"signal_name\" Attribute;
其中,“signal_name”是指所约束对象的名字,包含了对象所在层次的描述;“Attribute”为约束的具体描述;语句必须以分号“;”结束。可以用“#”或“/* */”添加注释。需要注意的是:UCF文件是大小写敏感的,信号名必须和设计中保持大小写一致,但约束的关键字可以是大写、小写甚至大小写混合。例如:
NET \"CLK\" LOC = P30;
“CLK”就是所约束信号名,LOC = P30;是约束具体的含义,将CLK信号分配到FPGA的P30管脚上。
对于所有的约束文件,使用与约束关键字或设计环境保留字相同的信号名会产生错误信息,除非将其用\" \"括起来,因此在输入约束文件时,最好用\" \"将所有的信号名括起来。
2.通配符
在UCF文件中,通配符指的是“*”和“?”。“*”可以代表任何字符串以及空,“?”则代表一个字符。在编辑约束文件时,使用通配符可以快速选择一组信号,当然这些信号都要包含部分共有的字符串。例如:
NET \"*CLK?\" FAST;
将包含“CLK”字符并以一个字符结尾的所有信号,并提高了其速率。
在位置约束中,可以在行号和列号中使用通配符。例如:
INST \"/CLK_logic/*\" LOC = CLB_r*c7;
把CLK_logic层次中所有的实例放在第7列的CLB中。
3.定义设计层次
在UCF文件中,通过通配符*可以指定信号的设计层次。其语法规则为:
* 遍历所有层次
Level1/* 遍历level1及以下层次中的模块
Level1/*/ 遍历level1种的模块,但不遍历更低层的模块
例4-5 根据图4-75所示的结构,使用通配符遍历表4-3所要求的各个模块。
图4-75 层次模块示意图
表4-3 要求遍历的符号列表
4.4.3 管脚和区域约束语法
LOC约束是FPGA设计中最基本的布局约束和综合约束,能够定义基本设计单元在FPGA芯片中的位置,可实现绝对定位、范围定位以及区域定位。此外,LOC还能将一组基本单元约束在特定区域之中。LOC语句既可以书写在约束文件中,也可以直接添加到设计文件中。换句话说,ISE中的FPGA底层工具编辑器(FPGA Editor)、布局规划器(Floorplanner)和引脚和区域约束编辑器的主要功能都可以通过LOC语句完成。
• LOC语句语法
基本的LOC语法为:
INST \"instance_name \" LOC = location;
其中“location”可以是FPGA芯片中任一或多个合法位置。如果为多个定位,需要
用逗号“,”隔开,如下所示:
LOC = location1,location2,...,locationx;
目前,还不支持将多个逻辑置于同一位置以及将多个逻辑至于多个位置上。需要说明的是,多位置约束并不是将设计定位到所有的位置上,而是在布局布线过程中,布局器任意挑选其中的一个作为最终的布局位置。
范围定位的语法为:
INST “instance_name” LOC=location:location [SOFT];
常用的LOC定位语句如表4-4所列。
表4-4 常用的LOC定位语句
使用LOC完成端口定义时,其语法如下:
NET \"Top_Module_PORT\" LOC = \"Chip_Port\";
其中,“Top_Module_PORT”为用户设计中顶层模块的信号端口,“Chip_Port”为FPGA芯片的管脚名。
LOC语句中是存在优先级的,当同时指定LOC端口和其端口连线时,对其连线约束的优先级是最高的。例如,在图4-76中,LOC=11的优先级高于LOC=38。
图4-76 LOC优先级示意图
2.LOC属性说明
LOC语句通过加载不同的属性可以约束管脚位置、CLB、Slice、TBUF、块RAM、硬核乘法器、全局时钟、数字锁相环(DLL)以及DCM模块等资源,基本涵盖了FPGA芯片中所有类型的资源。由此可见,LOC语句功能十分强大,表4-5列出了LOC的常用属性。
表4-5 LOC语句常用属性列表
4.4.4 使用PACE完成管脚约束
ISE中内嵌了图形化的引脚和区域约束编辑器PACE(Pinout and Area Constraints Editor)可以将设计管脚映射到器件中,并对逻辑区块进行平面布置,方便地完成管脚约束和区域约束。在PACE中,可将管脚拖放到器件的显示图形上,通过容易识别的彩色编码将管脚进行逻辑分组,定义I/O标准和库,分配和放置微分I/O等。和使用约束文件相
比,在中、大规模FPGA的开发中,能大大简化管脚约束流程。
通过检查定义的HDL层级和核对逻辑区块与预计的门尺寸的关系,PACE可以实现区块映射,使区块定义变得快速、准确和容易。在HDL编码开始之前,就可以使用PACE分配管脚,然后写HDL开始模板,供你编辑。可以通过标准CSV文件,将管脚信息导出或导入到PCB布局编辑器中,这大大简化了设计计划的编制。
1.PACE用户界面
PACE的启动方法有两种:一种是单独启动PACE,直接点击“开始” “程序” “Xilinx ISE 9.1i” “Accessories” “PACE”即可启动;另一种是在工程经过布局布线后,在过程管理区双击“User Constraints” “Assign Package Pins”来打开PACE,并自动加载当前工程。需要注意的是,在启动PACE之前,要确保相应的设计中存在UCF文件,否则会提示错误。这是因为,通过PACE完成的操作,最终的依然要写入到相应的UCF文件中。典型的PACE用户界面如图4-77所示。
图4-77 PACE的用户界面
PACE的用户界面主要由菜单栏、工具栏、设计浏览区、设计对象列表区、芯片管脚封装视图图、芯片结构视图区以及信息显示窗口组成。
2.使用PACE添加I/O约束
在分配管脚之前,首先需要确定芯片是否选择正确,可通过点击菜单“IOB”中的“”命令来查看所选芯片型号,弹出的对话框如图M所示。如芯片型号错误,可重新选择。
图4-78 所选芯片的型号
其次,点击菜单“IOB”中的“”命令来禁止不可用的输入输出管脚,弹出的对话框如图M所示。通过该菜单可完成所有复用管脚的控制,包括芯片配置管脚以及参考电压管脚。
图4-79 部分输入输出管脚的控制
再次,可将信号分组或组成总线模式来加快管脚分配的速度。一般来讲,PACE会自动将信号进行分组。此外,设计人员也可以手动添加信号分组,其方法如下:在设计信号列表区,按住“Ctrl”键,选取需要组合的多个信号,然后点击菜单“Edit”中的“Group”命令,即可将所选信号合并,并在信号列表区中的分组显示区显示出来,如图M所示。
图4-80 PACE信号合并界面
对于新添加的分组信号,PACE会以“UserGroupN”命名,其中N为添加的序号,用户可直接在“Group”列的对应表格中重新命名。对应信号“#”列的表格中的数字为分组或总线中的信号个数。
最后是分配管脚。在PACE中有两种方法可完成管脚分配,其一就是直接将设计浏览区中“I/O Pins”目录下的信号或总线直接拖到芯片管脚封装试图区中;另一种方法是在设计信号列表区中,选中相应的信号,直接在“LOC”列所对应的表格中敲入位置。分配完毕后,点击工具栏中的“保存”按钮即可。
此外,PACE中“IOBs”菜单下的“Show Differential Pairs”命令,可在芯片管脚封装视图区列出所有的差分对,如图M所示,每一对差分对都通过短线连接起来。
图4-81 PACE差分对示意图
3.使用PACE添加区域约束
区域约束的主要目的是关联耦合逻辑,减少后续布线压力;其次是加大资源利用率,距离近的信号延迟不一定就小,信号线上延迟主要是来自线与线之间的转接(如LUT,switch-box)。由于FPGA内部连接的结构是横纵两向的,斜向的连接延迟会大于横纵方向上最大跨度连接。所以,在做位置约束时尽量避免斜向;而区域约束要松,如果没有资源上的顾虑,约束面积建议为所需的3倍以上。需要注意的是,区域约束对时序的改善贡献很小,紧的约束甚至有恶化时序的可能。
通过PACE软件,可将设计中的所有逻辑资源,包括全局时钟缓冲器、硬核乘加器、块RAM、硬核处理器、高速收发器以及数字时钟管理模块等模块放入器件架构(Device Architecture)的任何位置。下面通过实例介绍如何使用PACE完成区域约束。
例4-6 使用PACE完成设计的区域约束。
(1)通过ISE打开设计工程以及其中的PACE,在设计浏览区选中“Logic”文件夹,单击右键,选择“Object Properties”命令,则会显示所用的资源,包括触发器、进位符、DCM以及BUFG等资源。
(2)在PACE工具栏单击“ ”图标(Assign Area constraint Mode),用鼠标在器件结构窗口划出用于布局的曲域,如图4-82所示。
图4-82 利用PACE划定约束区域
完成后区域布局划分后,保存设计,用户即可在ISE的UCF文件中查阅相应的区域约束文件,附加的区域约束如图4-83所示。
图4-83 完成约束区域后所添加的约束文件
(3)对于复杂图形的区域,可通过添加多个长方形来完成。首先选中已经规划的区域,
然后单击右键,添加新的长方形,依次下去,直到满足要求即可。如果需要修改,双击选中某个长方形,点击右键,选择“Remove Constraint”命令,可删除相应的区域。
(4)单击工具栏的“击“
”图标,可以在器件结构中划分出禁止布局布线的区域。单
”图标,可在禁止布局布线区域重新划定能用于布局布线的区域。
4.使用PACE完成时序分析
目前,FPGA的工作频率已达到数百兆以上,I/O端口的数据速率已达到数十吉赫兹,因此在高速设计中对管脚、逻辑资源的布局就显得特别重要,在低速设计中则可以忽略芯片内部的布局布线延迟。PACE可根据芯片尺寸、型号以及设计的约束,自动给出管脚和逻辑之间、逻辑和逻辑之间的信号延迟报告,该类延迟一般在ps数量级上,但对于数百兆的高速信号来讲,已经是非常宝贵的时隙裕量。PACE软件会自动考虑输入、输出信号的抖动,将高速输出信号放在延时最小的管脚上。特别是对于时钟信号,会附加最优的布局和分配处理,提高同步设计性能。
一般来讲,利用PACE完成FPGA引脚时序分析的3个步骤如下:
(1)打开PACE软件,选择“IOB”菜单下面的“Show Flight Times”命令,启动时延分析功能。
(2)选择“Tools”菜单下面的“Display Overlay”命令,则会弹出延迟对话框,用不同的颜色表明不同的时延,如图4-84所示。该窗口只是信息输出窗口,不能操作,点击“OK”按键即可。
图4-84 FPGA引脚之间的传输延迟分类列表
然后在图4-85中的芯片管脚封装测试区可以看到,不同延迟的管脚用不同颜色标注,用户可对关键的输入、输出信号进行重新分配,提高设计性能。细心的读者会发现,越处于芯片外围的引脚,其时延越大。
图4-85 FPGA引脚传输延迟分布示意图
(3)对于多时钟设计,用户需要了解芯片的时钟分区。选择“IOB”菜单下面的“Show Clock Regions”命令,则在芯片架构视图区用不同的颜色显示FPGA芯片内部不同的时钟分区,如图4-86所示。
图4-86 FPGA时钟分区示意图
此时,设计者更关心时钟和时钟区域的对应关系,点击选择“Tools”菜单下面的“Display Overlay”命令,并选择“Clock Regions”页面,即可直观得到该关系,如图4-87所示。
图4-87 FPGA时钟与时钟区域对应示意图
5.使用PACE完成DRC分析
不同逻辑区域所允许的时钟数量是有限的,若分配到该区域的设计超过了该时钟上限,则会导致设计错误。PACE提供了时钟分析工具来帮助用户检查此类错误,通过点击“Tools”菜单下的“Clock Analysis”命令来分析,如果时钟信号超过设定值,则会在其“Regions Per Clock”页面中以“*”号标出。
设计规则是电路或者芯片在版图设计中所必须遵循和满足的各种规定和要求,如果不能满足,则生产出来的芯片将可能无法正常工作。DRC(Design Rule Check)即设计规则检查,就是根据设计规则所规定的各掩膜图形的最小尺寸、最小间距等几何参数,对设计进行检查,找出不满足规则的偏差和错误,为用户修正设计提供依据。目前,FPGA芯片的管脚越来越多,因此检查时钟管脚分配、IO端口输出电平标准与相应的IO电压是否一致、核电压以及辅助电压是否正确成为任务繁重且容易出错的地方。PACE提供的DRC检查可自动完成上述核查,选择“Tools”菜单下的“Run Design Rule Check(DRC)”命令,即可得到设计的DRC结果,如图4-88所示。
图4-88 PACE的DRC检查结果示意图
第5节 ISE与第三方软件
4.5.1 Synplify Pro软件的使用
在FPGA设计中,许多设计人员都习惯于使用综合工具Synplify Pro。虽然ISE软件可以不依赖于任何第三方EDA软件完成整个设计,但Synplify Pro软件有综合性能高以及综合速度快等特点,无论在物理面积上还是工作频率都能达到较理想的效果。因此如何在ISE中调用Synplify Pro综合工具,并进行无缝的设计连接仍然是设计人员需要解决的一个设计流程问题。
1. Synplify Pro综合软件的安装
下面介绍Synplify Pro的安装步骤。运行安装程序,欢迎界面过后,将出现如图4-89所示的安装选择界面,可以根据自己的需要选择相应的组件。然后按照默认选项继续即可完成安装。
图4-89 Synplify的安装选择界面
在Synplify安装完后,还需要安装Identify。在开始 程序 Synplify菜单栏中会出现“Identify 211 Installation”,双击即开始安装,一般来讲,可以按照默认选项继续,直至安装完毕。安装完之后需要添加授权的License文件,才能正常使用。
2. 关联ISE和Synplify Pro
完成了Synplify Pro安装后,需要将其和ISE软件关联后才能使用Synplify Pro进行综合。运行ISE软件,在主界面中选择“Edit|Preference”菜单项,进行“Reference”设定如图4-90所示。在弹出的Preference对话框中选择“Integrated Tools”选项卡。该选项卡用于设定与ISE集成的软件的路径,第三项的Synplify Pro就用于设定Synplify Pro仿真软件的路径,如图4-91所示。
图4-90 选择Preference菜单
项 图4-91 ISE集成工具设定页面
单击Synplify Pro文本框后面的按钮,会弹出一个文件选择对话框,选择Synplify Pro安装路径下bin目录下的“synplify_pro.exe”文件即可。
注意:在“Integrated Tools”选项卡中还可以看到其他几个可以和ISE进行无缝链接的第三方软件,如ModelSim、synplifyLeonardoSpectrum、Chip Scope Analyzer等软件。
3. Synplify Pro的使用方法简介
Synthesis 简单地说就是将HDL代码转化为门级网表的过程,其对电路的综合包括以下3个步骤:首先,HDL compilation 把HDL的描述编译成已知的结构元素;其次,运用一些算法,对设计进行面积优化和减小时延。在没有目标库的情况下,Synplify只能执行一些最基本的优化措施;最后,将设计映射到指定厂家的特定器件上,并执行一些附加
的优化措施,包括根据由器件供应商提供的专用约束进行优化。工程文件以*.prj 作为扩展名,以tcl 的格式保留了以下信息:设计文件、约束文件、综合时开关选项的设置情况等。
1)Synplify Pro用户界面介绍
Synplify Pro是标准的windows应用程序,所有功能均可以通过菜单选择来实现。下面按照图4-92中数字所标示的次序,对其界面作简要介绍。图中1表示Synplify的主要工作窗口,在这个窗口中可以详细显示设计者所创建工程的详细信息,包括工程的源文件,综合后的各种结果文件。同时如果综合完成后,每个源文件有多少错误或者警告都会在这个窗口显示出来。图中2表示TCL窗口,在这个窗口中设计者可以通过TCL命令而不是菜单来完成相应的功能。图中3表示观察窗口,在这里可以观察设计被综合后的一些特性,比如最高工作频率等。图中4是状态窗口,它表示现在Synplify所处的状态,比如下图表示Synplify处于闲置状态,在综合过程中会显示编译状态、映射状态等等。图中5所示的一些复选框,可以对将要综合的设计的一些特性进行设置。Synplify可以根据这些设置对设计进行相应的优化工作。图中6是运行按钮,当一个工程加入之后,按这个RUN 按钮,Synplify就会对工程进行综合。图中7所示的是Synplify的工具栏。
图4-92 Synplify Pro综合工具示意图
2) 建立工程、添加源文件
建立工程首先需要打开Synplicity Pro。点击“开始”菜单,依次选择“程序Synplicity Synplify Pro”,启动Synplify Pro。在工程窗口中包含了以下内容:源文件信息、结果文件信息和目标器件信息。
缺省情况下,当Synplify启动时将自动建立一个新工程。这时,可以选择将工程,以新名字保存。如果结束了一个工程的操作,想新建一个工程,则可以选择“FILE NEW”;然后选择工程文件,就可以建立一个新的工程。这项操作也可以通过工具条来进行,单击工具条的P图标,则在弹出对话框选择工程文件即可。
新建工程之后,需要将源文件添加进来。点击“ADD FILE”按钮。添加源文件和约束
文件。Synplify Pro把最后编译的“module/entity and the architecture”作为顶层设计,所以需要把顶层设计文件用左键拖拉到源文件菜单的末尾处或者点击“Impl Options”按钮,在Verilog属性页中设置顶层模块的名称。
3)工程属性设置
添加完源文件后需要设置工程属性,点击“Impl option”按钮出现属性页对话框,如图4-51所示。下面介绍常用的芯片设置、综合选项、约束设置以及实现结果选项等参数的配置。
图4-93 设置器件属性页
• 首先,设置FPGA芯片信息。打开“Device”属性页,分别设置器件厂家器件
型号、速度级别和封装信息。根据设计的速度和面积要求。可以设置最大扇出系数,缺省是10000。根据该工程所属模块是否和片外有信号联系,选中或者不选中“Disable I/O insert”,如果选中该选项,则Synplify Pro不会为输入输出信号加缓冲,缺省为不选。
• 设置通用综合选项。点击“options”属性页,选中“Symbolic FSM
Compiler”,Synplify Pro会在综合过程中启动有限状态机编译器,对设计中的状态机进行优化。选中“Resource Sharing”选项,则启动资源共享;设置了资源共享后,设计的最高工作频率会低于不选中的情况,但是资源会节约很多,因此在设计能够满足时钟频率要求的情况下,一般选中以节省资源。选中“Use FSM Explorer”选项,即可以用synplify内置的状态机浏览器观察状态机的各种属性。选中“Pipelining”选项,即启动流水,在高速时钟设计中,如果其他措施都不能达到目标频率则最好选中此项。
• 设置约束选项。点击“Constraints”属性页,设置模块最高工作频率以及添
加约束文件(.sdc)。过严或是过松的约束都达不到最佳的效果。一般可先尝试通用的约束,如时钟扇出限制等;如果没有达到要求,可加入一些严格的具体约束,同时注意放松一些可以放松的约束。需要注意的是,综合约束的结果是估计值,应该以布局布线的结果为准。
• 设置实现结果。点击“Implementation Results”属性页,设置综合结果放置
的目录,综合结果的文件名称。同时一定要将“Write Vendor Constraint File”和“Write Verification Interface Format”选项选中。
4)时序约束
定义时间约束是为了让综合结果满足预期的时序要求,时间约束通常分为两类:一是
通用时间约束,用于目标结构的时序要求;二是黑盒时间约束,用于在设计中指定为黑盒的模块时间约束。在Synplify Pro中,可通过SCOPE、约束文件以及综合属性和指示等3种方法添加时序。本节主要介绍利用约束文件添加约束的方法。
约束文件采用Tcl语言,以*.sdc 保存,用来提供设计者定义的时序约束、综合属性以及FPGA生产商定义的属性等。约束文件既可以通过SCOPE创建编辑也可以使用正文编辑器创建编辑可被添加到在工程窗口的代码菜单中也可以被Tcl脚本文件调用。
5)综合属性和指示
(1)综合属性和指示简介
综合指示用于控制综合中编译阶段的设计分析,因而必须加入到源代码中。属性是在编译后读入的,因而既可以在源程序中说明,也可以在约束文件中说明。约束文件提供了较大的灵活性,使得可以仅修改约束而不用重新编译源程序,因而是强烈推荐采用的方法。
在Verilog源程序中,说明指示或属性采用注释的方法语法如下:
// synthesis directive|attribute = \"value\"
或 /* synthesis directive |attribute = \"value\" */
(2)综合指示
综合指示用于通知Synplify Pro软件某些用户定制的设置,常以注释的形式出现在源代码后面,Synplify软件会自动识别相应的说明,按照用户指令完成综合。常用的综合只
是如下:
① black_box_pad_pin
声明用户定义的黑盒管脚作为外部环境可见的I/O pad。如果有不止一个端口列在双引号内,则以逗号分开。由于Synplify提供了预定义的I/Os,一般不需要这一属性。其语法如下:
object /* synthesis syn_black_box black_box_pad_pin = \"port_list\" */ ;
例如:
module BS(D,IN,PAD,Q) /*synthesis syn_black_box black_box_pad_pin=\"PAD\" */;
② block_box_tri_pins
声明黑盒的一个输出端口是三态,如不止一个列在双引号内,则以逗号分开。其语法如下:
object /* synthesis syn_black_box black_box_tri_pins = \"port_list\" */ ;
例如:
module BBDLHS(D,E,GIN,GOUT,PAD,Q) /* synthesis syn_black_box
black_box_tri_pins=\"PAD\" */ ;
③ full_case
仅用于Verilog中的case语句,表明所有可能的状态都已经给出,不需要其他逻辑保持信号的值,其语法如下:
object /* synthesis full_case */
其中object可以是case、casex、casez、statements和declaration。
④ parallel_case
仅用于Verilog中case语句,表明生成一个并行的多路选择结构而不是一个优先译码结构。其语法如下:
object /* synthesis parallel_case */
其中object可以是case、casex、casez、statements和declaration。
⑤ syn_block_box
说明一个模块或组件为黑盒,仅利用其界面进行综合,而不管内部是否为空,也不进行优化。一般应用于厂家原语或宏或IP等用户定义的宏。其语法如下:
object /* synthesis syn_black_box */ ;
其中object可以是module和declaration。
⑥ syn_encoding
强制选择自动机实现的方式,其可选值(value)如下:
default:综合根据状态的数量选择编码方式编码方式可以是onehot gray sequential;
onehot:采用onehot编码方式;
gray:采用格雷码;
sequential:采用自然码;
safe:如果不能到达任一个状态时让其回到复位态。
syn_encoding的语法如下:
object /* synthesis syn_encoding = \"value\" */ ;
其中object是状态寄存器定义。
⑦ syn_isclock
说明黑盒的一个输入是时钟信号。对名字为clk 、rclk 、wclk的黑盒输入信号,软件
自动当作时钟,可以用这个属性说明任意输入信号为时钟信号。其语法如下:
object /* synthesis syn_isclock = 0|1 */ ;
其中object是黑盒的input port。
例如:
module ram4(myclk, out, opcode, a, b) /* synthesis syn_black_box*/;
output [7:0] out;
input myclk /* synthesis syn_isclock = 1 */;
input [2:0] opcode;
input [7:0] a, b;
/* Other coding */
⑧ syn_keep
保证被指定的wire在综合中保持不动,不会被优化掉,常用于用define_multicycle_path或define_false_path,用了-through 选项。如果你用了这一属性,将生成一个keepbuf,可对其定义时间约束,且这个Buffer只占用一个位置,不出现在门级网表里。其语法如下:
object /* synthesis syn_keep = 0|1 */ ;
其中object是wire或reg声明。
⑨ syn_noprune
用来保持一个或多个component的实例,而不管其输出能否完成映射。一般在没有该指示的情况下,未用输出端口的实例会从EDIF文件中删除。syn_noprune可被置于约束文件中,其语法如下:
.sdc文件中:
define_attribute {module|instance} syn_noprune {0|1}
Verilog中:
object /* synthesis syn_noprune = 0|1 */ ;
其中object可以是module、declaration,也可以是实例。
⑩ syn_preserve
用在某些独立的寄存器上或模块,使模块中的所有寄存器在优化时保持不动,也可用于保持某个自动机在优化时不动。其语法如下:
object /* synthesis syn_preserve = 0|1 */ ;
其中object可以是寄存器定义信号,也可以是Module。
• syn_sharing
• 确定综合时是否对运算符进行资源共享。缺省值是禁止,也可以在project视窗里设置这一选项。其语法如下:
• object / * synthesis syn_sharing = \" on|off \" */ ;
• 其中object可以是module定义语句。
• syn_state_machine
• 对设计中的某组状态寄存器进行自动机优化,其语法如下:
• object /* synthesis syn_state_machine = 0|1 */ ;
• 其中object是该组状态寄存器。
• syn_tco • 提供黑盒的输出延迟信息,其语法如下: • object /* syn_tcon = \"[!]clock -> bundle = value\" */ ; • 其中bundle是总线或标量信号的集合。 • syn_tpd • 提供穿过黑盒的组合逻辑的传输延迟信息,其语法如下: • object /* syn_tpdn = \"[!]clock -> bundle = value\" */ ; • 其中bundle是总线或标量信号的集合。 • syn_tristate • 指定黑盒的一个输出端口为三态端口,其语法如下: • object /* synthesis syn_tristate = 0|1 */ ; • 其中object可以是黑盒的output port。 • syn_tsu • 说明一个黑盒的输入要求的建立时间,其语法如下: • object /* syn_tsun = \"[!]clock -> bundle = value\" */ ; • translate_on/translate_off 用于与其他综合软件的兼容,这两者经常配对使用。在这两个指示中间的所有代码将在综合时被忽略,也可以用于在源代码中插入一段仿真代码。其语法如下: /* synthesis translate_off */ 综合时忽略的代码 /* synthesis translate_on */ 6)综合报告解读 综合报告主要由3部分组成:编译报告、映射优化报告以及时序报告,但是该报告是冗长的,不容易快速找出用户所关心的结果。因此,Synplify公司提供了综合报告观察窗,如图4-92中第3部分所示,可从综合报告文件中取出重要的信息。该窗口的使用非常简单,点击空白的参数显示栏,在下拉栏中选择要查看的项目,则会在同行的右侧显示出结果,如图4-94所示。 图4-93 Synplify综合结果示意图 4.5.2 ModelSim软件的使用 ModelSim软件是一款强大的仿真软件,具有速度快、精度高和便于操作的特点,此外还具有代码分析能力,可以看出不同代码段消耗资源的情况。其功能侧重于编译和仿真,不能制定编译的器件和下载配置的能力,所以需要和ISE等软件关联。 1.ModelSim 仿真软件的安装 下面介绍一下ModelSim的安装步骤。 1)运行安装程序后,出现图4-94所示的界面,如果拥有有效的License,可以选择完全版(Full Product)安装,反之,则应当选择评估版(Evaluation Edition)安装。 图4-94 ModelSim版本选择窗口 2)选择完安装类型之后,下一个步骤就是设定安装路径,如图4-95所示。 图4-95 ModelSim安装路径选择窗口 3)如果选择的是完全版本,安装之后会出现Liscense Wizard对话框,如图4-96所示。 图4-96 ModelSim软件License管理向导 4)单击Continue按钮后,会出现License文件选择的对话框,选择有效的License文件。单击OK按键后,系统会自动进行一系列的有效性检查,只有合法的License文件,才能使ModelSim正常工作。 2.关联ISE和ModelSim 完成了ModelSim安装后,需要将其和ISE软件关联后才能使用ModelSim进行仿真。运行ISE软件,在主界面中选择“Edit|Preference”菜单项,进行Reference设定如图4-4所示。在弹出的“Preference”对话框中选择“Integrated Tools”选项卡。该选项卡用于设定与ISE集成的软件的路径,第一项的“Model Tech Simulator”就用于设定ModelSim仿真软件的路径,如图4-5所示。 单击“Model Tech Simulator”文本框后面的按钮,会弹出一个文件选择对话框,选择ModelSim安装路径下win32目录下的“modelsim.exe”文件即可。 3. 在ModelSim中指定Xilinx的仿真库 ModelSim SE版在发行时是不带任何FPGA厂家的仿真库,因此用户必须手动编译这些库,由此面临的一个问题就是怎样建立各FPGA器件的仿真库,目前各FPGA厂家都支持用户编译库,所以实现比较简单。 在ModelSim中编译Xilinx仿真库有很多方法,下面介绍一种比较常用的方法,分为3步来完成。 • 点击“开始/运行”按钮,执行下面的命令: • “compxlib -s mti_se -f all -l all –o f:\\modeltech_6.2b\\xilinx_libs -p f:\\Modeltech_6.0\\win32” • 其中,f:\\modeltech_6.2b为 ModelSim软件的安装目录,用户可根据自己的目录 来替换。等待上述命令运行完毕,其运行时间较长,用户不要中途中断。 • 在Xilinx本地库编辑成功后,在相应的目录下,会自动生成Modelsim.ini的文件,用任何一个文本编辑器将该文件中[Library]目录下(除others以外)的内容添加到硬盘上相应的另外的ModelSim安装目录下同名“modelsim.ini”文件中的相应[Library]位置。 • 最后进入ISE主界面,点击“Edit”下拉菜单按纽,选中下拉菜单中的“Prefrence”选项,再选中“Intergal Tools”页面,重新指定ModelSim可执行文件即可。退出所有软件,以后再对Xilinx的设计进行仿真都不需要进行库的处理了。 4. ModelSim使用方法简介 本节主要简单介绍ModelSim SE 6. 6.2b的使用方法,主要包括建立工程和基本Verilog仿真,更多的操作方法需要在实际应用中熟悉并掌握。 1)建立工程 使用ModelSim建立工程主要包括5个基本步骤: <1>启动ModelSim,选择菜单“File New Poject”,会打开“Creat Project”对话框,如图4-97所示。在“Creat Projec”t对话框中填写“Project Name”为“test”,然后在“Project Location”栏中选择Project文件的存储目录,保留“Default Library Name”的设置为work。点击OK按键确认,在ModelSim软件主窗口的工作区中即增加了一个空的Project标签,同时弹出一个“Add items to the Project”对话框,如图4-98所示。 图4-97 ModelSim新建工程窗口 图4-98 添加文件到工程向 导示意图 <2>. 添加包含设计单元的文件。直接点击Add items to the Project对话框以后,在对话框中利用“Add Existing File”或“Create New File”选项,可以在工程中加入已经存在的文件或建立新文件。本节我们选择“Add Existing File”,弹出“Add file to the Project”对话框,如图4-99所示。点击对话框中的Browse按键,打开ModelSim安装路径中的examples/tutorials /verilog/compare/目录,选取sm.v和sm.v文件(选中多个文件时,只需要一直按住Ctrl按键,用鼠标点击即可),再选中对话框下面的“Reference from current location”选项,然后点击OK按键确认。 图4-99 ModelSIm添加文件选项示意图 <3>.在工作区中的Project标签页中可以看到新加入的文件,单击右键,选取“Compile Compile All”命令对加入的文件进行编译,如图4-100所示。 图4-100 ModelSim软件中的工程编译窗口 <4>. 两个文件编译完后,用鼠标点击“Library”标签栏。在标签栏中用鼠标点击work库前面的“+”,展开work库,就会看到两个编译了的设计单元。如图4-101。 图4-101 编译后的设计单元示意图 <5>. 导入设计单元。双击Library标签页中的“test_sm”,在工作区中将会出现sim标签,并在右边的对象窗口列出了test_sm单元所用到的信号,如图4-102所示。 图4-102 将test_sm模块加入工作区示意图 到此,一个工程就已经建立好了,接下来的就是开始运行仿真、分析和设计调试了。选择“File Close Poject”可以关闭当前目录。 2)基本Verilog仿真 在准备仿真的时候,需要完成(1)中的所有步骤。然后继续进行下面的步骤: <1>. 通过选择“View <窗口名>”调出signal、list和wave窗口。 也可以通过在主窗口命令行操作区的VSIM提示符下输入下面的命令:view signals list wave(回车) <2>. 向wave窗口添加信号。在signal窗口中,单击右键,在弹出的菜单中选择“Add to Wave”选项中的“Signal in design”,将设计中用到的所有信号都列在Wave窗口中,如图4-103所示。 图4-103 在Wave窗口中添加信号 <3>. 导入设计的时候,会在工作区打开一个新的sim标签,点击“+”展开设计层次结构,可以看到实例test_sm、sm等模块。点击sim标签中的顶层行保证test_sm模块显示在source窗口中。 <4>. 点击主窗口工具条的Run启动仿真,默认仿真长度为100ns。或者在命令行输入run。可以在仿真途中点击“Break”中断运行,在source窗口中查看中断时执行的语句。 <5>. 仿真完成,观察仿真波形如图4-104。确认无误后退出仿真,如果有错则返回source区域修改代码。 图4-104 test_sm模块的仿真结果示意图 4.5.3 Synplify Pro、ModelSim和ISE的联合开发流程 利用Synplify Pro、ModelSim和ISE进行联合开发的步骤基本如下:当工程设计完成后,首先需要利用ModelSim软件完成功能仿真,然后利用Synplify Pro进行综合优化,再在ISE中完成映射与布局布线,并借助于ModelSim完成布局布线后的时序仿真,最后在ISE中完成.bit文件的生成和FPGA芯片的配置。 通常上述流程有两种实现方法:第一,将前两者作为ISE的第三方插件,在ISE中通过按键自动调用;其次,就是通过相应的接口文件,手动完成各个流程。自动调用比较简单,只需要在ISE中进行简单的设计即可。 1. 自动调用流程 完成了Synplify Pro和ModelSim的安装,并在集成工具设定页面完成与ISE的关联后,如图4-91所示,单击ModelSim、Synplify /Synplify Pro文本框后面的按钮,会弹出一个文件选择对话框,选择ModelSim、Synplify /Synplify Pro安装路径中bin目录下的*.exe文件即可。 需要注意的是,并不是任意的ISE版本和任意的ModelSim、Synplify/Synplify Pro版本都可以实现无缝连接,只有在ISE发布后出现的第三方软件才能和ISE无缝连接,否则Synplify/Synplify Pro软件只能够用于综合逻辑,而不能识别Xilinx提供的IP core,ModelSim则不能用于嵌入式开发环境(EDK)设计的仿真。根据个人操作的结果,和ISE 9.1匹配的Synplify /Synplify Pro应当是8.8及其更高版本,相应的ModelSim应该为 6.1f以后的版本。 完成了上述设定后,就可以直接在设计中调用ModelSim和Synplify。在工程管理区的设计芯片上,点击右键,选择“Property”命令,即可打开用户设计的综合和仿真工具选择界面,如图4-105所示。在“Synthesis Tool”的下拉框中选择Synplify(Verilog)、在“Simulator”中选择ModelSin-SE Mixed。 图4-105 设计工具选择界面 2. 手动调用 由于ModelSim只是完成功能验证,也ISE没有直接的数据交互,手动操作就是分开单独操作。 手动调用Synplify Pro的方法比较灵活,但操作起来比较麻烦,用户可根据需要自行选择。首先单独启动Synplify Pro完成综合过程,再输出符合ISE格式的EDIF网表,在设置工程属性时选择EDIF设计流程,ISE仅完成网表的转换、映射和布局布线等操作。同时可在Synplify Pro中添加时序约束。 综合完成后,生成的后缀为.edif的文件就是综合输出的重要文件,是实现过程的输入,直接将其导入ISE即可。 4.5.4 ISE与MATLAB的联合使用 本节主要介绍MATLAB设计、ISE实现以及二者联合测试的FPGA开发流程,这是全书的核心思想之一,也是目前最流行的设计方法。 MATLAB软件是MathWorks公司的核心产品,具有用法简单、扩展性好、资源库丰富以及与其他软件接口方便的特点,已成为从事电子信息和信号处理领域人员必备的工具软件之一。MATLAB和ISE的联合使用主要通过以下两个途径来实现:即MATLAB辅助ISE的方法,以及利用接口软件System Generator的方法。本书主要围绕着第一种方法展开讨论,但System Generator作为一种新兴的设计模式,具有强大的发展势头,这里对其也作了简单介绍,关于System Generator的详细讨论将在第8章展开。 1. MATLAB辅助ISE完成FPGA 所谓辅助,就是利用MATLAB来加速浮点算法的实现和功能测试。即在进行FPGA设 计之前,先用MATLAB实现浮点算法,分析出算法的瓶颈所在,将程序的串行结构改造成并行结构,接着利用MATLAB完成定点仿真,得到满足性能需求的最小定点位宽以及中间步骤计算结果的截取范围,然后在ISE中完成设计。最后再利用MATLAB的定点仿真结果对设计进行功能验证,整个流程如图4-106所示。 图4-106 MATLAB辅助ISE完成设计的流程图 关于怎样完成定点仿真以及模块输出结果截取的原理和方法将在第5章中展开详细关系讨论。此外,利用MATLAB对FPGA设计进行功能仿真是比较关键的,下面介绍如何将MATLAB和ModelSim结合起来使用。 首先,在MATLAB中产生仿真所需的输入信号,以十六进制的形式存放在数据文件中,通常放在后缀为.txt的文本文件中;其次在ModelSim中用Verilog编写仿真测试文件,并通过系统函数$readmemh将上述仿真数据文件中的测试向量读入,在ModelSim中做功能仿真和时序仿真,并调用$fopen函数打开另外一个数据文件,用$fdisplay函数将仿真结果写入;再次,在MATLAB中将ModelSim仿真输出数据文件中的数据读入一个数组中,可以作图分析或者利用统计手段来分析。此外,还可以将ModelSim的仿真输出与MATLAB的浮点性能作对比,来验证设计的性能。这样比利用其他方式要方便、直观,并 且具有更高的正确性。 下面举例介绍Verilog语言中文件输入/输出函数的使用方法。 1)系统函数$fopen用于打开一个文件,并返回一个整数的文件指针。然后,$fdisplay就可以使用这个文件指针在文件中写入信息。写完后,用$fclose关闭文件。 其语法格式为: integer $fwrite( $fclose( 例如:integer W_file; //定义文件指针 W_file = $fopen(\"W_file.txt\"); $fdisplay (W_file, \"@%h\\n%h\ $fclose (W_file); 以上语句将“a”和“b”分别显示在“@%h\\n%h”中的两个%h位置,并写入 Write_out_file指针所指的文件W_file.txt中。 2)读文件操作通过$readmemh和$readmemb来完成,分别对应的数据文件为16进制和二进制。其语法格式为: reg [ $readmemh (\" 例如:reg [15:0] c [0:15]; $readmemh (“R_file.txt”, c); 上例就是将R_file中的数据读入数组c中,然后就可以直接使用这些数据了。其中数据文件的格式为: @2c 45 其中,@2c表示地址,为16进制数,45表示该地址的数据。 2. System Generator工具简介 System Generator工具由MathWorks 与 Xilinx 合作开发而成,DSP 设计人员可使用 MATLAB 和 Simulink 工具在 FPGA 内进行开发和仿真来完善 DSP 设计。新型 8.2版本System Generator使DSP系统和算法开发商不用写VHDL或Verilog编程,只需要利用MATLAB 及 Simulink 来开发他们的设计。一旦浮点建模完成,设计工程师采用Xilinx的比特及周期精确工具箱对其进行量化并自动生成HDL/RTL、用于Xilinx FPGA的网表或完整的比特流,包括新的Virtex-5 LX 和 LXT器件。最后,设计工程师在Simulink环境内采用高带宽硬件环境来验证并调试实际FPGA上的设计。 System Generator的关键特性主要包括: • DSP建模。利用包含信号处理(如FIR滤波器、FFT)、纠错(如Viterbi解码器、Reed-Solomon编码器/解码器)、算法、存储器(如FIFO、RAM、ROM)及数字逻辑功能的Xilinx模块集,在Simulink内构建和调试高性能DSP系统。 Xilinx模块集提供的模块可以使您导入MATLAB功能模块(如创建控制电路)及HDL模块(System Generator为Mentor Graphics的ModelSim和Xilinx ISE仿真器提供了HDL协仿真接口)。 • Simulink 的 VHDL 或 Verilog 的自动代码生成。从 Xilinx 模块集实现行为(RTL)生成与对象明确的 Xilinx IP 核。 • 硬件协同仿真。创建“FPGA 在环路(FPGA-in-the-loop)”仿真对象是代码生成选项,允许您验证工作硬件并加速 Simulink 与 MATLAB 中的仿真。System Generator 支持以太网(10/100/千兆位)、PCI、Cardbus 及硬件平台与 Simulink 之间的 JTAG 通信。 • 嵌入式系统的硬件/软件协设计。为 Xilinx MicroBlaze™ 32 位 RISC 处理器构建和调试 DSP 协处理器。System Generator 提供了 HW/SW 接口的共享存储器提取功能,自动生成 DSP 协处理器、总线接口逻辑、软件驱动器及协处理器使用方面的软件技 术文档。 一个典型的System Generator开发实例如图4-107所示,图中形如Xilinx公司标志的图标就是System Generator,只需要双击图标,就可以将浮点算法自动转化成FPGA实现。Xilinx公司网站上提供了System Generator完整的使用手册和丰富的实例,读者如有兴趣,可自行阅读。 图4-107 一个典型的System Generator开发实例 第6节 Xilinx FPGA芯片底层单元的使用 4.6.1 Xilinx全局时钟网络的使用 在 Xilinx 系列 FPGA 产品中,全局时钟网络是一种全局布线资源,它可以保证时钟信号到达各个目标逻辑单元的时延基本相同。其时钟分配树结构如图4-108所示。 图4-108Xilinx FPGA全局时钟分配树结构 针对不同类型的器件,Xilinx公司提供的全局时钟网络在数量、性能等方面略有区别,下面以Virtex-4系列芯片为例,简单介绍FPGA全局时钟网络结构。 Virtex-4系列FPGA利用1.2V、90nm三栅极氧化层技术制造而成,与前一代器件相比,具备灵活的时钟解决方案,多达80个独立时钟与20个数字时钟管理器,差分全局时钟控制技术将歪斜与抖动降至最低。以全铜工艺实现的全局时钟网络,加上专用时钟缓冲与驱动结构,从而可使全局时钟到达芯片内部所有的逻辑可配置单元,且I/O单元以及块RAM的时延和抖动最小,可满足高速同步电路对时钟触发沿的苛刻需求。 在FPGA设计中,FPGA全局时钟路径需要专用的时钟缓冲和驱动,具有最小偏移和最大扇出能力,因此最好的时钟方案是由专用的全局时钟输入引脚驱动的单个主时钟,去钟控设计项目中的每一个触发器。只要可能就应尽量在设计项目中采用全局时钟,因为对于一个设计项目来说,全局时钟是最简单和最可预测的时钟。 在软件代码中,可通过调用原语 IBUFGP来使用全局时钟。IBUFGP的基本用法是: IBUFGP U1(.I(clk_in), .O(clk_out)); 全局时钟网络对FPGA设计性能的影响很大,所以本书在第11章还会更深入、更全面地介绍全局时钟网络以及相关使用方法。 4.6.2 DCM模块的使用 1.DCM模块的组成和功能介绍 数字时钟管理模块(Digital Clock Manager,DCM)是基于Xilinx的其他系列器件所采用的数字延迟锁相环(DLL,Delay Locked Loop)模块。在时钟的管理与控制方面,DCM与DLL相比,功能更强大,使用更灵活。DCM的功能包括消除时钟的延时、频率的合成、时钟相位的调整等系统方面的需求。DCM的主要优点在于:①实现零时钟偏移(Skew),消除时钟分配延迟,并实现时钟闭环控制;②时钟可以映射到PCB上用于同步外部芯片,这样就减少了对外部芯片的要求,将芯片内外的时钟控制一体化,以利于系统设计。对于DCM模块来说,其关键参数为输入时钟频率范围、输出时钟频率范围、输入/输出时钟允许抖动范围等。 DCM共由四部分组成,如图M所示。其中最底层仍采用成熟的DLL模块;其次分别为数字频率合成器(DFS,Digital Frequency Synthesizer)、数字移相器(DPS,Digital Phase Shifter)和数字频谱扩展器(DSS,Digital Spread Spectrum)。不同的芯片模块的DCM输入频率范围是不同的,例如:。 图4-109 DCM功能块和相应的信号 1)DLL模块 DLL主要由一个延时线和控制逻辑组成。延时线对时钟输入端CLKIN产生一个延时,时钟分布网线将该时钟分配到器件内的各个寄存器和时钟反馈端CLKFB;控制逻辑在反馈时钟到达时采样输入时钟以调整二者之间的偏差,实现输入和输出的零延时,如图4-110所示。具体工作原理是:控制逻辑在比较输入时钟和反馈时钟的偏差后,调整延时线参数,在输入时钟后不停地插入延时,直到输入时钟和反馈时钟的上升沿同步,锁定环路进入“锁定”状态,只要输入时钟不发生变化,输入时钟和反馈时钟就保持同步。DLL可以被用来实现一些电路以完善和简化系统级设计,如提供零传播延迟,低时钟相位差和高级时钟区域控制等。 图4-110 DLL简单模型示意图 在Xilinx芯片中,典型的DLL标准原型如图4-111所示,其管脚分别说明如下: 图4-111 Xilinx DLL的典型模型示意图 CLKIN(源时钟输入):DLL输入时钟信号,通常来自IBUFG或BUFG。 CLKFB(反馈时钟输入):DLL时钟反馈信号,该反馈信号必须源自CL K0或CL K2X,并通过IBUFG或BUFG相连。 RST(复位):控制DLL的初始化,通常接地。 CLK0(同频信号输出):与CL KIN无相位偏移;CL K90与CL KIN 有90度相位偏移;CL K180与CL KIN 有180度相位偏移;CL K270与CL KIN有270度相位偏移。 CLKDV(分频输出):DLL输出时钟信号,是CLKIN的分频时钟信号。DLL支持的分频系数为1.5,2,2.5,3,4,5,8 和16。 CLK2X(两倍信号输出):CLKIN的2倍频时钟信号。 LOCKED(输出锁存):为了完成锁存,DLL可能要检测上千个时钟周期。当DLL完成锁存之后,LOCKED有效。 在FPGA 设计中,消除时钟的传输延迟,实现高扇出最简单的方法就是用DLL,把CLK0 与CLKFB相连即可。利用一个DLL可以实现2倍频输出,如图4-112所示。利用两个DLL 就可以实现4倍频输出,如图4-113所示。 图4-112 Xilinx DLL 2倍频典型模型示意图 图4-113 Xilinx DLL 4倍频典型模型示意图 2)数字频率合成器 DFS可以为系统产生丰富的频率合成时钟信号,输出信号为CLKFB和CLKFX180,可提供输入时钟频率分数倍或整数倍的时钟输出频率方案,输出频率范围为1.5~320 MHz(不同芯片的输出频率范围是不同的)。这些频率基于用户自定义的两个整数比值,一个是乘因子(CLKFX_ MULTIPLY),另外一个是除因子(CLKFX_ DIVIDE),输入频率和输出频 率之间的关系为: 比如取CLKFX_MULTIPLY = 3,CLKFX_DIVIDE = 1,PCB上源时钟为100 MHz,通过DCM 3倍频后,就能驱动时钟频率在300 MHz的FPGA,从而减少了板上的时钟路径,简化板子的设计,提供更好的信号完整性。 3) 数字移相器 DCM具有移动时钟信号相位的能力,因此能够调整I/O信号的建立和保持时间,能支持对其输出时钟进行0度、90度、180度、270度的相移粗调和相移细调。其中,相移细调对相位的控制可以达到1%输入时钟周期的精度(或者50 ps),并且具有补偿电压和温度漂移的动态相位调节能力。对DCM输出时钟的相位调整需要通过属性控制PHASE_SHIFT来设置。PS设置范围为-255到+255,比如输入时钟为200 MHz,需要将输出时钟调整+ 0.9 ns的话,PS =(0.9ns/ 5ns)×256 = 46。如果PHASE_ SHIFT值是一个负数,则表示时钟输出应该相对于CLKIN向后进行相位移动;如果PHASE_SHIFT是一个正值,则表示时钟输出应该相对于CLKIN向前进行相位移动。 移相用法的原理图与倍频用法的原理图很类似,只用把CLK2X输出端的输出缓存移到CLK90、CLK180或者CLK270端即可。利用原时钟和移相时钟与计数器相配合也可以产生相应的倍频。 4) 数字频谱合成器 Xilinx公司第一个提出利用创新的扩频时钟技术来减少电磁干扰(EMI)噪声辐射的可编程解决方案。最先在FPGA中实现电磁兼容的EMIControl技术,是利用数字扩频技术(DSS)通过扩展输出时钟频率的频谱来降低电磁干扰,减少用户在电磁屏蔽上的投资。数字扩频(DSS)技术通过展宽输出时钟的频谱,来减少EMI和达到FCC要求。这一特点使设计者可极大地降低系统成本,使电路板重新设计的可能性降到最小,并不再需要昂贵的屏蔽,从而缩短了设计周期。 2.DCM模块IP Core的使用 例4-7 在ISE中调用DCM模块,完成50MHz时钟信号到75MHz时钟信号的转换。 1)在源文件进程中,双击“Create New Source”;然后在源文件窗口,选择“IP (CoreGen & Architecture ClockingWizard)”,输入文件名“my_dcm”;再点击“Next”,在选择类型窗口中,“FPGA Features and Design Virtex-4”,然后选择“Single DCM ADV v9.1i”,如图4-114所示。 图114 新建DCM模块IP Core向导示意图 <2> 点击“Next”,“Finish”进入Xilinx 时钟向导的建立窗口,如图4-65所示。ISE默认选中CLK0和 LOCKED这两个信号,用户根据自己需求添加输出时钟。在“Input Clock Frequency”输入栏中敲入输入时钟的频率或周期,单位分别是MHz和ns,其余配置保留默认值。为了演示,这里添加了CLKFX 信号,并设定输入时钟为单端信号,频率为50MHz,其余选项保持默认值。 图-115 DCM模块配置向导界面 <3> 点击“Next”,进入时钟缓存窗口,如图4-116所示。默认配置为DCM输出添加全局时钟缓存以保证良好的时钟特性。如果设计全局时钟资源,用户亦可选择“Customize buffers”自行编辑输出缓存。一般选择默认配置即可。 图4-116 DCM模块时钟缓存配置向导界面 <4> 点击“Next”,进入时钟频率配置窗口,如图4-117所示。键入输出频率的数值,或者将手动计算的分频比输入。最后点击“Next”,“Finish”即可完成DCM模块IP Core的全部配置。本例直接键入输出频率为75MHz即可。 图4-117 指定 DCM 模块的输出频率 <5> 经过上述步骤,即可在源文件进程中看到“my_dcm.xaw”文件。剩余的工作就是在设计中调用该DCM IP Core,其例化代码如下: module dcm_top( CLKIN_IN, RST_IN, CLKFX_OUT, CLKIN_IBUFG_OUT, CLK0_OUT, LOCKED_OUT); input CLKIN_IN; input RST_IN; output CLKFX_OUT; output CLKIN_IBUFG_OUT; output CLK0_OUT; output LOCKED_OUT; mydcm dcm1( .CLKIN_IN(CLKIN_IN), .RST_IN(RST_IN), .CLKFX_OUT(CLKFX_OUT), .CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT), .CLK0_OUT(CLK0_OUT), .LOCKED_OUT(LOCKED_OUT) ); endmodule <6> 上述代码经过综合Synplify Pro综合后,得到的RTL级结构图如图4-118所示。 图4-118 DCM模块的RTL结构示意图 上述代码经过ModelSim仿真后,其局部仿真结果如图4-119所示。从中可以看出,当LOCKED_OUT信号变高时,DCM模块稳定工作,输出时钟频率CLKFX_OUT为输入时钟CLK_IN频率的1.5倍,完成了预定功能。需要注意的是,复位信号RST_IN是高有效。 图4-119 DCM的仿真结果示意图 在实际中,如果在一片FPGA内使用两个DCM,那么时钟从一个clk输入,再引到两个DCM的clk_in。这里,在DCM模块操作时,需要注意两点:首先,用CoreGen生成DCM模块的时候,clk_in源是内部的,不能直接连接到管脚,需要添加缓冲器;其次,手动例化一个IBUFG,然后把IBUFG的输入连接到两个DCM的clk_in。通常,如果没有设置clk_in 源为内部的,而是完全按照单个DCM的使用流程,就会造成clk_in信号有多个驱动。此时,ISE不能做到两个DCM模块输出信号的相位对齐,只能做到一个DCM的输出是相位对齐的。而时钟管脚到两个DCM的路径和DCM输出的路径都有不同的延时,因此如果用户对相位还有要求,就需要自己手动调整DCM模块在芯片中的位置。 4.6.3 Xilinx内嵌快存储器的使用 Xilinx公司提供了大量的存储器资源,包括了内嵌的块存储器、分布式存储器以及16位的移位寄存器。利用这些资源可以生成深度、位宽可配置的RAM、ROM、FIFO以及移位寄存器等存储逻辑。其中,块存储器是硬件存储器,不占用任何逻辑资源,其余两类都是Xilinx专有的存储结构,由FPGA芯片的查找表和触发器资源构建的,每个查找表可构成16 1位的分布式存储器或移位寄存器。一般来讲,块存储器是宝贵的资源,通常用于大 数据量的应用场合,而其余两类用于小数据量环境。 1.块存储器的组成和功能介绍 在Xilinx FPGA中,块RAM是按照列来排列的,这样保证了每个CLB单元周围都有比较接近的块RAM用于存储和交换数据。与块RAM接近的是硬核乘加单元,这样不仅有利于提高乘法的运算速度,还能形成微处理器的雏形,在数字信号处理领域非常实用。例如,在Spartan 3E系列芯片中,块RAM分布于整个芯片的边缘,其外部一般有两列CLB,如图4-120所示,可直接对输入数据进行大规模缓存以及数据同步操作,便于实现各种逻辑操作。 图4-120 Spartan3E系统芯片中块RAM的分布图 块RAM几乎是FPGA器件中除了逻辑资源之外用得最多的功能块,Xilinx的主流 FPGA芯片内部都集成了数量不等的块RAM硬核资源,速度可以达到数百兆赫兹,不会占用额外的CLB资源,而且可以在ISE环境的IP核生成器中灵活地对RAM进行配置,构成单端口RAM、简单双口RAM、真正双口RAM、ROM(在RAM中存入初值)和FIFO等应用模式,如图4-121所示。同时,还可以将多个块RAM通过同步端口连接起来构成容量更大的块RAM。 图4-121 块RAM组合操作示意图 1)单端口RAM模式 单端口RAM的模型如图4-122所示,只有一个时钟源CLK,WE为写使能信号,EN为单口RAM使能信号,SSR为清零信号,ADDR为地址信号,DI和DO分别为写入和读出数据信号。 图4-122 Xilinx单端块RAM的示意模型 单端口RAM模式支持非同时的读写操作。同时每个块RAM可以被分为两部分,分别实现两个独立的单端口RAM。需要注意的是,当要实现两个独立的单端口RAM模块时,首先要保证每个模块所占用的存储空间小于块RAM存储空间的1/2。在单端口RAM配置中,输出只在read-during-write模式有效,即只有在写操作有效时,写入到RAM的数据才能被读出。当输出寄存器被旁路时,新数据在其被写入时的时钟上升沿有效。 2)简单的双端口RAM 简单双端口RAM模型如图4-123所示,图中上边的端口只写,下边的端口只读,因此这种RAM也被称为伪双端口RAM(Pseudo Dual Port RAM)。这种简单双端口RAM模式也支持同时的读写操作。 图4-123 Xilinx简单双端口块RAM的示意模型 块RAM支持不同的端口宽度设置,允许读端口宽度与写端口宽度不同。这一特性有着广泛地应用,例如:不同总线宽度的并串转换器等。在简单双端口RAM模式中,块RAM具有一个写使能信号wren和一个读使能信号rden,当rden为高电平时,读操作有效。当读使能信号无效时,当前数据被保存在输出端口。 当读操作和写操作同时对同一个地址单元时,简单双口RAM的输出或者是不确定值,或者是存储在此地址单元的原来的数据。 3)真正双端口RAM模式 真正双端口RAM模型如图4-124所示,图中上边的端口A和下边的端口B都支持读写操作,WEA、WEB信号为高时进行写操作,低为读操作。同时它支持两个端口读写操作的任何组合:两个同时读操作、两个端口同时写操作或者在两个不同的时钟下一个端口执行写操作,另一个端口执行读操作。 图4-124 Xilinx真正双端口块RAM的示意模型 真正双端口RAM模式在很多应用中可以增加存储带宽。例如,在包含嵌入式处理器MiroBlaze和DMA控制器系统中,采用真正双端口RAM模式会很方便;相反,如果在这样的一个系统中,采用简单双端口RAM模式,当处理器和DMA控制器同时访问RAM时,就会出现问题。真正双端口RAM模式支持处理器和DMA控制器同时访问,这个特性避免了采用仲裁的麻烦,同时极大地提高了系统的带宽。 一般来讲,在单个块RAM实现的真正双端口RAM模式中,能达到的最宽数据位为36比特*512,但可以采用级联多个块RAM的方式实现更宽数据位的双端口RAM。当两个端口同时向同一个地址单元写入数据时,写冲突将会发生,这样存入该地址单元的信息将是未知的。要实现有效地向同一个地址单元写入数据,A端口和B端口时钟上升沿的到来之间必须满足一个最小写周期时间间隔。因为在写时钟的下降沿,数据被写入块RAM中,所以A端口时钟的上升沿要比B端口时钟的上升沿晚到来1/2个最小写时钟周期,如果不满足这个时间要求,则存入此地址单元的数据无效。 4)ROM模式 块RAM还可以配置成ROM,可以使用存储器初始化文件(.coe)对ROM进行初始化,在上电后使其内部的内容保持不变,即实现了ROM功能。 5)FIFO模式 FIFO即先入先出,其模型如图4-125所示。在FIFO具体实现时,数据存储的部分是采用简单双端口模式操作的,一个端口只写数据而另一个端口只读数据,另外在RAM(块RAM和分布式RAM)周围加一些控制电路来输出指示信息。FIFO最重要的特征是具备“满(FULL)”和“空(EMPTY)”的指示信号,当FULL信号有效时(一般为高电平),就不能再往FIFO中写入数据,否则会造成数据丢失;当EMPTY信号有效时(一般为高电平),就不能再从FIFO中读取数据,此时输出端口处于高阻态。 图4-125 Xilinx FIFO模块的示意模型 2.块RAM IP Core的使用 块RAM已在本书第3章有过介绍,这里就不再赘述。 3.ROM存储器IP Core的使用 对于ROM模块,主要是生成相应的.coe文件。下面以一个实例介绍如何借助MATLAB生成ROM的.coe文件。 例4-8 生成定点正余弦波形数值,形成.coe文件并加载到块ROM中。 整体过程主要分为下面的3步。 首先,利用MATLAB计算出正余弦波形的浮点值,并量化16比特的定点波形数值: x= linspace(0,6.28,1024); //在区间[0,6.28]之间等间隔地取1024个点 y1=cos(x); //计算相应的正余弦值 y2=sin(x); //由于正余弦波形的值在[0,1]之间,需要量化成16比特,先将数值放大 y1=y1*32678; y2=y2*32768; //再将放大的浮点值量化,并写到存放在C盘的文本中 fid = fopen('c:/cos_coe.txt', 'wt'); fprintf(fid, '%16.0f\\n', y1); //在写文件的时候量化成16比特 fclose(fid) fid = fopen('c:/sin_coe.txt', 'wt'); fprintf(fid, '%16.0f\\n', y2); fclose(fid) 其次,生成coe文件。在C盘根目录下,将cos_coe.txt和sin_coe.txt的后缀改成.coe,打开文件,把每一行之间的空格用文本的替换功能换成逗号“,”,并在最后一行添加一个分号“;”。最后在文件的最开始添加下面两行: memory_initialization_radix=10; memory_initialization_vector = 然后保存文件退出。 最后,将coe文件加载到BLOCKROM所生成的ROM中。新建一个BLOCKRAM的IP core,其位置为“Memories & Storage Elements RAMs & ROMS Block Memory Generator v2.4”,在第一页选择single port rom,在第二页选择位宽为16、深度为1024,在第三页下载coe文件,如图4-126所示,然后双击“Finish”,完成IP core的生成。如果coe文件生成的不对,图中用椭圆标志之处是红色的,coe文件错误的类型主要有数据基数不对和数据的长度不对这两类。 图4-126 块ROM加载coe文件的用户配置界面 第6节 Xilinx FPGA芯片底层单元的使用2 4.6.4 硬核乘加器的使用 随着FPGA芯片容量的提高和工艺的发展,很多FPGA内部都内嵌了硬件乘加器,所以FPGA内部的乘法器就有两种实现方式:硬核乘法器的实现和用逻辑单元搭建的乘法器。目前由于内嵌了大量的硬核乘法器,FPGA在数字信号处理系统方面的成本和功耗性能已经超越了专用的DSP处理器。 1. 硬核乘加器的组成和功能介绍 硬核乘加器是Xilinx XtremeDSP解决方案的核心组成部分,从而可以独立实现500MHz 的性能,或在整合到一列中时实现 DSP 功能,支持40多个动态控制的操作模式,包括乘法器、乘法器-累加器、乘法器-加法器/减法器、三输入加法器、桶形移位器、 宽总线多路复用器或宽计数器,其组成结构如图4-127所示。此外,级联硬核乘加器,无需使用 FPGA 逻辑和路由资源。 图4-127 硬核乘加器的组成结构 图4-127中的OPMODE是乘加器工作模式配置输入,可在ISE中通过软件方式指定。硬核乘加器的乘法器和加法器可以单独使用,但对于一个乘加器资源,只使用了其乘法器或加法器,则另外的加法器或乘法器就不能再被使用。不同系列芯片中乘加器的特点略有不同,从整体而言,都具有以下特点: • 18位 18位,两个补码乘法器具有完全准确的36位结果、符号可以扩展到48位。 • 三输入、灵活的48位加法器/减法器,具有可选的寄存器累加反馈。 • 40多个动态用户控制器操作模式,使乘加器的功能适应从一个时钟周期到下一个时钟周期的变化。 • 级联的18位B总线,支持输入取样传递。 • 级联的48位p总线,支持部分结果的输出传递。 • 多精度乘法器和算法支持17位操作数右移位,以对准宽乘法器的部分乘积(并行或顺序乘法)。 • 对称智能舍入支持更高的计算精度。 • 控制和数据信号使用的、能够提高性能的流水线选项,可以通过配置位来进行选择。 • 输入端口“C”通常用作乘、加、进位的三操作数加或灵活的舍入模式。 • 独立的复位和时钟,实现了控制和数据寄存器。 2. 硬核乘法器IP Core的使用 硬核乘法器IP Core可以完成有符号数、以及无符号数的乘法,还能够完成输出数据的位宽截取,支持流水线操作,功能强大。其用户操作界面如图4-128所示,点击“Next”按键进入下一页,可以让用户选择是使用FPGA芯片上的硬乘法器(Use Mults),还是用Slice来构建乘法器(Use LUTs)。 图4-128 乘法器IP core用户操作界面 乘法器具有丰富的控制信号,其详细说明见下文。 A:乘法器的一个输入操作数,在使用时应当确定其位宽,其位宽可以在右边的端口位宽编辑框可以输入,并且可以有符号数、无符号数的两种选择。 B:乘法器的一个输入操作数,在使用时应当确定其位宽,其位宽可以在右边的端口位宽编辑框可以输入,而且可以与A口的输入操作数位宽不同。可以有符号数、无符号数的两种选择。(注:乘法器可以只接收A口的输入信号,而与一常数相乘,此常数可以为固定的或可重导入的。对于可重导入数据(RCCM)情况中,此常数可以在B口重新导入而得到改变。) CLK:乘法器的工作时钟。上升沿有效。 CE:输入信号,指示时钟是否有效。 ND:握手信号。 ACLR:异步清零信号。 SCLR:同步清零信号。 LOADB:当RCCM时才有效。当此信号为高时,B端口新的输入可以重新写入计算模块的存储单元。 SWAPB:当RCCM时才有效。当此信号为高时,在计算模块的存储单元已存有的多个常数中进行选择。 RDY:输出的握手信号,当其变高时表明数据有效。 RFD:握手信号,在其变高后的下一个时钟上升沿数据有效。 O:异步输出信号,位宽根据输入信号的位宽而定。 Q:同步输出信号,位宽根据输入信号的位宽而定。 LOAD_DONE:当RCCM时才有效,指示重新导入数据的过程完成。 例4-9 使用IP Core实例化一个16位乘法器 IP Core直接生成的乘法器的Verilog模块接口为: module multiply(sclr, rfd, rdy, nd, clk, a, b, q); input sclr; output rfd; output rdy; input nd; input clk; input [17 : 0] a; input [17 : 0] b; output [35 : 0] q; …… endmodule 在使用时,直接调用multiply模块即可,如: module multiply1 (sclr, rfd, rdy, nd, clk, a, b, q); input sclr, nd, clk; output rfd, rdy; input [15 : 0] a, b; output [31 : 0] q; multiply multiply1(.sclr(sclr), .rfd(rfd), .rdy(rdy), .nd(nd), .clk(clk), .a(a), .b(b), .q(q)); endmuodule 上述程序经过Synplify Pro综合后,得到的RTL结构如图4-129所示。 图4-129 乘法器IP Core综合后的RTL结构图 经过仿真测试得到的功能波形图如图4-130所示,正确地实现了乘法功能。 图4-130 乘法器IP core的仿真波形 3. 硬核乘加器IP Core的使用 硬核乘加器在乘法器后面级联了一个可控加法器,都可工作在芯片的最高工作频率。下面给出一个应用实例。 例4-10 使用硬核乘加器完成两路输入数据的相乘,并将每8个乘积结果累加后送出。其中输入数据为16比特,工作频率为50MHz。 1)在工程中添加硬核乘加器的IP Core文件,位于“FPGA Features and Design” “XtremeDSP Slice” “Multiply Accumulator v9.1i”。 2)配置IP Core参数。输入数据位宽设为16比特,且输入输出不与其余的DSP Slice级联,输出位宽设置为19比特,如图4-131所示,点击“Next”进入下一页;无进位选项,且只选择加法输入,OPMODE 模式设置为“Normal accumulator mode”,如图4-132所示,点击“Next”进入下一页;A、B流水线都设为1,其余设置如图4-133所示,点击“Next”进入下一页;最后一页为乘加器的配置参数列表,如图4-134所示,点击“Finish”按键,即可完成全部配置。 图4-131 乘法器IP core的配置界面(1) 图4-132 乘法器IP core 的配置界面(2) 图4-133 乘法器IP core的配置界面(3) 图4-134 乘法器IP core的配置界面(4) 3)在过程窗口中点击“View HDL Instantiation Template”命令,可查阅其代码例化模版,如下所列: muladder instance_name ( .A_IN(A_IN), .B_IN(B_IN), .CE_IN(CE_IN), .CLK_IN(CLK_IN), .LOAD_IN(LOAD_IN), .RST_IN(RST_IN), .P_OUT(P_OUT) ); 4)调用该IP Core完成设计,代码如下: module my_muladder(clk_50MHz, reset, ce, dina, dinb, dout); input clk_50MHz; input reset; input ce; input [15:0] dina; input [15:0] dinb; output [34:0] dout; reg [34:0] dout; wire [34:0] p_out; reg load = 0; reg [2:0] cnt = 0; always @(posedge clk_50MHz) begin if(reset) begin cnt <= 0; load <= 0; dout <= 0; end else begin cnt <= cnt + 1'b1; if(cnt == 0) load <= 1'b0; //直通加法器 else load <= 1'b1; //load=1累加 if(cnt == 2) dout <= p_out; else dout <= dout; end end muladder muladder( .A_IN(dina), .B_IN(dinb), .CE_IN(ce), .CLK_IN(clk_50MHz), .LOAD_IN(load), .RST_IN(reset), .P_OUT(p_out) ); endmodule 上述程序经过Synplify Pro综合后,得到的RTL结构如图4-135所示。 图4-135 乘加器应用程序的RTL结构图 经过仿真测试得到的功能波形图如图4-136所示,可以看到本例正确地实现了8个乘积结果累加的功能。 图4-136 乘加器应用程序的仿真结果 4.7 本章小结 本章详细介绍了基于ISE的FPGA设计流程以及多个辅助工具(XST、XPower、PACE、ModelSim、Synplify以及MATLAB)的使用方法。首先介绍了ISE软件主要特性及其安装流程,然后介绍了如何通过ISE完成FPGA设计,详细介绍了综合、仿真以及实现的软件操作和XST、XPower、PACE等工具的基本操作。之后,简单介绍了Synplify Pro和ModelSim SE的安装流程,并介绍如何在ISE关联Synplify Pro和ModelSim SE 的使用方法以及和ISE的联合开发流程。再次,介绍了MATLAB和ISE的联合开发模式,其中利用MATLAB来辅助ISE开发是目前流行的设计方法之一,也是本书所强调的重点。最后,介绍了Xilinx FPGA底层单元(DCM、块RAM以及硬核乘加器)的原理和使用方法。鉴 于篇幅,不可能对以上所提及软件的其他功能进行详细介绍,读者应该在实际工作中学习并熟练掌握。 因篇幅问题不能全部显示,请点此查看更多更全内容