From 88903bf6cb6bd5c54395ebaed32f28acb4b924b0 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Mon, 6 Sep 2021 16:52:36 +0200 Subject: [PATCH] Prepared dp_bsn_align_v2.vhd (still empty) and mmp_, tb_ and tb_mmp_ files, that compile but have no functionality yet. --- libraries/base/dp/hdllib.cfg | 19 +- .../base/dp/src/vhdl/dp_bsn_align_v2.vhd | 106 +++++ .../base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd | 224 +++++++++ .../base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd | 425 ++++++++++++++++++ .../dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd | 191 ++++++++ 5 files changed, 959 insertions(+), 6 deletions(-) create mode 100644 libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd create mode 100644 libraries/base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd create mode 100644 libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd create mode 100644 libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 9cc984efdd..feea37ef59 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -82,6 +82,12 @@ synth_files = src/vhdl/dp_block_from_mm.vhd src/vhdl/dp_block_from_mm_dc.vhd src/vhdl/dp_block_to_mm.vhd + src/vhdl/dp_bsn_monitor.vhd + src/vhdl/dp_bsn_monitor_reg.vhd + src/vhdl/mms_dp_bsn_monitor.vhd + src/vhdl/dp_bsn_monitor_v2.vhd + src/vhdl/dp_bsn_monitor_reg_v2.vhd + src/vhdl/mms_dp_bsn_monitor_v2.vhd src/vhdl/dp_bsn_source.vhd src/vhdl/dp_bsn_source_v2.vhd src/vhdl/dp_bsn_source_reg.vhd @@ -97,6 +103,8 @@ 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 @@ -114,12 +122,6 @@ synth_files = src/vhdl/dp_packet_dec_channel_lo.vhd src/vhdl/dp_gap.vhd src/vhdl/dp_mon.vhd - src/vhdl/dp_bsn_monitor.vhd - src/vhdl/dp_bsn_monitor_reg.vhd - src/vhdl/mms_dp_bsn_monitor.vhd - src/vhdl/dp_bsn_monitor_v2.vhd - src/vhdl/dp_bsn_monitor_reg_v2.vhd - src/vhdl/mms_dp_bsn_monitor_v2.vhd src/vhdl/dp_distribute.vhd src/vhdl/dp_ram_from_mm.vhd src/vhdl/dp_ram_from_mm_reg.vhd @@ -210,6 +212,8 @@ 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 @@ -294,6 +298,7 @@ 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 + #src/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 @@ -364,6 +369,8 @@ regression_test_vhdl = 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_mmp_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 new file mode 100644 index 0000000000..b3ea7dc99f --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd @@ -0,0 +1,106 @@ +-- -------------------------------------------------------------------------- +-- 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. +-- +-- 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_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 + ); + PORT ( + 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 + + -- MM control + in_en_arr : IN STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + + -- 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_copi : IN t_mem_copi; -- read access to output block, all output streams share same mm_copi + mm_cipo_arr : OUT t_mem_copi_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 dp_bsn_align_v2; + + +ARCHITECTURE rtl OF dp_bsn_align_v2 IS + + TYPE t_reg IS RECORD + a : STD_LOGIC; + b : NATURAL; + END RECORD; + + CONSTANT c_reg_rst : t_reg := ('0', 0); + + -- Local registers + SIGNAL r : t_reg; + SIGNAL nxt_r : t_reg; + +BEGIN + + p_clk: 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; + + + + +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 new file mode 100644 index 0000000000..69c94300e6 --- /dev/null +++ b/libraries/base/dp/src/vhdl/mmp_dp_bsn_align_v2.vhd @@ -0,0 +1,224 @@ +-- -------------------------------------------------------------------------- +-- 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_copi_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 in_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 + ); + + in_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 + in_en_arr => in_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 new file mode 100644 index 0000000000..1fcccb9e61 --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd @@ -0,0 +1,425 @@ +-- -------------------------------------------------------------------------- +-- 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 := 17; -- > 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; -- number of bits in sosi data + g_filler_value : INTEGER := 0; -- output sosi data value for missing input blocks + + -- TB + g_diff_delay : NATURAL := 20; + g_diff_bsn : NATURAL := 3; -- 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); + + 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 : t_mem_copi; -- read access to output block, all output streams share same mm_copi + SIGNAL mm_cipo_arr : t_mem_copi_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 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 in_en_event : STD_LOGIC := '0'; -- pulse '1' indicates that the input enables in in_en_arr have been updated + SIGNAL in_en_arr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0) := (OTHERS=>'1'); -- default all inputs 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, in_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, in_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; + in_en_event <= '0'; + in_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'); + in_en_event <= '1'; + in_en_arr(c_event_input) <= '0'; -- switch an input off + proc_common_wait_some_cycles(clk, 1); + in_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'); + in_en_event <= '1'; + in_en_arr(c_event_input) <= '1'; -- switch this input on + proc_common_wait_some_cycles(clk, 1); + in_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 in_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_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 + ) + PORT MAP ( + dp_rst => rst, + dp_clk => clk, + -- Control + node_index => node_index, + in_en_arr => in_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 + ); + +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 new file mode 100644 index 0000000000..e9003e6c0d --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_mmp_dp_bsn_align_v2.vhd @@ -0,0 +1,191 @@ +-- -------------------------------------------------------------------------- +-- 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_copi_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; -- GitLab