第二章:FPGA基础与开发环境

好,咱们直接进入正题。FPGA 这东西,说白了就是一块可以「重新编程」的芯片。跟 CPU 那种固定指令集不一样,FPGA 的逻辑是硬件级别的——你写代码,就是在画电路。

我个人习惯把 FPGA 比作「乐高积木」。你买来一堆基本模块(查找表、触发器、布线资源),然后按自己的需求拼起来。拼好了,就是一个专用加速器。不满意?重新拼。这就是它做高频交易加速的核心优势。

2.1 FPGA 内部结构:到底长什么样?

先看一张经典的内部结构图(脑补一下):

+------------------+     +------------------+
|  可配置逻辑块     |-----|  可配置逻辑块     |
|  (CLB)           |     |  (CLB)           |
+------------------+     +------------------+
        |                         |
        |     +------------+      |
        |-----| 布线资源   |------|
        |     | (Switch)   |      |
        |     +------------+      |
+------------------+     +------------------+
|  可配置逻辑块     |-----|  可配置逻辑块     |
|  (CLB)           |     |  (CLB)           |
+------------------+     +------------------+

核心部件就三个:

  • 可配置逻辑块(CLB):这是干活的主力。每个 CLB 里包含几个查找表(LUT)和触发器(FF)。LUT 负责实现组合逻辑,FF 负责存储状态。
  • 布线资源:连接各个 CLB 的「高速公路」。我当年做第一个项目时,以为逻辑写对了就行,结果时序跑不过——就是因为布线资源用得太乱。
  • I/O 块:跟外界通信的接口。高频交易里,网卡数据就是从这里进来的。

重点:FPGA 的并行能力来自 CLB 的物理复制。你写一个加法器,综合工具会复制出 N 个加法器电路,每个独立运行。这就是为什么 FPGA 能同时处理几百个订单簿更新——CPU 得排队,FPGA 不用。

2.2 Verilog/VHDL 基础:选哪个?

这个问题我经常被问到。我的答案是:做交易加速,用 Verilog

为什么?因为交易系统里大部分是数据流处理——数据进来,算完,出去。Verilog 的语法更贴近 C 语言,写起来快。VHDL 强在系统级描述,但做算法加速时,Verilog 的简洁性更占优势。

看个最简单的例子——一个 D 触发器:

