URL
https://opencores.org/ocsvn/esoc/esoc/trunk
Subversion Repositories esoc
[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_search_engine_da.vhd] - Rev 53
Compare with Previous | Blame | View Log
-------------------------------------------------------------------------------- -- -- This VHDL file was generated by EASE/HDL 7.4 Revision 4 from HDL Works B.V. -- -- Ease library : work -- HDL library : work -- Host name : S212065 -- User name : df768 -- Time stamp : Tue Aug 19 08:05:18 2014 -- -- Designed by : L.Maarsen -- Company : LogiXA -- Project info : eSoC -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- 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