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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [tb_fft_pkg.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2011
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib, mm_lib, common_ram_lib;
23
USE IEEE.STD_LOGIC_1164.ALL;
24
USE IEEE.NUMERIC_STD.ALL;
25
use IEEE.std_logic_textio.all;
26
USE STD.textio.all;
27
USE common_pkg_lib.common_pkg.ALL;
28
USE common_ram_lib.common_ram_pkg.ALL;
29
USE common_pkg_lib.tb_common_pkg.ALL;
30
USE mm_lib.tb_common_mem_pkg.ALL;
31
USE dp_pkg_lib.dp_stream_pkg.ALL;
32
USE work.fft_pkg.ALL;
33
 
34
PACKAGE tb_fft_pkg IS
35
 
36
  CONSTANT c_fft_nof_subbands_max : NATURAL := 256;
37
 
38
  SUBTYPE t_fft_sst_arr  IS t_slv_64_arr(c_fft_nof_subbands_max-1 DOWNTO 0);  -- use subtype to allow using assignments via t_slv_64_arr as well                                         
39
  TYPE    t_fft_sst_arr2 IS ARRAY (INTEGER RANGE <>) OF t_fft_sst_arr;                                                                            -- Private procedures
40
 
41
  -- map fft output index to bin frequency
42
  function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_fft_shift, use_separate : boolean) return natural;
43
 
44
  -- use out_val and out_val_cnt to determine the FFT output bin frequency and channel
45
  procedure proc_fft_out_control(wb_factor          : natural;
46
                                 nof_points         : natural;
47
                                 nof_channels       : natural;
48
                                 use_reorder        : boolean;
49
                                 use_fft_shift      : boolean;
50
                                 use_separate       : boolean;
51
                                 signal out_val_cnt : in  natural;        -- count at sclk sample rate
52
                                 signal out_val     : in  std_logic;
53
                                 signal out_val_a   : out std_logic;
54
                                 signal out_val_b   : out std_logic;
55
                                 signal out_channel : out natural;
56
                                 signal out_bin     : out natural;
57
                                 signal out_bin_cnt : out natural);
58
 
59
  PROCEDURE proc_read_input_file(SIGNAL   clk                 : IN  STD_LOGIC;
60
                                 SIGNAL   in_file_data        : OUT t_integer_matrix;
61
                                 SIGNAL   in_file_sync        : OUT STD_LOGIC_VECTOR;
62
                                 SIGNAL   in_file_val         : OUT STD_LOGIC_VECTOR;
63
                                          file_name           : IN  STRING);
64
 
65
  PROCEDURE proc_read_input_file(SIGNAL   clk                 : IN  STD_LOGIC;         -- Same read procedure for data files that do not contain a valid and sync column
66
                                 SIGNAL   in_file_data        : OUT t_integer_matrix;
67
                                          file_name           : IN  STRING);
68
 
69
 
70
  PROCEDURE proc_fft_read_subband_statistics_memory(CONSTANT c_fft_lane     : IN  NATURAL;
71
                                                    CONSTANT c_fft          : IN  t_fft;
72
                                                    SIGNAL   clk            : IN  STD_LOGIC;
73
                                                    SIGNAL   mm_mosi        : OUT t_mem_mosi;
74
                                                    SIGNAL   mm_miso        : IN  t_mem_miso;
75
                                                    SIGNAL   statistics_arr : OUT t_slv_64_arr);
76
 
77
 
78
  -- Private procedures  
79
  PROCEDURE proc_read_subband_stats(CONSTANT nof_subbands      : IN  NATURAL;
80
                                    CONSTANT offset            : IN  NATURAL;
81
                                    SIGNAL   clk               : IN  STD_LOGIC;
82
                                    SIGNAL   mm_mosi           : OUT t_mem_mosi;
83
                                    SIGNAL   mm_miso           : IN  t_mem_miso;
84
                                    VARIABLE result            : OUT t_slv_64_arr);
85
 
86
 
87
--  PROCEDURE proc_prepare_input_data(CONSTANT nof_subbands        : IN  NATURAL;      
88
--                                    CONSTANT nof_inputs          : IN  NATURAL;      
89
--                                    CONSTANT nof_input_streams   : IN  NATURAL;      
90
--                                    CONSTANT input_stream_number : IN  NATURAL;      
91
--                                    VARIABLE re_arr              : OUT t_integer_arr;
92
--                                    VARIABLE im_arr              : OUT t_integer_arr;
93
--                                             file_name           : IN  STRING);  
94
 
