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

Subversion Repositories esoc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /esoc
    from Rev 42 to Rev 43
    Reverse comparison

Rev 42 → Rev 43

/trunk/Sources/esoc_port_mal_clock.vhd
0,0 → 1,228
--------------------------------------------------------------------------------
---- ----
---- 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_mal_clock
-- Last modified : Mon Apr 14 12:49:01 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_mal_clock is
port(
clk_control : in STD_LOGIC;
clk_rgmii : out std_logic;
clk_rgmii_125m : in std_logic;
clk_rgmii_25m : in std_logic;
clk_rgmii_2m5 : in std_logic;
ena_10 : in STD_LOGIC;
eth_mode : in STD_LOGIC;
reset : in STD_LOGIC;
set_10 : out STD_LOGIC := '0'; -- '0'
set_1000 : out STD_LOGIC := '0');
end entity esoc_port_mal_clock;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_mal_clock.esoc_port_mal_clock
-- Last modified : Mon Apr 14 12:49:01 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_mal_clock of esoc_port_mal_clock is
 
constant clk_off: std_logic := '1';
constant clk_on: std_logic := '0';
 
signal clk125m: std_logic;
signal clk125_stop: std_logic;
signal clk125_stopped: std_logic;
signal clk125_stop_reg: std_logic_vector(1 downto 0);
signal clk125_stopped_reg: std_logic_vector(1 downto 0);
constant clk125m_reset: std_logic := clk_off;
 
signal clk25m: std_logic;
signal clk25_stop: std_logic;
signal clk25_stopped: std_logic;
signal clk25_stop_reg: std_logic_vector(1 downto 0);
signal clk25_stopped_reg: std_logic_vector(1 downto 0);
constant clk25m_reset: std_logic := clk_on;
 
signal clk2m5: std_logic;
signal clk2m5_stop: std_logic;
signal clk2m5_stopped: std_logic;
signal clk2m5_stop_reg: std_logic_vector(1 downto 0);
signal clk2m5_stopped_reg: std_logic_vector(1 downto 0);
constant clk2m5_reset: std_logic := clk_off;
 
type speeds is (none, s10m, s100m, s1000m);
signal speed_setting: speeds;
signal speed_current: speeds;
 
type switch_states is (idle, wait_for_stop);
signal switch_state: switch_states;
 
begin
 
-- Define unused speed control signals
set_10 <= '0';
set_1000 <= '0';
 
-- Create speed select signals
speed_setting <= s1000m when reset = '1' else
s10m when eth_mode = '0' and ena_10 = '1' else
s100m when eth_mode = '0' and ena_10 = '0' else
s1000m;
 
-- Clock control 125MHz
clk125ctl: process (clk_rgmii_125m, reset)
begin
if reset = '1' then
clk125_stop_reg <= (others => clk125m_reset);
-- synchronize stop input command with clock
elsif clk_rgmii_125m'event and clk_rgmii_125m = '1' then
clk125_stop_reg <= clk125_stop & clk125_stop_reg(clk125_stop_reg'high downto 1);
end if;
end process clk125ctl;
-- use synchronized stop commando to switch on/off clock, reply with stopped indication
clk125m <= clk_rgmii_125m when clk125_stop_reg(0) = '0' else '1';
clk125_stopped <= clk125_stop_reg(0);
-- Clock control 25MHz
clk25ctl: process (clk_rgmii_25m, reset)
begin
if reset = '1' then
clk25_stop_reg <= (others => clk25m_reset);
-- synchronize stop input command with clock
elsif clk_rgmii_25m'event and clk_rgmii_25m = '1' then
clk25_stop_reg <= clk25_stop & clk25_stop_reg(clk25_stop_reg'high downto 1);
end if;
end process clk25ctl;
 
-- use synchronized stop commando to switch on/off clock, reply with stopped indication
clk25m <= clk_rgmii_25m when clk25_stop_reg(0) = '0' else '1';
clk25_stopped <= clk25_stop_reg(0);
-- Clock control 2.5MHz
clk2m5ctl: process (clk_rgmii_2m5, reset)
begin
if reset = '1' then
clk2m5_stop_reg <= (others => clk2m5_reset);
-- synchronize stop input command with clock
elsif clk_rgmii_2m5'event and clk_rgmii_2m5 = '1' then
clk2m5_stop_reg <= clk2m5_stop & clk2m5_stop_reg(clk2m5_stop_reg'high downto 1);
end if;
end process clk2m5ctl;
 
-- use synchronized stop commando to switch on/off clock, reply with stopped indication
clk2m5 <= clk_rgmii_2m5 when clk2m5_stop_reg(0) = '0' else '1';
clk2m5_stopped <= clk2m5_stop_reg(0);
 
-- Clock switch
clkswitch: process (clk_control, reset)
begin
if reset = '1' then
clk125_stop <= clk125m_reset;
clk25_stop <= clk25m_reset;
clk2m5_stop <= clk2m5_reset;
clk125_stopped_reg <= (others => clk125m_reset);
clk25_stopped_reg <= (others => clk25m_reset);
clk2m5_stopped_reg <= (others => clk2m5_reset);
speed_current <= s1000m;
switch_state <= idle;
elsif clk_control'event and clk_control = '1' then
-- store speed setting for change detection
speed_current <= speed_setting;
-- synchronize stopped indication with clock
clk125_stopped_reg <= clk125_stopped & clk125_stopped_reg(clk125_stopped_reg'high downto 1);
clk25_stopped_reg <= clk25_stopped & clk25_stopped_reg(clk25_stopped_reg'high downto 1);
clk2m5_stopped_reg <= clk2m5_stopped & clk2m5_stopped_reg(clk2m5_stopped_reg'high downto 1);
 
case switch_state is
when idle => -- Send stop command to all clock source when setting changed
if speed_current /= speed_setting then
clk125_stop <= '1';
clk25_stop <= '1';
clk2m5_stop <= '1';
switch_state <= wait_for_stop;
end if;
when wait_for_stop => -- When setting is stable, wait for stopped indication of all clock sources
if speed_current /= speed_setting then
NULL;
elsif clk125_stopped_reg(0) = '1' and clk25_stopped_reg(0) = '1' and clk2m5_stopped_reg(0) = '1' then
-- enable only the required clock source by deasserting its stop input
if speed_setting = s10m then
clk2m5_stop <= '0';
elsif speed_setting = s100m then
clk25_stop <= '0';
elsif speed_setting = s1000m then
clk125_stop <= '0';
end if;
switch_state <= idle;
end if;
when others => switch_state <= idle;
end case;
end if;
end process clkswitch;
-- Drive RGMII interface clock, push/force clock onto clock network (if not done by tool)
clk_rgmii <= clk125m and clk25m and clk2m5;
--clk_rgmii <= clk_rgmii_125m;
end architecture esoc_port_mal_clock ; -- of esoc_port_mal_clock
/trunk/Sources/esoc_search_engine_sa_store.vhd
0,0 → 1,129
--------------------------------------------------------------------------------
---- ----
---- 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_sa_store
-- Last modified : Mon Apr 14 12:50:14 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_search_engine_sa_store 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_sa_overload_cnt : out std_logic;
search_sa_store_d : out STD_LOGIC_VECTOR(79 downto 0);
search_sa_store_full : in STD_LOGIC;
search_sa_store_wr : out STD_LOGIC;
search_sof : in std_logic);
end entity esoc_search_engine_sa_store;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_search_engine_sa_store.esoc_search_engine_sa_store
-- Last modified : Mon Apr 14 12:50:14 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_search_engine_sa_store of esoc_search_engine_sa_store is
 
type store_sa_states is (idle, wait_sa, wait_full);
signal store_sa_state: store_sa_states;
 
begin
 
--=============================================================================================================
-- Process : proces store SA address for further processing
-- Description :
--=============================================================================================================
store_sa: process(clk_search, reset)
begin
if reset = '1' then
search_sa_store_wr <= '0';
search_sa_store_d <= (others => '0');
search_sa_overload_cnt <= '0';
store_sa_state <= idle;
elsif clk_search'event and clk_search = '1' then
-- clear one-clock active signals
search_sa_store_wr <= '0';
search_sa_overload_cnt <= '0';
-- define unused bits to avoid inferred latch warning during analysis & synthesis
search_sa_store_d(esoc_search_entry_valid) <= '0';
search_sa_store_d(esoc_search_entry_update) <= '0';
search_sa_store_d(esoc_search_entry_unused2 downto esoc_search_entry_unused1) <= (others => '0');
case store_sa_state is
when idle => -- wait for start of frame, first data is VID + DA, skip DA, store VID, wait for SA and port number ... report when storage is full!
if search_sof = '1' then
if search_sa_store_full = '0' then
search_sa_store_d(esoc_search_entry_vlan+11 downto esoc_search_entry_vlan) <= search_key(esoc_search_bus_vlan+11 downto esoc_search_bus_vlan);
store_sa_state <= wait_sa;
else
search_sa_overload_cnt <= '1';
store_sa_state <= wait_full;
end if;
end if;
when wait_sa => -- get Source Port + SA and calculate hash pointer (additional delay may be required after synthesis, due to large XOR tree)
search_sa_store_d(esoc_search_entry_destination+15 downto esoc_search_entry_destination) <= search_key(esoc_search_bus_sport+15 downto esoc_search_bus_sport);
search_sa_store_d(esoc_search_entry_mac+47 downto esoc_search_entry_mac) <= search_key(esoc_search_bus_mac+47 downto esoc_search_bus_mac);
search_sa_store_wr <= '1';
store_sa_state <= idle;
when wait_full => if search_sa_store_full = '0' then
store_sa_state <= idle;
end if;
when others => store_sa_state <= idle;
end case;
end if;
end process;
end architecture esoc_search_engine_sa_store ; -- of esoc_search_engine_sa_store
 
/trunk/Sources/esoc_search_engine.vhd
0,0 → 1,317
--------------------------------------------------------------------------------
---- ----
---- 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
-- Last modified : Mon Apr 14 12:49:54 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_search_engine is
port(
clk_control : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
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);
end entity esoc_search_engine;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_search_engine.esoc_search
-- Last modified : Mon Apr 14 12:49:54 2014.
--------------------------------------------------------------------------------
 
architecture esoc_search of esoc_search_engine is
 
signal q_b : STD_LOGIC_VECTOR(79 downto 0);
signal sa_wren : STD_LOGIC := '1';
signal data_b : STD_LOGIC_VECTOR(79 downto 0);
signal address_b : STD_LOGIC_VECTOR(12 downto 0);
signal wren_a : STD_LOGIC := '1';
signal address_a : STD_LOGIC_VECTOR(12 downto 0);
signal data_a : STD_LOGIC_VECTOR(79 downto 0);
signal q_a : STD_LOGIC_VECTOR(79 downto 0);
signal search_sa_drop_cnt : std_logic;
signal search_entry_age_time : std_logic_vector(11 downto 0);
signal wrreq : STD_LOGIC;
signal data : STD_LOGIC_VECTOR(79 downto 0);
signal wrfull : STD_LOGIC;
signal rdreq : std_logic;
signal q : STD_LOGIC_VECTOR(79 downto 0);
signal rdempty : STD_LOGIC;
signal search_sa_overload_cnt : std_logic;
signal rdusedw : STD_LOGIC_VECTOR(6 downto 0);
signal search_entry_age_time_ena : std_logic;
signal clk_en : std_logic;
signal esoc_clk_en_gen_div : integer;
signal Net_0 : STD_LOGIC;
signal rden_b : STD_LOGIC := '1';
 
component esoc_search_engine_da
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 component esoc_search_engine_da;
 
component esoc_search_engine_sa
port(
clk_search : in std_logic;
reset : in std_logic;
search_aging_tick : in std_logic;
search_entry_age_time : in std_logic_vector(11 downto 0);
search_entry_age_time_ena : in std_logic;
search_sa_drop_cnt : out std_logic;
search_sa_store_empty : in std_logic;
search_sa_store_q : in std_logic_vector(79 downto 0);
search_sa_store_rd : out std_logic;
search_sa_store_words : in STD_LOGIC_VECTOR(6 downto 0);
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 component esoc_search_engine_sa;
 
component esoc_search_engine_control
port(
clk_control : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
reset : in std_logic;
search_entry_age_time : out std_logic_vector(11 downto 0);
search_entry_age_time_ena : out std_logic;
search_sa_drop_cnt : in std_logic;
search_sa_overload_cnt : in std_logic);
end component esoc_search_engine_control;
 
component esoc_ram_8kx80
port(
address_a : in STD_LOGIC_VECTOR(12 downto 0);
address_b : in STD_LOGIC_VECTOR(12 downto 0);
data_a : in STD_LOGIC_VECTOR(79 downto 0);
data_b : in STD_LOGIC_VECTOR(79 downto 0);
wren_a : in STD_LOGIC := '0';
wren_b : in STD_LOGIC := '0';
q_a : out STD_LOGIC_VECTOR(79 downto 0);
q_b : out STD_LOGIC_VECTOR(79 downto 0);
clock : in STD_LOGIC := '1';
rden_a : in STD_LOGIC := '1';
rden_b : in STD_LOGIC := '1');
end component esoc_ram_8kx80;
 
component esoc_search_engine_sa_store
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_sa_overload_cnt : out std_logic;
search_sa_store_d : out STD_LOGIC_VECTOR(79 downto 0);
search_sa_store_full : in STD_LOGIC;
search_sa_store_wr : out STD_LOGIC;
search_sof : in std_logic);
end component esoc_search_engine_sa_store;
 
component esoc_fifo_128x80
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(79 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(79 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(6 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(6 downto 0));
end component esoc_fifo_128x80;
 
component esoc_clk_en_gen
port(
clk : in std_logic;
clk_div : in integer;
clk_en : out std_logic;
reset : in std_logic);
end component esoc_clk_en_gen;
 
begin
--Destination MAC
--Address Processing
--Source MAC Address
--Processing and aging control
--MAC Address Table
--Search Engine Control
--SA, VID and
--Source port buffer
esoc_clk_en_gen_div <= clk_search_en_div_1s when esoc_mode = normal else clk_search_en_div_1s_sim;
 
u0: esoc_search_engine_da
port map(
clk_search => clk_search,
reset => reset,
search_eof => search_eof,
search_key => search_key,
search_port_stalled => search_port_stalled,
search_result => search_result,
search_result_av => search_result_av,
search_sof => search_sof,
search_table_address => address_a,
search_table_data => data_a,
search_table_q => q_a,
search_table_rden => Net_0,
search_table_wren => wren_a);
 
u1: esoc_search_engine_sa
port map(
clk_search => clk_search,
reset => reset,
search_aging_tick => clk_en,
search_entry_age_time => search_entry_age_time,
search_entry_age_time_ena => search_entry_age_time_ena,
search_sa_drop_cnt => search_sa_drop_cnt,
search_sa_store_empty => rdempty,
search_sa_store_q => q,
search_sa_store_rd => rdreq,
search_sa_store_words => rdusedw,
search_table_address => address_b,
search_table_data => data_b,
search_table_q => q_b,
search_table_rden => rden_b,
search_table_wren => sa_wren);
 
u3: esoc_search_engine_control
port map(
clk_control => clk_control,
clk_search => clk_search,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
reset => reset,
search_entry_age_time => search_entry_age_time,
search_entry_age_time_ena => search_entry_age_time_ena,
search_sa_drop_cnt => search_sa_drop_cnt,
search_sa_overload_cnt => search_sa_overload_cnt);
 
u2: esoc_ram_8kx80
port map(
address_a => address_a,
address_b => address_b,
data_a => data_a,
data_b => data_b,
wren_a => wren_a,
wren_b => sa_wren,
q_a => q_a,
q_b => q_b,
clock => clk_search,
rden_a => Net_0,
rden_b => rden_b);
 
u5: esoc_search_engine_sa_store
port map(
clk_search => clk_search,
reset => reset,
search_eof => search_eof,
search_key => search_key,
search_sa_overload_cnt => search_sa_overload_cnt,
search_sa_store_d => data,
search_sa_store_full => wrfull,
search_sa_store_wr => wrreq,
search_sof => search_sof);
 
u6: esoc_fifo_128x80
port map(
aclr => reset,
data => data,
rdclk => clk_search,
rdreq => rdreq,
wrclk => clk_search,
wrreq => wrreq,
q => q,
rdempty => rdempty,
rdusedw => rdusedw,
wrfull => wrfull,
wrusedw => open);
 
u7: esoc_clk_en_gen
port map(
clk => clk_search,
clk_div => esoc_clk_en_gen_div,
clk_en => clk_en,
reset => reset);
 
end architecture esoc_search ; -- of esoc_search_engine
 
/trunk/Sources/esoc_search_engine_control.vhd
0,0 → 1,248
--------------------------------------------------------------------------------
---- ----
---- 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_control
-- Last modified : Mon Apr 14 12:49:59 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_search_engine_control is
port(
clk_control : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
reset : in std_logic;
search_entry_age_time : out std_logic_vector(11 downto 0);
search_entry_age_time_ena : out std_logic;
search_sa_drop_cnt : in std_logic;
search_sa_overload_cnt : in std_logic);
end entity esoc_search_engine_control;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_search_engine_control.esoc_search_engine_control
-- Last modified : Mon Apr 14 12:49:59 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_search_engine_control of esoc_search_engine_control is
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
constant reg_search_engine_sa_overload_count_add: integer := 2;
signal reg_search_engine_sa_overload_count: std_logic_vector(31 downto 0);
signal reg_search_engine_sa_overload_count_i: std_logic_vector(31 downto 0);
constant reg_search_engine_sa_overload_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_search_engine_sa_drop_count_add: integer := 1;
signal reg_search_engine_sa_drop_count: std_logic_vector(31 downto 0);
signal reg_search_engine_sa_drop_count_i: std_logic_vector(31 downto 0);
constant reg_search_engine_sa_drop_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_search_engine_stat_ctrl_add: integer := 0;
signal reg_search_engine_stat_ctrl: std_logic_vector(31 downto 0);
constant reg_search_engine_stat_ctrl_rst: std_logic_vector(31 downto 0) := X"8000012C";
constant reg_search_engine_stat_ctrl_rst_sim: std_logic_vector(31 downto 0) := X"00000002";
alias reg_search_engine_stat_ctrl_age_timer_ena : std_logic is reg_search_engine_stat_ctrl(31);
alias reg_search_engine_stat_ctrl_age_timer : std_logic_vector(11 downto 0) is reg_search_engine_stat_ctrl(11 downto 0);
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal search_sa_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
signal search_sa_cnt_update_sync : std_logic_vector(esoc_meta_ffs-1 downto 0);
signal search_sa_cnt_update : std_logic;
signal search_sa_cnt_update_ack : std_logic;
 
signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0);
signal ctrl_wait_i: std_logic;
signal ctrl_bus_enable: std_logic;
 
begin
 
--=============================================================================================================
-- Process : access registers when addressed or provide data to the ctrl_rddata_i bus
-- Description :
--=============================================================================================================
registers: process(clk_control, reset)
begin
if reset = '1' then
-- Reset value depends on esoc mode, simulation requires short aging timer
if esoc_mode = simulation then
reg_search_engine_stat_ctrl <= reg_search_engine_stat_ctrl_rst_sim;
else
reg_search_engine_stat_ctrl <= reg_search_engine_stat_ctrl_rst;
end if;
ctrl_rddata_i <= (others => '0');
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
elsif clk_control'event and clk_control = '1' then
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
-- continu if memory space of this entity is addressed
if (to_integer(unsigned(ctrl_address)) >= esoc_search_engine_base) and (to_integer(unsigned(ctrl_address)) < esoc_search_engine_base + esoc_search_engine_size) then
-- claim the bus for ctrl_wait and ctrl_rddata
ctrl_bus_enable <= '1';
--
-- READ CYCLE started, unit addressed?
--
if ctrl_rd = '1' then
-- Check register address and provide data when addressed
case to_integer(unsigned(ctrl_address)) - esoc_search_engine_base is
when reg_search_engine_sa_overload_count_add => if search_sa_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_search_engine_sa_overload_count;
ctrl_wait_i <= '0';
end if;
when reg_search_engine_sa_drop_count_add => if search_sa_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_search_engine_sa_drop_count;
ctrl_wait_i <= '0';
end if;
when reg_search_engine_stat_ctrl_add => ctrl_rddata_i <= reg_search_engine_stat_ctrl;
ctrl_wait_i <= '0';
when others => NULL;
end case;
--
-- WRITE CYCLE started, unit addressed?
--
elsif ctrl_wr = '1' then
-- Check address and accept data when addressed
case to_integer(unsigned(ctrl_address)) - esoc_search_engine_base is
when reg_search_engine_stat_ctrl_add => reg_search_engine_stat_ctrl <= ctrl_wrdata;
ctrl_wait_i <= '0';
 
when others => NULL;
end case;
end if;
end if;
end if;
end process;
-- Create tristate outputs
ctrl_wait <= ctrl_wait_i when ctrl_bus_enable = '1' else 'Z';
ctrl_rddata <= ctrl_rddata_i when ctrl_bus_enable = '1' else (others => 'Z');
 
-- use register content
search_entry_age_time <= reg_search_engine_stat_ctrl_age_timer;
search_entry_age_time_ena <= reg_search_engine_stat_ctrl_age_timer_ena;
--=============================================================================================================
-- Process : Update counters and transfer values from search clock domain to control clock domain
-- Description :
--=============================================================================================================
sync1a: process(clk_search, reset)
begin
if reset = '1' then
reg_search_engine_sa_drop_count_i <= reg_search_engine_sa_drop_count_rst;
reg_search_engine_sa_overload_count_i <= reg_search_engine_sa_overload_count_rst;
elsif clk_search'event and clk_search = '1' then
-- Update source address DROP counter
if search_sa_drop_cnt = '1' then
reg_search_engine_sa_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_search_engine_sa_drop_count_i)) + 1,reg_search_engine_sa_drop_count_i'length));
end if;
-- Update source address OVERLOAD counter
if search_sa_overload_cnt = '1' then
reg_search_engine_sa_overload_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_search_engine_sa_overload_count_i)) + 1,reg_search_engine_sa_overload_count_i'length));
end if;
end if;
end process;
 
sync1b: process(clk_search, reset)
begin
if reset = '1' then
search_sa_cnt_update <= '0';
search_sa_cnt_update_ack_sync <= (others => '0');
reg_search_engine_sa_drop_count <= reg_search_engine_sa_drop_count_rst;
reg_search_engine_sa_overload_count <= reg_search_engine_sa_overload_count_rst;
 
elsif clk_search'event and clk_search = '1' then
-- synchronise update acknowledge indication
search_sa_cnt_update_ack_sync <= search_sa_cnt_update_ack & search_sa_cnt_update_ack_sync(search_sa_cnt_update_ack_sync'high downto 1);
-- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
if search_sa_cnt_update = '0' and search_sa_cnt_update_ack_sync(0) = '0' then
search_sa_cnt_update <= '1';
reg_search_engine_sa_drop_count <= reg_search_engine_sa_drop_count_i;
reg_search_engine_sa_overload_count <= reg_search_engine_sa_overload_count_i;
-- finalize update when acknowledge is received
elsif search_sa_cnt_update_ack_sync(0) = '1' then
search_sa_cnt_update <= '0';
end if;
end if;
end process;
sync1c: process(clk_control, reset)
begin
if reset = '1' then
search_sa_cnt_update_sync <= (others => '0');
-- synchronise counter update indication
elsif clk_control'event and clk_control = '1' then
search_sa_cnt_update_sync <= search_sa_cnt_update & search_sa_cnt_update_sync(search_sa_cnt_update_sync'high downto 1);
end if;
end process;
-- send update acknowledge
search_sa_cnt_update_ack <= search_sa_cnt_update_sync(0);
end architecture esoc_search_engine_control ; -- of esoc_search_engine_control
 
/trunk/Sources/esoc_port_mal_inbound.vhd
0,0 → 1,231
--------------------------------------------------------------------------------
---- ----
---- 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_mal_inbound
-- Last modified : Mon Apr 14 12:49:11 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_mal_inbound is
port(
clk_control : in STD_LOGIC;
ff_rx_a_empty : in STD_LOGIC;
ff_rx_a_full : in STD_LOGIC;
ff_rx_data : in STD_LOGIC_VECTOR(31 downto 0);
ff_rx_dsav : in STD_LOGIC;
ff_rx_dval : in STD_LOGIC;
ff_rx_eop : in STD_LOGIC;
ff_rx_mod : in STD_LOGIC_VECTOR(1 downto 0);
ff_rx_rdy : out STD_LOGIC;
ff_rx_sop : in STD_LOGIC;
force_vlan_default_in : in std_logic;
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
port_vlan_default : in std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
rx_err_stat : in STD_LOGIC_VECTOR(17 downto 0);
rx_frm_type : in STD_LOGIC_VECTOR(3 downto 0));
end entity esoc_port_mal_inbound;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_mal_inbound.esoc_port_mal_inbound
-- Last modified : Mon Apr 14 12:49:11 2014.
--------------------------------------------------------------------------------
 
 
---------------------------------------------------------------------------------------------------------------
-- architecture and declarations
---------------------------------------------------------------------------------------------------------------
architecture esoc_port_mal_inbound of esoc_port_mal_inbound is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal ff_rx_counter: integer range 2**esoc_inbound_info_length_size-1 downto 0;
 
signal boundary64: std_logic;
signal boundary64_write: std_logic;
 
begin
--=============================================================================================================
-- Process : write header and information - DMAC, SMAC, VLAN ID, LENGTH, FLAGS - into HEADER and INFO FIFO
-- Description : header information is used by the search process in the esoc_port_processor
-- info information is used by the data process in the esoc_port_processor
--=============================================================================================================
infoheader: process(clk_control, reset)
begin
if reset = '1' then
inbound_header <= (others => '0');
inbound_info <= (others => '0');
inbound_data <= (others => '0');
inbound_header_write <= '0';
inbound_info_write <= '0';
inbound_data_write <= '0';
ff_rx_counter <= 0;
boundary64 <= '0';
boundary64_write <= '0';
elsif clk_control'event and clk_control = '1' then
-- clear one-clock active signals
inbound_header_write <= '0';
inbound_info_write <= '0';
inbound_data_write <= '0';
boundary64_write <= '0';
 
-- define unused bits to avoid inferred latch warning during analysis & synthesis
inbound_header(esoc_inbound_header_unused3_flag downto esoc_inbound_header_unused1_flag) <= (others => '0');
inbound_info(esoc_inbound_info_unused3_flag downto esoc_inbound_info_unused1_flag) <= (others => '0');
--
-- MONITOR THE ST INTERFACE TO MAC
--
-- finalise packet storage, always write at 64b boundaries, because the other side of the FIFO has a width of 64 bit!
-- create dummy write if the packet at completion does not end on a 64 bit boundary.
inbound_data_write <= boundary64_write;
if ff_rx_dval = '1' then
-- store data in FIFO
if ff_rx_sop = '1' or ff_rx_counter > 0 then
inbound_data_write <= '1';
inbound_data <= ff_rx_data;
ff_rx_counter <= ff_rx_counter + 4;
-- init boundary64 signal at start of new packet
if ff_rx_sop = '1' then
boundary64 <= '1';
else
boundary64 <= not(boundary64);
end if;
end if;
--
-- MANIPULATE DATA
--
case ff_rx_counter is
when 0 => -- store DMAC (4 MSbs) in data FIFO and prepare header FIFO input
if ff_rx_sop = '1' then
inbound_header(esoc_inbound_header_dmac_hi+31 downto esoc_inbound_header_dmac_hi) <= ff_rx_data;
end if;
when 4 => -- store DMAC (2LSBs), SMAC (2MSBs) in data FIFO and prepare header FIFO input
inbound_header(esoc_inbound_header_dmac_lo+15 downto esoc_inbound_header_smac_hi) <= ff_rx_data;
when 8 => -- store SMAC (4 LSBs) in data FIFO and prepare header FIFO input
inbound_header(esoc_inbound_header_smac_lo+31 downto esoc_inbound_header_smac_lo) <= ff_rx_data;
when 12 => -- tagged packet? store VLAN ID/TCI in data FIFO and prepare header FIFO input
if ff_rx_data(31 downto 16) = esoc_ethernet_vlan_type then
-- tagged with VLAN ID 0 is a QoS Packet only - or force default VLAN ID - replace VLAN ID with port default VLAN ID
if ff_rx_data(11 downto 0) = esoc_ethernet_vlan_qos or force_vlan_default_in = '1' then
inbound_data(15 downto 0) <= port_vlan_default;
-- store default port VLAN ID in the header FIFO for the search operation
inbound_header(esoc_inbound_header_vlan+11 downto esoc_inbound_header_vlan) <= port_vlan_default(11 downto 0);
inbound_header(esoc_inbound_header_vlan_flag) <= '1';
-- store default port VLAN tag in the info FIFO for the data transfer operation
inbound_info(esoc_inbound_info_vlan_tci+15 downto esoc_inbound_info_vlan_tci) <= port_vlan_default;
inbound_info(esoc_inbound_info_vlan_flag) <= '1';
-- tagged with VLAN ID > 0
else
-- store only VLAN ID in the header FIFO for the search operation
inbound_header(esoc_inbound_header_vlan+11 downto esoc_inbound_header_vlan) <= ff_rx_data(11 downto 0);
inbound_header(esoc_inbound_header_vlan_flag) <= '1';
-- store comlete VLAN tag in the info FIFO for the data transfer operation
inbound_info(esoc_inbound_info_vlan_tci+15 downto esoc_inbound_info_vlan_tci) <= ff_rx_data(15 downto 0);
inbound_info(esoc_inbound_info_vlan_flag) <= '1';
end if;
-- untagged packet
else
-- store default port VLAN ID in the header FIFO for the search operation
inbound_header(esoc_inbound_header_vlan+11 downto esoc_inbound_header_vlan) <= port_vlan_default(11 downto 0);
inbound_header(esoc_inbound_header_vlan_flag) <= '0';
-- store default port VLAN tag in the info FIFO for the data transfer operation
inbound_info(esoc_inbound_info_vlan_tci+15 downto esoc_inbound_info_vlan_tci) <= port_vlan_default;
inbound_info(esoc_inbound_info_vlan_flag) <= '0';
end if;
-- write header when complete, search operation can start!
inbound_header_write <= '1';
when others => -- Write information in to fifo when packet is complete, data operation can start!
if ff_rx_eop = '1' then
ff_rx_counter <= 0;
inbound_info(esoc_inbound_info_length+esoc_inbound_info_length_size-1 downto esoc_inbound_info_length) <= std_logic_vector(to_unsigned(ff_rx_counter + 4 - to_integer(unsigned(ff_rx_mod)),esoc_inbound_info_length_size));
inbound_info_write <= '1';
boundary64_write <= not(boundary64);
end if;
end case;
end if;
end if;
end process;
 
--=============================================================================================================
-- Process : write packet into DATA FIFO
-- Description :
--=============================================================================================================
-- FULL signal of FIFO is used to drive READY of ST Sink interface
ff_rx_rdy <= not(inbound_data_full);
 
end architecture esoc_port_mal_inbound ; -- of esoc_port_mal_inbound
/trunk/Sources/esoc_port_mal_outbound.vhd
0,0 → 1,236
--------------------------------------------------------------------------------
---- ----
---- 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_mal_outbound
-- Last modified : Mon Apr 14 12:49:17 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_mal_outbound is
port(
clk_control : in STD_LOGIC;
ff_tx_a_empty : in STD_LOGIC;
ff_tx_a_full : in STD_LOGIC;
ff_tx_crc_fwd : out STD_LOGIC;
ff_tx_data : out STD_LOGIC_VECTOR(31 downto 0);
ff_tx_eop : out STD_LOGIC;
ff_tx_err : out STD_LOGIC;
ff_tx_mod : out STD_LOGIC_VECTOR(1 downto 0);
ff_tx_rdy : in STD_LOGIC;
ff_tx_septy : in STD_LOGIC;
ff_tx_sop : out STD_LOGIC;
ff_tx_wren : out STD_LOGIC;
force_vlan_default_out : in std_logic;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
port_vlan_default : in std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
tx_ff_uflow : in STD_LOGIC);
end entity esoc_port_mal_outbound;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_mal_outbound.esoc_port_mal_outbound
-- Last modified : Mon Apr 14 12:49:17 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_mal_outbound of esoc_port_mal_outbound is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
type ff_tx_states is (idle, running, drop);
signal ff_tx_state: ff_tx_states;
 
signal ff_tx_byte_counter: integer range 2**esoc_outbound_info_length_size-1 downto 0;
signal ff_tx_word_counter: integer range ((2**esoc_outbound_info_length_size)/4)-1 downto 0;
 
signal outbound_data_read_enable: std_logic;
signal outbound_data_read_dummy: std_logic;
signal outbound_data_modify_enable: std_logic;
signal outbound_data_modify: std_logic_vector(outbound_data'high downto 0);
 
signal outbound_info_vlan_flag: std_logic;
 
signal boundary64: std_logic;
 
begin
 
--=============================================================================================================
-- Process : capture and store data when ready acycle occurs
-- Description :
--=============================================================================================================
capture: process(clk_control, reset)
begin
if reset = '1' then
ff_tx_sop <= '0';
ff_tx_eop <= '0';
ff_tx_wren <= '0';
ff_tx_mod <= (others => '0');
ff_tx_byte_counter <= 0;
ff_tx_word_counter <= 0;
outbound_info_vlan_flag <= '0';
outbound_data_modify_enable <= '0';
outbound_data_modify <= (others => '0');
outbound_info_read <= '0';
outbound_data_read_dummy <= '0';
outbound_data_read_enable <= '0';
boundary64 <= '0';
elsif clk_control'event and clk_control = '1' then
-- clear one-clock active signals
outbound_info_read <= '0';
outbound_data_read_dummy <= '0';
outbound_data_modify_enable <= '0';
case ff_tx_state is
when idle => -- create dummy read if the previous transaction does not end on a 64 bit boundary
if boundary64 = '1' then
boundary64 <= '0';
outbound_data_read_dummy <= '1';
-- Info fifo not empty? Get length from info fifo and acknowledge info fifo read! Start packet transmission.
elsif outbound_info_empty = '0' then
-- get the length, subtract 4 byes because first word is provided on ST interface immediately, acknowledge info from fifo
outbound_info_read <= '1';
ff_tx_word_counter <= 0;
ff_tx_byte_counter <= to_integer(unsigned(outbound_info(esoc_outbound_info_length+esoc_outbound_info_length_size-1 downto esoc_outbound_info_length)))-4;
outbound_info_vlan_flag <= outbound_info(esoc_outbound_info_vlan_flag);
-- send packet to MAC or drop packet if an error is indicated, error can be packet in data FIFO not complete due to overrun
if outbound_info(esoc_outbound_info_error_flag) = '0' then
outbound_data_read_enable <= '1';
ff_tx_sop <= '1';
ff_tx_wren <= '1';
ff_tx_state <= running;
-- receive data has an error, drop it!
else
outbound_data_read_dummy <= '1';
ff_tx_state <= drop;
end if;
end if;
when running => -- provide next data when ready is asserted (=acknowledge of current data)
if ff_tx_rdy = '1' then
--
-- CONTROL THE ST INTERFACE TO MAC
--
-- deassert the start of packet
ff_tx_sop <= '0';
-- last word of transaction read by ST Sink port, stop transfer
if ff_tx_byte_counter = 0 then
outbound_data_read_enable <= '0';
ff_tx_eop <= '0';
ff_tx_wren <= '0';
ff_tx_state <= idle;
-- last word of transaction to be read by ST Sink port?
elsif ff_tx_byte_counter <= 4 then
ff_tx_eop <= '1';
ff_tx_byte_counter <= 0;
ff_tx_mod <= std_logic_vector(to_unsigned(4-ff_tx_byte_counter,ff_tx_mod'length));
-- transaction not finished, update counter
else
ff_tx_byte_counter <= ff_tx_byte_counter - 4;
end if;
-- toggle to know from which boundary is read, 32b or 64b
boundary64 <= not(boundary64);
--
-- MANIPULATE DATA
--
-- modify vlan id with default vlan id if packet is tagged and force default vlan is enabled
if ff_tx_word_counter = 2 then
if outbound_info_vlan_flag = '1' and force_vlan_default_out = '1' then
outbound_data_modify_enable <= '1';
outbound_data_modify <= esoc_ethernet_vlan_type & port_vlan_default;
end if;
end if;
ff_tx_word_counter <= ff_tx_word_counter + 1;
end if;
when drop => -- read erroneous packet from FIFO and drop!
-- size of packet always multiple of 8 bytes, no boundary64 mechanism required
if ff_tx_byte_counter <= 4 then
ff_tx_state <= idle;
else
ff_tx_byte_counter <= ff_tx_byte_counter - 4;
end if;
outbound_data_read_dummy <= '1';
when others => ff_tx_state <= idle;
end case;
end if;
end process;
ff_tx_err <= '0';
ff_tx_crc_fwd <= '0';
ff_tx_data <= outbound_data when outbound_data_modify_enable = '0' else outbound_data_modify;
outbound_data_read <= (ff_tx_rdy and outbound_data_read_enable) or outbound_data_read_dummy;
end architecture esoc_port_mal_outbound ; -- of esoc_port_mal_outbound
/trunk/Sources/package_hash10_24b.vhd
0,0 → 1,56
--------------------------------------------------------------------------------
-- Object : Package work.package_hash10_24b
-- Last modified : Thu Oct 10 12:37:21 2013.
--------------------------------------------------------------------------------
 
 
 
library ieee, std;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
---------------------------------------------------------------------------------------------------------------
-- Package declaration
---------------------------------------------------------------------------------------------------------------
package package_hash10_24b is
 
-------------------------------------------------------------------------
-- functions to calculate CRC on the fly
-------------------------------------------------------------------------
function CALC_HASH10_24b
(data : std_logic_vector(23 downto 0))
return std_logic_vector;
end package_hash10_24b;
 
package body package_hash10_24b is
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function CALC_HASH10_24b
(data: std_logic_vector(23 downto 0))
return std_logic_vector is
variable d: std_logic_vector(23 downto 0);
variable hash: std_logic_vector(9 downto 0);
begin
d := data;
hash(0) := d(23) xor d(19) xor d(17) xor d(16) xor d(15) xor d(9) xor d(4) xor d(3) xor d(2) xor d(1) xor d(0);
hash(1) := d(23) xor d(20) xor d(19) xor d(18) xor d(15) xor d(10) xor d(9) xor d(5) xor d(0);
hash(2) := d(21) xor d(20) xor d(19) xor d(16) xor d(11) xor d(10) xor d(6) xor d(1);
hash(3) := d(22) xor d(21) xor d(20) xor d(17) xor d(12) xor d(11) xor d(7) xor d(2);
hash(4) := d(22) xor d(21) xor d(19) xor d(18) xor d(17) xor d(16) xor d(15) xor d(13) xor d(12) xor d(9) xor d(8) xor d(4) xor d(2) xor d(1) xor d(0);
hash(5) := d(22) xor d(20) xor d(18) xor d(15) xor d(14) xor d(13) xor d(10) xor d(5) xor d(4) xor d(0);
hash(6) := d(23) xor d(21) xor d(19) xor d(16) xor d(15) xor d(14) xor d(11) xor d(6) xor d(5) xor d(1);
hash(7) := d(22) xor d(20) xor d(17) xor d(16) xor d(15) xor d(12) xor d(7) xor d(6) xor d(2);
hash(8) := d(23) xor d(21) xor d(18) xor d(17) xor d(16) xor d(13) xor d(8) xor d(7) xor d(3);
hash(9) := d(23) xor d(22) xor d(18) xor d(16) xor d(15) xor d(14) xor d(8) xor d(3) xor d(2) xor d(1) xor d(0);
return hash;
end CALC_HASH10_24b;
 
end package_hash10_24b;
/trunk/Sources/esoc_search_engine_da.vhd
0,0 → 1,201
--------------------------------------------------------------------------------
---- ----
---- 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
 
/trunk/Sources/esoc_port_processor_inbound.vhd
0,0 → 1,234
--------------------------------------------------------------------------------
---- ----
---- 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
 
/trunk/Sources/esoc_bus_arbiter.vhd
0,0 → 1,236
--------------------------------------------------------------------------------
---- ----
---- 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_bus_arbiter
-- Last modified : Mon Apr 14 12:48:27 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_bus_arbiter is
generic(
id : integer := 0);
port(
bus_eof : in std_logic;
bus_gnt_rd : out std_logic_vector(esoc_port_count-1 downto 0);
bus_gnt_wr : out std_logic_vector(esoc_port_count-1 downto 0);
bus_req : in std_logic_vector(esoc_port_count-1 downto 0);
bus_sof : in std_logic;
clk_bus : in std_logic;
clk_control : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
reset : in std_logic);
end entity esoc_bus_arbiter;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_bus_arbiter.esoc_bus_arbiter
-- Last modified : Mon Apr 14 12:48:27 2014.
--------------------------------------------------------------------------------
 
 
---------------------------------------------------------------------------------------------------------------
-- architecture and declarations
---------------------------------------------------------------------------------------------------------------
architecture esoc_bus_arbiter of esoc_bus_arbiter is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
constant reg_arb_port_disable_add: integer := 7;
signal reg_arb_port_disable_dat: std_logic_vector(31 downto 0);
constant reg_arb_port_disable_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_arb_port_weight_add: integer := 0;
signal reg_arb_port_weight_dat: std_logic_vector(31 downto 0);
constant reg_arb_port_weight_rst: std_logic_vector(31 downto 0) := X"00000000";
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal port_select: integer range esoc_port_count-1 downto 0;
signal port_request: std_logic;
signal port_request_weight: std_logic_vector(1 downto 0);
 
type states_data_bus is (idle, wait_sof, wait_eof);
signal state_data_bus: states_data_bus;
 
signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0);
signal ctrl_wait_i: std_logic;
signal ctrl_bus_enable: std_logic;
 
begin
 
--=============================================================================================================
-- Process : process data bus access request, use weight factor for each port and approve access
-- Description :
--=============================================================================================================
req_scan: process(clk_bus, reset)
begin
if reset = '1' then
port_select <= 0;
port_request <= '0';
port_request_weight <= (others => '0');
bus_gnt_wr <= (others => '0');
bus_gnt_rd <= (others => '0');
state_data_bus <= idle;
elsif clk_bus'event and clk_bus = '1' then
-- scan request outputs from all ESOC ports, if asserted wait for free data bus
if bus_req(port_select) = '1' and reg_arb_port_disable_dat(port_select) = '0' then
port_request <= '1';
-- request output deasserted, current weight factor zero? determine next port to check, use weight factor of current port
else
port_request <= '0';
-- check weight of processed port, scan port again or go to next port with appropriate weight?
if to_integer(unsigned(port_request_weight)) = 0 then
if port_select = esoc_port_count-1 then
port_select <= 0;
port_request_weight <= reg_arb_port_weight_dat(1) & reg_arb_port_weight_dat(0);
else
port_select <= port_select + 1;
port_request_weight <= reg_arb_port_weight_dat(2*(port_select+1)+1) & reg_arb_port_weight_dat(2*(port_select+1));
end if;
-- weight not 0, do not proceed with next port, but decrease weight of actual port
else
port_request_weight <= std_logic_vector(to_unsigned(to_integer(unsigned(port_request_weight))-1,2));
end if;
end if;
-- monitor the data bus state and control the scan process
case state_data_bus is
when idle => -- if there is a bus request, give a write grant to selected port, a read grant to all other ports and wait for SOF and EOF
if port_request = '1' then
bus_gnt_wr(port_select) <= '1';
bus_gnt_rd <= (others => '1');
state_data_bus <= wait_sof;
end if;
when wait_sof => -- wait for start of packet, no further actions required yet (future)
if bus_sof = '1' then
state_data_bus <= wait_eof;
end if;
when wait_eof => -- End of packet detect? Terminate and go back to idle.
if bus_eof = '1' then
bus_gnt_wr <= (others => '0');
bus_gnt_rd <= (others => '0');
state_data_bus <= idle;
end if;
when others => state_data_bus <= idle;
end case;
end if;
end process;
 
--=============================================================================================================
-- Process : access registers when addressed or provide data from other units to the readdata bus
-- Description :
--=============================================================================================================
registers: process(clk_control, reset)
begin
if reset = '1' then
-- all ports have weight 1 after reset
reg_arb_port_disable_dat <= reg_arb_port_disable_rst;
reg_arb_port_weight_dat <= reg_arb_port_weight_rst;
ctrl_rddata_i <= (others => '0');
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
elsif clk_control'event and clk_control = '1' then
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
 
-- continu if memory space of this entity is addressed
if to_integer(unsigned(ctrl_address)) >= (esoc_bus_arbiter_base + (id * esoc_bus_arbiter_size)) and to_integer(unsigned(ctrl_address)) < (esoc_bus_arbiter_base + (id * esoc_bus_arbiter_size) + esoc_bus_arbiter_size) then
ctrl_bus_enable <= '1';
--
-- READ CYCLE started, unit addressed?
--
if ctrl_rd = '1' then
-- Check register address and provide data when addressed
case to_integer(unsigned(ctrl_address))- esoc_bus_arbiter_base - (id * esoc_bus_arbiter_size) is
when reg_arb_port_disable_add => ctrl_rddata_i <= reg_arb_port_disable_dat;
ctrl_wait_i <= '0';
when reg_arb_port_weight_add => ctrl_rddata_i <= reg_arb_port_weight_dat;
ctrl_wait_i <= '0';
when others => NULL;
end case;
--
-- WRITE CYCLE started, unit addressed?
--
elsif ctrl_wr = '1' then
-- Check address and accept data when addressed
case to_integer(unsigned(ctrl_address))- esoc_bus_arbiter_base - (id * esoc_bus_arbiter_size) is
when reg_arb_port_disable_add => reg_arb_port_disable_dat <= ctrl_wrdata;
ctrl_wait_i <= '0';
when reg_arb_port_weight_add => reg_arb_port_weight_dat <= ctrl_wrdata;
ctrl_wait_i <= '0';
when others => NULL;
end case;
end if;
end if;
end if;
end process;
-- Create tristate outputs
ctrl_wait <= ctrl_wait_i when ctrl_bus_enable = '1' else 'Z';
ctrl_rddata <= ctrl_rddata_i when ctrl_bus_enable = '1' else (others => 'Z');
end architecture esoc_bus_arbiter ; -- of esoc_bus_arbiter
/trunk/Sources/esoc_port_processor_outbound.vhd
0,0 → 1,200
--------------------------------------------------------------------------------
---- ----
---- 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
 
/trunk/Sources/package_hash10_48b.vhd
0,0 → 1,62
--------------------------------------------------------------------------------
-- Object : Package work.package_hash10_48b
-- Last modified : Thu Oct 10 12:37:02 2013.
--------------------------------------------------------------------------------
 
 
 
library ieee, std;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
---------------------------------------------------------------------------------------------------------------
-- Library declaration
---------------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
 
---------------------------------------------------------------------------------------------------------------
-- Package declaration
---------------------------------------------------------------------------------------------------------------
package package_hash10_48b is
 
-------------------------------------------------------------------------
-- functions to calculate CRC on the fly
-------------------------------------------------------------------------
function CALC_HASH10_48b
(data : std_logic_vector(47 downto 0))
return std_logic_vector;
end package_hash10_48b;
 
package body package_hash10_48b is
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function CALC_HASH10_48b
(data: std_logic_vector(47 downto 0))
return std_logic_vector is
variable d: std_logic_vector(47 downto 0);
variable hash: std_logic_vector(9 downto 0);
begin
d := data;
hash(0) := d(46) xor d(42) xor d(41) xor d(39) xor d(37) xor d(36) xor d(34) xor d(33) xor d(32) xor d(31) xor d(30) xor d(28) xor d(27) xor d(24) xor d(23) xor d(19) xor d(17) xor d(16) xor d(15) xor d(9) xor d(4) xor d(3) xor d(2) xor d(1) xor d(0);
hash(1) := d(47) xor d(46) xor d(43) xor d(41) xor d(40) xor d(39) xor d(38) xor d(36) xor d(35) xor d(30) xor d(29) xor d(27) xor d(25) xor d(23) xor d(20) xor d(19) xor d(18) xor d(15) xor d(10) xor d(9) xor d(5) xor d(0);
hash(2) := d(47) xor d(44) xor d(42) xor d(41) xor d(40) xor d(39) xor d(37) xor d(36) xor d(31) xor d(30) xor d(28) xor d(26) xor d(24) xor d(21) xor d(20) xor d(19) xor d(16) xor d(11) xor d(10) xor d(6) xor d(1);
hash(3) := d(45) xor d(43) xor d(42) xor d(41) xor d(40) xor d(38) xor d(37) xor d(32) xor d(31) xor d(29) xor d(27) xor d(25) xor d(22) xor d(21) xor d(20) xor d(17) xor d(12) xor d(11) xor d(7) xor d(2);
hash(4) := d(44) xor d(43) xor d(38) xor d(37) xor d(36) xor d(34) xor d(31) xor d(27) xor d(26) xor d(24) xor d(22) xor d(21) xor d(19) xor d(18) xor d(17) xor d(16) xor d(15) xor d(13) xor d(12) xor d(9) xor d(8) xor d(4) xor d(2) xor d(1) xor d(0);
hash(5) := d(46) xor d(45) xor d(44) xor d(42) xor d(41) xor d(38) xor d(36) xor d(35) xor d(34) xor d(33) xor d(31) xor d(30) xor d(25) xor d(24) xor d(22) xor d(20) xor d(18) xor d(15) xor d(14) xor d(13) xor d(10) xor d(5) xor d(4) xor d(0);
hash(6) := d(47) xor d(46) xor d(45) xor d(43) xor d(42) xor d(39) xor d(37) xor d(36) xor d(35) xor d(34) xor d(32) xor d(31) xor d(26) xor d(25) xor d(23) xor d(21) xor d(19) xor d(16) xor d(15) xor d(14) xor d(11) xor d(6) xor d(5) xor d(1);
hash(7) := d(47) xor d(46) xor d(44) xor d(43) xor d(40) xor d(38) xor d(37) xor d(36) xor d(35) xor d(33) xor d(32) xor d(27) xor d(26) xor d(24) xor d(22) xor d(20) xor d(17) xor d(16) xor d(15) xor d(12) xor d(7) xor d(6) xor d(2);
hash(8) := d(47) xor d(45) xor d(44) xor d(41) xor d(39) xor d(38) xor d(37) xor d(36) xor d(34) xor d(33) xor d(28) xor d(27) xor d(25) xor d(23) xor d(21) xor d(18) xor d(17) xor d(16) xor d(13) xor d(8) xor d(7) xor d(3);
hash(9) := d(45) xor d(41) xor d(40) xor d(38) xor d(36) xor d(35) xor d(33) xor d(32) xor d(31) xor d(30) xor d(29) xor d(27) xor d(26) xor d(23) xor d(22) xor d(18) xor d(16) xor d(15) xor d(14) xor d(8) xor d(3) xor d(2) xor d(1) xor d(0);
return hash;
end CALC_HASH10_48b;
 
end package_hash10_48b;
/trunk/Sources/esoc_port_interface.vhd
0,0 → 1,402
--------------------------------------------------------------------------------
---- ----
---- 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_interface
-- Last modified : Mon Apr 14 12:51:18 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_interface is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_rgmii_125m : in STD_LOGIC;
clk_rgmii_25m : in STD_LOGIC;
clk_rgmii_2m5 : in STD_LOGIC;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
mac_mdc : out std_logic;
mac_mdio : inout std_logic;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
reset : in std_logic;
rgmii_rxc : in std_logic;
rgmii_rxctl : in std_logic;
rgmii_rxd : in std_logic_vector(3 downto 0);
rgmii_txc : out std_logic;
rgmii_txctl : out std_logic;
rgmii_txd : out std_logic_vector(3 downto 0));
end entity esoc_port_interface;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_interface.structure
-- Last modified : Mon Apr 14 12:51:18 2014.
--------------------------------------------------------------------------------
 
architecture structure of esoc_port_interface is
 
signal ctrl_bus_enable : STD_LOGIC;
signal clk_rgmii : STD_LOGIC;
signal mac_rd : STD_LOGIC;
signal mac_address : STD_LOGIC_VECTOR(7 downto 0);
signal mdc : STD_LOGIC;
signal mdio_out : STD_LOGIC;
signal mdio_in : STD_LOGIC;
signal mdio_oen : STD_LOGIC;
signal mac_wait : STD_LOGIC;
signal mac_rddata : STD_LOGIC_VECTOR(31 downto 0);
signal mac_wrdata : STD_LOGIC_VECTOR(31 downto 0);
signal mac_wr : STD_LOGIC;
signal xon_gen : STD_LOGIC;
signal xoff_gen : STD_LOGIC;
signal magic_wakeup : STD_LOGIC;
signal magic_sleep_n : STD_LOGIC := '1';
signal set_1000 : STD_LOGIC := '0';
signal set_10 : STD_LOGIC := '0'; -- '0'
signal eth_mode : STD_LOGIC;
signal ena_10 : STD_LOGIC;
signal ff_tx_sop : STD_LOGIC;
signal ff_tx_eop : STD_LOGIC;
signal ff_tx_rdy : STD_LOGIC;
signal ff_tx_wren : STD_LOGIC;
signal ff_tx_data : STD_LOGIC_VECTOR(31 downto 0);
signal ff_tx_mod : STD_LOGIC_VECTOR(1 downto 0);
signal ff_tx_err : STD_LOGIC;
signal ff_tx_crc_fwd : STD_LOGIC;
signal tx_ff_uflow : STD_LOGIC;
signal ff_tx_a_full : STD_LOGIC;
signal ff_tx_a_empty : STD_LOGIC;
signal ff_tx_septy : STD_LOGIC;
signal ff_rx_sop : STD_LOGIC;
signal ff_rx_eop : STD_LOGIC;
signal ff_rx_rdy : STD_LOGIC;
signal ff_rx_dval : STD_LOGIC;
signal ff_rx_data : STD_LOGIC_VECTOR(31 downto 0);
signal ff_rx_mod : STD_LOGIC_VECTOR(1 downto 0);
signal rx_frm_type : STD_LOGIC_VECTOR(3 downto 0);
signal ff_rx_dsav : STD_LOGIC;
signal rx_err_stat : STD_LOGIC_VECTOR(17 downto 0);
signal ff_rx_a_full : STD_LOGIC;
signal ff_rx_a_empty : STD_LOGIC;
 
component esoc_port_mal
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in STD_LOGIC;
clk_rgmii : out std_logic;
clk_rgmii_125m : in std_logic;
clk_rgmii_25m : in std_logic;
clk_rgmii_2m5 : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
ena_10 : in STD_LOGIC;
eth_mode : in STD_LOGIC;
ff_rx_a_empty : in STD_LOGIC;
ff_rx_a_full : in STD_LOGIC;
ff_rx_data : in STD_LOGIC_VECTOR(31 downto 0);
ff_rx_dsav : in STD_LOGIC;
ff_rx_dval : in STD_LOGIC;
ff_rx_eop : in STD_LOGIC;
ff_rx_mod : in STD_LOGIC_VECTOR(1 downto 0);
ff_rx_rdy : out STD_LOGIC;
ff_rx_sop : in STD_LOGIC;
ff_tx_a_empty : in STD_LOGIC;
ff_tx_a_full : in STD_LOGIC;
ff_tx_crc_fwd : out STD_LOGIC;
ff_tx_data : out STD_LOGIC_VECTOR(31 downto 0);
ff_tx_eop : out STD_LOGIC;
ff_tx_err : out STD_LOGIC;
ff_tx_mod : out STD_LOGIC_VECTOR(1 downto 0);
ff_tx_rdy : in STD_LOGIC;
ff_tx_septy : in STD_LOGIC;
ff_tx_sop : out STD_LOGIC;
ff_tx_wren : out STD_LOGIC;
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
magic_sleep_n : out STD_LOGIC := '1';
magic_wakeup : in STD_LOGIC;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
reset : in STD_LOGIC;
rx_err_stat : in STD_LOGIC_VECTOR(17 downto 0);
rx_frm_type : in STD_LOGIC_VECTOR(3 downto 0);
set_10 : out STD_LOGIC := '0'; -- '0'
set_1000 : out STD_LOGIC := '0';
tx_ff_uflow : in STD_LOGIC;
xoff_gen : out STD_LOGIC;
xon_gen : out STD_LOGIC);
end component esoc_port_mal;
 
component esoc_port_mac
port(
ff_tx_crc_fwd : in STD_LOGIC;
ff_tx_data : in STD_LOGIC_VECTOR(31 downto 0);
ff_tx_eop : in STD_LOGIC;
ff_tx_err : in STD_LOGIC;
ff_tx_mod : in STD_LOGIC_VECTOR(1 downto 0);
ff_tx_sop : in STD_LOGIC;
ff_tx_wren : in STD_LOGIC;
ff_tx_clk : in STD_LOGIC;
ff_rx_rdy : in STD_LOGIC;
ff_rx_clk : in STD_LOGIC;
address : in STD_LOGIC_VECTOR(7 downto 0);
read : in STD_LOGIC;
writedata : in STD_LOGIC_VECTOR(31 downto 0);
write : in STD_LOGIC;
clk : in STD_LOGIC;
reset : in STD_LOGIC;
rgmii_in : in STD_LOGIC_VECTOR(3 downto 0);
rx_control : in STD_LOGIC;
tx_clk : in STD_LOGIC;
rx_clk : in STD_LOGIC;
set_10 : in STD_LOGIC;
set_1000 : in STD_LOGIC;
xon_gen : in STD_LOGIC;
xoff_gen : in STD_LOGIC;
magic_sleep_n : in STD_LOGIC;
mdio_in : in STD_LOGIC;
ff_tx_rdy : out STD_LOGIC;
ff_rx_data : out STD_LOGIC_VECTOR(31 downto 0);
ff_rx_dval : out STD_LOGIC;
ff_rx_eop : out STD_LOGIC;
ff_rx_mod : out STD_LOGIC_VECTOR(1 downto 0);
ff_rx_sop : out STD_LOGIC;
rx_err : out STD_LOGIC_VECTOR(5 downto 0);
rx_err_stat : out STD_LOGIC_VECTOR(17 downto 0);
rx_frm_type : out STD_LOGIC_VECTOR(3 downto 0);
ff_rx_dsav : out STD_LOGIC;
readdata : out STD_LOGIC_VECTOR(31 downto 0);
waitrequest : out STD_LOGIC;
rgmii_out : out STD_LOGIC_VECTOR(3 downto 0);
tx_control : out STD_LOGIC;
ena_10 : out STD_LOGIC;
eth_mode : out STD_LOGIC;
ff_tx_septy : out STD_LOGIC;
tx_ff_uflow : out STD_LOGIC;
ff_rx_a_full : out STD_LOGIC;
ff_rx_a_empty : out STD_LOGIC;
ff_tx_a_full : out STD_LOGIC;
ff_tx_a_empty : out STD_LOGIC;
magic_wakeup : out STD_LOGIC;
mdio_out : out STD_LOGIC;
mdio_oen : out STD_LOGIC;
mdc : out STD_LOGIC);
end component esoc_port_mac;
 
begin
rgmii_txc <= clk_rgmii;
u1: esoc_port_mal
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
clk_rgmii => clk_rgmii,
clk_rgmii_125m => clk_rgmii_125m,
clk_rgmii_25m => clk_rgmii_25m,
clk_rgmii_2m5 => clk_rgmii_2m5,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
ena_10 => ena_10,
eth_mode => eth_mode,
ff_rx_a_empty => ff_rx_a_empty,
ff_rx_a_full => ff_rx_a_full,
ff_rx_data => ff_rx_data,
ff_rx_dsav => ff_rx_dsav,
ff_rx_dval => ff_rx_dval,
ff_rx_eop => ff_rx_eop,
ff_rx_mod => ff_rx_mod,
ff_rx_rdy => ff_rx_rdy,
ff_rx_sop => ff_rx_sop,
ff_tx_a_empty => ff_tx_a_empty,
ff_tx_a_full => ff_tx_a_full,
ff_tx_crc_fwd => ff_tx_crc_fwd,
ff_tx_data => ff_tx_data,
ff_tx_eop => ff_tx_eop,
ff_tx_err => ff_tx_err,
ff_tx_mod => ff_tx_mod,
ff_tx_rdy => ff_tx_rdy,
ff_tx_septy => ff_tx_septy,
ff_tx_sop => ff_tx_sop,
ff_tx_wren => ff_tx_wren,
inbound_data => inbound_data,
inbound_data_full => inbound_data_full,
inbound_data_write => inbound_data_write,
inbound_header => inbound_header,
inbound_header_write => inbound_header_write,
inbound_info => inbound_info,
inbound_info_write => inbound_info_write,
magic_sleep_n => magic_sleep_n,
magic_wakeup => magic_wakeup,
outbound_data => outbound_data,
outbound_data_read => outbound_data_read,
outbound_info => outbound_info,
outbound_info_empty => outbound_info_empty,
outbound_info_read => outbound_info_read,
reset => reset,
rx_err_stat => rx_err_stat,
rx_frm_type => rx_frm_type,
set_10 => set_10,
set_1000 => set_1000,
tx_ff_uflow => tx_ff_uflow,
xoff_gen => xoff_gen,
xon_gen => xon_gen);
 
u0: esoc_port_mac
port map(
ff_tx_crc_fwd => ff_tx_crc_fwd,
ff_tx_data => ff_tx_data,
ff_tx_eop => ff_tx_eop,
ff_tx_err => ff_tx_err,
ff_tx_mod => ff_tx_mod,
ff_tx_sop => ff_tx_sop,
ff_tx_wren => ff_tx_wren,
ff_tx_clk => clk_control,
ff_rx_rdy => ff_rx_rdy,
ff_rx_clk => clk_control,
address => mac_address,
read => mac_rd,
writedata => mac_wrdata,
write => mac_wr,
clk => clk_control,
reset => reset,
rgmii_in => rgmii_rxd,
rx_control => rgmii_rxctl,
tx_clk => clk_rgmii,
rx_clk => rgmii_rxc,
set_10 => set_10,
set_1000 => set_1000,
xon_gen => xon_gen,
xoff_gen => xoff_gen,
magic_sleep_n => magic_sleep_n,
mdio_in => mdio_in,
ff_tx_rdy => ff_tx_rdy,
ff_rx_data => ff_rx_data,
ff_rx_dval => ff_rx_dval,
ff_rx_eop => ff_rx_eop,
ff_rx_mod => ff_rx_mod,
ff_rx_sop => ff_rx_sop,
rx_err => open,
rx_err_stat => rx_err_stat,
rx_frm_type => rx_frm_type,
ff_rx_dsav => ff_rx_dsav,
readdata => mac_rddata,
waitrequest => mac_wait,
rgmii_out => rgmii_txd,
tx_control => rgmii_txctl,
ena_10 => ena_10,
eth_mode => eth_mode,
ff_tx_septy => ff_tx_septy,
tx_ff_uflow => tx_ff_uflow,
ff_rx_a_full => ff_rx_a_full,
ff_rx_a_empty => ff_rx_a_empty,
ff_tx_a_full => ff_tx_a_full,
ff_tx_a_empty => ff_tx_a_empty,
magic_wakeup => magic_wakeup,
mdio_out => mdio_out,
mdio_oen => mdio_oen,
mdc => mdc);
 
 
mac_mdc <= mdc;
mac_mdio <= mdio_out when mdio_oen = '0' else 'Z';
mdio_in <= mac_mdio when mdio_oen = '1' else '0';
 
 
mac_address <= ctrl_address(mac_address'high downto 0);
 
mac_wrdata <= ctrl_wrdata;
 
mac_wr <= ctrl_wr when to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base and
to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base + esoc_port_mac_size
else '0';
mac_rd <= ctrl_rd when to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base and
to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base + esoc_port_mac_size
else '0';
 
ctrl_bus_enable <= '1' when to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base and
to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_mac_base + esoc_port_mac_size
else '0';
 
ctrl_wait <= mac_wait when ctrl_bus_enable = '1' else 'Z';
 
ctrl_rddata <= mac_rddata when ctrl_bus_enable = '1' else (others => 'Z');
end architecture structure ; -- of esoc_port_interface
 
/trunk/Sources/esoc_tb.vhd
0,0 → 1,1143
--------------------------------------------------------------------------------
---- ----
---- 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_tb
-- Last modified : Mon Apr 14 12:50:20 2014.
--------------------------------------------------------------------------------
 
 
 
library ieee, std, work;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
use work.package_crc32_8b.all;
use work.package_esoc_configuration.all;
use work.package_txt_utilities.all;
 
entity esoc_tb is
end entity esoc_tb;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_tb.esoc_tb
-- Last modified : Mon Apr 14 12:50:20 2014.
--------------------------------------------------------------------------------
 
architecture esoc_tb of esoc_tb is
 
type smi_states is (start, preamble, cmd, dev_addr, reg_addr, ta_cycles, data,store);
 
signal esoc_wait_timer_start : std_logic; -- Used by CONTROL testbench to protect bus cycles from freezing
signal esoc_wait_time_enable : std_logic;
signal esoc_wait_timer : integer; -- Used by CONTROL testbench to protect bus cycles from freezing
signal esoc_wait_timeout : std_logic; -- Used by CONTROL testbench to protect bus cycles from freezing
signal esoc_rgmii_rxc_int : std_logic; -- Used by RGMII testbench
signal esoc_rgmii_txc_int : std_logic_vector(esoc_port_count-1 downto 0); -- Used by RGMII testbench
signal reg_rgmii_port_enable : std_logic_vector(31 downto 0); -- Used by RGMII testbench, under control of CONTROL testbench
signal reg_rgmii_port_enable2 : std_logic_vector(31 downto 0); -- Used by RGMII testbench, under control of CONTROL testbench
signal smi_mdio : std_logic_vector(esoc_port_count-1 downto 0);
signal smi_mdio_ena : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_wait : std_logic;
signal esoc_rgmii_txc : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_rgmii_rxd : std_logic_vector(3+4*(esoc_port_count-1) downto 0);
signal esoc_rgmii_rxctl : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_rgmii_rxc : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_address : std_logic_vector(15 downto 0);
signal esoc_wr : std_logic;
signal esoc_data : std_logic_vector(31 downto 0);
signal esoc_rd : std_logic;
signal esoc_areset : std_logic;
signal esoc_cs : std_logic;
signal esoc_clk : std_logic;
signal esoc_rgmii_txctl : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_rgmii_txd : std_logic_vector(3+4*(esoc_port_count-1) downto 0);
signal esoc_boot_complete : std_logic;
signal esoc_mdio : std_logic_vector(esoc_port_count-1 downto 0);
signal esoc_mdc : std_logic_vector(esoc_port_count-1 downto 0);
 
component esoc
port(
esoc_address : in std_logic_vector(15 downto 0);
esoc_areset : in std_logic;
esoc_boot_complete : out std_logic;
esoc_clk : in std_logic;
esoc_cs : in std_logic;
esoc_data : inout std_logic_vector(31 downto 0);
esoc_mdc : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_mdio : inout std_logic_vector(esoc_port_count-1 downto 0);
esoc_rd : in std_logic;
esoc_rgmii_rxc : in std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_rxctl : in std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_rxd : in std_logic_vector(3+4*(esoc_port_count-1) downto 0);
esoc_rgmii_txc : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_txctl : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_txd : out std_logic_vector(3+4*(esoc_port_count-1) downto 0);
esoc_wait : out std_logic;
esoc_wr : in std_logic);
end component esoc;
 
begin
esoc_test_rgmii_loggers: for esoc_port_nr in esoc_port_count-1 downto 0 generate
begin
 
esoc_test_rgmii_logger: process -- EASE/HDL sens.list
begin
wait;
end process esoc_test_rgmii_logger ;
-- create shifted txc clock
esoc_rgmii_txc_int <= esoc_rgmii_txc after 2 ns;
 
--=============================================================================================================
-- Process : store all packets on RGMII RX interfaces
-- Description :
--=============================================================================================================
esoc_rgmii_rx_logging: process(esoc_rgmii_rxc, esoc_areset)
-- declare file for rgmii interface logging
file esoc_rgmii_rx_log : TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_rx_port_" & to_string(esoc_port_nr) & "_log.txt";
variable esoc_rgmii_rx_buffer: LINE;
variable byte: std_logic_vector(7 downto 0);
variable byte_counter: integer;
variable rx_state: std_logic;
begin
if esoc_areset = '1' then
byte_counter := 0;
rx_state := '0';
elsif esoc_rgmii_rxc(esoc_port_nr)'event and esoc_rgmii_rxc(esoc_port_nr) = '1' then
if esoc_rgmii_rxctl(esoc_port_nr) = '1' then
rx_state := '1';
byte(3 downto 0) := esoc_rgmii_rxd(esoc_port_nr*4+3 downto esoc_port_nr*4);
elsif rx_state = '1' then
rx_state := '0';
byte_counter := 0;
write(esoc_rgmii_rx_buffer,string'(""));
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
end if;
elsif esoc_rgmii_rxc(esoc_port_nr)'event and esoc_rgmii_rxc(esoc_port_nr) = '0' then
if esoc_rgmii_rxctl(esoc_port_nr) = '1' and rx_state = '1' then
byte(7 downto 4) := esoc_rgmii_rxd(esoc_port_nr*4+3 downto esoc_port_nr*4);
write(esoc_rgmii_rx_buffer, to_hexstring(byte) & " ");
if byte_counter = 15 then
byte_counter := 0;
writeline(esoc_rgmii_rx_log, esoc_rgmii_rx_buffer);
else
byte_counter := byte_counter + 1;
end if;
end if;
end if;
end process esoc_rgmii_rx_logging;
 
--=============================================================================================================
-- Process : store all packets on RGMII TX interfaces
-- Description :
--=============================================================================================================
esoc_rgmii_tx_logging: process(esoc_rgmii_txc_int, esoc_areset)
-- declare file for rgmii interface logging
file esoc_rgmii_tx_log : TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_tx_port_" & to_string(esoc_port_nr) & "_log.txt";
 
variable esoc_rgmii_tx_buffer: LINE;
variable byte: std_logic_vector(7 downto 0);
variable byte_counter: integer;
variable tx_state: std_logic;
begin
if esoc_areset = '1' then
byte_counter := 0;
tx_state := '0';
elsif esoc_rgmii_txc_int(esoc_port_nr)'event and esoc_rgmii_txc_int(esoc_port_nr) = '1' then
if esoc_rgmii_txctl(esoc_port_nr) = '1' then
tx_state := '1';
byte(3 downto 0) := esoc_rgmii_txd(esoc_port_nr*4+3 downto esoc_port_nr*4);
elsif tx_state = '1' then
tx_state := '0';
byte_counter := 0;
write(esoc_rgmii_tx_buffer,string'(""));
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
 
end if;
elsif esoc_rgmii_txc_int(esoc_port_nr)'event and esoc_rgmii_txc_int(esoc_port_nr) = '0' then
if esoc_rgmii_txctl(esoc_port_nr) = '1' and tx_state = '1' then
byte(7 downto 4) := esoc_rgmii_txd(esoc_port_nr*4+3 downto esoc_port_nr*4);
write(esoc_rgmii_tx_buffer, to_hexstring(byte) & " ");
if byte_counter = 15 then
byte_counter := 0;
writeline(esoc_rgmii_tx_log, esoc_rgmii_tx_buffer);
else
byte_counter := byte_counter + 1;
end if;
end if;
end if;
end process esoc_rgmii_tx_logging;
end generate esoc_test_rgmii_loggers;
esoc_test_smi: for esoc_port_nr in esoc_port_count-1 downto 0 generate
begin
 
esoc_test_smi: process (esoc_mdio, esoc_mdc, esoc_areset) is -- EASE/HDL sens.list
variable smi_cmd : std_logic_vector(1 downto 0);
variable smi_dev_addr : std_logic_vector(4 downto 0);
variable smi_dev_reg : std_logic_vector(4 downto 0);
variable smi_data : std_logic_vector(15 downto 0);
variable smi_counter : integer;
variable smi_registers: std_logic_vector(511 downto 0);
variable smi_state : smi_states;
begin
if esoc_areset = '1' then
smi_cmd := (others => '0');
smi_dev_addr := (others => '0');
smi_dev_reg := (others => '0');
smi_data := (others => '0');
smi_registers := (others => '0');
 
smi_mdio(esoc_port_nr) <= '0';
smi_mdio_ena(esoc_port_nr) <= '0';
smi_counter := 31;
smi_state := preamble;
elsif esoc_mdc(esoc_port_nr)'event and esoc_mdc(esoc_port_nr) = '1' then
case smi_state is
when preamble => -- detect preamble of 32 ones
if esoc_mdio(esoc_port_nr) = '1' then
if smi_counter = 0 then
smi_counter := 1;
smi_state := start;
else
smi_counter := smi_counter - 1;
end if;
else
smi_counter := 31;
end if;
when start => -- detect two start bits, if valid continue else back
if smi_counter = 1 then
if esoc_mdio(esoc_port_nr) = '0' then
smi_counter := smi_counter - 1;
end if;
elsif smi_counter = 0 then
if esoc_mdio(esoc_port_nr) = '1' then
smi_counter := 1;
smi_state := cmd;
else
smi_counter := 31;
smi_state := preamble;
end if;
end if;
when cmd => smi_cmd(smi_counter) := esoc_mdio(esoc_port_nr);
if smi_counter = 0 then
smi_counter := 4;
smi_state := dev_addr;
else
smi_counter := smi_counter - 1;
end if;
when dev_addr => smi_dev_addr(smi_counter) := esoc_mdio(esoc_port_nr);
if smi_counter = 0 then
smi_counter := 4;
smi_state := reg_addr;
else
smi_counter := smi_counter - 1;
end if;
when reg_addr => smi_dev_reg(smi_counter) := esoc_mdio(esoc_port_nr);
if smi_counter = 0 then
smi_counter := 1;
smi_state := ta_cycles;
else
smi_counter := smi_counter - 1;
end if;
when ta_cycles => -- check device address
if smi_dev_addr /= std_logic_vector(to_unsigned(esoc_port_nr,smi_dev_addr'length)) then
smi_counter := 31;
smi_state := preamble;
elsif smi_counter = 0 then
smi_mdio(esoc_port_nr) <= smi_data(smi_data'high);
smi_data := smi_data(smi_data'high-1 downto 0) & '0';
smi_counter := 15;
smi_state := data;
else
-- SMI Read, prepare
if smi_cmd = "10" then
smi_data := smi_registers((to_integer(unsigned(smi_dev_reg))*16)+15 downto (to_integer(unsigned(smi_dev_reg))*16));
smi_mdio(esoc_port_nr) <= '0';
smi_mdio_ena(esoc_port_nr) <= '1';
end if;
smi_counter := smi_counter - 1;
end if;
when data => -- SMI Read, provide data
if smi_cmd = "10" then
smi_mdio(esoc_port_nr) <= smi_data(smi_data'high);
smi_data := smi_data(smi_data'high-1 downto 0) & '0';
-- SMI Write, store data
else
smi_data := smi_data(smi_data'high-1 downto 0) & esoc_mdio(esoc_port_nr);
end if;
if smi_counter = 0 then
smi_counter := 31;
smi_mdio_ena(esoc_port_nr) <= '0';
-- SMI Read, return to preamble; SMI Write, store data
if smi_cmd = "10" then
smi_state := preamble;
else
smi_state := store;
end if;
else
smi_counter := smi_counter - 1;
end if;
when store => -- store received data
smi_registers((to_integer(unsigned(smi_dev_reg))*16)+15 downto (to_integer(unsigned(smi_dev_reg))*16)) := smi_data;
smi_state := preamble;
when others => smi_state := preamble;
end case;
end if;
end process esoc_test_smi ;
-- drive the mdio line when enabled
esoc_mdio(esoc_port_nr) <= smi_mdio(esoc_port_nr) when smi_mdio_ena(esoc_port_nr) = '1' else 'Z';
end generate esoc_test_smi;
esoc_tb: esoc
port map(
esoc_address => esoc_address,
esoc_areset => esoc_areset,
esoc_boot_complete => esoc_boot_complete,
esoc_clk => esoc_clk,
esoc_cs => esoc_cs,
esoc_data => esoc_data,
esoc_mdc => esoc_mdc,
esoc_mdio => esoc_mdio,
esoc_rd => esoc_rd,
esoc_rgmii_rxc => esoc_rgmii_rxc,
esoc_rgmii_rxctl => esoc_rgmii_rxctl,
esoc_rgmii_rxd => esoc_rgmii_rxd,
esoc_rgmii_txc => esoc_rgmii_txc,
esoc_rgmii_txctl => esoc_rgmii_txctl,
esoc_rgmii_txd => esoc_rgmii_txd,
esoc_wait => esoc_wait,
esoc_wr => esoc_wr);
 
 
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
esoc_test_control: process -- EASE/HDL sens.list
begin
wait;
end process esoc_test_control ;
--=============================================================================================================
-- Process : generate esoc input reset
-- Description :
--=============================================================================================================
esoc_reset: process
-- EASE/HDL sens.list
begin
esoc_areset <= '1';
wait for 1 us;
esoc_areset <= '0';
assert false report "ESOC Reset -> reset released" severity note;
wait;
end process esoc_reset ;
--=============================================================================================================
-- Process : generate esoc control input clock
-- Description :
--=============================================================================================================
esoc_ctrl_clock: process
-- EASE/HDL sens.list
begin
esoc_clk <= '1';
wait for 10 ns;
esoc_clk <= '0';
wait for 10 ns;
end process esoc_ctrl_clock ;
 
--=============================================================================================================
-- Process : generate input for the esoc control interface
-- Description :
--=============================================================================================================
esoc_ctrl: process
-- EASE/HDL sens.list
-- declare files for control interface stimuli and logging
file esoc_ctrl_out: TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_control_test_log.txt";
file esoc_ctrl_in : TEXT open READ_MODE is "../../Simulation/Scripts/esoc_control_test_stim.txt";
file esoc_control_auto_log : TEXT open APPEND_MODE is "../../Simulation/Logs/auto/esoc_control_auto_log.txt";
-- declare buffers for a complete line from file
variable esoc_ctrl_in_buffer: LINE;
variable esoc_ctrl_out_buffer: LINE;
variable esoc_control_auto_log_buffer: LINE;
-- define fields in a line (only white spaces before first field are skipped)
variable esoc_ctrl_in_id : string(7 downto 1);
variable esoc_ctrl_in_cmd : string(2 downto 1);
variable esoc_ctrl_in_addr: string(5 downto 1);
variable esoc_ctrl_in_val : string(9 downto 1);
variable esoc_ctrl_out_val : string(9 downto 1);
variable esoc_ctrl_in_info : string(40 downto 1);
variable esoc_ctrl_wait : integer;
variable error_counter: integer;
begin
-- init control interface inputs
esoc_cs <= '0';
esoc_wr <= '0';
esoc_rd <= '0';
esoc_address <= (others => '0');
esoc_data <= (others => 'Z');
esoc_wait_timer_start <= '0';
error_counter := 0;
-- wait for de-assertion of external reset
wait until esoc_areset = '0';
-- wait for assertion of boot status
wait until esoc_boot_complete = '1';
wait for 1 us;
-- read stimuli ID
readline(esoc_ctrl_in, esoc_ctrl_in_buffer);
read(esoc_ctrl_in_buffer, esoc_ctrl_in_cmd);
read(esoc_ctrl_in_buffer, esoc_ctrl_in_id);
 
-- start access on control interface
assert false report "ESOC Control -> generate read/write cycles on control interface" severity note;
write(esoc_ctrl_out_buffer, string'("ESOC Control -> start generating read/write cycles on control interface"));
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
-- read file until end of file is reached
loop
exit when endfile(esoc_ctrl_in);
-- read command before reading the arguments
readline(esoc_ctrl_in, esoc_ctrl_in_buffer);
read(esoc_ctrl_in_buffer, esoc_ctrl_in_cmd);
--
-- start WRITE CYCLE
--
if esoc_ctrl_in_cmd = "mw" then
-- read address and data from file
read(esoc_ctrl_in_buffer, esoc_ctrl_in_addr);
read(esoc_ctrl_in_buffer, esoc_ctrl_in_val);
-- drive the control interface
wait for 30 ns;
esoc_cs <= '1';
esoc_wr <= '1';
esoc_address <= hex_string_to_std_logic_vector(esoc_ctrl_in_addr(4 downto 1));
esoc_data <= hex_string_to_std_logic_vector(esoc_ctrl_in_val(8 downto 1));
-- enable timer to avoid lockup
esoc_wait_timer_start <= '1';
wait until esoc_wait = '0' or esoc_wait_timeout = '1';
-- check for timeout
if esoc_wait_timeout = '0' then
esoc_wait_timer_start <= '0';
end if;
-- finalize cycle
wait for 20 ns;
esoc_cs <= '0';
esoc_wr <= '0';
esoc_data <= (others => 'Z');
-- report time out
if esoc_wait_timeout = '1' then
esoc_wait_timer_start <= '0';
-- write control bus access to output file
assert false report "ESOC Control -> write to address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, status: TIMEOUT" severity error;
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", status: TIMEOUT");
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
else
-- write control bus access to output file
assert false report "ESOC Control -> write" & esoc_ctrl_in_val & "h" & " to address" & esoc_ctrl_in_addr & "h" severity note;
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_in_val);
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
end if;
--
-- start READ CYCLE
--
elsif esoc_ctrl_in_cmd = "mr" then
-- read address and data from file
read(esoc_ctrl_in_buffer, esoc_ctrl_in_addr);
read(esoc_ctrl_in_buffer, esoc_ctrl_in_val);
-- drive the control interface
wait for 30 ns;
esoc_cs <= '1';
esoc_rd <= '1';
esoc_address <= hex_string_to_std_logic_vector(esoc_ctrl_in_addr(4 downto 1));
-- enable timer to avoid lockup
esoc_wait_timer_start <= '1';
wait until esoc_wait = '0' or esoc_wait_timeout = '1';
-- check for timeout
if esoc_wait_timeout = '0' then
esoc_wait_timer_start <= '0';
end if;
-- finalize cycle
wait for 20 ns;
esoc_cs <= '0';
esoc_rd <= '0';
-- store read data, add space in front to be able to compare to expected value from file
esoc_ctrl_out_val(8 downto 1) := to_hexstring(esoc_data);
esoc_ctrl_out_val := " " & esoc_ctrl_out_val(8 downto 1);
-- check expected read value with actual read value or report time out
if esoc_wait_timeout = '1' then
esoc_wait_timer_start <= '0';
-- write control bus access to output file
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & ", status: TIMEOUT" severity error;
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", status: TIMEOUT");
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
elsif esoc_ctrl_in_val = esoc_ctrl_out_val then
-- write control bus access to output file
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & esoc_ctrl_in_val & "h, status: OK" severity note;
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", expected" & esoc_ctrl_in_val & ", status: OK");
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
else
-- write control bus access to output file
assert false report "ESOC Control -> read from address" & esoc_ctrl_in_addr & "h" & esoc_ctrl_out_val & "h, expected" & esoc_ctrl_in_val & "h, status: ERROR" severity note;
write(esoc_ctrl_out_buffer, esoc_ctrl_in_cmd & esoc_ctrl_in_addr & esoc_ctrl_out_val & ", expected" & esoc_ctrl_in_val & ", status: ERROR");
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
error_counter := error_counter + 1;
end if;
--
-- create delay
--
elsif esoc_ctrl_in_cmd = "wt" then
read(esoc_ctrl_in_buffer, esoc_ctrl_wait);
for i in esoc_ctrl_wait downto 0 loop
wait until esoc_clk'event and esoc_clk = '1';
end loop;
--
-- process information
--
elsif esoc_ctrl_in_cmd = "--" then
writeline(esoc_ctrl_out, esoc_ctrl_in_buffer);
-- ignore other commands
else
assert false report "ESOC Control -> illegal command for read/write cycles on control interface" severity error;
write(esoc_ctrl_out_buffer, string'("ESOC Control -> illegal command for read/write cycles on control interface"));
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
end if;
end loop;
if error_counter = 1 then
assert false report "ESOC Control -> end of stimuli for control interface (" & to_string(error_counter,10) & " error)" severity note;
else
assert false report "ESOC Control -> end of stimuli for control interface (" & to_string(error_counter,10) & " errors)" severity note;
end if;
--write(esoc_ctrl_out_buffer, string'("ESOC Control -> end of stimuli for control interface")& error_counter & " errors)");
write(esoc_ctrl_out_buffer, string'("ESOC Control -> end of stimuli for control interface (") & to_string(error_counter,10) & " errors)");
writeline(esoc_ctrl_out, esoc_ctrl_out_buffer);
write(esoc_control_auto_log_buffer, "Test script" & esoc_ctrl_in_id & " - " & to_string(error_counter,10) & " errors");
writeline(esoc_control_auto_log, esoc_control_auto_log_buffer);
wait;
end process esoc_ctrl ;
 
--=============================================================================================================
-- Process : start timer when previous process waits for signal from esoc
-- Description :
--=============================================================================================================
esoc_ctrl_timer: process (esoc_areset, esoc_clk)
begin
if esoc_areset = '1' then
esoc_wait_timer <= 3000;
esoc_wait_timeout <= '0';
esoc_wait_time_enable <= '1';
elsif esoc_clk = '1' and esoc_clk'event then
if esoc_wait_time_enable = '1' then
-- start timer on command of read/write process
if esoc_wait_timer_start = '1' then
-- assert time out signal when timer expires
if esoc_wait_timer = 0 then
esoc_wait_timeout <= '1';
else
esoc_wait_timer <= esoc_wait_timer - 1;
end if;
-- reset timer settings when timer is stopped by read/write process
else
esoc_wait_timeout <= '0';
esoc_wait_timer <= 3000;
end if;
end if;
end if;
end process esoc_ctrl_timer;
 
 
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
esoc_test_rgmii: process -- EASE/HDL sens.list
begin
wait;
end process esoc_test_rgmii ;
--=============================================================================================================
-- Process : generate esoc rgmii input clock
-- Description :
--=============================================================================================================
esoc_rgmii_clock: process
-- EASE/HDL sens.list
begin
-- create internal and external RGMII clock, phase shift of 90 degrees
for i in esoc_port_count-1 downto 0 loop
esoc_rgmii_rxc_int <= '1';
esoc_rgmii_rxc(i) <= '1' after 2 ns;
end loop;
wait for 4 ns;
for i in esoc_port_count-1 downto 0 loop
esoc_rgmii_rxc_int <= '0';
esoc_rgmii_rxc(i) <= '0' after 2 ns;
end loop;
wait for 4 ns;
end process esoc_rgmii_clock ;
 
--=============================================================================================================
-- Process : access registers of testbench
-- Description :
--=============================================================================================================
registers: process(esoc_areset, esoc_cs, esoc_rd, esoc_wr)
variable esoc_rd_pending: std_logic;
variable esoc_wr_pending: std_logic;
begin
if esoc_areset = '1' then
reg_rgmii_port_enable <= (others => '0');
esoc_wait <= 'Z';
esoc_data <= (others => 'Z');
esoc_rd_pending := '0';
esoc_wr_pending := '0';
-- continu if memory space of this entity is addressed
elsif to_integer(unsigned(esoc_address)) >= esoc_testbench_base and to_integer(unsigned(esoc_address)) < esoc_testbench_base + esoc_testbench_size then
--
-- READ CYCLE started, unit addressed?
--
if esoc_cs = '1' and esoc_rd = '1' and esoc_rd_pending = '0' then
-- Check register address and provide data when addressed
case to_integer(unsigned(esoc_address)) - esoc_testbench_base is
when 0 => esoc_data <= reg_rgmii_port_enable after 40 ns;
when others => esoc_data <= (others => '0');
end case;
esoc_rd_pending := '1';
esoc_wait <= '0' after 40 ns;
-- wait until cycle is finished
elsif esoc_cs = '0' and esoc_rd = '0' and esoc_rd_pending = '1' then
esoc_rd_pending := '0';
-- finalize cycle
esoc_wait <= 'Z' after 20 ns;
esoc_data <= (others => 'Z') after 20 ns;
--
-- WRITE CYCLE started, unit addressed?
--
elsif esoc_cs = '1' and esoc_wr = '1' and esoc_wr_pending = '0' then
-- Check register address and accept data when addressed
case to_integer(unsigned(esoc_address)) - esoc_testbench_base is
when 0 => reg_rgmii_port_enable <= esoc_data;
when others => NULL;
end case;
esoc_wr_pending := '1';
esoc_wait <= '0' after 40 ns;
 
-- wait until cycle is finished
elsif esoc_cs = '0' and esoc_wr = '0' and esoc_wr_pending = '1' then
-- finalize cycle
esoc_wr_pending := '0';
esoc_wait <= 'Z' after 20 ns;
end if;
end if;
end process;
--=============================================================================================================
-- Process : fill packet transmit buffers for all ports
-- Description :
--=============================================================================================================
esoc_rgmii_tx: process
-- declare files for rgmii interface stimuli and logging
file esoc_rgmii_in : TEXT open READ_MODE is "../../Simulation/Scripts/esoc_rgmii_test_stim.txt";
file esoc_rgmii_out: TEXT open WRITE_MODE is "../../Simulation/Logs/esoc_rgmii_test_log.txt";
-- declare buffer for a complete line from file
variable esoc_rgmii_in_buffer: LINE;
variable esoc_rgmii_out_buffer: LINE;
-- define fields in a line
variable esoc_rgmii_in_port : string(2 downto 1);
variable esoc_rgmii_in_dmac : string(12 downto 1);
variable esoc_rgmii_in_smac : string(12 downto 1);
variable esoc_rgmii_in_vid : string(8 downto 1);
variable esoc_rgmii_in_type : string(4 downto 1);
variable esoc_rgmii_in_plen : string(4 downto 1);
variable esoc_rgmii_in_pstart : string(2 downto 1);
variable esoc_rgmii_in_gap : string(8 downto 1);
variable esoc_rgmii_in_white_space : string(1 downto 1);
variable esoc_rgmii_in_wait : integer;
-- create packet buffers for all ports (use variable to avoid slow simulations)
constant packet_buffer_size : integer := 64*1024;
type packet_buffer_array is array (esoc_port_count-1 downto 0, packet_buffer_size-1 downto 0) of std_logic_vector(8 downto 0);
variable packet_buffers : packet_buffer_array;
constant pck_type_ipg: std_logic := '0';
constant pck_type_pck: std_logic := '1';
-- create packet counter for all ports (use variable to avoid slow simulations)
type packet_buffer_bytes_array is array (esoc_port_count-1 downto 0) of integer;
variable packet_buffer_bytes : packet_buffer_bytes_array;
variable packet_buffer_bytes_sent : packet_buffer_bytes_array;
-- create inter packet gap counter for all ports (use variable to avoid slow simulations)
type packet_ipg_array is array (esoc_port_count-1 downto 0) of integer;
variable packet_ipg : packet_ipg_array;
-- signals and variables for inside process
variable esoc_rgmii_port : integer;
variable esoc_rgmii_count : integer;
variable esoc_rgmii_data : std_logic_vector(47 downto 0);
variable esoc_rgmii_crc : std_logic_vector(31 downto 0);
begin
--
-- initialize signals, buffers and clear counters
--
for i in esoc_port_count-1 downto 0 loop
packet_buffer_bytes(i) := 0;
packet_buffer_bytes_sent(i) := 0;
esoc_rgmii_rxctl(i) <= '0';
esoc_rgmii_rxd(i*4+3 downto i*4) <= (others => '0');
packet_ipg(i) := 0;
for j in packet_buffer_size-1 downto 0 loop
packet_buffers(i,j) := '0' & X"00";
end loop;
end loop;
reg_rgmii_port_enable2 <= (others => '0');
-- wait for de-assertion of external reset
wait until esoc_areset = '0';
wait for 1 us;
--
-- start preprocessing of Ethernet packets
--
assert false report "ESOC RGMII Preprocessing -> start of processing stimuli for RGMII interfaces" severity note;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> start of processng stimuli for RGMII interfaces"));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
loop
exit when endfile(esoc_rgmii_in);
-- read packet information, read away the post white space
readline(esoc_rgmii_in, esoc_rgmii_in_buffer);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_port);
-- skip comment
if esoc_rgmii_in_port = "--" then
-- check packet information
elsif to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_port))) > esoc_port_count-1 then
assert false report "ESOC RGMII Preprocessing -> " & esoc_rgmii_in_port & " is illegal port number in RGMII stimuli (max ESOC Port count is " & to_string(esoc_port_count-1, 10) & ")" severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> " & esoc_rgmii_in_port & " is illegal port number in RGMII stimuli (max ESOC Port count is " & to_string(esoc_port_count-1, 10) & ")");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
-- write packet into buffer of correct port
else
-- read packet information, read away the pre white space
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_dmac);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_smac);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_vid);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_type);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_plen);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_pstart);
read(esoc_rgmii_in_buffer, esoc_rgmii_in_white_space); read(esoc_rgmii_in_buffer, esoc_rgmii_in_gap);
-- convert port number to have index inside the buffer and counter arrays, counter itself is also index inside buffer array
esoc_rgmii_port := to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_port)));
-- store current value of byte counter of port before new packet is written
esoc_rgmii_count := packet_buffer_bytes(esoc_rgmii_port);
-- reset CRC storage
esoc_rgmii_crc := (others => '0');
-- store preamble and SFD
for i in 7 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
-- write sfd as last byte, write preamble bytes before
if i = 0 then
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & X"D5";
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & X"55";
end if;
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
end if;
end loop;
-- store DMAC in buffer
esoc_rgmii_data := hex_string_to_std_logic_vector(esoc_rgmii_in_dmac);
for i in 5 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
-- invert first four bytes of packet (32 bits of DMAC) before CRC calculation
if i > 1 then
esoc_rgmii_data(i*8+7 downto i*8) := INVERT_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
end if;
-- swap bit order in accordance with bit order at physical interface before CRC calculation
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
end if;
end loop;
-- store SMAC in buffer
esoc_rgmii_data := hex_string_to_std_logic_vector(esoc_rgmii_in_smac);
for i in 5 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
-- swap bit order in accordance with bit order at physical interface before CRC calculation
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
end if;
end loop;
-- store VID in buffer (0x8100**** is VLAN tagged packet)
esoc_rgmii_data(31 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_vid);
if esoc_rgmii_data(31 downto 16) = X"8100" then
for i in 3 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
-- swap bit order in accordance with bit order at physical interface before CRC calculation
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
end if;
end loop;
end if;
-- store TYPE/LEN in buffer
esoc_rgmii_data(15 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_type);
for i in 1 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
-- swap bit order in accordance with bit order at physical interface before CRC calculation
esoc_rgmii_data(i*8+7 downto i*8) := SWAP_CRC32_DATA(esoc_rgmii_data(i*8+7 downto i*8));
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(i*8+7 downto i*8),esoc_rgmii_crc);
end if;
end loop;
 
-- store payload (if length is sufficient)
if to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_plen))) < 46 then
assert false report "ESOC RGMII Preprocessing -> payload field too short, should be at least 46 bytes." severity error;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> payload field too short, should be at least 46 bytes."));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
esoc_rgmii_data(7 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_pstart);
for i in to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_plen)))-1 downto 0 loop
-- check and update byte counter related to the port, store data if space available, update crc
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(7 downto 0);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
-- swap bit order in accordance with bit order at physical interface before CRC calculation
esoc_rgmii_data(7 downto 0) := SWAP_CRC32_DATA(esoc_rgmii_data(7 downto 0));
esoc_rgmii_crc := CALC_CRC32(esoc_rgmii_data(7 downto 0),esoc_rgmii_crc);
esoc_rgmii_data(7 downto 0) := SWAP_CRC32_DATA(esoc_rgmii_data(7 downto 0));
end if;
esoc_rgmii_data(7 downto 0) := std_logic_vector(to_unsigned(to_integer(unsigned(esoc_rgmii_data(7 downto 0)))+1, 8));
end loop;
end if;
-- store CRC, invert and change order before ...
esoc_rgmii_crc := SWAP_CRC32_RESULT(esoc_rgmii_crc);
esoc_rgmii_crc := INVERT_CRC32_RESULT(esoc_rgmii_crc);
esoc_rgmii_data(31 downto 0) := esoc_rgmii_crc;
for i in 3 downto 0 loop
-- check and update byte counter related to the port, store data if space available
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_pck & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
end if;
end loop;
-- store GAP (if length is sufficient)
esoc_rgmii_data(31 downto 0) := hex_string_to_std_logic_vector(esoc_rgmii_in_gap);
if to_integer(unsigned(hex_string_to_std_logic_vector(esoc_rgmii_in_gap))) < 12 then
assert false report "ESOC RGMII Preprocessing -> Inter Packet Gap too short, should be at least 12 bytes." severity error;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> Inter Packet Gap too short, should be at least 12 bytes."));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
for i in 3 downto 0 loop
-- check and update byte counter related to the port, store data if space available
if packet_buffer_bytes(esoc_rgmii_port) = packet_buffer_size then
assert false report "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded." severity error;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet buffer for port " & esoc_rgmii_in_port & "overloaded.");
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
else
packet_buffers(esoc_rgmii_port, packet_buffer_bytes(esoc_rgmii_port)) := pck_type_ipg & esoc_rgmii_data(i*8+7 downto i*8);
packet_buffer_bytes(esoc_rgmii_port) := packet_buffer_bytes(esoc_rgmii_port) + 1;
end if;
end loop;
end if;
-- log packet information in file
assert false report "ESOC RGMII Preprocessing -> packet with length of " & to_string(packet_buffer_bytes(esoc_rgmii_port) - esoc_rgmii_count) & " bytes written to port " & esoc_rgmii_in_port severity note;
assert false report "ESOC RGMII Preprocessing -> packet details -> dmac: 0x" & esoc_rgmii_in_dmac & " smac: 0x" & esoc_rgmii_in_smac & " vid: 0x" & esoc_rgmii_in_vid & " type: 0x" & esoc_rgmii_in_type & " plen: 0x" & esoc_rgmii_in_plen & " pstart: 0x" & esoc_rgmii_in_pstart & " crc: 0x" & to_hexstring(esoc_rgmii_crc) & " ipg: 0x" & esoc_rgmii_in_gap severity note;
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet with length of " & to_string(packet_buffer_bytes(esoc_rgmii_port) - esoc_rgmii_count) & " bytes written to port " & esoc_rgmii_in_port);
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
write(esoc_rgmii_out_buffer, "ESOC RGMII Preprocessing -> packet details -> dmac: 0x" & esoc_rgmii_in_dmac & " smac: 0x" & esoc_rgmii_in_smac & " vid: 0x" & esoc_rgmii_in_vid & " type: 0x" & esoc_rgmii_in_type & " plen: 0x" & esoc_rgmii_in_plen & " pstart: 0x" & esoc_rgmii_in_pstart & " crc: 0x" & to_hexstring(esoc_rgmii_crc) & " ipg: 0x" & esoc_rgmii_in_gap);
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
end if;
end loop;
 
assert false report "ESOC RGMII Preprocessing -> end of processing stimuli for RGMII interfaces" severity note;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Preprocessing -> end of processng stimuli for RGMII interfaces"));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
write(esoc_rgmii_out_buffer, string'(""));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
--
-- start transmitting of Ethernet packets
--
assert false report "ESOC RGMII Transmit -> start of transmitting stimuli to RGMII interfaces" severity note;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Transmit -> start of transmitting stimuli to RGMII interfaces"));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
while true loop
-- get data for each port from their buffer and send on rising edge
wait until esoc_rgmii_rxc_int'event and esoc_rgmii_rxc_int = '1';
for i in esoc_port_count-1 downto 0 loop
reg_rgmii_port_enable2(i) <= reg_rgmii_port_enable(i);
-- check whether the port is enabled or not
if reg_rgmii_port_enable(i) = '1' then
-- check whether there are still bytes to send
if packet_buffer_bytes_sent(i) < packet_buffer_bytes(i) then
-- start inter packet gap delay period?
if packet_buffers(i,packet_buffer_bytes_sent(i))(8) = pck_type_ipg and packet_ipg(i) = 0 then
esoc_rgmii_rxd(i*4+3 downto i*4) <= X"0";
esoc_rgmii_rxctl(i) <= '0';
packet_ipg(i) := to_integer(unsigned(packet_buffers(i,packet_buffer_bytes_sent(i))(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+1)(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+2)(7 downto 0) & packet_buffers(i,packet_buffer_bytes_sent(i)+3)(7 downto 0)));
packet_buffer_bytes_sent(i) := packet_buffer_bytes_sent(i) + 4;
-- inter packet gap delay passed?
elsif packet_ipg(i) /= 0 then
-- inter packet gap delay passed, send data
else
esoc_rgmii_rxd(i*4+3 downto i*4) <= packet_buffers(i,packet_buffer_bytes_sent(i))(3 downto 0);
esoc_rgmii_rxctl(i) <= '1';
end if;
end if;
end if;
end loop;
-- get data for each port from their buffer and send on falling edge
wait until esoc_rgmii_rxc_int'event and esoc_rgmii_rxc_int = '0';
for i in esoc_port_count-1 downto 0 loop
-- check whether the port is enabled or not
if reg_rgmii_port_enable2(i) = pck_type_pck then
-- check whether there are still bytes to send
if packet_buffer_bytes_sent(i) < packet_buffer_bytes(i) then
-- inter packet gap delay passed?
if packet_ipg(i) /= 0 then
packet_ipg(i) := packet_ipg(i) - 1;
-- inter packet gap delay passed, send data
else
esoc_rgmii_rxd(i*4+3 downto i*4) <= packet_buffers(i,packet_buffer_bytes_sent(i))(7 downto 4);
packet_buffer_bytes_sent(i) := packet_buffer_bytes_sent(i) + 1;
end if;
end if;
end if;
end loop;
end loop;
assert false report "ESOC RGMII Transmit -> end of transmitting stimuli to RGMII interfaces" severity note;
write(esoc_rgmii_out_buffer, string'("ESOC RGMII Transmit -> end of transmitting stimuli to RGMII interfaces"));
writeline(esoc_rgmii_out, esoc_rgmii_out_buffer);
wait;
end process esoc_rgmii_tx;
end architecture esoc_tb ; -- of esoc_tb
 
/trunk/Sources/package_crc32_8b.vhd
0,0 → 1,173
--------------------------------------------------------------------------------
-- Object : Package work.package_crc32_8b
-- Last modified : Thu Oct 10 12:37:58 2013.
--------------------------------------------------------------------------------
 
 
 
library ieee, std;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
---------------------------------------------------------------------------------------------------------------
-- Package declaration
---------------------------------------------------------------------------------------------------------------
package package_crc32_8b is
 
-----------------------------------------------------------------------------------------
-- functions to invert data/CRC (data: only applicable for the first 32 bits of a packet)
-----------------------------------------------------------------------------------------
function INVERT_CRC32_DATA
(din : std_logic_vector(7 downto 0))
return std_logic_vector;
function INVERT_CRC32_RESULT
(din : std_logic_vector(31 downto 0))
return std_logic_vector;
-------------------------------------------------------------------------
-- functions to swap bit order due to bit order on physical interface
-------------------------------------------------------------------------
function SWAP_CRC32_DATA
(din : std_logic_vector(7 downto 0))
return std_logic_vector;
function SWAP_CRC32_RESULT
(din : std_logic_vector(31 downto 0))
return std_logic_vector;
-------------------------------------------------------------------------
-- functions to calculate CRC on the fly
-------------------------------------------------------------------------
function CALC_CRC32
(din : std_logic_vector(7 downto 0);
cin : std_logic_vector(31 downto 0))
return std_logic_vector;
end package_crc32_8b;
 
package body package_crc32_8b is
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function INVERT_CRC32_DATA
(din : std_logic_vector(7 downto 0))
return std_logic_vector is
begin
return not(din);
end INVERT_CRC32_DATA;
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function INVERT_CRC32_RESULT
(din : std_logic_vector(31 downto 0))
return std_logic_vector is
begin
return not(din);
end INVERT_CRC32_RESULT;
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function SWAP_CRC32_DATA
(din : std_logic_vector(7 downto 0))
return std_logic_vector is
 
variable d : std_logic_vector(7 downto 0);
begin
d(7) := din(0);
d(6) := din(1);
d(5) := din(2);
d(4) := din(3);
d(3) := din(4);
d(2) := din(5);
d(1) := din(6);
d(0) := din(7);
return d;
end SWAP_CRC32_DATA;
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function SWAP_CRC32_RESULT
(din : std_logic_vector(31 downto 0))
return std_logic_vector is
variable d : std_logic_vector(31 downto 0);
begin
for i in 3 downto 0 loop
d(i*8+7) := din(i*8);
d(i*8+6) := din(i*8+1);
d(i*8+5) := din(i*8+2);
d(i*8+4) := din(i*8+3);
d(i*8+3) := din(i*8+4);
d(i*8+2) := din(i*8+5);
d(i*8+1) := din(i*8+6);
d(i*8+0) := din(i*8+7);
end loop;
return d;
end SWAP_CRC32_RESULT;
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
function CALC_CRC32
(din : std_logic_vector(7 downto 0);
cin : std_logic_vector(31 downto 0))
return std_logic_vector is
 
variable d : std_logic_vector(7 downto 0);
variable c : std_logic_vector(31 downto 0);
variable cout: std_logic_vector(31 downto 0);
 
begin
d := din;
c := cin;
cout(0) := d(6) xor d(0) xor c(24) xor c(30);
cout(1) := d(7) xor d(6) xor d(1) xor d(0) xor c(24) xor c(25) xor c(30) xor c(31);
cout(2) := d(7) xor d(6) xor d(2) xor d(1) xor d(0) xor c(24) xor c(25) xor c(26) xor c(30) xor c(31);
cout(3) := d(7) xor d(3) xor d(2) xor d(1) xor c(25) xor c(26) xor c(27) xor c(31);
cout(4) := d(6) xor d(4) xor d(3) xor d(2) xor d(0) xor c(24) xor c(26) xor c(27) xor c(28) xor c(30);
cout(5) := d(7) xor d(6) xor d(5) xor d(4) xor d(3) xor d(1) xor d(0) xor c(24) xor c(25) xor c(27) xor c(28) xor c(29) xor c(30) xor c(31);
cout(6) := d(7) xor d(6) xor d(5) xor d(4) xor d(2) xor d(1) xor c(25) xor c(26) xor c(28) xor c(29) xor c(30) xor c(31);
cout(7) := d(7) xor d(5) xor d(3) xor d(2) xor d(0) xor c(24) xor c(26) xor c(27) xor c(29) xor c(31);
cout(8) := d(4) xor d(3) xor d(1) xor d(0) xor c(0) xor c(24) xor c(25) xor c(27) xor c(28);
cout(9) := d(5) xor d(4) xor d(2) xor d(1) xor c(1) xor c(25) xor c(26) xor c(28) xor c(29);
cout(10) := d(5) xor d(3) xor d(2) xor d(0) xor c(2) xor c(24) xor c(26) xor c(27) xor c(29);
cout(11) := d(4) xor d(3) xor d(1) xor d(0) xor c(3) xor c(24) xor c(25) xor c(27) xor c(28);
cout(12) := d(6) xor d(5) xor d(4) xor d(2) xor d(1) xor d(0) xor c(4) xor c(24) xor c(25) xor c(26) xor c(28) xor c(29) xor c(30);
cout(13) := d(7) xor d(6) xor d(5) xor d(3) xor d(2) xor d(1) xor c(5) xor c(25) xor c(26) xor c(27) xor c(29) xor c(30) xor c(31);
cout(14) := d(7) xor d(6) xor d(4) xor d(3) xor d(2) xor c(6) xor c(26) xor c(27) xor c(28) xor c(30) xor c(31);
cout(15) := d(7) xor d(5) xor d(4) xor d(3) xor c(7) xor c(27) xor c(28) xor c(29) xor c(31);
cout(16) := d(5) xor d(4) xor d(0) xor c(8) xor c(24) xor c(28) xor c(29);
cout(17) := d(6) xor d(5) xor d(1) xor c(9) xor c(25) xor c(29) xor c(30);
cout(18) := d(7) xor d(6) xor d(2) xor c(10) xor c(26) xor c(30) xor c(31);
cout(19) := d(7) xor d(3) xor c(11) xor c(27) xor c(31);
cout(20) := d(4) xor c(12) xor c(28);
cout(21) := d(5) xor c(13) xor c(29);
cout(22) := d(0) xor c(14) xor c(24);
cout(23) := d(6) xor d(1) xor d(0) xor c(15) xor c(24) xor c(25) xor c(30);
cout(24) := d(7) xor d(2) xor d(1) xor c(16) xor c(25) xor c(26) xor c(31);
cout(25) := d(3) xor d(2) xor c(17) xor c(26) xor c(27);
cout(26) := d(6) xor d(4) xor d(3) xor d(0) xor c(18) xor c(24) xor c(27) xor c(28) xor c(30);
cout(27) := d(7) xor d(5) xor d(4) xor d(1) xor c(19) xor c(25) xor c(28) xor c(29) xor c(31);
cout(28) := d(6) xor d(5) xor d(2) xor c(20) xor c(26) xor c(29) xor c(30);
cout(29) := d(7) xor d(6) xor d(3) xor c(21) xor c(27) xor c(30) xor c(31);
cout(30) := d(7) xor d(4) xor c(22) xor c(28) xor c(31);
cout(31) := d(5) xor c(23) xor c(29);
return cout;
end CALC_CRC32;
 
end package_crc32_8b;
/trunk/Sources/esoc_port_processor_search.vhd
0,0 → 1,196
--------------------------------------------------------------------------------
---- ----
---- 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_search
-- Last modified : Mon Apr 14 12:49:39 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_search is
generic(
esoc_port_nr : integer := 0);
port(
clk_search : in std_logic;
inbound_header : in std_logic_vector(111 downto 0);
inbound_header_empty : in std_logic;
inbound_header_read : out std_logic;
inbound_vlan_member : in STD_LOGIC_VECTOR(0 downto 0);
reset : in std_logic;
search_data : out STD_LOGIC_VECTOR(15 downto 0);
search_done_cnt : out std_logic;
search_drop_cnt : out std_logic;
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic;
search_write : out STD_LOGIC);
end entity esoc_port_processor_search;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_processor_search.esoc_port_processor_search
-- Last modified : Mon Apr 14 12:49:39 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_processor_search of esoc_port_processor_search is
 
type search_states is (idle, send_key_1, send_key_2, wait_for_result);
signal search_state: search_states;
 
signal search_sof_o: std_logic;
signal search_eof_o: std_logic;
signal search_key_o: std_logic_vector(search_key'high downto 0);
 
signal inbound_header_empty_i: std_logic;
 
begin
 
-- control the shared bus to the search engine
search_sof <= search_sof_o when search_gnt_wr = '1' else 'Z';
search_eof <= search_eof_o when search_gnt_wr = '1' else 'Z';
search_key <= search_key_o when search_gnt_wr = '1' else (others => 'Z');
 
--=============================================================================================================
-- Process :
-- Description :
--=============================================================================================================
debug: process(clk_search, reset)
begin
if reset = '1' then
inbound_header_read <= '0';
inbound_header_empty_i <= '0';
search_req <= '0';
search_sof_o <= '0';
search_eof_o <= '0';
search_key_o <= (others => '0');
search_data <= (others => '0');
search_write <= '0';
search_done_cnt <= '0';
search_drop_cnt <= '0';
search_state <= idle;
elsif clk_search'event and clk_search = '1' then
-- reset one clock active signals
search_eof_o <= '0';
search_done_cnt <= '0';
search_drop_cnt <= '0';
search_write <= '0';
inbound_header_read <= '0';
-- delay the empty signal to proces the VLAN membership of the first packet correctly. When the header
-- data of first packet is written in de header FIFO the empty signal deasserts, but in parallel (outside
-- this entity) the VLAN ID RAM is addressed. This entity detects the deasserted EMTPY signal and expects
-- the corresponding VLAN membership info from the VLAN ID RAM, which is not available at that time!
-- This is only applicable if the first header in the FIFO is from a tagged packet and the EMPTY latency of the
-- FIFO is 0, the latter is not the case for Altera, so you can skip this delay by using the inbound_header_empty
-- iso. the inbound_header_empty_i signal in the search_state idle .... check simulation!
inbound_header_empty_i <= inbound_header_empty;
case search_state is
when idle => -- used to insert a clock delay
search_state <= send_key_1;
when send_key_1 => -- check for new header data,new header data means new packet is coming or already available
if inbound_header_empty = '0' then
-- Is the inbound port member of the VID of the tagged packet or
-- is the packet untagged and does the switch use the port default VID?
if inbound_header(esoc_inbound_header_vlan_flag) = '0' or inbound_vlan_member = "1" then
-- Request bus to the search engine, prepare to transfer VID and DA
search_req <= '1';
search_sof_o <= '1';
search_key_o(esoc_search_bus_vlan+11 downto esoc_search_bus_vlan) <= inbound_header(esoc_inbound_header_vlan+11 downto esoc_inbound_header_vlan);
search_key_o(esoc_search_bus_mac+47 downto esoc_search_bus_mac) <= inbound_header(esoc_inbound_header_dmac_lo+47 downto esoc_inbound_header_dmac_lo);
search_state <= send_key_2;
-- Packet is tagged and the inbound port is not member of the packet VID
else
-- Write destination port (none) and acknowledge header data
search_data <= (others => '0');
search_write <= '1';
inbound_header_read <= '1';
search_drop_cnt <= '1';
search_state <= idle;
end if;
end if;
when send_key_2 => -- VID and DA Address accepted when granted, provide Port Number and SA Address for learning process
if search_gnt_wr = '1' then
search_key_o(esoc_search_bus_sport+15 downto esoc_search_bus_sport) <= (others => '0');
search_key_o(esoc_search_bus_sport+esoc_port_nr) <= '1';
search_key_o(esoc_search_bus_mac+47 downto esoc_search_bus_mac) <= inbound_header(esoc_inbound_header_smac_lo+47 downto esoc_inbound_header_smac_lo);
search_sof_o <= '0';
inbound_header_read <= '1';
search_state <= wait_for_result;
end if;
when wait_for_result => -- Wait for result from search engine
if search_result_av = '1' then
-- Write destination ports, skip your self, acknowledge header data
search_data(search_result'high downto 0) <= search_result;
search_data(esoc_port_nr) <= '0';
search_write <= '1';
search_done_cnt <= '1';
search_req <= '0';
search_eof_o <= '1';
search_state <= send_key_1;
end if;
when others => search_state <= idle;
end case;
end if;
end process;
end architecture esoc_port_processor_search ; -- of esoc_port_processor_search
 
/trunk/Sources/esoc_port_storage.vhd
0,0 → 1,267
--------------------------------------------------------------------------------
---- ----
---- 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_storage
-- Last modified : Mon Apr 14 12:49:43 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_storage is
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
inbound_port_data : in std_logic_vector(31 downto 0);
inbound_port_data_full : out std_logic;
inbound_port_data_write : in std_logic;
inbound_port_header : in std_logic_vector(111 downto 0);
inbound_port_header_write : in std_logic;
inbound_port_info : in std_logic_vector(31 downto 0);
inbound_port_info_write : in std_logic;
inbound_proc_data : out std_logic_vector(63 downto 0);
inbound_proc_data_full : out std_logic;
inbound_proc_data_read : in std_logic;
inbound_proc_header : out std_logic_vector(111 downto 0);
inbound_proc_header_empty : out std_logic;
inbound_proc_header_read : in std_logic;
inbound_proc_info : out std_logic_vector(31 downto 0);
inbound_proc_info_empty : out std_logic;
inbound_proc_info_read : in std_logic;
outbound_port_data : out std_logic_vector(31 downto 0);
outbound_port_data_read : in std_logic;
outbound_port_info : out std_logic_vector(15 downto 0);
outbound_port_info_empty : out std_logic;
outbound_port_info_read : in std_logic;
outbound_proc_data : in std_logic_vector(63 downto 0);
outbound_proc_data_full : out std_logic;
outbound_proc_data_write : in std_logic;
outbound_proc_info : in std_logic_vector(15 downto 0);
outbound_proc_info_write : in std_logic;
reset : in std_logic);
end entity esoc_port_storage;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_storage.structure
-- Last modified : Mon Apr 14 12:49:43 2014.
--------------------------------------------------------------------------------
 
architecture structure of esoc_port_storage is
 
signal inbound_wrusedw : STD_LOGIC_VECTOR(10 downto 0);
signal inbound_rdusedw : STD_LOGIC_VECTOR(9 downto 0);
 
component esoc_fifo_256x32
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(31 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(31 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(7 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(7 downto 0));
end component esoc_fifo_256x32;
 
component esoc_fifo_256x112
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(111 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(111 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(7 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(7 downto 0));
end component esoc_fifo_256x112;
 
component esoc_fifo_256x16
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(15 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(15 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(7 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(7 downto 0));
end component esoc_fifo_256x16;
 
component esoc_fifo_2kx32x64
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(31 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(63 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(9 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(10 downto 0));
end component esoc_fifo_2kx32x64;
 
component esoc_fifo_2kx64x32
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(63 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(31 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(10 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(9 downto 0));
end component esoc_fifo_2kx64x32;
 
begin
--Inbound FIFO's
--- Data Fifo
--- Info Fifo
--- Header Fifo
--Outbound FIFO's
--- Data Fifo
--- Info Fifo
u1: esoc_fifo_256x32
port map(
aclr => reset,
data => inbound_port_info,
rdclk => clk_data,
rdreq => inbound_proc_info_read,
wrclk => clk_control,
wrreq => inbound_port_info_write,
q => inbound_proc_info,
rdempty => inbound_proc_info_empty,
rdusedw => open,
wrfull => open,
wrusedw => open);
 
u4: esoc_fifo_256x112
port map(
aclr => reset,
data => inbound_port_header,
rdclk => clk_search,
rdreq => inbound_proc_header_read,
wrclk => clk_control,
wrreq => inbound_port_header_write,
q => inbound_proc_header,
rdempty => inbound_proc_header_empty,
rdusedw => open,
wrfull => open,
wrusedw => open);
 
u5: esoc_fifo_256x16
port map(
aclr => reset,
data => outbound_proc_info,
rdclk => clk_control,
rdreq => outbound_port_info_read,
wrclk => clk_data,
wrreq => outbound_proc_info_write,
q => outbound_port_info,
rdempty => outbound_port_info_empty,
rdusedw => open,
wrfull => open,
wrusedw => open);
 
u6: esoc_fifo_2kx32x64
port map(
aclr => reset,
data => inbound_port_data,
rdclk => clk_data,
rdreq => inbound_proc_data_read,
wrclk => clk_control,
wrreq => inbound_port_data_write,
q => inbound_proc_data,
rdempty => open,
rdusedw => inbound_rdusedw,
wrfull => open,
wrusedw => inbound_wrusedw);
 
u0: esoc_fifo_2kx64x32
port map(
aclr => reset,
data => outbound_proc_data,
rdclk => clk_control,
rdreq => outbound_port_data_read,
wrclk => clk_data,
wrreq => outbound_proc_data_write,
q => outbound_port_data,
rdempty => open,
rdusedw => open,
wrfull => outbound_proc_data_full,
wrusedw => open);
 
 
-- FIFO Behaviour: ST to Write FIFO latency is 1 clock cycle, take this into account
-- WRUSEDW latency is 1 clock cycle, take this into account
-- WRUSEDW becomes 2047 -> 0 when FIFO is completely full, take this into account
-- WRUSEDW must end on an even number of words due to 32/64 conversion, take this into account
-- Conclusion: set Almost Full threshold offset on 3
--
-- Ready Latency @ ST Interface is 2
--
-- Required Almost Full threshold: 1 + 1 + 1 + 1 + 2 = 6
--
inbound_port_data_full <= '1' when (2**inbound_wrusedw'length - to_integer(unsigned(inbound_wrusedw))) <= 6 else '0';
 
--
inbound_proc_data_full <= '1' when to_integer(unsigned(inbound_rdusedw)) = ((2**inbound_rdusedw'length)-1) else '0';
end architecture structure ; -- of esoc_port_storage
 
/trunk/Sources/package_txt_utilities.vhd
0,0 → 1,644
--------------------------------------------------------------------------------
-- Object : Package work.package_txt_utilities
-- Last modified : Sun Dec 04 20:16:51 2011.
--------------------------------------------------------------------------------
 
 
 
library ieee, std;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
---------------------------------------------------------------------------------------------------------------
-- Library declaration
---------------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
 
---------------------------------------------------------------------------------------------------------------
-- Package declaration
---------------------------------------------------------------------------------------------------------------
package package_txt_utilities is
 
-- prints a message to the screen
procedure fwrite(text: string);
 
-- prints the message when active
-- useful for debug switches
procedure fwrite(active: boolean; text: string);
--------------------------------------------------
-- functions to convert strings into data type
--------------------------------------------------
-- converts a character into std_logic
function to_std_logic(c: character) return std_logic;
-- converts a string into std_logic_vector
function bin_string_to_std_logic_vector(s: string) return std_logic_vector;
function hex_string_to_std_logic_vector(s: string) return std_logic_vector;
 
-------------------------------------------
-- functions to convert data type to string
-------------------------------------------
-- converts std_logic into a character
function to_char(sl: std_logic) return character;
 
-- converts std_logic into a string (1 to 1)
function to_string(sl: std_logic) return string;
 
-- converts std_logic_vector into a string (binary base)
function to_string(slv: std_logic_vector) return string;
 
-- converts boolean into a string
function to_string(b: boolean) return string;
 
-- converts an integer into a single character
-- (can also be used for hex conversion and other bases)
function to_char(int: integer) return character;
 
-- converts integer into string using specified base
function to_string(int: integer; base: integer) return string;
 
-- converts integer to string, using base 10
function to_string(int: integer) return string;
 
-- convert std_logic_vector into a string in hex format
function to_hexstring(slv: std_logic_vector) return string;
 
-------------------------------------------
-- functions to manipulate strings
-------------------------------------------
-- convert a character to upper case
function to_upper(c: character) return character;
 
-- convert a character to lower case
function to_lower(c: character) return character;
 
-- convert a string to upper case
function to_upper(s: string) return string;
 
-- convert a string to lower case
function to_lower(s: string) return string;
 
--------------------------------------------------
-- file I/O
--------------------------------------------------
-- read variable length string from input file
procedure fread(file in_file: TEXT;
res_string: out string);
-- print string to a file and start new line
procedure fwrite(file out_file: TEXT;
new_string: in string);
-- print character to a file and start new line
procedure fwrite(file out_file: TEXT;
char: in character);
 
-- print string to a file and start new line
procedure fdebug(level: in integer;
threshold: in integer;
file out_file: TEXT;
new_string: in string);
end package_txt_utilities;
 
---------------------------------------------------------------------------------------------------------------
-- Package definitions
---------------------------------------------------------------------------------------------------------------
package body package_txt_utilities is
 
--=============================================================================================================
-- Process : print
-- Description : prints text to the screen
--=============================================================================================================
 
procedure fwrite(text: string) is
variable msg_line: line;
begin
write(msg_line, text);
writeline(output, msg_line);
end fwrite;
 
--=============================================================================================================
-- Process : print
-- Description : prints text to the screen when active
--=============================================================================================================
procedure fwrite(active: boolean; text: string) is
begin
if active then
fwrite(text);
end if;
end fwrite;
 
--=============================================================================================================
-- Process : chr
-- Description : converts std_logic into a character
--=============================================================================================================
function to_char(sl: std_logic) return character is
variable c: character;
begin
case sl is
when 'U' => c:= 'U';
when 'X' => c:= 'X';
when '0' => c:= '0';
when '1' => c:= '1';
when 'Z' => c:= 'Z';
when 'W' => c:= 'W';
when 'L' => c:= 'L';
when 'H' => c:= 'H';
when '-' => c:= '-';
end case;
return c;
end to_char;
 
--=============================================================================================================
-- Process : str
-- Description : converts std_logic into a string (1 to 1)
--=============================================================================================================
function to_string(sl: std_logic) return string is
variable s: string(1 to 1);
begin
s(1) := to_char(sl);
return s;
end to_string;
 
--=============================================================================================================
-- Process : str
-- Description : converts std_logic_vector into a string (binary base)
--=============================================================================================================
function to_string(slv: std_logic_vector) return string is
variable result : string (1 to slv'length);
variable r : integer;
begin
r := 1;
for i in slv'range loop
result(r) := to_char(slv(i));
r := r + 1;
end loop;
return result;
end to_string;
 
--=============================================================================================================
-- Process : str
-- Description :
--=============================================================================================================
function to_string(b: boolean) return string is
 
begin
if b then
return "true";
else
return "false";
end if;
end to_string;
 
--=============================================================================================================
-- Process : chr
-- Description : converts an integer into a character
--=============================================================================================================
function to_char(int: integer) return character is
variable c: character;
begin
case int is
when 0 => c := '0';
when 1 => c := '1';
when 2 => c := '2';
when 3 => c := '3';
when 4 => c := '4';
when 5 => c := '5';
when 6 => c := '6';
when 7 => c := '7';
when 8 => c := '8';
when 9 => c := '9';
when 10 => c := 'A';
when 11 => c := 'B';
when 12 => c := 'C';
when 13 => c := 'D';
when 14 => c := 'E';
when 15 => c := 'F';
when 16 => c := 'G';
when 17 => c := 'H';
when 18 => c := 'I';
when 19 => c := 'J';
when 20 => c := 'K';
when 21 => c := 'L';
when 22 => c := 'M';
when 23 => c := 'N';
when 24 => c := 'O';
when 25 => c := 'P';
when 26 => c := 'Q';
when 27 => c := 'R';
when 28 => c := 'S';
when 29 => c := 'T';
when 30 => c := 'U';
when 31 => c := 'V';
when 32 => c := 'W';
when 33 => c := 'X';
when 34 => c := 'Y';
when 35 => c := 'Z';
when others => c := '?';
end case;
return c;
end to_char;
 
--=============================================================================================================
-- Process : str
-- Description : convert integer to string using specified base
--=============================================================================================================
function to_string(int: integer; base: integer) return string is
 
variable temp: string(1 to 10);
variable num: integer;
variable abs_int: integer;
variable len: integer := 1;
variable power: integer := 1;
 
begin
 
-- bug fix for negative numbers
abs_int := abs(int);
 
num := abs_int;
 
while num >= base loop -- Determine how many
len := len + 1; -- characters required
num := num / base; -- to represent the
end loop ; -- number.
 
for i in len downto 1 loop -- Convert the number to
temp(i) := to_char(abs_int/power mod base); -- a string starting
power := power * base; -- with the right hand
end loop ; -- side.
 
-- return result and add sign if required
if int < 0 then
return '-'& temp(1 to len);
else
return temp(1 to len);
end if;
 
end to_string;
 
--=============================================================================================================
-- Process : str
-- Description : convert integer to string, using base 10
--=============================================================================================================
function to_string(int: integer) return string is
 
begin
 
return to_string(int, 10) ;
 
end to_string;
 
--=============================================================================================================
-- Process : hstr
-- Description : converts a std_logic_vector into a hex string
--=============================================================================================================
function to_hexstring(slv: std_logic_vector) return string is
variable hexlen: integer;
variable longslv : std_logic_vector(67 downto 0) := (others => '0');
variable hex : string(1 to 16);
variable fourbit : std_logic_vector(3 downto 0);
begin
hexlen := (slv'left+1)/4;
if (slv'left+1) mod 4 /= 0 then
hexlen := hexlen + 1;
end if;
longslv(slv'left downto 0) := slv;
for i in (hexlen -1) downto 0 loop
fourbit := longslv(((i*4)+3) downto (i*4));
case fourbit is
when "0000" => hex(hexlen -I) := '0';
when "0001" => hex(hexlen -I) := '1';
when "0010" => hex(hexlen -I) := '2';
when "0011" => hex(hexlen -I) := '3';
when "0100" => hex(hexlen -I) := '4';
when "0101" => hex(hexlen -I) := '5';
when "0110" => hex(hexlen -I) := '6';
when "0111" => hex(hexlen -I) := '7';
when "1000" => hex(hexlen -I) := '8';
when "1001" => hex(hexlen -I) := '9';
when "1010" => hex(hexlen -I) := 'A';
when "1011" => hex(hexlen -I) := 'B';
when "1100" => hex(hexlen -I) := 'C';
when "1101" => hex(hexlen -I) := 'D';
when "1110" => hex(hexlen -I) := 'E';
when "1111" => hex(hexlen -I) := 'F';
when "ZZZZ" => hex(hexlen -I) := 'z';
when "UUUU" => hex(hexlen -I) := 'u';
when "XXXX" => hex(hexlen -I) := 'x';
when others => hex(hexlen -I) := '?';
end case;
end loop;
return hex(1 to hexlen);
end to_hexstring;
 
--=============================================================================================================
-- Process : to_upper
-- Description : convert a character to upper case
--=============================================================================================================
function to_upper(c: character) return character is
 
variable u: character;
 
begin
 
case c is
when 'a' => u := 'A';
when 'b' => u := 'B';
when 'c' => u := 'C';
when 'd' => u := 'D';
when 'e' => u := 'E';
when 'f' => u := 'F';
when 'g' => u := 'G';
when 'h' => u := 'H';
when 'i' => u := 'I';
when 'j' => u := 'J';
when 'k' => u := 'K';
when 'l' => u := 'L';
when 'm' => u := 'M';
when 'n' => u := 'N';
when 'o' => u := 'O';
when 'p' => u := 'P';
when 'q' => u := 'Q';
when 'r' => u := 'R';
when 's' => u := 'S';
when 't' => u := 'T';
when 'u' => u := 'U';
when 'v' => u := 'V';
when 'w' => u := 'W';
when 'x' => u := 'X';
when 'y' => u := 'Y';
when 'z' => u := 'Z';
when others => u := c;
end case;
 
return u;
 
end to_upper;
 
--=============================================================================================================
-- Process : to_lower
-- Description : convert a character to lower case
--=============================================================================================================
function to_lower(c: character) return character is
 
variable l: character;
 
begin
 
case c is
when 'A' => l := 'a';
when 'B' => l := 'b';
when 'C' => l := 'c';
when 'D' => l := 'd';
when 'E' => l := 'e';
when 'F' => l := 'f';
when 'G' => l := 'g';
when 'H' => l := 'h';
when 'I' => l := 'i';
when 'J' => l := 'j';
when 'K' => l := 'k';
when 'L' => l := 'l';
when 'M' => l := 'm';
when 'N' => l := 'n';
when 'O' => l := 'o';
when 'P' => l := 'p';
when 'Q' => l := 'q';
when 'R' => l := 'r';
when 'S' => l := 's';
when 'T' => l := 't';
when 'U' => l := 'u';
when 'V' => l := 'v';
when 'W' => l := 'w';
when 'X' => l := 'x';
when 'Y' => l := 'y';
when 'Z' => l := 'z';
when others => l := c;
end case;
 
return l;
 
end to_lower;
 
--=============================================================================================================
-- Process : to_upper
-- Description : convert a string to upper case
--=============================================================================================================
function to_upper(s: string) return string is
 
variable uppercase: string (s'range);
 
begin
 
for i in s'range loop
uppercase(i):= to_upper(s(i));
end loop;
return uppercase;
 
end to_upper;
 
--=============================================================================================================
-- Process : to_lower
-- Description : convert a string to lower case
--=============================================================================================================
function to_lower(s: string) return string is
 
variable lowercase: string (s'range);
 
begin
 
for i in s'range loop
lowercase(i):= to_lower(s(i));
end loop;
return lowercase;
 
end to_lower;
 
--=============================================================================================================
-- Process : to_std_logic
-- Description : converts a character into a std_logic
--=============================================================================================================
function to_std_logic(c: character) return std_logic is
variable sl: std_logic;
begin
case c is
when 'U' =>
sl := 'U';
when 'X' =>
sl := 'X';
when '0' =>
sl := '0';
when '1' =>
sl := '1';
when 'Z' =>
sl := 'Z';
when 'W' =>
sl := 'W';
when 'L' =>
sl := 'L';
when 'H' =>
sl := 'H';
when '-' =>
sl := '-';
when others =>
sl := 'X';
end case;
return sl;
end to_std_logic;
 
--=============================================================================================================
-- Process : to_std_logic_vector
-- Description : converts a string into std_logic_vector
--=============================================================================================================
function bin_string_to_std_logic_vector(s: string) return std_logic_vector is
variable slv: std_logic_vector(s'high-s'low downto 0);
variable k: integer;
begin
k := s'high-s'low;
for i in s'range loop
slv(k) := to_std_logic(s(i));
k := k - 1;
end loop;
return slv;
end bin_string_to_std_logic_vector;
 
function hex_string_to_std_logic_vector(s: string) return std_logic_vector is
variable slv: std_logic_vector(4*s'high-1 downto 0);
begin
for i in s'range loop
case s(i) is
when '0' => slv(4*i-1 downto 4*i-4) := "0000";
when '1' => slv(4*i-1 downto 4*i-4) := "0001";
when '2' => slv(4*i-1 downto 4*i-4) := "0010";
when '3' => slv(4*i-1 downto 4*i-4) := "0011";
when '4' => slv(4*i-1 downto 4*i-4) := "0100";
when '5' => slv(4*i-1 downto 4*i-4) := "0101";
when '6' => slv(4*i-1 downto 4*i-4) := "0110";
when '7' => slv(4*i-1 downto 4*i-4) := "0111";
when '8' => slv(4*i-1 downto 4*i-4) := "1000";
when '9' => slv(4*i-1 downto 4*i-4) := "1001";
when 'A' => slv(4*i-1 downto 4*i-4) := "1010";
when 'B' => slv(4*i-1 downto 4*i-4) := "1011";
when 'C' => slv(4*i-1 downto 4*i-4) := "1100";
when 'D' => slv(4*i-1 downto 4*i-4) := "1101";
when 'E' => slv(4*i-1 downto 4*i-4) := "1110";
when 'F' => slv(4*i-1 downto 4*i-4) := "1111";
when 'a' => slv(4*i-1 downto 4*i-4) := "1010";
when 'b' => slv(4*i-1 downto 4*i-4) := "1011";
when 'c' => slv(4*i-1 downto 4*i-4) := "1100";
when 'd' => slv(4*i-1 downto 4*i-4) := "1101";
when 'e' => slv(4*i-1 downto 4*i-4) := "1110";
when 'f' => slv(4*i-1 downto 4*i-4) := "1111";
when others => slv(4*i-1 downto 4*i-4) := "0000";
end case;
end loop;
return slv;
end hex_string_to_std_logic_vector;
 
 
--=============================================================================================================
-- Process : fread
-- Description :
--=============================================================================================================
procedure fread(file in_file: TEXT;
res_string: out string) is
variable l: line;
variable c: character;
variable is_string: boolean;
begin
readline(in_file, l);
-- clear the contents of the result string
for i in res_string'range loop
res_string(i) := ' ';
end loop;
-- read all characters of the line, up to the length
-- of the results string
for i in res_string'range loop
read(l, c, is_string);
res_string(i) := c;
if not is_string then -- found end of line
exit;
end if;
end loop;
end fread;
 
--=============================================================================================================
-- Process : print
-- Description : print string to a file
--=============================================================================================================
procedure fwrite(file out_file: TEXT;
new_string: in string) is
variable l: line;
begin
write(l, new_string);
writeline(out_file, l);
end fwrite;
 
--=============================================================================================================
-- Process : print
-- Description : print string to a file
--=============================================================================================================
procedure fdebug(level: in integer;
threshold: in integer;
file out_file: TEXT;
new_string: in string) is
variable l: line;
begin
if level <= threshold then
write(l, new_string);
writeline(out_file, l);
end if;
end fdebug;
 
--=============================================================================================================
-- Process : print
-- Description : print character to a file and start new line
--=============================================================================================================
procedure fwrite(file out_file: TEXT;
char: in character) is
variable l: line;
begin
write(l, char);
writeline(out_file, l);
end fwrite;
 
--=============================================================================================================
-- Process : str_write
-- Description : appends contents of a string to a file until line feed occurs (LF is considered to be the end of the string)
--=============================================================================================================
procedure str_write(file out_file: TEXT;
new_string: in string) is
begin
for i in new_string'range loop
fwrite(out_file, new_string(i));
if new_string(i) = LF then -- end of string
exit;
end if;
end loop;
 
end str_write;
end package_txt_utilities;
 
 
 
 
/trunk/Sources/esoc_port_mal_control.vhd
0,0 → 1,187
--------------------------------------------------------------------------------
---- ----
---- 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_mal_control
-- Last modified : Mon Apr 14 12:49:06 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_mal_control is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in STD_LOGIC;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out STD_LOGIC;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
force_vlan_default_in : out std_logic;
force_vlan_default_out : out std_logic;
magic_sleep_n : out STD_LOGIC := '1';
magic_wakeup : in STD_LOGIC;
port_vlan_default : out std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
xoff_gen : out STD_LOGIC;
xon_gen : out STD_LOGIC);
end entity esoc_port_mal_control;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_mal_control.esoc_port_mal_control
-- Last modified : Mon Apr 14 12:49:06 2014.
--------------------------------------------------------------------------------
 
 
---------------------------------------------------------------------------------------------------------------
-- architecture and declarations
---------------------------------------------------------------------------------------------------------------
architecture esoc_port_mal_control of esoc_port_mal_control is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
constant reg_port_mal_vlan_default_add: integer := 385;
signal reg_port_mal_vlan_default: std_logic_vector(31 downto 0);
constant reg_port_mal_vlan_default_rst: std_logic_vector(31 downto 0) := X"00000001";
alias reg_port_mal_vlan_default_force_out: std_logic is reg_port_mal_vlan_default(31);
alias reg_port_mal_vlan_default_force_in : std_logic is reg_port_mal_vlan_default(30);
 
constant reg_port_mal_stat_ctrl_add : integer := 384;
signal reg_port_mal_stat_ctrl : std_logic_vector(31 downto 0);
constant reg_port_mal_stat_ctrl_rst : std_logic_vector(31 downto 0) := X"00000001";
alias reg_port_mal_stat_ctrl_xon_gen : std_logic is reg_port_mal_stat_ctrl(3);
alias reg_port_mal_stat_ctrl_xoff_gen : std_logic is reg_port_mal_stat_ctrl(2);
alias reg_port_mal_stat_ctrl_magic_wakeup: std_logic is reg_port_mal_stat_ctrl(1);
alias reg_port_mal_stat_ctrl_magic_sleep : std_logic is reg_port_mal_stat_ctrl(0);
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0);
signal ctrl_wait_i: std_logic;
signal ctrl_bus_enable: std_logic;
 
begin
 
--=============================================================================================================
-- Process : access registers when addressed or provide data from other units to the ctrl_rddata_i bus
-- Description :
--=============================================================================================================
registers: process(clk_control, reset)
begin
if reset = '1' then
reg_port_mal_vlan_default <= reg_port_mal_vlan_default_rst;
-- all ports have weight 1 after reset
reg_port_mal_stat_ctrl <= reg_port_mal_stat_ctrl_rst;
ctrl_rddata_i <= (others => '0');
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
elsif clk_control'event and clk_control = '1' then
reg_port_mal_stat_ctrl_magic_wakeup <= magic_wakeup;
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
-- continu if memory space of this entity is addressed
if (to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_mal_base) and (to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_mal_base + esoc_port_mal_size) then
-- claim the bus for ctrl_wait and ctrl_rddata
ctrl_bus_enable <= '1';
--
-- READ CYCLE started, unit addressed?
--
if ctrl_rd = '1' then
-- Check register address and provide data when addressed
case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
when reg_port_mal_vlan_default_add => ctrl_rddata_i <= reg_port_mal_vlan_default;
ctrl_wait_i <= '0';
when reg_port_mal_stat_ctrl_add => ctrl_rddata_i <= reg_port_mal_stat_ctrl;
ctrl_wait_i <= '0';
when others => NULL;
end case;
--
-- WRITE CYCLE started, unit addressed?
--
elsif ctrl_wr = '1' then
-- Check address and accept data when addressed
case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
when reg_port_mal_vlan_default_add => reg_port_mal_vlan_default <= ctrl_wrdata;
ctrl_wait_i <= '0';
when reg_port_mal_stat_ctrl_add => reg_port_mal_stat_ctrl <= ctrl_wrdata;
ctrl_wait_i <= '0';
when others => NULL;
end case;
end if;
end if;
end if;
end process;
-- Create tristate outputs
ctrl_wait <= ctrl_wait_i when ctrl_bus_enable = '1' else 'Z';
ctrl_rddata <= ctrl_rddata_i when ctrl_bus_enable = '1' else (others => 'Z');
-- use register content
force_vlan_default_out <= reg_port_mal_vlan_default_force_out;
force_vlan_default_in <= reg_port_mal_vlan_default_force_in;
port_vlan_default <= reg_port_mal_vlan_default(port_vlan_default'high downto 0);
magic_sleep_n <= reg_port_mal_stat_ctrl_magic_sleep;
xoff_gen <= reg_port_mal_stat_ctrl_xoff_gen;
xon_gen <= reg_port_mal_stat_ctrl_xon_gen;
end architecture esoc_port_mal_control ; -- of esoc_port_mal_control
 
/trunk/Sources/esoc_port_mal.vhd
0,0 → 1,296
--------------------------------------------------------------------------------
---- ----
---- 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_mal
-- Last modified : Mon Apr 14 12:48:57 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_mal is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in STD_LOGIC;
clk_rgmii : out std_logic;
clk_rgmii_125m : in std_logic;
clk_rgmii_25m : in std_logic;
clk_rgmii_2m5 : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
ena_10 : in STD_LOGIC;
eth_mode : in STD_LOGIC;
ff_rx_a_empty : in STD_LOGIC;
ff_rx_a_full : in STD_LOGIC;
ff_rx_data : in STD_LOGIC_VECTOR(31 downto 0);
ff_rx_dsav : in STD_LOGIC;
ff_rx_dval : in STD_LOGIC;
ff_rx_eop : in STD_LOGIC;
ff_rx_mod : in STD_LOGIC_VECTOR(1 downto 0);
ff_rx_rdy : out STD_LOGIC;
ff_rx_sop : in STD_LOGIC;
ff_tx_a_empty : in STD_LOGIC;
ff_tx_a_full : in STD_LOGIC;
ff_tx_crc_fwd : out STD_LOGIC;
ff_tx_data : out STD_LOGIC_VECTOR(31 downto 0);
ff_tx_eop : out STD_LOGIC;
ff_tx_err : out STD_LOGIC;
ff_tx_mod : out STD_LOGIC_VECTOR(1 downto 0);
ff_tx_rdy : in STD_LOGIC;
ff_tx_septy : in STD_LOGIC;
ff_tx_sop : out STD_LOGIC;
ff_tx_wren : out STD_LOGIC;
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
magic_sleep_n : out STD_LOGIC := '1';
magic_wakeup : in STD_LOGIC;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
reset : in STD_LOGIC;
rx_err_stat : in STD_LOGIC_VECTOR(17 downto 0);
rx_frm_type : in STD_LOGIC_VECTOR(3 downto 0);
set_10 : out STD_LOGIC := '0'; -- '0'
set_1000 : out STD_LOGIC := '0';
tx_ff_uflow : in STD_LOGIC;
xoff_gen : out STD_LOGIC;
xon_gen : out STD_LOGIC);
end entity esoc_port_mal;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_mal.esoc_port_mal
-- Last modified : Mon Apr 14 12:48:57 2014.
--------------------------------------------------------------------------------
 
architecture esoc_port_mal of esoc_port_mal is
 
signal port_vlan_default : std_logic_vector(15 downto 0);
signal force_vlan_default_in : std_logic;
signal force_vlan_default_out : std_logic;
 
component esoc_port_mal_control
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in STD_LOGIC;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out STD_LOGIC;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
force_vlan_default_in : out std_logic;
force_vlan_default_out : out std_logic;
magic_sleep_n : out STD_LOGIC := '1';
magic_wakeup : in STD_LOGIC;
port_vlan_default : out std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
xoff_gen : out STD_LOGIC;
xon_gen : out STD_LOGIC);
end component esoc_port_mal_control;
 
component esoc_port_mal_inbound
port(
clk_control : in STD_LOGIC;
ff_rx_a_empty : in STD_LOGIC;
ff_rx_a_full : in STD_LOGIC;
ff_rx_data : in STD_LOGIC_VECTOR(31 downto 0);
ff_rx_dsav : in STD_LOGIC;
ff_rx_dval : in STD_LOGIC;
ff_rx_eop : in STD_LOGIC;
ff_rx_mod : in STD_LOGIC_VECTOR(1 downto 0);
ff_rx_rdy : out STD_LOGIC;
ff_rx_sop : in STD_LOGIC;
force_vlan_default_in : in std_logic;
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
port_vlan_default : in std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
rx_err_stat : in STD_LOGIC_VECTOR(17 downto 0);
rx_frm_type : in STD_LOGIC_VECTOR(3 downto 0));
end component esoc_port_mal_inbound;
 
component esoc_port_mal_outbound
port(
clk_control : in STD_LOGIC;
ff_tx_a_empty : in STD_LOGIC;
ff_tx_a_full : in STD_LOGIC;
ff_tx_crc_fwd : out STD_LOGIC;
ff_tx_data : out STD_LOGIC_VECTOR(31 downto 0);
ff_tx_eop : out STD_LOGIC;
ff_tx_err : out STD_LOGIC;
ff_tx_mod : out STD_LOGIC_VECTOR(1 downto 0);
ff_tx_rdy : in STD_LOGIC;
ff_tx_septy : in STD_LOGIC;
ff_tx_sop : out STD_LOGIC;
ff_tx_wren : out STD_LOGIC;
force_vlan_default_out : in std_logic;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
port_vlan_default : in std_logic_vector(15 downto 0);
reset : in STD_LOGIC;
tx_ff_uflow : in STD_LOGIC);
end component esoc_port_mal_outbound;
 
component esoc_port_mal_clock
port(
clk_control : in STD_LOGIC;
clk_rgmii : out std_logic;
clk_rgmii_125m : in std_logic;
clk_rgmii_25m : in std_logic;
clk_rgmii_2m5 : in std_logic;
ena_10 : in STD_LOGIC;
eth_mode : in STD_LOGIC;
reset : in STD_LOGIC;
set_10 : out STD_LOGIC := '0'; -- '0'
set_1000 : out STD_LOGIC := '0');
end component esoc_port_mal_clock;
 
begin
u3: esoc_port_mal_control
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
force_vlan_default_in => force_vlan_default_in,
force_vlan_default_out => force_vlan_default_out,
magic_sleep_n => magic_sleep_n,
magic_wakeup => magic_wakeup,
port_vlan_default => port_vlan_default,
reset => reset,
xoff_gen => xoff_gen,
xon_gen => xon_gen);
 
u0: esoc_port_mal_inbound
port map(
clk_control => clk_control,
ff_rx_a_empty => ff_rx_a_empty,
ff_rx_a_full => ff_rx_a_full,
ff_rx_data => ff_rx_data,
ff_rx_dsav => ff_rx_dsav,
ff_rx_dval => ff_rx_dval,
ff_rx_eop => ff_rx_eop,
ff_rx_mod => ff_rx_mod,
ff_rx_rdy => ff_rx_rdy,
ff_rx_sop => ff_rx_sop,
force_vlan_default_in => force_vlan_default_in,
inbound_data => inbound_data,
inbound_data_full => inbound_data_full,
inbound_data_write => inbound_data_write,
inbound_header => inbound_header,
inbound_header_write => inbound_header_write,
inbound_info => inbound_info,
inbound_info_write => inbound_info_write,
port_vlan_default => port_vlan_default,
reset => reset,
rx_err_stat => rx_err_stat,
rx_frm_type => rx_frm_type);
 
u1: esoc_port_mal_outbound
port map(
clk_control => clk_control,
ff_tx_a_empty => ff_tx_a_empty,
ff_tx_a_full => ff_tx_a_full,
ff_tx_crc_fwd => ff_tx_crc_fwd,
ff_tx_data => ff_tx_data,
ff_tx_eop => ff_tx_eop,
ff_tx_err => ff_tx_err,
ff_tx_mod => ff_tx_mod,
ff_tx_rdy => ff_tx_rdy,
ff_tx_septy => ff_tx_septy,
ff_tx_sop => ff_tx_sop,
ff_tx_wren => ff_tx_wren,
force_vlan_default_out => force_vlan_default_out,
outbound_data => outbound_data,
outbound_data_read => outbound_data_read,
outbound_info => outbound_info,
outbound_info_empty => outbound_info_empty,
outbound_info_read => outbound_info_read,
port_vlan_default => port_vlan_default,
reset => reset,
tx_ff_uflow => tx_ff_uflow);
 
u2: esoc_port_mal_clock
port map(
clk_control => clk_control,
clk_rgmii => clk_rgmii,
clk_rgmii_125m => clk_rgmii_125m,
clk_rgmii_25m => clk_rgmii_25m,
clk_rgmii_2m5 => clk_rgmii_2m5,
ena_10 => ena_10,
eth_mode => eth_mode,
reset => reset,
set_10 => set_10,
set_1000 => set_1000);
 
end architecture esoc_port_mal ; -- of esoc_port_mal
 
/trunk/Sources/esoc_search_engine_sa.vhd
0,0 → 1,283
--------------------------------------------------------------------------------
---- ----
---- 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_sa
-- Last modified : Mon Apr 14 12:50:09 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_sa is
port(
clk_search : in std_logic;
reset : in std_logic;
search_aging_tick : in std_logic;
search_entry_age_time : in std_logic_vector(11 downto 0);
search_entry_age_time_ena : in std_logic;
search_sa_drop_cnt : out std_logic;
search_sa_store_empty : in std_logic;
search_sa_store_q : in std_logic_vector(79 downto 0);
search_sa_store_rd : out std_logic;
search_sa_store_words : in STD_LOGIC_VECTOR(6 downto 0);
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_sa;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_search_engine_sa.esoc_search_engine_sa
-- Last modified : Mon Apr 14 12:50:09 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_search_engine_sa of esoc_search_engine_sa is
 
type search_states is (idle, wait_sa, wait_hash, compare, add);
signal search_state: search_states;
 
type aging_states is (idle, wait_empty, wait_entry, evaluate);
signal aging_state: aging_states;
 
signal search_table_address_i: std_logic_vector(search_table_address'high downto 0);
 
signal search_hash_delay_cnt: integer range esoc_search_engine_hash_delay downto 0;
signal search_table_coll_cnt: integer range esoc_search_engine_col_depth downto 0;
signal search_table_free_entry_os: integer range esoc_search_engine_col_depth downto 0;
signal search_table_free_entry: std_logic;
 
signal search_key_i: std_logic_vector(search_table_data'high downto 0);
 
signal aging_count_down: integer range 2**search_entry_age_time'length-1 downto 0;
signal aging_address: integer range 2**search_table_address'length-1 downto 0;
 
begin
 
--=============================================================================================================
-- Process : proces search requests for source MAC address
-- Description :
--=============================================================================================================
search_sa: process(clk_search, reset)
begin
if reset = '1' then
search_table_free_entry <= '0';
search_table_free_entry_os <= 0;
search_table_coll_cnt <= 0;
search_hash_delay_cnt <= 0;
search_sa_drop_cnt <= '0';
search_table_rden <= '0';
search_table_wren <= '0';
search_sa_store_rd <= '0';
search_key_i <= (others => '0');
 
search_table_address_i <= (others => '0');
search_state <= idle;
aging_state <= idle;
aging_address <= 0;
aging_count_down <= 0;
elsif clk_search'event and clk_search = '1' then
-- clear one-clock active signals
search_sa_drop_cnt <= '0';
search_table_rden <= '0';
search_table_wren <= '0';
search_sa_store_rd <= '0';
--
-- process new search requests
--
case search_state is
when idle => -- get Source Port + SA and calculate hash pointer (additional delay may be required after synthesis, due to large XOR tree)
if search_sa_store_empty = '0' then
search_key_i <= search_sa_store_q;
search_table_address_i <= CALC_HASH10_24b(search_sa_store_q(esoc_search_bus_mac+23 downto esoc_search_bus_mac)) & "000";
search_table_rden <= '1';
search_table_free_entry <= '0';
search_table_free_entry_os <= 0;
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;
search_sa_store_rd <= '1';
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 SA and VID and the entry is valid
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) and
search_table_q(esoc_search_entry_valid) = '1' then
search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-1,search_table_address_i'length));
search_key_i(esoc_search_entry_valid) <= '1';
search_key_i(esoc_search_entry_update) <= '1';
search_table_wren <= '1';
search_state <= idle;
-- there is no hit on SA and VID
else
-- end of collission buffer not reached, prepare for next entry
if search_table_coll_cnt < esoc_search_engine_col_depth then
-- is the current entry empty, remember position to use it when end of collission buffer is reached without a hit
if search_table_free_entry = '0' and search_table_q(esoc_search_entry_valid) = '0' then
search_table_free_entry <= '1';
elsif search_table_free_entry = '0' then
search_table_free_entry_os <= search_table_free_entry_os + 1;
end if;
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 without a hit, check previous empty entries were found or that last entry is empty else report full collission buffer
else
-- previous entry of collission buffer was empty, use it to store new SA + VID
if search_table_free_entry = '1' then
search_table_address_i <= std_logic_vector(to_unsigned(to_integer(unsigned(search_table_address_i))-esoc_search_engine_col_depth+search_table_free_entry_os-1,search_table_address_i'length));
search_table_wren <= '1';
-- no previous empty entries, if last entry of collission buffer is empty, use it to store new SA + VID
elsif search_table_q(esoc_search_entry_valid) = '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_table_wren <= '1';
-- no entry of collission buffer is empty, no space to store new SA + VID
else
search_sa_drop_cnt <= '1';
end if;
search_key_i(esoc_search_entry_valid) <= '1';
search_key_i(esoc_search_entry_update) <= '1';
search_state <= idle;
end if;
end if;
when others => search_state <= idle;
end case;
--
-- process aging cycles
--
if search_aging_tick = '1' then
-- create aging timer based upon aging time setting register
if aging_count_down = 0 then
aging_count_down <= to_integer(unsigned(search_entry_age_time))+1;
else
aging_count_down <= aging_count_down - 1;
end if;
end if;
case aging_state is
when idle => -- start aging cycle when aging mechanism is enabled and timer expires
if aging_count_down = 0 and search_entry_age_time_ena = '1' then
aging_address <= 0;
aging_state <= wait_empty;
end if;
when wait_empty => -- wait for access to table with learned address (SA Search request first!)
-- provide access when table is free for aging process
if search_sa_store_empty = '1' and search_state = idle then
search_table_address_i <= std_logic_vector(to_unsigned(aging_address,search_table_address_i'length));
search_table_rden <= '1';
aging_state <= wait_entry;
end if;
when wait_entry => -- if table is still free prepare for entry evaluation else return to wait for access
if search_sa_store_empty = '0' then
aging_state <= wait_empty;
else
aging_state <= evaluate;
end if;
when evaluate => -- if table is still free update entry and increment address pointer else return to wait for access
if search_sa_store_empty = '0' then
aging_state <= wait_empty;
else
-- update the entry or even invalidate the entry
if search_table_q(esoc_search_entry_valid) = '1' then
search_key_i <= search_table_q;
search_key_i(esoc_search_entry_valid) <= search_table_q(esoc_search_entry_update);
search_key_i(esoc_search_entry_update) <= '0';
search_table_wren <= '1';
end if;
-- update address pointer to process next entry
if aging_address = 2**search_table_address_i'length - 1 then
aging_state <= idle;
else
aging_address <= aging_address + 1;
aging_state <= wait_empty;
end if;
end if;
when others => aging_state <= idle;
end case;
end if;
end process;
search_table_address <= search_table_address_i;
search_table_data <= search_key_i;
end architecture esoc_search_engine_sa ; -- of esoc_search_engine_sa
 
/trunk/Sources/esoc_control.vhd
0,0 → 1,328
--------------------------------------------------------------------------------
---- ----
---- 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_control
-- Last modified : Thu Apr 17 12:55:38 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_control is
port(
brom_address : out std_logic_vector(10 downto 0);
brom_rd : out std_logic;
brom_rddata : in std_logic_vector(31 downto 0);
clk_control : in std_logic;
ctrl_address : out std_logic_vector(15 downto 0);
ctrl_rd : out std_logic;
ctrl_rddata : in std_logic_vector(31 downto 0);
ctrl_wait : in std_logic;
ctrl_wr : out std_logic;
ctrl_wrdata : out std_logic_vector(31 downto 0);
esoc_address : in std_logic_vector(15 downto 0);
esoc_boot_complete : out std_logic;
esoc_cs : in std_logic;
esoc_data : inout std_logic_vector(31 downto 0);
esoc_rd : in std_logic;
esoc_wait : out std_logic;
esoc_wr : in std_logic;
pll1_locked : in STD_LOGIC;
pll2_locked : in STD_LOGIC;
reset : in std_logic);
end entity esoc_control;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_control.esoc_control
-- Last modified : Thu Apr 17 12:55:38 2014.
--------------------------------------------------------------------------------
 
 
---------------------------------------------------------------------------------------------------------------
-- architecture and declarations
---------------------------------------------------------------------------------------------------------------
architecture esoc_control of esoc_control is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
-- register and bit definitions
constant reg_ctrl_id_add : integer := 0;
 
constant reg_ctrl_version_add : integer := 1;
 
constant reg_ctrl_stat_ctrl_add : integer := 2;
 
constant reg_ctrl_scratch_add : integer := 3;
signal reg_ctrl_scratch_dat : std_logic_vector(31 downto 0);
constant reg_ctrl_scratch_rst : std_logic_vector(31 downto 0) := X"00000000";
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
type ctrl_bus_states is (boot, boot_wait, boot_rd_add, boot_rd_dat, operational);
signal ctrl_bus_state: ctrl_bus_states;
 
signal esoc_rd_sync: std_logic_vector(2 downto 0);
signal esoc_wr_sync: std_logic_vector(2 downto 0);
 
signal ctrl_rd_i: std_logic;
signal ctrl_wr_i: std_logic;
signal ctrl_rdwr_i: std_logic;
signal ctrl_rddata_i: std_logic_vector(31 downto 0);
signal ctrl_wrdata_i: std_logic_vector(31 downto 0);
signal ctrl_address_i: std_logic_vector(ctrl_address'high downto 0);
signal ctrl_wait_i: std_logic;
 
constant brom_wait_count_init: integer := 31;
signal brom_wait_count: integer range brom_wait_count_init downto 0;
signal brom_address_count: integer range 2**brom_address'length-1 downto 0;
signal brom_error: std_logic;
signal pll1_locked_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
signal pll2_locked_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
 
begin
 
--=============================================================================================================
-- Process : synchronise asynchronous control inputs
-- Description :
--=============================================================================================================
sync: process(clk_control, reset)
begin
if reset = '1' then
esoc_rd_sync <= (others => '0');
esoc_wr_sync <= (others => '0');
pll1_locked_sync <= (others => '0');
pll2_locked_sync <= (others => '0');
elsif clk_control'event and clk_control = '1' then
esoc_rd_sync <= (esoc_cs and esoc_rd) & esoc_rd_sync(esoc_rd_sync'high downto 1);
esoc_wr_sync <= (esoc_cs and esoc_wr) & esoc_wr_sync(esoc_wr_sync'high downto 1);
pll1_locked_sync <= pll1_locked & pll1_locked_sync(pll1_locked_sync'high downto 1);
pll2_locked_sync <= pll2_locked & pll2_locked_sync(pll2_locked_sync'high downto 1);
end if;
end process;
--=============================================================================================================
-- Process : control internal bus with external bus signal
-- Description :
--=============================================================================================================
ctrlbus: process(clk_control, reset)
begin
if reset = '1' then
ctrl_rd_i <= '0';
ctrl_wr_i <= '0';
ctrl_rdwr_i <= '0';
ctrl_address_i <= (others => '0');
ctrl_wrdata_i <= (others => '0');
ctrl_bus_state <= boot;
brom_rd <= '0';
brom_address <= (others => '0');
brom_address_count <= 0;
brom_wait_count <= 0;
brom_error <= '0';
esoc_boot_complete <= '0';
elsif clk_control'event and clk_control = '1' then
case ctrl_bus_state is
when boot => -- boot from rom disabled, start read from boot rom
if esoc_brom_mode = enabled then
brom_rd <= '1';
brom_address <= std_logic_vector(to_unsigned(brom_address_count,brom_address'length));
brom_address_count <= brom_address_count + 1;
ctrl_bus_state <= boot_wait;
-- boot from rom disabled, step to operational state immediately
else
esoc_boot_complete <= '1';
ctrl_bus_state <= operational;
end if;
 
when boot_wait => -- wait for word from boot rom (the register address), continu read from boot prom
brom_rd <= '1';
brom_address <= std_logic_vector(to_unsigned(brom_address_count,brom_address'length));
brom_address_count <= brom_address_count + 1;
ctrl_bus_state <= boot_rd_add;
when boot_rd_add => -- evaluate word from boot rom (the register address) and wait for word from boot rom (the register content)
brom_rd <= '0';
-- stop reading from boot rom if all ones is returned
if brom_rddata = X"FFFFFFFF" then
brom_error <= '0';
esoc_boot_complete <= '1';
ctrl_bus_state <= operational;
-- prepare write on internal bus by providing the address, init wait counter for dead lock detection
else
brom_wait_count <= brom_wait_count_init;
ctrl_address_i <= brom_rddata(ctrl_address_i'high downto 0);
ctrl_bus_state <= boot_rd_dat;
end if;
when boot_rd_dat => -- word from boot rom (the register content) available, start write cycle on internal bus and wait for ACK
ctrl_wr_i <= '1';
ctrl_rdwr_i <= '1';
ctrl_wrdata_i <= brom_rddata;
-- wait for acknowledge, start counter to avoid dead lock due to wrong ROM content
if ctrl_wait = '0' or ctrl_wait_i = '0' then
ctrl_wr_i <= '0';
ctrl_bus_state <= boot;
-- write cycle time out? Terminate boot initialisation!
elsif brom_wait_count = 0 then
brom_error <= '1';
esoc_boot_complete <= '1';
ctrl_wr_i <= '0';
ctrl_bus_state <= operational;
-- count down
else
brom_wait_count <= brom_wait_count - 1;
end if;
when operational => -- detect rising edge of synchronized read signal, check address and drive internal signals of control bus
if esoc_rd_sync(esoc_rd_sync'low+1 downto 0) = "10" and to_integer(unsigned(esoc_address)) >= esoc_base and to_integer(unsigned(esoc_address)) < esoc_base + esoc_size then
ctrl_rd_i <= '1';
ctrl_rdwr_i <= '0';
ctrl_address_i <= esoc_address;
-- detect rising edge of synchronized write signal, check address and drive internal signals of control bus
elsif esoc_wr_sync(esoc_wr_sync'low+1 downto 0) = "10" and to_integer(unsigned(esoc_address)) >= esoc_base and to_integer(unsigned(esoc_address)) < esoc_base + esoc_size then
ctrl_wr_i <= '1';
ctrl_rdwr_i <= '1';
ctrl_wrdata_i <= esoc_data;
ctrl_address_i <= esoc_address;
-- reset internal signals read/write after acknowledge from addresses unit (ack = inactive wait)
elsif ctrl_wait = '0' or ctrl_wait_i = '0' then
ctrl_rd_i <= '0';
ctrl_wr_i <= '0';
end if;
when others => ctrl_bus_state <= boot;
end case;
end if;
end process;
-- use eSOC control interface inputs to drive eSOC control bus signals after initialisation by boot rom
ctrl_rd <= ctrl_rd_i;
ctrl_wr <= ctrl_wr_i;
ctrl_address <= ctrl_address_i;
ctrl_wrdata <= ctrl_wrdata_i;
-- use eSOC control bus signals to drive eSOC control interface outputs
esoc_data <= ctrl_rddata when ctrl_wait = '0' and ctrl_rdwr_i = '0' else
ctrl_rddata_i when ctrl_wait_i = '0' and ctrl_rdwr_i = '0' else (others => 'Z');
esoc_wait <= '0' when ctrl_wait = '0' or ctrl_wait_i = '0' else 'Z';
 
--=============================================================================================================
-- Process : access registers of control unit itself
-- Description :
--=============================================================================================================
registers: process(clk_control, reset)
begin
if reset = '1' then
reg_ctrl_scratch_dat <= reg_ctrl_scratch_rst;
ctrl_wait_i <= '1';
ctrl_rddata_i <= (others => '0');
elsif clk_control'event and clk_control = '1' then
ctrl_wait_i <= '1';
-- continu if memory space of this entity is addressed
if to_integer(unsigned(ctrl_address_i)) >= esoc_control_base and to_integer(unsigned(ctrl_address_i)) < esoc_control_base + esoc_control_size then
--
-- READ CYCLE started, unit addressed?
--
if ctrl_rd_i = '1' then
-- Check register address and provide data when addressed
case to_integer(unsigned(ctrl_address_i))- esoc_control_base is
when reg_ctrl_id_add => ctrl_rddata_i <= esoc_id;
ctrl_wait_i <= '0';
when reg_ctrl_version_add => ctrl_rddata_i <= std_logic_vector(to_unsigned(esoc_version,16)) & std_logic_vector(to_unsigned(esoc_release,16));
ctrl_wait_i <= '0';
when reg_ctrl_stat_ctrl_add => if esoc_brom_mode = enabled then
ctrl_rddata_i <= pll2_locked_sync(0) & pll1_locked_sync(0) & brom_error & '1' & X"000000" & std_logic_vector(to_unsigned(esoc_port_count,4));
else
ctrl_rddata_i <= pll2_locked_sync(0) & pll1_locked_sync(0) & brom_error & '0' & X"000000" & std_logic_vector(to_unsigned(esoc_port_count,4));
end if;
ctrl_wait_i <= '0';
when reg_ctrl_scratch_add => ctrl_rddata_i <= reg_ctrl_scratch_dat;
ctrl_wait_i <= '0';
when others => NULL;
end case;
--
-- WRITE CYCLE started, unit addressed?
--
elsif ctrl_wr_i = '1' then
-- Check register address and accept data when addressed
case to_integer(unsigned(ctrl_address_i)) - esoc_control_base is
when reg_ctrl_scratch_add => reg_ctrl_scratch_dat <= ctrl_wrdata_i;
ctrl_wait_i <= '0';
when others => NULL;
end case;
end if;
end if;
end if;
end process;
end architecture esoc_control ; -- of esoc_control
 
/trunk/Sources/esoc.vhd
0,0 → 1,438
--------------------------------------------------------------------------------
---- ----
---- 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
-- Last modified : Mon Apr 14 12:48:20 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 is
port(
esoc_address : in std_logic_vector(15 downto 0);
esoc_areset : in std_logic;
esoc_boot_complete : out std_logic;
esoc_clk : in std_logic;
esoc_cs : in std_logic;
esoc_data : inout std_logic_vector(31 downto 0);
esoc_mdc : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_mdio : inout std_logic_vector(esoc_port_count-1 downto 0);
esoc_rd : in std_logic;
esoc_rgmii_rxc : in std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_rxctl : in std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_rxd : in std_logic_vector(3+4*(esoc_port_count-1) downto 0);
esoc_rgmii_txc : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_txctl : out std_logic_vector(esoc_port_count-1 downto 0);
esoc_rgmii_txd : out std_logic_vector(3+4*(esoc_port_count-1) downto 0);
esoc_wait : out std_logic;
esoc_wr : in std_logic);
end entity esoc;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc.structure
-- Last modified : Mon Apr 14 12:48:20 2014.
--------------------------------------------------------------------------------
 
architecture structure of esoc is
 
signal clk_control : std_logic;
signal reset : std_logic;
signal clk_search : STD_LOGIC;
signal clk_data : STD_LOGIC;
signal data_req : std_logic_vector(esoc_port_count-1 downto 0);
signal data_gnt_wr : std_logic_vector(esoc_port_count-1 downto 0);
signal data_sof : std_logic;
signal data_eof : std_logic;
signal data : std_logic_vector(63 downto 0);
signal clk_rgmii_125m : STD_LOGIC;
signal clk_rgmii_25m : STD_LOGIC;
signal clk_rgmii_2m5 : STD_LOGIC;
signal data_gnt_rd : std_logic_vector(esoc_port_count-1 downto 0);
signal ctrl_wait : std_logic;
signal ctrl_rddata : std_logic_vector(31 downto 0);
signal ctrl_rd : std_logic;
signal ctrl_wrdata : std_logic_vector(31 downto 0);
signal ctrl_wr : std_logic;
signal ctrl_address : std_logic_vector(15 downto 0);
signal search_req : std_logic_vector(esoc_port_count-1 downto 0);
signal search_sof : std_logic;
signal search_key : std_logic_vector(63 downto 0);
signal search_gnt_wr : std_logic_vector(esoc_port_count-1 downto 0);
signal search_eof : std_logic;
signal search_result_av : std_logic;
signal search_result : std_logic_vector(esoc_port_count-1 downto 0);
signal data_port_sel : std_logic_vector(esoc_port_count-1 downto 0);
signal search_port_stalled : std_logic_vector(esoc_port_count-1 downto 0);
signal pll1_locked : STD_LOGIC;
signal pll2_locked : STD_LOGIC;
signal ctrl_brom_rd : std_logic;
signal ctrl_brom_address : std_logic_vector(10 downto 0);
signal q : STD_LOGIC_VECTOR(31 downto 0);
 
component esoc_port
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_rgmii_125m : in STD_LOGIC;
clk_rgmii_25m : in STD_LOGIC;
clk_rgmii_2m5 : in STD_LOGIC;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
data : inout std_logic_vector(63 downto 0);
data_eof : inout std_logic;
data_gnt_rd : in 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;
mdc : out std_logic;
mdio : inout std_logic;
reset : in std_logic;
rgmii_rxc : in std_logic;
rgmii_rxctl : in std_logic;
rgmii_rxd : in std_logic_vector(3 downto 0);
rgmii_txc : out std_logic;
rgmii_txctl : out std_logic;
rgmii_txd : out std_logic_vector(3 downto 0);
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_port_stalled : out std_logic;
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic);
end component esoc_port;
 
component esoc_control
port(
brom_address : out std_logic_vector(10 downto 0);
brom_rd : out std_logic;
brom_rddata : in std_logic_vector(31 downto 0);
clk_control : in std_logic;
ctrl_address : out std_logic_vector(15 downto 0);
ctrl_rd : out std_logic;
ctrl_rddata : in std_logic_vector(31 downto 0);
ctrl_wait : in std_logic;
ctrl_wr : out std_logic;
ctrl_wrdata : out std_logic_vector(31 downto 0);
esoc_address : in std_logic_vector(15 downto 0);
esoc_boot_complete : out std_logic;
esoc_cs : in std_logic;
esoc_data : inout std_logic_vector(31 downto 0);
esoc_rd : in std_logic;
esoc_wait : out std_logic;
esoc_wr : in std_logic;
pll1_locked : in STD_LOGIC;
pll2_locked : in STD_LOGIC;
reset : in std_logic);
end component esoc_control;
 
component esoc_reset
port(
clk_control : in std_logic;
esoc_areset : in std_logic;
pll1_locked : in STD_LOGIC;
pll2_locked : in STD_LOGIC;
reset : out std_logic);
end component esoc_reset;
 
component esoc_bus_arbiter
generic(
id : integer := 0);
port(
bus_eof : in std_logic;
bus_gnt_rd : out std_logic_vector(esoc_port_count-1 downto 0);
bus_gnt_wr : out std_logic_vector(esoc_port_count-1 downto 0);
bus_req : in std_logic_vector(esoc_port_count-1 downto 0);
bus_sof : in std_logic;
clk_bus : in std_logic;
clk_control : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
reset : in std_logic);
end component esoc_bus_arbiter;
 
component esoc_search_engine
port(
clk_control : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
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);
end component esoc_search_engine;
 
component esoc_pll1_c3
port(
inclk0 : in STD_LOGIC := '0';
c0 : out STD_LOGIC;
c1 : out STD_LOGIC;
c2 : out STD_LOGIC;
locked : out STD_LOGIC);
end component esoc_pll1_c3;
 
component esoc_pll2_c3
port(
inclk0 : in STD_LOGIC := '0';
c0 : out STD_LOGIC;
locked : out STD_LOGIC;
c1 : out STD_LOGIC;
c2 : out STD_LOGIC);
end component esoc_pll2_c3;
 
component esoc_rom_2kx32
port(
aclr : in STD_LOGIC;
address : in STD_LOGIC_VECTOR(10 downto 0);
clock : in STD_LOGIC;
data : in STD_LOGIC_VECTOR(31 downto 0);
rden : in STD_LOGIC;
wren : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(31 downto 0));
end component esoc_rom_2kx32;
 
begin
--CLK IN:
--50MHz
--CLK OUT:
--C0 50MHz
--C1 100MHz
--C2 150MHz
--CLK IN:
--50MHz
--CLK OUT:
--C0 125MHz
--
--eSoc Clocks and Reset
--eSoc Host Control Interface
--eSoc Ethernet ports
--eSoc Search Engine
--eSoc Data bus Arbiter
--eSoc Search bus Arbiter
--eSoc Boot ROM
esoc_ports: for esoc_port_nr in esoc_port_count-1 downto 0 generate
begin
u0: esoc_port
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
clk_data => clk_data,
clk_rgmii_125m => clk_rgmii_125m,
clk_rgmii_25m => clk_rgmii_25m,
clk_rgmii_2m5 => clk_rgmii_2m5,
clk_search => clk_search,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
data => data,
data_eof => data_eof,
data_gnt_rd => data_gnt_rd(esoc_port_nr),
data_gnt_wr => data_gnt_wr(esoc_port_nr),
data_port_sel => data_port_sel,
data_req => data_req(esoc_port_nr),
data_sof => data_sof,
mdc => esoc_mdc(esoc_port_nr),
mdio => esoc_mdio(esoc_port_nr),
reset => reset,
rgmii_rxc => esoc_rgmii_rxc(esoc_port_nr),
rgmii_rxctl => esoc_rgmii_rxctl(esoc_port_nr),
rgmii_rxd => esoc_rgmii_rxd(3+4*esoc_port_nr downto 4*esoc_port_nr),
rgmii_txc => esoc_rgmii_txc(esoc_port_nr),
rgmii_txctl => esoc_rgmii_txctl(esoc_port_nr),
rgmii_txd => esoc_rgmii_txd(3+4*esoc_port_nr downto 4*esoc_port_nr),
search_eof => search_eof,
search_gnt_wr => search_gnt_wr(esoc_port_nr),
search_key => search_key,
search_port_stalled => search_port_stalled(esoc_port_nr),
search_req => search_req(esoc_port_nr),
search_result => search_result,
search_result_av => search_result_av,
search_sof => search_sof);
 
end generate esoc_ports;
 
-- TEST
u0: esoc_control
port map(
brom_address => ctrl_brom_address,
brom_rd => ctrl_brom_rd,
brom_rddata => q,
clk_control => clk_control,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
esoc_address => esoc_address,
esoc_boot_complete => esoc_boot_complete,
esoc_cs => esoc_cs,
esoc_data => esoc_data,
esoc_rd => esoc_rd,
esoc_wait => esoc_wait,
esoc_wr => esoc_wr,
pll1_locked => pll1_locked,
pll2_locked => pll2_locked,
reset => reset);
 
u2: esoc_reset
port map(
clk_control => clk_control,
esoc_areset => esoc_areset,
pll1_locked => pll1_locked,
pll2_locked => pll2_locked,
reset => reset);
 
u4: esoc_bus_arbiter
generic map(
id => 0)
port map(
bus_eof => data_eof,
bus_gnt_rd => data_gnt_rd,
bus_gnt_wr => data_gnt_wr,
bus_req => data_req,
bus_sof => data_sof,
clk_bus => clk_data,
clk_control => clk_control,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
reset => reset);
 
u6: esoc_search_engine
port map(
clk_control => clk_control,
clk_search => clk_search,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
reset => reset,
search_eof => search_eof,
search_key => search_key,
search_port_stalled => search_port_stalled,
search_result => search_result,
search_result_av => search_result_av,
search_sof => search_sof);
 
u1: esoc_pll1_c3
port map(
inclk0 => esoc_clk,
c0 => clk_control,
c1 => clk_search,
c2 => clk_data,
locked => pll1_locked);
 
u3: esoc_pll2_c3
port map(
inclk0 => esoc_clk,
c0 => clk_rgmii_125m,
locked => pll2_locked,
c1 => clk_rgmii_25m,
c2 => clk_rgmii_2m5);
 
u5: esoc_bus_arbiter
generic map(
id => 1)
port map(
bus_eof => search_eof,
bus_gnt_rd => open,
bus_gnt_wr => search_gnt_wr,
bus_req => search_req,
bus_sof => search_sof,
clk_bus => clk_search,
clk_control => clk_control,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
reset => reset);
 
u7: esoc_rom_2kx32
port map(
aclr => reset,
address => ctrl_brom_address,
clock => clk_control,
data => (others => '0'),
rden => ctrl_brom_rd,
wren => '0',
q => q);
 
end architecture structure ; -- of esoc
 
/trunk/Sources/esoc_reset.vhd
0,0 → 1,101
--------------------------------------------------------------------------------
---- ----
---- 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_reset
-- Last modified : Mon Apr 14 12:49:49 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_reset is
port(
clk_control : in std_logic;
esoc_areset : in std_logic;
pll1_locked : in STD_LOGIC;
pll2_locked : in STD_LOGIC;
reset : out std_logic);
end entity esoc_reset;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_reset.esoc_reset
-- Last modified : Mon Apr 14 12:49:49 2014.
--------------------------------------------------------------------------------
 
 
---------------------------------------------------------------------------------------------------------------
-- architecture and declarations
---------------------------------------------------------------------------------------------------------------
architecture esoc_reset of esoc_reset is
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal esoc_areset_sync : std_logic_vector(1 downto 0);
 
begin
--=============================================================================================================
-- Process : synchronise asynchronous reset input plus filtering
-- Description :
--=============================================================================================================
sync: process(clk_control,pll1_locked,pll2_locked)
begin
-- keep device in reset if pll's not locked
if pll1_locked = '0' or pll2_locked = '0' then
esoc_areset_sync <= (others => '1');
-- synchronise external reset
elsif clk_control'event and clk_control = '1' then
esoc_areset_sync <= esoc_areset & esoc_areset_sync(esoc_areset_sync'high downto 1);
end if;
end process;
 
reset <= esoc_areset_sync(0);
end architecture esoc_reset ; -- of esoc_reset
 
/trunk/Sources/package_esoc_configuration.vhd
0,0 → 1,160
--------------------------------------------------------------------------------
-- Object : Package work.package_esoc_configuration
-- Last modified : Thu Oct 10 12:38:17 2013.
--------------------------------------------------------------------------------
 
 
 
library ieee, std;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
---------------------------------------------------------------------------------------------------------------
-- Package declaration: ESoC Configuration items
---------------------------------------------------------------------------------------------------------------
package package_esoc_configuration is
-- Manufacturer and device ID
constant esoc_id: std_logic_vector(31 downto 0):= X"71022" & X"001";
 
-- Version information (version.release)
constant esoc_version: integer := 1;
constant esoc_release: integer := 0;
 
-- Mode of operation
type esoc_modes is (normal, simulation);
constant esoc_mode: esoc_modes := simulation;
 
-- Boot from ROM
type esoc_brom_modes is (disabled, enabled);
constant esoc_brom_mode: esoc_brom_modes := disabled;
 
-- Port count configuration (maximum is 16)
constant esoc_port_count: integer := 8;
 
---------------------------------------------------------------------------------------------------------------
-- Package declaration: ESoC Address Mapping
---------------------------------------------------------------------------------------------------------------
-- Address mapping
constant esoc_base : integer := 0; -- Boundaries of eSoc memory
constant esoc_size : integer := 65280;
 
constant esoc_testbench_base : integer := 65280; -- Base address = 0xFF00
constant esoc_testbench_size : integer := 8;
 
constant esoc_search_engine_base : integer := 34832; -- Base address = 0x8810
constant esoc_search_engine_size : integer := 8;
 
constant esoc_bus_arbiter_base : integer := 34816; -- Base address = 0x8808 for ID 1
constant esoc_bus_arbiter_size : integer := 8; -- Base address = 0x8800 for ID 0
 
constant esoc_control_base : integer := 32768; -- Base address = 0x8000
constant esoc_control_size : integer := 8;
 
constant esoc_port_mac_base : integer := 0; -- Base address = port_base + port_nr * port_base_offset
constant esoc_port_mac_size : integer := 256;
constant esoc_port_mal_base : integer := 384;
constant esoc_port_mal_size : integer := 8;
constant esoc_port_proc_base : integer := 400;
constant esoc_port_proc_size : integer := 16;
constant esoc_port_base_offset : integer := 2048;
 
---------------------------------------------------------------------------------------------------------------
-- Package declaration: ESoC Design items
---------------------------------------------------------------------------------------------------------------
-- Configuration of clock and clock enables
constant clk_control_freq : integer := 50000000;
constant clk_data_freq : integer := 125000000;
constant clk_search_freq : integer := 100000000;
 
constant clk_search_en_div_1s : integer := clk_search_freq/1; -- 1s enable --> 100MHz / 1Hz
constant clk_search_en_div_1s_sim : integer := clk_search_freq/100000; -- 10us enable --> 100MHz / 100kHz
 
-- Number of metastability flip flops
constant esoc_meta_ffs : integer := 2;
 
-- Ethernet Packet Known Values
constant esoc_ethernet_uc_mc_bc : integer := 40; -- if bit 40 of the DA is 0 it is a uni cast else a multicast or even broadcast
constant esoc_ethernet_vlan_type : std_logic_vector(15 downto 0) := X"8100";
constant esoc_ethernet_vlan_qos : std_logic_vector(11 downto 0) := X"000";
constant esoc_ethernet_ipv4_type : std_logic_vector(15 downto 0) := X"0800";
constant esoc_ethernet_ipv6_type : std_logic_vector(15 downto 0) := X"8808";
 
-- Entity ESoC Port Mal[Inbound] to ESoC Port Processor[Search]
-- Record stored in Header Fifo format (start positions)
constant esoc_inbound_header_dmac_hi : integer := 80; -- Position of destination MAC in header fifo entry, length is 48 bits
constant esoc_inbound_header_dmac_lo : integer := 64; -- Position of destination and source MAC in header fifo entry, length is 48 bits
constant esoc_inbound_header_smac_hi : integer := 48; -- Position of destination and source MAC in header fifo entry, length is 48 bits
constant esoc_inbound_header_smac_lo : integer := 16; -- Position of source MAC in header fifo entry, length is 48 bits
constant esoc_inbound_header_vlan : integer := 4; -- Position of vlan ID in header fifo entry, length is 12 bits
constant esoc_inbound_header_unused3_flag : integer := 3; -- Position of ... flag in header fifo entry, length is 1 bit
constant esoc_inbound_header_unused2_flag : integer := 2; -- Position of ... flag in header fifo entry, length is 1 bit
constant esoc_inbound_header_unused1_flag : integer := 1; -- Position of ... flag in header fifo entry, length is 1 bit
constant esoc_inbound_header_vlan_flag : integer := 0; -- Position of vlan tagged packet flag in header fifo entry, length is 1 bit
 
-- Entity ESoC Port Mal[Inbound] to ESoC Port Processor[Inbound Control]
-- Record stored in Info Fifo format (start positions)
constant esoc_inbound_info_length : integer := 20; -- Position of packet length in info fifo entry
constant esoc_inbound_info_length_size : integer := 12; -- Size of packet length in info fifo entry
constant esoc_inbound_info_vlan_tci : integer := 4; -- Position of vlan tag in info fifo entry, length is 16 bits
constant esoc_inbound_info_unused3_flag : integer := 3; -- Position of ... flag in info fifo entry, length is 1 bit
constant esoc_inbound_info_unused2_flag : integer := 2; -- Position of ... flag in info fifo entry, length is 1 bit
constant esoc_inbound_info_unused1_flag : integer := 1; -- Position of ... flag in info fifo entry, length is 1 bit
constant esoc_inbound_info_vlan_flag : integer := 0; -- Position of vlan tagged packet flag in info fifo entry, length is 1 bit
 
-- Entity ESoC Port Processor[Outbound Control] to ESoC Port Mal[Outbound]
-- Record stored in Info Fifo format (start positions)
constant esoc_outbound_info_length : integer := 4; -- Position of packet length in info fifo entry
constant esoc_outbound_info_length_size : integer := 12; -- Size of packet length in info fifo entry
constant esoc_outbound_info_unused3_flag : integer := 3; -- Position of ... flag in info fifo entry, length is 1 bit
constant esoc_outbound_info_unused2_flag : integer := 2; -- Position of ... flag in info fifo entry, length is 1 bit
constant esoc_outbound_info_vlan_flag : integer := 1; -- Position of vlan tagged packet flag in info fifo entry, length is 1 bit
constant esoc_outbound_info_error_flag : integer := 0; -- Position of error flag in info fifo entry, length is 1 bit
 
-- Entity ESoC Port Processor[Inbound Control] to ESoC Port Processor[Outbound Control]
-- Record prepended for each packet transferred over data bus (start positions)
constant esoc_dbus_packet_info_sport : integer := 32; -- Position of ESoC source port in prependeded packet info DWORD, length is 4 bits
constant esoc_dbus_packet_info_length : integer := 20; -- Position of packet length in prependeded packet info DWORD
constant esoc_dbus_packet_info_length_size : integer := 12; -- Size of packet length in prependeded packet info DWORD
constant esoc_dbus_packet_info_vlan_tci : integer := 4; -- Position of vlan tag in prependeded packet info DWORD, length is 16 bits
constant esoc_dbus_packet_info_unused3_flag : integer := 3; -- Position of ... flag in prependeded packet info DWORD, length is 1 bit
constant esoc_dbus_packet_info_unused2_flag : integer := 2; -- Position of ... flag in prependeded packet info DWORD, length is 1 bit
constant esoc_dbus_packet_info_unused1_flag : integer := 1; -- Position of ... flag in prependeded packet info DWORD, length is 1 bit
constant esoc_dbus_packet_info_vlan_flag : integer := 0; -- Position of vlan tagged packet flag in prependeded packet info DWORD, length is 1 bit
 
-- Entity ESoC Port Processor[Search] to ESoC Search Engine
-- Record transferred over search bus (start positions)
constant esoc_search_bus_sport : integer := 48; -- Position of ESoC source port, length is 16 bits
constant esoc_search_bus_vlan : integer := 48; -- Position of VLAN ID in table entry, length is 12 bit
constant esoc_search_bus_mac : integer := 0; -- Position of MAC address in table entry, length is 48 bit
 
-- Entity ESoC Search Engine configuration
constant esoc_search_engine_col_depth : integer := 7; -- Depth of collision buffer in number of entries, valid values 0 up to 7, results in a depth of 0 to 7 additional entries.
constant esoc_search_engine_hash_delay : integer := 1; -- Hash delay is determined by XOR tree and RAM latency (=1 clock)
 
-- Entity ESoC Search Engine
-- Record in MAC/VLAN Learning table
constant esoc_search_entry_valid : integer := 79; -- Position of entry valid flag in table entry, length is 1 bit
constant esoc_search_entry_update : integer := 78; -- Position of update flag for aging protocol in table entry, length is 1 bit
constant esoc_search_entry_unused2 : integer := 77; --
constant esoc_search_entry_unused1 : integer := 76; --
constant esoc_search_entry_destination : integer := 60; -- Position of destination ports in table entry, length is 16 bit
constant esoc_search_entry_vlan : integer := 48; -- Position of VLAN ID in table entry, length is 12 bit
constant esoc_search_entry_mac : integer := 0; -- Position of MAC address in table entry, length is 48 bit
 
end package_esoc_configuration;
 
---------------------------------------------------------------------------------------------------------------
-- Package definitions
---------------------------------------------------------------------------------------------------------------
package body package_esoc_configuration is
 
end package_esoc_configuration;
 
 
 
 
 
 
 
 
 
/trunk/Sources/esoc_port_processor_control.vhd
0,0 → 1,435
--------------------------------------------------------------------------------
---- ----
---- 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_control
-- Last modified : Mon Apr 14 12:49:26 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_control is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_vlan_id : out std_logic_vector(11 downto 0);
ctrl_vlan_id_member_in : in std_logic_vector(0 downto 0);
ctrl_vlan_id_member_out : out std_logic_vector(0 downto 0);
ctrl_vlan_id_wr : out std_logic;
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
inbound_done_cnt : in std_logic;
inbound_drop_cnt : in std_logic;
outbound_done_cnt : in std_logic;
outbound_drop_cnt : in std_logic;
reset : in STD_LOGIC := '0';
search_done_cnt : in std_logic;
search_drop_cnt : in std_logic);
end entity esoc_port_processor_control;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_processor_control.esoc_port_processor_control
-- Last modified : Mon Apr 14 12:49:26 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_port_processor_control of esoc_port_processor_control is
 
---------------------------------------------------------------------------------------------------------------
-- registers
---------------------------------------------------------------------------------------------------------------
constant reg_port_proc_vlan_control_add: integer := 407;
 
constant reg_port_proc_outbound_done_count_add: integer := 406;
signal reg_port_proc_outbound_done_count: std_logic_vector(31 downto 0);
signal reg_port_proc_outbound_done_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_outbound_done_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_outbound_drop_count_add: integer := 405;
signal reg_port_proc_outbound_drop_count: std_logic_vector(31 downto 0);
signal reg_port_proc_outbound_drop_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_outbound_drop_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_inbound_done_count_add: integer := 404;
signal reg_port_proc_inbound_done_count: std_logic_vector(31 downto 0);
signal reg_port_proc_inbound_done_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_inbound_done_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_inbound_drop_count_add: integer := 403;
signal reg_port_proc_inbound_drop_count: std_logic_vector(31 downto 0);
signal reg_port_proc_inbound_drop_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_inbound_drop_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_search_done_count_add: integer := 402;
signal reg_port_proc_search_done_count: std_logic_vector(31 downto 0);
signal reg_port_proc_search_done_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_search_done_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_search_drop_count_add: integer := 401;
signal reg_port_proc_search_drop_count: std_logic_vector(31 downto 0);
signal reg_port_proc_search_drop_count_i: std_logic_vector(31 downto 0);
constant reg_port_proc_search_drop_count_rst: std_logic_vector(31 downto 0) := X"00000000";
 
constant reg_port_proc_stat_ctrl_add: integer := 400;
signal reg_port_proc_stat_ctrl: std_logic_vector(31 downto 0);
constant reg_port_proc_stat_ctrl_rst: std_logic_vector(31 downto 0) := X"00000000";
 
---------------------------------------------------------------------------------------------------------------
-- signals
---------------------------------------------------------------------------------------------------------------
signal search_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
signal search_cnt_update_sync : std_logic_vector(esoc_meta_ffs-1 downto 0);
signal search_cnt_update : std_logic;
signal search_cnt_update_ack : std_logic;
 
signal inbound_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
signal inbound_cnt_update_sync : std_logic_vector(esoc_meta_ffs-1 downto 0);
signal inbound_cnt_update : std_logic;
signal inbound_cnt_update_ack : std_logic;
 
signal outbound_cnt_update_ack_sync: std_logic_vector(esoc_meta_ffs-1 downto 0);
signal outbound_cnt_update_sync : std_logic_vector(esoc_meta_ffs-1 downto 0);
signal outbound_cnt_update : std_logic;
signal outbound_cnt_update_ack : std_logic;
 
signal ctrl_rddata_i: std_logic_vector(ctrl_rddata'high downto 0);
signal ctrl_wait_i: std_logic;
signal ctrl_bus_enable: std_logic;
 
begin
 
--=============================================================================================================
-- Process : access registers when addressed or provide data to the ctrl_rddata_i bus
-- Description :
--=============================================================================================================
registers: process(clk_control, reset)
begin
if reset = '1' then
reg_port_proc_stat_ctrl <= reg_port_proc_stat_ctrl_rst;
ctrl_vlan_id <= (others => '0');
ctrl_vlan_id_member_out <= (others => '0');
ctrl_vlan_id_wr <= '0';
ctrl_rddata_i <= (others => '0');
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
elsif clk_control'event and clk_control = '1' then
ctrl_wait_i <= '1';
ctrl_bus_enable <= '0';
ctrl_vlan_id_wr <= '0';
-- continu if memory space of this entity is addressed
if (to_integer(unsigned(ctrl_address)) >= esoc_port_nr * esoc_port_base_offset + esoc_port_proc_base) and (to_integer(unsigned(ctrl_address)) < esoc_port_nr * esoc_port_base_offset + esoc_port_proc_base + esoc_port_proc_size) then
-- claim the bus for ctrl_wait and ctrl_rddata
ctrl_bus_enable <= '1';
--
-- READ CYCLE started, unit addressed?
--
if ctrl_rd = '1' then
-- Check register address and provide data when addressed
case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
when reg_port_proc_vlan_control_add => ctrl_rddata_i <= (others => '0');
ctrl_rddata_i(30 downto 30) <= ctrl_vlan_id_member_in;
ctrl_wait_i <= '0';
when reg_port_proc_outbound_done_count_add => if outbound_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_outbound_done_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_outbound_drop_count_add => if outbound_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_outbound_drop_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_inbound_done_count_add => if inbound_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_inbound_done_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_inbound_drop_count_add => if inbound_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_inbound_drop_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_search_done_count_add => if search_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_search_done_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_search_drop_count_add => if search_cnt_update_ack = '1' then
ctrl_rddata_i <= reg_port_proc_search_drop_count;
ctrl_wait_i <= '0';
end if;
when reg_port_proc_stat_ctrl_add => ctrl_rddata_i <= reg_port_proc_stat_ctrl;
ctrl_wait_i <= '0';
when others => NULL;
end case;
--
-- WRITE CYCLE started, unit addressed?
--
elsif ctrl_wr = '1' then
-- Check address and accept data when addressed
case to_integer(unsigned(ctrl_address))- esoc_port_nr * esoc_port_base_offset is
when reg_port_proc_vlan_control_add => ctrl_vlan_id_wr <= ctrl_wrdata(31);
ctrl_vlan_id_member_out <= ctrl_wrdata(30 downto 30);
ctrl_vlan_id <= ctrl_wrdata(11 downto 0);
ctrl_wait_i <= '0';
when reg_port_proc_stat_ctrl_add => reg_port_proc_stat_ctrl <= ctrl_wrdata;
ctrl_wait_i <= '0';
 
when others => NULL;
end case;
end if;
end if;
end if;
end process;
-- Create tristate outputs
ctrl_wait <= ctrl_wait_i when ctrl_bus_enable = '1' else 'Z';
ctrl_rddata <= ctrl_rddata_i when ctrl_bus_enable = '1' else (others => 'Z');
--=============================================================================================================
-- Process : Update counters and transfer values from search clock domain to control clock domain
-- Description :
--=============================================================================================================
sync1a: process(clk_search, reset)
begin
if reset = '1' then
reg_port_proc_search_done_count_i <= reg_port_proc_search_done_count_rst;
reg_port_proc_search_drop_count_i <= reg_port_proc_search_drop_count_rst;
elsif clk_search'event and clk_search = '1' then
-- Update DONE counter
if search_done_cnt = '1' then
reg_port_proc_search_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_search_done_count_i)) + 1,reg_port_proc_search_done_count_i'length));
end if;
-- Update DROP counter
if search_drop_cnt = '1' then
reg_port_proc_search_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_search_drop_count_i)) + 1,reg_port_proc_search_drop_count_i'length));
end if;
end if;
end process;
 
sync1b: process(clk_search, reset)
begin
if reset = '1' then
search_cnt_update <= '0';
search_cnt_update_ack_sync <= (others => '0');
reg_port_proc_search_done_count <= reg_port_proc_search_done_count_rst;
reg_port_proc_search_drop_count <= reg_port_proc_search_drop_count_rst;
 
elsif clk_search'event and clk_search = '1' then
-- synchronise update acknowledge indication
search_cnt_update_ack_sync <= search_cnt_update_ack & search_cnt_update_ack_sync(search_cnt_update_ack_sync'high downto 1);
-- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
if search_cnt_update = '0' and search_cnt_update_ack_sync(0) = '0' then
search_cnt_update <= '1';
reg_port_proc_search_done_count <= reg_port_proc_search_done_count_i;
reg_port_proc_search_drop_count <= reg_port_proc_search_drop_count_i;
-- finalize update when acknowledge is received
elsif search_cnt_update_ack_sync(0) = '1' then
search_cnt_update <= '0';
end if;
end if;
end process;
 
sync1c: process(clk_control, reset)
begin
if reset = '1' then
search_cnt_update_sync <= (others => '0');
-- synchronise counter update indication
elsif clk_control'event and clk_control = '1' then
search_cnt_update_sync <= search_cnt_update & search_cnt_update_sync(search_cnt_update_sync'high downto 1);
end if;
end process;
-- send update acknowledge
search_cnt_update_ack <= search_cnt_update_sync(0);
 
--=============================================================================================================
-- Process : Update counters and transfer values from data clock domain to control clock domain
-- Description :
--=============================================================================================================
sync2a: process(clk_data, reset)
begin
if reset = '1' then
reg_port_proc_inbound_done_count_i <= reg_port_proc_inbound_done_count_rst;
reg_port_proc_inbound_drop_count_i <= reg_port_proc_inbound_drop_count_rst;
elsif clk_data'event and clk_data = '1' then
-- Update DONE counter
if inbound_done_cnt = '1' then
reg_port_proc_inbound_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_inbound_done_count_i)) + 1,reg_port_proc_inbound_done_count_i'length));
end if;
-- Update DROP counter
if inbound_drop_cnt = '1' then
reg_port_proc_inbound_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_inbound_drop_count_i)) + 1,reg_port_proc_inbound_drop_count_i'length));
end if;
end if;
end process;
 
sync2b: process(clk_data, reset)
begin
if reset = '1' then
inbound_cnt_update <= '0';
inbound_cnt_update_ack_sync <= (others => '0');
reg_port_proc_inbound_done_count <= reg_port_proc_inbound_done_count_rst;
reg_port_proc_inbound_drop_count <= reg_port_proc_inbound_drop_count_rst;
 
elsif clk_data'event and clk_data = '1' then
-- synchronise update acknowledge indication
inbound_cnt_update_ack_sync <= inbound_cnt_update_ack & inbound_cnt_update_ack_sync(inbound_cnt_update_ack_sync'high downto 1);
-- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
if inbound_cnt_update = '0' and inbound_cnt_update_ack_sync(0) = '0' then
inbound_cnt_update <= '1';
reg_port_proc_inbound_done_count <= reg_port_proc_inbound_done_count_i;
reg_port_proc_inbound_drop_count <= reg_port_proc_inbound_drop_count_i;
-- finalize update when acknowledge is received
elsif inbound_cnt_update_ack_sync(0) = '1' then
inbound_cnt_update <= '0';
end if;
end if;
end process;
 
sync2c: process(clk_control, reset)
begin
if reset = '1' then
inbound_cnt_update_sync <= (others => '0');
-- synchronise counter update indication
elsif clk_control'event and clk_control = '1' then
inbound_cnt_update_sync <= inbound_cnt_update & inbound_cnt_update_sync(inbound_cnt_update_sync'high downto 1);
end if;
end process;
-- send update acknowledge
inbound_cnt_update_ack <= inbound_cnt_update_sync(0);
--=============================================================================================================
-- Process : Update counters and transfer values from data clock domain to control clock domain
-- Description :
--=============================================================================================================
sync3a: process(clk_data, reset)
begin
if reset = '1' then
reg_port_proc_outbound_done_count_i <= reg_port_proc_outbound_done_count_rst;
reg_port_proc_outbound_drop_count_i <= reg_port_proc_outbound_drop_count_rst;
elsif clk_data'event and clk_data = '1' then
-- Update DONE counter
if outbound_done_cnt = '1' then
reg_port_proc_outbound_done_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_outbound_done_count_i)) + 1,reg_port_proc_outbound_done_count_i'length));
end if;
-- Update DROP counter
if outbound_drop_cnt = '1' then
reg_port_proc_outbound_drop_count_i <= std_logic_vector(to_unsigned(to_integer(unsigned(reg_port_proc_outbound_drop_count_i)) + 1,reg_port_proc_outbound_drop_count_i'length));
end if;
end if;
end process;
 
sync3b: process(clk_data, reset)
begin
if reset = '1' then
outbound_cnt_update <= '0';
outbound_cnt_update_ack_sync <= (others => '0');
reg_port_proc_outbound_done_count <= reg_port_proc_outbound_done_count_rst;
reg_port_proc_outbound_drop_count <= reg_port_proc_outbound_drop_count_rst;
 
elsif clk_data'event and clk_data = '1' then
-- synchronise update acknowledge indication
outbound_cnt_update_ack_sync <= outbound_cnt_update_ack & outbound_cnt_update_ack_sync(outbound_cnt_update_ack_sync'high downto 1);
-- no running update? start updating the other clock domain, use a copy of the counters, because they can change during the update!
if outbound_cnt_update = '0' and outbound_cnt_update_ack_sync(0) = '0' then
outbound_cnt_update <= '1';
reg_port_proc_outbound_done_count <= reg_port_proc_outbound_done_count_i;
reg_port_proc_outbound_drop_count <= reg_port_proc_outbound_drop_count_i;
-- finalize update when acknowledge is received
elsif outbound_cnt_update_ack_sync(0) = '1' then
outbound_cnt_update <= '0';
end if;
end if;
end process;
 
sync3c: process(clk_control, reset)
begin
if reset = '1' then
outbound_cnt_update_sync <= (others => '0');
-- synchronise counter update indication
elsif clk_control'event and clk_control = '1' then
outbound_cnt_update_sync <= outbound_cnt_update & outbound_cnt_update_sync(outbound_cnt_update_sync'high downto 1);
end if;
end process;
-- send update acknowledge
outbound_cnt_update_ack <= outbound_cnt_update_sync(0);
end architecture esoc_port_processor_control ; -- of esoc_port_processor_control
 
/trunk/Sources/esoc_port_processor.vhd
0,0 → 1,396
--------------------------------------------------------------------------------
---- ----
---- 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
-- Last modified : Mon Apr 14 12:49:21 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 is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
data : inout std_logic_vector(63 downto 0);
data_eof : inout std_logic;
data_gnt_rd : in 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_header : in std_logic_vector(111 downto 0);
inbound_header_empty : in std_logic;
inbound_header_read : out std_logic;
inbound_info : in std_logic_vector(31 downto 0);
inbound_info_empty : in std_logic;
inbound_info_read : out std_logic;
outbound_data : out std_logic_vector(63 downto 0);
outbound_data_full : in std_logic;
outbound_data_write : out std_logic;
outbound_info : out std_logic_vector(15 downto 0);
outbound_info_write : out std_logic;
reset : in std_logic;
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic);
end entity esoc_port_processor;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port_processor.structure
-- Last modified : Mon Apr 14 12:49:21 2014.
--------------------------------------------------------------------------------
 
architecture structure of esoc_port_processor is
 
signal Net_0 : STD_LOGIC;
signal Net_1 : STD_LOGIC_VECTOR(15 downto 0);
signal rdempty : STD_LOGIC;
signal Net_2 : STD_LOGIC;
signal q_a : STD_LOGIC_VECTOR(0 downto 0);
signal outbound_drop_cnt : std_logic;
signal outbound_done_cnt : std_logic;
signal search_done_cnt : std_logic;
signal inbound_done_cnt : std_logic;
signal inbound_drop_cnt : std_logic;
signal ctrl_vlan_id : std_logic_vector(11 downto 0);
signal ctrl_vlan_id_member : std_logic_vector(0 downto 0);
signal outbound_vlan_id : STD_LOGIC_VECTOR(11 downto 0);
signal ctrl_vlan_id_wr : std_logic;
signal q_b : STD_LOGIC_VECTOR(0 downto 0);
signal search_data : STD_LOGIC_VECTOR(15 downto 0);
signal u4_q_b : STD_LOGIC_VECTOR(0 downto 0);
signal search_drop_cnt : std_logic;
 
component esoc_port_processor_search
generic(
esoc_port_nr : integer := 0);
port(
clk_search : in std_logic;
inbound_header : in std_logic_vector(111 downto 0);
inbound_header_empty : in std_logic;
inbound_header_read : out std_logic;
inbound_vlan_member : in STD_LOGIC_VECTOR(0 downto 0);
reset : in std_logic;
search_data : out STD_LOGIC_VECTOR(15 downto 0);
search_done_cnt : out std_logic;
search_drop_cnt : out std_logic;
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic;
search_write : out STD_LOGIC);
end component esoc_port_processor_search;
 
component esoc_port_processor_inbound
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 component esoc_port_processor_inbound;
 
component esoc_port_processor_outbound
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 component esoc_port_processor_outbound;
 
component esoc_port_processor_control
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_vlan_id : out std_logic_vector(11 downto 0);
ctrl_vlan_id_member_in : in std_logic_vector(0 downto 0);
ctrl_vlan_id_member_out : out std_logic_vector(0 downto 0);
ctrl_vlan_id_wr : out std_logic;
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
inbound_done_cnt : in std_logic;
inbound_drop_cnt : in std_logic;
outbound_done_cnt : in std_logic;
outbound_drop_cnt : in std_logic;
reset : in STD_LOGIC := '0';
search_done_cnt : in std_logic;
search_drop_cnt : in std_logic);
end component esoc_port_processor_control;
 
component esoc_fifo_256x16
port(
aclr : in STD_LOGIC := '0';
data : in STD_LOGIC_VECTOR(15 downto 0);
rdclk : in STD_LOGIC;
rdreq : in STD_LOGIC;
wrclk : in STD_LOGIC;
wrreq : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(15 downto 0);
rdempty : out STD_LOGIC;
rdusedw : out STD_LOGIC_VECTOR(7 downto 0);
wrfull : out STD_LOGIC;
wrusedw : out STD_LOGIC_VECTOR(7 downto 0));
end component esoc_fifo_256x16;
 
component esoc_ram_4kx1
port(
address_a : in STD_LOGIC_VECTOR(11 downto 0);
address_b : in STD_LOGIC_VECTOR(11 downto 0);
clock_a : in STD_LOGIC := '1';
clock_b : in STD_LOGIC;
data_a : in STD_LOGIC_VECTOR(0 downto 0);
data_b : in STD_LOGIC_VECTOR(0 downto 0);
wren_a : in STD_LOGIC := '0';
wren_b : in STD_LOGIC := '0';
q_a : out STD_LOGIC_VECTOR(0 downto 0);
q_b : out STD_LOGIC_VECTOR(0 downto 0);
rden_a : in STD_LOGIC := '1';
rden_b : in STD_LOGIC := '1');
end component esoc_ram_4kx1;
 
begin
--Search Engine Control
--Inbound Control - port to switch core
--Outbound Control - port to switch core
--Search Result FIFO
--VLAN Member Table
--Port Processor Control
--VLAN Member Table
u0: esoc_port_processor_search
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_search => clk_search,
inbound_header => inbound_header,
inbound_header_empty => inbound_header_empty,
inbound_header_read => inbound_header_read,
inbound_vlan_member => q_a,
reset => reset,
search_data => search_data,
search_done_cnt => search_done_cnt,
search_drop_cnt => search_drop_cnt,
search_eof => search_eof,
search_gnt_wr => search_gnt_wr,
search_key => search_key,
search_req => search_req,
search_result => search_result,
search_result_av => search_result_av,
search_sof => search_sof,
search_write => Net_2);
 
u1: esoc_port_processor_inbound
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_data => clk_data,
data => data,
data_eof => data_eof,
data_gnt_wr => data_gnt_wr,
data_port_sel => data_port_sel,
data_req => data_req,
data_sof => data_sof,
inbound_data => inbound_data,
inbound_data_full => inbound_data_full,
inbound_data_read => inbound_data_read,
inbound_done_cnt => inbound_done_cnt,
inbound_drop_cnt => inbound_drop_cnt,
inbound_info => inbound_info,
inbound_info_empty => inbound_info_empty,
inbound_info_read => inbound_info_read,
reset => reset,
search_data => Net_1,
search_empty => rdempty,
search_read => Net_0);
 
u2: esoc_port_processor_outbound
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_data => clk_data,
data => data,
data_eof => data_eof,
data_gnt_rd => data_gnt_rd,
data_port_sel => data_port_sel,
data_sof => data_sof,
outbound_data => outbound_data,
outbound_data_full => outbound_data_full,
outbound_data_write => outbound_data_write,
outbound_done_cnt => outbound_done_cnt,
outbound_drop_cnt => outbound_drop_cnt,
outbound_info => outbound_info,
outbound_info_write => outbound_info_write,
outbound_vlan_id => outbound_vlan_id,
outbound_vlan_member => u4_q_b,
reset => reset);
 
u3: esoc_port_processor_control
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
clk_data => clk_data,
clk_search => clk_search,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_vlan_id => ctrl_vlan_id,
ctrl_vlan_id_member_in => q_b,
ctrl_vlan_id_member_out => ctrl_vlan_id_member,
ctrl_vlan_id_wr => ctrl_vlan_id_wr,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
inbound_done_cnt => inbound_done_cnt,
inbound_drop_cnt => inbound_drop_cnt,
outbound_done_cnt => outbound_done_cnt,
outbound_drop_cnt => outbound_drop_cnt,
reset => reset,
search_done_cnt => search_done_cnt,
search_drop_cnt => search_drop_cnt);
 
u5: esoc_fifo_256x16
port map(
aclr => reset,
data => search_data,
rdclk => clk_data,
rdreq => Net_0,
wrclk => clk_search,
wrreq => Net_2,
q => Net_1,
rdempty => rdempty,
rdusedw => open,
wrfull => open,
wrusedw => open);
 
u6: esoc_ram_4kx1
port map(
address_a => inbound_header(esoc_inbound_header_vlan+11 downto esoc_inbound_header_vlan),
address_b => ctrl_vlan_id,
clock_a => clk_search,
clock_b => clk_control,
data_a => (others => '0'),
data_b => ctrl_vlan_id_member,
wren_a => '0',
wren_b => ctrl_vlan_id_wr,
q_a => q_a,
q_b => q_b,
rden_a => '1',
rden_b => '1');
 
u4: esoc_ram_4kx1
port map(
address_a => ctrl_vlan_id,
address_b => outbound_vlan_id,
clock_a => clk_control,
clock_b => clk_data,
data_a => ctrl_vlan_id_member,
data_b => (others => '0'),
wren_a => ctrl_vlan_id_wr,
wren_b => '0',
q_a => open,
q_b => u4_q_b,
rden_a => '1',
rden_b => '1');
 
end architecture structure ; -- of esoc_port_processor
 
/trunk/Sources/esoc_port.vhd
0,0 → 1,365
--------------------------------------------------------------------------------
---- ----
---- 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
-- Last modified : Mon Apr 14 12:48:46 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 is
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_rgmii_125m : in STD_LOGIC;
clk_rgmii_25m : in STD_LOGIC;
clk_rgmii_2m5 : in STD_LOGIC;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
data : inout std_logic_vector(63 downto 0);
data_eof : inout std_logic;
data_gnt_rd : in 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;
mdc : out std_logic;
mdio : inout std_logic;
reset : in std_logic;
rgmii_rxc : in std_logic;
rgmii_rxctl : in std_logic;
rgmii_rxd : in std_logic_vector(3 downto 0);
rgmii_txc : out std_logic;
rgmii_txctl : out std_logic;
rgmii_txd : out std_logic_vector(3 downto 0);
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_port_stalled : out std_logic;
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic);
end entity esoc_port;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_port.esoc_port
-- Last modified : Mon Apr 14 12:48:46 2014.
--------------------------------------------------------------------------------
 
architecture esoc_port of esoc_port is
 
signal Net_0 : std_logic;
signal Net_1 : std_logic_vector(31 downto 0);
signal Net_2 : std_logic;
signal Net_3 : std_logic_vector(31 downto 0);
signal Net_4 : std_logic;
signal Net_5 : std_logic_vector(111 downto 0);
signal Net_6 : std_logic;
signal Net_7 : std_logic_vector(31 downto 0);
signal Net_8 : std_logic;
signal Net_9 : std_logic_vector(15 downto 0);
signal Net_10 : std_logic;
signal Net_11 : std_logic;
signal inbound_data_read : std_logic;
signal Net_13 : std_logic;
signal Net_14 : std_logic_vector(31 downto 0);
signal Net_15 : std_logic;
signal Net_16 : std_logic;
signal Net_17 : std_logic_vector(111 downto 0);
signal Net_18 : std_logic;
signal Net_19 : std_logic;
signal search_port_stalled_net : std_logic;
signal Net_22 : std_logic;
signal outbound_info : std_logic_vector(15 downto 0);
signal inbound_proc_data : std_logic_vector(63 downto 0);
signal outbound_data : std_logic_vector(63 downto 0);
signal inbound_proc_data_full : std_logic;
 
component esoc_port_interface
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_rgmii_125m : in STD_LOGIC;
clk_rgmii_25m : in STD_LOGIC;
clk_rgmii_2m5 : in STD_LOGIC;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic := '0';
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
inbound_data : out std_logic_vector(31 downto 0);
inbound_data_full : in std_logic;
inbound_data_write : out std_logic;
inbound_header : out std_logic_vector(111 downto 0);
inbound_header_write : out std_logic;
inbound_info : out std_logic_vector(31 downto 0);
inbound_info_write : out std_logic;
mac_mdc : out std_logic;
mac_mdio : inout std_logic;
outbound_data : in std_logic_vector(31 downto 0);
outbound_data_read : out std_logic;
outbound_info : in std_logic_vector(15 downto 0);
outbound_info_empty : in std_logic;
outbound_info_read : out std_logic;
reset : in std_logic;
rgmii_rxc : in std_logic;
rgmii_rxctl : in std_logic;
rgmii_rxd : in std_logic_vector(3 downto 0);
rgmii_txc : out std_logic;
rgmii_txctl : out std_logic;
rgmii_txd : out std_logic_vector(3 downto 0));
end component esoc_port_interface;
 
component esoc_port_processor
generic(
esoc_port_nr : integer := 0);
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
ctrl_address : in std_logic_vector(15 downto 0);
ctrl_rd : in std_logic;
ctrl_rddata : out std_logic_vector(31 downto 0);
ctrl_wait : out std_logic;
ctrl_wr : in std_logic;
ctrl_wrdata : in std_logic_vector(31 downto 0);
data : inout std_logic_vector(63 downto 0);
data_eof : inout std_logic;
data_gnt_rd : in 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_header : in std_logic_vector(111 downto 0);
inbound_header_empty : in std_logic;
inbound_header_read : out std_logic;
inbound_info : in std_logic_vector(31 downto 0);
inbound_info_empty : in std_logic;
inbound_info_read : out std_logic;
outbound_data : out std_logic_vector(63 downto 0);
outbound_data_full : in std_logic;
outbound_data_write : out std_logic;
outbound_info : out std_logic_vector(15 downto 0);
outbound_info_write : out std_logic;
reset : in std_logic;
search_eof : out std_logic;
search_gnt_wr : in std_logic;
search_key : out std_logic_vector(63 downto 0);
search_req : out std_logic;
search_result : in std_logic_vector(esoc_port_count-1 downto 0);
search_result_av : in std_logic;
search_sof : out std_logic);
end component esoc_port_processor;
 
component esoc_port_storage
port(
clk_control : in std_logic;
clk_data : in std_logic;
clk_search : in std_logic;
inbound_port_data : in std_logic_vector(31 downto 0);
inbound_port_data_full : out std_logic;
inbound_port_data_write : in std_logic;
inbound_port_header : in std_logic_vector(111 downto 0);
inbound_port_header_write : in std_logic;
inbound_port_info : in std_logic_vector(31 downto 0);
inbound_port_info_write : in std_logic;
inbound_proc_data : out std_logic_vector(63 downto 0);
inbound_proc_data_full : out std_logic;
inbound_proc_data_read : in std_logic;
inbound_proc_header : out std_logic_vector(111 downto 0);
inbound_proc_header_empty : out std_logic;
inbound_proc_header_read : in std_logic;
inbound_proc_info : out std_logic_vector(31 downto 0);
inbound_proc_info_empty : out std_logic;
inbound_proc_info_read : in std_logic;
outbound_port_data : out std_logic_vector(31 downto 0);
outbound_port_data_read : in std_logic;
outbound_port_info : out std_logic_vector(15 downto 0);
outbound_port_info_empty : out std_logic;
outbound_port_info_read : in std_logic;
outbound_proc_data : in std_logic_vector(63 downto 0);
outbound_proc_data_full : out std_logic;
outbound_proc_data_write : in std_logic;
outbound_proc_info : in std_logic_vector(15 downto 0);
outbound_proc_info_write : in std_logic;
reset : in std_logic);
end component esoc_port_storage;
 
begin
--External PHY Interface
--Search engine
--interface
--Port to Port
--data interface
search_port_stalled <= search_port_stalled_net;
u0: esoc_port_interface
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
clk_rgmii_125m => clk_rgmii_125m,
clk_rgmii_25m => clk_rgmii_25m,
clk_rgmii_2m5 => clk_rgmii_2m5,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
inbound_data => Net_1,
inbound_data_full => Net_2,
inbound_data_write => Net_0,
inbound_header => Net_5,
inbound_header_write => Net_6,
inbound_info => Net_3,
inbound_info_write => Net_4,
mac_mdc => mdc,
mac_mdio => mdio,
outbound_data => Net_7,
outbound_data_read => Net_8,
outbound_info => Net_9,
outbound_info_empty => Net_11,
outbound_info_read => Net_10,
reset => reset,
rgmii_rxc => rgmii_rxc,
rgmii_rxctl => rgmii_rxctl,
rgmii_rxd => rgmii_rxd,
rgmii_txc => rgmii_txc,
rgmii_txctl => rgmii_txctl,
rgmii_txd => rgmii_txd);
 
u1: esoc_port_processor
generic map(
esoc_port_nr => esoc_port_nr)
port map(
clk_control => clk_control,
clk_data => clk_data,
clk_search => clk_search,
ctrl_address => ctrl_address,
ctrl_rd => ctrl_rd,
ctrl_rddata => ctrl_rddata,
ctrl_wait => ctrl_wait,
ctrl_wr => ctrl_wr,
ctrl_wrdata => ctrl_wrdata,
data => data,
data_eof => data_eof,
data_gnt_rd => data_gnt_rd,
data_gnt_wr => data_gnt_wr,
data_port_sel => data_port_sel,
data_req => data_req,
data_sof => data_sof,
inbound_data => inbound_proc_data,
inbound_data_full => inbound_proc_data_full,
inbound_data_read => inbound_data_read,
inbound_header => Net_17,
inbound_header_empty => Net_18,
inbound_header_read => Net_16,
inbound_info => Net_14,
inbound_info_empty => Net_15,
inbound_info_read => Net_13,
outbound_data => outbound_data,
outbound_data_full => search_port_stalled_net,
outbound_data_write => Net_19,
outbound_info => outbound_info,
outbound_info_write => Net_22,
reset => reset,
search_eof => search_eof,
search_gnt_wr => search_gnt_wr,
search_key => search_key,
search_req => search_req,
search_result => search_result,
search_result_av => search_result_av,
search_sof => search_sof);
 
u3: esoc_port_storage
port map(
clk_control => clk_control,
clk_data => clk_data,
clk_search => clk_search,
inbound_port_data => Net_1,
inbound_port_data_full => Net_2,
inbound_port_data_write => Net_0,
inbound_port_header => Net_5,
inbound_port_header_write => Net_6,
inbound_port_info => Net_3,
inbound_port_info_write => Net_4,
inbound_proc_data => inbound_proc_data,
inbound_proc_data_full => inbound_proc_data_full,
inbound_proc_data_read => inbound_data_read,
inbound_proc_header => Net_17,
inbound_proc_header_empty => Net_18,
inbound_proc_header_read => Net_16,
inbound_proc_info => Net_14,
inbound_proc_info_empty => Net_15,
inbound_proc_info_read => Net_13,
outbound_port_data => Net_7,
outbound_port_data_read => Net_8,
outbound_port_info => Net_9,
outbound_port_info_empty => Net_11,
outbound_port_info_read => Net_10,
outbound_proc_data => outbound_data,
outbound_proc_data_full => search_port_stalled_net,
outbound_proc_data_write => Net_19,
outbound_proc_info => outbound_info,
outbound_proc_info_write => Net_22,
reset => reset);
 
end architecture esoc_port ; -- of esoc_port
 
/trunk/Sources/esoc_clk_en_gen.vhd
0,0 → 1,99
--------------------------------------------------------------------------------
---- ----
---- 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_clk_en_gen
-- Last modified : Mon Apr 14 12:48:32 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_clk_en_gen is
port(
clk : in std_logic;
clk_div : in integer;
clk_en : out std_logic;
reset : in std_logic);
end entity esoc_clk_en_gen;
 
--------------------------------------------------------------------------------
-- Object : Architecture work.esoc_clk_en_gen.esoc_clk_en_gen
-- Last modified : Mon Apr 14 12:48:32 2014.
--------------------------------------------------------------------------------
 
 
architecture esoc_clk_en_gen of esoc_clk_en_gen is
 
signal clk_count: integer;
 
begin
 
--=============================================================================================================
-- Process : proces to create clock enable signal
-- Description :
--=============================================================================================================
create_en: process(clk, reset)
begin
if reset = '1' then
clk_count <= 0;
clk_en <= '0';
elsif clk'event and clk = '1' then
-- clear one-clock active signals
clk_en <= '0';
-- count down until 0, then assert the enable for one clock period
if clk_count = 0 then
clk_count <= clk_div;
clk_en <= '1';
else
clk_count <= clk_count - 1 ;
end if;
end if;
end process;
end architecture esoc_clk_en_gen ; -- of esoc_clk_en_gen
 

powered by: WebSVN 2.1.0

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