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

Subversion Repositories astron_wb_fft

[/] [astron_wb_fft/] [trunk/] [tb_fft_r2_bf_par.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: Test bench for fft_r2_bf_par
22
-- Features:
23
--
24
-- Usage:
25
-- > as 10
26
-- > run -all
27
-- Testbench is selftesting. 
28
 
29 5 danv
library IEEE, common_pkg_lib, dp_pkg_lib, astron_diagnostics_lib, astron_r2sdf_fft_lib, astron_ram_lib, astron_mm_lib, common_components_lib;
30 2 danv
use IEEE.std_logic_1164.ALL;
31
use IEEE.numeric_std.ALL;
32
use common_pkg_lib.common_pkg.ALL;
33 5 danv
use astron_ram_lib.common_ram_pkg.ALL;
34 2 danv
use common_pkg_lib.common_lfsr_sequences_pkg.ALL;
35
use common_pkg_lib.tb_common_pkg.ALL;
36 5 danv
use astron_mm_lib.tb_common_mem_pkg.ALL;
37 2 danv
use dp_pkg_lib.dp_stream_pkg.ALL;
38 5 danv
use astron_diagnostics_lib.diag_pkg.ALL;
39
use astron_r2sdf_fft_lib.twiddlesPkg.all;
40
use astron_r2sdf_fft_lib.rTwoSDFPkg.all;
41 2 danv
 
42
entity tb_fft_r2_bf_par is
43
  generic(
44
    g_stage       : natural := 4;
45
    g_element     : natural := 2
46
  );
47
end tb_fft_r2_bf_par;
48
 
49
architecture tb of tb_fft_r2_bf_par is
50
 
51 5 danv
  constant c_pipeline              : t_fft_pipeline := c_fft_pipeline;  -- defined in astron_r2sdf_fft_lib.rTwoSDFPkg
52 2 danv
 
53
  constant c_clk_period            : time    := 10 ns;
54
  constant c_nof_points            : natural := 1024;   -- Number of points should be a power of 2
55
  constant c_conjugate             : boolean := FALSE;
56
 
57
  constant c_in_dat_w              : natural := 16;
58
  constant c_weight_w              : natural := 16;
59
  constant c_prod_w                : natural := c_in_dat_w+c_weight_w;
60
  constant c_complex_prod_w        : natural := c_prod_w+1;
61
  constant c_bit_growth            : natural := 1;
62
  constant c_round_w               : natural := c_weight_w-c_bit_growth;   -- the weights are normalized
63
 
64
  -- BG derived constants
65
  constant c_nof_streams           : natural := 2;
66
  constant c_bg_mem_size           : natural := 1024;
67
  constant c_bg_addr_w             : natural := ceil_log2(c_bg_mem_size);
68
  constant c_nof_samples_in_packet : natural := c_nof_points;
69
  constant c_gap                   : natural := 0;    -- Gapsize is set to 0 in order to generate a continuous stream of packets. 
70
  constant c_bst_skip_nof_sync     : natural := 3;
71
  constant c_nof_accum_per_sync    : natural := 10;
72
  constant c_bsn_init              : natural := 32;
73
  constant c_bg_prefix             : string := "data/ramp";
74
 
75
  signal tb_end           : std_logic := '0';
76
  signal rst              : std_logic;
77
  signal clk              : std_logic := '1';
78
 
79
  signal ram_bg_data_mosi : t_mem_mosi;
80
  signal reg_bg_ctrl_mosi : t_mem_mosi;
81
  signal in_sosi_arr      : t_dp_sosi_arr(c_nof_streams-1 downto 0);
82
  signal in_siso_arr      : t_dp_siso_arr(c_nof_streams-1 downto 0);
83
  signal out_sosi         : t_dp_sosi;
84
  signal in_dat           : std_logic_vector(2*c_in_dat_w-1 downto 0);
85
  signal x_out_re         : std_logic_vector(c_in_dat_w-1 downto 0);
86
  signal x_out_im         : std_logic_vector(c_in_dat_w-1 downto 0);
87
  signal y_out_re         : std_logic_vector(c_in_dat_w-1 downto 0);
88
  signal y_out_im         : std_logic_vector(c_in_dat_w-1 downto 0);
89
  signal out_val          : std_logic;
90
 
91
  signal ref_x_out_re_dly : std_logic_vector(c_in_dat_w-1 downto 0);
92
  signal ref_x_out_im_dly : std_logic_vector(c_in_dat_w-1 downto 0);
93
  signal ref_x_out_re     : std_logic_vector(c_in_dat_w-1 downto 0);
94
  signal ref_x_out_im     : std_logic_vector(c_in_dat_w-1 downto 0);
95
 
96
  signal ref_y_out_re_dly : std_logic_vector(c_in_dat_w-1 downto 0);
97
  signal ref_y_out_im_dly : std_logic_vector(c_in_dat_w-1 downto 0);
98
  signal ref_y_out_re     : std_logic_vector(c_in_dat_w-1 downto 0);
99
  signal ref_y_out_im     : std_logic_vector(c_in_dat_w-1 downto 0);
100
  signal ref_y_out_re_dif : std_logic_vector(c_in_dat_w-1 downto 0);
101
  signal ref_y_out_im_dif : std_logic_vector(c_in_dat_w-1 downto 0);
102
  signal ref_y_prod_re    : std_logic_vector(2*c_in_dat_w-1 downto 0);
103
  signal ref_y_prod_im    : std_logic_vector(2*c_in_dat_w-1 downto 0);
104
 
105
  signal weight_re        : wTyp;
106
  signal weight_im        : wTyp;
107
 
108
begin
109
 
110
  clk <= (not clk) or tb_end after c_clk_period/2;
111
  rst <= '1', '0' after c_clk_period*3;
112
 
113
  p_control_input_stream : process
114
  begin
115
    tb_end <= '0';
116
    reg_bg_ctrl_mosi <= c_mem_mosi_rst;
117
 
118
    -- Wait until reset is done
119
    proc_common_wait_until_high(clk, rst);
120
    proc_common_wait_some_cycles(clk, 10);
121
 
122
    -- Set and enable the waveform generators. All generators are controlled by the same registers
123
    proc_mem_mm_bus_wr(1, c_nof_samples_in_packet,   clk, reg_bg_ctrl_mosi);  -- Set the number of samples per block
124
    proc_mem_mm_bus_wr(2, c_nof_accum_per_sync,      clk, reg_bg_ctrl_mosi);  -- Set the number of blocks per sync
125
    proc_mem_mm_bus_wr(3, c_gap,                     clk, reg_bg_ctrl_mosi);  -- Set the gapsize
126
    proc_mem_mm_bus_wr(4, 0,                         clk, reg_bg_ctrl_mosi);  -- Set the start address of the memory
127
    proc_mem_mm_bus_wr(5, c_nof_samples_in_packet-1, clk, reg_bg_ctrl_mosi);  -- Set the end address of the memory
128
    proc_mem_mm_bus_wr(6, c_bsn_init,                clk, reg_bg_ctrl_mosi);  -- Set the BSNInit low  value
129
    proc_mem_mm_bus_wr(7, 0,                         clk, reg_bg_ctrl_mosi);  -- Set the BSNInit high value
130
    proc_mem_mm_bus_wr(0, 1,                         clk, reg_bg_ctrl_mosi);  -- Enable the BG
131
 
132
    -- Run time
133
    proc_common_wait_some_cycles(clk, c_nof_points);
134
    proc_mem_mm_bus_wr(0, 0, clk, reg_bg_ctrl_mosi);      -- Disable the BG
135
 
136
    -- The end
137
    proc_common_wait_some_cycles(clk, c_nof_points + 20);
138
    tb_end <= '1';
139
    wait;
140
  end process;
141
 
142 5 danv
  u_block_generator : entity astron_diagnostics_lib.mms_diag_block_gen
143 2 danv
  generic map(
144
    g_nof_streams        => c_nof_streams,
145
    g_buf_dat_w          => c_nof_complex*c_in_dat_w,
146
    g_buf_addr_w         => c_bg_addr_w,              -- Waveform buffer size 2**g_buf_addr_w nof samples
147
    g_file_name_prefix   => c_bg_prefix
148
  )
149
  port map(
150
   -- Clocks and reset
151
    mm_rst           => rst,
152
    mm_clk           => clk,
153
    dp_rst           => rst,
154
    dp_clk           => clk,
155
    en_sync          => '1',
156
    ram_bg_data_mosi => ram_bg_data_mosi,
157
    ram_bg_data_miso => open,
158
    reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
159
    reg_bg_ctrl_miso => open,
160
    out_siso_arr     => in_siso_arr,
161
    out_sosi_arr     => in_sosi_arr
162
  );
163
  in_siso_arr(0) <= c_dp_siso_rdy;
164
  in_siso_arr(1) <= c_dp_siso_rdy;
165
 
166
  -- device under test
167
  u_dut : entity work.fft_r2_bf_par
168
  generic map (
169
    g_stage       => g_stage,
170
    g_element     => g_element
171
  )
172
  port map (
173
    clk      => clk,
174
    rst      => rst,
175
    x_in_re  => in_sosi_arr(0).re(c_in_dat_w-1 downto 0),
176
    x_in_im  => in_sosi_arr(0).im(c_in_dat_w-1 downto 0),
177
    y_in_re  => in_sosi_arr(1).re(c_in_dat_w-1 downto 0),
178
    y_in_im  => in_sosi_arr(1).im(c_in_dat_w-1 downto 0),
179
    in_val   => in_sosi_arr(0).valid,
180
    x_out_re => x_out_re,
181
    x_out_im => x_out_im,
182
    y_out_re => y_out_re,
183
    y_out_im => y_out_im,
184
    out_val  => out_val
185
  );
186
 
187
  -- verification 
188
  weight_re <= wRe(wMap(g_element, g_stage));
189
  weight_im <= wIm(wMap(g_element, g_stage));
190
 
191
  p_verify : process
192
    variable v_ref_y_out_re_dif : std_logic_vector(c_in_dat_w-1 downto 0);
193
    variable v_ref_y_out_im_dif : std_logic_vector(c_in_dat_w-1 downto 0);
194
    variable v_ref_y_prod_re    : std_logic_vector(2*c_in_dat_w-1 downto 0);
195
    variable v_ref_y_prod_im    : std_logic_vector(2*c_in_dat_w-1 downto 0);
196
  begin
197
    wait until (rising_edge(clk) and in_sosi_arr(0).valid = '1');
198
    ref_x_out_re       <= ADD_SVEC(in_sosi_arr(0).re(c_in_dat_w-1 downto 0), in_sosi_arr(1).re(c_in_dat_w-1 downto 0), ref_x_out_re'length);
199
    ref_x_out_im       <= ADD_SVEC(in_sosi_arr(0).im(c_in_dat_w-1 downto 0), in_sosi_arr(1).im(c_in_dat_w-1 downto 0), ref_x_out_im'length);
200
 
201
    v_ref_y_out_re_dif := SUB_SVEC(in_sosi_arr(0).re(c_in_dat_w-1 downto 0), in_sosi_arr(1).re(c_in_dat_w-1 downto 0), ref_x_out_re'length);
202
    v_ref_y_out_im_dif := SUB_SVEC(in_sosi_arr(0).im(c_in_dat_w-1 downto 0), in_sosi_arr(1).im(c_in_dat_w-1 downto 0), ref_x_out_im'length);
203
 
204
    v_ref_y_prod_re    := func_complex_multiply(v_ref_y_out_re_dif, v_ref_y_out_im_dif, weight_re, weight_im, c_conjugate, "RE", ref_y_prod_re'length);
205
    v_ref_y_prod_im    := func_complex_multiply(v_ref_y_out_re_dif, v_ref_y_out_im_dif, weight_re, weight_im, c_conjugate, "IM", ref_y_prod_im'length);
206
 
207
    ref_y_out_re       <= truncate_and_resize_svec(v_ref_y_prod_re, c_round_w, ref_y_out_re'length);
208
    ref_y_out_im       <= truncate_and_resize_svec(v_ref_y_prod_im, c_round_w, ref_y_out_im'length);
209
 
210
  end process;
211
 
212
  u_verify_pipeline_x_re : entity common_components_lib.common_pipeline
213
  generic map (
214
    g_pipeline  => (c_pipeline.bf_lat + c_pipeline.mul_lat),
215
    g_in_dat_w  => ref_x_out_re'length,
216
    g_out_dat_w => ref_x_out_re'length
217
  )
218
  port map (
219
    clk     => clk,
220
    in_dat  => ref_x_out_re,
221
    out_dat => ref_x_out_re_dly
222
  );
223
 
224
  u_verify_pipeline_x_im : entity common_components_lib.common_pipeline
225
  generic map (
226
    g_pipeline  => (c_pipeline.bf_lat + c_pipeline.mul_lat),
227
    g_in_dat_w  => ref_x_out_im'length,
228
    g_out_dat_w => ref_x_out_im'length
229
  )
230
  port map (
231
    clk     => clk,
232
    in_dat  => ref_x_out_im,
233
    out_dat => ref_x_out_im_dly
234
  );
235
 
236
  u_verify_pipeline_y_re : entity common_components_lib.common_pipeline
237
  generic map (
238
    g_pipeline  => (c_pipeline.bf_lat + c_pipeline.mul_lat),
239
    g_in_dat_w  => ref_y_out_re'length,
240
    g_out_dat_w => ref_y_out_re'length
241
  )
242
  port map (
243
    clk     => clk,
244
    in_dat  => ref_y_out_re,
245
    out_dat => ref_y_out_re_dly
246
  );
247
 
248
  u_verify_pipeline_y_im : entity common_components_lib.common_pipeline
249
  generic map (
250
    g_pipeline  => (c_pipeline.bf_lat + c_pipeline.mul_lat),
251
    g_in_dat_w  => ref_y_out_im'length,
252
    g_out_dat_w => ref_y_out_im'length
253
  )
254
  port map (
255
    clk     => clk,
256
    in_dat  => ref_y_out_im,
257
    out_dat => ref_y_out_im_dly
258
  );
259
 
260
  ------------------------------------------------------------------------  
261
  -- Simples process that does the final test.                     
262
  ------------------------------------------------------------------------ 
263
  p_tester : process(rst, clk)
264
    variable I : integer;
265
  begin
266
    if rst='0' then
267
      if rising_edge(clk) and out_val = '1' then
268
        assert ref_x_out_re_dly = x_out_re report "Error: wrong RTL result in X real path" severity error;
269
        assert ref_x_out_im_dly = x_out_im report "Error: wrong RTL result in X imag path" severity error;
270
        assert ref_y_out_re_dly = y_out_re report "Error: wrong RTL result in Y real path" severity error;
271
        assert ref_y_out_im_dly = y_out_im report "Error: wrong RTL result in Y imag path" severity error;
272
      end if;
273
    end if;
274
  end process p_tester;
275
 
276
end tb;

powered by: WebSVN 2.1.0

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