From 51d16411447e267609ce7e3ae510dca39460cec0 Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Sun, 26 Oct 2014 21:22:30 +0100 Subject: [PATCH] CBMNet: PCS-Reset issued when receive a Link-Reinit, Generic signal_sync in contrast to manual syncs, code clean-up --- cbmnet/code/cbmnet_bridge.lpf | 2 +- cbmnet/code/cbmnet_bridge.vhd | 181 +++++++++------------------ cbmnet/code/cbmnet_interface_pkg.vhd | 49 ++------ cbmnet/code/cbmnet_phy_ecp3.vhd | 135 ++++++++++---------- cbmnet/code/cbmnet_phy_pkg.vhd | 1 - cbmnet/code/cbmnet_phy_rx_gear.vhd | 26 +++- cbmnet/code/cbmnet_phy_tx_gear.vhd | 102 ++++++++++----- cbmnet/code/cbmnet_readout.vhd | 169 ++++++++++++++++++------- cbmnet/code/cbmnet_readout_obuf.vhd | 43 ++++++- cbmnet/code/cbmnet_sync_module.vhd | 56 ++++----- 10 files changed, 418 insertions(+), 346 deletions(-) diff --git a/cbmnet/code/cbmnet_bridge.lpf b/cbmnet/code/cbmnet_bridge.lpf index 3652e26..f52cf10 100644 --- a/cbmnet/code/cbmnet_bridge.lpf +++ b/cbmnet/code/cbmnet_bridge.lpf @@ -23,7 +23,7 @@ DEFINE BUS cbmnet_bridge_tx_data PRIORITIZE BUS "cbmnet_bridge_rx_data" 100 ; PRIORITIZE BUS "cbmnet_bridge_tx_data" 100 ; -MULTICYCLE TO CELL "THE_CBM_BRIDGE/THE_CBM_PHY/THE_RX_GEAR/delay_clock_crs_i" 2 X; +MULTICYCLE TO CELL "THE_CBM_BRIDGE/THE_CBM_PHY/THE_RX_GEAR/THE_DELAY_SYNC/sync_q[*]" 2 X; UGROUP "CBMNET_PHY_GROUP" BBOX 24 30 # BLKNAME THE_CBM_BRIDGE/THE_CBM_PHY/THE_RX_GEAR diff --git a/cbmnet/code/cbmnet_bridge.vhd b/cbmnet/code/cbmnet_bridge.vhd index 5440a39..e4c6a56 100644 --- a/cbmnet/code/cbmnet_bridge.vhd +++ b/cbmnet/code/cbmnet_bridge.vhd @@ -83,16 +83,8 @@ entity cbmnet_bridge is 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 + REGIO_IN : in CTRLBUS_RX; + REGIO_OUT : out CTRLBUS_TX ); end entity; @@ -170,33 +162,12 @@ architecture cbmnet_bridge_arch of cbmnet_bridge is signal cbm_rdo_data2send_i : std_logic_vector(15 downto 0); -- regio - signal cbm_rdo_regio_addr_i : std_logic_vector(15 downto 0); - signal cbm_rdo_regio_data_status_i : std_logic_vector(31 downto 0); - signal cbm_rdo_regio_read_enable_i : std_logic; - signal cbm_rdo_regio_write_enable_i : std_logic; - signal cbm_rdo_regio_data_ctrl_i : std_logic_vector(31 downto 0); - signal cbm_rdo_regio_dataready_i : std_logic; - signal cbm_rdo_regio_write_ack_i : std_logic; - signal cbm_rdo_regio_unknown_addr_i : std_logic; - - signal cbm_phy_regio_addr_i : std_logic_vector(15 downto 0); - signal cbm_phy_regio_data_status_i : std_logic_vector(31 downto 0); - signal cbm_phy_regio_read_enable_i : std_logic; - signal cbm_phy_regio_write_enable_i : std_logic; - signal cbm_phy_regio_data_ctrl_i : std_logic_vector(31 downto 0); - signal cbm_phy_regio_dataready_i : std_logic; - signal cbm_phy_regio_write_ack_i : std_logic; - signal cbm_phy_regio_unknown_addr_i : std_logic; - - signal cbm_sync_regio_read_en_i : std_logic; - signal cbm_sync_regio_write_en_i : std_logic; - signal cbm_sync_regio_status_data_i : std_logic_vector(31 downto 0); - signal cbm_sync_regio_addr_i : std_logic_vector(3 downto 0); - signal cbm_sync_regio_config_data_i : std_logic_vector(31 downto 0); - signal cbm_sync_regio_read_ack_i : std_logic; - signal cbm_sync_regio_write_ack_i : std_logic; - signal cbm_sync_regio_unknown_i : std_logic; + 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 ( @@ -238,43 +209,55 @@ begin -- Status and control port STAT_OP => open, - CTRL_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(cbm_phy_regio_addr_i(4 downto 0))); + addr := to_integer(unsigned(phy_regio_rx.addr(4 downto 0))); - cbm_phy_regio_dataready_i <= cbm_phy_regio_read_enable_i; - cbm_phy_regio_unknown_addr_i <= '0'; - cbm_phy_regio_write_ack_i <= '0'; + phy_regio_tx.rack <= phy_regio_rx.read; + phy_regio_tx.unknown <= '0'; + phy_regio_tx.wack <= '0'; - cbm_phy_regio_data_status_i <= (others => '0'); + phy_regio_tx.data <= (others => '0'); if addr < 16 then - cbm_phy_regio_data_status_i <= cbm_phy_debug(addr*32+31 downto addr*32); + phy_regio_tx.data <= cbm_phy_debug(addr*32+31 downto addr*32); elsif addr = 16 then - cbm_phy_regio_data_status_i(11 downto 8) <= "0" & cbm_data2send_stop_i & cbm_serdes_ready_i & cbm_link_active_i; - cbm_phy_regio_data_status_i(7 downto 4) <= "00" & cbm_lt_dlm_valid_i & cbm_lt_ctrl_valid_i; - cbm_phy_regio_data_status_i(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(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 cbm_phy_regio_write_enable_i='1' then - cbm_data_mux_i <= cbm_phy_regio_data_ctrl_i(3); - cbm_lt_data_enable_i <= cbm_phy_regio_data_ctrl_i(2); - cbm_lt_ctrl_enable_i <= cbm_phy_regio_data_ctrl_i(1); - cbm_lt_force_stop_i <= cbm_phy_regio_data_ctrl_i(0); + 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_phy_regio_write_ack_i <= '1'; + phy_regio_tx.wack <= '1'; end if; - + + elsif addr = 17 then + phy_regio_tx.data <= cbm_serdes_ready_counter_i; + else - cbm_phy_regio_unknown_addr_i <= cbm_phy_regio_write_enable_i or cbm_phy_regio_read_enable_i; + phy_regio_tx.unknown <= phy_regio_rx.write or phy_regio_rx.read; end if; @@ -381,14 +364,8 @@ begin GBE_FEE_BUSY_OUT => GBE_FEE_BUSY_OUT, -- reg io - REGIO_ADDR_IN => cbm_rdo_regio_addr_i, -- in std_logic_vector(15 downto 0); - REGIO_DATA_IN => cbm_rdo_regio_data_ctrl_i, -- in std_logic_vector(31 downto 0); - REGIO_READ_ENABLE_IN => cbm_rdo_regio_read_enable_i, -- in std_logic; - REGIO_WRITE_ENABLE_IN => cbm_rdo_regio_write_enable_i, -- in std_logic; - REGIO_DATA_OUT => cbm_rdo_regio_data_status_i, -- out std_logic_vector(31 downto 0); - REGIO_DATAREADY_OUT => cbm_rdo_regio_dataready_i, -- out std_logic; - REGIO_WRITE_ACK_OUT => cbm_rdo_regio_write_ack_i, -- out std_logic; - REGIO_UNKNOWN_ADDR_OUT => cbm_rdo_regio_unknown_addr_i, -- out std_logic; + REGIO_IN => rdo_regio_rx, + REGIO_OUT => rdo_regio_tx, -- CBMNet CBMNET_CLK_IN => cbm_clk_i, -- in std_logic; @@ -415,7 +392,8 @@ begin OWN_ADDR => x"0000", DEST_ADDR => "0000000000000000", PACKET_MODE => 1 --if enabled generates another packet size order to test further corner cases - ) port map ( + ) + 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; @@ -471,15 +449,8 @@ begin TRB_RDO_STATUSBIT_OUT => open, -- reg io - TRB_REGIO_ADDR_IN(15 downto 4) => x"000", - TRB_REGIO_ADDR_IN(3 downto 0) => cbm_sync_regio_addr_i, -- in std_logic_vector(15 downto 0); - TRB_REGIO_DATA_IN => cbm_sync_regio_config_data_i, -- in std_logic_vector(31 downto 0); - TRB_REGIO_READ_ENABLE_IN => cbm_sync_regio_read_en_i, -- in std_logic; - TRB_REGIO_WRITE_ENABLE_IN => cbm_sync_regio_write_en_i, -- in std_logic; - TRB_REGIO_DATA_OUT => cbm_sync_regio_status_data_i, -- out std_logic_vector(31 downto 0); - TRB_REGIO_DATAREADY_OUT => cbm_sync_regio_read_ack_i, -- out std_logic; - TRB_REGIO_WRITE_ACK_OUT => cbm_sync_regio_write_ack_i, -- out std_logic; - TRB_REGIO_UNKNOWN_ADDR_OUT => cbm_sync_regio_unknown_i, -- out std_logic; + TRB_REGIO_IN => sync_regio_rx, + TRB_REGIO_OUT => sync_regio_tx, -- CBMNET CBM_CLK_IN => cbm_clk_i, -- in std_logic; @@ -520,7 +491,7 @@ begin cbm_data_rec_stop_i <= '1'; - THE_BUS_HANDLER : trb_net16_regio_bus_handler + 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"), @@ -530,57 +501,17 @@ begin CLK => TRB_CLK_IN, RESET => TRB_RESET_IN, - DAT_ADDR_IN(8 downto 0) => REGIO_ADDR_IN(8 downto 0), - DAT_ADDR_IN(15 downto 9) => (others => '0'), - DAT_DATA_IN => REGIO_DATA_IN, - DAT_DATA_OUT => REGIO_DATA_OUT, - DAT_READ_ENABLE_IN => REGIO_READ_ENABLE_IN, - DAT_WRITE_ENABLE_IN => REGIO_WRITE_ENABLE_IN, - DAT_TIMEOUT_IN => REGIO_TIMEOUT_IN, - DAT_DATAREADY_OUT => REGIO_DATAREADY_OUT, - DAT_WRITE_ACK_OUT => REGIO_WRITE_ACK_OUT, - DAT_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT, - DAT_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, - - --CBMNet (read-out) - BUS_READ_ENABLE_OUT(0) => cbm_rdo_regio_read_enable_i, - BUS_WRITE_ENABLE_OUT(0) => cbm_rdo_regio_write_enable_i, - BUS_DATA_OUT(0*32+31 downto 0*32) => cbm_rdo_regio_data_ctrl_i, - BUS_ADDR_OUT(0*16+15 downto 0*16) => cbm_rdo_regio_addr_i, - BUS_TIMEOUT_OUT(0) => open, - BUS_DATA_IN(0*32+31 downto 0*32) => cbm_rdo_regio_data_status_i, - BUS_DATAREADY_IN(0) => cbm_rdo_regio_dataready_i, - BUS_WRITE_ACK_IN(0) => cbm_rdo_regio_write_ack_i, - BUS_NO_MORE_DATA_IN(0) => '0', - BUS_UNKNOWN_ADDR_IN(0) => cbm_rdo_regio_unknown_addr_i, - - --CBMNet (phy) - BUS_READ_ENABLE_OUT(1) => cbm_phy_regio_read_enable_i, - BUS_WRITE_ENABLE_OUT(1) => cbm_phy_regio_write_enable_i, - BUS_DATA_OUT(1*32+31 downto 1*32) => cbm_phy_regio_data_ctrl_i, - BUS_ADDR_OUT(1*16+15 downto 1*16) => cbm_phy_regio_addr_i, - BUS_TIMEOUT_OUT(1) => open, - BUS_DATA_IN(1*32+31 downto 1*32) => cbm_phy_regio_data_status_i, - BUS_DATAREADY_IN(1) => cbm_phy_regio_dataready_i, - BUS_WRITE_ACK_IN(1) => cbm_phy_regio_write_ack_i, - BUS_NO_MORE_DATA_IN(1) => '0', - BUS_UNKNOWN_ADDR_IN(1) => cbm_phy_regio_unknown_addr_i, - - --CBMNet (sync) - BUS_READ_ENABLE_OUT(2) => cbm_sync_regio_read_en_i, - BUS_WRITE_ENABLE_OUT(2) => cbm_sync_regio_write_en_i, - BUS_DATA_OUT(2*32+31 downto 2*32) => cbm_sync_regio_config_data_i, - BUS_ADDR_OUT(2*16+3 downto 2*16) => cbm_sync_regio_addr_i, - BUS_ADDR_OUT(2*16+15 downto 2*16+4) => open, - BUS_TIMEOUT_OUT(2) => open, - BUS_DATA_IN(2*32+31 downto 2*32) => cbm_sync_regio_status_data_i, - BUS_DATAREADY_IN(2) => cbm_sync_regio_read_ack_i, - BUS_WRITE_ACK_IN(2) => cbm_sync_regio_write_ack_i, - BUS_NO_MORE_DATA_IN(2) => '0', - BUS_UNKNOWN_ADDR_IN(2) => cbm_sync_regio_unknown_i, - - stat_debug => open + 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); 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 7bd2abc..0062f46 100644 --- a/cbmnet/code/cbmnet_interface_pkg.vhd +++ b/cbmnet/code/cbmnet_interface_pkg.vhd @@ -3,6 +3,9 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; + +library work; + use work.trb_net_std.all; package cbmnet_interface_pkg is component cbmnet_bridge is @@ -77,16 +80,8 @@ package cbmnet_interface_pkg is 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 + REGIO_IN : in CTRLBUS_RX; + REGIO_OUT : out CTRLBUS_TX ); end component; @@ -478,14 +473,9 @@ package cbmnet_interface_pkg is 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_DATA_OUT : out std_logic_vector(31 downto 0); - REGIO_DATAREADY_OUT : out std_logic; - REGIO_WRITE_ACK_OUT : out std_logic; - REGIO_UNKNOWN_ADDR_OUT : out std_logic; + REGIO_IN : in CTRLBUS_RX; + REGIO_OUT : out CTRLBUS_TX; + -- CBMNet CBMNET_CLK_IN : in std_logic; @@ -673,18 +663,7 @@ package cbmnet_interface_pkg is DATA_OUT : out std_logic ); end component; - - component gray_code_sync is - generic ( - WIDTH : positive := 32 - ); - port ( - IN_CLK_IN : in std_logic; - DATA_IN : in std_logic_vector(WIDTH-1 downto 0); - OUT_CLK_IN : in std_logic; - DATA_OUT : out std_logic_vector(WIDTH-1 downto 0) - ); - end component; + component cbmnet_sync_module is port( @@ -703,14 +682,8 @@ package cbmnet_interface_pkg is TRB_RDO_FINISHED_OUT : out std_logic; -- reg io - TRB_REGIO_ADDR_IN : in std_logic_vector(15 downto 0); - TRB_REGIO_DATA_IN : in std_logic_vector(31 downto 0); - TRB_REGIO_READ_ENABLE_IN : in std_logic; - TRB_REGIO_WRITE_ENABLE_IN : in std_logic; - TRB_REGIO_DATA_OUT : out std_logic_vector(31 downto 0); - TRB_REGIO_DATAREADY_OUT : out std_logic; - TRB_REGIO_WRITE_ACK_OUT : out std_logic; - TRB_REGIO_UNKNOWN_ADDR_OUT : out std_logic; + TRB_REGIO_IN : in CTRLBUS_RX; + TRB_REGIO_OUT : out CTRLBUS_TX; -- CBMNET CBM_CLK_IN : in std_logic; diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index c2b7ee9..090d929 100755 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -125,6 +125,8 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is -- 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 rx_rst_fsm_state_sync_i : std_logic_vector(3 downto 0); + signal tx_rst_fsm_state_sync_i : std_logic_vector(3 downto 0); signal tx_rst_fsm_ready_i : std_logic; signal tx_rst_fsm_ready_buf_i : std_logic; @@ -132,6 +134,7 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is signal word_alignment_to_fsm_i : std_logic; signal rx_rst_fsm_ready_i : std_logic; + signal rx_rst_fsm_ready_local_i : std_logic; signal serdes_ready_i : std_logic; @@ -176,6 +179,7 @@ architecture cbmnet_phy_ecp3_arch of cbmnet_phy_ecp3 is 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); @@ -291,9 +295,15 @@ begin -- 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', + +-- 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 @@ -334,13 +344,14 @@ begin 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; + RM_RESET_IN => rx_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_i, -- out std_logic_vector(17 downto 0) 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); THE_TX_GEAR: CBMNET_PHY_TX_GEAR generic map (IS_SYNC_SLAVE => IS_SYNC_SLAVE) @@ -349,18 +360,15 @@ begin 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 - + RESET_IN => tx_gear_reset_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); + DATA_OUT => tx_data_to_serdes_i, -- out std_logic_vector(8 downto 0); + + DEBUG_OUT => tx_gear_debug_i ); - tx_gear_reset_i <= not tx_rst_fsm_ready_i; - tx_gear_allow_relock_i <= '0'; - - + 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 @@ -426,18 +434,38 @@ begin ); proc_rst_fsms_ready: process is begin - wait until rising_edge(clk_125_local); + wait until rising_edge(rclk_125_i); rx_rst_fsm_ready_i <= '0'; - if rx_rst_fsm_state_i = x"6" then + if rx_rst_fsm_state_sync_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 + if tx_rst_fsm_state_sync_i = x"5" then tx_rst_fsm_ready_i <= '1'; end if; end process; + + THE_RX_FSM_STATE_SYNC: signal_sync + generic map (WIDTH => 4, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => clk_125_local, + CLK1 => rclk_125_i, + D_IN => rx_rst_fsm_state_i, + D_OUT => rx_rst_fsm_state_sync_i + ); + THE_TX_FSM_STATE_SYNC: signal_sync + generic map (WIDTH => 4, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => clk_125_local, + CLK1 => rclk_125_i, + D_IN => tx_rst_fsm_state_i, + D_OUT => tx_rst_fsm_state_sync_i + ); + ------------------------------------------------- -- CBMNet Ready Modules ------------------------------------------------- @@ -511,19 +539,7 @@ begin 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; + tx_rst_fsm_ready_buf_i <= 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; @@ -547,7 +563,7 @@ begin sci_read_i <= '0'; sci_write_i <= '0'; sci_timer <= sci_timer + 1; - if sci_timer(sci_timer'left) = '1' and rx_rst_fsm_ready_i = '1' then + if sci_timer(sci_timer'left) = '1' and rx_rst_fsm_state_i = x"6" then sci_timer <= (others => '0'); sci_state <= GET_WA; end if; @@ -606,36 +622,27 @@ begin end if; end process; - LED_RX_OUT <= '0' when rx_data_i /= "10" & x"fcc3" and rx_data_i /= "00" & x"0000" else '1'; - LED_TX_OUT <= '0' when tx_data_i /= "10" & x"fcc3" and tx_data_i /= "00" & x"0000" else '1'; - LED_OK_OUT <= serdes_ready_i; + PROC_LEDS: process is + begin + wait until rising_edge(rclk_125_i); + + -- leds are low-active ! + + LED_RX_OUT <= '1'; + LED_TX_OUT <= '1'; + LED_OK_OUT <= not serdes_ready_i; + + if rx_data_i /= "10" & x"fcc3" and rx_data_i /= "00" & x"0000" then + LED_RX_OUT <= '0'; + end if; + + if tx_data_i /= "10" & x"fcc3" and tx_data_i /= "00" & x"0000" then + LED_TX_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; - - process is + PROC_DBG_STAB_COUNTER: process is variable rx_v, tx_v : std_logic_vector(17 downto 0); begin wait until rising_edge(rclk_125_i); @@ -679,8 +686,7 @@ begin 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( 95 downto 64) <= rx_gear_debug_i(15 downto 0) & 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); @@ -706,7 +712,7 @@ begin -- DEBUG_OUT_END end process; - process is + PROC_DBG_RXFIFO: process is begin wait until rising_edge(rclk_125_i); if rx_data_i /= "10" & x"fcc3" and rx_data_i /= "00" & x"0000" then @@ -718,7 +724,7 @@ begin end process; - process is + PROC_DBG_TXFIFO: process is begin wait until rising_edge(rclk_125_i); if tx_data_i /= "10" & x"fcc3" and tx_data_i(17 downto 16) /= "00" then @@ -736,16 +742,5 @@ begin tx_data_sp_i11 <= tx_data_sp_i10; end if; end process; - - - process is - begin - wait until rising_edge(rclk_125_i); - - STAT_OP(0)<= '0'; - if rx_data_i = "10" & K277 & EBTB_D_ENCODE(14,6) then - STAT_OP(0) <= '1'; - end if; - end process; end generate; 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 0a0661d..485c3cf 100755 --- a/cbmnet/code/cbmnet_phy_pkg.vhd +++ b/cbmnet/code/cbmnet_phy_pkg.vhd @@ -88,7 +88,6 @@ package cbmnet_phy_pkg is CLK_125_OUT : out std_logic; RESET_IN : in std_logic; - ALLOW_RELOCK_IN : in std_logic; DATA_IN : in std_logic_vector(17 downto 0); DATA_OUT : out std_logic_vector(8 downto 0); diff --git a/cbmnet/code/cbmnet_phy_rx_gear.vhd b/cbmnet/code/cbmnet_phy_rx_gear.vhd index 6b52c87..2d104d9 100644 --- a/cbmnet/code/cbmnet_phy_rx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_rx_gear.vhd @@ -4,7 +4,7 @@ LIBRARY IEEE; library work; use work.trb_net_std.all; --- use work.trb_net_components.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; @@ -154,8 +154,16 @@ begin end process; -- Implement the 2:1 gearing and clock down-sampling - delay_clock_crs_i <= delay_clock_i when rising_edge(CLK_250_IN); - delay_clock_buf_i <= delay_clock_crs_i when rising_edge(CLK_250_IN); + THE_DELAY_SYNC: signal_sync + generic map (WIDTH => 1, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => clk_125_i, + CLK1 => CLK_250_IN, + D_IN(0) => delay_clock_i, + D_OUT(0) => delay_clock_buf_i + ); + proc_ctrl_gear: process begin wait until rising_edge(CLK_250_IN); @@ -177,7 +185,6 @@ begin 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; @@ -185,8 +192,15 @@ begin end process; -- meta stabilitiy should not be a problem at this point, as the slower clock is direved from the driving faster clock, but be to be sure ... - data_out_crs125_i <= data_out_buf250_i when rising_edge(clk_125_i); - data_out_buf125_i <= data_out_crs125_i when rising_edge(clk_125_i); + THE_DATA_SYNC: signal_sync + generic map (WIDTH => 18, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => CLK_250_IN, + CLK1 => clk_125_i, + D_IN => data_out_buf250_i, + D_OUT => data_out_buf125_i + ); DATA_OUT <= data_out_buf125_i; CLK_125_OUT <= clk_125_i; diff --git a/cbmnet/code/cbmnet_phy_tx_gear.vhd b/cbmnet/code/cbmnet_phy_tx_gear.vhd index 5504ad3..88c658d 100644 --- a/cbmnet/code/cbmnet_phy_tx_gear.vhd +++ b/cbmnet/code/cbmnet_phy_tx_gear.vhd @@ -16,12 +16,10 @@ entity CBMNET_PHY_TX_GEAR is port ( -- SERDES PORT CLK_250_IN : in std_logic; - CLK_TX_FULL_IN : in std_logic; CLK_125_IN : in std_logic; CLK_125_OUT : out std_logic; RESET_IN : in std_logic; - ALLOW_RELOCK_IN : in std_logic; DATA_IN : in std_logic_vector(17 downto 0); DATA_OUT : out std_logic_vector(8 downto 0); @@ -43,77 +41,123 @@ architecture CBMNET_PHY_TX_GEAR_ARCH of CBMNET_PHY_TX_GEAR is signal data_in_buf250_i : std_logic_vector(17 downto 0); - signal delay_data_i : std_logic_vector(8 downto 0); + constant MEM_ADDR_DEPTH : integer := 3; + type MEM_T is array(0 to 2**MEM_ADDR_DEPTH-1) of std_logic_vector(17 downto 0); + signal mem_i : MEM_T; + attribute syn_ramstyle : string; + 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 clk_125_xfer_i : std_logic := '0'; - signal clk_125_xfer_buf_i : std_logic := '0'; - signal clk_125_xfer_del_i : std_logic := '0'; + signal mem_sync_i, mem_sync_delay_i : std_logic; + signal fsm_locked_i, fsm_locked_slow_i : std_logic; - signal delay_counter_i : unsigned(15 downto 0); + signal delay_data_i : std_logic_vector(8 downto 0); begin process is begin wait until rising_edge(CLK_250_IN); - clk_125_xfer_del_i <= clk_125_xfer_buf_i; CLK_125_OUT <= '0'; DATA_OUT <= delay_data_i; + fsm_locked_i <= '0'; case fsm_i is when FSM_HIGH => CLK_125_OUT <= '1'; - delay_data_i <= data_in_buf250_i(17) & data_in_buf250_i(15 downto 8); DATA_OUT <= data_in_buf250_i(16) & data_in_buf250_i( 7 downto 0); + fsm_locked_i <= '1'; fsm_i <= FSM_LOW; 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; + fsm_locked_i <= '1'; when others => - if clk_125_xfer_del_i = '0' and clk_125_xfer_buf_i = '1' then - fsm_i <= FSM_HIGH; + if mem_sync_i = '1' and mem_sync_delay_i = '0' then + fsm_i <= FSM_LOW; + mem_write_ptr_i <= 0; end if; end case; - - reset_delay_i <= reset_i; - + if reset_i = '1' and reset_delay_i='1' then fsm_i <= FSM_LOCKING; + mem_write_ptr_i <= 0; 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_i(to_integer(mem_read_ptr_i)) <= DATA_IN; end process; - TX_READY_OUT <= not RESET_IN; + TX_READY_OUT <= fsm_locked_slow_i and not RESET_IN; THE_DATA_SYNC: signal_sync - generic map (WIDTH => 18, DEPTH => 3) + generic map (WIDTH => 1, DEPTH => 3) port map ( RESET => RESET_IN, CLK0 => CLK_125_IN, CLK1 => CLK_250_IN, - D_IN => DATA_IN, - D_OUT => data_in_buf250_i + D_IN(0) => mem_read_ptr_i(mem_read_ptr_i'high), + D_OUT(0) => mem_sync_i ); - - THE_CLK_SYNC: signal_sync + + THE_RESET_SYNC: signal_sync generic map (WIDTH => 1, DEPTH => 3) port map ( RESET => RESET_IN, - CLK0 => CLK_250_IN, + CLK0 => CLK_125_IN, CLK1 => CLK_250_IN, - D_IN(0) => CLK_125_IN, - D_OUT(0) => clk_125_xfer_buf_i + D_IN(0) => RESET_IN, + D_OUT(0) => reset_i ); - THE_RESET_SYNC: signal_sync + THE_LOCKDE_SYNC: signal_sync generic map (WIDTH => 1, DEPTH => 3) port map ( RESET => RESET_IN, - CLK0 => CLK_125_IN, - CLK1 => CLK_250_IN, - D_IN(0) => RESET_IN, - D_OUT(0) => reset_i + CLK0 => CLK_250_IN, + CLK1 => CLK_125_IN, + D_IN(0) => fsm_locked_i, + D_OUT(0) => fsm_locked_slow_i ); - DEBUG_OUT <= (others => '0'); -- x"0000" & STD_LOGIC_VECTOR( delay_counter_i ); + PROC_DEBUG_PTR: process is + variable delay_read_ptr, buf_read_ptr : unsigned(MEM_ADDR_DEPTH-1 downto 0); + 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 + wait until rising_edge(CLK_250_IN); + + if wait_cntr = x"00" then + 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; + wait_cntr := cnt; + wait_cntr(7) := '1'; + cnt := cnt + 1; + end if; + else + wait_cntr := wait_cntr - 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 ); end architecture CBMNET_PHY_TX_GEAR_ARCH; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_readout.vhd b/cbmnet/code/cbmnet_readout.vhd index 7639cc7..d66ff4e 100644 --- a/cbmnet/code/cbmnet_readout.vhd +++ b/cbmnet/code/cbmnet_readout.vhd @@ -2,6 +2,9 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.cbmnet_interface_pkg.all; + use work.trb_net_std.all; + use work.trb_net_components.all; + use work.trb3_components.all; entity CBMNET_READOUT is port ( @@ -38,14 +41,8 @@ entity CBMNET_READOUT is 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_DATA_OUT : out std_logic_vector(31 downto 0); - REGIO_DATAREADY_OUT : out std_logic; - REGIO_WRITE_ACK_OUT : out std_logic; - REGIO_UNKNOWN_ADDR_OUT : out std_logic; + REGIO_IN : in CTRLBUS_RX; + REGIO_OUT : out CTRLBUS_TX; -- CBMNet CBMNET_CLK_IN : in std_logic; @@ -60,6 +57,7 @@ entity CBMNET_READOUT is end entity; architecture cbmnet_readout_arch of CBMNET_READOUT is + signal cbm_from_trb_reset_i : std_logic; signal reset_combined_i : std_logic; signal reset_combined_125_i : std_logic; @@ -96,13 +94,19 @@ architecture cbmnet_readout_arch of CBMNET_READOUT is signal frame_packer_data_i : std_logic_vector(15 downto 0); signal obuf_stop_i : std_logic; + signal obuf_start_i : std_logic; + signal obuf_end_i : std_logic; + signal cbmnet_link_active_in_buf_i : std_logic; -- stats and monitoring signal cbm_stat_num_packets_i : unsigned(31 downto 0) := (others => '0'); signal cbm_stat_num_send_completed_i : unsigned(31 downto 0) := (others => '0'); signal cbm_stat_clks_dead_i : unsigned(31 downto 0) := (others => '0'); - signal cbm_stat_connections_i : unsigned(31 downto 0) := (others => '0'); + signal cbm_stat_connections_i : unsigned(31 downto 0) := (others => '0'); + signal cbm_stat_hwords_sent_i : unsigned(31 downto 0) := (others => '0'); + signal cbm_stat_transmitting_i : std_logic; + signal cbm_stat_frame_length_i : unsigned(31 downto 0) := (others => '0'); signal stat_num_packets_i : unsigned(31 downto 0); signal stat_num_send_completed_i : unsigned(31 downto 0); @@ -113,6 +117,13 @@ architecture cbmnet_readout_arch of CBMNET_READOUT is signal stat_num_recv_completed_i : unsigned(31 downto 0); signal stat_link_inactive_i : unsigned(31 downto 0); + signal stat_hwords_sent_i : unsigned(31 downto 0); + signal stat_frame_length_i : unsigned(31 downto 0) := (others => '0'); + + + signal cbm_regio_read_i : std_logic; + signal cbm_sync_ack_i : std_logic; + signal trb_from_cbm_sync_ack_i : std_logic; -- debug signal debug_decorder_i : std_logic_vector(31 downto 0); @@ -149,7 +160,7 @@ begin begin wait until rising_edge(CBMNET_CLK_IN); - if RESET_IN='1' or CBMNET_RESET_IN='1' or CBMNET_LINK_ACTIVE_IN='0' then + if cbm_from_trb_reset_i='1' or CBMNET_RESET_IN='1' or CBMNET_LINK_ACTIVE_IN='0' then counter_v := 0; elsif counter_v /= 15 then counter_v := counter_v + 1; @@ -160,7 +171,26 @@ begin reset_combined_125_i <= '0'; end if; end process; - reset_combined_i <= reset_combined_125_i when rising_edge(CLK_IN); + + THE_RESET_SYNC: signal_sync + generic map (WIDTH => 1, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => CLK_IN, + CLK1 => CBMNET_CLK_IN, + D_IN(0) => RESET_IN, + D_OUT(0) => cbm_from_trb_reset_i + ); + + THE_RESET1_SYNC: signal_sync + generic map (WIDTH => 1, DEPTH => 3) + port map ( + RESET => '0', + CLK0 => CBMNET_CLK_IN, + CLK1 => CLK_IN, + D_IN(0) => reset_combined_125_i, + D_OUT(0) => reset_combined_i + ); THE_DECODER: CBMNET_READOUT_TRBNET_DECODER @@ -291,13 +321,14 @@ begin -- cbmnet CBMNET_STOP_IN => CBMNET_DATA2SEND_STOP_IN, -- in std_logic; - CBMNET_START_OUT => CBMNET_DATA2SEND_START_OUT, -- out std_logic; - CBMNET_END_OUT => CBMNET_DATA2SEND_END_OUT, -- out std_logic; + CBMNET_START_OUT => obuf_start_i, -- out std_logic; + CBMNET_END_OUT => obuf_end_i, -- out std_logic; CBMNET_DATA_OUT => CBMNET_DATA2SEND_DATA_OUT, -- out std_logic_vector(15 downto 0); DEBUG_OUT => debug_obuf_i -- out std_logic_vector(31 downto 0) ); - + CBMNET_DATA2SEND_START_OUT <= obuf_start_i; + CBMNET_DATA2SEND_END_OUT <= obuf_end_i; ---------------------------------------- -- Slow control and monitoring ---------------------------------------- @@ -322,18 +353,67 @@ begin if fifo_rpacket_complete_ack_i = '1' then cbm_stat_num_send_completed_i <= cbm_stat_num_send_completed_i + 1; end if; + + if cbm_stat_transmitting_i='1' then + cbm_stat_hwords_sent_i <= cbm_stat_hwords_sent_i + 1; + cbm_stat_frame_length_i <= cbm_stat_frame_length_i + 1; + end if; + + if obuf_start_i='1' and CBMNET_DATA2SEND_STOP_IN='0' then + cbm_stat_transmitting_i <= '1'; + cbm_stat_frame_length_i <= 1; + cbm_stat_hwords_sent_i <= cbm_stat_hwords_sent_i + 1; + elsif CBMNET_LINK_ACTIVE_IN='0' or obuf_end_i='1' then + cbm_stat_transmitting_i <= '0'; + end if; last_link_active_v := CBMNET_LINK_ACTIVE_IN; last_end_v := frame_packer_end_i; end process; -- and cross over to TrbNet clock domain - stat_connections_i <= cbm_stat_connections_i when rising_edge(CLK_IN); - stat_num_packets_i <= cbm_stat_num_packets_i when rising_edge(CLK_IN); - stat_clks_dead_i <= cbm_stat_clks_dead_i when rising_edge(CLK_IN); - stat_num_send_completed_i <= cbm_stat_num_send_completed_i when rising_edge(CLK_IN); + PROC_CBM_SYNC: process is + variable ack_delay : std_logic; + begin + wait until rising_edge(CBMNET_CLK_IN); + + cbm_sync_ack_i <= ack_delay; + ack_delay := '0'; + + if cbm_regio_read_i = '1' then + cbm_sync_ack_i <= '0'; + + else + ack_delay := '1'; + + stat_connections_i <= cbm_stat_connections_i; + stat_num_packets_i <= cbm_stat_num_packets_i; + stat_clks_dead_i <= cbm_stat_clks_dead_i; + stat_num_send_completed_i <= cbm_stat_num_send_completed_i; + stat_hwords_sent_i <= cbm_stat_hwords_sent_i; + stat_frame_length_i <= cbm_stat_frame_length_i; + end if; + end process; + + THE_REGIO_READ_SYNC: signal_sync + generic map (WIDTH => 1, DEPTH => 3) + port map ( + RESET => reset_combined_i, + CLK0 => CLK_IN, + CLK1 => CBMNET_CLK_IN, + D_IN(0) => REGIO_IN.read, + D_OUT(0) => cbm_regio_read_i + ); + + THE_REGIO_READ_ACK_SYNC: pos_edge_strech_sync port map ( + IN_CLK_IN => CBMNET_CLK_IN, OUT_CLK_IN => CLK_IN, + DATA_IN => cbm_sync_ack_i, + DATA_OUT => trb_from_cbm_sync_ack_i + ); + -- statistics in TrbNet clock domain PROC_STATS: process is + variable fifo_waddr_restore_delay : std_logic; begin wait until rising_edge(CLK_IN); @@ -346,9 +426,10 @@ begin stat_num_recv_completed_i <= stat_num_recv_completed_i + 1; end if; - if fifo_waddr_restore_i = '1' then + if fifo_waddr_restore_i = '1' and fifo_waddr_restore_delay = '0' then stat_num_packets_aborted_i <= stat_num_packets_aborted_i + 1; end if; + fifo_waddr_restore_delay := fifo_waddr_restore_i; end process; PROC_READOUT_MUX: process is @@ -356,49 +437,51 @@ begin begin wait until rising_edge(CLK_IN); - regio_data_ready_i <= REGIO_READ_ENABLE_IN; + regio_data_ready_i <= REGIO_IN.read; regio_unkown_address_i <= '0'; regio_data_status_i <= x"00000000"; - addr := to_integer(UNSIGNED(REGIO_ADDR_IN(6 downto 0))); + addr := to_integer(UNSIGNED(REGIO_IN.addr(6 downto 0))); -- read case addr is when 16#00# => regio_data_status_i(0) <= cfg_enabled_i; when 16#01# => regio_data_status_i(16 downto 0) <= cfg_source_override_i & cfg_source_i; - when 16#02# => regio_data_status_i <= std_logic_vector(stat_connections_i); - when 16#03# => regio_data_status_i <= std_logic_vector(stat_clks_dead_i); - when 16#04# => regio_data_status_i <= std_logic_vector(stat_num_send_completed_i); - when 16#05# => regio_data_status_i <= std_logic_vector(stat_num_packets_i); + when 16#02# => regio_data_status_i <= std_logic_vector(stat_connections_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; + when 16#03# => regio_data_status_i <= std_logic_vector(stat_clks_dead_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; + when 16#04# => regio_data_status_i <= std_logic_vector(stat_num_send_completed_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; + when 16#05# => regio_data_status_i <= std_logic_vector(stat_num_packets_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; when 16#06# => regio_data_status_i <= std_logic_vector(stat_num_recv_completed_i); when 16#07# => regio_data_status_i <= std_logic_vector(stat_link_inactive_i); when 16#08# => regio_data_status_i <= std_logic_vector(stat_num_packets_aborted_i); + when 16#09# => regio_data_status_i <= std_logic_vector(stat_hwords_sent_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; + when 16#0a# => regio_data_status_i <= std_logic_vector(stat_frame_length_i); regio_data_ready_i <= trb_from_cbm_sync_ack_i; -- debug only ports - when 16#09# => regio_data_status_i <= debug_decorder_i; - when 16#0a# => regio_data_status_i <= debug_packer_i; - when 16#0b# => regio_data_status_i <= debug_frame_packer_i; - when 16#0c# => regio_data_status_i(1 downto 0) <= fifo_wfull_i & fifo_rpacket_complete_i; - when 16#0d# => regio_data_status_i <= HUB_CTS_INFORMATION_IN & HUB_CTS_CODE_IN & HUB_CTS_NUMBER_IN; - when 16#0e# => regio_data_status_i <= dec_evt_info_i; - when 16#0f# => regio_data_status_i <= dec_source_i & dec_length_i; + when 16#10# => regio_data_status_i <= debug_decorder_i; + when 16#11# => regio_data_status_i <= debug_packer_i; + when 16#12# => regio_data_status_i <= debug_frame_packer_i; + when 16#13# => regio_data_status_i(1 downto 0) <= fifo_wfull_i & fifo_rpacket_complete_i; + when 16#14# => regio_data_status_i <= HUB_CTS_INFORMATION_IN & HUB_CTS_CODE_IN & HUB_CTS_NUMBER_IN; + when 16#15# => regio_data_status_i <= dec_evt_info_i; + when 16#16# => regio_data_status_i <= dec_source_i & dec_length_i; - when 16#10# => regio_data_status_i <= debug_fifo_i; - when 16#11# => regio_data_status_i <= debug_obuf_i; + when 16#17# => regio_data_status_i <= debug_fifo_i; + when 16#18# => regio_data_status_i <= debug_obuf_i; - when others => regio_unkown_address_i <= REGIO_READ_ENABLE_IN; + when others => regio_unkown_address_i <= REGIO_IN.read; end case; -- write - if REGIO_WRITE_ENABLE_IN = '1' then + if REGIO_IN.write = '1' then case addr is when 16#0# => - cfg_enabled_i <= REGIO_DATA_IN(0); + cfg_enabled_i <= REGIO_IN.data(0); when 16#1# => - cfg_source_i <= REGIO_DATA_IN(15 downto 0); - cfg_source_override_i <= REGIO_DATA_IN(16); + cfg_source_i <= REGIO_IN.data(15 downto 0); + cfg_source_override_i <= REGIO_IN.data(16); when others => regio_unkown_address_i <= '1'; @@ -407,11 +490,11 @@ begin end process; - REGIO_DATA_OUT <= regio_data_status_i; - REGIO_UNKNOWN_ADDR_OUT <= regio_unkown_address_i; + REGIO_OUT.data <= regio_data_status_i; + REGIO_OUT.unknown <= regio_unkown_address_i; - REGIO_DATAREADY_OUT <= REGIO_READ_ENABLE_IN when rising_edge(CLK_IN); - REGIO_WRITE_ACK_OUT <= REGIO_WRITE_ENABLE_IN when rising_edge(CLK_IN); + REGIO_OUT.rack <= REGIO_IN.read when rising_edge(CLK_IN); + REGIO_OUT.wack <= REGIO_IN.write when rising_edge(CLK_IN); end architecture; diff --git a/cbmnet/code/cbmnet_readout_obuf.vhd b/cbmnet/code/cbmnet_readout_obuf.vhd index c014885..ff27260 100644 --- a/cbmnet/code/cbmnet_readout_obuf.vhd +++ b/cbmnet/code/cbmnet_readout_obuf.vhd @@ -47,10 +47,16 @@ architecture cbmnet_readout_obuf_arch of CBMNET_READOUT_OBUF is signal wfsm_i : WFSM_T; constant wfsm_dec_c : WFSM_DEC_T := (OBTAIN_FREE_BUFFER => x"1", WAIT_FOR_START => x"2", WAIT_FOR_END => x"3", COMPLETE => x"4"); - type RFSM_T is (OBTAIN_FULL_BUFFER, WAIT_WHILE_STOP, COPY, COMPLETE); + type RFSM_T is (OBTAIN_FULL_BUFFER, DELAY_WHILE_STOP, WAIT_WHILE_STOP, COPY, PADDING, COMPLETE); type RFSM_DEC_T is array(RFSM_T) of std_logic_vector(3 downto 0); signal rfsm_i, rfsm_next_i : RFSM_T; - constant rfsm_dec_c : RFSM_DEC_T := (OBTAIN_FULL_BUFFER => x"1", WAIT_WHILE_STOP => x"2", COPY => x"3", COMPLETE => x"4"); + constant rfsm_dec_c : RFSM_DEC_T := (OBTAIN_FULL_BUFFER => x"1", WAIT_WHILE_STOP => x"2", COPY => x"3", COMPLETE => x"4", DELAY_WHILE_STOP => x"5", PADDING => x"6"); + + signal delay_counter_i : integer range 0 to 15; + signal reset_delay_counter_i : std_logic; + + signal transmit_length_i : integer range 0 to 63; + begin WPROC: process is begin @@ -107,6 +113,19 @@ begin else rfsm_i <= rfsm_next_i; end if; + + if rfsm_next_i = OBTAIN_FULL_BUFFER then + transmit_length_i <= 0; + elsif rfsm_next_i = COPY or rfsm_next_i = PADDING then + transmit_length_i <= transmit_length_i + 1; + end if; + + if CBMNET_STOP_IN='1' then + delay_counter_i <= 7; + elsif delay_counter_i /= 0 then + delay_counter_i <= delay_counter_i - 1; + end if; + read_fifo_i <= read_fifo_next_i; end process; @@ -124,12 +143,17 @@ begin when OBTAIN_FULL_BUFFER => if fifo_get_filled_i(0) = '1' then read_fifo_next_i <= 0; - rfsm_next_i <= WAIT_WHILE_STOP; + rfsm_next_i <= DELAY_WHILE_STOP; elsif fifo_get_filled_i(1) = '1' then read_fifo_next_i <= 1; + rfsm_next_i <= DELAY_WHILE_STOP; + end if; + + when DELAY_WHILE_STOP => + if delay_counter_i = 0 then rfsm_next_i <= WAIT_WHILE_STOP; end if; - + when WAIT_WHILE_STOP => CBMNET_START_OUT <= '1'; if CBMNET_STOP_IN='0' then @@ -140,10 +164,21 @@ begin when COPY => fifo_deq_i <= '1'; if fifo_last_i(read_fifo_i)='1' then + if transmit_length_i < 3 then + rfsm_next_i <= PADDING; + else + CBMNET_END_OUT <= '1'; + rfsm_next_i <= COMPLETE; + end if; + end if; + + when PADDING => + if transmit_length_i >= 3 then CBMNET_END_OUT <= '1'; rfsm_next_i <= COMPLETE; end if; + when others => fifo_empty_i(read_fifo_i) <= '1'; rfsm_next_i <= OBTAIN_FULL_BUFFER; diff --git a/cbmnet/code/cbmnet_sync_module.vhd b/cbmnet/code/cbmnet_sync_module.vhd index be96d82..1ad56fd 100644 --- a/cbmnet/code/cbmnet_sync_module.vhd +++ b/cbmnet/code/cbmnet_sync_module.vhd @@ -1,7 +1,11 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; + +library work; use work.cbmnet_interface_pkg.all; + use work.trb_net_std.all; + entity cbmnet_sync_module is port( @@ -20,14 +24,8 @@ entity cbmnet_sync_module is TRB_RDO_FINISHED_OUT : out std_logic; -- reg io - TRB_REGIO_ADDR_IN : in std_logic_vector(15 downto 0); - TRB_REGIO_DATA_IN : in std_logic_vector(31 downto 0); - TRB_REGIO_READ_ENABLE_IN : in std_logic; - TRB_REGIO_WRITE_ENABLE_IN : in std_logic; - TRB_REGIO_DATA_OUT : out std_logic_vector(31 downto 0); - TRB_REGIO_DATAREADY_OUT : out std_logic; - TRB_REGIO_WRITE_ACK_OUT : out std_logic; - TRB_REGIO_UNKNOWN_ADDR_OUT : out std_logic; + TRB_REGIO_IN : in CTRLBUS_RX; + TRB_REGIO_OUT : out CTRLBUS_TX; -- CBMNET CBM_CLK_IN : in std_logic; @@ -279,16 +277,16 @@ begin end process; -- TRBNet slow control - trb_regio_addr_i <= to_integer(UNSIGNED(TRB_REGIO_ADDR_IN(3 downto 0))); + trb_regio_addr_i <= to_integer(UNSIGNED(TRB_REGIO_IN.addr(3 downto 0))); TRB_SLOW_CTRL_PROC: process is begin wait until rising_edge(TRB_CLK_IN); - TRB_REGIO_DATAREADY_OUT <= TRB_REGIO_READ_ENABLE_IN; - TRB_REGIO_WRITE_ACK_OUT <= TRB_REGIO_WRITE_ENABLE_IN; - TRB_REGIO_UNKNOWN_ADDR_OUT <= '0'; - TRB_REGIO_DATA_OUT <= (others => '0'); + TRB_REGIO_OUT.rack <= TRB_REGIO_IN.read; + TRB_REGIO_OUT.wack <= TRB_REGIO_IN.write; + TRB_REGIO_OUT.unknown <= '0'; + TRB_REGIO_OUT.data <= (others => '0'); if trb_from_cbm_dlm_sensed_i = '1' then trb_next_epoch_updated_i <= '0'; @@ -305,20 +303,20 @@ begin else case (trb_regio_addr_i) is when 0 => - TRB_REGIO_DATA_OUT(31 downto 16) <= trb_dlm_sense_mask_i; - TRB_REGIO_DATA_OUT(11 downto 8) <= trb_rdo_fsm_state_i; - TRB_REGIO_DATA_OUT(5) <= CBM_LINK_ACTIVE_IN; - TRB_REGIO_DATA_OUT(4) <= trb_from_cbm_current_epoch_updated_i; - TRB_REGIO_DATA_OUT( 3 downto 0) <= "00" & trb_epoch_update_scheme_i; + TRB_REGIO_OUT.data(31 downto 16) <= trb_dlm_sense_mask_i; + TRB_REGIO_OUT.data(11 downto 8) <= trb_rdo_fsm_state_i; + TRB_REGIO_OUT.data(5) <= CBM_LINK_ACTIVE_IN; + TRB_REGIO_OUT.data(4) <= trb_from_cbm_current_epoch_updated_i; + TRB_REGIO_OUT.data( 3 downto 0) <= "00" & trb_epoch_update_scheme_i; when 1 => - TRB_REGIO_DATA_OUT <= trb_pulser_threshold_i; + TRB_REGIO_OUT.data <= trb_pulser_threshold_i; when 2 => - TRB_REGIO_DATA_OUT <= trb_next_epoch_i; + TRB_REGIO_OUT.data <= trb_next_epoch_i; when trb_sync_lowest_address_c => - TRB_REGIO_DATA_OUT <= trb_from_cbm_current_epoch_i; + TRB_REGIO_OUT.data <= trb_from_cbm_current_epoch_i; trb_sync_buffer_i(trb_sync_lowest_address_c+1) <= trb_from_cbm_timestamp_i; trb_sync_buffer_i(trb_sync_lowest_address_c+2) <= trb_from_cbm_timestamp_last_dlm_i; trb_sync_buffer_i(trb_sync_lowest_address_c+3) <= trb_from_cbm_timestamp_last_pulse_i; @@ -330,28 +328,28 @@ begin trb_sync_buffer_i(trb_sync_lowest_address_c+9) <= STD_LOGIC_VECTOR(trb_reset_counter_i) & STD_LOGIC_VECTOR(trb_from_cbm_reset_counter_i); when trb_sync_lowest_address_c + 1 to trb_sync_lowest_address_c + trb_sync_buffer_i'high => - TRB_REGIO_DATA_OUT <= trb_sync_buffer_i(trb_regio_addr_i); + TRB_REGIO_OUT.data <= trb_sync_buffer_i(trb_regio_addr_i); when others => - TRB_REGIO_UNKNOWN_ADDR_OUT <= TRB_REGIO_READ_ENABLE_IN or TRB_REGIO_WRITE_ENABLE_IN; + TRB_REGIO_OUT.unknown <= TRB_REGIO_IN.read or TRB_REGIO_IN.write; end case; - if TRB_REGIO_WRITE_ENABLE_IN = '1' then + if TRB_REGIO_IN.write = '1' then case (trb_regio_addr_i) is when 0 => - trb_dlm_sense_mask_i <= TRB_REGIO_DATA_IN(31 downto 16); - trb_epoch_update_scheme_i <= TRB_REGIO_DATA_IN(1 downto 0); + trb_dlm_sense_mask_i <= TRB_REGIO_IN.data(31 downto 16); + trb_epoch_update_scheme_i <= TRB_REGIO_IN.data(1 downto 0); when 1 => - trb_pulser_threshold_i <= TRB_REGIO_DATA_IN; + trb_pulser_threshold_i <= TRB_REGIO_IN.data; when 2 => - trb_next_epoch_i <= TRB_REGIO_DATA_IN; + trb_next_epoch_i <= TRB_REGIO_IN.data; trb_next_epoch_updated_i <= '1'; when others => - TRB_REGIO_UNKNOWN_ADDR_OUT <= '1'; + TRB_REGIO_OUT.unknown <= '1'; end case; end if; end if; -- 2.43.0