一、FPGA网表基础:从代码到硬件的桥梁

大家好,我是你们的FPGA讲师。今天咱们聊聊网表——这个听起来有点抽象,但实际工作中天天打交道的概念。

说实话,我刚入行那会儿,对网表也是一知半解。总觉得它就是个中间产物,没啥好研究的。直到有一次,我在调试一个高速接口时,综合后的仿真明明过了,布局布线后却死活跑不起来。折腾了两天,最后发现是网表里一个扇出问题。从那以后,我就再也不敢小看网表了。

1.1 什么是网表?

网表,英文叫Netlist。说白了,它就是一份「电路连接清单」。

你想想看,我们写Verilog代码时,描述的是行为——「这个寄存器在时钟上升沿赋值」、「那个组合逻辑做加法」。但FPGA不认识这些抽象描述,它只认识具体的逻辑单元和连线。

网表就是这两者之间的翻译官。它把RTL代码翻译成一个个具体的逻辑元件(比如LUT、触发器、DSP块),以及它们之间的连接关系。

核心定义:网表 = 元件列表 + 连接关系

元件:LUT、FF、BRAM、DSP、IOB等

连接:Net(网络),即元件之间的连线

我习惯把网表比作一张「电路地图」。元件就是城市,Net就是高速公路。没有这张地图,你就没法知道信号是怎么从A点跑到B点的。

1.2 网表在FPGA设计流程中的位置

FPGA设计流程,说白了就是一条流水线:

  1. RTL设计 —— 写Verilog/VHDL代码
  2. 功能仿真 —— 验证逻辑对不对
  3. 逻辑综合 —— 把RTL转成网表 ← 这里开始出现网表
  4. 布局 —— 把元件放到FPGA的物理位置上
  5. 布线 —— 把元件之间的连线走通
  6. 时序仿真/分析 —— 检查能不能跑在目标频率
  7. 生成比特流 —— 下载到FPGA

网表出现在第3步之后,并且会随着布局、布线不断更新。嗯,这里有个关键点:网表不是一成不变的

个人经验:我建议初学者一定要养成看综合后网表的习惯。哪怕只是看一眼LUT用了多少、触发器用了多少,都能帮你快速发现代码中的资源浪费问题。我曾经带过一个实习生,写了个128位的加法器,综合后发现用了整整64个LUT——其实他只需要32位。一看网表就露馅了。

1.3 网表的分类

根据设计流程的不同阶段,网表可以分为三类。这三类网表,我当年可是被它们坑过不少次。

1.3.1 综合后网表(Post-Synthesis Netlist)

这是综合工具(比如Vivado的synth、Quartus的Analysis & Synthesis)输出的第一版网表。

  • 特点:只包含逻辑映射,没有物理位置信息
  • 元件:LUT、FF、DSP、BRAM等基本单元
  • 连接:理想连线,没有延迟
  • 用途:功能验证、资源估算

说白了,综合后网表就是「纸上谈兵」的阶段。逻辑是对的,但实际能不能跑通,还得看布局布线。

避坑指南:我曾经犯过一个错误——综合后网表仿真全过,就直接去生成比特流了。结果板子上电后,信号完全不对。后来才发现,综合后网表里没有考虑走线延迟,而我的设计对时序要求很苛刻。记住:综合后网表只能验证功能,不能验证时序

1.3.2 布局后网表(Post-Placement Netlist)

布局工具把综合后的元件分配到FPGA的物理位置上。这时候,每个LUT、每个触发器都有了具体的坐标。

  • 特点:包含物理位置信息,但走线还是理想的
  • 新增信息:元件坐标(如SLICE_X0Y0、SLICE_X1Y1)
  • 用途:检查布局是否合理、评估拥塞程度

我个人习惯在布局后先看一眼网表。如果发现某个区域的LUT密度特别高,那就要小心了——后面布线可能会很困难。

1.3.3 布线后网表(Post-Route Netlist)

这是最终版网表。布线工具把所有Net都走通了,每条连线都有了实际的延迟信息。

  • 特点:包含完整的时序信息(走线延迟、逻辑延迟)
  • 新增信息:每条Net的延迟值、扇出数、走线路径
  • 用途:时序仿真、静态时序分析(STA)、生成比特流

布线后网表,说白了就是「生米煮成熟饭」了。这时候如果时序不满足,那就得回到RTL或者综合阶段去改。

三种网表对比:

网表类型 逻辑信息 位置信息 延迟信息 主要用途
综合后 功能验证
布局后 布局检查
布线后 时序分析

1.4 网表长什么样?

咱们来看一个实际的网表片段。这是Vivado综合后导出的EDIF格式网表(简化版):

(cell my_and2
  (cellType LUT2)
  (view netlist
    (interface
      (port I0 (direction INPUT))
      (port I1 (direction INPUT))
      (port O (direction OUTPUT))
    )
    (implementation
      (net n1
        (joined
          (portRef I0)
          (portRef I1)
        )
      )
      (net n2
        (joined
          (portRef O)
        )
      )
    )
  )
)

你看,一个简单的2输入与门,在网表里就变成了一个LUT2元件,外加两个Net(n1和n2)。

嗯,这里要注意:网表格式不止一种。Vivado用EDIF,Quartus用VQM,还有通用的Verilog网表格式。但不管哪种格式,核心都是「元件+连接」。

1.5 为什么要理解网表?

可能有同学会问:「我直接用Vivado跑流程不就行了,干嘛要懂网表?」

这个问题问得好。我当年也这么想。但后来我发现,不懂网表,你根本没法做三件事:

  1. 调试时序问题 —— 时序违例了,你得看网表里哪条路径延迟最大
  2. 优化资源 —— 代码写得很漂亮,但综合后LUT用超了,你得看网表里哪里浪费了
  3. 逆向工程 —— 拿到别人的比特流,想分析它的逻辑,第一步就是提取网表

说白了,网表就是FPGA设计的「源代码」。不懂网表,你永远只是个「工具使用者」,而不是「电路设计者」。

一个小技巧:在Vivado里,用write_edif命令可以导出综合后网表。用write_verilog -mode funcsim可以导出用于仿真的网表。我每次做完一个模块,都会导出网表看一眼,确认综合工具没有「自作主张」优化掉我的关键逻辑。

1.6 本章小结

好了,咱们来捋一捋今天的内容:

  • 网表 = 元件列表 + 连接关系,是RTL到硬件的桥梁
  • 网表出现在综合之后,并随着布局布线不断更新
  • 三种网表:综合后(功能验证)、布局后(位置检查)、布线后(时序分析)
  • 理解网表是调试、优化、逆向的基础

下一章,咱们会深入讲解如何从比特流中提取网表——这可是FPGA逆向工程的核心技能。到时候我会分享一个我当年做安全分析时的真实案例,保证让你大开眼界。


公众号:蓝海资料掘金营,微信deep3321