From 8a428185dfeac5b215359623b1f231a472f40038 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Mon, 8 May 2023 16:46:02 +0200 Subject: [PATCH] Add out_en as OUT. Updated description. --- libraries/base/dp/src/vhdl/dp_xonoff.vhd | 60 +++++++++++++++++++----- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/libraries/base/dp/src/vhdl/dp_xonoff.vhd b/libraries/base/dp/src/vhdl/dp_xonoff.vhd index 9f7f9eccfd..5f200a6e3c 100644 --- a/libraries/base/dp/src/vhdl/dp_xonoff.vhd +++ b/libraries/base/dp/src/vhdl/dp_xonoff.vhd @@ -21,11 +21,44 @@ -- Purpose: Add flow XON-XOFF control by flushing frames -- Description: --- . The in_siso.ready = out_siso.ready so passed on unchanged, to support +-- The dp_xonoff can be applied when the upstream source keeps on producing +-- blocks of data, because it does not listen to the in_siso.xon = '0'. The +-- purpose of dp_xonoff.vhd is then to avoid downstream overflow, when the +-- downstream signals out_siso.xon = '0' to indicate that it cannot accept +-- more blocks. Therefore the dp_xonoff listens to the out_siso.xon and +-- flushes (discards) blocks when out_siso.xon = '0'. The dp_xonoff operates +-- per block, so it takes care that complete blocks are flushed when +-- out_siso.xon = '0', or passed on when out_siso.xon = '1'. The +-- in_siso.xon = '1' always, because the dp_xonoff will discard incoming +-- blocks if they cannot be passed on. When out_siso.xon = '1', then +-- in_siso.ready <= in_sosi.ready, so passed on. When out_siso.xon = '0', +-- then in_siso.xon = '1' and in_siso.ready <= '1' (so in_siso = +-- c_dp_sosi.rdy), because dp_xonoff can flush incoming blocks at maximum +-- rate, until out_siso.xon = '1' again. +-- +-- A dp_fifo will keep on outputing blocks when its out_siso.xon = '0', +-- because it only passes in_siso.xon <= out_siso.xon, so it relies on its +-- upsteam input to listen to the out_siso.xon. If there are still multiple +-- blocks in the FIFO then these will be output. Typicaaly it is not +-- necessary to have a dp_xonoff at the output of the dp_fifo to discard +-- these blocks, because the dp_fifo does listen to out_siso.ready = '0', +-- so the flow control per sample will then stop the dp_fifo from causing +-- downstream overflow. +-- +-- When a dp_fifo runs almost full within g_fifo_af_margin, then the +-- in_siso.ready is made '0'. New addition is g_fifo_af_xon that defines a +-- dp_fifo fill margin for making in_sosi.xon = '0'. If the upstream does +-- not listen to ready flow control and xon flow control (e.g. like input +-- from an ADC or a WG), then there may be need for an dp_xonoff at the +-- input of the FIFO to discard input blocks. +-- +-- The in_siso.ready = out_siso.ready so passed on unchanged, to support -- detailed output to input flow control per cycle. The in_siso.xon is -- always '1', because the out_siso.xon is taken care of in this -- dp_xonoff.vhd by flushing any in_sosi data when out_siso.xon = '0'. -- +-- . Use tb_dp_fifo_xonoff.vhd to verify dp_xonoff to avoid dp_fifo overflow. +-- -- . When g_bypass=TRUE then the in and out are wired and the component is void. -- . When g_bypass=FALSE then: -- The output is ON when flush='0'. @@ -61,6 +94,7 @@ ENTITY dp_xonoff IS -- Frame out out_siso : IN t_dp_siso; -- flush control via out_siso.xon out_sosi : OUT t_dp_sosi; + out_en : OUT STD_LOGIC; -- for monitoring purposes in tb -- Optional override to force XOFF ('1' = enable override) force_xoff : IN STD_LOGIC := '0' ); @@ -75,18 +109,20 @@ ARCHITECTURE rtl OF dp_xonoff IS SIGNAL flush : STD_LOGIC; SIGNAL nxt_flush : STD_LOGIC; - SIGNAL out_en : STD_LOGIC; + SIGNAL i_out_en : STD_LOGIC; SIGNAL nxt_out_en : STD_LOGIC; BEGIN + out_en <= i_out_en; + gen_bypass : IF g_bypass=TRUE GENERATE in_siso <= out_siso; out_sosi <= in_sosi; END GENERATE; no_bypass : IF g_bypass=FALSE GENERATE - in_siso.ready <= out_siso.ready OR (NOT out_en); -- pass on ready for detailed flow control per cycle only when output is enabled, otherwise ready = 1 + in_siso.ready <= out_siso.ready OR (NOT i_out_en); -- pass on ready for detailed flow control per cycle only when output is enabled, otherwise ready = 1 in_siso.xon <= '1'; -- upstream can remain on, because flush will handle out_siso.xon nxt_flush <= NOT out_siso.xon OR force_xoff; -- use xon for flow control at frame level @@ -95,11 +131,11 @@ BEGIN IF rst='1' THEN frm_busy_reg <= '0'; flush <= '0'; - out_en <= '1'; + i_out_en <= '1'; ELSIF rising_edge(clk) THEN frm_busy_reg <= frm_busy; flush <= nxt_flush; -- pipeline register flush to ease timing closure - out_en <= nxt_out_en; -- state register out_en because it can only change between frames + i_out_en <= nxt_out_en; -- state register out_en because it can only change between frames END IF; END PROCESS; @@ -114,9 +150,9 @@ BEGIN END IF; END PROCESS; - p_out_en : PROCESS(flush, out_en, frm_busy) + p_out_en : PROCESS(flush, i_out_en, frm_busy) BEGIN - nxt_out_en <= out_en; + nxt_out_en <= i_out_en; IF frm_busy='0' THEN IF flush='1' THEN nxt_out_en <= '0'; @@ -126,16 +162,16 @@ BEGIN END IF; END PROCESS; - p_out_sosi : PROCESS(in_sosi, out_en) + p_out_sosi : PROCESS(in_sosi, i_out_en) BEGIN -- Pass on sosi data via wires out_sosi <= in_sosi; -- XON/XOFF flow control via sosi control - out_sosi.sync <= in_sosi.sync AND out_en; - out_sosi.valid <= in_sosi.valid AND out_en; - out_sosi.sop <= in_sosi.sop AND out_en; - out_sosi.eop <= in_sosi.eop AND out_en; + out_sosi.sync <= in_sosi.sync AND i_out_en; + out_sosi.valid <= in_sosi.valid AND i_out_en; + out_sosi.sop <= in_sosi.sop AND i_out_en; + out_sosi.eop <= in_sosi.eop AND i_out_en; END PROCESS; END GENERATE; -- GitLab