diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 48865ad1dbd81ac2513b08448297ce8eb0e75d85..12f9c56edd7f921d5751fab385dcaca33cfa8365 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -36,6 +36,7 @@ synth_files = src/vhdl/dp_block_select.vhd src/vhdl/dp_block_validate_channel.vhd src/vhdl/mms_dp_block_select.vhd + src/vhdl/dp_calculate_crc.vhd src/vhdl/dp_force_data_parallel.vhd src/vhdl/mms_dp_force_data_parallel.vhd src/vhdl/mms_dp_force_data_parallel_arr.vhd @@ -215,6 +216,7 @@ test_bench_files = 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_calculate_crc.vhd tb/vhdl/tb_dp_bsn_align.vhd tb/vhdl/tb_mms_dp_bsn_align.vhd tb/vhdl/tb_dp_bsn_align_v2.vhd @@ -305,6 +307,7 @@ test_bench_files = 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_calculate_crc.vhd tb/vhdl/tb_tb_dp_bsn_align.vhd tb/vhdl/tb_tb_dp_bsn_align_v2.vhd tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd @@ -371,6 +374,7 @@ regression_test_vhdl = 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 + tb/vhdl/tb_tb_dp_calculate_crc.vhd tb/vhdl/tb_tb_dp_block_select.vhd tb/vhdl/tb_tb_dp_block_validate_length.vhd tb/vhdl/tb_tb_dp_block_validate_err.vhd diff --git a/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd b/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0d5b8f137dc334e1a872abd527375ebd853216b9 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_calculate_crc.vhd @@ -0,0 +1,116 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- + +-- Author: E. Kooistra +-- Date: 17 April 2023 +-- Purpose: Calculate CRC per block of data +-- Description: +-- The calculated blk_crc of a block is available immediately after the +-- snk_in.eop of that block. + +LIBRARY IEEE, common_lib, easics_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE work.dp_stream_pkg.ALL; + +USE easics_lib.PCK_CRC8_D8.ALL; +USE easics_lib.PCK_CRC16_D16.ALL; +USE easics_lib.PCK_CRC28_D28.ALL; +USE easics_lib.PCK_CRC32_D32.ALL; +USE easics_lib.PCK_CRC32_D64.ALL; + + +ENTITY dp_calculate_crc IS + GENERIC ( + g_data_w : NATURAL := 32; + g_crc_w : NATURAL := 32 + ); + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + -- ST sink + snk_in : IN t_dp_sosi; + blk_crc : OUT STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0) + ); +END dp_calculate_crc; + + +ARCHITECTURE rtl OF dp_calculate_crc IS + + CONSTANT c_crc_init : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0) := (OTHERS=>'1'); + + FUNCTION func_next_crc(data, crc : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS + VARIABLE v_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0) := c_crc_init; + BEGIN + IF g_data_w = 8 AND g_crc_w = 8 THEN v_crc := nextCRC8_D8(data, crc); + ELSIF g_data_w = 16 AND g_crc_w = 16 THEN v_crc := nextCRC16_D16(data, crc); + ELSIF g_data_w = 28 AND g_crc_w = 28 THEN v_crc := nextCRC28_D28(data, crc); + ELSIF g_data_w = 32 AND g_crc_w = 32 THEN v_crc := nextCRC32_D32(data, crc); + ELSIF g_data_w = 64 AND g_crc_w = 32 THEN v_crc := nextCRC32_D64(data, crc); + ELSE + REPORT "Data width and CRC width combination not supported (yet)" SEVERITY FAILURE; + END IF; + RETURN v_crc; + END func_next_crc; + + SIGNAL data : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0); + SIGNAL calc_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + SIGNAL nxt_calc_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + SIGNAL i_blk_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + SIGNAL nxt_blk_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + +BEGIN + + data <= snk_in.data(g_data_w-1 DOWNTO 0); + + blk_crc <= i_blk_crc; + + p_clk : PROCESS(rst, clk) + BEGIN + IF rst='1' THEN + calc_crc <= c_crc_init; + i_blk_crc <= c_crc_init; + ELSIF rising_edge(clk) THEN + calc_crc <= nxt_calc_crc; + i_blk_crc <= nxt_blk_crc; + END IF; + END PROCESS; + + p_crc : PROCESS(data, calc_crc, i_blk_crc, snk_in) + VARIABLE v_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + BEGIN + v_crc := func_next_crc(data, calc_crc); + + -- Calculate CRC per block + nxt_calc_crc <= calc_crc; + IF snk_in.sop = '1' THEN -- restart CRC at begin of block + nxt_calc_crc <= func_next_crc(data, c_crc_init); + ELSIF snk_in.valid = '1' THEN -- calculate CRC during block + nxt_calc_crc <= v_crc; + END IF; + + -- Hold CRC of previous block, available after eop + nxt_blk_crc <= i_blk_crc; + IF snk_in.eop = '1' THEN + nxt_blk_crc <= v_crc; + END IF; + END PROCESS; + +END rtl; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd b/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4af23cbdfa3aca5f9a2dca7bc319a8df55f1b794 --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_dp_calculate_crc.vhd @@ -0,0 +1,154 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra +-- Date: 17 Apr 2023 +-- Purpose: +-- . Test bench for dp_calculate_crc. +-- Description: +-- Verify that CRC is the same if the data in the blocks is the same, for +-- one specific combination of g_data_w, g_crc_w and c_nof_data_per_blk. +-- Assume that CRC calculation itself is OK, because it is used before. +-- 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_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_calculate_crc IS + GENERIC ( + g_data_w : NATURAL := 28; + g_crc_w : NATURAL := 28; + g_gap_size : NATURAL := 10 + ); +END tb_dp_calculate_crc; + + +ARCHITECTURE tb OF tb_dp_calculate_crc IS + + ------------------------------------------------------------------------------ + -- Clock & reset + ------------------------------------------------------------------------------ + CONSTANT c_clk_period : TIME := 5 ns; + + CONSTANT c_nof_sync : NATURAL := 1; + CONSTANT c_nof_blk_per_sync : NATURAL := 5; + CONSTANT c_nof_data_per_blk : NATURAL := 9; + + SIGNAL clk : STD_LOGIC := '1'; + SIGNAL rst : STD_LOGIC := '1'; + SIGNAL stimuli_end : STD_LOGIC := '0'; + SIGNAL tb_end : STD_LOGIC := '0'; + + SIGNAL stimuli_sosi : t_dp_sosi; + SIGNAL snk_in : t_dp_sosi; + + SIGNAL blk_crc : STD_LOGIC_VECTOR(g_crc_w-1 DOWNTO 0); + + SIGNAL new_crc : STD_LOGIC; + + -- Expected specific value obtained from simulation + SIGNAL exp_crc_28 : STD_LOGIC_VECTOR(28-1 DOWNTO 0) := X"ABDE9EB"; + +BEGIN + + ------------------------------------------------------------------------------ + -- Clock & reset + ------------------------------------------------------------------------------ + clk <= (NOT clk) OR tb_end AFTER c_clk_period/2; + rst <= '1', '0' AFTER c_clk_period*7; + + ------------------------------------------------------------------------------ + -- Stimuli: + ------------------------------------------------------------------------------ + + -- Generate snk_in with data frames + u_stimuli : ENTITY work.dp_stream_stimuli + GENERIC MAP ( + g_sync_period => c_nof_blk_per_sync, + g_nof_repeat => c_nof_blk_per_sync * c_nof_sync, + g_pkt_len => c_nof_data_per_blk, + g_pkt_gap => g_gap_size + ) + PORT MAP ( + rst => rst, + clk => clk, + + -- Generate stimuli + src_out => stimuli_sosi, + + -- End of stimuli + tb_end => stimuli_end + ); + + -- Use same dat for every block to verify restart of CRC calculation + p_snk_in : PROCESS(stimuli_sosi) + BEGIN + snk_in <= stimuli_sosi; + snk_in.data <= TO_DP_DATA(TO_UINT(stimuli_sosi.data) MOD c_nof_data_per_blk); + END PROCESS; + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + u_crc : ENTITY work.dp_calculate_crc + GENERIC MAP ( + g_data_w => g_data_w, + g_crc_w => g_crc_w + ) + PORT MAP ( + rst => rst, + clk => clk, + -- ST sink + snk_in => snk_in, + blk_crc => blk_crc + ); + + ------------------------------------------------------------------------------ + -- Verifycation + ------------------------------------------------------------------------------ + new_crc <= snk_in.eop WHEN rising_edge(clk); + + p_verify : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF new_crc = '1' THEN + --IF g_data_w = 28 AND g_crc_w = 28 AND c_nof_data_per_blk = 9 THEN + IF blk_crc = exp_crc_28 THEN + REPORT "OK CRC value." SEVERITY NOTE; + ELSE + REPORT "Wrong CRC value." SEVERITY ERROR; + END IF; + --END IF; + END IF; + END IF; + END PROCESS; + + tb_end <= '0', stimuli_end AFTER 10*c_clk_period; + +END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..17713141fe5edf7b711c05a65ab6d92772e7344a --- /dev/null +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_calculate_crc.vhd @@ -0,0 +1,57 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra +-- Date: 17 Apr 2023 +-- Purpose: +-- . Multi test bench for dp_calculate_crc. +-- Description: +-- 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_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_tb_dp_calculate_crc IS +END tb_tb_dp_calculate_crc; + + +ARCHITECTURE tb OF tb_tb_dp_calculate_crc IS + + SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' + +BEGIN + + -- g_data_w : NATURAL := 28; + -- g_crc_w : NATURAL := 28; + -- g_gap_size : NATURAL := 10 + + u_no_gap : ENTITY work.tb_dp_calculate_crc GENERIC MAP (28, 28, 0); + u_gap : ENTITY work.tb_dp_calculate_crc GENERIC MAP (28, 28, 10); + +END tb; diff --git a/libraries/external/easics/hdllib.cfg b/libraries/external/easics/hdllib.cfg index d507bd6a5bb7f49cbd926d327a4d231e12a3c043..75ed2ad88540f3d415bd70b13f3efe6d2cc1fb51 100644 --- a/libraries/external/easics/hdllib.cfg +++ b/libraries/external/easics/hdllib.cfg @@ -23,15 +23,18 @@ synth_files = src/vhdl/PCK_CRC32_D20.vhd src/vhdl/PCK_CRC32_D24.vhd src/vhdl/PCK_CRC32_D32.vhd + src/vhdl/PCK_CRC32_D32_eth.vhd src/vhdl/PCK_CRC32_D36.vhd src/vhdl/PCK_CRC32_D40.vhd src/vhdl/PCK_CRC32_D48.vhd src/vhdl/PCK_CRC32_D64.vhd + src/vhdl/PCK_CRC32_D64_eth.vhd src/vhdl/PCK_CRC32_D72.vhd src/vhdl/PCK_CRC32_D128.vhd src/vhdl/PCK_CRC32_D256.vhd src/vhdl/PCK_CRC32_D512.vhd src/vhdl/PCK_CRC32_D1024.vhd + src/vhdl/PCK_CRC28_D28.vhd src/vhdl/PCK_CRC16_D4.vhd src/vhdl/PCK_CRC16_D8.vhd src/vhdl/PCK_CRC16_D9.vhd @@ -40,7 +43,11 @@ synth_files = src/vhdl/PCK_CRC16_D18.vhd src/vhdl/PCK_CRC16_D20.vhd src/vhdl/PCK_CRC16_D24.vhd + src/vhdl/PCK_CRC16_D28.vhd + src/vhdl/PCK_CRC16_D28_usb.vhd src/vhdl/PCK_CRC16_D32.vhd + src/vhdl/PCK_CRC16_D32_usb.vhd + src/vhdl/PCK_CRC16_D32_x25.vhd src/vhdl/PCK_CRC16_D36.vhd src/vhdl/PCK_CRC16_D48.vhd src/vhdl/PCK_CRC16_D64.vhd