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

Try xon flow control with FIFOs and MUX.

parent 46bd5bce
Branches
No related tags found
1 merge request!330Resolve L2SDP-942
Pipeline #48646 failed
-------------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-- Author: Eric Kooistra
-- Date: 26 Apr 2023
-- Purpose:
-- . Test bench for dp_fifos to verify xon flow control when FIFO runs full
-- Description:
-- Verify that the dp_mux will not cause input FIFO overflow when the input
-- load is too large for the output capacity.
--
-- BG -> xonoff -> fifo_sc -> mux -> xonoff -> fifo <-- out_siso
-- arr arr arr fill
-- sc
--
-- Usage:
-- . as 12
-- . run -all
-- Self test result is OK when there is no FAILURE due to FIFO overflow.
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE work.tb_dp_pkg.ALL;
ENTITY tb_dp_fifo_xonoff IS
GENERIC (
g_nof_inputs : NATURAL := 5;
g_nof_blocks : NATURAL := 300;
g_block_size : NATURAL := 10;
g_gap_size : NATURAL := 0
);
END tb_dp_fifo_xonoff;
ARCHITECTURE tb OF tb_dp_fifo_xonoff IS
CONSTANT c_clk_period : TIME := 5 ns;
CONSTANT c_tb_nof_clk_cycles : NATURAL := g_nof_blocks * g_block_size;
-- c_fifo_af_ready >= 4, nof words below max (full) at which fifo is considered almost full for snk_out.ready
-- c_fifo_af_xon >= 0, nof words below max (full) at which fifo is considered almost full for snk_out.xon
CONSTANT c_fifo_af_ready : NATURAL := 4;
CONSTANT c_fifo_af_xon : NATURAL := g_block_size + 5;
CONSTANT c_in_fifo_size : NATURAL := g_block_size * 20;
CONSTANT c_out_fifo_size : NATURAL := g_block_size * 20;
CONSTANT c_out_fifo_fill : NATURAL := g_block_size;
CONSTANT c_out_fifo_af_xon : NATURAL := g_block_size + 5;
CONSTANT c_ready_latency : NATURAL := 1;
CONSTANT c_data_w : NATURAL := 16;
CONSTANT c_symbol_w : NATURAL := c_data_w;
CONSTANT c_symbol_init : NATURAL := 0;
CONSTANT c_nof_symbols : NATURAL := g_block_size;
CONSTANT c_bsn : NATURAL := 0;
CONSTANT c_sync : STD_LOGIC := '0';
CONSTANT c_nof_input_w : NATURAL := ceil_log2(g_nof_inputs);
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL in_en : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL bg_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL bg_sosi_arr : t_dp_sosi_arr(0 TO g_nof_inputs-1);
SIGNAL fifo_in_siso_arr : t_dp_siso_arr(0 TO g_nof_inputs-1);
SIGNAL fifo_in_sosi_arr : t_dp_sosi_arr(0 TO g_nof_inputs-1);
SIGNAL mux_in_siso_arr : t_dp_siso_arr(0 TO g_nof_inputs-1);
SIGNAL mux_in_sosi_arr : t_dp_sosi_arr(0 TO g_nof_inputs-1);
SIGNAL mux_out_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL mux_out_sosi : t_dp_sosi;
SIGNAL fifo_fill_in_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL fifo_fill_in_sosi : t_dp_sosi;
SIGNAL out_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL out_sosi : t_dp_sosi;
-- Monitor FIFO filling
TYPE t_in_fifo_usedw_slv_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(ceil_log2(c_out_fifo_size)-1 DOWNTO 0);
SIGNAL in_fifo_wr_ful_arr : STD_LOGIC_VECTOR(0 TO g_nof_inputs-1);
SIGNAL in_fifo_usedw_arr : t_in_fifo_usedw_slv_arr(0 TO g_nof_inputs-1);
SIGNAL in_fifo_rd_emp_arr : STD_LOGIC_VECTOR(0 TO g_nof_inputs-1);
SIGNAL out_fifo_wr_ful : STD_LOGIC;
SIGNAL out_fifo_usedw : STD_LOGIC_VECTOR(ceil_log2(c_out_fifo_size)-1 DOWNTO 0);
SIGNAL out_fifo_rd_emp : STD_LOGIC;
BEGIN
------------------------------------------------------------------------------
-- Clock & reset
------------------------------------------------------------------------------
clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
rst <= '1', '0' AFTER c_clk_period*7;
------------------------------------------------------------------------------
-- Stimuli:
------------------------------------------------------------------------------
gen_bg_arr : FOR I IN 0 TO g_nof_inputs-1 GENERATE
p_bg_arr : PROCESS
BEGIN
WHILE TRUE LOOP
proc_dp_gen_frame(c_ready_latency,
c_data_w,
c_symbol_w,
c_symbol_init,
c_nof_symbols,
c_bsn + I, -- use bsn to identify the inputs
c_sync,
clk,
in_en,
bg_siso,
bg_sosi_arr(I));
WAIT FOR g_gap_size * c_clk_period;
END LOOP;
-- Use WHILE LOOP and WAIT to avoid warning (vcom-1090) Possible infinite loop:
-- Process contains no WAIT statement.
WAIT;
END PROCESS;
u_dp_xonoff : ENTITY work.dp_xonoff
PORT MAP (
rst => rst,
clk => clk,
-- Frame in
in_siso => OPEN,
in_sosi => bg_sosi_arr(I),
-- Frame out
out_siso => fifo_in_siso_arr(I),
out_sosi => fifo_in_sosi_arr(I)
);
u_in_fifo : ENTITY work.dp_fifo_sc
GENERIC MAP (
g_data_w => c_data_w,
g_bsn_w => c_nof_input_w,
g_use_bsn => TRUE, -- use bsn to identify the inputs
g_use_ctrl => TRUE, -- sop & eop
g_fifo_size => c_in_fifo_size,
g_fifo_af_margin => c_fifo_af_ready,
g_fifo_af_xon => c_fifo_af_xon,
g_fifo_rl => c_ready_latency
)
PORT MAP (
rst => rst,
clk => clk,
-- Monitor FIFO filling
wr_ful => in_fifo_wr_ful_arr(I),
usedw => in_fifo_usedw_arr(I),
rd_emp => in_fifo_rd_emp_arr(I),
-- ST sink
snk_out => fifo_in_siso_arr(I), -- flush control via out_siso.xon
snk_in => fifo_in_sosi_arr(I),
-- ST source
src_in => mux_in_siso_arr(I),
src_out => mux_in_sosi_arr(I)
);
END GENERATE;
-- Eanble input after reset and disable it before tb_end, to read FIFOs empty
in_en <= '0', '1' AFTER c_clk_period*17,
'0' AFTER 4 * c_tb_nof_clk_cycles * c_clk_period;
-- Also verify toggling external siso.xon flow control
out_siso.xon <= '1',
'0' AFTER 2 * c_tb_nof_clk_cycles * c_clk_period,
'1' AFTER 3 * c_tb_nof_clk_cycles * c_clk_period;
-- End test
tb_end <= '0', '1' AFTER 5 * c_tb_nof_clk_cycles * c_clk_period;
------------------------------------------------------------------------------
-- Multiplexer
------------------------------------------------------------------------------
u_dp_mux : ENTITY work.dp_mux
GENERIC MAP (
g_nof_input => g_nof_inputs,
g_fifo_size => array_init(1024, g_nof_inputs), -- must match g_nof_input, even when g_use_fifo=FALSE
g_fifo_fill => array_init( 0, g_nof_inputs) -- must match g_nof_input, even when g_use_fifo=FALSE
)
PORT MAP (
rst => rst,
clk => clk,
-- ST sinks
snk_out_arr => mux_in_siso_arr,
snk_in_arr => mux_in_sosi_arr,
-- ST source
src_in => mux_out_siso,
src_out => mux_out_sosi
);
------------------------------------------------------------------------------
-- Output
------------------------------------------------------------------------------
-- u_dp_xonoff : ENTITY work.dp_xonoff
-- PORT MAP (
-- rst => rst,
-- clk => clk,
-- -- Frame in
-- in_siso => mux_out_siso,
-- in_sosi => mux_out_sosi,
-- -- Frame out
-- out_siso => fifo_fill_in_siso,
-- out_sosi => fifo_fill_in_sosi
-- );
u_out_fifo : ENTITY work.dp_fifo_fill_sc
GENERIC MAP (
g_data_w => c_data_w,
g_bsn_w => c_nof_input_w,
g_use_bsn => TRUE, -- use bsn to identify the inputs
g_fifo_fill => c_out_fifo_fill,
g_fifo_size => c_out_fifo_size,
g_fifo_af_margin => c_fifo_af_ready,
g_fifo_af_xon => c_fifo_af_xon,
g_fifo_rl => c_ready_latency
)
PORT MAP (
rst => rst,
clk => clk,
-- Monitor FIFO filling
wr_ful => out_fifo_wr_ful,
usedw => out_fifo_usedw,
rd_emp => out_fifo_rd_emp,
-- ST sink
snk_out => mux_out_siso,
snk_in => mux_out_sosi,
-- snk_out => fifo_fill_in_siso,
-- snk_in => fifo_fill_in_sosi,
-- ST source
src_in => out_siso,
src_out => out_sosi
);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment