OpenCores
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] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 divadnauj
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
 
6
entity prueba is
7
    --generic(K: natural:= 64; P: natural:= 53; E: natural:= 11);
8
    generic(K: natural:= 32; P: natural:= 24; E: natural:= 8);
9
    Port ( FP_A : in  std_logic_vector (K-1 downto 0);
10
           FP_B : in  std_logic_vector (K-1 downto 0);
11
           add_sub: in std_logic;                       --resta con '0', suma con '1'.
12
           FP_Z : out  std_logic_vector (K-1 downto 0));
13
end prueba;
14
 
15
architecture Behavioral of prueba is
16
   function log2 (n : natural) return natural is
17
      variable a, m : natural;
18
   begin
19
      a := 0; m := 1;
20
      while m < n loop
21
         a := a + 1; m := m * 2;
22
      end loop;
23
      return a;
24
   end log2;
25
   constant PLOG : natural := log2(P+3) - 1;
26
   constant ZEROS : std_logic_vector(K-1 downto 0) := (others => '0');
27
   constant ONES : std_logic_vector(K-1 downto 0) := (others => '1');
28
 
29
   signal A_int : std_logic_vector(K-1 downto 0);
30
   signal B_int : std_logic_vector(K-1 downto 0);
31
   signal expA_FF, expB_FF, expA_Z, expB_Z : std_logic;
32
   signal fracA_Z, fracB_Z : std_logic;
33
 
34
   signal isNaN_A, isNaN_B, isInf_A, isInf_B, isZero_A, isZero_B, isNaN, isInf : std_logic;
35
   signal underflow_sub : std_logic;
36
 
37
   signal sign_A, sign_B : std_logic;
38
   signal exp_A, exp_B  : std_logic_vector(E-1 downto 0);
39
 
40
   signal efectExp: std_logic_vector(E downto 0);
41
 
42
   signal efectFracA, efectFracB, efectFracB_align : std_logic_vector(P+3 downto 0);--P-1+1+3
43
   signal diffExpAB, diffExpBA, diffExp : std_logic_vector(E downto 0);
44
   signal addAB, addSubAB, subAB : std_logic_vector(P+3 downto 0);
45
   signal frac_add_Norm1    : std_logic_vector(P+3 downto 0);
46
   signal isSUB : std_logic;
47
 
48
   signal subBAExpEq : std_logic_vector(P+3 downto 0);
49
   signal frac_sub_Norm1 : std_logic_vector(P+3 downto 0);
50
   signal sign : std_logic;
51
 
52
   -- Component Declarations
53
   component right_shifter is
54
   generic (P: natural; E: natural; PLOG: natural);
55
   Port ( frac : in  std_logic_vector (P downto 0);
56
        diff_exp : in  std_logic_vector (E downto 0);
57
        frac_align : out  std_logic_vector (P downto 0));
58
   end component;
59
 
60
   component fp_leading_zeros_and_shift is
61
   generic (P: natural:= 27; E: natural := 8; PLOG: natural := 4);
62
   Port ( frac : in  std_logic_vector (P downto 0);
63
        exp     : in  std_logic_vector (E-1 downto 0);
64
        frac_Norm : out  std_logic_vector (P downto 0);
65
        exp_Norm : out  std_logic_vector (E-1 downto 0);
66
        underFlow : out std_logic);
67
   end component;
68
 
69
   signal isZero_AorB : std_logic;
70
 
71
   --signals for stage 2
72
   signal frac, frac_Norm1 : std_logic_vector (P+3 downto 0);
73
   signal frac_Norm2 : std_logic_vector (P-2 downto 0);
74
   signal frac_stg2 : std_logic_vector (P+3 downto 0);
75
   signal exp_Norm1, efectExp_stg2: std_logic_vector(E-1 downto 0);
76
   signal sign_stg2, isSUB_stg2, isNaN_stg2, isInf_stg2, overflow, underflow: std_logic;
77
   signal isZero_AorB_stg2: std_logic;
78
   signal isTwo : std_logic;
