From 5f58358e7d88418baf41231a1beed56879e31fd7 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Thu, 6 May 2021 14:41:00 +0200
Subject: [PATCH] fixed testbench and st_xsq to match expecting xsq values.
 also added tb_tb_st_xsq

---
 .../base/common/src/vhdl/common_math_pkg.vhd  |  6 +-
 libraries/dsp/st/hdllib.cfg                   |  2 +
 libraries/dsp/st/src/vhdl/st_pkg.vhd          |  4 +-
 libraries/dsp/st/src/vhdl/st_xsq.vhd          | 81 +++++++++++++------
 libraries/dsp/st/tb/vhdl/tb_st_xsq.vhd        | 80 +++++++++---------
 libraries/dsp/st/tb/vhdl/tb_tb_st_xsq.vhd     | 56 +++++++++++++
 6 files changed, 161 insertions(+), 68 deletions(-)
 create mode 100644 libraries/dsp/st/tb/vhdl/tb_tb_st_xsq.vhd

diff --git a/libraries/base/common/src/vhdl/common_math_pkg.vhd b/libraries/base/common/src/vhdl/common_math_pkg.vhd
index 8455d30e7d..1fd31bbd37 100644
--- a/libraries/base/common/src/vhdl/common_math_pkg.vhd
+++ b/libraries/base/common/src/vhdl/common_math_pkg.vhd
@@ -80,7 +80,7 @@ PACKAGE common_math_pkg IS
   FUNCTION common_math_create_look_up_table_phasor(N, W : POSITIVE; AMPL, FREQ, PHI : REAL) RETURN t_nat_integer_arr;
   FUNCTION common_math_create_look_up_table_phasor(N, W : POSITIVE; AMPL, FREQ, PHI : REAL) RETURN t_slv_32_arr;  -- range 0 TO N-1
  
-  FUNCTION common_math_create_random_arr(N, W : POSITIVE) RETURN t_integer_arr;
+  FUNCTION common_math_create_random_arr(N, W : POSITIVE; seed : NATURAL) RETURN t_integer_arr;
 
  
 END common_math_pkg;
@@ -182,9 +182,9 @@ PACKAGE BODY common_math_pkg IS
     RETURN v_exp_arr;
   END;
    
-  FUNCTION common_math_create_random_arr(N, W : POSITIVE) RETURN t_integer_arr IS
+  FUNCTION common_math_create_random_arr(N, W : POSITIVE; seed : NATURAL) RETURN t_integer_arr IS
     VARIABLE v_rand_arr : t_integer_arr(0 TO N-1);
-    VARIABLE v_random : STD_LOGIC_VECTOR(W-1 DOWNTO 0) := (OTHERS => '0');
+    VARIABLE v_random : STD_LOGIC_VECTOR(W-1 DOWNTO 0) := TO_UVEC(seed, W);
   BEGIN
     FOR I IN 0 TO N-1 LOOP
       v_random := func_common_random(v_random);
diff --git a/libraries/dsp/st/hdllib.cfg b/libraries/dsp/st/hdllib.cfg
index 7203491a3b..e1d6eb86e1 100644
--- a/libraries/dsp/st/hdllib.cfg
+++ b/libraries/dsp/st/hdllib.cfg
@@ -23,12 +23,14 @@ test_bench_files =
     tb/vhdl/tb_st_calc.vhd 
     tb/vhdl/tb_mmf_st_sst.vhd
     tb/vhdl/tb_st_xsq.vhd
+    tb/vhdl/tb_tb_st_xsq.vhd
     tb/vhdl/tb_st_histogram.vhd
     tb/vhdl/tb_mms_st_histogram.vhd
     tb/vhdl/tb_tb_st_histogram.vhd
 
 regression_test_vhdl = 
     tb/vhdl/tb_st_acc.vhd 
+    tb/vhdl/tb_tb_st_xsq.vhd
     #tb/vhdl/tb_st_calc.vhd   -- tb is not self checking yet
 
 
diff --git a/libraries/dsp/st/src/vhdl/st_pkg.vhd b/libraries/dsp/st/src/vhdl/st_pkg.vhd
index b790afd6a2..c9014472ab 100644
--- a/libraries/dsp/st/src/vhdl/st_pkg.vhd
+++ b/libraries/dsp/st/src/vhdl/st_pkg.vhd
@@ -43,8 +43,8 @@ PACKAGE BODY st_pkg IS
     FOR N IN 0 TO N_crosslets-1 LOOP
       FOR I IN 0 TO c_N_s-1 LOOP
         FOR J IN 0 TO c_N_s-1 LOOP
-          v_exp_xsq(c_nof_complex * (N*c_xsq + I*c_N_s+J)  ) := N_int * COMPLEX_MULT_REAL(a_re(N*c_N_s +I), a_im(N*c_N_s +I), b_re(N*c_N_s +J), b_im(N*c_N_s +J));
-          v_exp_xsq(c_nof_complex * (N*c_xsq + I*c_N_s+J)+1) := N_int * COMPLEX_MULT_IMAG(a_re(N*c_N_s +I), a_im(N*c_N_s +I), b_re(N*c_N_s +J), b_im(N*c_N_s +J));
+          v_exp_xsq(c_nof_complex * (N * c_xsq + I * c_N_s + J)    ) := N_int * COMPLEX_MULT_REAL(a_re(N * c_N_s + I), a_im(N * c_N_s + I), b_re(N * c_N_s + J), -1 * b_im(N * c_N_s + J));
+          v_exp_xsq(c_nof_complex * (N * c_xsq + I * c_N_s + J) + 1) := N_int * COMPLEX_MULT_IMAG(a_re(N * c_N_s + I), a_im(N * c_N_s + I), b_re(N * c_N_s + J), -1 * b_im(N * c_N_s + J));
         END LOOP;
       END LOOP;
     END LOOP;
diff --git a/libraries/dsp/st/src/vhdl/st_xsq.vhd b/libraries/dsp/st/src/vhdl/st_xsq.vhd
index 91ee30fc53..524b51f5e4 100644
--- a/libraries/dsp/st/src/vhdl/st_xsq.vhd
+++ b/libraries/dsp/st/src/vhdl/st_xsq.vhd
@@ -72,27 +72,27 @@ END st_xsq;
 
 ARCHITECTURE str OF st_xsq IS
 
-  CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
-  CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq;
-  
-  CONSTANT c_nof_stat_w   : NATURAL := ceil_log2(c_nof_statistics);
-  CONSTANT c_nof_word     : NATURAL := g_stat_data_sz*c_nof_statistics;
-  CONSTANT c_nof_word_w   : NATURAL := ceil_log2(c_nof_word);
-  CONSTANT c_stat_word_w  : NATURAL := g_stat_data_sz*c_word_w;
+  CONSTANT c_xsq               : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
+  CONSTANT c_nof_statistics    : NATURAL := g_nof_crosslets * c_xsq;
+  CONSTANT c_nof_stat_w        : NATURAL := ceil_log2(c_nof_statistics);
+  CONSTANT c_nof_word          : NATURAL := g_stat_data_sz*c_nof_statistics;
+  CONSTANT c_nof_word_w        : NATURAL := ceil_log2(c_nof_word);
+  CONSTANT c_stat_word_w       : NATURAL := g_stat_data_sz*c_word_w;
   CONSTANT c_total_ram_addr_w  : NATURAL := ceil_log2(c_nof_complex) + c_nof_word_w;
   
   -- Statistics register
