**double dabble"**is used for this.The explanation for the algorithm can be found here.

The function code is given below:

function to_bcd ( bin : std_logic_vector(7 downto 0) ) return std_logic_vector is

variable i : integer:=0;

variable bcd : std_logic_vector(11 downto 0) := (others => '0');

variable bint : std_logic_vector(7 downto 0) := bin;

begin

for i in 0 to 7 loop -- repeating 8 times.

bcd(11 downto 1) := bcd(10 downto 0); --shifting the bits.

bcd(0) := bint(7);

bint(7 downto 1) := bint(6 downto 0);

bint(0) :='0';

if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(3 downto 0) := bcd(3 downto 0) + "0011";

end if;

if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(7 downto 4) := bcd(7 downto 4) + "0011";

end if;

if(i < 7 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(11 downto 8) := bcd(11 downto 8) + "0011";

end if;

end loop;

return bcd;

end to_bcd;

variable i : integer:=0;

variable bcd : std_logic_vector(11 downto 0) := (others => '0');

variable bint : std_logic_vector(7 downto 0) := bin;

begin

for i in 0 to 7 loop -- repeating 8 times.

bcd(11 downto 1) := bcd(10 downto 0); --shifting the bits.

bcd(0) := bint(7);

bint(7 downto 1) := bint(6 downto 0);

bint(0) :='0';

if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(3 downto 0) := bcd(3 downto 0) + "0011";

end if;

if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(7 downto 4) := bcd(7 downto 4) + "0011";

end if;

if(i < 7 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(11 downto 8) := bcd(11 downto 8) + "0011";

end if;

end loop;

return bcd;

end to_bcd;

Some sample inputs and the corresponding outputs are shown below:

bin = "01100011" , output = "0000 1001 1001" (99).

bin = "11111110" , output = "0010 0101 0100" (254).

bin = "10111011" , output = "0001 1000 0111" (187).

The code is synthesisable, and the cell usage statistics for Virtex-5 FPGA is shown below:

# BELS : 24

# GND : 1

# LUT3 : 1

# LUT4 : 2

# LUT5 : 12

# LUT6 : 7

# MUXF7 : 1

# IO Buffers : 20

# IBUF : 8

# OBUF : 12

**Note**:- The code can be modified to convert any length binary number to BCD digits.This require very little change in the code.

Hi,

ReplyDeleteis it possible to create these netlist-graphics from the command-line using xilinx tools?

@marvin2k : See this link from xilinx.

ReplyDeletehttp://www.xilinx.com/itp/xilinx4/data/docs/xst/command_line9.html

@vipin: this is to synthesize a design? I meant something like the "RTL Viewer" mentioned in other posts (sorry, in fact I wanted to post in another blogentry of your blog...) to view the generated netlist.

ReplyDeleteThere is a command like this in that link :

ReplyDeleterun -ifn watchvhd.vhd -ifmt VHDL -ofn watchvhd.ngc -ofmt NGC -p xcv50-bg256-6 -opt_mode Speed

-opt_level 1

This will generate the ngc file.You have to open this file with a xilinx ngc file viewer.

Yes, and my question was if one can invoke such a tool from the commandline... sorry for this much text...

ReplyDeleteI havent explored command line options till.I guess you should try whatever is given in that link.Also share your experience here.

ReplyDeletecould we make it for n bit??

ReplyDelete@rourab : yes. you just have to understand the concept.you can make it for n bit. But the code will be more complicated.

ReplyDeletefunction to_bcd ( bin : std_logic_vector((n-1) downto 0) ) return std_logic_vector is

ReplyDeletevariable i : integer:=0;

variable j : integer:=1;

variable bcd : std_logic_vector(((4*q)-1) downto 0) := (others => '0');

variable bint : std_logic_vector((n-1) downto 0) := bin;

begin

for i in 0 to n-1 loop -- repeating 8 times.

bcd(((4*q)-1) downto 1) := bcd(((4*q)-2) downto 0); --shifting the bits.

bcd(0) := bint(n-1);

bint((n-1) downto 1) := bint((n-2) downto 0);

bint(0) :='0';

l1: for j in 1 to q loop

if(i < n-1 and bcd(((4*q)-1) downto ((4*q)-4)) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(((4*q)-1) downto ((4*q)-4)) := bcd(((4*q)-1) downto ((4*q)-4)) + "0011";

end if;

end loop l1;

end loop;

return bcd;

end to_bcd;

the previous code i have written in generic form ,where q is the number bcd digit,in that case i got the desire result up to 9 but when it exceed over 9 it gives the A,B,C,D,E,F. i cant get my mistake,

ReplyDeletevipin i have solved my problem just replacing the q by j in the inner loop

ReplyDeleterourab, please, can you tell me which q you replaced by j in the inner loop?

ReplyDeleteI wrote similar code, but without generic parameter, and I had same problem (A,B,C..F).

function to_bcd ( bin : std_logic_vector((n-1) downto 0) ) return std_logic_vector is

ReplyDeletevariable i : integer:=0;

variable j : integer:=1;

variable bcd : std_logic_vector(((4*q)-1) downto 0) := (others => '0');

variable bint : std_logic_vector((n-1) downto 0) := bin;

begin

for i in 0 to n-1 loop -- repeating 8 times.

bcd(((4*q)-1) downto 1) := bcd(((4*q)-2) downto 0); --shifting the bits.

bcd(0) := bint(n-1);

bint((n-1) downto 1) := bint((n-2) downto 0);

bint(0) :='0';

l1: for j in 1 to q loop

if(i < n-1 and bcd(((4*j)-1) downto ((4*j)-4)) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(((4*j)-1) downto ((4*j)-4)) := bcd(((4*j)-1) downto ((4*j)-4)) + "0011";

end if;

end loop l1;

end loop;

return bcd;

end to_bcd;

this is my code

rourab,

ReplyDeletethank you very much, but I still have problem with this code, even when its generic.

I wanted to convert 24-bit binary to 32-bit bcd and I inserted your function into my code, where I defined q := 8, because (4*q)-1) would be 32 bits.

When I wanna do 8-bit bin to 12-bit bcd, I need to define q := 3.

My question is:

What is relation between n and q, what is relation between number of bits for input (bin) and number of bits for output (bcd)?

Please, answer again...I am beginner and your little help is very great for me.

Sory for my bad english, i hope that you can understand me.

I found answer for my question, but I need help for implementing that solution.

ReplyDeleteRelation between n and q is :

**********************************************

q = round(n*(log(2)))

where q must be rounded to greater integer !!!,

**********************************************

for example:

for n = 24 and q = 8 it would be:

q = round (32*(log (2)))= round (24*0.3010)=round (7.224)= 8

I need help for implement this calculus for generic parameter (I want to make automatic calculus q = f(n)).

Is this possible to be done with "real" data type,could we use not-synthesizable data type for generic parameter , to make synthesizable entity ?

how to implement for D-ALGORITHM IN TESTING OF VLSI CIRCUITS" IN VHDL OR VERILOG?"

ReplyDeleteThanks, Men! That function helped me a lot. I made a physical implementation in a Spartan 3E using 8 switches as input and 3 displays as output. I wrote a post (Spanish) about it. I linked yours, of course!

ReplyDeleteHi, I have the same question/problem which Aleksander mentioned above.

ReplyDelete------------------------

Is this possible to be done with "real" data type,could we use not-synthesizable data type for generic parameter , to make synthesizable entity ?

------------------------

but, with a simpler implementation(from wiki): q = Roundup(n/3)

Could anyone help me with their views please ??

Thanks in advance.

Hello mate, I've written follow as your code above and my code is

ReplyDeleteLIBRARY ieee;

USE ieee.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.numeric_bit.all;

use IEEE.numeric_std.all;

use IEEE.std_logic_signed.all;

ENTITY ten_to_bcd IS

PORT ( b: IN std_logic_vector (7 downto 0) ; -- 10 bits input

y: OUT std_logic_vector( 11 downto 0)); -- 16 bits output / 4 digits

END ten_to_bcd;

ARCHITECTURE double_d OF ten_to_bcd IS

function dd( bin : std_logic_vector(7 downto 0) ) return std_logic_vector is

variable i : integer:=0;

variable bcd : std_logic_vector(11 downto 0) := "000000000000";

variable bint : std_logic_vector(7 downto 0) := bin;

variable kk : integer

begin

for i in 0 to 7 loop -- repeating 8 times.

bcd(11 downto 1) := bcd(10 downto 0); --shifting the bits.

bcd(0) := bint(7);

bint(7 downto 1) := bint(6 downto 0);

bint(0) :='0';

if(i < 7 and bcd(3 downto 0) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(3 downto 0) := bcd(3 downto 0) + "0011";

end if;

if(i < 7 and bcd(7 downto 4) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(7 downto 4) := bcd(7 downto 4) + "0011";

end if;

if(i < 7 and bcd(11 downto 8) > "0100") then --add 3 if BCD digit is greater than 4.

bcd(11 downto 8) := bcd(11 downto 8) + "0011";

end if;

end loop;

return bcd;

end dd;

begin

p:process(b)

begin

y <= dd(b);

end process;

END double_d;

so, I have some problem like when I run the simulation and when it get thought 15 , the value doesn't change to 16 but it shows 10 as tbl file mentioned below

0.0> 000 = 0000

10.0> 001 = 0001

20.0> 002 = 0002

30.0> 003 = 0003

40.0> 004 = 0004

50.0> 005 = 0005

60.0> 006 = 0006

70.0> 007 = 0007

80.0> 008 = 0008

90.0> 009 = 0009

100.0> 00A = 0010

110.0> 00B = 0011

120.0> 00C = 0012

130.0> 00D = 0013

140.0> 00E = 0014

150.0> 00F = 0015

160.0> 010 = 0010

170.0> 011 = 0011

180.0> 012 = 0012

190.0> 013 = 0013

200.0> 014 = 0020

could you please figure out what wrong with my code T^T

Thanksssss

Hi, did you managed to figure it out?

DeleteI am having the same issue.

Thanks!

This is my generic implementation:

ReplyDeletefunction ToBcd(bin : word; nbrDecs : positive) return word is

variable bcd : word(4*nbrDecs-1 downto 0);

variable bint : word(bin'length-1 downto 0);

variable i, j : integer;

begin

bint := bin;

bcd := (others => '0');

for i in 0 to bin'high loop

bcd(bcd'high downto 1) := bcd(bcd'high-1 downto 0); -- Shift

bcd(0) := bint(bin'high);

--

bint(bint'high downto 1) := bint(bint'high-1 downto 0); -- Shift

bint(0) := '0';

for j in 0 to nbrDecs-1 loop

if (i < bin'high and bcd((j+1)*4-1 downto j*4) > "0100") then

bcd((j+1)*4-1 downto j*4) := bcd((j+1)*4-1 downto j*4) + "0011";

end if;

end loop;

end loop;

return bcd;

end function;

Working on a project that will be using a modified code for binary to dual bcd outs.

ReplyDeleteHaving some issued mapping the inputs to our variables.

For example on input is marked as a and will be the MSB coming to the chipset.

There have been attempts to work it up as vin(7)<= a;

Would anyone be able to assist with explaining/helping/providing knowledge?

Thank you,

The main problem with your codes, is that when : '' add 3 if BCD digit is greater than 4 '' you do not pay attention of the eventual reminder, indeed if you have 1110, you add 3 because it is greater than 4, it should give you 10001 but you just keep 0001.

ReplyDeleteSincerly,

What's the proper way to do this? I am getting the same result as Sahacha Nilkumhang.

Delete