Booth乘法器Verilog代码正确性验证及无波形输出排查求助
Booth乘法器Verilog代码错误排查
我写了下面这段Booth乘法器的Verilog代码,跑测试平台时拿不到波形输出,不确定是代码本身有问题还是测试平台的问题,求帮忙确认代码正确性并排查故障。
module booth_multiplier( input signed [31:0] multiplicand, input signed [31:0] multiplier, input clk, input reset, output signed [63:0] product ); reg signed [63:0] product_reg; reg signed [31:0] recoded_multiplier; integer i; reg signed [63:0] extended_multiplicand; always @(*) begin // Booth multiplier recoding table for (i = 0; i < 32; i = i + 1) begin case ({multiplier[i], (i == 0) ? multiplier[0] : multiplier[i-1]}) 2'b11: recoded_multiplier[i] = 0; // no adjustment 2'b10: recoded_multiplier[i] = 1; // +1 adjustment 2'b01: recoded_multiplier[i] = -1; // -1 adjustment 2'b00: recoded_multiplier[i] = 0; // no adjustment endcase end end always @(posedge clk or negedge reset) begin if (!reset) begin product_reg <= 0; end else begin // Sign extend multiplicand to match the width of product_reg extended_multiplicand = {{32{multiplicand[31]}}, multiplicand}; // Add or subtract sign-extended multiplicand based on recoded multiplier case (recoded_multiplier) 1: product_reg <= product_reg + extended_multiplicand; // Addition -1: product_reg <= product_reg - extended_multiplicand; // Subtraction default: product_reg <= product_reg; // No adjustment endcase // Shift product_reg to the left by one bit product_reg <= {product_reg[62:0], 1'b0}; end end assign product = product_reg; endmodule
代码核心错误分析
- Booth编码逻辑完全错误:标准Booth算法基于当前位、前一位、初始虚拟0位的三位组编码,你仅用了两位,且i=0时错误地用
multiplier[0]与自身组合,正确初始组应为{multiplier[0], 1'b0},同时你也遗漏了±2的编码规则(标准Booth编码包含-2、-1、0、1、2五种情况)。 - 时序操作逻辑混乱:Booth乘法的正确流程是每时钟周期根据编码值更新乘积寄存器的高32位,然后整体右移一位,你这里做了左移,且错误地将32位
recoded_multiplier整体作为case条件,实际应逐位处理编码,需要计数器跟踪当前处理的位索引。 - 缺少运算周期控制:没有计数器控制32个时钟周期的运算过程,代码会在每个时钟周期重复无效的加减移位,导致乘积寄存器持续变化,测试平台无法捕获稳定结果。
修正后的简化版本示例
module booth_multiplier( input signed [31:0] multiplicand, input signed [31:0] multiplier, input clk, input reset_n, output reg signed [63:0] product, output reg done ); reg signed [63:0] product_reg; reg [5:0] cnt; reg [1:0] booth_code; reg signed [31:0] mult_reg; reg lsb; always @(posedge clk or negedge reset_n) begin if (!reset_n) begin product_reg <= {{32{multiplicand[31]}}, multiplicand}; mult_reg <= multiplier; lsb <= 1'b0; cnt <= 6'd0; done <= 1'b0; product <= 64'd0; end else begin if (cnt < 6'd32) begin // 生成Booth编码(当前位、前一位) booth_code <= {mult_reg[0], lsb}; lsb <= mult_reg[0]; mult_reg <= mult_reg >>> 1; // 乘数右移 // 根据编码更新乘积高32位 case (booth_code) 2'b01: product_reg[63:32] <= product_reg[63:32] + multiplicand; 2'b10: product_reg[63:32] <= product_reg[63:32] - multiplicand; default: ; // 无操作 endcase // 乘积整体右移 product_reg <= product_reg >>> 1; cnt <= cnt + 6'd1; end else begin done <= 1'b1; product <= product_reg; end end end endmodule
测试平台排查建议
- 确保测试平台正确生成复位信号(电平与代码中
reset匹配)、时钟信号,复位释放后稳定驱动时钟。 - 测试平台需等待
done信号拉高后再采样product输出,避免读取运算过程中的不稳定中间值。 - 检查波形工具的信号选择,确保已添加
product、clk、reset、done等关键信号。
内容的提问来源于stack exchange,提问作者Harminder Saini
相关产品推荐
相关产品推荐

