library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; -- DIVISOR_WIDTH*2 -1 = DIVIDEND_WIDTH entity divider is generic ( DELAY : POSITIVE := 1; DIVIDEND_WIDTH : POSITIVE := 15; DIVISOR_WIDTH : POSITIVE := 8 ); port( clock, reset : in std_logic; a : in std_logic_vector( DIVISOR_WIDTH-1 downto 0); b : in std_logic_vector( DIVIDEND_WIDTH-1 downto 0); done_div : out std_logic; quotient,remainder : out std_logic_vector( DIVISOR_WIDTH-1 downto 0) ); end divider2; architecture behavioural of divider2 is type STATES is (load, shift, subtract_and_set, done,catchup); signal present_state, next_state : STATES; begin control: process( present_state,clock ) variable M : std_logic_vector( DIVISOR_WIDTH -1 downto 0); variable Q : std_logic_vector( DIVIDEND_WIDTH -1 downto 0); variable bout : std_logic; variable P : std_logic_vector( DIVISOR_WIDTH-1 downto 0); variable Counter : INTEGER := 0; variable bitcounter : INTEGER := 0; variable flag : INTEGER := 0; variable sub : std_logic_vector( DIVISOR_WIDTH downto 0); variable temp : std_logic; begin if( rising_edge(clock)) then case present_state is when load => M := a; Q := b; P := (others => '0'); bout := '0'; Counter := 0; bitcounter := 0; next_state <= shift; done_div <= '0'; flag := 0; when shift => if( Counter <= (DIVISOR_WIDTH-2 )) then P(DIVISOR_WIDTH-1 downto 1) := P(DIVISOR_WIDTH-2 downto 0); P(0) := Q(DIVIDEND_WIDTH-1); Q(DIVIDEND_WIDTH - 1 downto 1) := Q(DIVIDEND_WIDTH-2 downto 0); Q(0) := '0'; Counter := Counter + 1; bout := '0'; if( Counter > (DIVISOR_WIDTH-2)) then next_state <= catchup; else next_state <= shift; end if; else if( bitcounter > DIVISOR_WIDTH - 1 ) then next_state <= done; else temp := P(DIVISOR_WIDTH-1); P := P(DIVISOR_WIDTH-2 downto 0) & Q(DIVIDEND_WIDTH-1); Q := Q(DIVIDEND_WIDTH-2 downto 0) & temp; bitcounter := bitcounter + 1; next_state <= catchup; end if; end if; when catchup => if( flag = DELAY ) then next_state <= subtract_and_set; flag := 0; else flag := flag + 1; next_state <= catchup; end if; when subtract_and_set => sub := P - M; bout := sub(DIVISOR_WIDTH); if( bout = '0' ) then P := sub(DIVISOR_WIDTH-1 downto 0); Q(0) := '1'; next_state <= shift; else next_state <= shift; end if; when done => quotient <= Q(DIVISOR_WIDTH-1 downto 0); remainder <= P; done_div <= '1'; end case; end if; end process control; timing : process(clock,reset) begin if( reset = '1') then present_state <= load; elsif( rising_edge(clock)) then present_state <= next_state; end if; end process timing; end behavioural;