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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [tb_mmf_fft_r2.vhd] - Blame information for rev 5

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
-- Purpose: Testbench for the radix-2 FFT.
22
--
23
--          The testbench serves the pipelined, wideband and parallel FFTs.
24
--          The generic g_fft_type is used to select the desired FFT. 
25
--
26
--          The testbech uses blockgenerators to generate data for 
27
--          every input of the FFT. 
28
--          The output of the FFT is stored in databuffers. 
29
--          Both the block generators and databuffers are controlled
30
--          via a mm interface. 
31
--          Use this testbench in conjunction with ../python/tc_mmf_fft_r2.py
32
--
33
-- The testbench can be used in two modes: auto-mode and non-auto-mode. The mode
34
-- is determined by the constant c_modelsim_start in the tc_mmf_fft_r2.py script. 
35
-- 
36
-- Usage in auto-mode (c_modelsim_start = 1 in python):
37
--   > Run python script in separate terminal: "python tc_mmf_fft_r2.py --unb 0 --bn 0 --sim"
38
--
39
-- Usage in non-auto-mode (c_modelsim_start = 0 in python):
40
--   > run -all
41
--   > Run python script in separate terminal: "python tc_mmf_fft_r2.py --unb 0 --bn 0 --sim"
42
--   > Check the results of the python script. 
43
--   > Stop the simulation manually in Modelsim by pressing the stop-button. 
44
 
45
 
46 5 danv
LIBRARY IEEE, common_pkg_lib, astron_mm_lib, astron_diagnostics_lib, dp_pkg_lib, astron_r2sdf_fft_lib, astron_ram_lib, astron_mm_lib, astron_sim_tools_lib;
47 2 danv
USE IEEE.std_logic_1164.ALL;
48
USE IEEE.numeric_std.ALL;
49
USE common_pkg_lib.common_pkg.ALL;
50 5 danv
USE astron_ram_lib.common_ram_pkg.ALL;
51 2 danv
USE common_pkg_lib.common_str_pkg.ALL;
52
USE common_pkg_lib.tb_common_pkg.ALL;
53 5 danv
USE astron_mm_lib.tb_common_mem_pkg.ALL;
54
USE astron_mm_lib.mm_file_unb_pkg.ALL;
55
USE astron_mm_lib.mm_file_pkg.ALL;
56 2 danv
USE dp_pkg_lib.dp_stream_pkg.ALL;
57 5 danv
USE astron_diagnostics_lib.diag_pkg.ALL;
58
USE astron_r2sdf_fft_lib.rTwoSDFPkg.all;
59 2 danv
USE work.fft_pkg.all;
60
 
61
ENTITY tb_mmf_fft_r2 IS
62
  GENERIC(
63
    g_fft_type         : string  := "wide"; -- = default "wide", 3 fft types possible: pipe, wide or par 
64
    g_nof_chan         : natural := 0;      -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan         
65
    g_wb_factor        : natural := 4;      -- = default 1, wideband factor
66
    g_nof_points       : natural := 1024;     -- = 1024, N point FFT
67
    g_nof_blocks       : natural := 4;      -- = 4, the number of blocks of g_nof_points each in the BG waveform (must be power of 2 due to that BG c_bg_block_len must be power of 2)
68
    g_in_dat_w         : natural := 8;      -- = 8, number of input bits                                                       
69
    g_out_dat_w        : natural := 16;     -- = 14, number of output bits: in_dat_w + natural((ceil_log2(nof_points))/2) 
70
    g_use_separate     : boolean := false   -- = false for complex input, true for two real inputs
71
 
72
  );
73
END tb_mmf_fft_r2;
74
 
75
ARCHITECTURE tb OF tb_mmf_fft_r2 IS
76
 
77
  CONSTANT c_fft : t_fft := (true, false, g_use_separate, g_nof_chan, g_wb_factor, 0, g_nof_points, g_in_dat_w, g_out_dat_w, 0, c_dsp_mult_w, 2, true, 56, 2);
78
    --  type t_rtwo_fft is record
79
    --    use_reorder    : boolean;  -- = false for bit-reversed output, true for normal output
