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

Go to most recent revision | 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_STORE_br - Behavioral 
-- Module Name:    arp_STORE_br - Behavioral 
-- Project Name: 
-- Project Name: 
-- Target Devices: 
-- Target Devices: 
-- Tool versions: 
-- Tool versions: 
-- Description:
-- Description:
--              ARP storage table using block ram with lookup based on IP address
--              ARP storage table using block ram with lookup based on IP address
--              implements upto 255 entries with sequential search
--              implements upto 255 entries with sequential search
--              uses round robin overwrite when full (LRU would be better, but ...)
--              uses round robin overwrite when full (LRU would be better, but ...)
--
--
--              store may take a number of cycles and the request is latched
--              store may take a number of cycles and the request is latched
--              lookup may take a number of cycles. Assumes that request signals remain valid during lookup
--              lookup may take a number of cycles. Assumes that request signals remain valid during lookup
--
--
-- Dependencies: 
-- Dependencies: 
--
--
-- Revision: 
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.01 - File Created
-- 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 ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
use work.arp_types.all;
use work.arp_types.all;
 
 
entity arp_STORE_br is
entity arp_STORE_br is
        generic (
  generic (
                        MAX_ARP_ENTRIES : integer := 255                                                        -- max entries in the store
    MAX_ARP_ENTRIES : integer := 255          -- max entries in the store
                        );
                        );
        Port (
  port (
                        -- read signals
                        -- read signals
                        read_req                                : in arp_store_rdrequest_t;             -- requesting a lookup or store
    read_req    : in  arp_store_rdrequest_t;  -- requesting a lookup or store
                        read_result                     : out arp_store_result_t;                       -- the result
    read_result : out arp_store_result_t;     -- the result
                        -- write signals
    -- write signals
                        write_req                       : in arp_store_wrrequest_t;             -- requesting a lookup or store
    write_req   : in  arp_store_wrrequest_t;  -- requesting a lookup or store
                        -- control and status signals
    -- control and status signals
                        clear_store                     : in std_logic;                                         -- erase all entries
    clear_store : in  std_logic;              -- erase all entries
                        entry_count                     : out unsigned(7 downto 0);              -- how many entries currently in store
    entry_count : out unsigned(7 downto 0);   -- how many entries currently in store
                        -- system signals
    -- system signals
                        clk                                     : in std_logic;
                        clk                                     : in std_logic;
                        reset                           : in  STD_LOGIC
    reset       : in  std_logic
                        );
                        );
end arp_STORE_br;
end arp_STORE_br;
 
 
architecture Behavioral of arp_STORE_br is
architecture Behavioral of arp_STORE_br is
 
 
        type st_state_t is (IDLE,PAUSE,SEARCH,FOUND,NOT_FOUND);
  type st_state_t is (IDLE, PAUSE, SEARCH, FOUND, NOT_FOUND);
 
 
        type ip_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(31 downto 0);
  type ip_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(31 downto 0);
        type mac_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(47 downto 0);
  type mac_ram_t is array (0 to MAX_ARP_ENTRIES-1) of std_logic_vector(47 downto 0);
        subtype addr_t is integer range 0 to MAX_ARP_ENTRIES;
  subtype addr_t is integer range 0 to MAX_ARP_ENTRIES;
 
 
        type count_mode_t is (RST,INCR,HOLD);
  type count_mode_t is (RST, INCR, HOLD);
 
 
        type mode_t is (MREAD,MWRITE);
  type mode_t is (MREAD, MWRITE);
 
 
        -- state variables
  -- state variables
        signal ip_ram                                   : ip_ram_t;                                                                             -- will be implemented as block ram
  signal ip_ram          : ip_ram_t;     -- will be implemented as block ram
        signal mac_ram                                  : mac_ram_t;                                                                    -- will be implemented as block ram     
  signal mac_ram         : mac_ram_t;    -- will be implemented as block ram     
        signal st_state                         : st_state_t;
  signal st_state        : st_state_t;
        signal next_write_addr          : addr_t;                                                                               -- where to make the next write
  signal next_write_addr : addr_t;       -- where to make the next write
        signal num_entries                      : addr_t;                                                                               -- number of entries in the store
  signal num_entries     : addr_t;       -- number of entries in the store
        signal next_read_addr           : addr_t;                                                                               -- next addr to read from
  signal next_read_addr  : addr_t;       -- next addr to read from
        signal entry_found                      : arp_entry_t;                                                                  -- entry found in search
  signal entry_found     : arp_entry_t;  -- entry found in search
        signal mode                                             : mode_t;                                                                               -- are we writing or reading?
  signal mode            : mode_t;       -- are we writing or reading?
        signal req_entry                                : arp_entry_t;                                                                  -- entry latched from req
  signal req_entry       : arp_entry_t;  -- entry latched from req
 
 
        -- busses
  -- busses
        signal next_st_state                    : st_state_t;
  signal next_st_state          : st_state_t;
        signal arp_entry_val                    : arp_entry_t;
  signal arp_entry_val          : arp_entry_t;
        signal mode_val                         : mode_t;
  signal mode_val               : mode_t;
        signal write_addr                               : addr_t;                                                                               -- actual write address to use
        signal write_addr                               : addr_t;                                                                               -- actual write address to use
 
  signal read_result_int        : arp_store_result_t;
 
 
        -- control signals
  -- control signals
        signal set_st_state             : std_logic;
  signal set_st_state        : std_logic;
        signal set_next_write_addr      : count_mode_t;
  signal set_next_write_addr : count_mode_t;
        signal set_num_entries          : count_mode_t;
  signal set_num_entries     : count_mode_t;
        signal set_next_read_addr       : count_mode_t;
  signal set_next_read_addr  : count_mode_t;
        signal write_ram                                : std_logic;
  signal write_ram           : std_logic;
        signal set_entry_found          : std_logic;
  signal set_entry_found     : std_logic;
        signal set_mode                         : std_logic;
  signal set_mode            : std_logic;
 
 
        function read_status(status : arp_store_rslt_t; signal mode : mode_t) return arp_store_rslt_t is
  function read_status(status : arp_store_rslt_t; signal mode : mode_t) return arp_store_rslt_t is
                variable ret : arp_store_rslt_t;
    variable ret : arp_store_rslt_t;
        begin
  begin
                case status is
    case status is
                        when IDLE =>
      when IDLE =>
                                ret := status;
        ret := status;
                        when others =>
      when others =>
                                if mode = MWRITE then
        if mode = MWRITE then
                                        ret := BUSY;
          ret := BUSY;
                                else
        else
                                        ret := status;
          ret := status;
                                end if;
        end if;
                end case;
    end case;
                return ret;
    return ret;
        end read_status;
  end read_status;
 
 
begin
begin
        combinatorial : process (
  combinatorial : process (
                -- input signals
    -- input signals
                read_req, write_req, clear_store, reset,
    read_req, write_req, clear_store, reset,
                -- state variables
    -- state variables
                ip_ram, mac_ram, st_state, next_write_addr, num_entries,
    ip_ram, mac_ram, st_state, next_write_addr, num_entries,
                next_read_addr, entry_found, mode, req_entry,
    next_read_addr, entry_found, mode, req_entry,
                -- busses
                -- busses
                next_st_state, arp_entry_val, mode_val, write_addr,
    next_st_state, arp_entry_val, mode_val, write_addr, read_result_int,
                -- control signals
                -- control signals
                set_st_state, set_next_write_addr, set_num_entries, set_next_read_addr, set_entry_found,
    set_st_state, set_next_write_addr, set_num_entries, set_next_read_addr, set_entry_found,
                write_ram, set_mode
    write_ram, set_mode
                )
    )
        begin
  begin
                -- set output followers
                -- set output followers
                read_result.status <= IDLE;
    read_result_int.status <= IDLE;
                read_result.entry <= entry_found;
    read_result_int.entry  <= entry_found;
                entry_count <= to_unsigned(num_entries,8);
                entry_count <= to_unsigned(num_entries,8);
 
 
                -- set bus defaults
    -- set bus defaults
                next_st_state <= IDLE;
    next_st_state <= IDLE;
                mode_val <= MREAD;
    mode_val      <= MREAD;
                write_addr <= next_write_addr;
    write_addr    <= next_write_addr;
 
 
                -- set signal defaults
    -- set signal defaults
                set_st_state <= '0';
    set_st_state        <= '0';
                set_next_write_addr <= HOLD;
    set_next_write_addr <= HOLD;
                set_num_entries <= HOLD;
    set_num_entries     <= HOLD;
                set_next_read_addr <= HOLD;
    set_next_read_addr  <= HOLD;
                write_ram <= '0';
    write_ram           <= '0';
                set_entry_found <= '0';
    set_entry_found     <= '0';
                set_mode <= '0';
    set_mode            <= '0';
 
 
                -- STORE FSM
    -- STORE FSM
                case st_state is
    case st_state is
                        when IDLE =>
      when IDLE =>
                                if write_req.req = '1' then
        if write_req.req = '1' then
                                        -- need to search to see if this IP already there
                                        -- need to search to see if this IP already there
                                        set_next_read_addr <= RST;                      -- start lookup from beginning
          set_next_read_addr <= RST;    -- start lookup from beginning
                                        mode_val <= MWRITE;
          mode_val           <= MWRITE;
                                        set_mode <= '1';
          set_mode           <= '1';
                                        next_st_state <= PAUSE;
          next_st_state      <= PAUSE;
                                        set_st_state <= '1';
          set_st_state       <= '1';
                                elsif read_req.req = '1' then
        elsif read_req.req = '1' then
                                        set_next_read_addr <= RST;                      -- start lookup from beginning
          set_next_read_addr <= RST;    -- start lookup from beginning
                                        mode_val <= MREAD;
          mode_val           <= MREAD;
                                        set_mode <= '1';
          set_mode           <= '1';
                                        next_st_state <= PAUSE;
          next_st_state      <= PAUSE;
                                        set_st_state <= '1';
          set_st_state       <= '1';
                                end if;
        end if;
 
 
                        when PAUSE =>
      when PAUSE =>
                                -- wait until read addr is latched and we get first data out of the ram
                                -- wait until read addr is latched and we get first data out of the ram
                                read_result.status <= read_status(BUSY,mode);
        read_result_int.status <= read_status(BUSY, mode);
                                set_next_read_addr <= INCR;
                                set_next_read_addr <= INCR;
                                next_st_state <= SEARCH;
        next_st_state      <= SEARCH;
                                set_st_state <= '1';
        set_st_state       <= '1';
 
 
                        when SEARCH =>
                        when SEARCH =>
                                read_result.status <= read_status(SEARCHING,mode);
        read_result_int.status                                    <= read_status(SEARCHING, mode);
                                -- check if have a match at this entry
                                -- check if have a match at this entry
                                if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
        if req_entry.ip = arp_entry_val.ip and next_read_addr <= num_entries then
                                        -- found it
                                        -- found it
                                        set_entry_found <= '1';
          set_entry_found <= '1';
                                        next_st_state <= FOUND;
          next_st_state   <= FOUND;
                                        set_st_state <= '1';
          set_st_state    <= '1';
                                elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
        elsif next_read_addr > num_entries or next_read_addr >= MAX_ARP_ENTRIES then
                                        -- reached end of entry table
                                        -- reached end of entry table
                                        read_result.status <= read_status(NOT_FOUND,mode);
          read_result_int.status <= read_status(NOT_FOUND, mode);
                                        next_st_state <= NOT_FOUND;
                                        next_st_state <= NOT_FOUND;
                                        set_st_state <= '1';
          set_st_state       <= '1';
                                else
        else
                                        -- no match at this entry , go to next
                                        -- no match at this entry , go to next
                                        set_next_read_addr <= INCR;
          set_next_read_addr <= INCR;
                                end if;
        end if;
 
 
                        when FOUND =>
                        when FOUND =>
                                read_result.status <= read_status(FOUND,mode);
        read_result_int.status <= read_status(FOUND, mode);
                                if mode = MWRITE then
                                if mode = MWRITE then
                                        write_addr <= next_read_addr - 1;
          write_addr    <= next_read_addr - 1;
                                        write_ram <= '1';
          write_ram     <= '1';
                                        next_st_state <= IDLE;
          next_st_state <= IDLE;
                                        set_st_state <= '1';
          set_st_state  <= '1';
                                elsif read_req.req = '0' then                    -- wait in this state until request de-asserted
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
                                        next_st_state <= IDLE;
          next_st_state <= IDLE;
                                        set_st_state <= '1';
          set_st_state  <= '1';
                                end if;
        end if;
 
 
                        when NOT_FOUND =>
                        when NOT_FOUND =>
                                read_result.status <= read_status(NOT_FOUND,mode);
        read_result_int.status <= read_status(NOT_FOUND, mode);
                                if mode = MWRITE then
                                if mode = MWRITE then
                                        -- need to write into the next free slot
                                        -- need to write into the next free slot
                                        write_addr <= next_write_addr;
          write_addr          <= next_write_addr;
                                        write_ram <= '1';
          write_ram           <= '1';
                                        set_next_write_addr <= INCR;
          set_next_write_addr <= INCR;
                                        if num_entries < MAX_ARP_ENTRIES then
          if num_entries < MAX_ARP_ENTRIES then
                                                -- if not full, count another entry (if full, it just wraps)
                                        -- if not full, count another entry (if full, it just wraps)
                                                set_num_entries <= INCR;
            set_num_entries <= INCR;
                                        end if;
          end if;
                                        next_st_state <= IDLE;
          next_st_state <= IDLE;
                                        set_st_state <= '1';
          set_st_state  <= '1';
                                elsif read_req.req = '0' then                    -- wait in this state until request de-asserted
        elsif read_req.req = '0' then   -- wait in this state until request de-asserted
                                        next_st_state <= IDLE;
          next_st_state <= IDLE;
                                        set_st_state <= '1';
          set_st_state  <= '1';
                                end if;
        end if;
 
 
                end case;
    end case;
        end process;
  end process;
 
 
        sequential : process (clk)
  sequential : process (clk)
        begin
  begin
                if rising_edge(clk) then
    if rising_edge(clk) then
                        -- ram processing
      -- ram processing
                        if write_ram = '1' then
      if write_ram = '1' then
                                ip_ram(write_addr) <= req_entry.ip;
        ip_ram(write_addr)  <= req_entry.ip;
                                mac_ram(write_addr) <= req_entry.mac;
        mac_ram(write_addr) <= req_entry.mac;
                        end if;
      end if;
                        if next_read_addr < MAX_ARP_ENTRIES then
      if next_read_addr < MAX_ARP_ENTRIES then
                                arp_entry_val.ip <= ip_ram(next_read_addr);
        arp_entry_val.ip  <= ip_ram(next_read_addr);
                                arp_entry_val.mac <= mac_ram(next_read_addr);
        arp_entry_val.mac <= mac_ram(next_read_addr);
                        else
      else
                                arp_entry_val.ip <= (others => '0');
        arp_entry_val.ip  <= (others => '0');
                                arp_entry_val.mac <= (others => '0');
        arp_entry_val.mac <= (others => '0');
                        end if;
      end if;
 
 
 
      read_result <= read_result_int;
 
 
                        if reset = '1' or clear_store = '1' then
                        if reset = '1' or clear_store = '1' then
                                -- reset state variables
        -- reset state variables
                                st_state <= IDLE;
        st_state        <= IDLE;
                                next_write_addr <= 0;
        next_write_addr <= 0;
                                num_entries <= 0;
        num_entries     <= 0;
                                next_read_addr <= 0;
        next_read_addr  <= 0;
                                entry_found.ip <= (others => '0');
        entry_found.ip  <= (others => '0');
                                entry_found.mac <= (others => '0');
        entry_found.mac <= (others => '0');
                                req_entry.ip <= (others => '0');
        req_entry.ip    <= (others => '0');
                                req_entry.mac <= (others => '0');
        req_entry.mac   <= (others => '0');
                                mode <= MREAD;
        mode            <= MREAD;
 
 
                        else
      else
                                -- Next req_state processing
        -- Next req_state processing
                                if set_st_state = '1' then
        if set_st_state = '1' then
                                        st_state <= next_st_state;
          st_state <= next_st_state;
                                else
        else
                                        st_state <= st_state;
          st_state <= st_state;
                                end if;
        end if;
 
 
                                -- mode setting and write request latching
        -- mode setting and write request latching
                                if set_mode = '1' then
        if set_mode = '1' then
                                        mode <= mode_val;
          mode <= mode_val;
                                        if mode_val = MWRITE then
          if mode_val = MWRITE then
                                                req_entry <= write_req.entry;
            req_entry <= write_req.entry;
                                        else
          else
                                                req_entry.ip <= read_req.ip;
            req_entry.ip  <= read_req.ip;
                                                req_entry.mac <= (others => '0');
            req_entry.mac <= (others => '0');
                                        end if;
          end if;
                                else
        else
                                        mode <= mode;
          mode      <= mode;
                                        req_entry <= req_entry;
          req_entry <= req_entry;
                                end if;
        end if;
 
 
                                -- latch entry found
        -- latch entry found
                                if set_entry_found = '1' then
        if set_entry_found = '1' then
                                        entry_found <= arp_entry_val;
          entry_found <= arp_entry_val;
                                else
        else
                                        entry_found <= entry_found;
          entry_found <= entry_found;
                                end if;
        end if;
 
 
                                -- next_write_addr counts and wraps
        -- next_write_addr counts and wraps
                                case set_next_write_addr is
        case set_next_write_addr is
                                        when HOLD => next_write_addr <= next_write_addr;
          when HOLD => next_write_addr                                             <= next_write_addr;
                                        when RST => next_write_addr <= 0;
          when RST  => next_write_addr                                             <= 0;
                                        when INCR => if next_write_addr < MAX_ARP_ENTRIES-1 then next_write_addr <= next_write_addr + 1;  else next_write_addr <= 0; end if;
          when INCR => if next_write_addr < MAX_ARP_ENTRIES-1 then next_write_addr <= next_write_addr + 1; else next_write_addr <= 0; end if;
                                end case;
        end case;
 
 
                                -- num_entries counts and holds at max
        -- num_entries counts and holds at max
                                case set_num_entries is
        case set_num_entries is
                                        when HOLD => num_entries <= num_entries;
          when HOLD => num_entries                                           <= num_entries;
                                        when RST => num_entries <= 0;
          when RST  => num_entries                                           <= 0;
                                        when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
          when INCR => if next_write_addr < MAX_ARP_ENTRIES then num_entries <= num_entries + 1; else num_entries <= num_entries; end if;
                                end case;
        end case;
 
 
                                -- next_read_addr counts and wraps
        -- next_read_addr counts and wraps
                                case set_next_read_addr is
        case set_next_read_addr is
                                        when HOLD => next_read_addr <= next_read_addr;
          when HOLD => next_read_addr                                          <= next_read_addr;
                                        when RST => next_read_addr <= 0;
          when RST  => next_read_addr                                          <= 0;
                                        when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
          when INCR => if next_read_addr < MAX_ARP_ENTRIES then next_read_addr <= next_read_addr + 1; else next_read_addr <= 0; end if;
                                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.