From 2d36ba0b2efe42de7d4488fc5ab2a41c9cd0bc7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Fri, 2 Dec 2022 20:13:15 +0100 Subject: [PATCH] feat: add jesd204b_rx toplevel entity --- src/jesd204b_pkg.vhd | 9 +++ src/jesd204b_rx.vhd | 131 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/jesd204b_pkg.vhd create mode 100644 src/jesd204b_rx.vhd diff --git a/src/jesd204b_pkg.vhd b/src/jesd204b_pkg.vhd new file mode 100644 index 0000000..a213982 --- /dev/null +++ b/src/jesd204b_pkg.vhd @@ -0,0 +1,9 @@ +library ieee; +use ieee.std_logic_1164.all; + +package jesd204b_pkg is + + -- array input data from lanes + type lane_input_array is array (natural range <>) of std_logic_vector(9 downto 0); + +end package jesd204b_pkg; diff --git a/src/jesd204b_rx.vhd b/src/jesd204b_rx.vhd new file mode 100644 index 0000000..c36ede8 --- /dev/null +++ b/src/jesd204b_rx.vhd @@ -0,0 +1,131 @@ +library ieee; +use ieee.std_logic_1164.all; +use work.transport_pkg.all; +use work.data_link_pkg.all; +use work.jesd204b_pkg.all; + +entity jesd204b_rx is + generic ( + K_character : std_logic_vector(7 downto 0) := "10111100"; + R_character : std_logic_vector(7 downto 0) := "00011100"; + A_character : std_logic_vector(7 downto 0) := "01111100"; + Q_character : std_logic_vector(7 downto 0) := "10011100"; + M : integer := 1; -- Count of converters + S : integer := 1; -- Count of samples + L : integer := 1; -- Count of lanes + F : integer := 1; + K : integer := 1; + CF : integer := 1; + N : integer := 16; + Nn : integer := 16; + ERROR_CONFIG : error_handling_config := (2, 0, 5, 5, 5); + SCRAMBLING : std_logic := '0'); + port ( + ci_char_clk : in std_logic; + ci_frame_clk : in std_logic; + ci_reset : in std_logic; + + co_lane_config : out link_config; + co_nsynced : out std_logic; + co_error : out std_logic; + + di_transceiver_data : in lane_input_array(L-1 downto 0); + do_samples : out samples_array(M - 1 downto 0, S - 1 downto 0); + co_correct_data : out std_logic); +end entity jesd204b_rx; + +architecture a1 of jesd204b_rx is + -- == DATA LINK == + -- outputs + signal data_link_ready_vector : std_logic_vector(L-1 downto 0) := (others => '0'); + signal data_link_synced_vector : std_logic_vector(L-1 downto 0) := (others => '0'); + signal data_link_chars_array : frame_character_array(0 to L-1); + -- inputs + signal data_link_start : std_logic := '0'; + + -- == DESCRAMBLER == + signal scrambler_chars_array : frame_character_array(0 to L-1); + + -- == TRANSPORT == + signal transport_chars_array : frame_character_array(0 to L-1); + + type lane_configs_array is array (0 to L-1) of link_config; + signal lane_configuration_array : lane_configs_array; + + signal all_ones : std_logic_vector(L-1 downto 0) := (others => '0'); + + function ConfigsMatch ( + config_array : lane_configs_array) + return std_logic is + variable matches : std_logic := '1'; + begin -- function ConfigsMatch + for i in 0 to L-2 loop + if config_array(i) /= config_array(i+1) then + matches := '0'; + end if; + + return matches; + end loop; -- i + end function ConfigsMatch; +begin -- architecture a1 + -- nsynced is active LOW, set '0' if all ready + co_nsynced <= '0' when data_link_synced_vector = all_ones else '1'; + -- choose the first config. + co_lane_config <= lane_configuration_array(0); + + -- start lanes data after all are ready + data_link_start <= '1' when data_link_ready_vector = all_ones else '0'; + + -- characters either from scrambler if scrambling enabled or directly from data_link + transport_chars_array <= scrambler_chars_array when SCRAMBLING = '1' else data_link_chars_array; + + -- error '1' if configs do not match + co_error <= not ConfigsMatch(lane_configuration_array); + + data_links: for i in 0 to L-1 generate + data_link_layer: entity work.data_link_layer + generic map ( + K_character => K_character, + R_character => R_character, + A_character => A_character, + Q_character => Q_character) + port map ( + ci_char_clk => ci_char_clk, + ci_reset => ci_reset, + ci_F => F, + ci_K => K, + ci_scrambled => SCRAMBLING, + do_lane_config => lane_configuration_array(i), + co_lane_ready => data_link_ready_vector(i), + ci_lane_start => data_link_start, + ci_error_config => ERROR_CONFIG, + co_synced => data_link_synced_vector(i), + di_10b => di_transceiver_data(i), + do_char => data_link_chars_array(i)); + + scrambler_gen: if SCRAMBLING = '1' generate + scrambler: entity work.descrambler + port map ( + ci_char_clk => ci_char_clk, + ci_reset => ci_reset, + di_char => data_link_chars_array(i), + do_char => scrambler_chars_array(i)); + end generate scrambler_gen; + end generate data_links; + + transport_layer: entity work.transport_layer + generic map ( + M => M, + S => S, + L => L) + port map ( + ci_char_clk => ci_char_clk, + ci_frame_clk => ci_frame_clk, + ci_reset => ci_reset, + di_lanes_data => transport_chars_array, + ci_N => N, + ci_Nn => Nn, + co_correct_data => co_correct_data, + do_samples_data => do_samples); + +end architecture a1; -- 2.48.1