A binary to binary-coded decimal, or BCD for short, is a method storing decimal numbers in binary form. The majority of the time a number in a logic design is stored as a binary number internally as to simplify math and logic operations and converted to a set of BCD numbers only when it needs to then be sent to something that requires it in decimal number form i.e. a display of some sort. The Verilog and VHDL code below is for an 8-bit binary to BCD decoder that gives and ones, tens and hundreds decimal place output for driving a display or other device.
The modules below take a 8-bit binary number on the number input and converts that number into three 4-bit BCD numbers, one for each decimal place. These 4-bit BCD numbers are still binary numbers but each one only goes from 0 to 9, even though 4-bits can go from 0 to 15, to represent the 10 possibilities of a decimal number.
CODE
Verilog
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
`timescale 1ns / 1ps module bcd(number, hundreds, tens, ones); // I/O Signal Definitions input [7:0] number; output reg [3:0] hundreds; output reg [3:0] tens; output reg [3:0] ones; // Internal variable for storing bits reg [19:0] shift; integer i; always @(number) begin // Clear previous number and store new number in shift register shift[19:8] = 0; shift[7:0] = number; // Loop eight times for (i=0; i<8; i=i+1) begin if (shift[11:8] >= 5) shift[11:8] = shift[11:8] + 3; if (shift[15:12] >= 5) shift[15:12] = shift[15:12] + 3; if (shift[19:16] >= 5) shift[19:16] = shift[19:16] + 3; // Shift entire register left once shift = shift << 1; end // Push decimal numbers to output hundreds = shift[19:16]; tens = shift[15:12]; ones = shift[11:8]; end endmodule |
VHDL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity bcd is Port ( number : in std_logic_vector (7 downto 0); hundreds : out std_logic_vector (3 downto 0); tens : out std_logic_vector (3 downto 0); ones : out std_logic_vector (3 downto 0) ); end bcd; architecture Behavioral of bcd is begin bin_to_bcd : process (number) -- Internal variable for storing bits variable shift : unsigned(19 downto 0); -- Alias for parts of shift register alias num is shift(7 downto 0); alias one is shift(11 downto 8); alias ten is shift(15 downto 12); alias hun is shift(19 downto 16); begin -- Clear previous number and store new number in shift register num := unsigned(number); one := X"0"; ten := X"0"; hun := X"0"; -- Loop eight times for i in 1 to num'Length loop -- Check if any digit is greater than or equal to 5 if one >= 5 then one := one + 3; end if; if ten >= 5 then ten := ten + 3; end if; if hun >= 5 then hun := hun + 3; end if; -- Shift entire register left once shift := shift_left(shift, 1); end loop; -- Push decimal numbers to output hundreds <= std_logic_vector(hun); tens <= std_logic_vector(ten); ones <= std_logic_vector(one); end process; end Behavioral; |
Test Bench
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY TB_bcd IS END TB_bcd; ARCHITECTURE behavior OF TB_bcd IS -- Component Declaration for the Unit Under Test (UUT) component bcd port( number : in std_logic_vector(7 downto 0); hundreds : out std_logic_vector(3 downto 0); tens : out std_logic_vector(3 downto 0); ones : out std_logic_vector(3 downto 0) ); end component; --Inputs signal number : std_logic_vector(7 downto 0) := (others => '0'); --Outputs signal hundreds : std_logic_vector(3 downto 0); signal tens : std_logic_vector(3 downto 0); signal ones : std_logic_vector(3 downto 0); BEGIN -- Instantiate the Unit Under Test (UUT) uut: bcd port map ( number => number, hundreds => hundreds, tens => tens, ones => ones ); -- Stimulus process stim_proc: process begin loop number <= std_logic_vector(unsigned(number) + 1); wait for 10 ns; end loop; wait; end process; end; |
tnks for your code vhdl …it served me
vhdl code dont work, show error on alias num is shift(7 downto 0);
alias one is shift(11 downto 8);
alias ten is shift(15 downto 12);
alias hun is shift(19 downto 16);
What was the specific error that it gave about those lines? and what software tools (IDE) are you using?
Thanks for the info 🙂 nice clear implementation. Using this code, I created a decoder over at EDA Playground that takes a 14-bit decimal number (0 – 9999) and decodes it to 4 segments:
http://www.edaplayground.com/x/C4D
The code also works great on the DE0 board (Altera Cyclone III), where the only difference is the segment output is inverted to suit the boards active low hardware setup.
hai sir
i’m doing project on floating point numbers i want to convert decimal numbers to binary format. i request you to help me out in
thanking you
k.manjunath
Do you want to convert to BCD to standard binary or BCD to floating point?
hai sir
i’m doing project i want to convert decimal numbers to binary coded decimal format. i request you to help me out in verilog
thanking you
M.faizal
I don’t quite follow what you are asking, you provide more information?
hai sir
i’m doing project on floating point numbers i want to convert decimal numbers to bcd format. i request you to help me out in
Hello Sir,
I am doing a project on SPI master in slave out VHDL code. Can you please help me out in this please.
I would suggest you take a look at the OpenCores website at http://opencores.org/projects. They have many pre-made SPI modules that you could use.
hai sir
i’m doing project on floating point numbers i want to convert decimal numbers to bcd format. i request you to help me out in
I would suggest asking a forum, you will get a quicker response and greater variety of help with your project. A few suggestions would be:
http://www.edaboard.com/group128.html
https://groups.google.com/forum/m/#!forum/comp.lang.verilog
http://embdev.net/forum/fpga-vhdl-verilog
hai sir
i’m doing project on floating point numbers i want to convert Binary to decimal and decimal to binary , both using “floating point” values. I request you to help me out in this Sir..
thanking you,
Satheesh.R (M.E. VLSI)
Hello,
I have some difficulties simulating the code. I think that it is because there is no input clock signal in the BCD block. I am using Xilinx ISE 9.1. Do you have any idea what shall I do to make it work?
Thank you in preliminary!
The code for the Binary to BCD decoder is combinational logic (i.e. uses only AND, OR, ADDERS, … which don’t use clocks) but you do need to have some sort of timing controlling the input. If you look at the test bench above, you will notice that the inputs are changed (line #43) and then it waits for a period of time (line #45). This delay is to allow the changes on the inputs to ripple though all of the logic and show up on the output of the module. The amount of time that is required depends on what FPGA you are using/simulating. For an older Spartan 3 FPGA the time needs to be somewhere in the 30 ns range, where as a modern Spartan 6 is in the 10 ns range. The inputs can be controlled by a clock but the period of the clock would need to be longer than the time it takes for the changes to ripple through the logic. If the clock is to fast then the changes will have not made it to the output yet and when you attempt to read the output there will be invalid data.
Let me know if this helps or if you are still having trouble.
Hello Daniel,
It looks that my problem with the simulation was because ISE9.1 doesn’t work properly on Windows 7. I installed ISE 14.7 and everything works fine now. I only have troubles with creating testbenches. In 9.1 there was no need of testbench, because the adding of input signals was made by graphic way. Can you recommend me tutorial on this matter?
Best regards!
The process for creating a test bench is very similar to creating an new VHDL entity. When you use the New Source Wizard you select VHDL Test Bench rather that VHDL Module and then associate that test bench with the module that you want to test. ISE will then generate most of the support code needed to implement the test bench and then you would just need to write some code to stimulate the inputs in the same manner that you would change the outputs of an VHDL module. The only difference is since this is a simulation you can use the
wait for ##ns;
orwait until X = 'Y';
rather than relying on the clock. I would suggest looking at some of the test benches that I have supplied with the various modules I’ve written and there is a good video showing and overview of the process at the link below.https://www.youtube.com/watch?v=vlb-SlfDNpY
can we use and modify this for our project? this is a big help, and it works perfectly!
Funciona a la perfección el de verilog!! Gracias!!
i am trying to convert 8 bit to 10 bit my verilog code is not working but vhdl is working can you please help me?
my verilog code is following:
module binbcd8(input[7:0] b,output reg[9:0] p);
reg[17:0] z;
integer i;
always@(b)
begin
z <=17'b0;
z[10:3] <=b;
for(i=0;i4)
z[11:8]<=z[11:8]+3;
else
z4)
z[15:12]<=z[15:12]+3;
else
z<=z;
z[17:1]<=z[16:0];
end
p4 then
z(11 downto 8):=z(11 downto 8)+3;
end if;
if z(15 downto 12)>4 then
z(15 downto 12):=z(15 downto 12)+3;
end if;
z(17 downto 1):=z(16 downto 0);
end loop;
p<=z(17 downto 8);
end process;
end Behavioral;
I would suggest looking at Siytek code from the comment above at http://www.edaplayground.com/x/C4D. It is a 14 binary to BCD decoder that you can use.
my verilog is following:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:28:08 12/19/2015
// Design Name:
// Module Name: binbcd8
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 – File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module binbcd8(input[7:0] b,output reg[9:0] p);
reg[17:0] z;
integer i;
always@(b)
begin
z <=17'b0;
z[10:3] <=b;
for(i=0;i4)
z[11:8]<=z[11:8]+3;
else
z4)
z[15:12]<=z[15:12]+3;
else
z<=z;
z[17:1]<=z[16:0];
end
p<=z[17:8];
end
endmodule
Thank you For Verilog Code
Hello sir I am doing project Fast architecture for decimal digit multiplication .I want code for binary to BCD converter and binary multiplier
Hai sir
I’m doing project on “a high performance binary to BCD converter” ,i want clear details about this project, and why we using this project. Can u send me sir…..
Hi Daniel.
I tried the VHDL code and it works well. Thank you.
But can I modify your codes so it accepts a number up to 999?
Regards,
dummy_c
Everything is free and opensource so feel free to modify and change as you wish. Siytek posted a link to a modified version of this that can handle 14 bits at http://www.edaplayground.com/x/C4D, it might we worth taking a look at.
Wow just what I am looking for!
Since I will output it to 4 seven segments(using Nexys 3).
And thank you so much for the fast response I really
appreciate it Daniel.
More power to your blog. 😀
Thanks very much for this code! I’m making a Gameboy in VHDL and I wasn’t sure how to approach and instruction that converted the accumulator to BCD. I wanted to credit you in the bcd file but I don’t know your last name. Could you tell me your last name or another way you wish to be recognized?
Pingback: Binary Coded Signals | Rise Fall Trading
what ise have you used to write this code
It was written in Xilinx ISE 13.2.
Hi, do you allow guest posting on deathbylogic.com ? 🙂 Let me know on my email