FPGA 结构与 CAD 设计(第3章)下

以下内容总结自《深亚微米FPGA结构与CAD设计》- 作为一个读书笔记与大家共享。部分内容为AI补充,不对的地方还请指出。

一、VPR 布局器概述:为"可变结构"而生

VPR(Versatile Place and Route)是一套非常经典的 FPGA CAD 工具,其设计目标就是两个字:通用

在布局阶段,VPR 做了几件事:

  1. 把逻辑单元块和 I/O 管脚放到一个二维网格上;
  2. 支持参数化的 FPGA 结构描述:
    • 逻辑块 I/O 引脚数量;
    • 每行/每列的 I/O 数目;
    • 各布线通道的相对宽度;
  3. 支持多种成本函数和约束(如是否锁定 I/O 位置)。

VPR 内部采用的是模拟退火(Simulated Annealing) 布局算法,第三章的后半部分重点在于:如何让退火过程足够快,同时布局结果足够好


二、新型自适应退火表:让退火"聪明一点"

2.1 初始温度设定

借鉴 Huang 等人的方法:

  1. 随机生成一个布局;
  2. 对逻辑块和 I/O 做 (N) 次随机交换((N) 为块和 I/O 总数);
  3. 计算这 (N) 次交换所造成成本变化的均方差 σ;
  4. 初始温度设为: 这样可以保证退火初期几乎所有移动都被接受,有利于跳出差解。

2.2 每个温度点的移动次数

  1. 每个温度点进行的移动次数为:
  • (N):块数量;

  • InnerNum:可调参数(默认 10)。

实测:

  • 若把 InnerNum 从 10 降到 1,布局质量可能下降 5%--10%,但 CPU 时间直接减少约 10 倍;
  • 这为工程实践提供了一个非常直接的"时间 vs 质量"调节旋钮。

2.3 接受率驱动的温度更新策略

新退火表的核心在于:用接受率 α 来调整降温速度。接受率定义为当前温度下,被接受的移动占总移动的比例。

新温度计算为:

直观理解:

  • 若当前温度太高(α≈1),说明几乎所有移动都被接受,搜索过于"散漫",就要加速降温;
  • 若当前温度过低(α 很小),说明几乎没有移动被接受,系统已经"冻结",也要快速降温以结束退火;
  • 当 α≈0.44时,退火过程最有效,此时 γ≈1,维持温度不变,多做几轮探索。

2.4 退火终止条件

退火在以下条件满足时终止:

  • Nnets:线网总数;
  • ϵ:常数,取 0.005。

含义:当温度相对于每条线网的平均成本已经非常小时,再尝试接受成本上升的移动已经没有意义,继续退火只是在浪费时间。

2.5 与 Huang 退火表的比较

文中对 8 个 MCNC 电路测试,结果大致如下(表 3.3):

  • 对 6 个中小电路:
    • 新退火表平均快 1.35 倍,成本只略高 0.9% 左右;
  • 对 2 个大电路:
    • Huang 表在 alu4 上 CPU 时间约为新表的 3.8 倍;
    • 在 bigkey 上即便多花 40 倍时间仍未收敛;
  • 8 个电路算术平均:
    • 新退火表在 CPU 时间上优于 Huang 表约 6.5 倍,
    • 最终布局成本还略低 1.5%。

结论很明确:

新退火表不仅平均更快,而且在"最坏情况"上更加可靠,可预测性强,更适合作为通用 CAD 工具的默认方案。


三、线性拥挤成本函数:面向不均匀布线结构的建模

3.1 动机:中心通道更宽怎么办?

许多 FPGA 结构中,不同区域的通道宽度并不相同,例如:

  • 芯片中心区域的通道更宽;
  • 边缘区域通道相对较窄。

如果仍然使用传统的"边界框"成本函数,只看线网的几何跨度,就无法区分这些资源差异,布局结果也不一定有利于全局布线。

3.2 线性拥挤成本函数定义

文中提出的线性拥挤成本(linear congestion)为:

  • bbx(i),bby(i):线网 i 边界框在 x / y 方向的跨度;
  • Cav,x(i),Cav,y(i):线网 i 所在边界框内,x / y 方向通道宽度的平均值(可理解为"可用轨道数");
  • β:调整对拥挤的惩罚程度,实验发现 β=1 时效果较好。

特点:

  • 当所有通道宽度相同时,Cav为常数,线性拥挤成本退化为标准边界框成本;
  • 当某个区域通道更窄时,线网边界框若横跨该区域,则会被额外"惩罚",促进布局把高需求线网往宽通道区域倾斜。

3.3 与非线性拥挤成本的比较

非线性拥挤成本的思路是把 FPGA 划分为 M×M个小区域,对每个区域的"布线供需差"进行精细建模,这在经典文献中已有介绍。

文中的对比结果(表 3.4)可以概括如下:

成本函数 对 36 电路平均布线轨道需求 CPU 时间
边界框 基准 1X
线性拥挤 轨道数减少约 7% 1X
非线性拥挤(16 区) 比线性拥挤再少约 1% 5X
非线性拥挤(256 区) 比线性拥挤再少约 3% 80X

可见:

  • 非线性拥挤在极限情况下可以稍微减少布线轨道(多 1%3% 优势),但 CPU 时间代价惊人(5X80X);
  • 而线性拥挤成本函数在几乎不增加时间开销 的情况下,就能在不均匀通道结构上带来5%~10% 的轨道节省。

工程上的结论是:

线性拥挤成本函数是一个在"效果 / 时间"上性价比极高的折中方案,非常适合作为 VPR 这类通用工具的默认成本函数。


四、增量式线网边界框更新:把 O(k) 变成 O(1)

4.1 问题:高扇出线网拖慢一切

在模拟退火布局中,每次尝试交换两个逻辑块,都需要评估"成本变化 ΔCΔC"。其中最费时的是:重新计算与这两个块相关的线网,其边界框及成本变化。

朴素做法:对每根线网重新遍历所有端点,复杂度 (O(k))(k 为线网端点数)。

而高扇出线网(k 几十甚至上百)非常多,导致整体布局时间被严重拖累。

4.2 数据结构设计

为每条线网 (i) 存储如下信息:

objectivec 复制代码
struct Net {
    int xmin, xmax, ymin, ymax;     // 边界框坐标
    int n_xmin, n_xmax;             // 落在 xmin/xmax 边上的端点数
    int n_ymin, n_ymax;             // 落在 ymin/ymax 边上的端点数
};

这允许我们在端点移动时,用局部信息判断边界框是否需要改变,而不必重新扫描所有端点。

4.3 核心更新伪代码示例

以下为更新 x 方向边界的简化伪代码:

objectivec 复制代码
void updateBoundingBoxX(int netId, int x_old, int x_new) {
    // 情况1:端点在水平方向没有变化
    if (x_new == x_old) return;

    // 情况2:端点移动到比当前 xmin 更小的位置
    if (x_new < xmin[netId]) {
        xmin[netId] = x_new;
        n_xmin[netId] = 1;
        return;
    }

    // 情况3:端点移动到新的 xmin 边上
    if (x_new == xmin[netId]) {
        n_xmin[netId]++;
        return;
    }

    // 情况4:端点原本位于 xmin 边界,现在离开
    if (x_old == xmin[netId]) {
        if (n_xmin[netId] > 1) {
            // 仍有其他端点在 xmin 边,无需重算
            n_xmin[netId]--;
        } else {
            // 这是 xmin 边上唯一一个端点,只能暴力重算
            bruteForceRecomputeBoundingBox(netId);
        }
    }

    // x_max 类似处理
}

同理可以写出 y 方向的更新函数。

关键观察:

  • 只有在"原来边界上的唯一端点被移走"这一种情况下,才需要 (O(k)) 的暴力重算;

  • 这一情况出现的概率与 1/k1/k 成正比,因此平均复杂度 为:

4.4 实测提速效果

对 10 个最大 MCNC 基准电路进行测试,结果显示:

  • 布局速度平均提升约 5 倍,在某些高扇出电路上甚至可达到 9 倍以上;
  • 布局质量不受影响(因为我们只是更快地算同一个成本函数);
  • 由于复杂度特性清晰,能更精确地根据电路规模预测布局用时。

五、综合小结:一套完整而实用的布局技术组合

第三章的布局部分,可以概括为 VPR 在三个关键技术点上的进化:

  1. 自适应退火表
    用接受率驱动温度更新,统一适配不同电路规模与结构;
  2. 线性拥挤成本函数
    在几乎零额外时间开销的前提下,对不均匀通道结构给出更合理的布局导向;
  3. 增量式边界框更新
    从算法层面消除了高扇出线网带来的 O(k) 瓶颈,实现 5X 级别的速度提升。

与前半部分的打包工具(VPack / T‑VPack)结合在一起,第三章完整地构建了一条:

面向 FPGA 的高质量打包 + 布局 CAD 流程

对于做 FPGA CAD 研究或工具开发的人来说,文中给出的很多设计思路和经验值(如 λ,β,ϵλ,β,ϵ 等取值范围),都可以直接作为工程实现的参考起点。

相关推荐
粤M温同学7 小时前
Android Studio 中安装 CodeBuddy AI助手
android·ide·android studio
学会放下ta8 小时前
安装breakpad
ide
萨文 摩尔杰8 小时前
GPS原理学习
学习·fpga开发
Huangichin9 小时前
跟着Gemini学System Verilog
fpga开发
szcsun510 小时前
关于在pycharm中新建项目创建虚拟化环境venv
ide·python·pycharm
LCMICRO-1331084774611 小时前
长芯微LDC90810完全P2P替代ADC128D818,是一款八通道系统监控器,专为监控复杂系统状态而设计。
stm32·单片机·嵌入式硬件·fpga开发·硬件工程·模数转换芯片adc
2501_9160074714 小时前
在非 Xcode 环境下完成苹果开发编译的记录 iOS 编译与调试
ide·vscode·ios·cocoa·个人开发·xcode·敏捷流程
s090713614 小时前
保姆级教程十二:USB摄像头接入!ZYNQ+OpenCV+FPGA硬件加速图像处理实战(视觉终极篇)
图像处理·opencv·fpga开发·zynq·硬件加速
cyforkk14 小时前
IntelliJ IDEA 配置 Java 类全局注释模板操作指南
java·ide·intellij-idea
Ama_tor18 小时前
Visual Studio Code (VS Code) |下载与前端开发环境配置(带图详细)
ide·vscode·编辑器