-  CONSTANT c_mm_ram       : t_c_mem := (latency  => 1,
-                                        adr_w    => c_nof_word_w,
-                                        dat_w    => c_word_w,
-                                        nof_dat  => c_nof_word,
-                                        init_sl  => '0');           -- MM side : sla_in, sla_out
-  CONSTANT c_stat_ram     : t_c_mem := (latency  => 1,
-                                        adr_w    => c_nof_stat_w,
-                                        dat_w    => c_stat_word_w,
-                                        nof_dat  => c_nof_statistics,
-                                        init_sl  => '0');           -- ST side : stat_mosi
-  
+  CONSTANT c_mm_ram   : t_c_mem := (latency  => 1,
+                                    adr_w    => c_nof_word_w,
+                                    dat_w    => c_word_w,
+                                    nof_dat  => c_nof_word,
+                                    init_sl  => '0');           -- MM side : sla_in, sla_out
+  CONSTANT c_stat_ram : t_c_mem := (latency  => 1,
+                                    adr_w    => c_nof_stat_w,
+                                    dat_w    => c_stat_word_w,
+                                    nof_dat  => c_nof_statistics,
+                                    init_sl  => '0');           -- ST side : stat_mosi
+  SIGNAL pipe_in_a    : t_dp_sosi;
+  SIGNAL pipe_in_b    : t_dp_sosi;  
   
   SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);  
   SIGNAL stat_data_im : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);  
@@ -100,13 +100,42 @@ ARCHITECTURE str OF st_xsq IS
   SIGNAL wrdata_re    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
   SIGNAL wrdata_im    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
   
-  SIGNAL stat_mosi    : t_mem_mosi;
+  SIGNAL stat_mosi    : t_mem_mosi := c_mem_mosi_rst;
 
-  SIGNAL ram_st_xsq_mosi_arr : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
-  SIGNAL ram_st_xsq_miso_arr : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
+  SIGNAL ram_st_xsq_mosi_arr      : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
+  SIGNAL ram_st_xsq_miso_arr      : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
   SIGNAL remapped_ram_st_xsq_mosi : t_mem_mosi;  
     
 BEGIN