79
   signal exp_add_Norm1, exp_sub_Norm1 : std_logic_vector(E-1 downto 0);
80
   signal isRoundUp, didNorm1 : std_logic;
81
   signal FP_Z_int : std_logic_vector(K-1 downto 0);
82
 
83
begin
84
 
85
   A_int <= FP_A;
86
   B_int <= FP_B;
87
 
88
   --unpacking and detections
89
   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)
90
   expB_FF <= '1' when B_int(K-2 downto K-E-1)= ONES(K-2 downto K-E-1) else '0';
91
   expA_Z <= '1' when A_int(K-2 downto K-E-1)= ZEROS(K-2 downto K-E-1) else '0';
92
   expB_Z <= '1' when B_int(K-2 downto K-E-1)= ZEROS(K-2 downto K-E-1) else '0';
93
   fracA_Z <= '1' when A_int(P-2 downto 0) = ZEROS(P-2 downto 0) else '0'; --In single (22..00)
94
   fracB_Z <= '1' when B_int(P-2 downto 0) = ZEROS(P-2 downto 0) else '0';
95
 
96
   isNaN_A <= expA_FF and (not fracA_Z);
97
   isNaN_B <= expB_FF and (not fracB_Z);
98
   isInf_A <= expA_FF; -- not compared the fractional part since NaN has priority.
99
   isInf_B <= expB_FF; -- 
100
   isZero_A <= expA_Z and fracA_Z;
101
   isZero_B <= expB_Z and fracB_Z;
102
   isZero_AorB <= isZero_A or isZero_B;
103
 
104
   --NaN Generacion del valor infinito.
105
   isNaN <= (isNaN_A or isNaN_B) or (isInf_A and isInf_B and isSUB); --NaN generation
106
   isInf <= (isInf_A xor isInf_B) or (isInf_A and isInf_B and (not isSUB)); --Infinite generation
107
 
108
   sign_A <= A_int(K-1); -- asignacion del valor de 32 bits.
109
   exp_A <= A_int(K-2 downto K-E-1); --in simple(30 .. 23);
110
 
111
   sign_B <= B_int(K-1) when add_sub='1' else not B_int(K-1); --establecimiento de bit de signo de operando B.
112
   exp_B <= B_int(K-2 downto K-E-1); --in simple(30 .. 23);
113
 
114
   isSUB <= sign_A XOR sign_B;
115
 
116
   diffExpAB <= ('0' & exp_A) - ('0' & exp_B); --one extra bit for sign
117
   diffExpBA <= ('0' & exp_B) - ('0' & exp_A);
118
 
119
   diffExp <= diffExpAB when diffExpAB(E)='0' else diffExpBA; --in binary32 E = 8;
120
 
121
   --swap
122
   efectFracA <= "01" & A_int(P-2 downto 0) & "000" when diffExpAB(E)='0' else "01" & B_int(P-2 downto 0) & "000";
123
   efectFracB <= "01" & B_int(P-2 downto 0) & "000" when diffExpAB(E)='0' else "01" & A_int(P-2 downto 0) & "000";
124
   efectExp <= '0' & exp_A when diffExpAB(E)='0' else '0' & exp_B;
125
   --in efectFracA, the number with bigger exponent, In efectFracB, nro with lower exp --> alignment needed
126
   --end swap
127
 
128
   --Effective alignment
129
   unioa: right_shifter generic map (P => P+3, E => E, PLOG => PLOG)
130
                                                        port map( frac => efectFracB, diff_exp => diffExp, frac_align => efectFracB_align);
131
 
132
 
133
   --Addition / subtraction 
134
   addAB <= efectFracA + efectFracB_align;
135
   subAB <= efectFracA - efectFracB_align;
136
   addSubAB <= addAB when isSUB = '0' else subAB ;
137
 
138
   --subtraction without alignment (equal exponents); no swap was done
139
   subBAExpEq <= (("01" & B_int(P-2 downto 0)) - ("01" & A_int(P-2 downto 0))) & "000";
140
 
141
   --selection of correct fractional (significand) result
142
   frac <= "01" & B_int(P-2 downto 0) & "000" when isZero_A='1' else
