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

Subversion Repositories astron_wpfb

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-- Author: Harm Jan Pepping : HJP at astron.nl: April 2012
2
--------------------------------------------------------------------------------
3
--
4
-- Copyright (C) 2012
5
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
6
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
7
--
8
-- This program is free software: you can redistribute it and/or modify
9
-- it under the terms of the GNU General Public License as published by
10
-- the Free Software Foundation, either version 3 of the License, or
11
-- (at your option) any later version.
12
--
13
-- This program is distributed in the hope that it will be useful,
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-- GNU General Public License for more details.
17
--
18
-- You should have received a copy of the GNU General Public License
19
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
--
21
--------------------------------------------------------------------------------
22
 
23
--
24
-- Purpose: Test bench for the Wideband Poly Phase Filter Bank
25
--
26
--
27
-- Usage:
28
--   > run -all
29
--   > testbench is selftesting. 
30
--
31
-- Remarks:
32
--         . The first c_nof_spectra_in_file(= 8) spectrums are verified.
33
--         . The statistics are verified, based on the raw output of the DUT. 
34
--         . Currently only the Noise file is tested.
35
--
36
--!!!NOTE!!! This testbench has become obsolete since the quantization of 
37
--           the FFT algorithm is changed. The testbench still works, but 
38
--           the goldenfiles are not valid anymore and therefor the test-
39
--           bench will report that the output contains errors. 
40
--           The tb_wpfb_unit testbench is replaced by the tb_mmf_wpfb_unit
41
--           testbench, which is a co-simulation between modelsim and python.  
42
--                 
43
--
44
 
45
library ieee, common_pkg_lib, dp_pkg_lib, astron_diagnostics_lib, astron_r2sdf_fft_lib, astron_wb_fft_lib, astron_filter_lib, astron_ram_lib, astron_mm_lib;
46
use IEEE.std_logic_1164.all;
47
use IEEE.numeric_std.all;
48
use IEEE.std_logic_textio.all;
49
use STD.textio.all;
50
use common_pkg_lib.common_pkg.all;
51
use astron_ram_lib.common_ram_pkg.ALL;
52
use common_pkg_lib.common_lfsr_sequences_pkg.all;
53
use common_pkg_lib.tb_common_pkg.all;
54
use astron_mm_lib.tb_common_mem_pkg.ALL;
55
use dp_pkg_lib.dp_stream_pkg.ALL;
56
use astron_r2sdf_fft_lib.twiddlesPkg.all;
57
use astron_r2sdf_fft_lib.rTwoSDFPkg.all;
58
use astron_wb_fft_lib.tb_fft_pkg.all;
59
use astron_wb_fft_lib.fft_pkg.all;
60
use astron_filter_lib.fil_pkg.all;
61
use work.wpfb_pkg.all;
62
 
63
entity tb_wpfb_unit is
64
  generic(
65
    -- generics for tb
66
    g_use_uniNoise_file  : boolean  := true;
67
    g_use_sinus_file     : boolean  := false;
68
    g_use_sinNoise_file  : boolean  := false;
69
    g_use_impulse_file   : boolean  := false;
70
 
71
    --  type t_wpfb is record  
72
    --  -- General parameters for the wideband poly phase filter
73
    --  wb_factor         : natural;        -- = default 4, wideband factor
74
    --  nof_points        : natural;        -- = 1024, N point FFT (Also the number of subbands for the filetr part)
75
    --  nof_chan          : natural;        -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan     
76
    --  nof_streams       : natural;        -- = 1, the number of parallel streams. The filter coefficients are shared on every stream. 
77
    --  
78
    --  -- Parameters for the poly phase filter
79
    --  nof_taps          : natural;        -- = 16, the number of FIR taps per subband
80
    --  fil_backoff_w     : natural;        -- = 0, number of bits for input backoff to avoid output overflow
81
    --  fil_in_dat_w      : natural;        -- = 8, number of input bits
82
    --  fil_out_dat_w     : natural;        -- = 16, number of output bits
83
    --  coef_dat_w        : natural;        -- = 16, data width of the FIR coefficients
84
    --                                    
85
    --  -- Parameters for the FFT         
86
    --  use_reorder       : boolean;        -- = false for bit-reversed output, true for normal output
87
    --  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
88
    --  use_separate      : boolean;        -- = false for complex input, true for two real inputs
89
    --  fft_in_dat_w      : natural;        -- = 16, number of input bits
90
    --  fft_out_dat_w     : natural;        -- = 13, number of output bits
91
    --  fft_out_gain_w    : natural;        -- = 0, output gain factor applied after the last stage output, before requantization to out_dat_w
92
    --  stage_dat_w       : natural;        -- = 18, number of bits that are used inter-stage
93
    --  guard_w           : natural;        -- = 2
94
    --  guard_enable      : boolean;        -- = true
95
    --
96
    --  -- Parameters for the statistics
97
    --  stat_data_w       : positive;       -- = 56
98
    --  stat_data_sz      : positive;       -- = 2
99
    --  nof_blk_per_sync  : natural;        -- = 800000, number of FFT output blocks per sync interval
100
    --
101
    --  -- Pipeline parameters for both poly phase filter and FFT. These are heritaged from the filter and fft libraries.  
102
    --  pft_pipeline      : t_fft_pipeline;     -- Pipeline settings for the pipelined FFT
103
    --  fft_pipeline      : t_fft_pipeline;     -- Pipeline settings for the parallel FFT
104
    --  fil_pipeline      : t_fil_ppf_pipeline; -- Pipeline settings for the filter units 
105
    --  
106
    --  end record;
107
 
108
    g_wpfb   : t_wpfb  := (4, 1024, 0, 1,
109
                           16, 0, 8, 16, 16,
110
                           true, false, true, 16, 16, 0, 18, 2, true, 56, 2, 10,
111
                           c_fft_pipeline, c_fft_pipeline, c_fil_ppf_pipeline);
112
 
113
    g_coefs_file_prefix : string            := "data/coefs_wide"
114
 
115
  );
116
 
117
end entity tb_wpfb_unit;
118
 
119
architecture tb of tb_wpfb_unit is
120
 
121
  constant c_clk_period : time    := 100 ns;
122
 
123
  constant c_fft        : t_fft   := (g_wpfb.use_reorder,
124
                                      g_wpfb.use_fft_shift,
125
                                      g_wpfb.use_separate,
126
                                      0,
127
                                      g_wpfb.wb_factor,
128
                                      0,
129
                                      g_wpfb.nof_points,
130
                                      g_wpfb.fft_in_dat_w,
131
                                      g_wpfb.fft_out_dat_w,
132
                                      g_wpfb.fft_out_gain_w,
133
                                      g_wpfb.stage_dat_w,
134
                                      g_wpfb.guard_w,
135
                                      g_wpfb.guard_enable,
136
                                      g_wpfb.stat_data_w,
137
                                      g_wpfb.stat_data_sz);
138
 
139
  -- input/output data width
140
  constant c_in_dat_w   : natural := g_wpfb.fil_in_dat_w;
141
  constant c_twiddle_w  : natural := 16;
142
  constant c_out_dat_w  : natural := g_wpfb.fft_out_dat_w; --   g_rtwo_fft.in_dat_w + natural((ceil_log2(g_rtwo_fft.nof_points))/2 + 2);  -- bit growth
143
 
144
  -- input/output files
145
  constant c_nof_spectra_in_file : natural := 8;
146
  constant c_file_len            : natural := c_nof_spectra_in_file*g_wpfb.nof_points;
147
  constant c_nof_spectra_to_output_file : natural := 8;
148
 
149
  -- block generator  
150
  constant c_bg_mem_size           : natural := g_wpfb.nof_points/g_wpfb.wb_factor;
151
  constant c_bg_addr_w             : natural := ceil_log2(c_bg_mem_size);
152
  constant c_nof_samples_in_packet : natural := c_bg_mem_size;
153
  constant c_gap                   : natural := 0;    -- Gapsize is set to 0 in order to generate a continuous stream of packets. 
154
  constant c_nof_accum_per_sync    : natural := g_wpfb.nof_blk_per_sync;
155
  constant c_bsn_init              : natural := 32;
156
  constant c_bg_prefix             : string  := "UNUSED";
157
  constant c_nof_sync_periods      : natural := 10;
158
  constant c_bst_skip_nof_sync     : natural := 3;
159
 
160
  constant c_nof_bands_per_chn     : natural := g_wpfb.nof_points/g_wpfb.wb_factor;