95
END tb_fft_pkg;
96
 
97
PACKAGE BODY tb_fft_pkg IS
98
 
99
  function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_fft_shift, use_separate : boolean) return natural is
100
    -- Purpose: map fft output index to bin frequency
101
    -- Description:
102
    --   The input index counts the bins as they are output by the HDL implementation of the FFT.
103
    --   This function maps this index to the corresponding bin frequency in the reference FFT.
104
    --   For the complex input reference FFT the assumption is that the bins are in fft_shift(fft())
105
    --   order, so first the negative frequencies, then 0 and the positive frequencies. For
106
    --   the real input reference FFT only 0 and the positive frequency bins are available.
107
    --
108
    --   For a N=8 point (complex) FFT the FFT index corresponds to FFT bin frequency according to:
109
    --
110
    --     0 1 2 3 4 5 6 7  -- index i
111
    --     0 4 2 6 1 5 3 7  -- flip(i)            : FFT bin frequency in bit-reversed index output order
112
    --     0 1 2 3 4 5 6 7  -- flip(flip(i)) = i  : FFT bin frequency after bit-reversed index flip
113
    --                                              yields Matlab fft() output order starting with
114
    --                                              [0 Hz, pos freqs incrementing, neg freqs incrementing]
115
    --     4 5 6 7 0 1 2 3  -- fft_shift(i)       : FFT bin frequency after bit-reversed index flip and
116
    --                                              fft_shift yields Matlab fft_shift(fft()) output order:
117
    --                                              [neg freqs incrementing, 0 Hz in the center, pos
118
    --                                              freqs incrementing]
119
    --     1 5 3 7 0 4 2 6  -- flip(fft_shift(i))
120
    --     4 0 6 2 5 1 7 3  -- fft_shift(flip(i)) : the order of fft_shift() and flip() matters
121
    --
122
    --   For real input only the 0 and positive frequency bins need to be kept:
123
    --
124
    --     0 1 2 3
125
    --
126
    --   The FFT needs to buffer the complex FFT output to be able to separate the FFT for two real
127
    --   inputs, because it needs access at indices N-m and m to do the separate.
128
    --   Therefore when use_separate=true then the use_reorder index flip is also done to have the bin
129
    --   frequencies in increasing order. The use_fft_shift is not applicable for real input.
130
    --
131
    --   For the complex FFT the index flip and fft_shift both require reordering in time, so buffering
132
    --   of the FFT output. The fft_shift is only useful after the index flip. Therefore when
133
    --   use_fft_shift=true then require that use_reorder=true. 
134
    --
135
    --   The bit-reverse index is a flip of the index bits. The flip() is the same as the inverse flip(),
136
    --   so index = flip(flip(index)). For wb_factor = 1 the flip() is done by use_reorder. For
137
    --   wb_factor > 1 the use_reorder implies that both the pipelined sections and the parallel section
138
    --   do there local flips. This combination of P serial flips and 1 parallel flip is not the same
139
    --   as the index flip.
140
    --
141
    --   The fft_shift() inverts the MSbit of the index. The fft_shift() is the same as the inverse
142
    --   fft_shift(), so index = fft_shift(fft_shift(index)).
143
    --
144
    --   The index counts from 0..nof_points-1. For wb_factor>1 the index first counts parallel over
145
    --   the P wide band streams and then serially. The transpose(i, P, N) function in common_pkg shows
146
    --   how the index counts over the P parallel streams and in time:
147
    --
148
    --                      i = 0 1 2 3 4 5 6 7
149
    --                                           t=0 1 2 3  p=
150
    --     transpose(i, 2, 4) = 0 2 4 6 1 3 5 7 :  0 2 4 6   0
151
    --                                             1 3 5 7   1
152
    --
153
    --                                           t=0 1 2 3  p=
154
    --     transpose(i, 4, 2) = 0 4 1 5 2 6 3 7 :  0 4       0
155
    --                                             1 5       1
156
    --                                             2 6       2
157
    --                                             3 7       3
158
    --
159
    --   In the HDL testbench the index i counts the FFT output valid samples. This index has to be 
160
    --   related to the bin frequency of the HDL FFT and to the same bin frequency in the Matlab
161
    --   reference data, to be able to verify the bin frequency output value.
162
    --   
163
    -- Example: wb_factor = 1
164
    --
165
    --   The default complex input FFT bit-reversed bin order and the Matlab reference bin order
166
    --   can relate to i as follows:
167
    --
168
    --      [scrambled bins]                   [0, pos, neg bins]                     [neg, 0, pos bins]