+  ---------------------------------------------------------------
+  -- pipeline inputs to increase latency with 1 in comparison to sync for st_calc 
+  ---------------------------------------------------------------
+  u_dp_pipeline_a : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline => 1
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    -- ST sink
+    snk_in       => in_a,
+    -- ST source
+    src_out      => pipe_in_a
+  );
+
+  u_dp_pipeline_b : ENTITY dp_lib.dp_pipeline
+  GENERIC MAP (
+    g_pipeline => 1
+  )
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    -- ST sink
+    snk_in       => in_b,
+    -- ST source
+    src_out      => pipe_in_b
+  );
+
   -- accumulators
   st_calc : ENTITY work.st_calc 
   GENERIC MAP (
@@ -121,11 +150,11 @@ BEGIN
   PORT MAP (
     rst            => dp_rst,
     clk            => dp_clk,
-    in_ar          => in_a.re(g_in_data_w-1 DOWNTO 0),
-    in_ai          => in_a.im(g_in_data_w-1 DOWNTO 0),
-    in_br          => in_b.re(g_in_data_w-1 DOWNTO 0),
-    in_bi          => in_b.im(g_in_data_w-1 DOWNTO 0),
-    in_val         => in_a.valid,
+    in_ar          => pipe_in_a.re(g_in_data_w-1 DOWNTO 0),
+    in_ai          => pipe_in_a.im(g_in_data_w-1 DOWNTO 0),
+    in_br          => pipe_in_b.re(g_in_data_w-1 DOWNTO 0),
+    in_bi          => pipe_in_b.im(g_in_data_w-1 DOWNTO 0),
+    in_val         => pipe_in_a.valid,
     in_sync        => in_a.sync,
     out_adr        => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
     out_re         => stat_data_re,
diff --git a/libraries/dsp/st/tb/vhdl/tb_st_xsq.vhd b/libraries/dsp/st/tb/vhdl/tb_st_xsq.vhd
index 29b752acce..d189297983 100644
--- a/libraries/dsp/st/tb/vhdl/tb_st_xsq.vhd
+++ b/libraries/dsp/st/tb/vhdl/tb_st_xsq.vhd
@@ -50,48 +50,48 @@ USE work.st_pkg.ALL;
 
 ENTITY tb_st_xsq IS 
   GENERIC(
-    g_nof_crosslets      : NATURAL := 1; 
-    g_nof_signal_inputs  : NATURAL := 2;  
+    g_nof_crosslets      : NATURAL := 2; 
+    g_nof_signal_inputs  : NATURAL := 12;  
     g_in_data_w          : NATURAL := 16;
-    g_stat_data_w        : NATURAL := 32;  -- statistics accumulator width
-    g_stat_data_sz       : NATURAL := 2;   -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
     g_nof_sync           : NATURAL := 3;
-    g_nof_block_per_sync : NATURAL := 20;
-    g_nof_clk_per_blk    : NATURAL := 512
+    g_stat_data_w        : NATURAL := 64;  -- statistics accumulator width
+    g_stat_data_sz       : NATURAL := 2;   -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
+    g_nof_block_per_sync : NATURAL := 5;
+    g_nof_clk_per_blk    : NATURAL := 1024
   );
 END tb_st_xsq;
 
 ARCHITECTURE tb OF tb_st_xsq IS
   
-  CONSTANT c_sim                : BOOLEAN := TRUE;
-  CONSTANT c_rl                   : NATURAL := 1;
-  CONSTANT c_block_size : NATURAL := g_nof_crosslets * g_nof_signal_inputs;
-  CONSTANT c_gap_size   : NATURAL := g_nof_clk_per_blk - c_block_size;
-  
-  CONSTANT c_xsq : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
+  CONSTANT c_sim            : BOOLEAN := TRUE;
+  CONSTANT c_rl             : NATURAL := 1;
+  CONSTANT c_block_size     : NATURAL := g_nof_crosslets * g_nof_signal_inputs;
+  CONSTANT c_random_data_w  : NATURAL := 8;
+  CONSTANT c_xsq            : NATURAL := g_nof_signal_inputs * g_nof_signal_inputs;
   CONSTANT c_nof_statistics : NATURAL := g_nof_crosslets * c_xsq;
+  CONSTANT c_gap_size       : NATURAL := g_nof_clk_per_blk - c_nof_statistics;
 
-  CONSTANT c_random_in_a_re     : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w);
-  CONSTANT c_random_in_a_im     : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-1);
-  CONSTANT c_random_in_b_re     : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-2);
-  CONSTANT c_random_in_b_im     : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, g_in_data_w-3);
+  CONSTANT c_random_in_a_re : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, c_random_data_w, 100);
+  CONSTANT c_random_in_a_im : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, c_random_data_w, 101);
+  CONSTANT c_random_in_b_re : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, c_random_data_w, 102);
+  CONSTANT c_random_in_b_im : t_integer_arr(0 TO c_block_size-1) := common_math_create_random_arr(c_block_size, c_random_data_w, 103);
 
-  CONSTANT c_expected_xsq : t_integer_arr(0 TO c_nof_statistics * c_nof_complex-1) := func_st_calculate_expected_xsq(c_random_in_a_re, c_random_in_a_im, c_random_in_b_re, c_random_in_b_im, g_nof_crosslets, g_nof_block_per_sync);
+  CONSTANT c_expected_xsq   : t_integer_arr(0 TO c_nof_statistics * c_nof_complex-1) := func_st_calculate_expected_xsq(c_random_in_a_re, c_random_in_a_im, c_random_in_b_re, c_random_in_b_im, g_nof_crosslets, g_nof_block_per_sync);
   ----------------------------------------------------------------------------
   -- Clocks and resets
   ----------------------------------------------------------------------------   
