---------------------------------------------------------- -- bloc divisor d'un nombre de 30 bits entre un de 16 -- -- creat per: Lluís Magí 1999 -- ---------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; ENTITY divi30bi IS PORT ( clear_n : in Std_Logic; ck : in Std_Logic; dividend_in : in integer range 0 to (2**30)-1; -- 30 bits divisor_in : in integer range 0 to (2**16)-1; -- 16 bits output_enable : out Std_Logic; quocient_out : out integer range 0 to (2**16)-1 -- 16 bits ); END divi30bi; ARCHITECTURE divisor OF divi30bi IS signal N : integer range 0 to 17 := 0; signal flag : std_logic; signal dividend : integer range -(2**30)+1 to (2**30)-1; -- 31 bits signal divisor : integer range -(2**30)+1 to (2**30)-1; -- 31 bits signal quocient : integer range 0 to (2**16)-1; -- 16 bits BEGIN ---------------------------------------------------------- -- Mentres ens mantinguem en l'estat N=0 no es fara cap -- -- operacio. En el moment que hi ha start=1 i un flanc -- -- de pujada del clock estarem 16 cicles fent la divisio-- -- Si en qualsevol moment clear=1, s'atura la divisio -- -- i es torna a l'estat N=0 -- -- Amb clear=1, el proces s'engega si en el raise del -- -- clock start=1. -- ---------------------------------------------------------- Proces_N: process (clear_n, ck) begin if clear_n = '0' then N <= 0; elsif ck'event and ck = '1' then if N = 17 then N <= 0; quocient_out <= quocient; output_enable <= '1'; else output_enable <= '0'; N <= N + 1; end if; end if; end process; Proces_Div: process(clear_n, ck) begin if clear_n = '0' then quocient <= 0; dividend <= 0; divisor <= 0; output_enable <= '0'; elsif ck'event and ck = '1' then if N = 0 then quocient <= 0; divisor <= divisor_in * 2**15; dividend <= dividend_in; flag <= '0'; elsif N = 1 THEN dividend <= 2*dividend - divisor; elsif N < 16 then if dividend >= 0 then dividend <= 2*dividend - divisor; quocient <= 2*quocient + 1; else dividend <= 2*dividend + divisor; quocient <= 2*quocient + 0; end if; elsif N = 16 THEN if dividend < 0 then quocient <= 2*quocient + 0; dividend <= dividend + divisor; flag <= '1'; else quocient <= 2*quocient + 1; end if; if divisor = 0 then quocient <= 0; END IF; end if; end if; end process; ----------------------------------------------------------------- -- output_enable sempre val 0, excepte el últim/primer cicle -- -- de rellotge en el qual el quocient de la divisio es -- -- valid, en que fa un pols d'un cicle a '1' -- ----------------------------------------------------------------- END divisor;