169
    --     b=0 4 2 6 1 5 3 7  --> flip(i) --> b=0 1 2 3 4 5 6 7 --> fft_shift(i) --> b=4 5 6 7 0 1 2 3
170
    --     i=0 1 2 3 4 5 6 7                  i=0 1 2 3 4 5 6 7                      i=0 1 2 3 4 5 6 7
171
    --
172
    --   The two real input FFT bin order (with A via real input and B via imaginary input) and
173
    --   Matlab reference bin order relate to i as follows:
174
    --
175
    --      [0, pos; alternating A,B]
176
    --     b=0 0 1 1 2 2 3 3  --> b = i/2
177
    --     i=0 1 2 3 4 5 6 7
178
    --
179
    --   Which bins the index i represents depends on the HDL generics use_reorder, use_fft_shift
180
    --   and use separate.
181
    --
182
    --     nof_points = 32 : index = 0..nof_points-1 = 0..31
183
    --
184
    --              index i    0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
185
    --          fft_shift(i)  16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
186
    --               flip(i)   0 16  8 24  4 20 12 28  2 18 10 26  6 22 14 30  1 17  9 25  5 21 13 29  3 19 11 27  7 23 15 31
187
    --     fft_shift(flip(i)) 16  0 24  8 20  4 28 12 18  2 26 10 22  6 30 14 17  1 25  9 21  5 29 13 19  3 27 11 23  7 31 15
188
    --                    i/2  0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15
189
    --
190
    --   Conclusion:-
191
    --     use_reorder  use_fft_shift  use_separate  name                 reference bin frequency:
192
    --     false        false          false         Complex              b = fft_shift(flip(i))
193
    --     true         false          false         Complex reordered    b = fft_shift(i)
194
    --     true         true           false         Complex fft_shifted  b = i
195
    --     true         false          true          Two real reordered   b = i/2
196
    --
197
    -- Example: wb_factor = 4
198
    --
199
    --   The default complex input FFT bit-reversed bin order and the Matlab reference bin order
200
    --   can relate to i as follows in wideband parallel order:
201
    --
202
    --     [scrambled bins] --> flip() --> [0, pos, neg bins] --> fft_shift() --> [neg, 0, pos bins]
203
    --     b=0  4  2  6  1  5  3  7       b=0  4  8 12 16 20 24 28               b=16 20 24 28  0  4  8 12
204
    --      16 20 18 22 17 21 19 23         1  5  9 13 17 21 25 29                 17 21 25 29  1  5  9 13
205
    --       8 12 10 14  9 13 11 15         2  6 10 14 18 22 26 30                 18 22 26 30  2  6 10 14
206
    --      24 28 26 30 25 29 27 31         3  7 11 15 19 23 27 31                 19 23 27 31  3  7 11 15
207
    --     
208
    --     i=0  4  8 12 16 20 24 28       i=0  4  8 12 16 20 24 28               i= 0  4  8 12 16 20 24 28
209
    --       1  5  9 13 17 21 25 29         1  5  9 13 17 21 25 29                  1  5  9 13 17 21 25 29
210
    --       2  6 10 14 18 22 26 30         2  6 10 14 18 22 26 30                  2  6 10 14 18 22 26 30
211
    --       3  7 11 15 19 23 27 31         3  7 11 15 19 23 27 31                  3  7 11 15 19 23 27 31
212
    --
213
    --   In the serial order this becomes:
214
    --
215
    --     [scrambled bins]    0 16  8 24  4 20 12 28  2 18 10 26  6 22 14 30  1 17  9 25  5 21 13 29  3 19 11 27  7 23 15 31
216
    --     [0, pos, neg bins]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
217
    --     [neg, 0, pos bins] 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
218
    --                      i= 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
219
    --
220
    --   The index flip in the HDL that is done in the P pipelined FFT sections and then in the
221
    --   parallel FFT section results in:
222
    --
223
    --     [scrambled bins]             flip serial()            --> flip parallel()
224
    --     b=0  4  2  6  1  5  3  7     b=0  1  2  3  4  5  6  7     b=0  1  2  3  4  5  6  7
225
    --      16 20 18 22 17 21 19 23      16 17 18 19 20 21 22 23       8  9 10 11 12 13 14 15
226
    --       8 12 10 14  9 13 11 15       8  9 10 11 12 13 14 15      16 17 18 19 20 21 22 23
227
    --      24 28 26 30 25 29 27 31      24 25 26 27 28 29 30 31      24 25 26 27 28 29 30 31
228
    --     
