URL
https://opencores.org/ocsvn/esoc/esoc/trunk
Subversion Repositories esoc
Compare Revisions
- This comparison shows the changes necessary to convert path
/esoc/trunk/Sources
- from Rev 42 to Rev 43
- ↔ Reverse comparison
Rev 42 → Rev 43
/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 |
/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 |
|
/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 |
|
/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 |
|
/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 |
/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 |
/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; |
/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 |
|
/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 |
|
/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 |
/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 |
|
/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; |
/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 |
|
/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 |
|
/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; |
/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 |
|
/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 |
|
/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; |
|
|
|
|
/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 |
|
/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 |
|
/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 |
|
/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 |
|
/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 |
|
/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 |
|
/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; |
|
|
|
|
|
|
|
|
|
/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 |
|
/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 |
|
/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 |
|
/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 |
|