From 8a8ac77e07c789d43a5e27fdd759f1df1e028686 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Wed, 14 Jul 2021 14:29:34 +0200
Subject: [PATCH] inital commit of dp_block_validate_err

---
 .../dp/src/vhdl/dp_block_validate_err.vhd     | 136 ++++++++++++++++++
 1 file changed, 136 insertions(+)
 create mode 100644 libraries/base/dp/src/vhdl/dp_block_validate_err.vhd

diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd
new file mode 100644
index 0000000000..ff4f40a6ca
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd
@@ -0,0 +1,136 @@
+-------------------------------------------------------------------------------
+--
+-- 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:
+--   Validate the length of a DP block.
+-- Description:
+-- The dp_block_validate_length.vhd checks whether the in_sosi block has the 
+-- expected length given by g_expected_length. The block length is defined by 
+-- the number of valid from sop to eop. The tasks of the 
+-- dp_block_validate_length.vhd are:
+-- . Default all in_sosi fields are passed on to the out_sosi.
+-- . If the input block length differs from g_expected_length, then the bit at
+--   bit index g_err_bi in the out_sosi.err field is forced to 1, else the 
+--   out_sosi.err field passes on the in_sosi.err field.
+-- . If the input block length > g_expected_length, then the out_sosi block 
+--   length is restricted to g_expected_length, by inserting an eop and 
+--   discarding the remaining data and eop information from the in_sosi.
+-- Remarks:
+-- - This component supports flow control and was designed by keeping the functional
+--   state registers and the pipeline registers seperate. Therefore the function is 
+--   implemented using combinatorial logic and local state registers to keep its
+--   state. The combinatorial function output preserves the snk_in ready latency and
+--   is pipelined using dp_pipeline to ease timing closure on the output.
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.all;
+USE work.dp_stream_pkg.ALL;
+
+ENTITY dp_block_validate_length IS
+  GENERIC (
+    g_err_bi          : NATURAL := 0;   -- bit index in error field
+    g_expected_length : NATURAL := 255 
+  );
+  PORT (
+    rst          : IN  STD_LOGIC;
+    clk          : IN  STD_LOGIC;
+    -- ST sink
+    snk_out      : OUT t_dp_siso;
+    snk_in       : IN  t_dp_sosi;
+    -- ST source
+    src_in       : IN  t_dp_siso := c_dp_siso_rdy;
+    src_out      : OUT t_dp_sosi
+  );
+END dp_block_validate_length;
+
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.all;
+USE work.dp_stream_pkg.ALL;
+
+ARCHITECTURE rtl OF dp_block_validate_length IS
+
+  SIGNAL cnt_reg      : NATURAL;
+  SIGNAL cnt          : NATURAL;
+  SIGNAL block_sosi   : t_dp_sosi;
+  
+BEGIN
+
+  p_clk : PROCESS(rst, clk)
+  BEGIN
+    IF rst='1' THEN
+      cnt_reg      <= 0;
+    ELSIF rising_edge(clk) THEN
+      cnt_reg      <= cnt;
+    END IF;
+  END PROCESS;
+
+  -- Count valid per block
+  p_cnt : PROCESS(snk_in, cnt_reg)
+  BEGIN
+    cnt <= cnt_reg;
+    IF snk_in.sop='1' THEN
+      cnt <= 0;
+    ELSIF snk_in.valid='1' THEN
+      cnt <= cnt_reg + 1;
+    END IF;
+  END PROCESS;
+
+  -- Resize snk_in combinatorially into block_sosi, so no impact on RL
+  p_block_sosi : PROCESS(snk_in, cnt)
+  BEGIN
+    -- Default keep snk_in info and data fields
+    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 snk_in.eop = '1' XOR cnt = g_expected_length-1 THEN
+        block_sosi.err(g_err_bi) <= '1';
+      END IF;
+        
+      IF cnt = g_expected_length-1 THEN
+        block_sosi.eop   <= '1';
+      END IF;
+
+      IF cnt > g_expected_length-1 THEN
+        block_sosi <= c_dp_sosi_rst;
+      END IF;
+    END IF;
+  END PROCESS;
+
+  -- Register block_sosi to easy timing closure
+  u_pipeline : ENTITY work.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    -- ST sink
+    snk_out      => snk_out,
+    snk_in       => block_sosi,
+    -- ST source
+    src_in       => src_in,
+    src_out      => src_out
+  );
+  
+END rtl;
-- 
GitLab