library BITLIB;
use BITLIB.bit_pack.all;

entity sdiv is
	port(Clk,St: in bit;
	     Dbus: in bit_vector(15 downto 0);
	     Quotient: out bit_vector(15 downto 0);
	     V, Rdy: out bit);
end sdiv;

architecture Signdiv of Sdiv is
  constant zero_vector: bit_vector(31 downto 0):=(others=>'0'); 
  signal State: integer range 0 to 6;
  signal Count : integer range 0 to 15;
  signal Sign,C,NC: bit;
  signal Divisor,Sum,Compout: bit_vector(15 downto 0);
  signal Dividend: bit_vector(31 downto 0);
  alias Q: bit_vector(15 downto 0) is Dividend(15 downto 0);
  alias Acc: bit_vector(15 downto 0) is Dividend(31 downto 16);
begin								-- concurrent statements
   compout <= divisor when divisor(15) = '1'		-- 1's complementer
     else not divisor;
   Addvec(Acc,compout,not divisor(15),Sum,C,16);	-- 16-bit adder
   Quotient <= Q;
   Rdy <= '1' when State=0 else '0';
   process
   begin
     wait until Clk = '1';  		-- wait for rising edge of clock
     case State is
	 when 0=>
	   if St = '1' then			
	     Acc <= Dbus;						-- load upper dividend
	     Sign <= Dbus(15);
	     State <= 1;
	     V <= '0';						-- initialize overflow
	     Count <= 0;						-- initialize counter
	   end if;
	 when 1=>
	   Q <= Dbus;						-- load lower dividend
	   State <= 2;
	 when 2=>
	   Divisor <= Dbus;
	   if Sign ='1'then		-- two's complement Dividend if necessary
	     addvec(not Dividend,zero_vector,'1',Dividend,NC,32);
	   end if;
	   State <= 3;
	 when 3=>
	   Dividend <= Dividend(30 downto 0) & '0'; 		-- left shift
	   Count <= Count+1;
	   State <= 4;
 	 when 4 =>
	   if C ='1' then						-- C
	     v <= '1';
	     State <= 0;
         else		 						-- C'
	     Dividend <= Dividend(30 downto 0) & '0'; 	-- left shift
	     Count <= Count+1;
	     State <= 5;	
	   end if;
	 when 5 =>
	   if C = '1' then 						-- C
	     ACC <= Sum;							-- subtract
	     Q(0)<= '1';
	   else
	     Dividend <= Dividend(30 downto 0) & '0';		-- left shift	
	     if Count = 15 then					-- KC' 	
	       count<= 0; State <= 6; 
               else Count <= Count+1;    
	     end if;
	   end if;
	 when 6=>
	   if C = '1' then						-- C
	     Acc <= Sum;							-- subtract
	     Q(0) <= '1';
	   else if (Sign xor Divisor(15))='1' then		-- C'Qneg
	       addvec(not Dividend,zero_vector,'1',Dividend,NC,32);
	     end if;					-- 2's complement Dividend
	     state <= 0;
	   end if;
     end case;
   end process;
end signdiv;

