目录
🧭 前言
🌱 1. Non-Booth 乘法器的实现原理(也叫常规乘法器)
🔧 构建方式
✍️ 例子:4x4 Non-Booth 乘法器示意
🧱 硬件结构
✅ 特点总结
⚡ 2. Booth Encoding(布斯编码)乘法器
🧠 核心思想
✨ 举例:Radix-4 Booth(每两位一组)
📐 Booth 操作编码表(Radix-4)
🔧 硬件结构简图
✅ 特点总结
🏛️ 3. 在 Synopsys DC 中的使用策略
默认行为:
控制变量:
🧪 4. 如何验证 DC 选择了哪种乘法器?
方法一:Datapath Debug Log
方法二:report datapath structure
🎯 总结
🔚 延伸阅读
🧭 前言
在 datapath 构建阶段,乘法器是最重要的资源单元之一。
-
面积最大
-
时序瓶颈集中
-
能力决定系统吞吐
而 Synopsys Design Compiler (DC) 在构建乘法器结构时,核心决策之一就是:
❓是否采用 Booth Encoding?
❓如果不采用,怎么构建标准 non-Booth 乘法器?
这并不是一个简单选择,而是涉及多个维度的性能平衡。我们现在就从最底层原理开始:
🌱 1. Non-Booth 乘法器的实现原理(也叫常规乘法器)
🔧 构建方式
假设我们要计算两个无符号 4-bit 数相乘:
A = a3 a2 a1 a0
B = b3 b2 b1 b0
我们需要构建如下的部分积(partial products):
P0 = A * b0 --> A AND b0 (bitwise)
P1 = A * b1 << 1 --> A AND b1, shift left 1
P2 = A * b2 << 2 --> A AND b2, shift left 2
P3 = A * b3 << 3 --> A AND b3, shift left 3
最终的乘法结果是:
Result = P0 + P1 + P2 + P3
也就是说,n-bit × n-bit 的 non-Booth 乘法器需要生成 n 个部分积,然后加起来。
✍️ 例子:4x4 Non-Booth 乘法器示意
假设:
A = 4'b1101 (13)
B = 4'b1010 (10)
部分积:
P0 = 1101 & 0 = 0000
P1 = 1101 & 1 = 1101 << 1 = 11010
P2 = 1101 & 0 = 00000
P3 = 1101 & 1 = 1101 << 3 = 1101000
最终加起来:
Result = 0 + 11010 + 0 + 1101000 = 10000010 = 130
🧱 硬件结构
-
每一项
A * bi
是 AND gates -
每个结果之间的加法使用 Carry-Save Adders(CSA)
-
最后一级使用 Carry-Propagate Adder(CPA)
非 Booth 的乘法器结构如下图逻辑(文字图):
A * b0 A * b1 A * b2 A * b3
| | | |
↓↓↓ ↓↓↓ ↓↓↓ ↓↓↓
+----------+ +----------+ +----------+ +----------+
| Shifter |-->| Shifter |-->| Shifter |-->| Shifter |
+----------+ +----------+ +----------+ +----------+
| | | |
+--------------+--------------+---------------+
|
Multi-Adder Tree
✅ 特点总结
维度 | Non-Booth |
---|---|
部分积数量 | n 个 |
面积 | 较大 |
延迟 | 多级加法器 |
符号位支持 | 需要扩展和修复 |
构建复杂度 | 中等 |
优点 | 实现简单,易调试 |
缺点 | 延迟长,乘法器大 |
⚡ 2. Booth Encoding(布斯编码)乘法器
Booth 是一种对乘法输入进行重编码的方式,可以减少部分积数量,进而降低延迟与面积。
🧠 核心思想
原始每个位做部分积太浪费。
Booth 把乘数 B 分组,比如两个一组,做符号差分编码,从而一组表示 3 种操作:
00 → 0
01 → +A
10 → -A
11 → 0(或特殊处理)
这样就可以跳过很多 "0" 操作,生成更少部分积。
✨ 举例:Radix-4 Booth(每两位一组)
假设:
B = b3 b2 b1 b0 = 1001 (9)
扩展为 b4=0
组合: (b4,b3,b2), (b2,b1,b0)
组1: 010 → +A
组2: 100 → -2A
所以只生成两组:
-
+A shift by 2
-
-2A shift by 0
相比非 Booth 的 4 个部分积,这里只用 2 个!
📐 Booth 操作编码表(Radix-4)
组值 (x2, x1, x0) | 操作 |
---|---|
000 | 0 |
001 | +A |
010 | +A |
011 | +2A |
100 | -2A |
101 | -A |
110 | -A |
111 | 0 |
🔧 硬件结构简图
Booth Encoder → Booth Selector (0, +A, -A, +2A, -2A)
↓
Partial Products
↓
Adder Tree (Wallace or Dadda)
✅ 特点总结
维度 | Booth Encoding |
---|---|
部分积数量 | 减半:n/2 |
延迟 | 更短 |
面积 | 较小(加法器更深但数量少) |
符号位支持 | 天然支持有符号数! |
实现复杂度 | 高(需要编码器+符号处理) |
优点 | 高性能,面积节省,支持负数 |
缺点 | 实现复杂,调试难,corner case 多 |
🏛️ 3. 在 Synopsys DC 中的使用策略
Design Compiler 会在 datapath 构建阶段自动选择:
默认行为:
-
有符号乘法 → Booth 优先
-
目标路径在 critical timing path → Booth 强制使用
-
常数乘法 → 不用 Booth,而是移位+加法特化
控制变量:
set_app_var datapath_enable_booth true
更精细控制:
set_app_var datapath_prefer_booth_multiplier true
set_app_var datapath_force_non_booth_multiplier false
你也可以用 constraint 引导:
set_multicycle_path -from A -to B -prefer_booth
🧪 4. 如何验证 DC 选择了哪种乘法器?
方法一:Datapath Debug Log
set_app_var datapath_debug_level 5
compile_design
会看到 log 中出现:
Info: Booth encoding applied to multiplier A * B
或
Warning: Fallback to non-Booth multiplier due to bit width mismatch
方法二:report datapath structure
report_datapath -design my_block
会显示 multiplier 类型和数量。
🎯 总结
比较维度 | Non-Booth | Booth |
---|---|---|
部分积数量 | n | n/2 |
结构复杂度 | 中等 | 高(需要编码器) |
支持负数 | 手动符号扩展 | ✅天然支持 |
面积 | 较大 | 较小 |
延迟 | 多级累加 | 更少级数 |
调试 | 简单 | 较复杂(corner case 多) |
🧠 在时序收敛关键路径或 DSP 优化目标中,Booth 是你最好的朋友。
🛠 在低位宽、功耗优先或 RTL级测试场景中,Non-Booth 更易用、可控、可验证。
🔚 延伸阅读
📙《终结乘法瓶颈!带你彻底掌握 Booth Encoding 的秘密与架构》
📘《Non-Booth 乘法器的全解析:从 RTL 表达式到部分积压缩的完整路径》