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

Add dp_add_flow_control.vhd to support streaming data flow control.

parent 33b9e856
No related branches found
No related tags found
1 merge request!353Resolve L2SDP-962
......@@ -30,6 +30,7 @@ synth_files =
src/vhdl/dp_pipeline.vhd
src/vhdl/dp_pipeline_arr.vhd
src/vhdl/dp_pipeline_ready.vhd
src/vhdl/dp_add_flow_control.vhd
src/vhdl/dp_block_resize.vhd
src/vhdl/dp_block_validate_length.vhd
src/vhdl/dp_block_validate_bsn_at_sync.vhd
......
--------------------------------------------------------------------------------
--
-- Copyright (C) 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
-- Purpose: Provide flow control
-- Description:
-- . This component can add src_in.ready flow control to a logic function
-- that no flow control.
-- - If g_use_ready = false, then src_in is ignored, so no flow control is
-- added and the dp_add_flow_control component reduces to wires.
-- - If g_use_ready = true then use flow control by src_in.ready.
-- . If g_pipeline_ready = false then dp_add_flow_control = dp_pipeline,
-- and then snk_in and src_in.ready are used combinatorially by
-- dp_pipeline.
-- . If g_pipeline_ready = true then dp_add_flow_control = dp_pipeline_ready,
-- and then the registered input snk_in_reg is used and the src_in.ready
-- is registered.
--
-- . The block diagram shows how the dp_add_flow_control is used.
--
-- g_use_ready
-- g_pipeline_ready
-- g_in_latency
-- g_out_latency
-- _____________________
-- | dp_add_flow_control |
-- | |
-- snk_out <--------------| snk_out src_in |<---------- src_in
-- | |
-- d.src_out -->| snk_in src_out|--> src_out
-- r.src_out -->| snk_in_reg |
-- |_____________________|
--
-- ________ _______
-- / \ | |
-- snk_in --------->| p_comb | --> d -->| p_reg |--> r
-- \________/ |_______|
-- | |
-- \-----------<------/
--
-- . The logic function is implemented in combinatorial process p_comb and the
-- internal state of it is kept in a clocked process p_reg.
-- . The p_reg increases the ready latency (RL) of p_reg.src_out by 1, because
-- p_comb does not use src_in.ready. Instead p_comb drives d.src_out based
-- on the snk_in.sop, eop, valid.
-- - With g_use_ready = true and g_pipeline_ready = true use a
-- dp_pipeline_ready to restore the RL from 2 to 1 for the src_out output.
-- With the dp_pipeline_ready a few register stages are needed to store
-- src_out to be able to adapt the RL and to be able to register the
-- src_in.ready. The advantage of dp_pipeline_ready is that it register the
-- src_in.ready, so that may ease achieving timing closure.
-- - The alternative with g_use_ready = true and g_pipeline_ready = false is
-- to use a dp_pipeline the d.src_out in combination with src_in.ready, to
-- keep the RL at 1 by means of dp_pipeline. The dp_pipeline adds a
-- register to store src_out. The p_reg.src_out is kept as well, to keep
-- the internal state of the function.
-- . If the p_comb also needs to apply flow control itself, then p_comb can
-- output a ready or d.ready signal that is or-ed with the input
-- src_in.ready and then applied to the src_in input of dp_add_flow_control.
-- . The g_in_latency and g_out_latency are only used when g_use_ready = true
-- and g_pipeline_ready = true. When g_pipeline_ready = false, then the
-- assumption is that snk_in and src_out both have RL = 1.
-- Remark:
-- . Default use g_use_ready = true and g_pipeline_ready = false for solution
-- that fits both flow control or no flow control with the least logic. The
-- flow control logic may even get entirely optimized away during synthesis
-- when snk_in.ready = '1' fixed.
library IEEE,common_lib;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use common_lib.common_pkg.all;
use work.dp_stream_pkg.all;
entity dp_add_flow_control is
generic (
g_use_ready : boolean := true;
g_pipeline_ready : boolean := false;
g_in_latency : natural := 1;
g_out_latency : natural := 1
);
port (
rst : in std_logic;
clk : in std_logic;
snk_out : out t_dp_siso;
snk_in : in t_dp_sosi; -- combinatorial input
snk_in_reg : in t_dp_sosi; -- registered input
src_in : in t_dp_siso := c_dp_siso_rst;
src_out : out t_dp_sosi
);
end dp_add_flow_control;
architecture str of dp_add_flow_control is
begin
no_flow_control : if g_use_ready = false generate
-- Only wires
snk_out <= c_dp_siso_rdy;
src_out <= snk_in_reg;
end generate;
use_flow_control : if g_use_ready = true generate
gen_dp_pipeline : if g_pipeline_ready = false generate
u_dp_pipeline : entity work.dp_pipeline
port map (
rst => rst,
clk => clk,
-- ST sink
snk_out => snk_out,
snk_in => snk_in,
-- ST source
src_in => src_in,
src_out => src_out
);
end generate;
gen_dp_pipeline_ready : if g_pipeline_ready = true generate
u_dp_pipeline_ready : entity work.dp_pipeline_ready
generic map (
g_in_latency => g_in_latency + 1, -- + 1 to account of registered input
g_out_latency => g_out_latency
)
port map (
rst => rst,
clk => clk,
-- ST sink
snk_out => snk_out,
snk_in => snk_in_reg,
-- ST source
src_in => src_in,
src_out => src_out
);
end generate;
end generate;
end str;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment