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_REQ.vhd] - Diff between revs 10 and 18

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

Rev 10 Rev 18
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
-- 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 (
 
    no_default_gateway : boolean := true;  -- set to false if communicating with devices accessed
 
                                            -- through a "default gateway or router"
                        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
 
    nwk_gateway      : in  std_logic_vector(31 downto 0);  -- IP address of default gateway
 
    nwk_mask         : in  std_logic_vector(31 downto 0);  -- Net mask
                        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;
 
 
 
  signal l_arp_req_req_ip : std_logic_vector(31 downto 0);  -- local network IP address for resolution
 
 
begin
begin
 
 
 
  default_GW: if (not no_default_gateway) generate
 
    default_gw_comb_p: process (arp_req_req.ip, nwk_gateway, nwk_mask) is
 
    begin  -- process default_gw_comb_p
 
      -- translate IP addresses to local IP address if necessary
 
      if ((nwk_mask and arp_req_req.ip) = (nwk_mask and nwk_gateway)) then
 
        -- on local network
 
        l_arp_req_req_ip <= arp_req_req.ip;
 
      else
 
        -- on remote network
 
        l_arp_req_req_ip <= nwk_gateway;
 
      end if;
 
    end process default_gw_comb_p;
 
  end generate default_GW;
 
 
 
  no_default_GW: if (no_default_gateway) generate
 
    no_default_gw_comb_p: process (arp_req_req.ip) is
 
    begin  -- process no_default_gw_comb_p
 
      l_arp_req_req_ip <= arp_req_req.ip;
 
    end process no_default_gw_comb_p;
 
  end generate no_default_GW;
 
 
        req_combinatorial : process (
        req_combinatorial : process (
                -- input signals
    arp_entry_cache.ip, arp_entry_cache.mac, arp_nwk_result.entry, arp_nwk_result.entry.ip,
                arp_req_req, arp_store_result, arp_nwk_result, clear_cache,
    arp_nwk_result.entry.mac, arp_nwk_result.status, arp_req_req.lookup_req,
                -- state variables
    arp_store_result.entry, arp_store_result.entry.mac, arp_store_result.status, cache_valid,
                req_state, req_ip_addr, arp_entry_cache, cache_valid, nwk_rx_cntr,
    clear_cache, freq_scaler, l_arp_req_req_ip, nwk_rx_cntr, req_ip_addr, req_state,
                freq_scaler, timer, timeout_reg,
    timeout_reg, timer)
                -- busses
 
                next_req_state, arp_entry_val,
 
                -- control signals
 
                set_req_state, set_req_ip, store_arp_cache, set_nwk_rx_cntr, clear_cache_valid,
 
                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 l_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 l_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 =>
 
            if arp_nwk_result.entry.ip = req_ip_addr then
                                                -- 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
 
                                                        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 <= l_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.