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 格式?(去除 logicgenerate、数组端口等不兼容语法)?

posted @ 2025-05-04 16:50  江左子固  阅读(59)  评论(0)    收藏  举报