diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 389a72855ad80892142d452f967d8a512a1d9a4c..ce0c6d9f2373328d179fc7890af6b4d95562acaf 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -10,6 +10,7 @@ build_dir_synth = $HDL_BUILD_DIR synth_files = src/vhdl/dp_stream_pkg.vhd + src/vhdl/dp_example_dut.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_packetizing_pkg.vhd $UNB/Firmware/modules/dp/src/vhdl/dp_packet_pkg.vhd @@ -142,7 +143,7 @@ test_bench_files = $UNB/Firmware/modules/dp/tb/vhdl/tb_dp_concat.vhd tb/vhdl/tb_dp_deinterleave.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_dp_distribute.vhd - tb/vhdl/tb_dp_example_no_dut.vhd + tb/vhdl/tb_dp_example_dut.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_dp_fifo_fill.vhd tb/vhdl/tb_dp_fifo_fill_sc.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_dp_fifo_info.vhd @@ -184,7 +185,7 @@ test_bench_files = $UNB/Firmware/modules/dp/tb/vhdl/tb_tb2_dp_demux.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_tb3_dp_demux.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_tb_dp_distribute.vhd - tb/vhdl/tb_tb_dp_example_no_dut.vhd + tb/vhdl/tb_tb_dp_example_dut.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_tb_dp_flush.vhd $UNB/Firmware/modules/dp/tb/vhdl/tb_tb_dp_fifo_info.vhd tb/vhdl/tb_tb_dp_fifo_sc.vhd diff --git a/libraries/base/dp/src/vhdl/dp_example_dut.vhd b/libraries/base/dp/src/vhdl/dp_example_dut.vhd new file mode 100644 index 0000000000000000000000000000000000000000..04198e0fdecf294797f6848e4676c7219a83d13b --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_example_dut.vhd @@ -0,0 +1,266 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2015 +-- 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: +-- The dp_example_dut serves as a template for a streaming component with +-- flow control. +-- +-- +-- Block diagram: +-- +-- A) Streaming interface +-- ____________________ +-- | dp_example_dut | +-- | | +-- <---|snk_out src_in |<--- +-- --->|snk_in src_out |---> +-- |____________________| + +-- B) Flow control +-- +-- RL=1 RL=1 RL=1 +-- . . . +-- . /-----------------------------------------\ +-- . | . _____ . | +-- . | /------\ nxt_r | | r | +-- . \-->| |---*-------*----->|p_reg|-----*---> src_out +-- . | | | | |_____| +-- snk_in -------->|p_comb|<--|-------|--------------*-------- src_in +-- | | | | | +-- | | | v | +-- | | | /-------\ | +-- | | | |p_flow | | +-- \------/ | \-------/ | +-- | | | +-- nxt_r.hold_out.valid | | | +-- v | | +-- /| |r_snk_out | +-- |0|------/ | +-- snk_out <------------------| | | +-- |1|---------------------/ +-- \| +-- +-- Description: +-- . p_comb = functionality: +-- The functionality of the DP component is defined in the p_comb process. +-- The rest of the block diagram is needed to fit support input valid and +-- output ready flow control and to pipeline the processing such that +-- the function can be implementend within 1 clock cycle. +-- +-- . p_reg = local storage and pipelining: +-- The storage is done in a register r and this r contains local storage +-- and the src_out. The r.src_out can directly be wired to src_out. The +-- latency from snk_in to src_out must be 1 clock cycle. If more pipelining +-- is needed then the functionality should be split over separate components +-- that can each again have a latency of 1. +-- +-- . p_flow = local flow control: +-- If the functionality does not add or remove valid data from the snk_in +-- input stream, then the src_in can be passed on directly to snk_out. +-- However if the functionality needs to apply backpressure itself or if it +-- can accept input data when the src_in is not ready then it can implement +-- p_flow to apply backpressure via r_snk_out. +-- +-- . nxt_r: +-- Note that the function yields nxt_r that gets pipeline stored in r. The +-- nxt_r is combinatorially related to snk_in so it does not change the RL. +-- The p_flow also works combinatorially because it uses nxt_r and via +-- p_comb also src_in. Hence in total the flow control logic does not change +-- the RL because snk_out relaies combinatorially on snk_in.valid, nxt_r +-- and src_in.ready. +-- +-- . nxt_r.hold_out.valid = combine local and remote flow control: +-- When the functionality in p_comb is about to yield new valid output then +-- nxt_r.hold_out.valid='1' and then the remote src-in is passed on to +-- snk_out. If p_comb is not yet about to yield new valid output then +-- nxt_r.hold_out.valid='0' and then the local r_snk_out is passed on to +-- snk_out. +-- +-- . src_out sosi control fields +-- The src_out sosi control fields (sync, sop, eop, valid) can only become +-- active when the src_in.ready='1'. If the function has new valid output +-- and src_in.ready is '0' then the function has to hold the src_out sosi +-- control in r.hold_out. +-- +-- . src_out sosi data fields +-- The src_out sosi data fields (, data, re, im, bsn, channel, empty, err) +-- can immediately be registered into r.src_out, because they are only +-- accepted when the corresponding sosi control field (valid, sop, eop) has +-- become active. Therefore the sosi dat fields are not kept in r.hold_out. +-- Typically a function that does not use all sosi fields should still pass +-- them on if that is not inappropriate. +-- +-- Design steps: +-- . First determine how to implement the function it self and setup the basic +-- structure in VHDL, eg dtermine what fields in r will be needed. +-- . The initial structure for the function should already be more or less +-- correct such that the default behaviour or simplest behaviour of the +-- function can already be verified with the test bench. Hence the testbench +-- and the component are developed simultaneously. +-- . Next the more detailed functionality, special cases or extra features of +-- the function can be tested one at a time, again starting with the easiest +-- items, until the whole functinality has been covered. This step by step +-- approach makes that the bugs appear one by one instead of all together. +-- Without a step by step approach the bugs are too big to solve. +-- . The development steps can becovered in a single testbench or they may also +-- be covered by representing them as tb instances in a multi tb testbench. +-- During the development the multi tb ensures that bug fixes do not +-- compromise functionality that did already verify ok. When the component +-- is finished, then the multi tb forms the regression test for the component +-- and should be added to the regression tb of the library. +-- . Typically the external flow control by src_in and snk_in is verified as +-- after the component has verified ok for e_active. Often it is sufficient +-- to only verify e_random for both snk_in and src_in, but sometimes it can +-- also be useful to try e_pulse and combinations of eg e_active for snk_in +-- and e_random for snk_out. +-- +-- Remarks: +-- . dp_repack_dev provides two usage examples of this dp_example_dut and of +-- the dp_stream_stimuli and dp_stream_verify components that are used in +-- the test bench. + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; + +ENTITY dp_example_dut IS + PORT ( + rst : IN STD_LOGIC; + clk : IN STD_LOGIC; + + snk_out : OUT t_dp_siso; + snk_in : IN t_dp_sosi; + + src_in : IN t_dp_siso; + src_out : OUT t_dp_sosi + ); +END dp_example_dut; + + +ARCHITECTURE rtl OF dp_example_dut IS + + TYPE t_reg IS RECORD + src_out : t_dp_sosi; -- sosi output + hold_out : t_dp_sosi; -- hold snk_in.sync/sop/eop until end of section and then hold valid src_out until src_in.ready + END RECORD; + + SIGNAL r_snk_out : t_dp_siso := c_dp_siso_rdy; + SIGNAL r : t_reg; + SIGNAL nxt_r : t_reg; + +BEGIN + + p_comb : PROCESS(rst, r, snk_in, src_in) + VARIABLE v : t_reg; + BEGIN + ------------------------------------------------------------------------ + -- Default + v := r; + v.src_out.sync := '0'; + v.src_out.valid := '0'; + v.src_out.sop := '0'; + v.src_out.eop := '0'; + + -------------------------------------------------------------------------- + -- Function + IF r.hold_out.valid='0' THEN + + -- Clear hold_out for new output valid (= new subsection) + IF r.src_out.valid='1' THEN + v.hold_out := c_dp_sosi_rst; + END IF; + + -- Capture the snk_in block info that is valid at sop and eop + IF snk_in.sop='1' THEN + v.hold_out.sop := '1'; + v.hold_out.sync := snk_in.sync; + v.src_out.bsn := snk_in.bsn; + v.src_out.channel := snk_in.channel; + END IF; + IF snk_in.eop='1' THEN + v.hold_out.eop := '1'; + v.src_out.empty := snk_in.empty; + v.src_out.err := snk_in.err; + END IF; + + IF snk_in.valid='1' THEN + + -- < main section of component function > + + v.src_out.data := snk_in.data; -- pipeline function as example + + IF src_in.ready='1' THEN + v.src_out.valid := '1'; + v.src_out.sync := v.hold_out.sync; + v.src_out.sop := v.hold_out.sop; + v.src_out.eop := v.hold_out.eop; + ELSE + v.hold_out.valid := '1'; + END IF; + END IF; + + ELSE + -- pending output + IF src_in.ready='1' THEN + v.src_out.valid := '1'; + v.src_out.sync := r.hold_out.sync; + v.src_out.sop := r.hold_out.sop; + v.src_out.eop := r.hold_out.eop; + v.hold_out.valid := '0'; + END IF; + END IF; + + ------------------------------------------------------------------------ + -- Reset and nxt_r + IF rst = '1' THEN + v.src_out := c_dp_sosi_rst; + v.hold_out := c_dp_sosi_rst; + END IF; + + nxt_r <= v; + END PROCESS; + + -------------------------------------------------------------------------- + -- p_reg + r <= nxt_r WHEN rising_edge(clk); + + -------------------------------------------------------------------------- + -- Wired output + src_out <= r.src_out; + + -------------------------------------------------------------------------- + -- Flow control + + -- local function flow control + p_flow : PROCESS(nxt_r) + BEGIN + r_snk_out <= c_dp_siso_rdy; + + -- < force r_snk_out.ready='0' based on nxt_r if function needs to apply backpressure > + + END PROCESS; + + -- combined local and remote src_in flow control + snk_out.ready <= r_snk_out.ready WHEN nxt_r.hold_out.valid='0' ELSE src_in.ready; -- if there is pending output then the src_in ready determines the flow control + snk_out.xon <= src_in.xon; -- just pass on the xon/off frame flow control + +END rtl; diff --git a/libraries/base/dp/tb/vhdl/tb_dp_example_no_dut.vhd b/libraries/base/dp/tb/vhdl/tb_dp_example_dut.vhd similarity index 87% rename from libraries/base/dp/tb/vhdl/tb_dp_example_no_dut.vhd rename to libraries/base/dp/tb/vhdl/tb_dp_example_dut.vhd index 7305e47165c996ffe9fb94c8854168eee668040a..6446be4b06b677e1f104c1c9963e92072236bb2f 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_example_no_dut.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_example_dut.vhd @@ -95,9 +95,9 @@ -- verification does not start too soon. -- -- . Multi testbench --- This tb_dp_example_no_dut can be instantiated multiple times is a multi --- tb_tb_dp_example_no_dut test bench to verify the DUT for different --- parameter configurations. When the tb_tb_dp_example_no_dut runs ok then it +-- This tb_dp_example_dut can be instantiated multiple times is a multi +-- tb_tb_dp_example_dut test bench to verify the DUT for different +-- parameter configurations. When the tb_tb_dp_example_dut runs ok then it -- can be added to the overall DP library regression testbench in -- tb_tb_tb_dp_backpressure.vhd. -- @@ -120,27 +120,26 @@ USE work.dp_stream_pkg.ALL; USE work.tb_dp_pkg.ALL; -ENTITY tb_dp_example_no_dut IS +ENTITY tb_dp_example_dut 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 + g_flow_control_verify : t_dp_flow_control_enum := e_random; -- always active, random or pulse flow control -- specific - g_in_dat_w : NATURAL := 64; + g_no_dut : BOOLEAN:= FALSE; + g_dat_w : NATURAL := 16; g_nof_repeat : NATURAL := 5; g_pkt_len : NATURAL := 5; g_pkt_gap : NATURAL := 4 ); -END tb_dp_example_no_dut; +END tb_dp_example_dut; -ARCHITECTURE tb OF tb_dp_example_no_dut IS - - CONSTANT c_no_dut : BOOLEAN:= TRUE; +ARCHITECTURE tb OF tb_dp_example_dut IS -- dp_stream_stimuli - CONSTANT c_stimuli_pulse_active : NATURAL := 1; - CONSTANT c_stimuli_pulse_period : NATURAL := 2; + CONSTANT c_stimuli_pulse_active : NATURAL := 3; + CONSTANT c_stimuli_pulse_period : NATURAL := 7; CONSTANT c_data_init : NATURAL := 0; CONSTANT c_bsn_init : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := X"0000000000000000"; -- X"0877665544332211" @@ -149,10 +148,10 @@ ARCHITECTURE tb OF tb_dp_example_no_dut IS -- dp_stream_verify CONSTANT c_verify_pulse_active : NATURAL := 1; - CONSTANT c_verify_pulse_period : NATURAL := 2; + CONSTANT c_verify_pulse_period : NATURAL := 5; - CONSTANT c_data_max : UNSIGNED(g_in_dat_w-1 DOWNTO 0) := (OTHERS=>'1'); - CONSTANT c_dsp_max : UNSIGNED(g_in_dat_w-1 DOWNTO 0) := (OTHERS=>'1'); + CONSTANT c_data_max : UNSIGNED(g_dat_w-1 DOWNTO 0) := (OTHERS=>'1'); + CONSTANT c_dsp_max : UNSIGNED(g_dat_w-1 DOWNTO 0) := (OTHERS=>'1'); --CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := c_dp_sosi_unsigned_rst; -- default 0 is no wrap CONSTANT c_verify_snk_in_cnt_max : t_dp_sosi_unsigned := TO_DP_SOSI_UNSIGNED('0', '0', '0', '0', c_data_max, c_dsp_max, c_dsp_max, c_unsigned_0, c_unsigned_0, c_unsigned_0, c_unsigned_0); @@ -168,7 +167,7 @@ ARCHITECTURE tb OF tb_dp_example_no_dut IS SIGNAL stimuli_src_in : t_dp_siso; SIGNAL stimuli_src_out : t_dp_sosi; - SIGNAL stimuli_src_out_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); + SIGNAL stimuli_src_out_data : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); SIGNAL verify_snk_in_enable : t_dp_sosi_sl := c_dp_sosi_sl_rst; SIGNAL last_snk_in : t_dp_sosi; @@ -183,7 +182,7 @@ ARCHITECTURE tb OF tb_dp_example_no_dut IS SIGNAL verify_snk_out : t_dp_siso := c_dp_siso_rdy; SIGNAL verify_snk_in : t_dp_sosi; - SIGNAL verify_snk_in_data : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0); + SIGNAL verify_snk_in_data : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0); BEGIN @@ -210,7 +209,7 @@ BEGIN g_err_init => c_err_init, g_channel_init => c_channel_init, -- specific - g_in_dat_w => g_in_dat_w, + g_in_dat_w => g_dat_w, g_nof_repeat => g_nof_repeat, g_pkt_len => g_pkt_len, g_pkt_gap => g_pkt_gap @@ -236,7 +235,7 @@ BEGIN -- Select fields that need to be verified -- . during the test - verify_snk_in_enable.sync <= '1'; + verify_snk_in_enable.sync <= '1'; -- or '0' verify_snk_in_enable.bsn <= '1'; verify_snk_in_enable.data <= '1'; verify_snk_in_enable.re <= '0'; @@ -249,8 +248,8 @@ BEGIN verify_snk_in_enable.err <= '1'; -- . after the test - verify_last_snk_in_evt.sync <= '0'; - verify_last_snk_in_evt.bsn <= '0'; + verify_last_snk_in_evt.sync <= last_snk_in_evt; + verify_last_snk_in_evt.bsn <= last_snk_in_evt; verify_last_snk_in_evt.data <= last_snk_in_evt; verify_last_snk_in_evt.re <= '0'; verify_last_snk_in_evt.im <= '0'; @@ -275,7 +274,7 @@ BEGIN g_snk_in_cnt_max => c_verify_snk_in_cnt_max, g_snk_in_cnt_gap => c_verify_snk_in_cnt_gap, -- specific - g_in_dat_w => g_in_dat_w, + g_in_dat_w => g_dat_w, g_pkt_len => g_pkt_len ) PORT MAP ( @@ -302,14 +301,24 @@ BEGIN stimuli_src_in <= dut_snk_out; dut_snk_in <= stimuli_src_out; - no_dut : IF c_no_dut=TRUE GENERATE + no_dut : IF g_no_dut=TRUE GENERATE dut_snk_out <= dut_src_in; dut_src_out <= dut_snk_in; END GENERATE; -- DUT function - gen_dut : IF c_no_dut=FALSE GENERATE + gen_dut : IF g_no_dut=FALSE GENERATE + u_dut : ENTITY work.dp_example_dut + PORT MAP ( + rst => rst, + clk => clk, + + snk_out => dut_snk_out, + snk_in => dut_snk_in, + src_in => dut_src_in, + src_out => dut_src_out + ); END GENERATE; -- Connect DUT source output stream to verification @@ -322,7 +331,7 @@ BEGIN ------------------------------------------------------------------------------ -- Map to slv to ease monitoring in wave window - stimuli_src_out_data <= stimuli_src_out.data(g_in_dat_w-1 DOWNTO 0); - verify_snk_in_data <= verify_snk_in.data(g_in_dat_w-1 DOWNTO 0); + stimuli_src_out_data <= stimuli_src_out.data(g_dat_w-1 DOWNTO 0); + verify_snk_in_data <= verify_snk_in.data(g_dat_w-1 DOWNTO 0); END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_example_no_dut.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_example_dut.vhd similarity index 62% rename from libraries/base/dp/tb/vhdl/tb_tb_dp_example_no_dut.vhd rename to libraries/base/dp/tb/vhdl/tb_tb_dp_example_dut.vhd index d0bd2fb7fe920587490d9d86229678bacb0a0bc2..3c0c066ba8ade8d21dde08ba71145a4cd3172148 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_example_no_dut.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_example_dut.vhd @@ -20,23 +20,27 @@ -- ------------------------------------------------------------------------------- -LIBRARY IEEE, dp_lib; +LIBRARY IEEE, common_lib; USE IEEE.std_logic_1164.ALL; -USE dp_lib.tb_dp_pkg.ALL; +USE common_lib.common_pkg.ALL; +USE work.tb_dp_pkg.ALL; --- Purpose: Verify multiple variations of tb_dp_example_no_dut +-- Purpose: Verify multiple variations of tb_dp_example_dut -- Description: -- Usage: --- > as 3 +-- > as 6 -- > run -all -ENTITY tb_tb_dp_example_no_dut IS -END tb_tb_dp_example_no_dut; +ENTITY tb_tb_dp_example_dut IS +END tb_tb_dp_example_dut; -ARCHITECTURE tb OF tb_tb_dp_example_no_dut IS +ARCHITECTURE tb OF tb_tb_dp_example_dut IS - CONSTANT c_nof_repeat : NATURAL := 10; + CONSTANT c_nof_repeat : NATURAL := 10; + + CONSTANT c_flow : t_dp_flow_control_enum_arr := c_dp_flow_control_enum_arr; + CONSTANT c_bool : t_nat_boolean_arr := c_nat_boolean_arr; BEGIN @@ -44,14 +48,18 @@ BEGIN -- g_flow_control_stimuli : t_dp_flow_control_enum := e_pulse; -- 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_no_dut : BOOLEAN:= TRUE; -- g_in_dat_w : NATURAL := 32; -- g_nof_repeat : NATURAL := 5; -- g_pkt_len : NATURAL := 16; -- g_pkt_gap : NATURAL := 4 - - u_act_act : ENTITY work.tb_dp_example_no_dut GENERIC MAP ( e_active, e_active, 32, c_nof_repeat, 139, 4); - u_rnd_act : ENTITY work.tb_dp_example_no_dut GENERIC MAP ( e_random, e_active, 24, c_nof_repeat, 139, 5); - u_rnd_rnd : ENTITY work.tb_dp_example_no_dut GENERIC MAP ( e_random, e_random, 16, c_nof_repeat, 139, 6); - u_pls_pls : ENTITY work.tb_dp_example_no_dut GENERIC MAP ( e_pulse, e_pulse, 8, c_nof_repeat, 139, 7); - + + g_flow_control_stimuli : FOR I IN 0 TO 2 GENERATE -- 0 = e_active, 1 = e_random, 2 = e_pulse + g_flow_control_verify : FOR J IN 0 TO 2 GENERATE -- 0 = e_active, 1 = e_random, 2 = e_pulse + gen_bool_dut : FOR K IN 0 TO 1 GENERATE -- 0 = TRUE, 1= FALSE + u_dut : ENTITY work.tb_dp_example_dut GENERIC MAP (c_flow(I), c_flow(J), c_bool(K), 16, c_nof_repeat, 17, 4); + END GENERATE; + END GENERATE; + END GENERATE; + END tb; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_tb_dp_backpressure.vhd b/libraries/base/dp/tb/vhdl/tb_tb_tb_dp_backpressure.vhd index 51635a294151298aa31931fb0dce4a4148fe894c..fc5d5db4514af3cdd9dab8a4deb266b539ed8311 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_tb_dp_backpressure.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_tb_dp_backpressure.vhd @@ -53,7 +53,7 @@ BEGIN u_tb_tb_dp_concat : ENTITY work.tb_tb_dp_concat; u_tb_tb_dp_demux : ENTITY work.tb_tb_dp_demux; u_tb_tb_dp_distribute : ENTITY work.tb_tb_dp_distribute; - u_tb_tb_dp_example_no_dut : ENTITY work.tb_tb_dp_example_no_dut; + u_tb_tb_dp_example_dut : ENTITY work.tb_tb_dp_example_dut; u_tb_tb_dp_fifo_dc : ENTITY work.tb_tb_dp_fifo_dc; u_tb_tb_dp_fifo_dc_mixed_widths : ENTITY work.tb_tb_dp_fifo_dc_mixed_widths; u_tb_tb_dp_fifo_fill : ENTITY work.tb_tb_dp_fifo_fill;