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

Subversion Repositories udp_ip_stack

[/] [udp_ip_stack/] [tags/] [v2.0/] [rtl/] [vhdl/] [arp_REQ.vhd] - Diff between revs 10 and 12

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

Rev 10 Rev 12
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- 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_REQ - Behavioral 
-- Module Name:    arp_REQ - Behavioral 
-- Project Name: 
-- Project Name: 
-- Target Devices: 
-- Target Devices: 
-- Tool versions: 
-- Tool versions: 
-- Description:
-- Description:
--              handle requests for ARP resolution
--              handle requests for ARP resolution
--              responds from single entry cache or searches external arp store, or asks to send a request
--              responds from single entry cache or searches external arp store, or asks to send a request
--
--
-- Dependencies: 
-- Dependencies: 
--
--
-- Revision: 
-- Revision: 
-- Revision 0.01 - File Created from arp.vhd 0.2
-- Revision 0.01 - File Created from arp.vhd 0.2
-- 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_req is
entity arp_req 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 := 5                                         -- # wrong nwk pkts received before set error
                        ARP_MAX_PKT_TMO  : integer := 5                                         -- # wrong nwk pkts received before set error
                        );
                        );
    Port (
    Port (
                        -- lookup request signals
                        -- lookup request signals
                        arp_req_req                     : in arp_req_req_type;                          -- request for a translation from IP to MAC
                        arp_req_req                     : in arp_req_req_type;                          -- request for a translation from IP to MAC
                        arp_req_rslt            : out arp_req_rslt_type;                        -- the result
                        arp_req_rslt            : out arp_req_rslt_type;                        -- the result
                        -- external arp store signals
                        -- external arp store signals
                        arp_store_req           : out arp_store_rdrequest_t;            -- requesting a lookup or store
                        arp_store_req           : out arp_store_rdrequest_t;            -- requesting a lookup or store
                        arp_store_result        : in arp_store_result_t;                        -- the result
                        arp_store_result        : in arp_store_result_t;                        -- the result
                        -- network request signals
                        -- network request signals
                        arp_nwk_req                     : out arp_nwk_request_t;                        -- requesting resolution via the network
                        arp_nwk_req                     : out arp_nwk_request_t;                        -- requesting resolution via the network
                        arp_nwk_result          : in arp_nwk_result_t;                          -- the result
                        arp_nwk_result          : in arp_nwk_result_t;                          -- the result
                        -- system signals
                        -- system signals
                        clear_cache                     : in std_logic;                                         -- clear the internal cache
                        clear_cache                     : in std_logic;                                         -- clear the internal cache
                        clk                                     : in std_logic;
                        clk                                     : in std_logic;
                        reset                           : in  STD_LOGIC
                        reset                           : in  STD_LOGIC
                        );
                        );
