OpenCores
URL https://opencores.org/ocsvn/udp_ip_stack/udp_ip_stack/trunk

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [trunk/] [rtl/] [vhdl/] [arp.vhd] - Diff between revs 8 and 10

Only display areas with differences | Details | Blame | View Log

Rev 8 Rev 10
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- Company: 
-- Company: 
-- Engineer:            Peter Fall
-- Engineer:            Peter Fall
-- 
-- 
-- Create Date:    12:00:04 05/31/2011 
-- Create Date:    12:00:04 05/31/2011 
-- Design Name: 
-- Design Name: 
-- Module Name:    arp - Behavioral 
-- Module Name:    arp - Behavioral 
-- Project Name: 
-- Project Name: 
-- Target Devices: 
-- Target Devices: 
-- Tool versions: 
-- Tool versions: 
-- Description:
-- Description:
--              handle simple IP lookup in cache
--              handle simple IP lookup in cache
--              request cache fill through ARP protocol if required
--              request cache fill through ARP protocol if required
--              cache is simple 1 deep
--              cache is simple 1 deep
--              Handle ARP protocol
--              Handle ARP protocol
--              Respond to ARP requests and replies
--              Respond to ARP requests and replies
--              Ignore pkts that are not ARP
--              Ignore pkts that are not ARP
--              Ignore pkts that are not addressed to us
--              Ignore pkts that are not addressed to us
--
--
-- Dependencies: 
-- Dependencies: 
--
--
-- Revision: 
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.01 - File Created
-- Revision 0.02 - Added req for mac tx and wait for grant
-- Revision 0.02 - Added req for mac tx and wait for grant
-- Revision 0.03 - Added data_out_first
-- Revision 0.03 - Added data_out_first
-- Revision 0.04 - Added arp response timeout
-- Revision 0.04 - Added arp response timeout
-- Revision 0.05 - Added arp cache reset control
-- Revision 0.05 - Added arp cache reset control
-- Additional Comments: 
-- Additional Comments: 
--
--
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.arp_types.all;
use work.arp_types.all;
 
 
entity arp is
entity arp is
         generic (
         generic (
                        CLOCK_FREQ                      : integer := 125000000;                                                 -- freq of data_in_clk -- needed to timout cntr
                        CLOCK_FREQ                      : integer := 125000000;                                                 -- freq of data_in_clk -- needed to timout cntr
                        ARP_TIMEOUT                     : integer := 60                                                                 -- ARP response timeout (s)
                        ARP_TIMEOUT                     : integer := 60;                                                                        -- ARP response timeout (s)
 
                        ARP_MAX_PKT_TMO : integer := 1;                                                                 -- (added for compatibility with arpv2. this value not used in this impl)
 
                        MAX_ARP_ENTRIES         : integer := 1                                                                          -- (added for compatibility with arpv2. this value not used in this impl)
                        );
                        );
    Port (
    Port (
                        -- lookup request signals
                        -- lookup request signals
                        arp_req_req                     : in arp_req_req_type;
                        arp_req_req                     : in arp_req_req_type;
                        arp_req_rslt            : out arp_req_rslt_type;
                        arp_req_rslt            : out arp_req_rslt_type;
                        -- MAC layer RX signals
                        -- MAC layer RX signals
                        data_in_clk             : in  STD_LOGIC;
                        data_in_clk             : in  STD_LOGIC;
                        reset                           : in  STD_LOGIC;
                        reset                           : in  STD_LOGIC;
                        data_in                                 : in  STD_LOGIC_VECTOR (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
                        data_in                                 : in  STD_LOGIC_VECTOR (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
                        data_in_valid           : in  STD_LOGIC;                                                                        -- indicates data_in valid on clock
                        data_in_valid           : in  STD_LOGIC;                                                                        -- indicates data_in valid on clock
                        data_in_last            : in  STD_LOGIC;                                                                        -- indicates last data in frame
                        data_in_last            : in  STD_LOGIC;                                                                        -- indicates last data in frame
                        -- MAC layer TX signals
                        -- MAC layer TX signals
                        mac_tx_req                      : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
                        mac_tx_req                      : out std_logic;                                                                        -- indicates that ip wants access to channel (stays up for as long as tx)
                        mac_tx_granted          : in std_logic;                                                                 -- indicates that access to channel has been granted            
                        mac_tx_granted          : in std_logic;                                                                 -- indicates that access to channel has been granted            
                        data_out_clk            : in std_logic;
                        data_out_clk            : in std_logic;
                        data_out_ready          : in std_logic;                                                                 -- indicates system ready to consume data
                        data_out_ready          : in std_logic;                                                                 -- indicates system ready to consume data
                        data_out_valid          : out std_logic;                                                                        -- indicates data out is valid
                        data_out_valid          : out std_logic;                                                                        -- indicates data out is valid
                        data_out_first          : out std_logic;                                                                        -- with data out valid indicates the first byte of a frame
                        data_out_first          : out std_logic;                                                                        -- with data out valid indicates the first byte of a frame
                        data_out_last           : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
                        data_out_last           : out std_logic;                                                                        -- with data out valid indicates the last byte of a frame
                        data_out                                : out std_logic_vector (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
                        data_out                                : out std_logic_vector (7 downto 0);             -- ethernet frame (from dst mac addr through to last byte of frame)
                        -- system signals
                        -- system signals
                        our_mac_address         : in STD_LOGIC_VECTOR (47 downto 0);
                        our_mac_address         : in STD_LOGIC_VECTOR (47 downto 0);
                        our_ip_address  : in STD_LOGIC_VECTOR (31 downto 0);
                        our_ip_address  : in STD_LOGIC_VECTOR (31 downto 0);
                        control                         : in arp_control_type;
                        control                         : in arp_control_type;
                        req_count                       : out STD_LOGIC_VECTOR(7 downto 0)                       -- count of arp pkts received
                        req_count                       : out STD_LOGIC_VECTOR(7 downto 0)                       -- count of arp pkts received
                        );
                        );
end arp;
end arp;
 
 
architecture Behavioral of arp is
architecture Behavioral of arp is
 
 
        type req_state_type is (IDLE,LOOKUP,REQUEST,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
        type req_state_type is (IDLE,LOOKUP,REQUEST,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
        type rx_state_type is (IDLE,PARSE,PROCESS_ARP,WAIT_END);
        type rx_state_type is (IDLE,PARSE,PROCESS_ARP,WAIT_END);
        type rx_event_type is (NO_EVENT,DATA);
        type rx_event_type is (NO_EVENT,DATA);
        type count_mode_type is (RST,INCR,HOLD);
        type count_mode_type is (RST,INCR,HOLD);
        type arp_oper_type is (NOP,REQUEST,REPLY);
        type arp_oper_type is (NOP,REQUEST,REPLY);
        type set_clr_type is (SET, CLR, HOLD);
        type set_clr_type is (SET, CLR, HOLD);
 
 
        type tx_state_type is (IDLE,WAIT_MAC,SEND);
        type tx_state_type is (IDLE,WAIT_MAC,SEND);
 
 
 
 
        type arp_entry_type is record
        type arp_entry_type is record
                ip                              : std_logic_vector (31 downto 0);
                ip                              : std_logic_vector (31 downto 0);
                mac                             : std_logic_vector (47 downto 0);
                mac                             : std_logic_vector (47 downto 0);
                is_valid                        : std_logic;
                is_valid                        : std_logic;
                reply_required  : std_logic;
                reply_required  : std_logic;
        end record;
        end record;
 
 
        -- state variables
        -- state variables
        signal req_state                        : req_state_type;
        signal req_state                        : req_state_type;
        signal req_ip_addr              : std_logic_vector (31 downto 0);                -- IP address to lookup
        signal req_ip_addr              : std_logic_vector (31 downto 0);                -- IP address to lookup
        signal mac_addr_found   : STD_LOGIC_VECTOR (47 downto 0);                -- mac address found
        signal mac_addr_found   : STD_LOGIC_VECTOR (47 downto 0);                -- mac address found
        signal mac_addr_valid_reg: std_logic;
        signal mac_addr_valid_reg: std_logic;
        signal send_request_needed              : std_logic;
        signal send_request_needed              : std_logic;
        signal tx_mac_chn_reqd  : std_logic;
        signal tx_mac_chn_reqd  : std_logic;
        signal freq_scaler              : unsigned (31 downto 0);                -- scales data_in_clk downto 1Hz
        signal freq_scaler              : unsigned (31 downto 0);                -- scales data_in_clk downto 1Hz
        signal timer                            : unsigned (7 downto 0);         -- counts seconds timeout
        signal timer                            : unsigned (7 downto 0);         -- counts seconds timeout
        signal timeout_reg              : std_logic;
        signal timeout_reg              : std_logic;
 
 
        signal rx_state                         : rx_state_type;
        signal rx_state                         : rx_state_type;
        signal rx_count                         : unsigned (7 downto 0);
        signal rx_count                         : unsigned (7 downto 0);
        signal arp_operation            : arp_oper_type;
        signal arp_operation            : arp_oper_type;
        signal arp_req_count            : unsigned (7 downto 0);
        signal arp_req_count            : unsigned (7 downto 0);
        signal arp_entry                        : arp_entry_type;                               -- arp entry store
        signal arp_entry                        : arp_entry_type;                               -- arp entry store
        signal new_arp_entry            : arp_entry_type;
        signal new_arp_entry            : arp_entry_type;
        signal tx_state                 : tx_state_type;
        signal tx_state                 : tx_state_type;
        signal tx_count                         : unsigned (7 downto 0);
        signal tx_count                         : unsigned (7 downto 0);
 
 
-- FIXME        - remove these debug state signals
-- FIXME        - remove these debug state signals
        signal arp_err_data             : std_logic_vector (7 downto 0);
        signal arp_err_data             : std_logic_vector (7 downto 0);
        signal set_err_data             : std_logic;
        signal set_err_data             : std_logic;
 
 
  attribute keep : string;
  attribute keep : string;
  attribute keep of arp_err_data             : signal is "true";
  attribute keep of arp_err_data             : signal is "true";
 
 
        -- requester control signals
        -- requester control signals
        signal next_req_state   : req_state_type;
        signal next_req_state   : req_state_type;
        signal set_req_state            : std_logic;
        signal set_req_state            : std_logic;
        signal set_req_ip                       : std_logic;
        signal set_req_ip                       : std_logic;
        signal set_mac_addr             : std_logic;
        signal set_mac_addr             : std_logic;
        signal set_mac_addr_invalid : std_logic;
        signal set_mac_addr_invalid : std_logic;
        signal set_send_req             : std_logic;
        signal set_send_req             : std_logic;
        signal clear_send_req   : std_logic;
        signal clear_send_req   : std_logic;
        signal set_timer                        : count_mode_type;              -- timer reset, count, hold control
        signal set_timer                        : count_mode_type;              -- timer reset, count, hold control
        signal timer_enable             : std_logic;                            -- enable the timer counting
        signal timer_enable             : std_logic;                            -- enable the timer counting
        signal set_timeout              : set_clr_type;                 -- control the timeout register
        signal set_timeout              : set_clr_type;                 -- control the timeout register
 
 
 
 
        -- rx control signals
        -- rx control signals
        signal next_rx_state    : rx_state_type;
        signal next_rx_state    : rx_state_type;
        signal set_rx_state             : std_logic;
        signal set_rx_state             : std_logic;
        signal rx_event                         : rx_event_type;
        signal rx_event                         : rx_event_type;
        signal rx_count_mode    : count_mode_type;
        signal rx_count_mode    : count_mode_type;
        signal set_arp_oper             : std_logic;
        signal set_arp_oper             : std_logic;
        signal arp_oper_set_val : arp_oper_type;
        signal arp_oper_set_val : arp_oper_type;
        signal dataval                  : std_logic_vector (7 downto 0);
        signal dataval                  : std_logic_vector (7 downto 0);
        signal set_arp_entry_request            : std_logic;
        signal set_arp_entry_request            : std_logic;
 
 
        signal set_mac5                         : std_logic;
        signal set_mac5                         : std_logic;
        signal set_mac4                         : std_logic;
        signal set_mac4                         : std_logic;
        signal set_mac3                         : std_logic;
        signal set_mac3                         : std_logic;
        signal set_mac2                         : std_logic;
        signal set_mac2                         : std_logic;
        signal set_mac1                         : std_logic;
        signal set_mac1                         : std_logic;
        signal set_mac0                         : std_logic;
        signal set_mac0                         : std_logic;
 
 
        signal set_ip3                  : std_logic;
        signal set_ip3                  : std_logic;
        signal set_ip2                  : std_logic;
        signal set_ip2                  : std_logic;
        signal set_ip1                  : std_logic;
        signal set_ip1                  : std_logic;
        signal set_ip0                  : std_logic;
        signal set_ip0                  : std_logic;
 
 
        -- tx control signals
        -- tx control signals
        signal next_tx_state    : tx_state_type;
        signal next_tx_state    : tx_state_type;
        signal set_tx_state             : std_logic;
        signal set_tx_state             : std_logic;
        signal tx_count_mode            : count_mode_type;
        signal tx_count_mode            : count_mode_type;
        signal clear_reply_req  : std_logic;
        signal clear_reply_req  : std_logic;
        signal set_chn_reqd             : set_clr_type;
        signal set_chn_reqd             : set_clr_type;
        signal kill_data_out_valid      : std_logic;
        signal kill_data_out_valid      : std_logic;
 
 
 
 
        -- function to determine whether the rx pkt is an arp pkt and whether we want to process it
        -- function to determine whether the rx pkt is an arp pkt and whether we want to process it
        -- Returns 1 if we should discard
        -- Returns 1 if we should discard
        -- The following will make us ignore the frame (all values hexadecimal):
        -- The following will make us ignore the frame (all values hexadecimal):
        -- PDU type /= 0806
        -- PDU type /= 0806
        -- Protocol Type /= 0800
        -- Protocol Type /= 0800
        -- Hardware Type /= 1
        -- Hardware Type /= 1
        -- Hardware Length /= 6
        -- Hardware Length /= 6
        -- Protocol Length /= 4
        -- Protocol Length /= 4
        -- Operation /= 1 or 2
        -- Operation /= 1 or 2
        -- Target IP /= our IP (i.er. message is not meant for us)
        -- Target IP /= our IP (i.er. message is not meant for us)
        --
        --
        function not_our_arp(data : STD_LOGIC_VECTOR; count : unsigned; our_ip : std_logic_vector) return std_logic is
        function not_our_arp(data : STD_LOGIC_VECTOR; count : unsigned; our_ip : std_logic_vector) return std_logic is
        begin
        begin
                if
                if
                        (count = 12 and data /= x"08") or                                               -- PDU type 0806 : ARP
                        (count = 12 and data /= x"08") or                                               -- PDU type 0806 : ARP
                        (count = 13 and data /= x"06") or
                        (count = 13 and data /= x"06") or
                        (count = 14 and data /= x"00") or                                               -- HW type 1 : eth
                        (count = 14 and data /= x"00") or                                               -- HW type 1 : eth
                        (count = 15 and data /= x"01") or
                        (count = 15 and data /= x"01") or
                        (count = 16 and data /= x"08") or                                               -- Protocol 0800 : IP
                        (count = 16 and data /= x"08") or                                               -- Protocol 0800 : IP
                        (count = 17 and data /= x"00") or
                        (count = 17 and data /= x"00") or
                        (count = 18 and data /= x"06") or                                               -- HW Length 6
                        (count = 18 and data /= x"06") or                                               -- HW Length 6
                        (count = 19 and data /= x"04") or                                               -- protocol length 4
                        (count = 19 and data /= x"04") or                                               -- protocol length 4
                        (count = 20 and data /= x"00") or                                               -- operation 1 or 2 (req or reply)
                        (count = 20 and data /= x"00") or                                               -- operation 1 or 2 (req or reply)
                        (count = 21 and data /= x"01" and data /= x"02") or
                        (count = 21 and data /= x"01" and data /= x"02") or
                        (count = 38 and data /= our_ip(31 downto 24)) or        -- target IP is ours
                        (count = 38 and data /= our_ip(31 downto 24)) or        -- target IP is ours
                        (count = 39 and data /= our_ip(23 downto 16)) or
                        (count = 39 and data /= our_ip(23 downto 16)) or
                        (count = 40 and data /= our_ip(15 downto 8)) or
                        (count = 40 and data /= our_ip(15 downto 8)) or
                        (count = 41 and data /= our_ip(7 downto 0))
                        (count = 41 and data /= our_ip(7 downto 0))
                then
                then
                        return '1';
                        return '1';
                else
                else
                        return '0';
                        return '0';
                end if;
                end if;
        end function not_our_arp;
        end function not_our_arp;
 
 
begin
begin
        req_combinatorial : process (
        req_combinatorial : process (
                -- input signals
                -- input signals
                arp_req_req,
                arp_req_req,
                -- state variables
                -- state variables
                req_state, req_ip_addr, mac_addr_found, mac_addr_valid_reg, send_request_needed, arp_entry,
                req_state, req_ip_addr, mac_addr_found, mac_addr_valid_reg, send_request_needed, arp_entry,
                freq_scaler, timer, timeout_reg,
                freq_scaler, timer, timeout_reg,
                -- control signals
                -- control signals
                next_req_state, set_req_state, set_req_ip, set_mac_addr, control,
                next_req_state, set_req_state, set_req_ip, set_mac_addr, control,
                set_mac_addr_invalid,set_send_req, clear_send_req, set_timer, timer_enable, set_timeout
                set_mac_addr_invalid,set_send_req, clear_send_req, set_timer, timer_enable, set_timeout
                )
                )
        begin
        begin
                -- set output followers
                -- set output followers
                if arp_req_req.lookup_req = '1' then
                if arp_req_req.lookup_req = '1' then
                        arp_req_rslt.got_err <= '0';
                        arp_req_rslt.got_err <= '0';
                else
                else
                        arp_req_rslt.got_err <= timeout_reg;
                        arp_req_rslt.got_err <= timeout_reg;
                end if;
                end if;
                -- zero time response to lookup request if already in cache
                -- zero time response to lookup request if already in cache
                if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
                if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
                        arp_req_rslt.got_mac <= '1';
                        arp_req_rslt.got_mac <= '1';
                        arp_req_rslt.mac <= arp_entry.mac;
                        arp_req_rslt.mac <= arp_entry.mac;
                elsif arp_req_req.lookup_req = '1' then
                elsif arp_req_req.lookup_req = '1' then
                        arp_req_rslt.got_mac <= '0';             -- hold off got_mac while req is there as arp_entry will not be correct yet
                        arp_req_rslt.got_mac <= '0';             -- hold off got_mac while req is there as arp_entry will not be correct yet
                        arp_req_rslt.mac <= arp_entry.mac;
                        arp_req_rslt.mac <= arp_entry.mac;
                else
                else
                        arp_req_rslt.got_mac <= mac_addr_valid_reg;
                        arp_req_rslt.got_mac <= mac_addr_valid_reg;
                        arp_req_rslt.mac <= mac_addr_found;
                        arp_req_rslt.mac <= mac_addr_found;
                end if;
                end if;
 
 
                -- set signal defaults
                -- set signal defaults
                next_req_state <= IDLE;
                next_req_state <= IDLE;
                set_req_state <= '0';
                set_req_state <= '0';
                set_req_ip <= '0';
                set_req_ip <= '0';
                set_mac_addr <= '0';
                set_mac_addr <= '0';
                set_mac_addr_invalid <= '0';
                set_mac_addr_invalid <= '0';
                set_send_req <= '0';
                set_send_req <= '0';
                clear_send_req <= '0';
                clear_send_req <= '0';
                set_timer <= INCR;                      -- default is timer running, unless we hold or reset it
                set_timer <= INCR;                      -- default is timer running, unless we hold or reset it
                set_timeout <= HOLD;
                set_timeout <= HOLD;
                timer_enable <= '0';
                timer_enable <= '0';
 
 
                -- combinatorial logic
                -- combinatorial logic
                if freq_scaler = x"00000000" then
                if freq_scaler = x"00000000" then
                                timer_enable <= '1';
                                timer_enable <= '1';
                end if;
                end if;
 
 
                -- REQ FSM
                -- REQ FSM
                case req_state is
                case req_state is
                        when IDLE =>
                        when IDLE =>
                                set_timer <= RST;
                                set_timer <= RST;
                                if arp_req_req.lookup_req = '1' then
                                if arp_req_req.lookup_req = '1' then
                                        -- check if we already have the info in cache
                                        -- check if we already have the info in cache
                                        if arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
                                        if arp_req_req.ip = arp_entry.ip and arp_entry.is_valid = '1' then
                                                -- already have this IP
                                                -- already have this IP
                                                set_mac_addr <= '1';
                                                set_mac_addr <= '1';
                                        else
                                        else
                                                set_timeout <= CLR;
                                                set_timeout <= CLR;
                                                next_req_state <= LOOKUP;
                                                next_req_state <= LOOKUP;
                                                set_req_state <= '1';
                                                set_req_state <= '1';
                                                set_req_ip <= '1';
                                                set_req_ip <= '1';
                                                set_mac_addr_invalid <= '1';
                                                set_mac_addr_invalid <= '1';
                                        end if;
                                        end if;
                                end if;
                                end if;
 
 
                        when LOOKUP =>
                        when LOOKUP =>
                                if arp_entry.ip = req_ip_addr and arp_entry.is_valid = '1' then
                                if arp_entry.ip = req_ip_addr and arp_entry.is_valid = '1' then
                                        -- already have this IP
                                        -- already have this IP
                                        next_req_state <= IDLE;
                                        next_req_state <= IDLE;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
                                        set_mac_addr <= '1';
                                        set_mac_addr <= '1';
                                else
                                else
                                        -- need to request mac for this IP
                                        -- need to request mac for this IP
                                        set_send_req <= '1';
                                        set_send_req <= '1';
                                        set_timer <= RST;
                                        set_timer <= RST;
                                        next_req_state <= REQUEST;
                                        next_req_state <= REQUEST;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
                                end if;
                                end if;
 
 
                        when REQUEST =>
                        when REQUEST =>
                                        clear_send_req <= '1';
                                        clear_send_req <= '1';
                                        next_req_state <= WAIT_REPLY;
                                        next_req_state <= WAIT_REPLY;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
 
 
                        when WAIT_REPLY =>
                        when WAIT_REPLY =>
                                        if arp_entry.is_valid = '1' then
                                        if arp_entry.is_valid = '1' then
                                                -- have reply, go back to LOOKUP state to see if it is the right one
                                                -- have reply, go back to LOOKUP state to see if it is the right one
                                                next_req_state <= LOOKUP;
                                                next_req_state <= LOOKUP;
                                                set_req_state <= '1';
                                                set_req_state <= '1';
                                        end if;
                                        end if;
                                        if timer >= ARP_TIMEOUT then
                                        if timer >= ARP_TIMEOUT then
                                                set_timeout <= SET;
                                                set_timeout <= SET;
                                                next_req_state <= PAUSE1;
                                                next_req_state <= PAUSE1;
                                                set_req_state <= '1';
                                                set_req_state <= '1';
                                        end if;
                                        end if;
 
 
                        when PAUSE1 =>
                        when PAUSE1 =>
                                        next_req_state <= PAUSE2;
                                        next_req_state <= PAUSE2;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
 
 
                        when PAUSE2 =>
                        when PAUSE2 =>
                                        next_req_state <= PAUSE3;
                                        next_req_state <= PAUSE3;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
 
 
                        when PAUSE3 =>
                        when PAUSE3 =>
                                        next_req_state <= IDLE;
                                        next_req_state <= IDLE;
                                        set_req_state <= '1';
                                        set_req_state <= '1';
 
 
                end case;
                end case;
        end process;
        end process;
 
 
        req_sequential : process (data_in_clk,reset)
        req_sequential : process (data_in_clk,reset)
        begin
        begin
                if rising_edge(data_in_clk) then
                if rising_edge(data_in_clk) then
                        if reset = '1' then
                        if reset = '1' then
                                -- reset state variables
                                -- reset state variables
                                req_state <= IDLE;
                                req_state <= IDLE;
                                req_ip_addr <= (others => '0');
                                req_ip_addr <= (others => '0');
                                mac_addr_found <= (others => '0');
                                mac_addr_found <= (others => '0');
                                mac_addr_valid_reg <= '0';
                                mac_addr_valid_reg <= '0';
                                send_request_needed <= '0';
                                send_request_needed <= '0';
                                freq_scaler <= to_unsigned(CLOCK_FREQ,32);
                                freq_scaler <= to_unsigned(CLOCK_FREQ,32);
                                timer <= (others => '0');
                                timer <= (others => '0');
                                timeout_reg <= '0';
                                timeout_reg <= '0';
                        else
                        else
                                -- Next req_state processing
                                -- Next req_state processing
                                if set_req_state = '1' then
                                if set_req_state = '1' then
                                        req_state <= next_req_state;
                                        req_state <= next_req_state;
                                else
                                else
                                        req_state <= req_state;
                                        req_state <= req_state;
                                end if;
                                end if;
 
 
                                -- Latch the requested IP address
                                -- Latch the requested IP address
                                if set_req_ip = '1' then
                                if set_req_ip = '1' then
                                        req_ip_addr <= arp_req_req.ip;
                                        req_ip_addr <= arp_req_req.ip;
                                else
                                else
                                        req_ip_addr <= req_ip_addr;
                                        req_ip_addr <= req_ip_addr;
                                end if;
                                end if;
 
 
                                -- send request to TX&RX FSMs to send an ARP request
                                -- send request to TX&RX FSMs to send an ARP request
                                if set_send_req = '1' then
                                if set_send_req = '1' then
                                        send_request_needed <= '1';
                                        send_request_needed <= '1';
                                elsif clear_send_req = '1' then
                                elsif clear_send_req = '1' then
                                        send_request_needed <= '0';
                                        send_request_needed <= '0';
                                else
                                else
                                        send_request_needed <= send_request_needed;
                                        send_request_needed <= send_request_needed;
                                end if;
                                end if;
 
 
                                -- Set the found mac address
                                -- Set the found mac address
                                if set_mac_addr = '1' then
                                if set_mac_addr = '1' then
                                        mac_addr_found <= arp_entry.mac;
                                        mac_addr_found <= arp_entry.mac;
                                        mac_addr_valid_reg <= '1';
                                        mac_addr_valid_reg <= '1';
                                elsif set_mac_addr_invalid = '1' then
                                elsif set_mac_addr_invalid = '1' then
                                        mac_addr_found <= (others => '0');
                                        mac_addr_found <= (others => '0');
                                        mac_addr_valid_reg <= '0';
                                        mac_addr_valid_reg <= '0';
                                else
                                else
                                        mac_addr_found <= mac_addr_found;
                                        mac_addr_found <= mac_addr_found;
                                        mac_addr_valid_reg <= mac_addr_valid_reg;
                                        mac_addr_valid_reg <= mac_addr_valid_reg;
                                end if;
                                end if;
 
 
                                -- freq scaling and 1-sec timer
                                -- freq scaling and 1-sec timer
                                if freq_scaler = x"00000000" then
                                if freq_scaler = x"00000000" then
                                        freq_scaler <= to_unsigned(CLOCK_FREQ,32);
                                        freq_scaler <= to_unsigned(CLOCK_FREQ,32);
                                else
                                else
                                        freq_scaler <= freq_scaler - 1;
                                        freq_scaler <= freq_scaler - 1;
                                end if;
                                end if;
 
 
                                -- timer processing
                                -- timer processing
                                case set_timer is
                                case set_timer is
                                        when RST =>
                                        when RST =>
                                                timer <= x"00";
                                                timer <= x"00";
                                        when INCR =>
                                        when INCR =>
                                                if timer_enable = '1' then
                                                if timer_enable = '1' then
                                                        timer <= timer + 1;
                                                        timer <= timer + 1;
                                                else
                                                else
                                                        timer <= timer;
                                                        timer <= timer;
                                                end if;
                                                end if;
                                        when HOLD =>
                                        when HOLD =>
                                                timer <= timer;
                                                timer <= timer;
                                end case;
                                end case;
 
 
                                -- timeout latching
                                -- timeout latching
                                case set_timeout is
                                case set_timeout is
                                        when CLR  => timeout_reg <= '0';
                                        when CLR  => timeout_reg <= '0';
                                        when SET  => timeout_reg <= '1';
                                        when SET  => timeout_reg <= '1';
                                        when HOLD => timeout_reg <= timeout_reg;
                                        when HOLD => timeout_reg <= timeout_reg;
                                end case;
                                end case;
 
 
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
 
 
        rx_combinatorial : process (
        rx_combinatorial : process (
                -- input signals
                -- input signals
                data_in, data_in_valid, data_in_last, our_ip_address,
                data_in, data_in_valid, data_in_last, our_ip_address,
                -- state variables
                -- state variables
                rx_state, rx_count, arp_operation, arp_req_count, arp_err_data,
                rx_state, rx_count, arp_operation, arp_req_count, arp_err_data,
                -- control signals
                -- control signals
                next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
                next_rx_state, set_rx_state, rx_event, rx_count_mode, set_arp_oper, arp_oper_set_val,
                dataval,set_mac5,set_mac4,set_mac3,set_mac2,set_mac1,set_mac0,set_ip3,set_ip2,set_ip1,set_ip0, set_err_data,
                dataval,set_mac5,set_mac4,set_mac3,set_mac2,set_mac1,set_mac0,set_ip3,set_ip2,set_ip1,set_ip0, set_err_data,
                set_arp_entry_request)
                set_arp_entry_request)
        begin
        begin
                -- set output followers
                -- set output followers
                req_count <= STD_LOGIC_VECTOR(arp_req_count);
                req_count <= STD_LOGIC_VECTOR(arp_req_count);
 
 
                -- set signal defaults
                -- set signal defaults
                next_rx_state <= IDLE;
                next_rx_state <= IDLE;
                set_rx_state <= '0';
                set_rx_state <= '0';
                rx_event <= NO_EVENT;
                rx_event <= NO_EVENT;
                rx_count_mode <= HOLD;
                rx_count_mode <= HOLD;
                set_arp_oper <= '0';
                set_arp_oper <= '0';
                arp_oper_set_val <= NOP;
                arp_oper_set_val <= NOP;
                dataval <= (others => '0');
                dataval <= (others => '0');
                set_mac5 <= '0';
                set_mac5 <= '0';
                set_mac4 <= '0';
                set_mac4 <= '0';
                set_mac3 <= '0';
                set_mac3 <= '0';
                set_mac2 <= '0';
                set_mac2 <= '0';
                set_mac1 <= '0';
                set_mac1 <= '0';
                set_mac0 <= '0';
                set_mac0 <= '0';
                set_ip3 <= '0';
                set_ip3 <= '0';
                set_ip2 <= '0';
                set_ip2 <= '0';
                set_ip1 <= '0';
                set_ip1 <= '0';
                set_ip0 <= '0';
                set_ip0 <= '0';
                set_arp_entry_request <= '0';
                set_arp_entry_request <= '0';
                set_err_data <= '0';
                set_err_data <= '0';
 
 
                -- determine event (if any)
                -- determine event (if any)
                if data_in_valid = '1' then
                if data_in_valid = '1' then
                        rx_event <= DATA;
                        rx_event <= DATA;
                end if;
                end if;
 
 
                -- RX FSM
                -- RX FSM
                case rx_state is
                case rx_state is
                        when IDLE =>
                        when IDLE =>
                                rx_count_mode <= RST;
                                rx_count_mode <= RST;
                                case rx_event is
                                case rx_event is
                                        when NO_EVENT => -- (nothing to do)
                                        when NO_EVENT => -- (nothing to do)
                                        when DATA =>
                                        when DATA =>
                                                next_rx_state <= PARSE;
                                                next_rx_state <= PARSE;
                                                set_rx_state <= '1';
                                                set_rx_state <= '1';
                                                rx_count_mode <= INCR;
                                                rx_count_mode <= INCR;
                                end case;
                                end case;
 
 
                        when PARSE =>
                        when PARSE =>
                                case rx_event is
                                case rx_event is
                                        when NO_EVENT => -- (nothing to do)
                                        when NO_EVENT => -- (nothing to do)
                                        when DATA =>
                                        when DATA =>
                                                rx_count_mode <= INCR;
                                                rx_count_mode <= INCR;
                                                -- handle early frame termination
                                                -- handle early frame termination
                                                if data_in_last = '1' then
                                                if data_in_last = '1' then
                                                        next_rx_state <= IDLE;
                                                        next_rx_state <= IDLE;
                                                        set_rx_state <= '1';
                                                        set_rx_state <= '1';
                                                else
                                                else
                                                        -- check for end of frame. Also, detect and discard if not our frame
                                                        -- check for end of frame. Also, detect and discard if not our frame
                                                        if rx_count = 42 then
                                                        if rx_count = 42 then
                                                                next_rx_state <= PROCESS_ARP;
                                                                next_rx_state <= PROCESS_ARP;
                                                                set_rx_state <= '1';
                                                                set_rx_state <= '1';
                                                        elsif not_our_arp(data_in,rx_count,our_ip_address) = '1' then
                                                        elsif not_our_arp(data_in,rx_count,our_ip_address) = '1' then
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                                set_err_data <= '1';
                                                                set_err_data <= '1';
                                                                next_rx_state <= WAIT_END;
                                                                next_rx_state <= WAIT_END;
                                                                set_rx_state <= '1';
                                                                set_rx_state <= '1';
                                                        elsif rx_count = 21 then
                                                        elsif rx_count = 21 then
                                                                -- capture ARP operation
                                                                -- capture ARP operation
                                                                case data_in is
                                                                case data_in is
                                                                        when x"01" =>
                                                                        when x"01" =>
                                                                                arp_oper_set_val <= REQUEST;
                                                                                arp_oper_set_val <= REQUEST;
                                                                                set_arp_oper <= '1';
                                                                                set_arp_oper <= '1';
                                                                        when x"02" =>
                                                                        when x"02" =>
                                                                                arp_oper_set_val <= REPLY;
                                                                                arp_oper_set_val <= REPLY;
                                                                                set_arp_oper <= '1';
                                                                                set_arp_oper <= '1';
                                                                        when others =>  -- ignore other values
                                                                        when others =>  -- ignore other values
                                                                end case;
                                                                end case;
                                                        -- capture source mac addr
                                                        -- capture source mac addr
                                                        elsif rx_count = 22 then
                                                        elsif rx_count = 22 then
                                                                set_mac5 <= '1';
                                                                set_mac5 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 23 then
                                                        elsif rx_count = 23 then
                                                                set_mac4 <= '1';
                                                                set_mac4 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 24 then
                                                        elsif rx_count = 24 then
                                                                set_mac3 <= '1';
                                                                set_mac3 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 25 then
                                                        elsif rx_count = 25 then
                                                                set_mac2 <= '1';
                                                                set_mac2 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 26 then
                                                        elsif rx_count = 26 then
                                                                set_mac1 <= '1';
                                                                set_mac1 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 27 then
                                                        elsif rx_count = 27 then
                                                                set_mac0 <= '1';
                                                                set_mac0 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        -- capture source ip addr
                                                        -- capture source ip addr
                                                        elsif rx_count = 28 then
                                                        elsif rx_count = 28 then
                                                                set_ip3 <= '1';
                                                                set_ip3 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 29 then
                                                        elsif rx_count = 29 then
                                                                set_ip2 <= '1';
                                                                set_ip2 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 30 then
                                                        elsif rx_count = 30 then
                                                                set_ip1 <= '1';
                                                                set_ip1 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        elsif rx_count = 31 then
                                                        elsif rx_count = 31 then
                                                                set_ip0 <= '1';
                                                                set_ip0 <= '1';
                                                                dataval <= data_in;
                                                                dataval <= data_in;
                                                        end if;
                                                        end if;
                                                end if;
                                                end if;
                                end case;
                                end case;
 
 
                        when PROCESS_ARP =>
                        when PROCESS_ARP =>
                                next_rx_state <= WAIT_END;
                                next_rx_state <= WAIT_END;
                                set_rx_state <= '1';
                                set_rx_state <= '1';
                                case arp_operation is
                                case arp_operation is
                                        when NOP => -- (nothing to do)
                                        when NOP => -- (nothing to do)
                                        when REQUEST =>
                                        when REQUEST =>
                                                        set_arp_entry_request <= '1';
                                                        set_arp_entry_request <= '1';
                                                        arp_oper_set_val <= NOP;
                                                        arp_oper_set_val <= NOP;
                                                        set_arp_oper <= '1';
                                                        set_arp_oper <= '1';
                                        when REPLY =>
                                        when REPLY =>
                                                        set_arp_entry_request <= '1';
                                                        set_arp_entry_request <= '1';
                                                        arp_oper_set_val <= NOP;
                                                        arp_oper_set_val <= NOP;
                                                        set_arp_oper <= '1';
                                                        set_arp_oper <= '1';
                                end case;
                                end case;
 
 
                        when WAIT_END =>
                        when WAIT_END =>
                                case rx_event is
                                case rx_event is
                                        when NO_EVENT => -- (nothing to do)
                                        when NO_EVENT => -- (nothing to do)
                                        when DATA =>
                                        when DATA =>
                                                if data_in_last = '1' then
                                                if data_in_last = '1' then
                                                        next_rx_state <= IDLE;
                                                        next_rx_state <= IDLE;
                                                        set_rx_state <= '1';
                                                        set_rx_state <= '1';
                                                end if;
                                                end if;
                                end case;
                                end case;
 
 
                end case;
                end case;
 
 
        end process;
        end process;
 
 
        rx_sequential : process (data_in_clk)
        rx_sequential : process (data_in_clk)
        begin
        begin
                if rising_edge(data_in_clk) then
                if rising_edge(data_in_clk) then
                        if reset = '1' then
                        if reset = '1' then
                                -- reset state variables
                                -- reset state variables
                                rx_state <= IDLE;
                                rx_state <= IDLE;
                                rx_count <= x"00";
                                rx_count <= x"00";
                                arp_operation <= NOP;
                                arp_operation <= NOP;
                                arp_req_count <= x"00";
                                arp_req_count <= x"00";
                                -- reset arp entry store
                                -- reset arp entry store
                                arp_entry.ip <= x"00000000";
                                arp_entry.ip <= x"00000000";
                                arp_entry.mac <= x"000000000000";
                                arp_entry.mac <= x"000000000000";
                                arp_entry.is_valid <= '0';
                                arp_entry.is_valid <= '0';
                                arp_entry.reply_required <= '0';
                                arp_entry.reply_required <= '0';
                                arp_err_data <= (others => '0');
                                arp_err_data <= (others => '0');
                        else
                        else
                                -- Next rx_state processing
                                -- Next rx_state processing
                                if set_rx_state = '1' then
                                if set_rx_state = '1' then
                                        rx_state <= next_rx_state;
                                        rx_state <= next_rx_state;
                                else
                                else
                                        rx_state <= rx_state;
                                        rx_state <= rx_state;
                                end if;
                                end if;
 
 
                                -- rx_count processing
                                -- rx_count processing
                                case rx_count_mode is
                                case rx_count_mode is
                                        when RST =>
                                        when RST =>
                                                rx_count <= x"00";
                                                rx_count <= x"00";
                                        when INCR =>
                                        when INCR =>
                                                rx_count <= rx_count + 1;
                                                rx_count <= rx_count + 1;
                                        when HOLD =>
                                        when HOLD =>
                                                rx_count <= rx_count;
                                                rx_count <= rx_count;
                                end case;
                                end case;
 
 
                                -- err data
                                -- err data
                                if set_err_data = '1' then
                                if set_err_data = '1' then
                                        arp_err_data <= data_in;
                                        arp_err_data <= data_in;
                                else
                                else
                                        arp_err_data <= arp_err_data;
                                        arp_err_data <= arp_err_data;
                                end if;
                                end if;
 
 
                                -- arp operation processing
                                -- arp operation processing
                                if set_arp_oper = '1' then
                                if set_arp_oper = '1' then
                                        arp_operation <= arp_oper_set_val;
                                        arp_operation <= arp_oper_set_val;
                                else
                                else
                                        arp_operation <= arp_operation;
                                        arp_operation <= arp_operation;
                                end if;
                                end if;
 
 
                                -- source mac capture
                                -- source mac capture
                                if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
                                if (set_mac5 = '1') then new_arp_entry.mac(47 downto 40) <= dataval; end if;
                                if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
                                if (set_mac4 = '1') then new_arp_entry.mac(39 downto 32) <= dataval; end if;
                                if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
                                if (set_mac3 = '1') then new_arp_entry.mac(31 downto 24) <= dataval; end if;
                                if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
                                if (set_mac2 = '1') then new_arp_entry.mac(23 downto 16) <= dataval; end if;
                                if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
                                if (set_mac1 = '1') then new_arp_entry.mac(15 downto 8) <= dataval; end if;
                                if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
                                if (set_mac0 = '1') then new_arp_entry.mac(7 downto 0) <= dataval; end if;
 
 
                                -- source ip capture
                                -- source ip capture
                                if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
                                if (set_ip3 = '1') then new_arp_entry.ip(31 downto 24) <= dataval; end if;
                                if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
                                if (set_ip2 = '1') then new_arp_entry.ip(23 downto 16) <= dataval; end if;
                                if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
                                if (set_ip1 = '1') then new_arp_entry.ip(15 downto 8) <= dataval; end if;
                                if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
                                if (set_ip0 = '1') then new_arp_entry.ip(7 downto 0) <= dataval; end if;
 
 
                                -- set arp entry request
                                -- set arp entry request
                                if control.clear_cache = '1' then
                                if control.clear_cache = '1' then
                                        arp_entry.ip <= x"00000000";
                                        arp_entry.ip <= x"00000000";
                                        arp_entry.mac <= x"000000000000";
                                        arp_entry.mac <= x"000000000000";
                                        arp_entry.is_valid <= '0';
                                        arp_entry.is_valid <= '0';
                                        arp_entry.reply_required <= '0';
                                        arp_entry.reply_required <= '0';
                                elsif set_arp_entry_request = '1' then
                                elsif set_arp_entry_request = '1' then
                                        -- copy info from new entry to arp_entry and set reply required
                                        -- copy info from new entry to arp_entry and set reply required
                                        arp_entry.mac <= new_arp_entry.mac;
                                        arp_entry.mac <= new_arp_entry.mac;
                                        arp_entry.ip <= new_arp_entry.ip;
                                        arp_entry.ip <= new_arp_entry.ip;
                                        arp_entry.is_valid <= '1';
                                        arp_entry.is_valid <= '1';
                                        if arp_operation = REQUEST then
                                        if arp_operation = REQUEST then
                                                arp_entry.reply_required <= '1';
                                                arp_entry.reply_required <= '1';
                                        else
                                        else
                                                arp_entry.reply_required <= '0';
                                                arp_entry.reply_required <= '0';
                                        end if;
                                        end if;
                                        -- count another ARP pkt received
                                        -- count another ARP pkt received
                                        arp_req_count <= arp_req_count + 1;
                                        arp_req_count <= arp_req_count + 1;
                                elsif clear_reply_req = '1' then
                                elsif clear_reply_req = '1' then
                                        -- note: clear_reply_req is set by tx logic, but handled in the clk domain of the rx
                                        -- note: clear_reply_req is set by tx logic, but handled in the clk domain of the rx
                                        -- maintain arp entry state, but reset the reply required flag
                                        -- maintain arp entry state, but reset the reply required flag
                                        arp_entry.mac <= arp_entry.mac;
                                        arp_entry.mac <= arp_entry.mac;
                                        arp_entry.ip <= arp_entry.ip;
                                        arp_entry.ip <= arp_entry.ip;
                                        arp_entry.is_valid <= arp_entry.is_valid;
                                        arp_entry.is_valid <= arp_entry.is_valid;
                                        arp_entry.reply_required <= '0';
                                        arp_entry.reply_required <= '0';
                                        arp_req_count <= arp_req_count;
                                        arp_req_count <= arp_req_count;
                                elsif send_request_needed = '1' then
                                elsif send_request_needed = '1' then
                                        -- set up the arp entry to take the request to be transmitted out by the TX FSM
                                        -- set up the arp entry to take the request to be transmitted out by the TX FSM
                                        arp_entry.ip <= req_ip_addr;
                                        arp_entry.ip <= req_ip_addr;
                                        arp_entry.mac <= (others => '0');
                                        arp_entry.mac <= (others => '0');
                                        arp_entry.is_valid <= '0';
                                        arp_entry.is_valid <= '0';
                                        arp_entry.reply_required <= '0';
                                        arp_entry.reply_required <= '0';
                                else
                                else
                                        arp_entry <= arp_entry;
                                        arp_entry <= arp_entry;
                                        arp_req_count <= arp_req_count;
                                        arp_req_count <= arp_req_count;
                                end if;
                                end if;
 
 
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
        tx_combinatorial : process (
        tx_combinatorial : process (
                -- input signals
                -- input signals
                data_out_ready, send_request_needed, mac_tx_granted, our_mac_address, our_ip_address,
                data_out_ready, send_request_needed, mac_tx_granted, our_mac_address, our_ip_address,
                -- state variables
                -- state variables
                tx_state, tx_count, tx_mac_chn_reqd, arp_entry,
                tx_state, tx_count, tx_mac_chn_reqd, arp_entry,
                -- control signals
                -- control signals
                next_rx_state, set_rx_state, tx_count_mode, kill_data_out_valid,
                next_rx_state, set_rx_state, tx_count_mode, kill_data_out_valid,
                set_chn_reqd, clear_reply_req)
                set_chn_reqd, clear_reply_req)
        begin
        begin
                -- set output followers
                -- set output followers
                mac_tx_req <= tx_mac_chn_reqd;
                mac_tx_req <= tx_mac_chn_reqd;
 
 
                -- set initial values for combinatorial outputs
                -- set initial values for combinatorial outputs
                data_out_first <= '0';
                data_out_first <= '0';
 
 
                case tx_state is
                case tx_state is
                        when SEND   =>
                        when SEND   =>
                                if data_out_ready = '1' and kill_data_out_valid = '0' then
                                if data_out_ready = '1' and kill_data_out_valid = '0' then
                                        data_out_valid <= '1';
                                        data_out_valid <= '1';
                                else
                                else
                                        data_out_valid <= '0';
                                        data_out_valid <= '0';
                                end if;
                                end if;
                        when OTHERS =>  data_out_valid <= '0';
                        when OTHERS =>  data_out_valid <= '0';
                end case;
                end case;
 
 
                -- set signal defaults
                -- set signal defaults
                next_tx_state <= IDLE;
                next_tx_state <= IDLE;
                set_tx_state <= '0';
                set_tx_state <= '0';
                tx_count_mode <= HOLD;
                tx_count_mode <= HOLD;
                data_out <= x"00";
                data_out <= x"00";
                data_out_last <= '0';
                data_out_last <= '0';
                clear_reply_req <= '0';
                clear_reply_req <= '0';
                set_chn_reqd <= HOLD;
                set_chn_reqd <= HOLD;
                kill_data_out_valid <= '0';
                kill_data_out_valid <= '0';
 
 
                -- TX FSM
                -- TX FSM
                case tx_state is
                case tx_state is
                        when IDLE =>
                        when IDLE =>
                                tx_count_mode <= RST;
                                tx_count_mode <= RST;
                                if arp_entry.reply_required = '1' then
                                if arp_entry.reply_required = '1' then
                                        set_chn_reqd <= SET;
                                        set_chn_reqd <= SET;
                                        next_tx_state <= WAIT_MAC;
                                        next_tx_state <= WAIT_MAC;
                                        set_tx_state <= '1';
                                        set_tx_state <= '1';
                                elsif send_request_needed = '1' then
                                elsif send_request_needed = '1' then
                                        set_chn_reqd <= SET;
                                        set_chn_reqd <= SET;
                                        next_tx_state <= WAIT_MAC;
                                        next_tx_state <= WAIT_MAC;
                                        set_tx_state <= '1';
                                        set_tx_state <= '1';
                                else
                                else
                                        set_chn_reqd <= CLR;
                                        set_chn_reqd <= CLR;
                                end if;
                                end if;
 
 
                        when WAIT_MAC =>
                        when WAIT_MAC =>
                                tx_count_mode <= RST;
                                tx_count_mode <= RST;
                                if mac_tx_granted = '1' then
                                if mac_tx_granted = '1' then
                                        next_tx_state <= SEND;
                                        next_tx_state <= SEND;
                                        set_tx_state <= '1';
                                        set_tx_state <= '1';
                                end if;
                                end if;
                                -- TODO - should handle timeout here
                                -- TODO - should handle timeout here
 
 
                        when SEND =>
                        when SEND =>
                                if data_out_ready = '1' then
                                if data_out_ready = '1' then
                                                tx_count_mode <= INCR;
                                                tx_count_mode <= INCR;
                                end if;
                                end if;
                                case tx_count is
                                case tx_count is
                                        when x"00"  =>
                                        when x"00"  =>
                                                data_out_first <= data_out_ready;
                                                data_out_first <= data_out_ready;
                                                data_out <= x"ff";                                                              -- dst = broadcast
                                                data_out <= x"ff";                                                              -- dst = broadcast
 
 
                                        when x"01"  => data_out <= x"ff";
                                        when x"01"  => data_out <= x"ff";
                                        when x"02"  => data_out <= x"ff";
                                        when x"02"  => data_out <= x"ff";
                                        when x"03"  => data_out <= x"ff";
                                        when x"03"  => data_out <= x"ff";
                                        when x"04"  => data_out <= x"ff";
                                        when x"04"  => data_out <= x"ff";
                                        when x"05"  => data_out <= x"ff";
                                        when x"05"  => data_out <= x"ff";
                                        when x"06"  => data_out <= our_mac_address (47 downto 40);      -- src = our mac
                                        when x"06"  => data_out <= our_mac_address (47 downto 40);      -- src = our mac
                                        when x"07"  => data_out <= our_mac_address (39 downto 32);
                                        when x"07"  => data_out <= our_mac_address (39 downto 32);
                                        when x"08"  => data_out <= our_mac_address (31 downto 24);
                                        when x"08"  => data_out <= our_mac_address (31 downto 24);
                                        when x"09"  => data_out <= our_mac_address (23 downto 16);
                                        when x"09"  => data_out <= our_mac_address (23 downto 16);
                                        when x"0a"  => data_out <= our_mac_address (15 downto 8);
                                        when x"0a"  => data_out <= our_mac_address (15 downto 8);
                                        when x"0b"  => data_out <= our_mac_address (7 downto 0);
                                        when x"0b"  => data_out <= our_mac_address (7 downto 0);
                                        when x"0c"  => data_out <= x"08";                                                                       -- pkt type = 0806 : ARP
                                        when x"0c"  => data_out <= x"08";                                                                       -- pkt type = 0806 : ARP
                                        when x"0d"  => data_out <= x"06";
                                        when x"0d"  => data_out <= x"06";
                                        when x"0e"  => data_out <= x"00";                                                                       -- HW type = 0001 : eth
                                        when x"0e"  => data_out <= x"00";                                                                       -- HW type = 0001 : eth
                                        when x"0f"  => data_out <= x"01";
                                        when x"0f"  => data_out <= x"01";
                                        when x"10"  => data_out <= x"08";                                                                       -- protocol = 0800 : ip
                                        when x"10"  => data_out <= x"08";                                                                       -- protocol = 0800 : ip
                                        when x"11"  => data_out <= x"00";
                                        when x"11"  => data_out <= x"00";
                                        when x"12"  => data_out <= x"06";                                                                       -- HW size = 06
                                        when x"12"  => data_out <= x"06";                                                                       -- HW size = 06
                                        when x"13"  => data_out <= x"04";                                                                       -- prot size = 04
                                        when x"13"  => data_out <= x"04";                                                                       -- prot size = 04
 
 
                                        when x"14"  =>  data_out <= x"00";                                                                      -- opcode =             
                                        when x"14"  =>  data_out <= x"00";                                                                      -- opcode =             
                                        when x"15"  =>
                                        when x"15"  =>
                                                if arp_entry.is_valid = '1' then
                                                if arp_entry.is_valid = '1' then
                                                        data_out <= x"02";                                                                                                                                                      -- 02 : REPLY if arp_entry valid
                                                        data_out <= x"02";                                                                                                                                                      -- 02 : REPLY if arp_entry valid
                                                else
                                                else
                                                        data_out <= x"01";                                                                                                                                                      -- 01 : REQ if arp_entry invalid
                                                        data_out <= x"01";                                                                                                                                                      -- 01 : REQ if arp_entry invalid
                                                end if;
                                                end if;
 
 
                                        when x"16" => data_out <= our_mac_address (47 downto 40);       -- sender mac
                                        when x"16" => data_out <= our_mac_address (47 downto 40);       -- sender mac
                                        when x"17" => data_out <= our_mac_address (39 downto 32);
                                        when x"17" => data_out <= our_mac_address (39 downto 32);
                                        when x"18" => data_out <= our_mac_address (31 downto 24);
                                        when x"18" => data_out <= our_mac_address (31 downto 24);
                                        when x"19" => data_out <= our_mac_address (23 downto 16);
                                        when x"19" => data_out <= our_mac_address (23 downto 16);
                                        when x"1a" => data_out <= our_mac_address (15 downto 8);
                                        when x"1a" => data_out <= our_mac_address (15 downto 8);
                                        when x"1b" => data_out <= our_mac_address (7 downto 0);
                                        when x"1b" => data_out <= our_mac_address (7 downto 0);
                                        when x"1c" => data_out <= our_ip_address (31 downto 24);        -- sender ip
                                        when x"1c" => data_out <= our_ip_address (31 downto 24);        -- sender ip
                                        when x"1d" => data_out <= our_ip_address (23 downto 16);
                                        when x"1d" => data_out <= our_ip_address (23 downto 16);
                                        when x"1e" => data_out <= our_ip_address (15 downto 8);
                                        when x"1e" => data_out <= our_ip_address (15 downto 8);
                                        when x"1f" => data_out <= our_ip_address (7 downto 0);
                                        when x"1f" => data_out <= our_ip_address (7 downto 0);
                                        when x"20" => data_out <= arp_entry.mac (47 downto 40);         -- target mac
                                        when x"20" => data_out <= arp_entry.mac (47 downto 40);         -- target mac
                                        when x"21" => data_out <= arp_entry.mac (39 downto 32);
                                        when x"21" => data_out <= arp_entry.mac (39 downto 32);
                                        when x"22" => data_out <= arp_entry.mac (31 downto 24);
                                        when x"22" => data_out <= arp_entry.mac (31 downto 24);
                                        when x"23" => data_out <= arp_entry.mac (23 downto 16);
                                        when x"23" => data_out <= arp_entry.mac (23 downto 16);
                                        when x"24" => data_out <= arp_entry.mac (15 downto 8);
                                        when x"24" => data_out <= arp_entry.mac (15 downto 8);
                                        when x"25" => data_out <= arp_entry.mac (7 downto 0);
                                        when x"25" => data_out <= arp_entry.mac (7 downto 0);
                                        when x"26" => data_out <= arp_entry.ip  (31 downto 24);         -- target ip
                                        when x"26" => data_out <= arp_entry.ip  (31 downto 24);         -- target ip
                                        when x"27" => data_out <= arp_entry.ip   (23 downto 16);
                                        when x"27" => data_out <= arp_entry.ip   (23 downto 16);
                                        when x"28" => data_out <= arp_entry.ip   (15 downto 8);
                                        when x"28" => data_out <= arp_entry.ip   (15 downto 8);
 
 
                                        when x"29" =>
                                        when x"29" =>
                                                data_out <= arp_entry.ip(7 downto 0);
                                                data_out <= arp_entry.ip(7 downto 0);
                                                data_out_last <= '1';
                                                data_out_last <= '1';
 
 
                                        when x"2a" =>
                                        when x"2a" =>
                                                clear_reply_req <= '1';                 -- reset the reply request (done in the rx clk process domain)
                                                clear_reply_req <= '1';                 -- reset the reply request (done in the rx clk process domain)
                                                kill_data_out_valid <= '1';     -- data is no longer valid
                                                kill_data_out_valid <= '1';     -- data is no longer valid
                                                next_tx_state <= IDLE;
                                                next_tx_state <= IDLE;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
 
 
                                        when others =>
                                        when others =>
                                                next_tx_state <= IDLE;
                                                next_tx_state <= IDLE;
                                                set_tx_state <= '1';
                                                set_tx_state <= '1';
                                end case;
                                end case;
                end case;
                end case;
        end process;
        end process;
 
 
        tx_sequential : process (data_out_clk,reset)
        tx_sequential : process (data_out_clk,reset)
        begin
        begin
                if rising_edge(data_out_clk) then
                if rising_edge(data_out_clk) then
                        if reset = '1' then
                        if reset = '1' then
                                -- reset state variables
                                -- reset state variables
                                tx_state <= IDLE;
                                tx_state <= IDLE;
                                tx_mac_chn_reqd <= '0';
                                tx_mac_chn_reqd <= '0';
                        else
                        else
                                -- Next rx_state processing
                                -- Next rx_state processing
                                if set_tx_state = '1' then
                                if set_tx_state = '1' then
                                        tx_state <= next_tx_state;
                                        tx_state <= next_tx_state;
                                else
                                else
                                        tx_state <= tx_state;
                                        tx_state <= tx_state;
                                end if;
                                end if;
 
 
                                -- tx_count processing
                                -- tx_count processing
                                case tx_count_mode is
                                case tx_count_mode is
                                        when RST =>
                                        when RST =>
                                                tx_count <= x"00";
                                                tx_count <= x"00";
                                        when INCR =>
                                        when INCR =>
                                                tx_count <= tx_count + 1;
                                                tx_count <= tx_count + 1;
                                        when HOLD =>
                                        when HOLD =>
                                                tx_count <= tx_count;
                                                tx_count <= tx_count;
                                end case;
                                end case;
 
 
                                -- control access request to mac tx chn
                                -- control access request to mac tx chn
                                case set_chn_reqd is
                                case set_chn_reqd is
                                        when SET => tx_mac_chn_reqd <= '1';
                                        when SET => tx_mac_chn_reqd <= '1';
                                        when CLR => tx_mac_chn_reqd <= '0';
                                        when CLR => tx_mac_chn_reqd <= '0';
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
                                        when HOLD => tx_mac_chn_reqd <= tx_mac_chn_reqd;
                                end case;
                                end case;
 
 
                        end if;
                        end if;
                end if;
                end if;
        end process;
        end process;
 
 
 
 
end Behavioral;
end Behavioral;
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.