Monday, March 17, 2014

four bit adder

-----------------------------------------------------------------
--four bit adder
--full adder of 2 four bits data and then convert the data to bcd
--then send the data out
-----------------------------------------------------------------

-----------------------------------------------------------------
--adder
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
library work;
use work.user_pkg.all;

entity adder is
port (
    clk   : in  std_logic                    ;
    rst_n : in  std_logic                    ;
    load  : in  std_logic                    ;
    a     : in  std_logic_vector(3 downto 0) ;
    b     : in  std_logic_vector(3 downto 0) ;
    y     : out std_logic_vector(3 downto 0)
);
end entity adder;

architecture behavioral of adder is
signal a_ff1     : std_logic_vector(3 downto 0);
signal a_ff2     : std_logic_vector(3 downto 0);
signal b_ff1     : std_logic_vector(3 downto 0);
signal b_ff2     : std_logic_vector(3 downto 0);
signal load_ff1  : std_logic;
signal load_ff2  : std_logic;
signal load_ff3  : std_logic;
signal load_trig : std_logic;

begin

process(clk, rst_n)
begin
    if(rst_n = '0') then
        a_ff1    <= (others => '0') ;
        a_ff2    <= (others => '0') ;
        b_ff1    <= (others => '0') ;
        b_ff2    <= (others => '0') ;
        load_ff1 <= '0'             ;
        load_ff2 <= '0'             ;
        load_ff3 <= '0'             ;
    elsif(rising_edge(clk)) then
        a_ff1    <= a        ;
        a_ff2    <= a_ff1    ;
        b_ff1    <= b        ;
        b_ff2    <= b_ff1    ;
        load_ff1 <= load     ;
        load_ff2 <= load_ff1 ;
        load_ff3 <= load_ff2 ;
    end if;
end process;

load_trig <= load_ff2 and (not load_ff3);

process(clk, rst_n)
begin
    if(rst_n = '0') then
        y <= (others => '0');
    elsif(rising_edge(clk)) then
        if(load_trig = '1') then
            four_bit_adder(a_ff2, b_ff2, y);
        end if;
    end if;
end process;

end behavioral;

-----------------------------------------------------------------
--process one bit of bin to convert to bcd
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity process_one_bit is
port (
    shift_in  : in std_logic;
    bcd_in    : in std_logic_vector(3 downto 0);
    bcd_out   : out std_logic_vector(3 downto 0);
    shift_out : out std_logic
);
end entity process_one_bit;

architecture behavioral of process_one_bit is
signal bcd_tmp: std_logic_vector(3 downto 0);

begin

bcd_tmp(3 downto 1) <= bcd_in(2 downto 0);
bcd_tmp(0) <= shift_in;
shift_out <= bcd_in(3);

--add 3 when bcd is greater than 4
process(bcd_tmp, shift_in)
begin
    if(bcd_tmp > "0100") then
        bcd_out <= bcd_tmp + "0011";
    else
        bcd_out <= bcd_tmp;
    end if;
end process;

end behavioral;

-----------------------------------------------------------------
--process one bcd
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity one_bcd is
port (
    shift_in  : in std_logic_vector(3 downto 0);
    bcd_in    : in std_logic_vector(3 downto 0);
    bcd_out   : out std_logic_vector(3 downto 0);
    shift_out : out std_logic_vector(3 downto 0)
);
end entity one_bcd;

architecture behavioral of one_bcd is
component process_one_bit is
    port (
        shift_in  : in std_logic;
        bcd_in    : in std_logic_vector(3 downto 0);
        bcd_out   : out std_logic_vector(3 downto 0);
        shift_out : out std_logic
    );
end component;


signal bcd_out1: std_logic_vector(3 downto 0);
signal bcd_out2: std_logic_vector(3 downto 0);
signal bcd_out3: std_logic_vector(3 downto 0);

begin

u_process_one_bit_3: process_one_bit port map (
    shift_in  => shift_in(3),
    bcd_in    => bcd_in,
    bcd_out   => bcd_out3,
    shift_out => shift_out(3)
);

u_process_one_bit_2: process_one_bit port map (
    shift_in  => shift_in(2),
    bcd_in    => bcd_out3,
    bcd_out   => bcd_out2,
    shift_out => shift_out(2)
);

u_process_one_bit_1: process_one_bit port map (
    shift_in  => shift_in(1),
    bcd_in    => bcd_out2,
    bcd_out   => bcd_out1,
    shift_out => shift_out(1)
);

bcd_out(3 downto 1) <= bcd_out1(2 downto 0);
bcd_out(0) <= shift_in(0);
shift_out(0) <= bcd_out1(3);

end behavioral;

-----------------------------------------------------------------
--bin to bcd
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity bin2bcd is
port (
    bin   : in  std_logic_vector(3 downto 0) ;
    bcd   : out std_logic_vector(7 downto 0)
);
end entity bin2bcd;

