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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [fft_r2_par.vhd] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
--------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 3 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
--------------------------------------------------------------------------------
20
-- Purpose: The fft_r2_par unit performs a complex parallel FFT.
21
--
22
--          There are two optional features: 
23
--
24
--          * Reordering: When enabled the output bins of the FFT are re-ordered in 
25
--                        in such a way that the bins represent the frequencies in an 
26
--                        incrementing way. 
27
--
28
--          * Separation: When enabled the rtwo_fft can be used to process two real streams.
29
--                        The first real stream (A) presented on the real input, the second 
30
--                        real stream (B) presented on the imaginary input. 
31
--                        The separation unit outputs the spectrum of A and B in 
32
--                        an alternating way: A(0), B(0), A(1), B(1).... etc
33
--                        The separate function adds and subtracts two complex bins. 
34
--                        Therefore it causes 1 bit growth that needs to be rounded, as
35
--                        explained in fft_sepa.vhd
36
 
37
library ieee, common_pkg_lib, common_components_lib, common_add_sub_lib, common_requantize_lib, rTwoSDF_lib;
38
use IEEE.std_logic_1164.all;
39
use common_pkg_lib.common_pkg.all;
40
use rTwoSDF_lib.rTwoSDFPkg.all;
41
use work.fft_pkg.all;
42
 
43
entity fft_r2_par is
44
  generic (
45
    g_fft      : t_fft := c_fft;                  -- generics for the FFT
46
    g_pipeline : t_fft_pipeline := c_fft_pipeline -- generics for pipelining, defined in rTwoSDF_lib.rTwoSDFPkg
47
  );
48
  port (
49
    clk        : in  std_logic;
50
    rst        : in  std_logic := '0';
51
    in_re_arr  : in  t_fft_slv_arr(g_fft.nof_points-1 downto 0);
52
    in_im_arr  : in  t_fft_slv_arr(g_fft.nof_points-1 downto 0);
53
    in_val     : in  std_logic := '1';
54
    out_re_arr : out t_fft_slv_arr(g_fft.nof_points-1 downto 0);
55
    out_im_arr : out t_fft_slv_arr(g_fft.nof_points-1 downto 0);
56
    out_val    : out std_logic
57
  );
58
end entity fft_r2_par;
59
 
60
architecture str of fft_r2_par is
61
 
62
  ------------------------------------------------------------------------------------------------
63
  -- This function determines the input number (return value) to which the output of a butterfly 
64
  -- should be connected, based on the output-sequence-number(element), the stage number(stage) 
65
  -- and the number of points of the FFT (nr_of_points).                        
66
  --
67
  -- The following table shows the connection matrix for a 16-point parallel FFT, where the 
68
  -- output column refers to the output sequence number of each stage and the stage columns
69
  -- give the corresponding input sequence number of the connected stage. In other words:
70
  --  output 3 of stage 4 is connected to input 10 of stage 3. 
71
  --  output 6 of stage 3 is connected to input  3 of stage 2. 
72
  --
73
  --  output  stage 3  stage 2  stage 1
74
  --
75
  --    0        0 |      0 |      0 |
76
  --    1        8 |      4 |      2 |
77
  --    2        2 |      2 |      1    
78
  --    3       10 |      6 |      3  
79
  --    4        4 |      1        4 |
80
  --    5       12 |      5        6 |
81
  --    6        6 |      3        5      
82
  --    7       14 |      7        7    
83
  --    8        1        8 |      8 |
84
  --    9        9       12 |     10 |
85
  --   10        3       10 |      9       
86
  --   11       11       14 |     11     
87
  --   12        5        9       12 |
88
  --   13       13       13       14 |
89
  --   14        7       11       13       
90
  --   15       15       15       15     
91
  --
92
  -- The function first checks if the output element falls in one of the "even" areas that 
93
  -- are marked by a "|". If so, it checks if the input element is odd or even. If even
94
  -- then output is equal to the input element. If odd then output is element+offset. 
95
  -- It the output element falls in an "odd" area: input element even => output= element - offset
96
  -- input element odd => output = element.   
97
 
98
  function func_butterfly_connect(array_index, stage, nr_of_points : natural) return natural is
99
    variable v_nr_of_domains : natural;  -- Variable that represents the number of "even" areas. 
100
    variable v_return        : natural;  -- Holds the return value
101
    variable v_offset        : natural;  -- Offset
102
  begin
103
    v_nr_of_domains := nr_of_points/2**(stage+1);
104
    v_offset := 2**stage;
105
    for I in 0 to v_nr_of_domains loop
106
      if array_index >= (2*I)*2**stage and array_index < (2*I+1)*2**stage then       -- Detect if output is an even section
107
        if (array_index mod 2) = 0 then                                              -- Check if input value is odd or even
108
          v_return := array_index;                                                   -- When even: value of element                                                 
109
        else
110
          v_return := array_index+v_offset-1;                                        -- When odd: value of element + offset
111
        end if;
112
      elsif array_index >= (2*I+1)*2**stage and array_index < (2*I+2)*2**stage then
113
        if (array_index mod 2) = 0 then                                              -- Check if input value is odd or even
114
          v_return := array_index-v_offset+1;                                        -- When even: offset is subtracted from the element
115
        else
116
          v_return := array_index;                                                   -- When odd: element stays the the same.       
117
        end if;
118
      end if;
119
    end loop;
120
    return v_return;
121
  end;
122
 
123
  constant c_pipeline_add_sub    : natural := 1;
124
  constant c_pipeline_remove_lsb : natural := 1;
125
  constant c_sepa_round          : boolean := true;  -- must be true, because separate should round the 1 bit growth
126
 
127
  constant c_nof_stages         : natural := ceil_log2(g_fft.nof_points);
128
  constant c_nof_bf_per_stage   : natural := g_fft.nof_points/2;
129
  constant c_in_scale_w_tester  : integer := g_fft.stage_dat_w - g_fft.in_dat_w - sel_a_b(g_fft.guard_enable, g_fft.guard_w, 0);
130
  constant c_in_scale_w         : natural := sel_a_b(c_in_scale_w_tester > 0, c_in_scale_w_tester, 0);  -- Only scale when in_dat_w is not too big. 
131
 
132
  constant c_out_scale_w        : integer := g_fft.stage_dat_w - g_fft.out_dat_w - g_fft.out_gain_w;    -- Estimate number of LSBs to throw away when > 0 or insert when < 0
133
 
134
  type   t_stage_dat_arr   is array (integer range <>)     of std_logic_vector(g_fft.stage_dat_w-1 downto 0);
135
  type   t_stage_sum_arr   is array (integer range <>)     of std_logic_vector(g_fft.stage_dat_w   downto 0);
136
  type   t_data_arr2       is array(c_nof_stages downto 0) of t_stage_dat_arr(g_fft.nof_points-1 downto 0);
137
  type   t_val_arr         is array(c_nof_stages downto 0) of std_logic_vector( g_fft.nof_points-1 downto 0);
138
 
139
  signal data_re          : t_data_arr2;
140
  signal data_im          : t_data_arr2;
141
  signal data_val         : t_val_arr;
142
  signal int_re_arr       : t_stage_dat_arr(g_fft.nof_points-1 downto 0);
143
  signal int_im_arr       : t_stage_dat_arr(g_fft.nof_points-1 downto 0);
144
  signal fft_re_arr       : t_stage_dat_arr(g_fft.nof_points-1 downto 0);
145
  signal fft_im_arr       : t_stage_dat_arr(g_fft.nof_points-1 downto 0);
146
  signal add_arr          : t_stage_sum_arr(g_fft.nof_points-1 downto 0);
147
  signal sub_arr          : t_stage_sum_arr(g_fft.nof_points-1 downto 0);
148
  signal int_val          : std_logic;
149
  signal fft_val          : std_logic;
150
 
151
begin
152
 
153
  ------------------------------------------------------------------------------
154
  -- Inputs are prepared/shuffled for the input stage    
155
  ------------------------------------------------------------------------------
156
  gen_get_the_inputs : for I in 0 to g_fft.nof_points/2-1 generate
157
    data_re( c_nof_stages)(2*I)   <= scale_and_resize_svec(in_re_arr(I),                    c_in_scale_w, g_fft.stage_dat_w);
158
    data_re( c_nof_stages)(2*I+1) <= scale_and_resize_svec(in_re_arr(I+g_fft.nof_points/2), c_in_scale_w, g_fft.stage_dat_w);
159
    data_im( c_nof_stages)(2*I)   <= scale_and_resize_svec(in_im_arr(I),                    c_in_scale_w, g_fft.stage_dat_w);
160
    data_im( c_nof_stages)(2*I+1) <= scale_and_resize_svec(in_im_arr(I+g_fft.nof_points/2), c_in_scale_w, g_fft.stage_dat_w);
161
    data_val(c_nof_stages)(I)     <= in_val;
162
  end generate;
163
 
164
  ------------------------------------------------------------------------------
165
  -- parallel FFT stages
166
  ------------------------------------------------------------------------------
167
  gen_fft_stages: for stage in c_nof_stages downto 1 generate
168
    gen_fft_elements: for element in 0 to c_nof_bf_per_stage-1 generate
169
      u_element : entity work.fft_r2_bf_par
170
      generic map (
171
        g_stage        => stage,
172
        g_element      => element,
173
        g_scale_enable => sel_a_b(stage <= g_fft.guard_w, FALSE, TRUE),
174
        g_pipeline     => g_pipeline
175
      )
176
      port map (
177
        clk      => clk,
178
        rst      => rst,
179
        x_in_re  => data_re(stage)(2*element),
180
        x_in_im  => data_im(stage)(2*element),
181
        y_in_re  => data_re(stage)(2*element+1),
182
        y_in_im  => data_im(stage)(2*element+1),
183
        in_val   => data_val(stage)(element),
184
        x_out_re => data_re(stage-1)(func_butterfly_connect(2*element,   stage-1, g_fft.nof_points)),
185
        x_out_im => data_im(stage-1)(func_butterfly_connect(2*element,   stage-1, g_fft.nof_points)),
186
        y_out_re => data_re(stage-1)(func_butterfly_connect(2*element+1, stage-1, g_fft.nof_points)),
187
        y_out_im => data_im(stage-1)(func_butterfly_connect(2*element+1, stage-1, g_fft.nof_points)),
188
        out_val  => data_val(stage-1)(element)
189
       );
190
    end generate;
191
  end generate;
192
 
193
  --------------------------------------------------------------------------------
194
  -- Optional output reorder 
195
  --------------------------------------------------------------------------------
196
  gen_reorder : if g_fft.use_reorder and not g_fft.use_fft_shift generate
197
    -- unflip the bin indices for complex and also required to prepare for g_fft.use_separate of two real
198
    gen_reordering : for I in 0 to g_fft.nof_points - 1 generate
199
      int_re_arr(I) <= data_re(0)(flip(I, c_nof_stages));
200
      int_im_arr(I) <= data_im(0)(flip(I, c_nof_stages));
201
    end generate;
202
  end generate;
203
 
204
  gen_fft_shift : if g_fft.use_reorder and g_fft.use_fft_shift generate
205
    -- unflip the bin indices and apply fft_shift for complex only, to have bin frequencies from negative via zero to positive
206
    gen_reordering : for I in 0 to g_fft.nof_points - 1 generate
207
      int_re_arr(fft_shift(I, c_nof_stages)) <= data_re(0)(flip(I, c_nof_stages));
208
      int_im_arr(fft_shift(I, c_nof_stages)) <= data_im(0)(flip(I, c_nof_stages));
209
    end generate;
210
  end generate;
211
 
212
  no_reorder : if g_fft.use_reorder=false generate
213
    -- use flipped bin index order as it comes by default
214
    int_re_arr <= data_re(0);
215
    int_im_arr <= data_im(0);
216
  end generate;
217
  int_val <= data_val(0)(0);
218
 
219
  --------------------------------------------------------------------------------
220
  -- Optional separate 
221
  --------------------------------------------------------------------------------
222
  gen_separate : if g_fft.use_separate generate
223
    ---------------------------------------------------------------------------
224
    -- Calulate the positive bins
225
    ---------------------------------------------------------------------------
226
    gen_positive_bins : for I in 1 to g_fft.nof_points/2 - 1 generate
227
      -- common_add_sub
228
      a_output_real_adder : entity common_add_sub_lib.common_add_sub
