Skip to content
Snippets Groups Projects
Commit 46a9ffa2 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Monitor FIFO fill level. Use BG xon block flow control when Tx FIFO gets too full.

parent 75f941c4
Branches
No related tags found
1 merge request!288Resolve L2SDP-836
...@@ -52,6 +52,8 @@ ENTITY eth_tester_tx IS ...@@ -52,6 +52,8 @@ ENTITY eth_tester_tx IS
ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0);
udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0); udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
tx_fifo_rd_emp : OUT STD_LOGIC;
tx_udp_sosi : OUT t_dp_sosi; tx_udp_sosi : OUT t_dp_sosi;
tx_udp_siso : IN t_dp_siso := c_dp_siso_rdy; tx_udp_siso : IN t_dp_siso := c_dp_siso_rdy;
...@@ -72,8 +74,12 @@ ARCHITECTURE str OF eth_tester_tx IS ...@@ -72,8 +74,12 @@ ARCHITECTURE str OF eth_tester_tx IS
CONSTANT c_empty_w : NATURAL := 2; -- for 0, 1, 2, 3 empty octets per word CONSTANT c_empty_w : NATURAL := 2; -- for 0, 1, 2, 3 empty octets per word
CONSTANT c_fifo_fill : NATURAL := c_eth_tester_bg_block_len_max / c_word_sz; -- = 9000 / 4 = 2250 -- Choose 10% extra margin for FIFO fill level that will result in BG block
CONSTANT c_fifo_size : NATURAL := true_log_pow2(c_fifo_fill); -- = 4096 -- level flow control via bg_siso.xon. The input eop will release blocks
-- for FIFO output already before the FIFO is fill level is reached.
-- Choose FIFO size to fit one more packet on top of FIFO fill level.
CONSTANT c_fifo_fill : NATURAL := c_eth_tester_bg_block_len_max * 11 / c_word_sz / 10;
CONSTANT c_fifo_size : NATURAL := true_log_pow2(c_fifo_fill + c_eth_tester_bg_block_len_max); -- = 8192
CONSTANT c_nof_total_counts : NATURAL := 1; -- one to count Tx packets CONSTANT c_nof_total_counts : NATURAL := 1; -- one to count Tx packets
...@@ -81,6 +87,7 @@ ARCHITECTURE str OF eth_tester_tx IS ...@@ -81,6 +87,7 @@ ARCHITECTURE str OF eth_tester_tx IS
SIGNAL udp_total_length : NATURAL; SIGNAL udp_total_length : NATURAL;
SIGNAL app_total_length : NATURAL; SIGNAL app_total_length : NATURAL;
SIGNAL bg_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL bg_sosi : t_dp_sosi; SIGNAL bg_sosi : t_dp_sosi;
SIGNAL bg_data : STD_LOGIC_VECTOR(c_octet_w-1 DOWNTO 0); SIGNAL bg_data : STD_LOGIC_VECTOR(c_octet_w-1 DOWNTO 0);
SIGNAL bg_ctrl_hold : t_diag_block_gen; SIGNAL bg_ctrl_hold : t_diag_block_gen;
...@@ -90,6 +97,10 @@ ARCHITECTURE str OF eth_tester_tx IS ...@@ -90,6 +97,10 @@ ARCHITECTURE str OF eth_tester_tx IS
SIGNAL tx_fifo_sosi : t_dp_sosi; SIGNAL tx_fifo_sosi : t_dp_sosi;
SIGNAL tx_fifo_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL tx_fifo_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL tx_fifo_siso : t_dp_siso; SIGNAL tx_fifo_siso : t_dp_siso;
SIGNAL tx_fifo_wr_ful : STD_LOGIC;
SIGNAL tx_fifo_wr_usedw : STD_LOGIC_VECTOR(ceil_log2(c_fifo_size)-1 DOWNTO 0);
SIGNAL i_tx_fifo_rd_emp : STD_LOGIC;
SIGNAL i_ref_sync : STD_LOGIC := '0'; SIGNAL i_ref_sync : STD_LOGIC := '0';
SIGNAL in_strobe_arr : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0); SIGNAL in_strobe_arr : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0);
SIGNAL i_tx_udp_sosi : t_dp_sosi; SIGNAL i_tx_udp_sosi : t_dp_sosi;
...@@ -104,6 +115,7 @@ ARCHITECTURE str OF eth_tester_tx IS ...@@ -104,6 +115,7 @@ ARCHITECTURE str OF eth_tester_tx IS
BEGIN BEGIN
ref_sync <= i_ref_sync; ref_sync <= i_ref_sync;
tx_fifo_rd_emp <= i_tx_fifo_rd_emp;
tx_udp_sosi <= i_tx_udp_sosi; tx_udp_sosi <= i_tx_udp_sosi;
-- View sosi.data in Wave Window -- View sosi.data in Wave Window
...@@ -133,9 +145,22 @@ BEGIN ...@@ -133,9 +145,22 @@ BEGIN
reg_bg_ctrl_miso => reg_bg_ctrl_cipo, reg_bg_ctrl_miso => reg_bg_ctrl_cipo,
-- ST interface -- ST interface
bg_ctrl_hold_arr(0) => bg_ctrl_hold, bg_ctrl_hold_arr(0) => bg_ctrl_hold,
out_sosi_arr(0) => bg_sosi out_sosi_arr(0) => bg_sosi,
out_siso_arr(0) => bg_siso
); );
-- BG block level flow control, needed in case BG settings result in eth bit
-- rate > 1 Gbps, to avoid u_tx_fifo overflow.
p_bg_siso_xon : PROCESS(st_clk)
BEGIN
IF rising_edge(st_clk) THEN
bg_siso.xon <= '1';
IF TO_UINT(tx_fifo_wr_usedw) > c_fifo_fill THEN
bg_siso.xon <= '0';
END IF;
END IF;
END PROCESS;
u_pack : ENTITY dp_lib.dp_repack_data -- pack 8b octets into 32b words u_pack : ENTITY dp_lib.dp_repack_data -- pack 8b octets into 32b words
GENERIC MAP ( GENERIC MAP (
g_in_dat_w => c_octet_w, -- = 8 g_in_dat_w => c_octet_w, -- = 8
...@@ -168,6 +193,10 @@ BEGIN ...@@ -168,6 +193,10 @@ BEGIN
wr_clk => st_clk, wr_clk => st_clk,
rd_rst => st_rst, rd_rst => st_rst,
rd_clk => st_clk, rd_clk => st_clk,
-- Monitor FIFO filling
wr_ful => tx_fifo_wr_ful,
wr_usedw => tx_fifo_wr_usedw,
rd_emp => i_tx_fifo_rd_emp,
-- ST sink -- ST sink
snk_in => tx_packed_sosi, snk_in => tx_packed_sosi,
-- ST source -- ST source
...@@ -220,8 +249,8 @@ BEGIN ...@@ -220,8 +249,8 @@ BEGIN
-- field in u_fifo. -- field in u_fifo.
bg_block_len <= TO_UINT(bg_ctrl_hold.samples_per_packet(15 DOWNTO 0)); -- packet lenghts fit in 16b bg_block_len <= TO_UINT(bg_ctrl_hold.samples_per_packet(15 DOWNTO 0)); -- packet lenghts fit in 16b
app_total_length <= c_eth_tester_app_hdr_len + bg_block_len WHEN rising_edge(st_clk); app_total_length <= c_eth_tester_app_hdr_len + bg_block_len WHEN rising_edge(st_clk);
udp_total_length <= app_total_length + c_network_udp_header_len WHEN rising_edge(st_clk); udp_total_length <= c_network_udp_header_len + app_total_length WHEN rising_edge(st_clk);
ip_total_length <= udp_total_length + c_network_ip_header_len WHEN rising_edge(st_clk); ip_total_length <= c_network_ip_header_len + udp_total_length WHEN rising_edge(st_clk);
hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "eth_src_mac" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "eth_src_mac" )) <= eth_src_mac; hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "eth_src_mac" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "eth_src_mac" )) <= eth_src_mac;
hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "ip_total_length" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_total_length" )) <= TO_UVEC(ip_total_length, 16); hdr_fields_slv_in(field_hi(c_eth_tester_hdr_field_arr, "ip_total_length" ) DOWNTO field_lo(c_eth_tester_hdr_field_arr, "ip_total_length" )) <= TO_UVEC(ip_total_length, 16);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment