From 9ea6cd237554e74468adbbfc648440421ee18b77 Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Wed, 9 Nov 2022 13:07:08 +0100 Subject: [PATCH] trbnetd not happy, but frames seem OK. --- gbe_trb/base/gbe_protocol_selector.vhd | 2 +- .../gbe_response_constructor_SCTRL.vhd | 1207 +++++++++-------- 2 files changed, 611 insertions(+), 598 deletions(-) diff --git a/gbe_trb/base/gbe_protocol_selector.vhd b/gbe_trb/base/gbe_protocol_selector.vhd index 86b6c6d..95043c1 100644 --- a/gbe_trb/base/gbe_protocol_selector.vhd +++ b/gbe_trb/base/gbe_protocol_selector.vhd @@ -137,7 +137,7 @@ begin -- DEBUG_OUT(15 downto 12) <= state; -- selector state -- DEBUG_OUT(11 downto 0) <= debug_dhcp(11 downto 0); -- FSM states DHCP DEBUG_OUT(63 downto 32) <= (others => '0'); - DEBUG_OUT(31 downto 0) <= debug_dhcp(31 downto 0); + DEBUG_OUT(31 downto 0) <= debug_sctrl(31 downto 0); ARP_GEN: if( INCLUDE_ARP = '1' ) generate -- protocol Nr. 1 ARP diff --git a/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd b/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd index 9922009..e3e605a 100644 --- a/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd +++ b/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd @@ -1,597 +1,610 @@ -library ieee; - use ieee.std_logic_1164.all; - use ieee.numeric_std.all; - -library work; - use work.trb_net_std.all; - use work.gbe_protocols.all; - -entity gbe_response_constructor_SCTRL is - generic( - SLOWCTRL_BUFFER_SIZE : integer range 1 to 4 := 1 - ); - port( - CLK : in std_logic; -- system clock - RESET : in std_logic; - -- INTERFACE - MY_MAC_IN : in std_logic_vector(47 downto 0); - MY_IP_IN : in std_logic_vector(31 downto 0); - PS_DATA_IN : in std_logic_vector(8 downto 0); - PS_WR_EN_IN : in std_logic; - PS_ACTIVATE_IN : in std_logic; - PS_RESPONSE_READY_OUT : out std_logic; - PS_BUSY_OUT : out std_logic; - PS_SELECTED_IN : in std_logic; - PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); - PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); - PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); - PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); - PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); - PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); --- - TC_RD_EN_IN : in std_logic; - TC_DATA_OUT : out std_logic_vector(8 downto 0); - TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); - TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); - TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); - TC_IDENT_OUT : out std_logic_vector(15 downto 0); - TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); - TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); - TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); - TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); - TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); - TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); --- - DEBUG_OUT : out std_logic_vector(63 downto 0); - -- END OF INTERFACE - -- protocol specific ports - GSC_CLK_IN : in std_logic; - GSC_INIT_DATAREADY_OUT : out std_logic; - GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0); - GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0); - GSC_INIT_READ_IN : in std_logic; - GSC_REPLY_DATAREADY_IN : in std_logic; - GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0); - GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0); - GSC_REPLY_READ_OUT : out std_logic; - GSC_BUSY_IN : in std_logic; - MAKE_RESET_OUT : out std_logic; - CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0); - -- end of protocol specific ports - MONITOR_SELECT_REC_OUT : out std_logic_vector(31 downto 0); - MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(31 downto 0); - MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(31 downto 0); - MONITOR_SELECT_SENT_OUT : out std_logic_vector(31 downto 0) - ); -end entity gbe_response_constructor_SCTRL; - -architecture gbe_response_constructor_SCTRL_arch of gbe_response_constructor_SCTRL is - - attribute syn_encoding : string; - - type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_HUB, LOAD_TO_HUB, WAIT_FOR_RESPONSE, SAVE_RESPONSE, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP); - signal dissect_current_state, dissect_next_state : dissect_states; - attribute syn_encoding of dissect_current_state: signal is "onehot"; - - type stats_states is (IDLE, LOAD_RECEIVED, LOAD_REPLY, CLEANUP); - signal stats_current_state, stats_next_state : stats_states; - attribute syn_encoding of stats_current_state : signal is "onehot"; - - signal saved_target_ip : std_logic_vector(31 downto 0); - signal data_ctr : integer range 0 to 30; - - signal rec_frames : std_logic_vector(15 downto 0); - - signal rx_fifo_q : std_logic_vector(17 downto 0); - signal rx_fifo_qq : std_logic_vector(17 downto 0); - signal rx_fifo_wr, rx_fifo_rd : std_logic; - signal tx_eod, rx_eod : std_logic; - - signal tx_fifo_q : std_logic_vector(8 downto 0); - signal tx_fifo_wr, tx_fifo_rd : std_logic; - signal tx_fifo_reset : std_logic; - signal gsc_reply_read : std_logic; - signal gsc_init_dataready : std_logic; - signal gsc_init_dataready_q : std_logic; - - signal tx_data_ctr : unsigned(15 downto 0); - signal tx_loaded_ctr : unsigned(15 downto 0); - signal tx_frame_loaded : std_logic_vector(15 downto 0); - - signal packet_num : unsigned(2 downto 0); - --- signal init_ctr : std_logic_vector(15 downto 0); - signal reply_ctr : unsigned(15 downto 0); - signal rx_empty : std_logic; - signal tx_empty : std_logic; - - signal rx_full : std_logic; - signal tx_full : std_logic; - - signal size_left : std_logic_vector(15 downto 0); - - signal reset_detected : std_logic := '0'; - signal make_reset : std_logic := '0'; - - signal fifo_rd_q : std_logic; - - signal too_much_data : std_logic; - - signal rx_fifo_data : std_logic_vector(8 downto 0); - signal tx_fifo_data : std_logic_vector(17 downto 0); - - signal tc_wr : std_logic; - signal state : std_logic_vector(3 downto 0); - signal saved_hdr_1 : std_logic_vector(7 downto 0) := x"ab"; - signal saved_hdr_2 : std_logic_vector(7 downto 0) := x"cd"; - signal saved_hdr_ctr : std_logic_vector(3 downto 0); - - signal mon_rec_frames : unsigned(31 downto 0); - signal mon_rec_bytes : unsigned(31 downto 0); - signal mon_sent_frames : unsigned(31 downto 0); - signal mon_sent_bytes : unsigned(31 downto 0); - - attribute syn_preserve : boolean; - attribute syn_keep : boolean; - attribute syn_keep of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true; - attribute syn_preserve of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true; - - signal rx_cnt : std_logic_vector(15 downto 0); - signal tx_cnt : std_logic_vector(15 downto 0); - -begin - - MAKE_RESET_OUT <= make_reset; - - THE_RECEIVE_FIFO: entity work.fifo_2kx9x18_wcnt - port map( - Reset => RESET, - RPReset => RESET, - WrClock => CLK, - RdClock => CLK, - Data => rx_fifo_data, - WrEn => rx_fifo_wr, - RdEn => rx_fifo_rd, - Q => rx_fifo_q, - Full => rx_full, - Empty => rx_empty, - WCNT => rx_cnt(11 downto 0) - ); - - --TODO: change to synchronous - rx_fifo_rd <= '1' when (gsc_init_dataready = '1' and dissect_current_state = LOAD_TO_HUB) or - (gsc_init_dataready = '1' and dissect_current_state = WAIT_FOR_HUB and GSC_INIT_READ_IN = '1') or - (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') - else '0'; -- preload first word - - PROC_RX_FIFO_WR_SYNC: process( CLK ) - begin - if( rising_edge(CLK) ) then - - if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and (saved_hdr_ctr = "0100" or saved_hdr_ctr = "1000") ) then - rx_fifo_wr <= '1'; - else - rx_fifo_wr <= '0'; - end if; - - rx_fifo_data <= PS_DATA_IN; - end if; - end process PROC_RX_FIFO_WR_SYNC; - - PROC_SAVED_HDR_CTR: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( dissect_current_state = IDLE and PS_WR_EN_IN = '0' and PS_ACTIVATE_IN = '0' ) then - saved_hdr_ctr <= "0001"; - elsif( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr /= "1000" ) then - saved_hdr_ctr(3 downto 0) <= saved_hdr_ctr(2 downto 0) & '0'; - end if; - end if; - end process PROC_SAVED_HDR_CTR; - - PROC_SAVED_HDR: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then - if ( saved_hdr_ctr = "0001" ) then - saved_hdr_1 <= PS_DATA_IN(7 downto 0); - saved_hdr_2 <= saved_hdr_2; - elsif( saved_hdr_ctr = "0010" ) then - saved_hdr_2 <= PS_DATA_IN(7 downto 0); - saved_hdr_1 <= saved_hdr_1; - end if; - end if; - end if; - end process PROC_SAVED_HDR; - - ----TODO: add a register - GSC_INIT_DATA_OUT(7 downto 0) <= rx_fifo_q(16 downto 9); - GSC_INIT_DATA_OUT(15 downto 8) <= rx_fifo_q(7 downto 0); - - ------ TODO: change it to synchronous - GSC_INIT_PACKET_NUM_OUT <= std_logic_vector(packet_num); - GSC_INIT_DATAREADY_OUT <= gsc_init_dataready; - gsc_init_dataready <= '1' when (GSC_INIT_READ_IN = '1' and dissect_current_state = LOAD_TO_HUB) or --TODO Ob das so richtig ist, ohne auf fifo_rd zu schauen? - (dissect_current_state = WAIT_FOR_HUB) - else '0'; - - PROC_PACKET_NUM: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( dissect_current_state = IDLE ) then - packet_num <= "100"; - elsif( GSC_INIT_READ_IN = '1' and rx_fifo_rd = '1' and packet_num = "100" and dissect_current_state /= READ_FRAME ) then --BUG zählt schon hoch beim fifo_rd weil read schon 1 ist. read geht aber nur auf 1 wenn dataready auf 1 ist - packet_num <= "000"; - elsif( rx_fifo_rd = '1' and packet_num /= "100" ) then - packet_num <= packet_num + "1"; - end if; - end if; - end process PROC_PACKET_NUM; - - TF_4K_GEN: if( SLOWCTRL_BUFFER_SIZE = 1 ) generate - THE_TRANSMIT_FIFO: entity work.fifo_4kx18x9_wcnt - port map( - Reset => tx_fifo_reset, - RPReset => tx_fifo_reset, - WrClock => CLK, - RdClock => CLK, - Data => tx_fifo_data, - WrEn => tx_fifo_wr, - RdEn => tx_fifo_rd, - Q => tx_fifo_q, - Full => tx_full, - Empty => tx_empty, - WCNT => tx_cnt(11 downto 0) - ); - end generate TF_4K_GEN; - - TF_65K_GEN: if( SLOWCTRL_BUFFER_SIZE = 2 ) generate - THE_TRANSMIT_FIFO: entity work.fifo_64kx18x9_wcnt - port map( - Reset => tx_fifo_reset, - RPReset => tx_fifo_reset, - WrClock => CLK, - RdClock => CLK, - Data => tx_fifo_data, - WrEn => tx_fifo_wr, - RdEn => tx_fifo_rd, - Q => tx_fifo_q, - Full => tx_full, - Empty => tx_empty, - WCNT => tx_cnt - ); - end generate TF_65K_GEN; - - PROC_TX_FIFO_WR_SYNC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( GSC_REPLY_DATAREADY_IN = '1' and gsc_reply_read = '1' ) then - tx_fifo_wr <= '1'; - elsif( saved_hdr_ctr = "0010" ) then - tx_fifo_wr <= '1'; - else - tx_fifo_wr <= '0'; - end if; - - if( saved_hdr_ctr(2 downto 0) = "010" ) then - tx_fifo_data <= '0' & PS_DATA_IN(7 downto 0) & '0' & x"02"; - else - tx_fifo_data(7 downto 0) <= GSC_REPLY_DATA_IN(15 downto 8); - tx_fifo_data(8) <= '0'; - tx_fifo_data(16 downto 9) <= GSC_REPLY_DATA_IN(7 downto 0); - tx_fifo_data(17) <= '0'; - end if; - end if; - end process PROC_TX_FIFO_WR_SYNC; - - tx_fifo_rd <= '1' when TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1' else '0'; - - TX_FIFO_SYNC_PROC: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - tx_fifo_reset <= '1'; - elsif( rising_edge(CLK) ) then - if( too_much_data = '1' and dissect_current_state = CLEANUP ) then - tx_fifo_reset <= '1'; - else - tx_fifo_reset <= '0'; - end if; - end if; - end process TX_FIFO_SYNC_PROC; - - TC_DATA_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - - TC_DATA_OUT(7 downto 0) <= tx_fifo_q(7 downto 0); - - if( tx_loaded_ctr = tx_data_ctr ) then - TC_DATA_OUT(8) <= '1'; - else - TC_DATA_OUT(8) <= '0'; - end if; - end if; - end process TC_DATA_PROC; - - GSC_REPLY_READ_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( dissect_current_state = WAIT_FOR_RESPONSE or dissect_current_state = SAVE_RESPONSE ) then - gsc_reply_read <= '1'; - else - gsc_reply_read <= '0'; - end if; - end if; - end process GSC_REPLY_READ_PROC; - GSC_REPLY_READ_OUT <= gsc_reply_read; - - -- counter of data received from TRBNet hub - TX_DATA_CTR_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if (dissect_current_state = IDLE) then - tx_data_ctr <= (others => '0'); - elsif( tx_fifo_wr = '1' ) then - tx_data_ctr <= tx_data_ctr + 2; - end if; - end if; - end process TX_DATA_CTR_PROC; - - TOO_MUCH_DATA_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( dissect_current_state = IDLE ) then - too_much_data <= '0'; - elsif( (dissect_current_state = SAVE_RESPONSE) and (tx_data_ctr = unsigned(CFG_MAX_REPLY_SIZE_IN(15 downto 0))) ) then - too_much_data <= '1'; - end if; - end if; - end process TOO_MUCH_DATA_PROC; - - -- total counter of data transported to frame constructor - TX_LOADED_CTR_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( dissect_current_state = IDLE ) then - tx_loaded_ctr <= x"0000"; - elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then - tx_loaded_ctr <= tx_loaded_ctr + x"1"; - end if; - end if; - end process TX_LOADED_CTR_PROC; - - PS_RESPONSE_SYNC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( too_much_data = '0' ) then - if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then - PS_RESPONSE_READY_OUT <= '1'; - else - PS_RESPONSE_READY_OUT <= '0'; - end if; - end if; - - if( dissect_current_state = IDLE or dissect_current_state = WAIT_FOR_RESPONSE ) then - PS_BUSY_OUT <= '0'; - else - PS_BUSY_OUT <= '1'; - end if; - end if; - end process PS_RESPONSE_SYNC; - - TC_FRAME_TYPE_OUT <= x"0008"; - TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN; - TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN; - TC_DEST_UDP_OUT(7 downto 0) <= PS_SRC_UDP_PORT_IN(15 downto 8); - TC_DEST_UDP_OUT(15 downto 8) <= PS_SRC_UDP_PORT_IN(7 downto 0); - TC_SRC_MAC_OUT <= MY_MAC_IN; - TC_SRC_IP_OUT <= MY_IP_IN; - TC_SRC_UDP_OUT <= x"9065"; --x"a861"; - TC_IP_PROTOCOL_OUT <= x"11"; - TC_IDENT_OUT <= x"3" & std_logic_vector(reply_ctr(11 downto 0)); - - TC_FRAME_SIZE_OUT <= std_logic_vector(tx_data_ctr); - - DISSECT_MACHINE_PROC: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - dissect_current_state <= IDLE; - elsif( rising_edge(CLK) ) then - dissect_current_state <= dissect_next_state; - end if; - end process DISSECT_MACHINE_PROC; - - DISSECT_MACHINE: process(dissect_current_state, reset_detected, too_much_data, PS_WR_EN_IN, PS_ACTIVATE_IN, - PS_DATA_IN, PS_SELECTED_IN, GSC_INIT_READ_IN, GSC_REPLY_DATAREADY_IN, tx_loaded_ctr, - tx_data_ctr, rx_fifo_q, GSC_BUSY_IN) - begin - state <= x"0"; - - case dissect_current_state is - - when IDLE => - state <= x"1"; - if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then - dissect_next_state <= READ_FRAME; - else - dissect_next_state <= IDLE; - end if; - - when READ_FRAME => - state <= x"2"; - if (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '0')) then - dissect_next_state <= WAIT_FOR_HUB; - elsif (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '1')) then - dissect_next_state <= LOAD_TO_HUB; - else - dissect_next_state <= READ_FRAME; - end if; - - when WAIT_FOR_HUB => - state <= x"3"; - if (GSC_INIT_READ_IN = '1') then - dissect_next_state <= LOAD_TO_HUB; - else - dissect_next_state <= WAIT_FOR_HUB; - end if; - - when LOAD_TO_HUB => - state <= x"4"; - if ((rx_fifo_q(17) = '1') and (GSC_INIT_READ_IN = '1')) then - if (reset_detected = '1') then - dissect_next_state <= CLEANUP; - else - dissect_next_state <= WAIT_FOR_RESPONSE; - end if; - else - dissect_next_state <= LOAD_TO_HUB; - end if; - - when WAIT_FOR_RESPONSE => - state <= x"5"; - if (GSC_REPLY_DATAREADY_IN = '1') then - dissect_next_state <= SAVE_RESPONSE; - else - dissect_next_state <= WAIT_FOR_RESPONSE; - end if; - - when SAVE_RESPONSE => - state <= x"6"; - if (GSC_REPLY_DATAREADY_IN = '0' and GSC_BUSY_IN = '0') then - if (too_much_data = '0') then - dissect_next_state <= WAIT_FOR_LOAD; - else - dissect_next_state <= CLEANUP; - end if; - else - dissect_next_state <= SAVE_RESPONSE; - end if; - - when WAIT_FOR_LOAD => - state <= x"7"; - if (PS_SELECTED_IN = '1') then - dissect_next_state <= LOAD_FRAME; - else - dissect_next_state <= WAIT_FOR_LOAD; - end if; - - when LOAD_FRAME => - state <= x"8"; - if (tx_loaded_ctr = tx_data_ctr) then - dissect_next_state <= CLEANUP; - else - dissect_next_state <= LOAD_FRAME; - end if; - - when CLEANUP => - state <= x"9"; - dissect_next_state <= IDLE; - - when others => dissect_next_state <= IDLE; - - end case; - end process DISSECT_MACHINE; - - -- reset request packet detection - RESET_DETECTED_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( dissect_current_state = IDLE ) then - reset_detected <= '0'; - elsif( PS_DATA_IN(7 downto 0) = x"80" and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr = "0100" ) then - reset_detected <= '1'; - end if; - end if; - end process RESET_DETECTED_PROC; - - MAKE_RESET_PROC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if ( dissect_current_state = IDLE ) then - make_reset <= '0'; - elsif( dissect_current_state = CLEANUP and reset_detected = '1' ) then - make_reset <= '1'; - end if; - end if; - end process MAKE_RESET_PROC; - - - -- monitoring - --- DATA_HIST_OUT <= (others => '0'); - - PROC_DEBUG: process( CLK ) - begin - if( rising_edge(CLK) ) then - DEBUG_OUT(0) <= rx_full; - DEBUG_OUT(1) <= rx_empty; - DEBUG_OUT(2) <= tx_full; - DEBUG_OUT(3) <= tx_empty; - DEBUG_OUT(7 downto 4) <= state; - DEBUG_OUT(23 downto 8) <= rx_cnt; - DEBUG_OUT(39 downto 24) <= tx_cnt; - DEBUG_OUT(63 downto 40) <= (others => '0'); - end if; - end process PROC_DEBUG; - - PROC_MRF: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - mon_rec_frames <= (others => '0'); - elsif( rising_edge(CLK) ) then - if( dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1' ) then - mon_rec_frames <= mon_rec_frames + 1; - end if; - end if; - end process PROC_MRF; - MONITOR_SELECT_REC_OUT <= std_logic_vector(mon_rec_frames); - - PROC_MRB: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - mon_rec_bytes <= (others => '0'); - elsif( rising_edge(CLK) ) then - if( rx_fifo_wr = '1' ) then - mon_rec_bytes <= mon_rec_bytes + 1; - end if; - end if; - end process PROC_MRB; - MONITOR_SELECT_REC_BYTES_OUT <= std_logic_vector(mon_rec_bytes); - - PROC_MSF: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - mon_sent_frames <= (others => '0'); - elsif( rising_edge(CLK) ) then - if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then - mon_sent_frames <= mon_sent_frames + 1; - end if; - end if; - end process PROC_MSF; - MONITOR_SELECT_SENT_OUT <= std_logic_vector(mon_sent_frames); - - PROC_MSB: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - mon_sent_bytes <= (others => '0'); - elsif( rising_edge(CLK) ) then - if( tx_fifo_rd = '1' ) then - mon_sent_bytes <= mon_sent_bytes + 1; - end if; - end if; - end process PROC_MSB; - MONITOR_SELECT_SENT_BYTES_OUT <= std_logic_vector(mon_sent_bytes); - - -- needed for identification - PROC_REPLY_CTR: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - reply_ctr <= (others => '0'); - elsif( rising_edge(CLK) ) then - if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then - reply_ctr <= reply_ctr + 1; - end if; - end if; - end process PROC_REPLY_CTR; - -end architecture gbe_response_constructor_SCTRL_arch; +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.trb_net_std.all; + use work.gbe_protocols.all; + +entity gbe_response_constructor_SCTRL is + generic( + SLOWCTRL_BUFFER_SIZE : integer range 1 to 4 := 1 + ); + port( + CLK : in std_logic; -- system clock + RESET : in std_logic; + -- INTERFACE + MY_MAC_IN : in std_logic_vector(47 downto 0); + MY_IP_IN : in std_logic_vector(31 downto 0); + PS_DATA_IN : in std_logic_vector(8 downto 0); + PS_WR_EN_IN : in std_logic; + PS_ACTIVATE_IN : in std_logic; + PS_RESPONSE_READY_OUT : out std_logic; + PS_BUSY_OUT : out std_logic; + PS_SELECTED_IN : in std_logic; + PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0); + PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0); + PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0); + PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0); +-- + TC_RD_EN_IN : in std_logic; + TC_DATA_OUT : out std_logic_vector(8 downto 0); + TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0); + TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0); + TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0); + TC_IDENT_OUT : out std_logic_vector(15 downto 0); + TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0); + TC_DEST_IP_OUT : out std_logic_vector(31 downto 0); + TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0); + TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0); + TC_SRC_IP_OUT : out std_logic_vector(31 downto 0); + TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0); +-- + DEBUG_OUT : out std_logic_vector(63 downto 0); + -- END OF INTERFACE + -- protocol specific ports + GSC_CLK_IN : in std_logic; + GSC_INIT_DATAREADY_OUT : out std_logic; + GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0); + GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0); + GSC_INIT_READ_IN : in std_logic; + GSC_REPLY_DATAREADY_IN : in std_logic; + GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0); + GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0); + GSC_REPLY_READ_OUT : out std_logic; + GSC_BUSY_IN : in std_logic; + MAKE_RESET_OUT : out std_logic; + CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0); + -- end of protocol specific ports + MONITOR_SELECT_REC_OUT : out std_logic_vector(31 downto 0); + MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(31 downto 0); + MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(31 downto 0); + MONITOR_SELECT_SENT_OUT : out std_logic_vector(31 downto 0) + ); +end entity gbe_response_constructor_SCTRL; + +architecture gbe_response_constructor_SCTRL_arch of gbe_response_constructor_SCTRL is + + attribute syn_encoding : string; + + type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_HUB, LOAD_TO_HUB, WAIT_FOR_RESPONSE, SAVE_RESPONSE, DELAY, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP); + signal dissect_current_state, dissect_next_state : dissect_states; + attribute syn_encoding of dissect_current_state: signal is "onehot"; + + signal rx_fifo_q : std_logic_vector(17 downto 0); + signal rx_fifo_qq : std_logic_vector(17 downto 0); + signal rx_fifo_wr, rx_fifo_rd : std_logic; + signal tx_eod, rx_eod : std_logic; + + signal tx_fifo_q : std_logic_vector(8 downto 0); + signal tx_fifo_wr, tx_fifo_rd : std_logic; + signal tx_fifo_reset : std_logic; + signal gsc_reply_read : std_logic; + signal gsc_init_dataready : std_logic; + signal gsc_init_dataready_q : std_logic; + + signal tx_data_ctr : unsigned(15 downto 0); + signal tx_loaded_ctr : unsigned(15 downto 0); + signal tx_frame_loaded : std_logic_vector(15 downto 0); + + signal packet_num : unsigned(2 downto 0); + + signal reply_ctr : unsigned(15 downto 0); + signal rx_empty : std_logic; + signal tx_empty : std_logic; + + signal rx_full : std_logic; + signal tx_full : std_logic; + + signal size_left : std_logic_vector(15 downto 0); + + signal reset_detected : std_logic := '0'; + signal make_reset : std_logic := '0'; + + signal fifo_rd_q : std_logic; + + signal too_much_data : std_logic; + + signal rx_fifo_data : std_logic_vector(8 downto 0); + signal tx_fifo_data : std_logic_vector(17 downto 0); + + signal tc_wr : std_logic; + signal state : std_logic_vector(3 downto 0); + signal saved_hdr_1 : std_logic_vector(7 downto 0) := x"ab"; + signal saved_hdr_2 : std_logic_vector(7 downto 0) := x"cd"; + signal saved_hdr_ctr : std_logic_vector(3 downto 0); + + signal mon_rec_frames : unsigned(31 downto 0); + signal mon_rec_bytes : unsigned(31 downto 0); + signal mon_sent_frames : unsigned(31 downto 0); + signal mon_sent_bytes : unsigned(31 downto 0); + + attribute syn_preserve : boolean; + attribute syn_keep : boolean; + attribute syn_keep of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true; + attribute syn_preserve of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true; + + signal rx_cnt : std_logic_vector(15 downto 0); + signal tx_cnt : std_logic_vector(15 downto 0); + + signal delay_ctr : unsigned(13 downto 0); + signal delay_done : std_logic; + +begin + + -- DEBUG lines + DEBUG_OUT(63 downto 32) <= (others => '0'); + -- limit of connector + DEBUG_OUT(31 downto 28) <= state; + DEBUG_OUT(27 downto 26) <= (others => '0'); + -- init channel + DEBUG_OUT(25) <= GSC_INIT_READ_IN; + DEBUG_OUT(24) <= gsc_init_dataready; + DEBUG_OUT(23 downto 21) <= std_logic_vector(packet_num); + DEBUG_OUT(20 downto 13) <= rx_fifo_q(16 downto 9); + -- reply channel + DEBUG_OUT(12) <= gsc_reply_read; + DEBUG_OUT(11) <= GSC_REPLY_DATAREADY_IN; + DEBUG_OUT(10 downto 8) <= GSC_REPLY_PACKET_NUM_IN; + DEBUG_OUT(7 downto 0) <= GSC_REPLY_DATA_IN(7 downto 0); + + MAKE_RESET_OUT <= make_reset; + + THE_RECEIVE_FIFO: entity work.fifo_2kx9x18_wcnt + port map( + Reset => RESET, + RPReset => RESET, + WrClock => CLK, + RdClock => CLK, + Data => rx_fifo_data, + WrEn => rx_fifo_wr, + RdEn => rx_fifo_rd, + Q => rx_fifo_q, + Full => rx_full, + Empty => rx_empty, + WCNT => rx_cnt(11 downto 0) + ); + + --TODO: change to synchronous + rx_fifo_rd <= '1' when (gsc_init_dataready = '1' and dissect_current_state = LOAD_TO_HUB) or + (gsc_init_dataready = '1' and dissect_current_state = WAIT_FOR_HUB and GSC_INIT_READ_IN = '1') or + (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') + else '0'; -- preload first word + + PROC_RX_FIFO_WR_SYNC: process( CLK ) + begin + if( rising_edge(CLK) ) then + + if( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') and ((saved_hdr_ctr = "0100") or (saved_hdr_ctr = "1000")) ) then + rx_fifo_wr <= '1'; + else + rx_fifo_wr <= '0'; + end if; + + rx_fifo_data <= PS_DATA_IN; + end if; + end process PROC_RX_FIFO_WR_SYNC; + + PROC_SAVED_HDR_CTR: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( (PS_WR_EN_IN = '0') and (PS_ACTIVATE_IN = '0') and (dissect_current_state = IDLE) ) then + saved_hdr_ctr <= "0001"; + elsif( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') and (saved_hdr_ctr /= "1000") ) then + saved_hdr_ctr(3 downto 0) <= saved_hdr_ctr(2 downto 0) & '0'; + end if; + end if; + end process PROC_SAVED_HDR_CTR; + + PROC_SAVED_HDR: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then + if ( saved_hdr_ctr = "0001" ) then + saved_hdr_1 <= PS_DATA_IN(7 downto 0); + saved_hdr_2 <= saved_hdr_2; + elsif( saved_hdr_ctr = "0010" ) then + saved_hdr_2 <= PS_DATA_IN(7 downto 0); + saved_hdr_1 <= saved_hdr_1; + end if; + end if; + end if; + end process PROC_SAVED_HDR; + + ----TODO: add a register + GSC_INIT_DATA_OUT(7 downto 0) <= rx_fifo_q(16 downto 9); + GSC_INIT_DATA_OUT(15 downto 8) <= rx_fifo_q(7 downto 0); + + ------ TODO: change it to synchronous + GSC_INIT_PACKET_NUM_OUT <= std_logic_vector(packet_num); + GSC_INIT_DATAREADY_OUT <= gsc_init_dataready; + gsc_init_dataready <= '1' when (GSC_INIT_READ_IN = '1' and dissect_current_state = LOAD_TO_HUB) or -- JM: TODO Ob das so richtig ist, ohne auf fifo_rd zu schauen? + (dissect_current_state = WAIT_FOR_HUB) + else '0'; + + PROC_PACKET_NUM: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( dissect_current_state = IDLE ) then + packet_num <= "100"; + elsif( GSC_INIT_READ_IN = '1' and rx_fifo_rd = '1' and packet_num = "100" and dissect_current_state /= READ_FRAME ) then -- JM: BUG zählt schon hoch beim fifo_rd weil read schon 1 ist. read geht aber nur auf 1 wenn dataready auf 1 ist + packet_num <= "000"; + elsif( rx_fifo_rd = '1' and packet_num /= "100" ) then + packet_num <= packet_num + "1"; + end if; + end if; + end process PROC_PACKET_NUM; + + TF_4K_GEN: if( SLOWCTRL_BUFFER_SIZE = 1 ) generate + THE_TRANSMIT_FIFO: entity work.fifo_4kx18x9_wcnt + port map( + Reset => tx_fifo_reset, + RPReset => tx_fifo_reset, + WrClock => CLK, + RdClock => CLK, + Data => tx_fifo_data, + WrEn => tx_fifo_wr, + RdEn => tx_fifo_rd, + Q => tx_fifo_q, + Full => tx_full, + Empty => tx_empty, + WCNT => tx_cnt(11 downto 0) + ); + end generate TF_4K_GEN; + + TF_65K_GEN: if( SLOWCTRL_BUFFER_SIZE = 2 ) generate + THE_TRANSMIT_FIFO: entity work.fifo_64kx18x9_wcnt + port map( + Reset => tx_fifo_reset, + RPReset => tx_fifo_reset, + WrClock => CLK, + RdClock => CLK, + Data => tx_fifo_data, + WrEn => tx_fifo_wr, + RdEn => tx_fifo_rd, + Q => tx_fifo_q, + Full => tx_full, + Empty => tx_empty, + WCNT => tx_cnt + ); + end generate TF_65K_GEN; + + PROC_TX_FIFO_WR_SYNC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( GSC_REPLY_DATAREADY_IN = '1' and gsc_reply_read = '1' ) then + tx_fifo_wr <= '1'; + elsif( saved_hdr_ctr = "0010" ) then + tx_fifo_wr <= '1'; + else + tx_fifo_wr <= '0'; + end if; + + if( saved_hdr_ctr(2 downto 0) = "010" ) then + tx_fifo_data <= '0' & PS_DATA_IN(7 downto 0) & '0' & x"02"; + else + tx_fifo_data(7 downto 0) <= GSC_REPLY_DATA_IN(15 downto 8); + tx_fifo_data(8) <= '0'; + tx_fifo_data(16 downto 9) <= GSC_REPLY_DATA_IN(7 downto 0); + tx_fifo_data(17) <= '0'; + end if; + end if; + end process PROC_TX_FIFO_WR_SYNC; + + tx_fifo_rd <= '1' when TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1' else '0'; + + TX_FIFO_SYNC_PROC: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + tx_fifo_reset <= '1'; + elsif( rising_edge(CLK) ) then + if( too_much_data = '1' and dissect_current_state = CLEANUP ) then + tx_fifo_reset <= '1'; + else + tx_fifo_reset <= '0'; + end if; + end if; + end process TX_FIFO_SYNC_PROC; + + TC_DATA_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + + TC_DATA_OUT(7 downto 0) <= tx_fifo_q(7 downto 0); + + if( tx_loaded_ctr = tx_data_ctr ) then + TC_DATA_OUT(8) <= '1'; + else + TC_DATA_OUT(8) <= '0'; + end if; + end if; + end process TC_DATA_PROC; + + GSC_REPLY_READ_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( dissect_current_state = WAIT_FOR_RESPONSE or dissect_current_state = SAVE_RESPONSE ) then + gsc_reply_read <= '1'; + else + gsc_reply_read <= '0'; + end if; + end if; + end process GSC_REPLY_READ_PROC; + GSC_REPLY_READ_OUT <= gsc_reply_read; + + -- counter of data received from TRBNet hub + TX_DATA_CTR_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if (dissect_current_state = IDLE) then + tx_data_ctr <= (others => '0'); + elsif( tx_fifo_wr = '1' ) then + tx_data_ctr <= tx_data_ctr + 2; + end if; + end if; + end process TX_DATA_CTR_PROC; + + TOO_MUCH_DATA_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( dissect_current_state = IDLE ) then + too_much_data <= '0'; + elsif( (dissect_current_state = SAVE_RESPONSE) and (tx_data_ctr = unsigned(CFG_MAX_REPLY_SIZE_IN(15 downto 0))) ) then + too_much_data <= '1'; + end if; + end if; + end process TOO_MUCH_DATA_PROC; + + -- total counter of data transported to frame constructor + TX_LOADED_CTR_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( dissect_current_state = IDLE ) then + tx_loaded_ctr <= x"0000"; + elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then + tx_loaded_ctr <= tx_loaded_ctr + x"1"; + end if; + end if; + end process TX_LOADED_CTR_PROC; + + PS_RESPONSE_SYNC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( too_much_data = '0' ) then + if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then + PS_RESPONSE_READY_OUT <= '1'; + else + PS_RESPONSE_READY_OUT <= '0'; + end if; + end if; + + if( dissect_current_state = IDLE or dissect_current_state = WAIT_FOR_RESPONSE ) then + PS_BUSY_OUT <= '0'; + else + PS_BUSY_OUT <= '1'; + end if; + end if; + end process PS_RESPONSE_SYNC; + + TC_FRAME_TYPE_OUT <= x"0008"; + TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN; + TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN; + TC_DEST_UDP_OUT(7 downto 0) <= PS_SRC_UDP_PORT_IN(15 downto 8); + TC_DEST_UDP_OUT(15 downto 8) <= PS_SRC_UDP_PORT_IN(7 downto 0); + TC_SRC_MAC_OUT <= MY_MAC_IN; + TC_SRC_IP_OUT <= MY_IP_IN; + TC_SRC_UDP_OUT <= x"9065"; --x"a861"; + TC_IP_PROTOCOL_OUT <= x"11"; + TC_IDENT_OUT <= x"3" & std_logic_vector(reply_ctr(11 downto 0)); + + TC_FRAME_SIZE_OUT <= std_logic_vector(tx_data_ctr); + + DISSECT_MACHINE_PROC: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + dissect_current_state <= IDLE; + elsif( rising_edge(CLK) ) then + dissect_current_state <= dissect_next_state; + end if; + end process DISSECT_MACHINE_PROC; + + DISSECT_MACHINE: process( dissect_current_state, reset_detected, too_much_data, PS_WR_EN_IN, PS_ACTIVATE_IN, + PS_DATA_IN, PS_SELECTED_IN, GSC_INIT_READ_IN, GSC_REPLY_DATAREADY_IN, tx_loaded_ctr, + tx_data_ctr, rx_fifo_q, GSC_BUSY_IN, delay_done ) + begin + state <= x"0"; + + case dissect_current_state is + + when IDLE => + state <= x"1"; + if( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') ) then + dissect_next_state <= READ_FRAME; + else + dissect_next_state <= IDLE; + end if; + + when READ_FRAME => + state <= x"2"; + if ( (PS_DATA_IN(8) = '1') and (GSC_INIT_READ_IN = '0') ) then + dissect_next_state <= WAIT_FOR_HUB; + elsif( (PS_DATA_IN(8) = '1') and (GSC_INIT_READ_IN = '1') ) then + dissect_next_state <= LOAD_TO_HUB; + else + dissect_next_state <= READ_FRAME; + end if; + + when WAIT_FOR_HUB => + state <= x"3"; + if( GSC_INIT_READ_IN = '1' ) then + dissect_next_state <= LOAD_TO_HUB; + else + dissect_next_state <= WAIT_FOR_HUB; + end if; + + when LOAD_TO_HUB => + state <= x"4"; + if( (rx_fifo_q(17) = '1') and (GSC_INIT_READ_IN = '1') ) then + if( reset_detected = '1' ) then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= WAIT_FOR_RESPONSE; + end if; + else + dissect_next_state <= LOAD_TO_HUB; + end if; + + when WAIT_FOR_RESPONSE => + state <= x"5"; + if( GSC_REPLY_DATAREADY_IN = '1' ) then + dissect_next_state <= SAVE_RESPONSE; + else + dissect_next_state <= WAIT_FOR_RESPONSE; + end if; + + when SAVE_RESPONSE => + state <= x"6"; + if( (GSC_REPLY_DATAREADY_IN = '0') and (GSC_BUSY_IN = '0') ) then + if( too_much_data = '0' ) then +-- dissect_next_state <= WAIT_FOR_LOAD; + dissect_next_state <= DELAY; + else + dissect_next_state <= CLEANUP; + end if; + else + dissect_next_state <= SAVE_RESPONSE; + end if; + + when DELAY => + if( delay_done = '1' ) then + dissect_next_state <= WAIT_FOR_LOAD; + else + dissect_next_state <= DELAY; + end if; + + when WAIT_FOR_LOAD => + state <= x"7"; + if (PS_SELECTED_IN = '1') then + dissect_next_state <= LOAD_FRAME; + else + dissect_next_state <= WAIT_FOR_LOAD; + end if; + + when LOAD_FRAME => + state <= x"8"; + if (tx_loaded_ctr = tx_data_ctr) then + dissect_next_state <= CLEANUP; + else + dissect_next_state <= LOAD_FRAME; + end if; + + when CLEANUP => + state <= x"9"; + dissect_next_state <= IDLE; + + when others => dissect_next_state <= IDLE; + + end case; + end process DISSECT_MACHINE; + + PROC_DELAY_CTR: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( dissect_current_state /= DELAY ) then + delay_ctr <= (others => '0'); + else + delay_ctr <= delay_ctr + 1; + end if; + end if; + end process PROC_DELAY_CTR; + + delay_done <= std_logic(delay_ctr(13)); + + -- reset request packet detection + RESET_DETECTED_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( dissect_current_state = IDLE ) then + reset_detected <= '0'; + elsif( PS_DATA_IN(7 downto 0) = x"80" and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr = "0100" ) then + reset_detected <= '1'; + end if; + end if; + end process RESET_DETECTED_PROC; + + MAKE_RESET_PROC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if ( dissect_current_state = IDLE ) then + make_reset <= '0'; + elsif( dissect_current_state = CLEANUP and reset_detected = '1' ) then + make_reset <= '1'; + end if; + end if; + end process MAKE_RESET_PROC; + + -- monitoring + + PROC_MRF: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + mon_rec_frames <= (others => '0'); + elsif( rising_edge(CLK) ) then + if( dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1' ) then + mon_rec_frames <= mon_rec_frames + 1; + end if; + end if; + end process PROC_MRF; + MONITOR_SELECT_REC_OUT <= std_logic_vector(mon_rec_frames); + + PROC_MRB: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + mon_rec_bytes <= (others => '0'); + elsif( rising_edge(CLK) ) then + if( rx_fifo_wr = '1' ) then + mon_rec_bytes <= mon_rec_bytes + 1; + end if; + end if; + end process PROC_MRB; + MONITOR_SELECT_REC_BYTES_OUT <= std_logic_vector(mon_rec_bytes); + + PROC_MSF: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + mon_sent_frames <= (others => '0'); + elsif( rising_edge(CLK) ) then + if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then + mon_sent_frames <= mon_sent_frames + 1; + end if; + end if; + end process PROC_MSF; + MONITOR_SELECT_SENT_OUT <= std_logic_vector(mon_sent_frames); + + PROC_MSB: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + mon_sent_bytes <= (others => '0'); + elsif( rising_edge(CLK) ) then + if( tx_fifo_rd = '1' ) then + mon_sent_bytes <= mon_sent_bytes + 1; + end if; + end if; + end process PROC_MSB; + MONITOR_SELECT_SENT_BYTES_OUT <= std_logic_vector(mon_sent_bytes); + + -- needed for identification + PROC_REPLY_CTR: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + reply_ctr <= (others => '0'); + elsif( rising_edge(CLK) ) then + if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then + reply_ctr <= reply_ctr + 1; + end if; + end if; + end process PROC_REPLY_CTR; + +end architecture gbe_response_constructor_SCTRL_arch; -- 2.43.0