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

Subversion Repositories astron_wpfb

[/] [astron_wpfb/] [trunk/] [wpfb_unit.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 FFT with Subband Statistics and streaming interfaces.
24
--
25
-- Description: This unit connects an incoming array of streaming interfaces
26
--              to the wideband fft. The output of the wideband fft is
27
--              connected to a set of subband statistics units. The statistics
28
--              can be read via the memory mapped interface.
29
--              A control unit takes care of the correct composition of the
30
--              output streams(sop,eop,sync,bsn,err).
31
--
32
-- Remarks:   . The unit can handle only one sync at a time. Therfor the
33
--              sync interval should be larger than the total pipeline
34
--              stages of the wideband fft.
35
--
36
--            . The g_coefs_file_prefix points to the location where the files
37
--              with the initial content for the coefficients memories are located.
38
--              These files can be created using the python script: create_mifs.py
39
--              create_mifs.py is located in $UNB/Firmware/dsp/filter/src/python/
40
--              It is possible to create the mif files based on every possible
41
--              configuration of the filterbank in terms of:
42
--                 * wb_factor
43
--                 * nof points
44
--                 * nof_taps
45
--            . The wbfb unit can handle a wideband factor > 1 (g_wpfb.wb_factor) or
46
--              a narrowband factor > 1 (g_wpfb.nof_chan). Both factors can NOT be
47
--              used at the same time.
48
 
49
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_mm_lib, astron_ram_lib;
50
use IEEE.std_logic_1164.all;
51
use STD.textio.all;
52
use common_pkg_lib.common_pkg.all;
53
use astron_ram_lib.common_ram_pkg.all;
54
use dp_pkg_lib.dp_stream_pkg.ALL;
55
use astron_r2sdf_fft_lib.rTwoSDFPkg.all;
56
use astron_statistics_lib.all;
57
use astron_filter_lib.all;
58
use astron_filter_lib.fil_pkg.all;
59
use astron_wb_fft_lib.all;
60
use astron_wb_fft_lib.fft_pkg.all;
61
use work.wpfb_pkg.all;
62
 
63
entity wpfb_unit is
64
  generic (
65
    g_wpfb              : t_wpfb;
66
    g_use_prefilter     : boolean           := TRUE;
67
    g_stats_ena         : boolean           := TRUE;    -- Enables the statistics unit
68
    g_use_bg            : boolean           := FALSE;
69
    g_coefs_file_prefix : string            := "../../../../filter/build/data/coefs_wide" -- File prefix for the coefficients files.
70
   );
71
  port (
72
    dp_rst             : in  std_logic := '0';
73
    dp_clk             : in  std_logic;
74
    mm_rst             : in  std_logic;
75
    mm_clk             : in  std_logic;
76
    ram_fil_coefs_mosi : in  t_mem_mosi;
77
    ram_fil_coefs_miso : out t_mem_miso := c_mem_miso_rst;
78
    ram_st_sst_mosi    : in  t_mem_mosi;                   -- Subband statistics registers
79
    ram_st_sst_miso    : out t_mem_miso := c_mem_miso_rst;
80
    reg_bg_ctrl_mosi   : in  t_mem_mosi;
81
    reg_bg_ctrl_miso   : out t_mem_miso;
82
    ram_bg_data_mosi   : in  t_mem_mosi;
83
    ram_bg_data_miso   : out t_mem_miso;
84
    in_sosi_arr        : in  t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
85
    out_sosi_arr       : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0)
86
  );
87
end entity wpfb_unit;
88
 
89
architecture str of wpfb_unit is
90
 
91
  constant c_nof_stats       : natural := 2**g_wpfb.nof_chan * g_wpfb.nof_points/g_wpfb.wb_factor;
92
 
93
  constant c_fil_ppf         : t_fil_ppf := (g_wpfb.wb_factor,
94
                                             g_wpfb.nof_chan,
95
                                             g_wpfb.nof_points,
96
                                             g_wpfb.nof_taps,
97
                                             c_nof_complex*g_wpfb.nof_wb_streams,  -- Complex FFT always requires 2 filter streams: real and imaginary
98
                                             g_wpfb.fil_backoff_w,
99
                                             g_wpfb.fil_in_dat_w,
100
                                             g_wpfb.fil_out_dat_w,
101
                                             g_wpfb.coef_dat_w);
102
 
103
  constant c_fft             : t_fft     := (g_wpfb.use_reorder,
104
                                             g_wpfb.use_fft_shift,
105
                                             g_wpfb.use_separate,
106
                                             g_wpfb.nof_chan,
107
                                             g_wpfb.wb_factor,
108
                                             0,
109
                                             g_wpfb.nof_points,
110
                                             g_wpfb.fft_in_dat_w,
111
                                             g_wpfb.fft_out_dat_w,
112
                                             g_wpfb.fft_out_gain_w,
113
                                             g_wpfb.stage_dat_w,
114
                                             g_wpfb.guard_w,
115
                                             g_wpfb.guard_enable,
116
                                             g_wpfb.stat_data_w,
117
                                             g_wpfb.stat_data_sz);
118
 
119
 
120
  constant c_bg_buf_adr_w           : natural := ceil_log2(g_wpfb.nof_points/g_wpfb.wb_factor);
121
  constant c_bg_data_file_index_arr : t_nat_natural_arr := array_init(0, g_wpfb.nof_wb_streams*g_wpfb.wb_factor, 1);
122
  constant c_bg_data_file_prefix    : string  := "UNUSED";
123
 
124
  signal ram_st_sst_mosi_arr : t_mem_mosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
125
  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);
126
 
127
  signal fil_in_arr          : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
128
  signal fil_out_arr         : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
129
  signal fil_out_val         : std_logic;
130
 
131
  signal fft_in_re_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
132
  signal fft_in_im_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
133
  signal fft_in_val          : std_logic;
134
 
135
  signal fft_out_re_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
136
  signal fft_out_im_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
137
  signal fft_out_re_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
138
  signal fft_out_im_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
139
  signal fft_out_val         : std_logic_vector(g_wpfb.nof_wb_streams-1 downto 0);
140
 
141
  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);
142
  signal bg_siso_arr         : t_dp_siso_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_siso_rdy);
143
 
144
  type reg_type is record
145
    in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
146
  end record;
147
 
148
  signal r, rin : reg_type;
149
 
150
begin
151
 
152
  ---------------------------------------------------------------
153
  -- CHECK IF PROVIDED GENERICS ARE ALLOWED.
154
  ---------------------------------------------------------------
155
  assert not(g_wpfb.nof_chan /= 0 and g_wpfb.wb_factor /= 1 and rising_edge(dp_clk)) report "nof_chan must be 0 when wb_factor > 1" severity FAILURE;
156
 
157
  ---------------------------------------------------------------
158
  -- INPUT REGISTER FOR THE SOSI ARRAY
159
  ---------------------------------------------------------------
160
  -- The complete input sosi arry is registered.
161
  comb : process(r, in_sosi_arr)
162
    variable v : reg_type;
163
  begin
164
    v             := r;
165
    v.in_sosi_arr := in_sosi_arr;
166
    rin           <= v;
167
  end process comb;
168
 
169
  regs : process(dp_clk)
170
  begin
171
    if rising_edge(dp_clk) then
172
      r <= rin;
173
    end if;
174
  end process;
175
 
176
  ---------------------------------------------------------------
177
  -- COMBINE MEMORY MAPPED INTERFACES
178
  ---------------------------------------------------------------
179
  -- Combine the internal array of mm interfaces for the subband
180
  -- statistics to one array that is connected to the port of the
181
  -- fft_wide_unit.
182
  u_mem_mux_sst : entity astron_mm_lib.common_mem_mux
183
  generic map (
184
    g_nof_mosi    => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
185
    g_mult_addr_w => ceil_log2(g_wpfb.stat_data_sz*c_nof_stats)
186
  )
187
  port map (
188
    mosi     => ram_st_sst_mosi,
189
    miso     => ram_st_sst_miso,
190
    mosi_arr => ram_st_sst_mosi_arr,
191
    miso_arr => ram_st_sst_miso_arr
192
  );
193
 
194
  gen_pfb : if g_use_bg = FALSE generate
195
    ---------------------------------------------------------------
196
    -- PREPARE INPUT DATA FOR WIDEBAND POLY PHASE FILTER
197
    ---------------------------------------------------------------
198
    -- Extract the data from the in_sosi_arr records and resize it
