From b496b11e75786b518526a3e5da580da9c884a24e Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Mon, 3 Nov 2014 09:49:33 +0100 Subject: [PATCH] CBMNet: Undo new-style CTRLBUS as incompatible with ChipScope. Migrated to new new CBMNet PCS-Init-Module, Added some synchroniser (that should not be vital), code clean-up --- cbmnet/code/cbmnet_bridge.vhd | 1142 ++++++++++-------- cbmnet/code/cbmnet_interface_pkg.vhd | 22 +- cbmnet/code/cbmnet_phy_ecp3.vhd | 88 +- cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd | 123 +- cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd | 113 +- cbmnet/code/cbmnet_phy_pkg.vhd | 2 +- cbmnet/code/cbmnet_phy_rx_gear.vhd | 5 +- cbmnet/code/cbmnet_phy_tx_gear.vhd | 42 +- 8 files changed, 827 insertions(+), 710 deletions(-) diff --git a/cbmnet/code/cbmnet_bridge.vhd b/cbmnet/code/cbmnet_bridge.vhd index e4c6a56..be87594 100644 --- a/cbmnet/code/cbmnet_bridge.vhd +++ b/cbmnet/code/cbmnet_bridge.vhd @@ -1,517 +1,627 @@ -Library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - use ieee.std_logic_unsigned.all; - -library work; - use work.trb_net_std.all; - use work.trb_net_components.all; - use work.trb3_components.all; - use work.trb_net16_hub_func.all; - use work.cbmnet_interface_pkg.all; - use work.cbmnet_phy_pkg.all; - -entity cbmnet_bridge is - port ( - -- clock and reset - CLK125_IN : in std_logic; - ASYNC_RESET_IN : in std_logic; - TRB_CLK_IN : in std_logic; - TRB_RESET_IN : in std_logic; - - CBM_CLK_OUT : out std_logic; - CBM_RESET_OUT: out std_logic; - - -- Media Interface - 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, '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 strobes - CBM_LINK_ACTIVE_OUT : out std_logic; - CBM_DLM_OUT : out std_logic; - CBM_TIMING_TRIGGER_OUT : out std_logic; - CBM_SYNC_PULSER_OUT : out std_logic; - - -- TRBNet Terminal - --data output for read-out - TRB_TRIGGER_IN : in std_logic; - TRB_RDO_VALID_DATA_TRG_IN : in std_logic; - TRB_RDO_VALID_NO_TIMING_IN : in std_logic; - TRB_RDO_DATA_OUT : out std_logic_vector(31 downto 0); - TRB_RDO_WRITE_OUT : out std_logic; - TRB_RDO_STATUSBIT_OUT: out std_logic_vector(31 downto 0); - TRB_RDO_FINISHED_OUT : out std_logic; - - TRB_TRIGGER_OUT : out std_logic; - - -- connect to hub - HUB_CTS_NUMBER_IN : in std_logic_vector (15 downto 0); - HUB_CTS_CODE_IN : in std_logic_vector (7 downto 0); - HUB_CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); - HUB_CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); - HUB_CTS_START_READOUT_IN : in std_logic; - HUB_CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM - HUB_CTS_STATUS_BITS_OUT : out std_logic_vector (31 downto 0); - HUB_FEE_DATA_IN : in std_logic_vector (15 downto 0); - HUB_FEE_DATAREADY_IN : in std_logic; - HUB_FEE_READ_OUT : out std_logic; --must be high when idle, otherwise you will never get a dataready - HUB_FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); - HUB_FEE_BUSY_IN : in std_logic; - - -- connect to GbE - GBE_CTS_NUMBER_OUT : out std_logic_vector (15 downto 0); - GBE_CTS_CODE_OUT : out std_logic_vector (7 downto 0); - GBE_CTS_INFORMATION_OUT : out std_logic_vector (7 downto 0); - GBE_CTS_READOUT_TYPE_OUT : out std_logic_vector (3 downto 0); - GBE_CTS_START_READOUT_OUT : out std_logic; - GBE_CTS_READOUT_FINISHED_IN : in std_logic; --no more data, end transfer, send TRM - GBE_CTS_STATUS_BITS_IN : in std_logic_vector (31 downto 0); - GBE_FEE_DATA_OUT : out std_logic_vector (15 downto 0); - GBE_FEE_DATAREADY_OUT : out std_logic; - GBE_FEE_READ_IN : in std_logic; --must be high when idle, otherwise you will never get a dataready - GBE_FEE_STATUS_BITS_OUT : out std_logic_vector (31 downto 0); - GBE_FEE_BUSY_OUT : out std_logic; - - -- reg io - REGIO_IN : in CTRLBUS_RX; - REGIO_OUT : out CTRLBUS_TX - ); -end entity; - -architecture cbmnet_bridge_arch of cbmnet_bridge is - attribute syn_hier : string; - attribute syn_hier of cbmnet_bridge_arch : architecture is "hard"; - - --- link port - signal cbm_clk_i : std_logic; - signal cbm_clk250_i : std_logic; - signal cbm_reset_i : std_logic; - signal cbm_reset_n_i : std_logic; - - signal cbm_ctrl2send_stop_i : std_logic := '0'; -- send control interface - signal cbm_ctrl2send_start_i : std_logic := '0'; - signal cbm_ctrl2send_end_i : std_logic := '0'; - signal cbm_ctrl2send_i : std_logic_vector(15 downto 0) := (others => '0'); - - signal cbm_data2send_stop_i : std_logic; -- send data interface - signal cbm_data2send_start_i : std_logic; - signal cbm_data2send_end_i : std_logic; - signal cbm_data2send_i : std_logic_vector(15 downto 0) := (others => '0'); - - signal cbm_dlm2send_va_i : std_logic := '0'; -- send dlm interface - signal cbm_dlm2send_i : std_logic_vector(3 downto 0) := (others => '0'); - - signal cbm_dlm_ref_rec_type_i: std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface - signal cbm_dlm_ref_rec_va_i : std_logic := '0'; - - signal cbm_dlm_rec_type_i : std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface - signal cbm_dlm_rec_va_i : std_logic := '0'; - - signal cbm_data_rec_i : std_logic_vector(15 downto 0); -- receive data interface - signal cbm_data_rec_start_i : std_logic; - signal cbm_data_rec_end_i : std_logic; - signal cbm_data_rec_stop_i : std_logic := '1'; - - signal cbm_ctrl_rec_i : std_logic_vector(15 downto 0); -- receive control interface - signal cbm_ctrl_rec_start_i : std_logic; - signal cbm_ctrl_rec_end_i : std_logic; - signal cbm_ctrl_rec_stop_i : std_logic; - - signal cbm_data_from_link_i : std_logic_vector(17 downto 0); -- interface from the phy - signal cbm_data2link_i : std_logic_vector(17 downto 0); -- interface to the phy - - signal cbm_serdes_ready_i : std_logic; -- signalize when phy ready - signal cbm_link_active_i : std_logic; -- signalize when lp_top is ready - - signal cbm_phy_debug : std_logic_vector(511 downto 0); - - --- data port mux - signal cbm_data_mux_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester - signal cbm_data_mux_buf_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester - signal cbm_data_mux_crs_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester - - signal cbm_lt_data_enable_buf_i : std_logic; - signal cbm_lt_data_enable_crs_i : std_logic; - - signal cbm_lt_data_enable_i : std_logic; - signal cbm_lt_ctrl_enable_i : std_logic; - signal cbm_lt_force_stop_i : std_logic; - signal cbm_lt_ctrl_valid_i : std_logic; - signal cbm_lt_dlm_valid_i : std_logic; - - signal cbm_lt_data2send_stop_i : std_logic; - signal cbm_lt_data2send_start_i : std_logic; - signal cbm_lt_data2send_end_i : std_logic; - signal cbm_lt_data2send_i : std_logic_vector(15 downto 0); - - signal cbm_rdo_data2send_stop_i : std_logic; - signal cbm_rdo_data2send_start_i : std_logic; - signal cbm_rdo_data2send_end_i : std_logic; - signal cbm_rdo_data2send_i : std_logic_vector(15 downto 0); - --- regio - signal regio_masked_addr_i, rdo_regio_rx, phy_regio_rx, sync_regio_rx : CTRLBUS_RX; - signal rdo_regio_tx, phy_regio_tx, sync_regio_tx : CTRLBUS_TX := (nack => '0', unknown => '0', ack => '0', wack => '0', rack => '0', data => (others => '0')); - - signal cbm_serdes_ready_counter_i : unsigned(31 downto 0) := (others => '0'); - signal cbm_serdes_ready_delay_i : std_logic; - -begin - THE_CBM_PHY: cbmnet_phy_ecp3 - generic map ( - IS_SYNC_SLAVE => c_YES, - DETERMINISTIC_LATENCY => c_YES - ) - port map ( - CLK => CLK125_IN, - RESET => TRB_RESET_IN, - CLEAR => ASYNC_RESET_IN, - - --Internal Connection TX - PHY_TXDATA_IN => cbm_data2link_i(15 downto 0), - PHY_TXDATA_K_IN => cbm_data2link_i(17 downto 16), - - --Internal Connection RX - PHY_RXDATA_OUT => cbm_data_from_link_i(15 downto 0), - PHY_RXDATA_K_OUT => cbm_data_from_link_i(17 downto 16), - - CLK_RX_HALF_OUT => cbm_clk_i, - CLK_RX_FULL_OUT => cbm_clk250_i, - CLK_RX_RESET_OUT => cbm_reset_i, - - SERDES_ready => cbm_serdes_ready_i, - - --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 => SD_PRSNT_N_IN, - SD_LOS_IN => SD_LOS_IN, - SD_TXDIS_OUT => SD_TXDIS_OUT, - - LED_RX_OUT => LED_RX_OUT, - LED_TX_OUT => LED_TX_OUT, - LED_OK_OUT => LED_OK_OUT, - - -- Status and control port - STAT_OP => open, - CTRL_OP => (others => '0'), - DEBUG_OUT => cbm_phy_debug - ); - CBM_CLK_OUT <= cbm_clk_i; - CBM_RESET_OUT <= cbm_reset_i; - - proc_serdes_counter: process is - begin - wait until rising_edge(cbm_clk_i); - cbm_serdes_ready_delay_i <= cbm_serdes_ready_i; - if cbm_serdes_ready_delay_i = '0' and cbm_serdes_ready_i = '1' then - cbm_serdes_ready_counter_i <= cbm_serdes_ready_counter_i + 1; - end if; - end process; - - proc_debug_regio: process is - variable addr : integer range 0 to 31; - begin - wait until rising_edge(TRB_CLK_IN); - addr := to_integer(unsigned(phy_regio_rx.addr(4 downto 0))); - - phy_regio_tx.rack <= phy_regio_rx.read; - phy_regio_tx.unknown <= '0'; - phy_regio_tx.wack <= '0'; - - phy_regio_tx.data <= (others => '0'); - - if addr < 16 then - phy_regio_tx.data <= cbm_phy_debug(addr*32+31 downto addr*32); - - elsif addr = 16 then - phy_regio_tx.data(11 downto 8) <= "0" & cbm_data2send_stop_i & cbm_serdes_ready_i & cbm_link_active_i; - phy_regio_tx.data(7 downto 4) <= "00" & cbm_lt_dlm_valid_i & cbm_lt_ctrl_valid_i; - phy_regio_tx.data(3 downto 0) <= cbm_data_mux_i & cbm_lt_data_enable_i & cbm_lt_ctrl_enable_i & cbm_lt_force_stop_i; - - if phy_regio_rx.write='1' then - cbm_data_mux_i <= phy_regio_rx.data(3); - cbm_lt_data_enable_i <= phy_regio_rx.data(2); - cbm_lt_ctrl_enable_i <= phy_regio_rx.data(1); - cbm_lt_force_stop_i <= phy_regio_rx.data(0); - - phy_regio_tx.wack <= '1'; - end if; - - elsif addr = 17 then - phy_regio_tx.data <= cbm_serdes_ready_counter_i; - - else - phy_regio_tx.unknown <= phy_regio_rx.write or phy_regio_rx.read; - - end if; - - if TRB_RESET_IN='1' then - cbm_lt_data_enable_i <= '0'; - cbm_lt_ctrl_enable_i <= '0'; - cbm_lt_force_stop_i <= '1'; - cbm_data_mux_i <= '0'; - end if; - end process; - - THE_CBM_ENDPOINT: cn_lp_top - port map ( - -- Clk & Reset - clk => cbm_clk_i, - res_n => cbm_reset_n_i, - - -- Phy - data_from_link => cbm_data_from_link_i, - data2link => cbm_data2link_i, - serdes_ready => cbm_serdes_ready_i, - - -- CBMNet Interface - link_active => cbm_link_active_i, - ctrl2send_stop => cbm_ctrl2send_stop_i, - ctrl2send_start => cbm_ctrl2send_start_i, - ctrl2send_end => cbm_ctrl2send_end_i, - ctrl2send => cbm_ctrl2send_i, - - data2send_stop => cbm_data2send_stop_i, - data2send_start => cbm_data2send_start_i, - data2send_end => cbm_data2send_end_i, - data2send => cbm_data2send_i, - - dlm2send_va => cbm_dlm2send_va_i, - dlm2send => cbm_dlm2send_i, - - dlm_rec => cbm_dlm_ref_rec_type_i, - dlm_rec_va => cbm_dlm_ref_rec_va_i, - - data_rec => cbm_data_rec_i, - data_rec_start => cbm_data_rec_start_i, - data_rec_end => cbm_data_rec_end_i, - data_rec_stop => cbm_data_rec_stop_i, - - ctrl_rec => cbm_ctrl_rec_i, - ctrl_rec_start => cbm_ctrl_rec_start_i, - ctrl_rec_end => cbm_ctrl_rec_end_i, - ctrl_rec_stop => cbm_ctrl_rec_stop_i - ); - cbm_reset_n_i <= not cbm_reset_i when rising_edge(cbm_clk_i); - CBM_LINK_ACTIVE_OUT <= cbm_link_active_i; - - THE_DLM_REFLECT: dlm_reflect - port map ( - clk => cbm_clk_i, -- in std_logic; - res_n => cbm_reset_n_i, -- in std_logic; - - -- from interface - dlm_rec_in => cbm_dlm_ref_rec_type_i, -- in std_logic_vector(3 downto 0); - dlm_rec_va_in => cbm_dlm_ref_rec_va_i, -- in std_logic; - - -- to application logic - dlm_rec_out => cbm_dlm_rec_type_i, -- out std_logic_vector(3 downto 0); - dlm_rec_va_out => cbm_dlm_rec_va_i, -- out std_logic; - - -- to interface - dlm2send_va => cbm_dlm2send_va_i, -- out std_logic; - dlm2send => cbm_dlm2send_i -- out std_logic_vector(3 downto 0) - ); - - THE_CBMNET_READOUT: cbmnet_readout - port map( - -- TrbNet - CLK_IN => TRB_CLK_IN, -- in std_logic; - RESET_IN => TRB_RESET_IN, -- in std_logic; - - -- connect to hub - HUB_CTS_NUMBER_IN => HUB_CTS_NUMBER_IN, - HUB_CTS_CODE_IN => HUB_CTS_CODE_IN, - HUB_CTS_INFORMATION_IN => HUB_CTS_INFORMATION_IN, - HUB_CTS_READOUT_TYPE_IN => HUB_CTS_READOUT_TYPE_IN, - HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, - HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, - HUB_CTS_STATUS_BITS_OUT => HUB_CTS_STATUS_BITS_OUT, - HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, - HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, - HUB_FEE_READ_OUT => HUB_FEE_READ_OUT, - HUB_FEE_STATUS_BITS_IN => HUB_FEE_STATUS_BITS_IN, - HUB_FEE_BUSY_IN => HUB_FEE_BUSY_IN, - - -- connect to GbE - GBE_CTS_NUMBER_OUT => GBE_CTS_NUMBER_OUT, - GBE_CTS_CODE_OUT => GBE_CTS_CODE_OUT, - GBE_CTS_INFORMATION_OUT => GBE_CTS_INFORMATION_OUT, - GBE_CTS_READOUT_TYPE_OUT => GBE_CTS_READOUT_TYPE_OUT, - GBE_CTS_START_READOUT_OUT => GBE_CTS_START_READOUT_OUT, - GBE_CTS_READOUT_FINISHED_IN => GBE_CTS_READOUT_FINISHED_IN, - GBE_CTS_STATUS_BITS_IN => GBE_CTS_STATUS_BITS_IN, - GBE_FEE_DATA_OUT => GBE_FEE_DATA_OUT, - GBE_FEE_DATAREADY_OUT => GBE_FEE_DATAREADY_OUT, - GBE_FEE_READ_IN => GBE_FEE_READ_IN, - GBE_FEE_STATUS_BITS_OUT => GBE_FEE_STATUS_BITS_OUT, - GBE_FEE_BUSY_OUT => GBE_FEE_BUSY_OUT, - - -- reg io - REGIO_IN => rdo_regio_rx, - REGIO_OUT => rdo_regio_tx, - - -- CBMNet - CBMNET_CLK_IN => cbm_clk_i, -- in std_logic; - CBMNET_RESET_IN => cbm_reset_i, -- in std_logic; - CBMNET_LINK_ACTIVE_IN => cbm_link_active_i, -- in std_logic; - - CBMNET_DATA2SEND_STOP_IN => cbm_rdo_data2send_stop_i, -- in std_logic; - CBMNET_DATA2SEND_START_OUT => cbm_rdo_data2send_start_i, -- out std_logic; - CBMNET_DATA2SEND_END_OUT => cbm_rdo_data2send_end_i, -- out std_logic; - CBMNET_DATA2SEND_DATA_OUT => cbm_rdo_data2send_i -- out std_logic_vector(15 downto 0) - ); - - - THE_CBM_LINK_TESTER: link_tester_fe - generic map ( - MIN_PACKET_SIZE => 8, - MAX_PACKET_SIZE => 64, - PACKET_GRAN => 2, - MIN_CTRL_PACKET_SIZE => 12, - MAX_CTRL_PACKET_SIZE => 60, - - - CTRL_PADDING => 16#A5A5#, - OWN_ADDR => x"0000", - DEST_ADDR => "0000000000000000", - PACKET_MODE => 1 --if enabled generates another packet size order to test further corner cases - ) - port map ( - clk => cbm_clk_i , -- in std_logic; - res_n => cbm_reset_n_i, -- in std_logic; - link_active => cbm_link_active_i, -- in std_logic; - - data_en => cbm_lt_data_enable_crs_i, -- in std_logic; -- enable data packet generation - ctrl_en => cbm_lt_ctrl_enable_i, -- in std_logic; -- enable ctrl packet generation - force_rec_ctrl_stop => cbm_lt_force_stop_i, -- in std_logic; -- force ctrl flow to stop - - ctrl2send_stop => cbm_ctrl2send_stop_i, -- in std_logic; - ctrl2send_start => cbm_ctrl2send_start_i, -- out std_logic; - ctrl2send_end => cbm_ctrl2send_end_i, -- out std_logic; - ctrl2send => cbm_ctrl2send_i, -- out std_logic_vector(15 downto 0); - - data2send_stop => cbm_lt_data2send_stop_i, -- in std_logic; - data2send_start => cbm_lt_data2send_start_i, -- out std_logic; - data2send_end => cbm_lt_data2send_end_i, -- out std_logic; - data2send => cbm_lt_data2send_i, -- out std_logic_vector(15 downto 0); - - dlm2send_valid => open, -- out std_logic; - dlm2send => open, -- out std_logic_vector(3 downto 0); - - dlm_rec => cbm_dlm_rec_type_i, -- in std_logic_vector(3 downto 0); - dlm_rec_valid => cbm_dlm_rec_va_i, -- in std_logic; - - data_rec_start => '0', -- in std_logic; - data_rec_end => '0', -- in std_logic; - data_rec => x"0000", -- in std_logic_vector(15 downto 0); - data_rec_stop => open, -- out std_logic; - - ctrl_rec_start => '0', -- in std_logic; - ctrl_rec_end => '0', -- in std_logic; - ctrl_rec => x"0000", -- in std_logic_vector(15 downto 0); - ctrl_rec_stop => open, -- out std_logic; - - ctrl_valid => cbm_lt_ctrl_valid_i, -- out std_logic; - dlm_valid => cbm_lt_dlm_valid_i -- out std_logic - ); - - THE_SYNC_MODULE: cbmnet_sync_module port map ( - -- TRB - TRB_CLK_IN => TRB_CLK_IN, -- in std_logic; - TRB_RESET_IN => TRB_RESET_IN, -- in std_logic; - TRB_TRIGGER_OUT => TRB_TRIGGER_OUT, -- out std_logic; - - --data output for read-out - TRB_TRIGGER_IN => TRB_TRIGGER_IN, -- in std_logic - - TRB_RDO_VALID_DATA_TRG_IN => TRB_RDO_VALID_DATA_TRG_IN, - TRB_RDO_VALID_NO_TIMING_IN => TRB_RDO_VALID_NO_TIMING_IN, - TRB_RDO_DATA_OUT => TRB_RDO_DATA_OUT, -- out std_logic_vector(31 downto 0); - TRB_RDO_WRITE_OUT => TRB_RDO_WRITE_OUT, -- out std_logic; - TRB_RDO_FINISHED_OUT => TRB_RDO_FINISHED_OUT, -- out std_logic; - TRB_RDO_STATUSBIT_OUT => open, - - -- reg io - TRB_REGIO_IN => sync_regio_rx, - TRB_REGIO_OUT => sync_regio_tx, - - -- CBMNET - CBM_CLK_IN => cbm_clk_i, -- in std_logic; - CBM_CLK_250_IN => cbm_clk250_i, - CBM_RESET_IN => cbm_reset_i, -- in std_logic; - CBM_LINK_ACTIVE_IN => cbm_link_active_i, - CBM_PHY_BARREL_SHIFTER_POS_IN => x"0", -- in std_logic_vector(3 downto 0); - - CBM_TIMING_TRIGGER_OUT => CBM_TIMING_TRIGGER_OUT, - - -- DLM port - CBM_DLM_REC_IN => cbm_dlm_rec_type_i, -- in std_logic_vector(3 downto 0); - CBM_DLM_REC_VALID_IN => cbm_dlm_rec_va_i, -- in std_logic; - CBM_DLM_SENSE_OUT => CBM_DLM_OUT, -- out std_logic; - CBM_PULSER_OUT => CBM_SYNC_PULSER_OUT, -- out std_logic; -- connect to TDC - - -- Ctrl port - CBM_CTRL_DATA_IN => cbm_ctrl_rec_i, -- in std_logic_vector(15 downto 0); - CBM_CTRL_DATA_START_IN => cbm_ctrl_rec_start_i, -- in std_logic; - CBM_CTRL_DATA_END_IN => cbm_ctrl_rec_end_i, -- in std_logic; - CBM_CTRL_DATA_STOP_OUT => cbm_ctrl_rec_stop_i, -- out std_logic; - - - DEBUG_OUT => open -- out std_logic_vector(31 downto 0) - ); - - cbm_lt_data_enable_buf_i <= cbm_lt_data_enable_i when rising_edge(cbm_clk_i); - cbm_lt_data_enable_crs_i <= cbm_lt_data_enable_buf_i when rising_edge(cbm_clk_i); - - cbm_data_mux_buf_i <= cbm_data_mux_i when rising_edge(cbm_clk_i); - cbm_data_mux_crs_i <= cbm_data_mux_buf_i when rising_edge(cbm_clk_i); - - cbm_data2send_start_i <= cbm_lt_data2send_start_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_start_i; - cbm_data2send_end_i <= cbm_lt_data2send_end_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_end_i; - cbm_data2send_i <= cbm_lt_data2send_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_i; - cbm_lt_data2send_stop_i <= (not cbm_data_mux_crs_i) or cbm_data2send_stop_i; - cbm_rdo_data2send_stop_i <= cbm_data_mux_crs_i or cbm_data2send_stop_i; - - cbm_data_rec_stop_i <= '1'; - - THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record - generic map( - PORT_NUMBER => 3, - PORT_ADDRESSES => (0 => x"0000", 1 => x"0080", 2 => x"0100", others => x"0000"), - PORT_ADDR_MASK => (0 => 7, 1 => 7, 2 => 7, others => 0) - ) - port map( - CLK => TRB_CLK_IN, - RESET => TRB_RESET_IN, - - REGIO_RX => regio_masked_addr_i, - REGIO_TX => REGIO_OUT, - - BUS_RX(0) => rdo_regio_rx, - BUS_RX(1) => phy_regio_rx, - BUS_RX(2) => sync_regio_rx, - BUS_TX(0) => rdo_regio_tx, - BUS_TX(1) => phy_regio_tx, - BUS_TX(2) => sync_regio_tx, - - STAT_DEBUG => open - ); - regio_masked_addr_i <= CTRLBUS_MASK_ADDR(REGIO_IN, 9); +Library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use ieee.std_logic_unsigned.all; + +library work; + use work.trb_net_std.all; + use work.trb_net_components.all; + use work.trb3_components.all; + use work.trb_net16_hub_func.all; + use work.cbmnet_interface_pkg.all; + use work.cbmnet_phy_pkg.all; + +entity cbmnet_bridge is + port ( + -- clock and reset + CLK125_IN : in std_logic; + ASYNC_RESET_IN : in std_logic; + TRB_CLK_IN : in std_logic; + TRB_RESET_IN : in std_logic; + + CBM_CLK_OUT : out std_logic; + CBM_RESET_OUT: out std_logic; + + -- Media Interface + 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, '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 strobes + CBM_LINK_ACTIVE_OUT : out std_logic; + CBM_DLM_OUT : out std_logic; + CBM_TIMING_TRIGGER_OUT : out std_logic; + CBM_SYNC_PULSER_OUT : out std_logic; + + -- TRBNet Terminal + --data output for read-out + TRB_TRIGGER_IN : in std_logic; + TRB_RDO_VALID_DATA_TRG_IN : in std_logic; + TRB_RDO_VALID_NO_TIMING_IN : in std_logic; + TRB_RDO_DATA_OUT : out std_logic_vector(31 downto 0); + TRB_RDO_WRITE_OUT : out std_logic; + TRB_RDO_STATUSBIT_OUT: out std_logic_vector(31 downto 0); + TRB_RDO_FINISHED_OUT : out std_logic; + + TRB_TRIGGER_OUT : out std_logic; + + -- connect to hub + HUB_CTS_NUMBER_IN : in std_logic_vector (15 downto 0); + HUB_CTS_CODE_IN : in std_logic_vector (7 downto 0); + HUB_CTS_INFORMATION_IN : in std_logic_vector (7 downto 0); + HUB_CTS_READOUT_TYPE_IN : in std_logic_vector (3 downto 0); + HUB_CTS_START_READOUT_IN : in std_logic; + HUB_CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + HUB_CTS_STATUS_BITS_OUT : out std_logic_vector (31 downto 0); + HUB_FEE_DATA_IN : in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN : in std_logic; + HUB_FEE_READ_OUT : out std_logic; --must be high when idle, otherwise you will never get a dataready + HUB_FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + HUB_FEE_BUSY_IN : in std_logic; + + -- connect to GbE + GBE_CTS_NUMBER_OUT : out std_logic_vector (15 downto 0); + GBE_CTS_CODE_OUT : out std_logic_vector (7 downto 0); + GBE_CTS_INFORMATION_OUT : out std_logic_vector (7 downto 0); + GBE_CTS_READOUT_TYPE_OUT : out std_logic_vector (3 downto 0); + GBE_CTS_START_READOUT_OUT : out std_logic; + GBE_CTS_READOUT_FINISHED_IN : in std_logic; --no more data, end transfer, send TRM + GBE_CTS_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + GBE_FEE_DATA_OUT : out std_logic_vector (15 downto 0); + GBE_FEE_DATAREADY_OUT : out std_logic; + GBE_FEE_READ_IN : in std_logic; --must be high when idle, otherwise you will never get a dataready + GBE_FEE_STATUS_BITS_OUT : out std_logic_vector (31 downto 0); + GBE_FEE_BUSY_OUT : out std_logic; + + -- reg io + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); + REGIO_DATA_IN : in std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN : in std_logic; + REGIO_WRITE_ENABLE_IN : in std_logic; + REGIO_TIMEOUT_IN : in std_logic; + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); + REGIO_DATAREADY_OUT : out std_logic; + REGIO_WRITE_ACK_OUT : out std_logic; + REGIO_NO_MORE_DATA_OUT : out std_logic; + REGIO_UNKNOWN_ADDR_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture cbmnet_bridge_arch of cbmnet_bridge is + attribute syn_hier : string; + attribute syn_hier of cbmnet_bridge_arch : architecture is "hard"; + + +-- link port + signal cbm_clk_i : std_logic; + signal cbm_clk250_i : std_logic; + signal cbm_reset_i : std_logic; + signal cbm_reset_n_i : std_logic; + + signal cbm_ctrl2send_stop_i : std_logic := '0'; -- send control interface + signal cbm_ctrl2send_start_i : std_logic := '0'; + signal cbm_ctrl2send_end_i : std_logic := '0'; + signal cbm_ctrl2send_i : std_logic_vector(15 downto 0) := (others => '0'); + + signal cbm_data2send_stop_i : std_logic; -- send data interface + signal cbm_data2send_start_i : std_logic; + signal cbm_data2send_end_i : std_logic; + signal cbm_data2send_i : std_logic_vector(15 downto 0) := (others => '0'); + + signal cbm_dlm2send_va_i : std_logic := '0'; -- send dlm interface + signal cbm_dlm2send_i : std_logic_vector(3 downto 0) := (others => '0'); + + signal cbm_dlm_ref_rec_type_i: std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface + signal cbm_dlm_ref_rec_va_i : std_logic := '0'; + + signal cbm_dlm_rec_type_i : std_logic_vector(3 downto 0) := (others => '0'); -- receive dlm interface + signal cbm_dlm_rec_va_i : std_logic := '0'; + + signal cbm_data_rec_i : std_logic_vector(15 downto 0); -- receive data interface + signal cbm_data_rec_start_i : std_logic; + signal cbm_data_rec_end_i : std_logic; + signal cbm_data_rec_stop_i : std_logic := '1'; + + signal cbm_ctrl_rec_i : std_logic_vector(15 downto 0); -- receive control interface + signal cbm_ctrl_rec_start_i : std_logic; + signal cbm_ctrl_rec_end_i : std_logic; + signal cbm_ctrl_rec_stop_i : std_logic; + + signal cbm_data_from_link_i : std_logic_vector(17 downto 0); -- interface from the phy + signal cbm_data2link_i : std_logic_vector(17 downto 0); -- interface to the phy + + signal cbm_serdes_ready_i : std_logic; -- signalize when phy ready + signal cbm_link_active_i : std_logic; -- signalize when lp_top is ready + + signal cbm_crc_error_cntr_i : std_logic_vector(15 downto 0); + signal cbm_crc_error_cntr_clr_i : std_logic := '0'; + + signal cbm_phy_debug : std_logic_vector(511 downto 0); + signal cbm_stat_op_i : std_logic_vector(15 downto 0); + + +-- data port mux + signal cbm_data_mux_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester + signal cbm_data_mux_buf_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester + signal cbm_data_mux_crs_i : std_logic := '0'; -- 0: connected with readout, 1: connected with link tester + + signal cbm_lt_data_enable_buf_i : std_logic; + signal cbm_lt_data_enable_crs_i : std_logic; + + signal cbm_lt_data_enable_i : std_logic; + signal cbm_lt_ctrl_enable_i : std_logic; + signal cbm_lt_force_stop_i : std_logic; + signal cbm_lt_ctrl_valid_i : std_logic; + signal cbm_lt_dlm_valid_i : std_logic; + + signal cbm_lt_data2send_stop_i : std_logic; + signal cbm_lt_data2send_start_i : std_logic; + signal cbm_lt_data2send_end_i : std_logic; + signal cbm_lt_data2send_i : std_logic_vector(15 downto 0); + + signal cbm_rdo_data2send_stop_i : std_logic; + signal cbm_rdo_data2send_start_i : std_logic; + signal cbm_rdo_data2send_end_i : std_logic; + signal cbm_rdo_data2send_i : std_logic_vector(15 downto 0); + + signal cbm_data2send_buf_i : std_logic_vector(15 downto 0); + + signal cbm_phy_ctrl_i : std_logic_vector(31 downto 0); + +-- regio + signal regio_rx, rdo_regio_rx, phy_regio_rx, sync_regio_rx : CTRLBUS_RX; + signal regio_tx, rdo_regio_tx, phy_regio_tx, sync_regio_tx : CTRLBUS_TX := (nack => '0', unknown => '0', ack => '0', wack => '0', rack => '0', data => (others => '0')); + + signal cbm_serdes_ready_counter_i : std_logic_vector(31 downto 0) := (others => '0'); + signal trb_serdes_ready_counter_i : std_logic_vector(31 downto 0) := (others => '0'); + + signal cbm_serdes_ready_delay_i : std_logic; + + + signal cbm_test_line_mux_i : std_logic; + + signal trb_data_override_i : std_logic_vector(16 downto 0); + signal cbm_data_override_i : std_logic_vector(16 downto 0); + +begin + THE_CBM_PHY: cbmnet_phy_ecp3 + generic map ( + IS_SYNC_SLAVE => c_YES, + DETERMINISTIC_LATENCY => c_YES +-- INCL_DEBUG_AIDS => c_NO + ) + port map ( + CLK => CLK125_IN, + RESET => TRB_RESET_IN, + CLEAR => ASYNC_RESET_IN, + + --Internal Connection TX + PHY_TXDATA_IN => cbm_data2link_i(15 downto 0), + PHY_TXDATA_K_IN => cbm_data2link_i(17 downto 16), + + --Internal Connection RX + PHY_RXDATA_OUT => cbm_data_from_link_i(15 downto 0), + PHY_RXDATA_K_OUT => cbm_data_from_link_i(17 downto 16), + + CLK_RX_HALF_OUT => cbm_clk_i, + CLK_RX_FULL_OUT => cbm_clk250_i, + CLK_RX_RESET_OUT => cbm_reset_i, + + SERDES_ready => cbm_serdes_ready_i, + + --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 => SD_PRSNT_N_IN, + SD_LOS_IN => SD_LOS_IN, + SD_TXDIS_OUT => SD_TXDIS_OUT, + + LED_RX_OUT => LED_RX_OUT, + LED_TX_OUT => LED_TX_OUT, + LED_OK_OUT => LED_OK_OUT, + + -- Status and control port + STAT_OP => cbm_stat_op_i, + CTRL_OP => cbm_phy_ctrl_i(15 downto 0), + DEBUG_OUT => cbm_phy_debug + ); + CBM_CLK_OUT <= cbm_clk_i; + CBM_RESET_OUT <= cbm_reset_i; + + proc_debug_regio: process is + variable addr : integer range 0 to 31; + begin + wait until rising_edge(TRB_CLK_IN); + addr := to_integer(unsigned(phy_regio_rx.addr(4 downto 0))); + + phy_regio_tx.rack <= phy_regio_rx.read; + phy_regio_tx.unknown <= '0'; + phy_regio_tx.wack <= '0'; + + phy_regio_tx.data <= (others => '0'); + + if addr < 16 then + phy_regio_tx.data <= cbm_phy_debug(addr*32+31 downto addr*32); + + elsif addr = 16 then + phy_regio_tx.data(11 downto 8) <= "0" & cbm_data2send_stop_i & cbm_serdes_ready_i & cbm_link_active_i; + phy_regio_tx.data(7 downto 4) <= "00" & cbm_lt_dlm_valid_i & cbm_lt_ctrl_valid_i; + phy_regio_tx.data(3 downto 0) <= cbm_data_mux_i & cbm_lt_data_enable_i & cbm_lt_ctrl_enable_i & cbm_lt_force_stop_i; + phy_regio_tx.data(16) <= cbm_test_line_mux_i; + + if phy_regio_rx.write='1' then + cbm_data_mux_i <= phy_regio_rx.data(3); + cbm_lt_data_enable_i <= phy_regio_rx.data(2); + cbm_lt_ctrl_enable_i <= phy_regio_rx.data(1); + cbm_lt_force_stop_i <= phy_regio_rx.data(0); + + cbm_test_line_mux_i <= phy_regio_rx.data(16); + + phy_regio_tx.wack <= '1'; + end if; + + elsif addr = 17 then + phy_regio_tx.data <= std_logic_vector(trb_serdes_ready_counter_i); + + elsif addr = 18 then + phy_regio_tx.data(16 downto 0) <=trb_data_override_i; + if phy_regio_rx.write='1' then + trb_data_override_i <= phy_regio_rx.data(16 downto 0); + phy_regio_tx.wack <= '1'; + end if; + + elsif addr = 19 then + phy_regio_tx.data <= cbm_phy_ctrl_i; + if phy_regio_rx.write='1' then + cbm_phy_ctrl_i <= phy_regio_rx.data; + phy_regio_tx.wack <= '1'; + end if; + + else + phy_regio_tx.unknown <= phy_regio_rx.write or phy_regio_rx.read; + + end if; + + if TRB_RESET_IN='1' then + cbm_lt_data_enable_i <= '0'; + cbm_lt_ctrl_enable_i <= '0'; + cbm_lt_force_stop_i <= '1'; + cbm_data_mux_i <= '0'; + cbm_test_line_mux_i <= '0'; + trb_data_override_i <= (others => '0'); + end if; + end process; + phy_regio_tx.nack <= '0'; + phy_regio_tx.ack <= phy_regio_tx.rack or phy_regio_tx.wack; -- make synplify shut up ;) + + THE_CBM_ENDPOINT: cn_lp_top + port map ( + -- Clk & Reset + clk => cbm_clk_i, + res_n => cbm_reset_n_i, + + -- Phy + data_from_link => cbm_data_from_link_i, + data2link => cbm_data2link_i, + serdes_ready => cbm_serdes_ready_i, + + -- CBMNet Interface + link_active => cbm_link_active_i, + ctrl2send_stop => cbm_ctrl2send_stop_i, + ctrl2send_start => cbm_ctrl2send_start_i, + ctrl2send_end => cbm_ctrl2send_end_i, + ctrl2send => cbm_ctrl2send_i, + + data2send_stop => cbm_data2send_stop_i, + data2send_start => cbm_data2send_start_i, + data2send_end => cbm_data2send_end_i, + data2send => cbm_data2send_buf_i, + + dlm2send_va => cbm_dlm2send_va_i, + dlm2send => cbm_dlm2send_i, + + dlm_rec => cbm_dlm_ref_rec_type_i, + dlm_rec_va => cbm_dlm_ref_rec_va_i, + + data_rec => cbm_data_rec_i, + data_rec_start => cbm_data_rec_start_i, + data_rec_end => cbm_data_rec_end_i, + data_rec_stop => cbm_data_rec_stop_i, + + ctrl_rec => cbm_ctrl_rec_i, + ctrl_rec_start => cbm_ctrl_rec_start_i, + ctrl_rec_end => cbm_ctrl_rec_end_i, + ctrl_rec_stop => cbm_ctrl_rec_stop_i, + + crc_error_cntr_flag => open, + crc_error_cntr => cbm_crc_error_cntr_i, + crc_error_cntr_clr => cbm_crc_error_cntr_clr_i + + ); + cbm_reset_n_i <= not cbm_reset_i when rising_edge(cbm_clk_i); + CBM_LINK_ACTIVE_OUT <= cbm_link_active_i; + + THE_DLM_REFLECT: dlm_reflect + port map ( + clk => cbm_clk_i, -- in std_logic; + res_n => cbm_reset_n_i, -- in std_logic; + + -- from interface + dlm_rec_in => cbm_dlm_ref_rec_type_i, -- in std_logic_vector(3 downto 0); + dlm_rec_va_in => cbm_dlm_ref_rec_va_i, -- in std_logic; + + -- to application logic + dlm_rec_out => cbm_dlm_rec_type_i, -- out std_logic_vector(3 downto 0); + dlm_rec_va_out => cbm_dlm_rec_va_i, -- out std_logic; + + -- to interface + dlm2send_va => cbm_dlm2send_va_i, -- out std_logic; + dlm2send => cbm_dlm2send_i -- out std_logic_vector(3 downto 0) + ); + + THE_CBMNET_READOUT: cbmnet_readout + port map( + -- TrbNet + CLK_IN => TRB_CLK_IN, -- in std_logic; + RESET_IN => TRB_RESET_IN, -- in std_logic; + + -- connect to hub + HUB_CTS_NUMBER_IN => HUB_CTS_NUMBER_IN, + HUB_CTS_CODE_IN => HUB_CTS_CODE_IN, + HUB_CTS_INFORMATION_IN => HUB_CTS_INFORMATION_IN, + HUB_CTS_READOUT_TYPE_IN => HUB_CTS_READOUT_TYPE_IN, + HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, + HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, + HUB_CTS_STATUS_BITS_OUT => HUB_CTS_STATUS_BITS_OUT, + HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, + HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, + HUB_FEE_READ_OUT => HUB_FEE_READ_OUT, + HUB_FEE_STATUS_BITS_IN => HUB_FEE_STATUS_BITS_IN, + HUB_FEE_BUSY_IN => HUB_FEE_BUSY_IN, + + -- connect to GbE + GBE_CTS_NUMBER_OUT => GBE_CTS_NUMBER_OUT, + GBE_CTS_CODE_OUT => GBE_CTS_CODE_OUT, + GBE_CTS_INFORMATION_OUT => GBE_CTS_INFORMATION_OUT, + GBE_CTS_READOUT_TYPE_OUT => GBE_CTS_READOUT_TYPE_OUT, + GBE_CTS_START_READOUT_OUT => GBE_CTS_START_READOUT_OUT, + GBE_CTS_READOUT_FINISHED_IN => GBE_CTS_READOUT_FINISHED_IN, + GBE_CTS_STATUS_BITS_IN => GBE_CTS_STATUS_BITS_IN, + GBE_FEE_DATA_OUT => GBE_FEE_DATA_OUT, + GBE_FEE_DATAREADY_OUT => GBE_FEE_DATAREADY_OUT, + GBE_FEE_READ_IN => GBE_FEE_READ_IN, + GBE_FEE_STATUS_BITS_OUT => GBE_FEE_STATUS_BITS_OUT, + GBE_FEE_BUSY_OUT => GBE_FEE_BUSY_OUT, + + -- reg io + REGIO_IN => rdo_regio_rx, + REGIO_OUT => rdo_regio_tx, + + -- CBMNet + CBMNET_CLK_IN => cbm_clk_i, -- in std_logic; + CBMNET_RESET_IN => cbm_reset_i, -- in std_logic; + CBMNET_LINK_ACTIVE_IN => cbm_link_active_i, -- in std_logic; + + CBMNET_DATA2SEND_STOP_IN => cbm_rdo_data2send_stop_i, -- in std_logic; + CBMNET_DATA2SEND_START_OUT => cbm_rdo_data2send_start_i, -- out std_logic; + CBMNET_DATA2SEND_END_OUT => cbm_rdo_data2send_end_i, -- out std_logic; + CBMNET_DATA2SEND_DATA_OUT => cbm_rdo_data2send_i -- out std_logic_vector(15 downto 0) + ); + + + THE_CBM_LINK_TESTER: link_tester_fe + generic map ( + MIN_PACKET_SIZE => 8, + MAX_PACKET_SIZE => 64, + PACKET_GRAN => 2, + MIN_CTRL_PACKET_SIZE => 12, + MAX_CTRL_PACKET_SIZE => 60, + + + CTRL_PADDING => 16#A5A5#, + OWN_ADDR => x"0000", + DEST_ADDR => "0000000000000000", + PACKET_MODE => 1 --if enabled generates another packet size order to test further corner cases + ) + port map ( + clk => cbm_clk_i , -- in std_logic; + res_n => cbm_reset_n_i, -- in std_logic; + link_active => cbm_link_active_i, -- in std_logic; + + data_en => cbm_lt_data_enable_crs_i, -- in std_logic; -- enable data packet generation + ctrl_en => cbm_lt_ctrl_enable_i, -- in std_logic; -- enable ctrl packet generation + force_rec_ctrl_stop => cbm_lt_force_stop_i, -- in std_logic; -- force ctrl flow to stop + + ctrl2send_stop => cbm_ctrl2send_stop_i, -- in std_logic; + ctrl2send_start => cbm_ctrl2send_start_i, -- out std_logic; + ctrl2send_end => cbm_ctrl2send_end_i, -- out std_logic; + ctrl2send => cbm_ctrl2send_i, -- out std_logic_vector(15 downto 0); + + data2send_stop => cbm_lt_data2send_stop_i, -- in std_logic; + data2send_start => cbm_lt_data2send_start_i, -- out std_logic; + data2send_end => cbm_lt_data2send_end_i, -- out std_logic; + data2send => cbm_lt_data2send_i, -- out std_logic_vector(15 downto 0); + + dlm2send_valid => open, -- out std_logic; + dlm2send => open, -- out std_logic_vector(3 downto 0); + + dlm_rec => cbm_dlm_rec_type_i, -- in std_logic_vector(3 downto 0); + dlm_rec_valid => cbm_dlm_rec_va_i, -- in std_logic; + + data_rec_start => '0', -- in std_logic; + data_rec_end => '0', -- in std_logic; + data_rec => x"0000", -- in std_logic_vector(15 downto 0); + data_rec_stop => open, -- out std_logic; + + ctrl_rec_start => '0', -- in std_logic; + ctrl_rec_end => '0', -- in std_logic; + ctrl_rec => x"0000", -- in std_logic_vector(15 downto 0); + ctrl_rec_stop => open, -- out std_logic; + + ctrl_valid => cbm_lt_ctrl_valid_i, -- out std_logic; + dlm_valid => cbm_lt_dlm_valid_i -- out std_logic + ); + + THE_SYNC_MODULE: cbmnet_sync_module port map ( + -- TRB + TRB_CLK_IN => TRB_CLK_IN, -- in std_logic; + TRB_RESET_IN => TRB_RESET_IN, -- in std_logic; + TRB_TRIGGER_OUT => TRB_TRIGGER_OUT, -- out std_logic; + + --data output for read-out + TRB_TRIGGER_IN => TRB_TRIGGER_IN, -- in std_logic + + TRB_RDO_VALID_DATA_TRG_IN => TRB_RDO_VALID_DATA_TRG_IN, + TRB_RDO_VALID_NO_TIMING_IN => TRB_RDO_VALID_NO_TIMING_IN, + TRB_RDO_DATA_OUT => TRB_RDO_DATA_OUT, -- out std_logic_vector(31 downto 0); + TRB_RDO_WRITE_OUT => TRB_RDO_WRITE_OUT, -- out std_logic; + TRB_RDO_FINISHED_OUT => TRB_RDO_FINISHED_OUT, -- out std_logic; + TRB_RDO_STATUSBIT_OUT => TRB_RDO_STATUSBIT_OUT, + + -- reg io + TRB_REGIO_IN => sync_regio_rx, + TRB_REGIO_OUT => sync_regio_tx, + + -- CBMNET + CBM_CLK_IN => cbm_clk_i, -- in std_logic; + CBM_CLK_250_IN => cbm_clk250_i, + CBM_RESET_IN => cbm_reset_i, -- in std_logic; + CBM_LINK_ACTIVE_IN => cbm_link_active_i, + CBM_PHY_BARREL_SHIFTER_POS_IN => x"0", -- in std_logic_vector(3 downto 0); + + CBM_TIMING_TRIGGER_OUT => CBM_TIMING_TRIGGER_OUT, + + -- DLM port + CBM_DLM_REC_IN => cbm_dlm_rec_type_i, -- in std_logic_vector(3 downto 0); + CBM_DLM_REC_VALID_IN => cbm_dlm_rec_va_i, -- in std_logic; + CBM_DLM_SENSE_OUT => CBM_DLM_OUT, -- out std_logic; + CBM_PULSER_OUT => CBM_SYNC_PULSER_OUT, -- out std_logic; -- connect to TDC + + -- Ctrl port + CBM_CTRL_DATA_IN => cbm_ctrl_rec_i, -- in std_logic_vector(15 downto 0); + CBM_CTRL_DATA_START_IN => cbm_ctrl_rec_start_i, -- in std_logic; + CBM_CTRL_DATA_END_IN => cbm_ctrl_rec_end_i, -- in std_logic; + CBM_CTRL_DATA_STOP_OUT => cbm_ctrl_rec_stop_i, -- out std_logic; + + + DEBUG_OUT => open -- out std_logic_vector(31 downto 0) + ); + +-- Data2Send Mux for RDO / LinkTester + cbm_lt_data_enable_buf_i <= cbm_lt_data_enable_i when rising_edge(cbm_clk_i); + cbm_lt_data_enable_crs_i <= cbm_lt_data_enable_buf_i when rising_edge(cbm_clk_i); + + cbm_data_mux_buf_i <= cbm_data_mux_i when rising_edge(cbm_clk_i); + cbm_data_mux_crs_i <= cbm_data_mux_buf_i when rising_edge(cbm_clk_i); + + cbm_data2send_start_i <= cbm_lt_data2send_start_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_start_i; + cbm_data2send_end_i <= cbm_lt_data2send_end_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_end_i; + cbm_data2send_i <= cbm_lt_data2send_i when cbm_data_mux_crs_i = '1' else cbm_rdo_data2send_i; + cbm_lt_data2send_stop_i <= (not cbm_data_mux_crs_i) or cbm_data2send_stop_i; + cbm_rdo_data2send_stop_i <= cbm_data_mux_crs_i or cbm_data2send_stop_i; + + cbm_data_rec_stop_i <= '1'; + + THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record + generic map( + PORT_NUMBER => 3, + PORT_ADDRESSES => (0 => x"0000", 1 => x"0080", 2 => x"0100", others => x"0000"), + PORT_ADDR_MASK => (0 => 7, 1 => 7, 2 => 7, others => 0) + ) + port map( + CLK => TRB_CLK_IN, + RESET => TRB_RESET_IN, + + REGIO_RX => regio_rx, + REGIO_TX => regio_tx, + + BUS_RX(0) => rdo_regio_rx, + BUS_RX(1) => phy_regio_rx, + BUS_RX(2) => sync_regio_rx, + BUS_TX(0) => rdo_regio_tx, + BUS_TX(1) => phy_regio_tx, + BUS_TX(2) => sync_regio_tx, + + STAT_DEBUG => open + ); + regio_rx <= ( + addr => "0000000" & REGIO_ADDR_IN(8 downto 0), + data => REGIO_DATA_IN, + read => REGIO_READ_ENABLE_IN, + write => REGIO_WRITE_ENABLE_IN, + timeout => REGIO_TIMEOUT_IN); + + +-- Statistics + proc_serdes_counter: process is + begin + wait until rising_edge(cbm_clk_i); + cbm_serdes_ready_delay_i <= cbm_serdes_ready_i; + if cbm_serdes_ready_delay_i = '0' and cbm_serdes_ready_i = '1' then + cbm_serdes_ready_counter_i <= std_logic_vector(unsigned(cbm_serdes_ready_counter_i) + to_unsigned(1,1)); + end if; + end process; + -- not realy necessary, as it's not updated that often, but let's trce shut up w/o add constraints ;) + THE_SERDES_COUNTER_SYNC: signal_sync + generic map (WIDTH => 32, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => cbm_clk_i, + CLK1 => TRB_CLK_IN, + D_IN => cbm_serdes_ready_counter_i, + D_OUT => trb_serdes_ready_counter_i + ); + +-- Debug + -- Data Override + cbm_data2send_buf_i <= cbm_data2send_i when cbm_data_override_i(16) = '0' else cbm_data_override_i(15 downto 0); + THE_OVERRIDE_SYNC: signal_sync + generic map (WIDTH => 17, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => TRB_CLK_IN, + CLK1 => cbm_clk_i, + D_IN => trb_data_override_i, + D_OUT => cbm_data_override_i + ); + + + PROC_TEST_LINE: process is + variable pattern : std_logic_vector(31 downto 0) := (0 => '1', others => '0'); + begin + wait until rising_edge(cbm_clk_i); + if trb_reset_in='1' then + pattern := (0 => '1', others => '0'); + else + pattern := pattern(0) & pattern(31 downto 1); + end if; + + if cbm_test_line_mux_i = '1' then + DEBUG_OUT <= pattern; + else + DEBUG_OUT <= (others => '0'); +-- DEBUG_OUT(4 downto 0) <= cbm_serdes_ready_i & & cbm_data2send_stop_i & cbm_data2send_start_i & cbm_data2send_end_i; + DEBUG_OUT(15 downto 0) <=cbm_link_active_i & cbm_stat_op_i(14 downto 0); + end if; + end process; + + REGIO_DATA_OUT <= regio_tx.data; + REGIO_DATAREADY_OUT <= regio_tx.ack; + REGIO_WRITE_ACK_OUT <= regio_tx.ack; + REGIO_NO_MORE_DATA_OUT <= regio_tx.nack; + REGIO_UNKNOWN_ADDR_OUT <= regio_tx.unknown; end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_interface_pkg.vhd b/cbmnet/code/cbmnet_interface_pkg.vhd index 0062f46..b7fb336 100644 --- a/cbmnet/code/cbmnet_interface_pkg.vhd +++ b/cbmnet/code/cbmnet_interface_pkg.vhd @@ -80,8 +80,19 @@ package cbmnet_interface_pkg is GBE_FEE_BUSY_OUT : out std_logic; -- reg io - REGIO_IN : in CTRLBUS_RX; - REGIO_OUT : out CTRLBUS_TX + -- reg io + REGIO_ADDR_IN : in std_logic_vector(15 downto 0); + REGIO_DATA_IN : in std_logic_vector(31 downto 0); + REGIO_READ_ENABLE_IN : in std_logic; + REGIO_WRITE_ENABLE_IN : in std_logic; + REGIO_TIMEOUT_IN : in std_logic; + REGIO_DATA_OUT : out std_logic_vector(31 downto 0); + REGIO_DATAREADY_OUT : out std_logic; + REGIO_WRITE_ACK_OUT : out std_logic; + REGIO_NO_MORE_DATA_OUT : out std_logic; + REGIO_UNKNOWN_ADDR_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) ); end component; @@ -161,6 +172,7 @@ package cbmnet_interface_pkg is bs_position : out std_logic_vector(4 downto 0); -- Number of bit-shifts necessary for word-alignment rxdata_out : out std_logic_vector(17 downto 0); ebtb_detect : out std_logic; -- Depends on the FSM state, alignment done + wait_for_ready1 : out std_logic; --diagnostics ebtb_code_err_cntr_clr : in std_logic; @@ -195,9 +207,11 @@ package cbmnet_interface_pkg is pma_ready : in std_logic; ebtb_detect : in std_logic; -- alignment done and valid 8b10b stream detected see_reinit : in std_logic; + rx_wait_for_ready1 : in std_logic; rxpcs_almost_ready : in std_logic; txdata_in : in std_logic_vector(17 downto 0); + rx_bitdelay_done : in std_logic; txpcs_ready : out std_logic; @@ -249,6 +263,10 @@ package cbmnet_interface_pkg is dlm_rec : out std_logic_vector(3 downto 0); --receive dlm interface dlm_rec_va : out std_logic; + crc_error_cntr_flag : out std_logic; + crc_error_cntr : out std_logic_vector(15 downto 0); + crc_error_cntr_clr : in std_logic; + -- link signals data_from_link : in std_logic_vector(17 downto 0); -- interface from the PHY data2link : out std_logic_vector(17 downto 0) -- interface to the PHY diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index 090d929..d0a1c66 100755 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -67,6 +67,8 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is constant WA_FIXATION : integer := c_YES; signal DETERMINISTIC_LATENCY_C : std_logic; + + constant USE_OWN_EBTB_C : std_logic := '1'; -- Clocks and global resets signal clk_125_local : std_logic; -- local 125 MHz reference clock driven by clock generators @@ -76,8 +78,8 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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 + signal rst_n_async_i : std_logic; -- reset for reset-fsms + signal rst_n_i : std_logic; -- synchronised to clk_local -- SERDES/PCS -- status @@ -159,6 +161,7 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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_data_coded_i : std_logic_vector(19 downto 0); signal tx_gear_reset_i : std_logic; signal tx_gear_allow_relock_i : std_logic; @@ -168,38 +171,24 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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 rx_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 @@ -209,8 +198,6 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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); @@ -239,6 +226,8 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal dlm_counter_i : unsigned(15 downto 0) := x"0000"; signal detect_dlm_125_i, detect_dlm_250_i : std_logic := '0'; + signal rm_rx_wait_for_ready1_i : std_logic; + --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); @@ -256,9 +245,16 @@ begin SD_TXDIS_OUT <= '0'; - rst_i <= (CLEAR or CTRL_OP(0)); - rst_n_i <= not rst_i; - + ------- RESET + rst_n_async_i <= not (CLEAR or CTRL_OP(0)); + THE_RST_SYNC: entity work.state_sync + port map ( + STATE_A_IN => rst_n_async_i, + RESET_B_IN => '0', + CLK_B_IN => clk_125_local, + STATE_B_OUT=> rst_n_i + ); + ------------------------------------------------- -- Serdes ------------------------------------------------- @@ -298,12 +294,6 @@ begin tx_force_disp_ch0 => '0', tx_disp_sel_ch0 => '0', --- txdata_ch0 => tx_data_i(15 downto 0), --- tx_k_ch0 => tx_data_i(17 downto 16), --- tx_force_disp_ch0 => "00", --- tx_disp_sel_ch0 => "00", - - tx_div2_mode_ch0_c => '0', -- RX DATA PORT @@ -351,7 +341,7 @@ begin DEBUG_OUT => rx_gear_debug_i ); - rx_gear_reset_i <= rm_rx_to_gear_reset_i or rm_rx_see_reinit when rising_edge(rclk_125_i); + rx_gear_reset_i <= rm_rx_to_gear_reset_i or (rm_rx_see_reinit and CTRL_OP(8)) when rising_edge(rclk_125_i); THE_TX_GEAR: CBMNET_PHY_TX_GEAR generic map (IS_SYNC_SLAVE => IS_SYNC_SLAVE) @@ -368,7 +358,7 @@ begin DEBUG_OUT => tx_gear_debug_i ); - tx_gear_reset_i <= not tx_rst_fsm_ready_i or gear_to_rm_rst_i; + tx_gear_reset_i <= (not tx_rst_fsm_ready_i) or gear_to_rm_rst_i; tx_serdes_rst_i <= '0'; --no function serdes_rst_qd_i <= '0'; --included in rst_qd_i @@ -489,6 +479,7 @@ begin 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 + wait_for_ready1 => rm_rx_wait_for_ready1_i, --diagnostics ebtb_code_err_cntr_clr => '0', -- in std_logic; @@ -511,7 +502,8 @@ begin SYNC_SIGNALS => 1, --integer range 0 to 1 := 1; INCL_8B10B_ENC => 0 --integer range 0 to 1 := 1 - ) port map ( + ) + 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 @@ -521,25 +513,23 @@ begin 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, - - rx_bitdelay_done => '1', --in std_logic; + rx_wait_for_ready1 => rm_rx_wait_for_ready1_i, + rx_bitdelay_done => '1', --in std_logic; 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 + txdata_out_coded => tx_data_coded_i, --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; + pcs_startup_cntr_clr => '0', --in std_logic; + pcs_startup_cntr => open, --out std_logic_vector(15 downto 0); -- Counts for link startups + pcs_startup_cntr_flag => open --out std_logic; ); - - rm_rx_status_for_tx_i <= rm_rx_almost_ready_i or rm_rx_ready_i; - tx_rst_fsm_ready_buf_i <= tx_rst_fsm_ready_i and not gear_to_rm_rst_i when rising_edge(rclk_125_i); + tx_rst_fsm_ready_buf_i <= rx_rst_fsm_ready_i and tx_rst_fsm_ready_i and not gear_to_rm_rst_i when rising_edge(rclk_125_i); 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; @@ -684,7 +674,7 @@ begin 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( 63 downto 60) <= serdes_ready_i & "0" & rm_tx_ready_i & "0"; DEBUG_OUT( 95 downto 64) <= rx_gear_debug_i(15 downto 0) & tx_gear_debug_i(15 downto 0); @@ -692,18 +682,14 @@ begin 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(123 downto 108) <= std_logic_vector(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(139 downto 124) <= std_logic_vector(rx_stab_i(15 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(211 downto 196) <= std_logic_vector(stat_dlm_counter_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(331 downto 316) <= dlm_counter_i(15 downto 0); + DEBUG_OUT(331 downto 316) <= std_logic_vector(dlm_counter_i(15 downto 0)); DEBUG_OUT(403 downto 332) <= tx_data_sp_i3(17 downto 0) & tx_data_sp_i2(17 downto 0) & tx_data_sp_i1(17 downto 0) & tx_data_sp_i0(17 downto 0); @@ -743,4 +729,10 @@ begin end if; end process; end generate; + + STAT_OP <= + "0" & tx_gear_debug_i(17 downto 16) & rx_cdr_lol_i + & rm_rx_almost_ready_i & rm_rx_rxpcs_ready_i & rm_rx_see_reinit & rm_rx_ebtb_detect_i + & rst_qd_i & rx_serdes_rst_i & tx_pcs_rst_i & rx_pcs_rst_i + & serdes_ready_i & "0" & rm_tx_ready_i & "0"; end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd index de4ffc9..08baeee 100644 --- a/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3_rx_reset_fsm.vhd @@ -107,80 +107,75 @@ begin end process; - proc_fsm_trans: process(cs, tx_pll_lol_qd_s_int, rx_los_low_int, rx_lol_los_int, timer2, proper_word_align_i, proper_byte_align_i, rx_lol_los_int, rm_reset_i) + proc_fsm_trans: process(cs, tx_pll_lol_qd_s_int, rx_los_low_int, rx_lol_los_int, rx_lol_los_del, + timer2, proper_word_align_i, proper_byte_align_i, rx_lol_los_int, rm_reset_i) begin - -- reset_timer1 <= '0'; - reset_timer2 <= '0'; - STATE_OUT <= x"F"; - case cs is - when WAIT_FOR_PLOL => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - if (tx_pll_lol_qd_s_int = '1' or rx_los_low_int = '1') then --Also make sure A Signal - ns <= WAIT_FOR_PLOL; --is Present prior to moving to the next - else - ns <= RX_SERDES_RESET; - end if; - STATE_OUT <= x"1"; - - when RX_SERDES_RESET => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '1'; - -- reset_timer1 <= '1'; - ns <= WAIT_FOR_timer1; - STATE_OUT <= x"2"; - - - when WAIT_FOR_timer1 => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '1'; - ns <= CHECK_LOL_LOS; - STATE_OUT <= x"3"; + reset_timer2 <= '0'; + STATE_OUT <= x"F"; + case cs is + when WAIT_FOR_PLOL => + rx_pcs_rst_ch_c_int <= '1'; + rx_serdes_rst_ch_c_int <= '0'; + if (tx_pll_lol_qd_s_int = '1' or rx_los_low_int = '1') then --Also make sure A Signal + ns <= WAIT_FOR_PLOL; --is Present prior to moving to the next + else + ns <= RX_SERDES_RESET; + end if; + STATE_OUT <= x"1"; + + when RX_SERDES_RESET => + rx_pcs_rst_ch_c_int <= '1'; + rx_serdes_rst_ch_c_int <= '1'; + ns <= WAIT_FOR_timer1; + STATE_OUT <= x"2"; + + + when WAIT_FOR_timer1 => + rx_pcs_rst_ch_c_int <= '1'; + rx_serdes_rst_ch_c_int <= '1'; + ns <= CHECK_LOL_LOS; + STATE_OUT <= x"3"; - when CHECK_LOL_LOS => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - reset_timer2 <= '1'; - ns <= WAIT_FOR_timer2; - STATE_OUT <= x"4"; + when CHECK_LOL_LOS => + rx_pcs_rst_ch_c_int <= '1'; + rx_serdes_rst_ch_c_int <= '0'; + reset_timer2 <= '1'; + ns <= WAIT_FOR_timer2; + STATE_OUT <= x"4"; - when WAIT_FOR_timer2 => - rx_pcs_rst_ch_c_int <= '1'; - rx_serdes_rst_ch_c_int <= '0'; - if rx_lol_los_int = rx_lol_los_del then --NO RISING OR FALLING EDGES - if timer2 = '1' then - if rx_lol_los_int = '1' then - ns <= WAIT_FOR_PLOL; - -- elsif proper_byte_align_i = '0' or proper_word_align_i = '0' then - -- ns <= CHECK_LOL_LOS; + when WAIT_FOR_timer2 => + rx_pcs_rst_ch_c_int <= '1'; + rx_serdes_rst_ch_c_int <= '0'; + if rx_lol_los_int = rx_lol_los_del then --NO RISING OR FALLING EDGES + if timer2 = '1' then + if rx_lol_los_int = '1' then + ns <= WAIT_FOR_PLOL; + else + ns <= NORMAL; + end if; else - ns <= NORMAL; + ns <= WAIT_FOR_timer2; end if; - -- elsif rx_lol_los_int = '0' then - -- ns <= NORMAL; else - ns <= WAIT_FOR_timer2; + ns <= CHECK_LOL_LOS; --RESET timer2 end if; - else - ns <= CHECK_LOL_LOS; --RESET timer2 - end if; - STATE_OUT <= x"5"; + STATE_OUT <= x"5"; - - when NORMAL => - rx_pcs_rst_ch_c_int <= '0'; - rx_serdes_rst_ch_c_int <= '0'; - if rx_lol_los_int = '1' or proper_byte_align_i = '0' or proper_word_align_i = '0' or rm_reset_i = '1' then + + when NORMAL => + rx_pcs_rst_ch_c_int <= '0'; + rx_serdes_rst_ch_c_int <= '0'; + if rx_lol_los_int = '1' or proper_byte_align_i = '0' or proper_word_align_i = '0' or rm_reset_i = '1' then + ns <= WAIT_FOR_PLOL; + else + ns <= NORMAL; + end if; + STATE_OUT <= x"6"; + + when others => ns <= WAIT_FOR_PLOL; - else - ns <= NORMAL; - end if; - STATE_OUT <= x"6"; - - when others => - ns <= WAIT_FOR_PLOL; - end case; + end case; end process; end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd b/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd index 2245a9b..8d33779 100644 --- a/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3_tx_reset_fsm.vhd @@ -109,66 +109,63 @@ end process; process(cs, TIMER1, TIMER2, tx_pll_lol_qd_s_int) begin - - reset_timer1 <= '0'; - reset_timer2 <= '0'; - STATE_OUT <= x"F"; - - case cs is - - when QUAD_RESET => - STATE_OUT <= x"1"; - tx_pcs_rst_ch_c_int <= '1'; - RST_QD_C_int <= '1'; - reset_timer1 <= '1'; - ns <= WAIT_FOR_TIMER1; - - when WAIT_FOR_TIMER1 => - STATE_OUT <= x"2"; - tx_pcs_rst_ch_c_int <= '1'; - RST_QD_C_int <= '1'; - if TIMER1 = '1' then - ns <= CHECK_PLOL; - else - ns <= WAIT_FOR_TIMER1; - end if; - - when CHECK_PLOL => - STATE_OUT <= x"3"; - tx_pcs_rst_ch_c_int <= '1'; - RST_QD_C_int <= '0'; - reset_timer2 <= '1'; - ns <= WAIT_FOR_TIMER2; - - when WAIT_FOR_TIMER2 => - STATE_OUT <= x"4"; - tx_pcs_rst_ch_c_int <= '1'; - RST_QD_C_int <= '0'; - if TIMER2 = '1' then - if tx_pll_lol_qd_s_int = '1' then + reset_timer1 <= '0'; + reset_timer2 <= '0'; + STATE_OUT <= x"F"; + + case cs is + when QUAD_RESET => + STATE_OUT <= x"1"; + tx_pcs_rst_ch_c_int <= '1'; + RST_QD_C_int <= '1'; + reset_timer1 <= '1'; + ns <= WAIT_FOR_TIMER1; + + when WAIT_FOR_TIMER1 => + STATE_OUT <= x"2"; + tx_pcs_rst_ch_c_int <= '1'; + RST_QD_C_int <= '1'; + if TIMER1 = '1' then + ns <= CHECK_PLOL; + else + ns <= WAIT_FOR_TIMER1; + end if; + + when CHECK_PLOL => + STATE_OUT <= x"3"; + tx_pcs_rst_ch_c_int <= '1'; + RST_QD_C_int <= '0'; + reset_timer2 <= '1'; + ns <= WAIT_FOR_TIMER2; + + when WAIT_FOR_TIMER2 => + STATE_OUT <= x"4"; + tx_pcs_rst_ch_c_int <= '1'; + RST_QD_C_int <= '0'; + if TIMER2 = '1' then + if tx_pll_lol_qd_s_int = '1' then + ns <= QUAD_RESET; + else + ns <= NORMAL; + end if; + else + ns <= WAIT_FOR_TIMER2; + end if; + + when NORMAL => + STATE_OUT <= x"5"; + tx_pcs_rst_ch_c_int <= '0'; + RST_QD_C_int <= '0'; + if tx_pll_lol_qd_s_int = '1' then ns <= QUAD_RESET; - else + else ns <= NORMAL; - end if; - else - ns <= WAIT_FOR_TIMER2; - end if; - - when NORMAL => - STATE_OUT <= x"5"; - tx_pcs_rst_ch_c_int <= '0'; - RST_QD_C_int <= '0'; - if tx_pll_lol_qd_s_int = '1' then - ns <= QUAD_RESET; - else - ns <= NORMAL; - end if; - - when others => - ns <= QUAD_RESET; - - end case; - + end if; + + when others => + ns <= QUAD_RESET; + + end case; end process; end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_phy_pkg.vhd b/cbmnet/code/cbmnet_phy_pkg.vhd index 485c3cf..dc731c9 100755 --- a/cbmnet/code/cbmnet_phy_pkg.vhd +++ b/cbmnet/code/cbmnet_phy_pkg.vhd @@ -10,7 +10,7 @@ package cbmnet_phy_pkg is generic( IS_SYNC_SLAVE : integer := c_NO; --select slave mode IS_SIMULATED : integer := c_NO; - INCL_DEBUG_AIDS : integer; + INCL_DEBUG_AIDS : integer := c_YES; DETERMINISTIC_LATENCY : integer := c_YES -- if selected proper alignment of barrel shifter and word alignment is enforced (link may come up slower) ); port( diff --git a/cbmnet/code/cbmnet_phy_rx_gear.vhd b/cbmnet/code/cbmnet_phy_rx_gear.vhd index 2d104d9..02140fc 100644 --- a/cbmnet/code/cbmnet_phy_rx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_rx_gear.vhd @@ -70,12 +70,11 @@ begin RESET_OUT <= '1'; reset_timer_i <= '0'; delay_clock_i <= '0'; - fsm_state_i <= x"0"; + fsm_state_i <= x"0"; if PCS_READY_IN = '0' then fsm_i <= FSM_START; - delay_clock_i <= '0'; else case (fsm_i) is @@ -168,7 +167,7 @@ begin begin wait until rising_edge(CLK_250_IN); - if not (delay_clock_buf_i = '1' and last_delay_clock_i = '0') or PCS_READY_IN='0' then + if not (delay_clock_buf_i = '1' and last_delay_clock_i = '0') then -- or PCS_READY_IN='0' then word_idx_i <= not word_idx_i; end if; diff --git a/cbmnet/code/cbmnet_phy_tx_gear.vhd b/cbmnet/code/cbmnet_phy_tx_gear.vhd index 88c658d..0066e90 100644 --- a/cbmnet/code/cbmnet_phy_tx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_tx_gear.vhd @@ -33,6 +33,9 @@ end entity; architecture CBMNET_PHY_TX_GEAR_ARCH of CBMNET_PHY_TX_GEAR is -- attribute HGROUP : string; -- attribute HGROUP of CBMNET_PHY_TX_GEAR_ARCH : architecture is "cbmnet_phy_tx_gear"; + attribute syn_hier : string; + attribute syn_hier of CBMNET_PHY_TX_GEAR_ARCH : architecture is "hard"; + type FSM_STATES is (FSM_LOCKING, FSM_HIGH, FSM_LOW); signal fsm_i : FSM_STATES; @@ -48,8 +51,9 @@ architecture CBMNET_PHY_TX_GEAR_ARCH of CBMNET_PHY_TX_GEAR is attribute syn_ramstyle of mem_i : signal is "registers"; signal mem_read_ptr_i, mem_write_ptr_i : unsigned(MEM_ADDR_DEPTH-1 downto 0) := (others => '0'); + signal overflow_read_ptr_i, overflow_write_ptr_i : std_logic; - signal mem_sync_i, mem_sync_delay_i : std_logic; + signal mem_sync_i : std_logic; signal fsm_locked_i, fsm_locked_slow_i : std_logic; signal delay_data_i : std_logic_vector(8 downto 0); @@ -73,31 +77,28 @@ begin when FSM_LOW => fsm_i <= FSM_HIGH; data_in_buf250_i <= mem_i(to_integer(mem_write_ptr_i)); - mem_write_ptr_i <= mem_write_ptr_i + 1; + mem_write_ptr_i <= mem_write_ptr_i + TO_UNSIGNED(1,1); fsm_locked_i <= '1'; when others => - if mem_sync_i = '1' and mem_sync_delay_i = '0' then + if mem_sync_i = '1' then fsm_i <= FSM_LOW; - mem_write_ptr_i <= 0; end if; + mem_write_ptr_i <= "110"; end case; if reset_i = '1' and reset_delay_i='1' then fsm_i <= FSM_LOCKING; - mem_write_ptr_i <= 0; + mem_write_ptr_i <= "110"; end if; reset_delay_i <= reset_i; - mem_sync_delay_i <= mem_sync_i; end process; - - PROC_MEM125: process is begin wait until rising_edge(CLK_125_IN); - mem_read_ptr_i <= mem_read_ptr_i + 1; + mem_read_ptr_i <= mem_read_ptr_i + TO_UNSIGNED(1,1); mem_i(to_integer(mem_read_ptr_i)) <= DATA_IN; end process; @@ -109,7 +110,7 @@ begin RESET => RESET_IN, CLK0 => CLK_125_IN, CLK1 => CLK_250_IN, - D_IN(0) => mem_read_ptr_i(mem_read_ptr_i'high), + D_IN(0) => overflow_read_ptr_i, D_OUT(0) => mem_sync_i ); @@ -123,7 +124,7 @@ begin D_OUT(0) => reset_i ); - THE_LOCKDE_SYNC: signal_sync + THE_LOCKED_SYNC: signal_sync generic map (WIDTH => 1, DEPTH => 3) port map ( RESET => RESET_IN, @@ -134,7 +135,7 @@ begin ); PROC_DEBUG_PTR: process is - variable delay_read_ptr, buf_read_ptr : unsigned(MEM_ADDR_DEPTH-1 downto 0); + variable delay_read_ptr, buf_read_ptr : unsigned(MEM_ADDR_DEPTH-1 downto 0) := (others => '1'); variable wait_cntr : unsigned(7 downto 0) := x"00"; -- lower the odds of a meta-stab when sampling over regio variable cnt : unsigned(7 downto 0) := x"00"; begin @@ -144,20 +145,25 @@ begin if delay_read_ptr = buf_read_ptr then -- stable, let's compare DEBUG_OUT(15 downto 0) <= x"0000"; - DEBUG_OUT(MEM_ADDR_DEPTH-1 downto 0) <= buf_read_ptr; - DEBUG_OUT(MEM_ADDR_DEPTH+3 downto 4) <= mem_write_ptr_i; - DEBUG_OUT(15 downto 8) <= cnt; + DEBUG_OUT(MEM_ADDR_DEPTH-1 downto 0) <= std_logic_vector(buf_read_ptr); + DEBUG_OUT(MEM_ADDR_DEPTH+3 downto 4) <= std_logic_vector(mem_write_ptr_i); + DEBUG_OUT(15 downto 8) <= std_logic_vector(cnt); wait_cntr := cnt; wait_cntr(7) := '1'; - cnt := cnt + 1; + cnt := cnt + TO_UNSIGNED(1,1); end if; else - wait_cntr := wait_cntr - 1; + wait_cntr := wait_cntr - TO_UNSIGNED(1,1); end if; delay_read_ptr := buf_read_ptr; buf_read_ptr := mem_read_ptr_i; end process; - DEBUG_OUT(31 downto 16) <= (others => '0'); -- x"0000" & STD_LOGIC_VECTOR( delay_counter_i ); + DEBUG_OUT(31 downto 18) <= (others => '0'); -- x"0000" & STD_LOGIC_VECTOR( delay_counter_i ); + + overflow_read_ptr_i <= '1' when mem_read_ptr_i = "000" else '0'; + overflow_write_ptr_i <= '1' when mem_write_ptr_i = "000" else '0'; + DEBUG_OUT(17 downto 16) <= overflow_write_ptr_i & overflow_read_ptr_i; + end architecture CBMNET_PHY_TX_GEAR_ARCH; \ No newline at end of file -- 2.43.0