-  CONSTANT c_mm_clk_period      : TIME := 100 ps;
-  CONSTANT c_dp_clk_period      : TIME := 5 ns;
-  CONSTANT c_dp_pps_period      : NATURAL := 64;
+  CONSTANT c_mm_clk_period  : TIME := 100 ps;
+  CONSTANT c_dp_clk_period  : TIME := 5 ns;
+  CONSTANT c_dp_pps_period  : NATURAL := 64;
 
-  SIGNAL tb_end                 : STD_LOGIC;
-  SIGNAL dp_pps                 : STD_LOGIC;
+  SIGNAL tb_end             : STD_LOGIC;
+  SIGNAL dp_pps             : STD_LOGIC;
 
-  SIGNAL mm_rst                 : STD_LOGIC := '1';
-  SIGNAL mm_clk                 : STD_LOGIC := '1';
+  SIGNAL mm_rst             : STD_LOGIC := '1';
+  SIGNAL mm_clk             : STD_LOGIC := '1';
 
-  SIGNAL dp_rst                 : STD_LOGIC;
-  SIGNAL dp_clk                 : STD_LOGIC := '1';
+  SIGNAL dp_rst             : STD_LOGIC;
+  SIGNAL dp_clk             : STD_LOGIC := '1';
 
   SIGNAL st_en              : STD_LOGIC := '1';
   SIGNAL st_siso            : t_dp_siso := c_dp_siso_rdy;
@@ -124,7 +124,8 @@ BEGIN
     FOR I IN 0 TO g_nof_sync -1 LOOP
       proc_common_wait_until_lo_hi(dp_clk, st_sosi.sync);
     END LOOP;
-    proc_common_wait_some_cycles(dp_clk, 3);
+    proc_common_wait_some_cycles(dp_clk, g_nof_clk_per_blk);
+    proc_common_wait_some_cycles(dp_clk, 20);
     -- read ram
     proc_mem_read_ram(0, c_nof_statistics * c_nof_complex * g_stat_data_sz, mm_clk, ram_st_xsq_mosi, ram_st_xsq_miso, st_xsq_out_arr);  
     WAIT;
@@ -143,12 +144,13 @@ BEGIN
   
     -- Run some sync intervals with DSP counter data for the real and imag fields
     WAIT UNTIL rising_edge(dp_clk);
+    proc_common_wait_some_cycles(dp_clk, 7);
     FOR I IN 0 TO g_nof_sync-1 LOOP
-      proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_block_size, 0, 0, '1', "0", dp_clk, st_en, st_siso, st_sosi);     -- next sync
+      proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_nof_statistics, 0, 0, '1', "0", dp_clk, st_en, st_siso, st_sosi);     -- next sync
       st_sosi <= c_dp_sosi_rst;
       proc_common_wait_some_cycles(dp_clk, c_gap_size);
       FOR J IN 0 TO g_nof_block_per_sync-2 LOOP  -- provide sop and eop for block reference
-        proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_block_size, 0, 0, '0', "0", dp_clk, st_en, st_siso, st_sosi);   -- no sync
+        proc_dp_gen_block_data(c_rl, FALSE, g_in_data_w, g_in_data_w, 0, v_re, v_im, c_nof_statistics, 0, 0, '0', "0", dp_clk, st_en, st_siso, st_sosi);   -- no sync
         st_sosi <= c_dp_sosi_rst;
         proc_common_wait_some_cycles(dp_clk, c_gap_size);
       END LOOP;
@@ -170,14 +172,18 @@ BEGIN
 
   p_random_stimuli : PROCESS
   BEGIN
-    FOR I IN 0 TO g_nof_sync * g_nof_block_per_sync-1 LOOP
+    FOR S IN 0 TO g_nof_sync * g_nof_block_per_sync -1 LOOP
       WAIT UNTIL rising_edge(st_sosi.sop);
