From 80ac83afd8e1deb1e5ffa074472202f209e126b1 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Tue, 12 Sep 2023 10:57:51 +0200 Subject: [PATCH] Add flow control. --- .../base/dp/src/vhdl/dp_packet_unmerge.vhd | 117 +++++++++++++++--- .../dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd | 19 +-- .../tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd | 40 +++--- 3 files changed, 128 insertions(+), 48 deletions(-) diff --git a/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd b/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd index d7f294f821..2a7d978adb 100644 --- a/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd +++ b/libraries/base/dp/src/vhdl/dp_packet_unmerge.vhd @@ -39,15 +39,34 @@ -- and remain valid until the snk_in.eop. Hence these signals are then valid -- when snk_in.valid = '1'. Use same snk_in.err and snk_in.empty value for -- all unmerged packets. +-- _ _ _ +-- snk_in.sop _____| |_____________________| |_____________________| |_ +-- _ _ +-- snk_in.eop ___________________________| |_____________________| |___ +-- _ _ _ _ _ _ _ +-- src_out.sop _____|0|_____|1|_____|2|_____|0|_____|1|_____|2|_____|0|_ +-- _ _ _ _ _ _ +-- src_out.eop ___________|0|_____|1|_____|2|_____|0|_____|1|_____|2|___ -- --- _ _ _ --- snk_in.sop _____| |___________________________| |___________________________| |_ --- _ _ --- snk_in.eop _________________________________| |___________________________| |___ --- _ _ _ _ _ _ _ --- src_out.sop _____|0|_______|1|_______|2|_______|0|_______|1|_______|2|_______|0|_ --- _ _ _ _ _ _ --- src_out.eop _____________|0|_______|1|_______|2|_______|0|_______|1|_______|2|___ +-- . Flow control. +-- . The component does not add additional snk_out.ready flow control itself, +-- but it can listen to external src_in.ready flow control. +-- - If g_use_src_in_ready = false, then src_in is ignored, so no flow +-- control, else do use flow control by src_in.ready. +-- - If g_use_src_in_ready = true, then g_use_dp_latency_adapter = false +-- determines that the src_in.ready is used combinatorially else the +-- src_in.ready is used registered. +-- . The p_reg increases the ready latency (RL) 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. Therefore c_use_dp_latency_adapter = true is +-- needed to restore the RL from 2 to 1 for the src_out the output. The +-- alternative is to use a dp_pipeline to register d.src_out in +-- combination with src_in.ready at the input, to keep RL at 1. +-- The p_reg keeps the internal state of the component. With dp_pipeline +-- a separate output register is needed to store src_out. With the +-- dp_latency_adapter a feq register stages are needed to store src_out, +-- but the adantage of dp_latency_adapter is that it also registers the +-- src_in.ready so that may ease timing closure. library IEEE,common_lib; use IEEE.std_logic_1164.all; @@ -57,9 +76,11 @@ use work.dp_stream_pkg.all; entity dp_packet_unmerge is generic ( - g_nof_pkt_max : natural := 1; -- Maximum nof packets to unmerge each incoming packet to - g_pkt_len : natural := 1; -- Length of the unmerged packets - g_bsn_increment : natural := 0 + g_use_src_in_ready : boolean := false; + g_use_dp_latency_adapter : boolean := true; + g_nof_pkt_max : natural := 1; -- Maximum nof packets to unmerge each incoming packet to + g_pkt_len : natural := 1; -- Length of the unmerged packets + g_bsn_increment : natural := 0 ); port ( rst : in std_logic; @@ -68,7 +89,7 @@ entity dp_packet_unmerge is snk_out : out t_dp_siso; snk_in : in t_dp_sosi; - src_in : in t_dp_siso; + src_in : in t_dp_siso := c_dp_siso_rst; src_out : out t_dp_sosi ); end dp_packet_unmerge; @@ -82,13 +103,64 @@ architecture rtl of dp_packet_unmerge is constant c_reg_rst : t_reg := (0, 0, c_dp_sosi_rst); + constant c_use_dp_latency_adapter : boolean := false; + signal r : t_reg; signal d : t_reg; + -- Signals for c_use_dp_latency_adapter = false + + -- Signals for c_use_dp_latency_adapter = true + signal dp_latency_adapter_snk_out : t_dp_siso; + signal dp_latency_adapter_snk_in : t_dp_sosi; + signal dp_latency_adapter_src_in : t_dp_siso; + signal dp_latency_adapter_src_out : t_dp_sosi; begin -- Map t_reg outputs to entity outputs - snk_out <= src_in; - src_out <= r.src_out; + no_flow_control : if g_use_src_in_ready = false generate + snk_out <= c_dp_siso_rdy; + src_out <= r.src_out; + end generate; + + gen_use_src_in_ready : if g_use_src_in_ready = true generate + gen_dp_pipeline : if c_use_dp_latency_adapter = false generate + u_dp_pipeline : entity work.dp_pipeline + port map ( + rst => rst, + clk => clk, + -- ST sink + snk_out => snk_out, + snk_in => d.src_out, + -- ST source + src_in => src_in, + src_out => src_out + ); + end generate; + + gen_dp_latency_adapter : if c_use_dp_latency_adapter = true generate + snk_out <= dp_latency_adapter_snk_out; + dp_latency_adapter_snk_in <= r.src_out; + + u_dp_latency_adapter : entity work.dp_latency_adapter + generic map ( + g_in_latency => 2, + g_out_latency => 1 + ) + port map ( + rst => rst, + clk => clk, + -- ST sink + snk_out => dp_latency_adapter_snk_out, + snk_in => dp_latency_adapter_snk_in, + -- ST source + src_in => dp_latency_adapter_src_in, + src_out => dp_latency_adapter_src_out + ); + + dp_latency_adapter_src_in <= src_in; + src_out <= dp_latency_adapter_src_out; + end generate; + end generate; -- p_reg r <= d when rising_edge(clk); @@ -100,12 +172,12 @@ begin v := r; -- Function - -- _ _ _ - -- snk_in.sop __| |_______________| |_______________| |_______________| - -- _ _ _ - -- snk_in.eop _________________| |_______________| |_______________| |_ - -- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - -- snk_in.valid __| + -- _ _ _ + -- snk_in.sop __| |_______________| |_______________| |_______________| + -- _ _ _ + -- snk_in.eop _________________| |_______________| |_______________| |_ + -- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + -- snk_in.valid __| -- v.val_cnt 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 -- v.pkt_cnt 0 1 2 0 1 2 0 1 2 -- ______________ _______________ _______________ _ @@ -134,6 +206,11 @@ begin end if; -- output packet bsn, sync, sop and eop + -- . Default passes on snk_in.sync, valid, data, re, im + -- . The sync, valid can be passed on from snk_in, without checking + -- src_in.ready, because the fact that snk_in.valid is '1' is + -- sufficient for src_out.valid to be '1' too. The RL is taken care + -- of by gen_use_src_in_ready. v.src_out := snk_in; -- passes on snk_in.sync, data, re, im v.src_out.bsn := r.src_out.bsn; v.src_out.channel := r.src_out.channel; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd index f94f237442..cc2fa6efa0 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_packet_merge_unmerge.vhd @@ -43,20 +43,23 @@ use work.tb_dp_pkg.all; entity tb_dp_packet_merge_unmerge is generic ( -- general - g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control - g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control + -- . always active, random or pulse flow control + g_flow_control_stimuli : t_dp_flow_control_enum := e_random; + g_flow_control_verify : t_dp_flow_control_enum := e_random; -- specific + g_use_dp_latency_adapter : boolean := true; g_data_w : natural := 16; g_nof_repeat : natural := 24; g_nof_pkt : natural := 3; - g_pkt_len : natural := 10; + g_pkt_len : natural := 29; g_pkt_gap : natural := 0; - g_bsn_increment : natural := 1 + g_bsn_increment : natural := 0 ); end tb_dp_packet_merge_unmerge; architecture tb of tb_dp_packet_merge_unmerge is constant c_rl : natural := 1; + constant c_use_src_in_ready : boolean := g_flow_control_verify /= e_active; constant c_pulse_active : natural := 1; constant c_pulse_period : natural := 7; @@ -307,9 +310,11 @@ begin ------------------------------------------------------------------------------ u_dp_packet_unmerge : entity work.dp_packet_unmerge generic map ( - g_nof_pkt_max => g_nof_pkt, - g_pkt_len => g_pkt_len, - g_bsn_increment => g_bsn_increment + g_use_src_in_ready => c_use_src_in_ready, + g_use_dp_latency_adapter => g_use_dp_latency_adapter, + g_nof_pkt_max => g_nof_pkt, + g_pkt_len => g_pkt_len, + g_bsn_increment => g_bsn_increment ) port map ( rst => rst, diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd index f0859b884a..76246a0f14 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_packet_merge_unmerge.vhd @@ -39,6 +39,7 @@ begin -- g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control -- g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active, random or pulse flow control -- -- specific + -- g_use_dp_latency_adapter : boolean := true; -- g_data_w : natural := 4; -- g_nof_repeat : natural := 20; -- g_nof_pkt : natural := 3; @@ -46,27 +47,24 @@ begin -- g_pkt_gap : natural := 0; -- g_bsn_increment : natural := 0; - u_act_act_8_nof_0 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 0, 29, 0, 1); - u_act_act_8_nof_1 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 1, 29, 0, 1); - u_act_act_8_nof_2 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 2, 29, 0, 1); - u_act_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1); - u_act_act_8_nof_4 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 4, 29, 0, 1); - u_act_act_8_nof_5 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 5, 29, 0, 1); - u_act_act_8_nof_6 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 6, 29, 0, 1); - u_act_act_8_nof_7 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 7, 29, 0, 1); + u_act_act_8_nof_0 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 0, 29, 0, 1); + u_act_act_8_nof_1 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 1, 29, 0, 1); + u_act_act_8_nof_2 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 2, 29, 0, 1); + u_act_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 3, 29, 0, 1); + u_act_act_8_nof_4 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 4, 29, 0, 1); + u_act_act_8_nof_4_bsn_0 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 4, 29, 0, 0); + --u_act_act_8_nof_4_bsn_2 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 4, 29, 0, 2); + u_act_act_8_nof_5 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 5, 29, 0, 1); + u_act_act_8_nof_6 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 6, 29, 0, 1); + u_act_act_8_nof_7 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, true, 8, c_nof_repeat, 7, 29, 0, 1); - u_rnd_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 0, 2); - u_rnd_rnd_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, 8, c_nof_repeat, 3, 29, 0, 3); - u_pls_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_active, 8, c_nof_repeat, 3, 29, 0, 4); - u_pls_rnd_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_random, 8, c_nof_repeat, 3, 29, 0, 5); - u_pls_pls_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_pulse, 8, c_nof_repeat, 3, 29, 0, 6); + u_rnd_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, true, 8, c_nof_repeat, 3, 29, 0, 1); + u_rnd_rnd_8_nof_3_pipe : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, false, 8, c_nof_repeat, 3, 29, 0, 1); + u_rnd_rnd_8_nof_3_adapt : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_random, true, 8, c_nof_repeat, 3, 29, 0, 1); + u_pls_act_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_active, true, 8, c_nof_repeat, 3, 29, 0, 1); + u_pls_rnd_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_random, true, 8, c_nof_repeat, 3, 29, 0, 1); + u_pls_pls_8_nof_3 : entity work.tb_dp_packet_merge_unmerge generic map ( e_pulse, e_pulse, true, 8, c_nof_repeat, 3, 29, 0, 1); - u_rnd_act_8_nof_1 : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 1, 29, 0, 1); - u_rnd_act_8_nof_3_gap : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, 8, c_nof_repeat, 3, 29, 17, 1); - - u_act_act_8_nof_3_no_err : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 0); - u_act_act_8_nof_3_err_10 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1); - u_act_act_8_nof_3_err_11 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1); - u_act_act_8_nof_3_err_12 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1); - u_act_act_8_nof_3_err_13 : entity work.tb_dp_packet_merge_unmerge generic map ( e_active, e_active, 8, c_nof_repeat, 3, 29, 0, 1); + u_rnd_act_8_nof_1 : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, true, 8, c_nof_repeat, 1, 29, 0, 1); + u_rnd_act_8_nof_3_gap : entity work.tb_dp_packet_merge_unmerge generic map ( e_random, e_active, true, 8, c_nof_repeat, 3, 29, 17, 1); end tb; -- GitLab