);
end component;
+ signal next_APL_DTYPE_OUT, reg_APL_DTYPE_OUT: std_logic_vector(3 downto 0);
+ signal next_APL_ERROR_PATTERN_OUT, reg_APL_ERROR_PATTERN_OUT: std_logic_vector(31 downto 0);
+ signal next_APL_SEQNR_OUT, reg_APL_SEQNR_OUT: std_logic_vector(7 downto 0);
+ signal next_APL_GOT_TRM, reg_APL_GOT_TRM: std_logic;
+ signal reg_APL_DTYPE_IN : std_logic_vector(3 downto 0);
+ signal reg_APL_ERROR_PATTERN_IN: std_logic_vector(31 downto 0);
+
+ signal fifo_term_buffer_data_in : std_logic_vector(15 downto 0);
+ signal fifo_term_buffer_write : std_logic;
+ signal fifo_term_buffer_data_out : std_logic_vector(15 downto 0);
+ signal fifo_term_buffer_read : std_logic;
+ signal fifo_term_buffer_full : std_logic;
+ signal fifo_term_buffer_empty : std_logic;
+ signal fifo_term_buffer_packet_num_in : std_logic_vector(1 downto 0);
+ signal fifo_term_buffer_packet_num_out : std_logic_vector(1 downto 0);
+
+ type TERM_BUFFER_STATE is (IDLE, SENDING_HEADER, RUNNING, SEND_TRAILER, MY_ERROR);
+ signal tb_current_state, tb_next_state : TERM_BUFFER_STATE;
+
+ signal tb_registered_trailer, tb_next_registered_trailer: std_logic_vector(47 downto 0);
+ signal tb_registered_target, tb_next_registered_target : std_logic_vector(15 downto 0);
+
+ signal next_INT_REPLY_READ_OUT, reg_INT_REPLY_READ_OUT : std_logic;
+ signal current_packet_type, saved_packet_type : std_logic_vector(2 downto 0);
+
+ signal reg_F1, next_F1 : std_logic_vector(15 downto 0);
+ signal reg_F2, next_F2 : std_logic_vector(15 downto 0);
+ signal reg_F3, next_F3 : std_logic_vector(15 downto 0);
+ signal reg_buffer_type, next_buffer_type : std_logic_vector(2 downto 0);
+ signal transfer_counter : std_logic_vector(1 downto 0);
begin
+ CHECK_BUFFER1: if FIFO_TERM_BUFFER_DEPTH >0 generate
+ FIFO_TERM_BUFFER: trb_net16_fifo
+ generic map (
+ DATA_WIDTH => 16,
+ NUM_WIDTH => 2,
+ DEPTH => FIFO_TERM_BUFFER_DEPTH)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ DATA_IN => fifo_term_buffer_data_in,
+ PACKET_NUM_IN => fifo_term_buffer_packet_num_in,
+ WRITE_ENABLE_IN => fifo_term_buffer_write,
+ DATA_OUT => fifo_term_buffer_data_out,
+ PACKET_NUM_OUT => fifo_term_buffer_packet_num_out,
+ READ_ENABLE_IN => fifo_term_buffer_read,
+ FULL_OUT => fifo_term_buffer_full,
+ EMPTY_OUT => fifo_term_buffer_empty
+ );
+ end generate CHECK_BUFFER1;
+
+ CHECK_BUFFER2: if FIFO_TERM_BUFFER_DEPTH =0 generate
+ fifo_term_buffer_empty <= '1';
+ fifo_term_buffer_full <= '0';
+ fifo_term_buffer_data_out <= (others => '0');
+ end generate CHECK_BUFFER2;
+
+ APL_DTYPE_OUT <= reg_APL_DTYPE_OUT;
+ APL_ERROR_PATTERN_OUT <= reg_APL_ERROR_PATTERN_OUT;
+ APL_SEQNR_OUT <= reg_APL_SEQNR_OUT;
+ APL_GOT_TRM <= reg_APL_GOT_TRM;
+
+ --count packets
+ REG_TRANSFER_COUNTER : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ transfer_counter <= (others => '0');
+ elsif fifo_term_buffer_write = '1' then
+ transfer_counter <= transfer_counter + 1;
+ end if;
+ end if;
+ end process;
+
+ --this holds the current packet type
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ saved_packet_type <= "111";
+ elsif INT_PACKET_NUM_IN = "00" then
+ saved_packet_type <= INT_DATA_IN(2 downto 0);
+ end if;
+ end if;
+ end process;
+
+ --create comb. real packet type
+ current_packet_type <= INT_DATA_IN(2 downto 0) when (INT_PACKET_NUM_IN = "00" and RESET = '0')
+ else saved_packet_type;
+
+
+ FIFO_TERM_BUFFER_CTRL: process (tb_current_state, INT_DATA_IN,
+ INT_DATAREADY_IN, tb_next_registered_trailer,
+ tb_registered_trailer,
+ fifo_term_buffer_empty, fifo_term_buffer_data_out,
+ INT_READ_IN, tb_registered_target,
+ reg_APL_DTYPE_OUT, reg_APL_ERROR_PATTERN_OUT,
+ reg_APL_SEQNR_OUT, reg_APL_GOT_TRM,APL_MY_ADDRESS_IN,
+ APL_HOLD_TRM, APL_DTYPE_IN, APL_ERROR_PATTERN_IN)
+ begin -- process
+ INT_READ_OUT <= '0';
+ fifo_term_buffer_write <= '0';
+ tb_next_state <= MY_ERROR;
+ fifo_term_buffer_read <= '0';
+ INT_DATAREADY_OUT <= '0';
+ next_APL_DTYPE_OUT <= reg_APL_DTYPE_OUT;
+ next_APL_ERROR_PATTERN_OUT <= reg_APL_ERROR_PATTERN_OUT;
+ next_APL_SEQNR_OUT <= reg_APL_SEQNR_OUT;
+ next_APL_GOT_TRM <= reg_APL_GOT_TRM;
+ next_F1 <= reg_F1;
+ next_F2 <= reg_F2;
+ next_F3 <= reg_F3;
+-----------------------------------------------------------------------
+-- IDLE
+-----------------------------------------------------------------------
+ if tb_current_state = IDLE then
+ INT_READ_OUT <= '1';
+ tb_next_state <= IDLE;
+
+ if current_packet_type = TYPE_HDR and INT_DATAREADY_IN = '1' then
+ --header is sent back with exchanged target and source address
+ tb_next_state <= SENDING_HEADER;
+
+ elsif current_packet_type = TYPE_DAT and INT_DATAREADY_IN = '1' then
+ --data can be directly sent back
+ fifo_term_buffer_data_in <= INT_DATA_IN;
+ if fifo_term_buffer_full = '0' and (tb_registered_target = APL_MY_ADDRESS_IN
+ or tb_registered_target = BROADCAST_ADRESS) then
+ fifo_term_buffer_write <= '1';
+ else
+ fifo_term_buffer_write <= '0';
+ end if;
+
+ elsif current_packet_type = TYPE_TRM and INT_DATAREADY_IN = '1' then
+ --TRM is given to APL
+ if INT_PACKET_NUM_IN = "01" then
+ next_APL_ERROR_PATTERN_OUT(31 downto 16) <= INT_DATA_IN;
+ elsif INT_PACKET_NUM_IN = "10" then
+ next_APL_ERROR_PATTERN_OUT(15 downto 0) <= INT_DATA_IN;
+ elsif INT_PACKET_NUM_IN = "11" then
+ next_APL_DTYPE_OUT <= INT_DATA_IN(DTYPE_POSITION);
+ next_APL_SEQNR_OUT <= INT_DATA_IN(SEQNR_POSITION);
+ next_APL_GOT_TRM <= '1';
+ end if;
+ tb_next_state <= RUNNING;
+ end if;
+-----------------------------------------------------------------------
+-- SENDING & RECEIVING HEADER
+-----------------------------------------------------------------------
+ --this state is needed to exchange source and target address
+ elsif tb_current_state = SENDING_HEADER then
+ INT_READ_OUT <= '1';
+ if INT_DATAREADY_IN = '1' then
+ fifo_term_buffer_write <= '1';
+ if INT_PACKET_NUM_IN = "01" then
+ next_F2 <= INT_DATA_IN;
+ fifo_term_buffer_data_in <= (others => '0');
+ fifo_term_buffer_data_in(2 downto 0) <= TYPE_HDR;
+ elsif INT_PACKET_NUM_IN = "10" then
+ next_F1 <= INT_DATA_IN;
+ fifo_term_buffer_data_in <= INT_DATA_IN;
+ elsif INT_PACKET_NUM_IN = "11" then
+ next_F3 <= INT_DATA_IN;
+ fifo_term_buffer_data_in <= reg_F2;
+ end if;
+ end if;
+ if transfer_counter = "11" then
+ INT_READ_OUT <= '0';
+ fifo_term_buffer_data_in <= reg_F3;
+ fifo_term_buffer_write <= '1';
+ tb_next_state <= IDLE;
+ end if;
+-----------------------------------------------------------------------
+-- RUNNING
+-----------------------------------------------------------------------
+ elsif tb_current_state = RUNNING then
+ if APL_HOLD_TRM = '1' then
+ tb_next_state <= RUNNING;
+ else
+ tb_next_state <= SEND_TRAILER;
+ end if;
+-----------------------------------------------------------------------
+-- TRAILER
+-----------------------------------------------------------------------
+ elsif tb_current_state = SEND_TRAILER then
+ tb_next_state <= SEND_TRAILER ;
+ fifo_term_buffer_write <= '1';
+ if transfer_counter = "00" then
+ fifo_term_buffer_data_in <= (others => '0');
+ fifo_term_buffer_data_in(2 downto 0) <= TYPE_TRM;
+ elsif transfer_counter = "01" then
+ fifo_term_buffer_data_in <= reg_APL_ERROR_PATTERN_IN(31 downto 16);
+ elsif transfer_counter = "10" then
+ fifo_term_buffer_data_in <= reg_APL_ERROR_PATTERN_IN(15 downto 0);
+ else
+ fifo_term_buffer_data_in(15 downto 12)<= (others => '0');
+ fifo_term_buffer_data_in(11 downto 4) <= reg_APL_SEQNR_OUT;
+ fifo_term_buffer_data_in(3 downto 0) <= reg_APL_DTYPE_OUT;
+ end if;
+ if transfer_counter = "11" then
+ tb_next_state <= IDLE;
+ tb_next_registered_target <= ILLEGAL_ADRESS;
+ next_APL_GOT_TRM <= '0';
+ end if;
+ end if;
+-----------------------------------------------------------------------
+-- WRITE FIFO TO INT
+-----------------------------------------------------------------------
+ if fifo_term_buffer_empty = '0' then
+ INT_DATAREADY_OUT <= '1';
+ INT_DATA_OUT <= fifo_term_buffer_data_out;
+ INT_PACKET_NUM_OUT <= fifo_term_buffer_packet_num_out;
+ if (INT_READ_IN = '1') then
+ fifo_term_buffer_read <= '1';
+ end if;
+ end if;
+ end process;
+
+ fifo_term_buffer_packet_num_in <= transfer_counter;
+
+ CLK_REG: process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ tb_current_state <= IDLE;
+ tb_registered_trailer <= (others => '0');
+ tb_registered_target <= ILLEGAL_ADRESS;
+ reg_buffer_type <= TYPE_ILLEGAL;
+ reg_F1 <= ILLEGAL_ADRESS;
+ reg_F2 <= ILLEGAL_ADRESS;
+ reg_F3 <= (others => '0');
+ reg_APL_GOT_TRM <= '0';
+ reg_APL_DTYPE_OUT <= (others => '0');
+ reg_APL_ERROR_PATTERN_OUT <= (others => '0');
+ reg_APL_SEQNR_OUT <= (others => '0');
+ else
+ tb_current_state <= tb_next_state;
+ tb_registered_trailer <= tb_next_registered_trailer;
+ tb_registered_target <= tb_next_registered_target;
+ reg_buffer_type <= next_buffer_type;
+ reg_F1 <= next_F1;
+ reg_F2 <= next_F2;
+ reg_F3 <= next_F3;
+ reg_APL_GOT_TRM <= next_APL_GOT_TRM;
+ reg_APL_DTYPE_OUT <= next_APL_DTYPE_OUT;
+ reg_APL_ERROR_PATTERN_OUT <= next_APL_ERROR_PATTERN_OUT;
+ reg_APL_SEQNR_OUT <= next_APL_SEQNR_OUT;
+ end if;
+ end if;
+ end process;
+
+ --save data from api while sending trailer
+ CLK_REG2: process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ reg_APL_DTYPE_IN <= (others => '0');
+ reg_APL_ERROR_PATTERN_IN <= (others => '0');
+ elsif APL_HOLD_TRM = '0' and tb_current_state /= SEND_TRAILER then
+ reg_APL_DTYPE_IN <= APL_DTYPE_IN;
+ reg_APL_ERROR_PATTERN_IN <= APL_ERROR_PATTERN_IN;
+ end if;
+ end if;
+ end process;
+
end architecture;