www.pudn.com > codeofvhdl2006.rar > BCD_ADD_SUB.VHD
--bcd_add_sub.vhd 3 digits bcd adder/subtractor with start and done library ieee ; use ieee.std_logic_1164.all; use work.components.all; entity bcd_add_sub is port( clock : in std_logic ;--時脈訊號 s : in std_logic ;--operate start enable ea : in std_logic ;--load a eb : in std_logic ;--load b dataa : in std_logic_vector(11 downto 0) ;--被加/減數 datab : in std_logic_vector(11 downto 0) ;--加/減數 sel : in std_logic ;--加/減模式選擇,0=>加,1=>減 sum : out std_logic_vector(15 downto 0) ;--和 done : out std_logic) ;--operate done end bcd_add_sub; architecture behavior of bcd_add_sub is type state_type is ( s1, s2 ) ;--state definition of fsm signal y : state_type ;--state delcare of fsm signal ec : std_logic ;--downcounter enable signal lc : std_logic ;--downcounter load signal z : std_logic ;--downcounter zero detect signal a : std_logic_vector(11 downto 0) ;--被加/減數register signal b : std_logic_vector(11 downto 0) ;--加/減數registr signal count : integer range 0 to 7 ;--counter signal sumc : std_logic_vector(11 downto 0) ;--bcd.sum -> negative.a interconnection signal co : std_logic ;--bcd3.co signal negative_com : std_logic ;--complement enable of negative sum begin fsm_transition: process ( clock ) begin if clock'event and clock = '1' then case y is when s1 => if z = '0' then y <= s1 ; else y <= s2 ; end if ; when s2 => if s = '1' then y <= s2 ; else y <= s1 ; end if ; end case ; end if ; end process ; fsm_output: process (y) begin case y is when s1 => done <= '0' ; when s2 => done <= '1' ; end case; end process; --datata register rega: regne generic map ( n => 12 ) port map ( dataa, ea, clock, a ) ; --datatb register regb: regne generic map ( n => 12 ) port map ( datab, eb, clock, b ) ; --downcounter ec <= '1' ; lc <= not s ; counter: downcnt generic map ( modulus => 8 ) port map ( clock, ec, lc, count ) ; z <= '1' when count = 0 else '0' ;--detect done --3 word bcd add/sub circuit bcd: bcd3 port map(a, b, sel, sel, co, sumc) ; --bcd.sumc 9's only if sel='1' for selecting sub mode and co='0' represent negative sum negative_com <= sel and (not co) ; --detect minus display and encode sum(15 downto 13) <= "000" when negative_com ='0' else "111" ; sum(12) <= ((not sel) and co) ; --10's negative sum correction circuit complement: negative port map(sumc, negative_com, sum(11 downto 0)) ; end behavior;;