229
    --     i=0  4  8 12 16 20 24 28     i=0  4  8 12 16 20 24 28     i=0  4  8 12 16 20 24 28
230
    --       1  5  9 13 17 21 25 29       1  5  9 13 17 21 25 29       1  5  9 13 17 21 25 29
231
    --       2  6 10 14 18 22 26 30       2  6 10 14 18 22 26 30       2  6 10 14 18 22 26 30
232
    --       3  7 11 15 19 23 27 31       3  7 11 15 19 23 27 31       3  7 11 15 19 23 27 31
233
    --
234
    --   In the serial order this becomes:
235
    --
236
    --     [scrambled bins]    0 16  8 24  4 20 12 28  2 18 10 26  6 22 14 30  1 17  9 25  5 21 13 29  3 19 11 27  7 23 15 31
237
    --     [flip serial()]     0 16  8 24  1 17  9 25  2 18 10 26  3 19 11 27  4 20 12 28  5 21 13 29  6 22 14 30  7 23 15 31
238
    --     [flip parallel()]   0  8 16 24  1  9 17 25  2 10 18 26  3 11 19 27  4 12 20 28  5 13 21 29  6 14 22 30  7 15 23 31
239
    --
240
    --   Note that the order of flip serial() and flip parallel() does not matter. However the combination of
241
    --   flip serial() and flip parallel() is not the same as a single flip(), because a single flip at once 
242
    --   yields the [0, pos, neg bins] order. To get from i to the flip serial() and flip parallel() order of
243
    --   the HDL output index i requires a transpose(i,8,4).
244
    --
245
    --                     i= 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
246
    --     transpose(i,8,4) = 0  8 16 24  1  9 17 25  2 10 18 26  3 11 19 27  4 12 20 28  5 13 21 29  6 14 22 30  7 15 23 31
247
    --     transpose(i,8,4) = 0  8 16 24
248
    --                        1  9 17 25
249
    --                        2 10 18 26
250
    --                        3 11 19 27
251
    --                        4 12 20 28
252
    --                        5 13 21 29
253
    --                        6 14 22 30
254
    --                        7 15 23 31
255
    --
256
    --     transpose(i,4,8) = 0  4  8 12 16 20 24 28  1  5  9 13 17 21 25 29  2  6 10 14 18 22 26 30  3  7 11 15 19 23 27 31
257
    --     transpose(i,4,8) = 0  4  8 12 16 20 24 28
258
    --                        1  5  9 13 17 21 25 29
259
    --                        2  6 10 14 18 22 26 30
260
    --                        3  7 11 15 19 23 27 31
261
    --
262
    --   For the wideband two real input FFT bin order (with A via real input and B via imaginary input) the
263
    --   the HDL does the flip serial and flip parallel (so use_reorder) and an additional reorder after the
264
    --   FFT. The output order then becomes:
265
    --
266
    --       [0, pos]
267
    --       [A  B  A  B  A  B  A  B]
268
    --      b=0  0  1  1  2  2  3  3     b = i/2 + wb_factor
269
    --        4  4  5  5  6  6  7  7
270
    --        8  8  9  9 10 10 11 11
271
    --       12 12 13 13 14 14 15 15
272
    --     
273
    --      i=0  4  8 12 16 20 24 28
274
    --        1  5  9 13 17 21 25 29
275
    --        2  6 10 14 18 22 26 30
276
    --        3  7 11 15 19 23 27 31
277
    --
278
    --   In the serial order this becomes:
279
    --                          A  A  A  A  B  B  B  B  A  A  A  A  B  B  B  B  A  A  A  A  B  B  B  B  A  A  A  A  B  B  B  B
280
    --             [Two real] = 0  4  8 12  0  4  8 12  1  5  9 13  1  5  9 13  2  6 10 14  2  6 10 14  3  7 11 15  3  7 11 15
281
    --                       i= 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
282
    --     transpose(i,8,4)   = 0  8 16 24  1  9 17 25  2 10 18 26  3 11 19 27  4 12 20 28  5 13 21 29  6 14 22 30  7 15 23 31
283
    --     transpose(i,8,4)/2 = 0  4  8 12  0  4  8 12  1  5  9 13  1  5  9 13  2  6 10 14  2  6 10 14  3  7 11 15  3  7 11 15
284
    --
285
    --   Conclusion:
286
    --     use_reorder  use_fft_shift  use_separate  name                 reference bin frequency:
287
    --     false        false          false         Complex              fft_shift(flip(i))
