From 55c5acbbb5afb4359ced114c397ede3f2ac0095e Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Mon, 10 Apr 2017 12:18:10 +0000
Subject: [PATCH] Added dp_force_data_arr.vhd with MM interface and test
benches.
---
libraries/base/dp/hdllib.cfg | 6 +
libraries/base/dp/src/vhdl/dp_force_data.vhd | 133 +++++++
.../base/dp/src/vhdl/mms_dp_force_data.vhd | 151 ++++++++
.../dp/src/vhdl/mms_dp_force_data_arr.vhd | 116 ++++++
.../dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd | 349 ++++++++++++++++++
.../tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd | 63 ++++
6 files changed, 818 insertions(+)
create mode 100644 libraries/base/dp/src/vhdl/dp_force_data.vhd
create mode 100644 libraries/base/dp/src/vhdl/mms_dp_force_data.vhd
create mode 100644 libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd
create mode 100644 libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd
create mode 100644 libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index ca25589a29..3567f0d5d0 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -28,6 +28,9 @@ synth_files =
src/vhdl/dp_pipeline.vhd
src/vhdl/dp_pipeline_arr.vhd
src/vhdl/dp_pipeline_ready.vhd
+ src/vhdl/dp_force_data.vhd
+ src/vhdl/mms_dp_force_data.vhd
+ src/vhdl/mms_dp_force_data_arr.vhd
src/vhdl/dp_paged_sop_eop_reg.vhd
src/vhdl/dp_packet_detect.vhd
src/vhdl/dp_shiftreg.vhd
@@ -204,6 +207,7 @@ test_bench_files =
tb/vhdl/tb_dp_folder.vhd
tb/vhdl/tb_dp_switch.vhd
tb/vhdl/tb_dp_counter_func.vhd
+ tb/vhdl/tb_mms_dp_force_data_arr.vhd
tb/vhdl/tb_mms_dp_gain_arr.vhd
tb/vhdl/tb_mms_dp_gain_serial_arr.vhd
@@ -238,6 +242,7 @@ test_bench_files =
tb/vhdl/tb_tb_dp_split.vhd
tb/vhdl/tb_tb_dp_sync_checker.vhd
tb/vhdl/tb_tb_dp_sync_insert.vhd
+ tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
tb/vhdl/tb_tb_mms_dp_gain_arr.vhd
tb/vhdl/tb_tb_mms_dp_gain_serial_arr.vhd
@@ -281,6 +286,7 @@ regression_test_vhdl =
tb/vhdl/tb_tb_dp_sync_checker.vhd
tb/vhdl/tb_mms_dp_sync_checker.vhd
tb/vhdl/tb_tb_dp_sync_insert.vhd
+ tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
tb/vhdl/tb_tb_mms_dp_gain_arr.vhd
tb/vhdl/tb_tb_mms_dp_gain_serial_arr.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_force_data.vhd b/libraries/base/dp/src/vhdl/dp_force_data.vhd
new file mode 100644
index 0000000000..87c0511d8b
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_force_data.vhd
@@ -0,0 +1,133 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- 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.
+--
+-- 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.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, 7 apr 2017
+-- Purpose:
+-- Pass the sosi data fields or force them to zero. All other sosi fields
+-- are passed on unchanged.
+-- Description:
+-- Default the force value is constant, but using the generics it can be
+-- made to automatically increment for every valid and restart at sync or
+-- sop.
+-- Usage:
+-- . DSP tests: Constant (zero) data is useful for DSP tests to be able to
+-- recognize a particular data stream in an array of streams.
+-- . Data move test: Incrementing data or a combination of constant re and
+-- incrementing im is useful for data move test when the data gets
+-- reordered.
+-- Remarks:
+-- . Ready latency = 1
+-- . When force_en='0' then this dp_force_data is equivalent to dp_pipeline.
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.all;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+ENTITY dp_force_data IS
+ GENERIC (
+ g_dat_w : NATURAL := 32; -- must be <= 32 to fit INTEGER range
+ g_increment_data : INTEGER := 0;
+ g_increment_re : INTEGER := 0;
+ g_increment_im : INTEGER := 0;
+ g_restart_on_sync : BOOLEAN := FALSE;
+ g_restart_on_sop : BOOLEAN := FALSE
+ );
+ PORT (
+ rst : IN STD_LOGIC;
+ clk : IN STD_LOGIC;
+ -- MM control
+ force_en : IN STD_LOGIC := '0';
+ force_data : IN INTEGER := 0; -- used for sosi.data
+ force_re : IN INTEGER := 0; -- used for sosi.re
+ force_im : IN INTEGER := 0; -- used for sosi.im
+ -- 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_force_data;
+
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.all;
+USE work.dp_stream_pkg.ALL;
+
+ARCHITECTURE str OF dp_force_data IS
+
+ SIGNAL data_in : t_dp_sosi;
+ SIGNAL data_out : t_dp_sosi;
+
+BEGIN
+
+ p_comb : PROCESS(snk_in, force_data, force_re, force_im, data_out)
+ BEGIN
+ data_in <= snk_in;
+ IF force_en='1' THEN
+ -- default force value
+ data_in.data <= TO_DP_SDATA(force_data);
+ data_in.re <= TO_DP_DSP_DATA(force_re);
+ data_in.im <= TO_DP_DSP_DATA(force_im);
+ -- optional increment
+ IF g_increment_data/=0 THEN
+ data_in.data <= RESIZE_DP_SDATA(STD_LOGIC_VECTOR(SIGNED(data_out.data(g_dat_w-1 DOWNTO 0)) + g_increment_data));
+ END IF;
+ IF g_increment_re/=0 THEN
+ data_in.re <= RESIZE_DP_DSP_DATA(STD_LOGIC_VECTOR(SIGNED(data_out.re(g_dat_w-1 DOWNTO 0)) + g_increment_re));
+ END IF;
+ IF g_increment_im/=0 THEN
+ data_in.im <= RESIZE_DP_DSP_DATA(STD_LOGIC_VECTOR(SIGNED(data_out.im(g_dat_w-1 DOWNTO 0)) + g_increment_im));
+ END IF;
+ -- optional restart increment
+ IF g_restart_on_sync=TRUE AND snk_in.sync='1' THEN
+ data_in.data <= TO_DP_SDATA(force_data);
+ data_in.re <= TO_DP_DSP_DATA(force_re);
+ data_in.im <= TO_DP_DSP_DATA(force_im);
+ END IF;
+ IF g_restart_on_sop=TRUE AND snk_in.sop='1' THEN
+ data_in.data <= TO_DP_SDATA(force_data);
+ data_in.re <= TO_DP_DSP_DATA(force_re);
+ data_in.im <= TO_DP_DSP_DATA(force_im);
+ END IF;
+ END IF;
+ END PROCESS;
+
+ u_dp_pipeline : ENTITY work.dp_pipeline
+ GENERIC MAP (
+ g_pipeline => 1
+ )
+ PORT MAP (
+ rst => rst,
+ clk => clk,
+ -- ST sink
+ snk_out => snk_out,
+ snk_in => data_in,
+ -- ST source
+ src_in => src_in,
+ src_out => data_out
+ );
+
+ src_out <= data_out;
+END str;
diff --git a/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd b/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd
new file mode 100644
index 0000000000..e38dffcb8d
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd
@@ -0,0 +1,151 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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.
+--
+-- 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.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author : E. Kooistra, 7 apr 2017
+-- Purpose : Control force data per stream via MM
+-- Description:
+-- Address Data Access Description
+-- 0 [0] R/W force enable or default disable for data pass on
+-- 1 [31:0] R/W force sosi data
+-- 2 [31:0] R/W force sosi re
+-- 3 [31:0] R/W force sosi im
+--
+-- The actual sosi data, re and im width integer is constrained by g_dat_w.
+-- Synthesis will optimize away unused bits from the full integer 32b range.
+--
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+
+ENTITY mms_dp_force_data IS
+ GENERIC (
+ g_dat_w : NATURAL := 32; -- must be <= 32 to fit INTEGER range
+ g_increment_data : INTEGER := 0;
+ g_increment_re : INTEGER := 0;
+ g_increment_im : INTEGER := 0;
+ g_restart_on_sync : BOOLEAN := FALSE;
+ g_restart_on_sop : BOOLEAN := FALSE
+ );
+ PORT (
+ -- Clocks and reset
+ mm_rst : IN STD_LOGIC;
+ mm_clk : IN STD_LOGIC;
+ dp_rst : IN STD_LOGIC;
+ dp_clk : IN STD_LOGIC;
+ -- MM control
+ reg_force_data_mosi : IN t_mem_mosi := c_mem_mosi_rst;
+ reg_force_data_miso : OUT t_mem_miso;
+ -- 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 mms_dp_force_data;
+
+ARCHITECTURE str OF mms_dp_force_data IS
+
+ -- TYPE t_c_mem IS RECORD
+ -- latency : NATURAL; -- read latency
+ -- adr_w : NATURAL;
+ -- dat_w : NATURAL;
+ -- nof_dat : NATURAL; -- optional, nof dat words <= 2**adr_w
+ -- init_sl : STD_LOGIC; -- optional, init all dat words to std_logic '0', '1' or 'X'
+ CONSTANT c_mm_reg : t_c_mem := (1, 2, g_dat_w, 4, 'X');
+
+ CONSTANT c_mm_reg_init : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS=>'0');
+
+ SIGNAL reg_force_data_wr : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0);
+ SIGNAL reg_force_data_rd : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+
+ SIGNAL force_en : STD_LOGIC := '0';
+ SIGNAL force_data : INTEGER := 0; -- used for sosi.data
+ SIGNAL force_re : INTEGER := 0; -- used for sosi.re
+ SIGNAL force_im : INTEGER := 0; -- used for sosi.im
+
+BEGIN
+
+ -- wires
+ force_en <= reg_force_data_wr(0);
+ reg_force_data_rd(0) <= reg_force_data_wr(0); -- other bits are not used and will read '0'
+ force_data <= TO_SINT(reg_force_data_wr(2*c_mm_reg.dat_w-1 DOWNTO c_mm_reg.dat_w));
+ reg_force_data_rd(2*c_mm_reg.dat_w-1 DOWNTO c_mm_reg.dat_w) <= reg_force_data_wr(2*c_mm_reg.dat_w-1 DOWNTO c_mm_reg.dat_w);
+ force_re <= TO_SINT(reg_force_data_wr(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w));
+ reg_force_data_rd(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w) <= reg_force_data_wr(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w);
+ force_im <= TO_SINT(reg_force_data_wr(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w));
+ reg_force_data_rd(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w) <= reg_force_data_wr(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w);
+
+ u_common_reg_r_w_dc_re : ENTITY common_lib.common_reg_r_w_dc
+ GENERIC MAP (
+ g_cross_clock_domain => TRUE,
+ g_readback => FALSE,
+ g_reg => c_mm_reg,
+ g_init_reg => c_mm_reg_init
+ )
+ 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_force_data_mosi,
+ sla_out => reg_force_data_miso,
+
+ -- MM registers in st_clk domain
+ reg_wr_arr => OPEN,
+ reg_rd_arr => OPEN,
+ out_reg => reg_force_data_wr, -- readback via ST clock domain
+ in_reg => reg_force_data_rd
+ );
+
+ u_dp_force_data : ENTITY work.dp_force_data
+ GENERIC MAP (
+ g_dat_w => g_dat_w,
+ g_increment_data => g_increment_data,
+ g_increment_re => g_increment_re,
+ g_increment_im => g_increment_im,
+ g_restart_on_sync => g_restart_on_sync,
+ g_restart_on_sop => g_restart_on_sop
+ )
+ PORT MAP (
+ rst => dp_rst,
+ clk => dp_clk,
+ -- MM control
+ force_en => force_en,
+ force_data => force_data,
+ force_re => force_re,
+ force_im => force_im,
+ -- ST sink
+ snk_out => snk_out,
+ snk_in => snk_in,
+ -- ST source
+ src_in => src_in,
+ src_out => src_out
+ );
+END str;
+
diff --git a/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd b/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000..2fa99c5c96
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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.
+--
+-- 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.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author : E. Kooistra, 7 apr 2017
+-- Purpose : Control force data per stream via MM
+-- Description:
+-- Stream Address Data Access Description
+-- 0 0 [0] R/W force enable or default disable for data pass on
+-- 0 1 [31:0] R/W force sosi data, re
+-- 0 2 [31:0] R/W force sosi im
+-- 0 3 - R/W not used, reads 0
+-- 1 4:7 idem
+-- 2 8:11 idem
+-- etc.
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+
+ENTITY mms_dp_force_data_arr IS
+ GENERIC (
+ g_nof_streams : NATURAL := 1;
+ g_dat_w : NATURAL := 32; -- must be <= 32 to fit INTEGER range
+ g_increment_data : INTEGER := 0;
+ g_increment_re : INTEGER := 0;
+ g_increment_im : INTEGER := 0;
+ g_restart_on_sync : BOOLEAN := FALSE;
+ g_restart_on_sop : BOOLEAN := FALSE
+ );
+ PORT (
+ -- Clocks and reset
+ mm_rst : IN STD_LOGIC;
+ mm_clk : IN STD_LOGIC;
+ dp_rst : IN STD_LOGIC;
+ dp_clk : IN STD_LOGIC;
+ -- MM control
+ reg_force_data_mosi : IN t_mem_mosi := c_mem_mosi_rst;
+ reg_force_data_miso : OUT t_mem_miso;
+ -- ST sink
+ snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+ snk_in_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+ -- ST source
+ src_in_arr : IN t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rdy);
+ src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
+ );
+END mms_dp_force_data_arr;
+
+
+ARCHITECTURE str OF mms_dp_force_data_arr IS
+
+ SIGNAL reg_force_data_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_mem_mosi_rst);
+ SIGNAL reg_force_data_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
+
+BEGIN
+
+ u_mem_mux : ENTITY common_lib.common_mem_mux
+ GENERIC MAP (
+ g_nof_mosi => g_nof_streams,
+ g_mult_addr_w => 2
+ )
+ PORT MAP (
+ mosi => reg_force_data_mosi,
+ miso => reg_force_data_miso,
+ mosi_arr => reg_force_data_mosi_arr,
+ miso_arr => reg_force_data_miso_arr
+ );
+
+ gen_nof_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
+ u_mms_dp_force_data : ENTITY work.mms_dp_force_data
+ GENERIC MAP (
+ g_dat_w => g_dat_w,
+ g_increment_data => g_increment_data,
+ g_increment_re => g_increment_re,
+ g_increment_im => g_increment_im,
+ g_restart_on_sync => g_restart_on_sync,
+ g_restart_on_sop => g_restart_on_sop
+ )
+ PORT MAP (
+ mm_rst => mm_rst,
+ mm_clk => mm_clk,
+ dp_rst => dp_rst,
+ dp_clk => dp_clk,
+ -- MM control
+ reg_force_data_mosi => reg_force_data_mosi_arr(I),
+ reg_force_data_miso => reg_force_data_miso_arr(I),
+ -- ST sink
+ snk_out => snk_out_arr(I),
+ snk_in => snk_in_arr(I),
+ -- ST source
+ src_in => src_in_arr(I),
+ src_out => src_out_arr(I)
+ );
+ END GENERATE;
+END str;
+
diff --git a/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd b/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000..c759470e0f
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd
@@ -0,0 +1,349 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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.
+--
+-- 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.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+-- Author: E. Kooistra, 10 Apr 2017
+-- Purpose: Verify mms_dp_force_data_arr and mms_dp_force_data
+-- Description:
+-- Usage:
+-- > as 10
+-- > run -all
+-- In wave window view sosi.data,re,im in radix decimal
+-- The tb is self stopping and self checking.
+
+
+LIBRARY IEEE, common_lib, technology_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+
+ENTITY tb_mms_dp_force_data_arr IS
+ GENERIC (
+ g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active or random stimuli valid flow control
+ g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active or random verify ready flow control
+ g_nof_streams : NATURAL := 1; -- >= 1
+ g_dat_w : NATURAL := 5; -- must be <= 32 to fit INTEGER range
+ g_force_stream : INTEGER := 0; -- must be < g_nof_streams, force data on this stream
+ g_force_data : INTEGER := -1;
+ g_force_re : INTEGER := 2;
+ g_force_im : INTEGER := -3;
+ g_increment_data : INTEGER := 1;
+ g_increment_re : INTEGER := -5;
+ g_increment_im : INTEGER := 5;
+ g_restart_on_sync : BOOLEAN := FALSE;
+ g_restart_on_sop : BOOLEAN := FALSE
+ );
+END tb_mms_dp_force_data_arr;
+
+
+ARCHITECTURE tb OF tb_mms_dp_force_data_arr IS
+
+ CONSTANT c_mm_clk_period : TIME := 20 ns;
+ CONSTANT c_dp_clk_period : TIME := 10 ns;
+ CONSTANT c_cross_clock_domain_latency : NATURAL := 20;
+
+ CONSTANT c_init_data : INTEGER := 0;
+ CONSTANT c_init_channel : INTEGER := 11; -- use recognizable value, will not change
+ CONSTANT c_init_error : INTEGER := 12; -- use recognizable value, will not change
+ CONSTANT c_nof_data_per_block : INTEGER := 17;
+ CONSTANT c_nof_block_per_sync : INTEGER := 10;
+ CONSTANT c_nof_blocks_per_test : INTEGER := c_nof_block_per_sync*3;
+
+ CONSTANT c_mm_reg_nof_dat : NATURAL := 4;
+ CONSTANT c_force_en : NATURAL := 1;
+ CONSTANT c_force_dis : NATURAL := 0;
+
+ SIGNAL tb_end : STD_LOGIC := '0';
+ SIGNAL mm_clk : STD_LOGIC := '1';
+ SIGNAL mm_rst : STD_LOGIC := '1';
+ SIGNAL dp_clk : STD_LOGIC := '1';
+ SIGNAL dp_rst : STD_LOGIC := '1';
+
+ SIGNAL random_valid : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
+ SIGNAL random_ready : STD_LOGIC_VECTOR(16 DOWNTO 0) := (OTHERS=>'0'); -- use different lengths to have different random sequences
+ SIGNAL stimuli_en : STD_LOGIC := '0';
+ SIGNAL verify_en : STD_LOGIC := '0';
+ SIGNAL force_en : STD_LOGIC := '0';
+
+ SIGNAL snk_out : t_dp_siso;
+ SIGNAL snk_in : t_dp_sosi;
+ SIGNAL snk_in_dly : t_dp_sosi;
+ SIGNAL snk_out_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+ SIGNAL snk_in_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+ SIGNAL src_in_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+ SIGNAL src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+ SIGNAL prev_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+ SIGNAL src_in : t_dp_siso;
+
+ SIGNAL reg_force_data_mosi : t_mem_mosi := c_mem_mosi_rst;
+ SIGNAL reg_force_data_miso : t_mem_miso;
+
+BEGIN
+
+ 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;
+ dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
+ mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
+
+ random_valid <= func_common_random(random_valid) WHEN rising_edge(dp_clk);
+ random_ready <= func_common_random(random_ready) WHEN rising_edge(dp_clk);
+
+ stimuli_en <= random_valid(random_valid'HIGH) WHEN g_flow_control_stimuli=e_random ELSE '1';
+ src_in.ready <= random_ready(random_ready'HIGH) WHEN g_flow_control_verify =e_random ELSE '1';
+ src_in.xon <= '1';
+
+ src_in_arr <= (OTHERS=>src_in);
+
+ ------------------------------------------------------------------------------
+ -- DATA GENERATION
+ ------------------------------------------------------------------------------
+ p_stimuli_st : PROCESS
+ VARIABLE v_sosi : t_dp_sosi := c_dp_sosi_rst;
+ BEGIN
+ -- Initialisations
+ v_sosi.bsn := TO_DP_BSN(0);
+ v_sosi.data := TO_DP_SDATA(0);
+
+ snk_in <= c_dp_sosi_rst;
+ proc_common_wait_until_low(dp_clk, mm_rst);
+ proc_common_wait_until_low(dp_clk, dp_rst);
+ proc_common_wait_some_cycles(dp_clk, 5);
+
+ -- Generate packets
+ WHILE tb_end='0' LOOP
+ v_sosi.sync := sel_a_b((UNSIGNED(v_sosi.bsn) MOD c_nof_block_per_sync) = 0, '1', '0'); -- insert sync starting at BSN=0 and with period g_sync_period
+ v_sosi.data := RESIZE_DP_DATA(v_sosi.data(g_dat_w-1 DOWNTO 0)); -- wrap when >= 2**g_dat_w
+ -- Send block
+ proc_dp_gen_block_data(g_dat_w, c_init_data, c_nof_data_per_block, c_init_channel, c_init_error, v_sosi.sync, v_sosi.bsn, dp_clk, stimuli_en, snk_out, snk_in);
+ -- Prepare for next block
+ v_sosi.bsn := INCR_UVEC(v_sosi.bsn, 1);
+ v_sosi.data := INCR_UVEC(v_sosi.data, c_nof_data_per_block);
+ END LOOP;
+
+ WAIT;
+ END PROCESS;
+
+ u_snk_in_dly : ENTITY work.dp_pipeline
+ GENERIC MAP (
+ g_pipeline => 1 -- latency of DUT
+ )
+ PORT MAP (
+ rst => dp_rst,
+ clk => dp_clk,
+ snk_out => OPEN,
+ snk_in => snk_in,
+ src_in => src_in_arr(0),
+ src_out => snk_in_dly
+ );
+
+ snk_out <= snk_out_arr(0); -- use stream 0 for flow control, all tb streams have same flow control
+ snk_in_arr <= (OTHERS=>snk_in); -- apply same default tb data to all streams
+
+ p_stimuli_mm : PROCESS
+ VARIABLE v_force_data : INTEGER := g_force_data;
+ BEGIN
+ proc_common_wait_until_low(dp_clk, mm_rst);
+ proc_common_wait_until_low(dp_clk, dp_rst);
+ proc_common_wait_some_cycles(mm_clk, 5);
+
+ -- Test default pass on the data unchanged
+ verify_en <= '1';
+ FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+ proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+ END LOOP;
+ verify_en <= '0';
+
+ -- Test force data on stream g_force_stream
+ force_en <= '1';
+ proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 0, c_force_en, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+ proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 1, g_force_data, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+ proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 2, g_force_re, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+ proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 3, g_force_im, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+ proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
+ proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency);
+
+ proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+ verify_en <= '1';
+ FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+ proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+ END LOOP;
+ verify_en <= '0';
+
+ -- Test default pass on the data unchanged
+ force_en <= '0';
+ proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 0, c_force_dis, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+ proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
+ proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency);
+
+ verify_en <= '1';
+ FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+ proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+ END LOOP;
+ verify_en <= '0';
+
+ tb_end <= '1';
+ WAIT;
+ END PROCESS;
+
+ -- capture previous valid src_out_arr to verify increments
+ prev_src_out_arr <= src_out_arr WHEN rising_edge(dp_clk) AND snk_in_dly.valid='1';
+
+ p_verify : PROCESS(dp_clk)
+ VARIABLE v_exp_data : INTEGER;
+ VARIABLE v_exp_re : INTEGER;
+ VARIABLE v_exp_im : INTEGER;
+ BEGIN
+ IF rising_edge(dp_clk) THEN
+ IF verify_en='1' AND snk_in_dly.valid='1' THEN
+ FOR I IN 0 TO g_nof_streams-1 LOOP
+ -- verify unchanged sosi fields (= pipeline)
+ ASSERT src_out_arr(I).sync = snk_in_dly.sync REPORT "Unexpected sync" SEVERITY ERROR;
+ ASSERT src_out_arr(I).sop = snk_in_dly.sop REPORT "Unexpected sop" SEVERITY ERROR;
+ ASSERT src_out_arr(I).eop = snk_in_dly.eop REPORT "Unexpected eop" SEVERITY ERROR;
+ ASSERT src_out_arr(I).valid = snk_in_dly.valid REPORT "Unexpected valid" SEVERITY ERROR;
+ ASSERT SIGNED(src_out_arr(I).bsn) =SIGNED(snk_in_dly.bsn) REPORT "Unexpected bsn" SEVERITY ERROR;
+ ASSERT SIGNED(src_out_arr(I).channel)=SIGNED(snk_in_dly.channel) REPORT "Unexpected channel" SEVERITY ERROR;
+ ASSERT SIGNED(src_out_arr(I).err) =SIGNED(snk_in_dly.err) REPORT "Unexpected err" SEVERITY ERROR;
+
+ IF force_en='0' OR I/=g_force_stream THEN
+ -- verify default data pass on (= pipeline)
+ ASSERT SIGNED(src_out_arr(I).data) =SIGNED(snk_in_dly.data) REPORT "Unexpected data" SEVERITY ERROR;
+ ASSERT SIGNED(src_out_arr(I).re) =SIGNED(snk_in_dly.re) REPORT "Unexpected real" SEVERITY ERROR;
+ ASSERT SIGNED(src_out_arr(I).im) =SIGNED(snk_in_dly.im) REPORT "Unexpected imag" SEVERITY ERROR;
+ ELSE
+ -- verify default force data on stream I=g_force_stream
+ v_exp_data := TO_SINT(INCR_DP_SDATA( prev_src_out_arr(I).data, g_increment_data, g_dat_w));
+ v_exp_re := TO_SINT(INCR_DP_DSP_DATA(prev_src_out_arr(I).re, g_increment_re, g_dat_w));
+ v_exp_im := TO_SINT(INCR_DP_DSP_DATA(prev_src_out_arr(I).im, g_increment_im, g_dat_w));
+
+ -- .data
+ IF g_increment_data=0 THEN
+ ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected force data" SEVERITY ERROR;
+ ELSE
+ IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected restart force data at sync" SEVERITY ERROR;
+ ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected restart force data at sop" SEVERITY ERROR;
+ ELSE
+ ASSERT TO_SINT(src_out_arr(I).data)=v_exp_data REPORT "Unexpected increment data" SEVERITY ERROR;
+ END IF;
+ END IF;
+
+ -- .re
+ IF g_increment_re=0 THEN
+ ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected force re" SEVERITY ERROR;
+ ELSE
+ IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected restart force re at sync" SEVERITY ERROR;
+ ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected restart force re at sop" SEVERITY ERROR;
+ ELSE
+ ASSERT TO_SINT(src_out_arr(I).re)=v_exp_re REPORT "Unexpected increment re" SEVERITY ERROR;
+ END IF;
+ END IF;
+
+ -- .im
+ IF g_increment_im=0 THEN
+ ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected force im" SEVERITY ERROR;
+ ELSE
+ IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected restart force im at sync" SEVERITY ERROR;
+ ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+ ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected restart force im at sop" SEVERITY ERROR;
+ ELSE
+ ASSERT TO_SINT(src_out_arr(I).im)=v_exp_im REPORT "Unexpected increment im" SEVERITY ERROR;
+ END IF;
+ END IF;
+ END IF;
+ END LOOP;
+ END IF;
+ END IF;
+ END PROCESS;
+
+ ------------------------------------------------------------------------------
+ -- DUT
+ ------------------------------------------------------------------------------
+
+ gen_one : IF g_nof_streams=1 GENERATE
+ u_dut_one : ENTITY work.mms_dp_force_data
+ GENERIC MAP (
+ g_dat_w => g_dat_w,
+ g_increment_data => g_increment_data,
+ g_increment_re => g_increment_re,
+ g_increment_im => g_increment_im,
+ g_restart_on_sync => g_restart_on_sync,
+ g_restart_on_sop => g_restart_on_sop
+ )
+ PORT MAP (
+ -- Clocks and reset
+ mm_rst => mm_rst,
+ mm_clk => mm_clk,
+ dp_rst => dp_rst,
+ dp_clk => dp_clk,
+ -- MM control
+ reg_force_data_mosi => reg_force_data_mosi,
+ reg_force_data_miso => reg_force_data_miso,
+ -- ST sink
+ snk_out => snk_out_arr(0),
+ snk_in => snk_in_arr(0),
+ -- ST source
+ src_in => src_in_arr(0),
+ src_out => src_out_arr(0)
+ );
+ END GENERATE;
+
+ gen_arr : IF g_nof_streams>1 GENERATE
+ u_dut_arr : ENTITY work.mms_dp_force_data_arr
+ GENERIC MAP (
+ g_nof_streams => g_nof_streams,
+ g_dat_w => g_dat_w,
+ g_increment_data => g_increment_data,
+ g_increment_re => g_increment_re,
+ g_increment_im => g_increment_im,
+ g_restart_on_sync => g_restart_on_sync,
+ g_restart_on_sop => g_restart_on_sop
+ )
+ PORT MAP (
+ -- Clocks and reset
+ mm_rst => mm_rst,
+ mm_clk => mm_clk,
+ dp_rst => dp_rst,
+ dp_clk => dp_clk,
+ -- MM control
+ reg_force_data_mosi => reg_force_data_mosi,
+ reg_force_data_miso => reg_force_data_miso,
+ -- ST sink
+ snk_out_arr => snk_out_arr,
+ snk_in_arr => snk_in_arr,
+ -- ST source
+ src_in_arr => src_in_arr,
+ src_out_arr => src_out_arr
+ );
+ END GENERATE;
+
+END tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd b/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000..833d348534
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
@@ -0,0 +1,63 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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.
+--
+-- 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.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+-- Author: E. Kooistra, 10 Apr 2017
+-- Purpose: Multi-testbench for mms_dp_force_data_arr
+-- Description:
+-- Verify mms_dp_force_data_arr
+-- Usage:
+-- > as 4
+-- > run -all
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_tb_mms_dp_force_data_arr IS
+END tb_tb_mms_dp_force_data_arr;
+
+ARCHITECTURE tb OF tb_tb_mms_dp_force_data_arr IS
+
+ SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+
+BEGIN
+
+-- g_flow_control_stimuli : t_dp_flow_control_enum := e_active; -- always active or random stimuli valid flow control
+-- g_flow_control_verify : t_dp_flow_control_enum := e_active; -- always active or random verify ready flow control
+-- g_nof_streams : NATURAL := 1; -- >= 1
+-- g_dat_w : NATURAL := 32; -- must be <= 32 to fit INTEGER range
+-- g_force_stream : INTEGER := 0; -- must be < g_nof_streams, force data on this stream
+-- g_force_data : INTEGER := -1;
+-- g_force_re : INTEGER := 2;
+-- g_force_im : INTEGER := -3;
+-- g_increment_data : INTEGER := 0;
+-- g_increment_re : INTEGER := 0;
+-- g_increment_im : INTEGER := 0;
+-- g_restart_on_sync : BOOLEAN := FALSE;
+-- g_restart_on_sop : BOOLEAN := FALSE
+
+ u_act_force_data_1 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_active, e_active, 1, 16, 0, -1, 2, -3, 0, 0, 0, FALSE, FALSE);
+ u_rnd_force_data_3 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0, -1, 2, -3, 0, 0, 0, FALSE, FALSE);
+ u_rnd_force_data_incr_3 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0, -1, 2, -3, 1, 1, 1, FALSE, FALSE);
+ u_rnd_force_data_incr_sync_3 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0, -1, 2, -3, 1, 1, 1, TRUE, FALSE);
+ u_rnd_force_data_incr_sop_3 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0, -1, 2, -3, 1, 1, 1, FALSE, TRUE);
+
+END tb;
--
GitLab