------------------------------------- -- Define Data Width -- ------------------------------------- package mypackage is constant NBITS: natural := 15; constant PBITS: natural := 16; -- should be 2**i constant FBITS: natural := 8; -- Bits at first stage function log_base_2(num: in natural)return natural; end mypackage; package body mypackage is function log_base_2(num: in natural) return natural is variable i,aux: natural; begin i := 1; aux := num/2; while (aux > 1) loop aux := aux/2; i := i+1; end loop; return i; end function; end mypackage; --------------------------------------------------------------- -- Newton-Raphson inverter -- X is 0.xxxxxxxx -- The result Q is 1.yyyyyyy The first '1' is provided at position Q(PBITS) -- --------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; USE work.mypackage.all; entity newton_raphson is port ( X: in std_logic_vector (NBITS-1 downto 0); -- 0.1XXXX Q: out std_logic_vector (PBITS downto 0) -- 1.XXXXX ); end newton_raphson; architecture behavioural of newton_raphson is component newton_raphson_step generic(XBITS : integer); port ( r: in std_logic_vector (XBITS downto 0); d: in std_logic_vector (NBITS-1 downto 0); r_n: out std_logic_vector (2*XBITS downto 0) ); end component; component LUT_Newton_Raphson port ( x: in std_logic_vector (NBITS-1 downto 0); l: out std_logic_vector (FBITS downto 0) ); end component; constant LOG_P: natural := log_base_2(PBITS); constant LOG_F: natural := log_base_2(FBITS); type remainder is array (0 to LOG_P-1) of std_logic_vector (PBITS downto 0); signal r: remainder; signal lut_val: std_logic_vector (FBITS downto 0); begin lut: LUT_Newton_Raphson port map (x =>X, l => lut_val); r(LOG_F-1)(PBITS downto PBITS-FBITS) <= lut_val; gen_p: for i in LOG_F to LOG_P-1 generate cell: newton_raphson_step generic map(2**i) port map (r => r(i-1)(PBITS downto PBITS-2**i), d=> X, r_n => r(i)(PBITS downto PBITS-2**(i+1)) ); end generate; Q <= r(LOG_P-1)(PBITS downto 0); end behavioural; --------------------------------------------------------------- -- Newton-Raphson inverter: Divsion STEP -- XBITS determines the data width -- --------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.mypackage.all; entity newton_raphson_step is generic(XBITS : integer := 4); port ( r: in std_logic_vector (XBITS downto 0); --r(XBITS) always '1' d: in std_logic_vector (NBITS-1 downto 0); r_n: out std_logic_vector (2*XBITS downto 0) ); end newton_raphson_step; architecture behavioural of newton_raphson_step is signal r_x_d, r_x_d_neg: std_logic_vector (XBITS+NBITS downto 0); signal r_n_long: std_logic_vector (2*XBITS+NBITS+1 downto 0); begin r_x_d <= r * d; r_x_d_neg <= not (r_x_d) + 1; r_n_long <= r * r_x_d_neg; r_n <= r_n_long(2*XBITS+NBITS downto NBITS); end behavioural; --------------------------------------------------------------- -- Newton-Raphson inverter: Look up table (behavioural implementation) -- Calculate the first result with FBITS precision. -- --------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.mypackage.all; entity LUT_Newton_Raphson is port ( x: in std_logic_vector (NBITS-1 downto 0); l: out std_logic_vector (FBITS downto 0) ); end LUT_Newton_Raphson; architecture behavioural of LUT_Newton_Raphson is signal xi: natural; begin xi <= conv_integer(x); process(x,xi) variable xi_inv: real; variable xi_shift: natural; begin if (xi = 0) then l <= (others => '1'); else xi_inv := real(2**(NBITS-1)) / real(xi); if (xi_inv < 1.0) then xi_shift := natural(xi_inv * real(2**(FBITS+1))-0.5); l <= conv_std_logic_vector(xi_shift,FBITS+1); else l <= (others => '1'); end if; end if; end process; end behavioural;