第二章: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 查找表 6输入真值表 组合逻辑实现 FF 触发器 状态记忆 时序逻辑基础 BRAM 块RAM 36Kb存储 FIFO/缓存 DSP 数字信号处理 乘法/累加 高速计算 可编程互联 局部互联 → 全局互联 → 高速互联 Switch Box + Routing Track 实现任意连接 配置方式 JTAG / SPI Flash / BPI / SelectMAP 上电加载比特流,SRAM掉电易失 主流厂商 Xilinx (AMD) vs Intel (Altera) Vivado vs Quartus / Virtex vs Stratix 四大基本单元 + 可编程互联 + 配置方式 + 厂商选择 = FPGA完整知识体系

好了,这一章的内容就到这里。FPGA的内部结构,说白了就是这些基本单元的排列组合。你理解了LUT、FF、BRAM、DSP,就理解了FPGA的“骨架”。再加上可编程互联这个“血管”,配置方式这个“启动开关”,以及厂商选择这个“品牌偏好”,整个知识体系就完整了。