]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
CBMNet: data_stop-related timing problem in combination with slow fifo required addit...
authorManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 7 Aug 2014 17:33:32 +0000 (19:33 +0200)
committerManuel Penschuck <manuel.penschuck@stud.uni-frankfurt.de>
Thu, 7 Aug 2014 17:33:32 +0000 (19:33 +0200)
12 files changed:
cbmnet/code/cbmnet_interface_pkg.vhd
cbmnet/code/cbmnet_readout.vhd
cbmnet/code/cbmnet_readout_fifo.vhd
cbmnet/code/cbmnet_readout_frame_packer.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_readout_obuf.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_readout_trbnet_decoder.vhd
cbmnet/code/cbmnet_readout_tx_fifo.vhd [new file with mode: 0644]
cbmnet/code/cbmnet_readout_tx_fsm.vhd [deleted file]
cbmnet/code/tb_cbmnet_logger.vhd
cbmnet/code/tb_cbmnet_readout.vhd
cbmnet/code/tb_cbmnet_readout2.vhd
cbmnet/test/check_frames.pl

index 7f9bcedbf623ebbaa53645493ac13edecc1564c2..6809235cc01fbf408c1397f60fe9c3eec748d741 100644 (file)
@@ -304,61 +304,6 @@ package cbmnet_interface_pkg is
          ctrl_rec_stop : out std_logic
       );
    end component;
-  
-   component CBMNET_READOUT_TX_FSM is
-      port (
-         CLK_IN   : in std_logic;
-         RESET_IN : in std_logic; 
-
-         -- fifo 
-         FIFO_DATA_IN   : in std_logic_vector(15 downto 0);
-         FIFO_DEQUEUE_OUT : out std_logic;
-         FIFO_PACKET_COMPLETE_IN : in std_logic;  
-         FIFO_PACKET_COMPLETE_ACK_OUT : out std_logic;
-
-         -- cbmnet
-         CBMNET_STOP_IN   : in std_logic;
-         CBMNET_START_OUT : out std_logic;
-         CBMNET_END_OUT   : out std_logic;
-         CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
-      
-         -- debug
-         DEBUG_OUT : out std_logic_vector(31 downto 0)
-      );
-   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 is
       port (
@@ -481,6 +426,103 @@ package cbmnet_interface_pkg is
       DEBUG_OUT                      : out std_logic_vector(31 downto 0)
    );
    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)
+         
+         DEBUG_OUT  : out std_logic_vector(31 downto 0)
+      );
+   end component;
+   
+   component CBMNET_READOUT_FRAME_PACKER is
+      port (
+         CLK_IN   : in std_logic;
+         RESET_IN : in std_logic; 
+
+         -- fifo 
+         FIFO_DATA_IN   : in std_logic_vector(15 downto 0);
+         FIFO_DEQUEUE_OUT : out std_logic;
+         FIFO_PACKET_COMPLETE_IN : in std_logic;  
+         FIFO_PACKET_COMPLETE_ACK_OUT : out std_logic;
+
+         -- cbmnet
+         CBMNET_STOP_IN   : in std_logic;
+         CBMNET_START_OUT : out std_logic;
+         CBMNET_END_OUT   : out std_logic;
+         CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
+      
+         -- debug
+         DEBUG_OUT : out std_logic_vector(31 downto 0)
+      );
+   end component;   
+   
+   component CBMNET_READOUT_OBUF is
+      port(
+         CLK_IN : std_logic;
+         RESET_IN : std_logic;
+
+         -- packer
+         PACKER_STOP_OUT  : out std_logic;
+         PACKER_START_IN  : in  std_logic;
+         PACKER_END_IN    : in  std_logic;
+         PACKER_DATA_IN   : in  std_logic_vector(15 downto 0);
+
+         -- cbmnet
+         CBMNET_STOP_IN   : in std_logic;
+         CBMNET_START_OUT : out std_logic;
+         CBMNET_END_OUT   : out std_logic;
+         CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
+         
+         DEBUG_OUT : out std_logic_vector(31 downto 0)
+      );
+   end component;
+   
+   component cbmnet_readout_tx_fifo is
+      port (
+         CLK_IN : in std_logic;
+         RESET_IN : in std_logic;
+         EMPTY_IN : in std_logic;   -- identical to reset_in
+         
+         DATA_IN  : in  std_logic_vector(15 downto 0);
+         DATA_OUT : out std_logic_vector(15 downto 0);
+         
+         ENQUEUE_IN : in std_logic;
+         DEQUEUE_IN : in std_logic;
+         
+         LAST_OUT : out std_logic;
+         
+         FILLED_IN : in std_logic;
+         FILLED_OUT : out std_logic
+      );
+   end component;   
 end package cbmnet_interface_pkg;
 
 package body cbmnet_interface_pkg is
index 3dc325024bd4fe7d2c038f42ae40354374010f5c..1a113e799c0400b7893f106bd3b53a6bcce5c74f 100644 (file)
@@ -60,6 +60,9 @@ entity CBMNET_READOUT is
 end entity;
 
 architecture cbmnet_readout_arch of CBMNET_READOUT is
+   signal reset_combined_i : std_logic;
+   signal reset_combined_125_i : std_logic;
+
 -- signals of readout chain (DECODER -> PACKER -> FIFO -> TX)
    signal fifo_rdata_i                : std_logic_vector(17 downto 0);
    signal fifo_rdequeue_i             : std_logic;
@@ -72,6 +75,7 @@ architecture cbmnet_readout_arch of CBMNET_READOUT is
    signal fifo_wenqueue_i         : std_logic;
    signal fifo_wpacket_complete_i : std_logic;
    signal fifo_wfull_i            : std_logic;
+   signal debug_fifo_i            : std_logic_vector(31 downto 0);
    
    signal dec_evt_info_i   : std_logic_vector(31 downto 0);
    signal dec_length_i     : std_logic_vector(15 downto 0);
@@ -88,9 +92,11 @@ architecture cbmnet_readout_arch of CBMNET_READOUT is
    signal pack_source_i    : std_logic_vector(15 downto 0);
 
 -- cbm strobe buffers
-   signal cbmnet_data2send_start_i : std_logic;
-   signal cbmnet_data2send_end_i   : std_logic;
-   signal cbmnet_data2send_data_i  : std_logic_vector(15 downto 0);
+   signal frame_packer_start_i : std_logic;
+   signal frame_packer_end_i   : std_logic;
+   signal frame_packer_data_i  : std_logic_vector(15 downto 0);
+   signal obuf_stop_i : std_logic;
+   
    signal cbmnet_link_active_in_buf_i : std_logic;
    
 -- stats and monitoring   
@@ -137,6 +143,25 @@ begin
    HUB_CTS_READOUT_FINISHED_OUT   <= GBE_CTS_READOUT_FINISHED_IN;
    HUB_CTS_STATUS_BITS_OUT        <= GBE_CTS_STATUS_BITS_IN;
    
+   proc_reset: process is
+      variable counter_v : integer range 0 to 15 := 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
+         counter_v := 0;
+      elsif counter_v /= 15 then
+         counter_v := counter_v + 1;
+      end if;
+      
+      reset_combined_125_i <= '1';
+      if counter_v = 15 then
+         reset_combined_125_i <= '0';
+      end if;
+   end process;
+   reset_combined_i <= reset_combined_125_i when rising_edge(CLK_IN);
+   
+   
    THE_DECODER: CBMNET_READOUT_TRBNET_DECODER
    port map (
    -- TrbNet
@@ -163,13 +188,13 @@ begin
       
       DEBUG_OUT                      => debug_decorder_i -- out std_logic_vector(31 downto 0);
    );
-   dec_reset_i <= RESET_IN or dec_issue_reset_i;
+   dec_reset_i <= reset_combined_i 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;
+      RESET_IN => reset_combined_i, -- in std_logic;
 
       -- connect to hub
       HUB_CTS_NUMBER_IN              => HUB_CTS_NUMBER_IN,       -- in  std_logic_vector (15 downto 0);
@@ -206,11 +231,11 @@ begin
    THE_READOUT_FIFO: CBMNET_READOUT_FIFO 
    generic map (
       ADDR_WIDTH => 12, -- 8kb ..
-      WATERMARK  => 2
+      WATERMARK  => 8
    ) port map (
       -- write port
       WCLK_IN   => CLK_IN,   -- in std_logic; -- not faster than rclk_in
-      WRESET_IN => RESET_IN, -- in std_logic;
+      WRESET_IN => reset_combined_i, -- in std_logic;
       
       WADDR_STORE_IN   => fifo_waddr_store_i,   -- in std_logic;
       WADDR_RESTORE_IN => fifo_waddr_restore_i, -- in std_logic;
@@ -219,24 +244,26 @@ begin
       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;
+      WALMOST_FULL_OUT => fifo_wfull_i,         -- out std_logic;
+      WFULL_OUT        => open, -- 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
+      RRESET_IN => reset_combined_125_i, -- 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)
+      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)
+      
+      DEBUG_OUT => debug_fifo_i
    );
    