end arp_req;
end arp_req;
 
 
architecture Behavioral of arp_req is
architecture Behavioral of arp_req is
 
 
        type req_state_t is (IDLE,LOOKUP,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
        type req_state_t is (IDLE,LOOKUP,WAIT_REPLY,PAUSE1,PAUSE2,PAUSE3);
        type set_cntr_t is (HOLD,CLR,INCR);
        type set_cntr_t is (HOLD,CLR,INCR);
        type set_clr_type is (SET, CLR, HOLD);
        type set_clr_type is (SET, CLR, HOLD);
 
 
        -- state variables
        -- state variables
        signal req_state                                : req_state_t;
        signal req_state                                : req_state_t;
        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 arp_entry_cache          : arp_entry_t;                                                                  -- single entry cache for fast response
        signal arp_entry_cache          : arp_entry_t;                                                                  -- single entry cache for fast response
        signal cache_valid                      : std_logic;                                                                    -- single entry cache is valid
        signal cache_valid                      : std_logic;                                                                    -- single entry cache is valid
        signal nwk_rx_cntr                      : unsigned(7 downto 0);                                          -- counts nwk rx pkts that dont satisfy
        signal nwk_rx_cntr                      : unsigned(7 downto 0);                                          -- counts nwk rx pkts that dont satisfy
        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;
 
 
        -- busses
        -- busses
        signal next_req_state           : req_state_t;
        signal next_req_state           : req_state_t;
        signal arp_entry_val                    : arp_entry_t;
        signal arp_entry_val                    : arp_entry_t;
 
 
        -- requester control signals
        -- requester control signals
        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 store_arp_cache          : std_logic;
        signal store_arp_cache          : std_logic;
        signal set_nwk_rx_cntr          : set_cntr_t;
        signal set_nwk_rx_cntr          : set_cntr_t;
        signal set_timer                                : set_cntr_t;                           -- timer reset, count, hold control
        signal set_timer                                : set_cntr_t;                           -- 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
        signal clear_cache_valid        : std_logic;
        signal clear_cache_valid        : std_logic;
 
 
begin
begin
        req_combinatorial : process (
        req_combinatorial : process (
                -- input signals
                -- input signals
                arp_req_req, arp_store_result, arp_nwk_result, clear_cache,
                arp_req_req, arp_store_result, arp_nwk_result, clear_cache,
                -- state variables
                -- state variables
                req_state, req_ip_addr, arp_entry_cache, cache_valid, nwk_rx_cntr,
                req_state, req_ip_addr, arp_entry_cache, cache_valid, nwk_rx_cntr,
                freq_scaler, timer, timeout_reg,
                freq_scaler, timer, timeout_reg,
                -- busses
                -- busses
                next_req_state, arp_entry_val,
                next_req_state, arp_entry_val,
                -- control signals
                -- control signals
                set_req_state, set_req_ip, store_arp_cache, set_nwk_rx_cntr, clear_cache_valid,
                set_req_state, set_req_ip, store_arp_cache, set_nwk_rx_cntr, clear_cache_valid,
                set_timer, timer_enable, set_timeout
                set_timer, timer_enable, set_timeout
                )
                )
        begin
        begin
                -- set output followers
                -- set output followers
                arp_req_rslt.got_mac <= '0';     -- set initial value of request result outputs
                arp_req_rslt.got_mac <= '0';     -- set initial value of request result outputs
                arp_req_rslt.got_err <= '0';
                arp_req_rslt.got_err <= '0';
                arp_req_rslt.mac <= (others => '0');
                arp_req_rslt.mac <= (others => '0');
                arp_store_req.req <= '0';
                arp_store_req.req <= '0';
                arp_store_req.ip <= (others => '0');
                arp_store_req.ip <= (others => '0');
                arp_nwk_req.req <= '0';
                arp_nwk_req.req <= '0';
                arp_nwk_req.ip <= (others => '0');
                arp_nwk_req.ip <= (others => '0');
 
 
                -- 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_cache.ip and cache_valid = '1' then
                if arp_req_req.lookup_req = '1' and arp_req_req.ip = arp_entry_cache.ip and cache_valid = '1' then
                        arp_req_rslt.got_mac <= '1';
                        arp_req_rslt.got_mac <= '1';
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                elsif arp_req_req.lookup_req = '1' then
                elsif arp_req_req.lookup_req = '1' then
                        -- hold off got_mac while req is there as arp_entry will not be correct yet
                        -- hold off got_mac while req is there as arp_entry will not be correct yet
                        arp_req_rslt.got_mac <= '0';
                        arp_req_rslt.got_mac <= '0';
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                else
                else
                        arp_req_rslt.got_mac <= cache_valid;
                        arp_req_rslt.got_mac <= cache_valid;
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                        arp_req_rslt.mac <= arp_entry_cache.mac;
                end if;
                end if;
 
 
                if arp_req_req.lookup_req = '1' then
                if arp_req_req.lookup_req = '1' then
                        -- ensure any existing error report is killed at the start of a request
                        -- ensure any existing error report is killed at the start of a request
                        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;
 
 
                -- 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';
                store_arp_cache <= '0';
                store_arp_cache <= '0';
                arp_entry_val.ip <= (others => '0');
                arp_entry_val.ip <= (others => '0');
                arp_entry_val.mac <= (others => '0');
                arp_entry_val.mac <= (others => '0');
                set_nwk_rx_cntr <= HOLD;
                set_nwk_rx_cntr <= HOLD;
                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';
                clear_cache_valid <= clear_cache;
                clear_cache_valid <= clear_cache;
 
 
                -- 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 <= CLR;
                                set_timer <= CLR;
                                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_cache.ip and cache_valid = '1' then
                                        if arp_req_req.ip = arp_entry_cache.ip and cache_valid = '1' then
                                                -- already have this IP - feed output back
                                                -- already have this IP - feed output back
                                                arp_req_rslt.got_mac <= '1';
                                                arp_req_rslt.got_mac <= '1';
                                                arp_req_rslt.mac <= arp_entry_cache.mac;
                                                arp_req_rslt.mac <= arp_entry_cache.mac;
                                        else
                                        else
                                                clear_cache_valid <= '1';               -- remove cache entry
                                                clear_cache_valid <= '1';               -- remove cache entry
                                                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';
                                        end if;
                                        end if;
                                end if;
                                end if;
 
 
                        when LOOKUP =>
                        when LOOKUP =>
                                -- put request on the store
                                -- put request on the store
                                arp_store_req.ip <= req_ip_addr;
                                arp_store_req.ip <= req_ip_addr;
                                arp_store_req.req <= '1';
                                arp_store_req.req <= '1';
                                case arp_store_result.status is
                                case arp_store_result.status is
                                        when FOUND =>
                                        when FOUND =>
                                                -- update the cache
                                                -- update the cache
                                                arp_entry_val <= arp_store_result.entry;
                                                arp_entry_val <= arp_store_result.entry;
                                                store_arp_cache <= '1';
                                                store_arp_cache <= '1';
                                                -- and feed output back
                                                -- and feed output back
                                                arp_req_rslt.got_mac <= '1';
                                                arp_req_rslt.got_mac <= '1';
                                                arp_req_rslt.mac <= arp_store_result.entry.mac;
                                                arp_req_rslt.mac <= arp_store_result.entry.mac;
                                                next_req_state <= IDLE;
                                                next_req_state <= IDLE;
                                                set_req_state <= '1';
                                                set_req_state <= '1';
 
 
                                        when NOT_FOUND =>
                                        when NOT_FOUND =>
                                                -- need to request from the network
                                                -- need to request from the network
                                                set_timer <= CLR;
                                                set_timer <= CLR;
                                                set_nwk_rx_cntr <= CLR;
                                                set_nwk_rx_cntr <= CLR;
                                                arp_nwk_req.req <= '1';
                                                arp_nwk_req.req <= '1';
                                                arp_nwk_req.ip <= req_ip_addr;
                                                arp_nwk_req.ip <= req_ip_addr;
                                                next_req_state <= WAIT_REPLY;
                                                next_req_state <= WAIT_REPLY;
                                                set_req_state <= '1';
                                                set_req_state <= '1';
 
 
                                        when OTHERS =>
                                        when OTHERS =>
                                                -- just keep waiting - no timeout (assumes lookup with either succeed or fail)
                                                -- just keep waiting - no timeout (assumes lookup with either succeed or fail)
                                end case;
                                end case;
 
 
                        when WAIT_REPLY =>
                        when WAIT_REPLY =>
                                case arp_nwk_result.status is
                                case arp_nwk_result.status is
                                        when RECEIVED =>
                                        when RECEIVED =>
                                                -- store into cache
                                                -- store into cache
                                                arp_entry_val <= arp_nwk_result.entry;
                                                arp_entry_val <= arp_nwk_result.entry;
                                                store_arp_cache <= '1';
                                                store_arp_cache <= '1';
                                                -- and feed output back
                                                -- and feed output back
                                                if arp_nwk_result.entry.ip = req_ip_addr then
                                                if arp_nwk_result.entry.ip = req_ip_addr then
                                                        arp_req_rslt.got_mac <= '1';
                                                        arp_req_rslt.got_mac <= '1';
                                                        arp_req_rslt.mac <= arp_nwk_result.entry.mac;
                                                        arp_req_rslt.mac <= arp_nwk_result.entry.mac;
                                                        next_req_state <= IDLE;
                                                        next_req_state <= IDLE;
                                                        set_req_state <= '1';
                                                        set_req_state <= '1';
                                                else
                                                else
                                                        if nwk_rx_cntr > ARP_MAX_PKT_TMO then
                                                        if nwk_rx_cntr > ARP_MAX_PKT_TMO then
                                                                set_timeout <= SET;
                                                                set_timeout <= SET;
                                                                next_req_state <= IDLE;
                                                                next_req_state <= IDLE;
                                                                set_req_state <= '1';
                                                                set_req_state <= '1';
                                                        else
                                                        else
                                                                set_nwk_rx_cntr <= INCR;
                                                                set_nwk_rx_cntr <= INCR;
                                                        end if;
                                                        end if;
                                                end if;
                                                end if;
 
 
                                        when ERROR =>
                                        when ERROR =>
                                                set_timeout <= SET;
                                                set_timeout <= SET;
 
 
                                        when OTHERS =>
                                        when OTHERS =>
                                                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;
                                end case;
                                end case;
 
 
                        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 (clk)
        req_sequential : process (clk)
        begin
        begin
                if rising_edge(clk) then
                if rising_edge(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');
                                arp_entry_cache.ip <= (others => '0');
                                arp_entry_cache.ip <= (others => '0');
                                arp_entry_cache.mac <= (others => '0');
                                arp_entry_cache.mac <= (others => '0');
                                cache_valid <= '0';
                                cache_valid <= '0';
                                nwk_rx_cntr <= (others => '0');
                                nwk_rx_cntr <= (others => '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;
 
 
                                -- network received counter
                                -- network received counter
                                case set_nwk_rx_cntr is
                                case set_nwk_rx_cntr is
                                        when CLR  => nwk_rx_cntr <= (others => '0');
                                        when CLR  => nwk_rx_cntr <= (others => '0');
                                        when INCR => nwk_rx_cntr <= nwk_rx_cntr + 1;
                                        when INCR => nwk_rx_cntr <= nwk_rx_cntr + 1;
                                        when HOLD => nwk_rx_cntr <= nwk_rx_cntr;
                                        when HOLD => nwk_rx_cntr <= nwk_rx_cntr;
                                end case;
                                end case;
 
 
                                -- set the arp_entry_cache
                                -- set the arp_entry_cache
                                if clear_cache_valid = '1' then
                                if clear_cache_valid = '1' then
                                        arp_entry_cache <= arp_entry_cache;
                                        arp_entry_cache <= arp_entry_cache;
                                        cache_valid <= '0';
                                        cache_valid <= '0';
                                elsif store_arp_cache = '1' then
                                elsif store_arp_cache = '1' then
                                        arp_entry_cache <= arp_entry_val;
                                        arp_entry_cache <= arp_entry_val;
                                        cache_valid <= '1';
                                        cache_valid <= '1';
                                else
                                else
                                        arp_entry_cache <= arp_entry_cache;
                                        arp_entry_cache <= arp_entry_cache;
                                        cache_valid <= cache_valid;
                                        cache_valid <= cache_valid;
                                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 CLR =>
                                        when CLR =>
                                                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;
 
 
end Behavioral;
end Behavioral;
 
 

powered by: WebSVN 2.1.0

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