2

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.

Sednus
  • 183
  • 2
  • 10
  • 2
    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 the "I cannot use a microcontroller" restriction from above ("Sednus, I want you to build this temperature -> 7-segment thing, and BTW - don't use a microcontroller") or from your own desires to avoid programming the microcontroller? – Kevin Vermeer Nov 22 '11 at 14:30
  • 1
    possible duplicate of [Binary coded decimal ICs](http://electronics.stackexchange.com/questions/10446/binary-coded-decimal-ics) – W5VO Nov 22 '11 at 15:00
  • Any practical solution is going to require a programmable device of some kind: be it a EPROM, CPLD, or Microcontroller. You could do it with discrete logic gates but that would only be practical if this is a homework assignment. We need more info before we can give you an acceptable answer. –  Nov 22 '11 at 15:37
  • I am supposed to design an air conditioner controller using an FPGA. I have most of the design done. I was just trying to find a simple way to get this conversion done. – Sednus Nov 22 '11 at 15:38
  • 1
    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
  • 1
    It is part of a class project... – Sednus Nov 22 '11 at 16:53
  • 1
    *"It is part of a class project"*. You should have mentioned that in the beginning. But you still haven't answered why no microcontroller. – Olin Lathrop Nov 22 '11 at 21:15
  • @Olin Lathrop - if it's an assignment, the selection of technologies is often artificially constrained in order to put the focus where intended for a given lesson. Additionally, this specific requirement has more efficient solutions within an fpga (ROM table) than inserting a soft processor core into the design if one is not needed for other purposes. – Chris Stratton Nov 22 '11 at 23:02
  • @Chris: Yes sometimes assignments artificially constrain, but it up to the OP to tell us this. I wasn't suggesting a soft core in a FPGA, just using a small micro. There is nothing here that makes a FPGA a better solution than just a micro. – Olin Lathrop Nov 22 '11 at 23:48
  • @Olin Lathrop - as stated, there's more to the project than this binary-to-BCD conversion need. Presumably the FPGA is chosen to meet educational and/or overall functional goals. Solving this one small part of the problem that is so simply accomplished with a table that it doesn't warrant a soft-core certainly doesn't warrant wiring up an external micro and bringing in it's support tools, until or unless there's some reason it can't be done internally or an educational mandate to use the external micro. – Chris Stratton Nov 23 '11 at 00:17
  • 1
    Here is a solution in VHDL http://www.doulos.com/knowhow/vhdl_designers_guide/models/binary_bcd/ – geometrikal Nov 23 '11 at 07:23

4 Answers4

5

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.

Majenko
  • 55,955
  • 9
  • 105
  • 187
  • 1
    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
  • 1
    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
  • @Mike DeSimone - model a ROM using language primitives and I'd be surprised if there is a tool that can't implement it in the fabric. Some tools however are smart enough to recognize that you want a memory, and substitute a block memory if one is available and meets the behavior modeled. You yourself seem to have posted an answer that depends on this capability of the tools to infer _some_ workable implementation, be it insightful or blind. – Chris Stratton Nov 22 '11 at 23:10
  • I remember having trouble with this with Altera's Quartus II a couple years back. Modeling a ROM meant that the Analysis & Synthesis stage would infer a ROM using a memory block, and then at Fitter time it would halt compilation if that put you over the number of memory blocks available. It couldn't back out the ROM into gates at Fitter time. So I had to do something (a checkbox or something) to tell it to force implementation as gates. – Mike DeSimone Nov 23 '11 at 02:54
4

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.

phuclv
  • 458
  • 4
  • 19
  • 1
    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
1

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.

Mike DeSimone
  • 4,705
  • 17
  • 22
1

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.

supercat
  • 45,939
  • 2
  • 84
  • 143