目录
🌱 什么是部分积压缩(Partial Product Reduction)?
📌 Synopsys DP Tree Construction Example
🧭 前言
在 datapath 优化阶段,特别是乘法器构建过程中,部分积(Partial Products)压缩是影响 面积 和 时序 的关键步骤。
无论是 Booth 还是 Non-Booth,最终都生成若干组 部分积位,这些位需要在硬件中以极高效率加总为一个最终的积。
这时候就要用到两个业界广泛使用的压缩策略:
-
Wallace Tree
-
Dadda Tree
在 Synopsys Design Compiler 中,DC 的底层 datapath 构建器会根据目标路径、PPA 策略自动选择其中之一,或者根据 library 支持情况固定使用某一类型。
那么这两种结构本质上是怎么工作的?DC 是如何实现并调度这些压缩器节点的?我们现在来揭开它们的实现机制。
🌱 什么是部分积压缩(Partial Product Reduction)?
假设我们有 8 个部分积位,如下:
Bit position 0: 1 bit
Bit position 1: 2 bits
Bit position 2: 3 bits
Bit position 3: 4 bits
Bit position 4: 3 bits
Bit position 5: 2 bits
Bit position 6: 1 bit
我们需要将每个位列上的多个 bits 加总成一个或两个输出,以便最后用一个 Carry-Propagate Adder(CPA) 做最终加法。
压缩树的任务就是:
以最少的逻辑级数,把这些垂直位列压缩为最多两行(Sum + Carry)
🌲 Wallace Tree
🧠 核心思想
Wallace Tree 使用一种激进并行的策略:
-
在每一层,能压缩就压缩,尽可能并行地使用 Full Adders (3:2) 和 Half Adders (2:2)
-
每个 bit 位列的高度 > 3 就触发压缩
-
没有延迟最小化的形式规约,而是贪婪策略
🧱 构造过程
-
对所有相同位宽的部分积列做分组
-
每组三个用 3:2 压缩器(Full Adder)
-
每两个用 2:2 压缩器(Half Adder)
-
将结果重新组织为下一层输入
-
重复直到所有列高度 ≤ 2
🔧 示例(文字图)
假设某列是 6 个 bit:
Initial: 6 → (FA+FA) → 4 → (FA+HA) → 2
每轮都在压缩,尽可能减少列的高度。
✅ 特点
维度 | Wallace Tree |
---|---|
结构类型 | 并行、贪婪 |
关键路径级数 | 少(最短延迟) |
面积 | 稍大 |
调度复杂度 | 高 |
Routing Congestion | 高(由于扇出和并行) |
适合场景 | 高频 / Critical path 优先设计 |
🌳 Dadda Tree
🧠 核心思想
Dadda Tree 采用一种延迟感知、渐进优化策略:
-
不立即压缩所有位
-
先计算出每一列最终需要的最大高度
-
只在必要时压缩,压缩更保守但更有层级控制
🧮 构造步骤
-
计算目标高度序列(从目标 2 开始,逆推)
-
h₀ = 2
-
h₁ = floor(1.5 * h₀) = 3
-
h₂ = floor(1.5 * h₁) = 4
-
… 直到 ≥ 最大初始列高度
-
-
从最高层级开始,每一层将列高度限制在 hₙ
-
到最后一层为止,每列 ≤ 2,进入 CPA
🔧 示例对比 Wallace
同样是某列 6 bit:
-
Dadda 可能先不压缩
-
等到后续阶段再压缩为 4、3、2
这样做的好处是每层 Fan-in、Fan-out 限制小,routing 更容易。
✅ 特点
维度 | Dadda Tree |
---|---|
结构类型 | 延迟平衡型 |
关键路径级数 | 稍多 |
面积 | 更紧凑(FA/HA 数量少) |
调度复杂度 | 较低 |
Routing Congestion | 更低 |
适合场景 | 面积优先 / layout-sensitive 设计 |
🧰 在 DC 中的实现与调用
Design Compiler 中并不会显式告诉你用的是哪种 Tree,但它在 datapath 中是一个内嵌策略。你可以通过观察结构和压缩层级来推测。
你也可以通过这些方式影响选择:
指定压缩器优先级(部分库支持)
set_app_var datapath_prefer_wallace_tree true
或者:
set_app_var datapath_use_custom_adder_tree false
报告结构:
report_datapath -structure -design mul_block
观察其中的 adder 类型和分布。
📌 Synopsys DP Tree Construction Example
假设有一个 8×8 Booth 乘法器,生成 4 个部分积(因为每 2 位一组):
-
DC 调用 datapath 调度器分配这些部分积到压缩层级
-
触发 datapath scheduling
-
分析位列高度分布
-
根据目标(e.g., timing critical vs. area critical)选择 Wallace or Dadda
-
Insert FA, HA
-
构建 Carry Propagate Adder
-
输出完整 datapath cell(可以打入 DesignWare)
🎯 总结对比表
维度 | Wallace Tree | Dadda Tree |
---|---|---|
压缩策略 | 贪婪并行压缩 | 延迟感知分阶段 |
逻辑级数 | 更少 | 稍多 |
Routing | 密集 | 更易布线 |
面积 | 稍大 | 更紧凑 |
Timing | 更好 | 稍弱 |
适用场景 | Critical path 优先 | 面积优先 |
🧠 设计建议
-
在 timing-critical 乘法路径中(如 MAC、DSP):建议偏向 Wallace
-
在低功耗、高密度 layout 优先的设计:Dadda 更有优势
-
RTL 中乘法表达式越复杂,DC 越倾向于 Booth+Wallace 组合