From ab6647601b3d6dd92b4a7f1c22371b01e2e9b1f4 Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Thu, 2 Dec 2021 16:29:07 +0100 Subject: [PATCH] adjustments to code --- media_interfaces/med_ecp3_sfp_sync_all_RS.vhd | 10 +- media_interfaces/sync/med_sync_control_RS.vhd | 37 ++- media_interfaces/sync/med_sync_define_RS.vhd | 21 +- media_interfaces/sync/rx_rsl.vhd | 256 +++++++++--------- media_interfaces/sync/sci_reader_RS.vhd | 29 +- 5 files changed, 175 insertions(+), 178 deletions(-) diff --git a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd index 0065776..6dddfc7 100644 --- a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd @@ -157,14 +157,6 @@ begin assert not (quad_mode = 8) report "Note: QUAD with one slave port detected" severity note; assert not ((quad_mode >= 9) and (quad_mode <= 11)) report "Note: mixed master/slave QUAD detected" severity note; -------------------------------------------------- --- only used SerDes are activated -------------------------------------------------- --- powerup_ch(3) <= '0' when IS_MODE(3) = c_IS_UNUSED else '1'; --- powerup_ch(2) <= '0' when IS_MODE(2) = c_IS_UNUSED else '1'; --- powerup_ch(1) <= '0' when IS_MODE(1) = c_IS_UNUSED else '1'; --- powerup_ch(0) <= '0' when IS_MODE(0) = c_IS_UNUSED else '1'; - ------------------------------------------------- -- SFPs are disabled on unused SerDes channels ------------------------------------------------- @@ -465,6 +457,8 @@ end generate; SCI_WR => sci_write_i, -- WAP WA_POS_OUT => wa_position, + WA_READ_OUT => open, + LINK_RX_READY_IN => '0', --Slowcontrol BUS_RX => BUS_RX, BUS_TX => BUS_TX, diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index 92b1299..c762028 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -116,7 +116,6 @@ begin TX_RESET_OUT <= '0'; -- RX_RESET_FSM reset --- clrn_rx_fsm_i <= not (CLEAR or RESET or sd_los_q); clr_rx_fsm_i <= sd_los_q; MASTER_RESET_OUT <= sd_los_q; @@ -130,23 +129,21 @@ begin ------------------------------------------------- THE_RX_RST_FSM: rx_rsl port map( - CLEAR => clr_rx_fsm_i, - REFCLK => CLK_REF, - pll_lol => PLL_LOL_IN, - cdr_lol => RX_CDR_LOL_IN, - cv => CV_IN, - lsm => LSM_IN, - los => RX_LOS_IN, + CLEAR => clr_rx_fsm_i, + CLK_REF => CLK_REF, + PLL_LOL_IN => PLL_LOL_IN, + CDR_LOL_IN => RX_CDR_LOL_IN, + CV_IN => CV_IN, + LSM_IN => LSM_IN, + LOS_IN => RX_LOS_IN, -- outputs - rx_serdes_rst => rx_serdes_rst_i, - rx_pcs_rst => rx_pcs_rst_i, - state_out => rx_fsm_state + RX_SERDES_RST_OUT => rx_serdes_rst_i, + RX_PCS_RST_OUT => rx_pcs_rst_i, + LINK_RX_READY_OUT => link_rx_ready_i, + STATE_OUT => rx_fsm_state ); - - link_rx_ready_i <= '0'; -- BUG - --- reset signals for RX SerDes need to be sync'ed to real RX clock +-- reset signals for RX SerDes need to be sync'ed to real RX clock for ECP5 SYNC_RST_SIGS: entity work.signal_sync generic map( WIDTH => 2 ) port map( @@ -297,11 +294,11 @@ begin DEBUG_OUT(2) <= RX_CDR_LOL_IN; DEBUG_OUT(3) <= rx_pcs_rst_i; DEBUG_OUT(4) <= rx_serdes_rst_i; - DEBUG_OUT(5) <= CV_IN;--link_rx_ready_i; - DEBUG_OUT(6) <= LSM_IN;--link_half_done_i; - DEBUG_OUT(7) <= PLL_LOL_IN;--link_full_done_i; - DEBUG_OUT(8) <= RESET;--LINK_TX_READY_IN; - DEBUG_OUT(9) <= CLEAR;--is_wap_zero_i; + DEBUG_OUT(5) <= CV_IN; + DEBUG_OUT(6) <= LSM_IN; + DEBUG_OUT(7) <= PLL_LOL_IN; + DEBUG_OUT(8) <= link_rx_ready_i; + DEBUG_OUT(9) <= CLEAR; DEBUG_OUT(10) <= clr_rx_fsm_i; DEBUG_OUT(11) <= reset_i; DEBUG_OUT(15 downto 12) <= rx_fsm_state; diff --git a/media_interfaces/sync/med_sync_define_RS.vhd b/media_interfaces/sync/med_sync_define_RS.vhd index 5b44a85..e3a8aa8 100644 --- a/media_interfaces/sync/med_sync_define_RS.vhd +++ b/media_interfaces/sync/med_sync_define_RS.vhd @@ -27,17 +27,18 @@ constant D_IDLE1 : std_logic_vector(7 downto 0) := x"50"; -- D16.2 component rx_rsl is port ( - CLEAR : in std_logic; - refclk : in std_logic; - pll_lol : in std_logic; - cdr_lol : in std_logic; - cv : in std_logic; - lsm : in std_logic; - los : in std_logic; + CLEAR : in std_logic; + CLK_REF : in std_logic; + PLL_LOL_IN : in std_logic; + CDR_LOL_IN : in std_logic; + CV_IN : in std_logic; + LSM_IN : in std_logic; + LOS_IN : in std_logic; -- outputs - rx_serdes_rst : out std_logic; - rx_pcs_rst : out std_logic; - state_out : out std_logic_vector(3 downto 0) + RX_SERDES_RST_OUT : out std_logic; + RX_PCS_RST_OUT : out std_logic; + LINK_RX_READY_OUT : out std_logic; + STATE_OUT : out std_logic_vector(3 downto 0) ); end component; diff --git a/media_interfaces/sync/rx_rsl.vhd b/media_interfaces/sync/rx_rsl.vhd index 90af3c8..0a2828d 100644 --- a/media_interfaces/sync/rx_rsl.vhd +++ b/media_interfaces/sync/rx_rsl.vhd @@ -1,195 +1,199 @@ library ieee; use ieee.std_logic_1164.all; -use IEEE.std_logic_unsigned.all; -use IEEE.std_logic_arith.all; +USE IEEE.numeric_std.all; entity rx_rsl is port ( - CLEAR : in std_logic; - refclk : in std_logic; - pll_lol : in std_logic; - cdr_lol : in std_logic; - cv : in std_logic; - lsm : in std_logic; - los : in std_logic; + CLEAR : in std_logic; + CLK_REF : in std_logic; + PLL_LOL_IN : in std_logic; + CDR_LOL_IN : in std_logic; + CV_IN : in std_logic; + LSM_IN : in std_logic; + LOS_IN : in std_logic; -- outputs - rx_serdes_rst : out std_logic; - rx_pcs_rst : out std_logic; - state_out : out std_logic_vector(3 downto 0) + RX_SERDES_RST_OUT : out std_logic; + RX_PCS_RST_OUT : out std_logic; + LINK_RX_READY_OUT : out std_logic; + STATE_OUT : out std_logic_vector(3 downto 0) ); end rx_rsl; architecture rx_rsl_arc of rx_rsl is -attribute syn_keep : boolean; + attribute syn_keep : boolean; ------------------------------------------------------------------- --- Constants Declaration -- ------------------------------------------------------------------- +-- Remark: work of Christian Michel. Just re-edited to reflect necessary changes for ECP3. +-- Without this piece of code, many things would have been a real pain. + constant Tshort : unsigned(31 downto 0) := x"00000007"; --@125MHz 100ms + constant Tplol : unsigned(31 downto 0) := x"00BEBC20"; + constant Tcdr : unsigned(31 downto 0) := x"00BEBC20"; + constant Tviol : unsigned(31 downto 0) := x"00BEBC20"; -constant Tplol : std_logic_vector (31 downto 0):=x"00BEBC20"; -constant Tcdr : std_logic_vector (31 downto 0):=x"00BEBC20"; -constant Tviol : std_logic_vector (31 downto 0):=x"00BEBC20"; + signal pll_lol_s : std_logic; + signal cdr_lol_s : std_logic; + signal cv_s : std_logic; + signal lsm_s : std_logic; + signal los_s : std_logic; ------------------------------------------------------------------- --- Internal Variables -- ------------------------------------------------------------------- -signal pll_lol_s : std_logic; -signal cdr_lol_s : std_logic; -signal cv_s : std_logic; -signal lsm_s : std_logic; -signal los_s : std_logic; + signal cnt : unsigned(31 downto 0); -signal cnt : std_logic_vector (31 downto 0); + type rx_sm_state is (POWERUP, APPLY_CDR_RST, WAIT_CDR_LOCK, TEST_CDR, + APPLY_RXPCS_RST, WAIT_RXPCS_LOCK, TEST_RXPCS, IDLE); -type rx_sm_state is (powerup, apply_cdr_rst, wait_cdr_lock, test_cdr, apply_rxpcs_rst, wait_rxpcs_lock, test_rxpcs, idle); -signal rx_sm : rx_sm_state; -attribute syn_keep of rx_sm : signal is true; + signal rx_sm : rx_sm_state; + + attribute syn_keep of rx_sm : signal is true; begin ------------------------------------------------------------------- --- Components Instantiation -- ------------------------------------------------------------------- ------------------------------------------------------------------- --- Begin Of The Design -- ------------------------------------------------------------------- - --- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. +-- Remark: on ECP3, rx_serdes_rst sets RX_CDR_LOL. Deadlocks on POWERUP. +-- Remark: RX_LOS is not necessary, as SFP_LOS keeps us safely in reset. +-- Remark: syncing is done here by one FF only. Might be dangerous. ------------------------------------------------------------------ -rx_reset_proc : process (CLEAR, refclk) +RX_RESET_PROC : process( CLEAR, CLK_REF ) begin if( CLEAR = '1' ) then - pll_lol_s <= '1'; - cdr_lol_s <= '1'; - cv_s <= '1'; - lsm_s <= '0'; - los_s <= '1'; - - rx_serdes_rst <= '1'; - rx_pcs_rst <= '1'; + pll_lol_s <= '1'; + cdr_lol_s <= '1'; + cv_s <= '1'; + lsm_s <= '0'; + los_s <= '1'; + + RX_SERDES_RST_OUT <= '1'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; rx_sm <= powerup; cnt <= (others => '0'); - elsif( rising_edge(refclk) ) then - pll_lol_s <= pll_lol; - cdr_lol_s <= cdr_lol; - cv_s <= cv; - lsm_s <= lsm; - los_s <= los; + elsif( rising_edge(CLK_REF) ) then + pll_lol_s <= PLL_LOL_IN; + cdr_lol_s <= CDR_LOL_IN; + cv_s <= CV_IN; + lsm_s <= LSM_IN; + los_s <= LOS_IN; case rx_sm is - when powerup => - state_out <= x"0"; --- rx_serdes_rst <= '1'; -- bad idea - rx_serdes_rst <= '0'; - rx_pcs_rst <= '1'; + when POWERUP => + STATE_OUT <= x"0"; + RX_SERDES_RST_OUT <= '0'; -- needed for RX_LOS to be active + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; if( (pll_lol_s = '1') or (los_s = '1') ) then - cnt <= (others => '0'); + cnt <= (others => '0'); else if( cnt = Tplol ) then - cnt <= (others => '0'); - rx_sm <= apply_cdr_rst; + cnt <= (others => '0'); + rx_sm <= APPLY_CDR_RST; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; end if; - when apply_cdr_rst => - state_out <= x"1"; - rx_serdes_rst <= '1'; - rx_pcs_rst <= '1'; - if( cnt = x"00000007" ) then - cnt <= (others => '0'); - rx_sm <= wait_cdr_lock; + when APPLY_CDR_RST => + STATE_OUT <= x"1"; + RX_SERDES_RST_OUT <= '1'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tshort ) then + cnt <= (others => '0'); + rx_sm <= WAIT_CDR_LOCK; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; - when wait_cdr_lock => - state_out <= x"2"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '1'; + when WAIT_CDR_LOCK => + STATE_OUT <= x"2"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= test_cdr; + cnt <= (others => '0'); + rx_sm <= TEST_CDR; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; - when test_cdr => - state_out <= x"3"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '1'; + when TEST_CDR => + STATE_OUT <= x"3"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; if( cdr_lol_s = '1' ) then - cnt <= (others => '0'); - rx_sm <= apply_cdr_rst; + cnt <= (others => '0'); + rx_sm <= APPLY_CDR_RST; else if( cnt = Tcdr ) then - cnt <= (others => '0'); - rx_sm <= apply_rxpcs_rst; + cnt <= (others => '0'); + rx_sm <= APPLY_RXPCS_RST; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; end if; - when apply_rxpcs_rst => - state_out <= x"4"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '1'; - if (cnt = x"00000007") then - cnt <= (others => '0'); - rx_sm <= wait_rxpcs_lock; + + when APPLY_RXPCS_RST => + STATE_OUT <= x"4"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '1'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tshort ) then + cnt <= (others => '0'); + rx_sm <= WAIT_RXPCS_LOCK; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; - when wait_rxpcs_lock => - state_out <= x"5"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '0'; - if (cnt = Tviol) then - cnt <= (others => '0'); - rx_sm <= test_rxpcs; + when WAIT_RXPCS_LOCK => + STATE_OUT <= x"5"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + if( cnt = Tviol ) then + cnt <= (others => '0'); + rx_sm <= TEST_RXPCS; else - cnt <= cnt + '1'; - end if; - when test_rxpcs => - state_out <= x"6"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '0'; - if (lsm_s = '0') or (cv_s = '1') then - cnt <= (others => '0'); - rx_sm <= apply_rxpcs_rst; + cnt <= cnt + 1; + end if; + + when TEST_RXPCS => + STATE_OUT <= x"6"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '0'; + if( (lsm_s = '0') or (cv_s = '1') ) then + cnt <= (others => '0'); + rx_sm <= APPLY_RXPCS_RST; else - if (cnt = Tviol) then - cnt <= (others => '0'); - rx_sm <= idle; + if( cnt = Tviol ) then + cnt <= (others => '0'); + rx_sm <= IDLE; else - cnt <= cnt + '1'; + cnt <= cnt + 1; end if; end if; when idle => - state_out <= x"7"; - rx_serdes_rst <= '0'; - rx_pcs_rst <= '0'; - if (lsm_s = '0') or (cv_s = '1') then - rx_sm <= apply_rxpcs_rst; - cnt <= (others => '0'); + STATE_OUT <= x"7"; + RX_SERDES_RST_OUT <= '0'; + RX_PCS_RST_OUT <= '0'; + LINK_RX_READY_OUT <= '1'; + if( (lsm_s = '0') or (cv_s = '1') ) then + rx_sm <= APPLY_RXPCS_RST; + cnt <= (others => '0'); end if; end case; ------------------------------------------------ -- if (pll_lol_s = '1') or (los_s = '1') then - if (pll_lol_s = '1') then - rx_sm <= powerup; - cnt <= (others => '0'); - end if; + if( pll_lol_s = '1' ) then + rx_sm <= POWERUP; + cnt <= (others => '0'); + end if; -end if; + end if; end process rx_reset_proc; end rx_rsl_arc; diff --git a/media_interfaces/sync/sci_reader_RS.vhd b/media_interfaces/sync/sci_reader_RS.vhd index 20721d7..0f99fce 100644 --- a/media_interfaces/sync/sci_reader_RS.vhd +++ b/media_interfaces/sync/sci_reader_RS.vhd @@ -11,26 +11,27 @@ library work; entity sci_reader_RS is port( - CLK : in std_logic; - RESET : in std_logic; + CLK : in std_logic; + RESET : in std_logic; --SCI - SCI_WRDATA : out std_logic_vector(7 downto 0); - SCI_RDDATA : in std_logic_vector(7 downto 0); - SCI_ADDR : out std_logic_vector(5 downto 0); - SCI_SEL : out std_logic_vector(4 downto 0); - SCI_RD : out std_logic; - SCI_WR : out std_logic; + SCI_WRDATA : out std_logic_vector(7 downto 0); + SCI_RDDATA : in std_logic_vector(7 downto 0); + SCI_ADDR : out std_logic_vector(5 downto 0); + SCI_SEL : out std_logic_vector(4 downto 0); + SCI_RD : out std_logic; + SCI_WR : out std_logic; - WA_POS_OUT : out std_logic_vector(15 downto 0); - WA_READ_OUT : out std_logic; + WA_POS_OUT : out std_logic_vector(15 downto 0); + WA_READ_OUT : out std_logic; + LINK_RX_READY_IN : in std_logic; --Slowcontrol - BUS_RX : in CTRLBUS_RX; - BUS_TX : out CTRLBUS_TX; + BUS_RX : in CTRLBUS_RX; + BUS_TX : out CTRLBUS_TX; MEDIA_STATUS_REG_IN : in std_logic_vector(255 downto 0) := (others => '0'); - DEBUG_OUT : out std_logic_vector(31 downto 0) + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end entity; @@ -87,7 +88,7 @@ begin SCI_RD <= BUS_RX.read and not (BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8)); next_sci_wr <= BUS_RX.write and not (BUS_RX.addr(6) and not BUS_RX.addr(7) and BUS_RX.addr(8)); sci_state <= SCTRL; - elsif sci_timer(sci_timer'left) = '1' then + elsif (sci_timer(sci_timer'left) = '1') and (LINK_RX_READY_IN = '0') then sci_timer <= (others => '0'); sci_state <= GET_WA; wa_read_i <= '1'; -- 2.43.0