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

Subversion Repositories special_functions_unit

[/] [special_functions_unit/] [Open_source_SFU/] [log2_vhdl/] [log2_fp.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 divadnauj
-- Proyecto                             : LOG2 IEEE754
2
-- Nombre de archivo    : log2_fp.vhd
3
--      Titulo                          : operacion logaritmo en base 2
4
-----------------------------------------------------------------------------   
5
-- Descripcion                  : calcula el logaritmo 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_log2                  : Resultado en formato numerico IEEE754
14
-----------------------------------------------------------------------------   
15
-- Universidad Pedagogica y Tecnologica de Colombia.
16
-- Facultad de ingenieria.
17
-- Escuela de ingenieria Electronica - extension Tunja.
18
-- 
19
-- Autor: Cristhian Fernando Moreno Manrique
20
-- Abril 2020
21
-----------------------------------------------------------------------------   
22
 
23
library ieee;
24
        use ieee.std_logic_1164.all;
25
        use ieee.numeric_std.all;
26
        use work.log2_pkg.all;
27
 
28
 
29
entity log2_fp is
30
        generic (MANTISBITS                             :               natural:= 23;           -- Formato IEEE754:
31
                                EXPBITS                                 :               natural:= 8;            -- signo[1] & exponente[8] & mantisa[23]
32
                                SEG                                             :               natural:= 64;
33
                                SEGBITS                                 :               natural:= 23);
34
        port      (i_x                                          : in    std_logic_vector(EXPBITS+MANTISBITS downto 0);
35
                                o_log2                                  : out std_logic_vector(EXPBITS+MANTISBITS downto 0));
36
end entity;
37
 
38
 
39
architecture rtl of log2_fp is
40
 
41
        constant c_64seg_23b                            : std_logic_vector(SEGBITS-1 downto 0) := "00000000000000000111101";
42
        constant c_log2_seg                             : natural       := f_log2(SEG);
43
 
44
        signal w_mantis                                 : std_logic_vector(MANTISBITS-1 downto 0);
45
        signal w_exp                                            : std_logic_vector(EXPBITS-1 downto 0);
46
        signal w_sgn                                            : std_logic;
47
 
48
        signal w_segment_ctrl                   : std_logic;
49
        signal w_lutA_addr                              : std_logic_vector(c_log2_seg-2 downto 0);
50
        signal w_lutA_adder                             : std_logic_vector(c_log2_seg-2 downto 0);
51
        signal w_lutA                                           : std_logic_vector(SEGBITS-1 downto 0);
52
        signal w_comp_EQseg                             : std_logic;
53
        signal w_mux_lutA_idata                 : std_logic_vector(2*SEGBITS-1 downto 0);
54
        --signal w_mux_lutA_isel                        : std_logic_vector(0 downto 0);
55
        signal w_mux_lutA                               : std_logic_vector(SEGBITS-1 downto 0);
56
        signal w_lutB_addr                              : std_logic_vector(c_log2_seg-2 downto 0);
57
        signal w_lutB                                           : std_logic_vector(SEGBITS-1 downto 0);
58
 
59
        signal w_comp_C1_ctrl                   : std_logic;
60
        signal w_comp_C1_ctrl_n                 : std_logic;
61
        signal w_comp_C1_ctrl_xor               : std_logic;
62
        signal w_comp_C1_ctrl_xnor              : std_logic;
63
        signal w_mux_lutA_C1                            : std_logic_vector(SEGBITS-1 downto 0);
64
        signal w_lutB_C1                                        : std_logic_vector(SEGBITS-1 downto 0);
65
        signal w_constants_sub                  : std_logic_vector(SEGBITS-1 downto 0);
66
 
67
        signal w_muxA_idata                             : std_logic_vector(2*SEGBITS-1 downto 0);
68
        --signal w_muxA_iselect                 : std_logic_vector(0 downto 0);
69
        signal w_muxA                                           : std_logic_vector(SEGBITS-1 downto 0);
70
        signal w_adderB                                 : std_logic_vector(SEGBITS-1 downto 0); -- generalizar entradas
71
        signal w_adderB_cout                            : std_logic;
72
        signal w_mantis_decimal                 : std_logic_vector(MANTISBITS-1 downto 0);
73
        signal w_mult                                           : std_logic_vector(MANTISBITS*2-1 downto 0);
74
        signal w_mult_C1_idata                  : std_logic_vector(MANTISBITS+2 downto 0);
75
        signal w_mult_C1                                        : std_logic_vector(MANTISBITS+2 downto 0);
76
        signal w_adderC_iterm1                  : std_logic_vector(MANTISBITS+2 downto 0);
77
        signal w_adderC                                 : std_logic_vector(MANTISBITS+2 downto 0);
78
 
79
        signal w_exp_comp                                       : std_logic;
80
        signal w_exp_ncomp                              : std_logic;
81
        signal w_adderD                                 : std_logic_vector(EXPBITS-2 downto 0);
82
        signal w_adderD_C1                              : std_logic_vector(EXPBITS-2 downto 0);
83
        signal w_adderC_C1_idata                : std_logic_vector(MANTISBITS+EXPBITS downto 0);
84
        signal w_adderC_C1                              : std_logic_vector(MANTISBITS+EXPBITS downto 0);
85
        signal w_adderE_iterm2                  : std_logic_vector(MANTISBITS+EXPBITS downto 0);
86
        signal w_adderE                                 : std_logic_vector(MANTISBITS+EXPBITS downto 0);
87
        signal w_adderE_cout                            : std_logic;
88
        signal w_CLZ                                            : std_logic_vector(f_log2(MANTISBITS)-1 downto 0);
89
        signal w_CLZ_MSB                                        : std_logic;
90
 
91
        signal w_CLZ_adj                                        : std_logic_vector(EXPBITS-2 downto 0);
92
        signal w_adderE_shift                   : std_logic_vector(w_adderE'left downto 0);
93
        signal w_adderF                                 : std_logic_vector(EXPBITS-2 downto 0);
94
        signal w_coutF                                          : std_logic;
95
 
96
        signal w_mantis_result                  : std_logic_vector(MANTISBITS-1 downto 0);
97
        signal w_exp_result                             : std_logic_vector(EXPBITS-1 downto 0);
98
        signal w_sgn_result                             : std_logic;
99
 
100
        signal w_ieeecase                                       : std_logic_vector(i_x'left downto 0);
101
        signal w_ieeecase_en                            : std_logic;
102
        signal w_mux_case_idata                 : std_logic_vector(i_x'length*2-1 downto 0);
103
        signal w_mux_case                                       : std_logic_vector(i_x'left downto 0);
104
 
105
begin
106
 
107
        w_mantis                                                                <= i_x(MANTISBITS-1 downto 0);
108
        w_exp                                                                   <= i_x(MANTISBITS+EXPBITS-1 downto MANTISBITS);
109
        w_sgn                                                                   <= i_x(MANTISBITS+EXPBITS);
110
 
111
 
112
        --------------------------------------------------------------------------      
113
        -- < Seleccion de constantes >
114
        --------------------------------------------------------------------------      
115
 
116
        w_lutA_addr                                                     <= w_mantis(w_mantis'left downto w_mantis'left-c_log2_seg+2);
117
        w_lutB_addr                                                     <= w_mantis(w_mantis'left downto w_mantis'left-c_log2_seg+2);
118
        w_segment_ctrl                                          <= w_mantis(w_mantis'left-c_log2_seg+1);
119
 
120
        adder_lutA                                                      :       entity work.sum_ripple_carry_adder
121
        generic map(WIDE                                        => c_log2_seg-1)
122
        port map   (i_term1                             => w_lutA_addr,
123
                                        i_term2                                 => std_logic_vector(to_unsigned(0, c_log2_seg-1)),
124
                                        i_cin                                   => w_segment_ctrl,
125
                                        o_sum                                   => w_lutA_adder);
126
 
127
--      LUT32C: if SEG = 32 generate
128
--              LUT32_23b                                                       : log2_luts_32x23b
129
--              port map          (i_lutA_addr                  => w_lutA_adder,
130
--                                              i_lutB_addr                     => w_lutB_addr,
131
--                                              o_lutA                          => w_lutA,
132
--                                              o_lutB                          => w_lutB);
133
--      end generate;
134
 
135
        LUT64C: if SEG = 64 generate
136
                LUT64_23b                                                       : entity work.log2_luts_64x23b
137
                generic map(SEG=>SEG)
138
                port map          (i_lutA_addr                  => w_lutA_adder,
139
                                                i_lutB_addr                     => w_lutB_addr,
140
                                                o_lutA                          => w_lutA,
141
                                                o_lutB                          => w_lutB);
142
        end generate;
143
 
144
        comparator_EQsegments                   : entity work.comparator
145
        generic map(WIDE                                        => c_log2_seg,
146
                                        MODO                                    => 0)
147
        port map          (i_data1                              => w_mantis(w_mantis'left downto MANTISBITS-c_log2_seg),
148
                                        i_data2                         => std_logic_vector(to_unsigned(SEG-1, c_log2_seg)),
149
                                        o_result                                => w_comp_EQseg);
150
 
151
   --w_mux_lutA_idata                                   <= c_64seg_23b & w_lutA;
152
        --w_mux_lutA_isel(0)                                    <= w_comp_EQseg & std_logic_vector(to_unsigned(0, 0));  -- entidad mux requiere que el dato siempre sea std_logic_vector
153
 
154
 
155
--      mux_lutA                                                                        : mux
156
--      generic map(SELECT_BITS                 => 1, 
157
--                                      DATA_BITS                       => SEGBITS)
158
--      port map          (i_data                               => w_mux_lutA_idata,
159
--                                      i_select                                => w_mux_lutA_isel(0),  
160
--                                      o_data                          =>      w_mux_lutA);    
161
 
162
        w_mux_lutA <= w_lutA when w_comp_EQseg='0' else c_64seg_23b;
163
 
164
        --------------------------------------------------------------------------
165
        -- < control resta de constantes >
166
        --------------------------------------------------------------------------
167
 
168
        comparator_control_lut                  :       entity work.comparator
169
        generic map(WIDE                                        => c_log2_seg,
170
                                        MODO                                    =>      2)
171
        port map          (i_data1                              => w_mantis(w_mantis'left downto MANTISBITS-c_log2_seg),
172
                                        i_data2                         => std_logic_vector(to_unsigned(SEG*7/16, c_log2_seg)), -- 
173
                                        o_result                                =>      w_comp_C1_ctrl);
174
 
175
        w_comp_C1_ctrl_n                                        <= not(w_comp_C1_ctrl);
176
        w_comp_C1_ctrl_xor                              <= w_comp_C1_ctrl_n xor w_mantis(MANTISBITS-c_log2_seg);
177
        w_comp_C1_ctrl_xnor                             <= not(w_comp_C1_ctrl_xor);
178
 
179
        ones_complement_lutA                            : entity work.ones_complement
180
        generic map(WIDE                                        =>      w_mux_lutA'length)
181
        port map          (i_data                               => w_mux_lutA,
182
                                        i_en                                    => w_comp_C1_ctrl_xnor,
183
                                        o_data                          => w_mux_lutA_C1);
184
 
185
        ones_complement_lutB                            : entity work.ones_complement
186
        generic map(WIDE                                        =>      MANTISBITS)
187
        port map          (i_data                               => w_lutB,
188
                                        i_en                                    => w_comp_C1_ctrl_xor,
189
                                        o_data                          => w_lutB_C1);
190
 
191
        constants_sub                                           :       entity work.sum_ripple_carry_adder
192
        generic map(WIDE                                        => MANTISBITS)
193
        port map   (i_term1                             => w_mux_lutA_C1,
194
                                        i_term2                                 => w_lutB_C1,
195
                                        i_cin                                   => '1',
196
                                        o_sum                                   => w_constants_sub);
197
 
198
 
199
        --------------------------------------------------------------------------
200
        -- < Calculo de parte fraccionaria >
201
        --------------------------------------------------------------------------
202
 
203
        --w_muxA_idata                                          <= w_lutB & w_mux_lutA;
204
        --w_muxA_iselect                                                <= w_segment_ctrl & std_logic_vector(to_unsigned(0, 0));  -- entidad mux requiere que el dato siempre sea std_logic_vector
205
 
206
--      muxA                                                                    : mux
207
--      generic map(SELECT_BITS                 => 1, 
208
--                                      DATA_BITS                       => MANTISBITS)
209
--      port map          (i_data                               => w_muxA_idata,
210
--                                      i_select                                => w_muxA_iselect,      
211
--                                      o_data                          =>      w_muxA);
212
 
213
w_muxA <= w_mux_lutA when w_segment_ctrl='0' else w_lutB;
214
 
215
        adderB                                                          : entity work.sum_ripple_carry_adder
216
        generic map(WIDE                                        => MANTISBITS)
217
        port map          (i_term1                              => w_muxA,
218
                                        i_term2                                 => w_mantis,
219
                                        i_cin                                   => '0',
220
                                        o_sum                                   => w_adderB,
221
                                        o_cout                          => w_adderB_cout);
222
 
223
        w_mantis_decimal                                        <= w_mantis(MANTISBITS-c_log2_seg-1 downto 0) & std_logic_vector(to_unsigned(0, c_log2_seg));
224
 
225
        multiplier                                                      : entity work.mult
226
        generic map(WIDE                                        => MANTISBITS)
227
        port map          (i_term1                              => w_constants_sub,
228
                                        i_term2                         => w_mantis_decimal,
229
                                        o_product                       => w_mult);
230
 
231
        w_mult_C1_idata                                 <= "0" & w_mult(MANTISBITS*2-1 downto MANTISBITS-2); -- se añade una parte entera al resultado
232
 
233
        ones_complement_mult                            : entity work.ones_complement
234
        generic map(WIDE                                        =>      w_mult_C1_idata'length)
235
        port map          (i_data                               => w_mult_C1_idata,
236
                                        i_en                                    => w_comp_C1_ctrl_n,
237
                                        o_data                          => w_mult_C1);
238
 
239
        w_adderC_iterm1                                 <= w_adderB_cout & w_adderB & "00";
240
 
241
        adderC                                                          : entity work.sum_ripple_carry_adder
242
        generic map(WIDE                                        => w_adderC_iterm1'length,
243
                                C1 => 0)
244
        port map          (i_term1                              => w_adderC_iterm1,
245
                                        i_term2                                 => w_mult_C1,
246
                                        i_cin                                   => w_comp_C1_ctrl_n,
247
                                        o_sum                                   => w_adderC);
248
 
249
 
250
        --------------------------------------------------------------------------
251
        -- < calculo de resultado en punto fijo >
252
        --------------------------------------------------------------------------      
253
 
254
        exp_comparator                          :       entity work.comparator
255
        generic map(WIDE                                        => EXPBITS,
256
                                        MODO                                    => 1)
257
        port map          (i_data1                              => std_logic_vector(to_unsigned(2**(EXPBITS-1)-1, EXPBITS)),
258
                                        i_data2                         => w_exp,
259
                                        o_result                                =>      w_exp_comp);
260
 
261
        w_exp_ncomp                                                     <= not(w_exp_comp);
262
 
263
        adderD                                                          : entity work.sum_ripple_carry_adder
264
        generic map(WIDE                                        => EXPBITS-1,
265
                                C1 => 0)
266
        port map          (i_term1                              => w_exp(w_exp'left-1 downto 0),
267
                                        i_term2                                 => std_logic_vector(to_unsigned(0, EXPBITS-1)),
268
                                        i_cin                                   => w_exp_ncomp,
269
                                        o_sum                                   => w_adderD);
270
 
271
        ones_complement_adderD                  : entity work.ones_complement
272
        generic map(WIDE                                        => w_adderD'length)
273
        port map   (i_data                              => w_adderD,
274
                                        i_en                                    => w_exp_comp,
275
                                        o_data                          => w_adderD_C1);
276
 
277
        w_adderC_C1_idata                                       <=  std_logic_vector(to_unsigned(0, EXPBITS-2)) & w_adderC;
278
 
279
        ones_complement_adderC                  : entity work.ones_complement
280
        generic map(WIDE                                        => w_adderC_C1_idata'length)
281
        port map   (i_data                              => w_adderC_C1_idata,
282
                                        i_en                                    => w_exp_comp,
283
                                        o_data                          => w_adderC_C1);
284
 
285
        w_adderE_iterm2                                 <= w_adderD_C1 & std_logic_vector(to_unsigned(0, MANTISBITS+2));
286
 
287
        adderE                                                          : entity work.sum_ripple_carry_adder
288
        generic map(WIDE                                        => w_adderC_C1'length,
289
                                C1 => 0)
290
        port map          (i_term1                              => w_adderC_C1,
291
                                        i_term2                                 => w_adderE_iterm2,
292
                                        i_cin                                   => w_exp_comp,
293
                                        o_sum                                   => w_adderE);
294
 
295
 
296
        --------------------------------------------------------------------------
297
        -- < calculo de resultado en punto flotante >
298
        --------------------------------------------------------------------------
299
 
300
        leading_zeros                                           : entity work.CLZ
301
        generic map(MODE => '0',
302
                                DATA_BITS                       => 2**f_log2(w_adderE'length)) -- el modulo solo acepta un ancho de datos 2^x
303
        port map          (i_data                               => w_adderE,
304
                                        o_zeros                         => w_CLZ,
305
                                        o_MSB_zeros                     =>      w_CLZ_MSB);
306
 
307
        shifter                                                         : entity work.left_shifter
308
        generic map(DATA_BITS                   => w_adderE'length)
309
        port map          (i_data                               => w_adderE,
310
                                        i_shifts                                => w_CLZ,
311
                                        o_dataShift                     => w_adderE_shift);
312
 
313
        w_CLZ_adj                                                       <= "00" & w_CLZ; -- se añaden ceros segun la cantidad de bits del exponente
314
 
315
        adderF                                                          : entity work.sum_ripple_carry_adder
316
        generic map(WIDE                                        => EXPBITS-1,
317
                                        C1                                              => 1) -- complemento a 1
318
        port map          (i_term1                              => w_CLZ_adj,
319
                                        i_term2                                 => "0000110",   -- cte encontrada experimentalmente
320
                                        i_cin                                   => '0',
321
                                        o_sum                                   => w_adderF,
322
                                        o_cout                          => w_coutF);
323
 
324
 
325
        --------------------------------------------------------------------------
326
        -- < deteccion de caso ieee>
327
        --------------------------------------------------------------------------
328
 
329
        w_sgn_result                                            <= w_exp_comp;
330
        w_exp_result                                            <= w_coutF  & w_adderF;
331
        w_mantis_result                                 <= w_adderE_shift(w_adderE_shift'left-1 downto w_adderE_shift'left-MANTISBITS);
332
 
333
        case_ieee32                                                     : entity work.log2_ieee
334
        port map          (i_data                               => i_x,
335
                                        o_case                          => w_ieeecase,
336
                                        o_case_en                       => w_ieeecase_en);
337
 
338
        --w_mux_case_idata                                      <= w_ieeecase & w_sgn_result & w_exp_result & w_mantis_result;
339
 
340
--      mux_case_select                                 : mux
341
--      generic map(SELECT_BITS                 => 1, 
342
--                                      DATA_BITS                       => i_x'length)
343
--      port map          (i_data                               => w_mux_case_idata,
344
--                                      i_select                                => w_ieeecase_en,       
345
--                                      o_data                          =>      w_mux_case);
346
 
347
        w_mux_case <= w_sgn_result & w_exp_result & w_mantis_result when w_ieeecase_en='0' else w_ieeecase;
348
 
349
        o_log2                                                          <= w_mux_case;
350
 
351
end rtl;

powered by: WebSVN 2.1.0

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