]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
CBMNet readout backup
authorManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 17 Jul 2014 20:55:34 +0000 (22:55 +0200)
committerManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 17 Jul 2014 20:55:34 +0000 (22:55 +0200)
cbmnet/code/cbmnet_interface_pkg.vhd
cbmnet/code/cbmnet_phy_ecp3.vhd
cbmnet/code/cbmnet_readout.vhd
cbmnet/code/cbmnet_readout_event_packer.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_readout_trbnet_decoder.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_readout_tx_fsm.vhd
cbmnet/code/tb_cbmnet_readout_trbnet_decoder.vhd [new file with mode: 0644]

index c36532eae3bfa20d44a1233c7e1715f91ee2fa1d..8a810d6185b0f0ec2c67cbb8206ec82e1271e828 100644 (file)
@@ -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
index 1e5f8eadaf69e70fc9eb3ab6a35ee762351b4b89..a5b626e4dac70483524f2604b6eb1378858fed1f 100755 (executable)
@@ -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;
index c22bfc304d5a6da3f7b46663af7e4c7e284d49cb..370bb61b8e5fb65dec37ed099bbaca6150103292 100644 (file)
@@ -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 (file)
index 0000000..409a890
--- /dev/null
@@ -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 (file)
index 0000000..e2e8981
--- /dev/null
@@ -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;
+
index 00dbc033555a8b11f0d8da4ac0952d98903b07a8..d1801e756573aec73170cd2d6a7025fefbac9a0d 100644 (file)
@@ -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 (file)
index 0000000..026d270
--- /dev/null
@@ -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