Commit 3ee33337 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

swcore: adding wishbone registers to export MPM status

parent 5f6ac509
......@@ -8,6 +8,8 @@
files = [
"swc_wbgen2_pkg.vhd",
"swc_wishbone_slave.vhd",
"swc_core.vhd",
"swc_multiport_linked_list.vhd",
......
......@@ -83,7 +83,6 @@ entity swc_multiport_page_allocator is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include 1 for unknown
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer := 10*3;
g_with_RESOURCE_MGR : boolean := false
);
port (
......@@ -137,7 +136,8 @@ entity swc_multiport_page_allocator is
set_usecnt_succeeded_o : out std_logic_vector(g_num_ports -1 downto 0);
res_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0)
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0)
-- tap_out_o : out std_logic_vector(62 + 49 downto 0)
);
......@@ -160,8 +160,7 @@ architecture syn of swc_multiport_page_allocator is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include: unknown, special and x* normal , so
-- g_resource_num = 2+x
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer );
g_resource_num_width : integer := 2);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
......@@ -191,7 +190,8 @@ architecture syn of swc_multiport_page_allocator is
set_usecnt_succeeded_o : out std_logic;
res_full_o : out std_logic_vector(g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0);
-----------------------
dbg_double_free_o : out std_logic;
dbg_double_force_free_o : out std_logic;
......@@ -474,8 +474,7 @@ begin -- syn
g_max_pck_size => g_max_pck_size,
g_special_res_num_pages => g_special_res_num_pages,
g_resource_num => g_resource_num,
g_resource_num_width => g_resource_num_width,
g_num_dbg_vector_width => g_num_dbg_vector_width)
g_resource_num_width => g_resource_num_width)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
......@@ -505,7 +504,8 @@ begin -- syn
rescnt_page_num_i => pg_rescnt_page_num,
res_full_o => pg_res_full,
res_almost_full_o => pg_res_almost_full,
dbg_o => dbg_o,
free_pages_o => free_pages_o,
afull_thr_i => afull_thr_i,
-------------------------------
dbg_double_force_free_o => dbg_double_force_free,
dbg_double_free_o => dbg_double_free,
......
......@@ -100,8 +100,7 @@ entity swc_page_allocator_new is
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3; -- this include: unknown, special and x* normal , so
-- g_resource_num = 2+x
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_resource_num_width : integer := 2
);
port (
......@@ -201,8 +200,8 @@ entity swc_page_allocator_new is
res_full_o : out std_logic_vector(g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0);
----------------------------------------------------------------------
......@@ -567,8 +566,7 @@ begin -- syn
resource_o <= (others => '0');
set_usecnt_succeeded_o <= '1';
res_full_o <= (others => std_logic(out_nomem or initializing));
dbg_o (g_page_addr_width+1-1 downto 0) <= std_logic_vector(free_pages);
dbg_o (g_num_dbg_vector_width-1 downto g_page_addr_width+1) <= (others =>'0');
free_pages_o <= std_logic_vector(free_pages);
set_usecnt_allowed_p1 <= '1';
p_gen_almost_full : process(clk_i)
begin
......@@ -576,7 +574,7 @@ begin -- syn
if rst_n_i = '0' then
res_almost_full_o <= (others => '0');
else
if(free_pages < to_unsigned(40, free_blocks'length) ) then
if(free_pages < unsigned(afull_thr_i) ) then
res_almost_full_o <= (others => '1');
else
res_almost_full_o <= (others => '0');
......@@ -629,8 +627,7 @@ begin -- syn
g_total_num_pages_width => g_page_addr_width,
g_special_res_num_pages => g_special_res_num_pages,
g_resource_num => g_resource_num,
g_resource_num_width => g_resource_num_width,
g_num_dbg_vector_width => g_num_dbg_vector_width
g_resource_num_width => g_resource_num_width
)
port map (
clk_i => clk_i,
......@@ -642,7 +639,7 @@ begin -- syn
rescnt_page_num_i => alloc_req_d1.rescnt_page_num,
res_full_o => res_full_o,
res_almost_full_o => res_almost_full,
dbg_o => dbg_o
dbg_o => open --dbg_o
);
resource_o <= rescnt_rddata_p1;
......
......@@ -136,7 +136,7 @@ entity swc_alloc_resource_manager is
g_resource_num : integer := 3; -- this include 1 for unknown
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_num_dbg_vector_width : integer := 30
);
port (
......
......@@ -73,8 +73,7 @@ entity swc_core is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -138,7 +137,6 @@ entity swc_core is
-- I/F misc
-------------------------------------------------------------------------------
dbg_o : out std_logic_vector(g_num_dbg_vector_width -1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic
);
end swc_core;
......@@ -178,8 +176,7 @@ architecture rtl of swc_core is
g_mpm_fifo_size => g_mpm_fifo_size,
g_mpm_fetch_next_pg_in_advance => g_mpm_fetch_next_pg_in_advance,
g_drop_outqueue_head_on_full => g_drop_outqueue_head_on_full,
g_num_global_pause => g_num_global_pause,
g_num_dbg_vector_width => g_num_dbg_vector_width
g_num_global_pause => g_num_global_pause
)
port map(
clk_i => clk_i,
......@@ -197,8 +194,6 @@ architecture rtl of swc_core is
global_pause_i => global_pause_i,
perport_pause_i=> perport_pause_i,
dbg_o => dbg_o,
rtu_rsp_i => rtu_rsp_i,
rtu_ack_o => rtu_rsp_ack_o
);
......
......@@ -49,6 +49,7 @@ library work;
use work.wr_fabric_pkg.all;
use work.wrsw_shared_types_pkg.all;
use work.genram_pkg.all;
use work.swc_wbgen2_pkg.all;
package swc_swcore_pkg is
......@@ -102,8 +103,7 @@ package swc_swcore_pkg is
g_max_pck_size : integer := 759;
g_special_res_num_pages : integer := 256;
g_resource_num : integer := 3;
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_resource_num_width : integer := 2
);
port (
clk_i : in std_logic;
......@@ -126,8 +126,7 @@ package swc_swcore_pkg is
rescnt_page_num_i : in std_logic_vector(g_page_addr_width -1 downto 0);
set_usecnt_succeeded_o : out std_logic;
res_full_o : out std_logic_vector(g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0)
res_almost_full_o : out std_logic_vector(g_resource_num -1 downto 0)
);
end component;
......@@ -298,7 +297,6 @@ package swc_swcore_pkg is
g_special_res_num_pages : integer ;
g_resource_num : integer ; -- this include 1 for unknown
g_resource_num_width : integer ;
g_num_dbg_vector_width : integer ;
g_with_RESOURCE_MGR : boolean := false
);
port (
......@@ -331,7 +329,8 @@ package swc_swcore_pkg is
set_usecnt_succeeded_o : out std_logic_vector(g_num_ports -1 downto 0);
res_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
res_almost_full_o : out std_logic_vector(g_num_ports * g_resource_num -1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0)
free_pages_o : out std_logic_vector(g_page_addr_width downto 0);
afull_thr_i : in std_logic_vector(g_page_addr_width downto 0)
);
end component;
......@@ -646,8 +645,7 @@ component swc_multiport_pck_pg_free_module is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -668,7 +666,6 @@ component swc_multiport_pck_pg_free_module is
nomem_o : out std_logic;
dbg_o : out std_logic_vector(g_num_dbg_vector_width -1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic
);
end component;
......@@ -694,8 +691,7 @@ component swc_multiport_pck_pg_free_module is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -738,7 +734,6 @@ component swc_multiport_pck_pg_free_module is
pp_quanta_i : in std_logic_vector(g_num_ports*16 - 1 downto 0);
pp_classes_i : in std_logic_vector(g_num_ports*8 - 1 downto 0);
dbg_o : out std_logic_vector(g_num_dbg_vector_width -1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic
);
end component;
......@@ -779,7 +774,7 @@ component swc_multiport_pck_pg_free_module is
g_special_res_num_pages : integer := 248;
g_resource_num : integer := 3; -- this include 1 for unknown
g_resource_num_width : integer := 2;
g_num_dbg_vector_width : integer
g_num_dbg_vector_width : integer := 30
);
port (
clk_i : in std_logic; -- clock & reset
......@@ -830,6 +825,22 @@ component swc_multiport_pck_pg_free_module is
);
end component;
component swc_wishbone_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 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;
regs_i : in t_swc_in_registers;
regs_o : out t_swc_out_registers);
end component;
component swc_core_vectorized_top is
generic(
......
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Switching core
---------------------------------------------------------------------------------------
-- File : swc_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wrsw_swcore.wb
-- Created : Wed Aug 10 12:03:23 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_swcore.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package swc_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_swc_in_registers is record
csr_mpm_afull_i : std_logic;
csr_mpm_full_i : std_logic;
stat_min_fpg_i : std_logic_vector(15 downto 0);
stat_max_fpg_i : std_logic_vector(15 downto 0);
cur_fpg_i : std_logic_vector(31 downto 0);
afull_thr_i : std_logic_vector(31 downto 0);
end record;
constant c_swc_in_registers_init_value: t_swc_in_registers := (
csr_mpm_afull_i => '0',
csr_mpm_full_i => '0',
stat_min_fpg_i => (others => '0'),
stat_max_fpg_i => (others => '0'),
cur_fpg_i => (others => '0'),
afull_thr_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_swc_out_registers is record
csr_new_stat_o : std_logic;
afull_thr_o : std_logic_vector(31 downto 0);
afull_thr_load_o : std_logic;
end record;
constant c_swc_out_registers_init_value: t_swc_out_registers := (
csr_new_stat_o => '0',
afull_thr_o => (others => '0'),
afull_thr_load_o => '0'
);
function "or" (left, right: t_swc_in_registers) return t_swc_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
end package;
package body swc_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):= '0';
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_swc_in_registers) return t_swc_in_registers is
variable tmp: t_swc_in_registers;
begin
tmp.csr_mpm_afull_i := f_x_to_zero(left.csr_mpm_afull_i) or f_x_to_zero(right.csr_mpm_afull_i);
tmp.csr_mpm_full_i := f_x_to_zero(left.csr_mpm_full_i) or f_x_to_zero(right.csr_mpm_full_i);
tmp.stat_min_fpg_i := f_x_to_zero(left.stat_min_fpg_i) or f_x_to_zero(right.stat_min_fpg_i);
tmp.stat_max_fpg_i := f_x_to_zero(left.stat_max_fpg_i) or f_x_to_zero(right.stat_max_fpg_i);
tmp.cur_fpg_i := f_x_to_zero(left.cur_fpg_i) or f_x_to_zero(right.cur_fpg_i);
tmp.afull_thr_i := f_x_to_zero(left.afull_thr_i) or f_x_to_zero(right.afull_thr_i);
return tmp;
end function;
end package body;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Switching core
---------------------------------------------------------------------------------------
-- File : swc_wishbone_slave.vhd
-- Author : auto-generated by wbgen2 from wrsw_swcore.wb
-- Created : Wed Aug 10 12:03:23 2016
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_swcore.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.swc_wbgen2_pkg.all;
entity swc_wishbone_slave is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 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;
regs_i : in t_swc_in_registers;
regs_o : out t_swc_out_registers
);
end swc_wishbone_slave;
architecture syn of swc_wishbone_slave is
signal swc_csr_new_stat_dly0 : std_logic ;
signal swc_csr_new_stat_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
swc_csr_new_stat_int <= '0';
regs_o.afull_thr_load_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
swc_csr_new_stat_int <= '0';
regs_o.afull_thr_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.afull_thr_load_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
swc_csr_new_stat_int <= wrdata_reg(0);
end if;
rddata_reg(0) <= '0';
rddata_reg(30) <= regs_i.csr_mpm_afull_i;
rddata_reg(31) <= regs_i.csr_mpm_full_i;
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
end if;
rddata_reg(15 downto 0) <= regs_i.stat_min_fpg_i;
rddata_reg(31 downto 16) <= regs_i.stat_max_fpg_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.cur_fpg_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
regs_o.afull_thr_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.afull_thr_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- Lock MMU free pages stats
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
swc_csr_new_stat_dly0 <= '0';
regs_o.csr_new_stat_o <= '0';
elsif rising_edge(clk_sys_i) then
swc_csr_new_stat_dly0 <= swc_csr_new_stat_int;
regs_o.csr_new_stat_o <= swc_csr_new_stat_int and (not swc_csr_new_stat_dly0);
end if;
end process;
-- MPM almost full
-- MPM Full
-- min pages
-- max pages
-- pages
-- pages
regs_o.afull_thr_o <= wrdata_reg(31 downto 0);
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
-- White-Rabbit Watchdog Module
-- author: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
--
-- Use wbgen2 to generate code, documentation and more.
-- wbgen2 is available at:
-- http://www.ohwr.org/projects/wishbone-gen
--
peripheral {
name = "WR Switching core";
description = "The module is responsible for Ethernet switching with special treatment for High Priority traffic";
hdl_entity = "swc_wishbone_slave";
prefix = "swc";
reg {
name = "SWcore control & status register";
description = "Various control and status bits of the Swcore";
prefix = "CSR";
field {
name = "Lock MMU free pages stats";
description = "write 1: lock new values of MPM_AFULL, MPM_FULL and STAT register \
write 0: no effect";
prefix = "NEW_STAT";
size = 1;
type = MONOSTABLE;
access_dev = READ_ONLY;
access_bus = WRITE_ONLY;
};
field {
name = "MPM almost full";
description = "Bit is 1 if since the last request of stats (NEW_STAT bit) the MMU has reported that MPM is almost full. \
This means we lost some best efford traffic, but not yet the HP traffic.";
prefix = "MPM_AFULL";
size = 1;
align = 30;
type = BIT;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "MPM Full";
description = "Bit is 1 if since the last request of stats (NEW_STAT bit) the MMU had no free pages to allocate - MPM was full. \
This usually means we have lost some frames (also HP frames).";
prefix = "MPM_FULL";
size = 1;
align = 31;
type = BIT;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Free pages in MPM stats";
description = "Values refreshed each time new stats are requested with a NEW_STAT bit";
prefix = "STAT";
field {
name = "min pages";
prefix = "MIN_FPG";
size = 16;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
field {
name = "max pages";
prefix = "MAX_FPG";
size = 16;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Current free pages in MPM";
description = "Exports the current number of free pages in the MPM";
prefix = "CUR_FPG";
field {
name = "pages";
size = 32;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
load = LOAD_EXT;
};
};
reg {
name = "MPM almost full threshold";
description = "Number of free pages in MPM when Almost Full flag is set.";
prefix = "AFULL_THR";
field {
name = "pages";
size = 32;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
};
......@@ -43,6 +43,7 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.numeric_std.all;
use ieee.math_real.CEIL;
use ieee.math_real.log2;
......@@ -52,9 +53,13 @@ use work.swc_swcore_pkg.all;
use work.wr_fabric_pkg.all;
use work.wrsw_shared_types_pkg.all;
use work.mpm_pkg.all;
use work.wishbone_pkg.all;
use work.swc_wbgen2_pkg.all;
entity xswc_core is
generic(
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := BYTE;
g_prio_num : integer ;--:= c_swc_output_prio_num; [works only for value of 8, output_block-causes problem]
g_output_queue_num : integer ;
......@@ -130,7 +135,13 @@ entity xswc_core is
-- Watchdog outputs
-------------------------------------------------------------------------------
wdog_o : out t_swc_fsms_array(g_num_ports-1 downto 0);
nomem_o : out std_logic);
nomem_o : out std_logic;
-------------------------------------------------------------------------------
-- Wishbone interface
-------------------------------------------------------------------------------
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out);
end xswc_core;
architecture rtl of xswc_core is
......@@ -155,7 +166,8 @@ architecture rtl of xswc_core is
constant c_res_mmu_resource_num : integer := 3; -- (1) unknown; (2) special; (3) normal
constant c_res_mmu_resource_num_width : integer := 2;
----------------------------------------------
constant c_hwdu_mmu_width : integer := 10*3;
constant c_ALMOST_FULL_THR : integer := 40;
----------------------------------------------------------------------------------------------------
-- signals connecting >>Input Block<< with >>Memory Management Unit<<
......@@ -357,10 +369,22 @@ architecture rtl of xswc_core is
signal wdog_ib : t_swc_fsms_array(g_num_ports-1 downto 0);
signal wdog_ob : t_swc_fsms_array(g_num_ports-1 downto 0);
signal wdog_free : t_swc_fsms_array(g_num_ports-1 downto 0);
signal hwdu_mmu : std_logic_vector(c_hwdu_mmu_width -1 downto 0);
signal dbg_pckstart_pageaddr : std_logic_vector(g_num_ports*c_mpm_page_addr_width - 1 downto 0);
signal dbg_pckinter_pageaddr : std_logic_vector(g_num_ports*c_mpm_page_addr_width - 1 downto 0);
-------------------------------------------------------------------------------
-- Wishbone interface
-------------------------------------------------------------------------------
signal wb_in : t_wishbone_master_out;
signal wb_out : t_wishbone_master_in;
signal regs_fromwb : t_swc_out_registers;
signal regs_towb : t_swc_in_registers;
signal mmu_free_pages : std_logic_vector(c_mpm_page_addr_width downto 0);
signal mmu_afull_thr : std_logic_vector(c_mpm_page_addr_width downto 0);
signal mmu_pmin, mmu_pmin_prev : unsigned(c_mpm_page_addr_width downto 0);
signal mmu_pmax, mmu_pmax_prev : unsigned(c_mpm_page_addr_width downto 0);
signal mmu_was_full, mmu_was_afull : std_logic;
begin --rtl
......@@ -377,6 +401,114 @@ architecture rtl of xswc_core is
-- TRIG2 => tap(95 downto 64),
-- TRIG3 => tap(127 downto 96));
-------------------------------------------------------------------------------
-- Wishbone interface
-------------------------------------------------------------------------------
U_Adapter : wb_slave_adapter
generic map (
g_master_use_struct => true,
g_master_mode => CLASSIC,
g_master_granularity => WORD,
g_slave_use_struct => true,
g_slave_mode => g_interface_mode,
g_slave_granularity => g_address_granularity)
port map (
clk_sys_i => clk_i,
rst_n_i => rst_n_i,
slave_i => wb_i,
slave_o => wb_o,
master_i => wb_out,
master_o => wb_in);
wb_out.err <= '0';
wb_out.rty <= '0';
wb_out.int <= '0';
U_WB_SLAVE : swc_wishbone_slave
port map (
rst_n_i => rst_n_i,
clk_sys_i => clk_i,
wb_adr_i => wb_in.adr(1 downto 0),
wb_dat_i => wb_in.dat,
wb_dat_o => wb_out.dat,
wb_cyc_i => wb_in.cyc,
wb_sel_i => wb_in.sel,
wb_stb_i => wb_in.stb,
wb_we_i => wb_in.we,
wb_ack_o => wb_out.ack,
wb_stall_o=> wb_out.stall,
regs_o => regs_fromwb,
regs_i => regs_towb);
regs_towb.cur_fpg_i(c_mpm_page_addr_width downto 0) <= mmu_free_pages;
regs_towb.cur_fpg_i(31 downto c_mpm_page_addr_width+1) <= (others=>'0');
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
mmu_afull_thr <= std_logic_vector(to_unsigned(c_ALMOST_FULL_THR, c_mpm_page_addr_width+1));
elsif regs_fromwb.afull_thr_load_o = '1' then
mmu_afull_thr <= regs_fromwb.afull_thr_o(c_mpm_page_addr_width downto 0);
end if;
end if;
end process;
regs_towb.afull_thr_i(c_mpm_page_addr_width downto 0) <= mmu_afull_thr;
regs_towb.afull_thr_i(31 downto c_mpm_page_addr_width+1) <= (others=>'0');
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
mmu_pmin <= to_unsigned(c_mpm_page_num, c_mpm_page_addr_width+1);
mmu_pmin_prev <= to_unsigned(c_mpm_page_num, c_mpm_page_addr_width+1);
mmu_pmax <= (others=>'0');
mmu_pmax_prev <= to_unsigned(c_mpm_page_num, c_mpm_page_addr_width+1);
elsif regs_fromwb.csr_new_stat_o = '1' then
mmu_pmin_prev <= mmu_pmin;
mmu_pmax_prev <= mmu_pmax;
mmu_pmin <= to_unsigned(c_mpm_page_num, c_mpm_page_addr_width+1);
mmu_pmax <= (others=>'0');
-- we look for minimal and maximal values
elsif unsigned(mmu_free_pages) > mmu_pmax then
mmu_pmax <= unsigned(mmu_free_pages);
elsif unsigned(mmu_free_pages) < mmu_pmin then
mmu_pmin <= unsigned(mmu_free_pages);
end if;
end if;
end process;
regs_towb.stat_min_fpg_i(c_mpm_page_addr_width downto 0) <= std_logic_vector(mmu_pmin_prev);
regs_towb.stat_min_fpg_i(15 downto c_mpm_page_addr_width+1) <= (others=>'0');
regs_towb.stat_max_fpg_i(c_mpm_page_addr_width downto 0) <= std_logic_vector(mmu_pmax_prev);
regs_towb.stat_max_fpg_i(15 downto c_mpm_page_addr_width+1) <= (others=>'0');
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
regs_towb.csr_mpm_afull_i <= '0';
regs_towb.csr_mpm_full_i <= '0';
mmu_was_full <= '0';
mmu_was_afull <= '0';
elsif regs_fromwb.csr_new_stat_o = '1' then
regs_towb.csr_mpm_afull_i <= mmu_was_afull;
regs_towb.csr_mpm_full_i <= mmu_was_full;
mmu_was_full <= '0';
mmu_was_afull <= '0';
else
if or_reduce(mmu2ib_res_almost_full) = '1' then
mmu_was_afull <= '1';
end if;
if or_reduce(mmu2ib_res_full) = '1' then
mmu_was_full <= '1';
end if;
end if;
end if;
end process;
-------------------------------------------------------------------------------
nomem_o <= mmu_nomem;
tap <= tap_alloc & tap_ob(2);
......@@ -679,8 +811,7 @@ architecture rtl of xswc_core is
g_page_size => g_mpm_page_size,
g_special_res_num_pages => c_res_mmu_special_res_num_pages,
g_resource_num => c_res_mmu_resource_num,
g_resource_num_width => c_res_mmu_resource_num_width,
g_num_dbg_vector_width => c_hwdu_mmu_width
g_resource_num_width => c_res_mmu_resource_num_width
)
port map (
rst_n_i => rst_n_i,
......@@ -723,7 +854,9 @@ architecture rtl of xswc_core is
res_full_o => mmu2ib_res_full,
res_almost_full_o => mmu2ib_res_almost_full,
dbg_o => hwdu_mmu
free_pages_o => mmu_free_pages,
afull_thr_i => mmu_afull_thr
-- tap_out_o => tap_alloc
);
......@@ -802,8 +935,6 @@ architecture rtl of xswc_core is
ib_hp_i => ib_hp
);
dbg_o(31 downto 0) <= "00" & hwdu_mmu;
WDOG_GEN: for I in 0 to g_num_ports-1 generate
wdog_o(I)(c_ALLOC_FSM_IDX) <= wdog_ib(I)(c_ALLOC_FSM_IDX);
wdog_o(I)(c_TRANS_FSM_IDX) <= wdog_ib(I)(c_TRANS_FSM_IDX);
......
......@@ -188,7 +188,7 @@ end scb_top_bare;
architecture rtl of scb_top_bare is
constant c_GW_VERSION : std_logic_vector(31 downto 0) := x"20_02_14_00"; --DD_MM_YY_VV
constant c_NUM_WB_SLAVES : integer := 14;
constant c_NUM_WB_SLAVES : integer := 15;
constant c_NUM_PORTS : integer := g_num_ports;
constant c_MAX_PORTS : integer := 18;
constant c_NUM_GL_PAUSE : integer := 2; -- number of output global PAUSE sources for SWcore
......@@ -220,6 +220,7 @@ architecture rtl of scb_top_bare is
constant c_SLAVE_PSTATS : integer := 11;
constant c_SLAVE_HWIU : integer := 12;
constant c_SLAVE_WDOG : integer := 13;
constant c_SLAVE_SWC : integer := 14;
--constant c_SLAVE_DUMMY : integer := 13;
......@@ -799,6 +800,8 @@ begin
U_Swcore : xswc_core
generic map (
g_interface_mode => PIPELINED,
g_address_granularity => BYTE,
g_prio_num => 8,
g_output_queue_num => 8,
g_max_pck_size => 10 * 1024,
......@@ -817,8 +820,7 @@ begin
g_mpm_fifo_size => 8,
g_mpm_fetch_next_pg_in_advance => false,
g_drop_outqueue_head_on_full => true,
g_num_global_pause => c_NUM_GL_PAUSE,
g_num_dbg_vector_width => c_DBG_V_SWCORE)
g_num_global_pause => c_NUM_GL_PAUSE)
port map (
clk_i => clk_sys,
clk_mpm_core_i => clk_aux_i,
......@@ -835,13 +837,12 @@ begin
global_pause_i => global_pause,
perport_pause_i => fc_rx_pause,
dbg_o => dbg_n_regs(32+c_DBG_V_SWCORE-1 downto 32),
rtu_rsp_i => rtu_rsp,
rtu_ack_o => swc_rtu_ack,
rtu_abort_o =>rtu_rsp_abort,-- open --rtu_rsp_abort
wdog_o => swc_wdog_out
);
wdog_o => swc_wdog_out,
wb_i => cnx_master_out(c_SLAVE_SWC),
wb_o => cnx_master_in(c_SLAVE_SWC));
-- SWcore global pause nr=0 assigned to TRU
global_pause(0) <= swc2tru_req;
......
......@@ -220,6 +220,22 @@ package wrs_sdb_pkg is
date => x"20150630",
name => "WRSW WATCHDOG ")));
constant c_xswc_swcore_sdb: t_sdb_device := (
abi_class => x"0000",
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7",
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"5783046b", -- echo -n "xswc_core" | md5sum - | cut -c1-8
version => x"00000001",
date => x"20160810",
name => "WRSW SWCORE ")));
-- RT subsystem crossbar
constant c_rtbar_layout : t_sdb_record_array(7 downto 0) :=
(0 => f_sdb_embed_device(f_xwb_dpram(16384), x"00000000"),
......@@ -259,7 +275,7 @@ package wrs_sdb_pkg is
f_xwb_bridge_layout_sdb(true, c_epbar_layout, c_epbar_sdb_address);
-- WRS main crossbar
constant c_layout : t_sdb_record_array(13+4 downto 0) :=
constant c_layout : t_sdb_record_array(14+4 downto 0) :=
(0 => f_sdb_embed_bridge(c_rtbar_bridge_sdb, x"00000000"), --RT subsystem
1 => f_sdb_embed_device(c_xwrsw_nic_sdb, x"00020000"), --NIC
2 => f_sdb_embed_bridge(c_epbar_bridge_sdb, x"00030000"), --Endpoints
......@@ -274,10 +290,11 @@ package wrs_sdb_pkg is
11 => f_sdb_embed_device(c_xwrsw_pstats_sdb, x"00058000"), --PSTATS
12 => f_sdb_embed_device(c_xwrsw_hwiu_sdb, x"00059000"), --HWIU
13 => f_sdb_embed_device(c_xwrsw_watchdog_sdb, x"0005a000"), --Watchdog
14 => f_sdb_embed_repo_url(c_sdb_repo_url),
15 => f_sdb_embed_synthesis(c_sdb_top_syn_info),
16 => f_sdb_embed_synthesis(c_sdb_general_cores_syn_info),
17 => f_sdb_embed_synthesis(c_sdb_wr_cores_syn_info));
14 => f_sdb_embed_device(c_xswc_swcore_sdb, x"0005b000"), --SWcore
15 => f_sdb_embed_repo_url(c_sdb_repo_url),
16 => f_sdb_embed_synthesis(c_sdb_top_syn_info),
17 => f_sdb_embed_synthesis(c_sdb_general_cores_syn_info),
18 => f_sdb_embed_synthesis(c_sdb_wr_cores_syn_info));
constant c_sdb_address : t_wishbone_address := x"00070000";
end wrs_sdb_pkg;
......@@ -264,6 +264,8 @@ package wrsw_components_pkg is
component xswc_core is
generic(
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := BYTE;
g_prio_num : integer ;
g_output_queue_num : integer ;
g_max_pck_size : integer ;
......@@ -284,8 +286,7 @@ package wrsw_components_pkg is
g_mpm_fifo_size : integer ;
g_mpm_fetch_next_pg_in_advance : boolean ;
g_drop_outqueue_head_on_full : boolean ;
g_num_global_pause : integer ;
g_num_dbg_vector_width : integer := 32
g_num_global_pause : integer
);
port (
clk_i : in std_logic;
......@@ -301,13 +302,13 @@ package wrsw_components_pkg is
global_pause_i : in t_global_pause_request_array(g_num_global_pause-1 downto 0);
perport_pause_i : in t_pause_request_array(g_num_ports-1 downto 0);
shaper_drop_at_hp_ena_i : in std_logic := '0';
dbg_o : out std_logic_vector(g_num_dbg_vector_width - 1 downto 0);
rtu_rsp_i : in t_rtu_response_array(g_num_ports - 1 downto 0);
rtu_ack_o : out std_logic_vector(g_num_ports - 1 downto 0);
rtu_abort_o : out std_logic_vector(g_num_ports - 1 downto 0);
wdog_o : out t_swc_fsms_array(g_num_ports-1 downto 0);
nomem_o : out std_logc
);
nomem_o : out std_logc;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out);
end component;
component xwrsw_rtu
generic (
......
......@@ -324,6 +324,8 @@ package wrsw_top_pkg is
end component;
component xswc_core is
generic(
g_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_address_granularity : t_wishbone_address_granularity := BYTE;
g_prio_num : integer ;--:= c_swc_output_prio_num; [works only for value of 8, output_block-causes problem]
g_output_queue_num : integer ;
g_max_pck_size : integer ;-- in 16bits words --:= c_swc_max_pck_size
......@@ -364,8 +366,9 @@ package wrsw_top_pkg is
rtu_ack_o : out std_logic_vector(g_num_ports - 1 downto 0);
rtu_abort_o : out std_logic_vector(g_num_ports - 1 downto 0);
wdog_o : out t_swc_fsms_array(g_num_ports-1 downto 0);
nomem_o : out std_logic
);
nomem_o : out std_logic;
wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out);
end component;
component xwrsw_rtu
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment