From: hadeshyp Date: Fri, 28 Sep 2007 10:28:58 +0000 (+0000) Subject: first version of trb_net16_iobuf, Jan X-Git-Tag: oldGBE~698 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=73c306d77fcdc73233b69b40d7e8d1939f04d08e;p=trbnet.git first version of trb_net16_iobuf, Jan --- diff --git a/trb_net16_iobuf.vhd b/trb_net16_iobuf.vhd index 05bbe95..87c7479 100644 --- a/trb_net16_iobuf.vhd +++ b/trb_net16_iobuf.vhd @@ -13,8 +13,8 @@ use work.trb_net_std.all; 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; @@ -87,7 +87,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is component trb_net16_obuf is generic ( - DATA_COUNT_WIDTH : integer := 4; + DATA_COUNT_WIDTH : integer := 5 ); port( -- Misc @@ -124,14 +124,14 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is -- 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 @@ -141,9 +141,280 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is ); 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; diff --git a/trb_net16_obuf.vhd b/trb_net16_obuf.vhd index 4883d56..ef7410a 100644 --- a/trb_net16_obuf.vhd +++ b/trb_net16_obuf.vhd @@ -2,15 +2,15 @@ -- 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 @@ -18,20 +18,20 @@ entity trb_net16_obuf is 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; @@ -40,32 +40,308 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is 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 diff --git a/trb_net16_term_ibuf.vhd b/trb_net16_term_ibuf.vhd index deb0737..da099ad 100644 --- a/trb_net16_term_ibuf.vhd +++ b/trb_net16_term_ibuf.vhd @@ -23,7 +23,7 @@ entity trb_net16_term_ibuf is -- 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 @@ -79,75 +79,95 @@ architecture trb_net16_term_ibuf_arch of trb_net16_term_ibuf is 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, @@ -198,8 +218,8 @@ this process has to be converted to 16 Bit 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'); diff --git a/trb_net_term_ibuf.vhd b/trb_net_term_ibuf.vhd index 3b8baed..6aee069 100644 --- a/trb_net_term_ibuf.vhd +++ b/trb_net_term_ibuf.vhd @@ -37,7 +37,7 @@ entity trb_net_term_ibuf is 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 @@ -63,7 +63,7 @@ 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 @@ -159,32 +159,32 @@ reg_buffer: process(CLK) 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;