229
      generic map (
230
        g_direction       => "ADD",
231
        g_representation  => "SIGNED",
232
        g_pipeline_input  => 0,
233
        g_pipeline_output => c_pipeline_add_sub,
234
        g_in_dat_w        => g_fft.stage_dat_w,
235
        g_out_dat_w       => g_fft.stage_dat_w+1
236
      )
237
      port map (
238
        clk     => clk,
239
        in_a    => int_re_arr(g_fft.nof_points-I),
240
        in_b    => int_re_arr(I),
241
        result  => add_arr(2*I)
242
      );
243
 
244
      b_output_real_adder : entity common_add_sub_lib.common_add_sub
245
      generic map (
246
        g_direction       => "ADD",
247
        g_representation  => "SIGNED",
248
        g_pipeline_input  => 0,
249
        g_pipeline_output => c_pipeline_add_sub,
250
        g_in_dat_w        => g_fft.stage_dat_w,
251
        g_out_dat_w       => g_fft.stage_dat_w+1
252
      )
253
      port map (
254
        clk     => clk,
255
        in_a    => int_im_arr(g_fft.nof_points-I),
256
        in_b    => int_im_arr(I),
257
        result  => add_arr(2*I+1)
258
      );
259
 
260
      a_output_imag_subtractor : entity common_add_sub_lib.common_add_sub
261
      generic map (
262
        g_direction       => "SUB",
263
        g_representation  => "SIGNED",
264
        g_pipeline_input  => 0,
265
        g_pipeline_output => c_pipeline_add_sub,
266
        g_in_dat_w        => g_fft.stage_dat_w,
267
        g_out_dat_w       => g_fft.stage_dat_w+1
268
      )
269
      port map (
270
        clk     => clk,
271
        in_a    => int_im_arr(I),
272
        in_b    => int_im_arr(g_fft.nof_points-I),
273
        result  => sub_arr(2*I)
274
      );
275
 
276
      b_output_imag_subtractor : entity common_add_sub_lib.common_add_sub
277
      generic map (
278
        g_direction       => "SUB",
279
        g_representation  => "SIGNED",
280
        g_pipeline_input  => 0,
281
        g_pipeline_output => c_pipeline_add_sub,
282
        g_in_dat_w        => g_fft.stage_dat_w,
283
        g_out_dat_w       => g_fft.stage_dat_w+1
284
      )
285
      port map (
286
        clk     => clk,
287
        in_a    => int_re_arr(g_fft.nof_points-I),
288
        in_b    => int_re_arr(I),
289
        result  => sub_arr(2*I+1)
290
      );
291
 
292
      gen_sepa_truncate : IF c_sepa_round=false GENERATE
293
        -- truncate the one LSbit
294
        fft_re_arr(2*I  ) <= add_arr(2*I  )(g_fft.stage_dat_w DOWNTO 1);  -- A real
295
        fft_re_arr(2*I+1) <= add_arr(2*I+1)(g_fft.stage_dat_w DOWNTO 1);  -- B real
296
        fft_im_arr(2*I  ) <= sub_arr(2*I  )(g_fft.stage_dat_w DOWNTO 1);  -- A imag
297
        fft_im_arr(2*I+1) <= sub_arr(2*I+1)(g_fft.stage_dat_w DOWNTO 1);  -- B imag
298
      end generate;
299
 
300
      gen_sepa_round : IF c_sepa_round=true GENERATE
301
        -- round the one LSbit
302
        round_re_a : ENTITY common_requantize_lib.common_round
303
        GENERIC MAP (
304
          g_representation  => "SIGNED",  -- SIGNED (round +-0.5 away from zero to +- infinity) or UNSIGNED rounding (round 0.5 up to + inifinity)
305
          g_round           => TRUE,      -- when TRUE round the input, else truncate the input
306
          g_round_clip      => FALSE,     -- when TRUE clip rounded input >= +max to avoid wrapping to output -min (signed) or 0 (unsigned)
307
          g_pipeline_input  => 0,         -- >= 0
308
          g_pipeline_output => 0,         -- >= 0, use g_pipeline_input=0 and g_pipeline_output=0 for combinatorial output
309
          g_in_dat_w        => g_fft.stage_dat_w+1,
310
          g_out_dat_w       => g_fft.stage_dat_w
311
        )
