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

Subversion Repositories dp_components

[/] [dp_components/] [trunk/] [tb_dp_latency_adapter.vhd] - Rev 4

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.
--
-------------------------------------------------------------------------------
 
LIBRARY IEEE, common_pkg_lib, dp_pkg_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE common_pkg_lib.common_pkg.ALL;
USE dp_pkg_lib.dp_stream_pkg.ALL;
USE dp_pkg_lib.tb_dp_pkg.ALL;
 
ENTITY tb_dp_latency_adapter IS
END tb_dp_latency_adapter;
 
 
ARCHITECTURE tb OF tb_dp_latency_adapter IS
 
  -- See tb_dp_pkg.vhd for explanation and run time
 
  SUBTYPE t_dut_range  IS INTEGER RANGE -1 to INTEGER'HIGH; 
 
  TYPE t_dut_natural_arr  IS ARRAY (t_dut_range RANGE <>) OF NATURAL;
  TYPE t_dut_data_arr     IS ARRAY (t_dut_range RANGE <>) OF STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  TYPE t_dut_logic_arr    IS ARRAY (t_dut_range RANGE <>) OF STD_LOGIC;  -- can not use STD_LOGIC_VECTOR because of integer range 
 
  -- TX ready latency to DUT chain
  CONSTANT c_tx_latency     : NATURAL := 3;
  CONSTANT c_tx_void        : NATURAL := sel_a_b(c_tx_latency, 1, 0);  -- used to avoid empty range VHDL warnings when c_tx_latency=0
 
  CONSTANT c_tx_offset_sop  : NATURAL := 3;
  CONSTANT c_tx_period_sop  : NATURAL := 7;              -- sop in data valid cycle 3,  10,  17, ...
  CONSTANT c_tx_offset_eop  : NATURAL := 5;              -- eop in data valid cycle   5,  12,  19, ...
  CONSTANT c_tx_period_eop  : NATURAL := c_tx_period_sop;
  CONSTANT c_tx_offset_sync : NATURAL := 3;                  -- sync in data valid cycle 3, 20, 37, ...
  CONSTANT c_tx_period_sync : NATURAL := 17;
 
  -- The TB supports using 1 or more dp_latency_adapter Devices Under Test in a chain. DUT 0 is the first DUT and it
  -- gets the tx_data from this test bench, which has index -1. Each next DUT gets its input from the previous DUT,
  -- hence the ready latency between DUTs should be the same.
  -- The output latency of the previous must equal the input latency of the next DUT, hence it is sufficient to define
  -- only the DUT output latencies.
  --CONSTANT c_dut_latency    : t_dut_natural_arr := (c_tx_latency, 3);  -- verify single dp_latency_adapter with only wires
  --CONSTANT c_dut_latency    : t_dut_natural_arr := (c_tx_latency, 4);  -- verify single dp_latency_adapter with latency increase
  --CONSTANT c_dut_latency    : t_dut_natural_arr := (c_tx_latency, 1);  -- verify single dp_latency_adapter with latency decrease
  CONSTANT c_dut_latency    : t_dut_natural_arr := (c_tx_latency, 1, 2, 0, 5, 5, 2, 1, 0, 7);
 
  -- The nof dut latencies in the c_dut_latency array automatically also defines the nof DUTs c_nof_dut.
  CONSTANT c_nof_dut        : NATURAL := c_dut_latency'HIGH+1;
 
  -- RX ready latency from DUT chain
  CONSTANT c_rx_latency     : NATURAL := c_dut_latency(c_nof_dut-1);
 
  CONSTANT c_verify_en_wait : NATURAL := 10+c_nof_dut*2;  -- wait some cycles before asserting verify enable
 
  CONSTANT c_empty_offset   : NATURAL := 1;
  CONSTANT c_channel_offset : NATURAL := 2;
 
  CONSTANT c_random_w       : NATURAL := 19;
 
  SIGNAL tb_end         : STD_LOGIC := '0';
  SIGNAL clk            : STD_LOGIC := '0';
  SIGNAL rst            : STD_LOGIC;
  SIGNAL sync           : STD_LOGIC;
  SIGNAL lfsr1          : STD_LOGIC_VECTOR(c_random_w-1 DOWNTO 0) := (OTHERS=>'0');
  SIGNAL lfsr2          : STD_LOGIC_VECTOR(c_random_w   DOWNTO 0) := (OTHERS=>'0');
 
  SIGNAL cnt_dat        : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  SIGNAL cnt_val        : STD_LOGIC;
  SIGNAL cnt_en         : STD_LOGIC;
 
  SIGNAL tx_data        : t_dp_data_arr(0 TO c_tx_latency + c_tx_void);
  SIGNAL tx_val         : STD_LOGIC_VECTOR(0 TO c_tx_latency + c_tx_void);
 
  SIGNAL in_ready       : STD_LOGIC;
  SIGNAL in_data        : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  SIGNAL in_sync        : STD_LOGIC;
  SIGNAL in_val         : STD_LOGIC;
  SIGNAL in_sop         : STD_LOGIC;
  SIGNAL in_eop         : STD_LOGIC;
 
  -- DUT index -1 = in_data
  SIGNAL dut_ready      : t_dut_logic_arr(-1 TO c_nof_dut-1);  -- SISO
  SIGNAL dut_data       : t_dut_data_arr(-1 TO c_nof_dut-1);   -- SOSI
  SIGNAL dut_empty      : t_dut_data_arr(-1 TO c_nof_dut-1) := (OTHERS=>(OTHERS=>'0'));
  SIGNAL dut_channel    : t_dut_data_arr(-1 TO c_nof_dut-1) := (OTHERS=>(OTHERS=>'0'));
  SIGNAL dut_sync       : t_dut_logic_arr(-1 TO c_nof_dut-1);
  SIGNAL dut_val        : t_dut_logic_arr(-1 TO c_nof_dut-1);
  SIGNAL dut_sop        : t_dut_logic_arr(-1 TO c_nof_dut-1);
  SIGNAL dut_eop        : t_dut_logic_arr(-1 TO c_nof_dut-1);
  -- DUT index c_nof_dut-1 = out_data
  SIGNAL dut_siso       : t_dp_siso_arr(-1 TO c_nof_dut-1);
  SIGNAL dut_sosi       : t_dp_sosi_arr(-1 TO c_nof_dut-1) := (OTHERS=>c_dp_sosi_rst);
 
  SIGNAL out_ready      : STD_LOGIC;
  SIGNAL prev_out_ready : STD_LOGIC_VECTOR(0 TO c_rx_latency);
  SIGNAL out_data       : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  SIGNAL out_empty      : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  SIGNAL out_channel    : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
  SIGNAL out_sync       : STD_LOGIC;
  SIGNAL out_val        : STD_LOGIC;
  SIGNAL out_sop        : STD_LOGIC;
  SIGNAL out_eop        : STD_LOGIC;
  SIGNAL hold_out_sop   : STD_LOGIC;
  SIGNAL prev_out_data  : STD_LOGIC_VECTOR(out_data'RANGE);
 
  SIGNAL state          : t_dp_state_enum;
 
  SIGNAL verify_en      : STD_LOGIC;
  SIGNAL verify_done    : STD_LOGIC;
 
  SIGNAL exp_data       : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := TO_UVEC(19555, c_dp_data_w);
 
BEGIN
 
  -- Use intervals marked by sync to start a new test named by state.
  --
  -- Under all circumstances the out_data should not mis or duplicate a count
  -- while out_val is asserted as checked by p_verify.
  -- The throughput must remain 100%, with only some increase in latency. This
  -- can be checked manually by checking that cnt_val does not toggle when the
  -- out_ready is asserted continuously. E.g. check that the out_data value 
  -- is sufficiently high given the number of sync intervals that have passed.
  --
  -- Stimuli to verify the dp_latency_adapter DUT:
  --
  -- * Use various ready latency combinations in c_dut_latency:
  --   .     c_in_latency > c_out_latency = 0
  --   .     c_in_latency > c_out_latency > 0
  --   .     c_in_latency = c_out_latency = 0
  --   .     c_in_latency = c_out_latency > 0
  --   . 0 = c_in_latency < c_out_latency
  --   . 0 < c_in_latency < c_out_latency
  --
  -- * Manipulate the stimuli in:
  --   . p_cnt_en    : cnt_en not always active when in_ready is asserted
  --   . p_out_ready : out_ready not always active
 
  clk <= NOT clk OR tb_end AFTER clk_period/2;
  rst <= '1', '0' AFTER clk_period*7;
 
  -- Sync interval
  proc_dp_sync_interval(clk, sync);
 
  -- Input data
  cnt_val <= in_ready AND cnt_en;
 
  proc_dp_cnt_dat(rst, clk, cnt_val, cnt_dat);
  proc_dp_tx_data(c_tx_latency, rst, clk, cnt_val, cnt_dat, tx_data, tx_val, in_data, in_val);
  proc_dp_tx_ctrl(c_tx_offset_sync, c_tx_period_sync, in_data, in_val, in_sync);
  proc_dp_tx_ctrl(c_tx_offset_sop, c_tx_period_sop, in_data, in_val, in_sop);
  proc_dp_tx_ctrl(c_tx_offset_eop, c_tx_period_eop, in_data, in_val, in_eop);
 
  -- Stimuli control
  proc_dp_count_en(rst, clk, sync, lfsr1, state, verify_done, tb_end, cnt_en);
  proc_dp_out_ready(rst, clk, sync, lfsr2, out_ready);
 
  -- Output verify
  proc_dp_verify_en(c_verify_en_wait, rst, clk, sync, verify_en);
  proc_dp_verify_data("out_data", c_rx_latency, clk, verify_en, out_ready, out_val, out_data, prev_out_data);
  proc_dp_verify_valid(c_rx_latency, clk, verify_en, out_ready, prev_out_ready, out_val);
  proc_dp_verify_ctrl(c_tx_offset_sync, c_tx_period_sync, "sync", clk, verify_en, out_data, out_val, out_sync);
  proc_dp_verify_ctrl(c_tx_offset_sop, c_tx_period_sop, "sop", clk, verify_en, out_data, out_val, out_sop);
  proc_dp_verify_ctrl(c_tx_offset_eop, c_tx_period_eop, "eop", clk, verify_en, out_data, out_val, out_eop);
  proc_dp_verify_sop_and_eop(c_rx_latency, FALSE, clk, out_val, out_val, out_sop, out_eop, hold_out_sop);  -- Verify that sop and eop come in pairs, no check on valid between eop and sop
  proc_dp_verify_other_sosi("empty", INCR_UVEC(out_data, c_empty_offset), clk, verify_en, out_empty);
  proc_dp_verify_other_sosi("channel", INCR_UVEC(out_data, c_channel_offset), clk, verify_en, out_channel);
 
  -- Check that the test has ran at all
  proc_dp_verify_value(e_equal, clk, verify_done, exp_data, out_data);
 
  ------------------------------------------------------------------------------
  -- Chain of 1 or more dp_latency_adapter DUTs
  --
  -- . Note this also models a series of streaming modules in a data path
  --
  ------------------------------------------------------------------------------
 
  -- Map the test bench tx counter data to the input of the chain
  in_ready        <= dut_ready(-1);
  dut_data(-1)    <=           in_data;
  dut_empty(-1)   <= INCR_UVEC(in_data, c_empty_offset);
  dut_channel(-1) <= INCR_UVEC(in_data, c_channel_offset);
  dut_sync(-1)    <= in_sync;
  dut_val(-1)     <= in_val;
  dut_sop(-1)     <= in_sop;
  dut_eop(-1)     <= in_eop;
 
  -- map sl, slv to record
  dut_ready(-1) <= dut_siso(-1).ready;                           -- SISO
  dut_sosi(-1).data(c_dp_data_w-1 DOWNTO 0) <= dut_data(-1);     -- SOSI
  dut_sosi(-1).empty                        <= dut_empty(-1)(c_dp_empty_w-1 DOWNTO 0);
  dut_sosi(-1).channel                      <= dut_channel(-1)(c_dp_channel_w-1 DOWNTO 0);
  dut_sosi(-1).sync                         <= dut_sync(-1);
  dut_sosi(-1).valid                        <= dut_val(-1);
  dut_sosi(-1).sop                          <= dut_sop(-1);
  dut_sosi(-1).eop                          <= dut_eop(-1);
 
  gen_chain : FOR I IN 0 TO c_nof_dut-1 GENERATE
    dut : ENTITY work.dp_latency_adapter
    GENERIC MAP (
      g_in_latency  => c_dut_latency(I-1),
      g_out_latency => c_dut_latency(I)
    )
    PORT MAP (
      rst       => rst,
      clk       => clk,
      -- ST sink
      snk_out   => dut_siso(I-1),
      snk_in    => dut_sosi(I-1),
      -- ST source
      src_in    => dut_siso(I),
      src_out   => dut_sosi(I)
    );
  END GENERATE;
 
  -- map record to sl, slv
  dut_siso(c_nof_dut-1).ready <= dut_ready(c_nof_dut-1);                                                      -- SISO
  dut_data(c_nof_dut-1)                               <= dut_sosi(c_nof_dut-1).data(c_dp_data_w-1 DOWNTO 0);  -- SOSI
  dut_empty(c_nof_dut-1)(c_dp_empty_w-1 DOWNTO 0)     <= dut_sosi(c_nof_dut-1).empty;
  dut_channel(c_nof_dut-1)(c_dp_channel_w-1 DOWNTO 0) <= dut_sosi(c_nof_dut-1).channel;
  dut_sync(c_nof_dut-1)                               <= dut_sosi(c_nof_dut-1).sync;
  dut_val(c_nof_dut-1)                                <= dut_sosi(c_nof_dut-1).valid;
  dut_sop(c_nof_dut-1)                                <= dut_sosi(c_nof_dut-1).sop;
  dut_eop(c_nof_dut-1)                                <= dut_sosi(c_nof_dut-1).eop;
 
  -- Map the output of the DUT chain to the test bench output data
  dut_ready(c_nof_dut-1) <= out_ready;
  out_data               <= dut_data(c_nof_dut-1);
  out_empty              <= dut_empty(c_nof_dut-1);
  out_channel            <= dut_channel(c_nof_dut-1);
  out_sync               <= dut_sync(c_nof_dut-1);
  out_val                <= dut_val(c_nof_dut-1);
  out_sop                <= dut_sop(c_nof_dut-1);
  out_eop                <= dut_eop(c_nof_dut-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.