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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_search_engine_da.vhd] - Rev 46

Go to most recent revision | Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
----                                                                        ----
---- Ethernet Switch on Configurable Logic IP Core                          ----
----                                                                        ----
---- This file is part of the ESoCL project                                 ----
---- http://www.opencores.org/cores/esoc/                                   ----
----                                                                        ----
---- Description: see design description ESoCL_dd_71022001.pdf              ----
----                                                                        ----
---- To Do: see roadmap description ESoCL_dd_71022001.pdf                   ----
----        and/or release bulleting ESoCL_rb_71022001.pdf                  ----
----                                                                        ----
---- Author(s): L.Maarsen                                                   ----
---- Bert Maarsen, lmaarsen@opencores.org                                   ----
----                                                                        ----
--------------------------------------------------------------------------------
----                                                                        ----
---- Copyright (C) 2009 Authors and OPENCORES.ORG                           ----
----                                                                        ----
---- This source file may be used and distributed without                   ----
---- restriction provided that this copyright statement is not              ----
---- removed from the file and that any derivative work contains            ----
---- the original copyright notice and the associated disclaimer.           ----
----                                                                        ----
---- This source file is free software; you can redistribute it             ----
---- and/or modify it under the terms of the GNU Lesser General             ----
---- Public License as published by the Free Software Foundation;           ----
---- either version 2.1 of the License, or (at your option) any             ----
---- later version.                                                         ----
----                                                                        ----
---- This source is distributed in the hope that it will be                 ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied             ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR                ----
---- PURPOSE. See the GNU Lesser General Public License for more            ----
---- details.                                                               ----
----                                                                        ----
---- You should have received a copy of the GNU Lesser General              ----
---- Public License along with this source; if not, download it             ----
---- from http://www.opencores.org/lgpl.shtml                               ----
----                                                                        ----
--------------------------------------------------------------------------------
-- Object        : Entity work.esoc_search_engine_da
-- Last modified : Mon Apr 14 12:50:04 2014.
--------------------------------------------------------------------------------
 
 
 
library ieee, std, work;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
use work.package_hash10_24b.all;
use work.package_esoc_configuration.all;
 
entity esoc_search_engine_da is
  port(
    clk_search           : in     std_logic;
    reset                : in     std_logic;
    search_eof           : in     std_logic;
    search_key           : in     std_logic_vector(63 downto 0);
    search_port_stalled  : in     std_logic_vector(esoc_port_count-1 downto 0);
    search_result        : out    std_logic_vector(esoc_port_count-1 downto 0);
    search_result_av     : out    std_logic;
    search_sof           : in     std_logic;
    search_table_address : out    STD_LOGIC_VECTOR(12 downto 0);
    search_table_data    : out    STD_LOGIC_VECTOR(79 downto 0);
    search_table_q       : in     STD_LOGIC_VECTOR(79 downto 0);
    search_table_rden    : out    STD_LOGIC;
    search_table_wren    : out    STD_LOGIC);
end entity esoc_search_engine_da;
 
--------------------------------------------------------------------------------
-- Object        : Architecture work.esoc_search_engine_da.esoc_search_engine_da
-- Last modified : Mon Apr 14 12:50:04 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_search_engine_da of esoc_search_engine_da is
 
type   search_states is (idle, wait_hash, compare);
signal search_state: search_states;
 
