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

Subversion Repositories astron_wpfb

[/] [astron_wpfb/] [trunk/] [wpfb_unit_dev.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
--------------------------------------------------------------------------------
2
-- Author: Harm Jan Pepping : HJP at astron.nl: April 2012
3
--------------------------------------------------------------------------------
4
--
5
-- Copyright (C) 2012
6
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
7
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
8
--
9
-- This program is free software: you can redistribute it and/or modify
10
-- it under the terms of the GNU General Public License as published by
11
-- the Free Software Foundation, either version 3 of the License, or
12
-- (at your option) any later version.
13
--
14
-- This program is distributed in the hope that it will be useful,
15
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
16
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
-- GNU General Public License for more details.
18
--
19
-- You should have received a copy of the GNU General Public License
20
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
--
22
--------------------------------------------------------------------------------
23
-- Purpose: Wideband polyphase filterbank with subband statistics and streaming interfaces.
24
--
25
-- Description:
26
--
27
-- This WPFB unit connects an incoming array of streaming interfaces to the
28
-- wideband pft + fft.
29
-- The output of the wideband fft is connected to a set of subband statistics
30
-- units. The statistics can be read via the memory mapped interface.
31
-- A control unit takes care of the correct composition of the control of the 
32
-- output streams regarding sop, eop, sync, bsn, err.
33
--
34
-- The wpfb unit can handle a wideband factor >= 1 (g_wpfb.wb_factor) or
35
-- a narrowband factor >= 1 (2**g_wpfb.nof_chan).
36
-- . For wb_factor = 1 the wpfb_unit uses fft_r2_pipe
37
-- . For wb_factor > 1 the wpfb_unit uses fft_r2_wide
38
-- . For wb_factor >= 1 the wpfb_unit supports nof_chan >= 0, even though the
39
--   concept of channels is typically not useful when wb_factor > 1.
40
-- . The wpfb_unit does support use_reorder.
41
-- . The wpfb_unit does support use_separate.
42
-- . The wpfb_unit does support input flow control with invalid gaps in the
43
--   input.
44
--
45
-- . g_coefs_file_prefix:
46
--   The g_coefs_file_prefix points to the location where the files
47
--   with the initial content for the coefficients memories are located and
48
--   is described in fil_ppf_wide.vhd.
49
--
50
-- . fft_out_gain_w
51
--   For two real input typically fft_out_gain_w = 1 is used to compensate for
52
--   the divide by 2 in the separate function that is done because real input
53
--   frequency bins have norm 0.5. For complex input typically fft_out_gain_w
54
--   = 0, because the complex bins have norm 1.
55
--
56
-- . g_dont_flip_channels:
57
--   True preserves channel interleaving, set by g_wpfb.nof_chan>0, of the FFT
58
--   output when g_bit_flip=true to reorder the FFT output.
59
--   The g_dont_flip_channels applies for both complex input and two_real
60
--   input FFT. The g_dont_flip_channels is only implemented for the pipelined
61
--   fft_r2_pipe, because for g_wpfb.wb_factor=1 using g_wpfb.nof_chan>0 makes
62
--   sense, while for the fft_r2_wide with g_wpfb.wb_factor>1 using input
63
--   multiplexing via g_wpfb.nof_chan>0 makes less sense.
64
--
65
-- The reordering to the fil_ppf_wide is done such that the FIR filter
66
-- coefficients are reused. The same filter coefficients are used for all
67
-- streams. The filter has real coefficients, because the filterbank
68
-- channels are symmetrical in frequency. The real part and the imaginary
69
-- part are filtered independently and also use the same real FIR
70
-- coefficients.
71
--
72
-- Note that:
73
-- . The same P of all streams are grouped the in filter and all P per
74
--   stream are grouped in the FFT. Hence the WPFB input is grouped per
75
--   P for all wideband streams to allow FIR coefficients reuse per P
76
--   for all wideband streams. The WPFB output is grouped per wideband
77
--   stream to have all P together.
78
--
79
-- . The wideband time index t is big-endian inside the prefilter and
80
--   little-endian inside the FFT. 
81
--   When g_big_endian_wb_in=true then the WPFB input must be in big-endian
82
--   format, else in little-endian format.
83
--   For little-endian time index t increments in the same direction as the
84
--   wideband factor index P, so P = 0, 1, 2, 3 --> t0, t1, t2, t3.
85
--   For big-endian the time index t increments in the opposite direction of
86
--   the wideband factor index P, so P = 3, 2, 1, 0 --> t0, t1, t2, t3.
87
--   The WPFB output is fixed little-endian, so with frequency bins in
88
--   incrementing order. However the precise frequency bin order depends
89
--   on the reorder generics.
90
--
91
-- When wb_factor = 4 and nof_wb_streams = 2 the mapping is as follows using 
92
-- the array notation:
93
--
94
--   . I = array index
95
--   . S = stream index of a wideband stream
96
--   . P = wideband factor index
97
--   . t = time index
98
--
99
--                    parallel                           serial   type
100
--   in_sosi_arr      [nof_streams][wb_factor]           [t]      cint
101
--                                               
102
--   fil_in_arr       [wb_factor][nof_streams][complex]  [t]       int
103
--   fil_out_arr      [wb_factor][nof_streams][complex]  [t]       int
104
--                                               
105
--   fil_sosi_arr     [nof_streams][wb_factor]           [t]      cint
106
--   fft_in_re_arr    [nof_streams][wb_factor]           [t]       int
107
--   fft_in_im_arr    [nof_streams][wb_factor]           [t]       int
108
--   fft_out_re_arr   [nof_streams][wb_factor]           [bin]     int
109
--   fft_out_im_arr   [nof_streams][wb_factor]           [bin]     int
110
--   fft_out_sosi_arr [nof_streams][wb_factor]           [bin]    cint
111
--   pfb_out_sosi_arr [nof_streams][wb_factor]           [bin]    cint with sync, BSN, sop, eop
112
--   out_sosi_arr     [nof_streams][wb_factor]           [bin]    cint with sync, BSN, sop, eop
113
-- 
114
--   in_sosi_arr  | fil_in_arr  | fft_in_re_arr | fft_out_re_arr  
115
--   fil_sosi_arr | fil_out_arr | fft_in_im_arr | fft_out_im_arr  
116
--                |             |               | fft_out_sosi_arr
117
--                |             |               | pfb_out_sosi_arr
118
--                |             |               |     out_sosi_arr
119
--                |             |               |
120
--    I  S P t    |   I  P S    | I  S P t      | I  S P          
121
--    7  1 3 0    |  15  3 1 IM | 7  1 3 3      | 7  1 3          
122
--    6  1 2 1    |  14  3 1 RE | 6  1 2 2      | 6  1 2          
123
--    5  1 1 2    |  13  3 0 IM | 5  1 1 1      | 5  1 1          
124
--    4  1 0 3    |  12  3 0 RE | 4  1 0 0      | 4  1 0          
125
--    3  0 3 0    |  11  2 1 IM | 3  0 3 3      | 3  0 3          
126
--    2  0 2 1    |  10  2 1 RE | 2  0 2 2      | 2  0 2          
127
--    1  0 1 2    |   9  2 0 IM | 1  0 1 1      | 1  0 1          
128
--    0  0 0 3    |   8  2 0 RE | 0  0 0 0      | 0  0 0          
129
--                |   7  1 1 IM |               |                 
130
--           ^    |   6  1 1 RE |        ^      |                 
131
--         big    |   5  1 0 IM |      little   |                 
132
--         endian |   4  1 0 RE |      endian   |                 
133
--                |   3  0 1 IM |               |                 
134
--                |   2  0 1 RE |               |                 
135
--                |   1  0 0 IM |               |                 
136
--                |   0  0 0 RE |               |                 
137
--
138
-- The WPFB output are the frequency bins per transformed block:
139
--   . subbands, in case ot two real input or
140
--   . channels, in case of complex input
141
--
142
-- The order of the WPFB output depends on the g_fft fields:
143
--   . wb_factor
144
--   . use_reorder
145
--   . use_fft_shift
146
--   . use_separate
147
-- 
148
-- The frequency bin order at the output is obtained with reg_out_bin
149
-- in the test bench tb_wpfb_unit_dev.vhd.
150
--
151
-- Output examples:
152
--
153
-- Frequency bins:
154
--     fs = sample frequency
155
--     Bb = fs/nof_points = bin bandwidth
156
--
157
--     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
158
--     ^                                           ^  ^  ^                                          ^
159
--     <--------- negative bin frequencies ---------> 0 <---------- positive bin frequencies ------->
160
--     -fs/2                                      -Bb 0 +Bb                                        +fs/2-Bb
161
--
162
-- I) Wideband wb_factor = 4
163
-- 1) Two real inputs:
164
-- 
165
--   out_sosi_arr:
166
--     I  S P    bin frequency order         . nof_streams   = 2            
167
--     7  1 3    12 12 13 13 14 14 15 15     . wb_factor     = 4                 
168
--     6  1 2     8  8  9  9 10 10 11 11     . nof_points    = 32               
169
--     5  1 1     4  4  5  5  6  6  7  7     . use_reorder   = true            
170
--     4  1 0     0  0  1  1  2  2  3  3     . use_fft_shift = false         
171
--     3  0 3    12 12 13 13 14 14 15 15     . use_separate  = true           
172
--     2  0 2     8  8  9  9 10 10 11 11       - input A via in_sosi_arr().re
173
--     1  0 1     4  4  5  5  6  6  7  7       - input B via in_sosi_arr().im
174
--     0  0 0     0  0  1  1  2  2  3  3
175
--      input     A  B  A  B  A  B  A  B
176
--
177
--   when nof_chan=1 then:
178
--     I  S P    bin frequency order    
179
--     7  1 3    12 12 13 13 14 14 15 15 12 12 13 13 14 14 15 15
180
--     6  1 2     8  8  9  9 10 10 11 11  8  8  9  9 10 10 11 11
181
--     5  1 1     4  4  5  5  6  6  7  7  4  4  5  5  6  6  7  7
182
--     4  1 0     0  0  1  1  2  2  3  3  0  0  1  1  2  2  3  3
183
--     3  0 3    12 12 13 13 14 14 15 15 12 12 13 13 14 14 15 15
184
--     2  0 2     8  8  9  9 10 10 11 11  8  8  9  9 10 10 11 11
185
--     1  0 1     4  4  5  5  6  6  7  7  4  4  5  5  6  6  7  7
186
--     0  0 0     0  0  1  1  2  2  3  3  0  0  1  1  2  2  3  3
187
--      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
188
--    channel     0....................0  1....................1
189
--
190
-- 2a) Complex input with fft_shift:
191
-- 
192
--   out_sosi_arr:
193
--     I  S P    bin frequency order         . nof_streams   = 2                    
194
--     7  1 3    24 25 26 27 28 29 30 31     . wb_factor     = 4                 
195
--     6  1 2    16 17 18 19 20 21 22 23     . nof_points    = 32               
196
--     5  1 1     8  9 10 11 12 13 14 15     . use_reorder   = true                         
197
--     4  1 0     0  1  2  3  4  5  6  7     . use_fft_shift = true 
198
--     3  0 3    24 25 26 27 28 29 30 31     . use_separate  = false                       
199
--     2  0 2    16 17 18 19 20 21 22 23       - complex input via in_sosi_arr().re and im
200
--     1  0 1     8  9 10 11 12 13 14 15
201
--     0  0 0     0  1  2  3  4  5  6  7
202
--
203
--   when nof_chan=1 then:
204
--     I  S P    bin frequency order    
205
--     7  1 3    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
206
--     6  1 2    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
207
--     5  1 1     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15 
208
--     4  1 0     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
209
--     3  0 3    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
210
--     2  0 2    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
211
--     1  0 1     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15
212
--     0  0 0     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
213
--    channel     0....................0  1....................1
214
--
215
-- 2b) Complex input with reorder, but no fft_shift:
216
-- 
217
--   out_sosi_arr:
218
--     I  S P    bin frequency order         . nof_streams   = 2                    
219
--     7  1 3     8  9 10 11 12 13 14 15     . wb_factor     = 4                 
220
--     6  1 2     0  1  2  3  4  5  6  7     . nof_points    = 32               
221
--     5  1 1    24 25 26 27 28 29 30 31     . use_reorder   = true                         
222
--     4  1 0    16 17 18 19 20 21 22 23     . use_fft_shift = false                      
223
--     3  0 3     8  9 10 11 12 13 14 15     . use_separate  = false                       
224
--     2  0 2     0  1  2  3  4  5  6  7       - complex input via in_sosi_arr().re and im
225
--     1  0 1    24 25 26 27 28 29 30 31
226
--     0  0 0    16 17 18 19 20 21 22 23
227
-- 
228
--   when nof_chan=1 then:
229
--     I  S P    bin frequency order
230
--     7  1 3     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15
231
--     6  1 2     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
232
--     5  1 1    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31  
233
--     4  1 0    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
234
--     3  0 3     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15 
235
--     2  0 2     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
236
--     1  0 1    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
237
--     0  0 0    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
238
--    channel     0....................0  1....................1
239
--
240
-- 2c) Complex input without reorder (so bit flipped):
241
-- 
242
--   out_sosi_arr:
243
--     I  S P    bin frequency order         . nof_streams   = 2                
244
--     7  1 3     8 12 10 14  9 13 11 15     . wb_factor     = 4                
245
--     6  1 2    24 28 26 30 25 29 27 31     . nof_points    = 32               
246
--     5  1 1     0  4  2  6  1  5  3  7     . use_reorder   = false                        
247
--     4  1 0    16 20 18 22 17 21 19 23     . use_fft_shift = false                      
248
--     3  0 3     8 12 10 14  9 13 11 15     . use_separate  = false                       
249
--     2  0 2    24 28 26 30 25 29 27 31       - complex input via in_sosi_arr().re and im
250
--     1  0 1     0  4  2  6  1  5  3  7
251
--     0  0 0    16 20 18 22 17 21 19 23
252
--
253
--   when nof_chan=1 then:
254
--     I  S P    bin frequency order    
255
--     7  1 3     8  8 12 12 10 10 14 14  9  9 13 13 11 11 15 15
256
--     6  1 2    24 24 28 28 26 26 30 30 25 25 29 29 27 27 31 31
257
--     5  1 1     0  0  4  4  2  2  6  6  1  1  5  5  3  3  7  7  
258
--     4  1 0    16 16 20 20 18 18 22 22 17 17 21 21 19 19 23 23
259
--     3  0 3     8  8 12 12 10 10 14 14  9  9 13 13 11 11 15 15 
260
--     2  0 2    24 24 28 28 26 26 30 30 25 25 29 29 27 27 31 31
261
--     1  0 1     0  0  4  4  2  2  6  6  1  1  5  5  3  3  7  7
262
--     0  0 0    16 16 20 20 18 18 22 22 17 17 21 21 19 19 23 23
263
--    channel     0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
264
--
265
-- II) Narrowband wb_factor = 1
266
--
267
-- 1) Two real inputs:
268
-- 
269
--   . nof_streams   = 2
270
--   . nof_chan      = 0
271
--   . wb_factor     = 1
272
--   . nof_points    = 32
273
--   . use_reorder   = true
274
--   . use_fft_shift = false
275
--   . use_separate  = true
276
--     - input A via in_sosi_arr().re
277
--     - input B via in_sosi_arr().im
278
--
279
--   out_sosi_arr:
280
--     I  S P    bin frequency order
281
--     1  1 0     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
282
--     0  0 0     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
283
--      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
284
--
285
--   when nof_chan=1 then:
286
--     I  S P    bin frequency order
287
--     1  1 0     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  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
288
--     0  0 0     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  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
289
--      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
290
--     channel:   0............................................................................................0  1............................................................................................1
291
--
292
-- 2) Complex input
293
--   . nof_streams = 2
294
--   . nof_chan = 0
295
--   . wb_factor = 1
296
--   . nof_points = 32
297
--   . use_separate = false
298
--     - complex input via in_sosi_arr().re and im
299
 
300
-- 2a) Complex input with fft_shift (so use_reorder = true, use_fft_shift = true)
301
-- 
302
--   out_sosi_arr:
303
--     I  S P    bin frequency order
304
--     1  1 0     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
305
--     0  0 0     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
306
--
307
--   when nof_chan=1 then:
308
--     I  S P    bin frequency order
309
--     1  1 0     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  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
310
--     0  0 0     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  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
311
--     channel:   0............................................................................................0  1............................................................................................1
312
--
313
-- 2b) Complex input with reorder but no fft_shift (so use_reorder = true, use_fft_shift = false)
314
-- 
315
--   out_sosi_arr:
316
--     I  S P    bin frequency order
317
--     1  1 0    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
318
--     0  0 0    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
319
--
320
--   when nof_chan=1 then:
321
--     I  S P    bin frequency order
322
--     1  1 0    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 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
323
--     0  0 0    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 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
324
--     channel:   0............................................................................................0  1............................................................................................1
325
--
326
-- 2c) Complex input without reorder (so use_reorder = false, use_fft_shift = false)
327
-- 
328
--   out_sosi_arr:
329
--     I  S P    bin frequency order
330
--     1  1 0    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
331
--     0  0 0    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
332
--
333
--   when nof_chan=1 then:
334
--     I  S P    bin frequency order
335
--     1  1 0    16 16  0  0 24 24  8  8 20 20  4  4 28 28 12 12 18 18  2  2 26 26 10 10 22 22  6  6 30 30 14 14 17 17  1  1 25 25  9  9 21 21  5  5 29 29 13 13 19 19  3  3 27 27 11 11 23 23  7  7 31 31 15 15
336
--     0  0 0    16 16  0  0 24 24  8  8 20 20  4  4 28 28 12 12 18 18  2  2 26 26 10 10 22 22  6  6 30 30 14 14 17 17  1  1 25 25  9  9 21 21  5  5 29 29 13 13 19 19  3  3 27 27 11 11 23 23  7  7 31 31 15 15
337
--     channel:   0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
338
--
339
-- Remarks:
340
-- . The unit can handle only one sync at a time. Therfor the
341
--   sync interval should be larger than the total pipeline
342
--   stages of the wideband fft.
343
--
344
 
