# Binary to BCD converison

I have an 8-bit number that the values ranges from 0 to 99. I need to convert that to a proper 8-bit BCD representation of the number using digital circuits.

In case you need to know, the original value is a temperature value read from a ADC and I need it in BCD to display it in two 7-segment displays. I cannot use a micro-controller.

• It makes no sense that you can't use a microcontroller. Any alternate circuitry will take more space and be more complex. Push back and find out what the real issue is behind the microcontroller restriction, then come back when you can state the real problem. – Olin Lathrop Nov 22 '11 at 14:21
• Is this homework? – Saad Nov 22 '11 at 14:27
• possible duplicate of Binary coded decimal ICs – W5VO Nov 22 '11 at 15:00
• This still makes no sense. Why does it have to be a FPGA? Certainly the speed is not required. A microcontroller would be more economical and easier to implement, and more flexible to change. Tell us the real requirements, not what you suppose the solution to be. – Olin Lathrop Nov 22 '11 at 16:35
• It is part of a class project... – Sednus Nov 22 '11 at 16:53

Simplest way:

Use a 256-byte EPROM / EEPROM.

The input value is applied to the address bus.

The output on the data bus is whatever you programmed it to be for that address - so program it with a mapping of binary to BCD values.

• This is the simplest solution, especially in component count: 1. However, if the reason microcontrollers are out is that OP can't program them, this is not going to help. – stevenvh Nov 22 '11 at 15:06
• He says he cannot use one - not why he cannot use one. He may be perfectly capable of using one but been told he mustn't. – Majenko Nov 22 '11 at 15:24
• The FPGA might not have an internal RAM, either because it has none at all or that they are all already in use. – Mike DeSimone Nov 22 '11 at 17:13
• @Mike DeSimone - the FPGA tools can implement small roms in the FPGA fabric itself if there are no block memories available. – Chris Stratton Nov 22 '11 at 17:16
• Some FPGA tools can do that, and of those, some require you to tell them explicitly to do that. – Mike DeSimone Nov 22 '11 at 21:18

The simple and fast way without any lookup table is using the double dabble algorithm. It operates by only shift by 1 and add 3 and iterates "the number of bits" times, hence very efficient on microcontrollers and architectures without multiplication/division and barrel shifter hardware

For example to convert 9710 = 110 00012 to BCD

0000 0000   1100001   Initialization
0000 0001   1000010   Shift (1)
0000 0011   0000100   Shift (2)
0000 0110   0001000   Shift (3)
0000 1001   0001000   Add 3 to ONES, since it was 6
0001 0010   0010000   Shift (4)
0010 0100   0100000   Shift (5)
0100 1000   1000000   Shift (6)
0100 1011   1000000   Add 3 to ONES, since it was 8
1001 0111   0000000   Shift (7)
9    7


The number is written with 7 bits (i.e. the most significant bit is bit 6) so it'll terminate after 7 shifts.

• This is the best solution when restricted to do a VHDL implementation in a FPGA. Wish I could upvote multiple times to give your answer better visibility... – Peque May 10 '15 at 19:42

You're supposed to do this with an FPGA? Write a program in some language (C, C++, Python, Perl... doesn't matter, as long as you're familiar with it) that generates the following output.

First, the preamble:

module BinaryToBCD
(
input [6:0] setting,
output [3:0] tens,
output [3:0] ones
)

always @(setting)
begin
case(setting)


Then, for each number from 0 to 99, generate this group of lines:

    7'd__: begin
tens = 4'd_;
ones = 4'd_;
end


Fill in the appropriate values where the _ are. A Python example:

for k in range(100):
print "    7'd%d: begin" % k
print "        tens = 4'd%d;" % (k // 10)
print "        ones = 4'd%d;" % (k % 10)
print "    end"
print


Finally, the postamble:

    default: begin
tens = 4'hX;
ones = 4'hX;
end

endcase
end

endmodule


Now you save this as a Verilog .v file and feed it to your FPGA compiler and let it do the dirty work.

Many, many things in FPGAs reduce to "write the code in whatever way solves the problem without too much fuss and let the compiler do the dirty work." Code generator programs are your friends.

Does the device have to do the conversion in a single step, or can it be an iterative process?

The cheapest method in terms of circuitry is probably to have a clocked circuit which, loaded with some number N in BCD format, and fed an single-bit input C, will load itself with 2*N+C on the next clock cycle. Feed such a circuit a binary number MSB first and after all the bits have been shifted in it will hold that number in BCD. This approach may be used with binary or BCD numbers of any size, observing that the carry out of one stage can't immediatley affect the carry out of the next stage until the next clock cycle.

If desired, one may use the BCD register to shift out the original number. For the general case, you'll have to arrange logic so that the portions of the register which hold part of the number in binary format have the BCD logic disabled so they act as straight shifter. In the particular case of two digits, one could preload the bottom three bits of the register with the three MSB's of the number, and the top 4 bits with the bottom four bits of the number, and simply not bother with any BCD logic for the upper digit (since it should be 0-9 anyway). When using more than two digits, somewhat fancier logic is needed, but it may still be worthwhile to use the same registers for holding the binary number and BCD result.

Incidentally, it's possible to use the reverse approach to convert a BCD number to binary. Each digit should be equal to its value divided by two (simple shift right), plus either five or zero depending upon the state of the next higher digit's LSB.