From 4f4ab1cf134d1a5200a87888d32243de1222a2d8 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Wed, 14 Jul 2021 11:11:27 +0200
Subject: [PATCH] Implemented (tb_)tb_dp_block_validate_length

---
 libraries/base/dp/hdllib.cfg                  |   2 +
 .../dp/src/vhdl/dp_block_validate_length.vhd  |   5 +-
 .../tb/vhdl/tb_dp_block_validate_length.vhd   | 123 ++++++++++--------
 .../vhdl/tb_tb_dp_block_validate_length.vhd   |  56 ++++++++
 4 files changed, 126 insertions(+), 60 deletions(-)
 create mode 100644 libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_length.vhd

diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 7d2c487626..521d6753de 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -274,6 +274,7 @@ test_bench_files =
     
 
     tb/vhdl/tb_tb_dp_block_select.vhd
+    tb/vhdl/tb_tb_dp_block_validate_length.vhd
     tb/vhdl/tb_tb_dp_block_reshape.vhd
     tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
     tb/vhdl/tb_tb_dp_block_gen.vhd
@@ -339,6 +340,7 @@ regression_test_vhdl =
     tb/vhdl/tb_mms_dp_bsn_source_v2.vhd
     
     tb/vhdl/tb_tb_dp_block_select.vhd
+    tb/vhdl/tb_tb_dp_block_validate_length.vhd
     tb/vhdl/tb_tb_dp_block_reshape.vhd
     tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
     tb/vhdl/tb_tb_dp_block_gen.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_length.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_length.vhd
index 44e5bf03de..ff4f40a6ca 100644
--- a/libraries/base/dp/src/vhdl/dp_block_validate_length.vhd
+++ b/libraries/base/dp/src/vhdl/dp_block_validate_length.vhd
@@ -103,8 +103,7 @@ BEGIN
     block_sosi       <= snk_in;
     IF snk_in.valid='1' THEN
       -- Set output eop, info @ eop gets lost if g_expected_length < actual block size
-      IF NOT(snk_in.eop = '1' AND cnt = g_expected_length-1) THEN
-        block_sosi.eop           <= '1';
+      IF snk_in.eop = '1' XOR cnt = g_expected_length-1 THEN
         block_sosi.err(g_err_bi) <= '1';
       END IF;
         
@@ -112,7 +111,7 @@ BEGIN
         block_sosi.eop   <= '1';
       END IF;
 
-      IF cnt > g_expected_length THEN
+      IF cnt > g_expected_length-1 THEN
         block_sosi <= c_dp_sosi_rst;
       END IF;
     END IF;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_length.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_length.vhd
index d0b6a19fbb..2ddb5db411 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_length.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_length.vhd
@@ -1,37 +1,29 @@
 -------------------------------------------------------------------------------
 --
--- Copyright (C) 2018
+-- Copyright 2021
 -- 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.
+-- 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
 --
--- 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.
+--     http://www.apache.org/licenses/LICENSE-2.0
 --
--- You should have received a copy of the GNU General Public License
--- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-- 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:
---   Eric Kooistra, 26 Apr 2018
+-------------------------------------------------------------------------------
+-- Author: R vd Walle
 -- Purpose:
--- . Test bench for dp_block_resize.
+-- Test bench for dp_block_validate_length.
 -- Description:
---   Block diagram:
---
---    stimuli --> dp_block_resize -- > verify
---   
--- Remark:
--- . Pipelining and flow control are already covered by tb_dp_pipeline.vhd.
---   
+-- Verifies the output sosi of the DUT with the expected sosi.   
 -- Usage:
 -- . as 5
 -- . run -all
@@ -49,8 +41,9 @@ USE work.tb_dp_pkg.ALL;
 ENTITY tb_dp_block_validate_length IS
   GENERIC (
     g_nof_blocks_per_sync  : NATURAL := 5;
-    g_index_lo             : NATURAL := 0;
-    g_expected_length             : NATURAL := 3
+    g_nof_data_per_blk     : NATURAL := 9; 
+    g_expected_length      : NATURAL := 3;
+    g_err_bi               : NATURAL := 3
   );
 END tb_dp_block_validate_length;
 
@@ -65,7 +58,7 @@ ARCHITECTURE tb OF tb_dp_block_validate_length IS
   CONSTANT c_dut_pipeline             : NATURAL := 1;
   CONSTANT c_nof_sync                 : NATURAL := 5;
   CONSTANT c_gap_size                 : NATURAL := 4;