345
library ieee, common_pkg_lib, dp_pkg_lib, astron_r2sdf_fft_lib, astron_statistics_lib, astron_filter_lib, astron_wb_fft_lib, astron_diagnostics_lib, astron_ram_lib, astron_mm_lib;
346
use IEEE.std_logic_1164.all;
347
use STD.textio.all;
348
use common_pkg_lib.common_pkg.all;
349
use astron_ram_lib.common_ram_pkg.all;
350
use dp_pkg_lib.dp_stream_pkg.ALL;
351
use astron_r2sdf_fft_lib.rTwoSDFPkg.all;
352
use astron_statistics_lib.all;
353
use astron_filter_lib.all;
354
use astron_filter_lib.fil_pkg.all;
355
use astron_wb_fft_lib.all;
356
use astron_wb_fft_lib.fft_pkg.all;
357
use work.wpfb_pkg.all;
358
 
359
entity wpfb_unit_dev is
360
  generic (
361
    g_big_endian_wb_in  : boolean           := true;
362
    g_wpfb              : t_wpfb;
363
    g_dont_flip_channels: boolean           := false;   -- True preserves channel interleaving for pipelined FFT
364
    g_use_prefilter     : boolean           := TRUE;
365
    g_stats_ena         : boolean           := TRUE;    -- Enables the statistics unit
366
    g_use_bg            : boolean           := FALSE;
367
    g_coefs_file_prefix : string            := "data/coefs_wide" -- File prefix for the coefficients files.
368
   );
369
  port (
370
    dp_rst             : in  std_logic := '0';
371
    dp_clk             : in  std_logic;
372
    mm_rst             : in  std_logic;
373
    mm_clk             : in  std_logic;
374
    ram_fil_coefs_mosi : in  t_mem_mosi;
375
    ram_fil_coefs_miso : out t_mem_miso := c_mem_miso_rst;
376
    ram_st_sst_mosi    : in  t_mem_mosi;                   -- Subband statistics registers
377
    ram_st_sst_miso    : out t_mem_miso := c_mem_miso_rst;
378
    reg_bg_ctrl_mosi   : in  t_mem_mosi;
379
    reg_bg_ctrl_miso   : out t_mem_miso;
380
    ram_bg_data_mosi   : in  t_mem_mosi;
381
    ram_bg_data_miso   : out t_mem_miso;
382
    in_sosi_arr        : in  t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
383
    fil_sosi_arr       : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
384
    out_sosi_arr       : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0)
385
  );
386
end entity wpfb_unit_dev;
387
 
388
architecture str of wpfb_unit_dev is
389
 
390
  constant c_nof_channels          : natural := 2**g_wpfb.nof_chan;
391
 
392
  constant c_nof_data_per_block    : natural := c_nof_channels * g_wpfb.nof_points;
