Newer
Older
-------------------------------------------------------------------------------
-- Title : Routing Table Unit's Components Package
-- Project : White Rabbit Switch
-------------------------------------------------------------------------------
-- File : wrsw_rtu_components_pkg.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-Co-HT
-- Created : 2010-05-09
-- Last update: 2012-06-25
-- Platform : FPGA-generic
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Routing Table Unit components
--
--
-------------------------------------------------------------------------------
--
-- Copyright (c) 2010 - 2012 CERN / BE-CO-HT
--
-- 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.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-05-09 1.0 lipinskimm Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.wishbone_pkg.all; -- for test part (to be moved)
use work.wrsw_shared_types_pkg.all;
use work.rtu_wbgen2_pkg.all;
Maciej Lipinski
committed
-- use work.rtu_wbgen2_pkg_old.all;
package rtu_private_pkg is
----------------------------------------------------------------------------------------
--| RTU top level
----------------------------------------------------------------------------------------
-- Number of switch ports (including NIC)
constant c_wrsw_mac_addr_width : integer := 48;
constant c_wrsw_vid_width : integer := 12;
constant c_wrsw_prio_width : integer := 3;
constant c_wrsw_prio_levels : integer := 8;
constant c_wrsw_fid_width : integer := 8;
constant c_wrsw_hash_width : integer := 9;
constant c_wrsw_crc_width : integer := 16;
constant c_wrsw_cam_addr_width : integer := 8;
constant c_wrsw_entry_words_number : std_logic_vector(5 downto 0) := "000101";
constant c_wrsw_rtu_debugging : std_logic := '0';
constant c_default_hash_poly : std_logic_vector(16 - 1 downto 0) := x"1021";
constant c_PACKED_REQUEST_WIDTH : integer :=
c_wrsw_mac_addr_width -- src MAC
+ c_wrsw_mac_addr_width -- dst MAC
+ c_wrsw_vid_width -- VID
+ c_wrsw_prio_width -- priority
+ 1 -- has_VID
+ 1; -- has_priority
constant c_PACKED_RESPONSE_WIDTH : integer :=
Maciej Lipinski
committed
c_rtu_max_ports -- DPM size
+ 1 -- drop bit
Maciej Lipinski
committed
+ 1 -- bpdu bit
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
+ c_wrsw_prio_width; -- priority
type t_rtu_htab_entry is record
valid : std_logic;
is_bpdu : std_logic;
go_to_cam : std_logic;
cam_addr : std_logic_vector(c_wrsw_cam_addr_width-1 downto 0);
fid : std_logic_vector(c_wrsw_fid_width-1 downto 0);
mac : std_logic_vector(47 downto 0);
bucket_entry : std_logic_vector(1 downto 0);
port_mask_src : std_logic_vector(c_rtu_max_ports-1 downto 0);
port_mask_dst : std_logic_vector(c_rtu_max_ports-1 downto 0);
drop_when_src : std_logic;
drop_when_dst : std_logic;
drop_unmatched_src_ports : std_logic;
prio_src : std_logic_vector(c_wrsw_prio_width-1 downto 0);
has_prio_src : std_logic;
prio_override_src : std_logic;
prio_dst : std_logic_vector(c_wrsw_prio_width-1 downto 0);
has_prio_dst : std_logic;
prio_override_dst : std_logic;
end record;
type t_rtu_vlan_tab_entry is record
drop : std_logic;
prio_override : std_logic;
prio : std_logic_vector(c_wrsw_prio_width-1 downto 0);
has_prio : std_logic;
fid : std_logic_vector(7 downto 0);
port_mask : std_logic_vector(c_rtu_max_ports-1 downto 0);
end record;
Maciej Lipinski
committed
constant c_ff_single_macs_number : integer := 4;
constant c_ff_range_macs_number : integer := 1; -- not implemented
------------------ new stuff ------------------------
Maciej Lipinski
committed
constant c_bpd_range_lower : std_logic_vector(47 downto 0) := x"0180C2000000";
-- constant c_bpd_range_upper : std_logic_vector := x"0180C200000F";
Maciej Lipinski
committed
type t_mac_array is array(integer range <>) of std_logic_vector(47 downto 0);
type t_rtu_special_traffic_config is record
Maciej Lipinski
committed
-- control
ff_mac_br_ena : std_logic;
ff_mac_range_ena : std_logic;
ff_mac_single_ena : std_logic;
ff_mac_ll_ena : std_logic;
ff_mac_ptp_ena : std_logic;
mr_ena : std_logic;
hp_prio : std_logic_vector(7 downto 0);
dop_on_fmatch_full : std_logic;
Maciej Lipinski
committed
hp_fw_cpu_ena : std_logic;
unrec_fw_cpu_ena : std_logic;
Maciej Lipinski
committed
-- config
Maciej Lipinski
committed
single_macs : t_mac_array(c_ff_single_macs_number-1 downto 0);
single_macs_valid : std_logic_vector(c_ff_single_macs_number-1 downto 0);
Maciej Lipinski
committed
Maciej Lipinski
committed
macs_range_up : std_logic_vector(47 downto 0);
macs_range_down : std_logic_vector(47 downto 0);
macs_range_valid : std_logic;
Maciej Lipinski
committed
cpu_forward_mask : std_logic_vector(c_rtu_max_ports-1 downto 0);
Maciej Lipinski
committed
mirror_port_src_tx : std_logic_vector(c_rtu_max_ports-1 downto 0);
mirror_port_src_rx : std_logic_vector(c_rtu_max_ports-1 downto 0);
mirror_port_dst : std_logic_vector(c_rtu_max_ports-1 downto 0);
Maciej Lipinski
committed
dbg_force_fast_match_only : std_logic;
dbg_force_full_match_only : std_logic;
Maciej Lipinski
committed
end record;
type t_match_response is record
Maciej Lipinski
committed
valid : std_logic; -- entry valid
port_mask : std_logic_vector(c_RTU_MAX_PORTS-1 downto 0); -- forwarding mask
prio : std_logic_vector(2 downto 0); -- priority
drop : std_logic; -- drop on ingress
nf : std_logic; -- non-forward (link-limited) traffic (table 7-10,p51, IEEE 802.1D)
ff : std_logic; -- fast forward traffic
hp : std_logic; -- high priority traffic
Maciej Lipinski
committed
end record;
function f_mac_in_range(in_mac, in_mac_lower, in_mac_upper : std_logic_vector(47 downto 0)
) return std_logic;
Maciej Lipinski
committed
function f_mac_reserved(in_mac: std_logic_vector(47 downto 0)
) return std_logic;
Maciej Lipinski
committed
function f_fast_match_mac_lookup(match_config : t_rtu_special_traffic_config;
in_mac : std_logic_vector(47 downto 0)
) return std_logic;
function f_pick (condition : boolean; w_true : std_logic_vector; w_false : std_logic_vector)
return std_logic_vector;
Maciej Lipinski
committed
function f_fast_match_response(vlan_entry : t_rtu_vlan_tab_entry;
rq_prio : std_logic_vector;
rq_has_prio : std_logic;
rq_port_mask : std_logic_vector;
Maciej Lipinski
committed
pcr_pass_all : std_logic_vector;
Maciej Lipinski
committed
pcr_drop_nonvlan_at_ingress: std_logic_vector;
Maciej Lipinski
committed
port_mask_width : integer)
return t_match_response;
function f_set_bit(data : std_logic_vector;
bit_val : std_logic;
bit_num : integer ) return std_logic_vector;
Maciej Lipinski
committed
function f_onehot_decode
(x : std_logic_vector) return integer;
function f_unmarshall_htab_entry (w0, w1, w2, w3, w4 : std_logic_vector) return t_rtu_htab_entry;
Maciej Lipinski
committed
------------------------------------------------------
component wrsw_rtu
generic(
g_num_ports: integer);
port (
clk_sys_i : in std_logic;
clk_match_i : in std_logic;
rst_n_i : in std_logic;
rtu_idle_o : out std_logic_vector(g_num_ports-1 downto 0);
rq_strobe_p_i : in std_logic_vector(g_num_ports-1 downto 0);
rq_smac_i : in std_logic_vector(c_wrsw_mac_addr_width * g_num_ports - 1 downto 0);
rq_dmac_i : in std_logic_vector(c_wrsw_mac_addr_width * g_num_ports -1 downto 0);
rq_vid_i : in std_logic_vector(c_wrsw_vid_width * g_num_ports - 1 downto 0);
rq_has_vid_i : in std_logic_vector(g_num_ports -1 downto 0);
rq_prio_i : in std_logic_vector(c_wrsw_prio_width * g_num_ports -1 downto 0);
rq_has_prio_i : in std_logic_vector(g_num_ports -1 downto 0);
rsp_valid_o : out std_logic_vector (g_num_ports-1 downto 0);
rsp_dst_port_mask_o : out std_logic_vector(c_rtu_max_ports * g_num_ports - 1 downto 0);
rsp_drop_o : out std_logic_vector(g_num_ports -1 downto 0);
rsp_prio_o : out std_logic_vector (g_num_ports * c_wrsw_prio_width-1 downto 0);
rsp_ack_i : in std_logic_vector(g_num_ports -1 downto 0);
port_almost_full_o : out std_logic_vector(g_num_ports -1 downto 0);
port_full_o : out std_logic_vector(g_num_ports -1 downto 0);
-------------------------------------------------------------------------------
-- TRU stuff
-------------------------------------------------------------------------------
tru_req_valid_o : out std_logic;
tru_req_smac_o : out std_logic_vector(c_wrsw_mac_addr_width-1 downto 0);
tru_req_dmac_o : out std_logic_vector(c_wrsw_mac_addr_width-1 downto 0);
tru_req_fid_o : out std_logic_vector(c_wrsw_fid_width -1 downto 0);
tru_req_isHP_o : out std_logic; -- high priority packet flag
tru_req_isBR_o : out std_logic; -- broadcast packet flag
tru_req_reqMask_o : out std_logic_vector(g_num_ports-1 downto 0); -- mask indicating requesting port
tru_resp_valid_i : in std_logic;
tru_resp_port_mask_i : in std_logic_vector(g_num_ports-1 downto 0); -- mask with 1's at forward ports
tru_resp_drop_i : in std_logic;
tru_resp_respMask_i : in std_logic_vector(g_num_ports-1 downto 0); -- mask with 1 at requesting port
tru_if_pass_all_o : out std_logic_vector(g_num_ports-1 downto 0);
tru_if_forward_bpdu_only_o: out std_logic_vector(g_num_ports-1 downto 0);
tru_if_request_valid_o : out std_logic_vector(g_num_ports-1 downto 0);
tru_if_priorities_o : out std_logic_vector(g_num_ports*c_wrsw_prio_width-1 downto 0);
----------------------------------------------------------------------------------
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
wb_addr_i : in std_logic_vector(13 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_sel_i : in std_logic_vector(3 downto 0);
wb_cyc_i : in std_logic;
wb_stb_i : in std_logic;
wb_ack_o : out std_logic;
wb_irq_o : out std_logic;
wb_we_i : in std_logic);
end component;
----------------------------------------------------------------------------------------
--| RTU port
----------------------------------------------------------------------------------------
component rtu_port
generic (
g_num_ports : integer;
g_port_index : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
rtu_gcr_g_ena_i : in std_logic;
rtu_idle_o : out std_logic;
rq_strobe_p_i : in std_logic;
rq_smac_i : in std_logic_vector(c_wrsw_mac_addr_width - 1 downto 0);
rq_dmac_i : in std_logic_vector(c_wrsw_mac_addr_width - 1 downto 0);
rq_vid_i : in std_logic_vector(c_wrsw_vid_width - 1 downto 0);
rq_has_vid_i : in std_logic;
rq_prio_i : in std_logic_vector(c_wrsw_prio_width -1 downto 0);
rq_has_prio_i : in std_logic;
rsp_valid_o : out std_logic;
rsp_dst_port_mask_o : out std_logic_vector(c_rtu_max_ports - 1 downto 0);
rsp_drop_o : out std_logic;
rsp_prio_o : out std_logic_vector (c_wrsw_prio_width-1 downto 0);
rsp_ack_i : in std_logic;
rq_fifo_write_o : out std_logic;
rq_fifo_full_i : in std_logic;
rq_fifo_data_o : out std_logic_vector(c_PACKED_REQUEST_WIDTH - 1 downto 0);
rsp_write_i : in std_logic;
rsp_match_data_i : in std_logic_vector(g_num_ports + c_PACKED_RESPONSE_WIDTH - 1 downto 0);
rr_request_wr_access_o : out std_logic;
rr_access_ena_i : in std_logic;
port_almost_full_o : out std_logic;
port_full_o : out std_logic;
rq_rsp_cnt_dec_i : in std_logic;
rtu_pcr_pass_bpdu_i : in std_logic;
rtu_pcr_pass_all_i : in std_logic;
rtu_pcr_fix_prio_i : in std_logic;
rtu_pcr_prio_val_i : in std_logic_vector(c_wrsw_prio_width - 1 downto 0));
end component;
Maciej Lipinski
committed
component rtu_port_new
generic(
g_num_ports : integer;
g_port_mask_bits : integer; -- usually: g_num_ports + 1 for CPU
Maciej Lipinski
committed
g_match_req_fifo_size : integer;
Maciej Lipinski
committed
g_port_index : integer
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
rtu_idle_o : out std_logic;
rtu_rq_i : in t_rtu_request;
Maciej Lipinski
committed
rtu_rq_abort_i : in std_logic;
rtu_rsp_abort_i : in std_logic;
Maciej Lipinski
committed
rtu_rsp_o : out t_rtu_response;
rtu_rsp_ack_i : in std_logic;
Maciej Lipinski
committed
full_match_wr_req_o : out std_logic;
full_match_wr_data_o : out std_logic_vector(c_PACKED_REQUEST_WIDTH - 1 downto 0);
full_match_wr_done_i : in std_logic;
full_match_wr_full_i : in std_logic;
full_match_rd_data_i : in std_logic_vector(g_num_ports + c_PACKED_RESPONSE_WIDTH - 1 downto 0);
full_match_rd_valid_i : in std_logic;
fast_match_wr_req_o : out std_logic;
fast_match_wr_data_o : out t_rtu_request;
fast_match_rd_valid_i : in std_logic;
fast_match_rd_data_i : in t_match_response;
Maciej Lipinski
committed
port_almost_full_o : out std_logic;
port_full_o : out std_logic;
links_up_i : in std_logic_vector(g_port_mask_bits-1 downto 0);
-- tru_o : out t_rtu2tru;
Maciej Lipinski
committed
rtu_str_config_i : in t_rtu_special_traffic_config;
rtu_gcr_g_ena_i : in std_logic;
-- rtu_pcr_pass_bpdu_i : in std_logic_vector(c_rtu_max_ports -1 downto 0);
-- rtu_pcr_pass_all_i : in std_logic_vector(c_rtu_max_ports -1 downto 0);
rtu_pcr_pass_bpdu_i : in std_logic;
rtu_pcr_pass_all_i : in std_logic;
Maciej Lipinski
committed
rtu_pcr_fix_prio_i : in std_logic;
rtu_pcr_prio_val_i : in std_logic_vector(c_wrsw_prio_width - 1 downto 0)
Maciej Lipinski
committed
);
Maciej Lipinski
committed
end component;
----------------------------------------------------------------------------------------
--| Round Robin Arbiter
----------------------------------------------------------------------------------------
component rtu_rr_arbiter is
generic (
g_width : natural);
port (
clk_i, rst_n_i : in std_logic;
req_i : in std_logic_vector(g_width - 1 downto 0);
gnt_o : out std_logic_vector(g_width - 1 downto 0)
);
end component;
----------------------------------------------------------------------------------------
--| WISHBONE
----------------------------------------------------------------------------------------
component rtu_lookup_engine
generic (
Maciej Lipinski
committed
g_num_ports : integer;
g_hash_size : integer := c_wrsw_hash_width);
port (
clk_match_i : in std_logic;
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
mfifo_rd_req_o : out std_logic;
mfifo_rd_empty_i : in std_logic;
mfifo_ad_sel_i : in std_logic;
mfifo_ad_val_i : in std_logic_vector(31 downto 0);
mfifo_trigger_i : in std_logic;
mfifo_busy_o : out std_logic;
start_i : in std_logic;
ack_i : in std_logic;
found_o : out std_logic;
hash_i : in std_logic_vector(g_hash_size-1 downto 0);
mac_i : in std_logic_vector(c_wrsw_mac_addr_width -1 downto 0);
fid_i : in std_logic_vector(c_wrsw_fid_width - 1 downto 0);
drdy_o : out std_logic;
Maciej Lipinski
committed
port_i : in std_logic_vector(g_num_ports -1 downto 0); -- ML (24/03/2013): aging bugfix
src_dst_i : in std_logic; -- ML (24/03/2013): aging bugfix
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
entry_o : out t_rtu_htab_entry);
end component;
----------------------------------------------------------------------------------------
--| CRC-based hash calculation
----------------------------------------------------------------------------------------
component rtu_crc
port (
mac_addr_i : in std_logic_vector(c_wrsw_mac_addr_width - 1 downto 0);
fid_i : in std_logic_vector(c_wrsw_fid_width - 1 downto 0);
crc_poly_i : in std_logic_vector(c_wrsw_crc_width - 1 downto 0);
hash_o : out std_logic_vector(c_wrsw_hash_width - 1 downto 0)
);
end component;
component rtu_match
generic (
g_num_ports : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
rq_fifo_read_o : out std_logic;
rq_fifo_empty_i : in std_logic;
rq_fifo_input_i : in std_logic_vector(g_num_ports + c_PACKED_REQUEST_WIDTH - 1 downto 0);
rsp_fifo_write_o : out std_logic;
rsp_fifo_full_i : in std_logic;
rsp_fifo_output_o : out std_logic_vector(g_num_ports + c_PACKED_RESPONSE_WIDTH - 1 downto 0);
htab_start_o : out std_logic;
htab_ack_o : out std_logic;
htab_found_i : in std_logic;
htab_hash_o : out std_logic_vector(c_wrsw_hash_width - 1 downto 0);
htab_mac_o : out std_logic_vector(c_wrsw_mac_addr_width -1 downto 0);
htab_fid_o : out std_logic_vector(c_wrsw_fid_width - 1 downto 0);
htab_drdy_i : in std_logic;
htab_entry_i : in t_rtu_htab_entry;
Maciej Lipinski
committed
htab_port_o : out std_logic_vector(g_num_ports-1 downto 0); -- ML (24/03/2013): aging bugfix
htab_src_dst_o : out std_logic; -- ML (24/03/2013): aging bugfix
rtu_ufifo_wr_req_o : out std_logic;
rtu_ufifo_wr_full_i : in std_logic;
rtu_ufifo_wr_empty_i : in std_logic;
rtu_ufifo_dmac_lo_o : out std_logic_vector(31 downto 0);
rtu_ufifo_dmac_hi_o : out std_logic_vector(15 downto 0);
rtu_ufifo_smac_lo_o : out std_logic_vector(31 downto 0);
rtu_ufifo_smac_hi_o : out std_logic_vector(15 downto 0);
rtu_ufifo_vid_o : out std_logic_vector(c_wrsw_vid_width - 1 downto 0);
rtu_ufifo_prio_o : out std_logic_vector(2 downto 0);
rtu_ufifo_pid_o : out std_logic_vector(7 downto 0);
rtu_ufifo_has_vid_o : out std_logic;
rtu_ufifo_has_prio_o : out std_logic;
rtu_aram_main_addr_o : out std_logic_vector(7 downto 0);
rtu_aram_main_data_i : in std_logic_vector(31 downto 0);
rtu_aram_main_rd_o : out std_logic;
rtu_aram_main_data_o : out std_logic_vector(31 downto 0);
rtu_aram_main_wr_o : out std_logic;
vlan_tab_addr_o : out std_logic_vector(c_wrsw_vid_width - 1 downto 0);
vlan_tab_entry_i : in t_rtu_vlan_tab_entry;
rtu_gcr_g_ena_i : in std_logic;
rtu_pcr_pass_all_i : in std_logic_vector(g_num_ports - 1 downto 0);
rtu_pcr_learn_en_i : in std_logic_vector(g_num_ports - 1 downto 0);
rtu_pcr_pass_bpdu_i : in std_logic_vector(g_num_ports - 1 downto 0);
rtu_pcr_b_unrec_i : in std_logic_vector(g_num_ports - 1 downto 0);
Maciej Lipinski
committed
rtu_b_unrec_fw_cpu_i : in std_logic;
rtu_cpu_mask_i : in std_logic_vector(c_RTU_MAX_PORTS-1 downto 0);
rtu_crc_poly_i : in std_logic_vector(c_wrsw_crc_width - 1 downto 0));
end component;
Maciej Lipinski
committed
component rtu_wishbone_slave
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(8 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
clk_match_i : in std_logic;
irq_nempty_i : in std_logic;
rtu_aram_addr_i : in std_logic_vector(7 downto 0);
rtu_aram_data_o : out std_logic_vector(31 downto 0);
rtu_aram_rd_i : in std_logic;
rtu_aram_data_i : in std_logic_vector(31 downto 0);
rtu_aram_wr_i : in std_logic;
regs_i : in t_rtu_in_registers;
regs_o : out t_rtu_out_registers);
end component;
Maciej Lipinski
committed
component rtu_wishbone_slave_old
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(8 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
clk_match_i : in std_logic;
irq_nempty_i : in std_logic;
rtu_aram_addr_i : in std_logic_vector(7 downto 0);
rtu_aram_data_o : out std_logic_vector(31 downto 0);
rtu_aram_rd_i : in std_logic;
rtu_aram_data_i : in std_logic_vector(31 downto 0);
rtu_aram_wr_i : in std_logic;
regs_i : in t_rtu_in_registers;
regs_o : out t_rtu_out_registers);
end component;
Maciej Lipinski
committed
component rtu_fast_match is
generic (
g_num_ports : integer;
g_port_mask_bits : integer);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
match_req_i : in std_logic_vector(g_num_ports-1 downto 0);
match_req_data_i : in t_rtu_request_array(g_num_ports-1 downto 0);
match_rsp_data_o : out t_match_response;
match_rsp_valid_o : out std_logic_vector(g_num_ports-1 downto 0);
vtab_rd_addr_o : out std_logic_vector(c_wrsw_vid_width-1 downto 0);
vtab_rd_entry_i : in t_rtu_vlan_tab_entry;
tru_req_o : out t_tru_request;
tru_rsp_i : in t_tru_response;
tru_enabled_i : in std_logic;
rtu_str_config_i : in t_rtu_special_traffic_config;
rtu_pcr_pass_all_i : in std_logic_vector(c_rtu_max_ports -1 downto 0)
);
end component;
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
end package rtu_private_pkg;
package body rtu_private_pkg is
function f_unmarshall_htab_entry (w0, w1, w2, w3, w4 : std_logic_vector) return t_rtu_htab_entry is
variable t : t_rtu_htab_entry;
begin
t.bucket_entry := "ZZ";
t.valid := w0(0);
t.is_bpdu := w0(2);
t.go_to_cam := w0(3);
t.cam_addr := w2(c_wrsw_cam_addr_width-1 downto 0);
t.has_prio_src := w2(16);
t.prio_src := w2(17 + c_wrsw_prio_width -1 downto 17);
t.fid := w0(4 + c_wrsw_fid_width - 1 downto 4);
t.prio_override_src := w2(20);
t.drop_when_src := w2(21);
t.drop_unmatched_src_ports := w2(22);
t.has_prio_dst := w2(23);
t.prio_dst := w2(24 + c_wrsw_prio_width - 1 downto 24);
t.prio_override_dst := w2(27);
t.drop_when_dst := w2(28);
-- src/dst masks
t.port_mask_src(15 downto 0) := w3(15 downto 0);
t.port_mask_dst(15 downto 0) := w3(31 downto 16);
t.port_mask_src(c_rtu_max_ports-1 downto 16) := w4(c_rtu_max_ports-16-1 downto 0);
t.port_mask_dst(c_rtu_max_ports-1 downto 16) := w4(c_rtu_max_ports-1 downto 16);
-- zbt adddr
-- MAC addr (used only interally, no need to output)
t.mac(47 downto 32) := w0(31 downto 16);
t.mac(31 downto 0) := w1(31 downto 0);
return t;
end function f_unmarshall_htab_entry;
Maciej Lipinski
committed
------------------ new stuff ------------------------
function f_mac_in_range(in_mac, in_mac_lower, in_mac_upper : std_logic_vector(47 downto 0)
) return std_logic is
variable ret : std_logic;
begin
ret := '0';
if((in_mac <= in_mac_upper) and (in_mac >= in_mac_lower)) then
ret :='1';
end if;
return ret;
end function f_mac_in_range;
Maciej Lipinski
committed
function f_mac_reserved(in_mac : std_logic_vector(47 downto 0)
) return std_logic is
variable ret : std_logic;
begin
ret := '0';
if(in_mac(47 downto 8) = c_bpd_range_lower(47 downto 8)) then
ret :='1';
end if;
return ret;
end function f_mac_reserved;
Maciej Lipinski
committed
function f_fast_match_mac_lookup(match_config : t_rtu_special_traffic_config;
in_mac : std_logic_vector(47 downto 0)
) return std_logic is
variable ret : std_logic;
begin
ret := '0';
-- pre-configured destination MAC
Maciej Lipinski
committed
if(match_config.ff_mac_single_ena = '1') then
for i in 0 to c_ff_single_macs_number-1 loop
if(match_config.single_macs_valid(i) = '1' and in_mac = match_config.single_macs(i)) then
ret := '1';
end if;
end loop;
end if;
Maciej Lipinski
committed
-- pre-configured range of destination addresses
Maciej Lipinski
committed
if(match_config.ff_mac_range_ena = '1') then
if(match_config.macs_range_valid = '1') then
if((in_mac <= match_config.macs_range_up) and (in_mac >= match_config.macs_range_down)) then
ret :='1';
end if;
Maciej Lipinski
committed
end if;
end if;
return ret;
end function f_fast_match_mac_lookup;
function f_pick (
condition : boolean;
w_true : std_logic_vector;
w_false : std_logic_vector) return std_logic_vector is
begin
if(condition) then
return w_true;
else
return w_false;
end if;
end function f_pick;
function f_fast_match_response(vlan_entry : t_rtu_vlan_tab_entry;
rq_prio : std_logic_vector;
rq_has_prio : std_logic;
Maciej Lipinski
committed
rq_port_mask : std_logic_vector;
Maciej Lipinski
committed
pcr_pass_all : std_logic_vector;
Maciej Lipinski
committed
pcr_drop_nonvlan_at_ingress: std_logic_vector;
Maciej Lipinski
committed
port_mask_width : integer)
return t_match_response is
variable rsp : t_match_response;
Maciej Lipinski
committed
variable egress_allowed_on_vlan : std_logic;
Maciej Lipinski
committed
begin
------- mask -----------
rsp.port_mask := (others =>'0');
Maciej Lipinski
committed
------- prio ----------
if(vlan_entry.has_prio = '1') then -- regardless of vlan_entry.prio_override value
rsp.prio := vlan_entry.prio;
elsif(rq_has_prio = '1') then
rsp.prio := rq_prio;
else
rsp.prio := (others =>'0');
end if;
------ drop ----------
Maciej Lipinski
committed
if(((rq_port_mask and pcr_drop_nonvlan_at_ingress(rq_port_mask'length-1 downto 0)) = rq_port_mask) and
((rq_port_mask and vlan_entry.port_mask(rq_port_mask'length-1 downto 0)) /= rq_port_mask)) then
Maciej Lipinski
committed
rsp.drop := '1';
rsp.port_mask := (others =>'0');
elsif(vlan_entry.drop = '1') then
rsp.drop := '1';
rsp.port_mask := (others =>'0');
elsif(traffic_br = '1') then
rsp.port_mask := vlan_entry.port_mask and pcr_pass_all; -- broadcast also to NIC !!!!!!
rsp.drop := '0';
Maciej Lipinski
committed
else
Maciej Lipinski
committed
rsp.drop := '0';
rsp.port_mask(port_mask_width-1 downto 0) := vlan_entry.port_mask(port_mask_width-1 downto 0) and
pcr_pass_all(port_mask_width-1 downto 0);
Maciej Lipinski
committed
end if;
------ filled in later -----------
-- rsp.bpdu := '0';
rsp.ff := '0';
rsp.nf := '0';
rsp.hp := '0';
Maciej Lipinski
committed
rsp.valid := '0';
return rsp;
end function f_fast_match_response;
function f_set_bit(data : std_logic_vector;
bit_val : std_logic;
bit_num : integer ) return std_logic_vector is
variable ret : std_logic_vector(data'length-1 downto 0);
begin
ret := data;
ret(bit_num) := bit_val;
return ret;
end function f_set_bit;
Maciej Lipinski
committed
function f_onehot_decode
(x : std_logic_vector) return integer is
begin
for i in 0 to x'length-1 loop
if(x(i) = '1') then
return i;
end if;
end loop; -- i
return 0;
end f_onehot_decode;
Maciej Lipinski
committed
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
-- function doPortMask(
-- s_fast_match : std_logic: -- info what kind of input we have
-- s_rtu_pcr_pass_bpdu, s_rtu_pcr_pass_all : std_logic; -- general config
-- s_dst_entry_is_bpdu : std_logic; -- info from full match
-- s_vlan_prio_override, s_vlan_has_prio, s_rq_has_prio : std_logic; -- validity of different priorities
-- s_rq_prio, s_vlan_prio : std_logic_vector; -- different priorities
-- s_vlan_port_mask, s_full_match_mask, s_tru_mask : std_logic_vector; -- different masks
-- s_vlan_drop, s_tru_drop : std_logic;
-- ) return t_rtu_response is
-- variable s_rsp_drop : t_rtu_response;
--
-- begin
--
-- rsp.valid := '1';
-- rsp.port_mask := (others=>'0');
-- rsp.prio := (others=>'0');
-- rsp.drop :='0';
--
-- if(s_fast_match = '1') then -------------- we need to do some additional work (normally done in match)
--
-- if(s_rtu_pcr_pass_all = '0') then -- we assume here that the PBDU is forwarded to FULL Match
-- rsp.port_mask := (others => '0');
-- rsp.prio := (others => '0');
-- rsp.drop := '1';
-- rsp.valid := '1';
--
-- else
--
-- rsp.port_mask := s_vlan_port_mask;
--
-- if (s_vlan_prio_override = '1' and s_vlan_has_prio = '1') then
-- -- take vlan priority
-- rsp.prio := s_vlan_prio;
-- else
-- if (s_vlan_has_prio = '1') then
-- -- take vlan priority
-- rsp.prio := s_vlan_prio;
-- elsif (s_port_has_prio = '1') then
-- -- take port priority
-- rsp.prio := s_port_prio;
-- else
-- -- nothning matching
-- rsp.prio := (others => '0');
-- end if; -- if (s_vlan_has_prio = '1') then
-- end if; -- (s_vlan_prio_override = '1' and s_vlan_has_prio = '1')
-- end if; -- (s_rtu_pcr_pass_all = '0')
--
-- rsp.port_mask := rsp.port_mask and s_tru_mask;
-- rsp.drop := s_tru_drop or s_vlan_drop;
-- ---
-- --- POSSIBLE BUG
-- --- what about if the source port is not in the VLAN ??
-- ---
--
-- end if; -- if(s_fast_match = '1')
--
-- -- we had normal match and it was BPDU pck, so it should be sent to all
-- -- ports, regardless of TRU decision
-- if(s_dst_entry_is_bpdu = '1' and s_fast_match = '0') then
-- rsp.port_mask := s_full_match_mask;
-- elsif(s_dst_entry_is_bpdu = '0' and s_fast_match = '0') then
-- rsp.port_mask := s_full_match_mask and s_tru_mask;
-- else
-- rsp.port_mask := rsp.port_mask and s_tru_mask
-- end if;
--
--
--
-- end doPortMask;
end rtu_private_pkg;