143
           "01" & A_int(P-2 downto 0) & "000" when isZero_B='1' else
144
         subBAExpEq when subBAExpEq(P+3) = '0' and exp_A = exp_B and isSUB = '1' else
145
         addSubAB;
146
 
147
   --sign computation
148
   sign <= sign_A when sign_A = sign_B else
149
         sign_B when diffExpAB(E)='1' else
150
         sign_A when addSubAB(P+3)='0' else sign_B;
151
 
152
   -- isSpecialCase <= isZero_A or isZero_B or isNan or isInf;
153
 
154
   -- second stage: Norm1, Round And Norm2
155
   frac_stg2 <= frac;
156
   efectExp_stg2 <= efectExp(E-1 downto 0);
157
   isZero_AorB_stg2 <= isZero_AorB;
158
   isNaN_stg2 <= isNaN;
159
   isInf_stg2 <= isInf;
160
   sign_stg2 <= sign;
161
   isSUB_stg2 <= isSUB;
162
 
163
 
164
   -- Establecimiento de criterios de normalizacion.
165
 
166
   --para sumas:
167
   addition_norm: process(frac_stg2)
168
   begin
169
      if (frac_stg2(P+3)='1') then
170
         frac_add_Norm1 <= '0' & frac_stg2(P+3 downto 2)&(frac_stg2(1) or frac_stg2(0));
171
         didNorm1 <= '1';
172
      else
173
         frac_add_Norm1 <= frac_stg2;
174
         didNorm1 <= '0';
175
      end if;
176
   end process;
177
 
178
   isTwo <= '1' when (frac_stg2(P+2 downto 2)= ONES(P+2 downto 2)) else '0'; --only could happen in addition
179
   exp_add_Norm1 <= efectExp_stg2 + (didNorm1 or isTwo);
180
 
181
   --para resta:
182
   subtraction_norm: fp_leading_zeros_and_shift
183
   generic map(P => P+3, E => E, PLOG => PLOG)
184
   port map(
185
      frac       => frac_stg2,
186
      exp        => efectExp_stg2,
187
      frac_Norm  => frac_sub_Norm1,
188
      exp_Norm   => exp_sub_Norm1,
189
      underFlow  => underflow_sub
190
   );
191
 
192
   --seleccion entre suma resta:
193
   frac_Norm1 <= frac_add_Norm1 when isSUB_stg2 = '0' else frac_sub_Norm1;
194
   exp_Norm1 <= exp_add_Norm1(E-1 downto 0)  when isSUB_stg2 = '0' else exp_sub_Norm1(E-1 downto 0);
195
 
196
 
197
   --aplicacion de criterios de redondeo, criterio de aprox al par. 
198
   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';
199
   frac_Norm2 <= frac_Norm1(P+1 downto 3) + isRoundUp;
200
 
201
   --seguda normalizacion.
202
   --Itīs only necessary for the case 01.111...1111 (almost 2). This is catched with isTwo and round up.
203
 
204
   --overflow, underflow detection
205
   overflow <= '1' when (exp_Norm1 = ONES(E-1 downto 0) and (isSUB_stg2 = '0')) else '0';
206
   underflow <= underflow_sub when isSUB_stg2 = '1' else '0';
207
 
208
   --pack
209
   FP_Z_int <= sign_stg2 & ONES(E-1 downto 0) & ZEROS(P-2 downto 1) & '1' when isNaN_stg2='1' else
210
               sign_stg2 & ONES(E-1 downto 0) & ZEROS(P-2 downto 0) when (isInf_stg2='1' or overflow = '1') else
211
               sign_stg2 & efectExp_stg2(E-1 downto 0) & frac_stg2(P+1 downto 3) when isZero_AorB_stg2 = '1' else
212
               sign_stg2 & ZEROS(K-2 downto 0) when underflow='1' else --if underflow => to zero.
213
               sign_stg2 & exp_Norm1 & frac_Norm2;
214
 
215
   -- asignacion de salida.
216
            FP_Z <= FP_Z_int;
217
 
218
end Behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.