diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index a925ba49ae0e65c0cc75b49b91ea20e17f00e487..fec9c157176011fa2f05ce1d136712b9d2d713d2 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -184,6 +184,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is constant c_gn_index : natural := c_unb_nr * 4 + c_node_nr; -- this node GN constant c_init_bsn : natural := 17; -- some recognizable value >= 0 constant c_bsn_latency : natural := 5; -- used to time stimuli_done + constant c_use_transpose : boolean := false; constant c_id : std_logic_vector(7 downto 0) := TO_UVEC(c_gn_index, 8); constant c_version : std_logic_vector(1 downto 0) := "00"; @@ -210,8 +211,6 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is constant c_stat_lo_factor : real := 1.0 - c_stat_percentage; -- lower boundary constant c_stat_hi_factor : real := 1.0 + c_stat_percentage; -- higher boundary - constant c_nof_beamlets_per_data : natural := c_sdp_cep_nof_beamlets_per_longword; -- = 2 dual pol beamlets per 64b data word - constant c_beamlet_output_delta : integer := 2; -- +-delta margin -- header fields @@ -447,13 +446,21 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is signal rx_beamlet_sop_cnt : natural := 0; signal rx_beamlet_eop_cnt : natural := 0; - signal rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] - signal rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] + -- [0 : 3] = X, Y, X, Y + signal rx_beamlet_arr_re : t_sdp_beamlet_longword_list; + signal rx_beamlet_arr_im : t_sdp_beamlet_longword_list; signal rx_beamlet_cnt : natural; signal rx_beamlet_valid : std_logic; - signal rx_beamlet_list_re : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1 downto 0); -- [488 * 2-1:0] = [975:0] - signal rx_beamlet_list_im : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1 downto 0); -- [488 * 2-1:0] = [975:0] + -- [0 : 4 * 488 * 2 - 1] = [0 : 3903] + signal rx_packet_list_re : t_sdp_beamlet_packet_list; + signal rx_packet_list_im : t_sdp_beamlet_packet_list; + signal rx_reordered_list_re : t_sdp_beamlet_packet_list; + signal rx_reordered_list_im : t_sdp_beamlet_packet_list; + + -- [0 : 488 * 2 - 1] = [0 : 975] + signal rx_beamlet_list_re : t_sdp_beamlet_block_list; + signal rx_beamlet_list_im : t_sdp_beamlet_block_list; signal rx_beamlet_x_output_re : integer; signal rx_beamlet_x_output_im : integer; @@ -1322,10 +1329,10 @@ begin begin rx_beamlet_cnt <= 0; rx_beamlet_valid <= '0'; - -- Wait until start of a beamlet packet, capture only first block in packet + -- Wait until start of a beamlet packet proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.sop); - -- c_nof_beamlets_per_data = 2 dual pol beamlets (= XY, XY) per 64b data word - for I in 0 to (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data) - 1 loop + -- c_sdp_cep_nof_beamlets_per_longword = 2 dual pol beamlets (= XY, XY) per 64b data word + for I in 0 to (c_sdp_cep_nof_beamlets_per_packet / c_sdp_cep_nof_beamlets_per_longword) - 1 loop proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); rx_beamlet_valid <= '1'; -- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window @@ -1337,27 +1344,68 @@ begin rx_beamlet_arr_im(2) <= rx_beamlet_sosi.data(23 downto 16); rx_beamlet_arr_re(3) <= rx_beamlet_sosi.data(15 downto 8); -- Y rx_beamlet_arr_im(3) <= rx_beamlet_sosi.data( 7 downto 0); - if I < c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data then - -- Only capture the first beamlets block of each packet in rx_beamlet_list - rx_beamlet_list_re(I * 4 + 0) <= rx_beamlet_sosi.data(63 downto 56); -- X - rx_beamlet_list_im(I * 4 + 0) <= rx_beamlet_sosi.data(55 downto 48); - rx_beamlet_list_re(I * 4 + 1) <= rx_beamlet_sosi.data(47 downto 40); -- Y - rx_beamlet_list_im(I * 4 + 1) <= rx_beamlet_sosi.data(39 downto 32); - rx_beamlet_list_re(I * 4 + 2) <= rx_beamlet_sosi.data(31 downto 24); -- X - rx_beamlet_list_im(I * 4 + 2) <= rx_beamlet_sosi.data(23 downto 16); - rx_beamlet_list_re(I * 4 + 3) <= rx_beamlet_sosi.data(15 downto 8); -- Y - rx_beamlet_list_im(I * 4 + 3) <= rx_beamlet_sosi.data( 7 downto 0); - end if; + -- Capture the beamlets block of each packet in rx_packet_list + rx_packet_list_re(I * 4 + 0) <= rx_beamlet_sosi.data(63 downto 56); -- X + rx_packet_list_im(I * 4 + 0) <= rx_beamlet_sosi.data(55 downto 48); + rx_packet_list_re(I * 4 + 1) <= rx_beamlet_sosi.data(47 downto 40); -- Y + rx_packet_list_im(I * 4 + 1) <= rx_beamlet_sosi.data(39 downto 32); + rx_packet_list_re(I * 4 + 2) <= rx_beamlet_sosi.data(31 downto 24); -- X + rx_packet_list_im(I * 4 + 2) <= rx_beamlet_sosi.data(23 downto 16); + rx_packet_list_re(I * 4 + 3) <= rx_beamlet_sosi.data(15 downto 8); -- Y + rx_packet_list_im(I * 4 + 3) <= rx_beamlet_sosi.data( 7 downto 0); proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); -- Use at least one WAIT instead of proc_common_wait_some_cycles() to -- avoid Modelsim warning: (vcom-1090) Possible infinite loop: Process -- contains no WAIT statement. wait until rising_edge(ext_clk); rx_beamlet_valid <= '0'; - rx_beamlet_cnt <= (rx_beamlet_cnt + c_nof_beamlets_per_data) mod c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet + rx_beamlet_cnt <= (rx_beamlet_cnt + c_sdp_cep_nof_beamlets_per_longword) mod c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet end loop; end process; + -- Undo the beamlet output transpose, to have original beamlet order + p_rx_reordered_list : process + begin + -- Wait until end of a beamlet packet + wait until rising_edge(ext_clk); -- to avoid Modelsim warning: (vcom-1090) + proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); -- to reduce simulation effort + rx_reordered_list_re <= func_sdp_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_re); + rx_reordered_list_im <= func_sdp_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_im); + end process; + + p_rx_beamlet_list : process + begin + -- Wait until p_rx_reordered_list has updated + proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); + wait until rising_edge(ext_clk); + + -- Copy first block from rx_packet_list into rx_beamlet_list of one block. + if c_use_transpose then + -- transposed beamlet output order + rx_beamlet_list_re <= rx_reordered_list_re(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); + rx_beamlet_list_im <= rx_reordered_list_im(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); + else + -- identity beamlet output order + -- . X at even indices + -- . Y at odd indices + rx_beamlet_list_re <= rx_packet_list_re(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); + rx_beamlet_list_im <= rx_packet_list_im(0 to c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1); + end if; + end process; + + -- Verify that beamlet values remain stable in time + p_verify_rx_beamlet_list : process + begin + -- . After some time all rx blocks should have same beamlet values, so + -- then rx_beamlet_list then does not change in time and the other + -- blocks should be the same as the first block. + -- TODO + end process; + -- get rx_beamlet for comparision with c_exp_beamlet rx_beamlet_x_output_re <= TO_SINT(rx_beamlet_list_re(c_exp_beamlet_x_index)); rx_beamlet_x_output_im <= TO_SINT(rx_beamlet_list_im(c_exp_beamlet_x_index));