diff --git a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd index 3bf9b72e6ecac1e58c5de9801cb834992ac66136..97e579d9d4a3100907e4971aaa1068af955f21c6 100644 --- a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd +++ b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd @@ -38,7 +38,7 @@ -- . tb supports use_reorder for complex input with flipped or reordered output -- . tb supports use_reorder for two real input with reordered output -- . tb does support nof_wb_streams > 1 --- . tb does not yet support nof_chan > 0 +-- . tb does support nof_chan > 0 -- -- Usage: -- > run -all @@ -66,7 +66,7 @@ use work.wpfb_pkg.all; entity tb_wpfb_unit_wide is generic( -- DUT generics - g_wpfb : t_wpfb := (1, 32, 0, 2, + g_wpfb : t_wpfb := (4, 32, 1, 1, 16, 1, 8, 16, 16, false, false, false, 16, 16, 0, c_dsp_mult_w, 2, true, 56, 2, c_fft_pipeline, c_fft_pipeline, c_fil_ppf_pipeline); @@ -247,8 +247,6 @@ architecture tb of tb_wpfb_unit_wide is signal exp_output_data_c_re_arr : t_integer_arr(0 to g_data_file_nof_lines-1) := (OTHERS=>0); -- full spectrum, re signal exp_output_data_c_im_arr : t_integer_arr(0 to g_data_file_nof_lines-1) := (OTHERS=>0); -- full spectrum, im - signal t_blk : integer := 0; -- block time counter - -- Input signal in_re_arr : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0); signal in_im_arr : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0); @@ -256,8 +254,11 @@ architecture tb of tb_wpfb_unit_wide is signal in_im_data : std_logic_vector(g_wpfb.wb_factor*c_in_dat_w-1 DOWNTO 0); -- scope data only for stream 0 signal in_val : std_logic:= '0'; signal in_val_cnt : natural := 0; + signal in_blk_val : std_logic; + signal in_blk_val_cnt : natural := 0; signal in_gap : std_logic := '0'; signal in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others=>c_dp_sosi_rst); + signal in_blk_time : integer := 0; -- input block time counter -- Input in sclk domain signal in_re_scope : integer; @@ -287,6 +288,7 @@ architecture tb of tb_wpfb_unit_wide is signal out_im_data : std_logic_vector(g_wpfb.wb_factor*c_out_dat_w-1 DOWNTO 0); -- scope data only for stream 0 signal out_val : std_logic:= '0'; -- for parallel output signal out_val_cnt : natural := 0; + signal out_blk_time : integer := 0; -- output block time counter -- Output in sclk domain signal out_re_scope : integer := 0; @@ -315,6 +317,7 @@ architecture tb of tb_wpfb_unit_wide is signal reg_out_cnt : natural := 0; signal reg_out_bin_cnt : natural := 0; signal reg_out_bin : natural; + signal reg_out_blk_time : integer := 0; -- Output data two real input data A and B signal out_re_a_scope : integer := 0; @@ -364,8 +367,9 @@ begin for S in 0 to g_wpfb.nof_wb_streams-1 loop -- parallel for P in 0 to g_wpfb.wb_factor-1 loop -- parallel vP := g_wpfb.wb_factor-1-P; -- time to big endian - if S=1 then - -- if present then stream 1 carries zero data to be able to recognize the stream order in the wave window + if K=1 or S=1 then + -- if present then serial channel 1 carries zero data to be able to recognize the serial channel order in the wave window + -- if present then parallel stream 1 carries zero data to be able to recognize the parallel stream order in the wave window in_re_arr(S*g_wpfb.wb_factor + vP) <= (OTHERS=>'0'); in_im_arr(S*g_wpfb.wb_factor + vP) <= (OTHERS=>'0'); else @@ -380,13 +384,13 @@ begin end if; end loop; end loop; - end loop; - in_val <= '1'; -- serial - proc_common_wait_some_cycles(clk, 1); - if in_gap='1' then - in_val <= '0'; -- serial + in_val <= '1'; -- serial proc_common_wait_some_cycles(clk, 1); - end if; + if in_gap='1' then + in_val <= '0'; -- serial + proc_common_wait_some_cycles(clk, 1); + end if; + end loop; end loop; -- Wait until done @@ -460,8 +464,12 @@ begin in_val_cnt <= in_val_cnt+1 when rising_edge(clk) and in_val='1' else in_val_cnt; out_val_cnt <= out_val_cnt+1 when rising_edge(clk) and out_val='1' else out_val_cnt; - -- Block count t_blk time axis - t_blk <= in_val_cnt / (g_wpfb.nof_points /g_wpfb.wb_factor); + -- Block count blocks for c_nof_channels>=1 channels per block + in_blk_val <= '1' when in_val='1' and (in_val_cnt mod c_nof_channels)=0 else '0'; + in_blk_val_cnt <= in_val_cnt/c_nof_channels; + + -- Block count time axis + in_blk_time <= in_blk_val_cnt / (g_wpfb.nof_points/g_wpfb.wb_factor); -- Verify nof valid counts p_verify_out_val_cnt : process @@ -484,18 +492,21 @@ begin -- DATA OUTPUT CONTROL IN SCLK DOMAIN --------------------------------------------------------------- out_cnt <= out_cnt + 1 when rising_edge(sclk) and out_val_c='1' else out_cnt; + + out_blk_time <= (out_cnt / c_nof_channels) / g_wpfb.nof_points; proc_fft_out_control(g_wpfb.wb_factor, g_wpfb.nof_points, c_nof_channels, g_wpfb.use_reorder, g_wpfb.use_fft_shift, g_wpfb.use_separate, out_cnt, out_val_c, out_val_a, out_val_b, out_channel, out_bin, out_bin_cnt); -- clk diff to avoid combinatorial glitches when selecting the data with out_val_a,b,c - reg_out_val_a <= out_val_a when rising_edge(sclk); - reg_out_val_b <= out_val_b when rising_edge(sclk); - reg_out_val_c <= out_val_c when rising_edge(sclk); - reg_out_channel <= out_channel when rising_edge(sclk); - reg_out_cnt <= out_cnt when rising_edge(sclk); - reg_out_bin_cnt <= out_bin_cnt when rising_edge(sclk); - reg_out_bin <= out_bin when rising_edge(sclk); + reg_out_val_a <= out_val_a when rising_edge(sclk); + reg_out_val_b <= out_val_b when rising_edge(sclk); + reg_out_val_c <= out_val_c when rising_edge(sclk); + reg_out_channel <= out_channel when rising_edge(sclk); + reg_out_cnt <= out_cnt when rising_edge(sclk); + reg_out_bin_cnt <= out_bin_cnt when rising_edge(sclk); + reg_out_bin <= out_bin when rising_edge(sclk); + reg_out_blk_time <= out_blk_time when rising_edge(sclk); out_re_a_scope <= out_re_scope when rising_edge(sclk) and out_val_a='1'; out_im_a_scope <= out_im_scope when rising_edge(sclk) and out_val_a='1'; @@ -521,17 +532,43 @@ begin --------------------------------------------------------------- -- VERIFY OUTPUT DATA --------------------------------------------------------------- - -- p_verify_output - gen_verify_two_real : if not c_in_complex generate - assert diff_re_a_scope >= -g_diff_margin and diff_re_a_scope <= g_diff_margin report "Output data A real error" severity error; - assert diff_im_a_scope >= -g_diff_margin and diff_im_a_scope <= g_diff_margin report "Output data A imag error" severity error; - assert diff_re_b_scope >= -g_diff_margin and diff_re_b_scope <= g_diff_margin report "Output data B real error" severity error; - assert diff_im_b_scope >= -g_diff_margin and diff_im_b_scope <= g_diff_margin report "Output data B imag error" severity error; - end generate; - gen_verify_complex : if c_in_complex generate - assert diff_re_c_scope >= -g_diff_margin and diff_re_c_scope <= g_diff_margin report "Output data C real error" severity error; - assert diff_im_c_scope >= -g_diff_margin and diff_im_c_scope <= g_diff_margin report "Output data C imag error" severity error; - end generate; + p_verify_output : process(sclk) + begin + -- verify at sclk rising edge to avoid void differences due to delta-cycle differences that can occur between combinatorial signals + if rising_edge(sclk) then + if not c_in_complex then + if reg_out_channel=1 then + --if reg_out_val_a='1' then + assert out_re_a_scope = 0 report "Output data A real error in channel" severity error; + assert out_im_a_scope = 0 report "Output data A imag error in channel" severity error; + --end if; + if reg_out_val_b='1' then + assert out_re_b_scope = 0 report "Output data B real error in channel" severity error; + assert out_im_b_scope = 0 report "Output data B imag error in channel" severity error; + end if; + else + --if reg_out_val_a='1' then + assert diff_re_a_scope >= -g_diff_margin and diff_re_a_scope <= g_diff_margin report "Output data A real error" severity error; + assert diff_im_a_scope >= -g_diff_margin and diff_im_a_scope <= g_diff_margin report "Output data A imag error" severity error; + --end if; + if reg_out_val_b='1' then + assert diff_re_b_scope >= -g_diff_margin and diff_re_b_scope <= g_diff_margin report "Output data B real error" severity error; + assert diff_im_b_scope >= -g_diff_margin and diff_im_b_scope <= g_diff_margin report "Output data B imag error" severity error; + end if; + end if; + else + if reg_out_val_c='1' then + if reg_out_channel=1 then + assert out_re_c_scope = 0 report "Output data C real error in channel" severity error; + assert out_im_c_scope = 0 report "Output data C imag error in channel" severity error; + else + assert diff_re_c_scope >= -g_diff_margin and diff_re_c_scope <= g_diff_margin report "Output data C real error" severity error; + assert diff_im_c_scope >= -g_diff_margin and diff_im_c_scope <= g_diff_margin report "Output data C imag error" severity error; + end if; + end if; + end if; + end if; + end process; --------------------------------------------------------------- -- READ EXPECTED FILTER OUTPUT DATA FROM FILE