288
    --     true         false          false         Complex reordered    fft_shift(transpose(i,4,8))  (See remark *)
289
    --     true         true           false         Complex fft_shifted  transpose(i,4,8)             (See remark *)
290
    --     true         false          true          Two real reordered   transpose(i,4,8)/2           (See remark *)
291
    --
292
    -- Remarks:
293
    -- * in the HDL use_fft_shift is not (yet) supported, so use_fft_shift = FALSE
294
    -- * for wb_factor > 1 the flip serial() and flip parallel() are better not done, because to fully reorder the 
295
    --   still needs a transpose() that requires a dual buffer after the wideband FFT.
296
    -- * strangely the analysis expects that transpose(i,8,4) is necessary to compensate for the incomplete
297
    --   use_reorder (by flip serial and flip parallel), however in practise transpose(i,4,8) is needed to match
298
    --   the HDL output
299
    --
300
    constant c_addr_w : natural := ceil_log2(nof_points);
301
 
302
    variable v_addr       : std_logic_vector(c_addr_w-1 downto 0);   -- used to convert index integer into slv
303
    variable v_index      : natural;
304
    variable v_bin        : natural;
305
  begin
306
    -- index = i
307
    if wb_factor=1 then
308
      -- Single serial data
309
      if use_separate=false then
310
        -- Complex input data
311
        if use_reorder=false then
312
          -- No HDL index flip
313
          v_addr := to_uvec(index, c_addr_w);
314
          v_addr := flip(v_addr);
315
          v_addr := fft_shift(v_addr);           -- b = fft_shift(flip(i))
316
        else
317
          -- With HDL index flip
318
          if use_fft_shift=false then
319
            -- No HDL fft_shift
320
            v_addr := to_uvec(index, c_addr_w);
321
            v_addr := fft_shift(v_addr);         -- b = fft_shift(i)
322
          else
323
            -- With HDL fft_shift
324
            v_addr := to_uvec(index, c_addr_w);  -- b = i
325
          end if;
326
        end if;
327
        v_bin := to_uint(v_addr);
328
      else
329
        -- Two real input data
330
        v_bin := index / 2;                      -- b = i/2
331
      end if;
332
    else
333
      -- Wideband parallel data
334
      if use_separate=false then
335
        -- Wideband complex input data
336
        if use_reorder=false then
337
          -- No HDL pipelined and parallel index flips
338
          v_addr := to_uvec(index, c_addr_w);
339
          v_addr := flip(v_addr);
340
          v_addr := fft_shift(v_addr);                                     -- b = fft_shift(flip(i))
341
        else
342
          -- With HDL pipelined and parallel index flips
343
          if use_fft_shift=false then
344
            -- No HDL fft_shift
345
            v_index := transpose(index, wb_factor, nof_points/wb_factor);  -- t = transpose(i, 4, 8)
346
            v_addr := to_uvec(v_index, c_addr_w);
347
            v_addr := fft_shift(v_addr);                                   -- b = fft_shift(t)
348
          else
349
            -- With HDL fft_shift
350
            v_index := transpose(index, wb_factor, nof_points/wb_factor);  -- t = transpose(i, 4, 8)
351
            v_addr := to_uvec(v_index, c_addr_w);                          -- b = t
352
          end if;
353
        end if;
354
        v_bin := to_uint(v_addr);
355
      else
356
        -- Wideband two real input data
357
        v_index := transpose(index, wb_factor, nof_points/wb_factor);      -- t = transpose(i, 4, 8)
358
        v_bin := v_index/2;                                                -- b = t/2
359
      end if;
360
    end if;
361
    return v_bin;
362
  end fft_index_to_bin_frequency;
363
 
364
 
365
  procedure proc_fft_out_control(wb_factor          : natural;
366
                                 nof_points         : natural;
367
                                 nof_channels       : natural;
368
                                 use_reorder        : boolean;
369
                                 use_fft_shift      : boolean;
370
                                 use_separate       : boolean;
371
                                 signal out_val_cnt : in  natural;        -- count at sclk sample rate
372
                                 signal out_val     : in  std_logic;
373
                                 signal out_val_a   : out std_logic;
374
                                 signal out_val_b   : out std_logic;
375
                                 signal out_channel : out natural;
376
                                 signal out_bin     : out natural;
377
                                 signal out_bin_cnt : out natural) is
378
    -- Purpose: Derive reference control signals from FFT out_val, out_val_cnt
379
    --          and derive an index per block that can be used to determine
380
    --          the frequency bin with fft_index_to_bin_frequency().
381
    -- Description:
382
    --   The out_val_cnt counts the valid output data from the FFT:
383
    --
384
    --   . out_val_a and out_val_b for interleaved output for two real inputs
385
    --   . out_channel index in range 0:nof_channels-1
386
    --
387
    --   Internally a v_index per block is determined that is independent of
388
    --   nof_channels and then fft_index_to_bin_frequency() is used with the
389
    --   reorder parameters use_reorder, use_fft_shift, use_separate,
390
    --   wb_factor to map this v_index to the bin frequency.
391
    --
392
    --   . out_bin is bin frequency index within a block
393
    --   . out_bin_cnt is bin frequency index in the reference data
394
    --
395
    variable v_blk_index   : natural;
396
    variable v_index       : natural;
397
    variable v_bin         : natural;
398
  begin
399
    out_val_a <= '0';
400
    out_val_b <= '0';
401
 
402
    if use_separate=true then
403
      -- Two real input data
404
      -- Toggle out_val serially starting with wb_factor*A then wb_factor*B
405
      if out_val_cnt/wb_factor mod c_nof_complex = 0 then
406
        out_val_a <= out_val;
407
      else
408
        out_val_b <= out_val;
409
      end if;
410
    end if;
411
 
412
    if use_reorder=true then
413
      v_blk_index := out_val_cnt / nof_points;       -- each block has nof_points
414
      out_channel <= v_blk_index mod nof_channels;   -- the nof_channels are interleaved per block
415
 
416
      v_index := out_val_cnt mod nof_points;         -- index within a block independent of nof_channels
417
 
418
      v_bin := fft_index_to_bin_frequency(wb_factor, nof_points, v_index, use_reorder, use_fft_shift, use_separate);
419
 
420
      out_bin <= v_bin;                              -- bin frequency in a block
421
      if use_separate=true then
422
        -- Two real input data
423
        out_bin_cnt <= v_bin + (v_blk_index/nof_channels) * (nof_points/c_nof_complex);  -- bin index in the half spectrum reference data stream of blocks
424
      else
425
        -- Complex input data
426
        out_bin_cnt <= v_bin + (v_blk_index/nof_channels) * nof_points;                  -- bin index in the full spectrum reference data stream of blocks
427
      end if;
428
    else
429
      -- Complex input data
430
      v_blk_index := out_val_cnt / nof_points / nof_channels;     -- each block has nof_channels*nof_points
431
      out_channel <= (out_val_cnt / wb_factor) mod nof_channels;  -- the nof_channels are interleaved per wb_factor number of samples
432
 
433
      v_index := ((out_val_cnt / wb_factor / nof_channels) * wb_factor +
434
                  (out_val_cnt MOD wb_factor)) mod nof_points;     -- index within a block independent of nof_channels
435
 
436
      v_bin := fft_index_to_bin_frequency(wb_factor, nof_points, v_index, use_reorder, use_fft_shift, use_separate);
437
 
438
      out_bin <= v_bin;                                         -- bin frequency in a block
439
      out_bin_cnt <= v_bin + v_blk_index * nof_points;          -- bin index in the full spectrum reference data stream of blocks
440
    end if;
441
  end proc_fft_out_control;
442
 
443
 
444
  ------------------------------------------------------------------------------
445
  -- PROCEDURE: Read input file.
446
  --            Reads data (re, im, sync and val) from a file and writes values 
447
  --            to the output signals. 
448
  ------------------------------------------------------------------------------
449
  PROCEDURE proc_read_input_file( SIGNAL   clk                 : IN  STD_LOGIC;
450
                                  SIGNAL   in_file_data        : OUT t_integer_matrix;
451
                                  SIGNAL   in_file_sync        : OUT STD_LOGIC_VECTOR;
452
                                  SIGNAL   in_file_val         : OUT STD_LOGIC_VECTOR;
453
                                           file_name           : IN  STRING) IS
454
 
455
    VARIABLE v_file_status : FILE_OPEN_STATUS;
456
    FILE     v_in_file     : TEXT;
457
    VARIABLE v_log_line    : LINE;
458
    VARIABLE v_input_line  : LINE;
459
    VARIABLE v_index       : INTEGER :=0;
460
    VARIABLE v_comma       : CHARACTER;
461
    VARIABLE v_sync        : STD_LOGIC_VECTOR(in_file_sync'RANGE):=(OTHERS => '0');
462
    VARIABLE v_val         : STD_LOGIC_VECTOR(in_file_val'RANGE) :=(OTHERS => '0');
463
    VARIABLE v_data        : t_integer_matrix(in_file_sync'RANGE, 1 to 2) := (OTHERS => (OTHERS => 0));
464
  BEGIN
465
    -- wait 1 clock cycle to avoid that the output messages 
466
    -- in the transcript window get lost in the 0 ps start up messages 
467
    proc_common_wait_some_cycles(clk, 1);
468
    write(v_log_line, string'("reading file : "));
469
    write(v_log_line, file_name);
470
    writeline(output, v_log_line);
471
    proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE); -- Open the file with data values for reading
472
    LOOP
473
      EXIT WHEN endfile(v_in_file);
474
      readline(v_in_file, v_input_line);
475
 
476
      read(v_input_line, v_sync(v_index));    -- sync
477
      read(v_input_line, v_comma);
478
 
479
      read(v_input_line, v_val(v_index));     -- valid
480
      read(v_input_line, v_comma);
481
 
482
      read(v_input_line, v_data(v_index,1));  -- real
483
      read(v_input_line, v_comma);
484
 
485
      read(v_input_line, v_data(v_index,2));  -- imag
486
      v_index := v_index + 1;
487
    END LOOP;
488
    proc_common_close_file(v_file_status, v_in_file);             -- Close the file 
489
    write(v_log_line, string'("finished reading file : "));
490
    write(v_log_line, file_name);
491
    writeline(output, v_log_line);
492
 
493
    in_file_data <= v_data;
494
    in_file_sync <= v_sync;
495
    in_file_val  <= v_val;
496
    WAIT;
497
  END proc_read_input_file;
498
 
499
  ------------------------------------------------------------------------------
500
  -- PROCEDURE: Read input file.
501
  --            Reads data (re, im, sync and val) from a file and writes values 
502
  --            to the output signals. 
503
  ------------------------------------------------------------------------------
504
  PROCEDURE proc_read_input_file( SIGNAL   clk                 : IN  STD_LOGIC;
505
                                  SIGNAL   in_file_data        : OUT t_integer_matrix;
506
                                           file_name           : IN  STRING) IS
507
 
508
    VARIABLE v_file_status : FILE_OPEN_STATUS;
509
    FILE     v_in_file     : TEXT;
510
    VARIABLE v_log_line    : LINE;
511
    VARIABLE v_input_line  : LINE;
512
    VARIABLE v_index       : INTEGER :=0;
513
    VARIABLE v_comma       : CHARACTER;
514
    VARIABLE v_data        : t_integer_matrix(in_file_data'RANGE, 1 to 2) := (OTHERS => (OTHERS => 0));
515
  BEGIN
516
    -- wait 1 clock cycle to avoid that the output messages 
517
    -- in the transcript window get lost in the 0 ps start up messages 
518
    proc_common_wait_some_cycles(clk, 1);
519
    write(v_log_line, string'("reading file : "));
520
    write(v_log_line, file_name);
521
    writeline(output, v_log_line);
522
    proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE); -- Open the file with data values for reading
523
    LOOP
524
      EXIT WHEN v_index = in_file_data'HIGH+1;
525
      readline(v_in_file, v_input_line);
526
 
527
      read(v_input_line, v_data(v_index,1));  -- real
528
      read(v_input_line, v_comma);
529
 
530
      read(v_input_line, v_data(v_index,2));  -- imag
531
      v_index := v_index + 1;
532
    END LOOP;
533
    proc_common_close_file(v_file_status, v_in_file);             -- Close the file 
534
    write(v_log_line, string'("finished reading file : "));
535
    write(v_log_line, file_name);
536
    writeline(output, v_log_line);
537
 
538
    in_file_data <= v_data;
539
    WAIT;
540
  END proc_read_input_file;
541
 
542
 
543
  ------------------------------------------------------------------------------
544
  -- PROCEDURE: Read the beamlet statistics memory into an matrix
545
  ------------------------------------------------------------------------------
546
 
547
  PROCEDURE proc_fft_read_subband_statistics_memory(CONSTANT c_fft_lane     : IN  NATURAL;
548
                                                    CONSTANT c_fft          : IN  t_fft;
549
                                                    SIGNAL   clk            : IN  STD_LOGIC;
550
                                                    SIGNAL   mm_mosi        : OUT t_mem_mosi;
551
                                                    SIGNAL   mm_miso        : IN  t_mem_miso;
552
                                                    SIGNAL   statistics_arr : OUT t_slv_64_arr) IS
553
    VARIABLE v_offset         : NATURAL;
554
    VARIABLE v_nof_stats      : NATURAL := c_fft.nof_points/c_fft.wb_factor;
555
    VARIABLE v_statistics_arr : t_slv_64_arr(statistics_arr'RANGE);
556
  BEGIN
557
    v_offset := c_fft_lane*c_fft.stat_data_sz*v_nof_stats;
558
    proc_read_subband_stats(v_nof_stats, v_offset, clk, mm_mosi, mm_miso, v_statistics_arr);
559
    statistics_arr <= v_statistics_arr;
560
    proc_common_wait_some_cycles(clk, 1);  -- ensure that the last statistics_arr value gets assigned too
561
  END proc_fft_read_subband_statistics_memory;
562
 
563
 
564
  ------------------------------------------------------------------------------
565
  -- PROCEDURE: Reads the beamlet statistics into an array. 
566
  ------------------------------------------------------------------------------
567
  PROCEDURE proc_read_subband_stats( CONSTANT nof_subbands      : IN  NATURAL;
568
                                     CONSTANT offset            : IN  NATURAL;
569
                                     SIGNAL   clk               : IN  STD_LOGIC;
570
                                     SIGNAL   mm_mosi           : OUT t_mem_mosi;
571
                                     SIGNAL   mm_miso           : IN  t_mem_miso;
572
                                     VARIABLE result            : OUT t_slv_64_arr) IS
573
    VARIABLE v_data_lo : STD_LOGIC_VECTOR(31 DOWNTO 0);
574
  BEGIN
575
    FOR J IN 0 TO nof_subbands-1 LOOP
576
      -- Memory is 32-bit, therefor each power value (56-bit wide) must be composed out of two reads. 
577
      proc_mem_mm_bus_rd(offset+2*J, clk, mm_mosi);
578
      proc_common_wait_some_cycles(clk, 1);
579
      v_data_lo := mm_miso.rddata(31 DOWNTO 0);
580
      proc_mem_mm_bus_rd(offset+2*J+1, clk, mm_mosi);
581
      proc_common_wait_some_cycles(clk, 1);
582
      result(J) := mm_miso.rddata(31 DOWNTO 0) & v_data_lo;
583
    END LOOP;
584
  END proc_read_subband_stats;
585
 
586
 
587
 
588
 
589
  ------------------------------------------------------------------------------
590
  -- PROCEDURE: Prepare input array.
591
  --            Combinatorial read data from source file and re-arrange in such
592
  --            a way that it represents the data of one input stream
593
  ------------------------------------------------------------------------------
594
--  PROCEDURE proc_prepare_input_data( CONSTANT nof_subbands        : IN  NATURAL;
595
--                                     CONSTANT nof_inputs          : IN  NATURAL;
596
--                                     CONSTANT nof_input_streams   : IN  NATURAL; 
597
--                                     CONSTANT input_stream_number : IN  NATURAL; 
598
--                                     VARIABLE re_arr              : OUT t_integer_arr;
599
--                                     VARIABLE im_arr              : OUT t_integer_arr;
600
--                                              file_name           : IN  STRING) IS
601
--    VARIABLE v_file_status                        : FILE_OPEN_STATUS;                                  
602
--    FILE     v_in_file                            : TEXT;
603
--    VARIABLE v_line                               : LINE;   
604
--    VARIABLE v_in_temp                            : t_integer_arr(2*nof_inputs-1 downto 0);
605
--    CONSTANT c_nof_signal_inputs_per_input_stream : NATURAL := nof_inputs/nof_input_streams;
606
--  BEGIN
607
--    proc_common_open_file(v_file_status, v_in_file, file_name, READ_MODE);        -- Open the file with data values for reading
608
--    FOR I IN 0 TO nof_subbands-1 LOOP                                                                                         
609
--      proc_common_readline_file(v_file_status, v_in_file, v_in_temp, 2*nof_inputs);   -- Read line with complex subband samples from all inputs
610
--      FOR J IN 0 TO c_nof_signal_inputs_per_input_stream-1 LOOP
611
--        re_arr(J*nof_subbands+I) := v_in_temp(2*(J+input_stream_number*c_nof_signal_inputs_per_input_stream));
612
--        im_arr(J*nof_subbands+I) := v_in_temp(2*(J+input_stream_number*c_nof_signal_inputs_per_input_stream)+1);         
613
--      END LOOP;
614
--    END LOOP;
615
--    proc_common_close_file(v_file_status, v_in_file);                               -- Close the file 
616
--  END proc_prepare_input_data;
617
 
618
END tb_fft_pkg;
619
 

powered by: WebSVN 2.1.0

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