161
  constant c_normal                : boolean := true;
162
 
163
  -- input from uniform noise file created automatically by MATLAB testFFT_input.m
164
  constant c_noiseInputFile    : string := "data/uniNoise_in.txt";
165
  constant c_noiseGoldenFile   : string := "data/uniNoise_p" & natural'image(g_wpfb.nof_points)& "_t"& natural'image(g_wpfb.nof_taps) & "_gold.txt";
166
  constant c_noiseOutputFile   : string := "data/uniNoise_out.txt";
167
 
168
  constant c_inputFile  : string := c_noiseInputFile;
169
 
170
  constant c_goldenFile : string := c_noiseGoldenFile;
171
 
172
  constant c_outputFile : string := c_noiseOutputFile;
173
 
174
  constant c_coefs_file_prefix : string := g_coefs_file_prefix & natural'image(g_wpfb.wb_factor) & "_p"& natural'image(g_wpfb.nof_points) & "_t"& natural'image(g_wpfb.nof_taps);
175
 
176
  -- signal definitions
177
  signal tb_end         : std_logic := '0';
178
  signal clk            : std_logic := '0';
179
  signal rst            : std_logic := '0';
180
 
181
  signal out_sync       : std_logic:= '0';
182
  signal out_val        : std_logic:= '0';
183
  signal out_re_arr     : t_fft_slv_arr(g_wpfb.wb_factor-1 downto 0);
184
  signal out_im_arr     : t_fft_slv_arr(g_wpfb.wb_factor-1 downto 0);
185
 
186
  signal in_file_data   : t_integer_matrix(0 to c_file_len-1, 1 to 2) := (others=>(others=>0));  -- [re, im]
187
  signal in_file_sync   : std_logic_vector(0 to c_file_len-1):= (others=>'0');
188
  signal in_file_val    : std_logic_vector(0 to c_file_len-1):= (others=>'0');
189
 
190
  signal gold_file_data : t_integer_matrix(0 to c_file_len-1, 1 to 2) := (others=>(others=>0));  -- [re, im]
191
  signal gold_file_sync : std_logic_vector(0 to c_file_len-1):= (others=>'0');
192
  signal gold_file_val  : std_logic_vector(0 to c_file_len-1):= (others=>'0');
193
 
194
  signal gold_sync      : std_logic;
195
  signal gold_re_arr    : t_integer_arr(g_wpfb.wb_factor-1 downto 0);
196
  signal gold_im_arr    : t_integer_arr(g_wpfb.wb_factor-1 downto 0);
197
 
198
  signal init_waveforms_done   : std_logic;
199
 
200
  signal in_sosi_arr     : t_dp_sosi_arr(g_wpfb.wb_factor-1 downto 0);
201
  signal in_siso_arr     : t_dp_siso_arr(g_wpfb.wb_factor-1 downto 0);
202
 
203
  type   t_dp_sosi_matrix  is array (integer range <>) of t_dp_sosi_arr(0 downto 0);
204
  type   t_dp_siso_matrix  is array (integer range <>) of t_dp_siso_arr(0 downto 0);
205
 
206
  signal in_sosi_matrix  : t_dp_sosi_matrix(g_wpfb.wb_factor-1 downto 0);
207
  signal in_siso_matrix  : t_dp_siso_matrix(g_wpfb.wb_factor-1 downto 0);
208
 
209
  signal result_sosi_arr : t_dp_sosi_arr(g_wpfb.wb_factor-1 downto 0);
210
 
211
  signal ram_sst_mosi    : t_mem_mosi := c_mem_mosi_rst;
212
  signal ram_sst_miso    : t_mem_miso := c_mem_miso_rst;
213
 
214
  signal ram_coefs_mosi  : t_mem_mosi := c_mem_mosi_rst;
215
  signal ram_coefs_miso  : t_mem_miso := c_mem_miso_rst;
216
  signal coefs_arr       : t_integer_arr (c_nof_bands_per_chn-1 downto 0);
217
 
218
  signal ram_bg_data_mosi_arr : t_mem_mosi_arr(g_wpfb.wb_factor-1 downto 0) := (others => c_mem_mosi_rst );
219
  signal reg_bg_ctrl_mosi     : t_mem_mosi;
220
 
221
  signal reg_diag_bg_dut_mosi : t_mem_mosi := c_mem_mosi_rst;
222
  signal reg_diag_bg_dut_miso : t_mem_miso := c_mem_miso_rst;
223
 
224
  signal ram_diag_bg_dut_mosi : t_mem_mosi := c_mem_mosi_rst;
225
  signal ram_diag_bg_dut_miso : t_mem_miso := c_mem_miso_rst;
226
 
227
  -- Subband Statistics output
228
  -- . DUT result
229
  signal result_sst_arr_temp   : t_slv_64_arr(c_nof_samples_in_packet-1 downto 0);
230
  signal result_sst_arr        : t_slv_64_arr(g_wpfb.nof_points-1 downto 0);
231
  -- . Expected result
232
  signal expected_sst_arr      : t_slv_64_arr(g_wpfb.nof_points-1 downto 0) := (others => (others => '0'));
233
 
234
  signal coefs_mem_write : boolean := FALSE;
235
  signal temp_reg        : integer;
236
 
237
begin
238
 
239
  clk <= (not clk) or tb_end after c_clk_period/2;
240
  rst <= '1', '0' after c_clk_period*7;
241
 
242
  ---------------------------------------------------------------
243
  -- WRITE AND READ THE COEFFICIENTS TO THE COEFS MEMORY
244
  ---------------------------------------------------------------  
245
  p_coefs_memory_write : process
246
  begin
247
    coefs_mem_write <= FALSE;
248
    ram_coefs_mosi  <= c_mem_mosi_rst;             -- Reset the master out interface
249
    -- Write the coefficients
250
    for L in 0 to c_nof_complex loop               -- There are two filters in the DUT: real and imaginary
251
      for K in 0 to g_wpfb.wb_factor-1 loop
252
        for J in 0 to g_wpfb.nof_taps-1 loop
