Skip to content
Snippets Groups Projects
Commit 5a3079e7 authored by Reinier van der Walle's avatar Reinier van der Walle
Browse files

inital commit of dp_block_validate_bsn_at_sync and the TBs

parent 50895123
No related branches found
No related tags found
1 merge request!124Resolve L2SDP-271
...@@ -31,6 +31,7 @@ synth_files = ...@@ -31,6 +31,7 @@ synth_files =
src/vhdl/dp_pipeline_ready.vhd src/vhdl/dp_pipeline_ready.vhd
src/vhdl/dp_block_resize.vhd src/vhdl/dp_block_resize.vhd
src/vhdl/dp_block_validate_length.vhd src/vhdl/dp_block_validate_length.vhd
src/vhdl/dp_block_validate_bsn_at_sync.vhd
src/vhdl/dp_block_select.vhd src/vhdl/dp_block_select.vhd
src/vhdl/mms_dp_block_select.vhd src/vhdl/mms_dp_block_select.vhd
src/vhdl/dp_force_data_parallel.vhd src/vhdl/dp_force_data_parallel.vhd
...@@ -197,6 +198,7 @@ test_bench_files = ...@@ -197,6 +198,7 @@ test_bench_files =
tb/vhdl/tb_dp_block_select.vhd tb/vhdl/tb_dp_block_select.vhd
tb/vhdl/tb_dp_block_validate_length.vhd tb/vhdl/tb_dp_block_validate_length.vhd
tb/vhdl/tb_dp_block_validate_err.vhd tb/vhdl/tb_dp_block_validate_err.vhd
tb/vhdl/tb_dp_block_validate_bsn_at_sync.vhd
tb/vhdl/tb_dp_block_reshape.vhd tb/vhdl/tb_dp_block_reshape.vhd
tb/vhdl/tb_dp_block_reshape_sync.vhd tb/vhdl/tb_dp_block_reshape_sync.vhd
tb/vhdl/tb_dp_block_gen.vhd tb/vhdl/tb_dp_block_gen.vhd
...@@ -278,6 +280,7 @@ test_bench_files = ...@@ -278,6 +280,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_block_select.vhd tb/vhdl/tb_tb_dp_block_select.vhd
tb/vhdl/tb_tb_dp_block_validate_length.vhd tb/vhdl/tb_tb_dp_block_validate_length.vhd
tb/vhdl/tb_tb_dp_block_validate_err.vhd tb/vhdl/tb_tb_dp_block_validate_err.vhd
tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd
tb/vhdl/tb_tb_dp_block_reshape.vhd tb/vhdl/tb_tb_dp_block_reshape.vhd
tb/vhdl/tb_tb_dp_block_reshape_sync.vhd tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
tb/vhdl/tb_tb_dp_block_gen.vhd tb/vhdl/tb_tb_dp_block_gen.vhd
...@@ -345,6 +348,7 @@ regression_test_vhdl = ...@@ -345,6 +348,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_block_select.vhd tb/vhdl/tb_tb_dp_block_select.vhd
tb/vhdl/tb_tb_dp_block_validate_length.vhd tb/vhdl/tb_tb_dp_block_validate_length.vhd
tb/vhdl/tb_tb_dp_block_validate_err.vhd tb/vhdl/tb_tb_dp_block_validate_err.vhd
tb/vhdl/tb_tb_dp_block_validate_bsn_at_sync.vhd
tb/vhdl/tb_tb_dp_block_reshape.vhd tb/vhdl/tb_tb_dp_block_reshape.vhd
tb/vhdl/tb_tb_dp_block_reshape_sync.vhd tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
tb/vhdl/tb_tb_dp_block_gen.vhd tb/vhdl/tb_tb_dp_block_gen.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author: R vd Walle
-- Purpose:
-- The dp_block_validate_bsn_at_sync.vhd checks whether the remote block
-- sequence number (BSN) at the start of an in_sosi.sync interval is equal to
-- the local BSN at start of the local bs_sosi.sync interval.
-- Description:
-- The dp_block_validate_bsn_at_sync.vhd holds the local BSN that it gets at
-- each bs_sosi.sync and uses that when it receives the remote BSN at the
-- in_sosi.sync. The dp_validate_bsn_at_sync.vhd compares the entire
-- g_bsn_w bit BSN. If the remote BSN at in_sosi.sync and the local BSN at
-- bs_sosi.sync are:
-- . Not equal, then discard all subsequent in_sosi blocks until the next
-- in_sosi .sync
-- . Equal, then pass on all subsequent in_sosi blocks until the next
-- in_sosi.sync
-- Only packets with channel = g_check_channel are checked. Other packets are
-- just passed on.
-- The dp_block_validate_bsn_at_sync.vhd maintains a total number of
-- in_sosi.sync counter and a number of discarded sync intervals counter, that
-- can be read via the MM interface.
-- Remarks:
-------------------------------------------------------------------------------
-- REGMAP
-------------------------------------------------------------------------------
-- wi Bits R/W Name Default
-- =====================================================================
-- 0 [31..0] RO nof_sync_discarded 0x0
-- 1 [31..0] RO nof_sync 0x0
-- =====================================================================
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.all;
USE work.dp_stream_pkg.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
ENTITY dp_block_validate_bsn_at_sync IS
GENERIC (
g_check_channel : NATURAL := 0;
g_bsn_w : NATURAL := c_dp_stream_bsn_w
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
-- ST sink
in_sosi : IN t_dp_sosi;
bs_sosi : IN t_dp_sosi;
-- ST source
out_sosi : OUT t_dp_sosi;
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
reg_mosi : IN t_mem_mosi := c_mem_mosi_rst;
reg_miso : OUT t_mem_miso := c_mem_miso_rst
);
END dp_block_validate_bsn_at_sync;
ARCHITECTURE rtl OF dp_block_validate_bsn_at_sync IS
-- Define the actual size of the MM slave register
CONSTANT c_mm_reg : t_c_mem := (latency => 1,
adr_w => ceil_log2(2),
dat_w => c_word_w, -- Use MM bus data width = c_word_w = 32 for all MM registers
nof_dat => 2, -- total counter + discarded counter
init_sl => '0');
-- Registers in st_clk domain
SIGNAL count_reg : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
SIGNAL cnt_clr : STD_LOGIC;
SIGNAL cnt_sync : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL cnt_sync_en : STD_LOGIC;
SIGNAL cnt_disc : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL cnt_disc_en : STD_LOGIC;
SIGNAL out_valid : STD_LOGIC;
SIGNAL bsn_ok : STD_LOGIC;
SIGNAL bsn_ok_reg : STD_LOGIC;
SIGNAL bsn_at_sync : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL bsn_at_sync_reg : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0);
SIGNAL block_sosi : t_dp_sosi;
BEGIN
u_common_spulse_cnt_clr : ENTITY common_lib.common_spulse
PORT MAP (
in_rst => mm_rst,
in_clk => mm_clk,
in_pulse => reg_mosi.rd,
in_busy => OPEN,
out_rst => dp_rst,
out_clk => dp_clk,
out_pulse => cnt_clr
);
-- sync counter
u_blk_counter : ENTITY common_lib.common_counter
GENERIC MAP (
g_width => c_word_w
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
cnt_clr => cnt_clr,
cnt_en => in_sosi.sync,
count => cnt_sync
);
-- discarded counter
cnt_disc_en <= '1' WHEN in_sosi.sync = '1' AND bsn_ok = '0' ELSE '0';
u_disc_counter : ENTITY common_lib.common_counter
GENERIC MAP (
g_width => c_word_w
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
cnt_clr => cnt_clr,
cnt_en => cnt_disc_en,
count => cnt_disc
);
-- Register mapping
count_reg( c_word_w - 1 DOWNTO 0 ) <= cnt_disc;
count_reg(2*c_word_w - 1 DOWNTO c_word_w ) <= cnt_sync;
u_reg : ENTITY common_lib.common_reg_r_w_dc
GENERIC MAP (
g_cross_clock_domain => TRUE,
g_readback => FALSE,
g_reg => c_mm_reg
)
PORT MAP (
-- Clocks and reset
mm_rst => mm_rst,
mm_clk => mm_clk,
st_rst => dp_rst,
st_clk => dp_clk,
-- Memory Mapped Slave in mm_clk domain
sla_in => reg_mosi,
sla_out => reg_miso,
-- MM registers in st_clk domain
reg_wr_arr => OPEN,
reg_rd_arr => OPEN,
in_reg => count_reg, -- read only
out_reg => OPEN -- no write
);
bsn_at_sync <= bs_sosi.bsn WHEN bs_sosi.sync = '1' ELSE bsn_at_sync_reg;
bsn_ok <= bsn_ok_reg WHEN in_sosi.sync = '0' ELSE '1' WHEN in_sosi.bsn = bsn_at_sync ELSE '0';
out_valid <= bsn_ok WHEN TO_UINT(in_sosi.channel) = g_check_channel ELSE '1';
p_dp_clk : PROCESS(dp_rst, dp_clk)
BEGIN
IF dp_rst='1' THEN
bsn_ok_reg <= '1';
bsn_at_sync_reg <= (OTHERS => '0');
ELSIF rising_edge(dp_clk) THEN
bsn_ok_reg <= bsn_ok;
bsn_at_sync_reg <= bsn_at_sync;
END IF;
END PROCESS;
p_sosi : PROCESS(in_sosi, out_valid)
BEGIN
block_sosi <= in_sosi;
block_sosi.valid <= in_sosi.valid AND out_valid;
block_sosi.sop <= in_sosi.sop AND out_valid;
block_sosi.eop <= in_sosi.eop AND out_valid;
block_sosi.sync <= in_sosi.sync AND out_valid;
END PROCESS;
u_pipeline : ENTITY work.dp_pipeline
GENERIC MAP (
g_pipeline => 1 -- 0 for wires, > 0 for registers,
)
PORT MAP (
rst => dp_rst,
clk => dp_clk,
-- ST sink
snk_in => block_sosi,
-- ST source
src_out => out_sosi
);
END rtl;
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author: R vd Walle
-- Purpose:
-- Test bench for dp_block_validate_bsn_at_sync.
-- Description:
-- Verifies the output sosi of the DUT with the expected sosi.
-- The TB also reads the register values via MM and verifies them against the
-- expected values.
-- Usage:
-- . as 5
-- . run -all
LIBRARY IEEE, common_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.tb_common_mem_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE common_lib.common_lfsr_sequences_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE work.tb_dp_pkg.ALL;
ENTITY tb_dp_block_validate_bsn_at_sync IS
GENERIC (
g_nof_blocks_per_sync : NATURAL := 5;
g_nof_data_per_blk : NATURAL := 6;
g_bsn_init : NATURAL := 7; -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync,
g_check_channel : NATURAL := 8 -- channel to check, the channel field is a counter value.
);
END tb_dp_block_validate_bsn_at_sync;
ARCHITECTURE tb OF tb_dp_block_validate_bsn_at_sync IS
------------------------------------------------------------------------------
-- Clock & reset
------------------------------------------------------------------------------
CONSTANT c_dp_clk_period : TIME := 5 ns;
CONSTANT c_mm_clk_period : TIME := 10 ns;
CONSTANT c_dut_pipeline : NATURAL := 1;
CONSTANT c_gap_size : NATURAL := 4;
CONSTANT c_nof_sync : NATURAL := 5;
CONSTANT c_nof_blk : NATURAL := g_nof_blocks_per_sync * c_nof_sync;
SIGNAL dp_clk : STD_LOGIC := '1';
SIGNAL mm_clk : STD_LOGIC := '1';
SIGNAL rst : STD_LOGIC := '1';
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL stimuli_end : STD_LOGIC;
SIGNAL stimuli_sosi : t_dp_sosi;
SIGNAL stimuli_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL bs_sosi : t_dp_sosi;
SIGNAL bs_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL stimuli_cnt_reg : NATURAL;
SIGNAL stimuli_cnt : NATURAL;
SIGNAL verify_sosi : t_dp_sosi;
SIGNAL verify_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL reference_cnt : NATURAL;
SIGNAL reference_cnt_reg : NATURAL;
SIGNAL reference_sosi : t_dp_sosi;
SIGNAL reference_siso : t_dp_siso := c_dp_siso_rdy;
SIGNAL reg_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL reg_miso : t_mem_miso := c_mem_miso_rst;
BEGIN
------------------------------------------------------------------------------
-- Clock & reset
------------------------------------------------------------------------------
dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2;
mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
rst <= '1', '0' AFTER c_dp_clk_period*7;
------------------------------------------------------------------------------
-- Stimuli:
------------------------------------------------------------------------------
-- Generate in_sosi with data frames
u_stimuli_in : ENTITY work.dp_stream_stimuli
GENERIC MAP (
g_sync_period => g_nof_blocks_per_sync,
g_nof_repeat => c_nof_blk,
g_pkt_len => g_nof_data_per_blk,
g_pkt_gap => c_gap_size,
g_channel_init=> 0,
g_bsn_init => TO_DP_BSN(0)
)
PORT MAP (
rst => rst,
clk => dp_clk,
-- Generate stimuli
src_in => stimuli_siso,
src_out => stimuli_sosi,
-- End of stimuli
tb_end => stimuli_end
);
-- Generate bs_sosi with data frames
u_stimuli_bs : ENTITY work.dp_stream_stimuli
GENERIC MAP (
g_sync_period => g_nof_blocks_per_sync,
g_nof_repeat => c_nof_blk,
g_pkt_len => g_nof_data_per_blk,
g_pkt_gap => c_gap_size,
g_channel_init=> 0,
g_bsn_init => TO_DP_BSN(g_bsn_init)
)
PORT MAP (
rst => rst,
clk => dp_clk,
-- Generate stimuli
src_in => bs_siso,
src_out => bs_sosi,
-- End of stimuli
tb_end => OPEN
);
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
u_dut : ENTITY work.dp_block_validate_bsn_at_sync
GENERIC MAP (
g_check_channel => g_check_channel
)
PORT MAP (
dp_rst => rst,
dp_clk => dp_clk,
mm_rst => rst,
mm_clk => mm_clk,
-- ST sink
in_sosi => stimuli_sosi,
bs_sosi => bs_sosi,
-- ST source
out_sosi => verify_sosi,
reg_mosi => reg_mosi,
reg_miso => reg_miso
);
------------------------------------------------------------------------------
-- Verification
------------------------------------------------------------------------------
u_pipeline : ENTITY work.dp_pipeline
GENERIC MAP (
g_pipeline => c_dut_pipeline
)
PORT MAP (
rst => rst,
clk => dp_clk,
-- ST sink
snk_out => OPEN,
snk_in => stimuli_sosi,
-- ST source
src_in => reference_siso,
src_out => reference_sosi
);
reference_cnt_reg <= reference_cnt WHEN rising_edge(dp_clk);
reference_cnt <= reference_cnt_reg + 1 WHEN reference_sosi.sync='1' ELSE reference_cnt_reg;
p_verify : PROCESS(dp_clk)
VARIABLE v_valid_blk : BOOLEAN := TRUE;
BEGIN
IF rising_edge(dp_clk) THEN
IF reference_sosi.sop = '1' THEN
IF g_bsn_init >= g_nof_blocks_per_sync AND TO_UINT(reference_sosi.channel) = g_check_channel THEN
v_valid_blk := FALSE;
ELSE
v_valid_blk := TRUE;
END IF;
END IF;
IF v_valid_blk THEN -- we expect a block
ASSERT verify_sosi = reference_sosi REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
ELSE -- we expect no block
ASSERT verify_sosi.valid = '0' REPORT "Wrong, valid is not '0' which is unexpected." SEVERITY ERROR;
ASSERT verify_sosi.sop = '0' REPORT "Wrong, sop is not '0' which is unexpected." SEVERITY ERROR;
ASSERT verify_sosi.eop = '0' REPORT "Wrong, eop is not '0' which is unexpected." SEVERITY ERROR;
END IF;
END IF;
END PROCESS;
p_verify_mm : PROCESS
BEGIN
proc_common_wait_until_lo_hi(dp_clk, stimuli_end);
proc_common_wait_some_cycles(dp_clk, c_dut_pipeline + 1);
proc_common_wait_some_cycles(mm_clk, 1);
proc_mem_mm_bus_rd(1, mm_clk, reg_miso, reg_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
ASSERT c_nof_sync = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong total sync count" SEVERITY ERROR;
proc_mem_mm_bus_rd(0, mm_clk, reg_miso, reg_mosi);
proc_mem_mm_bus_rd_latency(1, mm_clk);
IF g_bsn_init = g_nof_blocks_per_sync THEN -- should have c_nof_sync discarded sync
ASSERT c_nof_sync = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR;
ELSIF g_bsn_init > g_nof_blocks_per_sync THEN -- should have c_nof_sync -1 discarded sync
ASSERT c_nof_sync-1 = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR;
ELSE -- 0 discarded sync
ASSERT 0 = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong discarded sync count" SEVERITY ERROR;
END IF;
proc_common_wait_some_cycles(dp_clk, 10);
tb_end <= '1';
WAIT;
END PROCESS;
END tb;
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Author: R vd Walle
-- Purpose:
-- Verify multiple variations of tb_dp_block_validate_bsn_at_sync
-- Usage:
-- > as 3
-- > run -all
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY tb_tb_dp_block_validate_bsn_at_sync IS
END tb_tb_dp_block_validate_bsn_at_sync;
ARCHITECTURE tb OF tb_tb_dp_block_validate_bsn_at_sync IS
SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
CONSTANT c_blk_per_sync : NATURAL := 5;
CONSTANT c_data_per_blk : NATURAL := 9;
BEGIN
-- g_nof_blocks_per_sync : NATURAL := 5;
-- g_nof_data_per_blk : NATURAL := 6;
-- g_bsn_init : NATURAL := 7; -- >= g_nof_blocks_per_sync for discarded sync, < g_nof_blocks_per_sync for no discarded sync,
-- g_check_channel : NATURAL := 8 -- channel to check, the channel field is a counter value.
u_smaller : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 0, 8); -- g_bsn_init < g_nof_blocks_per_sync
u_equal : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 5, 8); -- g_bsn_init = g_nof_blocks_per_sync
u_larger : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 8, 8); -- g_bsn_init > g_nof_blocks_per_sync
u_ch_on_sync : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 5, 10); -- g_check_channel MOD c_blk_per_sync = 0,
u_no_ch : ENTITY work.tb_dp_block_validate_bsn_at_sync GENERIC MAP(c_blk_per_sync, c_data_per_blk, 8, 500); -- channel will never reach 500
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