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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [tb_fft_wide_unit.vhd] - Blame information for rev 2

Go to most recent revision | 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 Complex radix 2 FFT
25
--
26
--
27
-- Usage:
28
--   > run -all
29
--   > testbench is selftesting. The first four spectrums are verified. 
30
--
31
 
32
library ieee, common_pkg_lib, dp_pkg_lib, diag_lib, rTwoSDF_lib, common_ram_lib, mm_lib;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
use IEEE.std_logic_textio.all;
36
use STD.textio.all;
37
use common_pkg_lib.common_pkg.all;
38
use common_ram_lib.common_ram_pkg.ALL;
39
use common_pkg_lib.common_lfsr_sequences_pkg.all;
40
use common_pkg_lib.tb_common_pkg.all;
41
use mm_lib.tb_common_mem_pkg.ALL;
42
use dp_pkg_lib.dp_stream_pkg.ALL;
43
use rTwoSDF_lib.twiddlesPkg.all;
44
use rTwoSDF_lib.rTwoSDFPkg.all;
45
use work.tb_fft_pkg.all;
46
use work.fft_pkg.all;
47
 
48
entity tb_fft_wide_unit is
49
  generic(
50
    -- generics for tb
51
    g_use_uniNoise_file  : boolean  := true;
52
    g_use_sinus_file     : boolean  := false;
53
    g_use_sinNoise_file  : boolean  := false;
54
    g_use_impulse_file   : boolean  := false;
55
    g_use_2xreal_inputs  : boolean  := false;  -- Set to true for running the two-real input variants  
56
    g_fft : t_fft := (true, false, false, 0, 4, 0, 1024, 16, 18, 0, 18, 2, true, 56, 2)
57
    --  type t_rtwo_fft is record
58
    --    use_reorder    : boolean;  -- = false for bit-reversed output, true for normal output
59
    --    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
60
    --    use_separate   : boolean;  -- = false for complex input, true for two real inputs
61
    --    nof_chan       : natural;  -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan         
62
    --    wb_factor      : natural;  -- = default 1, wideband factor
63
    --    twiddle_offset : natural;  -- = default 0, twiddle offset for PFT sections in a wideband FFT
64
    --    nof_points     : natural;  -- = 1024, N point FFT
65
    --    in_dat_w       : natural;  -- = 8, number of input bits
66
    --    out_dat_w      : natural;  -- = 13, number of output bits: in_dat_w + natural((ceil_log2(nof_points))/2 + 2)  
67
    --    out_gain_w     : natural;  -- = 0, output gain factor applied after the last stage output, before requantization to out_dat_w
68
    --    stage_dat_w    : natural;  -- = 18, data width used between the stages(= DSP multiplier-width)
69
    --    guard_w        : natural;  -- = 2,  Guard used to avoid overflow in FFT stage. 
70
    --    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)
71
    --    stat_data_w    : positive; -- = 56
72
    --    stat_data_sz   : positive; -- = 2
73
    --  end record;
74
  );
75
end entity tb_fft_wide_unit;
76
 
77
architecture tb of tb_fft_wide_unit is
78
 
79
  constant c_clk_period : time    := 100 ns;
80
 
81
  -- input/output data width
82
  constant c_in_dat_w   : natural := g_fft.in_dat_w;
83
  constant c_twiddle_w  : natural := 16;
84
  constant c_out_dat_w  : natural := g_fft.out_dat_w; --   g_rtwo_fft.in_dat_w + natural((ceil_log2(g_rtwo_fft.nof_points))/2 + 2);  -- bit growth
85
 
86
  -- input/output files
87
  constant c_nof_spectra_in_file : natural := 4;
88
  constant c_file_len            : natural := c_nof_spectra_in_file*g_fft.nof_points;
89
 
90
  -- block generator  
91
  constant c_bg_mem_size           : natural := c_nof_spectra_in_file*g_fft.nof_points/g_fft.wb_factor;
92
  constant c_bg_addr_w             : natural := ceil_log2(c_bg_mem_size);
93
  constant c_nof_samples_in_packet : natural := c_bg_mem_size/c_nof_spectra_in_file;
94
  constant c_gap                   : natural := 3;    -- Gapsize is set to 0 in order to generate a continuous stream of packets. 
95
  constant c_nof_accum_per_sync    : natural := 8;
96
  constant c_bsn_init              : natural := 32;
97
  constant c_bg_prefix             : string  := "UNUSED";
98
  constant c_nof_sync_periods      : natural := 6;
99
  constant c_bst_skip_nof_sync     : natural := 3;
100
 
101
  constant c_normal                : BOOLEAN  := TRUE;
102
 
103
      -- input from uniform noise file created automatically by MATLAB testFFT_input.m
104
  constant c_noiseInputFile    : string := "data/test/in/uniNoise_p"  & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w) &"_in.txt";
105
  constant c_noiseGoldenFile   : string := "data/test/out/uniNoise_p" & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
106
  constant c_noiseOutputFile   : string := "data/test/out/uniNoise_out.txt";
107
 
108
  -- input from sinus file. Data is from diag_wg_wideband. 
109
  constant c_sinusInputFile    : string := "data/test/in/sinus_p"     & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_in.txt";
110
  constant c_sinusGoldenFile   : string := "data/test/out/sinus_p"    & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
111
  constant c_sinusOutputFile   : string := "data/test/out/sinus_out.txt";
112
 
113
  -- input from combined sinus with noise file. Real part is sinus, imaginary part is noise
114
  constant c_sinNoiseInputFile    : string := "data/test/in/sinNoise_p"     & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_in.txt";
115
  constant c_sinNoiseGoldenFile   : string := "data/test/out/sinNoise_p"    & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
116
  constant c_sinNoiseOutputFile   : string := "data/test/out/sinNoise_out.txt";
117
 
118
  -- input from impulse files
119
  constant c_impulseInputFile  : string := "data/impulse_p"           & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w)& "_in.txt";
120
  constant c_impulseGoldenFile : string := "data/impulse_p"           & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w)& "_out.txt";
121
  constant c_impulseOutputFile : string := "data/impulse_out.txt";
122
 
123
  -- input from 2xreal impulse files
124
  constant c_2xrealImpulseInputFile   : string := "data/2xreal_impulse_p"    & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w)& "_in.txt";
125
  constant c_2xrealImpulseGoldenFile  : string := "data/2xreal_impulse_p"    & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w)& "_out.txt";
126
  constant c_2xrealImpulseOutputFile  : string := "data/2xreal_impulse_out.txt";
127
 
128
  constant c_2xrealNoiseGoldenFile    : string := "data/test/out/uniNoise_2xreal_p" & natural'image(g_fft.nof_points)& "_b"& natural'image(c_twiddle_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
129
  constant c_2xrealSinusGoldenFile    : string := "data/test/out/sinus_2xreal_p"    & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
130
  constant c_2xrealSinNoiseGoldenFile : string := "data/test/out/sinNoise_2xreal_p" & natural'image(g_fft.nof_points)& "_b"& natural'image(g_fft.in_dat_w) &"_tb"&natural'image(wTyp'length) &"_out.txt";
131
 
132
  -- determine active stimuli and result files
133
  constant c_preSelImpulseInputFile   : string := sel_a_b(g_use_2xreal_inputs, c_2xrealImpulseInputFile,   c_impulseInputFile);
134
  constant c_preSelImpulseGoldenFile  : string := sel_a_b(g_use_2xreal_inputs, c_2xrealImpulseGoldenFile,  c_impulseGoldenFile);
135
  constant c_preSelImpulseOutputFile  : string := sel_a_b(g_use_2xreal_inputs, c_2xrealImpulseOutputFile,  c_impulseOutputFile);
136
  constant c_preSelNoiseGoldenFile    : string := sel_a_b(g_use_2xreal_inputs, c_2xrealNoiseGoldenFile,    c_noiseGoldenFile);
137
  constant c_preSelSinusGoldenFile    : string := sel_a_b(g_use_2xreal_inputs, c_2xrealSinusGoldenFile,    c_sinusGoldenFile);
138
  constant c_preSelSinNoiseGoldenFile : string := sel_a_b(g_use_2xreal_inputs, c_2xrealSinNoiseGoldenFile, c_sinNoiseGoldenFile);
139
 
140
  constant c_inputFile  : string := sel_a_b(g_use_uniNoise_file, c_noiseInputFile,
141
                                    sel_a_b(g_use_sinus_file,    c_sinusInputFile,
142
                                    sel_a_b(g_use_sinNoise_file, c_sinNoiseInputFile,        c_preSelImpulseInputFile)));