-   THE_TX_FSM: CBMNET_READOUT_TX_FSM
+   THE_FRAME_PACKER: CBMNET_READOUT_FRAME_PACKER
    port map (
       CLK_IN   => CBMNET_CLK_IN,   -- in std_logic;
-      RESET_IN => CBMNET_RESET_IN, -- in std_logic; 
+      RESET_IN => reset_combined_i, -- in std_logic; 
 
       -- fifo 
       FIFO_DATA_IN                 => fifo_rdata_i(15 downto 0), -- in std_logic_vector(15 downto 0);
@@ -245,17 +272,33 @@ begin
       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_i, -- out std_logic;
-      CBMNET_END_OUT   => cbmnet_data2send_end_i,   -- out std_logic;
-      CBMNET_DATA_OUT  => cbmnet_data2send_data_i,   -- out std_logic_vector(15 downto 0)
+      CBMNET_STOP_IN   => obuf_stop_i,   -- in std_logic;
+      CBMNET_START_OUT => frame_packer_start_i, -- out std_logic;
+      CBMNET_END_OUT   => frame_packer_end_i,   -- out std_logic;
+      CBMNET_DATA_OUT  => frame_packer_data_i,   -- out std_logic_vector(15 downto 0)
       
       DEBUG_OUT => debug_tx_fsm_i
    );
    
-   CBMNET_DATA2SEND_DATA_OUT  <= cbmnet_data2send_data_i;
-   CBMNET_DATA2SEND_START_OUT <= cbmnet_data2send_start_i;
-   CBMNET_DATA2SEND_END_OUT   <= cbmnet_data2send_end_i;
+   THE_OBUF: CBMNET_READOUT_OBUF 
+   port map (
+      CLK_IN => CBMNET_CLK_IN, -- std_logic;
+      RESET_IN => reset_combined_125_i, -- std_logic;
+
+      -- packer
+      PACKER_STOP_OUT  => obuf_stop_i, -- out std_logic;
+      PACKER_START_IN  => frame_packer_start_i, -- in  std_logic;
+      PACKER_END_IN    => frame_packer_end_i, -- in  std_logic;
+      PACKER_DATA_IN   => frame_packer_data_i, -- in  std_logic_vector(15 downto 0);
+
+      -- 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);
+      
+      DEBUG_OUT => open -- out std_logic_vector(31 downto 0)
+   );
    
 ----------------------------------------
 -- Slow control and monitoring
@@ -270,7 +313,7 @@ begin
          cbm_stat_connections_i <= cbm_stat_connections_i + 1;
       end if;
       
-      if cbmnet_data2send_end_i = '1' and last_end_v = '0' then
+      if frame_packer_end_i = '1' and last_end_v = '0' then
          cbm_stat_num_packets_i <= cbm_stat_num_packets_i + 1;
       end if;
          
@@ -283,7 +326,7 @@ begin
       end if;
    
       last_link_active_v := CBMNET_LINK_ACTIVE_IN;
-      last_end_v := cbmnet_data2send_end_i;
+      last_end_v := frame_packer_end_i;
    end process;
    
    -- and cross over to TrbNet clock domain
@@ -323,25 +366,27 @@ begin
       
    -- read
       case addr is
-         when 16#0# => regio_data_status_i(0) <= cfg_enabled_i;
-         when 16#1# => regio_data_status_i(16 downto 0) <= cfg_source_override_i & cfg_source_i;
+         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#2# => regio_data_status_i <= std_logic_vector(stat_connections_i);
-         when 16#3# => regio_data_status_i <= std_logic_vector(stat_clks_dead_i);
-         when 16#4# => regio_data_status_i <= std_logic_vector(stat_num_send_completed_i);
-         when 16#5# => regio_data_status_i <= std_logic_vector(stat_num_packets_i);
-         when 16#6# => regio_data_status_i <= std_logic_vector(stat_num_recv_completed_i);
-         when 16#7# => regio_data_status_i <= std_logic_vector(stat_link_inactive_i);
-         when 16#8# => regio_data_status_i <= std_logic_vector(stat_num_packets_aborted_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#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);
          
          -- debug only ports
-         when 16#9# => regio_data_status_i <= debug_decorder_i;
-         when 16#a# => regio_data_status_i <= debug_packer_i;
-         when 16#b# => regio_data_status_i <= debug_tx_fsm_i;
-         when 16#c# => regio_data_status_i(1 downto 0) <= fifo_wfull_i & fifo_rpacket_complete_i;
-         when 16#d# => regio_data_status_i <= HUB_CTS_INFORMATION_IN & HUB_CTS_CODE_IN & HUB_CTS_NUMBER_IN;
-         when 16#e# => regio_data_status_i <= dec_evt_info_i;
-         when 16#f# => regio_data_status_i <= dec_source_i & dec_length_i;
+         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_tx_fsm_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_fifo_i;
          
          when others => regio_unkown_address_i <= REGIO_READ_ENABLE_IN;
       end case;
index 5c9701f2d0af777694606d299dc37412daaa716a..381d8a5ceb6d9762329acc9f236bb187865385cc 100644 (file)
@@ -6,7 +6,7 @@ library ieee;
 entity CBMNET_READOUT_FIFO is
    generic (
       ADDR_WIDTH : positive := 10;
-      WATERMARK  : positive := 2
+      WATERMARK  : positive := 4
    );
 
    port (
@@ -32,7 +32,9 @@ entity CBMNET_READOUT_FIFO is
       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)
+      RPACKET_COMPLETE_ACK_IN : in std_logic; -- mark one event as dealt with (effectively decrease number of completed packets by one)
+      
+      DEBUG_OUT : out std_logic_vector(31 downto 0)
    );
 end CBMNET_READOUT_FIFO;
 
@@ -52,11 +54,13 @@ begin
       variable last_full_v : std_logic := '1';
    begin
       wait until rising_edge(WCLK_IN);
-      if (wfull_i = '0' or last_full_v = '0') and WENQUEUE_IN = '1' then
+      if (wfull_i = '0' ) and WENQUEUE_IN = '1' then
          mem_i(to_integer(waddr_i)) <= WDATA_IN;
       end if;
       
-      last_full_v := wfull_i;
+      if WENQUEUE_IN='1' then
+         last_full_v := wfull_i;
+      end if;
    end process;
 
 -- Read Port
@@ -82,9 +86,11 @@ begin
             delta_v := delta_v + TO_UNSIGNED(1, delta_v'length);
          end if;
          
-         rpacket_counter_i <= rpacket_counter_i + delta_v -  TO_UNSIGNED(1, 1);
+         if rpacket_counter_i /= 0 or delta_v /= 0 then
+            rpacket_counter_i <= rpacket_counter_i + delta_v -  TO_UNSIGNED(1, 1);
+         end if;
          
-         if rpacket_counter_i /= 0 or delta_v = 2 then
+         if (rpacket_counter_i /= 0 or delta_v = 2) then
             RPACKET_COMPLETE_OUT <= '1';
          end if;
       end if;
@@ -107,7 +113,7 @@ begin
       
       raddr_i <= next_addr_v;
    end process;
-   RDATA_OUT <= mem_i(to_integer(raddr_i));
+   RDATA_OUT <= mem_i(to_integer(raddr_i)) when rising_edge(RCLK_IN);
 
 -- Write Port
    wread_pointer_i <= raddr_i when rising_edge(WCLK_IN);
@@ -116,10 +122,14 @@ begin
       wait until rising_edge(WCLK_IN);
       if WADDR_RESTORE_IN = '1' then
          waddr_i <= waddr_stored_i;
-      elsif wfull_i = '0' and WENQUEUE_IN = '1' then
+      elsif WENQUEUE_IN = '1' and wfull_i = '0' then
          waddr_i <= waddr_i + 1;
       end if;
    end process;
+   
+-- synopsys translate_off
+   assert not(WENQUEUE_IN='1' and wfull_i='1' and rising_edge(WCLK_IN)) report "Enqueued into full fifo" severity warning;
+-- synopsys translate_on
 
    WPROC_STORE_ADDR: process is
    begin
@@ -157,4 +167,12 @@ begin
    
    WALMOST_FULL_OUT <= walmost_full_i;
    WFULL_OUT <= wfull_i;
+   
+   WPROC_DEBUG: process is
+   begin
+      wait until rising_edge(WCLK_IN);
+      DEBUG_OUT <= (others => '0');
+      DEBUG_OUT(wwords_remaining_i'range) <= STD_LOGIC_VECTOR(wwords_remaining_i);
+      DEBUG_OUT(16+rpacket_counter_i'high downto 16) <= STD_LOGIC_VECTOR(rpacket_counter_i);
+   end process;
 end architecture;
\ No newline at end of file
diff --git a/cbmnet/code/cbmnet_readout_frame_packer.vhd b/cbmnet/code/cbmnet_readout_frame_packer.vhd
new file mode 100644 (file)
index 0000000..5301781
--- /dev/null
@@ -0,0 +1,233 @@
+library ieee;
+   use ieee.std_logic_1164.all;
+   use ieee.numeric_std.all;
+
+
+entity CBMNET_READOUT_FRAME_PACKER is
+   port (
+      CLK_IN   : in std_logic;
+      RESET_IN : in std_logic; 
+
+      -- fifo 
+      FIFO_DATA_IN   : in std_logic_vector(15 downto 0);
+      FIFO_DEQUEUE_OUT : out std_logic;
+      FIFO_PACKET_COMPLETE_IN : in std_logic;  
+      FIFO_PACKET_COMPLETE_ACK_OUT : out std_logic;
+
+      -- cbmnet
+      CBMNET_STOP_IN   : in std_logic;
+      CBMNET_START_OUT : out std_logic;
+      CBMNET_END_OUT   : out std_logic;
+      CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
+      
+      -- debug
+      DEBUG_OUT : out std_logic_vector(31 downto 0)
+   );
+end entity;
+
+architecture cbmnet_readout_frame_packer_arch of CBMNET_READOUT_FRAME_PACKER is
+   type FSM_STATES_T is (
+      IDLE,
+      SETUP_TRANSACTION, SETUP_TRANSACTION_WAIT, SETUP_TRANSACTION_FETCH_LENGTH_H, SETUP_TRANSACTION_FETCH_LENGTH_L, 
+      FIRST_FRAME_SEND_HDR, FIRST_FRAME_SEND_LENGTH_H,
+      BEGIN_FRAME_WAIT, BEGIN_FRAME, BEGIN_FRAME_PRE_WAIT0, BEGIN_FRAME_PRE_WAIT1, BEGIN_FRAME_PRE_WAIT2, SEND_HDR,
+      SEND_PAYLOAD, SEND_STOP_WORD,
+      COMPLETE_TRANSACTION, COMPLETE_TRANSACTION_WAIT
+   );
+   
+   type FSM_STATES_ENC_T is array(FSM_STATES_T) of std_logic_vector(3 downto 0);
+   constant fsm_state_enc_c : FSM_STATES_ENC_T := (
+      IDLE => x"0",
+      SETUP_TRANSACTION => x"1", SETUP_TRANSACTION_WAIT => x"2", SETUP_TRANSACTION_FETCH_LENGTH_H => x"3", SETUP_TRANSACTION_FETCH_LENGTH_L => x"4", 
+      FIRST_FRAME_SEND_HDR => x"5", FIRST_FRAME_SEND_LENGTH_H => x"6",
+      BEGIN_FRAME => x"7", SEND_HDR => x"8", BEGIN_FRAME_WAIT => x"c", BEGIN_FRAME_PRE_WAIT0 => x"d", BEGIN_FRAME_PRE_WAIT1 => x"d", BEGIN_FRAME_PRE_WAIT2 => x"d",
+      SEND_PAYLOAD => x"9", SEND_STOP_WORD => x"a",
+      COMPLETE_TRANSACTION => x"b", COMPLETE_TRANSACTION_WAIT => x"b"
+   );
+   
+   signal fsm_i : FSM_STATES_T;
+   
+   signal transaction_number_i : unsigned(15 downto 0);
+   signal frame_number_i       : unsigned( 6 downto 0); -- frame in current transaction
+   
+   signal remaining_words_in_transaction_i : unsigned(15 downto 0);
+   signal remaining_words_in_frame_i       : unsigned(15 downto 0);
+   signal remaining_words_to_dequeue_i     : unsigned(15 downto 0);
+
+   signal dequeue_i : std_logic;
+   
+   signal buf_length_h_i : std_logic_vector(15 downto 0);
+   
+begin
+
+   PROC_TX_CNTL: process is 
+      variable dequeue_forced_v : std_logic;
+      variable dequeue_if_allowed_v : std_logic;
+   begin
+      wait until rising_edge(CLK_IN);
+      
+      CBMNET_START_OUT <= '0';
+      CBMNET_END_OUT <= '0';
+      CBMNET_DATA_OUT <= FIFO_DATA_IN;
+      
+      dequeue_if_allowed_v := '0';
+      dequeue_forced_v := '0';
+      
+      FIFO_PACKET_COMPLETE_ACK_OUT <= '0';
+      
+      if RESET_IN = '1' then
+         fsm_i <= IDLE;
+         transaction_number_i <= (others => '0');
+         
+      else
+         case(fsm_i) is
+            when IDLE =>
+               if FIFO_PACKET_COMPLETE_IN='1' then
+                  fsm_i <= SETUP_TRANSACTION;
+               end if;
+            
+            when SETUP_TRANSACTION =>
+               frame_number_i <= (others => '0');
+               transaction_number_i <= transaction_number_i + 1;
+               dequeue_forced_v := '1';
+               fsm_i <= SETUP_TRANSACTION_WAIT;
+               
+            when SETUP_TRANSACTION_WAIT =>
+               fsm_i <= SETUP_TRANSACTION_FETCH_LENGTH_H;
+            
+            when SETUP_TRANSACTION_FETCH_LENGTH_H =>
+               buf_length_h_i <= FIFO_DATA_IN;
+               assert(FIFO_DATA_IN = x"0000");
+               fsm_i <= SETUP_TRANSACTION_FETCH_LENGTH_L;
+            
+            when SETUP_TRANSACTION_FETCH_LENGTH_L =>
+               remaining_words_in_transaction_i <= (others =>'0');
+               remaining_words_in_transaction_i(14 downto 0) <= UNSIGNED(FIFO_DATA_IN(15 downto 1));
+               remaining_words_to_dequeue_i <= (others =>'0');
+               remaining_words_to_dequeue_i(14 downto 0) <= UNSIGNED(FIFO_DATA_IN(15 downto 1)) - TO_UNSIGNED(1, 15);
+               assert(to_integer(UNSIGNED(FIFO_DATA_IN)) >= 24) report "TrbNet packet too short. Expect minimal length of 24 bytes.";
+               assert(to_integer(UNSIGNED(FIFO_DATA_IN)) < 4096) report "TrbNet packet too long. This module should support sending of transactions with upto 32kb data, but only 4kb transactions have been specified and tested";
+               fsm_i <= FIRST_FRAME_SEND_HDR;
+            
+            when FIRST_FRAME_SEND_HDR =>
+               CBMNET_DATA_OUT <= (others => '0');
+               remaining_words_in_frame_i <= TO_UNSIGNED(31, 16);
+               if remaining_words_in_transaction_i <= 31 then
+                  CBMNET_DATA_OUT(15) <= '1'; -- stop
+                  remaining_words_in_frame_i <= remaining_words_in_transaction_i;
+               end if;
+               CBMNET_DATA_OUT(14) <= '1'; -- start
+               CBMNET_DATA_OUT(11 downto 0) <= STD_LOGIC_VECTOR(transaction_number_i(11 downto 0));
+               
+               if CBMNET_STOP_IN='0' then
+                  dequeue_if_allowed_v := '1';
+                  CBMNET_START_OUT <= '1';
+                  fsm_i <= FIRST_FRAME_SEND_LENGTH_H;
+               end if;
+            
+            when FIRST_FRAME_SEND_LENGTH_H =>
+               CBMNET_DATA_OUT <= buf_length_h_i;
+               dequeue_if_allowed_v := '1';
+               remaining_words_in_frame_i <= remaining_words_in_frame_i - 1;
+               remaining_words_in_transaction_i <= remaining_words_in_transaction_i - 1;
+               fsm_i <= SEND_PAYLOAD;
+            
+            
+            when BEGIN_FRAME_PRE_WAIT0 =>
+               fsm_i <= BEGIN_FRAME_PRE_WAIT1;
+            when BEGIN_FRAME_PRE_WAIT1 =>
+               fsm_i <= BEGIN_FRAME_PRE_WAIT2;
+            when BEGIN_FRAME_PRE_WAIT2 =>
+               fsm_i <= BEGIN_FRAME;
+            
+            when BEGIN_FRAME =>
+               if CBMNET_STOP_IN='0' then
+                  dequeue_if_allowed_v := '1';
+                  fsm_i <= SEND_HDR;
+                  frame_number_i <= frame_number_i + 1;
+               end if;
+               
+            when BEGIN_FRAME_WAIT =>
+               dequeue_if_allowed_v := '1';
+               fsm_i <= SEND_HDR;
+            
+            when SEND_HDR =>
+               CBMNET_DATA_OUT <= (others => '0');
+               remaining_words_in_frame_i <= TO_UNSIGNED(31, 16);
+               
+               if remaining_words_in_transaction_i <= 31 then
+                  CBMNET_DATA_OUT(15) <= '1'; -- stop
+                  CBMNET_DATA_OUT(11 downto 0) <= STD_LOGIC_VECTOR(transaction_number_i(11 downto 0));
+                  
+                  if remaining_words_in_transaction_i <= 3  then
+                     remaining_words_in_frame_i <= TO_UNSIGNED(3, 16);
+                  else
+                     remaining_words_in_frame_i <= remaining_words_in_transaction_i;
+                  end if;
+                  
+               else
+                  CBMNET_DATA_OUT(11 downto 7) <= STD_LOGIC_VECTOR(transaction_number_i(4 downto 0));
+                  CBMNET_DATA_OUT(6 downto 0)  <= STD_LOGIC_VECTOR(frame_number_i(6 downto 0));
+               end if;
+
+               dequeue_if_allowed_v := '1';
+               CBMNET_START_OUT <= '1';
+               fsm_i <= SEND_PAYLOAD;
+            
+            when SEND_PAYLOAD =>
+               if remaining_words_in_transaction_i = 0 then
+                  CBMNET_DATA_OUT <= x"aaaa";
+               else
+                  remaining_words_in_transaction_i <= remaining_words_in_transaction_i - 1;
+               end if;
+            
+               remaining_words_in_frame_i <= remaining_words_in_frame_i - 1;
+               if remaining_words_in_frame_i > 3 then
+                  dequeue_if_allowed_v := '1';
+               end if;
+               
+               if remaining_words_in_frame_i = 2 then
+                  fsm_i <= SEND_STOP_WORD;
+               end if;
+                  
+            when SEND_STOP_WORD =>
+               if remaining_words_in_transaction_i = 0 then
+                  CBMNET_DATA_OUT <= x"aaaa";
+               else
+                  remaining_words_in_transaction_i <= remaining_words_in_transaction_i - 1;
+               end if;
+               remaining_words_in_frame_i <= remaining_words_in_frame_i - 1;
+               dequeue_if_allowed_v := '1';
+
+               CBMNET_END_OUT <= '1';
+               if remaining_words_in_transaction_i = 1 or remaining_words_in_transaction_i = 0 then
+                  fsm_i <= COMPLETE_TRANSACTION;
+                  FIFO_PACKET_COMPLETE_ACK_OUT <= '1';
+               else
+                  fsm_i <= BEGIN_FRAME_PRE_WAIT0;
+               end if;
+            
+            
+            when COMPLETE_TRANSACTION =>
+               assert(remaining_words_to_dequeue_i = 0) report "Fifo was not properly emptied";
+               fsm_i <= COMPLETE_TRANSACTION_WAIT;
+               
+            when COMPLETE_TRANSACTION_WAIT =>
+               fsm_i <= IDLE;
+            
+            
+         end case;
+         
+         dequeue_i <= dequeue_forced_v;
+         if dequeue_if_allowed_v = '1' and remaining_words_to_dequeue_i > 0 then
+            dequeue_i <= '1';
+            remaining_words_to_dequeue_i <= remaining_words_to_dequeue_i - 1;
+         end if;
+      end if;
+   end process;
+   
+   FIFO_DEQUEUE_OUT <= dequeue_i;
+   DEBUG_OUT(31 downto 4) <= (others => '0');
+   DEBUG_OUT(3 downto 0) <= fsm_state_enc_c(fsm_i);
+end architecture;
+
diff --git a/cbmnet/code/cbmnet_readout_obuf.vhd b/cbmnet/code/cbmnet_readout_obuf.vhd
new file mode 100644 (file)
index 0000000..134216d
--- /dev/null
@@ -0,0 +1,190 @@
+library ieee;
+   use ieee.std_logic_1164.all;
+   use ieee.numeric_std.all;
+   use work.cbmnet_interface_pkg.all;
+
+-- this small output buffer is necessary, as the CBMNet interface directly switches to streaming
+-- mode once it accepted a start flag. thus the latency between the main buffer over the frame packer to lp_top
+-- is to large to corretly implement the stop - flag.
+entity CBMNET_READOUT_OBUF is
+   port(
+      CLK_IN : std_logic;
+      RESET_IN : std_logic;
+
+      -- packer
+      PACKER_STOP_OUT  : out std_logic;
+      PACKER_START_IN  : in  std_logic;
+      PACKER_END_IN    : in  std_logic;
+      PACKER_DATA_IN   : in  std_logic_vector(15 downto 0);
+
+      -- cbmnet
+      CBMNET_STOP_IN   : in std_logic;
+      CBMNET_START_OUT : out std_logic;
+      CBMNET_END_OUT   : out std_logic;
+      CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
+      
+      DEBUG_OUT : out std_logic_vector(31 downto 0)
+   );
+end entity;
+
+architecture cbmnet_readout_obuf_arch of CBMNET_READOUT_OBUF is
+   signal read_fifo_i, read_fifo_next_i, write_fifo_i : integer range 0 to 1 := 0;
+   
+   signal fifo_empty_i      : std_logic_vector(1 downto 0);
+   signal fifo_enqueue_i    : std_logic_vector(1 downto 0);
+   signal fifo_dequeue_i    : std_logic_vector(1 downto 0);
+   signal fifo_last_i       : std_logic_vector(1 downto 0);
+   signal fifo_set_filled_i : std_logic_vector(1 downto 0);
+   signal fifo_get_filled_i : std_logic_vector(1 downto 0);
+   
+   signal fifo_read_data_i  : std_logic_vector(31 downto 0);
+   signal fifo_write_data_i : std_logic_vector(15 downto 0);
+   
+   signal fifo_deq_i : std_logic;
+
+   type WFSM_T is (OBTAIN_FREE_BUFFER, WAIT_FOR_START, WAIT_FOR_END, COMPLETE);
+   signal wfsm_i : WFSM_T;
+   
+   type RFSM_T is (OBTAIN_FULL_BUFFER, WAIT_WHILE_STOP, COPY, COMPLETE);
+   signal rfsm_i, rfsm_next_i : RFSM_T;
+begin
+   WPROC: process is
+   begin
+      wait until rising_edge(CLK_IN);
+      
+      fifo_enqueue_i <= "00";
+      fifo_set_filled_i <= "00";
+      PACKER_STOP_OUT <= '0';
+      
+      if RESET_IN='1' then
+         wfsm_i <= OBTAIN_FREE_BUFFER;
+        
+      else
+         case (wfsm_i) is
+            when OBTAIN_FREE_BUFFER =>
+               if fifo_get_filled_i(0) = '0' then
+                  write_fifo_i <= 0;
+                  wfsm_i <= WAIT_FOR_START;
+               elsif fifo_get_filled_i(1) = '0' then
+                  write_fifo_i <= 1;
+                  wfsm_i <= WAIT_FOR_START;
+               else
+                  PACKER_STOP_OUT <= '1';
+               end if;
+               
+            when WAIT_FOR_START =>
+               if PACKER_START_IN='1' then
+                  fifo_enqueue_i(write_fifo_i) <= '1';
+                  wfsm_i <= WAIT_FOR_END;
+               end if;
+               
+               
+            when WAIT_FOR_END =>
+               fifo_enqueue_i(write_fifo_i) <= '1';
+               if PACKER_END_IN='1' then
+                  fifo_set_filled_i(write_fifo_i) <= '1';
+                  wfsm_i <= COMPLETE;
+               end if;
+                  
+            when COMPLETE =>
+               PACKER_STOP_OUT <= '1';            
+               wfsm_i <= OBTAIN_FREE_BUFFER;
+            
+         end case;
+      end if;
+   end process;
+
+   RSYNC: process is
+   begin 
+      wait until rising_edge(CLK_IN);
+      
+      if RESET_IN='1' then 
+         rfsm_i <= OBTAIN_FULL_BUFFER;
+      else
+         rfsm_i <= rfsm_next_i;
+      end if;
+      read_fifo_i <= read_fifo_next_i;
+   end process;
+   
+   RASYNC: process(rfsm_i, fifo_get_filled_i, fifo_last_i, CBMNET_STOP_IN) is
+   begin
+      CBMNET_START_OUT <= '0';
+      CBMNET_END_OUT   <= '0';
+
+      fifo_deq_i <= '0';
+      rfsm_next_i <= rfsm_i;
+      read_fifo_next_i <= read_fifo_i;
+      fifo_empty_i <= "00";
+      
+      case(rfsm_i) is
+         when OBTAIN_FULL_BUFFER =>
+            if fifo_get_filled_i(0) = '1' then
+               read_fifo_next_i <= 0;
+               rfsm_next_i <= WAIT_WHILE_STOP;
+            elsif fifo_get_filled_i(1) = '1' then
+               read_fifo_next_i <= 1;
+               rfsm_next_i <= WAIT_WHILE_STOP;
+            end if;
+         
+         when WAIT_WHILE_STOP =>
+            CBMNET_START_OUT <= '1';
+            if CBMNET_STOP_IN='0' then
+               fifo_deq_i <= '1';
+               rfsm_next_i <= COPY;
+            end if;
+            
+         when COPY =>
+            fifo_deq_i <= '1';
+            if fifo_last_i(read_fifo_i)='1' 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;
+      end case;
+   end process;
+   
+   -- fifo multiplexer
+   fifo_dequeue_i <= "0" & fifo_deq_i when read_fifo_i=0 else fifo_deq_i&"0";   
+   CBMNET_DATA_OUT <= fifo_read_data_i(read_fifo_i*16 + 15 downto read_fifo_i*16);
+
+   THE_FIFO_0: CBMNET_READOUT_TX_FIFO
+   port map (
+      CLK_IN => CLK_IN, -- in std_logic;
+      RESET_IN => RESET_IN, -- in std_logic;
+      EMPTY_IN => fifo_empty_i(0), -- in std_logic;   -- identical to reset_in
+      
+      DATA_IN  => fifo_write_data_i, -- in  std_logic_vector(15 downto 0);
+      DATA_OUT => fifo_read_data_i(0*16 + 15 downto 0*16), -- out std_logic_vector(15 downto 0);
+      
+      ENQUEUE_IN => fifo_enqueue_i(0), -- in std_logic;
+      DEQUEUE_IN => fifo_dequeue_i(0), -- in std_logic;
+      
+      LAST_OUT => fifo_last_i(0), -- out std_logic;
+      
+      FILLED_IN => fifo_set_filled_i(0), -- in std_logic;
+      FILLED_OUT => fifo_get_filled_i(0) -- out std_logic;
+   );
+   
+   THE_FIFO_1: CBMNET_READOUT_TX_FIFO
+   port map (
+      CLK_IN => CLK_IN, -- in std_logic;
+      RESET_IN => RESET_IN, -- in std_logic;
+      EMPTY_IN => fifo_empty_i(1), -- in std_logic;   -- identical to reset_in
+      
+      DATA_IN  => fifo_write_data_i, -- in  std_logic_vector(15 downto 0);
+      DATA_OUT => fifo_read_data_i(1*16 + 15 downto 1*16), -- out std_logic_vector(15 downto 0);
+      
+      ENQUEUE_IN => fifo_enqueue_i(1), -- in std_logic;
+      DEQUEUE_IN => fifo_dequeue_i(1), -- in std_logic;
+      
+      LAST_OUT => fifo_last_i(1), -- out std_logic;
+      
+      FILLED_IN => fifo_set_filled_i(1), -- in std_logic;
+      FILLED_OUT => fifo_get_filled_i(1) -- out std_logic;
+   );
+   
+   fifo_write_data_i <= PACKER_DATA_IN when rising_edge(CLK_IN);
+end architecture;
\ No newline at end of file
index 4a7ad1f29bcc1a4116faf665c244dc214b15b83f..cf24f061e0510c8ef862cff51d95ada24b3a43a7 100644 (file)
@@ -38,22 +38,6 @@ entity CBMNET_READOUT_TRBNET_DECODER is
 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;
--- 
    constant FIFO_LENGTH_C : integer := 4;
    type FIFO_MEM_T is array(0 to 2**FIFO_LENGTH_C-1) of std_logic_vector(15 downto 0);
    signal fifo_mem_i : FIFO_MEM_T;
@@ -133,6 +117,9 @@ begin
                word_counter_set_i <= '1';
                if read_word_i = '1' then
                   dec_length_i <= data_i(13 downto 0) & "00";
+-- synopsys translate_off
+   assert data_i(13 downto 0) & "00" /= x"0000" report "TrbNet packet must not be of length 0" severity warning;
+-- synopsys translate_on
                   fsm_i <= RECV_EVT_SOURCE;
                end if;
          
diff --git a/cbmnet/code/cbmnet_readout_tx_fifo.vhd b/cbmnet/code/cbmnet_readout_tx_fifo.vhd
new file mode 100644 (file)
index 0000000..420316a
--- /dev/null
@@ -0,0 +1,63 @@
+library ieee;
+   use ieee.std_logic_1164.all;
+   use ieee.numeric_std.all;
+
+entity cbmnet_readout_tx_fifo is
+   port (
+      CLK_IN : in std_logic;
+      RESET_IN : in std_logic;
+      EMPTY_IN : in std_logic;   -- identical to reset_in
+      
+
+      DATA_IN  : in  std_logic_vector(15 downto 0);
+      DATA_OUT : out std_logic_vector(15 downto 0);
+      
+      ENQUEUE_IN : in std_logic;
+      DEQUEUE_IN : in std_logic;
+      
+      LAST_OUT : out std_logic;
+      
+      FILLED_IN : in std_logic;
+      FILLED_OUT : out std_logic
+   );
+end entity;
+
+architecture RTL of cbmnet_readout_tx_fifo is
+   type MEM_T is array(0 to 31) of std_logic_vector(15 downto 0);
+   signal mem_i : MEM_T;
+   
+   signal raddr_i, waddr_i : unsigned(5 downto 0);
+   signal filled_i : std_logic;
+begin
+
+   WPROC: process is
+   begin
+      wait until rising_edge(CLK_IN);
+      
+      if RESET_IN='1' or EMPTY_IN='1' then
+         waddr_i <= (others => '0');
+      elsif ENQUEUE_IN='1' then
+         mem_i(to_integer(waddr_i(4 downto 0))) <= DATA_IN;
+         if waddr_i /= "100000" then
+            waddr_i <= waddr_i + 1;
+         end if;
+      end if;
+   end process;
+   
+   RPROC: process is
+   begin
+      wait until rising_edge(CLK_IN);
+      
+      if RESET_IN='1' or EMPTY_IN='1' then
+         raddr_i <= (others => '0');
+      elsif DEQUEUE_IN='1' then
+         raddr_i <= raddr_i + 1;
+      end if;
+   end process;
+   
+   LAST_OUT <= '1' when raddr_i+1 >= waddr_i else '0';
+   DATA_OUT <= mem_i(to_integer(raddr_i(4 downto 0)));
+   
+   filled_i <= not(RESET_IN or EMPTY_IN) and (filled_i or FILLED_IN) when rising_edge(CLK_IN);
+   FILLED_OUT <= filled_i;
+end architecture;
\ No newline at end of file
diff --git a/cbmnet/code/cbmnet_readout_tx_fsm.vhd b/cbmnet/code/cbmnet_readout_tx_fsm.vhd
deleted file mode 100644 (file)
index 3f51b73..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-library ieee;
-   use ieee.std_logic_1164.all;
-   use ieee.numeric_std.all;
-
-
-entity CBMNET_READOUT_TX_FSM is
-   port (
-      CLK_IN   : in std_logic;
-      RESET_IN : in std_logic; 
-
-      -- fifo 
-      FIFO_DATA_IN   : in std_logic_vector(15 downto 0);
-      FIFO_DEQUEUE_OUT : out std_logic;
-      FIFO_PACKET_COMPLETE_IN : in std_logic;  
-      FIFO_PACKET_COMPLETE_ACK_OUT : out std_logic;
-
-      -- cbmnet
-      CBMNET_STOP_IN   : in std_logic;
-      CBMNET_START_OUT : out std_logic;
-      CBMNET_END_OUT   : out std_logic;
-      CBMNET_DATA_OUT  : out std_logic_vector(15 downto 0);
-      
-      -- debug
-      DEBUG_OUT : out std_logic_vector(31 downto 0)
-   );
-end entity;
-
-architecture cbmnet_readout_tx_fsm_arch of CBMNET_READOUT_TX_FSM is
-   constant PAYLOAD_PER_PACKET_C : integer := 62; -- bytes
-
-
-   type FSM_STATES_T is (WAIT_FOR_COMPL_PACKET, SETUP_TRANSACTION, SETUP_TRANSACTION_RECV_LENGTH, SETUP_SEND_START_HEADER, SEND_START_LENGTH_HIGH, SEND_START_LENGTH_LOW, SEND_HEADER, SEND_PAYLOAD, SEND_PACKET_GAP, FINISH_TRANSACTION, FINISH_WAIT1, FINISH_WAIT2);
-   signal fsm_i : FSM_STATES_T;
-   signal fsm_state_i : unsigned(3 downto 0);
-   
-   signal trans_num_i : unsigned(5 downto 0);
-   
-   signal buffer_bytes_length_high_i : std_logic_vector(15 downto 0) := x"0000";
-   signal trans_bytes_length_i : unsigned(15 downto 0) := x"0000";
-   signal trans_bytes_send_i   : unsigned(15 downto 0);
-   
-   signal pack_num_i : unsigned(5 downto 0);
-   signal pack_payload_words_i : unsigned(4 downto 0);
-   
-   signal pack_start_i, pack_stop_i : std_logic;
-   
-   signal trans_complete_i : std_logic;
-   
-
-
-begin
-   assert(buffer_bytes_length_high_i = x"0000");
-
-   PROC_TX_CNTL: process is 
-   begin
-      wait until rising_edge(CLK_IN);
-      
-      CBMNET_START_OUT <= '0';
-      CBMNET_END_OUT <= '0';
-      CBMNET_DATA_OUT <= FIFO_DATA_IN;
-      
-      FIFO_DEQUEUE_OUT <= '0';
-      FIFO_PACKET_COMPLETE_ACK_OUT <= '0';
-      
-      if RESET_IN = '1' then
-         fsm_i <= WAIT_FOR_COMPL_PACKET;
-         trans_num_i <= (others => '0');
-         fsm_state_i <= x"0";         
-         
-      else
-         case(fsm_i) is
-            when WAIT_FOR_COMPL_PACKET =>
-               fsm_state_i <= x"1";
-               if FIFO_PACKET_COMPLETE_IN = '1' then
-                  fsm_i <= SETUP_TRANSACTION;
-                  FIFO_DEQUEUE_OUT <= '1';
-               end if;
-                       
-            when SETUP_TRANSACTION =>
-               fsm_state_i <= x"2";
-               trans_bytes_send_i <= (others => '0');
-               pack_num_i <= (others => '0');
-               pack_start_i <= '1';
-               buffer_bytes_length_high_i <= FIFO_DATA_IN;
-               fsm_i <= SETUP_TRANSACTION_RECV_LENGTH;
-               
-            when SETUP_TRANSACTION_RECV_LENGTH =>
-               fsm_state_i <= x"7";
-               trans_bytes_send_i <= (others => '0');
-               trans_bytes_length_i <= UNSIGNED(FIFO_DATA_IN);
-               fsm_i <= SETUP_SEND_START_HEADER;
-               
-            when SETUP_SEND_START_HEADER =>
-               fsm_state_i <= x"8";
-               trans_bytes_send_i <= (others => '0');
-               pack_payload_words_i <= (others => '0');
-               CBMNET_DATA_OUT <= (others => '0');
-               CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i);
-               CBMNET_DATA_OUT(11 downto 6) <= STD_LOGIC_VECTOR(trans_num_i);
-               CBMNET_DATA_OUT(14) <= '1';
-               CBMNET_DATA_OUT(15) <= pack_stop_i;
-
-               if CBMNET_STOP_IN = '0' then
-                  CBMNET_START_OUT <= '1';
-                  fsm_i <= SEND_START_LENGTH_HIGH;
-               end if;
-               
-            when SEND_START_LENGTH_HIGH =>
-               fsm_state_i <= x"9";
-               pack_payload_words_i <= (others => '0');
-               trans_bytes_send_i   <= TO_UNSIGNED(4, 16); -- +2 so trans_complete computation becomes easier
-               pack_payload_words_i <= TO_UNSIGNED(1, 5);
-               CBMNET_DATA_OUT <= buffer_bytes_length_high_i;
-               fsm_i <= SEND_PAYLOAD;
-               FIFO_DEQUEUE_OUT <= '1';
-               
-            when SEND_START_LENGTH_LOW =>
-               fsm_state_i <= x"a";
-               CBMNET_DATA_OUT <= STD_LOGIC_VECTOR(trans_bytes_length_i);
-               fsm_i <= SEND_PAYLOAD;
-            
-            when SEND_HEADER =>
-               fsm_state_i <= x"3";
-               CBMNET_DATA_OUT <= (others => '0');
-               CBMNET_DATA_OUT( 5 downto 0) <= STD_LOGIC_VECTOR(pack_num_i);
-               CBMNET_DATA_OUT(11 downto 6) <= STD_LOGIC_VECTOR(trans_num_i);
-               CBMNET_DATA_OUT(14) <= '0';
-               CBMNET_DATA_OUT(15) <= pack_stop_i;
-
-               pack_payload_words_i <= (others => '0');
-
-               if CBMNET_STOP_IN = '0' then
-                  CBMNET_START_OUT <= '1';
-                  FIFO_DEQUEUE_OUT <= '1';
-                  fsm_i <= SEND_PAYLOAD;
-               end if;
-            
-            when SEND_PAYLOAD =>
-               fsm_state_i <= x"4";
-               if pack_payload_words_i = 30 or trans_complete_i = '1' then
-                  CBMNET_END_OUT <= '1';
-                  pack_num_i <= pack_num_i + 1;
-                  
-                  if trans_complete_i = '1' then
-                     fsm_i <= FINISH_TRANSACTION;
-                  else
-                     fsm_i <= SEND_PACKET_GAP;
-                  end if;
-                  
-               else
-                  FIFO_DEQUEUE_OUT <= '1';
-               end if;
-
-               pack_start_i <= '0';
-               pack_payload_words_i <= pack_payload_words_i + 1;
-               trans_bytes_send_i <= trans_bytes_send_i + 2;
-               
-               
-            when SEND_PACKET_GAP =>
-               fsm_state_i <= x"5";
-               fsm_i <= SEND_HEADER;
-            
-            when FINISH_TRANSACTION =>
-               fsm_state_i <= x"6";
-               FIFO_PACKET_COMPLETE_ACK_OUT <= '1';
-               trans_num_i <= trans_num_i + 1;
-               fsm_i <= FINISH_WAIT1;
-         
-            when FINISH_WAIT1 =>
-               fsm_state_i <= x"6";
-               fsm_i <= FINISH_WAIT2;
-            
-            when FINISH_WAIT2 =>
-               fsm_state_i <= x"6";
-               fsm_i <= WAIT_FOR_COMPL_PACKET;
-         
-         end case;
-      end if;
-   end process;
-
-   pack_stop_i <= '1' when trans_bytes_length_i - trans_bytes_send_i < PAYLOAD_PER_PACKET_C else '0';
-   trans_complete_i <= '1' when trans_bytes_length_i = trans_bytes_send_i  else '0';
-   
-   DEBUG_OUT(3 downto 0) <= STD_LOGIC_VECTOR(fsm_state_i);
-end architecture;
-
index d1b2a16c989ffe37dc2a121161602182a754f8b5..8ef92334051ece42f3b80a93690162584a7893c5 100644 (file)
@@ -33,7 +33,7 @@ begin
       variable frame_line_v  : line;
    begin
       wait until rising_edge(CLK_IN);
-      
+     
       if RESET_IN = '0' and LINK_ACTIVE_IN = '1' then
          case (fsm_i) is
             when IDLE =>
@@ -50,7 +50,7 @@ begin
                write(frame_line_v, " " & hstr(DATA2SEND_IN));
                word_count_i <= word_count_i + 1;
             
-               if DATA2SEND_STOP_IN = '1' then
+               if DATA2SEND_END_IN = '1' then
                   writeline(l_file, frame_line_v);
                   --println ("DATA(" & str(word_count_i*2) & ") :" & frame_str_i);
                   fsm_i <= IDLE;
@@ -63,4 +63,6 @@ begin
       end if;
    end process;
 
+   assert word_count_i <= 32 report "CBMNet frame must not be longer than 64 bytes" severity warning;
+   
 end architecture;
\ No newline at end of file
index fd39dd54ce2221164b62a3945d2af44ec6aafa9e..be4f476e0b4661449776beba06fc4da796852938 100644 (file)
@@ -79,9 +79,6 @@ begin
       HUB_CTS_READOUT_TYPE_IN <= x"e";
       GBE_CTS_STATUS_BITS_IN <= x"12345678";
       
-00:00:00:70:00:03:00:62:00:00:00:64:00:02:00:11:00:00:f3:c0:00:09:45:f7:
-00:12:f3:c0:20:06:f3:53:cf:0f:3c:7c:00:00:00:61:cf:0f:3c:7c:05:06:ac:6e:cf:0f:3c:7c:00:00:00:00:00:00:00:00:00:00:00:00:cf:0f:3c:7c:00:00:00:61:cf:0f:3c:7c:05:06:ac:6e:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
-00:01:55:55:00:00:00:01:
       wait until rising_edge(CLK_IN);
       wait until rising_edge(CLK_IN);
       wait until rising_edge(CLK_IN);
index a96e90a1faa0d069dab7676595e252b450924975..6374253b25d903f1532c8d565c5b9fb07fd0aacb 100644 (file)
@@ -1,8 +1,9 @@
 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_readout2 is
 end tb_cbmnet_readout2;
 
@@ -79,7 +80,7 @@ architecture TB of tb_cbmnet_readout2 is
    signal send_wait_threshold_i : unsigned(31 downto 0) := x"0000_0010";
 
    signal event_id : unsigned(15 downto 0) := x"0000";
-   signal send_length_i : unsigned(15 downto 0) := x"0010";
+   signal send_length_i : unsigned(15 downto 0) := x"0100";
    signal send_counter_i : unsigned(15 downto 0);
 
    signal send_enabled_i : std_logic := '0';
@@ -88,17 +89,25 @@ architecture TB of tb_cbmnet_readout2 is
    type TRB_FSM_T is (IDLE, START_READOUT, START_READOUT_WAIT, FEE_BUSY, SEND_EINF_H, SEND_EINF_L, SEND_LENGTH, SEND_SOURCE, SEND_SOURCE_WAIT, SEND_PAYLOAD_H, SEND_PAYLOAD_L, COMPL_WAIT, COMPL_NOT_BUSY_WAIT, EVT_WAIT);
    signal trb_fsm_i : TRB_FSM_T;
    
+   
+   -- FEEs
+   signal fee_cbm_data_from_link_i, flib_cbm_data2link_i, flib_cbm_data_from_link_i, fee_cbm_data2link_i : std_logic_vector(17 downto 0);
+   signal flib_cbm_serdes_ready_i, fee_cbm_serdes_ready_i, flib_cbm_link_active_i, fee_cbm_link_active_i : std_logic;
+   signal cbm_reset_n_i1, cbm_reset_n_i2 : std_logic;
+   signal flib_data_rec_i : std_logic_vector(15 downto 0);
+   signal flib_data_rec_start_i, flib_data_rec_end_i, flib_data_rec_stop_i : std_logic := '0';
+   
 begin
    REGIO_ADDR_IN <= (others => '0');
    REGIO_DATA_IN <= x"0000_0001";
    REGIO_WRITE_ENABLE_IN <= '1';
 
    CLK_IN <= not CLK_IN after 5 ns;
-   RESET_IN <= '1', '0' after 30 ns;
+   RESET_IN <= '1', '0' after 20 ns;
    
    CBMNET_CLK_IN <= not CBMNET_CLK_IN after 4 ns;
-   CBMNET_RESET_IN <= '1', '0' after 20 ns;
-   CBMNET_LINK_ACTIVE_IN <= '1';
+   CBMNET_RESET_IN <= '1', '0' after 40 ns;
+--    CBMNET_LINK_ACTIVE_IN <= '0', '1' after 50 us;
    
    gbe_fee_read_in <= '1';
    gbe_cts_status_bits_in <= x"beafc0de";
@@ -107,6 +116,12 @@ begin
    
    process is
       variable wait_cnt_v : integer range 0 to 15 := 0;
+
+      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 until rising_edge(CLK_IN);
       
@@ -215,10 +230,16 @@ begin
 
             send_wait_counter_i <= send_wait_counter_i + 1;
             if send_wait_counter_i >= UNSIGNED(send_wait_threshold_i) then
-               send_length_i(9 downto 0) <= send_length_i(9 downto 0) + 1;
-               if send_length_i = x"0000" then
-                  send_length_i <= x"0001";
-               end if;
+               --send_length_i(8 downto 0) <= send_length_i(8 downto 0) + 1;
+               --if send_length_i = x"01ff" then
+               --   send_length_i <= x"0001";
+               --end if;
+               
+               uniform(seed1, seed2, rand);
+               int_rand := 4+integer(trunc(rand*500.0));
+               --int_rand := 2;
+               send_length_i(9 downto 0) <= TO_UNSIGNED(int_rand, 10);
+               
                trb_fsm_i <= IDLE;
             end if;
             
@@ -227,19 +248,22 @@ begin
       
    
    PROC_CBMNET: process is
-      variable wait_dur : integer range 0 to 10000 := 250;
+      variable wait_dur : integer range 0 to 10000 := 4;
+      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
-      CBMNET_DATA2SEND_STOP_IN <= '0';
-      wait until falling_edge(CBMNET_DATA2SEND_END_OUT);
-      CBMNET_DATA2SEND_STOP_IN <= '1';
+      flib_data_rec_stop_i <= '0';
       wait until rising_edge(CBMNET_CLK_IN);
-      wait for wait_dur * 8 ns;
-      
-      if wait_dur = 10000 then
-         wait_dur := 0;
-      else
-         wait_dur := wait_dur + 1;
-      end if;
+      uniform(seed1, seed2, rand);
+      int_rand := 4+integer(trunc(rand*10000.0));
+      wait for int_rand * 8 ns;
+
+      flib_data_rec_stop_i <= '1';
+      wait until rising_edge(CBMNET_CLK_IN);
+      uniform(seed1, seed2, rand);
+      int_rand := 4+integer(trunc(rand*256.0));
+      wait for int_rand * 8 ns;
    end process;
 
    --GBE_FEE_READ_IN <= HUB_FEE_DATAREADY_IN;
@@ -297,6 +321,200 @@ begin
       CBMNET_DATA2SEND_END_OUT   => CBMNET_DATA2SEND_END_OUT,    -- out std_logic;
       CBMNET_DATA2SEND_DATA_OUT  =>CBMNET_DATA2SEND_DATA_OUT     -- out std_logic_vector(15 downto 0)
    );
+   CBMNET_LINK_ACTIVE_IN <= fee_cbm_link_active_i;
+   
+   
+   THE_FEE_ENDPOINT: lp_top 
+   generic map (
+      NUM_LANES => 1,
+      TX_SLAVE  => 0
+   )
+   port map (
+   -- Clk & Reset
+      clk => CBMNET_CLK_IN,
+      res_n => cbm_reset_n_i1,
+
+   -- Phy
+      data_from_link => fee_cbm_data_from_link_i,
+      data2link => fee_cbm_data2link_i,
+      link_activeovr => '0',
+      link_readyovr => '0', 
+      SERDES_ready => fee_cbm_serdes_ready_i,
+
+   -- CBMNet Interface
+      link_active => fee_cbm_link_active_i,
+      ctrl2send_stop => open,
+      ctrl2send_start => '0',
+      ctrl2send_end => '0',
+      ctrl2send => x"0000",
+      
+      data2send_stop(0) => CBMNET_DATA2SEND_STOP_IN,
+      data2send_start(0) => CBMNET_DATA2SEND_START_OUT,
+      data2send_end(0) => CBMNET_DATA2SEND_END_OUT,
+      data2send => CBMNET_DATA2SEND_DATA_OUT,
+      
+      dlm2send_va => '0',
+      dlm2send => x"0",
+      
+      dlm_rec_type => open,
+      dlm_rec_va => open,
+
+      data_rec => open,
+      data_rec_start => open,
+      data_rec_end => open,
+      data_rec_stop => "0",
+      
+      ctrl_rec => open,
+      ctrl_rec_start => open,
+      ctrl_rec_end => open,
+      ctrl_rec_stop => '0',
+      
+      -- diagnostics Lane0
+      crc_error_cntr_flag_0     => open,      --  out std_logic;
+      retrans_cntr_flag_0       => open,        --  out std_logic;
+      retrans_error_cntr_flag_0 => open,  --  out std_logic;
+      crc_error_cntr_0          => open,           --  out std_logic_vector(15 downto 0);
+      retrans_cntr_0            => open,             --  out std_logic_vector(15 downto 0);
+      retrans_error_cntr_0      => open,       --  out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_0      => '0',       --  in std_logic;
+      retrans_cntr_clr_0        => '0',         --  in std_logic;
+      retrans_error_cntr_clr_0  => '0',   --  in std_logic;
+
+      -- diagnostics Lane1
+      crc_error_cntr_flag_1     => open, -- out std_logic;
+      retrans_cntr_flag_1       => open, -- out std_logic;
+      retrans_error_cntr_flag_1 => open, -- out std_logic;
+      crc_error_cntr_1          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_1            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_1      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_1      => '0', -- in std_logic;   
+      retrans_cntr_clr_1        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_1  => '0', -- in std_logic; 
+
+      -- diagnostics Lane2
+      crc_error_cntr_flag_2     => open, -- out std_logic;
+      retrans_cntr_flag_2       => open, -- out std_logic;
+      retrans_error_cntr_flag_2 => open, -- out std_logic;
+      crc_error_cntr_2          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_2            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_2      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_2      => '0', -- in std_logic;   
+      retrans_cntr_clr_2        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_2  => '0', -- in std_logic; 
+
+      -- diagnostics Lane3
+      crc_error_cntr_flag_3     => open, -- out std_logic;
+      retrans_cntr_flag_3       => open, -- out std_logic;
+      retrans_error_cntr_flag_3 => open, -- out std_logic;
+      crc_error_cntr_3          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_3            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_3      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_3      => '0', -- in std_logic;   
+      retrans_cntr_clr_3        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_3  => '0'  -- in std_logic
+   );   
+   
+   fee_cbm_data_from_link_i  <= flib_cbm_data2link_i when rising_edge(CBMNET_CLK_IN);
+   flib_cbm_data_from_link_i <= fee_cbm_data2link_i  when rising_edge(CBMNET_CLK_IN);
+   
+   fee_cbm_serdes_ready_i <= '0', '1' after 100 ns;
+   flib_cbm_serdes_ready_i <= '0', '1' after 100 ns;
+
+   cbm_reset_n_i2 <= not CBMNET_RESET_IN;
+   cbm_reset_n_i1 <= transport not CBMNET_RESET_IN  after 40 ns;
+
+   THE_FLIB_ENDPOINT: lp_top 
+   generic map (
+      NUM_LANES => 1,
+      TX_SLAVE  => 0
+   )
+   port map (
+   -- Clk & Reset
+      clk => CBMNET_CLK_IN,
+      res_n => cbm_reset_n_i2,
+
+   -- Phy
+      data_from_link => flib_cbm_data_from_link_i,
+      data2link => flib_cbm_data2link_i,
+      link_activeovr => '0',
+      link_readyovr => '0', 
+      SERDES_ready => flib_cbm_serdes_ready_i,
+
+   -- CBMNet Interface
+      link_active => flib_cbm_link_active_i,
+      ctrl2send_stop => open,
+      ctrl2send_start => '0',
+      ctrl2send_end => '0',
+      ctrl2send => x"0000",
+      
+      data2send_stop => open,
+      data2send_start => "0",
+      data2send_end => "0",
+      data2send => x"0000",
+      
+      dlm2send_va => '0',
+      dlm2send => x"0",
+      
+      dlm_rec_type => open,
+      dlm_rec_va => open,
+
+      data_rec => flib_data_rec_i,
+      data_rec_start(0) => flib_data_rec_start_i,
+      data_rec_end(0) => flib_data_rec_end_i,
+      data_rec_stop(0) => flib_data_rec_stop_i,
+      
+      ctrl_rec => open,
+      ctrl_rec_start => open,
+      ctrl_rec_end => open,
+      ctrl_rec_stop => '0',
+      
+      -- diagnostics Lane0
+      crc_error_cntr_flag_0     => open,      --  out std_logic;
+      retrans_cntr_flag_0       => open,        --  out std_logic;
+      retrans_error_cntr_flag_0 => open,  --  out std_logic;
+      crc_error_cntr_0          => open,           --  out std_logic_vector(15 downto 0);
+      retrans_cntr_0            => open,             --  out std_logic_vector(15 downto 0);
+      retrans_error_cntr_0      => open,       --  out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_0      => '0',       --  in std_logic;
+      retrans_cntr_clr_0        => '0',         --  in std_logic;
+      retrans_error_cntr_clr_0  => '0',   --  in std_logic;
+
+      -- diagnostics Lane1
+      crc_error_cntr_flag_1     => open, -- out std_logic;
+      retrans_cntr_flag_1       => open, -- out std_logic;
+      retrans_error_cntr_flag_1 => open, -- out std_logic;
+      crc_error_cntr_1          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_1            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_1      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_1      => '0', -- in std_logic;   
+      retrans_cntr_clr_1        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_1  => '0', -- in std_logic; 
+
+      -- diagnostics Lane2
+      crc_error_cntr_flag_2     => open, -- out std_logic;
+      retrans_cntr_flag_2       => open, -- out std_logic;
+      retrans_error_cntr_flag_2 => open, -- out std_logic;
+      crc_error_cntr_2          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_2            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_2      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_2      => '0', -- in std_logic;   
+      retrans_cntr_clr_2        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_2  => '0', -- in std_logic; 
+
+      -- diagnostics Lane3
+      crc_error_cntr_flag_3     => open, -- out std_logic;
+      retrans_cntr_flag_3       => open, -- out std_logic;
+      retrans_error_cntr_flag_3 => open, -- out std_logic;
+      crc_error_cntr_3          => open, -- out std_logic_vector(15 downto 0);
+      retrans_cntr_3            => open, -- out std_logic_vector(15 downto 0);
+      retrans_error_cntr_3      => open, -- out std_logic_vector(15 downto 0);
+      crc_error_cntr_clr_3      => '0', -- in std_logic;   
+      retrans_cntr_clr_3        => '0', -- in std_logic;    
+      retrans_error_cntr_clr_3  => '0'  -- in std_logic
+   );   
+   
+   
+   
    
    THE_LOGGER : TB_CBMNET_LOGGER 
    generic map (log_file => "frames2.txt")
@@ -311,4 +529,17 @@ begin
       DATA2SEND_END_IN => CBMNET_DATA2SEND_END_OUT --  std_logic
    );
 
+   THE_LOGGER_RECV : TB_CBMNET_LOGGER 
+   generic map (log_file => "recv_frames2.txt")
+   port map (
+      CLK_IN => CBMNET_CLK_IN, --  in std_logic;
+      RESET_IN => CBMNET_RESET_IN, --  in std_logic;
+      LINK_ACTIVE_IN => flib_cbm_link_active_i, --  in std_logic;
+
+      DATA2SEND_IN => flib_data_rec_i, --  std_logic_vector(15 downto 0);
+      DATA2SEND_STOP_IN => '0', --  std_logic;
+      DATA2SEND_START_IN => flib_data_rec_start_i, --  std_logic;
+      DATA2SEND_END_IN => flib_data_rec_end_i --  std_logic
+   );
+
 end architecture;
\ No newline at end of file
index 3bf4223838a1c01dc3901a697f040d84cc1f84fe..3553f75acb1a2de21cb7caee0db533e2ddc4ad3a 100755 (executable)
@@ -2,6 +2,7 @@
 use warnings;
 use strict;
 use Data::Dumper;
+use POSIX qw/ceil/;
 
 my @packet = ();
 
@@ -9,6 +10,7 @@ my $success = 0;
 my $errors = 0;
 my $skipped = 0;
 my $line = 0;
+my $matched = 0;
 my $ref = "";
 
 
@@ -26,7 +28,7 @@ sub fassert {
 }
 
 sub stats {
-   printf("Read: % 9d | Skipped: % 9d | Success: % 9d | Errors: % 9d\n", $line, $skipped, $success, $errors)
+   printf("Read: % 9d | Skipped: % 9d | Success: % 9d | Errors: % 9d | Unmatched: % 9d (%.1f %%)\n", $line, $skipped, $success, $errors, $line - $matched, 100* ($line - $matched) / $line )
 }
 
 my $lastFrameNo = -1;
@@ -40,43 +42,51 @@ while(my $frame = <STDIN>) {
    $ref = $1;
    $frame =~ s/DATA\(.*\):\s+//;
    $frame =~ s/\s+$//;
-   my @frameData = map {$_} split(" ", $frame);
-   print Dumper @frameData;
+   my @frameData = map {hex} split(" ", $frame);
    
-   next unless fassert($#frameData > 0, "Frame must no be empty");
-   next unless fassert($#frameData <= 32, "Frame must no be longer than 64 bytes. Got " . (2*$#frameData));
+   next unless fassert($#frameData+1 >= 4,  "Frame must no be shorter than 8 bytes. Got " . (2*$#frameData+2));
+   next unless fassert($#frameData+1 <= 32, "Frame must no be longer than 64 bytes. Got " . (2*$#frameData+2));
 
    my $hdr = shift @frameData;
       
    my $start = ($hdr & 0x4000) != 0;
    my $end   = ($hdr & 0x8000) != 0;
-   my $frameNo = $hdr & 0x3f;
-   my $transNo = ($hdr >> 6) & 0x3f;
+   my $frameNo = $hdr & 0x7f;
+   my $transNo = ($hdr >> 7) & 0x1f;
    
-   print "$#frameData\n";
+   if ($start or $end) {
+      $transNo = $hdr & 0xfff;
+   }
+   
+   #print "$#frameData\n";
    
    next unless fassert($#frameData == 30 or $end, "Only last frame can be shorted than 64 bytes. Got " . (2*$#frameData+2));
    
    
    if ($start) {
-      my $exp = ($lastTransNo+1) & 0x3f;
+      my $exp = ($lastTransNo+1) & 0xfff;
       fassert($lastTransNo == -1 or $exp == $transNo, "Expected sequential transaction numbers. Exp $exp. Got $transNo");
       fassert(-1 == $#packet, "Unexpected start");
       @packet = @frameData;
       $lastTransNo = $transNo;
    } else {
+   
       if ($#packet == -1) {
          $skipped++;
       } else {
-         next unless fassert($lastTransNo == $transNo, "TransNo mismatch");
+         my $exp = (($#packet+1)/31) & 0x7f;
+         next unless fassert($end or $exp == $frameNo, "FrameNo mismatch. Exp $exp, Got: $frameNo " );
+         next unless fassert(($lastTransNo & ($end ? 0xfff : 0x1f)) == $transNo, "TransNo mismatch. Exp $lastTransNo, Got: $transNo");
          @packet = (@packet, @frameData);
       }
    }
-   
+
   # print join(" ", map{sprintf("%04x", $_)} @packet) . "\n";
    
    if ($end and $#packet > 0) {
       my $expectLength = ($packet[0] << 16) | $packet[1];
+      
+      pop @packet while ((2*$#packet+2) > $expectLength and $packet[-1] == 0xaaaa);
       next unless fassert($expectLength == 2*$#packet+2, "Length mismatch. Packet says $expectLength. Got " . (2*$#packet+2));
             
       my $payloadLength = ($expectLength - 16 - 8);
@@ -85,28 +95,36 @@ while(my $frame = <STDIN>) {
       my $payloadWords = $payloadLength / 4;
       my $fail=0;
       for(my $i = 0; $i < $payloadWords and !$fail; $i++) {
-         $fail=1 unless fassert($packet[$i*2 + 8] == $packet[8], "TrbTransactionNo mismatch");
-         my $exp = ($payloadWords - $i) & 0xfff;
-         my $got = $packet[$i*2 + 8 + 1] & 0xfff;
-         $fail=1 unless fassert($fail or $exp == $got, "Payload-RunNo mismatch. Exp: $exp, Got: $got");
+         $fail=1 unless fassert($fail or $packet[$i*2 + 8] == $packet[8], "TrbTransactionNo mismatch");
+         unless($fail) {
+            my $exp = ($payloadWords - $i) & 0xfff;
+            my $got = $packet[$i*2 + 8 + 1] & 0xfff;
+            $fail=1 unless fassert($fail or $exp == $got, "Payload-RunNo mismatch. Exp: $exp, Got: $got");
+         }
       }
       
-      next unless fassert(($packet[8] & 0xff00) == 0xbb00, "Expected 0xbb-- as first word of payload");
-      
-      if ($lastInnerTransNo != -1) {
-         my $exp = ($lastInnerTransNo + 1) & 0xff;
-         my $got = $packet[8] & 0xff;
-       #  print "Error at $line: Inner TransNo mismatch. Exp: $exp, Got $got\n" unless ($exp == $got);
+      unless($fail) {
+         next unless fassert($fail or ($packet[8] & 0xff00) == 0xbb00, "Expected 0xbb-- as first word of payload");
+         
+         if ($lastInnerTransNo != -1) {
+            my $exp = ($lastInnerTransNo + 1) & 0xff;
+            my $got = $packet[8] & 0xff;
+         #  print "Error at $line: Inner TransNo mismatch. Exp: $exp, Got $got\n" unless ($exp == $got);
+         }
+         
+         $lastInnerTransNo = $packet[8] & 0xff;      
+         
+         $fail=1 unless fassert($fail or $packet[-1] == 0xc0de, "Trailer mismatch");
+         $fail=1 unless fassert($fail or $packet[-2] == 0xbeaf, "Trailer mismatch");
+         $fail=1 unless fassert($fail or $packet[-3] == 0x5555, "Trailer mismatch");
+         $fail=1 unless fassert($fail or $packet[-4] == 0x0001, "Trailer mismatch");
+         
+         unless ($fail) {
+            $success++;
+            $matched += ceil(($#packet+1)/31);
+         }
+         
       }
-      
-      $lastInnerTransNo = $packet[8] & 0xff;      
-      
-      $fail=1 unless fassert($fail or $packet[-1] == 0xc0de, "Trailer mismatch");
-      $fail=1 unless fassert($fail or $packet[-2] == 0xbeaf, "Trailer mismatch");
-      $fail=1 unless fassert($fail or $packet[-3] == 0x5555, "Trailer mismatch");
-      $fail=1 unless fassert($fail or $packet[-4] == 0x0001, "Trailer mismatch");
-            
-      $success++ unless $fail;
       #print "Sucessfully read packet with $expectLength bytes\n" unless $fail;
       @packet = ();
    }