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

使用Double Dabble算法实现二进制转BCD时if语句执行异常求助

Double Dabble二进制转BCD转换器Verilog代码问题

我用Double Dabble算法实现二进制转BCD的Verilog模块,输入14'd1157时预期输出千位1、百位1、十位5、个位7,但仿真结果不符合预期,代码中的if语句未正常执行。

原模块代码

`timescale 1ns / 1ps

module test_6( input [13:0] bin ,
                    output reg [3:0] ones,  // ones value of the input number
                    output reg [3:0] tens,  // tens value of the input number
                    output reg [3:0] hundreds, // hundreds value of the input nnumber
                    output reg [3:0] thousands // thousands value of the input number
    );

integer i;
reg [15:0] scratch; // 16 bit register 
reg [29:0] combined; // 30 bit concatenated register bin and scratch

always @(bin) begin
scratch = 0;
combined = {scratch[15:0], bin[13:0]};  // concatenating scratch and bin into combined

for (i=0; i<14; i=i+1) begin 
combined = combined<<1;    // left shift by 1     

    if (combined[17:14] > 4) begin 
        combined[17:14] = combined[17:14] + 4'b0011;  //check if >4, if yes add 3
        
        end
    if (combined[21:18] > 4) begin 
        combined[21:18] = combined[21:18] + 4'b0011;  //check if >4, if yes add 3
        
        end
    if (combined[25:22] > 4) begin
        combined[25:22] = combined[25:22] + 4'b0011;  //check if >4, if yes add 3
        
        end
    if (combined[29:26] > 4) begin 
        combined[29:26] = combined[29:26] + 4'b0011;  //check if >4, if yes add 3
        
        end
        
end
thousands = combined[29:26];  
hundreds = combined[25:22];
tens = combined[21:18];
ones = combined[17:14];

$display(ones);
$display(tens);
$display(hundreds);
$display(thousands);
end

endmodule

原测试平台代码

module test_6_tb;

    // Inputs
    reg [13:0] bin;
    // Outputs
    wire [3:0] ones;
    wire [3:0] tens;
    wire [3:0] hundreds;
    wire [3:0] thousands;
    // Instantiate the Unit Under Test (UUT)
    test_6 uut (
        .bin(bin), 
        .ones(ones), 
        .tens(tens), 
        .hundreds(hundreds), 
        .thousands(thousands)
    );

    initial begin
        // Initialize Inputs
            bin = 14'd1157;
        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here

    end
      
endmodule

问题分析与修正方案

原代码核心错误是Double Dabble算法执行顺序颠倒:算法要求先检查每组BCD值是否大于4(大于则加3),再执行左移操作;原代码先移位再检查修正,导致逻辑完全错误。

修正后的模块代码

`timescale 1ns / 1ps

module test_6( 
    input [13:0] bin ,
    output reg [3:0] ones,
    output reg [3:0] tens,
    output reg [3:0] hundreds,
    output reg [3:0] thousands
);

integer i;
reg [29:0] combined; // 4组BCD(16bit) + 14bit输入 = 30bit

always @(bin) begin
    // 初始化:4个BCD寄存器清零,拼接输入二进制数
    combined = {4'b0000, 4'b0000, 4'b0000, 4'b0000, bin[13:0]};

    for (i=0; i<14; i=i+1) begin 
        // 先检查每组BCD值,大于4则加3
        if (combined[17:14] > 4) begin 
            combined[17:14] = combined[17:14] + 4'b0011;
        end
        if (combined[21:18] > 4) begin 
            combined[21:18] = combined[21:18] + 4'b0011;
        end
        if (combined[25:22] > 4) begin
            combined[25:22] = combined[25:22] + 4'b0011;
        end
        if (combined[29:26] > 4) begin 
            combined[29:26] = combined[29:26] + 4'b0011;
        end
        
        // 左移一位,将输入的下一位移入BCD寄存器组
        combined = combined << 1;   
    end

    // 提取最终BCD值
    thousands = combined[29:26];  
    hundreds = combined[25:22];
    tens = combined[21:18];
    ones = combined[17:14];

    $display("ones: %0d, tens: %0d, hundreds: %0d, thousands: %0d", ones, tens, hundreds, thousands);
end

endmodule

修正说明

  1. 调整算法执行顺序:将"检查修正"步骤移到"左移"之前,严格遵循Double Dabble算法流程。
  2. 简化初始化逻辑:直接明确初始化4个BCD寄存器为0,避免额外的scratch寄存器,逻辑更清晰。
  3. 优化输出打印:合并多次$display,便于查看完整结果。

使用原测试平台仿真修正后的代码,输入14'd1157时,将输出预期的千位1、百位1、十位5、个位7。

内容的提问来源于stack exchange,提问作者Bojack Horseman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 23:10:31