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" ,
"nic_tx_fsm.vhd" ,
"nic_buffer.vhd" ,
"nic_elastic_buffer.vhd",
"nic_bw_throttling.vhd",
"nic_wbgen2_pkg.vhd",
"xwrsw_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
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
pps_p_i : in std_logic;
pps_valid_i : in std_logic;
-------------------------------------------------------------------------------
-- WRF sink
-------------------------------------------------------------------------------
......@@ -121,6 +123,20 @@ architecture behavioral of NIC_RX_FSM is
dreq_i : in std_logic);
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);
......@@ -147,17 +163,33 @@ architecture behavioral of NIC_RX_FSM is
signal fab_in : t_ep_internal_fabric;
signal fab_dreq : std_logic;
signal bw_src_out : t_wrf_source_out;
signal bw_src_in : t_wrf_source_in;
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
generic map (
g_depth => 64)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
snk_i => snk_i,
snk_o => snk_o,
snk_i => bw_src_out, --snk_i,
snk_o => bw_src_in, --snk_o,
fab_o => fab_in,
dreq_i => fab_dreq);
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : nic_wbgen2_pkg.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb
......@@ -27,6 +27,8 @@ package nic_wbgen2_pkg is
sr_tx_error_i : std_logic;
sr_cur_tx_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;
constant c_nic_in_registers_init_value: t_nic_in_registers := (
......@@ -35,7 +37,9 @@ package nic_wbgen2_pkg is
sr_tx_done_i => '0',
sr_tx_error_i => '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)
......@@ -71,20 +75,20 @@ end package;
package body nic_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if(x = 'X' or x = 'U') then
return '0';
if x = '1' then
return '1';
else
return x;
end if;
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) = 'X' or x(i) = 'U') then
tmp(i):= '0';
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):=x(i);
tmp(i):= '0';
end if;
end loop;
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
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_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;
end function;
end package body;
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : nic_wishbone_slave.vhd
-- 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
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_nic.wb
......@@ -223,6 +223,18 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(0) <= '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" =>
if (wb_we_i = '1') then
eic_idr_write_int <= '1';
......@@ -460,6 +472,8 @@ begin
regs_o.sr_tx_error_o <= wrdata_reg(3);
-- Current TX descriptor
-- Current RX descriptor
-- Bytes-per-second
-- 32-bit random number for throttling
-- extra code for reg/fifo/mem: TX descriptors mem
-- RAM block instantiation for memory: TX descriptors mem
nic_dtx_raminst : wbgen2_dpssram
......
......@@ -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 {
name = "Receive Complete";
prefix = "rcomp";
......
......@@ -54,6 +54,9 @@ entity wrsw_nic is
clk_sys_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
-------------------------------------------------------------------------------
......@@ -120,6 +123,8 @@ architecture rtl of wrsw_nic is
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_i : in t_wrf_source_in;
......@@ -154,6 +159,8 @@ begin
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_in,
snk_o => snk_out,
src_i => src_in,
......
......@@ -67,6 +67,9 @@ entity xwrsw_nic is
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;
-------------------------------------------------------------------------------
-- WRF sink
......@@ -138,6 +141,8 @@ architecture rtl of xwrsw_nic is
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;
regs_i : in t_nic_out_registers;
......@@ -488,6 +493,9 @@ begin -- rtl
clk_sys_i => clk_sys_i,
rst_n_i => nic_reset_n,
pps_p_i => pps_p_i,
pps_valid_i => pps_valid_i,
snk_i => snk_i,
snk_o => snk_o,
......
......@@ -607,6 +607,8 @@ begin
port map (
clk_sys_i => clk_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_o => endpoint_snk_out(c_NUM_PORTS),
src_i => endpoint_src_in(c_NUM_PORTS),
......
......@@ -184,6 +184,8 @@ package wrsw_components_pkg is
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_i : in t_wrf_source_in;
......
......@@ -184,6 +184,8 @@ package wrsw_top_pkg is
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_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