signal search_table_address_i: std_logic_vector(search_table_address'high downto 0);
signal search_result_i: std_logic_vector(esoc_port_count-1 downto 0);
signal search_port_stalled_sync : std_logic_vector(2*esoc_port_count-1 downto 0);
 
signal search_table_coll_cnt: integer range esoc_search_engine_col_depth downto 0 ;
signal search_hash_delay_cnt: integer range esoc_search_engine_hash_delay downto 0;
 
signal search_key_i: std_logic_vector(59 downto 0);
 
begin
 
--=============================================================================================================
-- Process		  : proces search requests for destination MAC address
-- Description	: 
--=============================================================================================================    
search_da:  process(clk_search, reset)
            begin
              if reset = '1' then
                search_table_coll_cnt <= 0;
                search_hash_delay_cnt <= 0;
 
                search_key_i           <= (others => '0');
                search_table_address_i <= (others => '0');
                search_table_rden      <= '0';             
                search_result_i        <= (others => '0');
                search_result_av       <= '0';
 
                search_port_stalled_sync <= (others => '0');
 
              elsif clk_search'event and clk_search = '1' then
                -- clear one-clock active signals
                search_result_av  <= '0';
                search_table_rden <= '0';             
 
                -- synchronise port stalled information with this clock
                search_port_stalled_sync(esoc_port_count-1 downto 0)                 <= search_port_stalled_sync(2*esoc_port_count-1 downto esoc_port_count);
                search_port_stalled_sync(2*esoc_port_count-1 downto esoc_port_count) <= search_port_stalled;
 
                -- process new search requests 
                case search_state is
                  when idle       =>  -- wait for start of frame, first data is VID + DA, calculate hash pointer (additional delay may be required after synthesis, due to large XOR tree)
                                      if search_sof = '1' then
 
                                        -- send result (all ports) immediately if destination address is a BC or MC, if UC start search action.
                                        -- the BC/MC detection is part of the search engine and not part of port because you still need to learn the SA!
                                        if search_key(esoc_search_bus_mac+esoc_ethernet_uc_mc_bc) = '0'then
                                          search_key_i(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) <= search_key(esoc_search_bus_vlan+11 downto esoc_search_bus_vlan);
                                          search_key_i(esoc_search_entry_mac+47 downto esoc_search_entry_mac)   <= search_key(esoc_search_bus_mac+47 downto esoc_search_bus_mac);
                                          search_table_address_i                                                <= CALC_HASH10_24b(search_key(esoc_search_bus_mac+23 downto esoc_search_bus_mac)) & "000";
                                          search_table_rden                                                     <= '1';
                                          search_table_coll_cnt                                                 <= 0;
 
                                          -- use delay mechanism to give the hash function - large xor tree - time to provide stable result
                                          -- depends on target speed, use target timing analysis result to optimze this delay! At least one clock
                                          -- delay due to RAM latency
                                          search_hash_delay_cnt <= esoc_search_engine_hash_delay-1;
                                          search_state          <= wait_hash;
 
                                        else
                                          search_result_av  <= '1';
                                          search_result_i   <=  (others => '1'); 
                                        end if;
                                      end if;
 
                  when wait_hash  =>  -- hash result stable?  
                                      if search_hash_delay_cnt = 0 then
                                        search_table_address_i  <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length));
                                        search_state <= compare;
                                      else
                                        search_hash_delay_cnt <= search_hash_delay_cnt-1;
                                      end if;
 
                                      search_table_rden <= '1';
 
                  when compare  => -- there is a hit on DA and VID
                                   if search_table_q(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) = search_key_i(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) and
                                     search_table_q(esoc_search_entry_mac+47 downto esoc_search_entry_mac) = search_key_i(esoc_search_entry_mac+47 downto esoc_search_entry_mac) then
 
                                    -- entry valid, provide destination information else return broadcast as result
                                    if search_table_q(esoc_search_entry_valid) = '1' then
                                      search_result_av  <= '1';
                                      search_result_i   <= search_table_q(esoc_search_entry_destination+esoc_port_count-1 downto esoc_search_entry_destination);
                                      search_state      <= idle;
                                    else
                                      search_result_av  <= '1';
                                      search_result_i   <= (others => '1');
                                      search_state      <= idle;
                                    end if;
 
                                  -- there is no hit on DA and VID
                                  else
                                    -- End of collision buffer reached, no increment address for next entry else return result
                                    if search_table_coll_cnt < esoc_search_engine_col_depth then    
                                      search_table_coll_cnt  <= search_table_coll_cnt + 1;      
                                      search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))+1,search_table_address_i'length)); 
                                      search_table_rden      <= '1';
 
                                    -- end of collission buffer, no hit, return broadcast as result
                                    else
                                      search_result_av  <= '1';
                                      search_result_i   <=  (others => '1');
                                      search_state      <= idle;
                                    end if;
                                  end if;
 
                  when others =>  search_state <= idle;
                end case;
              end if;
            end process;
 
            search_table_wren    <= '0';    
            search_table_data    <= (others => '0');
            search_table_address <= search_table_address_i;
 
            -- provide search result, but use port stall info to avoid use of data bus to stalled ports, waste of bus usage
            search_result <= search_result_i and not(search_port_stalled_sync(esoc_port_count-1 downto 0));
 
end architecture esoc_search_engine_da ; -- of esoc_search_engine_da
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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