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
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;
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 (
-- 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;
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;
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;
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;
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"),
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
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
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;
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;
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(
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;
-- 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;
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;
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);
-- 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
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)
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
);
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
-------------------------------------------------
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;
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;
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);
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);
-- 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
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
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
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);
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;
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);
data_delay_i <= data_in_buf_i;
clk_125_i <= '1';
else
--- data_out_buf_i <= data_delay_i(8) & data_in_buf_i(8) & data_delay_i(7 downto 0) & data_in_buf_i(7 downto 0);
data_out_buf250_i <= data_in_buf_i(8) & data_delay_i(8) & data_in_buf_i(7 downto 0) & data_delay_i(7 downto 0);
clk_125_i <= '0';
end if;
end process;
-- 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;
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);
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
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 (
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;
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;
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);
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);
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;
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
-- 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
----------------------------------------
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);
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
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';
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;
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
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;
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
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;
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(
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;
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';
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;
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;