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

Subversion Repositories esoc

[/] [esoc/] [trunk/] [Sources/] [logixa/] [esoc_port_processor_outbound.vhd] - Rev 42

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_outbound
-- Last modified : Mon Apr 14 12:49:34 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_outbound is
  generic(
    esoc_port_nr : integer := 0);
  port(
    clk_data             : in     std_logic;
    data                 : in     std_logic_vector(63 downto 0);
    data_eof             : in     std_logic;
    data_gnt_rd          : in     std_logic;
    data_port_sel        : in     std_logic_vector(esoc_port_count-1 downto 0);
    data_sof             : in     std_logic;
    outbound_data        : out    std_logic_vector(63 downto 0);
    outbound_data_full   : in     std_logic;
    outbound_data_write  : out    std_logic;
    outbound_done_cnt    : out    std_logic;
    outbound_drop_cnt    : out    std_logic;
    outbound_info        : out    std_logic_vector(15 downto 0);
    outbound_info_write  : out    std_logic;
    outbound_vlan_id     : out    STD_LOGIC_VECTOR(11 downto 0);
    outbound_vlan_member : in     STD_LOGIC_VECTOR(0 downto 0);
    reset                : in     std_logic);
end entity esoc_port_processor_outbound;
 
--------------------------------------------------------------------------------
-- Object        : Architecture work.esoc_port_processor_outbound.esoc_port_processor_outbound
-- Last modified : Mon Apr 14 12:49:34 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_processor_outbound of esoc_port_processor_outbound is
 
type   data_transfer_states is (idle, request, transfer);
signal data_transfer_state: data_transfer_states;
 
signal data_i             : std_logic_vector(data'high downto 0);
signal data_sof_i         : std_logic;
signal data_eof_i         : std_logic;
signal data_port_sel_i    : std_logic_vector(data_port_sel'high downto 0);
 
signal outbound_info_length: integer range 2**esoc_outbound_info_length_size-1 downto 0;
signal outbound_info_counter: integer range 2**esoc_outbound_info_length_size-1 downto 0;
 
signal outbound_data_write_i: std_logic;
 
signal outbound_vlan_member_check: std_logic;
 
begin
 
-- control the data bus when bus request is granted by arbiter for read access
data_i          <= data             when data_gnt_rd = '1'  else (others => '0');
data_sof_i      <= data_sof         when data_gnt_rd = '1'  else '0';
data_eof_i      <= data_eof         when data_gnt_rd = '1'  else '0';
data_port_sel_i <= data_port_sel    when data_gnt_rd = '1'  else (others => '0');
 
--=============================================================================================================
-- Process		  : control the data bus and drive the outbound fifo's 
-- Description	: 
--=============================================================================================================    
dbus: process(clk_data, reset)
      begin
        if reset = '1' then
          outbound_data         <= (others => '0');
          outbound_data_write_i <= '0';
 
          outbound_info         <= (others => '0');
          outbound_info_write   <= '0';
          outbound_info_length  <= 0; 
          outbound_info_counter <= 0;
 
          outbound_vlan_id      <= (others => '0');
          outbound_vlan_member_check <= '0';
 
          outbound_done_cnt     <= '0';  
          outbound_drop_cnt     <= '0';
 
        elsif clk_data'event and clk_data = '1' then
          -- reset one clock active signals
          outbound_info_write   <= '0';
          outbound_data_write_i <= '0';
 
          outbound_done_cnt     <= '0';
          outbound_drop_cnt     <= '0';
 
          -- define unused bits to avoid inferred latch warning during analysis & synthesis
          outbound_info(esoc_outbound_info_unused3_flag downto esoc_outbound_info_unused2_flag) <= (others => '0');
 
          case data_transfer_state is
            when idle     =>  -- store packet info (VID, LENGTH) when port is selected and SOF is asserted
                              if data_port_sel_i(esoc_port_nr) = '1' and data_sof_i = '1' then
                                -- store packet if there is still space in the FIFO else increment counters
                                if outbound_data_full = '0' then
                                  -- get length of packet
                                  outbound_info_length        <= to_integer(unsigned(data_i(esoc_dbus_packet_info_length + esoc_dbus_packet_info_length_size-1 downto esoc_dbus_packet_info_length)));
 
                                  -- get VLAN ID of packet and check whether this port is member of the VLAN or not
                                  outbound_vlan_id            <= data_i(esoc_dbus_packet_info_vlan_tci+11 downto esoc_dbus_packet_info_vlan_tci);
                                  outbound_vlan_member_check  <= '0';
                                  outbound_info_counter       <= 0;
                                  outbound_info(esoc_outbound_info_vlan_flag) <= data_i(esoc_dbus_packet_info_vlan_flag);
                                  data_transfer_state         <= transfer;
 
                                else
                                  outbound_drop_cnt     <= '1';
                                end if;
                              end if;
 
            when transfer =>  -- if outbound data fifo is full or port is selected but not member of VLAN -> drop packet, drop packet is done 
                              -- in the esoc_mal_outbound entity, an error and the amount of bytes yet stored are set here and forwarded to that 
                              -- entity. Note: a part of the packet is yet stored, so calculate the number of stored bytes and do not use only
                              -- the packet length that is sent by the source.
                              if outbound_data_full = '1' or (outbound_vlan_member = "0" and outbound_vlan_member_check = '1') then
                                outbound_info(esoc_outbound_info_length + esoc_outbound_info_length_size -1 downto esoc_outbound_info_length) <= std_logic_vector(to_unsigned(outbound_info_counter-8,esoc_outbound_info_length_size));
                                outbound_info(esoc_outbound_info_error_flag) <= '1';
                                outbound_info_write   <= '1';
                                outbound_drop_cnt     <= '1';
                                data_transfer_state   <= idle;
 
                              -- no error, write data into data FIFO, update outbound_info_counter, this outbound_info_counter is used to 
                              -- calculate stored bytes when packet storage is aborted before packet is complete due to an error (data FIFO 
                              -- full or port not member of VLAN)
                              else
                                outbound_data <= data_i;
                                outbound_data_write_i <= '1';
                                outbound_info_counter <= outbound_info_counter + 8;
 
                                -- end of packet, store length and flags in info FIFO
                                if data_eof_i = '1' then
                                  outbound_info(esoc_outbound_info_length + esoc_outbound_info_length_size -1 downto esoc_outbound_info_length) <= std_logic_vector(to_unsigned(outbound_info_length,esoc_outbound_info_length_size));
                                  outbound_info(esoc_outbound_info_error_flag) <= '0';
                                  outbound_info_write   <= '1';
                                  outbound_done_cnt     <= '1';
                                  data_transfer_state   <= idle;
                                end if;
                              end if;
 
                              -- next time vlan membership is known, memory requires additional clock cycle, enable checking!
                              outbound_vlan_member_check <= '1'; 
 
            when others   =>  data_transfer_state <= idle;
          end case;
        end if;
      end process;
 
      -- write when FIFO is not full!
      outbound_data_write <= outbound_data_write_i and not(outbound_data_full);
 
end architecture esoc_port_processor_outbound ; -- of esoc_port_processor_outbound
 
 

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.