From e9ed12fe1be809f26e5804e2b38f5de5a1e09cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sat, 15 Apr 2023 08:31:17 +0200 Subject: [PATCH] chore: remove octets_to_sample, put its behavior to transport_layer --- src/transport/octets_to_sample.vhd | 141 ------------------ src/transport/transport_layer.vhd | 118 ++++++++++++--- ...es_fc_tb.vhd => transport_layer_fc_tb.vhd} | 8 +- ...tb.vhd => transport_layer_multi_cf_tb.vhd} | 8 +- ...imp_tb.vhd => transport_layer_simp_tb.vhd} | 8 +- 5 files changed, 112 insertions(+), 171 deletions(-) delete mode 100644 src/transport/octets_to_sample.vhd rename testbench/transport/{octets_to_samples_fc_tb.vhd => transport_layer_fc_tb.vhd} (97%) rename testbench/transport/{octets_to_samples_multi_cf_tb.vhd => transport_layer_multi_cf_tb.vhd} (96%) rename testbench/transport/{octets_to_samples_simp_tb.vhd => transport_layer_simp_tb.vhd} (97%) diff --git a/src/transport/octets_to_sample.vhd b/src/transport/octets_to_sample.vhd deleted file mode 100644 index 420da8ff28cdb9e89d9bf67b355204edf8723f26..0000000000000000000000000000000000000000 --- a/src/transport/octets_to_sample.vhd +++ /dev/null @@ -1,141 +0,0 @@ -------------------------------------------------------------------------------- --- Title : octets to samples mapping -------------------------------------------------------------------------------- --- File : octets_to_sample.vhd -------------------------------------------------------------------------------- --- Description: Maps octets from lanes from data link to samples. --- In case of any error in the data, last frame will be streamed again. --- The data from wrong frame will be dropped. -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use work.data_link_pkg.all; -use work.transport_pkg.all; - -entity octets_to_samples is - generic ( - CS : integer := 1; -- Number of control bits per sample - M : integer := 1; -- Number of converters - S : integer := 1; -- Number of samples - L : integer := 1; -- Number of lanes - F : integer := 2; -- Number of octets in a frame - CF : integer := 0; -- Number of control words - N : integer := 12; -- Size of a sample - Nn : integer := 16); -- Size of a word (sample + ctrl if CF - -- =0 - port ( - ci_frame_clk : in std_logic; -- Frame clock - ci_reset : in std_logic; -- Reset (asynchronous, active low) - di_lanes_data : in lane_character_array(0 to L-1)(F*8-1 downto 0); -- Data from the lanes - -- bits - ci_frame_states : in frame_state_array(0 to L-1); - co_frame_state : out frame_state; - do_samples_data : out samples_array(0 to M - 1, 0 to S - 1)); -- The - -- output samples -end entity octets_to_samples; - -architecture a1 of octets_to_samples is - signal samples_data : samples_array - (0 to M - 1, 0 to S - 1) - (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); - signal prev_samples_data : samples_array - (0 to M - 1, 0 to S - 1) - (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); - signal next_samples_data : samples_array - (0 to M - 1, 0 to S - 1) - (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); - signal reg_error : std_logic; -- if err, repeat last samples. - signal current_frame_state : frame_state; - - signal reg_buffered_data : std_logic_vector(L*F*8-1 downto 0) := (others => '0'); - signal reg_state_user_data : std_logic_vector(L-1 downto 0); - signal reg_state_invalid_character : std_logic_vector(L-1 downto 0); - signal reg_state_not_enough_data : std_logic_vector(L-1 downto 0); - signal reg_state_ring_buffer_overflow : std_logic_vector(L-1 downto 0); - signal reg_state_disparity_error : std_logic_vector(L-1 downto 0); - signal reg_state_not_in_table_error : std_logic_vector(L-1 downto 0); - signal reg_state_wrong_alignment : std_logic_vector(L-1 downto 0); - signal reg_state_last_frame_repeated : std_logic_vector(L-1 downto 0); - - signal any_error : std_logic := '0'; - - constant all_ones : std_logic_vector(L-1 downto 0) := (others => '1'); - constant all_zeros : std_logic_vector(L-1 downto 0) := (others => '0'); -begin -- architecture a - set_data: process (ci_frame_clk, ci_reset) is - begin -- process set_data - if ci_reset = '0' then -- asynchronous reset (active low) - reg_error <= '0'; - reg_buffered_data <= (others => '0'); - elsif ci_frame_clk'event and ci_frame_clk = '1' then -- rising clock edge - do_samples_data <= next_samples_data; - co_frame_state <= current_frame_state; - - if any_error = '0' then - prev_samples_data <= samples_data; - end if; - - for i in 0 to L-1 loop - reg_buffered_data(L*F*8 - 1 - i*F*8 downto L*F*8 - (i + 1)*F*8) <= di_lanes_data(i); - reg_state_user_data(i) <= ci_frame_states(i).user_data; - reg_state_invalid_character(i) <= ci_frame_states(i).invalid_characters; - reg_state_not_enough_data(i) <= ci_frame_states(i).not_enough_data; - reg_state_ring_buffer_overflow(i) <= ci_frame_states(i).ring_buffer_overflow; - reg_state_disparity_error(i) <= ci_frame_states(i).disparity_error; - reg_state_not_in_table_error(i) <= ci_frame_states(i).not_in_table_error; - reg_state_wrong_alignment(i) <= ci_frame_states(i).wrong_alignment; - reg_state_last_frame_repeated(i) <= ci_frame_states(i).last_frame_repeated; - end loop; -- i - end if; - end process set_data; - - -- set output error in case any lane has an error - current_frame_state.user_data <= '1' when reg_state_user_data = all_ones else '0'; - current_frame_state.invalid_characters <= '0' when reg_state_invalid_character = all_zeros else '1'; - current_frame_state.not_enough_data <= '0' when reg_state_not_enough_data = all_zeros else '1'; - current_frame_state.ring_buffer_overflow <= '0' when reg_state_ring_buffer_overflow = all_zeros else '1'; - current_frame_state.disparity_error <= '0' when reg_state_disparity_error = all_zeros else '1'; - current_frame_state.not_in_table_error <= '0' when reg_state_not_in_table_error = all_zeros else '1'; - current_frame_state.wrong_alignment <= '0' when reg_state_wrong_alignment = all_zeros else '1'; - current_frame_state.last_frame_repeated <= '1' when any_error = '1' else '0'; - - any_error <= '1' when current_frame_state.invalid_characters = '1' or - current_frame_state.not_enough_data = '1' or - current_frame_state.ring_buffer_overflow = '1' or - current_frame_state.disparity_error = '1' or - current_frame_state.not_in_table_error = '1' or - current_frame_state.wrong_alignment = '1' else '0'; - next_samples_data <= samples_data when any_error = '0' else prev_samples_data; - - -- for one or multiple lanes if CF = 0 - -- (no control words) - -- (control chars are right after sample) - multi_lane_no_cf: if CF = 0 generate - converters: for ci in 0 to M - 1 generate - samples: for si in 0 to S - 1 generate - samples_data(ci, si).data <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn downto L*F*8 - 1 - ci*Nn*S - si*Nn - N + 1); - - control_bits: if CS > 0 generate - samples_data(ci, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn - N downto L*F*8 - 1 - ci*Nn*S - si*Nn - N - CS + 1); - end generate control_bits; - end generate samples; - end generate converters; - end generate multi_lane_no_cf; - - -- for one or mutliple lanes if CF != 0 - -- (control words are present) - multi_lane_cf: if CF > 0 generate - cf_groups: for cfi in 0 to CF-1 generate - converters: for ci in 0 to M/CF-1 generate - samples: for si in 0 to S - 1 generate - samples_data(ci + cfi*M/CF, si).data <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn downto L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn - N + 1); - - control_bits: if CS > 0 generate - samples_data(ci + cfi*M/CF, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*S*Nn - ci*S*CS - si*CS downto L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*Nn*S - ci*S*CS - si*CS - CS + 1); - end generate control_bits; - end generate samples; - end generate converters; - end generate cf_groups; - end generate multi_lane_cf; -end architecture a1; diff --git a/src/transport/transport_layer.vhd b/src/transport/transport_layer.vhd index 56deacee43babeef6a2a6c156e1c4239367ff2a0..2d7b583f817f0216e68761902a5ac7db9acbb21a 100644 --- a/src/transport/transport_layer.vhd +++ b/src/transport/transport_layer.vhd @@ -34,25 +34,107 @@ entity transport_layer is end entity transport_layer; architecture a1 of transport_layer is + signal samples_data : samples_array + (0 to M - 1, 0 to S - 1) + (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); + signal prev_samples_data : samples_array + (0 to M - 1, 0 to S - 1) + (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); + signal next_samples_data : samples_array + (0 to M - 1, 0 to S - 1) + (data(N - 1 downto 0), ctrl_bits(CS - 1 downto 0)); + signal reg_error : std_logic; -- if err, repeat last samples. + signal current_frame_state : frame_state; + + signal reg_buffered_data : std_logic_vector(L*F*8-1 downto 0) := (others => '0'); + signal reg_state_user_data : std_logic_vector(L-1 downto 0); + signal reg_state_invalid_character : std_logic_vector(L-1 downto 0); + signal reg_state_not_enough_data : std_logic_vector(L-1 downto 0); + signal reg_state_ring_buffer_overflow : std_logic_vector(L-1 downto 0); + signal reg_state_disparity_error : std_logic_vector(L-1 downto 0); + signal reg_state_not_in_table_error : std_logic_vector(L-1 downto 0); + signal reg_state_wrong_alignment : std_logic_vector(L-1 downto 0); + signal reg_state_last_frame_repeated : std_logic_vector(L-1 downto 0); + + signal any_error : std_logic := '0'; + + constant all_ones : std_logic_vector(L-1 downto 0) := (others => '1'); + constant all_zeros : std_logic_vector(L-1 downto 0) := (others => '0'); begin -- architecture a1 + set_data: process (ci_frame_clk, ci_reset) is + begin -- process set_data + if ci_reset = '0' then -- asynchronous reset (active low) + reg_error <= '0'; + reg_buffered_data <= (others => '0'); + elsif ci_frame_clk'event and ci_frame_clk = '1' then -- rising clock edge + do_samples_data <= next_samples_data; + co_frame_state <= current_frame_state; + + if any_error = '0' then + prev_samples_data <= samples_data; + end if; + + for i in 0 to L-1 loop + reg_buffered_data(L*F*8 - 1 - i*F*8 downto L*F*8 - (i + 1)*F*8) <= di_lanes_data(i); + reg_state_user_data(i) <= ci_frame_states(i).user_data; + reg_state_invalid_character(i) <= ci_frame_states(i).invalid_characters; + reg_state_not_enough_data(i) <= ci_frame_states(i).not_enough_data; + reg_state_ring_buffer_overflow(i) <= ci_frame_states(i).ring_buffer_overflow; + reg_state_disparity_error(i) <= ci_frame_states(i).disparity_error; + reg_state_not_in_table_error(i) <= ci_frame_states(i).not_in_table_error; + reg_state_wrong_alignment(i) <= ci_frame_states(i).wrong_alignment; + reg_state_last_frame_repeated(i) <= ci_frame_states(i).last_frame_repeated; + end loop; -- i + end if; + end process set_data; + + -- set output error in case any lane has an error + current_frame_state.user_data <= '1' when reg_state_user_data = all_ones else '0'; + current_frame_state.invalid_characters <= '0' when reg_state_invalid_character = all_zeros else '1'; + current_frame_state.not_enough_data <= '0' when reg_state_not_enough_data = all_zeros else '1'; + current_frame_state.ring_buffer_overflow <= '0' when reg_state_ring_buffer_overflow = all_zeros else '1'; + current_frame_state.disparity_error <= '0' when reg_state_disparity_error = all_zeros else '1'; + current_frame_state.not_in_table_error <= '0' when reg_state_not_in_table_error = all_zeros else '1'; + current_frame_state.wrong_alignment <= '0' when reg_state_wrong_alignment = all_zeros else '1'; + current_frame_state.last_frame_repeated <= '1' when any_error = '1' else '0'; + + any_error <= '1' when current_frame_state.invalid_characters = '1' or + current_frame_state.not_enough_data = '1' or + current_frame_state.ring_buffer_overflow = '1' or + current_frame_state.disparity_error = '1' or + current_frame_state.not_in_table_error = '1' or + current_frame_state.wrong_alignment = '1' else '0'; + next_samples_data <= samples_data when any_error = '0' else prev_samples_data; + + -- for one or multiple lanes if CF = 0 + -- (no control words) + -- (control chars are right after sample) + multi_lane_no_cf: if CF = 0 generate + converters: for ci in 0 to M - 1 generate + samples: for si in 0 to S - 1 generate + samples_data(ci, si).data <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn downto L*F*8 - 1 - ci*Nn*S - si*Nn - N + 1); + + control_bits: if CS > 0 generate + samples_data(ci, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - ci*Nn*S - si*Nn - N downto L*F*8 - 1 - ci*Nn*S - si*Nn - N - CS + 1); + end generate control_bits; + end generate samples; + end generate converters; + end generate multi_lane_no_cf; + + -- for one or mutliple lanes if CF != 0 + -- (control words are present) + multi_lane_cf: if CF > 0 generate + cf_groups: for cfi in 0 to CF-1 generate + converters: for ci in 0 to M/CF-1 generate + samples: for si in 0 to S - 1 generate + samples_data(ci + cfi*M/CF, si).data <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn downto L*F*8 - 1 - cfi*F*8*L/CF - ci*Nn*S - si*Nn - N + 1); - -- maps data from lanes to samples - octets_to_samples: entity work.octets_to_samples - generic map ( - CS => CS, - M => M, - S => S, - L => L, - F => F, - CF => CF, - N => N, - Nn => Nn) - port map ( - ci_frame_clk => ci_frame_clk, - ci_reset => ci_reset, - ci_frame_states => ci_frame_states, - di_lanes_data => di_lanes_data, - co_frame_state => co_frame_state, - do_samples_data => do_samples_data); + control_bits: if CS > 0 generate + samples_data(ci + cfi*M/CF, si).ctrl_bits <= reg_buffered_data(L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*S*Nn - ci*S*CS - si*CS downto L*F*8 - 1 - cfi*F*8*L/CF - (M/CF)*Nn*S - ci*S*CS - si*CS - CS + 1); + end generate control_bits; + end generate samples; + end generate converters; + end generate cf_groups; + end generate multi_lane_cf; end architecture a1; diff --git a/testbench/transport/octets_to_samples_fc_tb.vhd b/testbench/transport/transport_layer_fc_tb.vhd similarity index 97% rename from testbench/transport/octets_to_samples_fc_tb.vhd rename to testbench/transport/transport_layer_fc_tb.vhd index 6dc815d6ca9fd194442e64b8c1f95fff3760c009..536ebdc2e3a78e5d5cd6db3d11843b4dd40fec44 100644 --- a/testbench/transport/octets_to_samples_fc_tb.vhd +++ b/testbench/transport/transport_layer_fc_tb.vhd @@ -4,10 +4,10 @@ use work.data_link_pkg.all; use work.transport_pkg.all; use work.testing_functions.all; -entity octets_to_samples_fc_tb is -end entity octets_to_samples_fc_tb; +entity transport_layer_fc_tb is +end entity transport_layer_fc_tb; -architecture a1 of octets_to_samples_fc_tb is +architecture a1 of transport_layer_fc_tb is constant CONTROL_SIZE : integer := 1; -- Size in bits of the control bits constant M : integer := 4; -- Count of converters constant S : integer := 1; -- Count of samples @@ -87,7 +87,7 @@ architecture a1 of octets_to_samples_fc_tb is signal test_data_index : integer := 0; begin -- architecture a1 - uut : entity work.octets_to_samples + uut : entity work.transport_layer generic map ( CS => CONTROL_SIZE, M => M, diff --git a/testbench/transport/octets_to_samples_multi_cf_tb.vhd b/testbench/transport/transport_layer_multi_cf_tb.vhd similarity index 96% rename from testbench/transport/octets_to_samples_multi_cf_tb.vhd rename to testbench/transport/transport_layer_multi_cf_tb.vhd index c9391369fffa3b1e4bf93bded005082ad89cc1bd..85475fea0dfffaf205fa67f2cee7bde1203360a4 100644 --- a/testbench/transport/octets_to_samples_multi_cf_tb.vhd +++ b/testbench/transport/transport_layer_multi_cf_tb.vhd @@ -4,10 +4,10 @@ use work.data_link_pkg.all; use work.transport_pkg.all; use work.testing_functions.all; -entity octets_to_samples_multi_fc_tb is -end entity octets_to_samples_multi_fc_tb; +entity transport_layer_multi_fc_tb is +end entity transport_layer_multi_fc_tb; -architecture a1 of octets_to_samples_multi_fc_tb is +architecture a1 of transport_layer_multi_fc_tb is constant CONTROL_SIZE : integer := 2; -- Size in bits of the control bits constant M : integer := 4; -- Count of converters constant S : integer := 2; -- Count of samples @@ -85,7 +85,7 @@ architecture a1 of octets_to_samples_multi_fc_tb is signal test_data_index : integer := 0; begin -- architecture a1 - uut : entity work.octets_to_samples + uut : entity work.transport_layer generic map ( CS => CONTROL_SIZE, M => M, diff --git a/testbench/transport/octets_to_samples_simp_tb.vhd b/testbench/transport/transport_layer_simp_tb.vhd similarity index 97% rename from testbench/transport/octets_to_samples_simp_tb.vhd rename to testbench/transport/transport_layer_simp_tb.vhd index 59eb1f6b592383c48d99f9f68bc91a116296151e..de8056108752db9de8b8776a3f870580352e9c90 100644 --- a/testbench/transport/octets_to_samples_simp_tb.vhd +++ b/testbench/transport/transport_layer_simp_tb.vhd @@ -4,10 +4,10 @@ use work.data_link_pkg.all; use work.transport_pkg.all; use work.testing_functions.all; -entity octets_to_samples_simp_tb is -end entity octets_to_samples_simp_tb; +entity transport_layer_simp_tb is +end entity transport_layer_simp_tb; -architecture a1 of octets_to_samples_simp_tb is +architecture a1 of transport_layer_simp_tb is constant CONTROL_SIZE : integer := 1; -- Size in bits of the control bits constant M : integer := 4; -- Count of converters constant S : integer := 1; -- Count of samples @@ -98,7 +98,7 @@ architecture a1 of octets_to_samples_simp_tb is signal test_data_index : integer := 0; begin -- architecture a1 - uut : entity work.octets_to_samples + uut : entity work.transport_layer generic map ( CS => CONTROL_SIZE, M => M,