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

powered by: WebSVN 2.1.0

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