143
 
144
  constant c_goldenFile : string := sel_a_b(g_use_uniNoise_file, c_preSelNoiseGoldenFile,
145
                                    sel_a_b(g_use_sinus_file,    c_preSelSinusGoldenFile,
146
                                    sel_a_b(g_use_sinNoise_file, c_preSelSinNoiseGoldenFile, c_preSelImpulseGoldenFile)));
147
 
148
  constant c_outputFile : string := sel_a_b(g_use_uniNoise_file, c_noiseOutputFile,
149
                                    sel_a_b(g_use_sinus_file,    c_sinusOutputFile,
150
                                    sel_a_b(g_use_sinNoise_file, c_sinNoiseOutputFile,       c_preSelImpulseOutputFile)));
151
 
152
  -- signal definitions
153
  signal tb_end         : std_logic := '0';
154
  signal clk            : std_logic := '0';
155
  signal rst            : std_logic := '0';
156
 
157
  signal out_sync       : std_logic:= '0';
158
  signal out_val        : std_logic:= '0';
159
  signal out_re_arr     : t_fft_slv_arr(g_fft.wb_factor-1 downto 0);
160
  signal out_im_arr     : t_fft_slv_arr(g_fft.wb_factor-1 downto 0);
161
 
162
  signal in_file_data   : t_integer_matrix(0 to c_file_len-1, 1 to 2) := (others=>(others=>0));  -- [re, im]
163
  signal in_file_sync   : std_logic_vector(0 to c_file_len-1):= (others=>'0');
164
  signal in_file_val    : std_logic_vector(0 to c_file_len-1):= (others=>'0');
165
 
166
  signal gold_file_data : t_integer_matrix(0 to c_file_len-1, 1 to 2) := (others=>(others=>0));  -- [re, im]
167
  signal gold_file_sync : std_logic_vector(0 to c_file_len-1):= (others=>'0');
168
  signal gold_file_val  : std_logic_vector(0 to c_file_len-1):= (others=>'0');
169
 
170
  signal gold_sync      : std_logic;
171
  signal gold_re_arr    : t_integer_arr(g_fft.wb_factor-1 downto 0);
172
  signal gold_im_arr    : t_integer_arr(g_fft.wb_factor-1 downto 0);
173
 
174
  signal init_waveforms_done   : std_logic;
175
 
176
  signal in_sosi_arr     : t_dp_sosi_arr(g_fft.wb_factor-1 downto 0);
177
  signal in_siso_arr     : t_dp_siso_arr(g_fft.wb_factor-1 downto 0);
178
 
179
  type   t_dp_sosi_matrix  is array (integer range <>) of t_dp_sosi_arr(0 downto 0);
180
  type   t_dp_siso_matrix  is array (integer range <>) of t_dp_siso_arr(0 downto 0);
181
 
182
  signal in_sosi_matrix  : t_dp_sosi_matrix(g_fft.wb_factor-1 downto 0);
183
  signal in_siso_matrix  : t_dp_siso_matrix(g_fft.wb_factor-1 downto 0);
184
 
185
  signal result_sosi_arr : t_dp_sosi_arr(g_fft.wb_factor-1 downto 0);
186
 
187
  signal ram_sst_mosi    : t_mem_mosi := c_mem_mosi_rst;
188
  signal ram_sst_miso    : t_mem_miso := c_mem_miso_rst;
189
 
190
  signal ram_bg_data_mosi_arr : t_mem_mosi_arr(g_fft.wb_factor-1 downto 0) := (others => c_mem_mosi_rst );
191
  signal reg_bg_ctrl_mosi : t_mem_mosi;
192
 
193
  -- Subband Statistics output
194
  -- . DUT result
195
  signal result_sst_arr_temp   : t_slv_64_arr(c_nof_samples_in_packet-1 downto 0);
196
  signal result_sst_arr        : t_slv_64_arr(g_fft.nof_points-1 downto 0);
197
  -- . Expected result
198
  signal expected_sst_arr      : t_slv_64_arr(g_fft.nof_points-1 downto 0) := (others => (others => '0'));
199
 
200
begin
201
 
202
  clk <= (not clk) or tb_end after c_clk_period/2;
203
  rst <= '1', '0' after c_clk_period*7;