80
    --    use_fft_shift  : boolean;  -- = false for [0, pos, neg] bin frequencies order, true for [neg, 0, pos] bin frequencies order in case of complex input
81
    --    use_separate   : boolean;  -- = false for complex input, true for two real inputs
82
    --    nof_chan       : natural;  -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan         
83
    --    wb_factor      : natural;  -- = default 1, wideband factor
84
    --    twiddle_offset : natural;  -- = default 0, twiddle offset for PFT sections in a wideband FFT
85
    --    nof_points     : natural;  -- = 1024, N point FFT
86
    --    in_dat_w       : natural;  -- = 8, number of input bits
87
    --    out_dat_w      : natural;  -- = 13, number of output bits: in_dat_w + natural((ceil_log2(nof_points))/2 + 2)  
88
    --    out_gain_w     : natural;  -- = 0, output gain factor applied after the last stage output, before requantization to out_dat_w
89
    --    stage_dat_w    : natural;  -- = 18, data width used between the stages(= DSP multiplier-width)
90
    --    guard_w        : natural;  -- = 2,  Guard used to avoid overflow in FFT stage. 
91
    --    guard_enable   : boolean;  -- = true when input needs guarding, false when input requires no guarding but scaling must be skipped at the last stage(s) (used in wb fft)    
92
    --    stat_data_w    : positive; -- = 56
93
    --    stat_data_sz   : positive; -- = 2
94
    --  end record;  
95
 
96
  CONSTANT c_sim                : BOOLEAN := TRUE;
97
 
98
  ----------------------------------------------------------------------------
99
  -- Clocks and resets
100
  ----------------------------------------------------------------------------   
101
  CONSTANT c_mm_clk_period      : TIME := 100 ps;
102
  CONSTANT c_dp_clk_period      : TIME := 5 ns;
103
  CONSTANT c_sclk_period        : TIME := 1250 ps;
104
  CONSTANT c_dp_pps_period      : NATURAL := 64;
105
 
106
  SIGNAL dp_pps                 : STD_LOGIC;
107
 
108
  SIGNAL mm_rst                 : STD_LOGIC;
109
  SIGNAL mm_clk                 : STD_LOGIC := '0';
110
 
111
  SIGNAL dp_rst                 : STD_LOGIC;
112
  SIGNAL dp_clk                 : STD_LOGIC := '0';
113
 
114
  SIGNAL SCLK                   : STD_LOGIC := '0';
115
 
116
  ----------------------------------------------------------------------------
117
  -- MM buses
118
  ----------------------------------------------------------------------------                                         
119
  SIGNAL reg_diag_bg_mosi          : t_mem_mosi;
120
  SIGNAL reg_diag_bg_miso          : t_mem_miso;
121
 
122
  SIGNAL ram_diag_bg_mosi          : t_mem_mosi;
123
  SIGNAL ram_diag_bg_miso          : t_mem_miso;
124
 
125
  SIGNAL ram_diag_data_buf_re_mosi : t_mem_mosi;
126
  SIGNAL ram_diag_data_buf_re_miso : t_mem_miso;
127
 
128
  SIGNAL reg_diag_data_buf_re_mosi : t_mem_mosi;
129
  SIGNAL reg_diag_data_buf_re_miso : t_mem_miso;
130
 
131
  SIGNAL ram_diag_data_buf_im_mosi : t_mem_mosi;
132
  SIGNAL ram_diag_data_buf_im_miso : t_mem_miso;
133
 
134
  SIGNAL reg_diag_data_buf_im_mosi : t_mem_mosi;
135
  SIGNAL reg_diag_data_buf_im_miso : t_mem_miso;
136
 
137
  CONSTANT c_nof_channels           : NATURAL  := 2**c_fft.nof_chan;
138
  CONSTANT c_nof_streams            : POSITIVE := c_fft.wb_factor;
139
  CONSTANT c_bg_block_len           : NATURAL  := c_fft.nof_points*g_nof_blocks*c_nof_channels/c_fft.wb_factor;
140
 
141
  CONSTANT c_bg_buf_adr_w           : NATURAL := ceil_log2(c_bg_block_len);
142
  CONSTANT c_bg_data_file_index_arr : t_nat_natural_arr := array_init(0, c_fft.wb_factor, 1);
