You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:35:36