第二章:FPGA基础与架构
各位同学,今天我们来聊聊FPGA的“五脏六腑”。
很多人觉得FPGA就是个可编程的芯片,插上电就能用。其实没那么简单。我刚开始接触FPGA时,也以为它就是一堆逻辑门的集合。直到我在一个高频交易项目中,为了把行情解析延迟从10纳秒压到5纳秒,才真正开始研究它的内部结构。
说白了,你得知道你的“武器”长什么样,才能用好它。
2.1 FPGA内部结构:四大金刚
FPGA内部主要由四种基本单元构成:LUT、FF、BRAM、DSP。我习惯叫它们“四大金刚”。
2.4 查找表(LUT)
LUT,全称Look-Up Table,查找表。你可以把它理解成一个“真值表”。
举个例子,你想实现一个与门(AND)。用LUT怎么做?其实就是把输入A和B的所有组合(00,01,10,11)对应的输出(0,0,0,1)提前存好。输入来了,直接查表输出。
嗯,这里要注意:现在的FPGA里,LUT通常是6输入的。也就是可以同时处理6个变量的任意逻辑函数。我在做交易信号处理时,经常用LUT来实现一些复杂的组合逻辑,比如条件判断、状态机跳转。
核心要点:LUT本质上是一个小型的RAM,用输入信号作为地址,输出就是该地址存储的值。
2.2 触发器(FF)
触发器,Flip-Flop,简称FF。它是FPGA里用来“记住”状态的元件。
你想想看,如果只有LUT,那FPGA只能做组合逻辑,没有记忆能力。有了FF,我们才能做时序逻辑——比如计数器、状态机、流水线。
每个LUT后面通常紧跟着一个FF。我做过一个项目,需要把数据流做深度流水线处理,那时候我才意识到FF的数量有多重要。有些算法逻辑复杂,但FF不够用,就得牺牲性能去复用资源。
个人经验:在写Verilog时,我习惯把always块里的敏感列表写清楚。曾经因为漏写了一个信号,导致综合出来的FF数量翻了一倍,时序直接崩了。
2.3 块RAM(BRAM)
BRAM,Block RAM,块状随机存取存储器。它是FPGA里用来存数据的“仓库”。
BRAM的典型大小是36Kb(或者18Kb)。你可以把它配置成单端口、双端口、甚至真双端口。在高频交易中,BRAM用得特别多——比如存储订单簿的快照、历史行情数据、或者作为FIFO的缓存。
我记得有一次,需要缓存1000笔逐笔成交数据。如果用LUT搭出来的分布式RAM,面积会大得吓人。换成BRAM,一个块就搞定了,还省电。
| 存储类型 | 容量 | 延迟 | 典型用途 |
|---|---|---|---|
| 分布式RAM(LUT实现) | 几十到几百bit | 低 | 小规模FIFO、寄存器堆 |
| BRAM | 18Kb / 36Kb | 中 | 大容量缓存、FIFO、查找表 |
| URAM(UltraRAM) | 288Kb | 高 | 超大容量存储、DDR替代方案 |
避坑指南:我曾经在项目里把BRAM的读延迟设成了1拍,结果读出的数据总是比预期晚一个时钟。后来才发现,BRAM的读操作默认是“读后写”模式,需要额外一拍才能拿到数据。嗯,这个坑踩过一次就不会再犯了。
2.4 DSP单元
DSP,Digital Signal Processing,数字信号处理单元。它是FPGA里专门用来做乘法和累加的“计算器”。
在高频交易中,DSP用得最多的地方就是计算各种指标——比如移动平均线、波动率、相关系数。这些计算本质上就是大量的乘法和加法。
一个DSP48E2(Xilinx 7系列)可以在一个时钟周期内完成一个25x18位的乘法,然后累加。我做过一个策略,需要同时计算10个不同周期的均线。如果用LUT搭乘法器,资源消耗会爆炸。用DSP,一个周期就搞定了。
性能数据:在Xilinx Ultrascale+上,DSP单元可以跑到700MHz以上。这意味着每秒钟可以做7亿次乘加操作。对于高频交易来说,这个速度足够了。
2.5 可编程互联
有了LUT、FF、BRAM、DSP这些“零件”,怎么把它们连起来?靠的就是可编程互联。
你可以把FPGA想象成一个巨大的城市。LUT、FF是房子,BRAM是商场,DSP是工厂。可编程互联就是连接这些建筑的道路和立交桥。
互联结构是分层的:
- 局部互联:同一个CLB(可配置逻辑块)内部的连接,延迟极低。
- 全局互联:跨越不同区域的连接,通过Switch Box(开关盒)和Routing Track(布线轨道)实现。
- 高速互联:专门为时钟、复位等全局信号设计的低抖动网络。
我遇到过一个问题:一个设计在综合后时序不满足,原因是两个关键模块被布局得太远了,互联延迟太大。后来我手动加了位置约束,把它们放在相邻的SLICE里,时序就过了。
个人建议:写代码时,尽量让相关的逻辑在物理上靠近。比如一个流水线的各级,最好放在同一个CLB或者相邻的CLB里。这样可以减少互联延迟,提升性能。
2.6 配置方式
FPGA是SRAM-based的,掉电就没了。所以每次上电都需要重新加载配置。
常见的配置方式有几种:
- JTAG:调试时用的,通过下载器直接把比特流烧进去。我平时开发就用这个。
- SPI Flash:上电后FPGA自动从外挂的Flash里读取配置。量产时常用。
- BPI Flash:并行接口,速度更快,适合大容量配置。
- SelectMAP:并行配置,速度最快,适合需要快速启动的场景。
在高频交易系统中,启动时间很关键。有些交易所要求系统在断电后5秒内恢复运行。这时候我会选择SelectMAP或者BPI模式,配合压缩的比特流,把启动时间压缩到1秒以内。
注意:配置完成后,FPGA会释放IO引脚。如果外部电路没有处理好,可能会出现短暂的毛刺。我曾经因为这个原因,导致交易网关在启动时误发了一笔订单。后来加了上拉电阻和延时释放逻辑才解决。
2.7 主流厂商:Xilinx vs Intel
目前FPGA市场基本是两家独大:Xilinx(现在叫AMD)和Intel(原Altera)。
我两个厂家的芯片都用过,说说我的感受:
| 对比项 | Xilinx (AMD) | Intel (Altera) |
|---|---|---|
| 开发工具 | Vivado / ISE | Quartus Prime |
| 高端系列 | Virtex / Kintex / Artix | Stratix / Arria / Cyclone |
| DSP能力 | DSP48E2 (强) | DSP Block (强) |
| 高速收发器 | GTH / GTY (最高112G) | Transceiver (最高116G) |
| 生态 | IP核丰富,社区活跃 | OpenCL支持好,HLS成熟 |
我个人习惯用Xilinx的Vivado,因为它的时序分析工具更直观。但Intel的Quartus在编译速度上确实有优势。如果你做的是纯逻辑设计,两家差别不大。但如果涉及到高速串行接口(比如100G以太网),Xilinx的GTH/GTY收发器用起来更顺手。
我的选择:高频交易领域,Xilinx的Virtex和Kintex系列是主流。原因很简单:生态成熟,IP核多,社区案例丰富。Intel的Stratix也不错,但在金融圈里用的人相对少一些。
2.8 本章知识体系
下面这张图,是我自己画的FPGA内部结构概览。你可以把它当作一个“地图”,以后遇到具体问题时,知道该往哪个方向找答案。
好了,这一章的内容就到这里。FPGA的内部结构,说白了就是这些基本单元的排列组合。你理解了LUT、FF、BRAM、DSP,就理解了FPGA的“骨架”。再加上可编程互联这个“血管”,配置方式这个“启动开关”,以及厂商选择这个“品牌偏好”,整个知识体系就完整了。