-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;\r
+ use ieee.std_logic_1164.all;\r
+ use ieee.numeric_std.all;\r
+\r
+library work;\r
+ use work.trb_net_std.all;\r
+ use work.gbe_protocols.all;\r
+\r
+entity gbe_response_constructor_SCTRL is\r
+ generic(\r
+ SLOWCTRL_BUFFER_SIZE : integer range 1 to 4 := 1\r
+ );\r
+ port(\r
+ CLK : in std_logic; -- system clock\r
+ RESET : in std_logic;\r
+ -- INTERFACE\r
+ MY_MAC_IN : in std_logic_vector(47 downto 0);\r
+ MY_IP_IN : in std_logic_vector(31 downto 0);\r
+ PS_DATA_IN : in std_logic_vector(8 downto 0);\r
+ PS_WR_EN_IN : in std_logic;\r
+ PS_ACTIVATE_IN : in std_logic;\r
+ PS_RESPONSE_READY_OUT : out std_logic;\r
+ PS_BUSY_OUT : out std_logic;\r
+ PS_SELECTED_IN : in std_logic;\r
+ PS_SRC_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);\r
+ PS_DEST_MAC_ADDRESS_IN : in std_logic_vector(47 downto 0);\r
+ PS_SRC_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);\r
+ PS_DEST_IP_ADDRESS_IN : in std_logic_vector(31 downto 0);\r
+ PS_SRC_UDP_PORT_IN : in std_logic_vector(15 downto 0);\r
+ PS_DEST_UDP_PORT_IN : in std_logic_vector(15 downto 0);\r
+--\r
+ TC_RD_EN_IN : in std_logic;\r
+ TC_DATA_OUT : out std_logic_vector(8 downto 0);\r
+ TC_FRAME_SIZE_OUT : out std_logic_vector(15 downto 0);\r
+ TC_FRAME_TYPE_OUT : out std_logic_vector(15 downto 0);\r
+ TC_IP_PROTOCOL_OUT : out std_logic_vector(7 downto 0);\r
+ TC_IDENT_OUT : out std_logic_vector(15 downto 0);\r
+ TC_DEST_MAC_OUT : out std_logic_vector(47 downto 0);\r
+ TC_DEST_IP_OUT : out std_logic_vector(31 downto 0);\r
+ TC_DEST_UDP_OUT : out std_logic_vector(15 downto 0);\r
+ TC_SRC_MAC_OUT : out std_logic_vector(47 downto 0);\r
+ TC_SRC_IP_OUT : out std_logic_vector(31 downto 0);\r
+ TC_SRC_UDP_OUT : out std_logic_vector(15 downto 0);\r
+--\r
+ DEBUG_OUT : out std_logic_vector(63 downto 0);\r
+ -- END OF INTERFACE\r
+ -- protocol specific ports\r
+ GSC_CLK_IN : in std_logic;\r
+ GSC_INIT_DATAREADY_OUT : out std_logic;\r
+ GSC_INIT_DATA_OUT : out std_logic_vector(15 downto 0);\r
+ GSC_INIT_PACKET_NUM_OUT : out std_logic_vector(2 downto 0);\r
+ GSC_INIT_READ_IN : in std_logic;\r
+ GSC_REPLY_DATAREADY_IN : in std_logic;\r
+ GSC_REPLY_DATA_IN : in std_logic_vector(15 downto 0);\r
+ GSC_REPLY_PACKET_NUM_IN : in std_logic_vector(2 downto 0);\r
+ GSC_REPLY_READ_OUT : out std_logic;\r
+ GSC_BUSY_IN : in std_logic;\r
+ MAKE_RESET_OUT : out std_logic;\r
+ CFG_MAX_REPLY_SIZE_IN : in std_logic_vector(31 downto 0);\r
+ -- end of protocol specific ports\r
+ MONITOR_SELECT_REC_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_SELECT_REC_BYTES_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(31 downto 0);\r
+ MONITOR_SELECT_SENT_OUT : out std_logic_vector(31 downto 0)\r
+ );\r
+end entity gbe_response_constructor_SCTRL;\r
+\r
+architecture gbe_response_constructor_SCTRL_arch of gbe_response_constructor_SCTRL is\r
+\r
+ attribute syn_encoding : string;\r
+\r
+ 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);\r
+ signal dissect_current_state, dissect_next_state : dissect_states;\r
+ attribute syn_encoding of dissect_current_state: signal is "onehot";\r
+\r
+ signal rx_fifo_q : std_logic_vector(17 downto 0);\r
+ signal rx_fifo_qq : std_logic_vector(17 downto 0);\r
+ signal rx_fifo_wr, rx_fifo_rd : std_logic;\r
+ signal tx_eod, rx_eod : std_logic;\r
+\r
+ signal tx_fifo_q : std_logic_vector(8 downto 0);\r
+ signal tx_fifo_wr, tx_fifo_rd : std_logic;\r
+ signal tx_fifo_reset : std_logic;\r
+ signal gsc_reply_read : std_logic;\r
+ signal gsc_init_dataready : std_logic;\r
+ signal gsc_init_dataready_q : std_logic;\r
+\r
+ signal tx_data_ctr : unsigned(15 downto 0);\r
+ signal tx_loaded_ctr : unsigned(15 downto 0);\r
+ signal tx_frame_loaded : std_logic_vector(15 downto 0);\r
+\r
+ signal packet_num : unsigned(2 downto 0);\r
+\r
+ signal reply_ctr : unsigned(15 downto 0);\r
+ signal rx_empty : std_logic;\r
+ signal tx_empty : std_logic;\r
+\r
+ signal rx_full : std_logic;\r
+ signal tx_full : std_logic;\r
+\r
+ signal size_left : std_logic_vector(15 downto 0);\r
+\r
+ signal reset_detected : std_logic := '0';\r
+ signal make_reset : std_logic := '0';\r
+\r
+ signal fifo_rd_q : std_logic;\r
+\r
+ signal too_much_data : std_logic;\r
+\r
+ signal rx_fifo_data : std_logic_vector(8 downto 0);\r
+ signal tx_fifo_data : std_logic_vector(17 downto 0);\r
+\r
+ signal tc_wr : std_logic;\r
+ signal state : std_logic_vector(3 downto 0);\r
+ signal saved_hdr_1 : std_logic_vector(7 downto 0) := x"ab";\r
+ signal saved_hdr_2 : std_logic_vector(7 downto 0) := x"cd";\r
+ signal saved_hdr_ctr : std_logic_vector(3 downto 0);\r
+\r
+ signal mon_rec_frames : unsigned(31 downto 0);\r
+ signal mon_rec_bytes : unsigned(31 downto 0);\r
+ signal mon_sent_frames : unsigned(31 downto 0);\r
+ signal mon_sent_bytes : unsigned(31 downto 0);\r
+\r
+ attribute syn_preserve : boolean;\r
+ attribute syn_keep : boolean;\r
+ 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;\r
+ 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;\r
+\r
+ signal rx_cnt : std_logic_vector(15 downto 0);\r
+ signal tx_cnt : std_logic_vector(15 downto 0);\r
+\r
+ signal delay_ctr : unsigned(13 downto 0);\r
+ signal delay_done : std_logic;\r
+\r
+begin\r
+\r
+ -- DEBUG lines\r
+ DEBUG_OUT(63 downto 32) <= (others => '0');\r
+ -- limit of connector\r
+ DEBUG_OUT(31 downto 28) <= state;\r
+ DEBUG_OUT(27 downto 26) <= (others => '0');\r
+ -- init channel\r
+ DEBUG_OUT(25) <= GSC_INIT_READ_IN;\r
+ DEBUG_OUT(24) <= gsc_init_dataready;\r
+ DEBUG_OUT(23 downto 21) <= std_logic_vector(packet_num);\r
+ DEBUG_OUT(20 downto 13) <= rx_fifo_q(16 downto 9);\r
+ -- reply channel\r
+ DEBUG_OUT(12) <= gsc_reply_read;\r
+ DEBUG_OUT(11) <= GSC_REPLY_DATAREADY_IN;\r
+ DEBUG_OUT(10 downto 8) <= GSC_REPLY_PACKET_NUM_IN;\r
+ DEBUG_OUT(7 downto 0) <= GSC_REPLY_DATA_IN(7 downto 0);\r
+ \r
+ MAKE_RESET_OUT <= make_reset;\r
+\r
+ THE_RECEIVE_FIFO: entity work.fifo_2kx9x18_wcnt\r
+ port map(\r
+ Reset => RESET,\r
+ RPReset => RESET,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ Data => rx_fifo_data,\r
+ WrEn => rx_fifo_wr,\r
+ RdEn => rx_fifo_rd,\r
+ Q => rx_fifo_q,\r
+ Full => rx_full,\r
+ Empty => rx_empty,\r
+ WCNT => rx_cnt(11 downto 0)\r
+ );\r
+\r
+ --TODO: change to synchronous\r
+ rx_fifo_rd <= '1' when (gsc_init_dataready = '1' and dissect_current_state = LOAD_TO_HUB) or\r
+ (gsc_init_dataready = '1' and dissect_current_state = WAIT_FOR_HUB and GSC_INIT_READ_IN = '1') or\r
+ (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1')\r
+ else '0'; -- preload first word\r
+\r
+ PROC_RX_FIFO_WR_SYNC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+\r
+ if( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') and ((saved_hdr_ctr = "0100") or (saved_hdr_ctr = "1000")) ) then\r
+ rx_fifo_wr <= '1';\r
+ else\r
+ rx_fifo_wr <= '0';\r
+ end if;\r
+\r
+ rx_fifo_data <= PS_DATA_IN;\r
+ end if;\r
+ end process PROC_RX_FIFO_WR_SYNC;\r
+\r
+ PROC_SAVED_HDR_CTR: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( (PS_WR_EN_IN = '0') and (PS_ACTIVATE_IN = '0') and (dissect_current_state = IDLE) ) then\r
+ saved_hdr_ctr <= "0001";\r
+ elsif( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') and (saved_hdr_ctr /= "1000") ) then\r
+ saved_hdr_ctr(3 downto 0) <= saved_hdr_ctr(2 downto 0) & '0';\r
+ end if;\r
+ end if;\r
+ end process PROC_SAVED_HDR_CTR;\r
+\r
+ PROC_SAVED_HDR: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then\r
+ if ( saved_hdr_ctr = "0001" ) then\r
+ saved_hdr_1 <= PS_DATA_IN(7 downto 0);\r
+ saved_hdr_2 <= saved_hdr_2;\r
+ elsif( saved_hdr_ctr = "0010" ) then\r
+ saved_hdr_2 <= PS_DATA_IN(7 downto 0);\r
+ saved_hdr_1 <= saved_hdr_1;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ end process PROC_SAVED_HDR;\r
+\r
+ ----TODO: add a register\r
+ GSC_INIT_DATA_OUT(7 downto 0) <= rx_fifo_q(16 downto 9);\r
+ GSC_INIT_DATA_OUT(15 downto 8) <= rx_fifo_q(7 downto 0);\r
+\r
+ ------ TODO: change it to synchronous\r
+ GSC_INIT_PACKET_NUM_OUT <= std_logic_vector(packet_num);\r
+ GSC_INIT_DATAREADY_OUT <= gsc_init_dataready;\r
+ 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?\r
+ (dissect_current_state = WAIT_FOR_HUB)\r
+ else '0';\r
+\r
+ PROC_PACKET_NUM: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( dissect_current_state = IDLE ) then\r
+ packet_num <= "100";\r
+ 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\r
+ packet_num <= "000";\r
+ elsif( rx_fifo_rd = '1' and packet_num /= "100" ) then\r
+ packet_num <= packet_num + "1";\r
+ end if;\r
+ end if;\r
+ end process PROC_PACKET_NUM;\r
+\r
+ TF_4K_GEN: if( SLOWCTRL_BUFFER_SIZE = 1 ) generate\r
+ THE_TRANSMIT_FIFO: entity work.fifo_4kx18x9_wcnt\r
+ port map(\r
+ Reset => tx_fifo_reset,\r
+ RPReset => tx_fifo_reset,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ Data => tx_fifo_data,\r
+ WrEn => tx_fifo_wr,\r
+ RdEn => tx_fifo_rd,\r
+ Q => tx_fifo_q,\r
+ Full => tx_full,\r
+ Empty => tx_empty,\r
+ WCNT => tx_cnt(11 downto 0)\r
+ );\r
+ end generate TF_4K_GEN;\r
+\r
+ TF_65K_GEN: if( SLOWCTRL_BUFFER_SIZE = 2 ) generate\r
+ THE_TRANSMIT_FIFO: entity work.fifo_64kx18x9_wcnt\r
+ port map(\r
+ Reset => tx_fifo_reset,\r
+ RPReset => tx_fifo_reset,\r
+ WrClock => CLK,\r
+ RdClock => CLK,\r
+ Data => tx_fifo_data,\r
+ WrEn => tx_fifo_wr,\r
+ RdEn => tx_fifo_rd,\r
+ Q => tx_fifo_q,\r
+ Full => tx_full,\r
+ Empty => tx_empty,\r
+ WCNT => tx_cnt\r
+ );\r
+ end generate TF_65K_GEN;\r
+\r
+ PROC_TX_FIFO_WR_SYNC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( GSC_REPLY_DATAREADY_IN = '1' and gsc_reply_read = '1' ) then\r
+ tx_fifo_wr <= '1';\r
+ elsif( saved_hdr_ctr = "0010" ) then\r
+ tx_fifo_wr <= '1';\r
+ else\r
+ tx_fifo_wr <= '0';\r
+ end if;\r
+\r
+ if( saved_hdr_ctr(2 downto 0) = "010" ) then\r
+ tx_fifo_data <= '0' & PS_DATA_IN(7 downto 0) & '0' & x"02";\r
+ else\r
+ tx_fifo_data(7 downto 0) <= GSC_REPLY_DATA_IN(15 downto 8);\r
+ tx_fifo_data(8) <= '0';\r
+ tx_fifo_data(16 downto 9) <= GSC_REPLY_DATA_IN(7 downto 0);\r
+ tx_fifo_data(17) <= '0';\r
+ end if;\r
+ end if;\r
+ end process PROC_TX_FIFO_WR_SYNC;\r
+\r
+ tx_fifo_rd <= '1' when TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1' else '0';\r
+\r
+ TX_FIFO_SYNC_PROC: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ tx_fifo_reset <= '1';\r
+ elsif( rising_edge(CLK) ) then\r
+ if( too_much_data = '1' and dissect_current_state = CLEANUP ) then\r
+ tx_fifo_reset <= '1';\r
+ else\r
+ tx_fifo_reset <= '0';\r
+ end if;\r
+ end if;\r
+ end process TX_FIFO_SYNC_PROC;\r
+\r
+ TC_DATA_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+\r
+ TC_DATA_OUT(7 downto 0) <= tx_fifo_q(7 downto 0);\r
+\r
+ if( tx_loaded_ctr = tx_data_ctr ) then\r
+ TC_DATA_OUT(8) <= '1';\r
+ else\r
+ TC_DATA_OUT(8) <= '0';\r
+ end if;\r
+ end if;\r
+ end process TC_DATA_PROC;\r
+\r
+ GSC_REPLY_READ_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( dissect_current_state = WAIT_FOR_RESPONSE or dissect_current_state = SAVE_RESPONSE ) then\r
+ gsc_reply_read <= '1';\r
+ else\r
+ gsc_reply_read <= '0';\r
+ end if;\r
+ end if;\r
+ end process GSC_REPLY_READ_PROC;\r
+ GSC_REPLY_READ_OUT <= gsc_reply_read;\r
+\r
+ -- counter of data received from TRBNet hub\r
+ TX_DATA_CTR_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if (dissect_current_state = IDLE) then\r
+ tx_data_ctr <= (others => '0');\r
+ elsif( tx_fifo_wr = '1' ) then\r
+ tx_data_ctr <= tx_data_ctr + 2;\r
+ end if;\r
+ end if;\r
+ end process TX_DATA_CTR_PROC;\r
+\r
+ TOO_MUCH_DATA_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( dissect_current_state = IDLE ) then\r
+ too_much_data <= '0';\r
+ elsif( (dissect_current_state = SAVE_RESPONSE) and (tx_data_ctr = unsigned(CFG_MAX_REPLY_SIZE_IN(15 downto 0))) ) then\r
+ too_much_data <= '1';\r
+ end if;\r
+ end if;\r
+ end process TOO_MUCH_DATA_PROC;\r
+\r
+ -- total counter of data transported to frame constructor\r
+ TX_LOADED_CTR_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( dissect_current_state = IDLE ) then\r
+ tx_loaded_ctr <= x"0000";\r
+ elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then\r
+ tx_loaded_ctr <= tx_loaded_ctr + x"1";\r
+ end if;\r
+ end if;\r
+ end process TX_LOADED_CTR_PROC;\r
+\r
+ PS_RESPONSE_SYNC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( too_much_data = '0' ) then\r
+ if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then\r
+ PS_RESPONSE_READY_OUT <= '1';\r
+ else\r
+ PS_RESPONSE_READY_OUT <= '0';\r
+ end if;\r
+ end if;\r
+\r
+ if( dissect_current_state = IDLE or dissect_current_state = WAIT_FOR_RESPONSE ) then\r
+ PS_BUSY_OUT <= '0';\r
+ else\r
+ PS_BUSY_OUT <= '1';\r
+ end if;\r
+ end if;\r
+ end process PS_RESPONSE_SYNC;\r
+\r
+ TC_FRAME_TYPE_OUT <= x"0008";\r
+ TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN;\r
+ TC_DEST_IP_OUT <= PS_SRC_IP_ADDRESS_IN;\r
+ TC_DEST_UDP_OUT(7 downto 0) <= PS_SRC_UDP_PORT_IN(15 downto 8);\r
+ TC_DEST_UDP_OUT(15 downto 8) <= PS_SRC_UDP_PORT_IN(7 downto 0);\r
+ TC_SRC_MAC_OUT <= MY_MAC_IN;\r
+ TC_SRC_IP_OUT <= MY_IP_IN;\r
+ TC_SRC_UDP_OUT <= x"9065"; --x"a861";\r
+ TC_IP_PROTOCOL_OUT <= x"11";\r
+ TC_IDENT_OUT <= x"3" & std_logic_vector(reply_ctr(11 downto 0));\r
+\r
+ TC_FRAME_SIZE_OUT <= std_logic_vector(tx_data_ctr);\r
+\r
+ DISSECT_MACHINE_PROC: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ dissect_current_state <= IDLE;\r
+ elsif( rising_edge(CLK) ) then\r
+ dissect_current_state <= dissect_next_state;\r
+ end if;\r
+ end process DISSECT_MACHINE_PROC;\r
+\r
+ DISSECT_MACHINE: process( dissect_current_state, reset_detected, too_much_data, PS_WR_EN_IN, PS_ACTIVATE_IN,\r
+ PS_DATA_IN, PS_SELECTED_IN, GSC_INIT_READ_IN, GSC_REPLY_DATAREADY_IN, tx_loaded_ctr,\r
+ tx_data_ctr, rx_fifo_q, GSC_BUSY_IN, delay_done )\r
+ begin\r
+ state <= x"0";\r
+\r
+ case dissect_current_state is\r
+\r
+ when IDLE =>\r
+ state <= x"1";\r
+ if( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') ) then\r
+ dissect_next_state <= READ_FRAME;\r
+ else\r
+ dissect_next_state <= IDLE;\r
+ end if;\r
+\r
+ when READ_FRAME =>\r
+ state <= x"2";\r
+ if ( (PS_DATA_IN(8) = '1') and (GSC_INIT_READ_IN = '0') ) then\r
+ dissect_next_state <= WAIT_FOR_HUB;\r
+ elsif( (PS_DATA_IN(8) = '1') and (GSC_INIT_READ_IN = '1') ) then\r
+ dissect_next_state <= LOAD_TO_HUB;\r
+ else\r
+ dissect_next_state <= READ_FRAME;\r
+ end if;\r
+\r
+ when WAIT_FOR_HUB =>\r
+ state <= x"3";\r
+ if( GSC_INIT_READ_IN = '1' ) then\r
+ dissect_next_state <= LOAD_TO_HUB;\r
+ else\r
+ dissect_next_state <= WAIT_FOR_HUB;\r
+ end if;\r
+\r
+ when LOAD_TO_HUB =>\r
+ state <= x"4";\r
+ if( (rx_fifo_q(17) = '1') and (GSC_INIT_READ_IN = '1') ) then\r
+ if( reset_detected = '1' ) then\r
+ dissect_next_state <= CLEANUP;\r
+ else\r
+ dissect_next_state <= WAIT_FOR_RESPONSE;\r
+ end if;\r
+ else\r
+ dissect_next_state <= LOAD_TO_HUB;\r
+ end if;\r
+\r
+ when WAIT_FOR_RESPONSE =>\r
+ state <= x"5";\r
+ if( GSC_REPLY_DATAREADY_IN = '1' ) then\r
+ dissect_next_state <= SAVE_RESPONSE;\r
+ else\r
+ dissect_next_state <= WAIT_FOR_RESPONSE;\r
+ end if;\r
+\r
+ when SAVE_RESPONSE =>\r
+ state <= x"6";\r
+ if( (GSC_REPLY_DATAREADY_IN = '0') and (GSC_BUSY_IN = '0') ) then\r
+ if( too_much_data = '0' ) then\r
+-- dissect_next_state <= WAIT_FOR_LOAD;\r
+ dissect_next_state <= DELAY;\r
+ else\r
+ dissect_next_state <= CLEANUP;\r
+ end if;\r
+ else\r
+ dissect_next_state <= SAVE_RESPONSE;\r
+ end if;\r
+\r
+ when DELAY =>\r
+ if( delay_done = '1' ) then\r
+ dissect_next_state <= WAIT_FOR_LOAD;\r
+ else\r
+ dissect_next_state <= DELAY;\r
+ end if;\r
+ \r
+ when WAIT_FOR_LOAD =>\r
+ state <= x"7";\r
+ if (PS_SELECTED_IN = '1') then\r
+ dissect_next_state <= LOAD_FRAME;\r
+ else\r
+ dissect_next_state <= WAIT_FOR_LOAD;\r
+ end if;\r
+\r
+ when LOAD_FRAME =>\r
+ state <= x"8";\r
+ if (tx_loaded_ctr = tx_data_ctr) then\r
+ dissect_next_state <= CLEANUP;\r
+ else\r
+ dissect_next_state <= LOAD_FRAME;\r
+ end if;\r
+\r
+ when CLEANUP =>\r
+ state <= x"9";\r
+ dissect_next_state <= IDLE;\r
+\r
+ when others => dissect_next_state <= IDLE;\r
+\r
+ end case;\r
+ end process DISSECT_MACHINE;\r
+\r
+ PROC_DELAY_CTR: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if( dissect_current_state /= DELAY ) then\r
+ delay_ctr <= (others => '0');\r
+ else\r
+ delay_ctr <= delay_ctr + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_DELAY_CTR;\r
+\r
+ delay_done <= std_logic(delay_ctr(13));\r
+ \r
+ -- reset request packet detection\r
+ RESET_DETECTED_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( dissect_current_state = IDLE ) then\r
+ reset_detected <= '0';\r
+ 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\r
+ reset_detected <= '1';\r
+ end if;\r
+ end if;\r
+ end process RESET_DETECTED_PROC;\r
+\r
+ MAKE_RESET_PROC: process( CLK )\r
+ begin\r
+ if( rising_edge(CLK) ) then\r
+ if ( dissect_current_state = IDLE ) then\r
+ make_reset <= '0';\r
+ elsif( dissect_current_state = CLEANUP and reset_detected = '1' ) then\r
+ make_reset <= '1';\r
+ end if;\r
+ end if;\r
+ end process MAKE_RESET_PROC;\r
+\r
+ -- monitoring\r
+\r
+ PROC_MRF: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ mon_rec_frames <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1' ) then\r
+ mon_rec_frames <= mon_rec_frames + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_MRF;\r
+ MONITOR_SELECT_REC_OUT <= std_logic_vector(mon_rec_frames);\r
+\r
+ PROC_MRB: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ mon_rec_bytes <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( rx_fifo_wr = '1' ) then\r
+ mon_rec_bytes <= mon_rec_bytes + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_MRB;\r
+ MONITOR_SELECT_REC_BYTES_OUT <= std_logic_vector(mon_rec_bytes);\r
+\r
+ PROC_MSF: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ mon_sent_frames <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then\r
+ mon_sent_frames <= mon_sent_frames + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_MSF;\r
+ MONITOR_SELECT_SENT_OUT <= std_logic_vector(mon_sent_frames);\r
+\r
+ PROC_MSB: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ mon_sent_bytes <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( tx_fifo_rd = '1' ) then\r
+ mon_sent_bytes <= mon_sent_bytes + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_MSB;\r
+ MONITOR_SELECT_SENT_BYTES_OUT <= std_logic_vector(mon_sent_bytes);\r
+\r
+ -- needed for identification\r
+ PROC_REPLY_CTR: process( CLK, RESET )\r
+ begin\r
+ if ( RESET = '1' ) then\r
+ reply_ctr <= (others => '0');\r
+ elsif( rising_edge(CLK) ) then\r
+ if( dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr ) then\r
+ reply_ctr <= reply_ctr + 1;\r
+ end if;\r
+ end if;\r
+ end process PROC_REPLY_CTR;\r
+\r
+end architecture gbe_response_constructor_SCTRL_arch;\r