I am trying to build a binary to BCD converter using the double dabble algorithm. I wrote the code for the same, and when I simulated the entire thing, it was observed that my if statement is not getting executed properly.
`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
The testbench is given below.
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
The output on the simulation window was as shown:
The output I am expecting is:
Thousands should have the value 1, hundreds should have the value 1, tens should have the value 5, ones should have the value 7.
The mistake in your code is that you did not follow the double dabble algorithm. From Wikipedia:
The algorithm then iterates n times. On each iteration, any BCD digit which is at least 5 (0101 in binary) is incremented by 3 (0011); then the entire scratch space is left-shifted one bit.
You performed the left shift before the add-by-3, but it should be done after.
for (i=0; i<14; i=i+1) begin
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
combined = combined<<1; // left shift by 1
end
Now I get the expected output: 1157
.
After I posted my other answer, I was curious as to how the algorithm worked. So, I decided to try to follow the description as you did.