143
  CONSTANT c_bg_data_file_prefix    : STRING := "UNUSED";
144
 
145
  SIGNAL bg_siso_arr                : t_dp_siso_arr(c_fft.wb_factor-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
146
  SIGNAL bg_sosi_arr                : t_dp_sosi_arr(c_fft.wb_factor-1 DOWNTO 0);
147
 
148
  SIGNAL out_sosi_arr               : t_dp_sosi_arr(c_fft.wb_factor-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
149
 
150
  SIGNAL in_re_arr                  : t_fft_slv_arr(c_fft.wb_factor-1 DOWNTO 0);
151
  SIGNAL in_im_arr                  : t_fft_slv_arr(c_fft.wb_factor-1 DOWNTO 0);
152
  SIGNAL in_val                     : STD_LOGIC := '0';
153
 
154
  SIGNAL out_re_arr                 : t_fft_slv_arr(c_fft.wb_factor-1 DOWNTO 0);
155
  SIGNAL out_im_arr                 : t_fft_slv_arr(c_fft.wb_factor-1 DOWNTO 0);
156
  SIGNAL out_val                    : STD_LOGIC := '0';
157
 
158
  SIGNAL scope_in_sosi              : t_dp_sosi_integer;
159
  SIGNAL scope_out_sosi             : t_dp_sosi_integer;
160
 
161
BEGIN
162
 
163
  ----------------------------------------------------------------------------
164
  -- Clock and reset generation
165
  ----------------------------------------------------------------------------
166
  mm_clk <= NOT mm_clk AFTER c_mm_clk_period/2;
167
  mm_rst <= '1', '0' AFTER c_mm_clk_period*5;
168
 
169
  SCLK   <= NOT SCLK AFTER c_sclk_period/2;
170
  dp_clk <= NOT dp_clk AFTER c_dp_clk_period/2;
171
  dp_rst <= '1', '0' AFTER c_dp_clk_period*5;
172
 
173
  ------------------------------------------------------------------------------
174
  -- External PPS
175
  ------------------------------------------------------------------------------  
176
  proc_common_gen_pulse(1, c_dp_pps_period, '1', dp_clk, dp_pps);
177
 
178
   ----------------------------------------------------------------------------
179
  -- Procedure that polls a sim control file that can be used to e.g. get
180
  -- the simulation time in ns
181
  ----------------------------------------------------------------------------
182
  mmf_poll_sim_ctrl_file(c_mmf_unb_file_path & "sim.ctrl", c_mmf_unb_file_path & "sim.stat");
183
 
184
  ----------------------------------------------------------------------------
185
  -- MM buses  
186
  ----------------------------------------------------------------------------
187
  u_mm_file_reg_diag_bg          : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "REG_DIAG_BG")
188
                                           PORT MAP(mm_rst, mm_clk, reg_diag_bg_mosi, reg_diag_bg_miso);
189
 
190
  u_mm_file_ram_diag_bg          : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "RAM_DIAG_BG")
191
                                           PORT MAP(mm_rst, mm_clk, ram_diag_bg_mosi, ram_diag_bg_miso);
192
 
193
  u_mm_file_ram_diag_data_buf_re : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "RAM_DIAG_DATA_BUFFER_REAL")
194
                                           PORT MAP(mm_rst, mm_clk, ram_diag_data_buf_re_mosi, ram_diag_data_buf_re_miso);
195
 
196
  u_mm_file_reg_diag_data_buf_re : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "REG_DIAG_DATA_BUFFER_REAL")
197
                                           PORT MAP(mm_rst, mm_clk, reg_diag_data_buf_re_mosi, reg_diag_data_buf_re_miso);
198
 
199
  u_mm_file_ram_diag_data_buf_im : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "RAM_DIAG_DATA_BUFFER_IMAG")
200
                                           PORT MAP(mm_rst, mm_clk, ram_diag_data_buf_im_mosi, ram_diag_data_buf_im_miso);
201
 
202
  u_mm_file_reg_diag_data_buf_im : mm_file GENERIC MAP(mmf_unb_file_prefix(0, 0, "BN") & "REG_DIAG_DATA_BUFFER_IMAG")
203
                                           PORT MAP(mm_rst, mm_clk, reg_diag_data_buf_im_mosi, reg_diag_data_buf_im_miso);
204
 
205
  ----------------------------------------------------------------------------
206
  -- Source: block generator
207
  ---------------------------------------------------------------------------- 
208 5 danv
  u_bg : ENTITY astron_diagnostics_lib.mms_diag_block_gen
209 2 danv
  GENERIC MAP(
210
    g_nof_streams        => c_nof_streams,
211
    g_buf_dat_w          => c_nof_complex*c_fft.in_dat_w,
212
    g_buf_addr_w         => c_bg_buf_adr_w,               -- Waveform buffer size 2**g_buf_addr_w nof samples
213
    g_file_index_arr     => c_bg_data_file_index_arr,
214
    g_file_name_prefix   => c_bg_data_file_prefix
215
  )
216
  PORT MAP(
217
    -- System
218
    mm_rst           => mm_rst,
219
    mm_clk           => mm_clk,
220
    dp_rst           => dp_rst,
221
    dp_clk           => dp_clk,
222
    en_sync          => dp_pps,
223
    -- MM interface
224
    reg_bg_ctrl_mosi => reg_diag_bg_mosi,
225
    reg_bg_ctrl_miso => reg_diag_bg_miso,
226
    ram_bg_data_mosi => ram_diag_bg_mosi,
227
    ram_bg_data_miso => ram_diag_bg_miso,
228
    -- ST interface
229
    out_siso_arr     => bg_siso_arr,
230
    out_sosi_arr     => bg_sosi_arr
231
  );
232
 
233 5 danv
  u_in_scope : ENTITY astron_sim_tools_lib.dp_wideband_wb_arr_scope
234 2 danv
  GENERIC MAP (
235
    g_sim                 => TRUE,
236
    g_wideband_factor     => c_fft.wb_factor,
237
    g_wideband_big_endian => FALSE,
238
    g_dat_w               => c_fft.in_dat_w
239
  )
240
  PORT MAP (
241
    SCLK         => SCLK,
242
    wb_sosi_arr  => bg_sosi_arr,
243
    scope_sosi   => scope_in_sosi
244
  );
245
 
246
  connect_input_data : FOR I IN 0 TO c_fft.wb_factor -1 GENERATE
