From 479f285f8fb151df9e9fb750d7178972b942002a Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Wed, 25 Jun 2014 19:46:19 +0200 Subject: [PATCH] CBMNet: Relaxed Timing Constraints - Seems to work --- cbmnet/code/cbmnet_phy_ecp3.vhd | 1564 +++++++-------- cbmnet/code/cbmnet_phy_rx_gear.vhd | 396 ++-- cbmnet/compile_periph_frankfurt.pl | 6 +- cbmnet/trb3_periph_cbmnet.p2t | 4 +- cbmnet/trb3_periph_cbmnet.prj | 1 + cbmnet/trb3_periph_cbmnet.vhd | 2108 ++++++++++----------- cbmnet/trb3_periph_cbmnet_constraints.lpf | 323 +++- 7 files changed, 2355 insertions(+), 2047 deletions(-) mode change 100644 => 100755 cbmnet/trb3_periph_cbmnet.prj diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index 8530364..168dd2a 100755 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -1,781 +1,785 @@ ---Media interface for Lattice ECP3 using PCS at 2.5GHz - -LIBRARY IEEE; -USE IEEE.std_logic_1164.ALL; -USE IEEE.numeric_std.all; - -library work; -use work.trb_net_std.all; -use work.trb_net_components.all; -use work.med_sync_define.all; -use work.cbmnet_interface_pkg.all; -use work.cbmnet_phy_pkg.all; - -entity cbmnet_phy_ecp3 is - generic( - IS_SYNC_SLAVE : integer := c_YES; --select slave mode - DETERMINISTIC_LATENCY : integer := c_YES; -- if selected proper alignment of barrel shifter and word alignment is enforced (link may come up slower) - IS_SIMULATED : integer := c_NO; - INCL_DEBUG_AIDS : integer := c_YES - ); - port( - CLK : in std_logic; -- *internal* 125 MHz reference clock - RESET : in std_logic; -- synchronous reset - CLEAR : in std_logic; -- asynchronous reset - - --Internal Connection TX - PHY_TXDATA_IN : in std_logic_vector(15 downto 0); - PHY_TXDATA_K_IN : in std_logic_vector( 1 downto 0); - - --Internal Connection RX - PHY_RXDATA_OUT : out std_logic_vector(15 downto 0) := (others => '0'); - PHY_RXDATA_K_OUT : out std_logic_vector( 1 downto 0) := (others => '0'); - - 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'; - - LINK_ACTIVE_OUT : out std_logic; -- link is active and can send and receive data - SERDES_ready : out std_logic; - - --SFP Connection - SD_RXD_P_IN : in std_logic := '0'; - SD_RXD_N_IN : in std_logic := '0'; - SD_TXD_P_OUT : out std_logic := '0'; - SD_TXD_N_OUT : out std_logic := '0'; - - SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place,entity '1' = no SFP mounted) - SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) - SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable - - 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) := (others => '0'); - CTRL_OP : in std_logic_vector ( 15 downto 0) := (others => '0'); - DEBUG_OUT : out std_logic_vector (511 downto 0) := (others => '0') - ); -end entity; - -architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is - -- Placer Directives - attribute HGROUP : string; - -- for whole architecture - attribute HGROUP of cbmnet_phy_ecp3_arch : architecture is "cbmnet_phy_group"; - - attribute syn_hier: string; - attribute syn_hier of cbmnet_phy_ecp3_arch : architecture is "hard"; - - - attribute syn_sharing : string; - attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off"; - - constant WA_FIXATION : integer := c_YES; - signal DETERMINISTIC_LATENCY_C : std_logic; - --- Clocks and global resets - signal clk_125_local : std_logic; -- local 125 MHz reference clock driven by clock generators - 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 clk_tx_full_i : std_logic; -- 250 MHz clock generated by the serdes's TX-PLL - - signal clk_tx_half_i : std_logic; -- 250 MHz clock generated by the serdes's TX-PLL - - 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_dec_errors2_i : std_logic_vector(1 downto 0); - signal rx_dec_error_125_i, rx_dec_error_125_buf_i: std_logic_vector(1 downto 0); - - signal rx_error_delay : std_logic_vector(3 downto 0); -- shift register to detect a "stable error condition" - - -- resets - signal rst_qd_i : std_logic; - signal serdes_rst_qd_i : std_logic; - - signal tx_serdes_rst_i : std_logic; - signal tx_pcs_rst_i : std_logic; - - signal rx_serdes_rst_i : std_logic; - signal rx_pcs_rst_i : std_logic; - - -- data - signal tx_data_to_serdes_i : std_logic_vector( 8 downto 0); -- received by SERDES - signal rx_data_from_serdes_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; - signal sci_addr_i : std_logic_vector(8 downto 0); - signal sci_data_in_i : std_logic_vector(7 downto 0) := (others => '0'); - signal sci_data_out_i : std_logic_vector(7 downto 0); - signal sci_read_i : std_logic; - signal sci_write_i : std_logic; - 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_i : std_logic_vector(15 downto 0) := x"FFFF"; - signal barrel_shifter_misaligned_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; - - signal byte_alignment_to_fsm_i : std_logic; - signal word_alignment_to_fsm_i : std_logic; - - signal rx_rst_fsm_ready_i : std_logic; - - signal serdes_ready_i : std_logic; - --- 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'); - --- 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_from_gear_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated by gear - - signal rx_data_i : std_logic_vector(17 downto 0); -- in the front end this signal is identical to rx_data_from_gear_i - -- otherwise a clock domain crossing from rclk_125_i to clk_125_local is - -- necessary. this signal will not exhibit a deterministic latency !!!!!! - -- (however, this is no problem, as the clock master will not receive DLMs) - - signal rx_data_debug_i : std_logic_vector(17 downto 0); - - signal tx_data_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated fed to gear - signal tx_gear_reset_i : std_logic; - signal tx_gear_allow_relock_i : std_logic; - - signal tx_gear_ready_i : std_logic; - - signal rx_gear_debug_i : std_logic_vector(31 downto 0); - signal tx_gear_debug_i : std_logic_vector(31 downto 0); - --- 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 rm_tx_ready_i : std_logic; - signal rm_tx_almost_ready_i : std_logic; - - signal rm_rx_to_gear_reset_i : std_logic; - - signal rm_rx_data_buf_i : std_logic_vector(17 downto 0); - - signal rm_rx_ebtb_code_err_cntr_clr_i : std_logic; - signal rm_rx_ebtb_disp_err_cntr_clr_i : std_logic; - signal rm_rx_ebtb_code_err_cntr_i : std_logic_vector(15 downto 0); - signal rm_rx_ebtb_disp_err_cntr_i : std_logic_vector(15 downto 0); - signal rm_rx_ebtb_code_err_cntr_flag_i : std_logic; - signal rm_rx_ebtb_disp_err_cntr_flag_i : std_logic; - - signal rm_tx_to_rx_reinit_i : std_logic; - - signal rm_rx_see_reinit : std_logic; - signal rm_rx_ebtb_detect_i : std_logic; - signal rm_tx_link_lost_i : std_logic; - - signal rm_tx_pcs_startup_cntr_clr : std_logic; - signal rm_tx_pcs_startup_cntr : std_logic_vector(15 downto 0); -- Counts for link startups - signal rm_tx_pcs_startup_cntr_flag : std_logic; - - signal rm_rx_rxpcs_ready_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 - signal stat_last_reconnect_duration_i : unsigned(31 downto 0); - signal stat_decode_error_counter_i : unsigned(31 downto 0); - - - signal stat_wa_int_i : std_logic_vector(15 downto 0) := (others => '0'); - - signal tx_data_debug_i : std_logic_vector(17 downto 0); - signal tx_data_debug_state_i : std_logic; - - signal low_level_rx_see_dlm0 : std_logic; - signal low_level_tx_see_dlm0 : std_logic; - signal low_level_tx_see_dlm0_125 : std_logic; - - signal stat_dlm_counter_i : unsigned(15 downto 0); - signal stat_init_ack_counter_i : unsigned(15 downto 0); - - signal test_line_i : std_logic_vector(15 downto 0) := x"0001"; - - signal rx_stab_i, tx_stab_i : unsigned(15 downto 0); - - signal rx_data_sp_i0, rx_data_sp_i1, rx_data_sp_i2, rx_data_sp_i3 : std_logic_vector(17 downto 0); - - --signal see_dlm_lb_i, see_dlm_lb_buf_i : std_logic_vector(15 downto 0) := (others => '0'); - --signal see_dlm_lb_aggr_i, see_dlm_hb_i, see_dlm_hb_buf_i : std_logic; - --signal stat_sync_dlm_counter_i, stat_sync_dlm_inv_counter_i : unsigned(7 downto 0); - -begin - assert IS_SYNC_SLAVE = c_YES - report "Support of clock master PHY is not tested anymore and probably broken" - severity failure; - - DETERMINISTIC_LATENCY_C <= '1' when DETERMINISTIC_LATENCY = c_YES else '0'; - - clk_125_local <= CLK; - CLK_RX_HALF_OUT <= rclk_125_i; - CLK_RX_FULL_OUT <= rclk_250_i; - - SD_TXDIS_OUT <= '0'; - - rst_i <= (CLEAR or CTRL_OP(0)); - rst_n_i <= not rst_i; - - ------------------------------------------------- - -- Serdes - ------------------------------------------------- - THE_SERDES : cbmnet_sfp1 - port map( - -- SERIAL DATA PORTS - hdinp_ch0 => SD_RXD_P_IN, - hdinn_ch0 => SD_RXD_N_IN, - hdoutp_ch0 => SD_TXD_P_OUT, - hdoutn_ch0 => SD_TXD_N_OUT, - - -- CLOCKS - 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 => clk_tx_full_i, - tx_half_clk_ch0 => open, - - fpga_rxrefclk_ch0 => clk_125_local, - fpga_txrefclk => rclk_125_i, - txiclk_ch0 => rclk_250_i, - - -- RESETS - 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', - - -- TX DATA PORT - txdata_ch0 => tx_data_to_serdes_i(7 downto 0), - tx_k_ch0 => tx_data_to_serdes_i(8), - - tx_force_disp_ch0 => '0', - tx_disp_sel_ch0 => '0', - tx_div2_mode_ch0_c => '0', - - -- RX DATA PORT - rxdata_ch0 => rx_data_from_serdes_i(7 downto 0), - rx_k_ch0 => rx_data_from_serdes_i(8), - - rx_disp_err_ch0 => open, - rx_cv_err_ch0 => rx_dec_error_i, - rx_div2_mode_ch0_c => '0', - - -- LOOPBACK - sb_felb_ch0_c => '0', - sb_felb_rst_ch0_c => '0', - - -- STATUS - 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, - SCI_RDDATA => sci_data_out_i, - SCI_ADDR => sci_addr_i(5 downto 0), - SCI_SEL_QUAD => sci_qd_i, - SCI_SEL_CH0 => sci_ch_i(0), - SCI_RD => sci_read_i, - SCI_WRN => sci_write_i - ); - - THE_RX_GEAR: CBMNET_PHY_RX_GEAR - generic map ( - IS_SYNC_SLAVE => IS_SYNC_SLAVE - ) port map ( - -- SERDES PORT - 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_from_serdes_i, -- in std_logic_vector( 8 downto 0); - - -- RM PORT - 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_from_gear_i, -- out std_logic_vector(17 downto 0) - - DEBUG_OUT => rx_gear_debug_i - ); - - rx_data_i <= rx_data_from_gear_i when rising_edge(clk_125_local); - - THE_TX_GEAR: CBMNET_PHY_TX_GEAR - generic map (IS_SYNC_SLAVE => IS_SYNC_SLAVE) - port map ( - CLK_250_IN => clk_tx_full_i, -- in std_logic; - CLK_125_IN => rclk_125_i, -- in std_logic; - CLK_125_OUT => clk_tx_half_i, - - RESET_IN => tx_gear_reset_i, -- in std_logic; - ALLOW_RELOCK_IN => tx_gear_allow_relock_i, -- in std_logic - - TX_READY_OUT => tx_gear_ready_i, - - DATA_IN => tx_data_i, -- in std_logic_vector(17 downto 0) - DATA_OUT => tx_data_to_serdes_i -- out std_logic_vector(8 downto 0); - ); - tx_gear_reset_i <= not tx_rst_fsm_ready_i; - tx_gear_allow_relock_i <= '0'; - - - - tx_serdes_rst_i <= '0'; --no function - serdes_rst_qd_i <= '0'; --included in rst_qd_i - - ------------------------------------------------- - -- Reset FSM & Link states - ------------------------------------------------- - THE_RX_FSM : cbmnet_phy_ecp3_rx_reset_fsm - generic map ( - IS_SIMULATED => IS_SIMULATED - ) - port map( - RST_N => rst_n_i, - RX_REFCLK => clk_125_local, - 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_i, - RX_PCS_RST_CH_C => rx_pcs_rst_i, - STATE_OUT => rx_rst_fsm_state_i - ); - byte_alignment_to_fsm_i <= not (DETERMINISTIC_LATENCY_C and barrel_shifter_misaligned_i) or CTRL_OP(3); - word_alignment_to_fsm_i <= not (gear_to_fsm_rst_i or AND_ALL(rx_error_delay)) or CTRL_OP(5); - - - -- decode error - rx_dec_error_125_i <= rx_dec_error_125_i(0) & rx_dec_error_i when rising_edge(rclk_250_i); - rx_dec_error_125_buf_i <= rx_dec_error_125_i when rising_edge(clk_125_local); - - rx_error_delay <= rx_error_delay(rx_error_delay'high - 2 downto 0) & rx_dec_error_125_buf_i when rising_edge(clk_125_local); - process is - begin - wait until rising_edge(rclk_125_i); - if RESET='1' then - stat_decode_error_counter_i <= (others => '0'); - elsif rx_dec_error_125_buf_i = "11" then - stat_decode_error_counter_i <= stat_decode_error_counter_i + 2; - elsif rx_dec_error_125_buf_i = "10" or rx_dec_error_125_buf_i = "01" then - stat_decode_error_counter_i <= stat_decode_error_counter_i + 1; - end if; - end process; - - - THE_TX_FSM : cbmnet_phy_ecp3_tx_reset_fsm - generic map ( - IS_SIMULATED => IS_SIMULATED - ) - port map( - RST_N => rst_n_i, - TX_REFCLK => clk_125_local, - 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 - ); - - proc_rst_fsms_ready: process is begin - wait until rising_edge(clk_125_local); - rx_rst_fsm_ready_i <= '0'; - 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_rst_fsm_state_i = x"5" then - tx_rst_fsm_ready_i <= '1'; - end if; - end process; - - ------------------------------------------------- - -- CBMNet Ready Modules - ------------------------------------------------- - THE_RX_READY: cn_rx_pcs_wrapper - generic map ( - SIMULATION => 0, - USE_BS => 0, - SYNC_SIGNALS => 1, - INCL_8B10B_DEC => 0 - ) - port map ( - rx_clk => rclk_125_i, -- in std_logic; - res_n_rx => gear_to_rm_n_rst_i, -- in std_logic; - rxpcs_reinit => rm_tx_to_rx_reinit_i, -- in std_logic; -- Reinit RXPCS - rxdata_in(17 downto 0) => rx_data_i, - rxdata_in(19 downto 18) => "00", - reset_rx_cdr => rm_rx_to_gear_reset_i, -- out std_logic; -- Reset RX CDR to align - rxpcs_almost_ready => rm_rx_almost_ready_i, -- out std_logic; -- Ready1 detected, only waiting for break - rxpcs_ready => rm_rx_rxpcs_ready_i, -- out std_logic; -- RXPCS initialization done - see_reinit => rm_rx_see_reinit, -- out std_logic; -- Initialization pattern detected although ready - bs_position => open, -- out std_logic_vector(4 downto 0); -- Number of bit-shifts necessary for word-alignment - rxdata_out => rm_rx_data_buf_i, -- out std_logic_vector(17 downto 0); - ebtb_detect => rm_rx_ebtb_detect_i, -- out std_logic; -- Depends on the FSM state, alignment done - - --diagnostics - ebtb_code_err_cntr_clr => '0', -- in std_logic; - ebtb_disp_err_cntr_clr => '0', -- in std_logic; - ebtb_code_err_cntr => open, -- out std_logic_vector(15 downto 0); -- Counts for code errors if ebtb_detect is true - ebtb_disp_err_cntr => open, -- out std_logic_vector(15 downto 0); -- Counts for disparity errors if ebtb_detect is true - ebtb_code_err_cntr_flag => open,-- out std_logic; - ebtb_disp_err_cntr_flag => open -- out std_logic - ); - - PHY_RXDATA_OUT <= rx_data_i(15 downto 0); - PHY_RXDATA_K_OUT <= rx_data_i(17 downto 16); - gear_to_rm_n_rst_i <= not gear_to_rm_rst_i when rising_edge(rclk_125_i); - - - THE_TX_READY: cn_tx_pcs_wrapper - generic map ( - REVERSE_OUTPUT => 0, --integer range 0 to 1 := 1; - LINK_MASTER => 0, --integer range 0 to 1 := 1; - SYNC_SIGNALS => 1, --integer range 0 to 1 := 1; - - INCL_8B10B_ENC => 0 --integer range 0 to 1 := 1 - ) port map ( - tx_clk => rclk_125_i, --in std_logic; - res_n_tx => tx_rst_fsm_ready_buf_i, --in std_logic; - pcs_restart => CTRL_OP(14), --in std_logic; -- restart pcs layer - pma_ready => tx_gear_ready_i, --in std_logic; - ebtb_detect => rm_rx_ebtb_detect_i, --in std_logic; -- alignment done and valid 8b10b stream detected - see_reinit => rm_rx_see_reinit, --in std_logic; - rxpcs_almost_ready => rm_rx_almost_ready_i, --in std_logic; - txdata_in(15 downto 0) => PHY_TXDATA_IN, --in std_logic_vector(17 downto 0); - txdata_in(17 downto 16)=> PHY_TXDATA_K_IN, - - txpcs_ready => rm_tx_ready_i, --out std_logic; - link_lost => rm_tx_link_lost_i, --out std_logic; - reset_out => open, --out std_logic; - rxpcs_reinit => rm_tx_to_rx_reinit_i, --out std_logic; -- Reinit the RXPCS FSM - txdata_out => tx_data_i, --out std_logic_vector(17 downto 0); -- tx data to transceiver - txdata_out_coded => open, --out std_logic_vector(19 downto 0); -- tx data to transceiver already 8b10b coded - - --diagnostics - pcs_startup_cntr_clr => rm_tx_pcs_startup_cntr_clr, --in std_logic; - pcs_startup_cntr => rm_tx_pcs_startup_cntr, --out std_logic_vector(15 downto 0); -- Counts for link startups - pcs_startup_cntr_flag => rm_tx_pcs_startup_cntr_flag --out std_logic; - ); - - - rm_rx_status_for_tx_i <= rm_rx_almost_ready_i or rm_rx_ready_i; - - -- clock domain crossing from clk_125_local to rclk_125_i - PROC_SYNC_FSM_READY: process is begin - wait until rising_edge(rclk_125_i); - - if IS_SYNC_SLAVE = c_YES then - tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i and not gear_to_rm_rst_i; - - else - tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i; - - end if; - end process; - - serdes_ready_i <= rm_tx_ready_i and rm_rx_rxpcs_ready_i when rising_edge(rclk_125_i); - led_ok_i <= serdes_ready_i; - SERDES_ready <= serdes_ready_i; - - ------------------------------------------------- - -- SCI - ------------------------------------------------- - -- 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; - begin - wait until rising_edge(clk_125_local); - - case sci_state is - when IDLE => - sci_ch_i <= x"0"; - sci_qd_i <= '0'; - sci_reg_i <= '0'; - sci_read_i <= '0'; - sci_write_i <= '0'; - sci_timer <= sci_timer + 1; - if sci_timer(sci_timer'left) = '1' then - sci_timer <= (others => '0'); - sci_state <= GET_WA; - end if; - - when GET_WA => - if cnt = 4 then - cnt := 0; - sci_state <= IDLE; - - else - sci_state <= GET_WA_WAIT; - sci_addr_i <= '0' & x"22"; - sci_ch_i <= x"0"; - sci_ch_i(cnt) <= '1'; - sci_read_i <= '1'; - end if; - - when GET_WA_WAIT => - sci_state <= GET_WA_WAIT2; - - when GET_WA_WAIT2 => - sci_state <= GET_WA_FINISH; - - when GET_WA_FINISH => - 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; - end process; - - process is begin - wait until rising_edge(clk_125_local); - barrel_shifter_misaligned_i <= '0'; - if lsm_status_i = '1' and wa_position_i(3 downto 0) /= x"0" then - barrel_shifter_misaligned_i <= '1'; - end if; - end process; - - -- 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(rclk_125_i); - CLK_RX_RESET_OUT <= '1'; - - if serdes_ready_i = '0' then - counter := (others => '0'); - - elsif counter(counter'high) = '0' then - counter := counter + 1; - - else - CLK_RX_RESET_OUT <= '0'; - - end if; - end process; - - - 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'); - stat_last_reconnect_duration_i <= (others => '0'); - stat_wa_int_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; - - if serdes_ready_i = '0' then - stat_last_reconnect_duration_i <= stat_last_reconnect_duration_i + TO_UNSIGNED(1,1); - end if; - - stat_wa_int_i <= stat_wa_int_i or wa_position_i; - end if; - - last_rx_serdes_rst_i := rx_serdes_rst_i; - end process; - - PROC_SENSE_TX_DLM125: process is - begin - wait until rising_edge(rclk_125_i); - - low_level_tx_see_dlm0_125 <= '0'; - if tx_data_i = "10" & x"fb6a" then - low_level_tx_see_dlm0_125 <= '1'; - end if; - end process; - - process is - variable rx_v, tx_v : std_logic_vector(17 downto 0); - begin - wait until rising_edge(rclk_125_i); - - if reset = '1' or rx_v /= rx_data_i then rx_stab_i <= (others => '0'); - else rx_stab_i <= rx_stab_i + 1; end if; - - if reset = '1' or tx_v /= tx_data_i then tx_stab_i <= (others => '0'); - else tx_stab_i <= tx_stab_i + 1; end if; - - rx_v := rx_data_i; - tx_v := tx_data_i; - end process; - - - PROC_SENSE_DLMS: process begin - wait until rising_edge(rclk_125_i); - - if serdes_ready_i = '0' then - stat_dlm_counter_i <= (others => '0'); - elsif rx_data_i(17) = '1' and rx_data_i(15 downto 8) = K277 then - stat_dlm_counter_i <= stat_dlm_counter_i + TO_UNSIGNED(1,1); - end if; - end process; - --- DEBUG_OUT_BEGIN - DEBUG_OUT(19 downto 0) <= "00" & tx_data_i(17 downto 0); - 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_i(17 downto 0); - DEBUG_OUT( 59 downto 52) <= rx_rst_fsm_state_i(3 downto 0) & tx_rst_fsm_state_i(3 downto 0); - - DEBUG_OUT( 63 downto 60) <= serdes_ready_i & rm_rx_ready_i & rm_tx_ready_i & rm_tx_almost_ready_i; - - DEBUG_OUT( 79 downto 64) <= rx_gear_debug_i(15 downto 0); - DEBUG_OUT( 95 downto 80) <= tx_gear_debug_i(15 downto 0); - - DEBUG_OUT( 99 downto 96) <= rm_rx_almost_ready_i & rm_rx_rxpcs_ready_i & rm_rx_see_reinit & rm_rx_ebtb_detect_i; - DEBUG_OUT(103 downto 100) <= wa_position_i(3 downto 0); - DEBUG_OUT(107 downto 104) <= word_alignment_to_fsm_i & byte_alignment_to_fsm_i & rm_rx_to_gear_reset_i & gear_to_rm_rst_i; - - DEBUG_OUT(123 downto 108) <= tx_stab_i(15 downto 0); - - DEBUG_OUT(139 downto 124) <= rx_stab_i(15 downto 0); - DEBUG_OUT(147 downto 140) <= stat_init_ack_counter_i(7 downto 0); - DEBUG_OUT(179 downto 148) <= stat_last_reconnect_duration_i(31 downto 0); - - DEBUG_OUT(195 downto 180) <= stat_reconnect_counter_i(15 downto 0); - DEBUG_OUT(211 downto 196) <= stat_dlm_counter_i(15 downto 0); - DEBUG_OUT(243 downto 212) <= rm_rx_ebtb_code_err_cntr_i(15 downto 0) & rm_rx_ebtb_disp_err_cntr_i(15 downto 0); - - DEBUG_OUT(315 downto 244) <= rx_data_sp_i3(17 downto 0) & rx_data_sp_i2(17 downto 0) & rx_data_sp_i1(17 downto 0) & rx_data_sp_i0(17 downto 0); - - DEBUG_OUT(333 downto 316) <= PHY_TXDATA_K_IN(1 downto 0) & PHY_TXDATA_IN(15 downto 0); - --DEBUG_OUT(341 downto 334) <= stat_sync_dlm_inv_counter_i(7 downto 0) when rising_edge(rclk_125_i); - --DEBUG_OUT(349 downto 342) <= stat_sync_dlm_counter_i(7 downto 0) when rising_edge(rclk_125_i); - - - - --DEBUG_OUT(255 downto 170) <= (others => '0'); - --- DEBUG_OUT_END - - process is - begin - wait until rising_edge(rclk_125_i); - if rx_data_i /= "10" & x"fcc3" then - rx_data_sp_i0 <= rx_data_i; - rx_data_sp_i1 <= rx_data_sp_i0; - rx_data_sp_i2 <= rx_data_sp_i1; - rx_data_sp_i3 <= rx_data_sp_i2; - end if; - end process; - - --PROC_SEE_FAST_DLM: process is - --variable saw_lb_v, saw_hb_v : std_logic; - --begin - --wait until rising_edge(rclk_250_i); - - --see_dlm_hb_i <= '0' ; - --if rx_data_from_serdes_i = '1' & K277 then - --see_dlm_hb_i <= '1'; - --end if; - --see_dlm_hb_buf_i <= see_dlm_hb_i; - - --see_dlm_lb_aggr_i <= '0'; - --if rx_data_from_serdes_i = '1' & K277 then - --see_dlm_lb_aggr_i <= OR_ALL(see_dlm_lb_buf_i); - --end if; - - - - --if rst_i = '1' then - --stat_sync_dlm_counter_i <= (others => '0'); - --stat_sync_dlm_inv_counter_i <= (others => '0'); - --saw_lb_v := '0'; - --saw_hb_v := '0'; - - --else - --if see_dlm_hb_buf_i = '1' and saw_lb_v = '1' then - --stat_sync_dlm_counter_i <= stat_sync_dlm_counter_i + 1; - --end if; - - --if see_dlm_lb_aggr_i = '1' and saw_hb_v = '1' then - --stat_sync_dlm_inv_counter_i <= stat_sync_dlm_inv_counter_i + 1; - --end if; - - --saw_lb_v := see_dlm_lb_aggr_i; - --saw_hb_v := see_dlm_hb_buf_i; - --end if; - --end process; - - --see_dlm_lb_i(0) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(10, 3) else '0'; - --see_dlm_lb_i(1) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(14, 1) else '0'; - --see_dlm_lb_i(2) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(20, 1) else '0'; - --see_dlm_lb_i(3) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(20, 6) else '0'; - - --see_dlm_lb_i(4) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(22, 3) else '0'; - --see_dlm_lb_i(5) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(28, 2) else '0'; - --see_dlm_lb_i(6) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(28, 5) else '0'; - --see_dlm_lb_i(7) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(06, 2) else '0'; - - --see_dlm_lb_i(8) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(14, 6) else '0'; - --see_dlm_lb_i(9) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 3, 1) else '0'; - --see_dlm_lb_i(10)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(11, 2) else '0'; - --see_dlm_lb_i(11)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(17, 2) else '0'; - - --see_dlm_lb_i(12)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(25, 3) else '0'; - --see_dlm_lb_i(13)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(17, 5) else '0'; - --see_dlm_lb_i(14)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 3, 6) else '0'; - --see_dlm_lb_i(15)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 5, 3) else '0'; - - --see_dlm_lb_buf_i <= see_dlm_lb_i when rising_edge(rclk_250_i); - - - end generate; +--Media interface for Lattice ECP3 using PCS at 2.5GHz + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.med_sync_define.all; +use work.cbmnet_interface_pkg.all; +use work.cbmnet_phy_pkg.all; + +entity cbmnet_phy_ecp3 is + generic( + IS_SYNC_SLAVE : integer := c_YES; --select slave mode + DETERMINISTIC_LATENCY : integer := c_YES; -- if selected proper alignment of barrel shifter and word alignment is enforced (link may come up slower) + IS_SIMULATED : integer := c_NO; + INCL_DEBUG_AIDS : integer := c_YES + ); + port( + CLK : in std_logic; -- *internal* 125 MHz reference clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + + --Internal Connection TX + PHY_TXDATA_IN : in std_logic_vector(15 downto 0); + PHY_TXDATA_K_IN : in std_logic_vector( 1 downto 0); + + --Internal Connection RX + PHY_RXDATA_OUT : out std_logic_vector(15 downto 0) := (others => '0'); + PHY_RXDATA_K_OUT : out std_logic_vector( 1 downto 0) := (others => '0'); + + 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'; + + LINK_ACTIVE_OUT : out std_logic; -- link is active and can send and receive data + SERDES_ready : out std_logic; + + --SFP Connection + SD_RXD_P_IN : in std_logic := '0'; + SD_RXD_N_IN : in std_logic := '0'; + SD_TXD_P_OUT : out std_logic := '0'; + SD_TXD_N_OUT : out std_logic := '0'; + + SD_PRSNT_N_IN : in std_logic; -- SFP Present ('0' = SFP in place,entity '1' = no SFP mounted) + SD_LOS_IN : in std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal) + SD_TXDIS_OUT : out std_logic := '0'; -- SFP disable + + 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) := (others => '0'); + CTRL_OP : in std_logic_vector ( 15 downto 0) := (others => '0'); + DEBUG_OUT : out std_logic_vector (511 downto 0) := (others => '0') + ); +end entity; + +architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is + -- Placer Directives + attribute HGROUP : string; + -- for whole architecture + attribute HGROUP of cbmnet_phy_ecp3_arch : architecture is "cbmnet_phy_group"; + + attribute syn_hier: string; + attribute syn_hier of cbmnet_phy_ecp3_arch : architecture is "hard"; + + + attribute syn_sharing : string; + attribute syn_sharing of cbmnet_phy_ecp3_arch : architecture is "off"; + + constant WA_FIXATION : integer := c_YES; + signal DETERMINISTIC_LATENCY_C : std_logic; + +-- Clocks and global resets + signal clk_125_local : std_logic; -- local 125 MHz reference clock driven by clock generators + 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 clk_tx_full_i : std_logic; -- 250 MHz clock generated by the serdes's TX-PLL + + signal clk_tx_half_i : std_logic; -- 250 MHz clock generated by the serdes's TX-PLL + + 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_dec_error_delayed_i : std_logic; + signal rx_dec_error_250_i : std_logic_vector(1 downto 0); + signal rx_dec_error_125_i, rx_dec_error_125_buf_i: std_logic_vector(3 downto 0); + + signal rx_error_delay : std_logic_vector(3 downto 0); -- shift register to detect a "stable error condition" + + -- resets + signal rst_qd_i : std_logic; + signal serdes_rst_qd_i : std_logic; + + signal tx_serdes_rst_i : std_logic; + signal tx_pcs_rst_i : std_logic; + + signal rx_serdes_rst_i : std_logic; + signal rx_pcs_rst_i : std_logic; + + -- data + signal tx_data_to_serdes_i : std_logic_vector( 8 downto 0); -- received by SERDES + signal rx_data_from_serdes_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; + signal sci_addr_i : std_logic_vector(8 downto 0); + signal sci_data_in_i : std_logic_vector(7 downto 0) := (others => '0'); + signal sci_data_out_i : std_logic_vector(7 downto 0); + signal sci_read_i : std_logic; + signal sci_write_i : std_logic; + 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_i : std_logic_vector(15 downto 0) := x"FFFF"; + signal barrel_shifter_misaligned_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; + + signal byte_alignment_to_fsm_i : std_logic; + signal word_alignment_to_fsm_i : std_logic; + + signal rx_rst_fsm_ready_i : std_logic; + + signal serdes_ready_i : std_logic; + +-- 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'); + +-- 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_from_gear_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated by gear + + signal rx_data_i : std_logic_vector(17 downto 0); -- in the front end this signal is identical to rx_data_from_gear_i + -- otherwise a clock domain crossing from rclk_125_i to clk_125_local is + -- necessary. this signal will not exhibit a deterministic latency !!!!!! + -- (however, this is no problem, as the clock master will not receive DLMs) + + signal rx_data_debug_i : std_logic_vector(17 downto 0); + + signal tx_data_i : std_logic_vector(17 downto 0); -- 16(+2) bit word generated fed to gear + signal tx_gear_reset_i : std_logic; + signal tx_gear_allow_relock_i : std_logic; + + signal tx_gear_ready_i : std_logic; + + signal rx_gear_debug_i : std_logic_vector(31 downto 0); + signal tx_gear_debug_i : std_logic_vector(31 downto 0); + +-- 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 rm_tx_ready_i : std_logic; + signal rm_tx_almost_ready_i : std_logic; + + signal rm_rx_to_gear_reset_i : std_logic; + + signal rm_rx_data_buf_i : std_logic_vector(17 downto 0); + + signal rm_rx_ebtb_code_err_cntr_clr_i : std_logic; + signal rm_rx_ebtb_disp_err_cntr_clr_i : std_logic; + signal rm_rx_ebtb_code_err_cntr_i : std_logic_vector(15 downto 0); + signal rm_rx_ebtb_disp_err_cntr_i : std_logic_vector(15 downto 0); + signal rm_rx_ebtb_code_err_cntr_flag_i : std_logic; + signal rm_rx_ebtb_disp_err_cntr_flag_i : std_logic; + + signal rm_tx_to_rx_reinit_i : std_logic; + + signal rm_rx_see_reinit : std_logic; + signal rm_rx_ebtb_detect_i : std_logic; + signal rm_tx_link_lost_i : std_logic; + + signal rm_tx_pcs_startup_cntr_clr : std_logic; + signal rm_tx_pcs_startup_cntr : std_logic_vector(15 downto 0); -- Counts for link startups + signal rm_tx_pcs_startup_cntr_flag : std_logic; + + signal rm_rx_rxpcs_ready_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 + signal stat_last_reconnect_duration_i : unsigned(31 downto 0); + signal stat_decode_error_counter_i : unsigned(31 downto 0); + + + signal stat_wa_int_i : std_logic_vector(15 downto 0) := (others => '0'); + + signal tx_data_debug_i : std_logic_vector(17 downto 0); + signal tx_data_debug_state_i : std_logic; + + signal low_level_rx_see_dlm0 : std_logic; + signal low_level_tx_see_dlm0 : std_logic; + signal low_level_tx_see_dlm0_125 : std_logic; + + signal stat_dlm_counter_i : unsigned(15 downto 0); + signal stat_init_ack_counter_i : unsigned(15 downto 0); + + signal test_line_i : std_logic_vector(15 downto 0) := x"0001"; + + signal rx_stab_i, tx_stab_i : unsigned(15 downto 0); + + signal rx_data_sp_i0, rx_data_sp_i1, rx_data_sp_i2, rx_data_sp_i3 : std_logic_vector(17 downto 0); + + --signal see_dlm_lb_i, see_dlm_lb_buf_i : std_logic_vector(15 downto 0) := (others => '0'); + --signal see_dlm_lb_aggr_i, see_dlm_hb_i, see_dlm_hb_buf_i : std_logic; + --signal stat_sync_dlm_counter_i, stat_sync_dlm_inv_counter_i : unsigned(7 downto 0); + +begin + assert IS_SYNC_SLAVE = c_YES + report "Support of clock master PHY is not tested anymore and probably broken" + severity failure; + + DETERMINISTIC_LATENCY_C <= '1' when DETERMINISTIC_LATENCY = c_YES else '0'; + + clk_125_local <= CLK; + CLK_RX_HALF_OUT <= rclk_125_i; + CLK_RX_FULL_OUT <= rclk_250_i; + + SD_TXDIS_OUT <= '0'; + + rst_i <= (CLEAR or CTRL_OP(0)); + rst_n_i <= not rst_i; + + ------------------------------------------------- + -- Serdes + ------------------------------------------------- + THE_SERDES : cbmnet_sfp1 + port map( + -- SERIAL DATA PORTS + hdinp_ch0 => SD_RXD_P_IN, + hdinn_ch0 => SD_RXD_N_IN, + hdoutp_ch0 => SD_TXD_P_OUT, + hdoutn_ch0 => SD_TXD_N_OUT, + + -- CLOCKS + 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 => clk_tx_full_i, + tx_half_clk_ch0 => open, + + fpga_rxrefclk_ch0 => clk_125_local, + fpga_txrefclk => rclk_125_i, + txiclk_ch0 => rclk_250_i, + + -- RESETS + 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', + + -- TX DATA PORT + txdata_ch0 => tx_data_to_serdes_i(7 downto 0), + tx_k_ch0 => tx_data_to_serdes_i(8), + + tx_force_disp_ch0 => '0', + tx_disp_sel_ch0 => '0', + tx_div2_mode_ch0_c => '0', + + -- RX DATA PORT + rxdata_ch0 => rx_data_from_serdes_i(7 downto 0), + rx_k_ch0 => rx_data_from_serdes_i(8), + + rx_disp_err_ch0 => open, + rx_cv_err_ch0 => rx_dec_error_i, + rx_div2_mode_ch0_c => '0', + + -- LOOPBACK + sb_felb_ch0_c => '0', + sb_felb_rst_ch0_c => '0', + + -- STATUS + 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, + SCI_RDDATA => sci_data_out_i, + SCI_ADDR => sci_addr_i(5 downto 0), + SCI_SEL_QUAD => sci_qd_i, + SCI_SEL_CH0 => sci_ch_i(0), + SCI_RD => sci_read_i, + SCI_WRN => sci_write_i + ); + + THE_RX_GEAR: CBMNET_PHY_RX_GEAR + generic map ( + IS_SYNC_SLAVE => IS_SYNC_SLAVE + ) port map ( + -- SERDES PORT + 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_from_serdes_i, -- in std_logic_vector( 8 downto 0); + + -- RM PORT + 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_from_gear_i, -- out std_logic_vector(17 downto 0) + + DEBUG_OUT => rx_gear_debug_i + ); + + rx_data_i <= rx_data_from_gear_i when rising_edge(clk_125_local); + + THE_TX_GEAR: CBMNET_PHY_TX_GEAR + generic map (IS_SYNC_SLAVE => IS_SYNC_SLAVE) + port map ( + CLK_250_IN => clk_tx_full_i, -- in std_logic; + CLK_125_IN => rclk_125_i, -- in std_logic; + CLK_125_OUT => clk_tx_half_i, + + RESET_IN => tx_gear_reset_i, -- in std_logic; + ALLOW_RELOCK_IN => tx_gear_allow_relock_i, -- in std_logic + + TX_READY_OUT => tx_gear_ready_i, + + DATA_IN => tx_data_i, -- in std_logic_vector(17 downto 0) + DATA_OUT => tx_data_to_serdes_i -- out std_logic_vector(8 downto 0); + ); + tx_gear_reset_i <= not tx_rst_fsm_ready_i; + tx_gear_allow_relock_i <= '0'; + + + + tx_serdes_rst_i <= '0'; --no function + serdes_rst_qd_i <= '0'; --included in rst_qd_i + + ------------------------------------------------- + -- Reset FSM & Link states + ------------------------------------------------- + THE_RX_FSM : cbmnet_phy_ecp3_rx_reset_fsm + generic map ( + IS_SIMULATED => IS_SIMULATED + ) + port map( + RST_N => rst_n_i, + RX_REFCLK => clk_125_local, + 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_i, + RX_PCS_RST_CH_C => rx_pcs_rst_i, + STATE_OUT => rx_rst_fsm_state_i + ); + byte_alignment_to_fsm_i <= not (DETERMINISTIC_LATENCY_C and barrel_shifter_misaligned_i) or CTRL_OP(3); + word_alignment_to_fsm_i <= not (gear_to_fsm_rst_i or AND_ALL(rx_error_delay)) or CTRL_OP(5); + + +-- -- decode error +-- rx_dec_error_delayed_i <= rx_dec_error_delayed_i when rising_edge(rclk_250_i); +-- rx_dec_error_250_i <= rx_dec_error_i & rx_dec_error_delayed_i when rising_edge(rclk_250_i); +-- +-- rx_dec_error_125_i <= rx_dec_error_125_i(0) & rx_dec_error_i when rising_edge(clk_125_local); +-- rx_dec_error_125_buf_i <= rx_dec_error_125_i when rising_edge(clk_125_local); +-- +-- rx_error_delay <= rx_error_delay(rx_error_delay'high - 2 downto 0) & rx_dec_error_125_buf_i when rising_edge(clk_125_local); +-- process is +-- begin +-- wait until rising_edge(rclk_125_i); +-- if RESET='1' then +-- stat_decode_error_counter_i <= (others => '0'); +-- elsif rx_dec_error_125_buf_i = "11" then +-- stat_decode_error_counter_i <= stat_decode_error_counter_i + 2; +-- elsif rx_dec_error_125_buf_i = "10" or rx_dec_error_125_buf_i = "01" then +-- stat_decode_error_counter_i <= stat_decode_error_counter_i + 1; +-- end if; +-- end process; + + + THE_TX_FSM : cbmnet_phy_ecp3_tx_reset_fsm + generic map ( + IS_SIMULATED => IS_SIMULATED + ) + port map( + RST_N => rst_n_i, + TX_REFCLK => clk_125_local, + 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 + ); + + proc_rst_fsms_ready: process is begin + wait until rising_edge(clk_125_local); + rx_rst_fsm_ready_i <= '0'; + 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_rst_fsm_state_i = x"5" then + tx_rst_fsm_ready_i <= '1'; + end if; + end process; + + ------------------------------------------------- + -- CBMNet Ready Modules + ------------------------------------------------- + THE_RX_READY: cn_rx_pcs_wrapper + generic map ( + SIMULATION => 0, + USE_BS => 0, + SYNC_SIGNALS => 1, + INCL_8B10B_DEC => 0 + ) + port map ( + rx_clk => rclk_125_i, -- in std_logic; + res_n_rx => gear_to_rm_n_rst_i, -- in std_logic; + rxpcs_reinit => rm_tx_to_rx_reinit_i, -- in std_logic; -- Reinit RXPCS + rxdata_in(17 downto 0) => rx_data_i, + rxdata_in(19 downto 18) => "00", + reset_rx_cdr => rm_rx_to_gear_reset_i, -- out std_logic; -- Reset RX CDR to align + rxpcs_almost_ready => rm_rx_almost_ready_i, -- out std_logic; -- Ready1 detected, only waiting for break + rxpcs_ready => rm_rx_rxpcs_ready_i, -- out std_logic; -- RXPCS initialization done + see_reinit => rm_rx_see_reinit, -- out std_logic; -- Initialization pattern detected although ready + bs_position => open, -- out std_logic_vector(4 downto 0); -- Number of bit-shifts necessary for word-alignment + rxdata_out => rm_rx_data_buf_i, -- out std_logic_vector(17 downto 0); + ebtb_detect => rm_rx_ebtb_detect_i, -- out std_logic; -- Depends on the FSM state, alignment done + + --diagnostics + ebtb_code_err_cntr_clr => '0', -- in std_logic; + ebtb_disp_err_cntr_clr => '0', -- in std_logic; + ebtb_code_err_cntr => open, -- out std_logic_vector(15 downto 0); -- Counts for code errors if ebtb_detect is true + ebtb_disp_err_cntr => open, -- out std_logic_vector(15 downto 0); -- Counts for disparity errors if ebtb_detect is true + ebtb_code_err_cntr_flag => open,-- out std_logic; + ebtb_disp_err_cntr_flag => open -- out std_logic + ); + + PHY_RXDATA_OUT <= rx_data_i(15 downto 0); + PHY_RXDATA_K_OUT <= rx_data_i(17 downto 16); + gear_to_rm_n_rst_i <= not gear_to_rm_rst_i when rising_edge(rclk_125_i); + + + THE_TX_READY: cn_tx_pcs_wrapper + generic map ( + REVERSE_OUTPUT => 0, --integer range 0 to 1 := 1; + LINK_MASTER => 0, --integer range 0 to 1 := 1; + SYNC_SIGNALS => 1, --integer range 0 to 1 := 1; + + INCL_8B10B_ENC => 0 --integer range 0 to 1 := 1 + ) port map ( + tx_clk => rclk_125_i, --in std_logic; + res_n_tx => tx_rst_fsm_ready_buf_i, --in std_logic; + pcs_restart => CTRL_OP(14), --in std_logic; -- restart pcs layer + pma_ready => tx_gear_ready_i, --in std_logic; + ebtb_detect => rm_rx_ebtb_detect_i, --in std_logic; -- alignment done and valid 8b10b stream detected + see_reinit => rm_rx_see_reinit, --in std_logic; + rxpcs_almost_ready => rm_rx_almost_ready_i, --in std_logic; + txdata_in(15 downto 0) => PHY_TXDATA_IN, --in std_logic_vector(17 downto 0); + txdata_in(17 downto 16)=> PHY_TXDATA_K_IN, + + txpcs_ready => rm_tx_ready_i, --out std_logic; + link_lost => rm_tx_link_lost_i, --out std_logic; + reset_out => open, --out std_logic; + rxpcs_reinit => rm_tx_to_rx_reinit_i, --out std_logic; -- Reinit the RXPCS FSM + txdata_out => tx_data_i, --out std_logic_vector(17 downto 0); -- tx data to transceiver + txdata_out_coded => open, --out std_logic_vector(19 downto 0); -- tx data to transceiver already 8b10b coded + + --diagnostics + pcs_startup_cntr_clr => rm_tx_pcs_startup_cntr_clr, --in std_logic; + pcs_startup_cntr => rm_tx_pcs_startup_cntr, --out std_logic_vector(15 downto 0); -- Counts for link startups + pcs_startup_cntr_flag => rm_tx_pcs_startup_cntr_flag --out std_logic; + ); + + + rm_rx_status_for_tx_i <= rm_rx_almost_ready_i or rm_rx_ready_i; + + -- clock domain crossing from clk_125_local to rclk_125_i + PROC_SYNC_FSM_READY: process is begin + wait until rising_edge(rclk_125_i); + + if IS_SYNC_SLAVE = c_YES then + tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i and not gear_to_rm_rst_i; + + else + tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i; + + end if; + end process; + + serdes_ready_i <= rm_tx_ready_i and rm_rx_rxpcs_ready_i when rising_edge(rclk_125_i); + led_ok_i <= serdes_ready_i; + SERDES_ready <= serdes_ready_i; + + ------------------------------------------------- + -- SCI + ------------------------------------------------- + -- 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; + begin + wait until rising_edge(clk_125_local); + + case sci_state is + when IDLE => + sci_ch_i <= x"0"; + sci_qd_i <= '0'; + sci_reg_i <= '0'; + sci_read_i <= '0'; + sci_write_i <= '0'; + sci_timer <= sci_timer + 1; + if sci_timer(sci_timer'left) = '1' then + sci_timer <= (others => '0'); + sci_state <= GET_WA; + end if; + + when GET_WA => + if cnt = 4 then + cnt := 0; + sci_state <= IDLE; + + else + sci_state <= GET_WA_WAIT; + sci_addr_i <= '0' & x"22"; + sci_ch_i <= x"0"; + sci_ch_i(cnt) <= '1'; + sci_read_i <= '1'; + end if; + + when GET_WA_WAIT => + sci_state <= GET_WA_WAIT2; + + when GET_WA_WAIT2 => + sci_state <= GET_WA_FINISH; + + when GET_WA_FINISH => + 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; + end process; + + process is begin + wait until rising_edge(clk_125_local); + barrel_shifter_misaligned_i <= '0'; + if lsm_status_i = '1' and wa_position_i(3 downto 0) /= x"0" then + barrel_shifter_misaligned_i <= '1'; + end if; + end process; + + -- 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(rclk_125_i); + CLK_RX_RESET_OUT <= '1'; + + if serdes_ready_i = '0' then + counter := (others => '0'); + + elsif counter(counter'high) = '0' then + counter := counter + 1; + + else + CLK_RX_RESET_OUT <= '0'; + + end if; + end process; + + + 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'); + stat_last_reconnect_duration_i <= (others => '0'); + stat_wa_int_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; + + if serdes_ready_i = '0' then + stat_last_reconnect_duration_i <= stat_last_reconnect_duration_i + TO_UNSIGNED(1,1); + end if; + + stat_wa_int_i <= stat_wa_int_i or wa_position_i; + end if; + + last_rx_serdes_rst_i := rx_serdes_rst_i; + end process; + + PROC_SENSE_TX_DLM125: process is + begin + wait until rising_edge(rclk_125_i); + + low_level_tx_see_dlm0_125 <= '0'; + if tx_data_i = "10" & x"fb6a" then + low_level_tx_see_dlm0_125 <= '1'; + end if; + end process; + + process is + variable rx_v, tx_v : std_logic_vector(17 downto 0); + begin + wait until rising_edge(rclk_125_i); + + if reset = '1' or rx_v /= rx_data_i then rx_stab_i <= (others => '0'); + else rx_stab_i <= rx_stab_i + 1; end if; + + if reset = '1' or tx_v /= tx_data_i then tx_stab_i <= (others => '0'); + else tx_stab_i <= tx_stab_i + 1; end if; + + rx_v := rx_data_i; + tx_v := tx_data_i; + end process; + + + PROC_SENSE_DLMS: process begin + wait until rising_edge(rclk_125_i); + + if serdes_ready_i = '0' then + stat_dlm_counter_i <= (others => '0'); + elsif rx_data_i(17) = '1' and rx_data_i(15 downto 8) = K277 then + stat_dlm_counter_i <= stat_dlm_counter_i + TO_UNSIGNED(1,1); + end if; + end process; + +-- DEBUG_OUT_BEGIN + DEBUG_OUT(19 downto 0) <= "00" & tx_data_i(17 downto 0); + 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_i(17 downto 0); + DEBUG_OUT( 59 downto 52) <= rx_rst_fsm_state_i(3 downto 0) & tx_rst_fsm_state_i(3 downto 0); + + DEBUG_OUT( 63 downto 60) <= serdes_ready_i & rm_rx_ready_i & rm_tx_ready_i & rm_tx_almost_ready_i; + + DEBUG_OUT( 79 downto 64) <= rx_gear_debug_i(15 downto 0); + DEBUG_OUT( 95 downto 80) <= tx_gear_debug_i(15 downto 0); + + DEBUG_OUT( 99 downto 96) <= rm_rx_almost_ready_i & rm_rx_rxpcs_ready_i & rm_rx_see_reinit & rm_rx_ebtb_detect_i; + DEBUG_OUT(103 downto 100) <= wa_position_i(3 downto 0); + DEBUG_OUT(107 downto 104) <= word_alignment_to_fsm_i & byte_alignment_to_fsm_i & rm_rx_to_gear_reset_i & gear_to_rm_rst_i; + + DEBUG_OUT(123 downto 108) <= tx_stab_i(15 downto 0); + + DEBUG_OUT(139 downto 124) <= rx_stab_i(15 downto 0); + DEBUG_OUT(147 downto 140) <= stat_init_ack_counter_i(7 downto 0); + DEBUG_OUT(179 downto 148) <= stat_last_reconnect_duration_i(31 downto 0); + + DEBUG_OUT(195 downto 180) <= stat_reconnect_counter_i(15 downto 0); + DEBUG_OUT(211 downto 196) <= stat_dlm_counter_i(15 downto 0); + DEBUG_OUT(243 downto 212) <= rm_rx_ebtb_code_err_cntr_i(15 downto 0) & rm_rx_ebtb_disp_err_cntr_i(15 downto 0); + + DEBUG_OUT(315 downto 244) <= rx_data_sp_i3(17 downto 0) & rx_data_sp_i2(17 downto 0) & rx_data_sp_i1(17 downto 0) & rx_data_sp_i0(17 downto 0); + + DEBUG_OUT(333 downto 316) <= PHY_TXDATA_K_IN(1 downto 0) & PHY_TXDATA_IN(15 downto 0); + --DEBUG_OUT(341 downto 334) <= stat_sync_dlm_inv_counter_i(7 downto 0) when rising_edge(rclk_125_i); + --DEBUG_OUT(349 downto 342) <= stat_sync_dlm_counter_i(7 downto 0) when rising_edge(rclk_125_i); + + + + --DEBUG_OUT(255 downto 170) <= (others => '0'); + +-- DEBUG_OUT_END + + process is + begin + wait until rising_edge(rclk_125_i); + if rx_data_i /= "10" & x"fcc3" then + rx_data_sp_i0 <= rx_data_i; + rx_data_sp_i1 <= rx_data_sp_i0; + rx_data_sp_i2 <= rx_data_sp_i1; + rx_data_sp_i3 <= rx_data_sp_i2; + end if; + end process; + + --PROC_SEE_FAST_DLM: process is + --variable saw_lb_v, saw_hb_v : std_logic; + --begin + --wait until rising_edge(rclk_250_i); + + --see_dlm_hb_i <= '0' ; + --if rx_data_from_serdes_i = '1' & K277 then + --see_dlm_hb_i <= '1'; + --end if; + --see_dlm_hb_buf_i <= see_dlm_hb_i; + + --see_dlm_lb_aggr_i <= '0'; + --if rx_data_from_serdes_i = '1' & K277 then + --see_dlm_lb_aggr_i <= OR_ALL(see_dlm_lb_buf_i); + --end if; + + + + --if rst_i = '1' then + --stat_sync_dlm_counter_i <= (others => '0'); + --stat_sync_dlm_inv_counter_i <= (others => '0'); + --saw_lb_v := '0'; + --saw_hb_v := '0'; + + --else + --if see_dlm_hb_buf_i = '1' and saw_lb_v = '1' then + --stat_sync_dlm_counter_i <= stat_sync_dlm_counter_i + 1; + --end if; + + --if see_dlm_lb_aggr_i = '1' and saw_hb_v = '1' then + --stat_sync_dlm_inv_counter_i <= stat_sync_dlm_inv_counter_i + 1; + --end if; + + --saw_lb_v := see_dlm_lb_aggr_i; + --saw_hb_v := see_dlm_hb_buf_i; + --end if; + --end process; + + --see_dlm_lb_i(0) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(10, 3) else '0'; + --see_dlm_lb_i(1) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(14, 1) else '0'; + --see_dlm_lb_i(2) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(20, 1) else '0'; + --see_dlm_lb_i(3) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(20, 6) else '0'; + + --see_dlm_lb_i(4) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(22, 3) else '0'; + --see_dlm_lb_i(5) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(28, 2) else '0'; + --see_dlm_lb_i(6) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(28, 5) else '0'; + --see_dlm_lb_i(7) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(06, 2) else '0'; + + --see_dlm_lb_i(8) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(14, 6) else '0'; + --see_dlm_lb_i(9) <= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 3, 1) else '0'; + --see_dlm_lb_i(10)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(11, 2) else '0'; + --see_dlm_lb_i(11)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(17, 2) else '0'; + + --see_dlm_lb_i(12)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(25, 3) else '0'; + --see_dlm_lb_i(13)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE(17, 5) else '0'; + --see_dlm_lb_i(14)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 3, 6) else '0'; + --see_dlm_lb_i(15)<= '1' when rx_data_from_serdes_i = '0' & EBTB_D_ENCODE( 5, 3) else '0'; + + --see_dlm_lb_buf_i <= see_dlm_lb_i when rising_edge(rclk_250_i); + + + end generate; end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_rx_gear.vhd b/cbmnet/code/cbmnet_phy_rx_gear.vhd index 4e67460..f7b132e 100644 --- a/cbmnet/code/cbmnet_phy_rx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_rx_gear.vhd @@ -1,198 +1,200 @@ -LIBRARY IEEE; - USE IEEE.std_logic_1164.ALL; - USE IEEE.numeric_std.all; - -library work; - use work.trb_net_std.all; --- use work.trb_net_components.all; --- use work.med_sync_define.all; - use work.cbmnet_interface_pkg.all; - use work.cbmnet_phy_pkg.all; - -entity CBMNET_PHY_RX_GEAR is - generic( - IS_SYNC_SLAVE : integer := c_NO --select slave mode - ); - port ( - -- SERDES PORT - CLK_250_IN : in std_logic; - PCS_READY_IN: in std_logic; - SERDES_RESET_OUT : out std_logic; - DATA_IN : in std_logic_vector( 8 downto 0); - - -- RM PORT - RM_RESET_IN : in std_logic; - CLK_125_OUT : out std_logic; - RESET_OUT : out std_logic; - DATA_OUT : out std_logic_vector(17 downto 0); - - -- DEBUG - DEBUG_OUT : out std_logic_vector(31 downto 0) := (others => '0') - ); -end entity; - -architecture CBMNET_PHY_RX_GEAR_ARCH of CBMNET_PHY_RX_GEAR is - attribute HGROUP : string; - attribute HGROUP of CBMNET_PHY_RX_GEAR_ARCH : architecture is "cbmnet_phy_rx_gear"; - - - type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_RESET, FSM_LOCKED); - signal fsm_i : FSM_STATES_T; - signal fsm_state_i : std_logic_vector(3 downto 0); - - signal delay_clock_i : std_logic; - - signal indi_alignment_i : std_logic; - signal indi_misalignment_i : std_logic; - - signal data_delay_i : std_logic_vector(8 downto 0); - signal data_out_buf_i : std_logic_vector(17 downto 0); - signal clk_125_i : std_logic; - - signal reset_timer_i : std_logic; - signal timeout_i : std_logic; - - signal data_in_buf_i : std_logic_vector( 8 downto 0); - - - signal delay_clock_buf_i : std_logic; - signal delay_clock_buf1_i : std_logic; - signal last_delay_clock_i : std_logic := '0'; - signal word_idx_i : std_logic := '0'; -begin - data_in_buf_i <= DATA_IN when rising_edge(CLK_250_IN); - --- FSM sync part - process is begin - wait until rising_edge(clk_125_i); - - if PCS_READY_IN = '0' then - fsm_i <= FSM_START; - - RESET_OUT <= '1'; - delay_clock_i <= '0'; - fsm_state_i <= x"0"; - - elsif rising_edge(clk_125_i) then - SERDES_RESET_OUT <= '0'; - RESET_OUT <= '1'; - reset_timer_i <= '0'; - delay_clock_i <= '0'; - - case (fsm_i) is - when FSM_START => - fsm_state_i <= x"0"; - reset_timer_i <= '1'; - fsm_i <= FSM_WAIT_FOR_LOCK; - - when FSM_WAIT_FOR_LOCK => - fsm_state_i <= x"1"; - if indi_alignment_i = '1' then - -- already correctly aligned, so just fix current state - fsm_i <= FSM_LOCKED; - - elsif indi_misalignment_i = '1' then - -- we're off by one word. just wait a single frame - delay_clock_i <= '1'; - -- fsm_i <= FSM_LOCKED; - - elsif timeout_i = '1' then - fsm_i <= FSM_RESET; - - end if; - - when FSM_LOCKED => - fsm_state_i <= x"2"; - RESET_OUT <= '0'; - - if RM_RESET_IN = '1' then - fsm_i <= FSM_RESET; - - elsif indi_misalignment_i = '1' then - -- in this state we should already have a stable and correct lock. - -- if we, however, detect a missalignment, something is terribly wrong. - -- in this case, will perform a resychronisation - - fsm_i <= FSM_RESET; - end if; - - - when FSM_RESET => - fsm_state_i <= x"3"; - SERDES_RESET_OUT <= '1'; - - end case; - end if; - end process; - --- Timeout (approx. 2ms) - proc_timeout: process is - variable timer_v : unsigned(19 downto 0) := (others => '0'); - variable idx : integer := 18; - begin - wait until rising_edge(clk_125_i); - - if IS_SYNC_SLAVE = 0 then - idx := timer_v'high; - end if; - - if reset_timer_i = '1' then - timer_v := TO_UNSIGNED(0, timer_v'length); - - elsif timer_v(idx) = '0' then - timer_v := timer_v + TO_UNSIGNED(1,1); - - end if; - - timeout_i <= timer_v(idx); - end process; - --- Implement the 2:1 gearing and clock down-sampling - delay_clock_buf1_i <= delay_clock_i when rising_edge(CLK_250_IN); - delay_clock_buf_i <= delay_clock_buf1_i when rising_edge(CLK_250_IN); - - - proc_ctrl_gear: process - begin - wait until rising_edge(CLK_250_IN); - - if not (delay_clock_buf_i = '1' and last_delay_clock_i = '0') then - word_idx_i <= not word_idx_i; - end if; - - last_delay_clock_i <= delay_clock_buf_i; - end process; - - proc_gear: process - begin - wait until rising_edge(CLK_250_IN); - - if word_idx_i = '0' then - data_delay_i <= data_in_buf_i; - clk_125_i <= '1'; - else --- data_out_buf_i <= data_delay_i(8) & data_in_buf_i(8) & data_delay_i(7 downto 0) & data_in_buf_i(7 downto 0); - data_out_buf_i <= data_in_buf_i(8) & data_delay_i(8) & data_in_buf_i(7 downto 0) & data_delay_i(7 downto 0); - clk_125_i <= '0'; - end if; - - end process; - - - - DATA_OUT <= data_out_buf_i when rising_edge(clk_125_i); - CLK_125_OUT <= clk_125_i; - - DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i); - DEBUG_OUT(4) <= delay_clock_i; - DEBUG_OUT(5) <= indi_alignment_i; - DEBUG_OUT(6) <= indi_misalignment_i; - --- Detect Indications for correct or wrong alignment - indi_alignment_i <= '1' when data_out_buf_i(17 downto 16) = "01" and data_out_buf_i(15 downto 8) = x"00" and - (data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR0 or data_out_buf_i(7 downto 0) = CBMNET_READY_CHAR1 or data_out_buf_i(7 downto 0) = CBMNET_ALIGN_CHAR) else '0'; - - 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'; - +LIBRARY IEEE; + USE IEEE.std_logic_1164.ALL; + USE IEEE.numeric_std.all; + +library work; + use work.trb_net_std.all; +-- use work.trb_net_components.all; +-- use work.med_sync_define.all; + use work.cbmnet_interface_pkg.all; + use work.cbmnet_phy_pkg.all; + +entity CBMNET_PHY_RX_GEAR is + generic( + IS_SYNC_SLAVE : integer := c_NO --select slave mode + ); + port ( + -- SERDES PORT + CLK_250_IN : in std_logic; + PCS_READY_IN: in std_logic; + SERDES_RESET_OUT : out std_logic; + DATA_IN : in std_logic_vector( 8 downto 0); + + -- RM PORT + RM_RESET_IN : in std_logic; + CLK_125_OUT : out std_logic; + RESET_OUT : out std_logic; + DATA_OUT : out std_logic_vector(17 downto 0); + + -- DEBUG + DEBUG_OUT : out std_logic_vector(31 downto 0) := (others => '0') + ); +end entity; + +architecture CBMNET_PHY_RX_GEAR_ARCH of CBMNET_PHY_RX_GEAR is + attribute HGROUP : string; + attribute HGROUP of CBMNET_PHY_RX_GEAR_ARCH : architecture is "cbmnet_phy_rx_gear"; + + + type FSM_STATES_T is (FSM_START, FSM_WAIT_FOR_LOCK, FSM_RESET, FSM_LOCKED); + signal fsm_i : FSM_STATES_T; + signal fsm_state_i : std_logic_vector(3 downto 0); + + signal delay_clock_i : std_logic; + + signal indi_alignment_i : std_logic; + signal indi_misalignment_i : std_logic; + + signal data_delay_i : std_logic_vector(8 downto 0); + signal data_out_buf250_i : std_logic_vector(17 downto 0); + signal data_out_buf125_i : std_logic_vector(17 downto 0); + signal clk_125_i : std_logic; + + signal reset_timer_i : std_logic; + signal timeout_i : std_logic; + + signal data_in_buf_i : std_logic_vector( 8 downto 0); + + + signal delay_clock_buf_i : std_logic; + signal delay_clock_buf1_i : std_logic; + signal last_delay_clock_i : std_logic := '0'; + signal word_idx_i : std_logic := '0'; +begin + +-- FSM sync part + process is begin + wait until rising_edge(clk_125_i); + + if PCS_READY_IN = '0' then + fsm_i <= FSM_START; + + RESET_OUT <= '1'; + delay_clock_i <= '0'; + fsm_state_i <= x"0"; + + elsif rising_edge(clk_125_i) then + SERDES_RESET_OUT <= '0'; + RESET_OUT <= '1'; + reset_timer_i <= '0'; + delay_clock_i <= '0'; + + case (fsm_i) is + when FSM_START => + fsm_state_i <= x"0"; + reset_timer_i <= '1'; + fsm_i <= FSM_WAIT_FOR_LOCK; + + when FSM_WAIT_FOR_LOCK => + fsm_state_i <= x"1"; + if indi_alignment_i = '1' then + -- already correctly aligned, so just fix current state + fsm_i <= FSM_LOCKED; + + elsif indi_misalignment_i = '1' then + -- we're off by one word. just wait a single frame + delay_clock_i <= '1'; + -- fsm_i <= FSM_LOCKED; + + elsif timeout_i = '1' then + fsm_i <= FSM_RESET; + + end if; + + when FSM_LOCKED => + fsm_state_i <= x"2"; + RESET_OUT <= '0'; + + if RM_RESET_IN = '1' then + fsm_i <= FSM_RESET; + + elsif indi_misalignment_i = '1' then + -- in this state we should already have a stable and correct lock. + -- if we, however, detect a missalignment, something is terribly wrong. + -- in this case, will perform a resychronisation + + fsm_i <= FSM_RESET; + end if; + + + when FSM_RESET => + fsm_state_i <= x"3"; + SERDES_RESET_OUT <= '1'; + + end case; + end if; + end process; + +-- Timeout (approx. 2ms) + proc_timeout: process is + variable timer_v : unsigned(19 downto 0) := (others => '0'); + variable idx : integer := 18; + begin + wait until rising_edge(clk_125_i); + + if IS_SYNC_SLAVE = 0 then + idx := timer_v'high; + end if; + + if reset_timer_i = '1' then + timer_v := TO_UNSIGNED(0, timer_v'length); + + elsif timer_v(idx) = '0' then + timer_v := timer_v + TO_UNSIGNED(1,1); + + end if; + + timeout_i <= timer_v(idx); + end process; + +-- Implement the 2:1 gearing and clock down-sampling + delay_clock_buf1_i <= delay_clock_i when rising_edge(CLK_250_IN); + delay_clock_buf_i <= delay_clock_buf1_i when rising_edge(CLK_250_IN); + + + proc_ctrl_gear: process + begin + wait until rising_edge(CLK_250_IN); + + if not (delay_clock_buf_i = '1' and last_delay_clock_i = '0') then + word_idx_i <= not word_idx_i; + end if; + + last_delay_clock_i <= delay_clock_buf_i; + end process; + + data_in_buf_i <= DATA_IN when rising_edge(CLK_250_IN); + + proc_gear: process + begin + wait until rising_edge(CLK_250_IN); + + if word_idx_i = '0' then + data_delay_i <= data_in_buf_i; + clk_125_i <= '1'; + else +-- data_out_buf_i <= data_delay_i(8) & data_in_buf_i(8) & data_delay_i(7 downto 0) & data_in_buf_i(7 downto 0); + data_out_buf250_i <= data_in_buf_i(8) & data_delay_i(8) & data_in_buf_i(7 downto 0) & data_delay_i(7 downto 0); + clk_125_i <= '0'; + end if; + + end process; + + + data_out_buf125_i <= data_out_buf250_i when rising_edge(clk_125_i); + DATA_OUT <= data_out_buf125_i; + CLK_125_OUT <= clk_125_i; -- when rising_edge(CLK_250_IN); + + DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i); + DEBUG_OUT(4) <= delay_clock_i; + DEBUG_OUT(5) <= indi_alignment_i; + DEBUG_OUT(6) <= indi_misalignment_i; + +-- Detect Indications for correct or wrong alignment + indi_alignment_i <= '1' when data_out_buf125_i(17 downto 16) = "01" and data_out_buf125_i(15 downto 8) = x"00" and + (data_out_buf125_i(7 downto 0) = CBMNET_READY_CHAR0 or data_out_buf125_i(7 downto 0) = CBMNET_READY_CHAR1 or data_out_buf125_i(7 downto 0) = CBMNET_ALIGN_CHAR) else '0'; + + indi_misalignment_i <= '1' when data_out_buf125_i(17 downto 16) = "10" and data_out_buf125_i(7 downto 0) = x"00" and + (data_out_buf125_i(15 downto 8) = CBMNET_READY_CHAR0 or data_out_buf125_i(15 downto 8) = CBMNET_READY_CHAR1 or data_out_buf125_i(15 downto 8) = CBMNET_ALIGN_CHAR) else '0'; + end architecture CBMNET_PHY_RX_GEAR_ARCH; \ No newline at end of file diff --git a/cbmnet/compile_periph_frankfurt.pl b/cbmnet/compile_periph_frankfurt.pl index f311bcc..831d428 100755 --- a/cbmnet/compile_periph_frankfurt.pl +++ b/cbmnet/compile_periph_frankfurt.pl @@ -140,17 +140,17 @@ execute($c); #$c=qq|mpartrce -p "../$TOPNAME.p2t" -log "$TOPNAME.log" -o "$TOPNAME.rpt" -pr "$TOPNAME.prf" -tf "$TOPNAME.pt" "|.$TOPNAME.qq|_map.ncd" "$TOPNAME.ncd"|; # $c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; -$c=qq|$lattice_path/ispfpga/bin/lin/par -w -l 5 -i 6 -t 4 -c 0 -e 0 -exp parUseNBR=1:parCDP=0:parCDR=0:parPathBased=OFF $tpmap.ncd $TOPNAME.ncd $TOPNAME.prf|; +$c=qq|$lattice_path/ispfpga/bin/lin/par -w -l 5 -i 6 -t 2 -e 0 -exp parCDP=1:parCDR=1:parPlcInLimit=0:parPlcInNeighborSize=1:parPathBased=ON:parHold=ON:parHoldLimit=10000:paruseNBR=1: $tpmap.ncd $TOPNAME.ncd $TOPNAME.prf|; execute($c); # IOR IO Timing Report # $c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|; # execute($c); # TWR Timing Report -$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 15 -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; +$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 50 -html -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; execute($c); -$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 5 -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; +$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 50 -html -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; execute($c); $c=qq|$lattice_path/ispfpga/bin/lin/ltxt2ptxt $TOPNAME.ncd|; diff --git a/cbmnet/trb3_periph_cbmnet.p2t b/cbmnet/trb3_periph_cbmnet.p2t index b7ad87c..3323545 100755 --- a/cbmnet/trb3_periph_cbmnet.p2t +++ b/cbmnet/trb3_periph_cbmnet.p2t @@ -2,13 +2,13 @@ -w #-i 1 #-l 5 -#-n 1 +-n 1 -y #-s 12 -t 3 -c 1 #-e 2 --m nodelist.txt +#-m nodelist.txt # -w # -i 6 # -l 5 diff --git a/cbmnet/trb3_periph_cbmnet.prj b/cbmnet/trb3_periph_cbmnet.prj old mode 100644 new mode 100755 index 99c84ce..2764571 --- a/cbmnet/trb3_periph_cbmnet.prj +++ b/cbmnet/trb3_periph_cbmnet.prj @@ -160,6 +160,7 @@ add_file -vhdl -lib work "../../trbnet/media_interfaces/trb_net16_med_ecp3_sfp_4 add_file -vhdl -lib work "./code/cbmnet_interface_pkg.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_pkg.vhd" add_file -vhdl -lib work "./cores/cbmnet_sfp1.vhd" +add_file -vhdl -lib work "./cores/cbmnet_sfp1_slow.vhd" add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/med_sync_define.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_ecp3_rx_reset_fsm.vhd" add_file -vhdl -lib work "./code/cbmnet_phy_ecp3_tx_reset_fsm.vhd" diff --git a/cbmnet/trb3_periph_cbmnet.vhd b/cbmnet/trb3_periph_cbmnet.vhd index 0d44a12..ce4cc72 100755 --- a/cbmnet/trb3_periph_cbmnet.vhd +++ b/cbmnet/trb3_periph_cbmnet.vhd @@ -1,1055 +1,1055 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library work; -use work.trb_net_std.all; -use work.trb_net_components.all; -use work.trb3_components.all; -use work.version.all; - -use work.cbmnet_interface_pkg.all; -use work.cbmnet_phy_pkg.all; - - -entity trb3_periph_cbmnet is - generic ( - CBM_FEE_MODE : integer := CBM_FEE_MODE_C; -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received - -- in Master mode, logic will run on internal clock and regularly send dlms - INCLUDE_TRBNET : integer := INCLUDE_TRBNET_C - ); - port( - --Clocks - CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz - CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA - CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! - CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! - - --Trigger - TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out - TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out - - --Serdes - CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible - CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems - SERDES_INT_TX : out std_logic_vector(3 downto 0); - SERDES_INT_RX : in std_logic_vector(3 downto 0); - SERDES_ADDON_TX : out std_logic_vector(11 downto 0); - SERDES_ADDON_RX : in std_logic_vector(11 downto 0); - - --Inter-FPGA Communication - FPGA5_COMM : inout std_logic_vector(11 downto 0); - --Bit 0/1 input, serial link RX active - --Bit 2/3 output, serial link TX active - --others yet undefined - --Connection to AddOn - LED_LINKOK : out std_logic_vector(6 downto 1); - LED_RX : out std_logic_vector(6 downto 1); - LED_TX : out std_logic_vector(6 downto 1); - - SFP_MOD0 : in std_logic_vector(6 downto 1); - SFP_TXDIS : out std_logic_vector(6 downto 1); - SFP_LOS : in std_logic_vector(6 downto 1); - SFP_MOD1 : out std_logic_vector(6 downto 1); - SFP_MOD2 : inout std_logic_vector(6 downto 1); - - SFP_RATESEL: out std_logic_vector(6 downto 1); - SFP_TXFAULT: in std_logic_vector(6 downto 1); - - --Flash ROM & Reboot - FLASH_CLK : out std_logic; - FLASH_CS : out std_logic; - FLASH_DIN : out std_logic; - FLASH_DOUT : in std_logic; - PROGRAMN : out std_logic; --reboot FPGA - - --Misc - TEMPSENS : inout std_logic; --Temperature Sensor - CODE_LINE : in std_logic_vector(1 downto 0); - LED_GREEN : out std_logic; - LED_ORANGE : out std_logic; - LED_RED : out std_logic; - LED_YELLOW : out std_logic; - SUPPL : in std_logic; --terminated diff pair, PCLK, Pads - - --Test Connectors - TEST_LINE : out std_logic_vector(15 downto 0); - --TEST_LVDS_LINE : out std_logic_vector(1 downto 0); - - -- PCS Core TODO: Suppose this is necessary only for simulation - SD_RXD_N_IN : in std_logic; - SD_RXD_P_IN : in std_logic; - SD_TXD_N_OUT : out std_logic; - SD_TXD_P_OUT : out std_logic - ); - - attribute syn_useioff : boolean; - --no IO-FF for LEDs relaxes timing constraints - attribute syn_useioff of LED_GREEN : signal is false; - attribute syn_useioff of LED_ORANGE : signal is false; - attribute syn_useioff of LED_RED : signal is false; - attribute syn_useioff of LED_YELLOW : signal is false; - attribute syn_useioff of TEMPSENS : signal is false; - attribute syn_useioff of PROGRAMN : signal is false; - attribute syn_useioff of CODE_LINE : signal is false; - attribute syn_useioff of TRIGGER_LEFT : signal is false; - attribute syn_useioff of TRIGGER_RIGHT : signal is false; - attribute syn_useioff of LED_LINKOK : signal is false; - attribute syn_useioff of LED_RX : signal is false; - attribute syn_useioff of LED_TX : signal is false; - - --important signals _with_ IO-FF - attribute syn_useioff of FLASH_CLK : signal is true; - attribute syn_useioff of FLASH_CS : signal is true; - attribute syn_useioff of FLASH_DIN : signal is true; - attribute syn_useioff of FLASH_DOUT : signal is true; - attribute syn_useioff of FPGA5_COMM : signal is true; - attribute syn_useioff of TEST_LINE : signal is true; - - attribute nopad : string; - attribute nopad of SD_RXD_N_IN, SD_RXD_P_IN, SD_TXD_N_OUT, SD_TXD_P_OUT : signal is "true"; - - attribute syn_keep : boolean; - attribute syn_keep of CLK_GPLL_LEFT, CLK_GPLL_RIGHT, CLK_PCLK_LEFT, CLK_PCLK_RIGHT, TRIGGER_LEFT, TRIGGER_RIGHT : signal is true; - attribute syn_preserve : boolean; - -end entity; - -architecture trb3_periph_arch of trb3_periph_cbmnet is ---Constants - constant REGIO_NUM_STAT_REGS : integer := 2; - constant REGIO_NUM_CTRL_REGS : integer := 2; - - - --Clock / Reset - signal clk_125_i : std_logic; -- clock reference for CBMNet serdes - signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL - signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL - signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic. - signal pll_lock1, pll_lock2 : std_logic; - signal clear_i : std_logic; - signal reset_i : std_logic; - signal GSR_N : std_logic; - - attribute syn_keep of GSR_N : signal is true; - attribute syn_preserve of GSR_N : signal is true; - - - signal rclk_125_i : std_logic; -- recovered clock - signal rreset_i : std_logic; -- reset for recovered clock ~ 1us after clock becomes stable - - - --Media Interface - signal med_stat_op : std_logic_vector (1*16-1 downto 0) := (others => '0'); - signal med_ctrl_op : std_logic_vector (1*16-1 downto 0); - signal med_stat_debug : std_logic_vector (1*64-1 downto 0); - signal med_ctrl_debug : std_logic_vector (1*64-1 downto 0); - signal med_data_out : std_logic_vector (1*16-1 downto 0); - signal med_packet_num_out : std_logic_vector (1*3-1 downto 0); - signal med_dataready_out : std_logic; - signal med_read_out : std_logic; - signal med_data_in : std_logic_vector (1*16-1 downto 0); - signal med_packet_num_in : std_logic_vector (1*3-1 downto 0); - signal med_dataready_in : std_logic; - signal med_read_in : std_logic; - - --LVL1 channel - signal timing_trg_received_i : std_logic; - signal trg_data_valid_i : std_logic; - signal trg_timing_valid_i : std_logic; - signal trg_notiming_valid_i : std_logic; - signal trg_invalid_i : std_logic; - signal trg_type_i : std_logic_vector(3 downto 0); - signal trg_number_i : std_logic_vector(15 downto 0); - signal trg_code_i : std_logic_vector(7 downto 0); - signal trg_information_i : std_logic_vector(23 downto 0); - signal trg_int_number_i : std_logic_vector(15 downto 0); - signal trg_multiple_trg_i : std_logic; - signal trg_timeout_detected_i: std_logic; - signal trg_spurious_trg_i : std_logic; - signal trg_missing_tmg_trg_i : std_logic; - signal trg_spike_detected_i : std_logic; - - --Data channel - signal fee_trg_release_i : std_logic; - signal fee_trg_statusbits_i : std_logic_vector(31 downto 0); - signal fee_data_i : std_logic_vector(31 downto 0); - signal fee_data_write_i : std_logic; - signal fee_data_finished_i : std_logic; - signal fee_almost_full_i : std_logic; - - --Slow Control channel - signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0); - signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0); - signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0); - signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0); - signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0); - signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0); - signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0); - signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0); - - --RegIO - signal my_address : std_logic_vector (15 downto 0); - signal regio_addr_out : std_logic_vector (15 downto 0); - signal regio_read_enable_out : std_logic; - signal regio_write_enable_out : std_logic; - signal regio_data_out : std_logic_vector (31 downto 0); - signal regio_data_in : std_logic_vector (31 downto 0); - signal regio_dataready_in : std_logic; - signal regio_no_more_data_in : std_logic; - signal regio_write_ack_in : std_logic; - signal regio_unknown_addr_in : std_logic; - signal regio_timeout_out : std_logic; - - --Timer - signal global_time : std_logic_vector(31 downto 0); - signal local_time : std_logic_vector(7 downto 0); - signal time_since_last_trg : std_logic_vector(31 downto 0); - signal timer_ticks : std_logic_vector(1 downto 0); - - --Flash - signal spictrl_read_en : std_logic; - signal spictrl_write_en : std_logic; - signal spictrl_data_in : std_logic_vector(31 downto 0); - signal spictrl_addr : std_logic; - signal spictrl_data_out : std_logic_vector(31 downto 0); - signal spictrl_ack : std_logic; - signal spictrl_busy : std_logic; - signal spimem_read_en : std_logic; - signal spimem_write_en : std_logic; - signal spimem_data_in : std_logic_vector(31 downto 0); - signal spimem_addr : std_logic_vector(5 downto 0); - signal spimem_data_out : std_logic_vector(31 downto 0); - signal spimem_ack : std_logic; - - signal debug_read_en : std_logic; - signal debug_write_en : std_logic; - signal debug_data_in : std_logic_vector(31 downto 0); - signal debug_addr : std_logic_vector(5 downto 0); - signal debug_data_out : std_logic_vector(31 downto 0); - signal debug_ack : std_logic; - - - signal spi_bram_addr : std_logic_vector(7 downto 0); - signal spi_bram_wr_d : std_logic_vector(7 downto 0); - signal spi_bram_rd_d : std_logic_vector(7 downto 0); - signal spi_bram_we : std_logic; - - --FPGA Test - signal time_counter : unsigned(31 downto 0); - - -- CBMNet signals - constant NUM_LANES : integer := 1; - signal cbm_res_n : std_logic; -- Active low reset; can be changed by define - signal cbm_link_active : std_logic; -- link is active and can send and receive data - - signal cbm_ctrl2send_stop : std_logic := '0'; -- send control interface - signal cbm_ctrl2send_start : std_logic := '0'; - signal cbm_ctrl2send_end : std_logic := '0'; - signal cbm_ctrl2send : std_logic_vector(15 downto 0) := (others => '0'); - - signal cbm_data2send_stop : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); -- send data interface - signal cbm_data2send_start : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); - signal cbm_data2send_end : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); - signal cbm_data2send : std_logic_vector((16*NUM_LANES)-1 downto 0) := (others => '0'); - - signal cbm_dlm2send_va : std_logic := '0'; -- send dlm interface - signal cbm_dlm2send : std_logic_vector(3 downto 0) := (others => '0'); - - signal cbm_dlm_rec_type : std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface - signal cbm_dlm_rec_va : std_logic := '0'; - - signal cbm_data_rec : std_logic_vector((16*NUM_LANES)-1 downto 0); -- receive data interface - signal cbm_data_rec_start : std_logic_vector(NUM_LANES-1 downto 0); - signal cbm_data_rec_end : std_logic_vector(NUM_LANES-1 downto 0); - signal cbm_data_rec_stop : std_logic_vector(NUM_LANES-1 downto 0) := (others =>'0'); - - signal cbm_ctrl_rec : std_logic_vector(15 downto 0); -- receive control interface - signal cbm_ctrl_rec_start : std_logic; - signal cbm_ctrl_rec_end : std_logic; - signal cbm_ctrl_rec_stop : std_logic; - - signal cbm_data_from_link : std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface from the PHY - signal cbm_data2link : std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface to the PHY - - signal cbm_link_activeovr : std_logic := '0'; -- Overrides; set 0 by default - signal cbm_link_readyovr : std_logic := '0'; - - signal cbm_SERDES_ready : std_logic; -- signalize when PHY ready - - signal phy_stat_op, phy_ctrl_op : std_logic_vector(15 downto 0) := (others => '0'); - signal phy_stat_debug, phy_ctrl_debug : std_logic_vector(63 downto 0) := (others => '0'); - - signal phy_debug_i : std_logic_vector (511 downto 0) := (others => '0'); - signal phy_debug_i_buf : std_logic_vector (511 downto 0); - - --- Link Tester - signal link_tester_ctrl_en :std_logic; - signal link_tester_dlm_en :std_logic; - signal link_tester_data_en :std_logic; - - signal link_tester_data_stop :std_logic; - signal link_tester_ctrl_stop :std_logic; - - signal link_tester_data_valid:std_logic; - signal link_tester_ctrl_valid:std_logic; - signal link_tester_dlm_valid :std_logic; - - - signal link_tester_ctrl : std_logic_vector(31 downto 0) := (others => '0'); - signal link_tester_stat : std_logic_vector(31 downto 0) := (others => '0'); - - signal dummy : std_logic; - - type SEND_FSM_T is (START, SEND_HEADER, SEND_PACK_NUM, SEND_LENGTH, SEND_DATA, SEND_FOOTER, AFTER_SEND_WAIT); - signal send_fsm_i : SEND_FSM_T; - signal send_length_i : unsigned(4 downto 0); - signal send_num_pack_counter_i : unsigned(15 downto 0); - signal send_enabled_i : std_logic := '0'; - - signal send_wait_counter_i : std_logic_vector(31 downto 0); - signal send_wait_threshold_i : std_logic_vector(31 downto 0); - - signal dlm_counter_i : unsigned(31 downto 0); - signal dlm_glob_counter_i : unsigned(31 downto 0); - - - -- diagnostics Lane0 - signal cbm_crc_error_cntr_flag_0 : std_logic; - signal cbm_retrans_cntr_flag_0 : std_logic; - signal cbm_retrans_error_cntr_flag_0 : std_logic; - signal cbm_crc_error_cntr_0 : std_logic_vector(15 downto 0); - signal cbm_retrans_cntr_0 : std_logic_vector(15 downto 0); - signal cbm_retrans_error_cntr_0 : std_logic_vector(15 downto 0); - signal cbm_crc_error_cntr_clr_0 : std_logic; - signal cbm_retrans_cntr_clr_0 : std_logic; - signal cbm_retrans_error_cntr_clr_0 : std_logic; - - -- diagnostics Lane1 - signal cbm_crc_error_cntr_flag_1 : std_logic; - signal cbm_retrans_cntr_flag_1 : std_logic; - signal cbm_retrans_error_cntr_flag_1 : std_logic; - signal cbm_crc_error_cntr_1 : std_logic_vector(15 downto 0); - signal cbm_retrans_cntr_1 : std_logic_vector(15 downto 0); - signal cbm_retrans_error_cntr_1 : std_logic_vector(15 downto 0); - signal cbm_crc_error_cntr_clr_1 : std_logic; - signal cbm_retrans_cntr_clr_1 : std_logic; - signal cbm_retrans_error_cntr_clr_1 : std_logic; - - -- diagnostics Lane2 - signal cbm_crc_error_cntr_flag_2 : std_logic; - signal cbm_retrans_cntr_flag_2 : std_logic; - signal cbm_retrans_error_cntr_flag_2 : std_logic; - signal cbm_crc_error_cntr_2 : std_logic_vector(15 downto 0); - signal cbm_retrans_cntr_2 : std_logic_vector(15 downto 0); - signal cbm_retrans_error_cntr_2 : std_logic_vector(15 downto 0); - signal cbm_crc_error_cntr_clr_2 : std_logic; - signal cbm_retrans_cntr_clr_2 : std_logic; - signal cbm_retrans_error_cntr_clr_2 : std_logic; - - -- diagnostics Lane3 - signal cbm_crc_error_cntr_flag_3 : std_logic; - signal cbm_retrans_cntr_flag_3 : std_logic; - signal cbm_retrans_error_cntr_flag_3 : std_logic; - signal cbm_crc_error_cntr_3 : std_logic_vector(15 downto 0); - signal cbm_retrans_cntr_3 : std_logic_vector(15 downto 0); - signal cbm_retrans_error_cntr_3 : std_logic_vector(15 downto 0); - signal cbm_crc_error_cntr_clr_3 : std_logic; - signal cbm_retrans_cntr_clr_3 : std_logic; - signal cbm_retrans_error_cntr_clr_3 : std_logic; - - signal cbm_debug_overrides_i : std_logic_vector(1 downto 0) := "00"; - -begin - clk_125_i <= CLK_GPLL_LEFT; - - assert(INCLUDE_TRBNET = c_YES); - ---------------------------------------------------------------------------- --- CBMNet and PHY ---------------------------------------------------------------------------- - THE_CBM_PHY: cbmnet_phy_ecp3 - generic map (IS_SYNC_SLAVE => CBM_FEE_MODE) - port map ( - CLK => clk_125_i, - RESET => reset_i, - CLEAR => '0', - - --Internal Connection TX - PHY_TXDATA_IN => cbm_data2link(15 downto 0), - PHY_TXDATA_K_IN => cbm_data2link(17 downto 16), - - --Internal Connection RX - PHY_RXDATA_OUT => cbm_data_from_link(15 downto 0), - PHY_RXDATA_K_OUT => cbm_data_from_link(17 downto 16), - - CLK_RX_HALF_OUT => rclk_125_i, - CLK_RX_FULL_OUT => open, - CLK_RX_RESET_OUT => rreset_i, - - LINK_ACTIVE_OUT => open, - SERDES_ready => cbm_SERDES_ready, - - --SFP Connection - SD_RXD_P_IN => SD_RXD_P_IN, - SD_RXD_N_IN => SD_RXD_N_IN, - SD_TXD_P_OUT => SD_TXD_P_OUT, - SD_TXD_N_OUT => SD_TXD_N_OUT, - - SD_PRSNT_N_IN => SFP_MOD0(1), - SD_LOS_IN => SFP_LOS(1), - SD_TXDIS_OUT => SFP_TXDIS(1), - - 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, - DEBUG_OUT => phy_debug_i - ); - - TEST_LINE <= phy_stat_op; - - SFP_RATESEL <= (others => '1'); - - --TEST_LINE(1 downto 0) <= cbm_dlm2send_va & cbm_dlm_rec_va; - --- process is --- variable counter_v : unsigned(20 downto 0); --- begin --- wait until rising_edge(rclk_125_i); --- counter_v := counter_v + to_unsigned(1,1); --- cbm_dlm2send_va <= '0'; --- if counter_v = 0 then --- cbm_dlm2send_va <= '1'; --- end if; --- end process; --- - --- cbm_data2link <= "00" & x"dead"; - THE_CBM_ENDPOINT: lp_top - generic map ( - NUM_LANES => 1, - TX_SLAVE => 1 - ) - port map ( - -- Clk & Reset - clk => rclk_125_i, - res_n => cbm_res_n, - - -- Phy - data_from_link => cbm_data_from_link, - data2link => cbm_data2link, - link_activeovr => cbm_debug_overrides_i(0), - link_readyovr => cbm_debug_overrides_i(1), - SERDES_ready => cbm_SERDES_ready, - - -- CBMNet Interface - link_active => cbm_link_active, - ctrl2send_stop => cbm_ctrl2send_stop, - ctrl2send_start => cbm_ctrl2send_start, - ctrl2send_end => cbm_ctrl2send_end, - ctrl2send => cbm_ctrl2send, - - data2send_stop => cbm_data2send_stop, - data2send_start => cbm_data2send_start, - data2send_end => cbm_data2send_end, - data2send => cbm_data2send, - - dlm2send_va => cbm_dlm2send_va, - dlm2send => cbm_dlm2send, - - dlm_rec_type => cbm_dlm_rec_type, - dlm_rec_va => cbm_dlm_rec_va, - - data_rec => cbm_data_rec, - data_rec_start => cbm_data_rec_start, - data_rec_end => cbm_data_rec_end, - data_rec_stop => cbm_data_rec_stop, - - ctrl_rec => cbm_ctrl_rec, - ctrl_rec_start => cbm_ctrl_rec_start, - ctrl_rec_end => cbm_ctrl_rec_end, - ctrl_rec_stop => cbm_ctrl_rec_stop, - - -- diagnostics Lane0 - crc_error_cntr_flag_0 => cbm_crc_error_cntr_flag_0, -- out std_logic; - retrans_cntr_flag_0 => cbm_retrans_cntr_flag_0, -- out std_logic; - retrans_error_cntr_flag_0 => cbm_retrans_error_cntr_flag_0, -- out std_logic; - crc_error_cntr_0 => cbm_crc_error_cntr_0, -- out std_logic_vector(15 downto 0); - retrans_cntr_0 => cbm_retrans_cntr_0, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_0 => cbm_retrans_error_cntr_0, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_0 => cbm_crc_error_cntr_clr_0, -- in std_logic; - retrans_cntr_clr_0 => cbm_retrans_cntr_clr_0, -- in std_logic; - retrans_error_cntr_clr_0 => cbm_retrans_error_cntr_clr_0, -- in std_logic; - - -- diagnostics Lane1 - crc_error_cntr_flag_1 => cbm_crc_error_cntr_flag_1, -- out std_logic; - retrans_cntr_flag_1 => cbm_retrans_cntr_flag_1, -- out std_logic; - retrans_error_cntr_flag_1 => cbm_retrans_error_cntr_flag_1, -- out std_logic; - crc_error_cntr_1 => cbm_crc_error_cntr_1, -- out std_logic_vector(15 downto 0); - retrans_cntr_1 => cbm_retrans_cntr_1, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_1 => cbm_retrans_error_cntr_1, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_1 => cbm_crc_error_cntr_clr_1, -- in std_logic; - retrans_cntr_clr_1 => cbm_retrans_cntr_clr_1, -- in std_logic; - retrans_error_cntr_clr_1 => cbm_retrans_error_cntr_clr_1, -- in std_logic; - - -- diagnostics Lane2 - crc_error_cntr_flag_2 => cbm_crc_error_cntr_flag_2, -- out std_logic; - retrans_cntr_flag_2 => cbm_retrans_cntr_flag_2, -- out std_logic; - retrans_error_cntr_flag_2 => cbm_retrans_error_cntr_flag_2, -- out std_logic; - crc_error_cntr_2 => cbm_crc_error_cntr_2, -- out std_logic_vector(15 downto 0); - retrans_cntr_2 => cbm_retrans_cntr_2, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_2 => cbm_retrans_error_cntr_2, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_2 => cbm_crc_error_cntr_clr_2, -- in std_logic; - retrans_cntr_clr_2 => cbm_retrans_cntr_clr_2, -- in std_logic; - retrans_error_cntr_clr_2 => cbm_retrans_error_cntr_clr_2, -- in std_logic; - - -- diagnostics Lane3 - crc_error_cntr_flag_3 => cbm_crc_error_cntr_flag_3, -- out std_logic; - retrans_cntr_flag_3 => cbm_retrans_cntr_flag_3, -- out std_logic; - retrans_error_cntr_flag_3 => cbm_retrans_error_cntr_flag_3, -- out std_logic; - crc_error_cntr_3 => cbm_crc_error_cntr_3, -- out std_logic_vector(15 downto 0); - retrans_cntr_3 => cbm_retrans_cntr_3, -- out std_logic_vector(15 downto 0); - retrans_error_cntr_3 => cbm_retrans_error_cntr_3, -- out std_logic_vector(15 downto 0); - crc_error_cntr_clr_3 => cbm_crc_error_cntr_clr_3, -- in std_logic; - retrans_cntr_clr_3 => cbm_retrans_cntr_clr_3, -- in std_logic; - retrans_error_cntr_clr_3 => cbm_retrans_error_cntr_clr_3 -- in std_logic - - - ); - cbm_res_n <= not rreset_i; - - cbm_crc_error_cntr_clr_0 <= reset_i; - cbm_retrans_cntr_clr_0 <= reset_i; - cbm_retrans_error_cntr_clr_0 <= reset_i; - cbm_crc_error_cntr_clr_1 <= reset_i; - cbm_retrans_cntr_clr_1 <= reset_i; - cbm_retrans_error_cntr_clr_1 <= reset_i; - cbm_crc_error_cntr_clr_2 <= reset_i; - cbm_retrans_cntr_clr_2 <= reset_i; - cbm_retrans_error_cntr_clr_2 <= reset_i; - cbm_crc_error_cntr_clr_3 <= reset_i; - cbm_retrans_cntr_clr_3 <= reset_i; - cbm_retrans_error_cntr_clr_3 <= reset_i; - - THE_DLM_REFLECT: dlm_reflect port map ( - clk => rclk_125_i, -- in std_logic; - res_n => cbm_res_n, -- in std_logic; - dlm_rec_in => cbm_dlm_rec_type, -- in std_logic_vector(3 downto 0); - dlm_rec_va_in => cbm_dlm_rec_va, -- in std_logic; - dlm_rec_out => open, -- out std_logic_vector(3 downto 0); - dlm_rec_va_out => open, -- out std_logic; - dlm2send_va => cbm_dlm2send_va, -- out std_logic; - dlm2send => cbm_dlm2send -- out std_logic_vector(3 downto 0) - ); - - - PROC_DATA_SEND: process begin - wait until rising_edge(rclk_125_i); - - cbm_data2send <= (others => '0'); - cbm_data2send_start <= "0"; - cbm_data2send_end <= "0"; - - if reset_i = '1' or send_enabled_i = '0' then - send_fsm_i <= START; - send_num_pack_counter_i <= (others => '0'); - - else - case(send_fsm_i) is - when START => - if cbm_link_active='1' and cbm_data2send_stop = "0" then - send_fsm_i <= SEND_HEADER; - send_num_pack_counter_i <= send_num_pack_counter_i + 1; - send_length_i <= "0" & send_num_pack_counter_i(3 downto 0); - end if; - - when SEND_HEADER => - cbm_data2send <= x"f123"; - cbm_data2send_start <= "1"; - send_fsm_i <= SEND_PACK_NUM; - - when SEND_PACK_NUM => - cbm_data2send <= send_num_pack_counter_i; - send_fsm_i <= SEND_LENGTH; - - when SEND_LENGTH => - cbm_data2send(send_length_i'range) <= send_length_i; - send_fsm_i <= SEND_DATA; - - when SEND_DATA => - send_length_i <= send_length_i - 1; - cbm_data2send(15 downto 8) <= "0" & std_logic_vector(send_length_i(2 downto 0)) & std_logic_vector(send_length_i(3 downto 0)); - cbm_data2send(send_length_i'high + 0 downto 0) <= send_length_i; - - if send_length_i = TO_UNSIGNED(1, send_length_i'length) then - send_fsm_i <= SEND_FOOTER; - end if; - - when SEND_FOOTER => - cbm_data2send <= x"f321"; - cbm_data2send_end <= "1"; - - send_wait_counter_i <= (others => '0'); - send_fsm_i <= AFTER_SEND_WAIT; - - when AFTER_SEND_WAIT => - send_wait_counter_i <= STD_LOGIC_VECTOR( UNSIGNED(send_wait_counter_i) + 1 ); - if send_wait_counter_i >= send_wait_threshold_i then - send_fsm_i <= START; - end if; - - when others => - send_fsm_i <= START; - - end case; - end if; - end process; - - PROC_DLM_COUNTER: process is - variable dlm_type_v : integer range 15 downto 0; - begin - wait until rising_edge(rclk_125_i); - - if reset_i = '1' then - dlm_counter_i <= (others => '0'); - dlm_glob_counter_i <= (others => '0'); - elsif cbm_dlm_rec_va = '1' then - dlm_glob_counter_i <= dlm_glob_counter_i + TO_UNSIGNED(1,1); - - dlm_type_v := to_integer(unsigned(cbm_dlm_rec_type)); - for i in 0 to 15 loop - if dlm_type_v = i then - dlm_counter_i(1+i*2 downto i*2) <= dlm_counter_i(1+i*2 downto i*2) + TO_UNSIGNED(1,1); - end if; - end loop; - end if; - end process; - - phy_debug_i_buf <= phy_debug_i when rising_edge(clk_100_i); - - - PROC_REGIO_DEBUG: process is - variable address : integer range 0 to 255; - begin - wait until rising_edge(clk_100_i); - address := to_integer(unsigned(debug_addr)); - - debug_data_out <= x"00000000"; - - debug_ack <= debug_read_en or debug_write_en; - case address is - when 16#0# => debug_data_out <= x"0000" & phy_stat_op; - when 16#1# => debug_data_out <= x"0000" & phy_ctrl_op; - when 16#2# => debug_data_out <= phy_stat_debug(31 downto 0); - when 16#3# => debug_data_out <= phy_stat_debug(63 downto 32); - when 16#4# => debug_data_out <= phy_ctrl_debug(31 downto 0); - when 16#5# => debug_data_out <= phy_ctrl_debug(63 downto 32); - when 16#6# => debug_data_out <= STD_LOGIC_VECTOR(TO_UNSIGNED(CBM_FEE_MODE, 32)); - - when 16#20# => debug_data_out <= phy_debug_i_buf(31+32*0 downto 32*0); - when 16#21# => debug_data_out <= phy_debug_i_buf(31+32*1 downto 32*1); - when 16#22# => debug_data_out <= phy_debug_i_buf(31+32*2 downto 32*2); - when 16#23# => debug_data_out <= phy_debug_i_buf(31+32*3 downto 32*3); - when 16#24# => debug_data_out <= phy_debug_i_buf(31+32*4 downto 32*4); - when 16#25# => debug_data_out <= phy_debug_i_buf(31+32*5 downto 32*5); - when 16#26# => debug_data_out <= phy_debug_i_buf(31+32*6 downto 32*6); - when 16#27# => debug_data_out <= phy_debug_i_buf(31+32*7 downto 32*7); - when 16#28# => debug_data_out <= phy_debug_i_buf(31+32*8 downto 32*8); - when 16#29# => debug_data_out <= phy_debug_i_buf(31+32*9 downto 32*9); - when 16#2a# => debug_data_out <= phy_debug_i_buf(31+32*10 downto 32*10); - when 16#2b# => debug_data_out <= phy_debug_i_buf(31+32*11 downto 32*11); - when 16#2c# => debug_data_out <= phy_debug_i_buf(31+32*12 downto 32*12); - when 16#2d# => debug_data_out <= phy_debug_i_buf(31+32*13 downto 32*13); - when 16#2e# => debug_data_out <= phy_debug_i_buf(31+32*14 downto 32*14); - when 16#2f# => debug_data_out <= phy_debug_i_buf(31+32*15 downto 32*15); - - - when 16#10# => debug_data_out <= send_wait_threshold_i; - when 16#11# => debug_data_out(20 downto 0) <= cbm_res_n & "00" & cbm_data_from_link; - - when 16#12# => debug_data_out <= STD_LOGIC_VECTOR(dlm_counter_i); - when 16#13# => debug_data_out <= STD_LOGIC_VECTOR(dlm_glob_counter_i); - when 16#14# => - debug_data_out(21 downto 20) <= cbm_debug_overrides_i; - debug_data_out(19 downto 16) <= "0" & send_enabled_i & cbm_data2send_stop & cbm_link_active; - debug_data_out(15 downto 0) <= STD_LOGIC_VECTOR(send_num_pack_counter_i); - - - when 16#15# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_0; - when 16#16# => debug_data_out <= cbm_retrans_error_cntr_0 & cbm_retrans_cntr_0; - when 16#17# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_1; - when 16#18# => debug_data_out <= cbm_retrans_error_cntr_1 & cbm_retrans_cntr_1; - when 16#19# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_2; - when 16#1a# => debug_data_out <= cbm_retrans_error_cntr_2 & cbm_retrans_cntr_2; - when 16#1b# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_3; - when 16#1c# => debug_data_out <= cbm_retrans_error_cntr_3 & cbm_retrans_cntr_3; - - when others => debug_ack <= '0'; - end case; - - if debug_write_en = '1' then - case (address) is - when 16#1# => phy_ctrl_op <= debug_data_in(15 downto 0); - when 16#4# => phy_ctrl_debug(31 downto 0) <= debug_data_in; - when 16#5# => phy_ctrl_debug(63 downto 32) <= debug_data_in; - when 16#10# => send_wait_threshold_i <= debug_data_in; - when 16#14# => - send_enabled_i <= debug_data_in(18); - cbm_debug_overrides_i <= debug_data_in(21 downto 20); - - - when others => debug_ack <= '0'; - end case; - end if; - end process; - - - - ---------------------------------------------------------------------------- --- Reset Generation ---------------------------------------------------------------------------- - GSR_N <= pll_lock; - - THE_RESET_HANDLER : trb_net_reset_handler - generic map( - RESET_DELAY => x"FEEE" - ) - port map( - CLEAR_IN => '0', -- reset input (high active, async) - CLEAR_N_IN => '1', -- reset input (low active, async) - CLK_IN => clk_200_i, -- raw master clock, NOT from PLL/DLL! - SYSCLK_IN => clk_100_i, -- PLL/DLL remastered clock - PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) - RESET_IN => '0', -- general reset signal (SYSCLK) - TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) - CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE! - RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) - DEBUG_OUT => open - ); - - ---------------------------------------------------------------------------- --- Clock Handling ---------------------------------------------------------------------------- - - THE_MAIN_PLL : pll_in200_out100 - port map( - CLK => CLK_GPLL_RIGHT, - CLKOP => clk_100_i, - CLKOK => clk_200_i, - CLKOS => open, - LOCK => pll_lock1 - ); - - pll_lock <= pll_lock1; -- and pll_lock2; - --- GEN_TRBNET: if INCLUDE_TRBNET = c_YES generate ---------------------------------------------------------------------------- --- The TrbNet media interface (to other FPGA) ---------------------------------------------------------------------------- - THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp - generic map( - SERDES_NUM => 1, --number of serdes in quad - EXT_CLOCK => c_NO, --use internal clock - USE_200_MHZ => c_YES, --run on 200 MHz clock - USE_125_MHZ => c_NO, - USE_CTC => c_NO - ) - port map( - CLK => clk_200_i, - SYSCLK => clk_100_i, - RESET => reset_i, - CLEAR => clear_i, - CLK_EN => '1', - --Internal Connection - MED_DATA_IN => med_data_out, - MED_PACKET_NUM_IN => med_packet_num_out, - MED_DATAREADY_IN => med_dataready_out, - MED_READ_OUT => med_read_in, - MED_DATA_OUT => med_data_in, - MED_PACKET_NUM_OUT => med_packet_num_in, - MED_DATAREADY_OUT => med_dataready_in, - MED_READ_IN => med_read_out, - REFCLK2CORE_OUT => open, - --SFP Connection - SD_RXD_P_IN => SERDES_INT_RX(2), - SD_RXD_N_IN => SERDES_INT_RX(3), - SD_TXD_P_OUT => SERDES_INT_TX(2), - SD_TXD_N_OUT => SERDES_INT_TX(3), - SD_REFCLK_P_IN => open, - SD_REFCLK_N_IN => open, - SD_PRSNT_N_IN => FPGA5_COMM(0), - SD_LOS_IN => FPGA5_COMM(0), - SD_TXDIS_OUT => FPGA5_COMM(2), - -- Status and control port - STAT_OP => med_stat_op, - CTRL_OP => med_ctrl_op, - STAT_DEBUG => med_stat_debug, - CTRL_DEBUG => (others => '0'), - - sci_ack => open, - clk_rx_full_out => open, - clk_rx_half_out => open - ); - ---------------------------------------------------------------------------- --- Endpoint ---------------------------------------------------------------------------- - THE_ENDPOINT : trb_net16_endpoint_hades_full_handler - generic map( - REGIO_NUM_STAT_REGS => REGIO_NUM_STAT_REGS, --4, --16 stat reg - REGIO_NUM_CTRL_REGS => REGIO_NUM_CTRL_REGS, --3, --8 cotrol reg - ADDRESS_MASK => x"FFFF", - BROADCAST_BITMASK => x"FF", - BROADCAST_SPECIAL_ADDR => x"45", - REGIO_COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)), - REGIO_HARDWARE_VERSION => x"91000001", - REGIO_INIT_ADDRESS => x"f301", - REGIO_USE_VAR_ENDPOINT_ID => c_YES, - CLOCK_FREQUENCY => 100, - TIMING_TRIGGER_RAW => c_YES, - --Configure data handler - DATA_INTERFACE_NUMBER => 1, - DATA_BUFFER_DEPTH => 13, --13 - DATA_BUFFER_WIDTH => 32, - DATA_BUFFER_FULL_THRESH => 2**13-800, --2**13-1024 - TRG_RELEASE_AFTER_DATA => c_YES, - HEADER_BUFFER_DEPTH => 9, - HEADER_BUFFER_FULL_THRESH => 2**9-16 - ) - port map( - CLK => clk_100_i, - RESET => reset_i, - CLK_EN => '1', - MED_DATAREADY_OUT => med_dataready_out, -- open, -- - MED_DATA_OUT => med_data_out, -- open, -- - MED_PACKET_NUM_OUT => med_packet_num_out, -- open, -- - MED_READ_IN => med_read_in, - MED_DATAREADY_IN => med_dataready_in, - MED_DATA_IN => med_data_in, - MED_PACKET_NUM_IN => med_packet_num_in, - MED_READ_OUT => med_read_out, -- open, -- - MED_STAT_OP_IN => med_stat_op, - MED_CTRL_OP_OUT => med_ctrl_op, - - --Timing trigger in - TRG_TIMING_TRG_RECEIVED_IN => timing_trg_received_i, - --LVL1 trigger to FEE - LVL1_TRG_DATA_VALID_OUT => trg_data_valid_i, - LVL1_VALID_TIMING_TRG_OUT => trg_timing_valid_i, - LVL1_VALID_NOTIMING_TRG_OUT => trg_notiming_valid_i, - LVL1_INVALID_TRG_OUT => trg_invalid_i, - - LVL1_TRG_TYPE_OUT => trg_type_i, - LVL1_TRG_NUMBER_OUT => trg_number_i, - LVL1_TRG_CODE_OUT => trg_code_i, - LVL1_TRG_INFORMATION_OUT => trg_information_i, - LVL1_INT_TRG_NUMBER_OUT => trg_int_number_i, - - --Information about trigger handler errors - TRG_MULTIPLE_TRG_OUT => trg_multiple_trg_i, - TRG_TIMEOUT_DETECTED_OUT => trg_timeout_detected_i, - TRG_SPURIOUS_TRG_OUT => trg_spurious_trg_i, - TRG_MISSING_TMG_TRG_OUT => trg_missing_tmg_trg_i, - TRG_SPIKE_DETECTED_OUT => trg_spike_detected_i, - - --Response from FEE - FEE_TRG_RELEASE_IN(0) => fee_trg_release_i, - FEE_TRG_STATUSBITS_IN => fee_trg_statusbits_i, - FEE_DATA_IN => fee_data_i, - FEE_DATA_WRITE_IN(0) => fee_data_write_i, - FEE_DATA_FINISHED_IN(0) => fee_data_finished_i, - FEE_DATA_ALMOST_FULL_OUT(0) => fee_almost_full_i, - - -- Slow Control Data Port - REGIO_COMMON_STAT_REG_IN => common_stat_reg, --0x00 - REGIO_COMMON_CTRL_REG_OUT => common_ctrl_reg, --0x20 - REGIO_COMMON_STAT_STROBE_OUT => common_stat_reg_strobe, - REGIO_COMMON_CTRL_STROBE_OUT => common_ctrl_reg_strobe, - REGIO_STAT_REG_IN => stat_reg, --start 0x80 - REGIO_CTRL_REG_OUT => ctrl_reg, --start 0xc0 - REGIO_STAT_STROBE_OUT => stat_reg_strobe, - REGIO_CTRL_STROBE_OUT => ctrl_reg_strobe, - REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE, - REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'), - - BUS_ADDR_OUT => regio_addr_out, - BUS_READ_ENABLE_OUT => regio_read_enable_out, - BUS_WRITE_ENABLE_OUT => regio_write_enable_out, - BUS_DATA_OUT => regio_data_out, - BUS_DATA_IN => regio_data_in, - BUS_DATAREADY_IN => regio_dataready_in, - BUS_NO_MORE_DATA_IN => regio_no_more_data_in, - BUS_WRITE_ACK_IN => regio_write_ack_in, - BUS_UNKNOWN_ADDR_IN => regio_unknown_addr_in, - BUS_TIMEOUT_OUT => regio_timeout_out, - ONEWIRE_INOUT => TEMPSENS, - ONEWIRE_MONITOR_OUT => open, - - TIME_GLOBAL_OUT => global_time, - TIME_LOCAL_OUT => local_time, - TIME_SINCE_LAST_TRG_OUT => time_since_last_trg, - TIME_TICKS_OUT => timer_ticks, - - STAT_DEBUG_IPU => open, - STAT_DEBUG_1 => open, - STAT_DEBUG_2 => open, - STAT_DEBUG_DATA_HANDLER_OUT => open, - STAT_DEBUG_IPU_HANDLER_OUT => open, - STAT_TRIGGER_OUT => open, - CTRL_MPLEX => (others => '0'), - IOBUF_CTRL_GEN => (others => '0'), - STAT_ONEWIRE => open, - STAT_ADDR_DEBUG => open, - DEBUG_LVL1_HANDLER_OUT => open - ); - ---------------------------------------------------------------------------- --- Bus Handler ---------------------------------------------------------------------------- - THE_BUS_HANDLER : trb_net16_regio_bus_handler - generic map( - PORT_NUMBER => 3, - PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"a000", others => x"0000"), - PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 6, others => 0) - ) - port map( - CLK => clk_100_i, - RESET => reset_i, - - DAT_ADDR_IN => regio_addr_out, - DAT_DATA_IN => regio_data_out, - DAT_DATA_OUT => regio_data_in, - DAT_READ_ENABLE_IN => regio_read_enable_out, - DAT_WRITE_ENABLE_IN => regio_write_enable_out, - DAT_TIMEOUT_IN => regio_timeout_out, - DAT_DATAREADY_OUT => regio_dataready_in, - DAT_WRITE_ACK_OUT => regio_write_ack_in, - DAT_NO_MORE_DATA_OUT => regio_no_more_data_in, - DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in, - - --Bus Handler (SPI CTRL) - BUS_READ_ENABLE_OUT(0) => spictrl_read_en, - BUS_WRITE_ENABLE_OUT(0) => spictrl_write_en, - BUS_DATA_OUT(0*32+31 downto 0*32) => spictrl_data_in, - BUS_ADDR_OUT(0*16) => spictrl_addr, - BUS_ADDR_OUT(0*16+15 downto 0*16+1) => open, - BUS_TIMEOUT_OUT(0) => open, - BUS_DATA_IN(0*32+31 downto 0*32) => spictrl_data_out, - BUS_DATAREADY_IN(0) => spictrl_ack, - BUS_WRITE_ACK_IN(0) => spictrl_ack, - BUS_NO_MORE_DATA_IN(0) => spictrl_busy, - BUS_UNKNOWN_ADDR_IN(0) => '0', - - --Bus Handler (SPI Memory) - BUS_READ_ENABLE_OUT(1) => spimem_read_en, - BUS_WRITE_ENABLE_OUT(1) => spimem_write_en, - BUS_DATA_OUT(1*32+31 downto 1*32) => spimem_data_in, - BUS_ADDR_OUT(1*16+5 downto 1*16) => spimem_addr, - BUS_ADDR_OUT(1*16+15 downto 1*16+6) => open, - BUS_TIMEOUT_OUT(1) => open, - BUS_DATA_IN(1*32+31 downto 1*32) => spimem_data_out, - BUS_DATAREADY_IN(1) => spimem_ack, - BUS_WRITE_ACK_IN(1) => spimem_ack, - BUS_NO_MORE_DATA_IN(1) => '0', - BUS_UNKNOWN_ADDR_IN(1) => '0', - - --Bus Handler (SPI CTRL) - BUS_READ_ENABLE_OUT(2) => debug_read_en, - BUS_WRITE_ENABLE_OUT(2) => debug_write_en, - BUS_DATA_OUT(2*32+31 downto 2*32) => debug_data_in, - BUS_ADDR_OUT(2*16+5 downto 2*16) => debug_addr, - BUS_ADDR_OUT(2*16+15 downto 2*16+6) => open, - BUS_TIMEOUT_OUT(2) => open, - BUS_DATA_IN(2*32+31 downto 2*32) => debug_data_out, - BUS_DATAREADY_IN(2) => debug_ack, - BUS_WRITE_ACK_IN(2) => debug_ack, - BUS_NO_MORE_DATA_IN(2) => '0', - BUS_UNKNOWN_ADDR_IN(2) => '0', - - - STAT_DEBUG => open - ); - ---------------------------------------------------------------------------- --- SPI / Flash ---------------------------------------------------------------------------- - - THE_SPI_MASTER : spi_master - port map( - CLK_IN => clk_100_i, - RESET_IN => reset_i, - -- Slave bus - BUS_READ_IN => spictrl_read_en, - BUS_WRITE_IN => spictrl_write_en, - BUS_BUSY_OUT => spictrl_busy, - BUS_ACK_OUT => spictrl_ack, - BUS_ADDR_IN(0) => spictrl_addr, - BUS_DATA_IN => spictrl_data_in, - BUS_DATA_OUT => spictrl_data_out, - -- SPI connections - SPI_CS_OUT => FLASH_CS, - SPI_SDI_IN => FLASH_DOUT, - SPI_SDO_OUT => FLASH_DIN, - SPI_SCK_OUT => FLASH_CLK, - -- BRAM for read/write data - BRAM_A_OUT => spi_bram_addr, - BRAM_WR_D_IN => spi_bram_wr_d, - BRAM_RD_D_OUT => spi_bram_rd_d, - BRAM_WE_OUT => spi_bram_we, - -- Status lines - STAT => open - ); - --- data memory for SPI accesses - THE_SPI_MEMORY : spi_databus_memory - port map( - CLK_IN => clk_100_i, - RESET_IN => reset_i, - -- Slave bus - BUS_ADDR_IN => spimem_addr, - BUS_READ_IN => spimem_read_en, - BUS_WRITE_IN => spimem_write_en, - BUS_ACK_OUT => spimem_ack, - BUS_DATA_IN => spimem_data_in, - BUS_DATA_OUT => spimem_data_out, - -- state machine connections - BRAM_ADDR_IN => spi_bram_addr, - BRAM_WR_D_OUT => spi_bram_wr_d, - BRAM_RD_D_IN => spi_bram_rd_d, - BRAM_WE_IN => spi_bram_we, - -- Status lines - STAT => open - ); - ---------------------------------------------------------------------------- --- Reboot FPGA ---------------------------------------------------------------------------- - THE_FPGA_REBOOT : fpga_reboot - port map( - CLK => clk_100_i, - RESET => reset_i, - DO_REBOOT => common_ctrl_reg(15), - PROGRAMN => PROGRAMN - ); - - - ---------------------------------------------------------------------------- --- LED ---------------------------------------------------------------------------- - LED_GREEN <= not med_stat_op(9); - LED_ORANGE <= not med_stat_op(10); - LED_RED <= not time_counter(26); - LED_YELLOW <= not med_stat_op(11); - --- end generate; - - +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb3_components.all; +use work.version.all; + +use work.cbmnet_interface_pkg.all; +use work.cbmnet_phy_pkg.all; + + +entity trb3_periph_cbmnet is + generic ( + CBM_FEE_MODE : integer := CBM_FEE_MODE_C; -- in FEE mode, logic will run on recovered clock and (for now) listen only to data received + -- in Master mode, logic will run on internal clock and regularly send dlms + INCLUDE_TRBNET : integer := INCLUDE_TRBNET_C + ); + port( + --Clocks + CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz + CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA + CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + + --Trigger + TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out + TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out + + --Serdes + CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible + CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems + SERDES_INT_TX : out std_logic_vector(3 downto 0); + SERDES_INT_RX : in std_logic_vector(3 downto 0); + SERDES_ADDON_TX : out std_logic_vector(11 downto 0); + SERDES_ADDON_RX : in std_logic_vector(11 downto 0); + + --Inter-FPGA Communication + FPGA5_COMM : inout std_logic_vector(11 downto 0); + --Bit 0/1 input, serial link RX active + --Bit 2/3 output, serial link TX active + --others yet undefined + --Connection to AddOn + LED_LINKOK : out std_logic_vector(6 downto 1); + LED_RX : out std_logic_vector(6 downto 1); + LED_TX : out std_logic_vector(6 downto 1); + + SFP_MOD0 : in std_logic_vector(6 downto 1); + SFP_TXDIS : out std_logic_vector(6 downto 1); + SFP_LOS : in std_logic_vector(6 downto 1); + SFP_MOD1 : out std_logic_vector(6 downto 1); + SFP_MOD2 : inout std_logic_vector(6 downto 1); + + SFP_RATESEL: out std_logic_vector(6 downto 1); + SFP_TXFAULT: in std_logic_vector(6 downto 1); + + --Flash ROM & Reboot + FLASH_CLK : out std_logic; + FLASH_CS : out std_logic; + FLASH_DIN : out std_logic; + FLASH_DOUT : in std_logic; + PROGRAMN : out std_logic; --reboot FPGA + + --Misc + TEMPSENS : inout std_logic; --Temperature Sensor + CODE_LINE : in std_logic_vector(1 downto 0); + LED_GREEN : out std_logic; + LED_ORANGE : out std_logic; + LED_RED : out std_logic; + LED_YELLOW : out std_logic; + SUPPL : in std_logic; --terminated diff pair, PCLK, Pads + + --Test Connectors + TEST_LINE : out std_logic_vector(15 downto 0); + --TEST_LVDS_LINE : out std_logic_vector(1 downto 0); + + -- PCS Core TODO: Suppose this is necessary only for simulation + SD_RXD_N_IN : in std_logic; + SD_RXD_P_IN : in std_logic; + SD_TXD_N_OUT : out std_logic; + SD_TXD_P_OUT : out std_logic + ); + + attribute syn_useioff : boolean; + --no IO-FF for LEDs relaxes timing constraints + attribute syn_useioff of LED_GREEN : signal is false; + attribute syn_useioff of LED_ORANGE : signal is false; + attribute syn_useioff of LED_RED : signal is false; + attribute syn_useioff of LED_YELLOW : signal is false; + attribute syn_useioff of TEMPSENS : signal is false; + attribute syn_useioff of PROGRAMN : signal is false; + attribute syn_useioff of CODE_LINE : signal is false; + attribute syn_useioff of TRIGGER_LEFT : signal is false; + attribute syn_useioff of TRIGGER_RIGHT : signal is false; + attribute syn_useioff of LED_LINKOK : signal is false; + attribute syn_useioff of LED_RX : signal is false; + attribute syn_useioff of LED_TX : signal is false; + + --important signals _with_ IO-FF + attribute syn_useioff of FLASH_CLK : signal is true; + attribute syn_useioff of FLASH_CS : signal is true; + attribute syn_useioff of FLASH_DIN : signal is true; + attribute syn_useioff of FLASH_DOUT : signal is true; + attribute syn_useioff of FPGA5_COMM : signal is true; + attribute syn_useioff of TEST_LINE : signal is true; + + attribute nopad : string; + attribute nopad of SD_RXD_N_IN, SD_RXD_P_IN, SD_TXD_N_OUT, SD_TXD_P_OUT : signal is "true"; + + attribute syn_keep : boolean; + attribute syn_keep of CLK_GPLL_LEFT, CLK_GPLL_RIGHT, CLK_PCLK_LEFT, CLK_PCLK_RIGHT, TRIGGER_LEFT, TRIGGER_RIGHT : signal is true; + attribute syn_preserve : boolean; + +end entity; + +architecture trb3_periph_arch of trb3_periph_cbmnet is +--Constants + constant REGIO_NUM_STAT_REGS : integer := 2; + constant REGIO_NUM_CTRL_REGS : integer := 2; + + + --Clock / Reset + signal clk_125_i : std_logic; -- clock reference for CBMNet serdes + signal clk_100_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL + signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL + signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic. + signal pll_lock1, pll_lock2 : std_logic; + signal clear_i : std_logic; + signal reset_i : std_logic; + signal GSR_N : std_logic; + + attribute syn_keep of GSR_N : signal is true; + attribute syn_preserve of GSR_N : signal is true; + + + signal rclk_125_i : std_logic; -- recovered clock + signal rreset_i : std_logic; -- reset for recovered clock ~ 1us after clock becomes stable + + + --Media Interface + signal med_stat_op : std_logic_vector (1*16-1 downto 0) := (others => '0'); + signal med_ctrl_op : std_logic_vector (1*16-1 downto 0); + signal med_stat_debug : std_logic_vector (1*64-1 downto 0); + signal med_ctrl_debug : std_logic_vector (1*64-1 downto 0); + signal med_data_out : std_logic_vector (1*16-1 downto 0); + signal med_packet_num_out : std_logic_vector (1*3-1 downto 0); + signal med_dataready_out : std_logic; + signal med_read_out : std_logic; + signal med_data_in : std_logic_vector (1*16-1 downto 0); + signal med_packet_num_in : std_logic_vector (1*3-1 downto 0); + signal med_dataready_in : std_logic; + signal med_read_in : std_logic; + + --LVL1 channel + signal timing_trg_received_i : std_logic; + signal trg_data_valid_i : std_logic; + signal trg_timing_valid_i : std_logic; + signal trg_notiming_valid_i : std_logic; + signal trg_invalid_i : std_logic; + signal trg_type_i : std_logic_vector(3 downto 0); + signal trg_number_i : std_logic_vector(15 downto 0); + signal trg_code_i : std_logic_vector(7 downto 0); + signal trg_information_i : std_logic_vector(23 downto 0); + signal trg_int_number_i : std_logic_vector(15 downto 0); + signal trg_multiple_trg_i : std_logic; + signal trg_timeout_detected_i: std_logic; + signal trg_spurious_trg_i : std_logic; + signal trg_missing_tmg_trg_i : std_logic; + signal trg_spike_detected_i : std_logic; + + --Data channel + signal fee_trg_release_i : std_logic; + signal fee_trg_statusbits_i : std_logic_vector(31 downto 0); + signal fee_data_i : std_logic_vector(31 downto 0); + signal fee_data_write_i : std_logic; + signal fee_data_finished_i : std_logic; + signal fee_almost_full_i : std_logic; + + --Slow Control channel + signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0); + signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0); + signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0); + signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0); + signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0); + signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0); + + --RegIO + signal my_address : std_logic_vector (15 downto 0); + signal regio_addr_out : std_logic_vector (15 downto 0); + signal regio_read_enable_out : std_logic; + signal regio_write_enable_out : std_logic; + signal regio_data_out : std_logic_vector (31 downto 0); + signal regio_data_in : std_logic_vector (31 downto 0); + signal regio_dataready_in : std_logic; + signal regio_no_more_data_in : std_logic; + signal regio_write_ack_in : std_logic; + signal regio_unknown_addr_in : std_logic; + signal regio_timeout_out : std_logic; + + --Timer + signal global_time : std_logic_vector(31 downto 0); + signal local_time : std_logic_vector(7 downto 0); + signal time_since_last_trg : std_logic_vector(31 downto 0); + signal timer_ticks : std_logic_vector(1 downto 0); + + --Flash + signal spictrl_read_en : std_logic; + signal spictrl_write_en : std_logic; + signal spictrl_data_in : std_logic_vector(31 downto 0); + signal spictrl_addr : std_logic; + signal spictrl_data_out : std_logic_vector(31 downto 0); + signal spictrl_ack : std_logic; + signal spictrl_busy : std_logic; + signal spimem_read_en : std_logic; + signal spimem_write_en : std_logic; + signal spimem_data_in : std_logic_vector(31 downto 0); + signal spimem_addr : std_logic_vector(5 downto 0); + signal spimem_data_out : std_logic_vector(31 downto 0); + signal spimem_ack : std_logic; + + signal debug_read_en : std_logic; + signal debug_write_en : std_logic; + signal debug_data_in : std_logic_vector(31 downto 0); + signal debug_addr : std_logic_vector(5 downto 0); + signal debug_data_out : std_logic_vector(31 downto 0); + signal debug_ack : std_logic; + + + signal spi_bram_addr : std_logic_vector(7 downto 0); + signal spi_bram_wr_d : std_logic_vector(7 downto 0); + signal spi_bram_rd_d : std_logic_vector(7 downto 0); + signal spi_bram_we : std_logic; + + --FPGA Test + signal time_counter : unsigned(31 downto 0); + + -- CBMNet signals + constant NUM_LANES : integer := 1; + signal cbm_res_n : std_logic; -- Active low reset; can be changed by define + signal cbm_link_active : std_logic; -- link is active and can send and receive data + + signal cbm_ctrl2send_stop : std_logic := '0'; -- send control interface + signal cbm_ctrl2send_start : std_logic := '0'; + signal cbm_ctrl2send_end : std_logic := '0'; + signal cbm_ctrl2send : std_logic_vector(15 downto 0) := (others => '0'); + + signal cbm_data2send_stop : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); -- send data interface + signal cbm_data2send_start : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); + signal cbm_data2send_end : std_logic_vector(NUM_LANES-1 downto 0) := (others => '0'); + signal cbm_data2send : std_logic_vector((16*NUM_LANES)-1 downto 0) := (others => '0'); + + signal cbm_dlm2send_va : std_logic := '0'; -- send dlm interface + signal cbm_dlm2send : std_logic_vector(3 downto 0) := (others => '0'); + + signal cbm_dlm_rec_type : std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface + signal cbm_dlm_rec_va : std_logic := '0'; + + signal cbm_data_rec : std_logic_vector((16*NUM_LANES)-1 downto 0); -- receive data interface + signal cbm_data_rec_start : std_logic_vector(NUM_LANES-1 downto 0); + signal cbm_data_rec_end : std_logic_vector(NUM_LANES-1 downto 0); + signal cbm_data_rec_stop : std_logic_vector(NUM_LANES-1 downto 0) := (others =>'0'); + + signal cbm_ctrl_rec : std_logic_vector(15 downto 0); -- receive control interface + signal cbm_ctrl_rec_start : std_logic; + signal cbm_ctrl_rec_end : std_logic; + signal cbm_ctrl_rec_stop : std_logic; + + signal cbm_data_from_link : std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface from the PHY + signal cbm_data2link : std_logic_vector((18*NUM_LANES)-1 downto 0); -- interface to the PHY + + signal cbm_link_activeovr : std_logic := '0'; -- Overrides; set 0 by default + signal cbm_link_readyovr : std_logic := '0'; + + signal cbm_SERDES_ready : std_logic; -- signalize when PHY ready + + signal phy_stat_op, phy_ctrl_op : std_logic_vector(15 downto 0) := (others => '0'); + signal phy_stat_debug, phy_ctrl_debug : std_logic_vector(63 downto 0) := (others => '0'); + + signal phy_debug_i : std_logic_vector (511 downto 0) := (others => '0'); + signal phy_debug_i_buf : std_logic_vector (511 downto 0); + + +-- Link Tester + signal link_tester_ctrl_en :std_logic; + signal link_tester_dlm_en :std_logic; + signal link_tester_data_en :std_logic; + + signal link_tester_data_stop :std_logic; + signal link_tester_ctrl_stop :std_logic; + + signal link_tester_data_valid:std_logic; + signal link_tester_ctrl_valid:std_logic; + signal link_tester_dlm_valid :std_logic; + + + signal link_tester_ctrl : std_logic_vector(31 downto 0) := (others => '0'); + signal link_tester_stat : std_logic_vector(31 downto 0) := (others => '0'); + + signal dummy : std_logic; + + type SEND_FSM_T is (START, SEND_HEADER, SEND_PACK_NUM, SEND_LENGTH, SEND_DATA, SEND_FOOTER, AFTER_SEND_WAIT); + signal send_fsm_i : SEND_FSM_T; + signal send_length_i : unsigned(4 downto 0); + signal send_num_pack_counter_i : unsigned(15 downto 0); + signal send_enabled_i : std_logic := '0'; + + signal send_wait_counter_i : std_logic_vector(31 downto 0); + signal send_wait_threshold_i : std_logic_vector(31 downto 0); + + signal dlm_counter_i : unsigned(31 downto 0); + signal dlm_glob_counter_i : unsigned(31 downto 0); + + + -- diagnostics Lane0 + signal cbm_crc_error_cntr_flag_0 : std_logic; + signal cbm_retrans_cntr_flag_0 : std_logic; + signal cbm_retrans_error_cntr_flag_0 : std_logic; + signal cbm_crc_error_cntr_0 : std_logic_vector(15 downto 0); + signal cbm_retrans_cntr_0 : std_logic_vector(15 downto 0); + signal cbm_retrans_error_cntr_0 : std_logic_vector(15 downto 0); + signal cbm_crc_error_cntr_clr_0 : std_logic; + signal cbm_retrans_cntr_clr_0 : std_logic; + signal cbm_retrans_error_cntr_clr_0 : std_logic; + + -- diagnostics Lane1 + signal cbm_crc_error_cntr_flag_1 : std_logic; + signal cbm_retrans_cntr_flag_1 : std_logic; + signal cbm_retrans_error_cntr_flag_1 : std_logic; + signal cbm_crc_error_cntr_1 : std_logic_vector(15 downto 0); + signal cbm_retrans_cntr_1 : std_logic_vector(15 downto 0); + signal cbm_retrans_error_cntr_1 : std_logic_vector(15 downto 0); + signal cbm_crc_error_cntr_clr_1 : std_logic; + signal cbm_retrans_cntr_clr_1 : std_logic; + signal cbm_retrans_error_cntr_clr_1 : std_logic; + + -- diagnostics Lane2 + signal cbm_crc_error_cntr_flag_2 : std_logic; + signal cbm_retrans_cntr_flag_2 : std_logic; + signal cbm_retrans_error_cntr_flag_2 : std_logic; + signal cbm_crc_error_cntr_2 : std_logic_vector(15 downto 0); + signal cbm_retrans_cntr_2 : std_logic_vector(15 downto 0); + signal cbm_retrans_error_cntr_2 : std_logic_vector(15 downto 0); + signal cbm_crc_error_cntr_clr_2 : std_logic; + signal cbm_retrans_cntr_clr_2 : std_logic; + signal cbm_retrans_error_cntr_clr_2 : std_logic; + + -- diagnostics Lane3 + signal cbm_crc_error_cntr_flag_3 : std_logic; + signal cbm_retrans_cntr_flag_3 : std_logic; + signal cbm_retrans_error_cntr_flag_3 : std_logic; + signal cbm_crc_error_cntr_3 : std_logic_vector(15 downto 0); + signal cbm_retrans_cntr_3 : std_logic_vector(15 downto 0); + signal cbm_retrans_error_cntr_3 : std_logic_vector(15 downto 0); + signal cbm_crc_error_cntr_clr_3 : std_logic; + signal cbm_retrans_cntr_clr_3 : std_logic; + signal cbm_retrans_error_cntr_clr_3 : std_logic; + + signal cbm_debug_overrides_i : std_logic_vector(1 downto 0) := "00"; + +begin + clk_125_i <= CLK_GPLL_LEFT; + + assert(INCLUDE_TRBNET = c_YES); + +--------------------------------------------------------------------------- +-- CBMNet and PHY +--------------------------------------------------------------------------- + THE_CBM_PHY: cbmnet_phy_ecp3 + generic map (IS_SYNC_SLAVE => CBM_FEE_MODE) + port map ( + CLK => clk_125_i, + RESET => reset_i, + CLEAR => '0', + + --Internal Connection TX + PHY_TXDATA_IN => cbm_data2link(15 downto 0), + PHY_TXDATA_K_IN => cbm_data2link(17 downto 16), + + --Internal Connection RX + PHY_RXDATA_OUT => cbm_data_from_link(15 downto 0), + PHY_RXDATA_K_OUT => cbm_data_from_link(17 downto 16), + + CLK_RX_HALF_OUT => rclk_125_i, + CLK_RX_FULL_OUT => open, + CLK_RX_RESET_OUT => rreset_i, + + LINK_ACTIVE_OUT => open, + SERDES_ready => cbm_SERDES_ready, + + --SFP Connection + SD_RXD_P_IN => SD_RXD_P_IN, + SD_RXD_N_IN => SD_RXD_N_IN, + SD_TXD_P_OUT => SD_TXD_P_OUT, + SD_TXD_N_OUT => SD_TXD_N_OUT, + + SD_PRSNT_N_IN => SFP_MOD0(1), + SD_LOS_IN => SFP_LOS(1), + SD_TXDIS_OUT => SFP_TXDIS(1), + + 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, + DEBUG_OUT => phy_debug_i + ); + + TEST_LINE <= phy_stat_op; + + SFP_RATESEL <= (others => '1'); + + --TEST_LINE(1 downto 0) <= cbm_dlm2send_va & cbm_dlm_rec_va; + +-- process is +-- variable counter_v : unsigned(20 downto 0); +-- begin +-- wait until rising_edge(rclk_125_i); +-- counter_v := counter_v + to_unsigned(1,1); +-- cbm_dlm2send_va <= '0'; +-- if counter_v = 0 then +-- cbm_dlm2send_va <= '1'; +-- end if; +-- end process; +-- + +-- cbm_data2link <= "00" & x"dead"; + THE_CBM_ENDPOINT: lp_top + generic map ( + NUM_LANES => 1, + TX_SLAVE => 1 + ) + port map ( + -- Clk & Reset + clk => rclk_125_i, + res_n => cbm_res_n, + + -- Phy + data_from_link => cbm_data_from_link, + data2link => cbm_data2link, + link_activeovr => cbm_debug_overrides_i(0), + link_readyovr => cbm_debug_overrides_i(1), + SERDES_ready => cbm_SERDES_ready, + + -- CBMNet Interface + link_active => cbm_link_active, + ctrl2send_stop => cbm_ctrl2send_stop, + ctrl2send_start => cbm_ctrl2send_start, + ctrl2send_end => cbm_ctrl2send_end, + ctrl2send => cbm_ctrl2send, + + data2send_stop => cbm_data2send_stop, + data2send_start => cbm_data2send_start, + data2send_end => cbm_data2send_end, + data2send => cbm_data2send, + + dlm2send_va => cbm_dlm2send_va, + dlm2send => cbm_dlm2send, + + dlm_rec_type => cbm_dlm_rec_type, + dlm_rec_va => cbm_dlm_rec_va, + + data_rec => cbm_data_rec, + data_rec_start => cbm_data_rec_start, + data_rec_end => cbm_data_rec_end, + data_rec_stop => cbm_data_rec_stop, + + ctrl_rec => cbm_ctrl_rec, + ctrl_rec_start => cbm_ctrl_rec_start, + ctrl_rec_end => cbm_ctrl_rec_end, + ctrl_rec_stop => cbm_ctrl_rec_stop, + + -- diagnostics Lane0 + crc_error_cntr_flag_0 => cbm_crc_error_cntr_flag_0, -- out std_logic; + retrans_cntr_flag_0 => cbm_retrans_cntr_flag_0, -- out std_logic; + retrans_error_cntr_flag_0 => cbm_retrans_error_cntr_flag_0, -- out std_logic; + crc_error_cntr_0 => cbm_crc_error_cntr_0, -- out std_logic_vector(15 downto 0); + retrans_cntr_0 => cbm_retrans_cntr_0, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_0 => cbm_retrans_error_cntr_0, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_0 => cbm_crc_error_cntr_clr_0, -- in std_logic; + retrans_cntr_clr_0 => cbm_retrans_cntr_clr_0, -- in std_logic; + retrans_error_cntr_clr_0 => cbm_retrans_error_cntr_clr_0, -- in std_logic; + + -- diagnostics Lane1 + crc_error_cntr_flag_1 => cbm_crc_error_cntr_flag_1, -- out std_logic; + retrans_cntr_flag_1 => cbm_retrans_cntr_flag_1, -- out std_logic; + retrans_error_cntr_flag_1 => cbm_retrans_error_cntr_flag_1, -- out std_logic; + crc_error_cntr_1 => cbm_crc_error_cntr_1, -- out std_logic_vector(15 downto 0); + retrans_cntr_1 => cbm_retrans_cntr_1, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_1 => cbm_retrans_error_cntr_1, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_1 => cbm_crc_error_cntr_clr_1, -- in std_logic; + retrans_cntr_clr_1 => cbm_retrans_cntr_clr_1, -- in std_logic; + retrans_error_cntr_clr_1 => cbm_retrans_error_cntr_clr_1, -- in std_logic; + + -- diagnostics Lane2 + crc_error_cntr_flag_2 => cbm_crc_error_cntr_flag_2, -- out std_logic; + retrans_cntr_flag_2 => cbm_retrans_cntr_flag_2, -- out std_logic; + retrans_error_cntr_flag_2 => cbm_retrans_error_cntr_flag_2, -- out std_logic; + crc_error_cntr_2 => cbm_crc_error_cntr_2, -- out std_logic_vector(15 downto 0); + retrans_cntr_2 => cbm_retrans_cntr_2, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_2 => cbm_retrans_error_cntr_2, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_2 => cbm_crc_error_cntr_clr_2, -- in std_logic; + retrans_cntr_clr_2 => cbm_retrans_cntr_clr_2, -- in std_logic; + retrans_error_cntr_clr_2 => cbm_retrans_error_cntr_clr_2, -- in std_logic; + + -- diagnostics Lane3 + crc_error_cntr_flag_3 => cbm_crc_error_cntr_flag_3, -- out std_logic; + retrans_cntr_flag_3 => cbm_retrans_cntr_flag_3, -- out std_logic; + retrans_error_cntr_flag_3 => cbm_retrans_error_cntr_flag_3, -- out std_logic; + crc_error_cntr_3 => cbm_crc_error_cntr_3, -- out std_logic_vector(15 downto 0); + retrans_cntr_3 => cbm_retrans_cntr_3, -- out std_logic_vector(15 downto 0); + retrans_error_cntr_3 => cbm_retrans_error_cntr_3, -- out std_logic_vector(15 downto 0); + crc_error_cntr_clr_3 => cbm_crc_error_cntr_clr_3, -- in std_logic; + retrans_cntr_clr_3 => cbm_retrans_cntr_clr_3, -- in std_logic; + retrans_error_cntr_clr_3 => cbm_retrans_error_cntr_clr_3 -- in std_logic + + + ); + cbm_res_n <= not rreset_i when rising_edge(rclk_125_i); + + cbm_crc_error_cntr_clr_0 <= reset_i; + cbm_retrans_cntr_clr_0 <= reset_i; + cbm_retrans_error_cntr_clr_0 <= reset_i; + cbm_crc_error_cntr_clr_1 <= reset_i; + cbm_retrans_cntr_clr_1 <= reset_i; + cbm_retrans_error_cntr_clr_1 <= reset_i; + cbm_crc_error_cntr_clr_2 <= reset_i; + cbm_retrans_cntr_clr_2 <= reset_i; + cbm_retrans_error_cntr_clr_2 <= reset_i; + cbm_crc_error_cntr_clr_3 <= reset_i; + cbm_retrans_cntr_clr_3 <= reset_i; + cbm_retrans_error_cntr_clr_3 <= reset_i; + + THE_DLM_REFLECT: dlm_reflect port map ( + clk => rclk_125_i, -- in std_logic; + res_n => cbm_res_n, -- in std_logic; + dlm_rec_in => cbm_dlm_rec_type, -- in std_logic_vector(3 downto 0); + dlm_rec_va_in => cbm_dlm_rec_va, -- in std_logic; + dlm_rec_out => open, -- out std_logic_vector(3 downto 0); + dlm_rec_va_out => open, -- out std_logic; + dlm2send_va => cbm_dlm2send_va, -- out std_logic; + dlm2send => cbm_dlm2send -- out std_logic_vector(3 downto 0) + ); + + + PROC_DATA_SEND: process begin + wait until rising_edge(rclk_125_i); + + cbm_data2send <= (others => '0'); + cbm_data2send_start <= "0"; + cbm_data2send_end <= "0"; + + if reset_i = '1' or send_enabled_i = '0' then + send_fsm_i <= START; + send_num_pack_counter_i <= (others => '0'); + + else + case(send_fsm_i) is + when START => + if cbm_link_active='1' and cbm_data2send_stop = "0" then + send_fsm_i <= SEND_HEADER; + send_num_pack_counter_i <= send_num_pack_counter_i + 1; + send_length_i <= "0" & send_num_pack_counter_i(3 downto 0); + end if; + + when SEND_HEADER => + cbm_data2send <= x"f123"; + cbm_data2send_start <= "1"; + send_fsm_i <= SEND_PACK_NUM; + + when SEND_PACK_NUM => + cbm_data2send <= send_num_pack_counter_i; + send_fsm_i <= SEND_LENGTH; + + when SEND_LENGTH => + cbm_data2send(send_length_i'range) <= send_length_i; + send_fsm_i <= SEND_DATA; + + when SEND_DATA => + send_length_i <= send_length_i - 1; + cbm_data2send(15 downto 8) <= "0" & std_logic_vector(send_length_i(2 downto 0)) & std_logic_vector(send_length_i(3 downto 0)); + cbm_data2send(send_length_i'high + 0 downto 0) <= send_length_i; + + if send_length_i = TO_UNSIGNED(1, send_length_i'length) then + send_fsm_i <= SEND_FOOTER; + end if; + + when SEND_FOOTER => + cbm_data2send <= x"f321"; + cbm_data2send_end <= "1"; + + send_wait_counter_i <= (others => '0'); + send_fsm_i <= AFTER_SEND_WAIT; + + when AFTER_SEND_WAIT => + send_wait_counter_i <= STD_LOGIC_VECTOR( UNSIGNED(send_wait_counter_i) + 1 ); + if send_wait_counter_i >= send_wait_threshold_i then + send_fsm_i <= START; + end if; + + when others => + send_fsm_i <= START; + + end case; + end if; + end process; + + PROC_DLM_COUNTER: process is + variable dlm_type_v : integer range 15 downto 0; + begin + wait until rising_edge(rclk_125_i); + + if reset_i = '1' then + dlm_counter_i <= (others => '0'); + dlm_glob_counter_i <= (others => '0'); + elsif cbm_dlm_rec_va = '1' then + dlm_glob_counter_i <= dlm_glob_counter_i + TO_UNSIGNED(1,1); + + dlm_type_v := to_integer(unsigned(cbm_dlm_rec_type)); + for i in 0 to 15 loop + if dlm_type_v = i then + dlm_counter_i(1+i*2 downto i*2) <= dlm_counter_i(1+i*2 downto i*2) + TO_UNSIGNED(1,1); + end if; + end loop; + end if; + end process; + + phy_debug_i_buf <= phy_debug_i when rising_edge(clk_100_i); + + + PROC_REGIO_DEBUG: process is + variable address : integer range 0 to 255; + begin + wait until rising_edge(clk_100_i); + address := to_integer(unsigned(debug_addr)); + + debug_data_out <= x"00000000"; + + debug_ack <= debug_read_en or debug_write_en; + case address is + when 16#0# => debug_data_out <= x"0000" & phy_stat_op; + when 16#1# => debug_data_out <= x"0000" & phy_ctrl_op; + when 16#2# => debug_data_out <= phy_stat_debug(31 downto 0); + when 16#3# => debug_data_out <= phy_stat_debug(63 downto 32); + when 16#4# => debug_data_out <= phy_ctrl_debug(31 downto 0); + when 16#5# => debug_data_out <= phy_ctrl_debug(63 downto 32); + when 16#6# => debug_data_out <= STD_LOGIC_VECTOR(TO_UNSIGNED(CBM_FEE_MODE, 32)); + + when 16#20# => debug_data_out <= phy_debug_i_buf(31+32*0 downto 32*0); + when 16#21# => debug_data_out <= phy_debug_i_buf(31+32*1 downto 32*1); + when 16#22# => debug_data_out <= phy_debug_i_buf(31+32*2 downto 32*2); + when 16#23# => debug_data_out <= phy_debug_i_buf(31+32*3 downto 32*3); + when 16#24# => debug_data_out <= phy_debug_i_buf(31+32*4 downto 32*4); + when 16#25# => debug_data_out <= phy_debug_i_buf(31+32*5 downto 32*5); + when 16#26# => debug_data_out <= phy_debug_i_buf(31+32*6 downto 32*6); + when 16#27# => debug_data_out <= phy_debug_i_buf(31+32*7 downto 32*7); + when 16#28# => debug_data_out <= phy_debug_i_buf(31+32*8 downto 32*8); + when 16#29# => debug_data_out <= phy_debug_i_buf(31+32*9 downto 32*9); + when 16#2a# => debug_data_out <= phy_debug_i_buf(31+32*10 downto 32*10); + when 16#2b# => debug_data_out <= phy_debug_i_buf(31+32*11 downto 32*11); + when 16#2c# => debug_data_out <= phy_debug_i_buf(31+32*12 downto 32*12); + when 16#2d# => debug_data_out <= phy_debug_i_buf(31+32*13 downto 32*13); + when 16#2e# => debug_data_out <= phy_debug_i_buf(31+32*14 downto 32*14); + when 16#2f# => debug_data_out <= phy_debug_i_buf(31+32*15 downto 32*15); + + + when 16#10# => debug_data_out <= send_wait_threshold_i; + when 16#11# => debug_data_out(20 downto 0) <= "000" & cbm_data_from_link; + + when 16#12# => debug_data_out <= STD_LOGIC_VECTOR(dlm_counter_i); + when 16#13# => debug_data_out <= STD_LOGIC_VECTOR(dlm_glob_counter_i); + when 16#14# => + debug_data_out(21 downto 20) <= cbm_debug_overrides_i; + debug_data_out(19 downto 16) <= "0" & send_enabled_i & cbm_data2send_stop & cbm_link_active; + debug_data_out(15 downto 0) <= STD_LOGIC_VECTOR(send_num_pack_counter_i); + + + when 16#15# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_0; + when 16#16# => debug_data_out <= cbm_retrans_error_cntr_0 & cbm_retrans_cntr_0; + when 16#17# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_1; + when 16#18# => debug_data_out <= cbm_retrans_error_cntr_1 & cbm_retrans_cntr_1; + when 16#19# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_2; + when 16#1a# => debug_data_out <= cbm_retrans_error_cntr_2 & cbm_retrans_cntr_2; + when 16#1b# => debug_data_out(15 downto 0) <= cbm_crc_error_cntr_3; + when 16#1c# => debug_data_out <= cbm_retrans_error_cntr_3 & cbm_retrans_cntr_3; + + when others => debug_ack <= '0'; + end case; + + if debug_write_en = '1' then + case (address) is + when 16#1# => phy_ctrl_op <= debug_data_in(15 downto 0); + when 16#4# => phy_ctrl_debug(31 downto 0) <= debug_data_in; + when 16#5# => phy_ctrl_debug(63 downto 32) <= debug_data_in; + when 16#10# => send_wait_threshold_i <= debug_data_in; + when 16#14# => + send_enabled_i <= debug_data_in(18); + cbm_debug_overrides_i <= debug_data_in(21 downto 20); + + + when others => debug_ack <= '0'; + end case; + end if; + end process; + + + + +--------------------------------------------------------------------------- +-- Reset Generation +--------------------------------------------------------------------------- + GSR_N <= pll_lock; + + THE_RESET_HANDLER : trb_net_reset_handler + generic map( + RESET_DELAY => x"FEEE" + ) + port map( + CLEAR_IN => '0', -- reset input (high active, async) + CLEAR_N_IN => '1', -- reset input (low active, async) + CLK_IN => clk_200_i, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => clk_100_i, -- PLL/DLL remastered clock + PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) + RESET_IN => '0', -- general reset signal (SYSCLK) + TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) + CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE! + RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) + DEBUG_OUT => open + ); + + +--------------------------------------------------------------------------- +-- Clock Handling +--------------------------------------------------------------------------- + + THE_MAIN_PLL : pll_in200_out100 + port map( + CLK => CLK_GPLL_RIGHT, + CLKOP => clk_100_i, + CLKOK => clk_200_i, + CLKOS => open, + LOCK => pll_lock1 + ); + + pll_lock <= pll_lock1; -- and pll_lock2; + +-- GEN_TRBNET: if INCLUDE_TRBNET = c_YES generate +--------------------------------------------------------------------------- +-- The TrbNet media interface (to other FPGA) +--------------------------------------------------------------------------- + THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp + generic map( + SERDES_NUM => 1, --number of serdes in quad + EXT_CLOCK => c_NO, --use internal clock + USE_200_MHZ => c_YES, --run on 200 MHz clock + USE_125_MHZ => c_NO, + USE_CTC => c_NO + ) + port map( + CLK => clk_200_i, + SYSCLK => clk_100_i, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN => med_data_out, + MED_PACKET_NUM_IN => med_packet_num_out, + MED_DATAREADY_IN => med_dataready_out, + MED_READ_OUT => med_read_in, + MED_DATA_OUT => med_data_in, + MED_PACKET_NUM_OUT => med_packet_num_in, + MED_DATAREADY_OUT => med_dataready_in, + MED_READ_IN => med_read_out, + REFCLK2CORE_OUT => open, + --SFP Connection + SD_RXD_P_IN => SERDES_INT_RX(2), + SD_RXD_N_IN => SERDES_INT_RX(3), + SD_TXD_P_OUT => SERDES_INT_TX(2), + SD_TXD_N_OUT => SERDES_INT_TX(3), + SD_REFCLK_P_IN => open, + SD_REFCLK_N_IN => open, + SD_PRSNT_N_IN => FPGA5_COMM(0), + SD_LOS_IN => FPGA5_COMM(0), + SD_TXDIS_OUT => FPGA5_COMM(2), + -- Status and control port + STAT_OP => med_stat_op, + CTRL_OP => med_ctrl_op, + STAT_DEBUG => med_stat_debug, + CTRL_DEBUG => (others => '0'), + + sci_ack => open, + clk_rx_full_out => open, + clk_rx_half_out => open + ); + +--------------------------------------------------------------------------- +-- Endpoint +--------------------------------------------------------------------------- + THE_ENDPOINT : trb_net16_endpoint_hades_full_handler + generic map( + REGIO_NUM_STAT_REGS => REGIO_NUM_STAT_REGS, --4, --16 stat reg + REGIO_NUM_CTRL_REGS => REGIO_NUM_CTRL_REGS, --3, --8 cotrol reg + ADDRESS_MASK => x"FFFF", + BROADCAST_BITMASK => x"FF", + BROADCAST_SPECIAL_ADDR => x"45", + REGIO_COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME, 32)), + REGIO_HARDWARE_VERSION => x"91000001", + REGIO_INIT_ADDRESS => x"f301", + REGIO_USE_VAR_ENDPOINT_ID => c_YES, + CLOCK_FREQUENCY => 100, + TIMING_TRIGGER_RAW => c_YES, + --Configure data handler + DATA_INTERFACE_NUMBER => 1, + DATA_BUFFER_DEPTH => 13, --13 + DATA_BUFFER_WIDTH => 32, + DATA_BUFFER_FULL_THRESH => 2**13-800, --2**13-1024 + TRG_RELEASE_AFTER_DATA => c_YES, + HEADER_BUFFER_DEPTH => 9, + HEADER_BUFFER_FULL_THRESH => 2**9-16 + ) + port map( + CLK => clk_100_i, + RESET => reset_i, + CLK_EN => '1', + MED_DATAREADY_OUT => med_dataready_out, -- open, -- + MED_DATA_OUT => med_data_out, -- open, -- + MED_PACKET_NUM_OUT => med_packet_num_out, -- open, -- + MED_READ_IN => med_read_in, + MED_DATAREADY_IN => med_dataready_in, + MED_DATA_IN => med_data_in, + MED_PACKET_NUM_IN => med_packet_num_in, + MED_READ_OUT => med_read_out, -- open, -- + MED_STAT_OP_IN => med_stat_op, + MED_CTRL_OP_OUT => med_ctrl_op, + + --Timing trigger in + TRG_TIMING_TRG_RECEIVED_IN => timing_trg_received_i, + --LVL1 trigger to FEE + LVL1_TRG_DATA_VALID_OUT => trg_data_valid_i, + LVL1_VALID_TIMING_TRG_OUT => trg_timing_valid_i, + LVL1_VALID_NOTIMING_TRG_OUT => trg_notiming_valid_i, + LVL1_INVALID_TRG_OUT => trg_invalid_i, + + LVL1_TRG_TYPE_OUT => trg_type_i, + LVL1_TRG_NUMBER_OUT => trg_number_i, + LVL1_TRG_CODE_OUT => trg_code_i, + LVL1_TRG_INFORMATION_OUT => trg_information_i, + LVL1_INT_TRG_NUMBER_OUT => trg_int_number_i, + + --Information about trigger handler errors + TRG_MULTIPLE_TRG_OUT => trg_multiple_trg_i, + TRG_TIMEOUT_DETECTED_OUT => trg_timeout_detected_i, + TRG_SPURIOUS_TRG_OUT => trg_spurious_trg_i, + TRG_MISSING_TMG_TRG_OUT => trg_missing_tmg_trg_i, + TRG_SPIKE_DETECTED_OUT => trg_spike_detected_i, + + --Response from FEE + FEE_TRG_RELEASE_IN(0) => fee_trg_release_i, + FEE_TRG_STATUSBITS_IN => fee_trg_statusbits_i, + FEE_DATA_IN => fee_data_i, + FEE_DATA_WRITE_IN(0) => fee_data_write_i, + FEE_DATA_FINISHED_IN(0) => fee_data_finished_i, + FEE_DATA_ALMOST_FULL_OUT(0) => fee_almost_full_i, + + -- Slow Control Data Port + REGIO_COMMON_STAT_REG_IN => common_stat_reg, --0x00 + REGIO_COMMON_CTRL_REG_OUT => common_ctrl_reg, --0x20 + REGIO_COMMON_STAT_STROBE_OUT => common_stat_reg_strobe, + REGIO_COMMON_CTRL_STROBE_OUT => common_ctrl_reg_strobe, + REGIO_STAT_REG_IN => stat_reg, --start 0x80 + REGIO_CTRL_REG_OUT => ctrl_reg, --start 0xc0 + REGIO_STAT_STROBE_OUT => stat_reg_strobe, + REGIO_CTRL_STROBE_OUT => ctrl_reg_strobe, + REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE, + REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'), + + BUS_ADDR_OUT => regio_addr_out, + BUS_READ_ENABLE_OUT => regio_read_enable_out, + BUS_WRITE_ENABLE_OUT => regio_write_enable_out, + BUS_DATA_OUT => regio_data_out, + BUS_DATA_IN => regio_data_in, + BUS_DATAREADY_IN => regio_dataready_in, + BUS_NO_MORE_DATA_IN => regio_no_more_data_in, + BUS_WRITE_ACK_IN => regio_write_ack_in, + BUS_UNKNOWN_ADDR_IN => regio_unknown_addr_in, + BUS_TIMEOUT_OUT => regio_timeout_out, + ONEWIRE_INOUT => TEMPSENS, + ONEWIRE_MONITOR_OUT => open, + + TIME_GLOBAL_OUT => global_time, + TIME_LOCAL_OUT => local_time, + TIME_SINCE_LAST_TRG_OUT => time_since_last_trg, + TIME_TICKS_OUT => timer_ticks, + + STAT_DEBUG_IPU => open, + STAT_DEBUG_1 => open, + STAT_DEBUG_2 => open, + STAT_DEBUG_DATA_HANDLER_OUT => open, + STAT_DEBUG_IPU_HANDLER_OUT => open, + STAT_TRIGGER_OUT => open, + CTRL_MPLEX => (others => '0'), + IOBUF_CTRL_GEN => (others => '0'), + STAT_ONEWIRE => open, + STAT_ADDR_DEBUG => open, + DEBUG_LVL1_HANDLER_OUT => open + ); + +--------------------------------------------------------------------------- +-- Bus Handler +--------------------------------------------------------------------------- + THE_BUS_HANDLER : trb_net16_regio_bus_handler + generic map( + PORT_NUMBER => 3, + PORT_ADDRESSES => (0 => x"d000", 1 => x"d100", 2 => x"a000", others => x"0000"), + PORT_ADDR_MASK => (0 => 1, 1 => 6, 2 => 6, others => 0) + ) + port map( + CLK => clk_100_i, + RESET => reset_i, + + DAT_ADDR_IN => regio_addr_out, + DAT_DATA_IN => regio_data_out, + DAT_DATA_OUT => regio_data_in, + DAT_READ_ENABLE_IN => regio_read_enable_out, + DAT_WRITE_ENABLE_IN => regio_write_enable_out, + DAT_TIMEOUT_IN => regio_timeout_out, + DAT_DATAREADY_OUT => regio_dataready_in, + DAT_WRITE_ACK_OUT => regio_write_ack_in, + DAT_NO_MORE_DATA_OUT => regio_no_more_data_in, + DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in, + + --Bus Handler (SPI CTRL) + BUS_READ_ENABLE_OUT(0) => spictrl_read_en, + BUS_WRITE_ENABLE_OUT(0) => spictrl_write_en, + BUS_DATA_OUT(0*32+31 downto 0*32) => spictrl_data_in, + BUS_ADDR_OUT(0*16) => spictrl_addr, + BUS_ADDR_OUT(0*16+15 downto 0*16+1) => open, + BUS_TIMEOUT_OUT(0) => open, + BUS_DATA_IN(0*32+31 downto 0*32) => spictrl_data_out, + BUS_DATAREADY_IN(0) => spictrl_ack, + BUS_WRITE_ACK_IN(0) => spictrl_ack, + BUS_NO_MORE_DATA_IN(0) => spictrl_busy, + BUS_UNKNOWN_ADDR_IN(0) => '0', + + --Bus Handler (SPI Memory) + BUS_READ_ENABLE_OUT(1) => spimem_read_en, + BUS_WRITE_ENABLE_OUT(1) => spimem_write_en, + BUS_DATA_OUT(1*32+31 downto 1*32) => spimem_data_in, + BUS_ADDR_OUT(1*16+5 downto 1*16) => spimem_addr, + BUS_ADDR_OUT(1*16+15 downto 1*16+6) => open, + BUS_TIMEOUT_OUT(1) => open, + BUS_DATA_IN(1*32+31 downto 1*32) => spimem_data_out, + BUS_DATAREADY_IN(1) => spimem_ack, + BUS_WRITE_ACK_IN(1) => spimem_ack, + BUS_NO_MORE_DATA_IN(1) => '0', + BUS_UNKNOWN_ADDR_IN(1) => '0', + + --Bus Handler (SPI CTRL) + BUS_READ_ENABLE_OUT(2) => debug_read_en, + BUS_WRITE_ENABLE_OUT(2) => debug_write_en, + BUS_DATA_OUT(2*32+31 downto 2*32) => debug_data_in, + BUS_ADDR_OUT(2*16+5 downto 2*16) => debug_addr, + BUS_ADDR_OUT(2*16+15 downto 2*16+6) => open, + BUS_TIMEOUT_OUT(2) => open, + BUS_DATA_IN(2*32+31 downto 2*32) => debug_data_out, + BUS_DATAREADY_IN(2) => debug_ack, + BUS_WRITE_ACK_IN(2) => debug_ack, + BUS_NO_MORE_DATA_IN(2) => '0', + BUS_UNKNOWN_ADDR_IN(2) => '0', + + + STAT_DEBUG => open + ); + +--------------------------------------------------------------------------- +-- SPI / Flash +--------------------------------------------------------------------------- + + THE_SPI_MASTER : spi_master + port map( + CLK_IN => clk_100_i, + RESET_IN => reset_i, + -- Slave bus + BUS_READ_IN => spictrl_read_en, + BUS_WRITE_IN => spictrl_write_en, + BUS_BUSY_OUT => spictrl_busy, + BUS_ACK_OUT => spictrl_ack, + BUS_ADDR_IN(0) => spictrl_addr, + BUS_DATA_IN => spictrl_data_in, + BUS_DATA_OUT => spictrl_data_out, + -- SPI connections + SPI_CS_OUT => FLASH_CS, + SPI_SDI_IN => FLASH_DOUT, + SPI_SDO_OUT => FLASH_DIN, + SPI_SCK_OUT => FLASH_CLK, + -- BRAM for read/write data + BRAM_A_OUT => spi_bram_addr, + BRAM_WR_D_IN => spi_bram_wr_d, + BRAM_RD_D_OUT => spi_bram_rd_d, + BRAM_WE_OUT => spi_bram_we, + -- Status lines + STAT => open + ); + +-- data memory for SPI accesses + THE_SPI_MEMORY : spi_databus_memory + port map( + CLK_IN => clk_100_i, + RESET_IN => reset_i, + -- Slave bus + BUS_ADDR_IN => spimem_addr, + BUS_READ_IN => spimem_read_en, + BUS_WRITE_IN => spimem_write_en, + BUS_ACK_OUT => spimem_ack, + BUS_DATA_IN => spimem_data_in, + BUS_DATA_OUT => spimem_data_out, + -- state machine connections + BRAM_ADDR_IN => spi_bram_addr, + BRAM_WR_D_OUT => spi_bram_wr_d, + BRAM_RD_D_IN => spi_bram_rd_d, + BRAM_WE_IN => spi_bram_we, + -- Status lines + STAT => open + ); + +--------------------------------------------------------------------------- +-- Reboot FPGA +--------------------------------------------------------------------------- + THE_FPGA_REBOOT : fpga_reboot + port map( + CLK => clk_100_i, + RESET => reset_i, + DO_REBOOT => common_ctrl_reg(15), + PROGRAMN => PROGRAMN + ); + + + +--------------------------------------------------------------------------- +-- LED +--------------------------------------------------------------------------- + LED_GREEN <= not med_stat_op(9); + LED_ORANGE <= not med_stat_op(10); + LED_RED <= not time_counter(26); + LED_YELLOW <= not med_stat_op(11); + +-- end generate; + + end architecture; \ No newline at end of file diff --git a/cbmnet/trb3_periph_cbmnet_constraints.lpf b/cbmnet/trb3_periph_cbmnet_constraints.lpf index 063fbd6..808c963 100755 --- a/cbmnet/trb3_periph_cbmnet_constraints.lpf +++ b/cbmnet/trb3_periph_cbmnet_constraints.lpf @@ -29,11 +29,14 @@ LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200.THE_SERDES/PCSD_INST" SITE "PCSA" REGION "MEDIA_UPLINK" "R102C95D" 13 25 DEVSIZE; LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK" ; LOCATE COMP "THE_CBM_PHY/THE_SERDES/PCSD_INST" SITE "PCSB" ; -#LOCATE COMP "THE_CBM_PHY/GEN_EASY_SERDES/THE_EASY_SERDES/PCSD_INST" SITE "PCSB" ; +#LOCATE COMP "THE_CBM_PHY/GEN_EASY_SERDES/THE_EASY_SERDES/PCSD_INST" SITE "PCSB" + REGION "CBM_PHY" "R102C49D" 13 25; LOCATE UGROUP "THE_CBM_PHY/cbmnet_phy_group" REGION "CBM_PHY"; + REGION "CBM_PHY_RX_GEAR" "R102C50D" 13 15 DEVSIZE; LOCATE UGROUP "THE_CBM_PHY/THE_RX_GEAR/cbmnet_phy_rx_gear" REGION "CBM_PHY_RX_GEAR" ; + REGION "CBM_PHY_TX_GEAR" "R102C50D" 13 15 DEVSIZE; LOCATE UGROUP "THE_CBM_PHY/THE_TX_GEAR/cbmnet_phy_tx_gear" REGION "CBM_PHY_TX_GEAR" ; @@ -41,17 +44,315 @@ LOCATE UGROUP "THE_CBM_PHY/THE_TX_GEAR/cbmnet_phy_tx_gear" REGION "CBM_PHY_TX_GE # Relax some of the timing constraints ################################################################# -FREQUENCY PORT "CLK_GPLL_LEFT" 200 MHz ; -FREQUENCY NET "clk_200_i" 200 MHz ; -FREQUENCY NET "clk_100_i_c" 100 MHz ; -FREQUENCY NET "CLK_RX_FULL_OUT" 250 MHz ; -FREQUENCY NET "THE_CBM_PHY/clk_tx_full_i" 250 MHz ; -FREQUENCY NET "THE_MEDIA_UPLINK/un1_THE_MEDIA_UPLINK_2_c" 100 MHz ; -FREQUENCY NET "THE_CBM_PHY/THE_RX_GEAR/clk_125_i_i" 125 MHz ; -FREQUENCY NET "rclk_125_i" 125 MHz ; - DEFINE BUS "rx_data" NET "THE_CBM_PHY/rx_data_from_serdes_i[0]" NET "THE_CBM_PHY/rx_data_from_serdes_i[1]" NET "THE_CBM_PHY/rx_data_from_serdes_i[2]" NET "THE_CBM_PHY/rx_data_from_serdes_i[3]" NET "THE_CBM_PHY/rx_data_from_serdes_i[4]" NET "THE_CBM_PHY/rx_data_from_serdes_i[5]" NET "THE_CBM_PHY/rx_data_from_serdes_i[6]" NET "THE_CBM_PHY/rx_data_from_serdes_i[7]" NET "THE_CBM_PHY/rx_data_from_serdes_i[8]"; DEFINE BUS "tx_data" NET "THE_CBM_PHY/tx_data_to_serdes_i[0]" NET "THE_CBM_PHY/tx_data_to_serdes_i[1]" NET "THE_CBM_PHY/tx_data_to_serdes_i[2]" NET "THE_CBM_PHY/tx_data_to_serdes_i[3]" NET "THE_CBM_PHY/tx_data_to_serdes_i[4]" NET "THE_CBM_PHY/tx_data_to_serdes_i[5]" NET "THE_CBM_PHY/tx_data_to_serdes_i[6]" NET "THE_CBM_PHY/tx_data_to_serdes_i[7]" NET "THE_CBM_PHY/tx_data_to_serdes_i[8]"; PRIORITIZE BUS "rx_data" 51; -PRIORITIZE BUS "tx_data" 50; \ No newline at end of file +PRIORITIZE BUS "tx_data" 50; + +FREQUENCY PORT "CLK_GPLL_LEFT" 200.0 MHz; +FREQUENCY NET "THE_MAIN_PLL/clk_200_i" 200.0 MHz; +FREQUENCY NET "THE_MAIN_PLL/clk_100_i_c" 100.0 MHz; +FREQUENCY NET "THE_CBM_PHY/THE_SERDES/CLK_RX_FULL_OUT" 250.0 MHz; +FREQUENCY NET "THE_CBM_PHY/THE_SERDES/clk_tx_full_i" 250.0 MHz; +FREQUENCY NET "THE_CBM_PHY/THE_RX_GEAR/CLK_RX_HALF_OUT_c" 125.0 MHz; +FREQUENCY NET "THE_MEDIA_UPLINK/gen_serdes_1_200.THE_SERDES/un1_THE_MEDIA_UPLINK_c" 100.0 MHz; + + +# Output Constraints + +# Input Constraints + +# Point-to-point Delay Constraints + + +BLOCK PATH TO CELL "phy_debug_i_buf[0]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[1]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[2]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[3]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[4]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[5]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[6]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[7]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[8]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[9]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[10]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[11]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[12]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[13]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[14]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[15]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[16]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[17]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[20]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[21]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[22]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[24]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[25]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[26]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[27]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[28]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[29]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[30]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[31]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[32]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[33]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[34]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[35]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[36]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[37]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[38]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[39]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[40]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[41]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[42]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[43]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[44]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[45]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[46]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[47]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[48]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[49]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[52]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[53]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[54]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[56]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[57]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[58]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[61]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[63]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[64]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[65]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[68]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[69]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[70]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[96]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[97]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[98]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[99]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[100]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[101]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[102]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[103]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[104]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[105]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[106]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[107]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[108]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[109]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[110]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[111]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[112]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[113]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[114]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[115]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[116]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[117]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[118]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[119]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[120]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[121]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[122]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[123]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[124]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[125]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[126]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[127]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[128]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[129]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[130]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[131]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[132]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[133]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[134]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[135]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[136]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[137]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[138]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[139]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[148]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[149]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[150]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[151]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[152]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[153]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[154]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[155]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[156]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[157]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[158]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[159]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[160]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[161]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[162]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[163]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[164]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[165]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[166]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[167]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[168]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[169]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[170]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[171]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[172]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[173]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[174]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[175]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[176]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[177]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[178]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[179]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[180]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[181]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[182]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[183]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[184]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[185]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[186]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[187]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[188]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[189]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[190]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[191]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[192]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[193]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[194]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[195]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[196]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[197]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[198]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[199]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[200]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[201]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[202]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[203]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[204]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[205]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[206]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[207]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[208]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[209]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[210]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[211]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[244]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[245]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[246]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[247]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[248]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[249]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[250]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[251]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[252]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[253]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[254]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[255]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[256]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[257]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[258]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[259]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[260]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[261]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[262]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[263]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[264]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[265]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[266]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[267]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[268]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[269]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[270]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[271]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[272]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[273]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[274]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[275]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[276]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[277]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[278]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[279]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[280]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[281]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[282]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[283]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[284]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[285]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[286]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[287]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[288]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[289]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[290]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[291]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[292]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[293]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[294]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[295]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[296]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[297]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[298]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[299]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[300]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[301]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[302]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[303]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[304]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[305]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[306]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[307]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[308]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[309]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[310]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[311]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[312]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[313]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[314]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[315]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[316]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[317]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[318]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[319]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[320]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[321]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[322]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[323]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[324]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[325]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[326]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[327]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[328]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[329]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[330]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[331]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[332]" ; +BLOCK PATH TO CELL "phy_debug_i_buf[333]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[0]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[1]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[2]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[3]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[4]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[5]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[6]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[7]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[8]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[9]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[10]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[11]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[12]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[13]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[14]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[15]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[16]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[17]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[18]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[19]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[20]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[21]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[22]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[23]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[24]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[25]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[26]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[27]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[28]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[29]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[30]" ; +BLOCK PATH TO CELL "PROC_REGIO_DEBUG.debug_data_out[31]" ; -- 2.43.0