OpenCores
URL https://opencores.org/ocsvn/bcd_adder/bcd_adder/trunk

Subversion Repositories bcd_adder

[/] [bcd_adder/] [trunk/] [rtl/] [BCD_adder.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 GilianB
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
entity BCD_adder is
5
        generic(
6
                --DEC_SIZE is the amount of decimal digits. e.g. BCD_ADD_DEC_SIZE = 4 means the highest representable integer is 9999
7
                DEC_SIZE : positive := 4
8
        );
9
        port(
10
                clk_i  : in  STD_LOGIC;
11
                a_i    : in  STD_LOGIC_VECTOR(4*DEC_SIZE-1 downto 0);
12
                b_i    : in  STD_LOGIC_VECTOR(4*DEC_SIZE-1 downto 0);
13
                sum_o  : out STD_LOGIC_VECTOR(4*DEC_SIZE-1 downto 0);
14
                cin_i  : in  STD_LOGIC;
15
                cout_o : out STD_LOGIC
16
        );
17
end entity;
18
architecture behavioral of BCD_adder is
19
 
20
        --input and output registers
21
        signal a_r    : unsigned(4*DEC_SIZE downto 0);
22
        signal b_r    : unsigned(4*DEC_SIZE downto 0);
23
        signal sum_r  : STD_LOGIC_VECTOR(4*DEC_SIZE-1 downto 0);
24
        signal cin_r  : STD_LOGIC;
25
        signal cout_r : STD_LOGIC;
26
 
27
        --increment6: a function to increment a 4 bit unsigned number by 6.
28
        function increment6 (number : unsigned(3 downto 0)) return unsigned is
29
        begin
30
                return ((number(3) or number(2) or number(1)) & ((number(2) or number(1)) nand (number(2) nand number(1))) & not(number(1)) & number(0));
31
        end function;
32
 
33
        --decrement6: a function to decrement a 4 bit unsigned number by 6.
34
        function decrement6 (number : unsigned(3 downto 0)) return unsigned is
35
        begin
36
                return ((number(3) and number(2) and number(1)) & (number(2) xor number(1)) & not(number(1)) & number(0));
37
        end function;
38
begin
39
        process(clk_i)
40
 
41
                --BCD_SIZE is the amount of binary digits that are needed for the BCD number. Each decimal digit is 4 bits, so 4*BCD_ADD_DEC_SIZE.
42
                constant BCD_SIZE : integer := 4*DEC_SIZE;
43 8 GilianB
                variable sum_v    : unsigned(BCD_SIZE downto 0);
44
                variable a_v      : unsigned(BCD_SIZE downto 0);
45
                variable b_v      : unsigned(BCD_SIZE downto 0);
46
                variable cin_v    : STD_LOGIC;
47 6 GilianB
        begin
48
                if rising_edge(clk_i) then
49
 
50
                        --Put the inputs in the variables, add a leading '0' to store a later carry.
51
                        a_r   <= unsigned('0' & a_i);
52
                        b_r   <= unsigned('0' & b_i);
53
                        cin_r <= cin_i;
54
                        a_v   := a_r;
55
                        b_v   := b_r;
56
                        cin_v := cin_r;
57
 
58
                        --increment every decimal digit of operand b by 6
59
                        for i in 0 to DEC_SIZE-1 loop
60
                                b_v(4*i+3 downto 4*i) := increment6(b_v(4*i+3 downto 4*i));
61
                        end loop;
62
 
63
                        --add a, b and the carry_in to form a temporary sum that needs to be corrected
64
                        sum_v := a_v + b_v + ("" & cin_v);
65
 
66
                        --correction: if the sum of two decimal digits exceeded 9, subtract 6 from the temporary sum
67
                        for j in 0 to DEC_SIZE-1 loop
68
                                if (sum_v(4*j+4) = (a_v(4*j+4) xor b_v(4*j+4))) then
69
                                        sum_v(4*j+3 downto 4*j) := decrement6(sum_v(4*j+3 downto 4*j));
70
                                end if;
71
                        end loop;
72
 
73
                        sum_r  <= STD_LOGIC_VECTOR(sum_v(BCD_SIZE-1 downto 0));
74
                        cout_r <= sum_v(BCD_SIZE);
75
                end if;
76
        end process;
77
        sum_o  <= sum_r;
78
        cout_o <= cout_r;
79
end behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.