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

Added dp_block_gen_arr.vhd with tb and multi-tb.

parent 62dec963
Branches
No related tags found
No related merge requests found
......@@ -58,6 +58,7 @@ synth_files =
src/vhdl/dp_pad_insert.vhd
src/vhdl/dp_pad_remove.vhd
src/vhdl/dp_block_gen.vhd
src/vhdl/dp_block_gen_arr.vhd
src/vhdl/dp_bsn_source.vhd
src/vhdl/dp_bsn_source_reg.vhd
src/vhdl/mms_dp_bsn_source.vhd
......@@ -141,6 +142,7 @@ test_bench_files =
tb/vhdl/dp_stream_verify.vhd
tb/vhdl/tb_dp_block_gen.vhd
tb/vhdl/tb_dp_block_gen_arr.vhd
tb/vhdl/tb_dp_bsn_align.vhd
tb/vhdl/tb_mms_dp_bsn_align.vhd
tb/vhdl/tb_dp_bsn_monitor.vhd
......@@ -193,8 +195,8 @@ test_bench_files =
tb/vhdl/tb_dp_folder.vhd
tb/vhdl/tb_dp_switch.vhd
tb/vhdl/tb_tb_dp_block_gen.vhd
tb/vhdl/tb_tb_dp_block_gen_arr.vhd
tb/vhdl/tb_tb_dp_bsn_align.vhd
tb/vhdl/tb_tb_dp_concat.vhd
tb/vhdl/tb_tb_dp_demux.vhd
......@@ -233,6 +235,7 @@ regression_test_vhdl =
tb/vhdl/tb_dp_shiftreg.vhd
tb/vhdl/tb_tb_dp_block_gen.vhd
tb/vhdl/tb_tb_dp_block_gen_arr.vhd
tb/vhdl/tb_tb_dp_bsn_align.vhd
tb/vhdl/tb_tb_dp_concat.vhd
tb/vhdl/tb_tb_dp_demux.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- 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 : Generate the sosi control for a block of data based on the
-- input valid
-- Description:
-- When enabled a block of g_nof_data_per_block words is output via
-- src_out_arr under flow control by the input valid. The input valid is
-- taken from snk_in_arr(0). Therefore all input streams in the snk_in_arr
-- must have the same sosi ctrl and info fields, such that the valid from
-- snk_in_arr(0) is sufficient. Only the data, re, im in the snk_in_arr()
-- differs.
--
-- 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
-- g_nof_data_per_block for the output sop and eop, and using
-- g_nof_blk_per_sync for the output sync.
--
-- The first active input valid starts the dp_block_gen_arr. The first output
-- block will have an output sync and every g_nof_blk_per_sync there is
-- another output sync. Each output block is marked by output sop and output
-- eop. The output sop also marks the output BSN. The output BSN is generated
-- such that it increments for every block and that it restarts at 0 at every
-- output sync.
--
-- g_use_input_sync:
-- When g_use_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
-- sync. When g_use_input_sync=TRUE then the block output for a new sync
-- 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 *
-- g_nof_data_per_block should match the number of input valids in an input
-- sync interval.
--
-- g_use_input_bsn_at_sync:
-- When g_use_input_bsn_at_sync=FALSE then all output blocks will count the
-- local BSN that restarts at 0 for every new output sync interval. When
-- 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
-- is useful to preserve the longer term timestamp information that may be
-- carried by the input BSN.
--
-- Remarks:
-- . No siso flow control, although enable could be used as siso.xon
-- . Only the bsn info field is supported, the other info fields (channel,
-- empty and err) are output as 0.
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_block_gen_arr IS
GENERIC (
g_nof_streams : POSITIVE := 1;
g_nof_data_per_block : POSITIVE := 1; -- nof data per block
g_nof_blk_per_sync : POSITIVE := 8;
g_use_input_sync : BOOLEAN := FALSE;
g_use_input_bsn_at_sync : BOOLEAN := FALSE
);
PORT (
rst : IN STD_LOGIC;
clk : IN STD_LOGIC;
-- Streaming sink
snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Streaming source
src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Control
enable : IN STD_LOGIC := '1' -- can connect via MM or could also connect to a src_in.xon
);
END dp_block_gen_arr;
ARCHITECTURE rtl OF dp_block_gen_arr IS
TYPE t_state IS (s_sop, s_data, s_eop);
TYPE t_reg IS RECORD -- local registers
state : t_state;
data_cnt : NATURAL RANGE 0 TO g_nof_data_per_block;
blk_cnt : NATURAL RANGE 0 TO g_nof_blk_per_sync;
src_out : t_dp_sosi;
END RECORD;
CONSTANT c_reg_rst : t_reg := (s_sop, 0, 0, c_dp_sosi_rst);
SIGNAL snk_in : t_dp_sosi;
SIGNAL nxt_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
-- Define the local registers in t_reg record
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
BEGIN
p_clk : PROCESS(rst, clk)
BEGIN
IF rst='1' THEN
r <= c_reg_rst;
src_out_arr <= (OTHERS=>c_dp_sosi_rst);
ELSIF rising_edge(clk) THEN
r <= nxt_r;
src_out_arr <= nxt_src_out_arr;
END IF;
END PROCESS;
-- 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);
-- 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, snk_in)
BEGIN
nxt_r <= r;
-- default set the output ctrl to '0'
nxt_r.src_out.valid <= '0';
nxt_r.src_out.sop <= '0';
nxt_r.src_out.eop <= '0';
nxt_r.src_out.sync <= '0';
CASE r.state IS
WHEN s_sop =>
nxt_r.data_cnt <= 0; -- For clarity init data count to 0 (because it will become 1 anyway at sop)
IF enable='0' THEN -- Check enable in state s_sop to ensure that disable cannot happen during a block
nxt_r.blk_cnt <= 0; -- If disabled then reset block generator and remain in this state
ELSE -- Enabled block generator
IF snk_in.valid='1' THEN -- Once enabled the complete block will be output dependent on the input valid
-- maintain blk_cnt for output sync interval, the blk_cnt is the local bsn that wraps at every sync
IF r.blk_cnt>=g_nof_blk_per_sync-1 THEN
nxt_r.blk_cnt <= 0;
ELSE
nxt_r.blk_cnt <= r.blk_cnt+1;
END IF;
-- create local sync
IF r.blk_cnt=0 THEN -- output sync starts at first input valid
nxt_r.src_out.sync <= '1'; -- output sync for this block
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.sop <= '1';
IF g_nof_data_per_block=1 THEN
nxt_r.src_out.eop <= '1'; -- single word block
ELSE
nxt_r.data_cnt <= 1; -- start of multi word block
nxt_r.state <= s_data;
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 g_use_input_sync=TRUE THEN
IF r.blk_cnt=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.sop <= '0';
nxt_r.src_out.eop <= '0';
nxt_r.src_out.sync <= '0';
nxt_r.blk_cnt <= 0; -- restart blk_cnt
nxt_r.state <= s_sop; -- remain in this state and wait for snk_in.sync
END IF;
END IF;
END IF;
END IF;
END IF;
WHEN s_data =>
IF snk_in.valid='1' THEN
nxt_r.data_cnt <= r.data_cnt+1;
nxt_r.src_out.valid <= '1';
IF r.data_cnt=g_nof_data_per_block-2 THEN
nxt_r.state <= s_eop;
END IF;
END IF;
WHEN OTHERS => -- s_eop
IF snk_in.valid='1' THEN
nxt_r.src_out.valid <= '1';
nxt_r.src_out.eop <= '1';
nxt_r.state <= s_sop;
END IF;
END CASE;
END PROCESS;
END rtl;
......@@ -40,8 +40,8 @@ ENTITY tb_dp_block_gen IS
GENERIC (
g_use_src_in : BOOLEAN := FALSE;
g_nof_data_per_block : NATURAL := 11;
g_nof_blk_per_sync : NATURAL := 1;
g_enable : t_dp_flow_control_enum := e_active; -- always e_active or e_pulse block generator enable
g_nof_blk_per_sync : NATURAL := 5;
g_enable : t_dp_flow_control_enum := e_pulse; -- always e_active or e_pulse block generator enable
g_out_ready : t_dp_flow_control_enum := e_active; -- always e_active, e_random or e_pulse flow control
g_nof_repeat : NATURAL := 100
);
......@@ -190,7 +190,9 @@ BEGIN
g_empty => 1,
g_channel => 2,
g_error => 3,
g_bsn => c_bsn_init
g_bsn => c_bsn_init,
g_preserve_sync => false,
g_preserve_bsn => false
)
PORT MAP (
rst => rst,
......
-------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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: Verify dp_block_gen_arr
-- Description:
-- Usage:
-- > as 10
-- > run -all -- signal tb_end will stop the simulation by stopping the clk
-- Observe out_sosi in wave window
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE dp_lib.tb_dp_pkg.ALL;
ENTITY tb_dp_block_gen_arr IS
GENERIC (
g_nof_streams : POSITIVE := 1;
g_nof_data_per_block : POSITIVE := 11;
g_nof_blk_per_sync : POSITIVE := 8;
g_use_input_sync : BOOLEAN := FALSE;
g_use_input_bsn_at_sync : BOOLEAN := TRUE;
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_nof_repeat : NATURAL := 1000
);
END tb_dp_block_gen_arr;
ARCHITECTURE tb OF tb_dp_block_gen_arr IS
CONSTANT c_pulse_period : NATURAL := 5;
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_bsn_init : NATURAL := 3;
CONSTANT c_block_bsn_max : NATURAL := g_nof_blk_per_sync-1;
SIGNAL tb_input_end : STD_LOGIC := '0';
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL sl1 : STD_LOGIC := '1';
SIGNAL enable : STD_LOGIC;
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 in_sosi : t_dp_sosi;
SIGNAL out_sosi : t_dp_sosi;
SIGNAL prev_out_sosi : t_dp_sosi;
SIGNAL out_gap : STD_LOGIC := '0';
SIGNAL hold_sop : STD_LOGIC := '0';
SIGNAL exp_size : NATURAL := g_nof_data_per_block;
SIGNAL cnt_size : NATURAL := 0;
SIGNAL verify_en : STD_LOGIC := '0';
SIGNAL verify_bsn_en : STD_LOGIC := '0';
SIGNAL verify_done : STD_LOGIC := '0';
SIGNAL verify_valid : STD_LOGIC := '0';
SIGNAL verify_sop : STD_LOGIC := '0';
SIGNAL verify_eop : STD_LOGIC := '0';
BEGIN
clk <= (NOT clk) OR tb_end AFTER clk_period/2;
rst <= '1', '0' AFTER clk_period*7;
------------------------------------------------------------------------------
-- STIMULI
------------------------------------------------------------------------------
p_enable : PROCESS
VARIABLE vI : NATURAL := 0;
BEGIN
enable <= '0';
proc_common_wait_until_low(clk, rst);
proc_common_wait_some_cycles(clk, 5);
WHILE tb_input_end='0' LOOP
enable <= '1';
proc_common_wait_some_cycles(clk, 1);
IF g_enable=e_pulse THEN
IF vI MOD c_pulse_period=0 THEN
enable <= '0';
END IF;
END IF;
proc_common_wait_some_cycles(clk, c_nof_valid_per_enable);
vI := vI + 1;
END LOOP;
enable <= '0';
-- End of stimuli
proc_common_wait_some_cycles(clk, 100);
proc_common_gen_pulse(clk, verify_done);
proc_common_wait_some_cycles(clk, 10);
tb_end <= '1';
WAIT;
END PROCESS;
-- input data
u_dp_stream_stimuli : ENTITY work.dp_stream_stimuli
GENERIC MAP (
g_flow_control => g_flow_control, -- always active, random or pulse flow control
-- initializations
g_sync_period => g_nof_blk_per_sync,
g_sync_offset => 0,
g_data_init => 0,
g_bsn_init => TO_DP_BSN(c_bsn_init),
g_err_init => 0,
g_channel_init => 0,
-- specific
g_in_dat_w => 32,
g_nof_repeat => g_nof_repeat,
g_pkt_len => g_nof_data_per_block,
g_pkt_gap => 0
)
PORT MAP (
rst => rst,
clk => clk,
-- Generate stimuli
src_out => in_sosi,
-- End of stimuli
last_snk_in => OPEN, -- expected verify_snk_in after end of stimuli
last_snk_in_evt => OPEN, -- trigger verify to verify the last_snk_in
tb_end => tb_input_end -- signal end of tb as far as this dp_stream_stimuli is concerned
);
-- Use same stimuli for all streams
in_sosi_arr <= (OTHERS=>in_sosi);
------------------------------------------------------------------------------
-- VERIFICATION
------------------------------------------------------------------------------
verify_en <= '1';
p_verify_bsn : PROCESS
BEGIN
verify_bsn_en <= '0';
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
IF g_use_input_sync=TRUE THEN
proc_common_wait_until_hi_lo(clk, out_sosi.sync); -- if necessary also wait for first sync
END IF;
WHILE enable='1' LOOP
verify_bsn_en <= '1';
WAIT UNTIL rising_edge(clk);
END LOOP;
END PROCESS;
-- Verify stream 0
out_sosi <= out_sosi_arr(0);
-- Verify that the stimuli have been applied at all
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_eop <= '1' WHEN out_sosi.eop='1' AND rising_edge(clk);
proc_dp_verify_value("out_sosi.valid", clk, verify_done, sl1, verify_valid);
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);
-- 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
gen_use_input_bsn_at_sync : IF g_use_input_bsn_at_sync=TRUE GENERATE
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
END GENERATE;
gen_use_local_bsn_at_sync : IF g_use_input_bsn_at_sync=FALSE GENERATE
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
END GENERATE;
-- 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_block_size(exp_size, clk, out_sosi.valid, out_sosi.sop, out_sosi.eop, cnt_size);
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
u_dut: ENTITY work.dp_block_gen_arr
GENERIC MAP (
g_nof_streams => g_nof_streams,
g_nof_data_per_block => g_nof_data_per_block,
g_nof_blk_per_sync => g_nof_blk_per_sync,
g_use_input_sync => g_use_input_sync,
g_use_input_bsn_at_sync => g_use_input_bsn_at_sync
)
PORT MAP (
rst => rst,
clk => clk,
-- Streaming sink
snk_in_arr => in_sosi_arr,
-- Streaming source
src_out_arr => out_sosi_arr,
-- MM control
enable => enable
);
END tb;
-------------------------------------------------------------------------------
--
-- Copyright (C) 2016
-- 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: Multi test bench for dp_block_gen_arr
-- Usage:
-- > as 3
-- > run -all
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE work.tb_dp_pkg.ALL;
ENTITY tb_tb_dp_block_gen_arr IS
END tb_tb_dp_block_gen_arr;
ARCHITECTURE tb OF tb_tb_dp_block_gen_arr IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
BEGIN
-- g_nof_streams : POSITIVE := 1;
-- g_nof_data_per_block : POSITIVE := 11;
-- g_nof_blk_per_sync : POSITIVE := 8;
-- g_use_input_sync : BOOLEAN := FALSE;
-- g_use_input_bsn_at_sync : BOOLEAN := FALSE;
-- 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_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_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, FALSE, 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_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_rnd_input_sync : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 9, TRUE, FALSE, e_pulse, e_random, 300);
u_rnd_input_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 5, FALSE, TRUE, e_pulse, e_random, 300);
u_rnd_input_sync_bsn : ENTITY work.tb_dp_block_gen_arr GENERIC MAP (1, 11, 8, TRUE, TRUE, e_pulse, e_random, 300);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment