This model came about as a result of wondering if there was a simple hardware way of converting a binary number to Binary Coded Decimal (BCD). The clue required (courtesy of a quick search on the web) was found in a Xilinx Application note, XAPP029. This documents a serial binary to bcd conversion algorithm which, as usual, seems obvious once you've seen the idea!

The basic idea is to shift data serially into a shift register. As each bit is shifted in, the accumulated sum is collected. Each shift effectively doubles the value of the binary number in the four bit shift register which is going to hold the converted BCD digit.

Each time a bit is shifted in, the value in the shift register is doubled. After four bits have been shifted in, if the original value is 0, 1, 2, 3, or 4, then the result is within the 0-9 range of a BCD digit and there is no action required.

If the value is 5, 6, 7, 8, or 9, then the doubled result is greater than 10, so a carry out (called ModOut in the code) is generated to represent the overflow into the tens column (i.e. into the next BCD digit). Here's a little table showing how to double each bit in BCD. All numbers shown are decimal.

input tens units result 0 0 0 0 1 0 2 2 2 0 4 4 3 0 6 6 4 0 8 8 5 1 0 10 6 1 2 12 7 1 4 14 8 1 6 16 9 1 8 18

The tens column thus represents an overflow into the next most significant BCD digit.

Does this all seems a bit baffling? There's a more thorough explanation in the application note referenced above.

### The code

The code is in three files:

**digit.vhd**

This contains a model for one four bit BCD digit, with carry in (ModIn) and carry out (ModOut). The digit has asynchronous reset, and an Init signal. The Init signal forces the carry out to zero at before a conversion starts.

**bcdconv.vhd**

This contains a generic N which allows you to specify the number of 4 bit BCD digits in the BCD converter. The generic is used to control a generate statement, which makes N instances of the Digit component described above.

**bcdconvtb.vhd**

This contains a testbench which applies a serial binary input representing a range of binary numbers, and then writes out the corresponding BCD equivalents.

### Further work

The design was written for ease of comprehension, not for optimal area when synthesised. If you look at the original application note referred to above, the design was implemented at a lower level to ensure that the decoding logic would fit into a single four input lookup table. This is left as an exercise for the reader.

### Download the Code

The code is available as either a zip file (for Windows operating systems) or as a tar file (for Unix). Here are the links:

Your e-mail comments are welcome - *send email*