summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/engine.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'netfpga10g/hdl/engine.vhd')
-rw-r--r--netfpga10g/hdl/engine.vhd570
1 files changed, 570 insertions, 0 deletions
diff --git a/netfpga10g/hdl/engine.vhd b/netfpga10g/hdl/engine.vhd
new file mode 100644
index 0000000..16f0a8b
--- /dev/null
+++ b/netfpga10g/hdl/engine.vhd
@@ -0,0 +1,570 @@
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+library UNISIM;
+use UNISIM.VComponents.all;
+
+entity engine is
+generic (
+ BUFF_COUNT : integer := 16;
+ BUFF_BITS : integer := 4; -- 2^4 = 16
+ BAR_BITS : integer := 17;
+ TIME_BITS : integer := 20
+);
+port (
+ clk : in STD_LOGIC;
+
+ rd_buff : out STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0) := (others => '0');
+ rd_en : out STD_LOGIC := '0';
+ rd_data : in STD_LOGIC_VECTOR (63 downto 0);
+ rd_length : in STD_LOGIC_VECTOR (8 downto 0);
+ rd_valid : in STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+
+ wr_buff : out STD_LOGIC_VECTOR (BUFF_BITS - 1 downto 0) := (others => '0');
+ wr_en : out STD_LOGIC := '0';
+ wr_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ wr_done : out STD_LOGIC := '0';
+ wr_cancel : out STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+ wr_accept : in STD_LOGIC_VECTOR (BUFF_COUNT - 1 downto 0);
+
+ rx_read : in STD_LOGIC;
+ rx_write : in STD_LOGIC;
+ rx_complete : in STD_LOGIC;
+ rx_data : in STD_LOGIC_VECTOR (63 downto 0);
+ rx_address : in STD_LOGIC_VECTOR (63 downto 3);
+ rx_tag : in std_logic_vector(4 downto 0);
+
+ tx_read : out STD_LOGIC := '0';
+ tx_write : out STD_LOGIC := '0';
+ tx_complete : out STD_LOGIC := '0';
+ tx_data : out STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
+ tx_address : out STD_LOGIC_VECTOR (63 downto 3) := (others => '0');
+ tx_length : out STD_LOGIC_VECTOR (8 downto 0) := (others => '0');
+ tx_tag : out std_logic_vector(4 downto 0) := (others => '0');
+ tx_accept : in STD_LOGIC;
+ tx_done : in STD_LOGIC;
+
+ interrupt : out std_logic := '0';
+ interrupt_rdy : in std_logic;
+
+ max_read : in std_logic_vector(2 downto 0);
+ max_write : in std_logic_vector(2 downto 0);
+
+ mdio_command : out std_logic_vector(0 to 27) := (others => '0');
+ mdio_data : in std_logic_vector(0 to 15);
+ mdio_enable : out std_logic := '0';
+ mdio_done : in std_logic
+);
+end engine;
+
+architecture arch of engine is
+
+ constant BUFF_EMPTY : std_logic_vector(1 downto 0) := "00";
+ constant BUFF_ADDR : std_logic_vector(1 downto 0) := "01";
+ constant BUFF_DATA : std_logic_vector(1 downto 0) := "10";
+ constant BUFF_FULL : std_logic_vector(1 downto 0) := "11";
+
+ type buff_t is array (0 to BUFF_COUNT - 1) of std_logic_vector(1 downto 0);
+ type length_t is array (0 to BUFF_COUNT - 1) of unsigned(8 downto 0);
+ type address_t is array (0 to BUFF_COUNT - 1) of unsigned(63 downto 3);
+ type time_t is array (0 to BUFF_COUNT - 1) of unsigned(TIME_BITS - 1 downto 0);
+
+ type rx_state_t is (rx_state_idle, rx_state_write_done, rx_state_mdio);
+ type tx_state_t is (tx_state_idle, tx_state_read, tx_state_write,
+ tx_state_complete, tx_state_interrupt);
+
+ signal rx_state : rx_state_t := rx_state_idle;
+ signal tx_state : tx_state_t := tx_state_idle;
+
+ signal tx_data_i : std_logic_vector(63 downto 0) := (others => '0');
+
+ constant CMD_STATUS : std_logic_vector(1 downto 0) := "00";
+ constant CMD_SEND : std_logic_vector(1 downto 0) := "01";
+ constant CMD_RECV : std_logic_vector(1 downto 0) := "10";
+ constant CMD_MDIO : std_logic_vector(1 downto 0) := "11";
+
+ signal send_buff : buff_t := (others => BUFF_FULL);
+ signal send_length : length_t := (others => (others => '0'));
+ signal send_remain : length_t := (others => (others => '0'));
+ signal send_address : address_t := (others => (others => '0'));
+ signal send_read_time : time_t := (others => (others => '0'));
+
+ signal recv_buff : buff_t := (others => BUFF_EMPTY);
+ signal recv_address0 : unsigned(63 downto 3);
+ signal recv_address1 : unsigned(63 downto 3);
+ signal recv_address2 : unsigned(63 downto 3);
+ signal recv_address3 : unsigned(63 downto 3);
+ signal recv_address4 : unsigned(63 downto 3);
+ signal recv_address5 : unsigned(63 downto 3);
+ signal recv_address6 : unsigned(63 downto 3);
+ signal recv_address7 : unsigned(63 downto 3);
+ signal recv_address8 : unsigned(63 downto 3);
+ signal recv_address9 : unsigned(63 downto 3);
+ signal recv_address10 : unsigned(63 downto 3);
+ signal recv_address11 : unsigned(63 downto 3);
+ signal recv_address12 : unsigned(63 downto 3);
+ signal recv_address13 : unsigned(63 downto 3);
+ signal recv_address14 : unsigned(63 downto 3);
+ signal recv_address15 : unsigned(63 downto 3);
+
+ signal send_int : std_logic := '0';
+ signal send_int_needed : std_logic := '0';
+ signal send_read : std_logic := '0';
+ signal send_read_done : std_logic := '0';
+ signal send_read_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+ signal send_read_length : unsigned(8 downto 0);
+ signal send_read_remain : unsigned(8 downto 0);
+ signal send_read_address : unsigned(63 downto 3);
+ signal send_write : std_logic := '0';
+ signal send_write_new : std_logic := '0';
+ signal send_write_buff : integer range 0 to BUFF_COUNT - 1 := 0;
+ signal send_write_length : unsigned(8 downto 0);
+ signal send_write_address : unsigned(63 downto 3);
+
+ signal debug_address : std_logic_vector(63 downto 3) := (others => '0');
+ signal debug_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal debug_cmd : std_logic_vector(1 downto 0) := (others => '0');
+ signal debug_buff : std_logic_vector(BUFF_BITS - 1 downto 0) := (others => '0');
+ signal debug_length : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(42, 9));
+
+ signal debug_cmpl_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_cmpl_data : std_logic_vector(63 downto 0) := (others => '0');
+ signal debug_cmpl_tag : std_logic_vector(4 downto 0) := (others => '0');
+ signal debug_cmpl_state : std_logic_vector(7 downto 0) := x"FF";
+
+ signal debug_write_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_write_length : std_logic_vector(8 downto 0) := (others => '0');
+ signal debug_write_addr : std_logic_vector(63 downto 3) := (others => '0');
+ signal debug_write_data : std_logic_vector(63 downto 0) := (others => '0');
+
+ signal debug_accept_count : unsigned(7 downto 0) := (others => '0');
+ signal debug_done_count : unsigned(7 downto 0) := (others => '0');
+
+ signal timer : unsigned(TIME_BITS - 1 downto 0) := (others => '0');
+begin
+ rd_en <= tx_accept when tx_state = tx_state_write else '0';
+
+ tx_data <= rd_data when tx_state = tx_state_write else tx_data_i;
+
+ process (clk)
+ variable bar_read : std_logic := '0';
+ variable bar_read_address : std_logic_vector(63 downto 3) := (others => '0');
+
+ variable tmp_cmd : std_logic_vector(1 downto 0);
+ variable tmp_buff : integer range 0 to BUFF_COUNT - 1;
+ variable tmp_length : unsigned(8 downto 0);
+ variable tmp_remain : unsigned(8 downto 0);
+ variable tmp_address : unsigned(63 downto 3);
+ variable tmp_bar : unsigned(BAR_BITS - 1 downto 0);
+
+ -- see 'metered reads' in pcie core manual (xilinx)
+ -- a maximum of 8 openstanding reads is allowed
+ constant READ_MAX : unsigned(3 downto 0) := x"8";
+ variable read_count : unsigned(3 downto 0) := (others => '0');
+ variable read_decr : std_logic;
+ variable read_incr : std_logic;
+ begin
+ if rising_edge(clk) then
+ wr_en <= '0';
+ wr_data <= (others => '0');
+ wr_done <= '0';
+ wr_cancel <= (others => '0');
+ read_decr := '0';
+ read_incr := '0';
+
+ timer <= timer + 1;
+
+ -- ENGINE: RX
+ if rx_state = rx_state_idle then
+ if rx_read = '1' then
+ bar_read := '1';
+ bar_read_address := rx_address;
+
+ elsif rx_write = '1' then
+ tmp_cmd := rx_address(4 downto 3);
+ tmp_buff := to_integer(unsigned(rx_address(5 + BUFF_BITS - 1 downto 5)));
+ tmp_length := unsigned(rx_address(18 downto 10));
+ tmp_address := unsigned(rx_data(63 downto 3));
+
+ debug_address <= rx_address;
+ debug_data <= rx_data;
+ debug_cmd <= tmp_cmd;
+ debug_buff <= std_logic_vector(to_unsigned(tmp_buff, debug_buff'length));
+ debug_length <= std_logic_vector(tmp_length);
+
+ if tmp_cmd = CMD_SEND then
+ if send_buff(tmp_buff) = BUFF_EMPTY then
+ send_buff(tmp_buff) <= BUFF_ADDR;
+ send_address(tmp_buff) <= tmp_address;
+ send_length(tmp_buff) <= tmp_length;
+ end if;
+
+ elsif tmp_cmd = CMD_RECV then
+ if recv_buff(tmp_buff) = BUFF_FULL then
+ recv_buff(tmp_buff) <= BUFF_ADDR;
+
+ if tmp_buff = 0 then
+ recv_address0 <= tmp_address;
+ elsif tmp_buff = 1 then
+ recv_address1 <= tmp_address;
+ elsif tmp_buff = 2 then
+ recv_address2 <= tmp_address;
+ elsif tmp_buff = 3 then
+ recv_address3 <= tmp_address;
+ elsif tmp_buff = 4 then
+ recv_address4 <= tmp_address;
+ elsif tmp_buff = 5 then
+ recv_address5 <= tmp_address;
+ elsif tmp_buff = 6 then
+ recv_address6 <= tmp_address;
+ elsif tmp_buff = 7 then
+ recv_address7 <= tmp_address;
+ elsif tmp_buff = 8 then
+ recv_address8 <= tmp_address;
+ elsif tmp_buff = 9 then
+ recv_address9 <= tmp_address;
+ elsif tmp_buff = 10 then
+ recv_address10 <= tmp_address;
+ elsif tmp_buff = 11 then
+ recv_address11 <= tmp_address;
+ elsif tmp_buff = 12 then
+ recv_address12 <= tmp_address;
+ elsif tmp_buff = 13 then
+ recv_address13 <= tmp_address;
+ elsif tmp_buff = 14 then
+ recv_address14 <= tmp_address;
+ elsif tmp_buff = 15 then
+ recv_address15 <= tmp_address;
+ end if;
+ end if;
+
+ elsif tmp_cmd = CMD_MDIO then
+ rx_state <= rx_state_mdio;
+ mdio_enable <= '1';
+ mdio_command <= rx_data(27 downto 0);
+ end if;
+
+ elsif rx_complete = '1' then
+ tmp_buff := to_integer(unsigned(rx_tag(BUFF_BITS - 1 downto 0)));
+
+ debug_cmpl_count <= debug_cmpl_count + 1;
+ debug_cmpl_data <= rx_data;
+ debug_cmpl_tag <= rx_tag;
+ debug_cmpl_state <= x"00";
+
+ if send_buff(tmp_buff) = BUFF_DATA then
+ wr_en <= '1';
+ wr_data <= rx_data;
+ wr_buff <= std_logic_vector(to_unsigned(tmp_buff, BUFF_BITS));
+ send_remain(tmp_buff) <= send_remain(tmp_buff) - 1;
+ debug_cmpl_state <= x"01";
+
+ if send_remain(tmp_buff) = 1 then
+ read_decr := '1';
+
+ if send_length(tmp_buff) = 0 then
+ rx_state <= rx_state_write_done;
+ debug_cmpl_state <= x"02";
+ else
+ send_buff(tmp_buff) <= BUFF_ADDR;
+ debug_cmpl_state <= x"03";
+ end if;
+ end if;
+ end if;
+ end if;
+
+ elsif rx_state = rx_state_write_done then
+ rx_state <= rx_state_idle;
+ wr_done <= '1';
+
+ elsif rx_state = rx_state_mdio then
+ if mdio_done = '1' then
+ rx_state <= rx_state_idle;
+ mdio_enable <= '0';
+ end if;
+ end if;
+
+ -- ENGINE: TX
+ if send_read_done = '1' then
+ send_read_done <= '0';
+ send_buff(send_read_buff) <= BUFF_DATA;
+ send_length(send_read_buff) <= send_read_length - send_read_remain;
+ send_remain(send_read_buff) <= send_read_remain;
+ send_address(send_read_buff) <= send_read_address + send_read_remain;
+ send_read_time(send_read_buff) <= timer;
+ end if;
+
+ if tx_state = tx_state_idle or
+ (tx_state = tx_state_read and tx_done = '1') or
+ (tx_state = tx_state_write and tx_done = '1') or
+ (tx_state = tx_state_complete and tx_done = '1') or
+ (tx_state = tx_state_interrupt and interrupt_rdy = '1') then
+
+ tx_state <= tx_state_idle;
+ tx_read <= '0';
+ tx_write <= '0';
+ tx_complete <= '0';
+ tx_data_i <= (others => '0');
+ tx_address <= (others => '0');
+ tx_length <= (others => '0');
+ tx_tag <= (others => '0');
+ interrupt <= '0';
+
+ if bar_read = '1' then
+ tx_state <= tx_state_complete;
+ tx_complete <= '1';
+ tx_address <= bar_read_address;
+ tmp_cmd := bar_read_address(4 downto 3);
+ tmp_bar := unsigned(bar_read_address(3 + BAR_BITS - 1 downto 3));
+ bar_read := '0';
+
+ if tmp_bar = 0 then
+ --if tmp_cmd = CMD_STATUS then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tx_data_i(i*4 + 1 downto i*4 + 0) <= send_buff(i);
+ tx_data_i(i*4 + 3 downto i*4 + 2) <= recv_buff(i);
+ end loop;
+ send_int <= '0';
+ send_int_needed <= '1';
+
+ elsif tmp_bar = 1 then
+ tx_data_i(63 downto 3) <= debug_address;
+
+ elsif tmp_bar = 2 then
+ tx_data_i <= debug_data;
+
+ elsif tmp_bar = 3 then
+ tx_data_i(1 downto 0) <= debug_cmd;
+
+ elsif tmp_bar = 4 then
+ tx_data_i(BUFF_BITS - 1 downto 0) <= debug_buff;
+
+ elsif tmp_bar = 5 then
+ tx_data_i(8 downto 0) <= debug_length;
+
+ elsif tmp_bar = 10 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_cmpl_count);
+
+ elsif tmp_bar = 11 then
+ tx_data_i <= debug_cmpl_data;
+
+ elsif tmp_bar = 12 then
+ tx_data_i(4 downto 0) <= debug_cmpl_tag;
+
+ elsif tmp_bar = 13 then
+ tx_data_i(7 downto 0) <= debug_cmpl_state;
+
+ elsif tmp_bar = 20 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_write_count);
+
+ elsif tmp_bar = 21 then
+ tx_data_i(8 downto 0) <= debug_write_length;
+
+ elsif tmp_bar = 22 then
+ tx_data_i(63 downto 3) <= debug_write_addr;
+
+ elsif tmp_bar = 23 then
+ tx_data_i(63 downto 0) <= debug_write_data;
+
+ elsif tmp_bar = 24 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_accept_count);
+
+ elsif tmp_bar = 25 then
+ tx_data_i(7 downto 0) <= std_logic_vector(debug_done_count);
+
+ elsif tmp_bar = 30 then
+ tx_data_i(15 downto 0) <= mdio_data;
+
+ else
+ tx_data_i(63 downto 3) <= bar_read_address;
+ end if;
+
+ elsif send_int = '1' and send_int_needed = '1' then
+ tx_state <= tx_state_interrupt;
+ interrupt <= '1';
+ send_int_needed <= '0';
+
+ elsif send_read = '1' and read_count < READ_MAX then
+ tmp_buff := send_read_buff;
+ tmp_length := send_read_length;
+ tmp_address := send_read_address;
+ tmp_remain := 16 - resize(tmp_address(6 downto 3), tmp_remain'length);
+
+ if max_read = "001" then
+ tmp_remain := 32 - resize(tmp_address(7 downto 3), tmp_remain'length);
+ elsif max_read = "010" then
+ tmp_remain := 64 - resize(tmp_address(8 downto 3), tmp_remain'length);
+ elsif max_read = "011" then
+ tmp_remain := 128 - resize(tmp_address(9 downto 3), tmp_remain'length);
+ elsif max_read = "100" then
+ tmp_remain := 256 - resize(tmp_address(10 downto 3), tmp_remain'length);
+ elsif max_read = "101" then
+ tmp_remain := 512 - resize(tmp_address(11 downto 3), tmp_remain'length);
+ end if;
+
+ if tmp_remain > tmp_length then
+ tmp_remain := tmp_length;
+ end if;
+
+ tx_state <= tx_state_read;
+ tx_read <= '1';
+ tx_address <= std_logic_vector(tmp_address);
+ tx_length <= std_logic_vector(tmp_remain);
+ tx_tag <= std_logic_vector(to_unsigned(tmp_buff, tx_tag'length));
+
+ send_read <= '0';
+ send_read_done <= '1';
+ send_read_remain <= tmp_remain;
+ read_incr := '1';
+
+ elsif send_write = '1' then
+ if send_write_new = '1' then
+ tmp_length := unsigned(rd_length);
+ else
+ tmp_length := send_write_length;
+ end if;
+ tmp_address := send_write_address;
+ tmp_remain := 16 - resize(tmp_address(6 downto 3), tmp_remain'length);
+
+ if max_write = "001" then
+ tmp_remain := 32 - resize(tmp_address(7 downto 3), tmp_remain'length);
+ elsif max_write = "010" then
+ tmp_remain := 64 - resize(tmp_address(8 downto 3), tmp_remain'length);
+ elsif max_write = "011" then
+ tmp_remain := 128 - resize(tmp_address(9 downto 3), tmp_remain'length);
+ elsif max_write = "100" then
+ tmp_remain := 256 - resize(tmp_address(10 downto 3), tmp_remain'length);
+ elsif max_write = "101" then
+ tmp_remain := 512 - resize(tmp_address(11 downto 3), tmp_remain'length);
+ end if;
+
+ if tmp_remain > tmp_length then
+ tmp_remain := tmp_length;
+ end if;
+
+ tx_state <= tx_state_write;
+ tx_write <= '1';
+ tx_address <= std_logic_vector(tmp_address);
+ tx_length <= std_logic_vector(tmp_remain);
+
+ debug_write_count <= debug_write_count + 1;
+ debug_write_length <= std_logic_vector(tmp_remain);
+ debug_write_addr <= std_logic_vector(tmp_address);
+ debug_write_data <= rd_data;
+
+ tmp_length := tmp_length - tmp_remain;
+ tmp_address := tmp_address + tmp_remain;
+
+ send_write_length <= tmp_length;
+ send_write_address <= tmp_address;
+ send_write_new <= '0';
+
+ if tmp_length = 0 then
+ send_write <= '0';
+ end if;
+ end if;
+ end if;
+
+ if read_decr = '1' and read_incr = '0' then
+ read_count := read_count - 1;
+ elsif read_decr = '0' and read_incr = '1' then
+ read_count := read_count + 1;
+ end if;
+
+ if tx_accept = '1' then
+ debug_accept_count <= debug_accept_count + 1;
+ end if;
+ if tx_done = '1' then
+ debug_done_count <= debug_done_count + 1;
+ end if;
+
+ for i in 0 to BUFF_COUNT - 1 loop
+ if send_buff(i) = BUFF_DATA and wr_accept(i) = '0' then
+ send_buff(i) <= BUFF_FULL;
+ -- no send_int here
+ end if;
+ if send_buff(i) = BUFF_FULL and wr_accept(i) = '1' then
+ send_buff(i) <= BUFF_EMPTY;
+ send_int <= '1';
+ end if;
+ if recv_buff(i) = BUFF_EMPTY and rd_valid(i) = '1' then
+ recv_buff(i) <= BUFF_FULL;
+ send_int <= '1';
+ end if;
+ if recv_buff(i) = BUFF_DATA and rd_valid(i) = '0' then
+ recv_buff(i) <= BUFF_EMPTY;
+ send_int <= '1';
+ end if;
+
+ if send_buff(i) = BUFF_DATA and send_read_time(i) = timer then
+ -- read timeout
+ wr_cancel(i) <= '1';
+ end if;
+ end loop;
+
+ if send_read = '0' and send_read_done = '0' then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (send_read_buff + i) mod BUFF_COUNT;
+
+ if send_buff(tmp_buff) = BUFF_ADDR then
+ send_read <= '1';
+ send_read_buff <= tmp_buff;
+ send_read_length <= send_length(tmp_buff);
+ send_read_address <= send_address(tmp_buff);
+ exit;
+ end if;
+ end loop;
+ end if;
+
+ if send_write = '0' and (tx_state /= tx_state_write or tx_done = '1') then
+ for i in 0 to BUFF_COUNT - 1 loop
+ tmp_buff := (send_write_buff + i) mod BUFF_COUNT;
+
+ if recv_buff(tmp_buff) = BUFF_ADDR then
+ recv_buff(tmp_buff) <= BUFF_DATA;
+ send_write <= '1';
+ send_write_new <= '1';
+ send_write_buff <= tmp_buff;
+ rd_buff <= std_logic_vector(to_unsigned(tmp_buff, BUFF_BITS));
+
+ if tmp_buff = 0 then
+ send_write_address <= recv_address0;
+ elsif tmp_buff = 1 then
+ send_write_address <= recv_address1;
+ elsif tmp_buff = 2 then
+ send_write_address <= recv_address2;
+ elsif tmp_buff = 3 then
+ send_write_address <= recv_address3;
+ elsif tmp_buff = 4 then
+ send_write_address <= recv_address4;
+ elsif tmp_buff = 5 then
+ send_write_address <= recv_address5;
+ elsif tmp_buff = 6 then
+ send_write_address <= recv_address6;
+ elsif tmp_buff = 7 then
+ send_write_address <= recv_address7;
+ elsif tmp_buff = 8 then
+ send_write_address <= recv_address8;
+ elsif tmp_buff = 9 then
+ send_write_address <= recv_address9;
+ elsif tmp_buff = 10 then
+ send_write_address <= recv_address10;
+ elsif tmp_buff = 11 then
+ send_write_address <= recv_address11;
+ elsif tmp_buff = 12 then
+ send_write_address <= recv_address12;
+ elsif tmp_buff = 13 then
+ send_write_address <= recv_address13;
+ elsif tmp_buff = 14 then
+ send_write_address <= recv_address14;
+ elsif tmp_buff = 15 then
+ send_write_address <= recv_address15;
+ end if;
+ exit;
+ end if;
+ end loop;
+ end if;
+ end if;
+ end process;
+end arch;