原文链接:
5.2 如何进行FPGA设计早期系统规划
作者:Ricky Su (www.rickysu.com)
这篇文章讲述了如何用工具提高效率的方法,适用程度因人而异。
Situation: 在对FPGA 设计进行最初步的系统规划的时候,需要进行模块划分,模块接口定义等工作。通常,我们起初会在纸上进行设计,到了一定阶段的定稿可能会输入Visio 等工具,方便在Team 内部交流和审阅。虽然在纸上我们可以很随意地书写,而用纸画的不方便就在于,如果想对某一个模块进行一些改动或者重画模块,那么常常因为留出的空余纸张不够,而导致拿一张新的白纸重新画一遍,比较浪费时间。对于电子化的Visio 来说,方便修改是好处,但他不是专为设计FPGA 系统而设计的,添加输入输出端口没那么方便,也不会根据定义的模块自动生成HDL文件。
HDLQuestion: 我们能不能使用更好软件进行系统规划呢?
Solution: 答案是可以的。下面以ISE 10.1 为例作说明:
1) 画一个空模块,仅定义端口 - 新建Schematic,选择Tools -> Symbol Wizard,里面可以定义Symbol名和端口属性。完成后生成sym 格式的Symbol。如果端口是一个bus,那么可以用A(4:0) 的形式。
2) 将Symbol 添加到原理图 - 在Schematic 的Symbol 页面,选择Categories 为工程文件夹,在Symbols列表中就可以看到刚刚新建的Symbol。将它添加到原理图中。
3) 重复1-2 步骤,建立所有Symbol,并连接端口。如果需要修改连线的名字或者模块的例化名,可以选择需要修改名字的元件然后按右键--> Object Properties --> 在Name/InstName 窗格中填入需要的名字。
4) 如需修改Symbol,可以直接在sym 文件中修改 - 可以按右键-> Add -> Pin 等等添加,也可以Copy已存在的Pin,然后改变PinName。但是ISE10.1 的Symbol Editor 对Add Pin 有一些Bug。因此在UltraEditor打开这个sym 文件,在里面修改可能是更好的办法。sym 文件格式很易懂。改变 Symbol 端口后需要UpdateSchematic。在点到Schematic 后会自动弹出Update 对话框。
5) 生成原理图对应的HDL 文件 - 点击"Sources in Project" 列表中的sch 文件,在"Process" 窗口选择"View HDL Functional Model"。这样会自动生成Schematic 对应的HDL 文件,其中例化了上面的各个模块。要改变HDL文件类型,可以改变Project 属性中的"Generated Simulation Language" 属性。
6) 生成Symbol 对应的HDL 文件 - 在打开一个sym 文件时,选择Tools -> Generate HDL Template from Symbol。此时可以选择生成VHDL 还是Verilog 的文件。
至此,我们已经生成了顶层文件和待开发的子模块文件,我们已经可以在它的基础上进行开发了。在开发过程中我们可能还会碰到这些问题:
1. 我想把设计图打印下来- 除了ISE 自带的打印功能外,要打印好看的图纸,还可以使用Synplify Pro或PlanAhead。由于以上流程生成的代码都是可综合的,带有端口信息的HDL 会被综合工具认为是一个blackbox的wrapper,因此我们可以用ISE 或Synplify 将这些代码综合,综合工具会生成比较好看的综合模块图(RTL Schematic)。除了可以用ISE 和Synplify 打开这些综合网表产生RTL Schematic 之外,也可以用PlanAhead 打开综合网表,它的Schematic 显示功能更为强大。
2. 我要修改某些模块的端口,并添加连线修改模块端口是否还需要在原来的Schematic 上编辑修改呢?这是仁者见仁智者见智的问题了。我个人在生成了带端口信息的HDL 后还是偏好修改HDL --> 综合 --> 在PlanAhead 中产生需要的连接图 --> 打印 --> 在打印稿上继续思考写写划划 --> 继续修改HDL 这样的流程。
5.3.综合和仿真技巧
作者:田耘/云创工作室
5.3.1 综合工具XST的使用
所谓综合,就是将HDL语言、原理图等设计输入翻译成由与、或、非门和RAM、触发器等基本逻辑单元的逻辑连接( 网表),并根据目标和要求( 约束条件) 优化所生成的逻辑连接,生成EDF 文件。XST 内嵌在ISE 3 以后的版本中,并且在不断完善。此外,由于XST 是赛灵思公司自己的综合工具,对于部分赛灵思芯片独有的结构具有更好的融合性。
完成了输入、仿真以及管脚分配后就可以进行综合和实现了。在过程管理区双击Synthesize-XST,如图5-1所示,就可以完成综合,并且能够给出初步的资源消耗情况。图5-2 给出了模块所占用的资源。
图5-1 设计综合窗口
图5-2 综合结果报告
综合可能有3 种结果:如果综合后完全正确,则在Synthesize-XST 前面有一个打钩的绿色小圈圈;如果有警告,则出现一个带感叹号的黄色小圆圈;如果有错误,则出现一个带叉的红色小圈圈。综合完成之后,可以通过双击View RTL Schematics 来查看RTL 级结构图,察看综合结构是否按照设计意图来实现电路。ISE 会自动调用原理图编辑器ECS 来浏览RTL 结构。对于一个计数器,其RTL 结构图如图5-3 所示,综合结果符合设计者的意图,调用了加法器和寄存器来完成逻辑。
图5-3 经过综合后的RTL级结构图
2.综合参数的设置
一般在使用XST 时,所有的属性都采用默认值。其实XST 对不同的逻辑设计可提供丰富、灵活的属性配置。下面对ISE9.1 中内嵌的XST 属性进行说明。打开ISE 中的设计工程,在过程管理区选中“Synthesis –XST”并单击右键,弹出界面如图5-4 所示。
图5-4 综合选项
由图5-4 可以看出,XST 配置页面分为综合选项(Synthesis Options)、HDL 语言选项(HDL Options) 以及赛灵思特殊选项(Xilinx Specific Options) 等三大类,分别用于设置综合的全局目标和整体策略、HDL 硬件语法规则以及赛灵思特有的结构属性。
1) 综合选项参数
综合参数配置界面如图5-4 所示,包括8 个选项,具体如下所列:
【Optimization Goal】:优化的目标。该参数决定了综合工具对设计进行优化时,是以面积还是以速度作为优先原则。面积优先原则可以节省器件内部的逻辑资源,即尽可能地采用串行逻辑结构,但这是以牺牲速度为代价的。而速度优先原则保证了器件的整体工作速度,即尽可能地采用并行逻辑结构,但这样将会浪费器件内部大量的逻辑资源,因此,它是以牺牲逻辑资源为代价的。
【Optimization Effort】:优化器努力程度。这里有【normal】和【high】两种选择方式。对于【normal】,优化器对逻辑设计仅仅进行普通的优化处理,其结果可能并不是最好的,但是综合和优化流程执行地较快。如果选择【high】,优化器对逻辑设计进行反复的优化处理和分析,并能生成最理想的综合和优化结果,在对高性能和最终的设计通常采用这种模式;当然在综合和优化时,需要的时间较长。
【Use Synthesis Constraints File】:使用综合约束文件。如果选择了该选项,那么综合约束文件XCF 有效。
【Synthesis Constraints File】:综合约束文件。该选项用于指定XST 综合约束文件XCF 的路径。
【Global Optimization Goal】:全局优化目标。可以选择的属性包括有【AllClockNets】、【Inpad To
Outpad】、【Offest In Before】、【Offest Out After】、【Maximm Delay】。该参数仅对FPGA 器件有效,可用于选择所设定的寄存器之间、输入引脚到寄存器之间、寄存器到输出引脚之间,或者是输入引脚到输出引脚之间逻
辑的优化策略。
【Generate RTL Schematic】:生成寄存器传输级视图文件。该参数用于将综合结果生成RTL 视图。
【Write Timing Constraints】:写时序约束。该参数仅对FPGA 有效,用来设置是否将HDL 源代码中用于控制综合的时序约束传给NGC 网表文件,该文件用于布局和布线。
【Verilog 2001】:选择是否支持Verilog 2001 版本。
HDL语言选项
HDL 语言选项的配置界面如图5-5 所示,包括16 个选项,具体如下所列:
图5-5 HDL语言选项的配置界面选项
【FSM Encoding Algorithm】:有限状态机编码算法。该参数用于指定有限状态机的编码方式。选项有【Auto】、
【One-Hot】、【Compact】、【Sequential】、【Gray】、【Johnson】、【User】、【Speed1】、【None】编码方式,默认为【Auto】编码方式。
【Safe Implementation】:将添加安全模式约束来实现有限状态机,将添加额外的逻辑将状态机从无效状态
调转到有效状态,否则只能复位来实现,有【Yes】、【No】两种选择,默认为【No】。
【Case Implementation Sytle】:条件语句实现类型。该参数用于控制XST 综合工具解释和推论Verilog 的
条件语句。其中选项有【None】、【Full】、【Parallel】、【Full-Parallel】,默认为【None】。 对于这四种选项,区别如下:(1)【None】,XST 将保留程序中条件语句的原型,不进行任何处理;(2)【Full】,XST 认为条件语句是完整的,避免锁存器的产生;(3)【Parallel】,XST 认为在条件语句中不能产生分支,并且不使用优先级编码器;(4)【Full-Parallel】,XST 认为条件语句是完整的,并且在内部没有分支,不使用锁存器和优先级编码器。
【RAM Extraction】:存储器扩展。该参数仅对FPGA 有效,用于使能和禁止RAM 宏接口。默认为允许使用RAM 宏接口。
【RAM Style】:RAM 实现类型。该参数仅对FPGA 有效,用于选择是采用块RAM 还是分布式RAM 来作为RAM 的实现类型。默认为【Auto】。
【ROM Extraction】:只读存储器扩展。该参数仅对FPGA 有效,用于使能和禁止只读存储器ROM 宏接口。默认为允许使用ROM 宏接口。
【ROM Style】:ROM 实现类型。该参数仅对FPGA 有效,用于选择是采用块RAM 还是分布式RAM 来作为ROM 的实现和推论类型。默认为【Auto】。
【Mux Extraction】:多路复用器扩展。该参数用于使能和禁止多路复用器的宏接口。根据某些内定的算法,对于每个已识别的多路复用/ 选择器,XST 能够创建一个宏,并进行逻辑的优化。可以选择【Yes】、【No】和【Force】
中的任何一种,默认为【Yes】。
【Mux Style】:多路复用实现类型。该参数用于胃宏生成器选择实现和推论多路复用/ 选择器的宏类型。可以选择【Auto】、【MUXF】和【MUXCY】中的任何一种,默认为【Auto】。
【Decoder Extraction】:译码器扩展。该参数用于使能和禁止译码器宏接口,默认为允许使用该接口。
【Priority Encoder Extraction】:优先级译码器扩展。该参数用于指定是否使用带有优先级的编码器宏单元。
【Shift Register Extraction】:移位寄存器扩展。该参数仅对FPGA 有效,用于指定是否使用移位寄存器宏单元。默认为使能。
【Logical Shifter Extraction】:逻辑移位寄存器扩展。该参数仅对FPGA 有效,用于指定是否使用逻辑移位寄存器宏单元。默认为使能。
【XOR Collapsing】:异或逻辑合并方式。该参数仅对FPGA 有效,用于指定是否将级联的异或逻辑单元合并成一个大的异或宏逻辑结构。默认为使能。
【Resource Sharing】:资源共享。该参数用于指定在XST 综合时,是否允许复用一些运算处理模块,如加法器、减法器、加/ 减法器和乘法器。默认为使能。如果综合工具的选择是以速度为优先原则的,那么就不考虑资源共享。
【Multiplier Style】:乘法器实现类型。该参数仅对FPGA 有效,用于指定宏生成器使用乘法器宏单元的方式。选项有【Auto】、【Block】、【LUT】和【Pipe_LUT】。默认为【Auto】。选择的乘法器实现类型和所选择的器件有关。
2) 赛灵思特殊选项
赛灵思特殊选项用于将用户逻辑适配到赛灵思芯片的特殊结构中,不仅能节省资源,还能提高设计的工作频率,其配置界面如图5-6 所示,包括10 个配置选项,具体如下所列。
图5-6 赛灵思指定的选项
【Add I/O Buffers】:插入I/O 缓冲器。该参数用于控制对所综合的模块是否自动插入I/O 缓冲器。默认为自动插入。
【Max Fanout】:最大扇出数。该参数用于指定信号和网线的最大扇出数。这里扇出数的选择与设计的性能有直接的关系,需要用户合理选择。
【Register Duplication】:寄存器复制。该参数用于控制是否允许寄存器的复制。对于高扇出和时序不能满足要求的寄存器进行复制,可以减少缓冲器输出的数目以及逻辑级数,改变时序的某些特性,提高设计的工作频率。默认为允许寄存器复制。
【Equivalent Register Removal】:等效寄存器删除。该参数用于指定是否把寄存器传输级功能等效的寄存器删除,这样可以减少寄存器资源的使用。如果某个寄存器是用赛灵思的硬件原语指定的,那么就不会被删除。默认为使能。
【Register Balancing】:寄存器配平。该参数仅对FPGA 有效,用于指定是否允许平衡寄存器。可选项有【No】、【Yes】、【Forward】和【Backward】。采用寄存器配平技术,可以改善某些设计的时序条件。其中【Forward】
为前移寄存器配平,【Backward】为后移寄存器配平。采用寄存器配平后,所用到的寄存器数就会相应地增减。默认为寄存器不配平。
【Move First Flip-Flop Stage】:移动前级寄存器。该参数仅对FPGA 有效,用于控制在进行寄存器配平时,是否允许移动前级寄存器。如果【Register Balancing】的设置为【No】,那么该参数的设置无效。
【Move Last Flip-Flop Stage】:移动后级寄存器。该参数仅对FPGA 有效,用于控制在进行寄存器配平时,是否允许移动后级寄存器。如果【Register Balancing】的设置为【No】,那么该参数的设置无效。
【Pack I/O Registers into IOBs】:I/O 寄存器置于输入输出块。该参数仅对FPGA 有效,用于控制是否将逻辑设计中的寄存器用IOB 内部寄存器实现。在赛灵思系列FPGA 的IOB 中分别有输入和输出寄存器。如果将设计中的第一级寄存器或最后一级寄存器用IOB 内部寄存器实现,那么就可以缩短IO 引脚到寄存器之间的路径,这通常可以缩短大约1~2ns 的传输时延。默认为【Auto】。
【Slice Packing】:优化Slice 结构。该参数仅对FPGA 有效,用于控制是否将关键路径的查找表逻辑尽量配置在同一个Slice 或者CLB 模块中,由此来缩短LUT 之间的布线。这一功能对于提高设计的工作频率、改善时序特性是非常有用的。 默认为允许优化Slice 结构。
【Optimize Instantiated Primitives】:优化已例化的原语。该参数控制是否需要优化在HDL 代码中已例化的原语。默认为不优化。
在代码编写完毕后,需要借助于测试平台来验证所设计的模块是否满足要求。ISE 提供了两种测试平台的建立方法,一种是使用HDL Bencher 的图形化波形编辑功能编写,另一种就是利用HDL 语言,相对于前者使用简单、功能强大。下面介绍基于Verilog 语言建立测试平台的方法。
首先在工程管理区将“Sources for”设置为Behavioral Simulation,在任意位置单击鼠标右键,并在弹出的菜单中选择“New Source”命令,然后选中“Verilog Test Fixture”类型,输入文件名为“test_test”,再点击“Next”进入下一页。这时,工程中所有Verilog Module 的名称都会显示出来,设计人员需要选择要进行测试的模块。
用鼠标选中test,点击“Next”后进入下一页,直接点击“Finish”按键,ISE 会在源代码编辑区自动显示测试模块的代码:
`timescale 1ns / 1ps
module test_test_v;
// Inputs
reg clk;
reg [7:0] din;
// Outputs
wire [7:0] dout;
// Instantiate the Unit Under Test (UUT)
test uut (
.clk(clk),
.din(din),
.dout(dout)
);
initial begin
// Initialize Inputs
clk = 0;
din = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
endmodule
由此可见,ISE 自动生成了测试平台的完整架构,包括所需信号、端口声明以及模块调用的完成。所需的工作就是在initial…end 模块中的“// Add stimulus here”后面添加测试向量生成代码。添加的测试代码如下:
forever begin
#5;
clk = !clk;
if(clk == 1)
din = din + 1;
else
din = din;
end
完成测试平台后。在工程管理区将“Sources for”选项设置为Behavioral Simulation,这时在过程管理区会显示与仿真有关的进程,如图5-7 所示。
图5-7 仿真过程示意图
选中图5-7 中Xilinx ISE Simulator 下的Simulate Behavioral Model 项,点击鼠标右键,选择弹出菜单的Properties项,会弹出如图5-8 所示的属性设置对话框,最后一行的Simulation Run Time 就是仿真时间的设置,可将其修改为任意时长,本例采用默认值。
图5-8 仿真属性设置对话框
仿真参数设置完后,就可以进行仿真了,直接双击ISE Simulator 软件中的Simulate Behavioral Model,则ISE 会自动启动ISE Simulator 软件,并得到如图5-9所示的仿真结果,从中可以看到设计达到了预计目标。
图5-9 test模块的仿真结果