From 089c700bc4b366e2523c32e6420213f562f98c1b Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Fri, 28 Sep 2007 15:46:51 +0000 Subject: [PATCH] first version of trb_net16_api, Jan --- trb_net16_active_api.vhd | 11 +- trb_net16_base_api.vhd | 695 ++++++++++++++++++++++++++++++++++++++ trb_net16_dummy_fifo.vhd | 10 +- trb_net16_passive_api.vhd | 4 +- trb_net16_term.vhd | 69 +++- trb_net_dummy_fifo.vhd | 6 +- 6 files changed, 761 insertions(+), 34 deletions(-) diff --git a/trb_net16_active_api.vhd b/trb_net16_active_api.vhd index dfd3954..744ad19 100644 --- a/trb_net16_active_api.vhd +++ b/trb_net16_active_api.vhd @@ -2,15 +2,6 @@ -- for a description see HADES wiki -- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetAPI - ---the packet numbers to the api are ---Bit 48 - 32 : 01 ---Bit 31 - 16 : 10 ---Bit 15 - 00 : 11 ---packet number 00 is added by the api to the medium. ---the packets must be transmitted in the given order ---if you prefer an other sequence for your internal logic, consider using the inverted numbers - LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; @@ -214,10 +205,12 @@ begin INT_SLAVE_DATAREADY_OUT => INT_REPLY_DATAREADY_OUT, INT_SLAVE_DATA_OUT => INT_REPLY_DATA_OUT, + INT_SLAVE_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT, INT_SLAVE_READ_IN => INT_REPLY_READ_IN, INT_SLAVE_DATAREADY_IN => INT_REPLY_DATAREADY_IN, INT_SLAVE_DATA_IN => INT_REPLY_DATA_IN, + INT_SLAVE_PACKET_NUM_IN => INT_REPLY_PACKET_NUM_IN, INT_SLAVE_READ_OUT => INT_REPLY_READ_OUT, -- Status and control port STAT_FIFO_TO_INT => STAT_FIFO_TO_INT, diff --git a/trb_net16_base_api.vhd b/trb_net16_base_api.vhd index cead880..6cff6aa 100644 --- a/trb_net16_base_api.vhd +++ b/trb_net16_base_api.vhd @@ -82,6 +82,701 @@ end entity; architecture trb_net16_base_api_arch of trb_net16_base_api is + component trb_net16_dummy_fifo is + generic ( + DATA_WIDTH : integer := 16; -- FIFO word width + NUM_WIDTH : integer := 2 + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + DATA_IN : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- Input data + PACKET_NUM_IN : in std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + WRITE_ENABLE_IN : in std_logic; + DATA_OUT : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- Output data + PACKET_NUM_OUT : out std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + READ_ENABLE_IN : in std_logic; + FULL_OUT : out std_logic; -- Full Flag + EMPTY_OUT : out std_logic; + DEPTH_OUT : out std_logic_vector(7 downto 0) + ); + end component; + + component trb_net16_fifo is + generic ( + DATA_WIDTH : integer := 16; -- FIFO word width + NUM_WIDTH : integer := 2; + DEPTH : integer := 3 -- Depth of the FIFO, 2^(n+1) 64Bit packets + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + DATA_IN : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- Input data + PACKET_NUM_IN : in std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + WRITE_ENABLE_IN : in std_logic; + DATA_OUT : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- Output data + PACKET_NUM_OUT : out std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + READ_ENABLE_IN : in std_logic; + FULL_OUT : out std_logic; -- Full Flag + EMPTY_OUT : out std_logic; + DEPTH_OUT : out std_logic_vector(7 downto 0) + ); + end component; + + component trb_net16_sbuf is + generic ( + DATA_WIDTH : integer := 16; + NUM_WIDTH : integer := 2; + VERSION : integer := 0 + ); + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + -- port to combinatorial logic + COMB_DATAREADY_IN : in STD_LOGIC; --comb logic provides data word + COMB_next_READ_OUT: out STD_LOGIC; --sbuf can read in NEXT cycle + COMB_READ_IN : in STD_LOGIC; --comb logic IS reading + COMB_DATA_IN : in STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word + COMB_PACKET_NUM_IN: in STD_LOGIC_VECTOR(NUM_WIDTH-1 downto 0); + -- Port to synchronous output. + SYN_DATAREADY_OUT : out STD_LOGIC; + SYN_DATA_OUT : out STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word + SYN_PACKET_NUM_OUT: out STD_LOGIC_VECTOR(NUM_WIDTH-1 downto 0); + SYN_READ_IN : in STD_LOGIC; + -- Status and control port + STAT_BUFFER : out STD_LOGIC + ); + end component; + + component trb_net16_term is + generic ( + FIFO_TERM_BUFFER_DEPTH : integer := 0 -- fifo for auto-answering of + -- the master path, if set to 0 + -- no buffer is used at all + ); + port( + -- Misc + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + INT_DATAREADY_OUT: out std_logic; + INT_DATA_OUT: out std_logic_vector (15 downto 0); -- Data word + INT_PACKET_NUM_OUT: out std_logic_vector (1 downto 0); + INT_READ_IN: in std_logic; + INT_DATAREADY_IN: in std_logic; + INT_DATA_IN: in std_logic_vector (15 downto 0); -- Data word + INT_PACKET_NUM_IN: in std_logic_vector (1 downto 0); + INT_READ_OUT: out std_logic; + -- "mini" APL, just to see the triggers coming in + APL_DTYPE_OUT: out std_logic_vector (3 downto 0); -- see NewTriggerBusNetworkDescr + APL_ERROR_PATTERN_OUT: out std_logic_vector (31 downto 0); -- see NewTriggerBusNetworkDescr + APL_SEQNR_OUT: out std_logic_vector (7 downto 0); + APL_GOT_TRM: out std_logic; + APL_HOLD_TRM: in std_logic; + APL_DTYPE_IN: in std_logic_vector (3 downto 0); -- see NewTriggerBusNetworkDescr + APL_ERROR_PATTERN_IN: in std_logic_vector (31 downto 0); -- see NewTriggerBusNetworkDescr + APL_MY_ADDRESS_IN: in std_logic_vector (15 downto 0) -- My own address (temporary solution!!!) + -- Status and control port + ); + end component; + + -- signals for the APL to INT fifo: + signal fifo_to_int_data_in : std_logic_vector(15 downto 0); + signal fifo_to_int_packet_num_in : std_logic_vector(1 downto 0); + signal fifo_to_int_write : std_logic; + signal fifo_to_int_data_out : std_logic_vector(15 downto 0); + signal fifo_to_int_packet_num_out : std_logic_vector(1 downto 0); + signal fifo_to_int_read : std_logic; + signal fifo_to_int_full : std_logic; + signal fifo_to_int_empty : std_logic; + + -- signals for the INT to APL: + signal fifo_to_apl_data_in : std_logic_vector(15 downto 0); + signal fifo_to_apl_packet_num_in : std_logic_vector(1 downto 0); + signal fifo_to_apl_write : std_logic; + signal fifo_to_apl_data_out : std_logic_vector(15 downto 0); + signal fifo_to_apl_packet_num_out : std_logic_vector(1 downto 0); + signal fifo_to_apl_read : std_logic; + signal fifo_to_apl_full : std_logic; + signal fifo_to_apl_empty : std_logic; + signal saved_fifo_to_apl_packet_type, current_fifo_to_apl_packet_type : std_logic_vector(2 downto 0); + + + -- signals for the test buffer + signal fifo_term_buffer_data_in : std_logic_vector(15 downto 0); + signal fifo_term_buffer_packet_num_in : std_logic_vector(1 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_packet_num_out : std_logic_vector(1 downto 0); + signal fifo_term_buffer_read : std_logic; + signal fifo_term_buffer_full : std_logic; + signal fifo_term_buffer_empty : std_logic; + + signal state_bits : std_logic_vector(2 downto 0); + type API_STATE is (IDLE, SEND_HEADER, RUNNING, SHUTDOWN, SEND_SHORT, SEND_TRAILER, WAITING,MY_ERROR); + type TERM_BUFFER_STATE is (IDLE, RUNNING, SEND_TRAILER, MY_ERROR); + signal current_state, next_state : API_STATE; + signal tb_current_state, tb_next_state : TERM_BUFFER_STATE; + signal slave_running, next_slave_running : std_logic; + + signal next_INT_MASTER_DATA_OUT: std_logic_vector(15 downto 0); + signal next_INT_MASTER_PACKET_NUM_OUT: std_logic_vector(1 downto 0); + signal next_INT_MASTER_DATAREADY_OUT: std_logic; + signal sbuf_free, sbuf_next_READ: std_logic; + signal next_INT_SLAVE_READ_OUT, reg_INT_SLAVE_READ_OUT: std_logic; + signal next_APL_DATAREADY_OUT, reg_APL_DATAREADY_OUT: std_logic; + signal next_APL_DATA_OUT, reg_APL_DATA_OUT: std_logic_vector(15 downto 0); + signal next_APL_PACKET_NUM_OUT, reg_APL_PACKET_NUM_OUT: std_logic_vector(1 downto 0); + signal next_APL_TYP_OUT, reg_APL_TYP_OUT: std_logic_vector(2 downto 0); + + type OUTPUT_SELECT is (HDR, DAT, TRM, TRM_COMB); + signal out_select: OUTPUT_SELECT; + signal sequence_counter,next_sequence_counter : std_logic_vector(7 downto 0); + signal combined_header_F1, combined_header_F2, combined_header_F3 : std_logic_vector(15 downto 0); + signal combined_trailer_F1, combined_trailer_F2, combined_trailer_F3 : std_logic_vector(15 downto 0); + signal next_registered_trailer_F1, next_registered_trailer_F2, next_registered_trailer_F3 : std_logic_vector(15 downto 0); + signal registered_trailer_F1, registered_trailer_F2, registered_trailer_F3 : std_logic_vector(15 downto 0); + + signal update_registered_trailer: std_logic; + + signal master_counter : std_logic_vector(1 downto 0); + begin +--------------------------------------- +-- termination for active api +--------------------------------------- + + TrbNetTerm: trb_net16_term + generic map( + FIFO_TERM_BUFFER_DEPTH => 0) + port map( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + INT_DATAREADY_OUT => INT_SLAVE_DATAREADY_OUT, + INT_DATA_OUT => INT_SLAVE_DATA_OUT, + INT_PACKET_NUM_OUT=> INT_SLAVE_PACKET_NUM_OUT, + INT_READ_IN => INT_SLAVE_READ_IN, + INT_DATAREADY_IN => INT_MASTER_DATAREADY_IN, + INT_DATA_IN => INT_MASTER_DATA_IN, + INT_PACKET_NUM_IN => INT_MASTER_PACKET_NUM_IN, + INT_READ_OUT => INT_MASTER_READ_OUT, + APL_HOLD_TRM => '0', + APL_DTYPE_IN => (others => '0'), + APL_ERROR_PATTERN_IN => (others => '0'), + APL_MY_ADDRESS_IN => APL_MY_ADDRESS_IN); + +--------------------------------------- +-- fifo to internal +--------------------------------------- + + CHECK_BUFFER3: if FIFO_TO_INT_DEPTH >0 generate + FIFO_TO_INT: trb_net16_fifo + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2, + DEPTH => FIFO_TO_INT_DEPTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_int_data_in, + PACKET_NUM_IN => fifo_to_int_packet_num_in, + WRITE_ENABLE_IN => fifo_to_int_write, + DATA_OUT => fifo_to_int_data_out, + PACKET_NUM_OUT => fifo_to_int_packet_num_out, + READ_ENABLE_IN => fifo_to_int_read, + FULL_OUT => fifo_to_int_full, + EMPTY_OUT => fifo_to_int_empty + ); + end generate; + + CHECK_BUFFER4: if FIFO_TO_INT_DEPTH =0 generate + FIFO_TO_INT: trb_net16_dummy_fifo + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_int_data_in, + PACKET_NUM_IN => fifo_to_int_packet_num_in, + WRITE_ENABLE_IN => fifo_to_int_write, + DATA_OUT => fifo_to_int_data_out, + PACKET_NUM_OUT => fifo_to_int_packet_num_out, + READ_ENABLE_IN => fifo_to_int_read, + FULL_OUT => fifo_to_int_full, + EMPTY_OUT => fifo_to_int_empty + ); + end generate CHECK_BUFFER4; + + STAT_FIFO_TO_INT(2 downto 0) <= fifo_to_int_data_in(2 downto 0); + STAT_FIFO_TO_INT(3) <= fifo_to_int_write; + STAT_FIFO_TO_INT(10 downto 8) <= fifo_to_int_data_out(2 downto 0); + STAT_FIFO_TO_INT(11) <= fifo_to_int_read; + STAT_FIFO_TO_INT(14) <= fifo_to_int_full; + STAT_FIFO_TO_INT(15) <= fifo_to_int_empty; + STAT_FIFO_TO_INT(7 downto 4) <= (others => '0'); + STAT_FIFO_TO_INT(13 downto 12) <= (others => '0'); + STAT_FIFO_TO_INT(28 downto 16) <= (others => '0'); + STAT_FIFO_TO_INT(31 downto 29) <= state_bits; +--------------------------------------- +-- fifo to apl +--------------------------------------- + + CHECK_BUFFER5: if FIFO_TO_APL_DEPTH >0 generate + FIFO_TO_APL: trb_net16_fifo + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2, + DEPTH => FIFO_TO_APL_DEPTH) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_apl_data_in, + PACKET_NUM_IN => fifo_to_apl_packet_num_in, + WRITE_ENABLE_IN => fifo_to_apl_write, + DATA_OUT => fifo_to_apl_data_out, + PACKET_NUM_OUT => fifo_to_apl_packet_num_out, + READ_ENABLE_IN => fifo_to_apl_read, + FULL_OUT => fifo_to_apl_full, + EMPTY_OUT => fifo_to_apl_empty + ); + end generate CHECK_BUFFER5; + + CHECK_BUFFER6: if FIFO_TO_APL_DEPTH =0 generate + FIFO_TO_APL: trb_net16_dummy_fifo + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + DATA_IN => fifo_to_apl_data_in, + PACKET_NUM_IN => fifo_to_apl_packet_num_in, + WRITE_ENABLE_IN => fifo_to_apl_write, + DATA_OUT => fifo_to_apl_data_out, + PACKET_NUM_OUT => fifo_to_apl_packet_num_out, + READ_ENABLE_IN => fifo_to_apl_read, + FULL_OUT => fifo_to_apl_full, + EMPTY_OUT => fifo_to_apl_empty + ); + end generate CHECK_BUFFER6; + + STAT_FIFO_TO_APL(2 downto 0) <= fifo_to_apl_data_in(2 downto 0); + STAT_FIFO_TO_APL(3) <= fifo_to_apl_write; + STAT_FIFO_TO_APL(9 downto 8) <= fifo_to_apl_data_out(1 downto 0); + STAT_FIFO_TO_APL(11) <= fifo_to_apl_read; + STAT_FIFO_TO_APL(14) <= fifo_to_apl_full; + STAT_FIFO_TO_APL(15) <= fifo_to_apl_empty; + STAT_FIFO_TO_APL(7 downto 4) <= (others => '0'); + --STAT_FIFO_TO_APL(13 downto 12) <= (others => '0'); + STAT_FIFO_TO_APL(31 downto 16) <= (others => '0'); + STAT_FIFO_TO_APL(13) <= reg_INT_SLAVE_READ_OUT; + STAT_FIFO_TO_APL(12) <= INT_SLAVE_DATAREADY_IN; + STAT_FIFO_TO_APL(10) <= reg_APL_DATAREADY_OUT; + +--------------------------------------- +-- a sbuf on the active channel +--------------------------------------- + + ACTIVE_SBUF: trb_net16_sbuf + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2, + VERSION => 0) + port map ( + CLK => CLK, + RESET => RESET, + CLK_EN => CLK_EN, + COMB_DATAREADY_IN => next_INT_MASTER_DATAREADY_OUT, + COMB_next_READ_OUT => sbuf_next_READ, + COMB_READ_IN => '1', + COMB_DATA_IN => next_INT_MASTER_DATA_OUT, + COMB_PACKET_NUM_IN => next_INT_MASTER_PACKET_NUM_OUT, + SYN_DATAREADY_OUT => INT_MASTER_DATAREADY_OUT, + SYN_DATA_OUT => INT_MASTER_DATA_OUT, + SYN_PACKET_NUM_OUT => INT_MASTER_PACKET_NUM_OUT, + SYN_READ_IN => INT_MASTER_READ_IN + ); + + sbuf_free <= sbuf_next_READ; + next_registered_trailer_F1 <= combined_trailer_F1; + next_registered_trailer_F2 <= combined_trailer_F2; + next_registered_trailer_F3 <= combined_trailer_F3; + + next_APL_DATA_OUT <= fifo_to_apl_data_out; + next_APL_PACKET_NUM_OUT <= fifo_to_apl_packet_num_out; + next_APL_TYP_OUT <= current_fifo_to_apl_packet_type; + + + --this holds the current packet type from fifo_to_apl + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + saved_fifo_to_apl_packet_type <= TYPE_ILLEGAL; + elsif fifo_to_apl_packet_num_out = "00" then + saved_fifo_to_apl_packet_type <= fifo_to_apl_data_out(2 downto 0); + end if; + end if; + end process; + --create comb. real packet type + current_fifo_to_apl_packet_type <= fifo_to_apl_data_out(2 downto 0) when (fifo_to_apl_packet_num_out = "00" and RESET = '0') + else saved_fifo_to_apl_packet_type; + +--------------------------------------- +-- select data for int direction +--------------------------------------- + process (out_select, combined_header_F1, combined_header_F2, + combined_header_F3, registered_trailer_F1, registered_trailer_F2, + registered_trailer_F3, fifo_to_int_data_out, combined_trailer_F1, + combined_trailer_F2, combined_trailer_F3, master_counter) + begin + if out_select = HDR then + if master_counter = "00" then + next_INT_MASTER_DATA_OUT <= (others => '0'); + next_INT_MASTER_DATA_OUT(2 downto 0) <= TYPE_HDR; + elsif master_counter = "01" then + next_INT_MASTER_DATA_OUT <= combined_header_F1; + elsif master_counter = "10" then + next_INT_MASTER_DATA_OUT <= combined_header_F2; + elsif master_counter = "11" then + next_INT_MASTER_DATA_OUT <= combined_header_F3; + end if; + elsif out_select = TRM then + if master_counter = "00" then + next_INT_MASTER_DATA_OUT <= (others => '0'); + next_INT_MASTER_DATA_OUT(2 downto 0) <= TYPE_TRM; + elsif master_counter = "01" then + next_INT_MASTER_DATA_OUT <= registered_trailer_F1; + elsif master_counter = "10" then + next_INT_MASTER_DATA_OUT <= registered_trailer_F2; + elsif master_counter = "11" then + next_INT_MASTER_DATA_OUT <= registered_trailer_F3; + end if; + elsif out_select = TRM_COMB then + if master_counter = "00" then + next_INT_MASTER_DATA_OUT <= (others => '0'); + next_INT_MASTER_DATA_OUT(2 downto 0) <= TYPE_TRM; + elsif master_counter = "01" then + next_INT_MASTER_DATA_OUT <= combined_trailer_F1; + elsif master_counter = "10" then + next_INT_MASTER_DATA_OUT <= combined_trailer_F2; + elsif master_counter = "11" then + next_INT_MASTER_DATA_OUT <= combined_trailer_F3; + end if; + else + if master_counter = "00" then + next_INT_MASTER_DATA_OUT <= (others => '0'); + next_INT_MASTER_DATA_OUT(2 downto 0) <= TYPE_DAT; + else + next_INT_MASTER_DATA_OUT <= fifo_to_int_data_out; + end if; + end if; + end process; + + next_INT_MASTER_PACKET_NUM_OUT <= master_counter; + + MASTER_TRANSFER_COUNTER : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + master_counter <= (others => '0'); + elsif next_INT_MASTER_DATAREADY_OUT = '1' then + master_counter <= master_counter + 1; + end if; + end if; + end process; + + +--------------------------------------- +--the state machine +--------------------------------------- + + STATE_COMB: process(current_state, APL_SEND_IN, slave_running, sequence_counter, + APL_SHORT_TRANSFER_IN, APL_WRITE_IN, fifo_to_int_empty, + sbuf_free, master_counter, fifo_to_apl_full, + reg_APL_DATAREADY_OUT, reg_INT_SLAVE_READ_OUT, + INT_SLAVE_DATAREADY_IN, fifo_to_apl_empty, APL_READ_IN, + fifo_to_apl_packet_num_out, reg_APL_TYP_OUT, + reg_APL_PACKET_NUM_OUT) + begin + next_state <= MY_ERROR; + next_INT_MASTER_DATAREADY_OUT <= '0'; + out_select <= DAT; + update_registered_trailer <= '0'; + fifo_to_int_read <= '0'; + next_INT_SLAVE_READ_OUT <= '0'; + fifo_to_apl_write <= '0'; + next_APL_DATAREADY_OUT <= '0'; + fifo_to_apl_read <= '0'; + next_slave_running <= slave_running; + next_sequence_counter <= sequence_counter; + ------------------------------------------------------------------------------- + -- IDLE + ------------------------------------------------------------------------------- + if current_state = IDLE then + if APL_SEND_IN = '1' then + if APL_SHORT_TRANSFER_IN = '1' and APL_WRITE_IN = '0' and fifo_to_int_empty = '1' then + next_state <= SEND_SHORT; -- no next data word, waiting for falling edge of APL_SEND_IN + update_registered_trailer <= '1'; -- moved from SEND_SHORT + else -- normal transfer, prepare the header + next_state <= SEND_HEADER; + out_select <= HDR; + next_INT_MASTER_DATAREADY_OUT <= '1'; + end if; -- next word will be a header + else + next_state <= IDLE; + end if; -- APL_SEND_IN + ------------------------------------------------------------------------------- + -- SEND_SHORT + ------------------------------------------------------------------------------- + elsif current_state = SEND_SHORT then + next_state <= SEND_SHORT; + if APL_SEND_IN = '0' then -- terminate the transfer + next_state <= SEND_TRAILER; + next_INT_MASTER_DATAREADY_OUT <= '1'; + out_select <= TRM; + end if; + ------------------------------------------------------------------------------- + -- SEND_HEADER + ------------------------------------------------------------------------------- + elsif current_state = SEND_HEADER then + if sbuf_free = '1' then + next_INT_MASTER_DATAREADY_OUT <= '1'; + end if; + if master_counter = "11" then + next_state <= RUNNING; + else + next_state <= SEND_HEADER; + end if; + ------------------------------------------------------------------------------- + -- RUNNING + ------------------------------------------------------------------------------- + elsif current_state = RUNNING then + if APL_SEND_IN = '0' then -- terminate the transfer + if fifo_to_int_empty = '1' then -- immediate stop + update_registered_trailer <= '1'; + next_INT_MASTER_DATAREADY_OUT <= '1'; + if master_counter = "11" then + next_state <= SEND_TRAILER; + out_select <= TRM_COMB; + end if; + else + next_state <= SHUTDOWN; + update_registered_trailer <= '1'; + if sbuf_free = '1' then + next_INT_MASTER_DATAREADY_OUT <= '1'; + out_select <= DAT; + if master_counter /= "00" then + fifo_to_int_read <= '1'; + end if; + end if; + end if; + else -- APL_SEND_IN: still running + next_state <= RUNNING; + if fifo_to_int_empty = '0' and sbuf_free = '1' then + -- data words have to be prepared + next_INT_MASTER_DATAREADY_OUT <= '1'; + out_select <= DAT; + if master_counter /= "00" then + fifo_to_int_read <= '1'; + end if; + end if; -- fifo_to_int_empty = '0' + end if; + ------------------------------------------------------------------------------- + -- SHUTDOWN: Empty the pipe + ------------------------------------------------------------------------------- + elsif current_state = SHUTDOWN then + next_state <= SHUTDOWN; + if fifo_to_int_empty = '0' and sbuf_free = '1' then + -- data words have to be prepared + next_INT_MASTER_DATAREADY_OUT <= '1'; + out_select <= DAT; + if master_counter /= "00" then + fifo_to_int_read <= '1'; + end if; + elsif sbuf_free = '1' then + -- we are done + if master_counter = "11" then + next_state <= SEND_TRAILER; + out_select <= TRM; + end if; + next_INT_MASTER_DATAREADY_OUT <= '1'; + end if; + ------------------------------------------------------------------------------- + -- SEND_TRAILER + ------------------------------------------------------------------------------- + elsif current_state = SEND_TRAILER then + if sbuf_free = '1' then + next_INT_MASTER_DATAREADY_OUT <= '1'; + end if; + if master_counter = "11" then + next_state <= WAITING; + else + next_state <= SEND_TRAILER; + end if; + ------------------------------------------------------------------------------- + -- WAITING => for the answer or a request + ------------------------------------------------------------------------------- + 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_full = '0' or (fifo_to_apl_read = '1' and reg_APL_DATAREADY_OUT = '1') then + next_INT_SLAVE_READ_OUT <= '1'; + end if; + if reg_INT_SLAVE_READ_OUT = '1' and INT_SLAVE_DATAREADY_IN = '1' then + fifo_to_apl_write <= '1'; -- use fifo as the pipe + end if; + + -- part 2: connection to apl +-- if fifo_to_apl_empty = '0' then + if fifo_to_apl_empty = '0' and not (reg_APL_DATAREADY_OUT = '1' and APL_READ_IN = '1') + and fifo_to_apl_packet_num_out /= "00" then --is this really correct???? + next_APL_DATAREADY_OUT <= '1'; + end if; -- read/no read + + if (reg_APL_DATAREADY_OUT = '1' and APL_READ_IN = '1') or fifo_to_apl_packet_num_out = "00" then + -- valid read + fifo_to_apl_read <= '1'; + if (reg_APL_TYP_OUT = TYPE_TRM or reg_APL_TYP_OUT = TYPE_HDR) then + next_slave_running <= '1'; + end if; + if reg_APL_TYP_OUT = TYPE_TRM and reg_APL_PACKET_NUM_OUT= "11" + and (APL_READ_IN = '1' and reg_APL_DATAREADY_OUT = '1') then --fifo_to_apl_read = '1' + next_state <= IDLE; + next_sequence_counter <= sequence_counter +1; + end if; + end if; + -- MISSING: SEQNR check + -- OPEN QUESTION: Address matching? makes sense for a reply transfer? + end if; + + end process; + + CLK_REG: process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + sequence_counter <= (others => '0'); + reg_INT_SLAVE_READ_OUT <= '0'; + if API_TYPE = 1 then + current_state <= IDLE; + else + current_state <= WAITING; + end if; + slave_running <= '0'; + tb_current_state <= IDLE; + elsif CLK_EN = '1' then + sequence_counter <= next_sequence_counter; + reg_INT_SLAVE_READ_OUT <= next_INT_SLAVE_READ_OUT; + current_state <= next_state; + slave_running <= next_slave_running; + tb_current_state <= tb_next_state; + end if; + end if; + end process; + +--------------------------------------- +-- +--------------------------------------- + + -- combine the next header + combined_header_F1 <= APL_MY_ADDRESS_IN; + combined_header_F2 <= APL_TARGET_ADDRESS_IN; + combined_header_F3(15 downto 14) <= (others => '0'); -- LAY + combined_header_F3(13 downto 12) <= (others => '0'); -- VERS + combined_header_F3(11 downto 4) <= sequence_counter; -- SEQNR + combined_header_F3(3 downto 0) <= APL_DTYPE_IN; + combined_trailer_F1 <= APL_ERROR_PATTERN_IN(31 downto 16); + combined_trailer_F2 <= APL_ERROR_PATTERN_IN(15 downto 0); + combined_trailer_F3(15 downto 14) <= (others => '0'); -- res. + combined_trailer_F3(13 downto 12) <= (others => '0'); -- VERS + combined_trailer_F3(11 downto 4) <= sequence_counter; -- SEQNR + combined_trailer_F3(3 downto 0) <= APL_DTYPE_IN; + + -- connect Transmitter port + fifo_to_int_data_in <= APL_DATA_IN; + fifo_to_int_packet_num_in <= APL_PACKET_NUM_IN; + fifo_to_int_write <= (APL_WRITE_IN and not fifo_to_int_full) + when (current_state = IDLE or current_state = SEND_HEADER or current_state = RUNNING) + else '0'; + + APL_FIFO_FULL_OUT <= fifo_to_int_full; -- APL has to stop writing + + INT_SLAVE_READ_OUT <= reg_INT_SLAVE_READ_OUT; + + process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + reg_APL_DATAREADY_OUT <= '0'; + reg_APL_DATA_OUT <= (others => '0'); + reg_APL_PACKET_NUM_OUT <= (others => '0'); + reg_APL_TYP_OUT <= (others => '0'); + else + reg_APL_DATAREADY_OUT <= next_APL_DATAREADY_OUT; + reg_APL_DATA_OUT <= next_APL_DATA_OUT; + reg_APL_PACKET_NUM_OUT <= next_APL_PACKET_NUM_OUT; + reg_APL_TYP_OUT <= next_APL_TYP_OUT; + end if; + end if; + end process; + + + -- connect receiver + fifo_to_apl_data_in <= INT_SLAVE_DATA_IN; + fifo_to_apl_packet_num_in <= INT_SLAVE_PACKET_NUM_IN; + + APL_DATAREADY_OUT <= reg_APL_DATAREADY_OUT; + APL_DATA_OUT <= reg_APL_DATA_OUT; + APL_PACKET_NUM_OUT <= reg_APL_PACKET_NUM_OUT; + APL_TYP_OUT <= reg_APL_TYP_OUT; + APL_RUN_OUT <= '0' when ((current_state = IDLE and API_TYPE = 1) + or (slave_running = '0' and API_TYPE = 0)) + else '1'; + APL_SEQNR_OUT <= sequence_counter; + + REG3 : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + registered_trailer_F1 <= (others => '0'); + registered_trailer_F2 <= (others => '0'); + registered_trailer_F3 <= (others => '0'); + elsif update_registered_trailer = '1' then + registered_trailer_F1 <= next_registered_trailer_F1; + registered_trailer_F2 <= next_registered_trailer_F2; + registered_trailer_F3 <= next_registered_trailer_F3; + else + registered_trailer_F1 <= registered_trailer_F1; + registered_trailer_F2 <= registered_trailer_F2; + registered_trailer_F3 <= registered_trailer_F3; + end if; + end if; + end process; + + process(current_state) + begin + case current_state is + when IDLE => state_bits <= "000"; + when SEND_HEADER => state_bits <= "001"; + when RUNNING => state_bits <= "010"; + when SHUTDOWN => state_bits <= "011"; + when SEND_SHORT => state_bits <= "100"; + when SEND_TRAILER => state_bits <= "101"; + when WAITING => state_bits <= "110"; + when others => state_bits <= "111"; + end case; + end process; end architecture; \ No newline at end of file diff --git a/trb_net16_dummy_fifo.vhd b/trb_net16_dummy_fifo.vhd index 24e7ee5..24c0efc 100644 --- a/trb_net16_dummy_fifo.vhd +++ b/trb_net16_dummy_fifo.vhd @@ -10,8 +10,7 @@ USE ieee.std_logic_arith.ALL; entity trb_net16_dummy_fifo is generic ( DATA_WIDTH : integer := 16; -- FIFO word width - NUM_WIDTH : integer := 2; - DEPTH : integer := 4 -- Depth of the FIFO, 2^(n+1) + NUM_WIDTH : integer := 2 ); port ( CLK : in std_logic; @@ -32,7 +31,7 @@ end entity; architecture arch_trb_net16_dummy_fifo of trb_net16_dummy_fifo is - entity trb_net_dummy_fifo is + component trb_net_dummy_fifo is generic ( WIDTH : integer := DATA_WIDTH + NUM_WIDTH); port ( @@ -47,16 +46,17 @@ architecture arch_trb_net16_dummy_fifo of trb_net16_dummy_fifo is EMPTY_OUT : out std_logic; DEPTH_OUT : out std_logic_vector(7 downto 0) ); - end trb_net_dummy_fifo; + end component; signal din, dout : std_logic_vector(DATA_WIDTH + NUM_WIDTH -1 downto 0); + begin din(DATA_WIDTH - 1 downto 0) <= DATA_IN; din(DATA_WIDTH + NUM_WIDTH -1 downto DATA_WIDTH) <= PACKET_NUM_IN; DATA_OUT <= dout(DATA_WIDTH - 1 downto 0); PACKET_NUM_OUT <= dout(DATA_WIDTH + NUM_WIDTH - 1 downto DATA_WIDTH); - fifo : trb_net_fifo + fifo : trb_net_dummy_fifo port map( CLK => CLK, RESET => RESET, diff --git a/trb_net16_passive_api.vhd b/trb_net16_passive_api.vhd index 9692dbd..31543a8 100644 --- a/trb_net16_passive_api.vhd +++ b/trb_net16_passive_api.vhd @@ -201,14 +201,16 @@ begin INT_MASTER_PACKET_NUM_IN => INT_REPLY_PACKET_NUM_IN, INT_MASTER_READ_OUT => INT_REPLY_READ_OUT, - INT_SLAVE_HEADER_IN => INT_INIT_HEADER_IN, + INT_SLAVE_HEADER_IN => INT_REPLY_HEADER_IN, INT_SLAVE_DATAREADY_OUT => INT_INIT_DATAREADY_OUT, INT_SLAVE_DATA_OUT => INT_INIT_DATA_OUT, + INT_SLAVE_PACKET_NUM_OUT => INT_INIT_PACKET_NUM_OUT, INT_SLAVE_READ_IN => INT_INIT_READ_IN, INT_SLAVE_DATAREADY_IN => INT_INIT_DATAREADY_IN, INT_SLAVE_DATA_IN => INT_INIT_DATA_IN, + INT_SLAVE_PACKET_NUM_IN => INT_INIT_PACKET_NUM_IN, INT_SLAVE_READ_OUT => INT_INIT_READ_OUT, -- Status and control port STAT_FIFO_TO_INT => STAT_FIFO_TO_INT, diff --git a/trb_net16_term.vhd b/trb_net16_term.vhd index 4d9ef08..bb16db1 100644 --- a/trb_net16_term.vhd +++ b/trb_net16_term.vhd @@ -70,6 +70,27 @@ architecture trb_net16_term_arch of trb_net16_term is ); end component; + component trb_net16_dummy_fifo is + generic ( + DATA_WIDTH : integer := 16; -- FIFO word width + NUM_WIDTH : integer := 2 + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + CLK_EN : in std_logic; + DATA_IN : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- Input data + PACKET_NUM_IN : in std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + WRITE_ENABLE_IN : in std_logic; + DATA_OUT : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- Output data + PACKET_NUM_OUT : out std_logic_vector(NUM_WIDTH - 1 downto 0); -- Input data + READ_ENABLE_IN : in std_logic; + FULL_OUT : out std_logic; -- Full Flag + EMPTY_OUT : out std_logic; + DEPTH_OUT : out std_logic_vector(7 downto 0) + ); + 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); @@ -89,21 +110,18 @@ architecture trb_net16_term_arch of trb_net16_term is 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 + FIFO_TERM_BUFFER1: trb_net16_fifo generic map ( DATA_WIDTH => 16, NUM_WIDTH => 2, @@ -124,9 +142,24 @@ begin 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'); + FIFO_TERM_BUFFER0: trb_net16_dummy_fifo + generic map ( + DATA_WIDTH => 16, + NUM_WIDTH => 2) + 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_BUFFER2; APL_DTYPE_OUT <= reg_APL_DTYPE_OUT; @@ -164,17 +197,21 @@ begin FIFO_TERM_BUFFER_CTRL: process (tb_current_state, INT_DATA_IN, - INT_DATAREADY_IN, tb_next_registered_trailer, - tb_registered_trailer, + INT_DATAREADY_IN, 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) + APL_HOLD_TRM, APL_DTYPE_IN, APL_ERROR_PATTERN_IN, reg_F1, + reg_F2, reg_F3, current_packet_type, fifo_term_buffer_full, + INT_PACKET_NUM_IN, transfer_counter, + reg_APL_ERROR_PATTERN_IN, reg_APL_DTYPE_IN, + fifo_term_buffer_packet_num_out) begin -- process INT_READ_OUT <= '0'; fifo_term_buffer_write <= '0'; tb_next_state <= MY_ERROR; + tb_next_registered_target <= tb_registered_target; fifo_term_buffer_read <= '0'; INT_DATAREADY_OUT <= '0'; next_APL_DTYPE_OUT <= reg_APL_DTYPE_OUT; @@ -184,6 +221,7 @@ begin next_F1 <= reg_F1; next_F2 <= reg_F2; next_F3 <= reg_F3; + fifo_term_buffer_data_in <= (others => '0'); ----------------------------------------------------------------------- -- IDLE ----------------------------------------------------------------------- @@ -232,6 +270,7 @@ begin fifo_term_buffer_data_in(2 downto 0) <= TYPE_HDR; elsif INT_PACKET_NUM_IN = "10" then next_F1 <= INT_DATA_IN; + tb_next_registered_target <= INT_DATA_IN; fifo_term_buffer_data_in <= INT_DATA_IN; elsif INT_PACKET_NUM_IN = "11" then next_F3 <= INT_DATA_IN; @@ -269,7 +308,7 @@ begin 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; + fifo_term_buffer_data_in(3 downto 0) <= reg_APL_DTYPE_IN; end if; if transfer_counter = "11" then tb_next_state <= IDLE; @@ -280,10 +319,10 @@ begin ----------------------------------------------------------------------- -- WRITE FIFO TO INT ----------------------------------------------------------------------- + INT_DATA_OUT <= fifo_term_buffer_data_out; + INT_PACKET_NUM_OUT <= fifo_term_buffer_packet_num_out; 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; @@ -297,9 +336,7 @@ 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'); @@ -309,9 +346,7 @@ begin 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; diff --git a/trb_net_dummy_fifo.vhd b/trb_net_dummy_fifo.vhd index 57c778c..8ac1438 100644 --- a/trb_net_dummy_fifo.vhd +++ b/trb_net_dummy_fifo.vhd @@ -31,7 +31,7 @@ end trb_net_dummy_fifo; architecture arch_trb_net_dummy_fifo of trb_net_dummy_fifo is - signal current_DOUT, next_DOUT : std_logic_vector(WIDTH -1 downto 0); + signal current_DOUT : std_logic_vector(WIDTH -1 downto 0); signal current_FULL, next_FULL : std_logic; signal current_EMPTY, next_EMPTY : std_logic; @@ -41,7 +41,9 @@ architecture arch_trb_net_dummy_fifo of trb_net_dummy_fifo is EMPTY_OUT <= current_EMPTY; DATA_OUT <= current_DOUT; - process(READ_ENABLE_IN, WRITE_ENABLE_IN, current_EMPTY) + DEPTH_OUT <= (others => '0'); + + process(READ_ENABLE_IN, WRITE_ENABLE_IN, current_EMPTY, current_FULL) begin if WRITE_ENABLE_IN = '1' and READ_ENABLE_IN = '1' then next_FULL <= current_FULL; -- 2.43.0