diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 39ca669c8f184bc1e880bf341840641e720fd402..cef1f9dee76adb58239f003d87201c74c4bac9a9 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -31,6 +31,7 @@ synth_files = src/vhdl/dp_pipeline_ready.vhd src/vhdl/dp_block_resize.vhd src/vhdl/dp_block_select.vhd + src/vhdl/dp_block_validate_channel.vhd src/vhdl/mms_dp_block_select.vhd src/vhdl/dp_force_data_parallel.vhd src/vhdl/mms_dp_force_data_parallel.vhd @@ -198,6 +199,7 @@ test_bench_files = tb/vhdl/tb_dp_block_gen.vhd tb/vhdl/tb_dp_block_gen_valid_arr.vhd tb/vhdl/tb_dp_block_from_mm.vhd + 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_monitor.vhd @@ -277,6 +279,7 @@ test_bench_files = tb/vhdl/tb_tb_dp_block_gen.vhd 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.vhd tb/vhdl/tb_tb_dp_bsn_source_v2.vhd tb/vhdl/tb_tb_dp_concat.vhd @@ -342,6 +345,7 @@ regression_test_vhdl = tb/vhdl/tb_tb_dp_block_gen.vhd 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.vhd tb/vhdl/tb_tb_dp_bsn_source_v2.vhd tb/vhdl/tb_tb_dp_concat.vhd diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_channel.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_channel.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e833f544fc370ec9ca50e407c4445b432e7ae735 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_block_validate_channel.vhd @@ -0,0 +1,133 @@ +------------------------------------------------------------------------------- +-- +-- 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: R vd Walle +-- Purpose: +-- The dp_block_validate_channel.vhd can remove a block of data from a +-- multiplexed in_sosi stream based on the in_sosi.channel field. +-- If in_sosi.channel = g_remove_channel, then the in_sosi is passed on to +-- remove_sosi and not passed on to keep_sosi, else vice versa. +-- Other modes can be selected by setting g_mode. g_mode options are: +-- . "=" which removes all blocks with channel = g_remove_channel +-- . "<" which removes all blocks with channel < g_remove_channel +-- . ">" which removes all blocks with channel > g_remove_channel +-- Remarks: + +LIBRARY IEEE, common_lib; +USE IEEE.std_logic_1164.all; +USE IEEE.numeric_std.all; +USE work.dp_stream_pkg.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; + +ENTITY dp_block_validate_channel IS + GENERIC ( + g_remove_channel : NATURAL := 0; + g_mode : STRING := "=" -- can be "=", "<", ">" + ); + PORT ( + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + -- ST sink + in_sosi : IN t_dp_sosi; + -- ST source + out_keep_sosi : OUT t_dp_sosi; + out_remove_sosi : OUT t_dp_sosi + + ); +END dp_block_validate_channel; + +ARCHITECTURE rtl OF dp_block_validate_channel IS + + SIGNAL remove_blk : STD_LOGIC; + SIGNAL remove_blk_reg : STD_LOGIC := '0'; + SIGNAL remove_sosi : t_dp_sosi; + SIGNAL keep_sosi : t_dp_sosi; + +BEGIN + + ASSERT g_mode = "=" OR g_mode = "<" OR g_mode = ">" REPORT "g_mode must be one of three options: '=', '<' or '>'" SEVERITY ERROR; + gen_equal : IF g_mode = "=" GENERATE -- remove all blocks with ch = g_remove_channel + remove_blk <= remove_blk_reg WHEN in_sosi.sop = '0' ELSE + '1' WHEN TO_UINT(in_sosi.channel) = g_remove_channel ELSE '0'; + END GENERATE; + gen_smaller : IF g_mode = "<" GENERATE -- remove all blocks with ch < g_remove_channel + remove_blk <= remove_blk_reg WHEN in_sosi.sop = '0' ELSE + '1' WHEN TO_UINT(in_sosi.channel) < g_remove_channel ELSE '0'; + END GENERATE; + gen_larger : IF g_mode = ">" GENERATE -- remove all blocks with ch > g_remove_channel + remove_blk <= remove_blk_reg WHEN in_sosi.sop = '0' ELSE + '1' WHEN TO_UINT(in_sosi.channel) > g_remove_channel ELSE '0'; + END GENERATE; + + p_dp_clk : PROCESS(dp_rst, dp_clk) + BEGIN + IF dp_rst='1' THEN + remove_blk_reg <= '0'; + ELSIF rising_edge(dp_clk) THEN + remove_blk_reg <= remove_blk; + END IF; + END PROCESS; + + p_sosi : PROCESS(in_sosi, remove_blk) + BEGIN + -- sosi that contains the removed blocks + remove_sosi <= in_sosi; + remove_sosi.valid <= in_sosi.valid AND remove_blk; + remove_sosi.sop <= in_sosi.sop AND remove_blk; + remove_sosi.eop <= in_sosi.eop AND remove_blk; + remove_sosi.sync <= in_sosi.sync AND remove_blk; + -- sosi that contains the all but the removed blocks + keep_sosi <= in_sosi; + keep_sosi.valid <= in_sosi.valid AND NOT remove_blk; + keep_sosi.sop <= in_sosi.sop AND NOT remove_blk; + keep_sosi.eop <= in_sosi.eop AND NOT remove_blk; + keep_sosi.sync <= in_sosi.sync AND NOT remove_blk; + + END PROCESS; + + u_pipe_remove : ENTITY work.dp_pipeline + GENERIC MAP ( + g_pipeline => 1 -- 0 for wires, > 0 for registers, + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + -- ST sink + snk_in => remove_sosi, + -- ST source + src_out => out_remove_sosi + ); + + u_pipe_keep : ENTITY work.dp_pipeline + GENERIC MAP ( + g_pipeline => 1 -- 0 for wires, > 0 for registers, + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + -- ST sink + snk_in => keep_sosi, + -- ST source + src_out => out_keep_sosi + ); + +END rtl; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_channel.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_channel.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0319f451ddeb77a4aaa2fbdec7a3a38e7f0ca094 --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_channel.vhd @@ -0,0 +1,192 @@ + +------------------------------------------------------------------------------- +-- +-- 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: R vd Walle +-- Purpose: +-- Test bench for dp_block_validate_channel. +-- Description: +-- Verifies the output sosi of the DUT with the expected sosi. +-- The TB also reads the register values via MM and verifies them against the +-- expected values. +-- Usage: +-- . as 5 +-- . run -all + +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 common_lib.tb_common_mem_pkg.ALL; +USE common_lib.common_str_pkg.ALL; +USE common_lib.common_lfsr_sequences_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE work.dp_stream_pkg.ALL; +USE work.tb_dp_pkg.ALL; + +ENTITY tb_dp_block_validate_channel IS + GENERIC ( + g_nof_blocks_per_sync : NATURAL := 8; + g_nof_data_per_blk : NATURAL := 8; + g_gap_size : NATURAL := 5; + g_remove_channel : NATURAL := 0; + g_mode : STRING := "=" + ); +END tb_dp_block_validate_channel; + + +ARCHITECTURE tb OF tb_dp_block_validate_channel IS + + ------------------------------------------------------------------------------ + -- Clock & reset + ------------------------------------------------------------------------------ + CONSTANT c_dp_clk_period : TIME := 5 ns; + CONSTANT c_mm_clk_period : TIME := 10 ns; + + CONSTANT c_dut_pipeline : NATURAL := 1; + CONSTANT c_nof_sync : NATURAL := 5; + CONSTANT c_nof_blk : NATURAL := g_nof_blocks_per_sync * c_nof_sync; + + SIGNAL dp_clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC := '1'; + SIGNAL tb_end : STD_LOGIC := '0'; + + SIGNAL stimuli_end : STD_LOGIC; + SIGNAL stimuli_sosi : t_dp_sosi; + SIGNAL stimuli_siso : t_dp_siso := c_dp_siso_rdy; + SIGNAL keep_sosi : t_dp_sosi; + SIGNAL remove_sosi : t_dp_sosi; + SIGNAL reference_sosi : t_dp_sosi; + SIGNAL reference_siso : t_dp_siso := c_dp_siso_rdy; +BEGIN + + ------------------------------------------------------------------------------ + -- Clock & reset + ------------------------------------------------------------------------------ + dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2; + rst <= '1', '0' AFTER c_dp_clk_period*7; + + ------------------------------------------------------------------------------ + -- Stimuli: + ------------------------------------------------------------------------------ + + -- Generate snk_in with data frames + u_stimuli : ENTITY work.dp_stream_stimuli + GENERIC MAP ( + g_sync_period => g_nof_blocks_per_sync, + g_nof_repeat => g_nof_blocks_per_sync * c_nof_sync, + g_pkt_len => g_nof_data_per_blk, + g_pkt_gap => g_gap_size + ) + PORT MAP ( + rst => rst, + clk => dp_clk, + + -- Generate stimuli + src_in => stimuli_siso, + src_out => stimuli_sosi, + + -- End of stimuli + tb_end => stimuli_end + ); + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + u_dut : ENTITY work.dp_block_validate_channel + GENERIC MAP ( + g_remove_channel => g_remove_channel, + g_mode => g_mode + ) + PORT MAP ( + dp_rst => rst, + dp_clk => dp_clk, + + -- ST sink + in_sosi => stimuli_sosi, + -- ST source + out_keep_sosi => keep_sosi, + out_remove_sosi => remove_sosi + ); + + + ------------------------------------------------------------------------------ + -- Verification + ------------------------------------------------------------------------------ + + u_pipeline : ENTITY work.dp_pipeline + GENERIC MAP ( + g_pipeline => c_dut_pipeline + ) + PORT MAP ( + rst => rst, + clk => dp_clk, + -- ST sink + snk_out => OPEN, + snk_in => stimuli_sosi, + -- ST source + src_in => reference_siso, + src_out => reference_sosi + ); + + p_verify : PROCESS(dp_clk) + BEGIN + IF rising_edge(dp_clk) THEN + IF reference_sosi.valid = '1' THEN + IF TO_UINT(reference_sosi.channel) = g_remove_channel AND g_mode = "=" THEN + ASSERT remove_sosi = reference_sosi REPORT "remove_sosi does not contain removed block!" SEVERITY ERROR; + ASSERT keep_sosi.valid = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.sop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.eop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ELSIF g_mode = "=" THEN + ASSERT keep_sosi = reference_sosi REPORT "No block in keep_sosi" SEVERITY ERROR; + ASSERT remove_sosi.valid = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.sop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.eop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ELSIF TO_UINT(reference_sosi.channel) < g_remove_channel AND g_mode = "<" THEN + ASSERT remove_sosi = reference_sosi REPORT "remove_sosi does not contain removed block!" SEVERITY ERROR; + ASSERT keep_sosi.valid = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.sop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.eop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ELSIF g_mode = "<" THEN + ASSERT keep_sosi = reference_sosi REPORT "No block in keep_sosi" SEVERITY ERROR; + ASSERT remove_sosi.valid = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.sop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.eop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ELSIF TO_UINT(reference_sosi.channel) > g_remove_channel AND g_mode = ">" THEN + ASSERT remove_sosi = reference_sosi REPORT "remove_sosi does not contain removed block!" SEVERITY ERROR; + ASSERT keep_sosi.valid = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.sop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ASSERT keep_sosi.eop = '0' REPORT "Wrong, removed block occurs in keep_sosi!" SEVERITY ERROR; + ELSIF g_mode = ">" THEN + ASSERT keep_sosi = reference_sosi REPORT "No block in keep_sosi" SEVERITY ERROR; + ASSERT remove_sosi.valid = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.sop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + ASSERT remove_sosi.eop = '0' REPORT "Wrong, block occurs in remove_sosi which is unexpected!" SEVERITY ERROR; + END IF; + END IF; + END IF; + END PROCESS; + + tb_end <= '0', stimuli_end AFTER (1 + 10*c_dut_pipeline)*c_dp_clk_period; + +END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_channel.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_channel.vhd new file mode 100644 index 0000000000000000000000000000000000000000..15847f0396dace201254fc98e352d22863e7064d --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_channel.vhd @@ -0,0 +1,55 @@ +------------------------------------------------------------------------------- +-- +-- 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: R vd Walle +-- Purpose: +-- Verify multiple variations of tb_dp_block_validate_channel +-- Usage: +-- > as 3 +-- > run -all + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + +ENTITY tb_tb_dp_block_validate_channel IS +END tb_tb_dp_block_validate_channel; + + +ARCHITECTURE tb OF tb_tb_dp_block_validate_channel IS + + SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' + + CONSTANT c_blk_per_sync : NATURAL := 5; + CONSTANT c_data_per_blk : NATURAL := 9; + CONSTANT c_gap_size : NATURAL := 5; + +BEGIN +-- g_nof_blocks_per_sync : NATURAL := 8; +-- g_nof_data_per_blk : NATURAL := 8; +-- g_gap_size : NATURAL := 5; +-- g_remove_channel : NATURAL := 0; +-- g_mode : STRING := "=" + + u_equal : ENTITY work.tb_dp_block_validate_channel GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_gap_size, 7, "="); + u_smaller : ENTITY work.tb_dp_block_validate_channel GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_gap_size, 7, "<"); + u_greater : ENTITY work.tb_dp_block_validate_channel GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_gap_size, 7, ">"); + +END tb;