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

Improved dp_block_gen_arr.vhd and described three typical use cases.

parent e390c5db
No related branches found
No related tags found
No related merge requests found
...@@ -22,12 +22,13 @@ ...@@ -22,12 +22,13 @@
-- Purpose : Generate the sosi control for a block of data based on the -- Purpose : Generate the sosi control for a block of data based on the
-- input valid -- input valid
-- Description: -- Description:
-- When enabled a block of g_nof_data_per_block words is output via -- All input streams in the snk_in_arr must have the same sosi ctrl and info
-- src_out_arr under flow control by the input valid. The input valid is -- fields, such that the valid from snk_in_arr(0) is sufficient. Only the
-- taken from snk_in_arr(0). Therefore all input streams in the snk_in_arr -- data, re, im in the snk_in_arr() differs. Therefore default connect snk_in
-- must have the same sosi ctrl and info fields, such that the valid from -- = snk_in_arr(0).
-- snk_in_arr(0) is sufficient. Only the data, re, im in the snk_in_arr() --
-- differs. -- When enabled (enable='1') then a block of g_nof_data_per_block words is
-- output via src_out_arr under flow control by the input valid.
-- --
-- The input sync, sop and eop are ignored. For the output the sync, sop and -- The input sync, sop and eop are ignored. For the output the sync, sop and
-- eop are generated by counting the input valid and using -- eop are generated by counting the input valid and using
...@@ -41,27 +42,89 @@ ...@@ -41,27 +42,89 @@
-- such that it increments for every block and that it restarts at 0 at every -- such that it increments for every block and that it restarts at 0 at every
-- output sync. -- output sync.
-- --
-- g_use_input_sync: -- Typically the size of g_nof_blk_per_sync*g_nof_data_per_block should match
-- When g_use_input_sync=FALSE then the input sync is ignored and the first -- the number of input valids in an input sync interval.
--
-- The local BSN restarts at 0 for every new output sync interval, but instead
-- of BSN = 0 the input BSN will be inserted at the first block in a new
-- output sync interval. If the first output BSN should remain 0 then simply
-- keep snk_in.bsn = 0.
--
-- g_nof_pages_bsn:
-- The input BSN is not available in snk_in_arr(0) if the upstream component
-- does not pass the BSN on. In that case the snk_in.sync and snk_in.bsn can
-- be connected to some further upstream interface that does have the proper
-- BSN. The input BSN is then buffered to align it with the local sync that is
-- recreated for the output. This buffer is set via g_nof_pages_bsn. Typically
-- g_nof_pages_bsn = 1 is sufficient to align the BSN along some DSP,
-- components, because the latency in number of blocks of most DSP functions
-- is much less than a sync interval. For a corner turn that operates per sync
-- interval choosing g_nof_pages_bsn = 2 seems appropriate.
--
-- g_check_input_sync:
-- When g_check_input_sync=FALSE then the input sync is ignored and the first
-- input valid that occurs after when enable is active will start the local -- input valid that occurs after when enable is active will start the local
-- sync. When g_use_input_sync=TRUE then the block output for a new sync -- sync. When g_check_input_sync=TRUE then the block output for a new sync
-- interval is only started if the input valid also coincides with a input -- interval is only started if the input valid also coincides with a input
-- sync. Hence for this mode the size of g_nof_blk_per_sync * -- sync. Until then all input valid are ignored and there is no output then.
-- g_nof_data_per_block should match the number of input valids in an input
-- sync interval.
-- --
-- g_use_input_bsn_at_sync: -- Usage:
-- When g_use_input_bsn_at_sync=FALSE then all output blocks will count the -- * Example 1: Use snk_in.valid to recreate sync, sop, eop, bsn for a DP
-- local BSN that restarts at 0 for every new output sync interval. When -- function that only passes on the valid.
-- g_use_input_bsn_at_sync=TRUE then the input BSN will be inserted instead --
-- of BSN = 0 for the first block in a new output sync interval. This mode -- - g_check_input_sync = False
-- is useful to preserve the longer term timestamp information that may be -- - g_nof_pages_bsn = 0
-- carried by the input BSN. --
-- -- |------|
-- snk_in_arr() ----*--------->| |----> src_out_arr
-- | | dp |
-- (0)| | block|
-- | snk_in | gen |
-- \--------->| arr |
-- |------|
--
-- * Example 2: Use snk_in.valid to recreate sop, eop, bsn and check that the
-- local sync is aligned with the snk_in.sync. If the snk_in.sync
-- does not coincide with the local sync, then stop the output of
-- blocks until the snk_in.sync occurs again.
--
-- - g_check_input_sync = True
-- - g_nof_pages_bsn = 0
--
-- |------|
-- snk_in_arr() ----*--------->| |----> src_out_arr
-- | | dp |
-- (0)| | block|
-- | snk_in | gen |
-- \--------->| arr |
-- |------|
-- * Example 3: Use snk_in.valid to recreate sop, eop, bsn for a DP
-- function that only passes on the valid. However for delay
-- the snk_in.bsn by g_nof_pages_bsn to account for the block
-- latency of the upstream DP components that did not pass on
-- the snk_in.bsn.
--
-- - g_check_input_sync = False
-- - g_nof_pages_bsn >= 1
--
-- |-----| snk_in_arr() |------|
-- -----*-->| |-------*--------->| |----> src_out_arr
-- | | DP | | | dp |
-- | | | (0)| | block|
-- | | | | snk_in | gen |
-- | | | \--*------>| arr |
-- sync| |-----| ^ |------|
-- bsn | |
-- \--------------------/
--
-- Remarks: -- Remarks:
-- . No siso flow control, although enable could be used as siso.xon -- . No siso flow control, although enable could be used as siso.xon
-- . Only the bsn info field is supported, the other info fields (channel, -- . The channel, empty and err fields are passed on to the output. Typically
-- empty and err) are output as 0. -- these fields are not used with DSP data. However this scheme still
-- allows setting these fields to a fixed value via snk_in.
-- . Using g_check_input_sync=True is similar to using a dp_sync_checker in
-- front of this dp_block_gen_arr. However the advantage of dp_sync_checker
-- is that it provides monitoring and control via MM.
LIBRARY IEEE, common_lib; LIBRARY IEEE, common_lib;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_1164.ALL;
...@@ -72,15 +135,16 @@ USE work.dp_stream_pkg.ALL; ...@@ -72,15 +135,16 @@ USE work.dp_stream_pkg.ALL;
ENTITY dp_block_gen_arr IS ENTITY dp_block_gen_arr IS
GENERIC ( GENERIC (
g_nof_streams : POSITIVE := 1; g_nof_streams : POSITIVE := 1;
g_nof_data_per_block : POSITIVE := 1; -- nof data per block g_nof_data_per_block : POSITIVE := 1;
g_nof_blk_per_sync : POSITIVE := 8; g_nof_blk_per_sync : POSITIVE := 8;
g_use_input_sync : BOOLEAN := FALSE; g_check_input_sync : BOOLEAN := FALSE;
g_use_input_bsn_at_sync : BOOLEAN := FALSE g_nof_pages_bsn : NATURAL := 0
); );
PORT ( PORT (
rst : IN STD_LOGIC; rst : IN STD_LOGIC;
clk : IN STD_LOGIC; clk : IN STD_LOGIC;
-- Streaming sink -- Streaming sink
snk_in : IN t_dp_sosi; -- = snk_in_arr(0)
snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Streaming source -- Streaming source
src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
...@@ -92,6 +156,22 @@ END dp_block_gen_arr; ...@@ -92,6 +156,22 @@ END dp_block_gen_arr;
ARCHITECTURE rtl OF dp_block_gen_arr IS ARCHITECTURE rtl OF dp_block_gen_arr IS
-- Check consistancy of the parameters, the function return value is void, because always true or abort due to failure
FUNCTION parameter_asserts(g_check_input_sync : BOOLEAN; g_nof_pages_bsn : NATURAL) return BOOLEAN IS
BEGIN
IF g_check_input_sync=TRUE THEN
ASSERT g_nof_pages_bsn=0 REPORT "When g_check_input_sync=TRUE then g_nof_pages_bsn must be 0." SEVERITY FAILURE;
-- because snk_in.sync and snk_in.bsn are then already aligned with the first snk_in.valid
END IF;
IF g_nof_pages_bsn>0 THEN
ASSERT g_check_input_sync=FALSE REPORT "When g_nof_pages_bsn>0 then g_check_input_sync must be FALSE." SEVERITY FAILURE;
-- because snk_in.sync and snk_in.bsn are then NOT aligned with the first snk_in.valid
END IF;
RETURN TRUE;
END parameter_asserts;
CONSTANT c_parameters_ok : BOOLEAN := parameter_asserts(g_check_input_sync, g_nof_pages_bsn);
TYPE t_state IS (s_sop, s_data, s_eop); TYPE t_state IS (s_sop, s_data, s_eop);
TYPE t_reg IS RECORD -- local registers TYPE t_reg IS RECORD -- local registers
...@@ -102,8 +182,11 @@ ARCHITECTURE rtl OF dp_block_gen_arr IS ...@@ -102,8 +182,11 @@ ARCHITECTURE rtl OF dp_block_gen_arr IS
END RECORD; END RECORD;
CONSTANT c_reg_rst : t_reg := (s_sop, 0, 0, c_dp_sosi_rst); CONSTANT c_reg_rst : t_reg := (s_sop, 0, 0, c_dp_sosi_rst);
SIGNAL in_sosi : t_dp_sosi;
SIGNAL in_sync_wr_en : STD_LOGIC_VECTOR(g_nof_pages_bsn-1 DOWNTO 0);
SIGNAL in_bsn_buffer : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
SIGNAL snk_in : t_dp_sosi;
SIGNAL nxt_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL nxt_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Define the local registers in t_reg record -- Define the local registers in t_reg record
...@@ -123,17 +206,46 @@ BEGIN ...@@ -123,17 +206,46 @@ BEGIN
END IF; END IF;
END PROCESS; END PROCESS;
no_bsn_buffer : IF g_nof_pages_bsn=0 GENERATE
in_sosi <= snk_in;
END GENERATE;
gen_bsn_buffer : IF g_nof_pages_bsn>0 GENERATE
-- Buffer input BSN at each input sync
in_sync_wr_en <= (OTHERS=>snk_in.sync);
u_paged_bsn : ENTITY common_lib.common_paged_reg
GENERIC MAP (
g_data_w => c_dp_stream_bsn_w,
g_nof_pages => g_nof_pages_bsn
)
PORT MAP (
rst => rst,
clk => clk,
wr_en => in_sync_wr_en,
wr_dat => snk_in.bsn,
out_dat => in_bsn_buffer
);
p_snk_in : PROCESS(snk_in, in_bsn_buffer)
BEGIN
in_sosi <= snk_in;
in_sosi.sync <= '0';
in_sosi.bsn <= in_bsn_buffer;
END PROCESS;
END GENERATE;
-- Combine input data with the same out_put info and output ctrl for all streams -- Combine input data with the same out_put info and output ctrl for all streams
nxt_src_out_arr <= func_dp_stream_arr_combine_data_info_ctrl(snk_in_arr, nxt_r.src_out, nxt_r.src_out); nxt_src_out_arr <= func_dp_stream_arr_combine_data_info_ctrl(snk_in_arr, nxt_r.src_out, nxt_r.src_out);
-- Determine the output info and output ctrl using snk_in and r.src_out -- Determine the output info and output ctrl using snk_in and r.src_out
snk_in <= snk_in_arr(0); p_state : PROCESS(r, enable, in_sosi)
p_state : PROCESS(r, enable, snk_in)
BEGIN BEGIN
nxt_r <= r; nxt_r <= r;
-- default set the output ctrl to '0' -- default output in_sosi, hold output bsn and set the output ctrl to '0'
nxt_r.src_out <= in_sosi;
nxt_r.src_out.bsn <= r.src_out.bsn;
nxt_r.src_out.valid <= '0'; nxt_r.src_out.valid <= '0';
nxt_r.src_out.sop <= '0'; nxt_r.src_out.sop <= '0';
nxt_r.src_out.eop <= '0'; nxt_r.src_out.eop <= '0';
...@@ -153,19 +265,14 @@ BEGIN ...@@ -153,19 +265,14 @@ BEGIN
nxt_r.blk_cnt <= r.blk_cnt+1; nxt_r.blk_cnt <= r.blk_cnt+1;
END IF; END IF;
-- create local sync -- create local sync and pass on input bsn at local sync
IF r.blk_cnt=0 THEN -- output sync starts at first input valid IF r.blk_cnt=0 THEN -- output sync starts at first input valid
nxt_r.src_out.sync <= '1'; -- output sync for this block nxt_r.src_out.sync <= '1'; -- output sync for this block
nxt_r.src_out.bsn <= in_sosi.bsn; -- output input bsn at sync
ELSE
nxt_r.src_out.bsn <= TO_DP_BSN(r.blk_cnt); -- output local bsn for the subsequent blocks
END IF; END IF;
-- create local bsn
nxt_r.src_out.bsn <= TO_DP_BSN(r.blk_cnt); -- default use local bsn for all blocks
IF g_use_input_bsn_at_sync=TRUE THEN
IF r.blk_cnt=0 THEN
nxt_r.src_out.bsn <= snk_in.bsn; -- if enabled then pass on the input bsn at the sync
END IF;
END IF;
nxt_r.src_out.valid <= '1'; nxt_r.src_out.valid <= '1';
nxt_r.src_out.sop <= '1'; nxt_r.src_out.sop <= '1';
...@@ -177,7 +284,7 @@ BEGIN ...@@ -177,7 +284,7 @@ BEGIN
END IF; END IF;
-- if enabled then check input sync and stop the new block output if the local sync does not coincide with the input sync -- if enabled then check input sync and stop the new block output if the local sync does not coincide with the input sync
IF g_use_input_sync=TRUE THEN IF g_check_input_sync=TRUE THEN
IF r.blk_cnt=0 THEN IF r.blk_cnt=0 THEN
IF snk_in.sync='0' THEN IF snk_in.sync='0' THEN
nxt_r.src_out.valid <= '0'; -- undo all ctrl preparations for the new block nxt_r.src_out.valid <= '0'; -- undo all ctrl preparations for the new block
......
...@@ -42,8 +42,8 @@ ENTITY tb_dp_block_gen_arr IS ...@@ -42,8 +42,8 @@ ENTITY tb_dp_block_gen_arr IS
g_nof_streams : POSITIVE := 1; g_nof_streams : POSITIVE := 1;
g_nof_data_per_block : POSITIVE := 11; g_nof_data_per_block : POSITIVE := 11;
g_nof_blk_per_sync : POSITIVE := 8; g_nof_blk_per_sync : POSITIVE := 8;
g_use_input_sync : BOOLEAN := FALSE; g_check_input_sync : BOOLEAN := FALSE;
g_use_input_bsn_at_sync : BOOLEAN := TRUE; g_nof_pages_bsn : NATURAL := 0;
g_enable : t_dp_flow_control_enum := e_active; -- always e_active or e_pulse block generator enable g_enable : t_dp_flow_control_enum := e_active; -- always e_active or e_pulse block generator enable
g_flow_control : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control for input valid g_flow_control : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control for input valid
g_nof_repeat : NATURAL := 1000 g_nof_repeat : NATURAL := 1000
...@@ -57,34 +57,48 @@ ARCHITECTURE tb OF tb_dp_block_gen_arr IS ...@@ -57,34 +57,48 @@ ARCHITECTURE tb OF tb_dp_block_gen_arr IS
CONSTANT c_nof_valid_per_sync : NATURAL := g_nof_blk_per_sync*g_nof_data_per_block; CONSTANT c_nof_valid_per_sync : NATURAL := g_nof_blk_per_sync*g_nof_data_per_block;
CONSTANT c_nof_valid_per_enable : NATURAL := 3*c_nof_valid_per_sync+1; CONSTANT c_nof_valid_per_enable : NATURAL := 3*c_nof_valid_per_sync+1;
CONSTANT c_dsp_latency : NATURAL := 1; -- >= 1 block and typically << g_nof_blk_per_sync blocks
CONSTANT c_bsn_init : NATURAL := 3; CONSTANT c_bsn_init : NATURAL := 3;
CONSTANT c_block_bsn_max : NATURAL := g_nof_blk_per_sync-1; CONSTANT c_channel_init : NATURAL := 17;
CONSTANT c_err_init : NATURAL := 13;
CONSTANT c_input_bsn_no_wrap : NATURAL := 0; -- use 0 to indicate no max, so no wrap
CONSTANT c_input_bsn_gap : NATURAL := g_nof_blk_per_sync;
CONSTANT c_local_bsn_max : NATURAL := g_nof_blk_per_sync-1;
CONSTANT c_local_bsn_gap : NATURAL := 2;
SIGNAL tb_input_end : STD_LOGIC := '0'; SIGNAL tb_input_end : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL clk : STD_LOGIC := '1'; SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1'; SIGNAL rst : STD_LOGIC := '1';
SIGNAL sl1 : STD_LOGIC := '1'; SIGNAL sl1 : STD_LOGIC := '1';
SIGNAL exp_channel : STD_LOGIC_VECTOR(c_dp_stream_channel_w-1 DOWNTO 0) := TO_DP_CHANNEL(c_channel_init);
SIGNAL exp_err : STD_LOGIC_VECTOR(c_dp_stream_error_w-1 DOWNTO 0) := TO_DP_ERROR(c_err_init);
SIGNAL enable : STD_LOGIC; SIGNAL enable : STD_LOGIC;
SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL in_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); SIGNAL out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
SIGNAL stimuli_sosi : t_dp_sosi;
SIGNAL dsp_sosi : t_dp_sosi;
SIGNAL in_sosi : t_dp_sosi; SIGNAL in_sosi : t_dp_sosi;
SIGNAL out_sosi : t_dp_sosi; SIGNAL out_sosi : t_dp_sosi;
SIGNAL prev_out_sosi : t_dp_sosi; SIGNAL prev_out_sosi : t_dp_sosi;
SIGNAL out_sosi_local : t_dp_sosi;
SIGNAL prev_out_sosi_local : t_dp_sosi;
SIGNAL out_gap : STD_LOGIC := '0'; SIGNAL out_gap : STD_LOGIC := '0';
SIGNAL hold_sop : STD_LOGIC := '0'; SIGNAL hold_sop : STD_LOGIC := '0';
SIGNAL exp_size : NATURAL := g_nof_data_per_block; SIGNAL exp_size : NATURAL := g_nof_data_per_block;
SIGNAL cnt_size : NATURAL := 0; SIGNAL cnt_size : NATURAL := 0;
SIGNAL verify_en : STD_LOGIC := '0';
SIGNAL verify_bsn_en : STD_LOGIC := '0'; SIGNAL verify_bsn_en : STD_LOGIC := '0';
SIGNAL verify_done : STD_LOGIC := '0'; SIGNAL verify_done : STD_LOGIC := '0';
SIGNAL verify_valid : STD_LOGIC := '0'; SIGNAL verify_valid : STD_LOGIC := '0';
SIGNAL verify_sop : STD_LOGIC := '0'; SIGNAL verify_sop : STD_LOGIC := '0';
SIGNAL verify_eop : STD_LOGIC := '0'; SIGNAL verify_eop : STD_LOGIC := '0';
SIGNAL verify_sync : STD_LOGIC := '0';
BEGIN BEGIN
...@@ -131,8 +145,10 @@ BEGIN ...@@ -131,8 +145,10 @@ BEGIN
g_sync_offset => 0, g_sync_offset => 0,
g_data_init => 0, g_data_init => 0,
g_bsn_init => TO_DP_BSN(c_bsn_init), g_bsn_init => TO_DP_BSN(c_bsn_init),
g_err_init => 0, g_err_init => c_err_init,
g_channel_init => 0, g_err_incr => 0,
g_channel_init => c_channel_init,
g_channel_incr => 0,
-- specific -- specific
g_in_dat_w => 32, g_in_dat_w => 32,
g_nof_repeat => g_nof_repeat, g_nof_repeat => g_nof_repeat,
...@@ -144,7 +160,7 @@ BEGIN ...@@ -144,7 +160,7 @@ BEGIN
clk => clk, clk => clk,
-- Generate stimuli -- Generate stimuli
src_out => in_sosi, src_out => stimuli_sosi,
-- End of stimuli -- End of stimuli
last_snk_in => OPEN, -- expected verify_snk_in after end of stimuli last_snk_in => OPEN, -- expected verify_snk_in after end of stimuli
...@@ -152,6 +168,29 @@ BEGIN ...@@ -152,6 +168,29 @@ BEGIN
tb_end => tb_input_end -- signal end of tb as far as this dp_stream_stimuli is concerned tb_end => tb_input_end -- signal end of tb as far as this dp_stream_stimuli is concerned
); );
-- Use dp_pipeline to model the latency introduced by upstream DSP components
u_dp_pipeline : ENTITY work.dp_pipeline
GENERIC MAP (
g_pipeline => c_dsp_latency -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => rst,
clk => clk,
-- ST sink
snk_in => stimuli_sosi,
-- ST source
src_out => dsp_sosi
);
p_in_sosi : PROCESS(dsp_sosi, stimuli_sosi)
BEGIN
in_sosi <= dsp_sosi;
IF g_nof_pages_bsn>0 THEN
in_sosi.sync <= stimuli_sosi.sync;
in_sosi.bsn <= stimuli_sosi.bsn;
END IF;
END PROCESS;
-- Use same stimuli for all streams -- Use same stimuli for all streams
in_sosi_arr <= (OTHERS=>in_sosi); in_sosi_arr <= (OTHERS=>in_sosi);
...@@ -159,14 +198,13 @@ BEGIN ...@@ -159,14 +198,13 @@ BEGIN
-- VERIFICATION -- VERIFICATION
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
verify_en <= '1';
p_verify_bsn : PROCESS p_verify_bsn : PROCESS
BEGIN BEGIN
verify_bsn_en <= '0'; verify_bsn_en <= '0';
proc_common_wait_until_high(clk, enable); proc_common_wait_until_high(clk, enable);
proc_common_wait_until_hi_lo(clk, out_sosi.sop); -- first sop will have occured, so start verification for subsequent BSN proc_common_wait_until_hi_lo(clk, out_sosi.sop);
IF g_use_input_sync=TRUE THEN proc_common_wait_until_hi_lo(clk, out_sosi.sop); -- first two sop will have occured, so start verification for subsequent BSN
IF g_check_input_sync=TRUE THEN
proc_common_wait_until_hi_lo(clk, out_sosi.sync); -- if necessary also wait for first sync proc_common_wait_until_hi_lo(clk, out_sosi.sync); -- if necessary also wait for first sync
END IF; END IF;
WHILE enable='1' LOOP WHILE enable='1' LOOP
...@@ -182,28 +220,35 @@ BEGIN ...@@ -182,28 +220,35 @@ BEGIN
verify_valid <= '1' WHEN out_sosi.valid='1' AND rising_edge(clk); verify_valid <= '1' WHEN out_sosi.valid='1' AND rising_edge(clk);
verify_sop <= '1' WHEN out_sosi.sop='1' AND rising_edge(clk); verify_sop <= '1' WHEN out_sosi.sop='1' AND rising_edge(clk);
verify_eop <= '1' WHEN out_sosi.eop='1' AND rising_edge(clk); verify_eop <= '1' WHEN out_sosi.eop='1' AND rising_edge(clk);
proc_dp_verify_value("out_sosi.valid", clk, verify_done, sl1, verify_valid); verify_sync <= '1' WHEN out_sosi.sync='1' AND rising_edge(clk);
proc_dp_verify_value("out_sosi.sop", clk, verify_done, sl1, verify_sop); proc_dp_verify_value("out_sosi.valid", clk, verify_done, sl1, verify_valid);
proc_dp_verify_value("out_sosi.eop", clk, verify_done, sl1, verify_eop); proc_dp_verify_value("out_sosi.sop", clk, verify_done, sl1, verify_sop);
proc_dp_verify_value("out_sosi.eop", clk, verify_done, sl1, verify_eop);
proc_dp_verify_value("out_sosi.sync", clk, verify_done, sl1, verify_sync);
proc_dp_verify_value("out_sosi.channel", e_equal, clk, verify_done, exp_channel, out_sosi.channel);
proc_dp_verify_value("out_sosi.err", e_equal, clk, verify_done, exp_err, out_sosi.err);
-- Verify some general streaming interface properties -- Verify some general streaming interface properties
proc_dp_verify_gap_invalid(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, out_gap); -- Verify that the out_sosi valid is low between blocks proc_dp_verify_gap_invalid(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, out_gap); -- Verify that the out_sosi valid is low between blocks
gen_use_input_bsn_at_sync : IF g_use_input_bsn_at_sync=TRUE GENERATE -- define out_sosi_local with sync = '0' to be able to verify local bsn incrementing during rest of sync interval
proc_dp_verify_data("BSN", 0, g_nof_blk_per_sync, clk, verify_bsn_en, out_sosi.sync, out_sosi.bsn, prev_out_sosi.bsn); -- only verify BSN at sync p_out_sosi_local : PROCESS(out_sosi)
END GENERATE; BEGIN
gen_use_local_bsn_at_sync : IF g_use_input_bsn_at_sync=FALSE GENERATE out_sosi_local <= out_sosi;
proc_dp_verify_data("BSN", c_block_bsn_max, clk, verify_bsn_en, out_sosi.sop, out_sosi.bsn, prev_out_sosi.bsn); -- verify all BSN out_sosi_local.sync <= '0';
END GENERATE; IF out_sosi.sync='1' THEN
out_sosi_local.sop <= '0';
END IF;
END PROCESS;
-- only verify BSN at sync using out_sosi
proc_dp_verify_sync(1, c_bsn_init, clk, verify_bsn_en, out_sosi.sync, out_sosi.sync, out_sosi.bsn);
proc_dp_verify_data("BSN", c_input_bsn_no_wrap, c_input_bsn_gap, clk, verify_bsn_en, out_sosi.sync, out_sosi.bsn, prev_out_sosi.bsn);
-- verify BSN at all sop using out_sosi_local
proc_dp_verify_data("BSN", c_local_bsn_max, c_local_bsn_gap, clk, verify_bsn_en, out_sosi_local.sop, out_sosi_local.bsn, prev_out_sosi_local.bsn);
-- Verify intervals -- Verify intervals
gen_use_input_sync : IF g_use_input_sync GENERATE
proc_dp_verify_sync(1, c_bsn_init, clk, verify_en, out_sosi.sync, out_sosi.sync, out_sosi.bsn);
END GENERATE;
gen_use_local_sync : IF g_use_input_sync GENERATE
proc_dp_verify_sync(g_nof_blk_per_sync, 0, clk, verify_en, out_sosi.sync, out_sosi.sop, out_sosi.bsn);
END GENERATE;
proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_sop); proc_dp_verify_sop_and_eop(clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, hold_sop);
proc_dp_verify_block_size(exp_size, clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, cnt_size); proc_dp_verify_block_size(exp_size, clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, cnt_size);
...@@ -217,13 +262,14 @@ BEGIN ...@@ -217,13 +262,14 @@ BEGIN
g_nof_streams => g_nof_streams, g_nof_streams => g_nof_streams,
g_nof_data_per_block => g_nof_data_per_block, g_nof_data_per_block => g_nof_data_per_block,
g_nof_blk_per_sync => g_nof_blk_per_sync, g_nof_blk_per_sync => g_nof_blk_per_sync,
g_use_input_sync => g_use_input_sync, g_check_input_sync => g_check_input_sync,
g_use_input_bsn_at_sync => g_use_input_bsn_at_sync g_nof_pages_bsn => g_nof_pages_bsn
) )
PORT MAP ( PORT MAP (
rst => rst, rst => rst,
clk => clk, clk => clk,
-- Streaming sink -- Streaming sink
snk_in => in_sosi,
snk_in_arr => in_sosi_arr, snk_in_arr => in_sosi_arr,
-- Streaming source -- Streaming source
src_out_arr => out_sosi_arr, src_out_arr => out_sosi_arr,
......
...@@ -39,19 +39,21 @@ BEGIN ...@@ -39,19 +39,21 @@ BEGIN
-- g_nof_streams : POSITIVE := 1; -- g_nof_streams : POSITIVE := 1;
-- g_nof_data_per_block : POSITIVE := 11; -- g_nof_data_per_block : POSITIVE := 11;
-- g_nof_blk_per_sync : POSITIVE := 8; -- g_nof_blk_per_sync : POSITIVE := 8;
-- g_use_input_sync : BOOLEAN := FALSE; -- g_check_input_sync : BOOLEAN := FALSE;
-- g_use_input_bsn_at_sync : BOOLEAN := FALSE; -- g_nof_pages_bsn : NATURAL := 0;
-- g_enable : t_dp_flow_control_enum := e_active; -- always e_active or e_pulse block generator enable -- g_enable : t_dp_flow_control_enum := e_active; -- always e_active or e_pulse block generator enable
-- g_flow_control : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control for input valid -- g_flow_control : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control for input valid
-- g_nof_repeat : NATURAL := 200 -- g_nof_repeat : NATURAL := 200
u_local : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, FALSE, FALSE, e_active, e_active, 100); u_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, FALSE, 0, e_active, e_active, 100);
u_input_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, FALSE, e_active, e_active, 100); u_input_bsn_check_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, 0, e_active, e_active, 100);
u_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, TRUE, e_active, e_active, 100); u_buffer_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, 1, e_active, e_active, 100);
u_input_sync_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, TRUE, TRUE, e_active, e_active, 100);
u_rnd_local : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, FALSE, FALSE, e_pulse, e_random, 300); u_en_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, FALSE, 0, e_pulse, e_active, 500);
u_rnd_input_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, FALSE, e_pulse, e_random, 300); u_en_input_bsn_check_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, 0, e_pulse, e_active, 500);
u_rnd_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, TRUE, e_pulse, e_random, 300); u_en_buffer_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, 1, e_pulse, e_active, 500);
u_rnd_input_sync_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, TRUE, TRUE, e_pulse, e_random, 300);
u_en_rnd_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, FALSE, 0, e_pulse, e_random, 500);
u_en_rnd_input_bsn_check_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, 0, e_pulse, e_random, 500);
u_en_rnd_buffer_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, 1, e_pulse, e_random, 500);
END tb; END tb;
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