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;;