architecture behavioral of bin2bcd is
signal bcd_tmp    : std_logic_vector(7 downto 0);
signal shift_out0 : std_logic_vector(3 downto 0);
signal shift_out1 : std_logic_vector(3 downto 0);

component one_bcd is
port (
    shift_in  : in std_logic_vector(3 downto 0);
    bcd_in    : in std_logic_vector(3 downto 0);
    bcd_out   : out std_logic_vector(3 downto 0);
    shift_out : out std_logic_vector(3 downto 0)
);
end component;

begin

--change bin to bcd for data 0
u_one_bcd_0: one_bcd PORT MAP (
    shift_in  => bin,
    bcd_in    => b"0000",
    bcd_out   => bcd_tmp(3 downto 0),
    shift_out => shift_out0
);

--change bin to bcd for data 1
u_one_bcd_1: one_bcd PORT MAP (
    shift_in  => shift_out0,
    bcd_in    => b"0000",
    bcd_out   => bcd_tmp(7 downto 4),
    shift_out => shift_out1
);

--send bcd out
bcd <= bcd_tmp;

end behavioral;

-----------------------------------------------------------------
--bcd to segment
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity bcd2segment is
port (
    bcd     : in  std_logic_vector(3 downto 0) ;
    segment : out std_logic_vector(6 downto 0)
);
end entity bcd2segment;

architecture behavioral of bcd2segment is

begin

process(bcd)
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"1000000";
        when x"1" => segment <= b"1111001";
        when x"2" => segment <= b"0100100";
        when x"3" => segment <= b"0110000";
        when x"4" => segment <= b"0011001";
        when x"5" => segment <= b"0010010";
        when x"6" => segment <= b"0000010";
        when x"7" => segment <= b"1111000";
        when x"8" => segment <= b"0000000";
        when x"9" => segment <= b"0010000";
        --when in selector 1, counter should add 1 after each half second
        --for other unknown selectors, set counter to 0
        when others => segment <= b"1000000";
    end case;
end process;

end behavioral;

-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
port (
    clk      : in  std_logic                    ;
    rst_n    : in  std_logic                    ;
    load     : in  std_logic                    ;
    a        : in  std_logic_vector(3 downto 0) ;
    b        : in  std_logic_vector(3 downto 0) ;
    segment0 : out std_logic_vector(6 downto 0) ;
    segment1 : out std_logic_vector(6 downto 0)
);
end entity top;

architecture behavioral of top is
--signal declaration in architecture
signal y   : std_logic_vector(3 downto 0) ;
signal bcd : std_logic_vector(7 downto 0) ;

component adder is
port (
    clk   : in  std_logic                    ;
    rst_n : in  std_logic                    ;
    load  : in  std_logic                    ;
    a     : in  std_logic_vector(3 downto 0) ;
    b     : in  std_logic_vector(3 downto 0) ;
    y     : out std_logic_vector(3 downto 0)
);
end component;

component bin2bcd is
port (
    bin   : in  std_logic_vector(3 downto 0) ;
    bcd   : out std_logic_vector(7 downto 0)
);
end component;

component bcd2segment is
port (
    bcd     : in  std_logic_vector(3 downto 0) ;
    segment : out std_logic_vector(6 downto 0)
);
end component;

--begin of architecture
begin

--instance adder
u_adder: adder port map (
    clk   => clk   ,
    rst_n => rst_n ,
    load  => load  ,
    a     => a     ,
    b     => b     ,
    y     => y      
);

--instance bin2bcd
u_bin2bcd: bin2bcd PORT MAP (
    bin   => y   ,
    bcd   => bcd  
);

--instance segment0
u_bcd2segment_0: bcd2segment PORT MAP (
    bcd     => bcd(3 downto 0) ,
    segment => segment0        
);

--instance segment1
u_bcd2segment_1: bcd2segment PORT MAP (
    bcd     => bcd(7 downto 4) ,
    segment => segment1        
);

end behavioral;
--end of architecture

-----------------------------------------------------------------
--user_pkg.vhd
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

package user_pkg is
procedure four_bit_adder (signal a, b: in std_logic_vector(3 downto 0); signal y : out std_logic_vector(3 downto 0));
end;

package body user_pkg is

procedure four_bit_adder (
    signal a, b: in std_logic_vector(3 downto 0);
    signal y : out std_logic_vector(3 downto 0)
) is
variable i  : integer;
variable c  : std_logic_vector(4 downto 0);
begin
    c(0) := '0';
    for i in 0 to 3 loop
        y(i) <= a(i) xor b(i) xor c(i);
        c(i+1) := (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i));
    end loop;
end procedure four_bit_adder;

end package body;

No comments:

Post a Comment