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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_port_processor_inbound.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_port_processor_inbound
-- Last modified : Mon Apr 14 12:49:30 2014.
--------------------------------------------------------------------------------
 
 
 
library ieee, std, work;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
use work.package_esoc_configuration.all;
 
entity esoc_port_processor_inbound is
  generic(
    esoc_port_nr : integer := 0);
  port(
    clk_data           : in     std_logic;
    data               : inout  std_logic_vector(63 downto 0);
    data_eof           : inout  std_logic;
    data_gnt_wr        : in     std_logic;
    data_port_sel      : inout  std_logic_vector(esoc_port_count-1 downto 0);
    data_req           : out    std_logic;
    data_sof           : inout  std_logic;
    inbound_data       : in     std_logic_vector(63 downto 0);
    inbound_data_full  : in     std_logic;
    inbound_data_read  : out    std_logic;
    inbound_done_cnt   : out    std_logic;
    inbound_drop_cnt   : out    std_logic;
    inbound_info       : in     std_logic_vector(31 downto 0);
    inbound_info_empty : in     std_logic;
    inbound_info_read  : out    std_logic;
    reset              : in     std_logic;
    search_data        : in     STD_LOGIC_VECTOR(15 downto 0);
    search_empty       : in     STD_LOGIC;
    search_read        : out    STD_LOGIC);
end entity esoc_port_processor_inbound;
 
--------------------------------------------------------------------------------
-- Object        : Architecture work.esoc_port_processor_inbound.esoc_port_processor_inbound
-- Last modified : Mon Apr 14 12:49:30 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_processor_inbound of esoc_port_processor_inbound is
 
type   data_transfer_states is (idle, granted, transfer, wait_gnt, wait_no_gnt);
signal data_transfer_state: data_transfer_states;
 
signal data_o             : std_logic_vector(data'high downto 0);
signal data_sof_o         : std_logic;
signal data_eof_o         : std_logic;
signal data_port_sel_o    : std_logic_vector(data_port_sel'high downto 0);
 
signal clear_data_req     : std_logic;
 
signal inbound_drop       : std_logic;
signal inbound_data_full_i: std_logic;
signal inbound_data_read_o: std_logic;
signal inbound_info_length: integer range 2**esoc_inbound_info_length_size-1 downto 0;
 
begin
 
-- control the data bus when bus request is granted by arbiter for write access
data            <= data_o           when data_gnt_wr = '1' else (others => 'Z');
data_sof        <= data_sof_o       when data_gnt_wr = '1' else 'Z';
data_eof        <= data_eof_o       when data_gnt_wr = '1' else 'Z';
data_port_sel   <= data_port_sel_o  when data_gnt_wr = '1' else (others => 'Z');
 
--=============================================================================================================
-- Process		  : read the inbound fifo's and control the data bus
-- Description	: 
--=============================================================================================================    
dbus:      process(clk_data, reset)
            begin
              if reset = '1' then
                data_o            <= (others => '0');
                data_sof_o        <= '0';
                data_eof_o        <= '0';
                data_port_sel_o   <= (others => '0');
                data_req          <= '0';
                clear_data_req    <= '0';
 
                inbound_info_read   <= '0';
                inbound_data_read_o <= '0';
                search_read         <= '0';
 
                inbound_info_length <= 0;
                inbound_done_cnt    <= '0';
                inbound_drop_cnt    <= '0';
                inbound_drop        <= '0';
                inbound_data_full_i <= '0';
 
              elsif clk_data'event and clk_data = '1' then
                -- reset one clock active signals
                inbound_info_read   <= '0';
                search_read         <= '0';
                data_eof_o          <= '0';
                clear_data_req      <= '0';
                inbound_done_cnt    <= '0';
                inbound_drop_cnt    <= '0';
 
                -- detect rising edges of the inbound_data_full input and count!
                inbound_data_full_i <= inbound_data_full;
 
                if inbound_data_full_i = '0' and inbound_data_full = '1'  then
                  inbound_drop_cnt <= '1';
                end if;
 
                -- request for data bus as long as there are new packets ready to transfer with a destination, de-assert one clock between
                -- two request to acknowledge the grant to the arbiter.
                if inbound_info_empty = '0' and search_empty = '0' and to_integer(unsigned(search_data)) /=0 and clear_data_req = '0' then
                  data_req <= '1';
                elsif clear_data_req = '1' then
                  data_req <= '0';
                end if;
 
                case data_transfer_state is
                  when idle     =>      -- new info and search data present? Ready to transfer packet, prepare and wait for bus grant!
                                        if inbound_info_empty = '0' and search_empty = '0' then
                                          -- INFO FIFO -> store packet length from fifo for further processing
                                          inbound_info_length <= to_integer(unsigned(inbound_info(esoc_inbound_info_length+esoc_inbound_info_length_size-1 downto esoc_inbound_info_length)));
 
                                          -- INFO FIFO -> drive the data bus signals with packet info like eSOC source port, length. VLAN and flags
                                          data_o(esoc_dbus_packet_info_sport+3 downto esoc_dbus_packet_info_sport)                                     <= std_logic_vector(to_unsigned(esoc_port_nr,4));
                                          data_o(esoc_dbus_packet_info_length+esoc_dbus_packet_info_length_size-1 downto esoc_dbus_packet_info_length) <= inbound_info(esoc_inbound_info_length+esoc_inbound_info_length_size-1 downto esoc_inbound_info_length);
                                          data_o(esoc_dbus_packet_info_unused3_flag downto esoc_dbus_packet_info_vlan_flag)                            <= inbound_info(esoc_inbound_info_unused3_flag downto esoc_inbound_info_vlan_flag);
                                          data_o(esoc_dbus_packet_info_vlan_tci+15 downto esoc_dbus_packet_info_vlan_tci)                              <= inbound_info(esoc_inbound_info_vlan_tci+15 downto esoc_inbound_info_vlan_tci);
 
                                          -- SEARCH FIFO -> drive data bus port select signals with data from SEARCH FIFO, only valid destinations will be enabled
                                          data_port_sel_o <= search_data(data_port_sel_o'high downto 0);
 
                                          -- DATA FIFO -> start acknowledging data from the DATA FIFO, real acknowledge depends on outcome of if-then-else statement below!
                                          -- No drop -> real acknowledges when bus grant is detectt, drop -> acknowledges immediately
                                          inbound_data_read_o <= '1'; 
 
                                          -- if there are no ports selected then packet must be dropped else request data bus and acknowledge data from search and info FIFO
                                          if to_integer(unsigned(search_data)) = 0 then
                                            inbound_drop        <= '1';
                                            search_read         <= '1';
                                            inbound_info_read   <= '1';
                                            data_transfer_state <= transfer;
                                          else
                                            data_sof_o <= '1';
                                            inbound_drop <= '0';
                                            data_transfer_state <= wait_gnt;
                                          end if;
                                        end if;
 
                  when wait_gnt =>      -- Wait for bus grant from arbiter before acknowledge data from the INFO and SEARCH FIFO when granted
                                        -- If data_gnt_wr is sampled high the first word is already transferred, remove SOF, provide next word.
                                        if data_gnt_wr = '1' then
                                          -- Bus grant received, clear request and acknowledge data from search and info FIFO
                                          clear_data_req      <= '1';
                                          search_read         <= '1';
                                          inbound_info_read   <= '1';
 
                                          -- First word (packet info) send, remove Start of Frame and provide the first data of packet
                                          data_sof_o          <= '0';
                                          data_o              <= inbound_data;
                                          inbound_info_length <= inbound_info_length - 8;
                                          data_transfer_state <= transfer;
                                        end if;
 
                  when transfer     =>  -- Keep on reading data FIFO until last word is read, terminate bus (End of Frame) if the packet isn't dropped
                                        if inbound_info_length > 8 then
                                          inbound_info_length <= inbound_info_length - 8;
                                          data_o <= inbound_data;
 
                                        else
                                          -- Provide last data, stop accessing data FIFO
                                          data_o <= inbound_data;
                                          inbound_data_read_o <= '0';
 
                                          -- Termination of bus access and increment of drop counter depends on the drop status
                                          data_eof_o <= not(inbound_drop);
                                          inbound_drop_cnt <= inbound_drop;
                                          inbound_done_cnt <= not(inbound_drop);
                                          data_transfer_state <= wait_no_gnt;
                                        end if;
 
                  when  wait_no_gnt =>  -- Wait for no bus grant from bus arbiter , bus arbiter must proces the EOF of this module, wait one clock cycle before next packet can be processed.
                                        data_transfer_state <= idle;
 
                  when others       =>  data_transfer_state <= idle;
                end case;
              end if;
            end process;
 
            -- Read from fifo is under control of the data bus grant signal or drop decision
            inbound_data_read <= inbound_data_read_o when data_gnt_wr = '1' or inbound_drop = '1' else '0';
 
end architecture esoc_port_processor_inbound ; -- of esoc_port_processor_inbound
 
 

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.