芯片原厂必学课程 - 第六篇章 - FPGA 设计篇
06-02 FPGA 开发流程
新芯设计:专注,积累,探索,挑战
文章目录
引言
FPGA 开发流程,指的就是基于 EDA 自动化工具对 FPGA 芯片进行详细的开发过程,FPGA 开发流程不同于芯片的制造流程,区分于 IC 设计制造流程
例如,基于 ASIC 标准单元与基于 FPGA 的 APR 自动布局布线的区别在于 FPGA 内部的逻辑单元和走线资源都是确定不变的,布局布线工具只是完成如何基于这些资源来令整个设计收敛,而基于 ASIC 标准单元的 APR 的模块位置和走线资源都是自己设计调整的,灵活性更大,可以更好地完成设计的收敛
FPGA 开发流程主要包括了电路设计、设计输入、综合、布局布线、编程配置
五大主干,其中,还有功能仿真、静态仿真、时序仿真
三大仿真,以及综合约束、布局布线约束
两大约束等等,如下所示:
NOTES:本文来自《芯片原厂必学课程 - 第六篇章 - FPGA 设计篇》技术专栏
🌏 一、电路设计(FPGA Design)
在电路设计之前,首先要进行的是算法的设计与验证、方案论证、架构设计和 FPGA 芯片选型等等准备工作;算法工程师可以在 PYTHON 或 MATLAB 设计中完成,而至于算法的来源通常是基于特定的市场需求来开发的,这个就不在本次的讨论之中了
系统工程师根据具体的任务要求,如系统的指标、算法复杂度、芯片成本、功能性和稳定性、性能(延时和主频)和芯片本身的各种资源、功耗等等方面进行权衡(红色加粗部分也是数字电子系统的五大设计目标),制定合理的设计方案(浮点定点、设计优化)和合适的 FPGA 器件类型(CYLONE、SPARTAN、ARTIX、VIRTEX、KINTEX、ZYNQ、ZYNQ ULTRASCALE+)
电路设计方法分为自底向上和自顶向下的设计方法,通常都采用自顶向下的设计方法,即从系统设计开始,逐渐向子系统设计、模块设计、器件设计、版图设计等等更加物理的层次推进,直到可以直接使用 EDA 元件库为止,能够先勾勒出来电路了,才开始 Coding(记住,Coding Style 也是非常重要的)
🌏 二、设计输入(Design Entry)
设计输入指的是以开发软件要求的设计方式表达出来具体的电路设计,可以是电路设计图或者硬件描述语言,最常见的设计输入的表达方式为 IP 核、原理图(Schematic)和 HDL 文本输入
这里的 IP 按照来源的不同可以分为三类,第一种是来自前一个设计创建的模块(Design by Yourself),第二种是 FPGA 厂家,第三种就是来自 IP 厂商,而按照产品交付的形式,IP 核又分为:
✅ 软核:HDL or NETLIST 形式的功能块,如 MICROBLAZE 软核
✅ 硬核:LAYOUT 形式,提供了设计的最终阶段产品,如 ZEDBOARD 的 ARM CORTEX-A9
✅ 固核:NETLIST 形式,完成了综合与布局布线的功能块,只能基于特定芯片的 IP 核
🌏 三、综合(Synthesis)
无论是什么样的设计输入,最终都要通过综合来生成统一的网表形式,从而与 FPGA 硬件资源互相匹配,例如,FPGA 是基于 LUT 结构的,那么就需要综合出一个基于 LUT 的门级网表文件(不同于 IC 的综合)
IC 综合指的是从高级抽象层次的设计描述自动转化为较低层次描述的过程,IC 综合器能够基于 SCHEMATIC 或者 VERILOG 来转换成实际的芯片电路,编译成由与或阵列、RAM、DFF 等逻辑单元组成的电路结构的门级网表文件,这是一个 RTL - to - Netlist 的过程
综合包括编译、映射和优化,编译就是 HDL → 门级网表,映射就是门级网表 → LUT,优化就是优化设计
在 ALTERA 的开发流程中,编译和映射的过程称之为综合,而在 XILINX 的开发流程中,由设计输入得到门级网表的过程称之为综合,对于 FPGA 本身而言,综合就是逻辑综合器根据约束条件把 Verilog HDL 或 VHDL 描述的 RTL 级设计,转换成可与 FPGA/CPLD 的门阵列基本结构相映射的网表文件
🌏 四、布局布线(Place & Route)
对于实现(Implementation),指的就是通过配置综合生成的门级网表到具体的 FPGA 芯片上,而布局布线就是其中最重要的过程
Vivado 中的实现具体如下所示:分为设计初始化(Design Initialization)、优化设计(Opt Design)、功耗优化设计(Power Opt Design)、布局设计(Place Design)、后布局功耗优化设计(Post-Place Power Opt Design)、后布局物理优化设计(Post-Place Phys Opt Design)、布线设计(Route Design)、后布线物理优化设计(Post-Route Phys Opt Design)、生成比特流(Write Bitstream)
✅ 布局布线:指的是将综合生成的电路门级网表映射到具体的目标器件中实现,最终生成可下载文件的过程
✅ 布局:指的是利用器件内部逻辑资源的相应位置来存放各个逻辑设计,令其易于连线
✅ 布线:指的是利用器件的布线资源来完成各功能模块之间和反馈互连信号之间的连接
🌏 五、约束(Constraint)
约束分为综合约束(一级约束)和布局布线约束(二级约束),综合约束如资源共享约束(不同的约束将会导致生成不同性能的电路),布局布线约束又可以分为引脚约束、时序约束
约束,就是对这些操作环节定制规则,定制条件,比如引脚约束和时序约束;通常开发环境会有个默认的约束,这些默认的设置对大部分情况下还是适用的,但是通常布局布线约束中的 I/O 约束是我们每一个工程都必须给定的
############### TIMING CONSTRAINTS ###############
create_clock -name i_sys_clk -period 5.00 -waveform {0.00 2.50} [get_ports sys_clk_p]
set_clock_groups -asynchronous -group [get_clocks "i_sys_clk"]
create_clock -name SWD_TCK -period 100.00 -waveform {0.00 50.00} [get_ports SWD_TCK]
set_clock_groups -asynchronous -group [get_clocks "SWD_TCK"]
set_input_delay -clock [get_clocks SWD_TCK] 60 [get_ports SWD_TMS]
set_output_delay -clock [get_clocks SWD_TCK] 30 [get_ports SWD_TMS]
create_clock -name vga_dclk_o -period 40.00 -waveform {0.00 20.00} [get_ports vga_dclk_o]
set_clock_groups -asynchronous -group [get_clocks "vga_dclk_o"]
set_input_delay -clock [get_clocks vga_dclk_o] 24 [get_ports vga_data_o[*]]
set_input_delay -clock [get_clocks vga_dclk_o] 24 [get_ports vga_hsync_o]
set_input_delay -clock [get_clocks vga_dclk_o] 24 [get_ports vga_vsync_o]
set_input_delay -clock [get_clocks vga_dclk_o] 24 [get_ports vga_de_o]
set_output_delay -clock [get_clocks vga_dclk_o] 12 [get_ports vga_data_o[*]]
set_output_delay -clock [get_clocks vga_dclk_o] 12 [get_ports vga_hsync_o]
set_output_delay -clock [get_clocks vga_dclk_o] 12 [get_ports vga_vsync_o]
set_output_delay -clock [get_clocks vga_dclk_o] 12 [get_ports vga_de_o]
create_clock -name cmos_pclk_i -period 40.00 -waveform {0.00 20.00} [get_ports cmos_pclk_i]
create_clock -name cmos_xclk_o -period 40.00 -waveform {0.00 20.00} [get_ports cmos_xclk_o]
create_clock -name QSPI_FLASH_SCK -period 40.00 -waveform {0.00 20.00} [get_ports QSPI_FLASH_SCK]
set_clock_groups -asynchronous -group [get_clocks "cmos_pclk_i"]
set_clock_groups -asynchronous -group [get_clocks "cmos_xclk_o"]
set_clock_groups -asynchronous -group [get_clocks "QSPI_FLASH_SCK"]
set_false_path -from [get_ports sys_rst_n]
set_false_path -from [get_pins u_arm_video_soc_wrapper/*] -to [get_pins *_ila_r_reg/D]
set_false_path -from [get_pins u_arm_video_soc_wrapper/*] -to [get_pins *_ila_r*]
set_false_path -from [get_pins *] -to [get_pins *_ila_r_reg/D]
set_false_path -from [get_pins *] -to [get_pins *_ila_r*]
🌏 六、仿真(Simulation)
仿真指的是对设计电路的一种功能验证,其包括了功能仿真、静态仿真和时序仿真,如下所示:
✅ 功能仿真:指的是对 HDL 代码仿真和测试,又称之为 RTL 仿真或者前仿,是在编译之前对设计的电路进行逻辑功能验证,仿真不带任何的延时信息,是理想的,例如对于一个寄存器的 D -> Q 传输延时等价于 0
✅ 静态仿真:指的是对综合之后的 LUT 门级网表进行仿真,又称之为门级仿真或者综合后仿,仿真会注入综合生成的 SDF 标准延时文件,具备详细的门延时,不具备具体的线延时,和布局布线后仿存在一定的差距
✅ 时序仿真:指的是对已完成具体器件的选择同时完成布局布线的流程之后进行的包含延时的仿真,又称之为布局布线后仿,仿真会注入布局布线生成的 SDF 标准延时文件,来完整地检测整个芯片的时序情况,也就是检查芯片设计是否满足时序约束条件或者器件特定的时序规则,如建立时间、保持时间等等,布局布线后防包含的延时信息最精确,是能够较好地反映芯片的实际工作情况的
从验证完整性而言,前端仿真和后端仿真均需要在项目中实施,而它们侧重的目标也不太一样,如下所示:
✅ 前端仿真:主要是为了检测出功能逻辑的缺陷
✅ 后端仿真:主要是为了检测出实际门级电路中由于延时问题可能导致采样失败从而产生的功能缺陷
🌏 七、编程配置(Program & Configuration)
编程配置就是生成 bitfile 比特流文件同时载入 FPGA 芯片中的一个过程,这里存在一些概念如下所示:
✅ 下载:指的是对 PLD 器件载入布局布线之后的编程文件的过程
✅ 编程:指的是对基于 EEPROM 工艺的非易失结构 CPLD 器件的下载,通常是 bitfile 编程数据下载到 FPGA 芯片中的过程
✅ 配置:指的是基于 SRAM 工艺结构的 FPGA 器件的下载过程