// Verilog 版本
module d_flip_flop (
    input  clk,
    input  rst_n,
    input  d,
    output reg q
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            q <= 1'b0;
        else
            q <= d;
    end
endmodule
-- VHDL 版本
entity d_flip_flop is
    port (
        clk   : in  std_logic;
        rst_n : in  std_logic;
        d     : in  std_logic;
        q     : out std_logic
    );
end entity;

architecture behavioral of d_flip_flop is
begin
    process(clk, rst_n)
    begin
        if rst_n = '0' then
            q <= '0';
        elsif rising_edge(clk) then
            q <= d;
        end if;
    end process;
end architecture;

你看,Verilog 的代码量明显少。但 VHDL 的语法更严谨,不容易写出歧义。我个人习惯是:小模块用 Verilog,大系统用 VHDL。不过现在做交易加速的团队,90% 都用 Verilog。

我的经验:刚开始学 Verilog 时,最容易犯的错误是把 always 块当成 C 语言的函数。记住:always 块里每个赋值对应一个硬件寄存器。你写 10 个赋值,综合出来就是 10 个触发器。不是循环执行,是并行复制。

2.3 Vivado/Quartus 环境搭建

环境搭建这块,我踩过不少坑。先说结论:

  • Xilinx 的 FPGA(现在叫 AMD):用 Vivado
  • Intel 的 FPGA(原 Altera):用 Quartus

做高频交易,我个人更推荐 Xilinx 的芯片。原因很简单:生态成熟,IP 核多。尤其是 10G/25G 以太网 IP,Xilinx 的支持比 Intel 好很多。

2.3.1 Vivado 安装要点

安装 Vivado 时,注意这几点:

  1. 版本选择:别追最新版。我建议用 2022.2 或 2023.1。新版 bug 多,老版有些 IP 不支持。
  2. 安装组件:只勾选你需要的器件型号。全装的话,硬盘 100GB 都不够。
  3. License 问题:WebPACK 版免费,但只支持小芯片。做交易加速一般用 Kintex 或 Virtex 系列,需要付费 License。

避坑指南:我曾经在 Ubuntu 22.04 上装 Vivado 2023.2,结果死活装不上。查了两天,发现是 libtinfo 库版本不兼容。最后换成 CentOS 7 才搞定。所以:用 CentOS 7 或 Ubuntu 20.04,别用太新的系统

2.3.2 Quartus 安装要点

Quartus 相对友好一些:

  • Windows 下安装基本无坑
  • Linux 下需要装一些 32 位库(libc6-i386 等)
  • 免费版(Lite)支持 Cyclone 和 MAX 系列
  • Pro 版才支持 Stratix 和 Arria 系列

我个人觉得 Quartus 的 GUI 比 Vivado 流畅。但综合速度上,Vivado 更快。尤其是大工程,Vivado 能快 30% 左右。

2.4 第一个工程:点亮 LED

好,环境装好了,咱们跑个最简单的例子——点亮开发板上的 LED。别小看这个,它能验证你的整个工具链是否正常。

Vivado 工程步骤:

  1. 创建工程,选好器件型号(比如 xc7k325tffg900-2)
  2. 添加设计文件(.v 或 .vhd)
  3. 写约束文件(.xdc),定义引脚和时钟
  4. 综合(Synthesis)→ 实现(Implementation)→ 生成比特流
  5. 下载到开发板

代码很简单:

module led_blink (
    input  clk_50m,   // 50MHz 时钟
    input  rst_n,     // 复位,低有效
    output reg led    // LED 输出
);

reg [24:0] counter;

always @(posedge clk_50m or negedge rst_n) begin
    if (!rst_n) begin
        counter <= 25'd0;
        led     <= 1'b0;
    end else begin
        counter <= counter + 1'b1;
        // 50MHz / 2^25 ≈ 1.5Hz 闪烁
        led <= counter[24];
    end
end

endmodule

约束文件(.xdc)示例:

set_property PACKAGE_PIN Y9 [get_ports clk_50m]
set_property IOSTANDARD LVCMOS33 [get_ports clk_50m]

set_property PACKAGE_PIN L17 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]

set_property PACKAGE_PIN H17 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports led]

小技巧:第一次跑综合时,别急着看结果。打开「Synthesis Report」,看看用了多少 LUT、多少 FF。如果资源占用率超过 80%,后面时序大概率会出问题。我一般控制在 60% 以内,留点余量给布线。

2.5 高频交易场景的特殊要求

做交易加速,跟普通 FPGA 开发有几点不同:

普通开发 交易加速
关注功能正确 关注延迟确定性
时钟频率尽量高 时钟频率稳定即可
资源利用率优先 路径延迟优先
可以重配置 必须热重配置

举个例子:普通开发里,你可能会用 PLL 把时钟倍频到 500MHz。但在交易系统里,我更倾向于用 200MHz 的稳定时钟,配合流水线设计。为什么?因为高频时钟容易产生时序抖动,而交易系统对确定性要求极高——你不想因为一次时序违规,导致订单处理延迟多出 10 纳秒。

核心原则:交易加速的 FPGA 设计,延迟确定性 > 吞吐量 > 资源利用率。记住这个优先级,后面所有设计决策都围绕它展开。

2.6 本章小结

嗯,这一章内容不少。咱们捋一下重点:

  • FPGA 内部就是 CLB + 布线 + I/O,核心是并行复制
  • 做交易加速,Verilog 比 VHDL 更合适
  • 环境搭建推荐 Vivado + Xilinx 芯片,系统用 CentOS 7
  • 第一个工程跑通 LED,验证工具链
  • 交易场景下,延迟确定性是第一位的

下一章,咱们开始真正接触交易系统的核心——如何用 FPGA 实现一个纳秒级的加法器。别觉得简单,这里面门道多着呢。

课后练习:在你的开发板上跑通 LED 闪烁程序。然后试着把闪烁频率改成 1Hz 和 10Hz。看看约束文件里时钟周期怎么改?综合报告里资源占用有什么变化?

好,今天就到这儿。有问题随时交流。