OpenCores
URL https://opencores.org/ocsvn/special_functions_unit/special_functions_unit/trunk

Subversion Repositories special_functions_unit

[/] [special_functions_unit/] [Open_source_SFU/] [exp2_vhdl/] [exp2_fp.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 divadnauj
-- Proyecto                             : EXPONENT BASE 2 IEEE754
2
-- Nombre de archivo    : exp2_fp.vhd
3
--      Titulo                          : operacion exponencial base 2
4
-----------------------------------------------------------------------------   
5
-- Descripcion                  : calcula la potencia en base de dos de un numero en
6
--                                                        formato IEEE754.
7
--
8
--              MANTISBITS              : Numero de bits de la mantisa
9
--              EXPBITS                 : Numero de bits del exponente
10
--      SEG                             : Numero de segmentos utilizados para la aproximacion
11
--              SEGBITS                 : Ancho del segmento
12
--      i_x                             : Numero en formato numerico IEEE754
13
--      o_exp2                  : Resultado en formato numerico IEEE754
14
-- 
15
-- Notas: 
16
--              las constantes correspondientes a los segmentos se encuentran en 
17
--      complemento a 2.
18
--              c_BX controla la cantidad de desplazamientos hacia la derecha para el
19
--              dato de entrada. Conforme se incrementa se aumenta la precision para
20
--              valores de entrada con exponente negativo, a su vez se incrementa el
21
--              numero de multiplexores para realizar el desplazamiento.
22
-----------------------------------------------------------------------------   
23
-- Universidad Pedagogica y Tecnologica de Colombia.
24
-- Facultad de ingenieria.
25
-- Escuela de ingenieria Electronica - extension Tunja.
26
-- 
27
-- Autor: Cristhian Fernando Moreno Manrique
28
-- Mayo 2020
29
-----------------------------------------------------------------------------   
30
 
31
library ieee;
32
        use ieee.std_logic_1164.all;
33
        use ieee.numeric_std.all;
34
        use work.log2_pkg.all;
35
 
36
 
37
entity exp2_fp is
38
        generic (MANTISBITS                             :               natural:= 23;           -- Formato IEEE754:
39
                                EXPBITS                                 :               natural:= 8;            -- signo[1] & exponente[8] & mantisa[23]
40
                                SEG                                             :               natural:= 64;
41
                                SEGBITS                                 :               natural:= 23);
42
        port      (i_x                                          : in    std_logic_vector(EXPBITS+MANTISBITS downto 0);
43
                                o_exp2                                  : out std_logic_vector(EXPBITS+MANTISBITS downto 0));
44
end entity;
45
 
46
 
47
architecture arch of exp2_fp is
48
        constant c_BX                                           : natural       := 16;  -- %errormax: BX=16: 0.00105,  BX=12: 0.0169
49
        constant c_64seg_23b                            : std_logic_vector(SEGBITS-1 downto 0) := "11111111111111101011101";
50
        constant c_log2_seg                             : natural       := f_log2(SEG);
51
 
52
        signal w_mantis                                 : std_logic_vector(MANTISBITS-1 downto 0);
53
        signal w_exp                                            : std_logic_vector(EXPBITS-1 downto 0);
54
        signal w_sgn                                            : std_logic;
55
 
56
        signal w_exp_adj                                        : std_logic_vector(EXPBITS-2 downto 0); -- se ajusta segun el valor maximo calculable
57
        signal w_adderA_iterm1                  : std_logic_vector(EXPBITS-2 downto 0);
58
        signal w_adderA                                 : std_logic_vector(EXPBITS-2 downto 0);
59
        signal w_mantis_adj                             : std_logic_vector(c_BX+EXPBITS+MANTISBITS-2 downto 0);
60
        signal w_lshifter                                       : std_logic_vector(w_mantis_adj'left downto 0);
61
        signal w_lshifter_ishifts               : std_logic_vector(f_log2(w_mantis_adj'length)-1 downto 0);
62
        signal w_c1_lshifter                            : std_logic_vector(EXPBITS+MANTISBITS-2 downto 0);
63
 
64
        signal w_adderB                                 : std_logic_vector(EXPBITS-2 downto 0);
65
        signal w_comp_EQexp                             : std_logic;
66
        signal w_exp_MSB_result                 : std_logic;
67
 
68
        signal w_ctrl_seg                                       : std_logic;
69
        signal w_addr_lutA                              : std_logic_vector(c_log2_seg-2 downto 0);
70
        signal w_adderC                                 : std_logic_vector(c_log2_seg-2 downto 0);
71
        signal w_lutA                                           : std_logic_vector(SEGBITS-1 downto 0);
72
        signal w_comp_EQseg                             : std_logic;
73
        signal w_muxA_idata                             : std_logic_vector(2*SEGBITS-1 downto 0);
74
        --signal w_muxA_isel                            : std_logic_vector(0 downto 0);
75
        signal w_muxA                                           : std_logic_vector(SEGBITS-1 downto 0);
76
        signal w_addr_lutB                              : std_logic_vector(c_log2_seg-2 downto 0);
77
        signal w_lutB                                           : std_logic_vector(SEGBITS-1 downto 0);
78
 
79
        signal w_comp_ctrlsubs                  : std_logic;
80
        signal w_xor_comp_ctrlsubs              : std_logic;
81
        signal w_nxor_comp_ctrlsubs     : std_logic;
82
        signal w_C1_muxA                                        : std_logic_vector(SEGBITS-1 downto 0);
83
        signal w_C1_lutB                                        : std_logic_vector(SEGBITS-1 downto 0);
84
        signal w_adderE                                 : std_logic_vector(SEGBITS-1 downto 0);
85
 
86
        signal w_muxB_idata                             : std_logic_vector(2*SEGBITS-1 downto 0);
87
        --signal w_muxB_iselect                 : std_logic_vector(0 downto 0);
88
        signal w_muxB                                           : std_logic_vector(SEGBITS-1 downto 0);
89
        signal w_adderD                                 : std_logic_vector(SEGBITS-1 downto 0);
90
        signal w_adderD_cout                            : std_logic;
91
        signal w_slf_segx                                       : std_logic_vector(MANTISBITS-1 downto 0); -- (s*lf - segx)
92
        signal w_mult                                           : std_logic_vector(MANTISBITS*2-1 downto 0);
93
        signal w_C1_mult_idata                  : std_logic_vector(MANTISBITS+1 downto 0);
94
        signal w_C1_mult                                        : std_logic_vector(w_C1_mult_idata'left downto 0);
95
        signal w_adderF_iterm1                  : std_logic_vector(w_C1_mult_idata'left downto 0);
96
        signal w_adderF                                 : std_logic_vector(w_C1_mult_idata'left downto 0);
97
 
98
        signal mantis_result                            : std_logic_vector(MANTISBITS-1 downto 0);
99
        signal exp_result                               : std_logic_vector(EXPBITS-1 downto 0);
100
        signal sgn_result                                       : std_logic;
101
 
102
        signal w_ieeecase                                       : std_logic_vector(i_x'left downto 0);
103
        signal w_case_en                                        : std_logic_vector(1 downto 0);
104
        signal w_mux_case_idata                 : std_logic_vector(i_x'length*2-1 downto 0);
105
        signal w_mux_case                               : std_logic_vector(i_x'left downto 0);
106
begin
107
 
108
        w_mantis                                                                <= i_x(MANTISBITS-1 downto 0);
109
        w_exp                                                                   <= i_x(MANTISBITS+EXPBITS-1 downto MANTISBITS);
110
        w_sgn                                                                   <= i_x(MANTISBITS+EXPBITS);
111
 
112
 
113
        --------------------------------------------------------------------------      
114
        -- < Ajuste de dato >
115
        --------------------------------------------------------------------------      
116
 
117
        w_exp_adj                                                       <= w_exp(w_exp_adj'left downto 0);
118
        w_adderA_iterm1                                 <= w_exp_adj;
119
 
120
        adderA                                                          :       entity work.sum_ripple_carry_adder
121
        generic map(WIDE                                        => EXPBITS-1,
122
                                C1 => 0)
123
        port map   (i_term1                             => w_adderA_iterm1,
124
                                        i_term2                                 => std_logic_vector(to_unsigned(c_BX, EXPBITS-1)),
125
                                        i_cin                                   => '1',
126
                                        o_sum                                   => w_adderA);
127
 
128
        w_mantis_adj                                            <= std_logic_vector(to_unsigned(0, c_BX)) & std_logic_vector(to_unsigned(1, EXPBITS-1)) & w_mantis;
129
        w_lshifter_ishifts                              <= w_adderA(f_log2(w_mantis_adj'length)-1 downto 0);
130
 
131
        lshifter                                                                : entity work.left_shifter
132
        generic map(DATA_BITS                   => w_mantis_adj'length)
133
        port map          (i_data                               => w_mantis_adj,
134
                                        i_shifts                                => w_lshifter_ishifts,
135
                                        o_dataShift                     => w_lshifter);
136
 
137
        ones_complement_lshifter                : entity work.ones_complement
138
        generic map(WIDE                                        =>      w_c1_lshifter'length)
139
        port map          (i_data                               => w_lshifter(c_BX+MANTISBITS+EXPBiTS-2 downto c_BX),
140
                                        i_en                                    => w_sgn,
141
                                        o_data                          => w_c1_lshifter);
142
 
143
 
144
        --------------------------------------------------------------------------      
145
        -- < calculo de esxponente >
146
        --------------------------------------------------------------------------      
147
 
148
        adderB                                                          :entity work.sum_ripple_carry_adder
149
        generic map(WIDE                                        => EXPBITS-1,
150
                                        C1                                              => 2)
151
        port map   (i_term1                             => w_c1_lshifter(w_c1_lshifter'left downto MANTISBITS),
152
                                        i_term2                                 => std_logic_vector(to_unsigned(1, EXPBITS-1)),
153
                                        i_cin                                   => '1',
154
                                        o_sum                                   => w_adderB);
155
 
156
        comparator_EQexponent                   : entity work.comparator
157
        generic map(WIDE                                        => w_exp'length,
158
                                        MODO                                    => 1)
159
        port map          (i_data1                              => w_exp,
160
                                        i_data2                         => std_logic_vector(to_unsigned(126, w_exp'length)),
161
                                        o_result                                => w_comp_EQexp);
162
 
163
        w_exp_MSB_result                                        <= w_comp_EQexp and not(w_sgn);
164
 
165
 
166
        --------------------------------------------------------------------------      
167
        -- < Seleccion de constantes >
168
        --------------------------------------------------------------------------      
169
 
170
        w_addr_lutA                                                     <= w_c1_lshifter(w_mantis'left downto w_mantis'left-c_log2_seg+2);
171
        w_addr_lutB                                                     <= w_c1_lshifter(w_mantis'left downto w_mantis'left-c_log2_seg+2);
172
        w_ctrl_seg                                                      <= w_c1_lshifter(w_mantis'left-c_log2_seg+1);
173
 
174
        adderC                                                          :       entity work.sum_ripple_carry_adder
175
        generic map(WIDE                                        => c_log2_seg-1,
176
                                C1 => 0)
177
        port map   (i_term1                             => w_addr_lutA,
178
                                        i_term2                                 => std_logic_vector(to_unsigned(0, c_log2_seg-1)),
179
                                        i_cin                                   => w_ctrl_seg,
180
                                        o_sum                                   => w_adderC);
181
 
182
--      LUT32C: if SEG = 32 generate
183
--              LUT32_23b                                                       : luts_32x23b
184
--              port map          (i_lutA_addr                  => w_adderC,
185
--                                              i_lutB_addr                     => w_addr_lutB,
186
--                                              o_lutA                          => w_lutA,
187
--                                              o_lutB                          => w_lutB);
188
--      end generate;
189
 
190
        LUT64C: if SEG = 64 generate
191
                LUT64_23b                                                       : entity work.exp2_luts_64x23b
192
                generic map(SEG => SEG)
193
                port map          (i_lutA_addr                  => w_adderC,
194
                                                i_lutB_addr                     => w_addr_lutB,
195
                                                o_lutA                          => w_lutA,
196
                                                o_lutB                          => w_lutB);
197
        end generate;
198
 
199
        comparator_EQsegments                   : entity work.comparator
200
        generic map(WIDE                                        => c_log2_seg,
201
                                        MODO                                    => 0)
202
        port map          (i_data1                              => w_c1_lshifter(w_mantis'left downto MANTISBITS-c_log2_seg),
203
                                        i_data2                         => std_logic_vector(to_unsigned(SEG-1, c_log2_seg)),
204
                                        o_result                                => w_comp_EQseg);
205
 
206
   --w_muxA_idata                                               <= c_64seg_23b & w_lutA;
207
        --w_muxA_isel                                                   <= w_comp_EQseg & std_logic_vector(to_unsigned(0, 0));  -- entidad mux requiere que el dato siempre sea std_logic_vector
208
 
209
--      mux_lutA                                                                        : mux
210
--      generic map(SELECT_BITS                 => 1, 
211
--                                      DATA_BITS                       => SEGBITS)
212
--      port map          (i_data                               => w_muxA_idata,
213
--                                      i_select                                => w_muxA_isel,         
214
--                                      o_data                          =>      w_muxA);        
215
 
216
w_muxA <= w_lutA when w_comp_EQseg='0' else c_64seg_23b;
217
        --------------------------------------------------------------------------
218
        -- < control resta de constantes >
219
        --------------------------------------------------------------------------
220
 
221
        comparator_control_lut                  :       entity work.comparator
222
        generic map(WIDE                                        => c_log2_seg,
223
                                        MODO                                    =>      2)
224
        port map          (i_data1                              => w_c1_lshifter(w_mantis'left downto MANTISBITS-c_log2_seg),
225
                                        i_data2                         => std_logic_vector(to_unsigned(34, c_log2_seg)), -- constante solo funciona para 64 segmentos 
226
                                        o_result                                =>      w_comp_ctrlsubs);
227
 
228
        w_xor_comp_ctrlsubs                             <= w_comp_ctrlsubs xor w_c1_lshifter(MANTISBITS-c_log2_seg);
229
        w_nxor_comp_ctrlsubs                            <= not(w_xor_comp_ctrlsubs);
230
 
231
        ones_complement_muxA                            : entity work.ones_complement
232
        generic map(WIDE                                        =>      SEGBITS)
233
        port map          (i_data                               => w_muxA,
234
                                        i_en                                    => w_nxor_comp_ctrlsubs,
235
                                        o_data                          => w_C1_muxA);
236
 
237
        ones_complement_lutB                            : entity work.ones_complement
238
        generic map(WIDE                                        =>      SEGBITS)
239
        port map          (i_data                               => w_lutB,
240
                                        i_en                                    => w_xor_comp_ctrlsubs,
241
                                        o_data                          => w_C1_lutB);
242
 
243
        constants_sub                                           :       entity work.sum_ripple_carry_adder
244
        generic map(WIDE                                        => SEGBITS,
245
                                C1 => 0)
246
        port map   (i_term1                             => w_C1_muxA,
247
                                        i_term2                                 => w_C1_lutB,
248
                                        i_cin                                   => '1',
249
                                        o_sum                                   => w_adderE);
250
 
251
 
252
        --------------------------------------------------------------------------
253
        -- < Calculo de mantisa >
254
        --------------------------------------------------------------------------
255
 
256
        w_muxB_idata                                            <= w_lutB & w_muxA;
257
        --w_muxB_iselect                                                <= w_ctrl_seg & std_logic_vector(to_unsigned(0, 0));  -- entidad mux requiere que el dato siempre sea del tipo std_logic_vector
258
 
259
--      muxB                                                                    : mux
260
--      generic map(SELECT_BITS                 => 1, 
261
--                                      DATA_BITS                       => SEGBITS)
262
--      port map          (i_data                               => w_muxB_idata,
263
--                                      i_select                                => w_muxB_iselect,      
264
--                                      o_data                          =>      w_muxB);
265
w_muxB <= w_muxA when w_ctrl_seg='0' else w_lutB;
266
 
267
        adderD                                                          : entity work.sum_ripple_carry_adder
268
        generic map(WIDE                                        => SEGBITS,
269
                                C1 => 0)
270
        port map          (i_term1                              => w_muxB,
271
                                        i_term2                                 => w_c1_lshifter(w_mantis'left downto 0),
272
                                        i_cin                                   => '0',
273
                                        o_sum                                   => w_adderD,
274
                                        o_cout                          => w_adderD_cout);
275
 
276
        w_slf_segx                                                      <= w_c1_lshifter(MANTISBITS-c_log2_seg-1 downto 0) & std_logic_vector(to_unsigned(0, c_log2_seg));
277
 
278
        multiplier                                                      : entity work.mult
279
        generic map(WIDE                                        => SEGBITS)
280
        port map          (i_term1                              => w_adderE,
281
                                        i_term2                         => w_slf_segx,
282
                                        o_product                       => w_mult);
283
 
284
        w_C1_mult_idata                                 <= w_mult(MANTISBITS*2-1 downto MANTISBITS-2);
285
 
286
        ones_complement_mult                            : entity work.ones_complement
287
        generic map(WIDE                                        =>      w_C1_mult_idata'length)
288
        port map          (i_data                               => w_C1_mult_idata,
289
                                        i_en                                    => w_comp_ctrlsubs,
290
                                        o_data                          => w_C1_mult);
291
 
292
        w_adderF_iterm1                                 <= w_adderD & "00";
293
 
294
        adderF                                                          : entity work.sum_ripple_carry_adder
295
        generic map(WIDE                                        => w_C1_mult'length,
296
                                C1 => 0)
297
        port map          (i_term1                              => w_adderF_iterm1,
298
                                        i_term2                                 => w_C1_mult,
299
                                        i_cin                                   => w_comp_ctrlsubs,
300
                                        o_sum                                   => w_adderF,
301
                                        o_cout                          => open);
302
 
303
        --------------------------------------------------------------------------
304
        -- < deteccion de caso ieee>
305
        --------------------------------------------------------------------------
306
        sgn_result                                              <= '0';
307
        exp_result                                              <= w_exp_MSB_result  & w_adderB;
308
        mantis_result                                   <= w_adderF(w_adderF'left downto w_adderF'left-MANTISBITS+1);
309
 
310
        ieee32_case                                                     : entity work.exp2_ieee
311
        generic map(BX                                  => c_BX)
312
        port map          (i_data                               => i_x,
313
                                        o_case                          => w_ieeecase,
314
                                        o_case_en                       => w_case_en(0));
315
 
316
        w_mux_case_idata                                        <= w_ieeecase & sgn_result & exp_result & mantis_result;
317
 
318
--      mux_ieee32_case                                 : mux
319
--      generic map(SELECT_BITS                 => 1,
320
--                                      DATA_BITS                       => i_x'length)
321
--      port map          (i_data                               => w_mux_case_idata,
322
--                                      i_select                                => w_case_en,
323
--                                      o_data                          => w_mux_case);
324
 
325
 
326
w_mux_case <= sgn_result & exp_result & mantis_result when w_case_en(0)='0' else w_ieeecase;
327
        --------------------------------------------------------------------------
328
        -- < RESULTADO >
329
        --------------------------------------------------------------------------      
330
 
331
        o_exp2                                                          <= w_mux_case ;
332
 
333
 
334
end arch;

powered by: WebSVN 2.1.0

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