253
          proc_common_read_mif_file(c_coefs_file_prefix & "_" & integer'image(k*g_wpfb.nof_taps+J) & ".mif", coefs_arr);
254
          wait for 1 ns;
255
          for I in 0 to c_nof_bands_per_chn-1 loop
256
            proc_mem_mm_bus_wr(L*g_wpfb.nof_points*g_wpfb.nof_taps + K*c_nof_bands_per_chn*g_wpfb.nof_taps + J*c_nof_bands_per_chn + I, coefs_arr(I), clk, ram_coefs_mosi); -- Write the coefficient to the memory       
257
          end loop;
258
        end loop;
259
      end loop;
260
    end loop;
261
    -- Read the coefficients back and verify
262
    for L in 0 to c_nof_complex loop               -- There are two filters in the DUT: real and imaginary
263
      for K in 0 to g_wpfb.wb_factor-1 loop
264
        for J in 0 to g_wpfb.nof_taps-1 loop
265
          proc_common_read_mif_file(c_coefs_file_prefix & "_" & integer'image(k*g_wpfb.nof_taps+J) & ".mif", coefs_arr);
266
          wait for 1 ns;
267
          for I in 0 to c_nof_bands_per_chn-1 loop
268
            proc_mem_mm_bus_rd(L*g_wpfb.nof_points*g_wpfb.nof_taps + K*c_nof_bands_per_chn*g_wpfb.nof_taps + J*c_nof_bands_per_chn + I, clk, ram_coefs_miso, ram_coefs_mosi); -- Read the coefficient from the memory       
269
            temp_reg <= coefs_arr(I);
270
            if(ram_coefs_miso.rdval = '1') then
271
              assert temp_reg = TO_UINT(ram_coefs_miso.rddata(g_wpfb.coef_dat_w-1 downto 0))  report "Read data from memory error" severity error;
272
            end if;
273
          end loop;
274
          proc_common_wait_some_cycles(clk, 1);
275
        end loop;
276
      end loop;
277
    end loop;
278
 
279
    coefs_mem_write <= TRUE;
280
    wait;
281
  end process;
282
 
283
  ---------------------------------------------------------------
284
  -- READ STIMULI DATA FROM INPUT FILE
285
  ---------------------------------------------------------------  
286
  proc_read_input_file(clk, in_file_data, c_inputFile);
287
 
288
  ------------------------------------------------------------------------------
289
  -- WRITE THE WAVEFORMS INTO MEMORY FOR EACH INPUT STREAM.
290
  ------------------------------------------------------------------------------
291
  gen_init_waveforms : for I in 0 to g_wpfb.wb_factor-1 generate
292
    p_init_waveforms_memory : process
293
      variable v_mem_data : std_logic_vector(c_nof_complex*g_wpfb.fil_in_dat_w-1 downto 0);
294
    begin
295
      init_waveforms_done <= '0';
296
 
297
      proc_common_wait_until_low(clk, rst);      -- Wait until reset has finished
298
      proc_common_wait_some_cycles(clk, 10);     -- Wait an additional amount of cycles
299
 
300
      for J in 0 to c_bg_mem_size-1 loop
301
        v_mem_data := (others => '0');
302
        v_mem_data := TO_SVEC(in_file_data(I+J*g_wpfb.wb_factor, 2), g_wpfb.fil_in_dat_w) & TO_SVEC(in_file_data(I+J*g_wpfb.wb_factor, 1), g_wpfb.fil_in_dat_w);
303
        proc_mem_mm_bus_wr(J, v_mem_data, clk, ram_bg_data_mosi_arr(I));
304
      end loop;
305
 
306
      init_waveforms_done <= '1';
307
      wait;
308
    end process;
309
  end generate;
310
 
311
  ------------------------------------------------------------------------------
312
  -- CONFIGURE AND ENABLE THE BLOCK GENERATORS (Start Stimuli)
313
  ------------------------------------------------------------------------------
314
  p_control_input_stream : process
315
  begin
316
    reg_bg_ctrl_mosi <= c_mem_mosi_rst;
317
 
318
    -- Wait until reset is done
319
    proc_common_wait_until_high(clk, rst);
320
    proc_common_wait_some_cycles(clk, 10);
321
    wait until init_waveforms_done = '1';       -- Wait until the waveform data is written. 
322
    wait until coefs_mem_write     = TRUE;      -- Wait until the coefficients are written. 
323
 
324
    -- Set and enable the waveform generators. All generators are controlled by the same registers
325
    proc_mem_mm_bus_wr(1, c_nof_samples_in_packet, clk, reg_bg_ctrl_mosi);  -- Set the number of samples per block
326
    proc_mem_mm_bus_wr(2, c_nof_accum_per_sync,    clk, reg_bg_ctrl_mosi);  -- Set the number of blocks per sync
327
    proc_mem_mm_bus_wr(3, c_gap,                   clk, reg_bg_ctrl_mosi);  -- Set the gapsize
328
    proc_mem_mm_bus_wr(4, 0,                       clk, reg_bg_ctrl_mosi);  -- Set the start address of the memory
329
    proc_mem_mm_bus_wr(5, c_bg_mem_size-1,         clk, reg_bg_ctrl_mosi);  -- Set the end address of the memory
330
    proc_mem_mm_bus_wr(6, c_bsn_init,              clk, reg_bg_ctrl_mosi);  -- Set the BSNInit low  value
331
    proc_mem_mm_bus_wr(7, 0,                       clk, reg_bg_ctrl_mosi);  -- Set the BSNInit high value
332
    proc_mem_mm_bus_wr(0, 1,                       clk, reg_bg_ctrl_mosi);  -- Enable the BG
333
 
334
    -- Run time is defined by:
335
    --   * the number of sync periods
336
    --   * the number of packets in a sync period (c_nof_accum_per_sync)
337
    --   * the number of samples in a packet
338
    --   * the gap size
339
    proc_common_wait_some_cycles(clk, c_nof_sync_periods*c_nof_accum_per_sync*(c_nof_samples_in_packet+c_gap));
340
 
341
    -- Disable the BG
342
    proc_mem_mm_bus_wr(0, 0, clk, reg_bg_ctrl_mosi);
343
 
344
    -- Wait some additional time in order to let release the pipline stages of the FFT. 
345
    proc_common_wait_some_cycles(clk, 4*g_wpfb.nof_points);
346
    tb_end <= '1';
347
 
348
    wait;
349
  end process;
350
 
351
  ---------------------------------------------------------------  
352
  -- GENERATE BLOCK GENERATORS FOR STIMULI GENERATION
353
  ---------------------------------------------------------------  
354
  gen_block_gen : for I in 0 to g_wpfb.wb_factor-1 generate
355
    u_block_generator : entity astron_diagnostics_lib.mms_diag_block_gen
356
    generic map(
357
      g_nof_streams        => 1,
358
      g_buf_dat_w          => c_nof_complex*g_wpfb.fil_in_dat_w,
359
      g_buf_addr_w         => c_bg_addr_w,
360
      g_file_name_prefix   => c_bg_prefix
361
    )
362
    port map(
363
     -- Clocks and Reset
364
      mm_rst           => rst,
365
      mm_clk           => clk,
366
      dp_rst           => rst,
367
      dp_clk           => clk,
368
      en_sync          => '1',
369
      ram_bg_data_mosi => ram_bg_data_mosi_arr(I),
370
      ram_bg_data_miso => open,
371
      reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
372
      reg_bg_ctrl_miso => open,
373
      out_siso_arr     => in_siso_matrix(I),
374
      out_sosi_arr     => in_sosi_matrix(I)
375
    );
376
    in_sosi_arr(I)       <= in_sosi_matrix(I)(0);
377
    in_siso_matrix(I)(0) <= c_dp_siso_rdy;
378
  end generate;
379
 
380
  ------------------------------------------------------------------------------  
381
  -- READ THE BEAMLET STATISTICS AND VERIFY  
382
  ------------------------------------------------------------------------------
383
  -- Read statistics from the memory interface once every sync interval.
384
  p_read_sst_memory : process
385
    variable c_sync_cnt : natural;
386
  begin
387
    proc_common_wait_until_low(clk, rst);    -- Wait until reset has finished
388
 
389
    -- Skip reading for the initial syncs to save simulation time
390
    for J in 0 to c_bst_skip_nof_sync-2 loop
391
      wait until result_sosi_arr(0).sync = '1';
392
      wait until result_sosi_arr(0).sync = '0';
393
    end loop;
394
 
395
    while(true) loop
396
      wait until result_sosi_arr(0).sync = '1';
397
      proc_common_wait_some_cycles(clk, c_nof_samples_in_packet+6);
398
 
399
      for I in 0 to g_wpfb.wb_factor-1 loop
400
        proc_fft_read_subband_statistics_memory(I, c_fft, clk, ram_sst_mosi, ram_sst_miso, result_sst_arr_temp);
401
        result_sst_arr((I+1)*c_nof_samples_in_packet-1 downto I*c_nof_samples_in_packet) <= result_sst_arr_temp;  -- can not use result_bst_arr2(I) directly as argument in proc_bf_read_beamlet_statistics_memory()
402
      end loop;
403
 
404
      proc_common_wait_some_cycles(clk, 10);
405
 
406
      assert expected_sst_arr  = result_sst_arr   report "Output statistics error"  severity error;
407
      assert expected_sst_arr /= result_sst_arr   report "Output statistics OK!!!!" severity note;
408
 
409
    end loop;
410
  end process;
411
 
412
  ---------------------------------------------------------------  
413
  -- DUT = Device Under Test
414
  ---------------------------------------------------------------  
415
  u_dut : entity work.wpfb_unit
416
  generic map (
417
    g_wpfb              => g_wpfb,
418
    g_use_bg            => FALSE,
419
    g_coefs_file_prefix => c_coefs_file_prefix
420
  )
421
  port map (
422
    dp_rst             => rst,
423
    dp_clk             => clk,
424
    mm_rst             => rst,
425
    mm_clk             => clk,
426
    ram_fil_coefs_mosi => ram_coefs_mosi,
427
    ram_fil_coefs_miso => ram_coefs_miso,
428
    ram_st_sst_mosi    => ram_sst_mosi,
429
    ram_st_sst_miso    => ram_sst_miso,
430
    reg_bg_ctrl_mosi   => reg_diag_bg_dut_mosi,
431
    reg_bg_ctrl_miso   => reg_diag_bg_dut_miso,
432
    ram_bg_data_mosi   => ram_diag_bg_dut_mosi,
433
    ram_bg_data_miso   => ram_diag_bg_dut_miso,
434
    in_sosi_arr        => in_sosi_arr,
435
    out_sosi_arr       => result_sosi_arr
436
  );
437
 
438
  ---------------------------------------------------------------  
439
  -- REARRANGE THE OUTPUT-DATA FOR VERIFICATION
440
  ---------------------------------------------------------------  
441
  gen_extract_data : for I in 0 to g_wpfb.wb_factor-1 generate
442
    out_re_arr(I) <= RESIZE_SVEC(result_sosi_arr(I).re, out_re_arr(I)'length);
443
    out_im_arr(I) <= RESIZE_SVEC(result_sosi_arr(I).im, out_im_arr(I)'length);
444
  end generate;
445
  out_val <= result_sosi_arr(0).valid;
446
 
447
  ---------------------------------------------------------------  
448
  -- READ GOLDEN FILE WITH THE EXPECTED DUT OUTPUT
449
  ---------------------------------------------------------------  
450
  proc_read_input_file(clk, gold_file_data, c_goldenFile);
451
 
452
  ---------------------------------------------------------------  
453
  -- CALCULATE THE STATISTICS, BASED ON THE RAW OUTPUT DATA 
454
  -- OF THE DUT
455
  ---------------------------------------------------------------  
456
  p_calculate_stats_reference_array : process
457
    constant c_sst_in_w       : natural := 18;
458
    variable v_nof_outs       : natural := g_wpfb.nof_points/g_wpfb.wb_factor;
459
    variable v_int_time       : integer := 0;
460
    variable v_subband_cnt    : integer := 0;
461
 
462
    variable v_sum_re         : std_logic_vector(c_sst_in_w-1 downto 0);
463
    variable v_sum_im         : std_logic_vector(c_sst_in_w-1 downto 0);
464
 
465
    variable v_sum_pwr        : std_logic_vector(g_wpfb.stat_data_w-1 downto 0) := (others => '0');
466
    variable v_acc_pwr_arr    : t_slv_64_arr(g_wpfb.nof_points-1 downto 0) := (others => (others => '0'));
467
  begin
468
    wait until rising_edge(clk);
469
    if(out_val = '1') then
470
      for I in 0 to g_wpfb.wb_factor-1 loop
471
        -- Calculate the auto correlation power:
472
        v_sum_re := RESIZE_SVEC(SHIFT_SVEC(out_re_arr(I), g_wpfb.fft_out_dat_w-c_sst_in_w), v_sum_re'length);
473
        v_sum_im := RESIZE_SVEC(SHIFT_SVEC(out_im_arr(I), g_wpfb.fft_out_dat_w-c_sst_in_w), v_sum_im'length);
474
        v_sum_pwr(32 downto 0) := func_complex_multiply(v_sum_re, v_sum_im, v_sum_re, v_sum_im, c_normal, "RE", 33);
475
        v_acc_pwr_arr(I*v_nof_outs + v_subband_cnt) := ADD_UVEC(v_acc_pwr_arr(I*v_nof_outs + v_subband_cnt), v_sum_pwr);
476
      end loop;
477
 
478
      if(v_subband_cnt = v_nof_outs-1) then
479
        v_subband_cnt := 0;
480
      else
481
        v_subband_cnt := v_subband_cnt + 1;
482
      end if;
483
 
484
      ------------------------------------------------------------------------
485
      -- Latch the expected accumulated statistics to the output at the sync
486
      ------------------------------------------------------------------------
487
      if(v_int_time = c_nof_accum_per_sync*v_nof_outs-1) then
488
        v_int_time := 0;
489
        -- Output the expected BST array
490
        expected_sst_arr <= v_acc_pwr_arr;
491
        v_acc_pwr_arr    :=(others => (others => '0'));
492
      else
493
        v_int_time := v_int_time + 1;
494
      end if;
495
    end if;
496
 
497
  end process;
498
 
499
  ---------------------------------------------------------------  
500
  -- CREATE THE GOLDEN ARRAY FOR VERIFICATION
501
  ---------------------------------------------------------------  
502
  p_create_golden_array : process
503
    constant c_sst_in_w       : natural := 16;
504
    variable v_nof_outs       : natural := g_wpfb.nof_points/g_wpfb.wb_factor;
505
    variable v_bin_index      : natural := 0;
506
    variable v_spectrum_index : natural := 0;
507
    variable v_list_index     : natural := 0;
508
  begin
509
    wait until rising_edge(clk);
510
    if(out_val = '1') then
511
      if(v_spectrum_index = v_nof_outs - 1) then
512
        v_spectrum_index := 0;
513
        v_bin_index := v_bin_index + g_wpfb.nof_points - v_nof_outs;
514
      else
515
        v_spectrum_index := v_spectrum_index + 1;
516
      end if;
517
      v_bin_index := v_bin_index + 1;
518
 
519
      if(v_list_index = c_file_len/g_wpfb.wb_factor-1) then
520
        v_bin_index    := 0;
521
        v_list_index   := 0;
522
      else
523
        v_list_index := v_list_index + 1;
524
      end if;
525
 
526
    end if;
527
 
528
    for I in 0 to g_wpfb.wb_factor-1 loop
529
      gold_re_arr(I) <= gold_file_data(v_bin_index + I*v_nof_outs, 1);
530
      gold_im_arr(I) <= gold_file_data(v_bin_index + I*v_nof_outs, 2);
531
    end loop;
532
 
533
    gold_sync  <= gold_file_sync(v_bin_index);
534
 
535
  end process;
536
 
537
  -- Verify the output of the DUT with the expected output from the golden reference file
538
  p_verify_output : process(clk)
539
    variable v_output_cnt : integer := 0;
540
  begin
541
    -- Compare
542
    if rising_edge(clk) then
543
      if (out_val='1' and v_output_cnt < (c_nof_spectra_in_file*g_wpfb.nof_points/g_wpfb.wb_factor)) then
544
        -- only write when out_val='1', because then the file is independent of cycles with invalid out_dat
545
        -- only check the first c_nof_spectra_in_file spectrums. 
546
        assert out_sync = gold_sync report "Output sync error"  severity error;
547
        for I in 0 to g_wpfb.wb_factor-1 loop
548
          assert TO_SINT(out_re_arr(I)) = gold_re_arr(I)   report "Output real data error" severity error;
549
          assert TO_SINT(out_im_arr(I)) = gold_im_arr(I)   report "Output imag data error" severity error;
550
        end loop;
551
        v_output_cnt := v_output_cnt + 1;
552
      end if;
553
    end if;
554
  end process;
555
 
556
  -- Write to default output file, this allows using command line diff or graphical diff viewer to compare it with the golden result file
557
  p_write_output_file : process(clk)
558
    file     v_output        : text open WRITE_MODE is c_outputFile;
559
    variable v_line          : line;
560
    constant c_nof_bins      : natural := g_wpfb.nof_points/g_wpfb.wb_factor;
561
    variable v_out_re_matrix : t_integer_matrix(g_wpfb.wb_factor-1 downto 0, c_nof_bins-1 downto 0);
562
    variable v_out_im_matrix : t_integer_matrix(g_wpfb.wb_factor-1 downto 0, c_nof_bins-1 downto 0);
563
    variable v_bin_cnt       : integer := 0;
564
    variable v_spectra_cnt   : integer := 0;
565
  begin
566
    if rising_edge(clk) then
567
      if out_val='1' then
568
        -- only write when out_val='1', because then the file is independent of cycles with invalid out_dat
569
        for I in 0 to g_wpfb.wb_factor-1 loop
570
          v_out_re_matrix(I, v_bin_cnt) := TO_SINT(out_re_arr(I));
571
          v_out_im_matrix(I, v_bin_cnt) := TO_SINT(out_im_arr(I));
572
        end loop;
573
 
574
        if(v_bin_cnt = c_nof_bins-1) then
575
          if (v_spectra_cnt < c_nof_spectra_to_output_file) then
576
            for K in 0 to g_wpfb.wb_factor-1 loop
577
              for L in 0 to c_nof_bins-1 loop
578
                write(v_line, v_out_re_matrix(K,L));
579
                write(v_line, string'(","));
580
                write(v_line, v_out_im_matrix(K,L));
581
                writeline(v_output, v_line);
582
              end loop;
583
            end loop;
584
          end if;
585
          v_spectra_cnt := v_spectra_cnt + 1;
586
          v_bin_cnt     := 0;
587
        else
588
          v_bin_cnt := v_bin_cnt + 1;
589
        end if;
590
      end if;
591
    end if;
592
  end process;
593
 
594
end tb;

powered by: WebSVN 2.1.0

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