-      FOR J IN 0 TO c_block_size-1 LOOP
-        in_sosi_a.re <= TO_DP_DSP_DATA(c_random_in_a_re(J));
-        in_sosi_a.im <= TO_DP_DSP_DATA(c_random_in_a_im(J));
-        in_sosi_b.re <= TO_DP_DSP_DATA(c_random_in_b_re(J));
-        in_sosi_b.im <= TO_DP_DSP_DATA(c_random_in_b_im(J));
-        proc_common_wait_some_cycles(dp_clk, 1);
+      FOR N IN 0 TO g_nof_crosslets -1 LOOP
+        FOR I IN 0 TO g_nof_signal_inputs -1 LOOP
+          FOR J IN 0 TO g_nof_signal_inputs -1 LOOP      
+            in_sosi_a.re <= TO_DP_DSP_DATA(c_random_in_a_re(N * g_nof_signal_inputs + I));
+            in_sosi_a.im <= TO_DP_DSP_DATA(c_random_in_a_im(N * g_nof_signal_inputs + I));
+            in_sosi_b.re <= TO_DP_DSP_DATA(c_random_in_b_re(N * g_nof_signal_inputs + J));
+            in_sosi_b.im <= TO_DP_DSP_DATA(c_random_in_b_im(N * g_nof_signal_inputs + J));
+            proc_common_wait_some_cycles(dp_clk, 1);
+          END LOOP;
+        END LOOP;
       END LOOP;
     END LOOP;
     WAIT;
@@ -189,7 +195,7 @@ BEGIN
   p_verify : PROCESS
   BEGIN
     proc_common_wait_until_high(mm_clk, ram_st_xsq_miso.rdval);
-    proc_common_wait_some_cycles(mm_clk, c_nof_statistics * c_nof_complex * g_stat_data_sz + 10);
+    proc_common_wait_some_cycles(mm_clk, 2* c_nof_statistics * c_nof_complex * g_stat_data_sz + 10);
     FOR I IN 0 TO c_nof_statistics * c_nof_complex -1 LOOP
       ASSERT TO_SINT(st_xsq_out_arr(I*2)) = c_expected_xsq(I) REPORT "WRONG XSQ DATA" SEVERITY ERROR; -- Only read low part of statistic
     END LOOP;
diff --git a/libraries/dsp/st/tb/vhdl/tb_tb_st_xsq.vhd b/libraries/dsp/st/tb/vhdl/tb_tb_st_xsq.vhd
new file mode 100644
index 0000000000..3c2bf4340e
--- /dev/null
+++ b/libraries/dsp/st/tb/vhdl/tb_tb_st_xsq.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: Test multiple instances of tb_st_xsq
+-- Usage:
+-- > as 10
+-- > run -all
+--
+-- Description: See tb_st_xsq
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+
+ENTITY tb_tb_st_xsq IS
+END tb_tb_st_xsq;
+
+ARCHITECTURE tb OF tb_tb_st_xsq IS
+
+  CONSTANT c_nof_sync       : NATURAL := 3;
+  CONSTANT c_dsp_data_w     : NATURAL := 16;
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+  
+BEGIN
+--  GENERICS:
+--    g_nof_crosslets      : NATURAL := 2; 
+--    g_nof_signal_inputs  : NATURAL := 12;  
+--    g_in_data_w          : NATURAL := 16;
+--    g_stat_data_w        : NATURAL := 32;  -- statistics accumulator width
+--    g_stat_data_sz       : NATURAL := 2;   -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
+--    g_nof_sync           : NATURAL := 3;
+--    g_nof_block_per_sync : NATURAL := 5;
+--    g_nof_clk_per_blk    : NATURAL := 1024
+
+  u_sdp : ENTITY work.tb_st_xsq GENERIC MAP (1, 12, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024);
+  u_max : ENTITY work.tb_st_xsq GENERIC MAP (16, 8, c_dsp_data_w, c_nof_sync, 64, 2, 5, 1024); -- g_nof_crosslets * g_nof_signal_inputs**2 = 16 * 8 * 8 = 1024 = g_nof_clk_per_blk 
+  
+END tb;
-- 
GitLab