204
 
205
  ---------------------------------------------------------------
206
  -- READ STIMULI DATA FROM INPUT FILE
207
  ---------------------------------------------------------------  
208
  proc_read_input_file(clk, in_file_data, in_file_sync, in_file_val, c_inputFile);
209
 
210
  ------------------------------------------------------------------------------
211
  -- WRITE THE WAVEFORMS INTO MEMORY FOR EACH INPUT STREAM.
212
  ------------------------------------------------------------------------------
213
  gen_init_waveforms : for I in 0 to g_fft.wb_factor-1 generate
214
    p_init_waveforms_memory : process
215
      variable v_mem_data : std_logic_vector(c_nof_complex*g_fft.in_dat_w-1 downto 0);
216
    begin
217
      init_waveforms_done <= '0';
218
 
219
      proc_common_wait_until_low(clk, rst);      -- Wait until reset has finished
220
      proc_common_wait_some_cycles(clk, 10);     -- Wait an additional amount of cycles
221
 
222
      for J in 0 to c_bg_mem_size-1 loop
223
        v_mem_data := (others => '0');
224
        v_mem_data := TO_SVEC(in_file_data(I+J*g_fft.wb_factor, 2), g_fft.in_dat_w) & TO_SVEC(in_file_data(I+J*g_fft.wb_factor, 1), g_fft.in_dat_w);  -- two k_bf.in_dat_w = 16 fits in c_word_w = 32 bit
225
        proc_mem_mm_bus_wr(J, v_mem_data, clk, ram_bg_data_mosi_arr(I));
226
      end loop;
227
 
228
      init_waveforms_done <= '1';
229
      wait;
230
    end process;
231
  end generate;
232
 
233
  ------------------------------------------------------------------------------
234
  -- CONFIGURE AND ENABLE THE BLOCK GENERATORS (Start Stimuli)
235
  ------------------------------------------------------------------------------
236
  p_control_input_stream : process
237
  begin
238
    reg_bg_ctrl_mosi <= c_mem_mosi_rst;
239
 
240
    -- Wait until reset is done
241
    proc_common_wait_until_high(clk, rst);
242
    proc_common_wait_some_cycles(clk, 10);
243
    wait until init_waveforms_done = '1';       -- Wait until the waveform data is written. 
244
 
245
    -- Set and enable the waveform generators. All generators are controlled by the same registers
246
    proc_mem_mm_bus_wr(1, c_nof_samples_in_packet, clk, reg_bg_ctrl_mosi);  -- Set the number of samples per block
247
    proc_mem_mm_bus_wr(2, c_nof_accum_per_sync,    clk, reg_bg_ctrl_mosi);  -- Set the number of blocks per sync
248
    proc_mem_mm_bus_wr(3, c_gap,                   clk, reg_bg_ctrl_mosi);  -- Set the gapsize
249
    proc_mem_mm_bus_wr(4, 0,                       clk, reg_bg_ctrl_mosi);  -- Set the start address of the memory
250
    proc_mem_mm_bus_wr(5, c_bg_mem_size-1,         clk, reg_bg_ctrl_mosi);  -- Set the end address of the memory
251
    proc_mem_mm_bus_wr(6, c_bsn_init,              clk, reg_bg_ctrl_mosi);  -- Set the BSNInit low  value
252
    proc_mem_mm_bus_wr(7, 0,                       clk, reg_bg_ctrl_mosi);  -- Set the BSNInit high value
253
    proc_mem_mm_bus_wr(0, 1,                       clk, reg_bg_ctrl_mosi);  -- Enable the BG
254
 
255
    -- Run time is defined by:
256
    --   * the number of sync periods
257
    --   * the number of packets in a sync period (c_nof_accum_per_sync)
258
    --   * the number of samples in a packet
259
    --   * the gap size
260
    proc_common_wait_some_cycles(clk, c_nof_sync_periods*c_nof_accum_per_sync*(c_nof_samples_in_packet+c_gap));
261
 
262
    -- Disable the BG
263
    proc_mem_mm_bus_wr(0, 0, clk, reg_bg_ctrl_mosi);
264
 
265
    -- Wait some additional time in order to let release the pipline stages of the FFT. 
266
    proc_common_wait_some_cycles(clk, 4*g_fft.nof_points);
267
    tb_end <= '1';
268
 
269
    wait;
270
  end process;
271
 
272
  ---------------------------------------------------------------  
273
  -- GENERATE BLOCK GENERATORS FOR STIMULI GENERATION
274
  ---------------------------------------------------------------  
275
  gen_block_gen : for I in 0 to g_fft.wb_factor-1 generate
276
    u_block_generator : entity diag_lib.mms_diag_block_gen
277
    generic map(
278
      g_nof_streams        => 1,
279
      g_buf_dat_w          => c_nof_complex*g_fft.in_dat_w,
280
      g_buf_addr_w         => c_bg_addr_w,
281
      g_file_name_prefix   => c_bg_prefix
282
    )
283
    port map(
284
     -- Clocks and Reset
285
      mm_rst           => rst,
286
      mm_clk           => clk,
287
      dp_rst           => rst,
288
      dp_clk           => clk,
289
      en_sync          => '1',
290
      ram_bg_data_mosi => ram_bg_data_mosi_arr(I),
291
      ram_bg_data_miso => open,
292
      reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
293
      reg_bg_ctrl_miso => open,
294
      out_siso_arr     => in_siso_matrix(I),
295
      out_sosi_arr     => in_sosi_matrix(I)
296
    );
297
    in_sosi_arr(I)       <= in_sosi_matrix(I)(0);
298
    in_siso_matrix(I)(0) <= c_dp_siso_rdy;
299
  end generate;
300
 
301
  ------------------------------------------------------------------------------  
302
  -- READ THE BEAMLET STATISTICS     
303
  ------------------------------------------------------------------------------
304
  -- Read statistics from the memory interface once every sync interval.
305
  p_read_sst_memory : process
306
    variable c_sync_cnt : natural;
307
  begin
308
    proc_common_wait_until_low(clk, rst);    -- Wait until reset has finished
309
 
310
    -- Skip reading for the initial syncs to save simulation time
311
    for J in 0 to c_bst_skip_nof_sync-2 loop
312
      wait until result_sosi_arr(0).sync = '1';
313
      wait until result_sosi_arr(0).sync = '0';
314
    end loop;
315
 
316
    while(true) loop
317
      wait until result_sosi_arr(0).sync = '1';
318
      proc_common_wait_some_cycles(clk, c_nof_samples_in_packet+10);
319
 
320
      for I in 0 to g_fft.wb_factor-1 loop
321
        proc_fft_read_subband_statistics_memory(I, g_fft, clk, ram_sst_mosi, ram_sst_miso, result_sst_arr_temp);
322
        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()
323
      end loop;
324
    end loop;
325
  end process;
326
 
327
  ---------------------------------------------------------------  
328
  -- DUT = Device Under Test
329
  ---------------------------------------------------------------  
330
  u_dut : entity work.fft_wide_unit
331
  generic map (
332
    g_fft          => g_fft
333
  )
334
  port map (
335
    dp_rst          => rst,
336
    dp_clk          => clk,
337
    mm_rst          => rst,
338
    mm_clk          => clk,
339
    ram_st_sst_mosi => ram_sst_mosi,
340
    ram_st_sst_miso => ram_sst_miso,
341
    in_sosi_arr     => in_sosi_arr,
342
    out_sosi_arr    => result_sosi_arr
343
  );
344
  ---------------------------------------------------------------  
345
  -- REARRANGE THE OUTPUT-DATA FOR VERIFICATION
346
  ---------------------------------------------------------------  
347
  gen_extract_data : for I in 0 to g_fft.wb_factor-1 generate