247
    in_re_arr(I) <= RESIZE_SVEC(bg_sosi_arr(I).re(c_fft.in_dat_w-1 DOWNTO 0), in_re_arr(I)'LENGTH);
248
    in_im_arr(I) <= RESIZE_SVEC(bg_sosi_arr(I).im(c_fft.in_dat_w-1 DOWNTO 0), in_im_arr(I)'LENGTH);
249
  END GENERATE;
250
 
251
  in_val <= bg_sosi_arr(0).valid;
252
 
253
  -- DUT = Device Under Test  
254
  -- Based on the g_fft_type generic the appropriate 
255
  -- DUT is instantiated.  
256
  gen_wideband_fft : IF g_fft_type = "wide" GENERATE
257
    u_dut : ENTITY work.fft_r2_wide
258
    GENERIC MAP(
259
      g_fft          => c_fft     -- generics for the FFT
260
    )
261
    PORT MAP(
262
      clk        => dp_clk,
263
      rst        => dp_rst,
264
      in_re_arr  => in_re_arr,
265
      in_im_arr  => in_im_arr,
266
      in_val     => in_val,
267
      out_re_arr => out_re_arr,
268
      out_im_arr => out_im_arr,
269
      out_val    => out_val
270
    );
271
  END GENERATE;
272
 
273
  gen_pipelined_fft : IF g_fft_type = "pipe" GENERATE
274
    u_dut : ENTITY work.fft_r2_pipe
275
    GENERIC MAP(
276
      g_fft      => c_fft
277
    )
278
    port map(
279
      clk       => dp_clk,
280
      rst       => dp_rst,
281
      in_re     => in_re_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
282
      in_im     => in_im_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
283
      in_val    => in_val,
284
      out_re    => out_re_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
285
      out_im    => out_im_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
286
      out_val   => out_val
287
    );
288
  END GENERATE;
289
 
290
  gen_parallel_fft : IF g_fft_type = "par" GENERATE
291
    u_dut : ENTITY work.fft_r2_par
292
    GENERIC MAP(
293
      g_fft      => c_fft
294
    )
295
    PORT MAP(
296
      clk        => dp_clk,
297
      rst        => dp_rst,
298
      in_re_arr  => in_re_arr,
299
      in_im_arr  => in_im_arr,
300
      in_val     => in_val,
301
      out_re_arr => out_re_arr,
302
      out_im_arr => out_im_arr,
303
      out_val    => out_val
304
    );
305
  END GENERATE;
306
 
307
  connect_output_data : FOR I IN 0 TO c_fft.wb_factor -1 GENERATE
308
    out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(out_re_arr(I));
309
    out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(out_im_arr(I));
310
    out_sosi_arr(I).valid <= out_val;
311
  END GENERATE;
312
 
313 5 danv
  u_out_scope : ENTITY astron_sim_tools_lib.dp_wideband_wb_arr_scope
314 2 danv
  GENERIC MAP (
315
    g_sim                 => TRUE,
316
    g_wideband_factor     => c_fft.wb_factor,
317
    g_wideband_big_endian => FALSE,
318
    g_dat_w               => c_fft.out_dat_w
319
  )
320
  PORT MAP (
321
    SCLK         => SCLK,
322
    wb_sosi_arr  => out_sosi_arr,
323
    scope_sosi   => scope_out_sosi
324
  );
325
 
326
  ----------------------------------------------------------------------------
327
  -- Sink: data buffer real 
328
  ---------------------------------------------------------------------------- 
329 5 danv
  u_data_buf_re : ENTITY astron_diagnostics_lib.mms_diag_data_buffer
330 2 danv
  GENERIC MAP (
331
    g_nof_streams  => c_nof_streams,
332
    g_data_type    => e_real,
333
    g_data_w       => c_fft.out_dat_w,
334
    g_buf_nof_data => c_bg_block_len,
335
    g_buf_use_sync => FALSE
336
  )
337
  PORT MAP (
338
    -- System
339
    mm_rst            => mm_rst,
340
    mm_clk            => mm_clk,
341
    dp_rst            => dp_rst,
342
    dp_clk            => dp_clk,
343
 
344
    -- MM interface
345
    ram_data_buf_mosi => ram_diag_data_buf_re_mosi,
346
    ram_data_buf_miso => ram_diag_data_buf_re_miso,
347
 
348
    reg_data_buf_mosi => reg_diag_data_buf_re_mosi,
349
    reg_data_buf_miso => reg_diag_data_buf_re_miso,
350
 
351
    -- ST interface
352
    in_sync           => OPEN,
353
    in_sosi_arr       => out_sosi_arr
354
  );
355
 
356
  ----------------------------------------------------------------------------
357
  -- Sink: data buffer imag 
358
  ---------------------------------------------------------------------------- 
359 5 danv
  u_data_buf_im : ENTITY astron_diagnostics_lib.mms_diag_data_buffer
360 2 danv
  GENERIC MAP (
361
    g_nof_streams  => c_nof_streams,
362
    g_data_type    => e_imag,
363
    g_data_w       => c_fft.out_dat_w,
364
    g_buf_nof_data => c_bg_block_len,
365
    g_buf_use_sync => FALSE
366
  )
367
  PORT MAP (
368
    -- System
369
    mm_rst            => mm_rst,
370
    mm_clk            => mm_clk,
371
    dp_rst            => dp_rst,
372
    dp_clk            => dp_clk,
373
 
374
    -- MM interface
375
    ram_data_buf_mosi => ram_diag_data_buf_im_mosi,
376
    ram_data_buf_miso => ram_diag_data_buf_im_miso,
377
 
378
    reg_data_buf_mosi => reg_diag_data_buf_im_mosi,
379
    reg_data_buf_miso => reg_diag_data_buf_im_miso,
380
 
381
    -- ST interface
382
    in_sync           => OPEN,
383
    in_sosi_arr       => out_sosi_arr
384
  );
385
 
386
END tb;

powered by: WebSVN 2.1.0

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