From 1caca1862aa56d5164238d68a1d9f1d0002751a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Wed, 12 Apr 2023 10:50:22 +0200 Subject: [PATCH] feat: split synced combination and lmfc generation to separate entities --- src/jesd204b_link_rx.vhd | 39 ++++++----------- src/jesd204b_multipoint_link_rx.vhd | 67 ++++++++--------------------- src/lmfc_generation.vhd | 61 ++++++++++++++++++++++++++ src/synced_combination.vhd | 58 +++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 76 deletions(-) create mode 100644 src/lmfc_generation.vhd create mode 100644 src/synced_combination.vhd diff --git a/src/jesd204b_link_rx.vhd b/src/jesd204b_link_rx.vhd index fda0635..1da5f8f 100644 --- a/src/jesd204b_link_rx.vhd +++ b/src/jesd204b_link_rx.vhd @@ -128,33 +128,18 @@ architecture a1 of jesd204b_link_rx is end function ConfigsMatch; begin -- architecture a1 -- nsynced is active LOW, set '0' if all ready - nsynced_subclass_0: if SUBCLASSV = 0 generate - set_nsynced: process (ci_frame_clk, ci_reset) is - begin -- process set_nsynced - if ci_reset = '0' then -- asynchronous reset (active low) - co_nsynced <= '1'; - elsif ci_frame_clk'event and ci_frame_clk = '1' then -- rising clock edge - co_nsynced <= '1'; - if data_link_synced_vector = all_ones then - co_nsynced <= '0'; - end if; - end if; - end process set_nsynced; - end generate nsynced_subclass_0; - - nsynced_subclass_1: if SUBCLASSV = 1 generate - set_nsynced: process (ci_multiframe_clk, ci_reset) is - begin -- process set_nsynced - if ci_reset = '0' then -- asynchronous reset (active low) - co_nsynced <= '1'; - elsif ci_multiframe_clk'event and ci_multiframe_clk = '1' then -- rising clock edge - co_nsynced <= '1'; - if data_link_synced_vector = all_ones then - co_nsynced <= '0'; - end if; - end if; - end process set_nsynced; - end generate nsynced_subclass_1; + sync_combination: entity work.synced_combination + generic map ( + SUBCLASSV => SUBCLASSV, + N => L, + INVERSE => '0') + port map ( + ci_frame_clk => ci_frame_clk, + ci_multiframe_clk => ci_multiframe_clk, + ci_reset => ci_reset, + ci_lmfc_aligned => '1', + ci_synced_array => data_link_synced_vector, + co_nsynced => co_nsynced); request_sync_gen: process (ci_char_clk, ci_reset) is begin -- process request_sync diff --git a/src/jesd204b_multipoint_link_rx.vhd b/src/jesd204b_multipoint_link_rx.vhd index ce9d3f4..a61ddf9 100644 --- a/src/jesd204b_multipoint_link_rx.vhd +++ b/src/jesd204b_multipoint_link_rx.vhd @@ -53,12 +53,9 @@ architecture a1 of jesd204b_multipoint_link_rx is signal links_nsynced : std_logic_vector(LINKS - 1 downto 0); signal multiframe_clk : std_logic; - signal multiframe_aligned : std_logic; - signal multiframe_enable_sync : std_logic; + signal lmfc_aligned : std_logic; signal nsynced : std_logic; - signal reg_lmfc_aligned : std_logic; - -- purpose: Count lanes before link with index link_index function sumCummulativeLanes ( link_index : integer range 0 to LINKS-1) @@ -89,59 +86,31 @@ architecture a1 of jesd204b_multipoint_link_rx is return converters_count; end function sumCummulativeConverters; begin -- architecture a1 - nsynced <= '0' when links_nsynced = all_zeros else '1'; - co_error <= '0' when links_error = all_zeros else '1'; co_correct_data <= '1' when links_correct_data = all_ones else '0'; + co_nsynced <= nsynced; - multiframe_subclass_0: if CONFIG(0).SUBCLASSV = 0 generate - co_nsynced <= nsynced; - end generate multiframe_subclass_0; - - multiframe_subclass_1: if CONFIG(0).SUBCLASSV = 1 generate - sysref_alignment: process (ci_device_clk, ci_reset) is - begin -- process sysref_alignment - if ci_reset = '0' then -- asynchronous reset (active low) - reg_lmfc_aligned <= '0'; - multiframe_enable_sync <= '0'; - elsif ci_device_clk'event and ci_device_clk = '1' then -- rising clock edge - if multiframe_enable_sync = '0' and reg_lmfc_aligned = '0' then - multiframe_enable_sync <= '1'; - elsif reg_lmfc_aligned = '0' and multiframe_aligned = '1' then - reg_lmfc_aligned <= '1'; - multiframe_enable_sync <= '0'; - elsif co_nsynced = '0' and nsynced = '1' then - reg_lmfc_aligned <= '0'; - multiframe_enable_sync <= '1'; - end if; - end if; - end process sysref_alignment; - - set_multiframe_sync: process (multiframe_clk, ci_reset) is - begin -- process set_multiframe_sync - if ci_reset = '0' then -- asynchronous reset (active low) - co_nsynced <= '1'; - elsif multiframe_clk'event and multiframe_clk = '1' then -- rising clock edge - co_nsynced <= '1'; - if nsynced = '0' and reg_lmfc_aligned = '1' then - co_nsynced <= '0'; - end if; - end if; - end process set_multiframe_sync; - end generate multiframe_subclass_1; - - multiframe_gen: entity work.lmfc_counter + sync_combination : entity work.synced_combination generic map ( - DATA_RATE_MULT => DATA_RATE_MULT, - PHASE_ADJUST => 0, - MULTIFRAME_RATE => MULTIFRAME_RATE) + SUBCLASSV => CONFIG(0).SUBCLASSV, + N => LINKS, + INVERSE => '1') + port map ( + ci_frame_clk => ci_frame_clk, + ci_multiframe_clk => multiframe_clk, + ci_reset => ci_reset, + ci_lmfc_aligned => lmfc_aligned, + ci_synced_array => links_nsynced, + co_nsynced => nsynced); + + lmfc_generation: entity work.lmfc_generation port map ( ci_device_clk => ci_device_clk, ci_reset => ci_reset, ci_sysref => ci_sysref, - ci_enable_sync => multiframe_enable_sync, - co_aligned => multiframe_aligned, - co_multiframe_clk => multiframe_clk); + ci_nsynced => nsynced, + co_multiframe_clk => multiframe_clk, + co_lmfc_aligned => lmfc_aligned); links_rx : for i in 0 to LINKS - 1 generate link : entity work.jesd204b_link_rx diff --git a/src/lmfc_generation.vhd b/src/lmfc_generation.vhd new file mode 100644 index 0000000..839623a --- /dev/null +++ b/src/lmfc_generation.vhd @@ -0,0 +1,61 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity lmfc_generation is + generic ( + MULTIFRAME_RATE : integer; + DATA_RATE_MULT : integer); + port ( + ci_device_clk : in std_logic; + ci_reset : in std_logic; + ci_sysref : in std_logic; + ci_nsynced : in std_logic; + co_multiframe_clk : out std_logic; + co_lmfc_aligned : out std_logic); +end entity lmfc_generation; + +architecture a1 of lmfc_generation is + signal prev_nsynced : std_logic; + signal reg_lmfc_aligned : std_logic; + + signal multiframe_clk : std_logic; + signal multiframe_aligned : std_logic; + signal multiframe_enable_sync : std_logic; +begin -- architecture a1 + co_lmfc_aligned <= reg_lmfc_aligned; + co_multiframe_clk <= multiframe_clk; + + sysref_alignment: process (ci_device_clk, ci_reset) is + begin -- process sysref_alignment + if ci_reset = '0' then -- asynchronous reset (active low) + reg_lmfc_aligned <= '0'; + multiframe_enable_sync <= '0'; + prev_nsynced <= '1'; + elsif ci_device_clk'event and ci_device_clk = '1' then -- rising clock edge + prev_nsynced <= ci_nsynced; + if multiframe_enable_sync = '0' and reg_lmfc_aligned = '0' then + multiframe_enable_sync <= '1'; + elsif reg_lmfc_aligned = '0' and multiframe_aligned = '1' then + reg_lmfc_aligned <= '1'; + multiframe_enable_sync <= '0'; + elsif prev_nsynced = '0' and ci_nsynced = '1' then + reg_lmfc_aligned <= '0'; + multiframe_enable_sync <= '1'; + end if; + end if; + end process sysref_alignment; + + multiframe_gen: entity work.lmfc_counter + generic map ( + DATA_RATE_MULT => DATA_RATE_MULT, + PHASE_ADJUST => 0, + MULTIFRAME_RATE => MULTIFRAME_RATE) + port map ( + ci_device_clk => ci_device_clk, + ci_reset => ci_reset, + ci_sysref => ci_sysref, + ci_enable_sync => multiframe_enable_sync, + co_aligned => multiframe_aligned, + co_multiframe_clk => multiframe_clk); + +end architecture a1; diff --git a/src/synced_combination.vhd b/src/synced_combination.vhd new file mode 100644 index 0000000..360062c --- /dev/null +++ b/src/synced_combination.vhd @@ -0,0 +1,58 @@ +library ieee; +use ieee.std_logic_1164.all; + +entity synced_combination is + + generic ( + SUBCLASSV : integer := 0; + N : integer := 1; + INVERSE : std_logic := '0'); + port ( + ci_frame_clk : in std_logic; + ci_multiframe_clk : in std_logic; + ci_reset : in std_logic; + ci_lmfc_aligned : in std_logic; + ci_synced_array : std_logic_vector(N-1 downto 0); + co_nsynced : out std_logic); + +end entity synced_combination; + +architecture a1 of synced_combination is + constant all_ones : std_logic_vector(N - 1 downto 0) := (others => '1'); + constant all_zeros : std_logic_vector(N - 1 downto 0) := (others => '0'); + + signal nsynced : std_logic; +begin -- architecture a1 + gen_nsynced: if INVERSE = '0' generate + nsynced <= '0' when ci_synced_array = all_ones else '1'; + end generate gen_nsynced; + gen_nsynced_inverse: if INVERSE = '1' generate + nsynced <= '0' when ci_synced_array = all_zeros else '1'; + end generate gen_nsynced_inverse; + + nsynced_subclass_0: if SUBCLASSV = 0 generate + set_nsynced: process (ci_frame_clk, ci_reset) is + begin -- process set_nsynced + if ci_reset = '0' then -- asynchronous reset (active low) + co_nsynced <= '1'; + elsif ci_frame_clk'event and ci_frame_clk = '1' then -- rising clock edge + co_nsynced <= nsynced; + end if; + end process set_nsynced; + end generate nsynced_subclass_0; + + nsynced_subclass_1: if SUBCLASSV = 1 generate + set_nsynced: process (ci_multiframe_clk, ci_reset) is + begin -- process set_nsynced + if ci_reset = '0' then -- asynchronous reset (active low) + co_nsynced <= '1'; + elsif ci_multiframe_clk'event and ci_multiframe_clk = '1' then -- rising clock edge + co_nsynced <= '1'; + if nsynced = '0' and ci_lmfc_aligned = '1' then + co_nsynced <= '0'; + end if; + end if; + end process set_nsynced; + end generate nsynced_subclass_1; + +end architecture a1; -- 2.48.1