diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index f205872d5f5895afbc7cf991251984e17bea507a..1d3533b137fdbd8d27f60afb547b4febd902487b 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -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 diff --git a/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd b/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd new file mode 100644 index 0000000000000000000000000000000000000000..739917a35ef9a1b434fd9992a04d6b3eebe57d5d --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_add_flow_control.vhd @@ -0,0 +1,153 @@ +-------------------------------------------------------------------------------- +-- +-- 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;