-  CONSTANT c_nof_data_per_blk         : NATURAL := 9; 
+  CONSTANT c_exp_err                  : STD_LOGIC_VECTOR(c_dp_stream_error_w-1 DOWNTO 0) := TO_UVEC(2**g_err_bi, c_dp_stream_error_w);
   
   SIGNAL clk            : STD_LOGIC := '1';
   SIGNAL rst            : STD_LOGIC := '1';
@@ -74,14 +67,13 @@ ARCHITECTURE tb OF tb_dp_block_validate_length IS
   SIGNAL stimuli_end         : STD_LOGIC;
   SIGNAL stimuli_sosi        : t_dp_sosi;
   SIGNAL stimuli_siso        : t_dp_siso;
-  SIGNAL stimuli_blk_cnt_reg : NATURAL;
-  SIGNAL stimuli_blk_cnt     : NATURAL;
+  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_blk_cnt   : NATURAL;
+  SIGNAL reference_cnt       : NATURAL;
   SIGNAL reference_sosi      : t_dp_sosi;
   SIGNAL reference_siso      : t_dp_siso := c_dp_siso_rdy;
-  SIGNAL sync_sosi           : t_dp_sosi;
   
 BEGIN
   
@@ -100,8 +92,10 @@ BEGIN
   GENERIC MAP (
     g_sync_period => g_nof_blocks_per_sync,
     g_nof_repeat  => g_nof_blocks_per_sync * c_nof_sync,
-    g_pkt_len     => c_nof_data_per_blk,
-    g_pkt_gap     => c_gap_size
+    g_pkt_len     => g_nof_data_per_blk,
+    g_pkt_gap     => c_gap_size,
+    g_err_init    => 0,
+    g_err_incr    => 0
   )
   PORT MAP (
     rst               => rst,
@@ -118,8 +112,9 @@ BEGIN
   ------------------------------------------------------------------------------
   -- DUT
   ------------------------------------------------------------------------------     
-  u_select : ENTITY work.dp_block_validate_length
+  u_dut : ENTITY work.dp_block_validate_length
   GENERIC MAP (
+    g_err_bi           => g_err_bi,
     g_expected_length  => g_expected_length
   )
   PORT MAP (
@@ -153,36 +148,50 @@ BEGIN
     src_out     => reference_sosi 
   );
   
-  stimuli_blk_cnt_reg <= stimuli_blk_cnt WHEN rising_edge(clk);
-  stimuli_blk_cnt <= 0                       WHEN stimuli_sosi.sync='1' ELSE
-                     stimuli_blk_cnt_reg + 1 WHEN stimuli_sosi.sop='1' ELSE
-                     stimuli_blk_cnt_reg;
+  stimuli_cnt_reg <= stimuli_cnt WHEN rising_edge(clk);
+  stimuli_cnt     <= 0           WHEN stimuli_sosi.sop='1' ELSE
+             stimuli_cnt_reg + 1 WHEN stimuli_sosi.valid='1' ELSE
+             stimuli_cnt_reg;
   
-  -- Only support c_dut_pipeline = 0 or 1
-  reference_blk_cnt <= stimuli_blk_cnt WHEN c_dut_pipeline=0 ELSE
-                       stimuli_blk_cnt WHEN rising_edge(clk);
+  reference_cnt <= stimuli_cnt WHEN rising_edge(clk);
                        
-  -- Keep BSN at sync
-  sync_sosi <= reference_sosi WHEN  rising_edge(clk) AND reference_sosi.sync='1';
-  
   p_verify : PROCESS(clk)
   BEGIN
     IF rising_edge(clk) THEN
-      IF reference_sosi.valid='1' THEN
-        IF reference_blk_cnt<=g_expected_length AND reference_blk_cnt < g_nof_blocks_per_sync THEN
-          ---------------------------------------------------------------------
-          -- Selected blocks
-          ---------------------------------------------------------------------
-          -- Direct sosi verification because sync and BSN are not moved when g_index_lo=0
-          ASSERT verify_sosi=reference_sosi REPORT "Wrong selected subsequent blocks" SEVERITY ERROR;
-        ELSE
-          ---------------------------------------------------------------------
-          -- Skipped blocks
-          ---------------------------------------------------------------------
-          ASSERT verify_sosi.sync='0'  REPORT "Wrong skipped sync"  SEVERITY ERROR;
-          ASSERT verify_sosi.valid='0' REPORT "Wrong skipped valid" SEVERITY ERROR;
-          ASSERT verify_sosi.sop='0'   REPORT "Wrong skipped sop"   SEVERITY ERROR;
-          ASSERT verify_sosi.eop='0'   REPORT "Wrong skipped eop"   SEVERITY ERROR;
+      IF reference_sosi.valid = '1' THEN
+        IF g_expected_length = g_nof_data_per_blk THEN -- in sosi should be identical to out sosi
+          ASSERT verify_sosi=reference_sosi REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+
+        ELSIF g_expected_length < g_nof_data_per_blk THEN -- expect an err bit to be set and the block length to be limited to g_expected_length
+          IF reference_cnt < g_expected_length-1 THEN
+            ASSERT verify_sosi=reference_sosi REPORT "Wrong block while reference_cnt < g_expected_length-1" SEVERITY ERROR;
+          ELSIF reference_cnt = g_expected_length-1 THEN
+            ASSERT verify_sosi.sync    = reference_sosi.sync    REPORT "Wrong sync, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.bsn     = reference_sosi.bsn     REPORT "Wrong bsn, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.channel = reference_sosi.channel REPORT "Wrong valid, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.data    = reference_sosi.data    REPORT "Wrong data, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.valid   = reference_sosi.valid   REPORT "Wrong valid, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.sop     = reference_sosi.sop     REPORT "Wrong sop, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.eop     = '1'                    REPORT "Wrong eop, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.err     = c_exp_err              REPORT "Wrong err, while reference_cnt = g_expected_length-1" SEVERITY ERROR; 
+          ELSE -- reference_cnt > g_expected_length-1
+            ASSERT verify_sosi.valid = '0' REPORT "Wrong, valid should be '0' when reference_cnt > g_expected_length-1" SEVERITY ERROR;
+          END IF;
+
+        ELSE -- g_expected_length > g_nof_data_per_blk
+          -- Expected an err bit to be set at eop
+          IF reference_cnt = g_nof_data_per_blk-1 THEN
+            ASSERT verify_sosi.sync    = reference_sosi.sync    REPORT "Wrong sync, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.bsn     = reference_sosi.bsn     REPORT "Wrong bsn, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.channel = reference_sosi.channel REPORT "Wrong valid, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.data    = reference_sosi.data    REPORT "Wrong data, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.valid   = reference_sosi.valid   REPORT "Wrong valid, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.sop     = reference_sosi.sop     REPORT "Wrong sop, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.eop     = reference_sosi.eop     REPORT "Wrong eop, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+            ASSERT verify_sosi.err     = c_exp_err              REPORT "Wrong err, while reference_cnt = g_nof_data_per_blk-1" SEVERITY ERROR; 
+          ELSE
+            ASSERT verify_sosi        = reference_sosi REPORT "Wrong block while g_expected_length > g_nof_data_per_blk" SEVERITY ERROR;
+          END IF;
         END IF;
       END IF;
     END IF;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_length.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_length.vhd
new file mode 100644
index 0000000000..49da01a7ea
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_length.vhd
@@ -0,0 +1,56 @@
+-------------------------------------------------------------------------------
+--
+-- 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_length
+-- Usage:
+-- > as 3
+-- > run -all
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+
+ENTITY tb_tb_dp_block_validate_length IS
+END tb_tb_dp_block_validate_length;
+
+
+ARCHITECTURE tb OF tb_tb_dp_block_validate_length 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;
+  CONSTANT c_exp_length   : NATURAL := 9;
+  CONSTANT c_err_bi       : NATURAL := 3;
+
+BEGIN
+
+--    g_nof_blocks_per_sync  : NATURAL := 5;
+--    g_nof_data_per_blk     : NATURAL := 9; 
+--    g_expected_length      : NATURAL := 3;
+--    g_err_bi               : NATURAL := 3 
+
+  u_equal   : ENTITY work.tb_dp_block_validate_length GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_exp_length,     c_err_bi); -- g_expected_length = g_nof_data_per_blk
+  u_smaller : ENTITY work.tb_dp_block_validate_length GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_exp_length - 3, c_err_bi); -- g_expected_length < g_nof_data_per_blk
+  u_larger  : ENTITY work.tb_dp_block_validate_length GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_exp_length + 3, c_err_bi); -- g_expected_length > g_nof_data_per_blk
+  
+END tb;
-- 
GitLab