使用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
修正说明
- 调整算法执行顺序:将"检查修正"步骤移到"左移"之前,严格遵循Double Dabble算法流程。
- 简化初始化逻辑:直接明确初始化4个BCD寄存器为0,避免额外的scratch寄存器,逻辑更清晰。
- 优化输出打印:合并多次
$display,便于查看完整结果。
使用原测试平台仿真修正后的代码,输入14'd1157时,将输出预期的千位1、百位1、十位5、个位7。
内容的提问来源于stack exchange,提问作者Bojack Horseman
相关产品推荐
相关产品推荐

