gen_prods
我们开始逐行分析 gen_prods.sv 的前 20 行。该模块是 Booth 乘法器的中间层模块,用于批量调用 gen_product 子模块,根据 Booth 编码生成所有 部分积(partial products)。
📝 第 1 行:功能注释
// Generate partial products based on modified sign extension in booth multipliers
📘 模块功能:根据扩展后的乘数,在 Booth 编码规则下生成多个部分积。
🔧 第 2–7 行:模块与参数定义
module gen_prods #(
parameter int unsigned WIDTH_A = 16,
parameter int unsigned WIDTH_B = 16,
parameter int unsigned COUNT = (WIDTH_B+2)/2,
parameter int unsigned WIDTH_O = WIDTH_A + WIDTH_B
)(
| 参数名 | 含义 |
|---|---|
WIDTH_A |
被乘数 operand_a 的宽度 |
WIDTH_B |
乘数 operand_b 的宽度 |
COUNT |
应生成的部分积数量(Booth 每两个位生成一个 partial product) |
WIDTH_O |
每个部分积的输出位宽(= 两数之和) |
📌 注意: COUNT = (WIDTH_B+2)/2,这是 Radix-4 Booth 编码的特性(3-bit 编码窗口覆盖两个乘数位)。
🔌 第 8–11 行:端口定义
input logic [WIDTH_A-1:0] operand_a,
input logic [WIDTH_B-1:0] operand_b,
output [COUNT-1:0][WIDTH_O-1:0] partial_prods
);
| 信号名 | 说明 |
|---|---|
operand_a |
被乘数(将与 Booth 编码的结果相乘) |
operand_b |
乘数(将生成 Booth 编码) |
partial_prods |
输出多个部分积 |
🔁 第 12–15 行:中间变量声明
logic [WIDTH_B+2:0] multiplier;
logic [COUNT-1:0][2:0] codes;
logic [COUNT-1:0][WIDTH_A:0] temp_prods;
logic [COUNT-1:0] signs;
| 名称 | 含义 |
|---|---|
multiplier |
乘数扩展后带符号辅助位(用于 Booth 编码) |
codes |
所有 Booth 编码段(每 3-bit) |
temp_prods |
每个部分积的结果(带符号扩展) |
signs |
每个部分积是否为负数(是否需要补码) |
🔗 第 17–18 行:构造扩展乘数 + 提取第一个 3-bit 编码段
assign multiplier = {2'b00, operand_b, 1'b0};
assign codes[0] = multiplier[2:0];
📌 Booth 编码需要每个窗口为 3-bit,其中:
- 扩展方式是
00 + operand_b + 0 - 第一个 Booth 编码窗口为
[2:0]
是否继续分析接下来如何对 Booth 编码进行划分、如何调用 gen_product 子模块批量生成部分积?
我们继续分析 gen_prods.sv 第 21–40 行的内容,这部分完成了:
- 对 Booth 编码窗口的逐段划分
- 实例化多个
gen_product子模块 - 按需拼接 sign 扩展生成
partial_prods
🧩 行 21–28:第一个 Booth partial product
gen_product #(
.WIDTH(WIDTH_A)
) ua_gen_product(
.multiplicand(operand_a),
.code(codes[0]),
.partial_prod(temp_prods[0]),
.sign(signs[0])
);
📌 第一个 Booth 窗口 [2:0] 已由上方 assign 得到,此处将其输入 gen_product:
- 使用
operand_a作为被乘数 - 得到部分积
temp_prods[0] - 得到其符号
signs[0]
🔗 行 29:拼接最终输出 partial_prods[0]
assign partial_prods[0] = {~signs[0], signs[0], signs[0], temp_prods[0]};
这是一个重要设计细节,符合 Booth 部分积补码扩展格式:
| 段 | 含义 |
|---|---|
~sign |
MSB 保证符号 |
signx2 |
用于 CSA 或压缩树中的统一加法修正 |
temp_prod |
Booth 部分积 |
👉 这是 Booth 乘法压缩树中经典的3 位补码扩展方案,用于统一加法逻辑。
🔁 行 31–34:生成后续 Booth 编码窗口与模块
generate
genvar i;
for(i=1;i<COUNT-1;i++) begin
assign codes[i] = multiplier[2*i+2:2*i];
📌 Radix-4 Booth 使用 3-bit 窗口 每次滑动两个位,因此窗口为 [2i+2 : 2i]。
例如:
i=1→[4:2]i=2→[6:4]
依此类推。
🧱 行 35–40:批量实例化 gen_product
gen_product #(
.WIDTH(WIDTH_A)
) ub_gen_product(
.multiplicand(operand_a),
.code(codes[i]),
批量生成多个 gen_product 模块,分别处理每一个 Booth 编码段。
接下来几行将继续连接其输出 temp_prods[i] 与 signs[i],是否继续分析后半部分?(生成最后一段部分积及完整模块结构)
继续分析 gen_prods.sv 的最后部分,其中包括:
- 每个
gen_product模块的部分积输出处理 - Booth 特有的补码扩展拼接
- 最后一个部分积的特殊处理
🔧 行 41–43:完成每个 gen_product 的端口连接
.partial_prod(temp_prods[i]),
.sign(signs[i])
);
连接输出部分积与符号。
🔁 行 44–45:补码扩展形式 + 左移对齐
// modified sign extension in booth multipliers
assign partial_prods[i] = {1'b1, ~signs[i], temp_prods[i], 1'b0, signs[i-1]} << (2*i - 2);
📌 分析拼接部分积的构成:
{1'b1, ~sign, prod, 1'b0, prev_sign}- 然后左移
(2*i - 2)位,保证 Booth partial 对齐到正确位置
这是改进型 Booth 乘法器的常见写法,通过在前/后添加符号位控制使 CSA 树中无需加一补码,仅需 OR/INV 等组合逻辑完成补码修正。
🔚 行 46–47:结束 generate 块
end
endgenerate
标记批量实例化结束。
🔺 行 49:提取最后一个 Booth 编码段
assign codes[COUNT-1] = multiplier[2*COUNT:2*COUNT-2];
最后一段单独处理,因为数组可能越界或边界控制需要手动指定。
🧩 行 50–54:实例化最后一个 gen_product
gen_product #(.WIDTH(WIDTH_A)) uc_gen_product (
.multiplicand(operand_a),
.code(codes[COUNT-1]),
.partial_prod(temp_prods[COUNT-1]),
.sign(signs[COUNT-1])
);
🧷 行 55:最后一个部分积的补码拼接方式
assign partial_prods[COUNT-1] = {temp_prods[COUNT-1], 1'b0, signs[COUNT-2]} << (2*COUNT - 4);
和前面的类似,只是前缀更简略,表示收尾的对齐方式。
🔚 行 57:模块结束
endmodule
✅ 总结:gen_prods 功能
| 部分 | 功能 |
|---|---|
multiplier |
为 Booth 编码添加扩展位 |
codes[] |
提取 Booth 编码块(每 3 位滑窗) |
gen_product 实例 |
为每段编码生成 Booth 部分积 |
partial_prods[i] |
使用特定格式和位扩展方案完成部分积对齐输出 |
是否将这个模块也转换为 Verilog-2001 格式?(去除 logic、generate、数组端口等不兼容语法)?

浙公网安备 33010602011771号