From 53ef12597ab738c5ed931d006335492a3d98b588 Mon Sep 17 00:00:00 2001 From: Manuel Penschuck Date: Thu, 17 Jul 2014 22:55:34 +0200 Subject: [PATCH] CBMNet readout backup --- cbmnet/code/cbmnet_interface_pkg.vhd | 101 ++++++--- cbmnet/code/cbmnet_phy_ecp3.vhd | 16 +- cbmnet/code/cbmnet_readout.vhd | 156 +++++++++++++ cbmnet/code/cbmnet_readout_event_packer.vhd | 157 +++++++++++++ cbmnet/code/cbmnet_readout_trbnet_decoder.vhd | 210 ++++++++++++++++++ cbmnet/code/cbmnet_readout_tx_fsm.vhd | 2 +- .../code/tb_cbmnet_readout_trbnet_decoder.vhd | 98 ++++++++ 7 files changed, 703 insertions(+), 37 deletions(-) create mode 100644 cbmnet/code/cbmnet_readout_event_packer.vhd create mode 100644 cbmnet/code/cbmnet_readout_trbnet_decoder.vhd create mode 100644 cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd diff --git a/cbmnet/code/cbmnet_interface_pkg.vhd b/cbmnet/code/cbmnet_interface_pkg.vhd index c36532e..8a810d6 100644 --- a/cbmnet/code/cbmnet_interface_pkg.vhd +++ b/cbmnet/code/cbmnet_interface_pkg.vhd @@ -304,40 +304,6 @@ package cbmnet_interface_pkg is ctrl_rec_stop : out std_logic ); end component; - - component CBMNET_READOUT_FIFO is - generic ( - ADDR_WIDTH : positive := 10; - WATERMARK : positive := 2 - ); - - port ( - -- write port - WCLK_IN : in std_logic; -- not faster than rclk_in - WRESET_IN : in std_logic; - - WADDR_STORE_IN : in std_logic; - WADDR_RESTORE_IN : in std_logic; - - WDATA_IN : in std_logic_vector(17 downto 0); - WENQUEUE_IN : in std_logic; - WPACKET_COMPLETE_IN : in std_logic; - - WALMOST_FULL_OUT : out std_logic; - WFULL_OUT : out std_logic; - - -- read port - RCLK_IN : in std_logic; - RRESET_IN : in std_logic; -- has to active at least two clocks AFTER (or while) write port was (is being) initialised - - RDATA_OUT : out std_logic_vector(17 downto 0); - RDEQUEUE_IN : in std_logic; - - RPACKET_COMPLETE_OUT : out std_logic; -- atleast one packet is completed in fifo - RPACKET_COMPLETE_ACK_IN : in std_logic -- mark one event as dealt with (effectively decrease number of completed packets by one) - ); - end component; - component CBMNET_READOUT_TX_FSM is port ( @@ -446,6 +412,73 @@ package cbmnet_interface_pkg is CBMNET_DATA2SEND_DATA_OUT : out std_logic_vector(15 downto 0) ); end component; + + component CBMNET_READOUT_TRBNET_DECODER is + port ( + -- TrbNet + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- connect to hub + HUB_CTS_START_READOUT_IN : in std_logic; + HUB_CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + HUB_FEE_DATA_IN : in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN : in std_logic; + GBE_FEE_READ_IN : in std_logic; + + -- Decode + DEC_EVT_INFO_OUT : out std_logic_vector(31 downto 0); + DEC_LENGTH_OUT : out std_logic_vector(15 downto 0); + DEC_SOURCE_OUT : out std_logic_vector(15 downto 0); + DEC_DATA_OUT : out std_logic_vector(15 downto 0); + DEC_DATA_READY_OUT : out std_logic; + DEC_DATA_READ_IN : in std_logic; + + DEC_ACTIVE_OUT : out std_logic; + DEC_ERROR_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0); + ); + end component; + + component CBMNET_READOUT_EVENT_PACKER is + port ( + -- TrbNet + CLK_IN : in std_logic; + RESET_IN : in 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_FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + + + -- connect to decoder + DEC_EVT_INFO_IN : in std_logic_vector(31 downto 0); + DEC_LENGTH_IN : in std_logic_vector(15 downto 0); + DEC_SOURCE_IN : in std_logic_vector(15 downto 0); + DEC_DATA_IN : in std_logic_vector(15 downto 0); + DEC_DATA_READY_IN : in std_logic; + DEC_ACTIVE_IN : in std_logic; + DEC_ERROR_IN : in std_logic; + + DEC_DATA_READ_OUT : out std_logic; + DEC_RESET_OUT : out std_logic; + + -- connect to fifo + WADDR_STORE_OUT : out std_logic; + WADDR_RESTORE_OUT: out std_logic; + WDATA_OUT : out std_logic_vector(17 downto 0); + WENQUEUE_OUT : out std_logic; + WPACKET_COMPLETE_OUT: out std_logic; + WALMOST_FULL_IN : in std_logic; + WFULL_IN : in std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); + end component; end package cbmnet_interface_pkg; package body cbmnet_interface_pkg is diff --git a/cbmnet/code/cbmnet_phy_ecp3.vhd b/cbmnet/code/cbmnet_phy_ecp3.vhd index 1e5f8ea..a5b626e 100755 --- a/cbmnet/code/cbmnet_phy_ecp3.vhd +++ b/cbmnet/code/cbmnet_phy_ecp3.vhd @@ -706,10 +706,13 @@ begin 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(333 downto 316) <= PHY_TXDATA_K_IN(1 downto 0) & PHY_TXDATA_IN(15 downto 0); - DEBUG_OUT(511 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) & tx_data_sp_i7(17 downto 0) & tx_data_sp_i6(17 downto 0) & tx_data_sp_i5(17 downto 0) & tx_data_sp_i4(17 downto 0) & tx_data_sp_i8(17 downto 0) & tx_data_sp_i9(17 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); + DEBUG_OUT(421 downto 404) <= PHY_TXDATA_K_IN(1 downto 0) & PHY_TXDATA_IN(15 downto 0); + + + -- & tx_data_sp_i7(17 downto 0) & tx_data_sp_i6(17 downto 0) & tx_data_sp_i5(17 downto 0) & tx_data_sp_i4(17 downto 0) & tx_data_sp_i8(17 downto 0) & tx_data_sp_i9(17 downto 0); --DEBUG_OUT(341 downto 334) <= stat_sync_dlm_inv_counter_i(7 downto 0) when rising_edge(rclk_125_i); --DEBUG_OUT(349 downto 342) <= stat_sync_dlm_counter_i(7 downto 0) when rising_edge(rclk_125_i); @@ -776,8 +779,17 @@ begin end if; detect_dlm_125_i <= detect_dlm_250_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; + STAT_OP(2 downto 1) <= detect_dlm_125_i & detect_dlm_250_i; + --PROC_SEE_FAST_DLM: process is --variable saw_lb_v, saw_hb_v : std_logic; diff --git a/cbmnet/code/cbmnet_readout.vhd b/cbmnet/code/cbmnet_readout.vhd index c22bfc3..370bb61 100644 --- a/cbmnet/code/cbmnet_readout.vhd +++ b/cbmnet/code/cbmnet_readout.vhd @@ -59,7 +59,163 @@ entity CBMNET_READOUT is end entity; architecture cbmnet_readout_arch of CBMNET_READOUT is + signal fifo_rdata_i : std_logic_vector(17 downto 0); + signal fifo_rdequeue_i : std_logic; + signal fifo_rpacket_complete_i : std_logic; + signal fifo_rpacket_complete_ack_i : std_logic; + + signal fifo_wdata_i : std_logic_vector(17 downto 0) := (others => '0'); + signal fifo_waddr_store_i : std_logic; + signal fifo_waddr_restore_i : std_logic; + signal fifo_wenqueue_i : std_logic; + signal fifo_wpacket_complete_i : std_logic; + signal fifo_wfull_i : std_logic; + + signal dec_evt_info_i : std_logic_vector(31 downto 0); + signal dec_length_i : std_logic_vector(15 downto 0); + signal dec_source_i : std_logic_vector(15 downto 0); + signal dec_data_i : std_logic_vector(15 downto 0); + + signal dec_reset_i : std_logic; + signal dec_issue_reset_i: std_logic; + signal dec_data_read_i : std_logic; + signal dec_error_i : std_logic; + signal dec_actice_i : std_logic; + signal dec_data_ready_i : std_logic; + + + signal : std_logic; + signal : std_logic; + signal : std_logic; + + begin + GBE_CTS_NUMBER_OUT <= HUB_CTS_NUMBER_IN; + GBE_CTS_CODE_OUT <= HUB_CTS_CODE_IN; + GBE_CTS_INFORMATION_OUT <= HUB_CTS_INFORMATION_IN; + GBE_CTS_READOUT_TYPE_OUT <= HUB_CTS_READOUT_TYPE_IN; + GBE_CTS_START_READOUT_OUT <= HUB_CTS_START_READOUT_IN; + GBE_FEE_DATA_OUT <= HUB_FEE_DATA_IN; + GBE_FEE_DATAREADY_OUT <= HUB_FEE_DATAREADY_IN; + GBE_FEE_STATUS_BITS_OUT <= HUB_FEE_STATUS_BITS_IN; + GBE_FEE_BUSY_OUT <= HUB_FEE_BUSY_IN; + + HUB_FEE_READ_OUT <= GBE_FEE_READ_IN; + HUB_CTS_READOUT_FINISHED_OUT <= GBE_CTS_READOUT_FINISHED_IN; + HUB_CTS_STATUS_BITS_OUT <= GBE_CTS_STATUS_BITS_IN; + + THE_DECODER: CBMNET_READOUT_TRBNET_DECODER + port map ( + -- TrbNet + CLK_IN => CLK_IN, -- in std_logic; + RESET_IN => dec_reset_i, -- in std_logic; + + -- connect to hub + HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, -- in std_logic; + HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, -- out std_logic; --no more data, end transfer, send TRM + HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, -- in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, -- in std_logic; + GBE_FEE_READ_IN => GBE_FEE_READ_IN, -- in std_logic; + + -- Decode + DEC_EVT_INFO_OUT => dec_evt_info_i, -- out std_logic_vector(31 downto 0); + DEC_LENGTH_OUT => dec_length_i, -- out std_logic_vector(15 downto 0); + DEC_SOURCE_OUT => dec_source_i, -- out std_logic_vector(15 downto 0); + DEC_DATA_OUT => dec_data_i, -- out std_logic_vector(15 downto 0); + DEC_DATA_READY_OUT => dec_data_ready_i, -- out std_logic; + DEC_DATA_READ_IN => dec_data_read_i, -- in std_logic; + + DEC_ACTIVE_OUT => dec_actice_i, -- out std_logic; + DEC_ERROR_OUT => dec_error_i, -- out std_logic; + + DEBUG_OUT => open -- out std_logic_vector(31 downto 0); + ); + dec_reset_i <= RESET_IN or dec_issue_reset_i; + + THE_PACKER: CBMNET_READOUT_EVENT_PACKER + port map ( + -- TrbNet + CLK_IN => CLK_IN, -- in std_logic; + RESET_IN => RESET_IN, -- in std_logic; + -- connect to hub + HUB_CTS_NUMBER_IN => HUB_CTS_NUMBER_IN, -- in std_logic_vector (15 downto 0); + HUB_CTS_CODE_IN => HUB_CTS_CODE_IN, -- in std_logic_vector (7 downto 0); + HUB_CTS_INFORMATION_IN => HUB_CTS_INFORMATION_IN, -- in std_logic_vector (7 downto 0); + HUB_CTS_READOUT_TYPE_IN => HUB_CTS_READOUT_TYPE_IN, -- in std_logic_vector (3 downto 0); + HUB_FEE_STATUS_BITS_IN => HUB_FEE_STATUS_BITS_IN, -- in std_logic_vector (31 downto 0); + + + -- connect to decoder + DEC_EVT_INFO_IN => dec_evt_info_i, -- in std_logic_vector(31 downto 0); + DEC_LENGTH_IN => dec_length_i, -- in std_logic_vector(15 downto 0); + DEC_SOURCE_IN => dec_source_i, -- in std_logic_vector(15 downto 0); + DEC_DATA_IN => dec_data_i, -- in std_logic_vector(15 downto 0); + DEC_DATA_READY_IN => dec_data_ready_i, -- in std_logic; + DEC_ACTIVE_IN => dec_actice_i, -- in std_logic; + DEC_ERROR_IN => dec_error_i, -- in std_logic; + + DEC_DATA_READ_OUT => dec_data_read_i, -- out std_logic; + DEC_RESET_OUT => dec_issue_reset_i, -- out std_logic; + + -- connect to fifo + WADDR_STORE_OUT => fifo_waddr_store_i, -- out std_logic; + WADDR_RESTORE_OUT => fifo_waddr_restore_i, -- out std_logic; + WDATA_OUT => fifo_wdata_i, -- out std_logic_vector(17 downto 0); + WENQUEUE_OUT => fifo_wenqueue_i, -- out std_logic; + WPACKET_COMPLETE_OUT=> fifo_wpacket_complete_i, -- out std_logic; + WFULL_IN => fifo_wfull_i, -- in std_logic; + + DEBUG_OUT => open -- out std_logic_vector(31 downto 0) + ); + + THE_READOUT_FIFO: CBMNET_READOUT_FIFO + generic map ( + ADDR_WIDTH => 10, + WATERMARK => 2 + ) port map ( + -- write port + WCLK_IN => CLK_IN, -- in std_logic; -- not faster than rclk_in + WRESET_IN => RESET_IN, -- in std_logic; + + WADDR_STORE_IN => fifo_waddr_store_i, -- in std_logic; + WADDR_RESTORE_IN => fifo_waddr_restore_i, -- in std_logic; + + WDATA_IN => fifo_wdata_i, -- in std_logic_vector(17 downto 0); + WENQUEUE_IN => fifo_wenqueue_i, -- in std_logic; + WPACKET_COMPLETE_IN => fifo_wpacket_complete_i, -- in std_logic; + + WALMOST_FULL_OUT => open, -- out std_logic; + WFULL_OUT => fifo_wfull_i, -- out std_logic; + + -- read port + RCLK_IN => CBMNET_CLK_IN, -- in std_logic; + RRESET_IN => CBMNET_RESET_IN, -- in std_logic; -- has to active at least two clocks AFTER (or while) write port was (is being) initialised + + RDATA_OUT => fifo_rdata_i, -- out std_logic_vector(17 downto 0); + RDEQUEUE_IN => fifo_rdequeue_i, -- in std_logic; + + RPACKET_COMPLETE_OUT => fifo_rpacket_complete_i, -- out std_logic; -- atleast one packet is completed in fifo + RPACKET_COMPLETE_ACK_IN => fifo_rpacket_complete_ack_i -- in std_logic -- mark one event as dealt with (effectively decrease number of completed packets by one) + ); + + THE_TX_FSM: CBMNET_READOUT_TX_FSM is + port map ( + CLK_IN => CBMNET_CLK_IN, -- in std_logic; + RESET_IN => CBMNET_RESET_IN, -- in std_logic; + + -- fifo + FIFO_DATA_IN => fifo_rdata_i(15 downto 0), -- in std_logic_vector(15 downto 0); + FIFO_DEQUEUE_OUT => fifo_rdequeue_i, -- out std_logic; + FIFO_PACKET_COMPLETE_IN => fifo_rpacket_complete_i, -- in std_logic; + FIFO_PACKET_COMPLETE_ACK_OUT => fifo_rpacket_complete_ack_i, -- out std_logic; + + -- 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_DATA_OUT => CBMNET_DATA2SEND_DATA_OUT -- out std_logic_vector(15 downto 0) + ); + end architecture; diff --git a/cbmnet/code/cbmnet_readout_event_packer.vhd b/cbmnet/code/cbmnet_readout_event_packer.vhd new file mode 100644 index 0000000..409a890 --- /dev/null +++ b/cbmnet/code/cbmnet_readout_event_packer.vhd @@ -0,0 +1,157 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +entity CBMNET_READOUT_EVENT_PACKER is + port ( + -- TrbNet + CLK_IN : in std_logic; + RESET_IN : in 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_FEE_STATUS_BITS_IN : in std_logic_vector (31 downto 0); + + + -- connect to decoder + DEC_EVT_INFO_IN : in std_logic_vector(31 downto 0); + DEC_LENGTH_IN : in std_logic_vector(15 downto 0); + DEC_SOURCE_IN : in std_logic_vector(15 downto 0); + DEC_DATA_IN : in std_logic_vector(15 downto 0); + DEC_DATA_READY_IN : in std_logic; + DEC_ACTIVE_IN : in std_logic; + DEC_ERROR_IN : in std_logic; + + DEC_DATA_READ_OUT : out std_logic; + DEC_RESET_OUT : out std_logic; + + -- connect to fifo + WADDR_STORE_OUT : out std_logic; + WADDR_RESTORE_OUT: out std_logic; + WDATA_OUT : out std_logic_vector(17 downto 0); + WENQUEUE_OUT : out std_logic; + WPACKET_COMPLETE_OUT: out std_logic; + WALMOST_FULL_IN : in std_logic; + WFULL_IN : in std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture cbmnet_readout_event_packer_arch of CBMNET_READOUT_EVENT_PACKER is + type FSM_STATES_T is ( + IDLE, + HDR_SIZE_H, HDR_SIZE_L, + HDR_DECODING_H, HDR_DECODING_L, + HDR_ID_H, HDR_ID_L, + HDR_NUMBER_H, HDR_NUMBER_L, + PAYLOAD, + FTR_TRAILER_H, FTR_TRAILER_L, + FTR_STATUS_H, FTR_STATUS_L + ); + + signal fsm_i : FSM_STATES_T; + signal header_data_i : std_logic_vector(15 downto 0); + signal header_enqueue_i : std_logic; +begin + THE_PACKER: process is + begin + wait until rising_edge(CLK_IN); + + WADDR_STORE_OUT <= '0'; + WADDR_RESTORE_OUT <= '0'; + DEC_RESET_OUT <= '0'; + copy_payload_i <= '0'; + header_data_i <= (others => '-'); + header_enqueue_i <= '0'; + WPACKET_COMPLETE_OUT <= '0'; + + if RESET_IN='1' then + fsm_i <= IDLE; + + elsif fsm_i /= IDLE and (DEC_ERROR_IN = '1' or WFULL_IN = '1') then + WADDR_RESTORE_OUT <= '1'; + DEC_RESET_OUT <= '1'; + fsm_i <= IDLE; + + else + case(fsm_i) is + when IDLE => + if DEC_ACTIVE_IN='1' then + WADDR_STORE_OUT <= '1'; + fsm_i <= HDR_SIZE_H; + end if; + + when HDR_SIZE_H => + header_data_i <= x"0000"; + header_enqueue_i <= '1'; + fsm_i <= HDR_SIZE_L; + when HDR_SIZE_L => + header_data_i <= DEC_LENGTH_IN; + header_enqueue_i <= '1'; + fsm_i <= HDR_DECODING_H; + + when HDR_DECODING_H => + header_data_i <= x"0003"; + header_enqueue_i <= '1'; + fsm_i <= HDR_DECODING_L; + when HDR_DECODING_L => + header_data_i <= x"000" & HUB_CTS_READOUT_TYPE_IN; + header_enqueue_i <= '1'; + fsm_i <= HDR_ID_H; + + when HDR_ID_H => + header_data_i <= x"0000"; + header_enqueue_i <= '1'; + fsm_i <= HDR_ID_L; + when HDR_ID_L => + header_data_i <= x"beaf"; + header_enqueue_i <= '1'; + fsm_i <= HDR_NUMBER_H; + + when HDR_NUMBER_H => + header_data_i <= x"00" & HUB_CTS_NUMBER_IN(15 downto 8); + header_enqueue_i <= '1'; + fsm_i <= HDR_NUMBER_L; + when HDR_NUMBER_L => + header_data_i <= HUB_CTS_NUMBER_IN(7 downto 0) & HUB_CTS_CODE_IN; + header_enqueue_i <= '1'; + fsm_i <= HDR_SIZE_L; + + when PAYLOAD => + if DEC_ACTIVE_IN = '0' then + fsm_i <= FTR_TRAILER_H; + else + copy_payload_i <= '1'; + end if; + + when FTR_TRAILER_H => + header_data_i <= x"0001"; + header_enqueue_i <= '1'; + fsm_i <= FTR_TRAILER_L; + when FTR_TRAILER_L => + header_data_i <= x"5555"; + header_enqueue_i <= '1'; + fsm_i <= FTR_STATUS_H; + + when FTR_STATUS_H => + header_data_i <= x"0001"; + header_enqueue_i <= '1'; + fsm_i <= FTR_STATUS_L; + when FTR_STATUS_L => + header_data_i <= x"5555"; + header_enqueue_i <= '1'; + WPACKET_COMPLETE_OUT <= '1'; + fsm_i <= IDLE; + + end case; + end if; + end process; + + WDATA_OUT <= DEC_DATA_IN when copy_payload_i='1' else header_data_i; + WENQUEUE_OUT <= header_data_i or DEC_DATA_READY_IN; + DEC_DATA_READ_OUT <= copy_payload_i and DEC_DATA_READY_IN; +end architecture; \ No newline at end of file diff --git a/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd b/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd new file mode 100644 index 0000000..e2e8981 --- /dev/null +++ b/cbmnet/code/cbmnet_readout_trbnet_decoder.vhd @@ -0,0 +1,210 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +-- receives data stream from hub and extracts header information +-- payload is then stored in an 16 word fifo, which gives the event packer roughly 8 cycles grace time +-- (8 words are required for the header structure expected from the event builders) + +-- DEC_ACTIVE_OUT is asserted as soon as DEC_EVT_INFO_OUT, DEC_LENGTH_OUT and DEC_SOURCE_OUT are valid +-- Once DEC_ERROR_OUT is asserted at least one word was lost and no gurantees for correct operations +-- are given. In this case, discarding of the event and reset of the decoder are recommended +entity CBMNET_READOUT_TRBNET_DECODER is + port ( + -- TrbNet + CLK_IN : in std_logic; + RESET_IN : in std_logic; + + -- connect to hub + HUB_CTS_START_READOUT_IN : in std_logic; + HUB_CTS_READOUT_FINISHED_OUT : out std_logic; --no more data, end transfer, send TRM + HUB_FEE_DATA_IN : in std_logic_vector (15 downto 0); + HUB_FEE_DATAREADY_IN : in std_logic; + GBE_FEE_READ_IN : in std_logic; + + -- Decode + DEC_EVT_INFO_OUT : out std_logic_vector(31 downto 0); + DEC_LENGTH_OUT : out std_logic_vector(15 downto 0); + DEC_SOURCE_OUT : out std_logic_vector(15 downto 0); + DEC_DATA_OUT : out std_logic_vector(15 downto 0); + DEC_DATA_READY_OUT : out std_logic; + DEC_DATA_READ_IN : in std_logic; + + DEC_ACTIVE_OUT : out std_logic; + DEC_ERROR_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture cbmnet_readout_trbnet_decoder_arch of CBMNET_READOUT_TRBNET_DECODER is + component lattice_ecp3_fifo_16x16_dualport is + port ( + Data: in std_logic_vector(15 downto 0); + WrClock: in std_logic; + RdClock: in std_logic; + WrEn: in std_logic; + RdEn: in std_logic; + Reset: in std_logic; + RPReset: in std_logic; + Q: out std_logic_vector(15 downto 0); + Empty: out std_logic; + Full: out std_logic; + AlmostFull: out std_logic + ); + end component; + + type FSM_STATES_T is (WAIT_FOR_IDLE, IDLE, RECV_EVT_INFO_H, RECV_EVT_INFO_L, RECV_EVT_LENGTH, RECV_EVT_SOURCE, RECV_PAYLOAD, ERROR_COND); + signal fsm_i : FSM_STATES_T; + + signal data_i : std_logic_vector(15 downto 0); + signal dec_evt_info_i : std_logic_vector(31 downto 0); + signal dec_length_i : std_logic_vector(15 downto 0); + signal dec_source_i : std_logic_vector(15 downto 0); + signal dec_error_i : std_logic; + + signal word_counter_i : unsigned(15 downto 0); + signal word_counter_set_i : std_logic; + signal word_counter_done_i : std_logic; + + signal read_word_i : std_logic; + + signal fifo_active_i : std_logic; + signal fifo_enqueue_i : std_logic; + signal fifo_full_i : std_logic; + signal fifo_empty_i : std_logic; + + signal fifo_data_i : std_logic_vector(15 downto 0); +begin + data_i <= HUB_FEE_DATA_IN; + + THE_FSM: process is + begin + wait until rising_edge(CLK_IN); + + fifo_active_i <= '0'; + DEC_ACTIVE_OUT <= '0'; + word_counter_set_i <= '0'; + dec_error_i <= dec_error_i or not HUB_CTS_START_READOUT_IN; + + if RESET_IN = '1' then + fsm_i <= WAIT_FOR_IDLE; + dec_error_i <= '0'; + + else + case(fsm_i) is + when WAIT_FOR_IDLE => + DEBUG_OUT(3 downto 0) <= x"0"; + if HUB_CTS_START_READOUT_IN = '0' then + fsm_i <= IDLE; + end if; + + when IDLE => + DEBUG_OUT(3 downto 0) <= x"1"; + dec_error_i <= '0'; + if HUB_CTS_START_READOUT_IN = '1' then + fsm_i <= RECV_EVT_INFO_H; + end if; + + when RECV_EVT_INFO_H => + DEBUG_OUT(3 downto 0) <= x"2"; + if read_word_i = '1' then + dec_evt_info_i(31 downto 16) <= data_i; + fsm_i <= RECV_EVT_INFO_L; + end if; + + when RECV_EVT_INFO_L => + DEBUG_OUT(3 downto 0) <= x"3"; + if read_word_i = '1' then + dec_evt_info_i(15 downto 0) <= data_i; + fsm_i <= RECV_EVT_LENGTH; + end if; + + when RECV_EVT_LENGTH => + DEBUG_OUT(3 downto 0) <= x"4"; + word_counter_set_i <= '1'; + if read_word_i = '1' then + dec_length_i <= data_i; + fsm_i <= RECV_EVT_SOURCE; + end if; + + when RECV_EVT_SOURCE => + DEBUG_OUT(3 downto 0) <= x"5"; + if read_word_i = '1' then + dec_source_i <= data_i; + fsm_i <= RECV_PAYLOAD; + fifo_active_i <= '1'; + end if; + + when RECV_PAYLOAD => + DEBUG_OUT(3 downto 0) <= x"6"; + fifo_active_i <= '1'; + DEC_ACTIVE_OUT <= '1'; + + if fifo_full_i = '1' and read_word_i = '1' then + fsm_i <= ERROR_COND; + end if; + + if fifo_empty_i = '1' and word_counter_done_i = '1' then + fsm_i <= WAIT_FOR_IDLE; + end if; + + when others => -- error cond + DEBUG_OUT(3 downto 0) <= x"7"; + dec_error_i <= '1'; + + end case; + end if; + + DEBUG_OUT(3 downto 0) <= x"0"; + end process; + + + THE_COUNTER: process is + begin + wait until rising_edge(CLK_IN); + + if word_counter_set_i = '1' then + word_counter_i <= UNSIGNED("0" & dec_length_i(15 downto 1)); + + elsif word_counter_done_i = '0' and read_word_i = '1' then + word_counter_i <= word_counter_i - 1; + + end if; + + DEBUG_OUT(31 downto 16) <= STD_LOGIC_VECTOR(word_counter_i); + end process; + + word_counter_done_i <= '1' when word_counter_i = x"0002" else '0'; + + THE_FIFO: lattice_ecp3_fifo_16x16_dualport + port map ( + WrClock => CLK_IN, -- in std_logic; + RdClock => CLK_IN, -- in std_logic; + Reset => RESET_IN, -- in std_logic; + RPReset => RESET_IN, -- in std_logic; + + Data => HUB_FEE_DATA_IN, -- in std_logic_vector(17 downto 0); + WrEn => fifo_enqueue_i, -- in std_logic; + + RdEn => DEC_DATA_READ_IN, -- in std_logic; + Q => fifo_data_i, -- out std_logic_vector(17 downto 0); + + Empty => fifo_empty_i, -- out std_logic; + Full => fifo_full_i, -- out std_logic; + AlmostFull => open -- out std_logic + ); + + read_word_i <= HUB_FEE_DATAREADY_IN and GBE_FEE_READ_IN; + fifo_enqueue_i <= fifo_active_i and read_word_i; + + DEC_ERROR_OUT <= dec_error_i; + DEC_LENGTH_OUT <= dec_length_i; + DEC_EVT_INFO_OUT <= dec_evt_info_i; + DEC_SOURCE_OUT <= dec_source_i; + DEC_DATA_READY_OUT <= not fifo_empty_i; + + DEC_DATA_OUT <= x"aaaa" when fifo_empty_i = '1' else fifo_data_i; + +end architecture; + diff --git a/cbmnet/code/cbmnet_readout_tx_fsm.vhd b/cbmnet/code/cbmnet_readout_tx_fsm.vhd index 00dbc03..d1801e7 100644 --- a/cbmnet/code/cbmnet_readout_tx_fsm.vhd +++ b/cbmnet/code/cbmnet_readout_tx_fsm.vhd @@ -70,7 +70,7 @@ begin when SEND_HEADER => if CBMNET_STOP_IN = '0' then - CBMNET_DATA_OUT(10 downto 0) <= STD_LOGIC_VECTOR(pack_num_i); + CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i); CBMNET_DATA_OUT(14) <= pack_start_i; CBMNET_DATA_OUT(15) <= pack_stop_i; CBMNET_START_OUT <= '1'; diff --git a/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd b/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd new file mode 100644 index 0000000..026d270 --- /dev/null +++ b/cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd @@ -0,0 +1,98 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + use ieee.math_real.all; + use work.cbmnet_interface_pkg.all; + +entity TB_CBMNET_READOUT_TRBNET_DECODER is +end TB_CBMNET_READOUT_TRBNET_DECODER; + +architecture TB of TB_CBMNET_READOUT_TRBNET_DECODER is + -- TrbNet +signal CLK_IN : std_logic := '1'; +signal RESET_IN : std_logic := '0'; + + -- connect to hub +signal HUB_CTS_START_READOUT_IN : std_logic := '0'; +signal HUB_CTS_READOUT_FINISHED_OUT : std_logic := '0'; --no more data, end transfer, send TRM +signal HUB_FEE_DATA_IN : std_logic_vector (15 downto 0) := (others => '0'); +signal HUB_FEE_DATAREADY_IN : std_logic := '0'; +signal GBE_FEE_READ_IN : std_logic := '0'; + + -- Decode +signal DEC_EVT_INFO_OUT : std_logic_vector(31 downto 0) := (others => '0'); +signal DEC_LENGTH_OUT : std_logic_vector(15 downto 0) := (others => '0'); +signal DEC_SOURCE_OUT : std_logic_vector(15 downto 0) := (others => '0'); +signal DEC_DATA_OUT : std_logic_vector(15 downto 0) := (others => '0'); +signal DEC_DATA_READY_OUT : std_logic := '0'; +signal DEC_DATA_READ_IN : std_logic := '0'; + +signal DEC_ACTIVE_OUT : std_logic := '0'; +signal DEC_ERROR_OUT : std_logic := '0'; + +signal DEBUG_OUT : std_logic_vector(31 downto 0) := (others => '0'); +begin + DUT: cbmnet_readout_trbnet_decoder + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + HUB_CTS_START_READOUT_IN => HUB_CTS_START_READOUT_IN, + HUB_CTS_READOUT_FINISHED_OUT => HUB_CTS_READOUT_FINISHED_OUT, + HUB_FEE_DATA_IN => HUB_FEE_DATA_IN, + HUB_FEE_DATAREADY_IN => HUB_FEE_DATAREADY_IN, + GBE_FEE_READ_IN => GBE_FEE_READ_IN, + DEC_EVT_INFO_OUT => DEC_EVT_INFO_OUT, + DEC_LENGTH_OUT => DEC_LENGTH_OUT, + DEC_SOURCE_OUT => DEC_SOURCE_OUT, + DEC_DATA_OUT => DEC_DATA_OUT, + DEC_DATA_READY_OUT => DEC_DATA_READY_OUT, + DEC_DATA_READ_IN => DEC_DATA_READ_IN, + DEC_ACTIVE_OUT => DEC_ACTIVE_OUT, + DEC_ERROR_OUT => DEC_ERROR_OUT, + DEBUG_OUT => DEBUG_OUT + ); + + CLK_IN <= not CLK_IN after 5 ns; + RESET_IN <= '1', '0' after 20 ns; + + TRBNET_EMU: process is + variable seed1, seed2: positive; -- seed values for random generator + variable rand: real; -- random real-number value in range 0 to 1.0 + variable int_rand: integer; -- random integer value in range 0..4095 + + begin + wait for 50 ns; + wait until rising_edge(CLK_IN); + + HUB_CTS_START_READOUT_IN <= '1'; + wait for 50 ns; + + for i in 0 to 16#40# + 2 loop + HUB_FEE_DATAREADY_IN <= '0'; + GBE_FEE_READ_IN <= '0'; + case(i) is + when 0 => HUB_FEE_DATA_IN <= x"beaf"; + when 1 => HUB_FEE_DATA_IN <= x"dead"; + when 2 => HUB_FEE_DATA_IN <= x"0080"; + when 3 => HUB_FEE_DATA_IN <= x"affe"; + when others => HUB_FEE_DATA_IN <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, 16)); + end case; + + UNIFORM(seed1, seed2, rand); + while (rand > 0.8) loop + UNIFORM(seed1, seed2, rand); + wait until rising_edge(CLK_IN); + end loop; + HUB_FEE_DATAREADY_IN <= '1'; + UNIFORM(seed1, seed2, rand); + while (rand > 0.7) loop + UNIFORM(seed1, seed2, rand); + wait until rising_edge(CLK_IN); + end loop; + GBE_FEE_READ_IN <= '1'; + wait until rising_edge(CLK_IN); + end loop; + + wait for 1 us; + end process; +end architecture; \ No newline at end of file -- 2.43.0