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.

  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Nov 22, 2011 at 14:21
  • 1
    \$\begingroup\$ possible duplicate of Binary coded decimal ICs \$\endgroup\$
    – W5VO
    Nov 22, 2011 at 15:00
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Nov 22, 2011 at 16:35
  • 1
    \$\begingroup\$ It is part of a class project... \$\endgroup\$
    – Sednus
    Nov 22, 2011 at 16:53
  • 1
    \$\begingroup\$ "It is part of a class project". You should have mentioned that in the beginning. But you still haven't answered why no microcontroller. \$\endgroup\$ Nov 22, 2011 at 21:15

4 Answers 4


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.

  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – stevenvh
    Nov 22, 2011 at 15:06
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Majenko
    Nov 22, 2011 at 15:24
  • \$\begingroup\$ The FPGA might not have an internal RAM, either because it has none at all or that they are all already in use. \$\endgroup\$ Nov 22, 2011 at 17:13
  • \$\begingroup\$ @Mike DeSimone - the FPGA tools can implement small roms in the FPGA fabric itself if there are no block memories available. \$\endgroup\$ Nov 22, 2011 at 17:16
  • \$\begingroup\$ Some FPGA tools can do that, and of those, some require you to tell them explicitly to do that. \$\endgroup\$ Nov 22, 2011 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.

  • 1
    \$\begingroup\$ 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... \$\endgroup\$
    – Peque
    May 10, 2015 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)

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

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

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"

Finally, the postamble:

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



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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.