OpenCores
URL https://opencores.org/ocsvn/dp_pkg/dp_pkg/trunk

Subversion Repositories dp_pkg

[/] [dp_pkg/] [trunk/] [dp_stream_verify.vhd] - Rev 7

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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.
--
-------------------------------------------------------------------------------
 
-- Purpose:
-- . The dp_stream_verify verifies the stream of packets with counter data that
--   are generated by dp_stimuli_st.
-- Description:
--   The component can verify a stream:
--   . The sosi control fields are verified conform the bus specifications
--     eg. considering the RL, no missing eop, etc.
--   . The sosi data fields are verified based on their previous value under
--     the assumption that they contain incrementing data. Whether a field
--     is checked depends on verify_snk_in_enable.
--  
--   The component also checks whether the stream is active at all. A
--   pulse in verify_expected_snk_in_evt triggers the verification of the
--   corresponding field in snk_in using the expected_snk_in as reference.
--
-- Usage:
-- . See tb_dp_example_no_dut for usage example
--
 
LIBRARY IEEE, common_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE common_pkg_lib.common_lfsr_sequences_pkg.ALL;
USE common_pkg_lib.tb_common_pkg.ALL;
USE work.dp_stream_pkg.ALL;
USE work.tb_dp_pkg.ALL;
 
 
ENTITY dp_stream_verify IS
  GENERIC (
    g_instance_nr         : NATURAL := 0;
    -- flow control
    g_random_w            : NATURAL := 14;                       -- use different random width for stimuli and for verify to have different random sequences
    g_pulse_active        : NATURAL := 1;
    g_pulse_period        : NATURAL := 2;
    g_flow_control        : t_dp_flow_control_enum := e_active;  -- always active, random or pulse flow control
    -- initializations
    g_sync_period         : NATURAL := 10;
    g_sync_offset         : NATURAL := 7;
    g_snk_in_cnt_max      : t_dp_sosi_unsigned := c_dp_sosi_unsigned_rst;  -- default 0 is no wrap
    g_snk_in_cnt_gap      : t_dp_sosi_unsigned := c_dp_sosi_unsigned_ones; -- default only accept increment +1
    -- specific
    g_in_dat_w            : NATURAL := 32;
    g_pkt_len             : NATURAL := 16
  );
  PORT (
    rst                        : IN  STD_LOGIC;
    clk                        : IN  STD_LOGIC;
 
    -- Verify data
    snk_out                    : OUT t_dp_siso;
    snk_in                     : IN  t_dp_sosi;
 
    -- During stimuli
    verify_snk_in_enable       : IN  t_dp_sosi_sl;  -- enable to verify that the snk_in fields are incrementing 
 
    -- End of stimuli
    expected_snk_in            : IN  t_dp_sosi;          -- expected snk_in at verify_expected_snk_in_evt
    verify_expected_snk_in_evt : IN  t_dp_sosi_sl   -- trigger to verify the expected_snk_in 
  );
END dp_stream_verify;
 
 
ARCHITECTURE tb OF dp_stream_verify IS
 
  CONSTANT c_rl                       : NATURAL := 1;
  CONSTANT c_no_dut                   : BOOLEAN:= TRUE;
 
  SIGNAL random                     : STD_LOGIC_VECTOR(g_random_w-1 DOWNTO 0) := TO_UVEC(g_instance_nr, g_random_w);  -- use different initialization to have different random sequences per stream
  SIGNAL pulse                      : STD_LOGIC;
  SIGNAL pulse_en                   : STD_LOGIC := '1';
 
  SIGNAL i_snk_out                  : t_dp_siso := c_dp_siso_rdy;
  SIGNAL prev_snk_out               : t_dp_siso;
  SIGNAL hold_snk_in_data           : STD_LOGIC_VECTOR(c_dp_stream_data_w-1 DOWNTO 0);  -- used to hold valid data for verify at verify_expected_snk_in_evt
  SIGNAL snk_in_data                : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
  SIGNAL prev_snk_in                : t_dp_sosi;
 
  SIGNAL hold_snk_in_sop            : STD_LOGIC := '0';
  SIGNAL detected_snk_in_ctrl       : t_dp_sosi_sl := c_dp_sosi_sl_rst;
  SIGNAL verify_snk_in_increment    : t_dp_sosi_sl := c_dp_sosi_sl_rst;
  SIGNAL verify_snk_in_ctrl         : t_dp_sosi_sl := c_dp_sosi_sl_rst;
 
  SIGNAL exp_size                   : NATURAL;
  SIGNAL cnt_size                   : NATURAL;
 
BEGIN
 
  snk_out <= i_snk_out;
 
  ------------------------------------------------------------------------------
  -- STREAM CONTROL
  ------------------------------------------------------------------------------
 
  random <= func_common_random(random) WHEN rising_edge(clk);
 
  proc_common_gen_duty_pulse(g_pulse_active, g_pulse_period, '1', rst, clk, pulse_en, pulse);
 
  i_snk_out.ready <= '1'                 WHEN g_flow_control=e_active  ELSE
                     random(random'HIGH) WHEN g_flow_control=e_random  ELSE
                     pulse               WHEN g_flow_control=e_pulse;
 
  ------------------------------------------------------------------------------
  -- DATA VERIFICATION
  ------------------------------------------------------------------------------  
 
  -- Detect first sync, sop, eop, valid
  detected_snk_in_ctrl.sync  <= '1' WHEN snk_in.sync='1'  AND rising_edge(clk);
  detected_snk_in_ctrl.valid <= '1' WHEN snk_in.valid='1' AND rising_edge(clk);
  detected_snk_in_ctrl.sop   <= '1' WHEN snk_in.sop='1'   AND rising_edge(clk);
  detected_snk_in_ctrl.eop   <= '1' WHEN snk_in.eop='1'   AND rising_edge(clk);
 
  -- Verify that the stimuli have been applied at all so at least one active sosi sync, sop, eop, valid field has been detected
  proc_dp_verify_value("snk_in.sync",             clk, verify_expected_snk_in_evt.sync,    expected_snk_in.sync,    detected_snk_in_ctrl.sync);
  proc_dp_verify_value("snk_in.sop",              clk, verify_expected_snk_in_evt.sop,     expected_snk_in.sop,     detected_snk_in_ctrl.sop);
  proc_dp_verify_value("snk_in.eop",              clk, verify_expected_snk_in_evt.eop,     expected_snk_in.eop,     detected_snk_in_ctrl.eop);
  proc_dp_verify_value("snk_in.valid",            clk, verify_expected_snk_in_evt.valid,   expected_snk_in.valid,   detected_snk_in_ctrl.valid);
 
  -- Verify that the last sosi data, bsn, channel and err fields are correct
  proc_dp_verify_value("snk_in.data",    e_equal, clk, verify_expected_snk_in_evt.data,    expected_snk_in.data,    hold_snk_in_data);
  proc_dp_verify_value("snk_in.bsn",     e_equal, clk, verify_expected_snk_in_evt.bsn,     expected_snk_in.bsn,     snk_in.bsn);
  proc_dp_verify_value("snk_in.channel", e_equal, clk, verify_expected_snk_in_evt.channel, expected_snk_in.channel, snk_in.channel);
  proc_dp_verify_value("snk_in.err",     e_equal, clk, verify_expected_snk_in_evt.err,     expected_snk_in.err,     snk_in.err);
 
  -- Verify that the output is incrementing data, like the input stimuli
  p_verify_snk_in_increment : PROCESS(verify_snk_in_enable, detected_snk_in_ctrl)
  BEGIN
    verify_snk_in_increment         <= verify_snk_in_enable;
    verify_snk_in_increment.data    <= verify_snk_in_enable.data    AND detected_snk_in_ctrl.valid;
    verify_snk_in_increment.re      <= verify_snk_in_enable.re      AND detected_snk_in_ctrl.valid;
    verify_snk_in_increment.im      <= verify_snk_in_enable.im      AND detected_snk_in_ctrl.valid;
    verify_snk_in_increment.bsn     <= verify_snk_in_enable.bsn     AND detected_snk_in_ctrl.sop;
    verify_snk_in_increment.channel <= verify_snk_in_enable.channel AND detected_snk_in_ctrl.sop;
    verify_snk_in_increment.empty   <= verify_snk_in_enable.empty   AND detected_snk_in_ctrl.eop;
    verify_snk_in_increment.err     <= verify_snk_in_enable.err     AND detected_snk_in_ctrl.eop;
  END PROCESS;
 
  proc_dp_verify_data("snk_in.data",    c_rl, g_snk_in_cnt_max.data,    g_snk_in_cnt_gap.data,    clk, verify_snk_in_increment.data,    i_snk_out.ready, snk_in.valid, snk_in.data,    prev_snk_in.data);
  proc_dp_verify_data("snk_in.re",      c_rl, g_snk_in_cnt_max.re,      g_snk_in_cnt_gap.re,      clk, verify_snk_in_increment.re,      i_snk_out.ready, snk_in.valid, snk_in.re,      prev_snk_in.re);
  proc_dp_verify_data("snk_in.im",      c_rl, g_snk_in_cnt_max.im,      g_snk_in_cnt_gap.im,      clk, verify_snk_in_increment.im,      i_snk_out.ready, snk_in.valid, snk_in.im,      prev_snk_in.im);
  proc_dp_verify_data("snk_in.bsn",     c_rl, g_snk_in_cnt_max.bsn,     g_snk_in_cnt_gap.bsn,     clk, verify_snk_in_increment.bsn,     i_snk_out.ready, snk_in.sop,   snk_in.bsn,     prev_snk_in.bsn);
  proc_dp_verify_data("snk_in.channel", c_rl, g_snk_in_cnt_max.channel, g_snk_in_cnt_gap.channel, clk, verify_snk_in_increment.channel, i_snk_out.ready, snk_in.sop,   snk_in.channel, prev_snk_in.channel);
  proc_dp_verify_data("snk_in.empty",   c_rl, g_snk_in_cnt_max.empty,   g_snk_in_cnt_gap.empty,   clk, verify_snk_in_increment.empty,   i_snk_out.ready, snk_in.eop,   snk_in.empty,   prev_snk_in.empty);
  proc_dp_verify_data("snk_in.err",     c_rl, g_snk_in_cnt_max.err,     g_snk_in_cnt_gap.err,     clk, verify_snk_in_increment.err,     i_snk_out.ready, snk_in.eop,   snk_in.err,     prev_snk_in.err);
 
  -- Verify that the snk_in control fields are correct
  p_verify_snk_in_ctrl: PROCESS(snk_in, verify_snk_in_enable)
  BEGIN
    verify_snk_in_ctrl.sync  <= snk_in.sync  AND verify_snk_in_enable.valid AND verify_snk_in_enable.sync;
    verify_snk_in_ctrl.sop   <= snk_in.sop   AND verify_snk_in_enable.valid AND verify_snk_in_enable.sop AND verify_snk_in_enable.eop;
    verify_snk_in_ctrl.eop   <= snk_in.eop   AND verify_snk_in_enable.valid AND verify_snk_in_enable.sop AND verify_snk_in_enable.eop;
    verify_snk_in_ctrl.valid <= snk_in.valid AND verify_snk_in_enable.valid;
  END PROCESS;
 
  -- Verify that the output sync occurs when expected
  proc_dp_verify_sync(g_sync_period, g_sync_offset, clk, detected_snk_in_ctrl.sop, verify_snk_in_ctrl.sync, verify_snk_in_ctrl.sop, snk_in.bsn);
 
  -- Verify output packet ctrl
  proc_dp_verify_sop_and_eop(clk, verify_snk_in_ctrl.valid, verify_snk_in_ctrl.sop, verify_snk_in_ctrl.eop, hold_snk_in_sop);
 
  -- Verify output packet block size
  exp_size <= g_pkt_len;
 
  proc_dp_verify_block_size(exp_size, clk, verify_snk_in_ctrl.valid, verify_snk_in_ctrl.sop, verify_snk_in_ctrl.eop, cnt_size);
 
  -- Verify output ready latency
  proc_dp_verify_valid(clk, detected_snk_in_ctrl.valid, i_snk_out.ready, prev_snk_out.ready, verify_snk_in_ctrl.valid);
 
  ------------------------------------------------------------------------------
  -- Auxiliary
  ------------------------------------------------------------------------------
 
  -- Map to slv to ease monitoring in wave window
  snk_in_data  <= snk_in.data(g_in_dat_w-1 DOWNTO 0);
 
  hold_snk_in_data <= snk_in.data WHEN snk_in.valid='1';
 
END tb;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.