312
        PORT MAP (
313
          clk        => clk,
314
          in_dat     => add_arr(2*I),
315
          out_dat    => fft_re_arr(2*I)
316
        );
317
 
318
        round_re_b : ENTITY common_requantize_lib.common_round
319
        GENERIC MAP (
320
          g_representation  => "SIGNED",  -- SIGNED (round +-0.5 away from zero to +- infinity) or UNSIGNED rounding (round 0.5 up to + inifinity)
321
          g_round           => TRUE,      -- when TRUE round the input, else truncate the input
322
          g_round_clip      => FALSE,     -- when TRUE clip rounded input >= +max to avoid wrapping to output -min (signed) or 0 (unsigned)
323
          g_pipeline_input  => 0,         -- >= 0
324
          g_pipeline_output => 0,         -- >= 0, use g_pipeline_input=0 and g_pipeline_output=0 for combinatorial output
325
          g_in_dat_w        => g_fft.stage_dat_w+1,
326
          g_out_dat_w       => g_fft.stage_dat_w
327
        )
328
        PORT MAP (
329
          clk        => clk,
330
          in_dat     => add_arr(2*I+1),
331
          out_dat    => fft_re_arr(2*I+1)
332
        );
333
 
334
        round_im_a : ENTITY common_requantize_lib.common_round
335
        GENERIC MAP (
336
          g_representation  => "SIGNED",  -- SIGNED (round +-0.5 away from zero to +- infinity) or UNSIGNED rounding (round 0.5 up to + inifinity)
337
          g_round           => TRUE,      -- when TRUE round the input, else truncate the input
338
          g_round_clip      => FALSE,     -- when TRUE clip rounded input >= +max to avoid wrapping to output -min (signed) or 0 (unsigned)
339
          g_pipeline_input  => 0,         -- >= 0
340
          g_pipeline_output => 0,         -- >= 0, use g_pipeline_input=0 and g_pipeline_output=0 for combinatorial output
341
          g_in_dat_w        => g_fft.stage_dat_w+1,
342
          g_out_dat_w       => g_fft.stage_dat_w
343
        )
344
        PORT MAP (
345
          clk        => clk,
346
          in_dat     => sub_arr(2*I),
347
          out_dat    => fft_im_arr(2*I)
348
        );
349
 
350
        round_im_b : ENTITY common_requantize_lib.common_round
351
        GENERIC MAP (
352
          g_representation  => "SIGNED",  -- SIGNED (round +-0.5 away from zero to +- infinity) or UNSIGNED rounding (round 0.5 up to + inifinity)
353
          g_round           => TRUE,      -- when TRUE round the input, else truncate the input
354
          g_round_clip      => FALSE,     -- when TRUE clip rounded input >= +max to avoid wrapping to output -min (signed) or 0 (unsigned)
355
          g_pipeline_input  => 0,         -- >= 0
356
          g_pipeline_output => 0,         -- >= 0, use g_pipeline_input=0 and g_pipeline_output=0 for combinatorial output
357
          g_in_dat_w        => g_fft.stage_dat_w+1,
358
          g_out_dat_w       => g_fft.stage_dat_w
359
        )
360
        PORT MAP (
361
          clk        => clk,
362
          in_dat     => sub_arr(2*I+1),
363
          out_dat    => fft_im_arr(2*I+1)
364
        );
365
      end generate;
366
    end generate;
367
 
368
    ---------------------------------------------------------------------------
369
    -- Generate bin 0 directly
370
    ---------------------------------------------------------------------------
371
    -- Index N=g_fft.nof_points wraps to index 0:
372
    -- . fft_re_arr(0) = (int_re_arr(0) + int_re_arr(N)) / 2 = int_re_arr(0)
373
    -- . fft_re_arr(1) = (int_im_arr(0) + int_im_arr(N)) / 2 = int_im_arr(0)
374
    -- . fft_im_arr(0) = (int_im_arr(0) - int_im_arr(N)) / 2 = 0
375
    -- . fft_im_arr(1) = (int_re_arr(0) - int_re_arr(N)) / 2 = 0
376
 
377
    u_pipeline_a_re_0 : entity common_components_lib.common_pipeline
