URL
https://opencores.org/ocsvn/special_functions_unit/special_functions_unit/trunk
Subversion Repositories special_functions_unit
[/] [special_functions_unit/] [Open_source_SFU/] [cordic_vhdl/] [parts/] [prueba.vhd] - Rev 4
Compare with Previous | Blame | View Log
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity prueba is --generic(K: natural:= 64; P: natural:= 53; E: natural:= 11); generic(K: natural:= 32; P: natural:= 24; E: natural:= 8); Port ( FP_A : in std_logic_vector (K-1 downto 0); FP_B : in std_logic_vector (K-1 downto 0); add_sub: in std_logic; --resta con '0', suma con '1'. FP_Z : out std_logic_vector (K-1 downto 0)); end prueba; architecture Behavioral of prueba is function log2 (n : natural) return natural is variable a, m : natural; begin a := 0; m := 1; while m < n loop a := a + 1; m := m * 2; end loop; return a; end log2; constant PLOG : natural := log2(P+3) - 1; constant ZEROS : std_logic_vector(K-1 downto 0) := (others => '0'); constant ONES : std_logic_vector(K-1 downto 0) := (others => '1'); signal A_int : std_logic_vector(K-1 downto 0); signal B_int : std_logic_vector(K-1 downto 0); signal expA_FF, expB_FF, expA_Z, expB_Z : std_logic; signal fracA_Z, fracB_Z : std_logic; signal isNaN_A, isNaN_B, isInf_A, isInf_B, isZero_A, isZero_B, isNaN, isInf : std_logic; signal underflow_sub : std_logic; signal sign_A, sign_B : std_logic; signal exp_A, exp_B : std_logic_vector(E-1 downto 0); signal efectExp: std_logic_vector(E downto 0); signal efectFracA, efectFracB, efectFracB_align : std_logic_vector(P+3 downto 0);--P-1+1+3 signal diffExpAB, diffExpBA, diffExp : std_logic_vector(E downto 0); signal addAB, addSubAB, subAB : std_logic_vector(P+3 downto 0); signal frac_add_Norm1 : std_logic_vector(P+3 downto 0); signal isSUB : std_logic; signal subBAExpEq : std_logic_vector(P+3 downto 0); signal frac_sub_Norm1 : std_logic_vector(P+3 downto 0); signal sign : std_logic; -- Component Declarations component right_shifter is generic (P: natural; E: natural; PLOG: natural); Port ( frac : in std_logic_vector (P downto 0); diff_exp : in std_logic_vector (E downto 0); frac_align : out std_logic_vector (P downto 0)); end component; component fp_leading_zeros_and_shift is generic (P: natural:= 27; E: natural := 8; PLOG: natural := 4); Port ( frac : in std_logic_vector (P downto 0); exp : in std_logic_vector (E-1 downto 0); frac_Norm : out std_logic_vector (P downto 0); exp_Norm : out std_logic_vector (E-1 downto 0); underFlow : out std_logic); end component; signal isZero_AorB : std_logic; --signals for stage 2 signal frac, frac_Norm1 : std_logic_vector (P+3 downto 0); signal frac_Norm2 : std_logic_vector (P-2 downto 0); signal frac_stg2 : std_logic_vector (P+3 downto 0); signal exp_Norm1, efectExp_stg2: std_logic_vector(E-1 downto 0); signal sign_stg2, isSUB_stg2, isNaN_stg2, isInf_stg2, overflow, underflow: std_logic; signal isZero_AorB_stg2: std_logic; signal isTwo : std_logic; signal exp_add_Norm1, exp_sub_Norm1 : std_logic_vector(E-1 downto 0); signal isRoundUp, didNorm1 : std_logic; signal FP_Z_int : std_logic_vector(K-1 downto 0); begin A_int <= FP_A; B_int <= FP_B; --unpacking and detections expA_FF <= '1' when A_int(K-2 downto K-E-1)= ONES(K-2 downto K-E-1) else '0'; --In single (30..23) expB_FF <= '1' when B_int(K-2 downto K-E-1)= ONES(K-2 downto K-E-1) else '0'; expA_Z <= '1' when A_int(K-2 downto K-E-1)= ZEROS(K-2 downto K-E-1) else '0'; expB_Z <= '1' when B_int(K-2 downto K-E-1)= ZEROS(K-2 downto K-E-1) else '0'; fracA_Z <= '1' when A_int(P-2 downto 0) = ZEROS(P-2 downto 0) else '0'; --In single (22..00) fracB_Z <= '1' when B_int(P-2 downto 0) = ZEROS(P-2 downto 0) else '0'; isNaN_A <= expA_FF and (not fracA_Z); isNaN_B <= expB_FF and (not fracB_Z); isInf_A <= expA_FF; -- not compared the fractional part since NaN has priority. isInf_B <= expB_FF; -- isZero_A <= expA_Z and fracA_Z; isZero_B <= expB_Z and fracB_Z; isZero_AorB <= isZero_A or isZero_B; --NaN Generacion del valor infinito. isNaN <= (isNaN_A or isNaN_B) or (isInf_A and isInf_B and isSUB); --NaN generation isInf <= (isInf_A xor isInf_B) or (isInf_A and isInf_B and (not isSUB)); --Infinite generation sign_A <= A_int(K-1); -- asignacion del valor de 32 bits. exp_A <= A_int(K-2 downto K-E-1); --in simple(30 .. 23); sign_B <= B_int(K-1) when add_sub='1' else not B_int(K-1); --establecimiento de bit de signo de operando B. exp_B <= B_int(K-2 downto K-E-1); --in simple(30 .. 23); isSUB <= sign_A XOR sign_B; diffExpAB <= ('0' & exp_A) - ('0' & exp_B); --one extra bit for sign diffExpBA <= ('0' & exp_B) - ('0' & exp_A); diffExp <= diffExpAB when diffExpAB(E)='0' else diffExpBA; --in binary32 E = 8; --swap efectFracA <= "01" & A_int(P-2 downto 0) & "000" when diffExpAB(E)='0' else "01" & B_int(P-2 downto 0) & "000"; efectFracB <= "01" & B_int(P-2 downto 0) & "000" when diffExpAB(E)='0' else "01" & A_int(P-2 downto 0) & "000"; efectExp <= '0' & exp_A when diffExpAB(E)='0' else '0' & exp_B; --in efectFracA, the number with bigger exponent, In efectFracB, nro with lower exp --> alignment needed --end swap --Effective alignment unioa: right_shifter generic map (P => P+3, E => E, PLOG => PLOG) port map( frac => efectFracB, diff_exp => diffExp, frac_align => efectFracB_align); --Addition / subtraction addAB <= efectFracA + efectFracB_align; subAB <= efectFracA - efectFracB_align; addSubAB <= addAB when isSUB = '0' else subAB ; --subtraction without alignment (equal exponents); no swap was done subBAExpEq <= (("01" & B_int(P-2 downto 0)) - ("01" & A_int(P-2 downto 0))) & "000"; --selection of correct fractional (significand) result frac <= "01" & B_int(P-2 downto 0) & "000" when isZero_A='1' else "01" & A_int(P-2 downto 0) & "000" when isZero_B='1' else subBAExpEq when subBAExpEq(P+3) = '0' and exp_A = exp_B and isSUB = '1' else addSubAB; --sign computation sign <= sign_A when sign_A = sign_B else sign_B when diffExpAB(E)='1' else sign_A when addSubAB(P+3)='0' else sign_B; -- isSpecialCase <= isZero_A or isZero_B or isNan or isInf; -- second stage: Norm1, Round And Norm2 frac_stg2 <= frac; efectExp_stg2 <= efectExp(E-1 downto 0); isZero_AorB_stg2 <= isZero_AorB; isNaN_stg2 <= isNaN; isInf_stg2 <= isInf; sign_stg2 <= sign; isSUB_stg2 <= isSUB; -- Establecimiento de criterios de normalizacion. --para sumas: addition_norm: process(frac_stg2) begin if (frac_stg2(P+3)='1') then frac_add_Norm1 <= '0' & frac_stg2(P+3 downto 2)&(frac_stg2(1) or frac_stg2(0)); didNorm1 <= '1'; else frac_add_Norm1 <= frac_stg2; didNorm1 <= '0'; end if; end process; isTwo <= '1' when (frac_stg2(P+2 downto 2)= ONES(P+2 downto 2)) else '0'; --only could happen in addition exp_add_Norm1 <= efectExp_stg2 + (didNorm1 or isTwo); --para resta: subtraction_norm: fp_leading_zeros_and_shift generic map(P => P+3, E => E, PLOG => PLOG) port map( frac => frac_stg2, exp => efectExp_stg2, frac_Norm => frac_sub_Norm1, exp_Norm => exp_sub_Norm1, underFlow => underflow_sub ); --seleccion entre suma resta: frac_Norm1 <= frac_add_Norm1 when isSUB_stg2 = '0' else frac_sub_Norm1; exp_Norm1 <= exp_add_Norm1(E-1 downto 0) when isSUB_stg2 = '0' else exp_sub_Norm1(E-1 downto 0); --aplicacion de criterios de redondeo, criterio de aprox al par. isRoundUp <= '1' when ( (frac_Norm1(2) = '1' and (frac_Norm1(1) = '1' or frac_Norm1(0) = '1')) or frac_Norm1(3 downto 0)="1100") else '0'; frac_Norm2 <= frac_Norm1(P+1 downto 3) + isRoundUp; --seguda normalizacion. --Itīs only necessary for the case 01.111...1111 (almost 2). This is catched with isTwo and round up. --overflow, underflow detection overflow <= '1' when (exp_Norm1 = ONES(E-1 downto 0) and (isSUB_stg2 = '0')) else '0'; underflow <= underflow_sub when isSUB_stg2 = '1' else '0'; --pack FP_Z_int <= sign_stg2 & ONES(E-1 downto 0) & ZEROS(P-2 downto 1) & '1' when isNaN_stg2='1' else sign_stg2 & ONES(E-1 downto 0) & ZEROS(P-2 downto 0) when (isInf_stg2='1' or overflow = '1') else sign_stg2 & efectExp_stg2(E-1 downto 0) & frac_stg2(P+1 downto 3) when isZero_AorB_stg2 = '1' else sign_stg2 & ZEROS(K-2 downto 0) when underflow='1' else --if underflow => to zero. sign_stg2 & exp_Norm1 & frac_Norm2; -- asignacion de salida. FP_Z <= FP_Z_int; end Behavioral;