393
  constant c_nof_valid_per_block   : natural := c_nof_data_per_block / g_wpfb.wb_factor;
394
 
395
  constant c_nof_stats             : natural := c_nof_valid_per_block;
396
 
397
  constant c_fil_ppf         : t_fil_ppf := (g_wpfb.wb_factor,
398
                                             g_wpfb.nof_chan,
399
                                             g_wpfb.nof_points,
400
                                             g_wpfb.nof_taps,
401
                                             c_nof_complex*g_wpfb.nof_wb_streams,  -- Complex FFT always requires 2 filter streams: real and imaginary
402
                                             g_wpfb.fil_backoff_w,
403
                                             g_wpfb.fil_in_dat_w,
404
                                             g_wpfb.fil_out_dat_w,
405
                                             g_wpfb.coef_dat_w);
406
 
407
  constant c_fft             : t_fft     := (g_wpfb.use_reorder,
408
                                             g_wpfb.use_fft_shift,
409
                                             g_wpfb.use_separate,
410
                                             g_wpfb.nof_chan,
411
                                             g_wpfb.wb_factor,
412
                                             0,
413
                                             g_wpfb.nof_points,
414
                                             g_wpfb.fft_in_dat_w,
415
                                             g_wpfb.fft_out_dat_w,
416
                                             g_wpfb.fft_out_gain_w,
417
                                             g_wpfb.stage_dat_w,
418
                                             g_wpfb.guard_w,
419
                                             g_wpfb.guard_enable,
420
                                             g_wpfb.stat_data_w,
421
                                             g_wpfb.stat_data_sz);
422
 
