diff --git a/libraries/base/reorder/hdllib.cfg b/libraries/base/reorder/hdllib.cfg index 2f5353878ee6356ca89876905375690e860d7c0e..063dedb9b1d6564bd45e278e71070493e1196c05 100644 --- a/libraries/base/reorder/hdllib.cfg +++ b/libraries/base/reorder/hdllib.cfg @@ -1,8 +1,8 @@ hdl_lib_name = reorder hdl_library_clause_name = reorder_lib -hdl_lib_uses_synth = common dp +hdl_lib_uses_synth = common dp hdl_lib_uses_sim = io_ddr tech_ddr -hdl_lib_technology = +hdl_lib_technology = # Description: see doc/ss_parallel.pdf # @@ -32,15 +32,15 @@ hdl_lib_technology = # synth_files = - src/vhdl/reorder_pkg.vhd + src/vhdl/reorder_pkg.vhd src/vhdl/reorder_retreive.vhd src/vhdl/reorder_store.vhd src/vhdl/reorder_col.vhd src/vhdl/reorder_col_select.vhd src/vhdl/reorder_col_wide.vhd src/vhdl/reorder_col_wide_select.vhd - src/vhdl/reorder_row.vhd - src/vhdl/reorder_row_select.vhd + src/vhdl/reorder_row.vhd + src/vhdl/reorder_row_select.vhd src/vhdl/reorder_matrix.vhd src/vhdl/reorder_sequencer.vhd src/vhdl/reorder_transpose.vhd @@ -48,20 +48,21 @@ synth_files = src/vhdl/reorder_rewire_reg.vhd src/vhdl/mms_reorder_rewire.vhd -test_bench_files = +test_bench_files = tb/vhdl/tb_reorder_transpose.vhd tb/vhdl/tb_reorder_col.vhd - tb/vhdl/tb_tb_reorder_col.vhd - tb/vhdl/tb_reorder_col_wide.vhd - tb/vhdl/tb_reorder_col_wide_row_select.vhd - tb/vhdl/tb_tb_reorder_col_wide_row_select.vhd - tb/vhdl/tb_mmf_reorder_matrix.vhd - tb/vhdl/tb_mmf_reorder_row.vhd + tb/vhdl/tb_tb_reorder_col.vhd + tb/vhdl/tb_reorder_col_wide.vhd + tb/vhdl/tb_reorder_col_wide_row_select.vhd + tb/vhdl/tb_tb_reorder_col_wide_row_select.vhd + tb/vhdl/tb_mmf_reorder_matrix.vhd + tb/vhdl/tb_mmf_reorder_row.vhd tb/vhdl/tb_mms_reorder_rewire.vhd + tb/vhdl/tb_reorder_col_select_all.vhd -regression_test_vhdl = - tb/vhdl/tb_tb_reorder_col_wide_row_select.vhd - tb/vhdl/tb_tb_reorder_col.vhd +regression_test_vhdl = + tb/vhdl/tb_tb_reorder_col_wide_row_select.vhd + tb/vhdl/tb_tb_reorder_col.vhd [modelsim_project_file] diff --git a/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd b/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd new file mode 100644 index 0000000000000000000000000000000000000000..506795c4dc98b60ab99830d35289c82005a13c10 --- /dev/null +++ b/libraries/base/reorder/tb/vhdl/tb_reorder_col_select_all.vhd @@ -0,0 +1,329 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Author : E. Kooistra +-- Purpose: +-- Verify reorder_col_select using two instances and selects all inputdata. +-- Description: +-- The second reorder_col_select instances undo's the reordering of the +-- first reorder_col_select instance. All data in the input block is used, +-- so that the output of the second reorder_col_select instance is equal +-- to the tb input data, except for a delay, so that the output data can +-- easily be verified. +-- +-- Usage: +-- > as 10 +-- > run -all +-- * The tb is self stopping and self checking, tb_end will stop the simulation +-- by stopping the clk and thus all toggling. + +library IEEE, common_lib, dp_lib; +use IEEE.std_logic_1164.all; +use common_lib.common_pkg.all; +use common_lib.common_mem_pkg.all; +use common_lib.tb_common_pkg.all; +use common_lib.tb_common_mem_pkg.all; +use dp_lib.dp_stream_pkg.all; +use dp_lib.tb_dp_pkg.all; + +entity tb_reorder_col_select_all is + generic( + g_dsp_data_w : natural := 16; -- complex data width, = c_data_w / 2 + g_nof_sync : natural := 1; + g_nof_packets_per_sync : natural := 1; + g_nof_blocks_per_packet : natural := 4; + g_nof_data_per_block : natural := 3; + g_use_complex : boolean := false + ); +end tb_reorder_col_select_all; + + +architecture tb of tb_reorder_col_select_all is + + constant c_clk_period : time := 10 ns; + constant c_rl : natural := 1; + + constant c_use_data : boolean := not g_use_complex; + constant c_data_w : natural := c_nof_complex * g_dsp_data_w; + constant c_nof_ch : natural := g_nof_blocks_per_packet * g_nof_data_per_block; + + type t_transpose is record + select_copi : t_mem_copi; + addr : natural range 0 to c_nof_ch + g_nof_data_per_block; + blk_cnt : natural range 0 to g_nof_blocks_per_packet; + data_cnt : natural range 0 to g_nof_data_per_block; + end record; + + constant c_transpose_rst : t_transpose := (c_mem_copi_rst, 0, 0, 0); + + -- The p_comb_transpose and p_comb_undo_transpose can both use + -- func_transpose(), by swapping the transpose dimensions. For + -- example, with + -- . g_nof_blocks_per_packet = 4 and + -- . g_nof_data_per_block = 3 + -- the p_comb_transpose selects: + -- + -- v.blk_cnt: 0 1 2 3 + -- v.data_cnt: 0 1 2 0 1 2 0 1 2 0 1 2 + -- ch: 0 1 2 3 4 5 6 7 8 9 10 11 + -- data_in 0 1 2 3 4 5 6 7 8 9 10 11 -- in_sosi + -- transpose: 0 3 6 9 + -- 1 4 7 10 + -- 2 5 8 11 + -- v.addr 0 3 6 9 1 4 7 10 2 5 8 11 + -- data_out 0 3 6 9 1 4 7 10 2 5 8 11 -- transposed_sosi + -- + -- and then with swapped parameter values: + -- . g_nof_blocks_per_packet = 3 and + -- . g_nof_data_per_block = 4 + -- the p_comb_undo_transpose selects: + -- + -- v.blk_cnt: 0 1 2 + -- v.data_cnt: 0 1 2 3 0 1 2 3 0 1 2 3 + -- ch: 0 1 2 3 4 5 6 7 8 9 10 11 + -- data_in 0 3 6 9 1 4 7 10 2 5 8 11 -- transposed_sosi + -- undo_transpose: 0 4 8 + -- 1 5 9 + -- 2 6 10 + -- 3 7 11 + -- v.addr: 0 4 8 1 5 9 2 6 10 3 7 11 + -- data_out: 0 1 2 3 4 5 6 7 8 9 10 11 -- out_sosi + -- + -- to restore the original order. + function func_transpose(constant c_nof_blocks_per_packet : natural; + constant c_nof_data_per_block : natural; + signal transpose : t_transpose) return t_transpose is + variable v : t_transpose; + begin + v := transpose; + -- read at current address + v.select_copi.address := TO_MEM_ADDRESS(v.addr); + v.select_copi.rd := '1'; + -- prepare next read address + if v.blk_cnt < c_nof_blocks_per_packet - 1 then + if v.data_cnt < c_nof_data_per_block - 1 then + v.data_cnt := v.data_cnt + 1; + v.addr := v.addr + c_nof_data_per_block; + else + v.data_cnt := 0; + v.blk_cnt := v.blk_cnt + 1; + v.addr := v.blk_cnt; + end if; + else + v.data_cnt := 0; + v.blk_cnt := 0; + v.addr := 0; + end if; + return v; + end; + + signal rst : std_logic; + signal clk : std_logic := '1'; + signal tb_end : std_logic := '0'; + + -- Data + signal in_en : std_logic := '1'; + signal in_sosi : t_dp_sosi := c_dp_sosi_rst; + signal in_siso : t_dp_siso := c_dp_siso_rdy; -- used for proc_dp_gen_block_data + signal transposed_sosi : t_dp_sosi; + signal out_sosi : t_dp_sosi; + signal expected_sosi : t_dp_sosi; + + -- Reorder and undo reorder control + signal nof_ch : natural range 0 to c_nof_ch := c_nof_ch; + signal select_cipo : t_mem_cipo; + signal undo_select_cipo : t_mem_cipo; + signal r_transpose : t_transpose; + signal d_transpose : t_transpose; + signal r_undo_transpose : t_transpose; + signal d_undo_transpose : t_transpose; + +begin + + clk <= (not clk) or tb_end after c_clk_period / 2; + rst <= '1', '0' after c_clk_period * 7; + + -- Input data packets stimuli + p_st_stimuli : process + variable v_bsn : std_logic_vector(31 downto 0) := (others => '0'); + variable v_data : natural := 0; + begin + proc_common_wait_until_low(clk, rst); + + -- Run some sync intervals with counter data in the packets + -- proc_dp_gen_block_data( + -- constant c_ready_latency : in natural; -- 0, 1 are supported by proc_dp_stream_ready_latency() + -- constant c_use_data : in boolean; -- when TRUE use data field, else use re, im fields, and keep unused fields at 'X' + -- constant c_data_w : in natural; -- data width for the data, re and im fields + -- constant c_symbol_w : in natural; -- c_data_w/c_symbol_w must be an integer + -- constant c_symbol_init : in natural; -- init counter for symbols in data field + -- constant c_symbol_re_init : in natural; -- init counter for symbols in re field + -- constant c_symbol_im_init : in natural; -- init counter for symbols in im field + -- constant c_nof_symbols : in natural; -- nof symbols per frame for the data, re and im fields + -- constant c_channel : in natural; -- channel field + -- constant c_error : in natural; -- error field + -- constant c_sync : in std_logic; -- when '1' issue sync pulse during this block + -- constant c_bsn : in std_logic_vector; -- bsn field + -- signal clk : in std_logic; + -- signal in_en : in std_logic; -- when '0' then no valid output even when src_in is ready + -- signal src_in : in t_dp_siso; + -- signal src_out : out t_dp_sosi); + wait until rising_edge(clk); + for I in 0 to g_nof_sync - 1 loop + -- first block in sync interval + proc_dp_gen_block_data(c_rl, + c_use_data, + g_dsp_data_w, + g_dsp_data_w, + v_data, + v_data, + v_data + 1, + c_nof_ch, + 0, + 0, + '1', -- with sync + v_bsn, + clk, + in_en, + in_siso, + in_sosi); + for J in 0 to g_nof_packets_per_sync - 2 loop + -- next blocks in sync interval + v_bsn := INCR_UVEC(v_bsn, 1); + v_data := v_data + c_nof_ch; + proc_dp_gen_block_data(c_rl, + c_use_data, + g_dsp_data_w, + g_dsp_data_w, + v_data, + v_data, + v_data + 1, + c_nof_ch, + 0, + 0, + '0', -- no sync + v_bsn, + clk, + in_en, + in_siso, + in_sosi); + end loop; + end loop; + in_sosi <= c_dp_sosi_rst; + proc_common_wait_some_cycles(clk, c_nof_ch); + proc_common_wait_some_cycles(clk, 10); + tb_end <= '1'; + wait; + end process; + + ------------------------------------------------------------------------------ + -- Verification + ------------------------------------------------------------------------------ + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + r_transpose <= d_transpose when rising_edge(clk); + r_undo_transpose <= d_undo_transpose when rising_edge(clk); + + p_comb_transpose : process(rst, r_transpose, select_cipo) + variable v : t_transpose; + begin + if select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_transpose(g_nof_blocks_per_packet, g_nof_data_per_block, r_transpose); + else + -- No read, new reorder_col_select page not available yet + v := c_transpose_rst; + end if; + -- Synchronous reset + if rst = '1' THEN + v := c_transpose_rst; + end if; + d_transpose <= v; + end process; + + p_comb_undo_transpose : process(rst, r_undo_transpose, undo_select_cipo) + variable v : t_transpose; + begin + if undo_select_cipo.waitrequest = '0' then + -- Read from reorder_col_select page + v := func_transpose(g_nof_data_per_block, g_nof_blocks_per_packet, r_undo_transpose); + else + -- No read, new reorder_col_select page not available yet + v := c_transpose_rst; + end if; + -- Synchronous reset + if rst = '1' THEN + v := c_transpose_rst; + end if; + d_undo_transpose <= v; + end process; + + u_transpose : entity work.reorder_col_select + generic map ( + g_dsp_data_w => g_dsp_data_w, + g_nof_ch_in => c_nof_ch, + g_nof_ch_sel => c_nof_ch, + g_use_complex => g_use_complex + ) + port map ( + dp_rst => rst, + dp_clk => clk, + + -- Dynamic reorder block size control + nof_ch_in => nof_ch, + nof_ch_sel => nof_ch, + + -- Memory Mapped + col_select_mosi => r_transpose.select_copi, + col_select_miso => select_cipo, -- only used for waitrequest + + -- Streaming + input_sosi => in_sosi, + output_sosi => transposed_sosi + ); + + u_undo_transpose : entity work.reorder_col_select + generic map ( + g_dsp_data_w => g_dsp_data_w, + g_nof_ch_in => c_nof_ch, + g_nof_ch_sel => c_nof_ch, + g_use_complex => g_use_complex + ) + port map ( + dp_rst => rst, + dp_clk => clk, + + -- Dynamic reorder block size control + nof_ch_in => nof_ch, + nof_ch_sel => nof_ch, + + -- Memory Mapped + col_select_mosi => r_undo_transpose.select_copi, + col_select_miso => undo_select_cipo, -- only used for waitrequest + + -- Streaming + input_sosi => transposed_sosi, + output_sosi => out_sosi + ); + +end tb;