378
    generic map (
379
      g_pipeline  => c_pipeline_add_sub,
380
      g_in_dat_w  => g_fft.stage_dat_w,
381
      g_out_dat_w => g_fft.stage_dat_w
382
    )
383
    port map (
384
      clk     => clk,
385
      in_dat  => int_re_arr(0),
386
      out_dat => fft_re_arr(0)
387
    );
388
 
389
    u_pipeline_b_re_0 : entity common_components_lib.common_pipeline
390
    generic map (
391
      g_pipeline  => c_pipeline_add_sub,
392
      g_in_dat_w  => g_fft.stage_dat_w,
393
      g_out_dat_w => g_fft.stage_dat_w
394
    )
395
    port map (
396
      clk     => clk,
397
      in_dat  => int_im_arr(0),
398
      out_dat => fft_re_arr(1)
399
    );
400
 
401
    -- The imaginary outputs of A(0) and B(0) are always zero in case two real inputs are provided
402
    fft_im_arr(0) <= (others=>'0');
403
    fft_im_arr(1) <= (others=>'0');
404
 
405
    ------------------------------------------------------------------------------
406
    -- Valid pipelining for separate
407
    ------------------------------------------------------------------------------
408
    u_seperate_fft_val : entity common_components_lib.common_pipeline_sl
409
    generic map (
410
      g_pipeline => c_pipeline_add_sub
411
    )
412
    port map (
413
      clk     => clk,
414
      in_dat  => int_val,
415
      out_dat => fft_val
416
    );
417
  end generate;
418
 
419
  no_separate : if g_fft.use_separate=false generate
420
    assign_outputs : for I in 0 to g_fft.nof_points-1 generate
421
      fft_re_arr(I) <= int_re_arr(I);
422
      fft_im_arr(I) <= int_im_arr(I);
423
    end generate;
424
    fft_val <= int_val;
425
  end generate;
426
 
427
  ------------------------------------------------------------------------------
428
  -- Parallel FFT output requantization
429
  ------------------------------------------------------------------------------
430
  gen_output_requantizers : for I in 0 to g_fft.nof_points-1 generate
431
    u_requantize_re : entity common_requantize_lib.common_requantize
432
    generic map (
433
      g_representation      => "SIGNED",
434
      g_lsb_w               => c_out_scale_w,
435
      g_lsb_round           => TRUE,
436
      g_lsb_round_clip      => FALSE,
437
      g_msb_clip            => FALSE,
438
      g_msb_clip_symmetric  => FALSE,
439
      g_pipeline_remove_lsb => c_pipeline_remove_lsb,
440
      g_pipeline_remove_msb => 0,
441
      g_in_dat_w            => g_fft.stage_dat_w,
442
      g_out_dat_w           => g_fft.out_dat_w
443
    )
444
    port map (
445
      clk        => clk,
446
      in_dat     => fft_re_arr(I),
447
      out_dat    => out_re_arr(I),
448
      out_ovr    => open
449
    );
450
 
451
    u_requantize_im : entity common_requantize_lib.common_requantize
452
    generic map (
453
      g_representation      => "SIGNED",
454
      g_lsb_w               => c_out_scale_w,
455
      g_lsb_round           => TRUE,
456
      g_lsb_round_clip      => FALSE,
457
      g_msb_clip            => FALSE,
458
      g_msb_clip_symmetric  => FALSE,
459
      g_pipeline_remove_lsb => c_pipeline_remove_lsb,
460
      g_pipeline_remove_msb => 0,
461
      g_in_dat_w            => g_fft.stage_dat_w,
462
      g_out_dat_w           => g_fft.out_dat_w
463
    )
464
    port map (
465
      clk        => clk,
466
      in_dat     => fft_im_arr(I),
467
      out_dat    => out_im_arr(I),
468
      out_ovr    => open
469
    );
470
 
471
  end generate;
472
 
473
  u_out_val : entity common_components_lib.common_pipeline_sl
474
  generic map (
475
    g_pipeline => c_pipeline_remove_lsb
476
  )
477
  port map (
478
    rst     => rst,
479
    clk     => clk,
480
    in_dat  => fft_val,
481
    out_dat => out_val
482
  );
483
end str;

powered by: WebSVN 2.1.0

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