348
    out_re_arr(I) <= RESIZE_SVEC(result_sosi_arr(I).re, out_re_arr(I)'length);
349
    out_im_arr(I) <= RESIZE_SVEC(result_sosi_arr(I).im, out_im_arr(I)'length);
350
  end generate;
351
  out_val <= result_sosi_arr(0).valid;
352
 
353
  ---------------------------------------------------------------  
354
  -- READ GOLDEN FILE WITH THE EXPECTED DUT OUTPUT
355
  ---------------------------------------------------------------  
356
  proc_read_input_file(clk, gold_file_data, gold_file_sync, gold_file_val, c_goldenFile);
357
 
358
  ---------------------------------------------------------------  
359
  -- CREATE THE GOLDEN ARRAY FOR VERIFICATION
360
  ---------------------------------------------------------------  
361
  p_create_golden_array : process
362
    constant c_sst_in_w       : natural := 16;
363
    variable v_nof_outs       : natural := g_fft.nof_points/g_fft.wb_factor;
364
    variable v_bin_index      : natural := 0;
365
    variable v_spectrum_index : natural := 0;
366
    variable v_list_index     : natural := 0;
367
    variable v_int_time       : integer := 0;
368
    variable v_subband_cnt    : integer := 0;
369
 
370
    variable v_sum_re         : std_logic_vector(c_sst_in_w-1 downto 0);
371
    variable v_sum_im         : std_logic_vector(c_sst_in_w-1 downto 0);
372
 
373
    variable v_sum_pwr        : std_logic_vector(g_fft.stat_data_w-1 downto 0) := (others => '0');
374
    variable v_acc_pwr_arr    : t_slv_64_arr(g_fft.nof_points-1 downto 0) := (others => (others => '0'));
375
  begin
376
    wait until rising_edge(clk);
377
    if(out_val = '1') then
378
      if(v_spectrum_index = v_nof_outs - 1) then
379
        v_spectrum_index := 0;
380
        v_bin_index := v_bin_index + g_fft.nof_points - v_nof_outs;
381
      else
382
        v_spectrum_index := v_spectrum_index + 1;
383
      end if;
384
      v_bin_index := v_bin_index + 1;
385
 
386
      if(v_list_index = c_file_len/g_fft.wb_factor-1) then
387
        v_bin_index    := 0;
388
        v_list_index   := 0;
389
      else
390
        v_list_index := v_list_index + 1;
391
      end if;
392
 
393
      for I in 0 to g_fft.wb_factor-1 loop
394
        -- Calculate the auto correlation power:
395
        v_sum_re := RESIZE_SVEC(TO_SVEC(gold_re_arr(I), c_word_w), v_sum_re'length);
396
        v_sum_im := RESIZE_SVEC(TO_SVEC(gold_im_arr(I), c_word_w), v_sum_im'length);
397
        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);
398
        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);
399
      end loop;
400
 
401
      if(v_subband_cnt = v_nof_outs-1) then
402
        v_subband_cnt := 0;
403
      else
404
        v_subband_cnt := v_subband_cnt + 1;
405
      end if;
406
 
407
      ------------------------------------------------------------------------
408
      -- Latch the expected accumulated statistics to the output at the sync
409
      ------------------------------------------------------------------------
410
      if(v_int_time = c_nof_accum_per_sync*v_nof_outs-1) then
411
        v_int_time := 0;
412
        -- Output the expected BST array
413
        expected_sst_arr <= v_acc_pwr_arr;
414
        v_acc_pwr_arr    :=(others => (others => '0'));
415
        assert expected_sst_arr = result_sst_arr   report "Output statistics error" severity error;
416
        assert expected_sst_arr /= result_sst_arr   report "Output statistics OK!!!!" severity note;
417
      else
418
        v_int_time := v_int_time + 1;
419
      end if;
420
    end if;
421
 
422
    for I in 0 to g_fft.wb_factor-1 loop
423
      gold_re_arr(I) <= gold_file_data(v_bin_index + I*v_nof_outs, 1);
424
      gold_im_arr(I) <= gold_file_data(v_bin_index + I*v_nof_outs, 2);
425
    end loop;
426
 
427
    gold_sync  <= gold_file_sync(v_bin_index);
428
 
429
  end process;
430
 
431
  -- Verify the output of the DUT with the expected output from the golden reference file
432
  p_verify_output : process(clk)
433
  begin
434
    -- Compare
435
    if rising_edge(clk) then
436
      if out_val='1' then
437
        -- only write when out_val='1', because then the file is independent of cycles with invalid out_dat
438
        assert out_sync = gold_sync report "Output sync error"  severity error;
439
        for I in 0 to g_fft.wb_factor-1 loop
440
          assert TO_SINT(out_re_arr(I)) = gold_re_arr(I)   report "Output real data error" severity error;
441
          assert TO_SINT(out_im_arr(I)) = gold_im_arr(I)   report "Output imag data error" severity error;
442
        end loop;
443
      end if;
444
    end if;
445
  end process;
446
 
447
end tb;

powered by: WebSVN 2.1.0

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