Commit 7d0948af authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

wrsw_nic: Random Early Detection for b/w throttling

parent a3f22277
-------------------------------------------------------------------------------
-- Title : Rx bandwidth throttling
-- Project : WhiteRabbit Switch
-------------------------------------------------------------------------------
-- File : nic_bw_throttling.vhd
-- Author : Grzegorz Daniluk
-- Company : CERN BE-Co-HT
-- Created : 2016-07-28
-- Platform : FPGA-generic
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
-- Module implementing Random Early Detection algorithm for throttling the
-- bandwidth of RX traffic on NIC.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2016 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
-- 2016-08-01 1.0 greg.d Created
-------------------------------------------------------------------------------
library IEEE; library IEEE;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use work.wr_fabric_pkg.all; use work.wr_fabric_pkg.all;
--use work.gencores_pkg.all;
entity nic_bw_throttling is entity nic_bw_throttling is
generic (
g_true_random : boolean := false);
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;
...@@ -20,88 +56,99 @@ entity nic_bw_throttling is ...@@ -20,88 +56,99 @@ entity nic_bw_throttling is
src_o : out t_wrf_source_out; src_o : out t_wrf_source_out;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
bw_o : out std_logic_vector(31 downto 0); new_limit_i : in std_logic;
rnd_o : out std_logic_vector(31 downto 0)); bwmax_kbps_i : in unsigned(15 downto 0);
bw_bps_o : out std_logic_vector(31 downto 0));
end nic_bw_throttling; end nic_bw_throttling;
architecture behav of nic_bw_throttling is architecture behav of nic_bw_throttling is
signal bw_cnt : unsigned(31 downto 0); signal bw_bps_cnt : unsigned(31 downto 0);
signal bw_reg : unsigned(31 downto 0); signal is_data : std_logic;
signal is_data : std_logic; signal src_out : t_wrf_source_out;
signal drop_frame : std_logic; signal drop_frame : std_logic;
type t_fwd_fsm is (WAIT_FRAME, FLUSH, PASS, DROP); type t_fwd_fsm is (WAIT_FRAME, FLUSH, PASS, DROP);
signal state_fwd : t_fwd_fsm; signal state_fwd : t_fwd_fsm;
signal wrf_reg : t_wrf_sink_in; signal wrf_reg : t_wrf_sink_in;
signal ring_out : std_logic_vector(31 downto 0); signal rnd_reg : unsigned(7 downto 0);
signal rnd_reg : std_logic_vector(31 downto 0);
--attribute keep : string; constant c_LFSR_START : unsigned(7 downto 0) := x"A5";
--attribute keep of ring_out : signal is "true"; constant c_DROP_STEP : unsigned(7 downto 0) := x"20"; --32
--attribute keep_hierarchy : string; constant c_DROP_THR_MAX : unsigned(8 downto 0) := to_unsigned(256, 9);
--attribute keep_hierarchy of behav : architecture is "true"; signal drop_thr : unsigned(8 downto 0); -- 1 more bit than rnd_reg
attribute S : string; -- so that we can have drop_thr larger than any random number and drop the
attribute S of ring_out : signal is "true"; -- whole traffic.
signal bwmin_kbps : unsigned(15 downto 0);
constant c_LFSR_START : std_logic_vector := x"A5A5"; signal bwcur_kbps : unsigned(31 downto 0);
signal last_thr_kbps : unsigned(31 downto 0);
signal thr_step_kbps : unsigned(15 downto 0);
begin begin
------------------------------------------------- -------------------------------------------------
-- Random number generation -- -- Pseudo-random number generation --
-- based on LSFR x^8 + x^6 + x^5 + x^4 + 1 --
------------------------------------------------- -------------------------------------------------
GEN_RND: if g_true_random generate process(clk_sys_i)
-- based on Generalized Ring Oscillator begin
ring_out(0) <= ring_out(31) xnor ring_out(0) xnor ring_out(1); if rising_edge(clk_sys_i) then
GEN_RND: for I in 1 to 30 generate if rst_n_i = '0' then
ring_out(I) <= ring_out(I-1) xor ring_out(I) xor ring_out(I+1); rnd_reg(7 downto 0) <= c_LFSR_START;
end generate; else
ring_out(31) <= ring_out(30) xor ring_out(31) xor ring_out(0); rnd_reg(0) <= rnd_reg(7) xor rnd_reg(5) xor rnd_reg(4) xor rnd_reg(3);
rnd_reg(7 downto 1) <= rnd_reg(6 downto 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 if;
end process; end if;
end generate; end process;
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) -- Monitoring b/w and generating drop decisions--
begin -------------------------------------------------
if rising_edge(clk_sys_i) then drop_frame <= '1' when (rnd_reg < drop_thr) else
if rst_n_i = '0' then '0';
rnd_reg(31 downto 0) <= (others=>'0');
rnd_reg(15 downto 0) <= c_LFSR_START; -- set min b/w from which we start the throttling
else -- set it to half of the required max b/w
rnd_reg(0) <= rnd_reg(15) xor rnd_reg(14) xor rnd_reg(12) xor rnd_reg(3); bwmin_kbps <= shift_right(bwmax_kbps_i, 1);
rnd_reg(15 downto 1) <= rnd_reg(14 downto 0);
-- convert current b/w to KBps
-- it's bw_bps_cnt divided by 1024 (2^10)
bwcur_kbps <= shift_right(bw_bps_cnt, 10);
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or new_limit_i = '1' then
drop_thr <= (others=>'0');
last_thr_kbps <= x"0000" & bwmin_kbps;
thr_step_kbps <= shift_right(bwmax_kbps_i - bwmin_kbps, 3);
-- both max and min b/w we divide by 8 (because we want 8 steps like with
-- c_DROP_STEP = 64 for range 0-255)
else
if (bwcur_kbps > last_thr_kbps and drop_thr < c_DROP_THR_MAX) then
-- current b/w is larger than the last crossed threshold
-- we increase the probability of drop
drop_thr <= drop_thr + c_DROP_STEP;
last_thr_kbps <= last_thr_kbps + thr_step_kbps;
elsif (bwcur_kbps + thr_step_kbps < last_thr_kbps and drop_thr > 0) then
-- current b/w has dropped below the last crossed threshold,
-- we decrease the probability of drop
drop_thr <= drop_thr - c_DROP_STEP;
last_thr_kbps <= last_thr_kbps - thr_step_kbps;
end if; end if;
end if;
end process;
end generate; end if;
end if;
end process;
rnd_o <= rnd_reg;
------------------------------------------------- -------------------------------------------------
-- Forwarding or dropping frames -- -- Forwarding or dropping frames --
------------------------------------------------- -------------------------------------------------
drop_frame <= '0';
process(clk_sys_i) process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
...@@ -109,15 +156,15 @@ begin ...@@ -109,15 +156,15 @@ begin
state_fwd <= WAIT_FRAME; state_fwd <= WAIT_FRAME;
wrf_reg <= c_dummy_snk_in; wrf_reg <= c_dummy_snk_in;
snk_o <= c_dummy_src_in; snk_o <= c_dummy_src_in;
src_o <= c_dummy_snk_in; src_out <= c_dummy_snk_in;
else else
case state_fwd is case state_fwd is
when WAIT_FRAME => when WAIT_FRAME =>
snk_o.ack <= '0'; snk_o.ack <= '0';
snk_o.err <= '0'; snk_o.err <= '0';
snk_o.rty <= '0'; snk_o.rty <= '0';
src_o <= c_dummy_snk_in; src_out <= c_dummy_snk_in;
if (snk_i.cyc='1' and snk_i.stb='1') then if (snk_i.cyc='1' and snk_i.stb='1') then
-- new frame is transmitted -- new frame is transmitted
snk_o.stall <= '1'; snk_o.stall <= '1';
...@@ -136,14 +183,17 @@ begin ...@@ -136,14 +183,17 @@ begin
-- flush wrf_reg stored on stall or in WAIT_FRAME -- flush wrf_reg stored on stall or in WAIT_FRAME
snk_o <= src_i; snk_o <= src_i;
if (src_i.stall = '0') then if (src_i.stall = '0') then
src_o <= wrf_reg; src_out <= wrf_reg;
state_fwd <= PASS; state_fwd <= PASS;
end if; end if;
when PASS => when PASS =>
snk_o <= src_i; snk_o <= src_i;
if (src_i.stall = '0') then if (src_i.stall = '0') then
src_o <= snk_i; src_out <= snk_i;
if (snk_i.cyc='0' and snk_i.stb='0') then
state_fwd <= WAIT_FRAME;
end if;
else else
wrf_reg <= snk_i; wrf_reg <= snk_i;
state_fwd <= FLUSH; state_fwd <= FLUSH;
...@@ -154,7 +204,7 @@ begin ...@@ -154,7 +204,7 @@ begin
snk_o.stall <= '0'; snk_o.stall <= '0';
snk_o.err <= '0'; snk_o.err <= '0';
snk_o.rty <= '0'; snk_o.rty <= '0';
src_o <= c_dummy_snk_in; src_out <= c_dummy_snk_in;
if (snk_i.stb='1') then if (snk_i.stb='1') then
snk_o.ack <= '1'; snk_o.ack <= '1';
else else
...@@ -169,36 +219,35 @@ begin ...@@ -169,36 +219,35 @@ begin
end if; end if;
end process; end process;
src_o <= src_out;
------------------------------------------------- -------------------------------------------------
-- Calculating bandwidth actually going to ARM -- -- 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 is_data <= '1' when (src_out.adr=c_WRF_DATA and src_out.cyc='1' and src_out.stb='1' and src_i.stall='0') else
'0'; '0';
process(clk_sys_i) process(clk_sys_i)
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
if rst_n_i = '0' or pps_valid_i = '0' then if rst_n_i = '0' or pps_valid_i = '0' then
bw_cnt <= (others=>'0'); bw_bps_cnt <= (others=>'0');
bw_reg <= (others=>'0'); bw_bps_o <= (others=>'0');
elsif pps_p_i = '1' then elsif pps_p_i = '1' then
bw_reg <= bw_cnt; bw_bps_cnt <= (others=>'0');
bw_cnt <= (others=>'0'); bw_bps_o <= std_logic_vector(bw_bps_cnt);
elsif is_data = '1' then elsif is_data = '1' then
-- we count incoming bytes here -- we count incoming bytes here
if snk_i.sel(0) = '1' then if src_out.sel(0) = '1' then
-- 16bits carry valid data -- 16bits carry valid data
bw_cnt <= bw_cnt + 2; bw_bps_cnt <= bw_bps_cnt + 2;
elsif snk_i.sel(0) = '0' then elsif src_out.sel(0) = '0' then
-- only 8bits carry valid data -- only 8bits carry valid data
bw_cnt <= bw_cnt + 1; bw_bps_cnt <= bw_bps_cnt + 1;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
bw_o <= std_logic_vector(bw_reg);
end behav; end behav;
...@@ -133,8 +133,9 @@ architecture behavioral of NIC_RX_FSM is ...@@ -133,8 +133,9 @@ architecture behavioral of NIC_RX_FSM is
snk_o : out t_wrf_sink_out; snk_o : out t_wrf_sink_out;
src_o : out t_wrf_source_out; src_o : out t_wrf_source_out;
src_i : in t_wrf_source_in; src_i : in t_wrf_source_in;
bw_o : out std_logic_vector(31 downto 0); new_limit_i : in std_logic;
rnd_o : out std_logic_vector(31 downto 0)); bwmax_kbps_i : in unsigned(15 downto 0);
bw_bps_o : out std_logic_vector(31 downto 0));
end component; end component;
...@@ -166,6 +167,7 @@ architecture behavioral of NIC_RX_FSM is ...@@ -166,6 +167,7 @@ architecture behavioral of NIC_RX_FSM is
signal bw_src_out : t_wrf_source_out; signal bw_src_out : t_wrf_source_out;
signal bw_src_in : t_wrf_source_in; signal bw_src_in : t_wrf_source_in;
signal max_bw_reg : std_logic_vector(15 downto 0);
begin begin
...@@ -179,8 +181,21 @@ begin ...@@ -179,8 +181,21 @@ begin
snk_o => snk_o, snk_o => snk_o,
src_o => bw_src_out, src_o => bw_src_out,
src_i => bw_src_in, src_i => bw_src_in,
bw_o => regs_o.bw_i, new_limit_i => regs_i.maxrxbw_load_o,
rnd_o => regs_o.rnd_i); bwmax_kbps_i => unsigned(regs_i.maxrxbw_o),
bw_bps_o => regs_o.rxbw_i);
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
max_bw_reg <= (others=>'0');
elsif regs_i.maxrxbw_load_o = '1' then
max_bw_reg <= regs_i.maxrxbw_o;
end if;
end if;
end process;
regs_o.maxrxbw_i <= max_bw_reg;
U_Buffer : nic_elastic_buffer U_Buffer : nic_elastic_buffer
generic map ( generic map (
......
...@@ -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 : Thu Jul 28 10:18:55 2016 -- Created : Mon Aug 1 16:03:57 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,8 +27,8 @@ package nic_wbgen2_pkg is ...@@ -27,8 +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); rxbw_i : std_logic_vector(31 downto 0);
rnd_i : std_logic_vector(31 downto 0); maxrxbw_i : std_logic_vector(15 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 := (
...@@ -38,8 +38,8 @@ package nic_wbgen2_pkg is ...@@ -38,8 +38,8 @@ package nic_wbgen2_pkg is
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'), rxbw_i => (others => '0'),
rnd_i => (others => '0') maxrxbw_i => (others => '0')
); );
-- Output registers (WB slave -> user design) -- Output registers (WB slave -> user design)
...@@ -54,6 +54,8 @@ package nic_wbgen2_pkg is ...@@ -54,6 +54,8 @@ package nic_wbgen2_pkg is
sr_tx_done_load_o : std_logic; sr_tx_done_load_o : std_logic;
sr_tx_error_o : std_logic; sr_tx_error_o : std_logic;
sr_tx_error_load_o : std_logic; sr_tx_error_load_o : std_logic;
maxrxbw_o : std_logic_vector(15 downto 0);
maxrxbw_load_o : std_logic;
end record; end record;
constant c_nic_out_registers_init_value: t_nic_out_registers := ( constant c_nic_out_registers_init_value: t_nic_out_registers := (
...@@ -65,7 +67,9 @@ package nic_wbgen2_pkg is ...@@ -65,7 +67,9 @@ package nic_wbgen2_pkg is
sr_tx_done_o => '0', sr_tx_done_o => '0',
sr_tx_done_load_o => '0', sr_tx_done_load_o => '0',
sr_tx_error_o => '0', sr_tx_error_o => '0',
sr_tx_error_load_o => '0' sr_tx_error_load_o => '0',
maxrxbw_o => (others => '0'),
maxrxbw_load_o => '0'
); );
function "or" (left, right: t_nic_in_registers) return t_nic_in_registers; function "or" (left, right: t_nic_in_registers) return t_nic_in_registers;
function f_x_to_zero (x:std_logic) return std_logic; function f_x_to_zero (x:std_logic) return std_logic;
...@@ -102,8 +106,8 @@ tmp.sr_tx_done_i := f_x_to_zero(left.sr_tx_done_i) or f_x_to_zero(right.sr_tx_do ...@@ -102,8 +106,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.rxbw_i := f_x_to_zero(left.rxbw_i) or f_x_to_zero(right.rxbw_i);
tmp.rnd_i := f_x_to_zero(left.rnd_i) or f_x_to_zero(right.rnd_i); tmp.maxrxbw_i := f_x_to_zero(left.maxrxbw_i) or f_x_to_zero(right.maxrxbw_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 : Thu Jul 28 10:18:55 2016 -- Created : Mon Aug 1 16:03:57 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
...@@ -120,6 +120,7 @@ begin ...@@ -120,6 +120,7 @@ begin
regs_o.sr_rec_load_o <= '0'; regs_o.sr_rec_load_o <= '0';
regs_o.sr_tx_done_load_o <= '0'; regs_o.sr_tx_done_load_o <= '0';
regs_o.sr_tx_error_load_o <= '0'; regs_o.sr_tx_error_load_o <= '0';
regs_o.maxrxbw_load_o <= '0';
eic_idr_write_int <= '0'; eic_idr_write_int <= '0';
eic_ier_write_int <= '0'; eic_ier_write_int <= '0';
eic_isr_write_int <= '0'; eic_isr_write_int <= '0';
...@@ -133,6 +134,7 @@ begin ...@@ -133,6 +134,7 @@ begin
regs_o.sr_rec_load_o <= '0'; regs_o.sr_rec_load_o <= '0';
regs_o.sr_tx_done_load_o <= '0'; regs_o.sr_tx_done_load_o <= '0';
regs_o.sr_tx_error_load_o <= '0'; regs_o.sr_tx_error_load_o <= '0';
regs_o.maxrxbw_load_o <= '0';
eic_idr_write_int <= '0'; eic_idr_write_int <= '0';
eic_ier_write_int <= '0'; eic_ier_write_int <= '0';
eic_isr_write_int <= '0'; eic_isr_write_int <= '0';
...@@ -141,6 +143,7 @@ begin ...@@ -141,6 +143,7 @@ begin
regs_o.sr_rec_load_o <= '0'; regs_o.sr_rec_load_o <= '0';
regs_o.sr_tx_done_load_o <= '0'; regs_o.sr_tx_done_load_o <= '0';
regs_o.sr_tx_error_load_o <= '0'; regs_o.sr_tx_error_load_o <= '0';
regs_o.maxrxbw_load_o <= '0';
end if; end if;
else else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
...@@ -226,13 +229,30 @@ begin ...@@ -226,13 +229,30 @@ begin
when "0010" => when "0010" =>
if (wb_we_i = '1') then if (wb_we_i = '1') then
end if; end if;
rddata_reg(31 downto 0) <= regs_i.bw_i; rddata_reg(31 downto 0) <= regs_i.rxbw_i;
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "0011" => when "0011" =>
if (wb_we_i = '1') then if (wb_we_i = '1') then
regs_o.maxrxbw_load_o <= '1';
end if; end if;
rddata_reg(31 downto 0) <= regs_i.rnd_i; rddata_reg(15 downto 0) <= regs_i.maxrxbw_i;
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';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1'; ack_sreg(0) <= '1';
ack_in_progress <= '1'; ack_in_progress <= '1';
when "1000" => when "1000" =>
...@@ -473,7 +493,8 @@ begin ...@@ -473,7 +493,8 @@ begin
-- Current TX descriptor -- Current TX descriptor
-- Current RX descriptor -- Current RX descriptor
-- Bytes-per-second -- Bytes-per-second
-- 32-bit random number for throttling -- KBytes-per-second
regs_o.maxrxbw_o <= wrdata_reg(15 downto 0);
-- 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
......
...@@ -153,8 +153,8 @@ top = peripheral { ...@@ -153,8 +153,8 @@ top = peripheral {
}; };
reg { reg {
name = "NIC Bandwidth Register"; name = "NIC Current Rx Bandwidth Register";
prefix = "BW"; prefix = "RXBW";
field { field {
name = "Bytes-per-second"; name = "Bytes-per-second";
type = SLV; type = SLV;
...@@ -166,14 +166,14 @@ top = peripheral { ...@@ -166,14 +166,14 @@ top = peripheral {
}; };
reg { reg {
name = "NIC Random Register"; name = "NIC Max Rx Bandwidth Register";
prefix = "RND"; prefix = "MAXRXBW";
field { field {
name = "32-bit random number for throttling"; name = "KBytes-per-second";
type = SLV; type = SLV;
size = 32; size = 16;
access_bus = READ_ONLY; access_bus = READ_WRITE;
access_dev = WRITE_ONLY; access_dev = READ_WRITE;
load = LOAD_EXT; load = LOAD_EXT;
}; };
}; };
......
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