Commit 55291edc authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

wrsw_nic: bw throttling, no throttling yet

parent d6cf3c7c
...@@ -6,6 +6,7 @@ files = [ "nic_constants_pkg.vhd" , ...@@ -6,6 +6,7 @@ files = [ "nic_constants_pkg.vhd" ,
"nic_tx_fsm.vhd" , "nic_tx_fsm.vhd" ,
"nic_buffer.vhd" , "nic_buffer.vhd" ,
"nic_elastic_buffer.vhd", "nic_elastic_buffer.vhd",
"nic_bw_throttling.vhd",
"nic_wbgen2_pkg.vhd", "nic_wbgen2_pkg.vhd",
"xwrsw_nic.vhd", "xwrsw_nic.vhd",
"wrsw_nic.vhd"]; "wrsw_nic.vhd"];
......
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wr_fabric_pkg.all;
--use work.gencores_pkg.all;
entity nic_bw_throttling is
generic (
g_true_random : boolean := false);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_o : out t_wrf_source_out;
src_i : in t_wrf_source_in;
bw_o : out std_logic_vector(31 downto 0);
rnd_o : out std_logic_vector(31 downto 0));
end nic_bw_throttling;
architecture behav of nic_bw_throttling is
signal bw_cnt : unsigned(31 downto 0);
signal bw_reg : unsigned(31 downto 0);
signal is_data : std_logic;
signal drop_frame : std_logic;
type t_fwd_fsm is (WAIT_FRAME, FLUSH, PASS, DROP);
signal state_fwd : t_fwd_fsm;
signal wrf_reg : t_wrf_sink_in;
signal ring_out : std_logic_vector(31 downto 0);
signal rnd_reg : std_logic_vector(31 downto 0);
--attribute keep : string;
--attribute keep of ring_out : signal is "true";
--attribute keep_hierarchy : string;
--attribute keep_hierarchy of behav : architecture is "true";
attribute S : string;
attribute S of ring_out : signal is "true";
constant c_LFSR_START : std_logic_vector := x"A5A5";
begin
-------------------------------------------------
-- Random number generation --
-------------------------------------------------
GEN_RND: if g_true_random generate
-- based on Generalized Ring Oscillator
ring_out(0) <= ring_out(31) xnor ring_out(0) xnor ring_out(1);
GEN_RND: for I in 1 to 30 generate
ring_out(I) <= ring_out(I-1) xor ring_out(I) xor ring_out(I+1);
end generate;
ring_out(31) <= ring_out(30) xor ring_out(31) xor ring_out(0);
--GEN_ANTI_META: for J in 0 to 31 generate
-- SYNC_FFS: gc_sync_ffs
-- port map (
-- clk_i => clk_sys_i,
-- rst_n_i => rst_n_i,
-- data_i => ring_out(J),
-- synced_o => rnd_reg(J));
--end generate;
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
rnd_reg <= (others=>'0');
else
rnd_reg <= ring_out;
end if;
end if;
end process;
end generate;
GEN_PSEUDO_RND: if not g_true_random generate
-- based on LSFR x^16 + x^15 + x^13 + x^4 + 1
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
rnd_reg(31 downto 0) <= (others=>'0');
rnd_reg(15 downto 0) <= c_LFSR_START;
else
rnd_reg(0) <= rnd_reg(15) xor rnd_reg(14) xor rnd_reg(12) xor rnd_reg(3);
rnd_reg(15 downto 1) <= rnd_reg(14 downto 0);
end if;
end if;
end process;
end generate;
rnd_o <= rnd_reg;
-------------------------------------------------
-- Forwarding or dropping frames --
-------------------------------------------------
drop_frame <= '0';
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
state_fwd <= WAIT_FRAME;
wrf_reg <= c_dummy_snk_in;
snk_o <= c_dummy_src_in;
src_o <= c_dummy_snk_in;
else
case state_fwd is
when WAIT_FRAME =>
snk_o.ack <= '0';
snk_o.err <= '0';
snk_o.rty <= '0';
src_o <= c_dummy_snk_in;
if (snk_i.cyc='1' and snk_i.stb='1') then
-- new frame is transmitted
snk_o.stall <= '1';
wrf_reg <= snk_i;
if (drop_frame = '0') then
state_fwd <= FLUSH;
elsif (drop_frame = '1') then
state_fwd <= DROP;
end if;
else
snk_o.stall <= '0';
end if;
when FLUSH =>
-- flush wrf_reg stored on stall or in WAIT_FRAME
snk_o <= src_i;
if (src_i.stall = '0') then
src_o <= wrf_reg;
state_fwd <= PASS;
end if;
when PASS =>
snk_o <= src_i;
if (src_i.stall = '0') then
src_o <= snk_i;
else
wrf_reg <= snk_i;
state_fwd <= FLUSH;
end if;
when DROP =>
-- ack everything from SNK, pass nothing to SRC
snk_o.stall <= '0';
snk_o.err <= '0';
snk_o.rty <= '0';
src_o <= c_dummy_snk_in;
if (snk_i.stb='1') then
snk_o.ack <= '1';
else
snk_o.ack <= '0';
end if;
if (snk_i.cyc='0' and snk_i.stb='0') then
state_fwd <= WAIT_FRAME;
end if;
end case;
end if;
end if;
end process;
-------------------------------------------------
-- Calculating bandwidth actually going to ARM --
-------------------------------------------------
is_data <= '1' when (snk_i.adr=c_WRF_DATA and snk_i.cyc='1' and snk_i.stb='1') else
'0';
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or pps_valid_i = '0' then
bw_cnt <= (others=>'0');
bw_reg <= (others=>'0');
elsif pps_p_i = '1' then
bw_reg <= bw_cnt;
bw_cnt <= (others=>'0');
elsif is_data = '1' then
-- we count incoming bytes here
if snk_i.sel(0) = '1' then
-- 16bits carry valid data
bw_cnt <= bw_cnt + 2;
elsif snk_i.sel(0) = '0' then
-- only 8bits carry valid data
bw_cnt <= bw_cnt + 1;
end if;
end if;
end if;
end process;
bw_o <= std_logic_vector(bw_reg);
end behav;
...@@ -57,6 +57,8 @@ entity nic_rx_fsm is ...@@ -57,6 +57,8 @@ entity nic_rx_fsm is
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- WRF sink -- WRF sink
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -121,6 +123,20 @@ architecture behavioral of NIC_RX_FSM is ...@@ -121,6 +123,20 @@ architecture behavioral of NIC_RX_FSM is
dreq_i : in std_logic); dreq_i : in std_logic);
end component; end component;
component nic_bw_throttling
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_o : out t_wrf_source_out;
src_i : in t_wrf_source_in;
bw_o : out std_logic_vector(31 downto 0);
rnd_o : out std_logic_vector(31 downto 0));
end component;
type t_rx_fsm_state is (RX_DISABLED, RX_WAIT_SOF, RX_REQUEST_DESCRIPTOR, RX_DATA, RX_UPDATE_DESC, RX_MEM_RESYNC, RX_MEM_FLUSH); type t_rx_fsm_state is (RX_DISABLED, RX_WAIT_SOF, RX_REQUEST_DESCRIPTOR, RX_DATA, RX_UPDATE_DESC, RX_MEM_RESYNC, RX_MEM_FLUSH);
...@@ -147,17 +163,33 @@ architecture behavioral of NIC_RX_FSM is ...@@ -147,17 +163,33 @@ architecture behavioral of NIC_RX_FSM is
signal fab_in : t_ep_internal_fabric; signal fab_in : t_ep_internal_fabric;
signal fab_dreq : std_logic; signal fab_dreq : std_logic;
signal bw_src_out : t_wrf_source_out;
signal bw_src_in : t_wrf_source_in;
begin begin
U_Throttling: nic_bw_throttling
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
pps_p_i => pps_p_i,
pps_valid_i => pps_valid_i,
snk_i => snk_i,
snk_o => snk_o,
src_o => bw_src_out,
src_i => bw_src_in,
bw_o => regs_o.bw_i,
rnd_o => regs_o.rnd_i);
U_Buffer : nic_elastic_buffer U_Buffer : nic_elastic_buffer
generic map ( generic map (
g_depth => 64) g_depth => 64)
port map ( port map (
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
snk_i => snk_i, snk_i => bw_src_out, --snk_i,
snk_o => snk_o, snk_o => bw_src_in, --snk_o,
fab_o => fab_in, fab_o => fab_in,
dreq_i => fab_dreq); dreq_i => fab_dreq);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : nic_wbgen2_pkg.vhd -- File : nic_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wr_nic.wb -- Author : auto-generated by wbgen2 from wr_nic.wb
-- Created : Fri Jul 3 16:18:39 2015 -- Created : Thu Jul 28 10:18:55 2016
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb
...@@ -27,6 +27,8 @@ package nic_wbgen2_pkg is ...@@ -27,6 +27,8 @@ package nic_wbgen2_pkg is
sr_tx_error_i : std_logic; sr_tx_error_i : std_logic;
sr_cur_tx_desc_i : std_logic_vector(2 downto 0); sr_cur_tx_desc_i : std_logic_vector(2 downto 0);
sr_cur_rx_desc_i : std_logic_vector(2 downto 0); sr_cur_rx_desc_i : std_logic_vector(2 downto 0);
bw_i : std_logic_vector(31 downto 0);
rnd_i : std_logic_vector(31 downto 0);
end record; end record;
constant c_nic_in_registers_init_value: t_nic_in_registers := ( constant c_nic_in_registers_init_value: t_nic_in_registers := (
...@@ -35,7 +37,9 @@ package nic_wbgen2_pkg is ...@@ -35,7 +37,9 @@ package nic_wbgen2_pkg is
sr_tx_done_i => '0', sr_tx_done_i => '0',
sr_tx_error_i => '0', sr_tx_error_i => '0',
sr_cur_tx_desc_i => (others => '0'), sr_cur_tx_desc_i => (others => '0'),
sr_cur_rx_desc_i => (others => '0') sr_cur_rx_desc_i => (others => '0'),
bw_i => (others => '0'),
rnd_i => (others => '0')
); );
-- Output registers (WB slave -> user design) -- Output registers (WB slave -> user design)
...@@ -71,20 +75,20 @@ end package; ...@@ -71,20 +75,20 @@ end package;
package body nic_wbgen2_pkg is package body nic_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is function f_x_to_zero (x:std_logic) return std_logic is
begin begin
if(x = 'X' or x = 'U') then if x = '1' then
return '0'; return '1';
else else
return x; return '0';
end if; end if;
end function; end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0); variable tmp: std_logic_vector(x'length-1 downto 0);
begin begin
for i in 0 to x'length-1 loop for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then if x(i) = '1' then
tmp(i):= '0'; tmp(i):= '1';
else else
tmp(i):=x(i); tmp(i):= '0';
end if; end if;
end loop; end loop;
return tmp; return tmp;
...@@ -98,6 +102,8 @@ tmp.sr_tx_done_i := f_x_to_zero(left.sr_tx_done_i) or f_x_to_zero(right.sr_tx_do ...@@ -98,6 +102,8 @@ tmp.sr_tx_done_i := f_x_to_zero(left.sr_tx_done_i) or f_x_to_zero(right.sr_tx_do
tmp.sr_tx_error_i := f_x_to_zero(left.sr_tx_error_i) or f_x_to_zero(right.sr_tx_error_i); tmp.sr_tx_error_i := f_x_to_zero(left.sr_tx_error_i) or f_x_to_zero(right.sr_tx_error_i);
tmp.sr_cur_tx_desc_i := f_x_to_zero(left.sr_cur_tx_desc_i) or f_x_to_zero(right.sr_cur_tx_desc_i); tmp.sr_cur_tx_desc_i := f_x_to_zero(left.sr_cur_tx_desc_i) or f_x_to_zero(right.sr_cur_tx_desc_i);
tmp.sr_cur_rx_desc_i := f_x_to_zero(left.sr_cur_rx_desc_i) or f_x_to_zero(right.sr_cur_rx_desc_i); tmp.sr_cur_rx_desc_i := f_x_to_zero(left.sr_cur_rx_desc_i) or f_x_to_zero(right.sr_cur_rx_desc_i);
tmp.bw_i := f_x_to_zero(left.bw_i) or f_x_to_zero(right.bw_i);
tmp.rnd_i := f_x_to_zero(left.rnd_i) or f_x_to_zero(right.rnd_i);
return tmp; return tmp;
end function; end function;
end package body; end package body;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- File : nic_wishbone_slave.vhd -- File : nic_wishbone_slave.vhd
-- Author : auto-generated by wbgen2 from wr_nic.wb -- Author : auto-generated by wbgen2 from wr_nic.wb
-- Created : Fri Jul 3 16:18:39 2015 -- Created : Thu Jul 28 10:18:55 2016
-- Standard : VHDL'87 -- Standard : VHDL'87
--------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb -- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb
...@@ -223,6 +223,18 @@ begin ...@@ -223,6 +223,18 @@ begin
rddata_reg(31) <= 'X'; rddata_reg(31) <= 'X';
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0010" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.bw_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0011" =>
if (wb_we_i = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.rnd_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1000" => when "1000" =>
if (wb_we_i = '1') then if (wb_we_i = '1') then
eic_idr_write_int <= '1'; eic_idr_write_int <= '1';
...@@ -460,6 +472,8 @@ begin ...@@ -460,6 +472,8 @@ begin
regs_o.sr_tx_error_o <= wrdata_reg(3); regs_o.sr_tx_error_o <= wrdata_reg(3);
-- Current TX descriptor -- Current TX descriptor
-- Current RX descriptor -- Current RX descriptor
-- Bytes-per-second
-- 32-bit random number for throttling
-- extra code for reg/fifo/mem: TX descriptors mem -- extra code for reg/fifo/mem: TX descriptors mem
-- RAM block instantiation for memory: TX descriptors mem -- RAM block instantiation for memory: TX descriptors mem
nic_dtx_raminst : wbgen2_dpssram nic_dtx_raminst : wbgen2_dpssram
......
...@@ -152,6 +152,32 @@ top = peripheral { ...@@ -152,6 +152,32 @@ top = peripheral {
}; };
}; };
reg {
name = "NIC Bandwidth Register";
prefix = "BW";
field {
name = "Bytes-per-second";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
load = LOAD_EXT;
};
};
reg {
name = "NIC Random Register";
prefix = "RND";
field {
name = "32-bit random number for throttling";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
load = LOAD_EXT;
};
};
irq { irq {
name = "Receive Complete"; name = "Receive Complete";
prefix = "rcomp"; prefix = "rcomp";
......
...@@ -54,6 +54,9 @@ entity wrsw_nic is ...@@ -54,6 +54,9 @@ entity wrsw_nic is
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Pipelined Wishbone interface -- Pipelined Wishbone interface
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -120,6 +123,8 @@ architecture rtl of wrsw_nic is ...@@ -120,6 +123,8 @@ architecture rtl of wrsw_nic is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in; snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
...@@ -154,6 +159,8 @@ begin ...@@ -154,6 +159,8 @@ begin
port map ( port map (
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i, rst_n_i => rst_n_i,
pps_p_i => pps_p_i,
pps_valid_i => pps_valid_i,
snk_i => snk_in, snk_i => snk_in,
snk_o => snk_out, snk_o => snk_out,
src_i => src_in, src_i => src_in,
......
...@@ -67,6 +67,9 @@ entity xwrsw_nic is ...@@ -67,6 +67,9 @@ entity xwrsw_nic is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- WRF sink -- WRF sink
...@@ -138,6 +141,8 @@ architecture rtl of xwrsw_nic is ...@@ -138,6 +141,8 @@ architecture rtl of xwrsw_nic is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in; snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
regs_i : in t_nic_out_registers; regs_i : in t_nic_out_registers;
...@@ -488,6 +493,9 @@ begin -- rtl ...@@ -488,6 +493,9 @@ begin -- rtl
clk_sys_i => clk_sys_i, clk_sys_i => clk_sys_i,
rst_n_i => nic_reset_n, rst_n_i => nic_reset_n,
pps_p_i => pps_p_i,
pps_valid_i => pps_valid_i,
snk_i => snk_i, snk_i => snk_i,
snk_o => snk_o, snk_o => snk_o,
......
...@@ -607,6 +607,8 @@ begin ...@@ -607,6 +607,8 @@ begin
port map ( port map (
clk_sys_i => clk_sys, clk_sys_i => clk_sys,
rst_n_i => rst_n_sys, rst_n_i => rst_n_sys,
pps_p_i => pps_csync,
pps_valid_i => pps_valid,
snk_i => endpoint_snk_in(c_NUM_PORTS), snk_i => endpoint_snk_in(c_NUM_PORTS),
snk_o => endpoint_snk_out(c_NUM_PORTS), snk_o => endpoint_snk_out(c_NUM_PORTS),
src_i => endpoint_src_in(c_NUM_PORTS), src_i => endpoint_src_in(c_NUM_PORTS),
......
...@@ -184,6 +184,8 @@ package wrsw_components_pkg is ...@@ -184,6 +184,8 @@ package wrsw_components_pkg is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in; snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
......
...@@ -184,6 +184,8 @@ package wrsw_top_pkg is ...@@ -184,6 +184,8 @@ package wrsw_top_pkg is
port ( port (
clk_sys_i : in std_logic; clk_sys_i : in std_logic;
rst_n_i : in std_logic; rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
snk_i : in t_wrf_sink_in; snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
......
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