1.2 设计方法的演变
FPGA的设计方法是伴随着芯片架构的演变而演变的。在FPGA诞生初期,由于其内部资源较为单一,因此仅仅扮演着胶合逻辑的角色,在整个系统中只能起到协同作用。此时的设计方法也比较简单,如图1-24所示。设计输入使用RTL(Register Transfer Level,寄存器传输级)描述方式,功能仿真也称为前仿或行为级仿真,以验证设计功能是否正确;综合后仿真(Post Synthesis Simulation)则用于验证综合后的电路功能是否正确;时序仿真又称为后仿,仿真时反标了门级延迟和布线延迟信息,用于验证布线后的电路功能是否正确。一般情况下,无论是综合后仿真还是时序仿真,相比于行为级仿真都更为耗时,尤其是当设计规模比较大时,因此,通常当设计出现问题时才会执行综合后仿真和时序仿真。
随着FPGA内部资源越来越丰富,嵌入了BRAM,增大了存储空间,嵌入了乘加器,增强了计算能力,嵌入了高速收发器,提升了数据传输带宽,进行FPGA设计时要结合算法特征,分析哪些算法适合在FPGA上实现,以充分发挥FPGA的性能,从而形成如图1-25所示的开发流程。这里,软/硬件分割是设计的关键点。总体而言,数据流比较单一、运算密集但比较规整的算法(如FIR数字滤波器、FFT等)就非常适合在FPGA上实现。进一步划分,则要采取“缓存-计算-缓存”的模式,以适配FPGA的架构。而分支较多、判断条件复杂、数据路径形成反馈回路的算法更适合在CPU上实现。同时,FPGA更适合处理定点数据类型(尽管目前FPGA也支持浮点数据类型)。图1-25中FPGA部分的顶层功能验证过程与图1-24一致,可采用Xilinx开发工具ISE(Integrated Software Environment)完成。
图1-24
图1-25
针对FPGA子系统,要从3个角度考虑,即物理级设计规范、时序设计规范和硬件设计规范,如图1-26所示。其中,物理级设计规范是为芯片选型服务的,根据资源评估、功耗预算和时钟频率确定芯片型号。时序设计规范是指在确定时钟网络拓扑结构(时钟管脚位置、输入时钟频率、输出时钟频率、全局时钟/区域时钟)的基础上,规划I/O时序(尤其是源同步设计和系统同步设计)和跨时钟域路径时序,基于此描述时序约束。硬件设计规范则是指根据数据流合理规划RTL代码层次结构,在此基础上进行各子模块的开发,最终为时序收敛服务。
图1-26
在硬件设计规范中,RTL代码层次结构是重点,这对综合、布局布线和时序收敛都会产生直接影响,应遵循的原则如下。
• 需要实例化的输入/输出单元(如IDDR、ODDR、ISERDES、OSERDES等)应尽可能靠近设计顶层,尽管IBUF、OBUF、IOBUF和OBUFT可由综合工具自动推断出来,但要确保IOBUF、OBUFT的使能信号和输入/输出信号在同一层次,以确保工具正确推断。
• 将时钟生成模块(通常采用IP Clocking Wizard生成时钟,不建议使用MMCM或PLL原语)放在顶层,方便其他模块使用时钟。
• 在层次边界添加寄存器,确保关键模块是寄存器输出,这样可将关键路径隔离在单一层次或模块之内,对于修复时序违例及设计调试大有裨益。
• 确保需要手工布局的模块在同一层次之内。
图1-27给出了基于上述原则而形成的层次结构,图中,每个子模块的阴影部分表示输出寄存器。
图1-27
随着FPGA中嵌入ARM核构成SoC芯片,如Zynq-7000,SoC的设计方法应运而生,如图1-28所示。在软/硬件分割阶段,根据算法特征和系统需求(是否运行操作系统)将系统分为两大模块:硬件模块(在PL上实现)和软件模块(在PS上实现)。硬件开发依然采用传统的FPGA开发模式。软件开发则需要借助Xilinx开发工具SDK(Software Development Kit)。
图1-28
芯片架构和设计方法的演变也催生了Xilinx新一代开发工具Vivado的问世,随之问世的还有高层次综合工具Vivado HLS(现更名为Vitis HLS),Vivado反过来又影响了设计方法。如图1-29所示,Vivado提出了以IP为核心的设计理念,进一步强调了设计的可复用性。在设计输入阶段,设计源文件可以是传统的RTL代码,可以是C/C++或OpenCL模型(采用Vitis HLS开发),也可以是Simulink下的AIE模型、HDL模型(原System Generator)或HLS模型(这3个模型隶属于同一个开发工具Vitis Model Composer,该开发工具嵌入在Simulink中)。其中,以高级语言(C/C++或OpenCL)描述的模型和以Vitis Model Composer搭建的模型均为高抽象度模型,需要借助相应的工具将其转化为HDL(Hardware Description Language)代码。而Vitis HLS或Vitis Model Composer最终都将其封装为IP,同时,传统的RTL代码描述的模型也可以通过IP封装器(IP Packager)封装为IP,这些IP均可直接嵌入Vivado IP Catalog当作常规IP使用,也可以直接在IP集成器(IP Integrator,IPI)中以模块方式使用。这样,在IPI中进行设计开发就像搭积木一样。基于IPI开发设计形成的文件为.bd文件,为了实现IPI模型的可复用,Vivado又引入了BDC(Block Design Container)功能,即可以在一个IPI模型中实例化另一个IPI模型。在设计调试方面,可以借助VLA(Vivado Logic Analyzer,Vivado逻辑分析仪)。VLA取代了ISE时代的ChipScope。使用VLA需要在设计中添加ILA(Integrated Logic Analyzer)或VIO(Virtual Input/Output)。有3种方式可以完成这一操作:①在RTL代码中实例化ILA和VIO(VIO仅支持代码实例化);②在综合后的网表中插入ILA;③在布线后的网表中采用ECO(Engineering Change Order,工程变更命令)方式修改ILA。
图1-29
对比图1-29和图1-24不难发现,Vivado要求在综合之后就要对设计进行时序分析,确保建立时间收敛或接近收敛,这实际上是一个重大变化。这意味着若综合后依然存在建立时间违例,那么布线后时序收敛的可能性也不会大。
在软件开发方面,Xilinx于2019年推出了统一的软件开发平台Vitis,取代了原有的SDAccel,同时,其功能进一步增强。SoC、MPSoC、AIE均可在Vitis下进行开发。
无论工具如何推陈出新,功能如何变化,到目前为止,FPGA设计始终遵循的一个思路就是提高设计的可复用性。简而言之,对于一些常用模块,通过参数化处理,使其可以适配不同项目的需求,提高设计的可复用性。这样的好处是避免了重复开发,从而缩短开发周期,同时因为这些模块已经经过实际项目的验证,所以在功能和质量方面都有所保障。这其实就是用户自己开发的IP。我们把“可复用性”的理念进一步扩大,如图1-30所示。设计输入阶段,从RTL代码到C/C++代码,再到Model Composer模型,都可以做成参数化形式。相应的功能仿真阶段用到的HDL测试平台、C/C++测试平台和Model Composer测试平台也可以做成参数化形式。
图1-30
本书提供的很多VHDL代码均已做参数化处理,可以方便快捷地实现设计复用。