From d3825bd0fd9a8c6bd1183bf78373684265239fba Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Thu, 3 Oct 2013 19:45:49 +0200 Subject: [PATCH] CBMNet Litte clean up in code --- .gitignore | 8 +- cbmnet/code/cbmnet_interface_pkg.vhd | 2 + cbmnet/code/cbmnet_phy_ecp3.vhd | 401 ++++++++++++++------------- cbmnet/code/cbmnet_phy_gear.vhd | 9 +- cbmnet/code/cbmnet_phy_pkg.vhd | 23 +- cbmnet/trb3_periph_cbmnet.vhd | 20 +- 6 files changed, 235 insertions(+), 228 deletions(-) diff --git a/.gitignore b/.gitignore index 55cfd33..edb675f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,14 @@ version.vhd *tmpl.vhd *.log workdir -*.kate-swp +workdir_* +*.bit +*.kate-swp* +*.kate-swap* .run_manager.ini reportview.xml .kateproject.d cts/project* +cbmnet/project* +cbmnet/sim* + diff --git a/cbmnet/code/cbmnet_interface_pkg.vhd b/cbmnet/code/cbmnet_interface_pkg.vhd index 8460f90..9c2b5dd 100644 --- a/cbmnet/code/cbmnet_interface_pkg.vhd +++ b/cbmnet/code/cbmnet_interface_pkg.vhd @@ -1,3 +1,5 @@ +-- Hardware Independent CBMNet components (merely an interface definition for the Verilog modules) + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index 9628648..0ad5677 100644 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -13,7 +13,8 @@ use work.cbmnet_phy_pkg.all; entity cbmnet_phy_ecp3 is generic( - IS_SYNC_SLAVE : integer := c_NO --select slave mode + IS_SYNC_SLAVE : integer := c_NO; --select slave mode + INCL_DEBUG_AIDS : integer := c_YES ); port( CLK : in std_logic; -- *internal* 125 MHz reference clock @@ -45,20 +46,13 @@ entity cbmnet_phy_ecp3 is SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --Control Interface - SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); - SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); - SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); - SCI_READ : in std_logic := '0'; - SCI_WRITE : in std_logic := '0'; - SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; - + LED_RX_OUT : out std_logic; + LED_TX_OUT : out std_logic; + LED_OK_OUT : out std_logic; + -- Status and control port - STAT_OP : out std_logic_vector (15 downto 0); + STAT_OP : out std_logic_vector (15 downto 0) := (others => '0'); CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0'); DEBUG_OUT : out std_logic_vector (127 downto 0) := (others => '0') ); end entity; @@ -72,39 +66,41 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off"; constant WA_FIXATION : integer := c_YES; - - signal clk_125_i : std_logic; - signal clk_125_local : std_logic; - signal clk_rx_full : std_logic; - signal clk_rx_half : std_logic; - signal tx_data_i : std_logic_vector(17 downto 0); - - signal rx_data_i : std_logic_vector(8 downto 0); - signal rx_data_buf_i : std_logic_vector(17 downto 0); +-- Clocks and global resets + signal clk_125_local : std_logic; -- local 125 MHz reference clock driven by clock generators + signal clk_125_i : std_logic; -- in FEE mode, driven by recovered clock, in Master mode, driven by local clock + signal rclk_250_i : std_logic; -- recovered word clock + signal rclk_125_i : std_logic; -- rclk_250_i divided by two. aligned s.t. the rising edge corresponds to the lower received word + + signal rst_i : std_logic; -- High-active reset driven by external logic + signal rst_n_i : std_logic; -- Low-active version of rst_i + +-- SERDES/PCS + -- status + signal rx_los_low_i : std_logic; + signal rx_cdr_lol_i : std_logic; + signal tx_pll_lol_i : std_logic; + signal lsm_status_i : std_logic; + + signal rx_dec_error_i: std_logic; + signal rx_error_delay : std_logic_vector(3 downto 0); -- shift register to detect a "stable error condition" - signal rx_error : std_logic; - - signal rst_n : std_logic; - signal rst : std_logic; - signal tx_serdes_rst : std_logic; - signal tx_pcs_rst : std_logic; - signal rst_qd : std_logic; - signal serdes_rst_qd : std_logic; - signal sd_los_i : std_logic; - - signal rx_pcs_rst : std_logic; - signal rx_serdes_rst : std_logic; - signal rx_reset_from_rm_i: std_logic; + -- resets + signal rst_qd_i : std_logic; + signal serdes_rst_qd_i : std_logic; - signal rx_los_low : std_logic; - signal rx_cdr_lol : std_logic; - signal tx_pll_lol : std_logic; + signal tx_serdes_rst_i : std_logic; + signal tx_pcs_rst_i : std_logic; - signal serdes_ready_i : std_logic; - signal serdes_rx_ready_i : std_logic; - signal serdes_tx_ready_i : std_logic; + signal rx_serdes_rst_i : std_logic; + signal rx_pcs_rst_i : std_logic; + + -- data + signal tx_data_i : std_logic_vector(17 downto 0); -- data to send using SERDES + signal rx_data_i : std_logic_vector( 8 downto 0); -- received by SERDES + -- status & control interface (and obtained info) signal sci_ch_i : std_logic_vector(3 downto 0); signal sci_qd_i : std_logic; signal sci_reg_i : std_logic; @@ -116,68 +112,67 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal sci_write_shift_i : std_logic_vector(2 downto 0); signal sci_read_shift_i : std_logic_vector(2 downto 0); - signal wa_position : std_logic_vector(15 downto 0) := x"FFFF"; + signal wa_position_i : std_logic_vector(15 downto 0) := x"FFFF"; + signal barrel_shifter_misaligned_i: std_logic; - signal rx_fsm_state : std_logic_vector(3 downto 0); - signal tx_fsm_state : std_logic_vector(3 downto 0); - signal tx_rst_fsm_ready_i : std_logic; - signal tx_rst_fsm_ready_buf_i : std_logic; +-- RESET FSM + signal rx_rst_fsm_state_i : std_logic_vector(3 downto 0); + signal tx_rst_fsm_state_i : std_logic_vector(3 downto 0); + signal tx_rst_fsm_ready_i : std_logic; + signal tx_rst_fsm_ready_buf_i : std_logic; - - type sci_ctrl is (IDLE, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH); - signal sci_state : sci_ctrl; - signal sci_timer : unsigned( 4 downto 0) := (others => '0'); - signal start_timer : unsigned(18 downto 0) := (others => '0'); - - signal led_ok : std_logic; - signal led_tx, last_led_tx : std_logic; - signal led_rx, last_led_rx : std_logic; - signal led_timer : unsigned(20 downto 0); - - signal proper_byte_align_i : std_logic; signal byte_alignment_to_fsm_i : std_logic; - - signal gear_to_serder_rst_i : std_logic; signal word_alignment_to_fsm_i : std_logic; - - signal rx_rm_to_gear_reset_i : std_logic; - + signal rx_rst_fsm_ready_i : std_logic; - signal rx_serdes_ready_for_gear_i : std_logic; - signal lsm_status_i : std_logic; - - signal rx_error_delay : std_logic_vector(3 downto 0); +-- SCI Logic to obtain the barrel shifter position + type sci_ctrl is (IDLE, GET_WA, GET_WA_WAIT, GET_WA_WAIT2, GET_WA_FINISH); + signal sci_state : sci_ctrl; + signal sci_timer : unsigned( 7 downto 0) := (others => '0'); + signal start_timer : unsigned(18 downto 0) := (others => '0'); --- RX READY MODULE - signal rx_ready_i : std_logic; - signal rx_almost_ready_i : std_logic; - signal rx_rm_ready_i : std_logic; - signal rx_see_ready0_i : std_logic; - signal rx_saw_ready1_i : std_logic; - signal rx_valid_char_i : std_logic; - signal link_init_rx_reset_i : std_logic; +-- GEAR + signal gear_to_fsm_rst_i : std_logic; + signal gear_to_rm_rst_i : std_logic; -- gear keeps CBMNet ready manager reset until gear locked successfully + signal gear_to_rm_n_rst_i : std_logic; -- inverted version of above + + signal rx_data_buf_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated by gear + +-- CBMNet Ready Managers + signal rm_rx_ready_i : std_logic; + signal rm_rx_almost_ready_i : std_logic; + signal rm_rx_status_for_tx_i : std_logic; + signal rm_rx_see_ready0_i : std_logic; + signal rm_rx_saw_ready1_i : std_logic; + signal rm_rx_valid_char_i : std_logic; - signal rx_rm_rst_n, tx_rm_rst_n :std_logic; + signal rm_tx_ready_i : std_logic; + signal rm_tx_almost_ready_i : std_logic; - signal gear_to_rm_rst_i : std_logic; - signal gear_to_rm_n_rst_i : std_logic; + signal rm_rx_to_gear_reset_i : std_logic; + +-- LEDs + signal led_ok_i : std_logic; + signal led_tx_i, last_led_tx_i : std_logic; + signal led_rx_i, last_led_rx_i : std_logic; + signal led_timer_i : unsigned(20 downto 0); + +-- Stats + signal stat_reconnect_counter_i : unsigned(15 downto 0); -- counts the number of RX-serdes resets since last external reset --- TX READY MODULE - signal tx_ready_i : std_logic; - signal tx_almost_ready_i : std_logic; begin clk_125_local <= CLK; - CLK_RX_HALF_OUT <= clk_rx_half; - CLK_RX_FULL_OUT <= clk_rx_full; + CLK_RX_HALF_OUT <= rclk_125_i; + CLK_RX_FULL_OUT <= rclk_250_i; SD_TXDIS_OUT <= '0'; - rst <= (CLEAR or CTRL_OP(0)); - rst_n <= not rst; + rst_i <= (CLEAR or CTRL_OP(0)); + rst_n_i <= not rst_i; gen_slave_clock : if IS_SYNC_SLAVE = c_YES generate - clk_125_i <= clk_rx_half; + clk_125_i <= rclk_125_i; end generate; gen_master_clock : if IS_SYNC_SLAVE = c_NO generate @@ -196,11 +191,10 @@ begin hdoutn_ch0 => SD_TXD_N_OUT, -- CLOCKS - --rxiclk_ch0 => clk_125_i, txiclk_ch0 => clk_125_i, - rx_full_clk_ch0 => clk_rx_full, - -- rx_half_clk_ch0 => clk_rx_half, + rx_full_clk_ch0 => rclk_250_i, + rx_half_clk_ch0 => open, -- recovered (and correctly aligned) 125 MHz clock is generated by gear tx_full_clk_ch0 => open, tx_half_clk_ch0 => open, @@ -209,12 +203,12 @@ begin -- RESETS fpga_txrefclk => clk_125_i, - rst_qd_c => rst_qd, - serdes_rst_qd_c => serdes_rst_qd, -- always 0 - tx_serdes_rst_c => tx_serdes_rst, -- always 0 - rx_serdes_rst_ch0_c => rx_serdes_rst, - tx_pcs_rst_ch0_c => tx_pcs_rst, - rx_pcs_rst_ch0_c => rx_pcs_rst, + rst_qd_c => rst_qd_i, + serdes_rst_qd_c => serdes_rst_qd_i, -- always 0 + tx_serdes_rst_c => tx_serdes_rst_i, -- always 0 + rx_serdes_rst_ch0_c => rx_serdes_rst_i, + tx_pcs_rst_ch0_c => tx_pcs_rst_i, + rx_pcs_rst_ch0_c => rx_pcs_rst_i, tx_pwrup_ch0_c => '1', rx_pwrup_ch0_c => '1', @@ -232,7 +226,7 @@ begin rx_k_ch0 => rx_data_i(8), rx_disp_err_ch0 => open, - rx_cv_err_ch0 => rx_error, + rx_cv_err_ch0 => rx_dec_error_i, rx_div2_mode_ch0_c => '0', -- LOOPBACK @@ -240,9 +234,9 @@ begin sb_felb_rst_ch0_c => '0', -- STATUS - tx_pll_lol_qd_s => tx_pll_lol, - rx_los_low_ch0_s => rx_los_low, - rx_cdr_lol_ch0_s => rx_cdr_lol, + tx_pll_lol_qd_s => tx_pll_lol_i, + rx_los_low_ch0_s => rx_los_low_i, + rx_cdr_lol_ch0_s => rx_cdr_lol_i, lsm_status_ch0_s => lsm_status_i, SCI_WRDATA => sci_data_in_i, @@ -254,85 +248,70 @@ begin SCI_WRN => sci_write_i ); - tx_serdes_rst <= '0'; --no function - serdes_rst_qd <= '0'; --included in rst_qd - - DEBUG_OUT(19 downto 0) <= "00" & tx_data_i; - DEBUG_OUT(23 downto 20) <= "0" & tx_pll_lol & rx_los_low & rx_cdr_lol; - DEBUG_OUT(27 downto 24) <= gear_to_serder_rst_i & proper_byte_align_i & SD_PRSNT_N_IN & SD_LOS_IN; - DEBUG_OUT(31 downto 28) <= rst_qd & rx_serdes_rst & tx_pcs_rst & rx_pcs_rst; + tx_serdes_rst_i <= '0'; --no function + serdes_rst_qd_i <= '0'; --included in rst_qd_i - DEBUG_OUT(51 downto 32) <= "00" & rx_data_buf_i; - DEBUG_OUT(59 downto 52) <= rx_fsm_state & tx_fsm_state; - - DEBUG_OUT(63 downto 60) <= SERDES_ready & rx_ready_i & tx_ready_i & tx_almost_ready_i; - DEBUG_OUT(99 downto 96) <= rx_almost_ready_i & rx_see_ready0_i & rx_saw_ready1_i & rx_valid_char_i; - DEBUG_OUT(103 downto 100) <= wa_position(3 downto 0); - DEBUG_OUT(107 downto 104) <= "00" & rx_rm_to_gear_reset_i & gear_to_rm_rst_i; - ------------------------------------------------- -- Reset FSM & Link states ------------------------------------------------- THE_RX_FSM : cbmnet_phy_ecp3_rx_reset_fsm port map( - RST_N => rst_n, + RST_N => rst_n_i, RX_REFCLK => clk_125_local, - TX_PLL_LOL_QD_S => tx_pll_lol, - RX_CDR_LOL_CH_S => rx_cdr_lol, - RX_LOS_LOW_CH_S => rx_los_low, + TX_PLL_LOL_QD_S => tx_pll_lol_i, + RX_CDR_LOL_CH_S => rx_cdr_lol_i, + RX_LOS_LOW_CH_S => rx_los_low_i, RM_RESET_IN => CTRL_OP(4), --rx_reset_from_rm_i, PROPER_BYTE_ALIGN_IN=> byte_alignment_to_fsm_i, PROPER_WORD_ALIGN_IN=> word_alignment_to_fsm_i, - RX_SERDES_RST_CH_C => rx_serdes_rst, - RX_PCS_RST_CH_C => rx_pcs_rst, - STATE_OUT => rx_fsm_state + RX_SERDES_RST_CH_C => rx_serdes_rst_i, + RX_PCS_RST_CH_C => rx_pcs_rst_i, + STATE_OUT => rx_rst_fsm_state_i ); - byte_alignment_to_fsm_i <= proper_byte_align_i or CTRL_OP(1); - word_alignment_to_fsm_i <= not (gear_to_serder_rst_i or AND_ALL(rx_error_delay)) or CTRL_OP(2); - rx_error_delay <= rx_error_delay(rx_error_delay'high - 1 downto 0) & rx_error when rising_edge(clk_125_local); + byte_alignment_to_fsm_i <= (not barrel_shifter_misaligned_i); + word_alignment_to_fsm_i <= not (gear_to_fsm_rst_i or AND_ALL(rx_error_delay)); + rx_error_delay <= rx_error_delay(rx_error_delay'high - 1 downto 0) & rx_dec_error_i when rising_edge(clk_125_local); THE_TX_FSM : tx_reset_fsm port map( - RST_N => rst_n, + RST_N => rst_n_i, TX_REFCLK => clk_125_local, - TX_PLL_LOL_QD_S => tx_pll_lol, - RST_QD_C => rst_qd, - TX_PCS_RST_CH_C => tx_pcs_rst, - STATE_OUT => tx_fsm_state + TX_PLL_LOL_QD_S => tx_pll_lol_i, + RST_QD_C => rst_qd_i, + TX_PCS_RST_CH_C => tx_pcs_rst_i, + STATE_OUT => tx_rst_fsm_state_i ); --tx_data_i <= "01" & x"00" & CBMNET_READY_CHAR0; proc_rst_fsms_ready: process is begin wait until rising_edge(clk_125_local); rx_rst_fsm_ready_i <= '0'; - if rx_fsm_state = x"6" then + if rx_rst_fsm_state_i = x"6" then rx_rst_fsm_ready_i <= '1'; end if; tx_rst_fsm_ready_i <= '0'; - if tx_fsm_state = x"5" then + if tx_rst_fsm_state_i = x"5" then tx_rst_fsm_ready_i <= '1'; end if; end process; THE_GEAR: CBMNET_PHY_GEAR port map ( -- SERDES PORT - CLK_250_IN => clk_rx_full, -- in std_logic; - PCS_READY_IN => rx_serdes_ready_for_gear_i, -- in std_logic; - SERDES_RESET_OUT=> gear_to_serder_rst_i, -- out std_logic; + CLK_250_IN => rclk_250_i, -- in std_logic; + PCS_READY_IN => rx_rst_fsm_ready_i, -- in std_logic; + SERDES_RESET_OUT=> gear_to_fsm_rst_i, -- out std_logic; DATA_IN => rx_data_i, -- in std_logic_vector( 8 downto 0); -- RM PORT - RM_RESET_IN => rx_rm_to_gear_reset_i, -- in std_logic; - CLK_125_OUT => clk_rx_half, -- out std_logic; + RM_RESET_IN => rm_rx_to_gear_reset_i, -- in std_logic; + CLK_125_OUT => rclk_125_i, -- out std_logic; RESET_OUT => gear_to_rm_rst_i, -- out std_logic; DATA_OUT => rx_data_buf_i -- out std_logic_vector(17 downto 0) ); - rx_serdes_ready_for_gear_i <= (rx_rst_fsm_ready_i and proper_byte_align_i) or CTRL_OP(5); - rx_rm_to_gear_reset_i <= rx_reset_from_rm_i and not CTRL_OP(6); ------------------------------------------------- -- CBMNet Ready Modules @@ -346,20 +325,20 @@ begin rxdata_in(17 downto 0) => rx_data_buf_i, rxdata_in(19 downto 18) => "00", - tx_ready => tx_ready_i, - tx_almost_ready => tx_almost_ready_i, + tx_ready => rm_tx_ready_i, + tx_almost_ready => rm_tx_almost_ready_i, - ready_RM2LP => rx_ready_i, + ready_RM2LP => rm_rx_ready_i, rxdata_out => PHY_RXDATA_OUT, charisk_out => PHY_RXDATA_K_OUT, - almost_ready_OUT => rx_almost_ready_i, - see_ready0 => rx_see_ready0_i, - saw_ready1 => rx_saw_ready1_i, - valid_char => rx_valid_char_i, + almost_ready_OUT => rm_rx_almost_ready_i, + see_ready0 => rm_rx_see_ready0_i, + saw_ready1 => rm_rx_saw_ready1_i, + valid_char => rm_rx_valid_char_i, - reset_rx => rx_reset_from_rm_i + reset_rx => rm_rx_to_gear_reset_i ); gear_to_rm_n_rst_i <= not gear_to_rm_rst_i when rising_edge(clk_125_i); @@ -372,18 +351,20 @@ begin txdata_in => PHY_TXDATA_IN , -- : in std_logic_vector((DATAWIDTH-1) downto 0); txcharisk_in => PHY_TXDATA_K_IN, -- : in std_logic_vector((WORDS-1) downto 0); - see_ready0 => rx_see_ready0_i, -- : in std_logic; - saw_ready1 => rx_saw_ready1_i, -- : in std_logic; - valid_char => rx_valid_char_i, -- : in std_logic; - rx_rm_ready => rx_rm_ready_i, -- : in std_logic; + see_ready0 => rm_rx_see_ready0_i, -- : in std_logic; + saw_ready1 => rm_rx_saw_ready1_i, -- : in std_logic; + valid_char => rm_rx_valid_char_i, -- : in std_logic; + rx_rm_ready => rm_rx_status_for_tx_i, -- : in std_logic; - ready_RM2LP => tx_ready_i, -- : out std_logic; + ready_RM2LP => rm_tx_ready_i, -- : out std_logic; txdata_out => tx_data_i, -- : out std_logic_vector((WORDS*9)-1 downto 0); - almost_ready => tx_almost_ready_i, -- : out std_logic; + almost_ready => rm_tx_almost_ready_i, -- : out std_logic; gt11_reinit => open -- : out std_logic ); + rm_rx_status_for_tx_i <= rm_rx_almost_ready_i or rm_rx_ready_i; - process is begin + -- clock domain crossing from clk_125_local to clk_125_i + PROC_SYNC_FSM_READY: process is begin wait until rising_edge(clk_125_i); if IS_SYNC_SLAVE = c_YES then @@ -395,24 +376,21 @@ begin end if; end process; - - rx_rm_ready_i <= rx_almost_ready_i or rx_ready_i; - - SERDES_ready <= tx_ready_i and rx_ready_i when rising_edge(clk_125_i); - led_ok <= SERDES_ready; + SERDES_ready <= rm_tx_ready_i and rm_rx_ready_i when rising_edge(clk_125_i); + led_ok_i <= SERDES_ready; ------------------------------------------------- -- SCI ------------------------------------------------- - --gives access to serdes config port from slow control and reads word alignment every ~ 40 us + -- gives access to serdes config port from slow control and reads word alignment every ~ 40 us + -- upon retrival the barrel shifter is checked and - if necessary - a serdes reset is issued PROC_SCI_CTRL: process variable cnt : integer range 0 to 4 := 0; variable lsm_status_buf : std_logic; begin - wait until rising_edge(CLK); - SCI_ACK <= '0'; - proper_byte_align_i <= '1'; + wait until rising_edge(clk_125_local); + barrel_shifter_misaligned_i <= '0'; case sci_state is when IDLE => @@ -432,8 +410,8 @@ begin cnt := 0; sci_state <= IDLE; - if lsm_status_buf = '1' and wa_position(3 downto 0) /= x"0" then - proper_byte_align_i <= '0'; + if lsm_status_buf = '1' and wa_position_i(3 downto 0) /= x"0" then + barrel_shifter_misaligned_i <= '1'; end if; else @@ -451,18 +429,12 @@ begin sci_state <= GET_WA_FINISH; when GET_WA_FINISH => - wa_position(cnt*4+3 downto cnt*4) <= sci_data_out_i(3 downto 0); + wa_position_i(cnt*4+3 downto cnt*4) <= sci_data_out_i(3 downto 0); sci_state <= GET_WA; cnt := cnt + 1; end case; - if (SCI_READ = '1' or SCI_WRITE = '1') and sci_state /= IDLE then - SCI_NACK <= '1'; - else - SCI_NACK <= '0'; - end if; - lsm_status_buf := lsm_status_i; end process; @@ -472,32 +444,37 @@ begin begin wait until rising_edge(CLK); - led_rx <= not rx_cdr_lol; - led_tx <= not tx_pll_lol; + led_rx_i <= not gear_to_rm_rst_i; + led_tx_i <= tx_rst_fsm_ready_i; - if (led_timer(20) = '1') or (rx_data_buf_i(17 downto 16) = "10" and rx_data_buf_i(15 downto 0) = x"fcce") then - led_rx <= '0'; + if (led_timer_i(20) = '1') or (rx_data_buf_i(17 downto 16) = "10" and rx_data_buf_i(15 downto 0) = x"fcce") then + led_rx_i <= '0'; end if; - if (led_timer(20) = '1') or (tx_data_i(17 downto 16) = "10" and tx_data_i(15 downto 0) = x"fcce") then - led_tx <= '0'; + if (led_timer_i(20) = '1') or (tx_data_i(17 downto 16) = "10" and tx_data_i(15 downto 0) = x"fcce") then + led_tx_i <= '0'; end if; - led_timer <= led_timer + 1 ; - if led_timer(20) = '1' then - led_timer <= (others => '0'); - last_led_rx <= led_rx ; - last_led_tx <= led_tx; + led_timer_i <= led_timer_i + 1 ; + if led_timer_i(20) = '1' then + led_timer_i <= (others => '0'); + last_led_rx_i <= led_rx_i ; + last_led_tx_i <= led_tx_i; end if; end process; + LED_OK_OUT <= led_ok_i; + LED_RX_OUT <= led_rx_i; + LED_TX_OUT <= led_tx_i; + + -- Produce 1us reset pulse for external logic PROC_CLK_RESET: process is variable counter : unsigned(8 downto 0) := (others => '0'); begin - wait until rising_edge(clk_rx_half); + wait until rising_edge(rclk_125_i); CLK_RX_RESET_OUT <= '1'; - if rx_cdr_lol = '1' then + if rx_cdr_lol_i = '1' then counter := (others => '0'); elsif counter(counter'high) = '0' then @@ -508,16 +485,50 @@ begin end if; end process; - --- STAT_OP REGISTER -STAT_OP(8 downto 0) <= rx_data_i; - -STAT_OP(9) <= clk_rx_full; -STAT_OP(10) <= clk_125_i; -STAT_OP(11) <= rx_cdr_lol; -STAT_OP(12) <= rx_los_low; -STAT_OP(13) <= lsm_status_i; -STAT_OP(14) <= rx_serdes_rst; -STAT_OP(15) <= rx_pcs_rst; + + GEN_DEBUG: if INCL_DEBUG_AIDS = c_YES generate + proc_stat: process is + variable last_rx_serdes_rst_i : std_logic; + begin + wait until rising_edge(clk_125_local); + + if rst_n_i = '0' then + stat_reconnect_counter_i <= (others => '0'); + else + if rx_serdes_rst_i = '1' and last_rx_serdes_rst_i = '0' then + stat_reconnect_counter_i <= stat_reconnect_counter_i + TO_UNSIGNED(1,1); + end if; + end if; + + last_rx_serdes_rst_i := rx_serdes_rst_i; + end process; + + + DEBUG_OUT(19 downto 0) <= "00" & tx_data_i; + DEBUG_OUT(23 downto 20) <= "0" & tx_pll_lol_i & rx_los_low_i & rx_cdr_lol_i; + DEBUG_OUT(27 downto 24) <= gear_to_fsm_rst_i & barrel_shifter_misaligned_i & SD_PRSNT_N_IN & SD_LOS_IN; + DEBUG_OUT(31 downto 28) <= rst_qd_i & rx_serdes_rst_i & tx_pcs_rst_i & rx_pcs_rst_i; + + DEBUG_OUT(51 downto 32) <= "00" & rx_data_buf_i; + DEBUG_OUT(59 downto 52) <= rx_rst_fsm_state_i & tx_rst_fsm_state_i; + + DEBUG_OUT(63 downto 60) <= SERDES_ready & rm_rx_ready_i & rm_tx_ready_i & rm_tx_almost_ready_i; + DEBUG_OUT(99 downto 96) <= rm_rx_almost_ready_i & rm_rx_see_ready0_i & rm_rx_saw_ready1_i & rm_rx_valid_char_i; + DEBUG_OUT(103 downto 100) <= wa_position_i(3 downto 0); + DEBUG_OUT(107 downto 104) <= "00" & rm_rx_to_gear_reset_i & gear_to_rm_rst_i; + + DEBUG_OUT(127 downto 112) <= STD_LOGIC_VECTOR(stat_reconnect_counter_i); + + -- STAT_OP REGISTER + STAT_OP(8 downto 0) <= rx_data_i; + + STAT_OP(9) <= rclk_250_i; + STAT_OP(10) <= clk_125_i; + STAT_OP(11) <= rx_cdr_lol_i; + STAT_OP(12) <= rx_los_low_i; + STAT_OP(13) <= lsm_status_i; + STAT_OP(14) <= rx_serdes_rst_i; + STAT_OP(15) <= rx_pcs_rst_i; + end generate; end architecture; diff --git a/cbmnet/code/cbmnet_phy_gear.vhd b/cbmnet/code/cbmnet_phy_gear.vhd index 6a43775..acc6e02 100644 --- a/cbmnet/code/cbmnet_phy_gear.vhd +++ b/cbmnet/code/cbmnet_phy_gear.vhd @@ -1,5 +1,3 @@ ---Media interface for Lattice ECP3 using PCS at 2.5GHz - LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.all; @@ -27,7 +25,10 @@ entity CBMNET_PHY_GEAR is ); end entity; -architecture RTL of CBMNET_PHY_GEAR is +architecture CBMNET_PHY_GEAR_ARCH of CBMNET_PHY_GEAR is + attribute HGROUP : string; + attribute HGROUP of CBMNET_PHY_GEAR_ARCH : architecture is "cbmnet_phy_gear"; + type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_RESET, FSM_DELAY, FSM_LOCKED); signal fsm_i, fsm_next_i : FSM_STATES_T; @@ -157,4 +158,4 @@ begin indi_misalignment_i <= '1' when data_out_buf_i(17 downto 16) = "10" and data_out_buf_i(7 downto 0) = x"00" and (data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR0 or data_out_buf_i(15 downto 8) = CBMNET_READY_CHAR1 or data_out_buf_i(15 downto 8) = CBMNET_ALIGN_CHAR) else '0'; -end architecture RTL; \ No newline at end of file +end architecture CBMNET_PHY_GEAR_ARCH; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_pkg.vhd b/cbmnet/code/cbmnet_phy_pkg.vhd index 87eaa8d..253083c 100644 --- a/cbmnet/code/cbmnet_phy_pkg.vhd +++ b/cbmnet/code/cbmnet_phy_pkg.vhd @@ -1,3 +1,5 @@ +-- Hardware Dependent CBMNet PHY for the Lattice ECP3 + library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; @@ -23,7 +25,7 @@ package cbmnet_phy_pkg is CLK_RX_HALF_OUT : out std_logic := '0'; -- recovered 125 MHz CLK_RX_FULL_OUT : out std_logic := '0'; -- recovered 250 MHz - CLK_RX_RESET_OUT : out std_logic := '1'; -- set to 0, ~1us after link is assumed to be stable + CLK_RX_RESET_OUT : out std_logic := '1'; -- set to 0, ~1us after link is recognised to be stable LINK_ACTIVE_OUT : out std_logic; -- link is active and can send and receive data SERDES_ready : out std_logic; @@ -38,24 +40,20 @@ package cbmnet_phy_pkg is SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable - --Control Interface - SCI_DATA_IN : in std_logic_vector(7 downto 0) := (others => '0'); - SCI_DATA_OUT : out std_logic_vector(7 downto 0) := (others => '0'); - SCI_ADDR : in std_logic_vector(8 downto 0) := (others => '0'); - SCI_READ : in std_logic := '0'; - SCI_WRITE : in std_logic := '0'; - SCI_ACK : out std_logic := '0'; - SCI_NACK : out std_logic := '0'; - + LED_RX_OUT : out std_logic; + LED_TX_OUT : out std_logic; + LED_OK_OUT : out std_logic; + -- Status and control port STAT_OP : out std_logic_vector (15 downto 0); CTRL_OP : in std_logic_vector (15 downto 0) := (others => '0'); - STAT_DEBUG : out std_logic_vector (63 downto 0); - CTRL_DEBUG : in std_logic_vector (63 downto 0) := (others => '0'); DEBUG_OUT : out std_logic_vector (127 downto 0) := (others => '0') ); end component; +----------------------------------------------------------------------------------------------------------------------- +-- INTERNAL +----------------------------------------------------------------------------------------------------------------------- component CBMNET_PHY_GEAR is port ( -- SERDES PORT @@ -73,7 +71,6 @@ package cbmnet_phy_pkg is end component; ---------------------------------------------------- INTERNAL COMPONENT cbmnet_sfp1 PORT( hdinp_ch0 : IN std_logic; diff --git a/cbmnet/trb3_periph_cbmnet.vhd b/cbmnet/trb3_periph_cbmnet.vhd index ea0b237..00fc2dd 100644 --- a/cbmnet/trb3_periph_cbmnet.vhd +++ b/cbmnet/trb3_periph_cbmnet.vhd @@ -319,29 +319,19 @@ begin SD_PRSNT_N_IN => SFP_MOD0(1), SD_LOS_IN => SFP_LOS(1), SD_TXDIS_OUT => SFP_TXDIS(1), - - --Control Interface (not used, default values set in component def) - SCI_DATA_IN => (others => '0'), - SCI_DATA_OUT => open, - SCI_ADDR => (others => '0'), - SCI_READ => '0', - SCI_WRITE => '0', - SCI_ACK => open, - SCI_NACK => open, + + LED_RX_OUT => LED_RX(1), + LED_TX_OUT => LED_TX(1), + LED_OK_OUT => LED_LINKOK(1), -- Status and control port STAT_OP => phy_stat_op, CTRL_OP => phy_ctrl_op, - STAT_DEBUG => phy_stat_debug, - CTRL_DEBUG => phy_ctrl_debug, DEBUG_OUT => phy_debug_i ); SFP_RATESEL <= (others => '1'); - LED_LINKOK(1) <= cbm_link_active; - LED_LINKOK(2) <= cbm_SERDES_ready; - LED_RX(1) <= phy_stat_op(10); - LED_TX(1) <= phy_stat_op(11); + THE_CBM_ENDPOINT: lp_top generic map ( -- 2.43.0