Skip to content
Snippets Groups Projects
Commit 9bd1cc7a authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Verify expected out_cnt_val.

parent 40c5da2e
No related branches found
No related tags found
No related merge requests found
......@@ -36,7 +36,7 @@
-- (p_verify_output). The coefficients appear in the order of the taps, but
-- in reversed order per tap.
--
-- The fil_ppf_filter in fil_ppf_single mulitplies the in_dat by the filter
-- The fil_ppf_filter in fil_ppf_single multiplies the in_dat by the filter
-- coefficients. The product has a double sign bit, whereby one sign bit is
-- dropped, because it only is needed to represent the positive result of
-- the product of the most negative in_dat and coeff, which does never occur
......@@ -58,17 +58,25 @@
-- Via g_enable_in_val_gaps it is possible toggle in_val in a random way to
-- verify that the DUT can handle arbitray gaps in in_dat.
--
-- It is possible to vary wb_factor, nof_chan, nof_bands, nof_taps, coef_w
-- and nof_streams. The input dat file is different for nof_taps, nof_bands
-- and coef_w. In addition the MIF files are different for wb_factor.
-- The nof_chan and nof_streams do not affect the input and output files,
-- because all multiplexed channels and pallellel streams use the same
-- filter coefficients.
--
-- The reference dat file is generated by the Matlab program:
--
-- $RADIOHDL/applications/apertif/matlab/run_pfir_coeff.m
--
-- The MIF files are generated by the Python script:
--
-- $RADIOHDL/libraries/dsp/filter/src/python/fil_create_mifs.py
-- $RADIOHDL/libraries/dsp/filter/src/python/fil_ppf_create_mifs.py
--
-- The reference dat file and the MIF files use the same g_coefs_file_prefix.
-- For the reference dat file this prefix is expanded by nof_taps, nof_bands
-- and coef_dat_w and the MIF files in addition also have the wb_factor.
-- and coef_dat_w and the MIF files in addition also have the wb_factor and
-- the MIF file index.
--
-- The example below shows how the mif file index relates to the reference
-- coefficients:
......@@ -140,7 +148,7 @@ entity tb_fil_ppf_single is
-- requant_remove_lsb : natural; -- = 1
-- requant_remove_msb : natural; -- = 0
-- end record;
g_fil_ppf : t_fil_ppf := (1, 0, 64, 8, 1, 8, 15, 16);
g_fil_ppf : t_fil_ppf := (1, 1, 64, 8, 1, 8, 16, 16);
-- type t_fil_ppf is record
-- wb_factor : natural; -- = 1, the wideband factor
-- nof_chan : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan
......@@ -162,11 +170,11 @@ architecture tb of tb_fil_ppf_single is
constant c_clk_period : time := 10 ns;
constant c_wb_factor : natural := 1; -- force wb_factor = 1 for fil_ppf_single, so do not use g_fil_ppf.wb_factor in this tb
constant c_nof_coefs : natural := g_fil_ppf.nof_taps * g_fil_ppf.nof_bands; -- nof PFIR coef
constant c_nof_channels : natural := 2**g_fil_ppf.nof_chan;
constant c_block_size : natural := g_fil_ppf.nof_bands * c_nof_channels;
constant c_block_nof_coefs : natural := g_fil_ppf.nof_taps * c_block_size; -- nof PFIR coef expanded for all channels
constant c_nof_mif_files : natural := c_wb_factor * g_fil_ppf.nof_taps;
constant c_nof_coefs : natural := g_fil_ppf.nof_taps * g_fil_ppf.nof_bands; -- nof PFIR coef
constant c_nof_data_in_filter : natural := c_nof_coefs * c_nof_channels; -- nof PFIR coef expanded for all channels
constant c_nof_data_per_tap : natural := g_fil_ppf.nof_bands * c_nof_channels;
constant c_nof_mif_files : natural := g_fil_ppf.nof_taps;
constant c_mif_coef_mem_addr_w : natural := ceil_log2(g_fil_ppf.nof_bands);
constant c_mif_coef_mem_span : natural := 2**c_mif_coef_mem_addr_w; -- mif coef mem span for one tap
constant c_coefs_file_prefix : string := g_coefs_file_prefix & "_" & integer'image(g_fil_ppf.nof_taps) & "taps" &
......@@ -180,6 +188,8 @@ architecture tb of tb_fil_ppf_single is
constant c_fil_lsb_w : natural := c_fil_sum_w - g_fil_ppf.out_dat_w; -- nof LSbits that get rounded for out_dat
constant c_in_ampl : natural := 2**c_fil_lsb_w; -- scale in_dat to compensate for rounding
constant c_gap_factor : natural := sel_a_b(g_enable_in_val_gaps, 3, 1);
-- input/output data width
constant c_in_dat_w : natural := g_fil_ppf.in_dat_w;
constant c_out_dat_w : natural := g_fil_ppf.out_dat_w; -- must be >= coef_dat_w to be able to show the coeff in out_dat
......@@ -187,6 +197,7 @@ architecture tb of tb_fil_ppf_single is
-- signal definitions
signal tb_end : std_logic := '0';
signal tb_end_mm : std_logic := '0';
signal tb_end_almost : std_logic := '0';
signal clk : std_logic := '0';
signal rst : std_logic := '0';
signal random : std_logic_vector(15 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
......@@ -194,18 +205,20 @@ architecture tb of tb_fil_ppf_single is
signal ram_coefs_mosi : t_mem_mosi := c_mem_mosi_rst;
signal ram_coefs_miso : t_mem_miso;
signal in_dat : std_logic_vector(c_in_dat_w*g_fil_ppf.nof_streams-1 downto 0);
signal in_dat : std_logic_vector(g_fil_ppf.nof_streams*c_in_dat_w-1 downto 0);
signal in_val : std_logic;
signal in_val_cnt : natural := 0;
signal in_gap : std_logic := '0';
signal out_dat : std_logic_vector(c_out_dat_w*g_fil_ppf.nof_streams-1 downto 0);
signal out_dat : std_logic_vector(g_fil_ppf.nof_streams*c_out_dat_w-1 downto 0);
signal out_val : std_logic;
signal out_val_cnt : natural := 0;
signal mif_coefs_arr : t_integer_arr(g_fil_ppf.nof_bands-1 downto 0) := (OTHERS=>0); -- = PFIR coef for 1 tap as read from 1 MIF file
signal mif_dat_arr : t_integer_arr(c_block_nof_coefs-1 downto 0) := (OTHERS=>0); -- = PFIR coef for all taps as read from all MIF files and expanded for all channels
signal mif_dat_arr : t_integer_arr(c_nof_data_in_filter-1 downto 0) := (OTHERS=>0); -- = PFIR coef for all taps as read from all MIF files and expanded for all channels
signal ref_coefs_arr : t_integer_arr(c_nof_coefs-1 downto 0) := (OTHERS=>0); -- = PFIR coef for all taps as read from the coefs file
signal ref_dat_arr : t_integer_arr(c_block_nof_coefs-1 downto 0) := (OTHERS=>0); -- = PFIR coef for all taps as read from the coefs file expanded for all channels
signal ref_dat_arr : t_integer_arr(c_nof_data_in_filter-1 downto 0) := (OTHERS=>0); -- = PFIR coef for all taps as read from the coefs file expanded for all channels
signal ref_dat : integer := 0;
signal ref_index : natural := 0;
......@@ -229,8 +242,8 @@ begin
proc_common_wait_until_low(clk, rst); -- Wait until reset has finished
proc_common_wait_some_cycles(clk, 10); -- Wait an additional amount of cycles
-- Pulse during first block
FOR I IN 0 TO c_block_size-1 LOOP
-- Pulse during first tap of all channels
FOR I IN 0 TO c_nof_data_per_tap-1 LOOP
FOR J IN 0 To g_fil_ppf.nof_streams-1 LOOP
in_dat((J+1)*c_in_dat_w-1 DOWNTO J*c_in_dat_w) <= TO_UVEC(c_in_ampl, c_in_dat_w);
END LOOP;
......@@ -242,10 +255,10 @@ begin
END IF;
END LOOP;
-- Zero during next nof_taps-1 blocks, +1 more to account for block latency of PPF and 1 more to have zeros output in last block
FOR J IN 0 TO g_fil_ppf.nof_taps-2 +1 +1 LOOP
FOR I IN 0 TO g_fil_ppf.nof_bands-1 LOOP
-- Zero during next nof_taps-1 blocks, +1 more to account for block latency of PPF and +1 more to have zeros output in last block
in_dat <= (OTHERS=>'0');
FOR J IN 0 TO g_fil_ppf.nof_taps-2 +1 +1 LOOP
FOR I IN 0 TO c_nof_data_per_tap-1 LOOP
in_val <= '1';
proc_common_wait_some_cycles(clk, 1);
IF in_gap='1' THEN
......@@ -254,11 +267,12 @@ begin
END IF;
END LOOP;
END LOOP;
-- End with invalid
in_dat <= (OTHERS => '0');
in_val <= '0';
proc_common_wait_until_high(clk, tb_end_mm);
-- Wait until done
proc_common_wait_some_cycles(clk, c_gap_factor*c_nof_data_per_tap); -- PPF latency of 1 tap
proc_common_wait_until_high(clk, tb_end_mm); -- MM read done
tb_end_almost <= '1';
proc_common_wait_some_cycles(clk, 10);
tb_end <= '1';
WAIT;
......@@ -283,7 +297,7 @@ begin
for J in 0 to g_fil_ppf.nof_taps-1 loop
for I in 0 to g_fil_ppf.nof_bands-1 loop
for K in 0 to c_nof_channels-1 loop
ref_dat_arr(J*c_block_size + I*c_nof_channels + K) <= TO_SINT(TO_SVEC(v_coefs_flip_arr(J*g_fil_ppf.nof_bands+I), g_fil_ppf.coef_dat_w));
ref_dat_arr(J*c_nof_data_per_tap + I*c_nof_channels + K) <= TO_SINT(TO_SVEC(v_coefs_flip_arr(J*g_fil_ppf.nof_bands+I), g_fil_ppf.coef_dat_w));
end loop;
end loop;
end loop;
......@@ -299,7 +313,7 @@ begin
-- Expand the channels
for I in 0 to g_fil_ppf.nof_bands-1 loop
for K in 0 to c_nof_channels-1 loop
mif_dat_arr(J*c_block_size + I*c_nof_channels + K) <= TO_SINT(TO_SVEC(mif_coefs_arr(I), g_fil_ppf.coef_dat_w));
mif_dat_arr(J*c_nof_data_per_tap + I*c_nof_channels + K) <= TO_SINT(TO_SVEC(mif_coefs_arr(I), g_fil_ppf.coef_dat_w));
end loop;
end loop;
end loop;
......@@ -342,7 +356,7 @@ begin
p_verify_ref_coeff_versus_mm_ram : PROCESS
begin
-- Wait until the coeff dat file has been read and the coeff have been read via MM
proc_common_wait_until_high(clk, tb_end_mm);
proc_common_wait_until_high(clk, tb_end_almost);
assert read_coefs_arr = ref_coefs_arr report "Coefs file does not match coefs read via MM" severity error;
wait;
end process;
......@@ -350,8 +364,8 @@ begin
---------------------------------------------------------------
-- MAKE THE REFERENCE STREAM
---------------------------------------------------------------
ref_index <= ref_index + 1 when rising_edge(clk) and out_val='1' and ref_index < c_block_nof_coefs;
ref_dat <= ref_dat_arr(ref_index) WHEN ref_index < c_block_nof_coefs ELSE 0;
ref_index <= ref_index + 1 when rising_edge(clk) and out_val='1' and ref_index < c_nof_data_in_filter;
ref_dat <= ref_dat_arr(ref_index) WHEN ref_index < c_nof_data_in_filter ELSE 0;
---------------------------------------------------------------
-- DUT = Device Under Test
......@@ -381,12 +395,25 @@ begin
---------------------------------------------------------------
p_verify_out_dat_width : process
begin
-- Wait until te_end to avoid that the Error message gets lost in earlier messages
proc_common_wait_until_high(clk, tb_end);
-- Wait until tb_end_almost to avoid that the Error message gets lost in earlier messages
proc_common_wait_until_high(clk, tb_end_almost);
assert g_fil_ppf.out_dat_w >= g_fil_ppf.coef_dat_w report "Output data width too small for coefficients" severity error;
wait;
end process;
p_verify_out_val_cnt : process
begin
-- Wait until tb_end_almost
proc_common_wait_until_high(clk, tb_end_almost);
-- there remains in_dat for tap in the filter
assert in_val_cnt > 0 report "Test did not run, no valid input data" severity error;
assert out_val_cnt = in_val_cnt-c_nof_data_per_tap report "Unexpected number of valid output data coefficients" severity error;
wait;
end process;
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;
p_verify_out_dat : process(clk)
variable v_coeff : integer;
begin
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment