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 (
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
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;
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);
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
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
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);
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;
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);
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
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;
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
-- 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;
entity CBMNET_READOUT_FIFO is
generic (
ADDR_WIDTH : positive := 10;
- WATERMARK : positive := 2
+ WATERMARK : positive := 4
);
port (
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;
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
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;
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);
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
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
--- /dev/null
+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;
+
--- /dev/null
+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
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;
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;
--- /dev/null
+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
+++ /dev/null
-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;
-
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 =>
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;
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
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);
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;
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';
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";
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);
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;
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;
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")
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
use warnings;
use strict;
use Data::Dumper;
+use POSIX qw/ceil/;
my @packet = ();
my $errors = 0;
my $skipped = 0;
my $line = 0;
+my $matched = 0;
my $ref = "";
}
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;
$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);
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 = ();
}