entity trb_net16_iobuf is
generic (
--FIFO size is given in 2^(n+1) 64Bit-packets i.e. 2^(n+3) 16bit packets
- INIT_DEPTH : integer := 3;
- REPLY_DEPTH : integer := 3);
+ INIT_DEPTH : integer := 2;
+ REPLY_DEPTH : integer := 2);
port(
-- Misc
CLK : in std_logic;
component trb_net16_obuf is
generic (
- DATA_COUNT_WIDTH : integer := 4;
+ DATA_COUNT_WIDTH : integer := 5
);
port(
-- Misc
-- Media direction port
MED_DATAREADY_IN: in std_logic; -- Data word is offered by the Media (the IOBUF MUST read)
MED_DATA_IN: in std_logic_vector (15 downto 0); -- Data word
- MED_PACKET_NUM_IN :out std_logic_vector(1 downto 0);
+ MED_PACKET_NUM_IN :in std_logic_vector(1 downto 0);
MED_READ_OUT: out std_logic; -- buffer reads a word from media
MED_ERROR_IN: in std_logic_vector (2 downto 0); -- Status bits
-- Internal direction port
INT_HEADER_IN: in std_logic; -- Concentrator kindly asks to resend the last header
INT_DATAREADY_OUT: out std_logic;
INT_DATA_OUT: out std_logic_vector (15 downto 0); -- Data word
- INT_PACKET_NUM_IN: in std_logic_vector(1 downto 0);
+ INT_PACKET_NUM_OUT:out std_logic_vector(1 downto 0);
INT_READ_IN: in std_logic;
INT_ERROR_OUT: out std_logic_vector (2 downto 0); -- Status bits
-- Status and control port
);
end component;
+ component trb_net16_term_ibuf is
+ port(
+ -- Misc
+ CLK : in std_logic;
+ RESET : in std_logic;
+ CLK_EN : in std_logic;
+ -- Media direction port
+ MED_DATAREADY_IN: in std_logic; -- Data word is offered by the Media (the IOBUF MUST read)
+ MED_DATA_IN: in std_logic_vector (15 downto 0); -- Data word
+ MED_PACKET_NUM_IN: in std_logic_vector (1 downto 0);
+ MED_READ_OUT: out std_logic; -- buffer reads a word from media
+ MED_ERROR_IN: in std_logic_vector (2 downto 0); -- Status bits
+ -- Internal direction port
+ INT_HEADER_IN: in std_logic; -- Concentrator kindly asks to resend the last header
+ 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_ERROR_OUT: out std_logic_vector (2 downto 0); -- Status bits
+ -- Status and control port
+ STAT_LOCKED: out std_logic_vector (15 downto 0);
+ CTRL_LOCKED: in std_logic_vector (15 downto 0);
+ STAT_BUFFER: out std_logic_vector (31 downto 0)
+ );
+ end component;
+
+ -- internal signals for the INITIBUF
+ signal INITIBUF_error: STD_LOGIC_VECTOR (2 downto 0); -- error watch needed!
+ signal INITIBUF_stat_locked, INITIBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+ signal INITIBUF_stat_buffer : STD_LOGIC_VECTOR (31 downto 0);
+
+ -- internal signals for the REPLYIBUF
+ signal REPLYIBUF_error: STD_LOGIC_VECTOR (2 downto 0); -- error watch needed!
+ signal REPLYIBUF_stat_locked, REPLYIBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+ signal REPLYIBUF_stat_buffer : STD_LOGIC_VECTOR (31 downto 0);
+
+ -- internal signals for the INITOBUF
+ signal INITOBUF_stat_locked, INITOBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+ signal INITOBUF_stat_buffer, INITOBUF_ctrl_buffer: STD_LOGIC_VECTOR (31 downto 0);
+
+ -- internal signals for the REPLYOBUF
+ signal REPLYOBUF_stat_locked, REPLYOBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+ signal REPLYOBUF_stat_buffer, REPLYOBUF_ctrl_buffer: STD_LOGIC_VECTOR (31 downto 0);
+
+-- locking control
+ signal INIT_IS_LOCKED, REPLY_IS_LOCKED: STD_LOGIC;
+ signal next_INIT_IS_LOCKED, next_REPLY_IS_LOCKED: STD_LOGIC;
begin
+ GEN_IBUF: if INIT_DEPTH>0 generate
+ INITIBUF : trb_net16_ibuf
+ generic map (
+ DEPTH => INIT_DEPTH)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_IN => MED_INIT_DATAREADY_IN,
+ MED_DATA_IN => MED_INIT_DATA_IN,
+ MED_PACKET_NUM_IN => MED_INIT_PACKET_NUM_IN,
+ MED_READ_OUT => MED_INIT_READ_OUT,
+ MED_ERROR_IN => MED_INIT_ERROR_IN,
+ INT_HEADER_IN => '0',
+ INT_DATAREADY_OUT => INT_INIT_DATAREADY_OUT,
+ INT_DATA_OUT => INT_INIT_DATA_OUT,
+ INT_PACKET_NUM_OUT => INT_INIT_PACKET_NUM_OUT,
+ INT_READ_IN => INT_INIT_READ_IN,
+ INT_ERROR_OUT => INITIBUF_error,
+ STAT_LOCKED(15 downto 0) => INITIBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => INITIBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => INITIBUF_stat_buffer
+ );
+ REPLYIBUF : trb_net16_ibuf
+ generic map (
+ DEPTH => REPLY_DEPTH)
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_IN => MED_REPLY_DATAREADY_IN,
+ MED_DATA_IN => MED_REPLY_DATA_IN,
+ MED_PACKET_NUM_IN => MED_REPLY_PACKET_NUM_IN,
+ MED_READ_OUT => MED_REPLY_READ_OUT,
+ MED_ERROR_IN => MED_REPLY_ERROR_IN,
+ INT_HEADER_IN => INT_REPLY_HEADER_IN,
+ INT_DATAREADY_OUT => INT_REPLY_DATAREADY_OUT,
+ INT_DATA_OUT => INT_REPLY_DATA_OUT,
+ INT_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT,
+ INT_READ_IN => INT_REPLY_READ_IN,
+ INT_ERROR_OUT => REPLYIBUF_error,
+ STAT_LOCKED(15 downto 0) => REPLYIBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => REPLYIBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => REPLYIBUF_stat_buffer
+ );
+ end generate;
+ GEN_TERM_IBUF: if INIT_DEPTH=0 generate
+ INITIBUF : trb_net16_term_ibuf
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_IN => MED_INIT_DATAREADY_IN,
+ MED_DATA_IN => MED_INIT_DATA_IN,
+ MED_PACKET_NUM_IN => MED_INIT_PACKET_NUM_IN,
+ MED_READ_OUT => MED_INIT_READ_OUT,
+ MED_ERROR_IN => MED_INIT_ERROR_IN,
+ INT_HEADER_IN => '0',
+ INT_DATAREADY_OUT => INT_INIT_DATAREADY_OUT,
+ INT_DATA_OUT => INT_INIT_DATA_OUT,
+ INT_PACKET_NUM_OUT => INT_INIT_PACKET_NUM_OUT,
+ INT_READ_IN => INT_INIT_READ_IN,
+ INT_ERROR_OUT => INITIBUF_error,
+ STAT_LOCKED(15 downto 0) => INITIBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => INITIBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => INITIBUF_stat_buffer
+ );
+ REPLYIBUF : trb_net16_term_ibuf
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_IN => MED_REPLY_DATAREADY_IN,
+ MED_DATA_IN => MED_REPLY_DATA_IN,
+ MED_PACKET_NUM_IN => MED_REPLY_PACKET_NUM_IN,
+ MED_READ_OUT => MED_REPLY_READ_OUT,
+ MED_ERROR_IN => MED_REPLY_ERROR_IN,
+ INT_HEADER_IN => INT_REPLY_HEADER_IN,
+ INT_DATAREADY_OUT => INT_REPLY_DATAREADY_OUT,
+ INT_DATA_OUT => INT_REPLY_DATA_OUT,
+ INT_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT,
+ INT_READ_IN => INT_REPLY_READ_IN,
+ INT_ERROR_OUT => REPLYIBUF_error,
+ STAT_LOCKED(15 downto 0) => REPLYIBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => REPLYIBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => REPLYIBUF_stat_buffer
+ );
+ end generate;
-end architecture;
+ INITOBUF : trb_net16_obuf
+
+-- generic map (
+-- DATA_COUNT_WIDTH => 16
+-- )
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_OUT => MED_INIT_DATAREADY_OUT,
+ MED_DATA_OUT => MED_INIT_DATA_OUT,
+ MED_PACKET_NUM_OUT => MED_INIT_PACKET_NUM_OUT,
+ MED_READ_IN => MED_INIT_READ_IN,
+ INT_DATAREADY_IN => INT_INIT_DATAREADY_IN,
+ INT_DATA_IN => INT_INIT_DATA_IN,
+ INT_PACKET_NUM_IN => INT_INIT_PACKET_NUM_IN,
+ INT_READ_OUT => INT_INIT_READ_OUT,
+ STAT_LOCKED(15 downto 0) => INITOBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => INITOBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => INITOBUF_stat_buffer,
+ CTRL_BUFFER(31 downto 0) => INITOBUF_ctrl_buffer
+ );
+
+ REPLYOBUF : trb_net16_obuf
+-- generic map (
+-- DATA_COUNT_WIDTH => 16
+-- )
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ MED_DATAREADY_OUT => MED_REPLY_DATAREADY_OUT,
+ MED_DATA_OUT => MED_REPLY_DATA_OUT,
+ MED_PACKET_NUM_OUT => MED_REPLY_PACKET_NUM_OUT,
+ MED_READ_IN => MED_REPLY_READ_IN,
+ INT_DATAREADY_IN => INT_REPLY_DATAREADY_IN,
+ INT_DATA_IN => INT_REPLY_DATA_IN,
+ INT_PACKET_NUM_IN => INT_REPLY_PACKET_NUM_IN,
+ INT_READ_OUT => INT_REPLY_READ_OUT,
+ STAT_LOCKED(15 downto 0) => REPLYOBUF_stat_locked,
+ CTRL_LOCKED(15 downto 0) => REPLYOBUF_ctrl_locked,
+ STAT_BUFFER(31 downto 0) => REPLYOBUF_stat_buffer,
+ CTRL_BUFFER(31 downto 0) => REPLYOBUF_ctrl_buffer
+ );
+
+
+-- build the registers according to the wiki page
+ STAT_INIT_BUFFER(11 downto 0) <= INITIBUF_stat_buffer(11 downto 0);
+ STAT_INIT_BUFFER(15 downto 14) <= INITOBUF_stat_buffer(1 downto 0);
+ STAT_INIT_BUFFER(31 downto 16) <= INITOBUF_stat_buffer(31 downto 16);
+ STAT_REPLY_BUFFER(11 downto 0) <= REPLYIBUF_stat_buffer(11 downto 0);
+ STAT_REPLY_BUFFER(15 downto 14) <= REPLYOBUF_stat_buffer(1 downto 0);
+ STAT_REPLY_BUFFER(31 downto 16) <= REPLYOBUF_stat_buffer(31 downto 16);
+
+-- build the CTRL register of the OBUFs
+ INITOBUF_ctrl_buffer(9 downto 0) <= INITIBUF_stat_buffer(9 downto 0);
+ INITOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+ REPLYOBUF_ctrl_buffer(9 downto 0) <= REPLYIBUF_stat_buffer(9 downto 0);
+ REPLYOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+
+ STAT_LOCKED(0) <= INIT_IS_LOCKED;
+ STAT_LOCKED(1) <= REPLY_IS_LOCKED;
+ STAT_LOCKED(31 downto 2) <= (others => '0');
+
+ REPLYOBUF_ctrl_locked(15 downto 2) <= (others => '0');
+ REPLYIBUF_ctrl_locked(15 downto 2) <= (others => '0');
+ INITOBUF_ctrl_locked(15 downto 2) <= (others => '0');
+ INITIBUF_ctrl_locked(15 downto 2) <= (others => '0');
+
+-- comb part of the locking control
+ comb_locked : process (INIT_IS_LOCKED, REPLY_IS_LOCKED, INITIBUF_stat_locked,
+ REPLYOBUF_stat_locked, REPLYIBUF_stat_locked,
+ INITOBUF_stat_locked, CTRL_LOCKED)
+
+ begin -- process
+ next_INIT_IS_LOCKED <= INIT_IS_LOCKED;
+ next_REPLY_IS_LOCKED <= REPLY_IS_LOCKED;
+ REPLYOBUF_ctrl_locked(1 downto 0) <= (others => '0');
+ REPLYIBUF_ctrl_locked(1 downto 0) <= (others => '0');
+ INITOBUF_ctrl_locked(1 downto 0) <= (others => '0');
+ INITIBUF_ctrl_locked(1 downto 0) <= (others => '0');
+ if REPLY_IS_LOCKED = '1' then
+ -- listen to INITOBUF
+ if INITOBUF_stat_locked(0) = '1' or CTRL_LOCKED(1) = '1' then
+ next_REPLY_IS_LOCKED <= '0';
+ REPLYIBUF_ctrl_locked(0) <= '1';
+ else
+ next_REPLY_IS_LOCKED <= '1';
+ end if;
+ else
+ -- listen to REPLYIBUF itself
+ if REPLYIBUF_stat_locked(0) = '1' then
+ next_REPLY_IS_LOCKED <= '1';
+ INITOBUF_ctrl_locked(0) <= '1';
+ else
+ next_REPLY_IS_LOCKED <= '0';
+ end if;
+ end if;
+
+ if INIT_IS_LOCKED = '1' then
+ -- listen to REPLYOBUF
+ if REPLYOBUF_stat_locked(0) = '1' or CTRL_LOCKED(0) = '1' then
+ next_INIT_IS_LOCKED <= '0';
+ INITIBUF_ctrl_locked(0) <= '1';
+ else
+ next_INIT_IS_LOCKED <= '1';
+ end if;
+ else
+ -- listen to INITIBUF itself
+ if INITIBUF_stat_locked(0) = '1' then
+ next_INIT_IS_LOCKED <= '1';
+ REPLYOBUF_ctrl_locked(0) <= '1';
+ else
+ next_INIT_IS_LOCKED <= '0';
+
+ end if;
+ end if;
+
+ end process;
+
+ reg_locked: process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ INIT_IS_LOCKED <= '0';
+ REPLY_IS_LOCKED <= '1';
+ elsif CLK_EN = '1' then
+ INIT_IS_LOCKED <= next_INIT_IS_LOCKED;
+ REPLY_IS_LOCKED <= next_REPLY_IS_LOCKED;
+ else
+ INIT_IS_LOCKED <= INIT_IS_LOCKED;
+ REPLY_IS_LOCKED <= REPLY_IS_LOCKED;
+ end if;
+ end if;
+ end process;
+
+end architecture;
-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetOBUF
LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
-USE IEEE.STD_LOGIC_ARITH.ALL;
-USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.std_logic_ARITH.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
use work.trb_net_std.all;
entity trb_net16_obuf is
generic (
- DATA_COUNT_WIDTH : integer := 4;
+ DATA_COUNT_WIDTH : integer := 5
);
port(
-- Misc
RESET : in std_logic;
CLK_EN : in std_logic;
-- Media direction port
- MED_DATAREADY_OUT: out STD_LOGIC;
- MED_DATA_OUT: out STD_LOGIC_VECTOR (15 downto 0); -- Data word
- MED_PACKET_NUM_OUT:out STD_LOGIC_VECTOR(1 downto 0);
- MED_READ_IN: in STD_LOGIC;
+ MED_DATAREADY_OUT: out std_logic;
+ MED_DATA_OUT: out std_logic_vector (15 downto 0); -- Data word
+ MED_PACKET_NUM_OUT:out std_logic_vector(1 downto 0);
+ MED_READ_IN: in std_logic;
-- Internal direction port
- 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;
+ 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;
-- Status and control port
- STAT_LOCKED: out STD_LOGIC_VECTOR (15 downto 0);
- CTRL_LOCKED: in STD_LOGIC_VECTOR (15 downto 0);
- STAT_BUFFER: out STD_LOGIC_VECTOR (31 downto 0);
- CTRL_BUFFER: in STD_LOGIC_VECTOR (31 downto 0)
+ STAT_LOCKED: out std_logic_vector (15 downto 0);
+ CTRL_LOCKED: in std_logic_vector (15 downto 0);
+ STAT_BUFFER: out std_logic_vector (31 downto 0);
+ CTRL_BUFFER: in std_logic_vector (31 downto 0)
);
end entity;
component trb_net16_sbuf is
generic (
DATA_WIDTH : integer := 16;
- NUM_WIDTH : integer := 2;
- VERSION : integer := 0
+ NUM_WIDTH : integer := 2;
+ VERSION : integer := 0
);
port(
-- Misc
- CLK : in std_logic;
- RESET : in std_logic;
+ 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);
+ 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;
+ 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
+ STAT_BUFFER: out std_logic
);
end component;
- begin
+ signal current_output_data_buffer : STD_LOGIC_VECTOR (15 downto 0);
+ signal current_output_num_buffer : STD_LOGIC_VECTOR (1 downto 0);
+ signal current_ACK_word, current_EOB_word, current_DATA_word, current_NOP_word :
+ STD_LOGIC_VECTOR (15 downto 0);
+ signal comb_dataready, comb_next_read, comb_read ,sbuf_free: STD_LOGIC;
+ signal reg_INT_READ_OUT , next_INT_READ_OUT:STD_LOGIC;
+
+ signal next_SEND_ACK_IN, reg_SEND_ACK_IN : STD_LOGIC;
+ signal send_ACK, send_EOB, send_DATA : STD_LOGIC;
+
+ signal CURRENT_DATA_COUNT, next_DATA_COUNT : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0);
+-- signal max_DATA_COUNT, next_max_DATA_COUNT : STD_LOGIC_VECTOR (15 downto 0);
+ signal max_DATA_COUNT_minus_one, next_max_DATA_COUNT_minus_one : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0);
+ signal max_DATA_COUNT_minus_two, next_max_DATA_COUNT_minus_two : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0);
+ signal TRANSMITTED_BUFFERS, next_TRANSMITTED_BUFFERS : STD_LOGIC_VECTOR (1 downto 0);
+ signal increase_TRANSMITTED_BUFFERS, decrease_TRANSMITTED_BUFFERS : STD_LOGIC;
+ signal SEND_BUFFER_SIZE_IN : STD_LOGIC_VECTOR (3 downto 0);
+ signal REC_BUFFER_SIZE_IN : STD_LOGIC_VECTOR (3 downto 0);
+ signal SEND_ACK_IN : STD_LOGIC;
+ signal GOT_ACK_IN : STD_LOGIC;
+
+ signal is_locked, got_locked,release_locked : std_logic;
-end architecture;
+ type transfer_state_t is (IDLE, SENDING_DATA, SENDING_ACK, SENDING_EOB);
+ signal transfer_state, next_transfer_state : transfer_state_t;
+ signal transfer_counter : std_logic_vector(1 downto 0);
+ signal saved_packet_type : std_logic_vector(2 downto 0);
+begin
+
+ 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 => comb_dataready,
+ COMB_next_READ_OUT => comb_next_read,
+ COMB_READ_IN => comb_read,
+ COMB_DATA_IN => current_output_data_buffer,
+ COMB_PACKET_NUM_IN => current_output_num_buffer,
+ SYN_DATAREADY_OUT => MED_DATAREADY_OUT,
+ SYN_DATA_OUT => MED_DATA_OUT,
+ SYN_PACKET_NUM_OUT => MED_PACKET_NUM_OUT,
+ SYN_READ_IN => MED_READ_IN
+ );
+
+ decrease_TRANSMITTED_BUFFERS <= GOT_ACK_IN;
+ comb_read <= '1';
+ INT_READ_OUT <= reg_INT_READ_OUT;
+ sbuf_free <= comb_next_read;
+
+ send_ACK <= SEND_ACK_IN or reg_SEND_ACK_IN;
+ send_DATA <= '1' when (TRANSMITTED_BUFFERS(1) = '0') else '0';
+ send_EOB <= '1' when (CURRENT_DATA_COUNT = max_DATA_COUNT_minus_one) else '0';
+
+
+ -- buffer registers
+ STAT_BUFFER(1 downto 0) <= TRANSMITTED_BUFFERS;
+ STAT_BUFFER(15 downto 2) <= (others => '0');
+ STAT_BUFFER(31 downto 16) <= CURRENT_DATA_COUNT;
+ SEND_BUFFER_SIZE_IN <= CTRL_BUFFER(3 downto 0);
+ REC_BUFFER_SIZE_IN <= CTRL_BUFFER(7 downto 4);
+ SEND_ACK_IN <= CTRL_BUFFER(8);
+ GOT_ACK_IN <= CTRL_BUFFER(9);
+
+
+
+ GENERATE_WORDS : process(transfer_counter, SEND_BUFFER_SIZE_IN)
+ begin
+ current_NOP_word <= (others => '0');
+ current_ACK_word <= (others => '0');
+ current_EOB_word <= (others => '0');
+ current_DATA_word <= INT_DATA_IN;
+ if transfer_counter = "10" then
+ current_ACK_word(3 downto 0) <= SEND_BUFFER_SIZE_IN;
+ end if;
+ if transfer_counter = "00" then
+ current_NOP_word(2 downto 0) <= TYPE_ILLEGAL;
+ current_ACK_word(2 downto 0) <= TYPE_ACK;
+ current_EOB_word(2 downto 0) <= TYPE_EOB;
+ end if;
+ end process;
+
+ REG_TRANSFER_COUNTER : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ transfer_counter <= (others => '0');
+ elsif comb_dataready = '1' then
+ transfer_counter <= transfer_counter + 1;
+ end if;
+ end if;
+ end process;
+
+ SAVE_PACKET_TYPE : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ saved_packet_type <= TYPE_ILLEGAL;
+ elsif transfer_counter <= "00" and comb_dataready = '1' then
+ saved_packet_type <= current_output_data_buffer(2 downto 0);
+ end if;
+ end if;
+ end process;
+
+ --since we count only 64Bit packets, each counter is updated on the last packet
+ --the EOB and ACK flags must be available when the last packet is sent.
+ --full buffers (despite the sbuf) can only occur on the last packet.
+ COMB_NEXT_TRANSFER : process(transfer_state, comb_dataready, transfer_counter, current_NOP_word,
+ CURRENT_DATA_COUNT, reg_SEND_ACK_IN, INT_DATAREADY_IN, INT_DATA_IN,
+ reg_INT_READ_OUT, reg_SEND_ACK_IN, saved_packet_type )
+ begin
+ if transfer_counter = "11" and comb_dataready = '1' then
+ next_transfer_state <= IDLE;
+ else
+ next_transfer_state <= transfer_state;
+ end if;
+
+ current_output_data_buffer <= current_NOP_word;
+ current_output_num_buffer <= transfer_counter;
+ next_INT_READ_OUT <= '1';
+ increase_TRANSMITTED_BUFFERS <= '0';
+ next_DATA_COUNT <= CURRENT_DATA_COUNT;
+ next_SEND_ACK_IN <= reg_SEND_ACK_IN;
+ comb_dataready <= '0';
+
+ if (reg_INT_READ_OUT = '1' and INT_DATAREADY_IN = '1') then
+ --can only happen if idle or sending_data
+ next_transfer_state <= SENDING_DATA;
+ current_output_data_buffer <= current_DATA_word;
+ comb_dataready <= '1'; --I hope sbuf can store
+ if saved_packet_type = TYPE_TRM and transfer_counter = "11" then --TRM means EOB
+ next_DATA_COUNT <= (others => '0');
+ increase_TRANSMITTED_BUFFERS <= '1';
+ else
+ next_DATA_COUNT <= CURRENT_DATA_COUNT +1;
+ end if;
+ if (send_ACK = '1' or send_EOB = '1' ) then
+ if transfer_counter = "11" then --finish running packet, then stop.
+ next_INT_READ_OUT <= '0';
+ end if;
+ end if;
+ if send_ACK = '1' then --BUGBUG: next_SEND_ACK_IN should be a counter (2 may arrive)
+ --no real problem due to same speed of transmission
+ next_SEND_ACK_IN <= '1';
+ end if;
+ elsif (send_ACK = '1' or transfer_state = SENDING_ACK) then
+ if not (transfer_counter = "11" and comb_dataready = '1') then
+ next_transfer_state <= SENDING_ACK;
+ end if;
+ next_INT_READ_OUT <= '0';
+ if sbuf_free = '1' then
+ current_output_data_buffer <= current_ACK_word;
+ next_SEND_ACK_IN <= '0';
+ comb_dataready <= '1';
+ end if;
+ elsif send_EOB = '1' or transfer_state = SENDING_EOB then
+ if not (transfer_counter = "11" and comb_dataready = '1') then
+ next_transfer_state <= SENDING_EOB;
+ else
+ next_DATA_COUNT <= (others => '0');
+ increase_TRANSMITTED_BUFFERS <= '1';
+ end if;
+ next_INT_READ_OUT <= '0';
+ if sbuf_free = '1' then
+ current_output_data_buffer <= current_EOB_word;
+ comb_dataready <= '1';
+ end if;
+ end if;
+ if send_data = '0' or --block reading if two buffers have been sent or current buffer runs full
+ ((current_DATA_COUNT(DATA_COUNT_WIDTH-1 downto 0) = (max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0)))
+ and reg_INT_READ_OUT = '1' and INT_DATAREADY_IN = '1' ) --and INT_DATA_IN(TYPE_POSITION) = TYPE_TRM
+ --long version of (next_count = max_count-1)
+ or (next_TRANSMITTED_BUFFERS(1) = '1')
+ or sbuf_free = '0' then
+ next_INT_READ_OUT <= '0';
+ end if;
+ end process;
+
+
+ REG : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ reg_SEND_ACK_IN <= '0';
+ CURRENT_DATA_COUNT <= (others => '0');
+ reg_INT_READ_OUT <= '0';
+ transfer_state <= IDLE;
+ elsif CLK_EN = '1' then
+ reg_SEND_ACK_IN <= next_SEND_ACK_IN;
+ CURRENT_DATA_COUNT <= next_DATA_COUNT;
+ reg_INT_READ_OUT <= next_INT_READ_OUT;
+ transfer_state <= next_transfer_state;
+ end if;
+ end if;
+ end process;
+
+
+ next_max_DATA_COUNT_minus_one <= "0000000000000011" when REC_BUFFER_SIZE_IN="0001" else
+ "0000000000000111" when REC_BUFFER_SIZE_IN="0010" else
+ "0000000000001111" when REC_BUFFER_SIZE_IN="0011" else
+ "0000000000011111" when REC_BUFFER_SIZE_IN="0100" else
+ "0000000000000001";
+ next_max_DATA_COUNT_minus_two <= "0000000000000010" when REC_BUFFER_SIZE_IN="0001" else
+ "0000000000000110" when REC_BUFFER_SIZE_IN="0010" else
+ "0000000000001110" when REC_BUFFER_SIZE_IN="0011" else
+ "0000000000011110" when REC_BUFFER_SIZE_IN="0100" else
+ "0000000000000000";
+
+ reg_max_DATA_COUNT : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ max_DATA_COUNT_minus_one(0) <= '1';
+ max_DATA_COUNT_minus_one(DATA_COUNT_WIDTH-1 downto 1) <= (others => '0');
+ max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0) <= (others => '0');
+ else
+ max_DATA_COUNT_minus_one <= next_max_DATA_COUNT_minus_one(DATA_COUNT_WIDTH-1 downto 0);
+ max_DATA_COUNT_minus_two <= next_max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0);
+ end if;
+ end if;
+ end process;
+
+ comb_TRANSMITTED_BUFFERS : process (increase_TRANSMITTED_BUFFERS, decrease_TRANSMITTED_BUFFERS, TRANSMITTED_BUFFERS)
+ begin
+ if (increase_TRANSMITTED_BUFFERS = '1' and decrease_TRANSMITTED_BUFFERS = '0') then
+ next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS +1;
+ elsif (increase_TRANSMITTED_BUFFERS = '0' and decrease_TRANSMITTED_BUFFERS = '1') then
+ next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS -1;
+ else
+ next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS;
+ end if;
+ end process;
+
+ reg_TRANSMITTED_BUFFERS : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ TRANSMITTED_BUFFERS <= "00";
+ elsif CLK_EN = '1' then
+ TRANSMITTED_BUFFERS <= next_TRANSMITTED_BUFFERS;
+ end if;
+ end if;
+ end process;
+
+ comb_locked : process (MED_READ_IN, saved_packet_type, transfer_counter, release_locked, is_locked)
+ begin -- process
+ got_locked <= is_locked;
+ if MED_READ_IN = '1' then
+ if saved_packet_type = TYPE_TRM and transfer_counter = "11" and release_locked = '0' then
+ got_locked <= '1';
+ elsif release_locked = '1' then
+ got_locked <= '0';
+ end if;
+ elsif release_locked = '1' then
+ got_locked <= '0';
+ end if;
+ end process;
+
+ release_locked <= CTRL_LOCKED(0);
+ STAT_LOCKED(0) <= is_locked;
+ STAT_LOCKED(15 downto 1) <= (others => '0');
+
+ reg_locked: process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ is_locked <= '0';
+ elsif CLK_EN = '1' then
+ is_locked <= got_locked;
+ end if;
+ end if;
+ end process;
+
+end architecture;
\ No newline at end of file
-- Media direction port
MED_DATAREADY_IN: in std_logic; -- Data word is offered by the Media (the IOBUF MUST read)
MED_DATA_IN: in std_logic_vector (15 downto 0); -- Data word
- MED_PACKET_NUM_IN :out std_logic_vector(1 downto 0);
+ MED_PACKET_NUM_IN :in std_logic_vector(1 downto 0);
MED_READ_OUT: out std_logic; -- buffer reads a word from media
MED_ERROR_IN: in std_logic_vector (2 downto 0); -- Status bits
-- Internal direction port
type ERROR_STATE is (IDLE, GOT_OVERFLOW_ERROR, GOT_LOCKED_ERROR, GOT_UNDEFINED_ERROR);
signal current_error_state, next_error_state : ERROR_STATE;
signal next_rec_buffer_size_out, current_rec_buffer_size_out : std_logic_vector(3 downto 0);
+ signal current_packet_type, saved_packet_type : std_logic_vector(2 downto 0);
+
-- buffer size control
begin
-this process has to be converted to 16 Bit
-------------------------------------------
-
-
--- -- this process controls the writing of the media into the fifo
--- FILTER_DATAREADY_IN : process(MED_DATA_IN, MED_DATAREADY_IN, MED_ERROR_IN,
--- is_locked, current_rec_buffer_size_out,
--- current_error_state, release_locked,
--- sbuf_free)
--- begin -- process
--- got_ack_internal <= '0';
--- next_rec_buffer_size_out <= current_rec_buffer_size_out;
--- next_error_state <= current_error_state;
--- tmp_INT_DATA_OUT <= (others => '1');
--- tmp_INT_DATAREADY_OUT <= '0';
--- got_eob_out <= '0';
--- got_locked <= is_locked;
---
--- if MED_DATAREADY_IN = '1' then -- data word offered
--- if MED_DATA_IN(TYPE_POSITION) = TYPE_ACK then
--- got_ack_internal <= '1';
--- if MED_DATA_IN(F1_POSITION) = F1_CHECK_ACK then
--- next_rec_buffer_size_out <= MED_DATA_IN(BUFFER_SIZE_POSITION);
--- end if;
--- elsif MED_DATA_IN(TYPE_POSITION) = TYPE_TRM then
--- got_eob_out <= '1'; --exactly when buffer is killed
--- tmp_INT_DATA_OUT <= MED_DATA_IN;
--- tmp_INT_DATAREADY_OUT <= '1';
--- if release_locked = '0' then
--- got_locked <= '1';
--- end if;
--- elsif MED_DATA_IN(TYPE_POSITION) = TYPE_EOB then
--- got_eob_out <= '1';
--- tmp_INT_DATAREADY_OUT <= '0';
--- -- this should happen only one CLK cycle
--- elsif sbuf_free = '0' then
--- next_error_state <= GOT_OVERFLOW_ERROR;
--- elsif is_locked = '1' then
--- next_error_state <= GOT_LOCKED_ERROR;
--- end if; -- end TYPE
--- end if; -- end MED_DATAREADY_IN
--- end process;
---
--- MED_READ_OUT <= '1'; -- I always can read
---
--- reg_buffer: process(CLK)
--- begin
--- if rising_edge(CLK) then
--- if RESET = '1' then
--- current_rec_buffer_size_out <= (others => '0');
--- reg_ack_internal <= '0';
--- current_error_state <= IDLE;
--- elsif CLK_EN = '1' then
--- current_rec_buffer_size_out <= next_rec_buffer_size_out;
--- reg_ack_internal <= got_ack_internal;
--- current_error_state <= next_error_state;
--- else
--- current_rec_buffer_size_out <= current_rec_buffer_size_out;
--- reg_ack_internal <= reg_ack_internal;
--- current_error_state <= current_error_state;
--- 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 MED_PACKET_NUM_IN = "00" then
+ saved_packet_type <= MED_DATA_IN(2 downto 0);
+ end if;
+ end if;
+ end process;
+ --create comb. real packet type
+ current_packet_type <= MED_DATA_IN(2 downto 0) when (MED_PACKET_NUM_IN = "00" and RESET = '0')
+ else saved_packet_type;
+
+ -- this process controls the writing of the media into the fifo
+ FILTER_DATAREADY_IN : process(MED_DATA_IN, MED_DATAREADY_IN, MED_ERROR_IN,
+ is_locked, current_rec_buffer_size_out,
+ current_error_state, release_locked,
+ sbuf_free, MED_PACKET_NUM_IN, current_packet_type)
+ begin
+ got_ack_internal <= '0';
+ next_rec_buffer_size_out <= current_rec_buffer_size_out;
+ next_error_state <= current_error_state;
+ tmp_INT_DATA_OUT <= (others => '1');
+ tmp_INT_PACKET_NUM_OUT <= (others => '0');
+ tmp_INT_DATAREADY_OUT <= '0';
+ got_eob_out <= '0';
+ got_locked <= is_locked;
+
+ if MED_DATAREADY_IN = '1' then -- data word offered
+ if current_packet_type = TYPE_ACK then
+ if MED_PACKET_NUM_IN = "00" then
+ got_ack_internal <= '1';
+ elsif MED_PACKET_NUM_IN = "10" then
+ next_rec_buffer_size_out <= MED_DATA_IN(3 downto 0);
+ end if;
+ elsif current_packet_type = TYPE_TRM then
+ if MED_PACKET_NUM_IN = "11" then
+ got_eob_out <= '1'; --exactly when buffer is killed
+ if release_locked = '0' then
+ got_locked <= '1';
+ end if;
+ end if;
+ tmp_INT_DATA_OUT <= MED_DATA_IN;
+ tmp_INT_PACKET_NUM_OUT <= MED_PACKET_NUM_IN;
+ tmp_INT_DATAREADY_OUT <= '1';
+ elsif current_packet_type = TYPE_EOB then
+ if MED_PACKET_NUM_IN = "11" then
+ got_eob_out <= '1';
+ end if;
+ elsif sbuf_free = '0' then
+ next_error_state <= GOT_OVERFLOW_ERROR;
+ elsif is_locked = '1' then
+ next_error_state <= GOT_LOCKED_ERROR;
+ end if;
+ end if;
+ end process;
+
+
+
+ MED_READ_OUT <= '1'; -- I always can read
+
+ reg_buffer: process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ current_rec_buffer_size_out <= (others => '0');
+ reg_ack_internal <= '0';
+ current_error_state <= IDLE;
+ elsif CLK_EN = '1' then
+ current_rec_buffer_size_out <= next_rec_buffer_size_out;
+ reg_ack_internal <= got_ack_internal;
+ current_error_state <= next_error_state;
+ else
+ current_rec_buffer_size_out <= current_rec_buffer_size_out;
+ reg_ack_internal <= reg_ack_internal;
+ current_error_state <= current_error_state;
+ end if;
+ end if;
+ end process;
+
+
+
SBUF: trb_net16_sbuf
generic map (
DATA_WIDTH => 16,
STAT_BUFFER(7 downto 4) <= current_rec_buffer_size_out;
STAT_BUFFER(8) <= reg_eob_out;
STAT_BUFFER(9) <= reg_ack_internal;
- STAT_BUFFER(11 downto 10) <= "00" when current_error_state = IDLE,
- "01" when current_error_state = GOT_OVERFLOW_ERROR,
+ STAT_BUFFER(11 downto 10) <= "00" when current_error_state = IDLE else
+ "01" when current_error_state = GOT_OVERFLOW_ERROR else
"10" when current_error_state = GOT_LOCKED_ERROR
else "11";
STAT_BUFFER(31 downto 12) <= (others => '0');
CTRL_LOCKED: in STD_LOGIC_VECTOR (15 downto 0);
STAT_BUFFER: out STD_LOGIC_VECTOR (31 downto 0)
);
-END trb_net_term_ibuf;
+end trb_net_term_ibuf;
architecture trb_net_term_ibuf_arch of trb_net_term_ibuf is
-- Status and control port
STAT_BUFFER: out STD_LOGIC
);
- END component;
+ end component;
signal got_ack_internal, reg_ack_internal : std_logic; --should be raised for 1 cycle when ack
SYN_DATA_OUT => INT_DATA_OUT,
SYN_READ_IN => INT_READ_IN
);
-
+
sbuf_free <= comb_next_read or INT_READ_IN; --sbuf killed
-
-release_locked <= CTRL_LOCKED(0);
-STAT_LOCKED(0) <= is_locked;
-STAT_LOCKED(15 downto 1) <= (others => '0');
-
-reg_locked: process(CLK)
+
+ release_locked <= CTRL_LOCKED(0);
+ STAT_LOCKED(0) <= is_locked;
+ STAT_LOCKED(15 downto 1) <= (others => '0');
+
+ reg_locked: process(CLK)
begin
- if rising_edge(CLK) then
- if RESET = '1' then
- is_locked <= '0';
- reg_eob_out <= '0';
- elsif CLK_EN = '1' then
- if release_locked = '1' then
+ if rising_edge(CLK) then
+ if RESET = '1' then
is_locked <= '0';
+ reg_eob_out <= '0';
+ elsif CLK_EN = '1' then
+ if release_locked = '1' then
+ is_locked <= '0';
+ else
+ is_locked <= got_locked;
+ end if;
+ reg_eob_out <= got_eob_out;
else
- is_locked <= got_locked;
+ is_locked <= is_locked;
+ reg_eob_out <= reg_eob_out;
end if;
- reg_eob_out <= got_eob_out;
- else
- is_locked <= is_locked;
- reg_eob_out <= reg_eob_out;
end if;
- end if;
- end process;
+ end process;