199
    -- to fit the format for the fil_ppf_wide unit. The reordering
200
    -- is done in such a way that the filtercoeficients are reused.
201
    -- Note that both the real part and the imaginary part have
202
    -- their own filterchannel.
203
    -- When wb_factor = 4 and nof_wb_streams = 2 the mapping is as
204
    -- follows (S = wb stream number, W = wideband stream number):
205
    --
206
    -- in_sosi_arr       | fil_in_arr          |  fft_in_re_arr    |  fft_in_im_arr
207
    --              S W  |            S W      |           S W     |           S W
208
    --     0        0 0  |     0      0 0 RE   |0   0      0 0 RE  |1   0      0 0 IM
209
    --     1        0 1  |     1      0 0 IM   |4   1      0 1 RE  |5   1      0 1 IM
210
    --     2        0 2  |     2      1 0 RE   |8   2      0 2 RE  |9   2      0 2 IM
211
    --     3        0 3  |     3      1 0 IM   |12  3      0 3 RE  |13  3      0 3 IM
212
    --     4        1 0  |     4      0 1 RE   |2   4      1 0 RE  |3   4      1 0 IM
213
    --     5        1 1  |     5      0 1 IM   |6   5      1 1 RE  |7   5      1 1 IM
214
    --     6        1 2  |     6      1 1 RE   |10  6      1 2 RE  |11  6      1 2 IM
215
    --     7        1 3  |     7      1 1 IM   |14  7      1 3 RE  |15  7      1 3 IM
216
    --                   |     8      0 2 RE   |                   |
217
    --                   |     9      0 2 IM   |                   |
218
    --                   |    10      1 2 RE   |                   |
219
    --                   |    11      1 2 IM   |                   |
220
    --                   |    12      0 3 RE   |                   |
221
    --                   |    13      0 3 IM   |                   |
222
    --                   |    14      1 3 RE   |                   |
223
    --                   |    15      1 3 IM   |                   |
224
    --
225
    gen_prep_filter_wb_factor: for I in 0 to g_wpfb.wb_factor-1   generate
226
      gen_prep_filter_streams: for J in 0 to g_wpfb.nof_wb_streams-1 generate
227
        fil_in_arr(2*J+I*g_wpfb.nof_wb_streams*c_nof_complex)   <= RESIZE_SVEC(r.in_sosi_arr(I+J*g_wpfb.wb_factor).re(g_wpfb.fil_in_dat_w-1 downto 0), fil_in_arr(0)'length);
228
        fil_in_arr(2*J+I*g_wpfb.nof_wb_streams*c_nof_complex+1) <= RESIZE_SVEC(r.in_sosi_arr(I+J*g_wpfb.wb_factor).im(g_wpfb.fil_in_dat_w-1 downto 0), fil_in_arr(0)'length);
229
      end generate;
230
    end generate;
231
 
232
    ---------------------------------------------------------------
233
    -- THE POLY PHASE FILTER
234
    ---------------------------------------------------------------
235
    gen_prefilter : IF g_use_prefilter = TRUE generate
236
      u_filter : entity astron_filter_lib.fil_ppf_wide
237
      generic map (
238
        g_fil_ppf           => c_fil_ppf,
239
        g_fil_ppf_pipeline  => g_wpfb.fil_pipeline,
240
        g_coefs_file_prefix => g_coefs_file_prefix
241
      )
242
      port map (
243
        dp_clk         => dp_clk,
244
        dp_rst         => dp_rst,
245
        mm_clk         => mm_clk,
246
        mm_rst         => mm_rst,
247
        ram_coefs_mosi => ram_fil_coefs_mosi,
248
        ram_coefs_miso => ram_fil_coefs_miso,
249
        in_dat_arr     => fil_in_arr,
250
        in_val         => r.in_sosi_arr(0).valid,
251
        out_dat_arr    => fil_out_arr,
252
        out_val        => fil_out_val
253
      );
254
    end generate;
255
 
256
    -- Bypass filter
257
    gen_no_prefilter : if g_use_prefilter = FALSE generate
258
      fil_out_arr <= fil_in_arr;
259
      fil_out_val <= r.in_sosi_arr(0).valid;
260
    end generate;
261
 
262
    fft_in_val <= fil_out_val;
263
 
264
    ---------------------------------------------------------------
265
    -- THE WIDEBAND FFT
266
    ---------------------------------------------------------------
267
    gen_wide_band_fft: if g_wpfb.wb_factor > 1  generate
268
      ---------------------------------------------------------------
269
      -- PREPARE INPUT DATA FOR WIDEBAND FFT
270
      ---------------------------------------------------------------
271
      -----------------------------------------------------------------------------------------------------
272
      gen_prep_fft_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
273
        gen_prep_fft_wb_factor: for J in 0 to g_wpfb.wb_factor-1 generate
274
          fft_in_re_arr(I*g_wpfb.wb_factor+J) <= fil_out_arr(J*c_nof_complex*g_wpfb.nof_wb_streams+I*c_nof_complex);
275
          fft_in_im_arr(I*g_wpfb.wb_factor+J) <= fil_out_arr(J*c_nof_complex*g_wpfb.nof_wb_streams+I*c_nof_complex+1);
276
        end generate;
277
      end generate;
278
      -----------------------------------------------------------------------------------------------------
279
      gen_prep_wide_fft_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
280
        u_fft_wide : entity astron_wb_fft_lib.fft_r2_wide
281
        generic map(
282
          g_fft          => c_fft,         -- generics for the WFFT
283
          g_pft_pipeline => g_wpfb.pft_pipeline,
284
          g_fft_pipeline => g_wpfb.fft_pipeline
285
        )
286
        port map(
287
          clk        => dp_clk,
288
          rst        => dp_rst,
289
          in_re_arr  => fft_in_re_arr((I+1)*g_wpfb.wb_factor-1 downto I*g_wpfb.wb_factor),
290
          in_im_arr  => fft_in_im_arr((I+1)*g_wpfb.wb_factor-1 downto I*g_wpfb.wb_factor),
291
          in_val     => fft_in_val,
292
          out_re_arr => fft_out_re_arr((I+1)*g_wpfb.wb_factor-1 downto I*g_wpfb.wb_factor),
293
          out_im_arr => fft_out_im_arr((I+1)*g_wpfb.wb_factor-1 downto I*g_wpfb.wb_factor),
294
          out_val    => fft_out_val(I)
295
        );
296
      end generate;
297
    end generate;
298
 
299
   ---------------------------------------------------------------
300
    -- THE PIPELINED FFT
301
    ---------------------------------------------------------------
302
    gen_pipeline_fft: if g_wpfb.wb_factor = 1  generate
303
      ---------------------------------------------------------------
304
      -- PREPARE INPUT DATA FOR WIDEBAND FFT
305
      ---------------------------------------------------------------
306
      gen_prep_fft_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
307
        fft_in_re_arr(I) <= fil_out_arr(I*c_nof_complex);
308
        fft_in_im_arr(I) <= fil_out_arr(I*c_nof_complex+1);
309
      end generate;
310
 
311
      gen_prep_pipe_fft_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
312
        u_fft_pipe : entity astron_wb_fft_lib.fft_r2_pipe
313
        generic map(
314
          g_fft      => c_fft,
315
          g_pipeline => g_wpfb.fft_pipeline
316
        )
317
        port map(
318
          clk       => dp_clk,
319
          rst       => dp_rst,
320
          in_re     => fft_in_re_arr(I)(c_fft.in_dat_w-1 downto 0),
321
          in_im     => fft_in_im_arr(I)(c_fft.in_dat_w-1 downto 0),
322
          in_val    => fft_in_val,
323
          out_re    => fft_out_re_arr_i(I)(c_fft.out_dat_w-1 downto 0),
324
          out_im    => fft_out_im_arr_i(I)(c_fft.out_dat_w-1 downto 0),
325
          out_val   => fft_out_val(I)
326
        );
327
        fft_out_re_arr(I) <= RESIZE_SVEC(fft_out_re_arr_i(I)(c_fft.out_dat_w-1 downto 0), fft_out_re_arr(I)'length);
328
        fft_out_im_arr(I) <= RESIZE_SVEC(fft_out_im_arr_i(I)(c_fft.out_dat_w-1 downto 0), fft_out_im_arr(I)'length);
329
      end generate;
330
    end generate;
331
 
332
    ---------------------------------------------------------------
333
    -- FFT CONTROL UNIT
334
    ---------------------------------------------------------------
335
    -- The fft control unit composes the output array in the dp-
336
    -- streaming format.
337
    u_fft_control : entity astron_wb_fft_lib.fft_wide_unit_control
338
    generic map (
339
      g_fft        => c_fft,
340
      g_nof_ffts   => g_wpfb.nof_wb_streams
341
    )
342
    port map(
343
      rst          => dp_rst,
344
      clk          => dp_clk,
345
      in_re_arr    => fft_out_re_arr,
346
      in_im_arr    => fft_out_im_arr,
347
      in_val       => fft_out_val(0),
348
      ctrl_sosi    => r.in_sosi_arr(0),
349
      out_sosi_arr => fft_out_sosi_arr
350
    );
351
 
352
  end generate;
353
 
354
  ----------------------------------------------------------------------------
355
  -- Source: block generator
356
  ----------------------------------------------------------------------------
357
  gen_bg : if g_use_bg = TRUE generate
358
    u_bg : entity astron_diagnostics_lib.mms_diag_block_gen
359
    generic map(
360
      g_nof_streams      => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
361
      g_buf_dat_w        => c_nof_complex*g_wpfb.fft_out_dat_w,
362
      g_buf_addr_w       => c_bg_buf_adr_w,               -- Waveform buffer size 2**g_buf_addr_w nof samples
363
      g_file_index_arr   => c_bg_data_file_index_arr,
364
      g_file_name_prefix => c_bg_data_file_prefix
365
    )
366
    port map(
367
      -- System
368
      mm_rst           => mm_rst,
369
      mm_clk           => mm_clk,
370
      dp_rst           => dp_rst,
371
      dp_clk           => dp_clk,
372
      en_sync          => '0',
373
      -- MM interface
374
      reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
375
      reg_bg_ctrl_miso => reg_bg_ctrl_miso,
376
      ram_bg_data_mosi => ram_bg_data_mosi,
377
      ram_bg_data_miso => ram_bg_data_miso,
378
      -- ST interface
379
      out_siso_arr     => bg_siso_arr,
380
      out_sosi_arr     => fft_out_sosi_arr
381
    );
382
  end generate;
383
 
384
 ---------------------------------------------------------------
385
  -- SUBBAND STATISTICS
386
  ---------------------------------------------------------------
387
  -- For all "wb_factor"x"nof_wb_streams" output streams of the
388
  -- wideband FFT a subband statistics unit is placed if the
389
  -- g_stats_ena is TRUE.
390
  -- Since the subband statistics module uses embedded DSP blocks
391
  -- for multiplication, the incoming data cannot be wider
392
  -- than 18 bit.
393
  gen_stats : if g_stats_ena = TRUE generate
394
    gen_stats_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
395
      gen_stats_wb_factor: for J in 0 to g_wpfb.wb_factor-1 generate
396
        u_subband_stats : entity astron_statistics_lib.st_sst
397
        generic map(
398
          g_nof_stat      => c_nof_stats,
399
          g_in_data_w     => g_wpfb.fft_out_dat_w,
400
          g_stat_data_w   => g_wpfb.stat_data_w,
401
          g_stat_data_sz  => g_wpfb.stat_data_sz
402
        )
403
        port map (
404
          mm_rst          => mm_rst,
405
          mm_clk          => mm_clk,
406
          dp_rst          => dp_rst,
407
          dp_clk          => dp_clk,
408
          in_complex      => fft_out_sosi_arr(I*g_wpfb.wb_factor+J),
409
          ram_st_sst_mosi => ram_st_sst_mosi_arr(I*g_wpfb.wb_factor+J),
410
          ram_st_sst_miso => ram_st_sst_miso_arr(I*g_wpfb.wb_factor+J)
411
        );
412
      end generate;
413
    end generate;
414
  end generate;
415
 
416
  -- Connect to the outside world
417
  gen_output_streams: for I in 0 to g_wpfb.nof_wb_streams-1 generate
418
    gen_output_wb_factor : for J in 0 to g_wpfb.wb_factor-1 generate
419
      out_sosi_arr(I*g_wpfb.wb_factor+J) <= fft_out_sosi_arr(I*g_wpfb.wb_factor+J);
420
    end generate;
421
  end generate;
422
 
423
end str;
424
 
425
 
426
 

powered by: WebSVN 2.1.0

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