APL_FIFO_FULL_OUT: out STD_LOGIC; -- Stop transfer, the fifo is full
APL_SHORT_TRANSFER_IN: in STD_LOGIC; --
APL_DTYPE_IN: in STD_LOGIC_VECTOR (3 downto 0); -- see NewTriggerBusNetworkDescr
- APL_ERROR_PATTERN: in STD_LOGIC_VECTOR (31 downto 0); -- see NewTriggerBusNetworkDescr
+ APL_ERROR_PATTERN_IN: in STD_LOGIC_VECTOR (31 downto 0); -- see NewTriggerBusNetworkDescr
APL_SEND_IN: in STD_LOGIC; -- Release sending of the data
APL_TARGET_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- Address of
-- the target (only for active APIs)
-- APL Control port
APL_RUN_OUT: out STD_LOGIC; -- Data transfer is running
APL_MY_ADDRESS_IN: in STD_LOGIC_VECTOR (15 downto 0); -- My own address (temporary solution!!!)
+ APL_SEQNR_OUT: out STD_LOGIC_VECTOR (7 downto 0);
-- Internal direction port
-- This is just a clone from trb_net_iobuf
signal combined_header, registered_header, next_registered_header: std_logic_vector(47 downto 0);
signal combined_trailer, registered_trailer, next_registered_trailer: std_logic_vector(47 downto 0);
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 sequence_counter,next_sequence_counter : std_logic_vector(7 downto 0);
signal next_INT_INIT_DATA_OUT, reg_INT_INIT_DATA_OUT: std_logic_vector(50 downto 0);
FIFO_TERM_BUFFER_CTRL: process (tb_current_state, INT_INIT_DATA_IN,
INT_INIT_DATAREADY_IN, tb_next_registered_trailer, tb_registered_trailer,
fifo_term_buffer_empty, fifo_term_buffer_data_out,
- INT_REPLY_READ_IN)
+ INT_REPLY_READ_IN, tb_registered_target)
begin -- process
INT_INIT_READ_OUT <= '0';
fifo_term_buffer_data_in(TYPE_POSITION) <= TYPE_ILLEGAL;
fifo_term_buffer_write <= '0';
tb_next_state <= MY_ERROR;
tb_next_registered_trailer <= tb_registered_trailer;
+ tb_next_registered_target <= tb_registered_target;
fifo_term_buffer_read<= '0';
INT_REPLY_DATAREADY_OUT <= '0';
INT_REPLY_DATA_OUT(DWORD_POSITION) <= (others => '0');
INT_INIT_READ_OUT <= '1'; -- I always can read
tb_next_state <= IDLE;
if INT_INIT_DATA_IN(TYPE_POSITION) = TYPE_HDR and INT_INIT_DATAREADY_IN = '1' then
- fifo_term_buffer_data_in(F1_POSITION) <= INT_INIT_DATA_IN(F2_POSITION);
- fifo_term_buffer_data_in(F2_POSITION) <= INT_INIT_DATA_IN(F1_POSITION);
+ -- switch source and target adress
+ fifo_term_buffer_data_in(SOURCE_POSITION) <= INT_INIT_DATA_IN(TARGET_POSITION);
+ fifo_term_buffer_data_in(TARGET_POSITION) <= INT_INIT_DATA_IN(SOURCE_POSITION);
fifo_term_buffer_data_in(F3_POSITION) <= INT_INIT_DATA_IN(F3_POSITION);
fifo_term_buffer_data_in(TYPE_POSITION) <= TYPE_HDR;
- fifo_term_buffer_write <= '1';
- -- switch source and target adress
+ tb_next_registered_target <= INT_INIT_DATA_IN(TARGET_POSITION);
+ if fifo_term_buffer_empty = '1' and (tb_next_registered_target = APL_MY_ADDRESS_IN
+ or tb_next_registered_target = BROADCAST_ADRESS) then
+ fifo_term_buffer_write <= '1';
+ else
+ fifo_term_buffer_write <= '0';
elsif INT_INIT_DATA_IN(TYPE_POSITION) <= TYPE_DAT and INT_INIT_DATAREADY_IN = '1' then
fifo_term_buffer_data_in <= INT_INIT_DATA_IN;
- fifo_term_buffer_write <= '1';
+ if fifo_term_buffer_empty = '1' 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';
elsif INT_INIT_DATA_IN(TYPE_POSITION) <= TYPE_TRM and INT_INIT_DATAREADY_IN = '1' then
tb_next_registered_trailer <= INT_INIT_DATA_IN(DWORD_POSITION);
--keep trailer for later use
INT_REPLY_DATA_OUT(TYPE_POSITION) <= TYPE_TRM;
if (INT_REPLY_READ_IN = '1') then
tb_next_state <= IDLE;
+ tb_next_registered_target <= ILLEGAL_ADRESS;
end if;
end if; -- tb_current_state switch
end process;
APL_WRITE_IN, fifo_to_int_empty, next_registered_header, registered_header,
reg_INT_INIT_DATA_OUT, reg_INT_INIT_DATA_OUT,
fifo_to_int_data_out, combined_trailer,
- next_registered_trailer, fifo_to_int_data_out)
+ next_registered_trailer, fifo_to_int_data_out, fifo_to_apl_empty,
+ INT_REPLY_DATAREADY_IN, reg_INT_REPLY_READ_OUT,fifo_to_apl_read,
+ reg_APL_DATAREADY_OUT, fifo_to_apl_data_out, reg_APL_DATAREADY_OUT,
+ APL_READ_IN)
begin -- process
next_state <= MY_ERROR;
next_registered_header <= registered_header;
next_INT_INIT_DATA_OUT(DWORD_POSITION) <= (others => '0');
next_registered_trailer <= registered_trailer;
fifo_to_int_read <= '0';
+
+ next_INT_REPLY_READ_OUT <= '0';
+ fifo_to_apl_write <= '0';
+ next_APL_DATAREADY_OUT <= '0';
+ next_APL_DATA_OUT <= (others => '0');
+ next_APL_TYP_OUT <= TYPE_ILLEGAL;
+ fifo_to_apl_read <= '0';
-------------------------------------------------------------------------------
-- IDLE
-------------------------------------------------------------------------------
next_INT_INIT_DATA_OUT(DWORD_POSITION) <= combined_trailer;
else
next_state <= SHUTDOWN;
+ next_registered_trailer <= combined_trailer;
+ if fifo_to_int_empty = '0' then
+ -- data words have to be prepared
+ next_INT_INIT_DATAREADY_OUT <= '1';
+ next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_DAT;
+ next_INT_INIT_DATA_OUT(DWORD_POSITION) <= fifo_to_int_data_out;
+ if INT_INIT_READ_IN = '1' and reg_INT_INIT_DATAREADY_OUT = '1' then
+ fifo_to_int_read <= '1';
+ else
+ fifo_to_int_read <= '0';
+ end if;
end if;
else -- APL_SEND_IN: still running
next_state <= RUNNING;
next_INT_INIT_DATAREADY_OUT <= '1';
next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_DAT;
next_INT_INIT_DATA_OUT(DWORD_POSITION) <= fifo_to_int_data_out;
- fifo_to_int_read <= '1';
+ if INT_INIT_READ_IN = '1' and reg_INT_INIT_DATAREADY_OUT = '1' then
+ fifo_to_int_read <= '1';
+ else
+ fifo_to_int_read <= '0';
end if;
end if;
-------------------------------------------------------------------------------
+-- SHUTDOWN: Empty the pipe
+-------------------------------------------------------------------------------
+ elsif current_state = SHUTDOWN then
+ if fifo_to_int_empty = '0' then
+ -- data words have to be prepared
+ next_INT_INIT_DATAREADY_OUT <= '1';
+ next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_DAT;
+ next_INT_INIT_DATA_OUT(DWORD_POSITION) <= fifo_to_int_data_out;
+ if INT_INIT_READ_IN = '1' and reg_INT_INIT_DATAREADY_OUT = '1' then
+ fifo_to_int_read <= '1';
+ else
+ fifo_to_int_read <= '0';
+ else
+ -- we are done
+ next_state <= SEND_TRAILER;
+ next_INT_INIT_DATAREADY_OUT <= '1';
+ next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_TRM;
+ next_INT_INIT_DATA_OUT(DWORD_POSITION) <= registered_trailer;
+ end if;
+-------------------------------------------------------------------------------
-- SEND_TRAILER
-------------------------------------------------------------------------------
elsif current_state = SEND_TRAILER then
+ if INT_INIT_READ_IN = '1' then -- kill current trailer
+ next_state <= WAITING;
+ next_INT_INIT_DATAREADY_OUT <= '0';
+ else
+ next_state <= SEND_TRAILER;
+ next_INT_INIT_DATAREADY_OUT <= '1';
+ next_INT_INIT_DATA_OUT(TYPE_POSITION) <= TYPE_TRM;
+ next_INT_INIT_DATA_OUT(DWORD_POSITION) <= registered_trailer;
+ end if;
+-------------------------------------------------------------------------------
+-- WAITING => for the answer
+-------------------------------------------------------------------------------
+ elsif current_state = WAITING then
+ next_state <= WAITING;
+ -- here we have to supply the receiver port
+ -- part 1: connection to network
+ if fifo_to_apl_empty = '0' or (fifo_to_apl_read = '1' and reg_APL_DATAREADY_OUT = '1') then
+ next_INT_REPLY_READ_OUT <= '1';
+ end if;
+ if reg_INT_REPLY_READ_OUT = '1' and INT_REPLY_DATAREADY_IN = '1' then
+ fifo_to_apl_write <= '1';
+ end if;
-
- end if; -- end state switch
-
+ -- part 2: connection to apl
+ if fifo_to_apl_empty = '0' then
+ -- data words have to be prepared
+ next_APL_DATAREADY_OUT <= '1';
+ next_APL_DATA_OUT <= fifo_to_apl_data_out(DWORD_POSITION);
+ next_APL_TYP_OUT <= fifo_to_apl_data_out(TYP_POSITION);
+ end if;
+ if reg_APL_DATAREADY_OUT = '1' and APL_READ_IN = '1' then
+ fifo_to_apl_read <= '1';
+ if reg_APL_TYP_OUT = TYPE_TRM and fifo_to_apl_empty = '1' then -- transfer completely finished
+ next_state <= IDLE;
+ elsif reg_APL_TYP_OUT = TYPE_TRM and fifo_to_apl_empty = '0' then
+ -- something wrong
+ next_state <= MY_ERROR;
+ end if;
+ end if;
+ -- MISSING: SEQNR check
+ -- OPEN QUESTION: Address matching? makes sense for a reply transfer?
+ end if; -- end state switch
end process;
-- internal port
INT_INIT_DATAREADY_OUT <= reg_INT_INIT_DATAREADY_OUT;
-
+ -- connect receiver
+ fifo_to_apl_data_in <= INT_REPLY_DATA_IN;
-- generate the sequence counter
-- combinatorial part
SEQNR_COMB : process(sequence_counter)
begin
- if current_state = SEND_TRAILER and next_state = WAITING then
+ if current_state = WAITING and next_state = IDLE then
next_sequence_counter <= sequence_counter+1;
else
next_sequence_counter <= sequence_counter;
registered_header <= (others => '0');
registered_trailer <= (others => '0');
tb_registered_trailer <= (others => '0');
+ tb_registered_target <= ILLEGAL_ADRESS;
elsif CLK_EN = '1' then
sequence_counter <= next_sequence_counter;
reg_INT_INIT_DATA_OUT <= next_INT_INIT_DATA_OUT;
registered_header <= next_registered_header;
registered_trailer <= next_registered_trailer;
tb_registered_trailer <= tb_next_registered_trailer;
+ tb_registered_target <= tb_next_registered_target;
else
sequence_counter <= sequence_counter;
reg_INT_INIT_DATA_OUT <= reg_INT_INIT_DATA_OUT;
registered_header <= registered_header;
registered_trailer <= registered_trailer;
tb_registered_trailer <= tb_registered_trailer;
+ tb_registered_target <= tb_registered_target;
end if;
end if;
end process;