diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 3b1bff1f02a4186cb170dc23e7f7e42b99c69aea..c33690558424837b122beee5e306d9266d1a86ad 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -104,8 +104,6 @@ synth_files = src/vhdl/dp_bsn_align.vhd src/vhdl/dp_bsn_align_reg.vhd src/vhdl/mms_dp_bsn_align.vhd - src/vhdl/dp_bsn_align_v2.vhd - src/vhdl/mmp_dp_bsn_align_v2.vhd src/vhdl/dp_frame_rd.vhd src/vhdl/dp_frame_fsn.vhd src/vhdl/dp_frame_tx.vhd @@ -213,8 +211,6 @@ test_bench_files = tb/vhdl/tb_dp_block_validate_channel.vhd tb/vhdl/tb_dp_bsn_align.vhd tb/vhdl/tb_mms_dp_bsn_align.vhd - tb/vhdl/tb_dp_bsn_align_v2.vhd - tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd tb/vhdl/tb_dp_bsn_monitor.vhd tb/vhdl/tb_dp_bsn_monitor_v2.vhd tb/vhdl/tb_dp_bsn_source.vhd @@ -299,7 +295,6 @@ test_bench_files = tb/vhdl/tb_tb_dp_block_from_mm.vhd tb/vhdl/tb_tb_dp_block_validate_channel.vhd tb/vhdl/tb_tb_dp_bsn_align.vhd - tb/vhdl/tb_tb_dp_bsn_align_v2.vhd tb/vhdl/tb_tb_dp_bsn_source_v2.vhd tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_concat.vhd @@ -356,7 +351,6 @@ regression_test_vhdl = tb/vhdl/tb_dp_latency_adapter.vhd tb/vhdl/tb_dp_shiftreg.vhd tb/vhdl/tb_dp_bsn_source.vhd - tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd tb/vhdl/tb_mms_dp_bsn_source.vhd tb/vhdl/tb_mms_dp_bsn_source_v2.vhd tb/vhdl/tb_mmp_dp_bsn_sync_scheduler.vhd @@ -370,7 +364,6 @@ regression_test_vhdl = tb/vhdl/tb_tb_dp_block_gen_valid_arr.vhd tb/vhdl/tb_tb_dp_block_from_mm.vhd tb/vhdl/tb_tb_dp_block_validate_channel.vhd - tb/vhdl/tb_tb_dp_bsn_align_v2.vhd tb/vhdl/tb_tb_dp_bsn_source_v2.vhd tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd tb/vhdl/tb_tb_dp_concat.vhd diff --git a/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd deleted file mode 100644 index d8e6bdc3162be028b613391888ae9df311af495d..0000000000000000000000000000000000000000 --- a/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd +++ /dev/null @@ -1,401 +0,0 @@ --- -------------------------------------------------------------------------- --- Copyright 2021 --- 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: Eric Kooistra, 3 Sept 2021 --- Purpose : --- Align frames from multiple input streams --- Description: --- The aligner uses a circular buffer to capture the blocks that arrive at --- the input streams. The blocks have a block sequence number (BSN) that --- is used to align the inputs. The input stream 0 is treated as local --- input stream that is ahead of the other remote input streams. After a --- certain number of blocks on input 0, the same block on all remote --- inputs should also have arrived. If not then they are replaced by --- filler data. The output streams are paced by the block rate of input 0. --- The user has to read the block within the block period. --- --- Features: --- . uses filler flag and data to replace lost input blocks --- . output block can be read in arbitrary order --- --- For more detailed description see: --- https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+BSN+aligner+v2 --- --- Remarks: --- . This dp_bsn_align_v2.vhd replaces the dp_bsn_align.vhd that was used in --- APERTIF. Mian differences are that the old component uses FIFO buffers, --- timeouts and states, and v2 does not, which makes v2 simpler and more --- robust. - -LIBRARY IEEE,common_lib; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.ALL; -USE common_lib.common_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE work.dp_stream_pkg.ALL; - - -ENTITY dp_bsn_align_v2 IS - GENERIC ( - g_nof_streams : NATURAL; -- number of input and output streams - g_bsn_latency_max : NATURAL; -- Maximum travel latency of a remote block in number of block periods T_blk - g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node - g_node_index_max : NATURAL := 31; -- limit to functional 5 bit range, instead of full 31 bit NATURAL range - g_block_size : NATURAL := 32; -- > 1, g_block_size=1 is not supported - g_buffer_nof_blocks : NATURAL; -- circular buffer size per input, choose ceil_pow2(1 + g_bsn_latency_max) - g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN - g_data_w : NATURAL; -- number of bits in sosi data - g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks - g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP - g_pipeline_input : NATURAL := 0; -- >= 0, choose 0 for wires, choose 1 to ease timing closure - g_rd_latency : NATURAL := 1 -- 1 or 2, choose 2 to ease timing closure - ); - PORT ( - dp_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - - node_index : IN NATURAL RANGE 0 TO g_node_index_max := 0; -- only used when g_bsn_latency_use_node_index is TRUE - - -- MM control - stream_en_arr : IN STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); - - -- Streaming input - in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - - -- Output via local MM interface in dp_clk domain - mm_sosi : OUT t_dp_sosi; -- streaming information that signals that an output block can be read - mm_copi : IN t_mem_copi; -- read access to output block, all output streams share same mm_copi - mm_cipo_arr : OUT t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); - - -- Output via streaming DP interface - out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) - ); -END dp_bsn_align_v2; - - -ARCHITECTURE rtl OF dp_bsn_align_v2 IS - - -- Circular buffer per stream - CONSTANT c_ram_size : NATURAL := g_buffer_nof_blocks * g_block_size; - CONSTANT c_ram_buf : t_c_mem := (latency => 1, - adr_w => ceil_log2(c_ram_size), - dat_w => g_data_w, - nof_dat => c_ram_size, - init_sl => '0'); - - CONSTANT c_block_size_w : NATURAL := ceil_log2(g_block_size); - CONSTANT c_block_size_slv : STD_LOGIC_VECTOR(c_block_size_w-1 DOWNTO 0) := TO_UVEC(g_block_size, c_block_size_w); - CONSTANT c_blk_pointer_w : NATURAL := ceil_log2(g_buffer_nof_blocks); - - -- Use fixed slv width instead of using naturals for address calculation, to - -- avoid that synthesis may infer a too larger multiplier - CONSTANT c_product_w : NATURAL := c_blk_pointer_w + c_block_size_w; - - TYPE t_bsn_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); - TYPE t_adr_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_mem_ram.adr_w-1 DOWNTO 0); - TYPE t_filled_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_buffer_nof_blocks-1 DOWNTO 0); - - TYPE t_reg IS RECORD - -- p_write_arr - wr_pointer : NATURAL; - wr_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); - -- all streams - filled_arr : t_filled_arr(g_nof_streams-1 DOWNTO 0); - use_filler_data : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - -- local reference - sync_arr : STD_LOGIC_VECTOR(g_buffer_nof_blocks-1 DOWNTO 0); - bsn_arr : t_bsn_arr(g_buffer_nof_blocks-1 DOWNTO 0); - mm_sosi : t_dp_sosi; - -- p_read - rd_pointer : INTEGER; -- use integer to detect need to wrap to natural - rd_offset : STD_LOGIC_VECTOR(c_mem_ram.adr_w-1 DOWNTO 0); - rd_copi : t_mem_copi; - fill_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); -- used combinatorial to contain rd_cipo_arr from buffer or filler data - out_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); -- hold BSN for streaming output - END RECORD; - - CONSTANT c_reg_rst : t_reg := (0, - (OTHERS=>c_mem_copi_rst), - (OTHERS=>(OTHERS=>'0')), - (OTHERS=>'0'), - (OTHERS=>'0'), - (OTHERS=>(OTHERS=>'0')), - c_dp_sosi_rst, - 0, - (OTHERS=>'0'), - c_mem_copi_rst, - (OTHERS=>c_mem_cipo_rst), - (OTHERS=>'0')); - - -- State registers - SIGNAL r : t_reg; - SIGNAL nxt_r : t_reg; - - -- Wires - SIGNAL dp_done : STD_LOGIC; - SIGNAL dp_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL dp_copi : t_mem_copi; - SIGNAL dp_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); - - SIGNAL dp_sosi : t_dp_sosi; - SIGNAL rd_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL rd_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_mem_cipo_rst); - - -- Pipeline registers - SIGNAL in_sosi_arr_p : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL rd_copi_p : t_mem_copi; - -BEGIN - - mm_sosi <= r.mm_sosi; - - p_reg : PROCESS(dp_clk, dp_rst) - BEGIN - IF dp_rst='1' THEN - r <= c_reg_rst; - ELSIF rising_edge(dp_clk) THEN - r <= nxt_r; - END IF; - END PROCESS; - - p_comb : PROCESS(r, in_sosi_arr_p, mm_copi, rd_cipo_arr, rd_sosi_arr) - -- State variable - VARIABLE v : t_reg; - -- Auxiliary variables / local wires / no memory - VARIABLE v_ref_sosi : t_dp_sosi; - VARIABLE v_pointer_slv : STD_LOGIC_VECTOR(c_blk_pointer_w-1 DOWNTO 0); - VARIABLE v_product_slv : STD_LOGIC_VECTOR(c_product_w-1 DOWNTO 0); - VARIABLE v_filler_flag : STD_LOGIC; - VARIABLE v_out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - BEGIN - v := r; - v.mm_sosi := func_dp_stream_reset_control(r.mm_sosi); - v.wr_copi_arr := RESET_MEM_COPI_CTRL(r.wr_copi_arr); - - ---------------------------------------------------------------------------- - -- p_write_arr - ---------------------------------------------------------------------------- - FOR I IN 0 TO g_nof_streams-1 LOOP - -- p_write - IF in_sosi_arr_p(I).valid = '1' THEN - -- . increment address during block - v.wr_copi_arr(I).address := RESIZE_MEM_ADDRESS(INCR_UVEC(r.wr_copi_arr(I).address(c_mem_ram.adr_w-1 DOWNTO 0), 1)); - v.wr_copi_arr(I).wr := '1'; - v.wr_copi_arr(I).wrdata := RESIZE_MEM_SDATA(in_sosi_arr_p(I).data); - END IF; - - IF in_sosi_arr_p(I).sop = '1' THEN - -- . set address at start of block - v_pointer_slv := in_sosi_arr_p(I).bsn(c_blk_pointer_w-1 DOWNTO 0); - v_product_slv := MULT_UVEC(v_pointer_slv, c_block_size_slv); - v.wr_copi_arr(I).address := RESIZE_MEM_ADDRESS(v_product_slv); - - -- . set filled flag at sop, so assume rest of block will follow in time - v.filled_arr(I)(TO_UINT(v_pointer_slv)) := '1'; - END IF; - END LOOP; - - ---------------------------------------------------------------------------- - -- p_control, all at sop of local reference input 0 - ---------------------------------------------------------------------------- - v_ref_sosi := in_sosi_arr_p(0); - IF v_ref_sosi.sop = '1' THEN - -- . write sync & bsn buffer - v.wr_pointer := TO_UINT(v_ref_sosi.bsn(c_blk_pointer_w-1 DOWNTO 0)); - v.sync_arr(v.wr_pointer) := v_ref_sosi.sync; - v.bsn_arr(v.wr_pointer) := v_ref_sosi.bsn(g_bsn_w-1 DOWNTO 0); - - -- . update read block pointer at g_bsn_latency_max blocks behind the reference write pointer - IF g_bsn_latency_use_node_index = FALSE THEN - v.rd_pointer := v.wr_pointer - g_bsn_latency_max; - ELSE - v.rd_pointer := v.wr_pointer - g_bsn_latency_max * node_index; - END IF; - IF v.rd_pointer < 0 THEN - v.rd_pointer := v.rd_pointer + g_buffer_nof_blocks; - END IF; - - -- . update read address of read block pointer - v_pointer_slv := TO_UVEC(v.rd_pointer, c_blk_pointer_w); - v_product_slv := MULT_UVEC(v_pointer_slv, c_block_size_slv); - v.rd_offset := RESIZE_UVEC(v_product_slv, c_mem_ram.adr_w); - - -- . issue mm_sosi, if there is output ready to be read, indicated by filled reference block - IF r.filled_arr(0)(v.rd_pointer) = '1' THEN - v.mm_sosi.sop := '1'; - v.mm_sosi.eop := '1'; - v.mm_sosi.valid := '1'; - -- . pass on timestamp information - v.mm_sosi.sync := v.sync_arr(v.rd_pointer); - v.mm_sosi.bsn := RESIZE_DP_BSN(v.bsn_arr(v.rd_pointer)); - -- . pass on filled flags for enabled streams via channel field, and - -- determine whether the ouput has to insert filler data - v.mm_sosi.channel := (OTHERS=>'0'); - FOR I IN 0 TO g_nof_streams-1 LOOP - v_filler_flag := NOT v.filled_arr(I)(v.rd_pointer); - IF stream_en_arr(I) = '1' THEN -- use MM bit at sop - v.use_filler_data(I) := v_filler_flag; -- enabled stream - v.mm_sosi.channel(I) := v_filler_flag; - ELSE - v.use_filler_data(I) := '1'; -- disabled stream - END IF; - END LOOP; - END IF; - - -- . clear filled flags, after mm_sosi was issued, or could have been issued - FOR I IN 0 TO g_nof_streams-1 LOOP - v.filled_arr(I)(v.rd_pointer) := '0'; - END LOOP; - END IF; - - ---------------------------------------------------------------------------- - -- p_read - ---------------------------------------------------------------------------- - - -- Read the data from the buffer, or replace a block by filler data - -- . default use input data from the circular buffer - v.fill_cipo_arr := rd_cipo_arr; - -- . if necessary, replace a stream by filler data - FOR I IN 0 TO g_nof_streams-1 LOOP - IF r.use_filler_data(I) = '1' THEN - v.fill_cipo_arr(I).rddata := TO_MEM_SDATA(g_filler_value); - END IF; - END LOOP; - - IF g_use_mm_output THEN - -------------------------------------------------------------------------- - -- Do the output via the MM interface - -------------------------------------------------------------------------- - -- . adjust the rd address to the current buffer output block - v.rd_copi := mm_copi; - v.rd_copi.address := RESIZE_MEM_ADDRESS(ADD_UVEC(r.rd_offset, mm_copi.address)); -- sum yields c_mem_ram.adr_w bits, because left operand determines width - - -- . output via MM interface - mm_cipo_arr <= v.fill_cipo_arr; - ELSE - -------------------------------------------------------------------------- - -- Do the output via the DP streaming interface - -------------------------------------------------------------------------- - -- . adjust the rd address - v.rd_copi := dp_copi; - v.rd_copi.address := RESIZE_MEM_ADDRESS(ADD_UVEC(r.rd_offset, dp_copi.address)); -- sum yields c_mem_ram.adr_w bits, because left operand determines width - - -- . hold mm_sosi.sync, bsn - IF r.mm_sosi.sop = '1' THEN - dp_sosi <= r.mm_sosi; - END IF; - - -- apply mm_sosi.sync and bsn at sop to all streams in out_sosi_arr - v_out_sosi_arr := rd_sosi_arr; -- the input data from the buffer or filler data (= v.fill_cipo_arr in streaming format) - IF rd_sosi_arr(0).sop = '1' THEN - v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, dp_sosi.sync, "SYNC"); - v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, dp_sosi.bsn, "BSN"); - v.out_bsn := dp_sosi.bsn(g_bsn_w-1 DOWNTO 0); -- hold BSN until next sop, to ease view in wave window - ELSE - -- hold BSN until next sop, to ease view in wave window - v_out_sosi_arr := func_dp_stream_arr_set(v_out_sosi_arr, r.out_bsn, "BSN"); - END IF; - - -- . output via DP streaming interface - out_sosi_arr <= v_out_sosi_arr; - END IF; - - ---------------------------------------------------------------------------- - -- next state - ---------------------------------------------------------------------------- - nxt_r <= v; - END PROCESS; - - ------------------------------------------------------------------------------ - -- Circular buffers - ------------------------------------------------------------------------------ - - gen_data_buffer : FOR I IN 0 TO g_nof_streams-1 GENERATE - u_data_buffer : ENTITY common_lib.common_ram_r_w - GENERIC MAP ( - g_ram => c_ram_buf - ) - PORT MAP ( - rst => dp_rst, - clk => dp_clk, - wr_en => r.wr_copi_arr(I).wr, - wr_adr => r.wr_copi_arr(I).address(c_ram_buf.adr_w-1 DOWNTO 0), - wr_dat => r.wr_copi_arr(I).wrdata(c_ram_buf.dat_w-1 DOWNTO 0), - rd_en => rd_copi_p.rd, - rd_adr => rd_copi_p.address(c_ram_buf.adr_w-1 DOWNTO 0), - rd_dat => rd_cipo_arr(I).rddata(c_ram_buf.dat_w-1 DOWNTO 0), - rd_val => rd_cipo_arr(I).rdval - ); - END GENERATE; - - ------------------------------------------------------------------------------ - -- MM to streaming DP - ------------------------------------------------------------------------------ - - gen_streaming_output : IF NOT g_use_mm_output GENERATE - dp_copi <= dp_copi_arr(0); - dp_done <= dp_done_arr(0); -- for viewing only - - gen_mm_to_dp : FOR I IN 0 TO g_nof_streams-1 GENERATE - u_mm_to_dp: ENTITY work.dp_block_from_mm - GENERIC MAP ( - g_data_size => 1, - g_step_size => 1, - g_nof_data => g_block_size, - g_data_w => g_data_w, - g_mm_rd_latency => g_rd_latency, - g_reverse_word_order => FALSE - ) - PORT MAP ( - rst => dp_rst, - clk => dp_clk, - start_pulse => r.mm_sosi.sop, - start_address => 0, - mm_done => dp_done_arr(I), - mm_mosi => dp_copi_arr(I), - mm_miso => nxt_r.fill_cipo_arr(I), - out_sosi => rd_sosi_arr(I), - out_siso => c_dp_siso_rdy - ); - END GENERATE; - END GENERATE; - - - ------------------------------------------------------------------------------ - -- Pipelining - ------------------------------------------------------------------------------ - - -- . input - u_in_sosi_arr_p : ENTITY work.dp_pipeline_arr - GENERIC MAP ( - g_nof_streams => g_nof_streams, - g_pipeline => g_pipeline_input -- 0 for wires, > 0 for registers, - ) - PORT MAP ( - rst => dp_rst, - clk => dp_clk, - -- ST sink - snk_in_arr => in_sosi_arr, - -- ST source - src_out_arr => in_sosi_arr_p - ); - - -- . read RAM - rd_copi_p <= nxt_r.rd_copi WHEN g_rd_latency = 1 ELSE r.rd_copi; - -END rtl; diff --git a/libraries/base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd b/libraries/base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd deleted file mode 100644 index 1bc78884b78807cc69c43931d05dfc7474540e8b..0000000000000000000000000000000000000000 --- a/libraries/base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd +++ /dev/null @@ -1,224 +0,0 @@ --- -------------------------------------------------------------------------- --- Copyright 2021 --- 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: Eric Kooistra, 6 Sept 2021 --- Purpose: MMP for dp_bsn_align_v2 --- Description: --- Add MM interfaces to dp_bsn_align_v2: --- --- * Instantiates input BSN monitors when g_nof_input_bsn_monitors > 0 --- * Instantiates output BSN monitor g_use_bsn_output_monitor = TRUE --- * Define MM reg for input enable/disable control for input i: --- --- wi Bits Access Type Name --- i [0] RW boolean input_enable --- --- where i = 0:g_nof_streams-1 and input_enable '1' is on, '0' is off --- --- For more description see dp_bsn_align_v2 and --- https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+BSN+aligner+v2 - -LIBRARY IEEE, common_lib; -USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.NUMERIC_STD.ALL; -USE common_lib.common_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE work.dp_stream_pkg.ALL; - - -ENTITY mmp_dp_bsn_align_v2 IS - GENERIC ( - g_nof_streams : NATURAL; -- number of input and output streams - g_bsn_latency_max : NATURAL; -- Maximum travel latency of a remote block in number of block periods T_blk - g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node - g_block_size : NATURAL := 32; -- > 1, g_block_size=1 is not supported - g_buffer_nof_blocks : NATURAL; -- circular buffer size per input, choose ceil_pow2(1 + g_bsn_latency_max) - g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN - g_data_w : NATURAL; -- number of bits in sosi data - g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks - g_nof_clk_per_sync : NATURAL := 200*10**6; - g_nof_input_bsn_monitors : NATURAL := 0; - g_use_bsn_output_monitor : BOOLEAN := FALSE - ); - PORT ( - -- Memory-mapped clock domain - mm_rst : IN STD_LOGIC; - mm_clk : IN STD_LOGIC; - - reg_copi : IN t_mem_copi; - reg_cipo : OUT t_mem_cipo; - - reg_input_monitor_copi : IN t_mem_copi; - reg_input_monitor_cipo : OUT t_mem_cipo; - - reg_output_monitor_copi : IN t_mem_copi; - reg_output_monitor_cipo : OUT t_mem_cipo; - - -- Streaming clock domain - dp_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - - node_index : IN NATURAL := 0; -- only used when g_bsn_latency_use_node_index is TRUE - - -- Streaming input - in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - - -- Output via local MM in dp_clk domain - mm_copi : IN t_mem_copi; -- read access to output block, all output streams share same mm_copi - mm_cipo_arr : OUT t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); - mm_sosi : OUT t_dp_sosi -- streaming information that signals that an output block can be read - ); -END mmp_dp_bsn_align_v2; - - -ARCHITECTURE str OF mmp_dp_bsn_align_v2 IS - - -- Use one MM word (bit 0) per input_enable bit, similar as in dp_bsn_align_reg.vhd. - - -- TYPE t_c_mem IS RECORD - -- latency : NATURAL; -- read latency - -- adr_w : NATURAL; - -- dat_w : NATURAL; - -- nof_dat : NATURAL; -- optional, nof dat words <= 2**adr_w - -- init_sl : STD_LOGIC; -- optional, init all dat words to std_logic '0', '1' or 'X' - CONSTANT c_mm_reg : t_c_mem := (1, ceil_log2(g_nof_streams), 1, g_nof_streams, '0'); - - SIGNAL reg_wr : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0); - SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - - SIGNAL mm_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0); - -BEGIN - - u_reg : ENTITY common_lib.common_reg_r_w_dc - GENERIC MAP ( - g_cross_clock_domain => TRUE, - g_readback => FALSE, - g_reg => c_mm_reg - ) - PORT MAP ( - -- Clocks and reset - mm_rst => mm_rst, - mm_clk => mm_clk, - st_rst => dp_rst, - st_clk => dp_clk, - - -- Memory Mapped Slave in mm_clk domain - sla_in => reg_copi, - sla_out => reg_cipo, - - -- MM registers in st_clk domain - reg_wr_arr => OPEN, - reg_rd_arr => OPEN, - out_reg => reg_wr, -- readback via ST clock domain - in_reg => reg_wr - ); - - stream_en_arr <= reg_wr; - - -- Use input BSN monitors for the first g_nof_input_bsn_monitors input - -- streams, e.g. to support: - -- . only one input stream (g_nof_input_bsn_monitors = 1), or - -- . all input streams (g_nof_input_bsn_monitors = g_nof_streams). - gen_bsn_mon_input : IF g_nof_input_bsn_monitors > 0 GENERATE - u_bsn_mon_input : ENTITY work.mms_dp_bsn_monitor_v2 - GENERIC MAP ( - g_nof_streams => g_nof_input_bsn_monitors, - g_cross_clock_domain => TRUE, - g_sync_timeout => g_nof_clk_per_sync, - g_bsn_w => g_bsn_w, - g_error_bi => 0, - g_cnt_sop_w => c_word_w, - g_cnt_valid_w => c_word_w, - g_cnt_latency_w => c_word_w - ) - PORT MAP ( - -- Memory-mapped clock domain - mm_rst => mm_rst, - mm_clk => mm_clk, - reg_mosi => reg_input_monitor_copi, - reg_miso => reg_input_monitor_cipo, - - -- Streaming clock domain - dp_rst => dp_rst, - dp_clk => dp_clk, - ref_sync => in_sosi_arr(0).sync, -- local reference sync input - - in_siso_arr => (OTHERS=>c_dp_siso_rdy), - in_sosi_arr => in_sosi_arr(g_nof_input_bsn_monitors-1 DOWNTO 0) - ); - END GENERATE; - - gen_bsn_mon_output : IF g_use_bsn_output_monitor GENERATE - u_bsn_mon_output : ENTITY work.mms_dp_bsn_monitor_v2 - GENERIC MAP ( - g_nof_streams => 1, -- all outputs have same BSN monitor information - g_cross_clock_domain => TRUE, - g_sync_timeout => g_nof_clk_per_sync, - g_bsn_w => g_bsn_w, - g_error_bi => 0, - g_cnt_sop_w => c_word_w, - g_cnt_valid_w => c_word_w, - g_cnt_latency_w => c_word_w - ) - PORT MAP ( - -- Memory-mapped clock domain - mm_rst => mm_rst, - mm_clk => mm_clk, - reg_mosi => reg_output_monitor_copi, - reg_miso => reg_output_monitor_cipo, - - -- Streaming clock domain - dp_rst => dp_rst, - dp_clk => dp_clk, - ref_sync => in_sosi_arr(0).sync, -- local reference sync input - - in_siso_arr => (OTHERS=>c_dp_siso_rdy), - in_sosi_arr => mm_sosi_arr - ); - END GENERATE; - - u_bsn_align : ENTITY work.dp_bsn_align_v2 - GENERIC MAP ( - g_nof_streams => g_nof_streams, - g_bsn_latency_max => g_bsn_latency_max, - g_bsn_latency_use_node_index => g_bsn_latency_use_node_index, - g_block_size => g_block_size, - g_buffer_nof_blocks => g_buffer_nof_blocks, - g_bsn_w => g_bsn_w, - g_data_w => g_data_w, - g_filler_value => g_filler_value - ) - PORT MAP ( - dp_rst => dp_rst, - dp_clk => dp_clk, - node_index => node_index, - -- MM control - stream_en_arr => stream_en_arr, - -- Streaming input - in_sosi_arr => in_sosi_arr, - -- Output via local MM in dp_clk domain - mm_copi => mm_copi, - mm_cipo_arr => mm_cipo_arr, - mm_sosi => mm_sosi - ); - - mm_sosi <= mm_sosi_arr(0); - -END str; - diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd deleted file mode 100644 index 07a8dc23666a4e89d58ceaa9d67766bcf171ef50..0000000000000000000000000000000000000000 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd +++ /dev/null @@ -1,520 +0,0 @@ --- -------------------------------------------------------------------------- --- Copyright 2021 --- 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: Eric Kooistra, 3 Sept 2021 --- Purpose: Verify dp_bsn_align_v2 --- Description: --- Usage: --- > as 10 --- > run -all - -LIBRARY IEEE, common_lib, dp_lib; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.ALL; -USE common_lib.common_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.common_lfsr_sequences_pkg.ALL; -USE common_lib.tb_common_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE dp_lib.tb_dp_pkg.ALL; - - -ENTITY tb_dp_bsn_align_v2 IS - GENERIC ( - -- DUT - g_nof_streams : NATURAL := 2; -- number of input and output streams - g_bsn_latency_max : NATURAL := 1; -- Maximum travel latency of a remote block in number of block periods T_blk - g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node - g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported - g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN - g_data_w : NATURAL := 16; -- number of bits in sosi data - g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks - g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP - g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure - g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure - - -- TB - g_diff_delay : NATURAL := 0; - g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned - g_nof_repeat : NATURAL := 100 -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli - ); -END tb_dp_bsn_align_v2; - - -ARCHITECTURE tb OF tb_dp_bsn_align_v2 IS - - CONSTANT c_rl : NATURAL := 1; - CONSTANT c_pulse_active : NATURAL := 1; - CONSTANT c_pulse_period : NATURAL := 7; - - CONSTANT c_data_w : NATURAL := 16; - CONSTANT c_data_init : INTEGER := 0; - CONSTANT c_bsn_w : NATURAL := 16; - CONSTANT c_bsn_init : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := TO_UVEC(3, c_bsn_w); - CONSTANT c_channel_init : INTEGER := 0; - CONSTANT c_err_init : NATURAL := 247; - CONSTANT c_sync_period : NATURAL := 7; - CONSTANT c_sync_offset : NATURAL := 2; - - CONSTANT c_gap_size : NATURAL := 10; - CONSTANT c_block_period : NATURAL := g_block_size + c_gap_size; - CONSTANT c_xoff_timeout : NATURAL := c_block_period * g_bsn_latency_max * 2; -- xoff timeout to recover for next alignment attempt - CONSTANT c_sop_timeout : NATURAL := c_block_period * g_bsn_latency_max; -- sop timeout to end current aligment attempt - - CONSTANT c_event_input : NATURAL := smallest(1, g_nof_streams-1); -- select special event input at which the event will apply, use >= g_nof_streams to disable the special events - - CONSTANT c_buffer_nof_blocks : NATURAL := ceil_pow2(1 + g_bsn_latency_max); -- circular buffer size per input - - TYPE t_data_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_data_w-1 DOWNTO 0); - TYPE t_bsn_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0); - TYPE t_err_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_dp_stream_error_w-1 DOWNTO 0); - TYPE t_channel_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(c_dp_stream_channel_w-1 DOWNTO 0); - TYPE t_rl_vec_arr IS ARRAY (g_nof_streams-1 DOWNTO 0) OF STD_LOGIC_VECTOR(0 TO c_rl); - - TYPE t_tb_state IS (s_idle, s_bsn_mis_aligned, s_bsn_aligned, s_small_bsn_diff, s_large_bsn_diff, s_restore_bsn, s_disable_one_input, s_enable_inputs); - - TYPE t_reg IS RECORD - -- p_write_arr - sync : STD_LOGIC; - bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); - out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - END RECORD; - - SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL clk : STD_LOGIC := '1'; - SIGNAL rst : STD_LOGIC := '1'; - SIGNAL sl1 : STD_LOGIC := '1'; - - SIGNAL random : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences - SIGNAL pulse : STD_LOGIC; - SIGNAL pulse_en : STD_LOGIC := '1'; - - SIGNAL node_index : NATURAL := 0; - - SIGNAL in_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); - SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL in_bsn : t_bsn_arr; - SIGNAL in_data : t_data_arr; - SIGNAL in_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_eop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL in_err : t_err_arr; - SIGNAL in_channel : t_channel_arr; - - SIGNAL mm_copi_arr : t_mem_copi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi - SIGNAL mm_cipo_arr : t_mem_cipo_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_sosi : t_dp_sosi; -- streaming information that signals that an output block can be read - SIGNAL mm_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL mm_done : STD_LOGIC; - SIGNAL dut_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL tb_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL r : t_reg; - SIGNAL nxt_r : t_reg; - - SIGNAL out_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy); - SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL out_bsn : t_bsn_arr; - SIGNAL out_data : t_data_arr; - SIGNAL out_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_eop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL out_gap : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); - SIGNAL out_err : t_err_arr; - SIGNAL out_channel : t_channel_arr; - - SIGNAL tb_state : t_tb_state; - - SIGNAL verify_done_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL default_end_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL default_end : STD_LOGIC; - SIGNAL verify_dis_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL verify_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - - SIGNAL hold_out_sop : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL prev_out_ready : t_rl_vec_arr; - SIGNAL prev_out_bsn : t_bsn_arr; - SIGNAL expected_out_bsn : t_bsn_arr; - SIGNAL prev_out_data : t_data_arr; - SIGNAL expected_out_data : t_data_arr; - - SIGNAL verify_extra_end : STD_LOGIC := '0'; - SIGNAL bsn_diff : INTEGER; - SIGNAL bsn_offset : INTEGER; - SIGNAL bsn_event : STD_LOGIC := '0'; -- pulse '1' triggers a BSN offset for an input - SIGNAL bsn_event_ack_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'0'); - SIGNAL bsn_event_ack : STD_LOGIC; - SIGNAL stream_en_event : STD_LOGIC := '0'; -- pulse '1' indicates that the stream enables in stream_en_arr have been updated - SIGNAL stream_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); -- default all streams are enabled - -BEGIN - - clk <= (NOT clk) OR tb_end AFTER clk_period/2; - rst <= '1', '0' AFTER clk_period*7; - - random <= func_common_random(random) WHEN rising_edge(clk); - - proc_common_gen_duty_pulse(c_pulse_active, c_pulse_period+1, '1', rst, clk, pulse_en, pulse); - - ------------------------------------------------------------------------------ - -- DATA GENERATION - ------------------------------------------------------------------------------ - - -- Generate data path input data - gen_input : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE - p_stimuli : PROCESS - VARIABLE v_sync : STD_LOGIC := '0'; - VARIABLE v_bsn : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := c_bsn_init; - VARIABLE v_data : NATURAL := c_data_init; - VARIABLE v_channel : NATURAL := c_channel_init; - VARIABLE v_err : NATURAL := c_err_init; - VARIABLE v_diff_bsn : NATURAL := 0; - BEGIN - -- Create BSN misalignment between the input streams - v_diff_bsn := I MOD (g_diff_bsn+1); - - v_data := v_data + I; - v_bsn := INCR_UVEC(v_bsn, v_diff_bsn); - in_sosi_arr(I) <= c_dp_sosi_rst; - proc_common_wait_until_low(clk, rst); - proc_common_wait_some_cycles(clk, c_xoff_timeout*2); - - -- Create latency misalignment between the input streams - proc_common_wait_some_cycles(clk, I*g_diff_delay/g_nof_streams); - - -- Begin of stimuli - FOR R IN 0 TO g_nof_repeat-v_diff_bsn-1 LOOP - v_sync := sel_a_b(TO_UINT(v_bsn) MOD c_sync_period = c_sync_offset, '1', '0'); - proc_dp_gen_block_data(c_rl, TRUE, c_data_w, c_data_w, v_data, 0, 0, g_block_size, v_channel, v_err, v_sync, v_bsn, clk, stream_en_arr(I), in_siso_arr(I), in_sosi_arr(I)); - v_bsn := INCR_UVEC(v_bsn, 1); - v_data := v_data + g_block_size; - proc_common_wait_some_cycles(clk, c_gap_size); -- create gap between frames - END LOOP; - - -- End of default stimuli - expected_out_bsn(I) <= INCR_UVEC(v_bsn, -1); - expected_out_data(I) <= TO_UVEC(v_data-1, c_data_w); - - proc_common_wait_some_cycles(clk, 100); -- depends on stream control - default_end_arr(I) <= '1'; - verify_done_arr(I) <= '1'; - proc_common_wait_some_cycles(clk, 1); - verify_done_arr(I) <= '0'; - - -------------------------------------------------------------------------- - -- Extra - -------------------------------------------------------------------------- - - proc_common_wait_some_cycles(clk, 500); - WHILE verify_extra_end /= '1' LOOP - v_sync := sel_a_b(TO_UINT(v_bsn) MOD c_sync_period = c_sync_offset, '1', '0'); - proc_dp_gen_block_data(c_rl, TRUE, c_data_w, c_data_w, v_data, 0, 0, g_block_size, v_channel, v_err, v_sync, v_bsn, clk, stream_en_arr(I), in_siso_arr(I), in_sosi_arr(I)); - v_bsn := INCR_UVEC(v_bsn, 1); - bsn_event_ack_arr(I) <= '0'; - IF I=c_event_input AND bsn_event='1' THEN - v_bsn := INCR_UVEC(v_bsn, bsn_offset); - bsn_event_ack_arr(I) <= '1'; - END IF; - v_data := v_data + g_block_size; - proc_common_wait_some_cycles(clk, c_gap_size); -- create gap between frames - END LOOP; - - -- End of extra stimuli - expected_out_bsn(I) <= INCR_UVEC(v_bsn, -1); - expected_out_data(I) <= TO_UVEC(v_data-1, c_data_w); - - verify_done_arr(I) <= '1'; - proc_common_wait_some_cycles(clk, 1); - verify_done_arr(I) <= '0'; - WAIT; - END PROCESS; - END GENERATE; - - default_end <= vector_and(default_end_arr); - bsn_event_ack <= vector_or(bsn_event_ack_arr); - - p_special_stimuli : PROCESS - BEGIN - verify_dis_arr <= (OTHERS=>'0'); - - tb_state <= s_bsn_mis_aligned; - stream_en_event <= '0'; - stream_en_arr <= (OTHERS=>'1'); - - ---------------------------------------------------------------------------- - -- Wait until default verify test is done - ---------------------------------------------------------------------------- - - proc_common_wait_until_high(clk, default_end); - - verify_dis_arr <= (OTHERS=>'1'); - proc_common_wait_some_cycles(clk, 100); - verify_dis_arr <= (OTHERS=>'0'); - - tb_state <= s_bsn_aligned; - proc_common_wait_some_cycles(clk, 1000); - - ---------------------------------------------------------------------------- - -- Verify change in input BSN offset - ---------------------------------------------------------------------------- - - -- . enforce small BSN misalignment - tb_state <= s_small_bsn_diff; - verify_dis_arr <= (OTHERS=>'1'); - bsn_offset <= -1; - bsn_event <= '1'; - proc_common_wait_until_high(clk, bsn_event_ack); - bsn_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 1000); - verify_dis_arr <= (OTHERS=>'1'); - - -- . restore original BSN sequence - tb_state <= s_restore_bsn; - bsn_offset <= +1; - bsn_event <= '1'; - proc_common_wait_until_high(clk, bsn_event_ack); - bsn_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 1000); --- verify_dis_arr <= (OTHERS=>'1'); - - -- . enforce large BSN misalignment - tb_state <= s_large_bsn_diff; - bsn_offset <= -g_bsn_latency_max-1; - bsn_event <= '1'; - proc_common_wait_until_high(clk, bsn_event_ack); - bsn_event <= '0'; - -- expect no output, because difference remains too large, so do not restart verify_en here and leave it commented: --- proc_common_wait_some_cycles(clk, 100); --- verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 1000); - verify_dis_arr <= (OTHERS=>'1'); - - -- . restore original BSN sequence - tb_state <= s_restore_bsn; - bsn_offset <= g_bsn_latency_max+1; - bsn_event <= '1'; - proc_common_wait_until_high(clk, bsn_event_ack); - bsn_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 1000); - - ---------------------------------------------------------------------------- - -- Verify change in input enables - ---------------------------------------------------------------------------- - - tb_state <= s_disable_one_input; - verify_dis_arr <= (OTHERS=>'1'); - stream_en_event <= '1'; - stream_en_arr(c_event_input) <= '0'; -- switch an input off - proc_common_wait_some_cycles(clk, 1); - stream_en_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 2000); -- keep this input off for a while - - tb_state <= s_enable_inputs; - verify_dis_arr <= (OTHERS=>'1'); - stream_en_event <= '1'; - stream_en_arr(c_event_input) <= '1'; -- switch this input on - proc_common_wait_some_cycles(clk, 1); - stream_en_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 500); - - tb_state <= s_restore_bsn; - verify_dis_arr <= (OTHERS=>'1'); - bsn_offset <= bsn_diff; -- use input 0 to restore original BSN sequence for input c_event_input, that got lost due to input disable - bsn_event <= '1'; - proc_common_wait_until_high(clk, bsn_event_ack); - bsn_event <= '0'; - proc_common_wait_some_cycles(clk, 100); - verify_dis_arr <= (OTHERS=>'0'); - proc_common_wait_some_cycles(clk, 2000); - - tb_state <= s_idle; - verify_extra_end <= '1'; - proc_common_wait_some_cycles(clk, 500); - tb_end <= '1'; - WAIT; - END PROCESS; - - bsn_diff <= TO_UINT(in_sosi_arr(0).bsn) - TO_UINT(in_sosi_arr(c_event_input).bsn) WHEN rising_edge(clk) AND in_sosi_arr(0).sop='1'; - - ------------------------------------------------------------------------------ - -- DATA VERIFICATION - ------------------------------------------------------------------------------ - - gen_verify : FOR I IN g_nof_streams-1 DOWNTO 0 GENERATE - -- Verification logistics - verify_en_arr(I) <= '1' WHEN rising_edge(clk) AND verify_dis_arr(I)='0' AND stream_en_arr(I)='1' AND out_sosi_arr(I).sop='1' ELSE - '0' WHEN rising_edge(clk) AND verify_dis_arr(I)='1'; -- verify enable after first output sop - - -- Ease in_sosi_arr monitoring - in_data(I) <= in_sosi_arr(I).data(c_data_w-1 DOWNTO 0); - in_val(I) <= in_sosi_arr(I).valid; - in_sop(I) <= in_sosi_arr(I).sop; - in_eop(I) <= in_sosi_arr(I).eop; - in_err(I) <= in_sosi_arr(I).err; - in_channel(I) <= in_sosi_arr(I).channel; - in_sync(I) <= in_sosi_arr(I).sync; - in_bsn(I) <= in_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); - - -- Ease out_sosi_arr monitoring and verification - out_data(I) <= out_sosi_arr(I).data(c_data_w-1 DOWNTO 0); - out_val(I) <= out_sosi_arr(I).valid; - out_sop(I) <= out_sosi_arr(I).sop; - out_eop(I) <= out_sosi_arr(I).eop; - out_err(I) <= out_sosi_arr(I).err; - out_channel(I) <= out_sosi_arr(I).channel; - out_sync(I) <= out_sosi_arr(I).sync; - out_bsn(I) <= out_sosi_arr(I).bsn(c_bsn_w-1 DOWNTO 0); - - -- Actual verification of the output streams - -- . Verify that the output valid fits with the output ready latency - proc_dp_verify_valid(c_rl, clk, verify_en_arr(I), out_siso_arr(I).ready, prev_out_ready(I), out_val(I)); - -- . Verify that sop and eop come in pairs - proc_dp_verify_sop_and_eop(clk, out_val(I), out_sop(I), out_eop(I), hold_out_sop(I)); - - -- . Verify that the output is incrementing, like the input stimuli - proc_dp_verify_data("out_sosi.data", c_rl, clk, verify_en_arr(I), out_siso_arr(I).ready, out_val(I), out_data(I), prev_out_data(I)); - proc_dp_verify_data("out_sosi.bsn", c_rl, clk, verify_en_arr(I), out_siso_arr(I).ready, out_sop(I), out_bsn(I), prev_out_bsn(I)); - - -- . Verify that the stimuli have been applied at all - proc_dp_verify_value(e_equal, clk, verify_done_arr(I), expected_out_data(I), prev_out_data(I)); - proc_dp_verify_value(e_equal, clk, verify_done_arr(I), expected_out_bsn(I), prev_out_bsn(I)); - END GENERATE; - - - ------------------------------------------------------------------------------ - -- DUT - ------------------------------------------------------------------------------ - - u_bsn_align : ENTITY work.dp_bsn_align_v2 - GENERIC MAP ( - g_nof_streams => g_nof_streams, - g_bsn_latency_max => g_bsn_latency_max, - g_bsn_latency_use_node_index => g_bsn_latency_use_node_index, - g_node_index_max => 31, -- limit to functional 5 bit range, instead of full 31 bit NATURAL range - g_block_size => g_block_size, - g_buffer_nof_blocks => c_buffer_nof_blocks, - g_bsn_w => g_bsn_w, - g_data_w => g_data_w, - g_filler_value => g_filler_value, - g_use_mm_output => g_use_mm_output, -- output via MM or via streaming DP - g_pipeline_input => g_pipeline_input, -- >= 0, choose 0 for wires, choose 1 to ease timing closure - g_rd_latency => g_rd_latency -- 1 or 2, choose 2 to ease timing closure - ) - PORT MAP ( - dp_rst => rst, - dp_clk => clk, - -- Control - node_index => node_index, - stream_en_arr => stream_en_arr, - -- Streaming input - in_sosi_arr => in_sosi_arr, - -- Output via local MM interface in dp_clk domain - mm_copi => mm_copi, - mm_cipo_arr => mm_cipo_arr, - mm_sosi => mm_sosi, - - -- Output via streaming DP interface - out_sosi_arr => dut_sosi_arr - ); - - ------------------------------------------------------------------------------ - -- MM to streaming DP - ------------------------------------------------------------------------------ - no_use_mm_output : IF NOT g_use_mm_output GENERATE - out_sosi_arr <= dut_sosi_arr; - END GENERATE; - - gen_use_mm_output : IF g_use_mm_output GENERATE - mm_copi <= mm_copi_arr(0); - mm_done <= mm_done_arr(0); -- for viewing only - - gen_mm_to_dp : FOR I IN 0 TO g_nof_streams-1 GENERATE - u_mm_to_dp: ENTITY work.dp_block_from_mm - GENERIC MAP ( - g_data_size => 1, - g_step_size => 1, - g_nof_data => g_block_size, - g_data_w => g_data_w, - g_mm_rd_latency => g_rd_latency, - g_reverse_word_order => FALSE - ) - PORT MAP ( - rst => rst, - clk => clk, - start_pulse => mm_sosi.sop, - start_address => 0, - mm_done => mm_done_arr(I), - mm_mosi => mm_copi_arr(I), - mm_miso => mm_cipo_arr(I), - out_sosi => tb_sosi_arr(I), - out_siso => c_dp_siso_rdy - ); - END GENERATE; - - p_comb : PROCESS(r, mm_sosi, tb_sosi_arr) - VARIABLE v : t_reg; - BEGIN - v := r; - - -- hold mm_sosi.sync, bsn - IF mm_sosi.sop = '1' THEN - v.sync := mm_sosi.sync; - v.bsn := mm_sosi.bsn(g_bsn_w-1 DOWNTO 0); - END IF; - - -- apply mm_sosi.sync, bsn at sop to all streams in out_sosi_arr - v.out_sosi_arr := tb_sosi_arr; - IF tb_sosi_arr(0).sop = '1' THEN - v.out_sosi_arr := func_dp_stream_arr_set(v.out_sosi_arr, r.sync, "SYNC"); - v.out_sosi_arr := func_dp_stream_arr_set(v.out_sosi_arr, r.bsn, "BSN"); - ELSE - -- hold sosi.bsn until next sop, to easy view in wave window - FOR I IN 0 TO g_nof_streams-1 LOOP - v.out_sosi_arr(I).bsn := r.out_sosi_arr(I).bsn; - END LOOP; - END IF; - - -- next state - nxt_r <= v; - END PROCESS; - - p_reg : PROCESS(clk) - BEGIN - IF rising_edge(clk) THEN - r <= nxt_r; - END IF; - END PROCESS; - - out_sosi_arr <= nxt_r.out_sosi_arr; - END GENERATE; - -END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd deleted file mode 100644 index cdc26095fd4a2953491ecccbbc09627bb2b79faa..0000000000000000000000000000000000000000 --- a/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd +++ /dev/null @@ -1,191 +0,0 @@ --- -------------------------------------------------------------------------- --- Copyright 2021 --- 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, 6 sept 2021 --- Purpose: Verify MM part of mmp_dp_bsn_align_v2 --- Description: --- The functional part is already verified by tb_tb_dp_bsn_align_v2.vhd. --- Usage: --- > as 5 --- > run -all - -LIBRARY IEEE, common_lib, technology_lib; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.ALL; -USE common_lib.common_pkg.ALL; -USE common_lib.tb_common_pkg.ALL; -USE common_lib.common_mem_pkg.ALL; -USE common_lib.tb_common_mem_pkg.ALL; -USE common_lib.common_str_pkg.ALL; -USE work.dp_stream_pkg.ALL; -USE work.tb_dp_pkg.ALL; - -ENTITY tb_mmp_dp_bsn_align_v2 IS -END tb_mmp_dp_bsn_align_v2; - - -ARCHITECTURE tb OF tb_mmp_dp_bsn_align_v2 IS - - CONSTANT c_mm_clk_period : TIME := 40 ns; - CONSTANT c_dp_clk_period : TIME := 10 ns; - CONSTANT c_cross_clock_domain_latency : NATURAL := 20; - - CONSTANT c_report_note : BOOLEAN := FALSE; -- Use TRUE for tb debugging, else FALSE to keep Transcript window more empty - - CONSTANT c_nof_input_sync : NATURAL := 10; - CONSTANT c_nof_block_per_sync : NATURAL := 32; - CONSTANT c_block_size : NATURAL := 10; - CONSTANT c_input_gap_size : NATURAL := 3; - CONSTANT c_sim_nof_blocks : NATURAL := c_nof_block_per_sync * c_nof_input_sync; - - CONSTANT c_nof_streams : NATURAL := 2; - CONSTANT c_bsn_latency_max : NATURAL := 2; - CONSTANT c_bsn_latency_use_node_index : BOOLEAN := FALSE; - CONSTANT c_buffer_nof_blocks : NATURAL := ceil_pow2(1 + c_bsn_latency_max); - CONSTANT c_bsn_w : NATURAL := c_dp_stream_bsn_w; - CONSTANT c_data_w : NATURAL := 16; - CONSTANT c_filler_value : INTEGER := 0; - CONSTANT c_nof_clk_per_sync : NATURAL := 200*10**6; - CONSTANT c_nof_input_bsn_monitors : NATURAL := 0; - CONSTANT c_use_bsn_output_monitor : BOOLEAN := FALSE; - - SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL stimuli_end : STD_LOGIC := '0'; - - -- MM clock domain - SIGNAL mm_clk : STD_LOGIC := '1'; - SIGNAL mm_rst : STD_LOGIC := '1'; - - SIGNAL reg_copi : t_mem_copi := c_mem_copi_rst; - SIGNAL reg_cipo : t_mem_cipo; - SIGNAL reg_input_monitor_copi : t_mem_copi := c_mem_copi_rst; - SIGNAL reg_input_monitor_cipo : t_mem_cipo; - SIGNAL reg_output_monitor_copi : t_mem_copi := c_mem_copi_rst; - SIGNAL reg_output_monitor_cipo : t_mem_cipo; - - -- DP clock domain - SIGNAL dp_clk : STD_LOGIC := '1'; - SIGNAL dp_rst : STD_LOGIC := '1'; - - SIGNAL node_index : NATURAL := 0; -- only used when g_bsn_latency_use_node_index is TRUE - SIGNAL stimuli_sosi : t_dp_sosi; - SIGNAL in_sosi_arr : t_dp_sosi_arr(c_nof_streams-1 DOWNTO 0); - SIGNAL mm_copi : t_mem_copi; -- read access to output block, all output streams share same mm_copi - SIGNAL mm_cipo_arr : t_mem_cipo_arr(c_nof_streams-1 DOWNTO 0); - SIGNAL mm_sosi : t_dp_sosi; -- streaming information that signals that an output block can be read - -BEGIN - - dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2; - mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2; - dp_rst <= '1', '0' AFTER c_dp_clk_period*7; - mm_rst <= '1', '0' AFTER c_mm_clk_period*7; - - ------------------------------------------------------------------------------ - -- MM stimuli and verification - ------------------------------------------------------------------------------ - - p_stimuli_and_verify_mm : PROCESS - VARIABLE v_bsn : NATURAL; - BEGIN - proc_common_wait_until_low(dp_clk, mm_rst); - proc_common_wait_until_low(dp_clk, dp_rst); - proc_common_wait_some_cycles(mm_clk, 5); - - - --------------------------------------------------------------------------- - -- End of test - --------------------------------------------------------------------------- - proc_common_wait_until_high(dp_clk, stimuli_end); - tb_end <= '1'; - WAIT; - END PROCESS; - - ------------------------------------------------------------------------------ - -- Streaming stimuli - ------------------------------------------------------------------------------ - - -- Generate data blocks with input sync - u_stimuli : ENTITY work.dp_stream_stimuli - GENERIC MAP ( - g_sync_period => c_nof_block_per_sync, - g_err_init => 0, - g_err_incr => 0, -- do not increment, to not distract from viewing of BSN in Wave window - g_channel_init => 0, - g_channel_incr => 0, -- do not increment, to not distract from viewing of BSN in Wave window - g_nof_repeat => c_sim_nof_blocks, - g_pkt_len => c_block_size, - g_pkt_gap => c_input_gap_size - ) - PORT MAP ( - rst => dp_rst, - clk => dp_clk, - - -- Generate stimuli - src_out => stimuli_sosi, - - -- End of stimuli - tb_end => stimuli_end - ); - - in_sosi_arr <= (OTHERS => stimuli_sosi); - - ------------------------------------------------------------------------------ - -- DUT - ------------------------------------------------------------------------------ - - u_bsn_align : ENTITY work.mmp_dp_bsn_align_v2 - GENERIC MAP ( - g_nof_streams => c_nof_streams, - g_bsn_latency_max => c_bsn_latency_max, - g_bsn_latency_use_node_index => c_bsn_latency_use_node_index, - g_block_size => c_block_size, - g_buffer_nof_blocks => c_buffer_nof_blocks, - g_bsn_w => c_bsn_w, - g_data_w => c_data_w, - g_filler_value => c_filler_value, - g_nof_clk_per_sync => c_nof_clk_per_sync, - g_nof_input_bsn_monitors => c_nof_input_bsn_monitors, - g_use_bsn_output_monitor => c_use_bsn_output_monitor - ) - PORT MAP ( - mm_rst => mm_rst, - mm_clk => mm_clk, - - reg_copi => reg_copi, - reg_cipo => reg_cipo, - - reg_input_monitor_copi => reg_input_monitor_copi, - reg_input_monitor_cipo => reg_input_monitor_cipo, - - reg_output_monitor_copi => reg_output_monitor_copi, - reg_output_monitor_cipo => reg_output_monitor_cipo, - - dp_rst => dp_rst, - dp_clk => dp_clk, - - node_index => node_index, - -- Streaming input - in_sosi_arr => in_sosi_arr, - -- Output via local MM in dp_clk domain - mm_copi => mm_copi, - mm_cipo_arr => mm_cipo_arr, - mm_sosi => mm_sosi - ); - -END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd deleted file mode 100644 index bfc16dfa090c75a33227375c8429322bea4b4e30..0000000000000000000000000000000000000000 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_bsn_align_v2.vhd +++ /dev/null @@ -1,66 +0,0 @@ --- -------------------------------------------------------------------------- --- Copyright 2021 --- 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, 15 sept 2021 --- Purpose: Regression multi tb for dp_bsn_align_v2 --- Description: --- Usage: --- > as 3 --- > run -all - -LIBRARY IEEE; -USE IEEE.std_logic_1164.ALL; -USE work.tb_dp_pkg.ALL; - - -ENTITY tb_tb_dp_bsn_align_v2 IS -END tb_tb_dp_bsn_align_v2; - - -ARCHITECTURE tb OF tb_tb_dp_bsn_align_v2 IS - - CONSTANT c_block_size : NATURAL := 11; - CONSTANT c_diff_delay : NATURAL := 20; - CONSTANT c_diff_bsn : NATURAL := 3; -- g_diff_bsn = g_bsn_latency can just be aligned - CONSTANT c_bsn_latency_max : NATURAL := 1; - CONSTANT c_nof_repeat : NATURAL := 100; -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli - - SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' -BEGIN - - -- -- DUT - -- g_nof_streams : NATURAL := 2; -- number of input and output streams - -- g_bsn_latency_max : NATURAL := 1; -- Maximum travel latency of a remote block in number of block periods T_blk - -- g_bsn_latency_use_node_index : BOOLEAN := FALSE; -- FALSE for align at end node, TRUE for align at every intermediate node - -- g_block_size : NATURAL := 11; -- > 1, g_block_size=1 is not supported - -- g_bsn_w : NATURAL := c_dp_stream_bsn_w; -- number of bits in sosi BSN - -- g_data_w : NATURAL := 16; -- number of bits in sosi data - -- g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks - -- g_use_mm_output : BOOLEAN := FALSE; -- output via MM or via streaming DP - -- g_pipeline_input : NATURAL := 1; -- >= 0, choose 0 for wires, choose 1 to ease timing closure - -- g_rd_latency : NATURAL := 2; -- 1 or 2, choose 2 to ease timing closure - -- - -- -- TB - -- g_diff_delay : NATURAL := 0; - -- g_diff_bsn : NATURAL := 0; -- g_diff_bsn = g_bsn_latency_max can just be aligned - -- g_nof_repeat : NATURAL := 100 -- for constant active stream control using 1 is sufficient, use > 1 to verify longer with random stimuli - - u_mm_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, FALSE, 11, 32, 16, 0, TRUE, 0, 1, 0, 9, c_nof_repeat); - u_dp_output : ENTITY work.tb_dp_bsn_align_v2 GENERIC MAP (2, c_bsn_latency_max, FALSE, 11, 32, 16, 0, FALSE, 0, 1, 0, 9, c_nof_repeat); - -END tb;