423
  constant c_fft_r2_check           : boolean := fft_r2_parameter_asserts(c_fft);
424
 
425
  constant c_bg_buf_adr_w           : natural := ceil_log2(g_wpfb.nof_points/g_wpfb.wb_factor);
426
  constant c_bg_data_file_index_arr : t_nat_natural_arr := array_init(0, g_wpfb.nof_wb_streams*g_wpfb.wb_factor, 1);
427
  constant c_bg_data_file_prefix    : string  := "UNUSED";
428
 
429
  signal ram_st_sst_mosi_arr : t_mem_mosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
430
  signal ram_st_sst_miso_arr : t_mem_miso_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_mem_miso_rst);
431
 
432
  signal fil_in_arr          : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
433
  signal fil_in_val          : std_logic;
434
  signal fil_out_arr         : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
435
  signal fil_out_val         : std_logic;
436
 
437
  signal fft_in_re_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
438
  signal fft_in_im_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
439
  signal fft_in_val          : std_logic;
440
 
441
  signal fft_out_re_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
442
  signal fft_out_im_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
443
  signal fft_out_re_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
444
  signal fft_out_im_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
445
  signal fft_out_re_arr_pipe : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
446
  signal fft_out_im_arr_pipe : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
447
  signal fft_out_val_arr     : std_logic_vector(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
448
 
449
  signal fft_out_sosi        : t_dp_sosi;
450
  signal fft_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
451
 
452
  signal pfb_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
453
 
454
  type reg_type is record
455
    in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
456
  end record;
457
 
458
  signal r, rin : reg_type;
459
 
460
begin
461
 
462
  -- The complete input sosi arry is registered.
463
  comb : process(r, in_sosi_arr)
464
    variable v : reg_type;
465
  begin
466
    v             := r;
467
    v.in_sosi_arr := in_sosi_arr;
468
    rin           <= v;
469
  end process comb;
470
 
471
  regs : process(dp_clk)
472
  begin
473
    if rising_edge(dp_clk) then
474
      r <= rin;
475
    end if;
476
  end process;
477
 
478
  ---------------------------------------------------------------
479
  -- COMBINE MEMORY MAPPED INTERFACES
480
  ---------------------------------------------------------------
481
  -- Combine the internal array of mm interfaces for the subband
482
  -- statistics to one array that is connected to the port of the
483
  -- fft_wide_unit.
484
  u_mem_mux_sst : entity astron_mm_lib.common_mem_mux
485
  generic map (
486
    g_nof_mosi    => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
487
    g_mult_addr_w => ceil_log2(g_wpfb.stat_data_sz*c_nof_stats)
488
  )
489
  port map (
490
    mosi     => ram_st_sst_mosi,
491
    miso     => ram_st_sst_miso,
492
    mosi_arr => ram_st_sst_mosi_arr,
493
    miso_arr => ram_st_sst_miso_arr
494
  );
495
 
496
  gen_pfb : if g_use_bg = FALSE generate
497
    ---------------------------------------------------------------
498
    -- REWIRE THE DATA FOR WIDEBAND POLY PHASE FILTER
499
    ---------------------------------------------------------------
500
 
501
    -- Wire in_sosi_arr --> fil_in_arr
502
    wire_fil_in_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
503
      wire_fil_in_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
504
        fil_in_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex)   <= RESIZE_SVEC_32(r.in_sosi_arr(S*g_wpfb.wb_factor+P).re(g_wpfb.fil_in_dat_w-1 downto 0));
505
        fil_in_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1) <= RESIZE_SVEC_32(r.in_sosi_arr(S*g_wpfb.wb_factor+P).im(g_wpfb.fil_in_dat_w-1 downto 0));
506
      end generate;
507
    end generate;
508
    fil_in_val <= r.in_sosi_arr(0).valid;
509
 
510
    -- Wire fil_out_arr --> fil_sosi_arr
511
    wire_fil_sosi_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
512
      wire_fil_sosi_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
513
        fil_sosi_arr(S*g_wpfb.wb_factor+P).valid <= fil_out_val;
514
        fil_sosi_arr(S*g_wpfb.wb_factor+P).re    <= RESIZE_DP_DSP_DATA(fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex  ));
515
        fil_sosi_arr(S*g_wpfb.wb_factor+P).im    <= RESIZE_DP_DSP_DATA(fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1));
516
      end generate;
517
    end generate;
518
 
519
    -- Wire fil_out_arr --> fft_in_re_arr, fft_in_im_arr
520
    wire_fft_in_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
521
      wire_fft_in_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
522
        fft_in_re_arr(S*g_wpfb.wb_factor + P) <= fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex);
523
        fft_in_im_arr(S*g_wpfb.wb_factor + P) <= fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1);
524
      end generate;
525
    end generate;
526
 
527
    ---------------------------------------------------------------
528
    -- THE POLY PHASE FILTER
529
    ---------------------------------------------------------------
530
    gen_prefilter : IF g_use_prefilter = TRUE generate
531
      u_filter : entity astron_filter_lib.fil_ppf_wide
532
      generic map (
533
        g_big_endian_wb_in  => g_big_endian_wb_in,
534
        g_big_endian_wb_out => false,  -- reverse wideband order from big-endian [3:0] = [t0,t1,t2,t3] in fil_ppf_wide to little-endian [3:0] = [t3,t2,t1,t0] in fft_r2_wide
535
        g_fil_ppf           => c_fil_ppf,
536
        g_fil_ppf_pipeline  => g_wpfb.fil_pipeline,
537
        g_coefs_file_prefix => g_coefs_file_prefix
538
      )
539
      port map (
540
        dp_clk         => dp_clk,
541
        dp_rst         => dp_rst,
542
        mm_clk         => mm_clk,
543
        mm_rst         => mm_rst,
544
        ram_coefs_mosi => ram_fil_coefs_mosi,
545
        ram_coefs_miso => ram_fil_coefs_miso,
546
        in_dat_arr     => fil_in_arr,
547
        in_val         => fil_in_val,
548
        out_dat_arr    => fil_out_arr,
549
        out_val        => fil_out_val
550
      );
551
    end generate;
552
 
553
    -- Bypass filter
554
    no_prefilter : if g_use_prefilter = FALSE generate
555
      fil_out_arr <= fil_in_arr;
556
      fil_out_val <= fil_in_val;
557
    end generate;
558
 
559
    fft_in_val <= fil_out_val;
560
 
561
    ---------------------------------------------------------------
562
    -- THE WIDEBAND FFT
563
    ---------------------------------------------------------------
564
    gen_wideband_fft: if g_wpfb.wb_factor > 1  generate
565
      gen_fft_r2_wide_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
566
        u_fft_r2_wide : entity astron_wb_fft_lib.fft_r2_wide
567
        generic map(
568
          g_fft          => c_fft,         -- generics for the WFFT
569
          g_pft_pipeline => g_wpfb.pft_pipeline,
570
          g_fft_pipeline => g_wpfb.fft_pipeline
571
        )
572
        port map(
573
          clk        => dp_clk,
574
          rst        => dp_rst,
575
          in_re_arr  => fft_in_re_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
576
          in_im_arr  => fft_in_im_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
577
          in_val     => fft_in_val,
578
          out_re_arr => fft_out_re_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
579
          out_im_arr => fft_out_im_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
580
          out_val    => fft_out_val_arr(S)
581
        );
582
      end generate;
583
    end generate;
584
 
585
    ---------------------------------------------------------------
586
    -- THE PIPELINED FFT
587
    ---------------------------------------------------------------
588
    gen_pipeline_fft: if g_wpfb.wb_factor = 1  generate
589
      gen_fft_r2_pipe_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
590
        u_fft_r2_pipe : entity astron_wb_fft_lib.fft_r2_pipe
591
        generic map(
592
          g_fft      => c_fft,
593
          g_dont_flip_channels => g_dont_flip_channels,
594
          g_pipeline => g_wpfb.fft_pipeline
595
        )
596
        port map(
597
          clk       => dp_clk,
598
          rst       => dp_rst,
599
          in_re     => fft_in_re_arr(S)(c_fft.in_dat_w-1 downto 0),
600
          in_im     => fft_in_im_arr(S)(c_fft.in_dat_w-1 downto 0),
601
          in_val    => fft_in_val,
602
          out_re    => fft_out_re_arr_i(S)(c_fft.out_dat_w-1 downto 0),
603
          out_im    => fft_out_im_arr_i(S)(c_fft.out_dat_w-1 downto 0),
604
          out_val   => fft_out_val_arr(S)
605
        );
606
 
607
        fft_out_re_arr(S) <= RESIZE_SVEC_32(fft_out_re_arr_i(S)(c_fft.out_dat_w-1 downto 0));
608
        fft_out_im_arr(S) <= RESIZE_SVEC_32(fft_out_im_arr_i(S)(c_fft.out_dat_w-1 downto 0));
609
      end generate;
610
    end generate;
611
 
612
    ---------------------------------------------------------------
613
    -- FFT CONTROL UNIT
614
    ---------------------------------------------------------------
615
 
616
    -- Capture input BSN at input sync and pass the captured input BSN it on to PFB output sync.
617
    -- The FFT output valid defines PFB output sync, sop, eop.
618
 
619
    fft_out_sosi.sync  <= r.in_sosi_arr(0).sync;
620
    fft_out_sosi.bsn   <= r.in_sosi_arr(0).bsn;
621
    fft_out_sosi.valid <= fft_out_val_arr(0);
622
 
623
    wire_fft_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
624
      fft_out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I));
625
      fft_out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I));
626
      fft_out_sosi_arr(I).valid <=                    fft_out_val_arr(I);
627
    end generate;
628
 
629
    u_dp_block_gen_valid_arr : ENTITY work.dp_block_gen_valid_arr
630
    GENERIC MAP (
631
      g_nof_streams         => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
632
      g_nof_data_per_block  => c_nof_valid_per_block,
633
      g_nof_blk_per_sync    => g_wpfb.nof_blk_per_sync,
634
      g_check_input_sync    => false,
635
      g_nof_pages_bsn       => 1,
636
      g_restore_global_bsn  => true
637
    )
638
    PORT MAP (
639
      rst         => dp_rst,
640
      clk         => dp_clk,
641
      -- Streaming sink
642
      snk_in      => fft_out_sosi,
643
      snk_in_arr  => fft_out_sosi_arr,
644
      -- Streaming source
645
      src_out_arr => pfb_out_sosi_arr,
646
      -- Control
647
      enable      => '1'
648
    );
649
  end generate;
650
 
651
  ----------------------------------------------------------------------------
652
  -- Source: block generator
653
  ----------------------------------------------------------------------------
654
  gen_bg : if g_use_bg = TRUE generate
655
    u_bg : entity astron_diagnostics_lib.mms_diag_block_gen
656
    generic map(
657
      g_nof_streams      => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
658
      g_buf_dat_w        => c_nof_complex*g_wpfb.fft_out_dat_w,
659
      g_buf_addr_w       => c_bg_buf_adr_w,               -- Waveform buffer size 2**g_buf_addr_w nof samples
660
      g_file_index_arr   => c_bg_data_file_index_arr,
661
      g_file_name_prefix => c_bg_data_file_prefix
662
    )
663
    port map(
664
      -- System
665
      mm_rst           => mm_rst,
666
      mm_clk           => mm_clk,
667
      dp_rst           => dp_rst,
668
      dp_clk           => dp_clk,
669
      en_sync          => '0',
670
      -- MM interface
671
      reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
672
      reg_bg_ctrl_miso => reg_bg_ctrl_miso,
673
      ram_bg_data_mosi => ram_bg_data_mosi,
674
      ram_bg_data_miso => ram_bg_data_miso,
675
      -- ST interface
676
      out_sosi_arr     => pfb_out_sosi_arr
677
    );
678
  end generate;
679
 
680
 ---------------------------------------------------------------
681
  -- SUBBAND STATISTICS
682
  ---------------------------------------------------------------
683
  -- For all "wb_factor"x"nof_wb_streams" output streams of the
684
  -- wideband FFT a subband statistics unit is placed if the
685
  -- g_stats_ena is TRUE.
686
  -- Since the subband statistics module uses embedded DSP blocks
687
  -- for multiplication, the incoming data cannot be wider
688
  -- than 18 bit.
689
  gen_stats : if g_stats_ena = TRUE generate
690
    gen_stats_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
691
      gen_stats_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
692
        u_subband_stats : entity astron_statistics_lib.st_sst
693
        generic map(
694
          g_nof_stat      => c_nof_stats,
695
          g_in_data_w     => g_wpfb.fft_out_dat_w,
696
          g_stat_data_w   => g_wpfb.stat_data_w,
697
          g_stat_data_sz  => g_wpfb.stat_data_sz
698
        )
699
        port map (
700
          mm_rst          => mm_rst,
701
          mm_clk          => mm_clk,
702
          dp_rst          => dp_rst,
703
          dp_clk          => dp_clk,
704
          in_complex      => pfb_out_sosi_arr(S*g_wpfb.wb_factor+P),
705
          ram_st_sst_mosi => ram_st_sst_mosi_arr(S*g_wpfb.wb_factor+P),
706
          ram_st_sst_miso => ram_st_sst_miso_arr(S*g_wpfb.wb_factor+P)
707
        );
708
      end generate;
709
    end generate;
710
  end generate;
711
 
712
  -- Connect to the outside world
713
  out_sosi_arr <= pfb_out_sosi_arr;
714
 
715
end str;
716
 
717
 
718
 

powered by: WebSVN 2.1.0

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