From 802e66ab15a04351b3bec1b572aed01fa5040f2a Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Mon, 14 Sep 2020 10:32:51 +0200
Subject: [PATCH] Expanded mm IO

---
 .../src/vhdl/mmm_lofar2_unb2b_filterbank.vhd  |  62 ++++-
 .../tb/vhdl/tb_lofar2_unb2b_filterbank.vhd    | 240 +++++++++++++++---
 2 files changed, 255 insertions(+), 47 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2b_filterbank/src/vhdl/mmm_lofar2_unb2b_filterbank.vhd b/applications/lofar2/designs/lofar2_unb2b_filterbank/src/vhdl/mmm_lofar2_unb2b_filterbank.vhd
index 9fa83326b9..a5b3d810a3 100644
--- a/applications/lofar2/designs/lofar2_unb2b_filterbank/src/vhdl/mmm_lofar2_unb2b_filterbank.vhd
+++ b/applications/lofar2/designs/lofar2_unb2b_filterbank/src/vhdl/mmm_lofar2_unb2b_filterbank.vhd
@@ -142,12 +142,15 @@ ENTITY mmm_lofar2_unb2b_filterbank IS
     reg_aduh_monitor_mosi         : OUT t_mem_mosi;
     reg_aduh_monitor_miso         : IN  t_mem_miso;
 
+    -- Subband statistics
     ram_st_sst_mosi               : OUT t_mem_mosi;
     ram_st_sst_miso               : IN  t_mem_miso;
 
+    -- Filter coefficients
     ram_fil_coefs_mosi            : OUT t_mem_mosi;
     ram_fil_coefs_miso            : IN  t_mem_miso;
 
+    -- Spectral Inversion
     reg_si_mosi                   : OUT t_mem_mosi;
     reg_si_miso                   : IN  t_mem_miso
   );
@@ -167,41 +170,76 @@ BEGIN
   ----------------------------------------------------------------------------
   gen_mm_file_io : IF g_sim = TRUE GENERATE
 
-    u_mm_file_reg_unb_system_info : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "PIO_SYSTEM_INFO")
+    u_mm_file_reg_unb_system_info    : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "PIO_SYSTEM_INFO")
                                                PORT MAP(mm_rst, mm_clk, reg_unb_system_info_mosi, reg_unb_system_info_miso );
 
-    u_mm_file_rom_unb_system_info : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "ROM_SYSTEM_INFO")
+    u_mm_file_rom_unb_system_info    : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "ROM_SYSTEM_INFO")
                                                PORT MAP(mm_rst, mm_clk, rom_unb_system_info_mosi, rom_unb_system_info_miso );
 
-    u_mm_file_reg_wdi             : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_WDI")
+    u_mm_file_reg_wdi                : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_WDI")
                                                PORT MAP(mm_rst, mm_clk, reg_wdi_mosi, reg_wdi_miso );
 
-    u_mm_file_reg_unb_sens        : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_UNB_SENS")
+    u_mm_file_reg_unb_sens           : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_UNB_SENS")
                                                PORT MAP(mm_rst, mm_clk, reg_unb_sens_mosi, reg_unb_sens_miso );
 
-    u_mm_file_reg_unb_pmbus       : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_UNB_PMBUS")
+    u_mm_file_reg_unb_pmbus          : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_UNB_PMBUS")
                                                PORT MAP(mm_rst, mm_clk, reg_unb_pmbus_mosi, reg_unb_pmbus_miso );
 
-    u_mm_file_reg_fpga_temp_sens  : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_FPGA_TEMP_SENS")
+    u_mm_file_reg_fpga_temp_sens     : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_FPGA_TEMP_SENS")
                                                PORT MAP(mm_rst, mm_clk, reg_fpga_temp_sens_mosi, reg_fpga_temp_sens_miso );
 
-    u_mm_file_reg_fpga_voltage_sens :  mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_FPGA_VOLTAGE_SENS")
+    u_mm_file_reg_fpga_voltage_sens  :  mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_FPGA_VOLTAGE_SENS")
                                                PORT MAP(mm_rst, mm_clk, reg_fpga_voltage_sens_mosi, reg_fpga_voltage_sens_miso );
 
-    u_mm_file_reg_ppsh            : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "PIO_PPS")
+    u_mm_file_reg_ppsh               : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "PIO_PPS")
                                                PORT MAP(mm_rst, mm_clk, reg_ppsh_mosi, reg_ppsh_miso );
 
     -- Note: the eth1g RAM and TSE buses are only required by unb_osy on the NIOS as they provide the ethernet<->MM gateway.
-    u_mm_file_reg_eth             : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_0_MMS_REG")
+    u_mm_file_reg_eth                : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_0_MMS_REG")
                                                PORT MAP(mm_rst, mm_clk, eth1g_reg_mosi, eth1g_reg_miso );
 
-    u_mm_file_ram_st_sst          : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_ST_SST")
+    u_mm_file_jesd204b               : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "JESD204B")
+                                                PORT MAP(mm_rst, mm_clk, jesd204b_mosi, jesd204b_miso );
+
+    u_mm_file_reg_dp_shiftram        : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_DP_SHIFTRAM")
+                                                PORT MAP(mm_rst, mm_clk, reg_dp_shiftram_mosi, reg_dp_shiftram_miso );
+
+    u_mm_file_reg_bsn_source         : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_BSN_SOURCE")
+                                                PORT MAP(mm_rst, mm_clk, reg_bsn_source_mosi, reg_bsn_source_miso );
+
+    u_mm_file_reg_bsn_scheduler      : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_BSN_SCHEDULER")
+                                                PORT MAP(mm_rst, mm_clk, reg_bsn_scheduler_mosi, reg_bsn_scheduler_miso );
+
+    u_mm_file_reg_bsn_monitor_input  : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_BSN_MONITOR_INPUT")
+                                                PORT MAP(mm_rst, mm_clk, reg_bsn_monitor_input_mosi, reg_bsn_monitor_input_miso );
+
+    u_mm_file_reg_wg                 : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_WG")
+                                                PORT MAP(mm_rst, mm_clk, reg_wg_mosi, reg_wg_miso );
+    u_mm_file_ram_wg                 : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_WG")
+                                               PORT MAP(mm_rst, mm_clk, ram_wg_mosi, ram_wg_miso );
+
+    u_mm_file_ram_diag_data_buf_jesd : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_DIAG_DATA_BUF_JESD")
+                                               PORT MAP(mm_rst, mm_clk, ram_diag_data_buf_jesd_mosi, ram_diag_data_buf_jesd_miso );
+    u_mm_file_reg_diag_data_buf_jesd : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_DIAG_DATA_BUF_JESD")
+                                               PORT MAP(mm_rst, mm_clk, reg_diag_data_buf_jesd_mosi, reg_diag_data_buf_jesd_miso );
+
+    u_mm_file_ram_diag_data_buf_bsn  : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_DIAG_DATA_BUF_BSN")
+                                               PORT MAP(mm_rst, mm_clk, ram_diag_data_buf_bsn_mosi, ram_diag_data_buf_bsn_miso );
+    u_mm_file_reg_diag_data_buf_bsn  : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_DIAG_DATA_BUF_BSN")
+                                               PORT MAP(mm_rst, mm_clk, reg_diag_data_buf_bsn_mosi, reg_diag_data_buf_bsn_miso );
+
+    u_mm_file_ram_aduh_monitor       : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_ADUH_MONITOR")
+                                               PORT MAP(mm_rst, mm_clk, ram_aduh_monitor_mosi, ram_aduh_monitor_miso );
+    u_mm_file_reg_aduh_monitor       : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_ADUH_MONITOR")
+                                               PORT MAP(mm_rst, mm_clk, reg_aduh_monitor_mosi, reg_aduh_monitor_miso );
+
+    u_mm_file_ram_st_sst             : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_ST_SST")
                                                PORT MAP(mm_rst, mm_clk, ram_st_sst_mosi, ram_st_sst_miso );
 
-    u_mm_file_ram_fil_coefs       : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_FIL_COEFS")
+    u_mm_file_ram_fil_coefs          : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "RAM_FIL_COEFS")
                                                PORT MAP(mm_rst, mm_clk, ram_fil_coefs_mosi, ram_fil_coefs_miso );
 
-    u_mm_file_reg_si              : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_SI")
+    u_mm_file_reg_si                 : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_SI")
                                               PORT MAP(mm_rst, mm_clk, reg_si_mosi, reg_si_miso );
     ----------------------------------------------------------------------------
     -- Procedure that polls a sim control file that can be used to e.g. get
diff --git a/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd b/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd
index f4c85a2ff1..31b4150fdf 100644
--- a/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd
+++ b/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd
@@ -1,41 +1,62 @@
 -------------------------------------------------------------------------------
 --
--- Copyright (C) 2018
+-- Copyright 2020
 -- 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.
+-- 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
 --
--- 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.
+--     http://www.apache.org/licenses/LICENSE-2.0
 --
--- You should have received a copy of the GNU General Public License
--- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-- 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: Jonathan Hargreaves
--- Purpose: Tb to show that lofar2_unb2b_filterbank can simulate
+-------------------------------------------------------------------------------
+--
+-- Author: R. van der Walle
+-- Purpose: Self-checking testbench for simulating lofar2_unb2b_adc using WG data.
+--
 -- Description:
---   Must use c_sim = TRUE to speed up simulation
---   This is a compile-only test bench
+--   MM control actions:
+--
+--   1) Enable calc mode for WG via reg_diag_wg with:
+--        freq = 20MHz
+--        ampl = 0.5 * 2**13
+--   
+--   2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg 
+--      to trigger start of WG at BSN.
+--     
+--   3) Read WG data via ram_aduh_mon into sp_sample and replay sp_sample for
+--      analogue view in Wave window:
+--   
+--   4) Read ADUH monitor power sum for via reg_aduh_mon and verify with 
+--      c_exp_wg_power_sp.
+--      View sp_power_sum in Wave window
+--
 -- Usage:
---   Load sim    # check that design can load in vsim
---   > as 10     # check that the hierarchy for g_design_name is complete
---   > run -a    # check that design can simulate some us without error
-
-LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib;
+--   > as 7    # default
+--   > as 12   # for detailed debugging
+--   > run -a  
+--
+-------------------------------------------------------------------------------
+LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
 USE common_lib.common_pkg.ALL;
 USE unb2b_board_lib.unb2b_board_pkg.ALL;
 USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
+USE mm_lib.mm_file_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE mm_lib.mm_file_unb_pkg.ALL;
+USE diag_lib.diag_pkg.ALL;
 
 ENTITY tb_lofar2_unb2b_filterbank IS
 END tb_lofar2_unb2b_filterbank;
@@ -44,23 +65,73 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_filterbank IS
 
   CONSTANT c_sim             : BOOLEAN := TRUE;
   CONSTANT c_unb_nr          : NATURAL := 0; -- UniBoard 0
-  CONSTANT c_node_nr         : NATURAL := 0; -- Back node 3
+  CONSTANT c_node_nr         : NATURAL := 0; 
   CONSTANT c_id              : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000";
   CONSTANT c_version         : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00";
   CONSTANT c_fw_version      : t_unb2b_board_fw_version := (1, 0);
 
-  CONSTANT c_eth_clk_period  : TIME := 8 ns;  -- 125 MHz XO on UniBoard
-  CONSTANT c_ext_clk_period  : TIME := 5 ns;
+  CONSTANT c_eth_clk_period      : TIME := 8 ns;  -- 125 MHz XO on UniBoard
+  CONSTANT c_ext_clk_period      : TIME := 5 ns;
   CONSTANT c_bck_ref_clk_period  : TIME := 5 ns;
-  CONSTANT c_pps_period      : NATURAL := 1000;
+  CONSTANT c_pps_period          : NATURAL := 1000;
+
+  CONSTANT c_tb_clk_period       : TIME := 100 ps; -- use fast tb_clk to speed up M&C
+  CONSTANT c_cable_delay         : TIME := 12 ns
+;
+  CONSTANT c_sample_freq         : NATURAL := c_unb2b_board_ext_clk_freq_200M/10**6;  -- 200 MSps
+  CONSTANT c_sample_period       : TIME := (10**6 / c_sample_freq) * 1 ps; 
+
+  CONSTANT c_nof_sync            : NATURAL := 5;
+  CONSTANT c_nof_block_per_sync  : NATURAL := 16; 
+ 
+  CONSTANT c_percentage          : REAL := 0.05;  -- percentage that actual value may differ from expected value
+  CONSTANT c_lo_factor           : REAL := 1.0 - c_percentage;  -- lower boundary  
+  CONSTANT c_hi_factor           : REAL := 1.0 + c_percentage;  -- higher boundary
+
+  CONSTANT c_nof_points          : NATURAL := 1024; 
+  CONSTANT c_nof_taps            : NATURAL := 16; 
+  
+  CONSTANT c_subband_period      : TIME := c_nof_points * c_sample_period;
+
+  -- WG
+  CONSTANT c_full_scale_ampl      : REAL := REAL(2**(18-1)-1);  -- = full scale of WG
+  CONSTANT c_bsn_start_wg         : NATURAL := 2;  -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
+  CONSTANT c_ampl_sp              : NATURAL := 2**(14-1)/2;  -- in number of lsb
+  CONSTANT c_subband_sp           : REAL := 51.2;  -- Select subband at index 512/10 = 51.2 = 20 MHz
+  CONSTANT c_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/512.0;  -- subband freq = Fs/512 = 200 MSps/512 = 390625 Hz sinus
+  CONSTANT c_wg_ampl_lsb          : REAL := c_diag_wg_ampl_unit / c_full_scale_ampl;  -- amplitude in number of LSbit resolution steps
+  CONSTANT c_exp_wg_power_sp      : REAL := REAL(c_ampl_sp**2)/2.0 * REAL(c_nof_points*c_nof_block_per_sync);
+   
+  -- ADUH
+  CONSTANT c_mon_buffer_nof_samples  : NATURAL := 1024; --samples per stream 
+  CONSTANT c_mon_buffer_nof_words    : NATURAL := c_mon_buffer_nof_samples; 
+  
+  -- MM  
+  CONSTANT c_mm_file_reg_ppsh               : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS";
+  CONSTANT c_mm_file_reg_bsn_source         : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE";
+  CONSTANT c_mm_file_reg_bsn_scheduler_wg   : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
+  CONSTANT c_mm_file_reg_diag_wg            : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
+  CONSTANT c_mm_file_reg_aduh_mon           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_ADUH_MONITOR";
+  CONSTANT c_mm_file_ram_aduh_mon           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ADUH_MONITOR";
+
 
   -- Tb
   SIGNAL tb_end              : STD_LOGIC := '0';
   SIGNAL sim_done            : STD_LOGIC := '0';
+  SIGNAL tb_clk              : STD_LOGIC := '0';  
+  SIGNAL rd_data             : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
+
+  -- WG
+  SIGNAL dbg_c_exp_wg_power_sp : REAL := c_exp_wg_power_sp;
+  SIGNAL sp_samples            : t_integer_arr(0 TO c_mon_buffer_nof_samples-1) := (OTHERS=>0); 
+  SIGNAL sp_sample             : INTEGER := 0;
+  SIGNAL sp_power_sum          : UNSIGNED(63 DOWNTO 0);
+  SIGNAL current_bsn_wg        : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
 
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
   SIGNAL pps                 : STD_LOGIC := '0';
+  SIGNAL ext_pps             : STD_LOGIC := '0'; 
   SIGNAL pps_rst             : STD_LOGIC := '0';
 
   SIGNAL WDI                 : STD_LOGIC;
@@ -77,17 +148,15 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_filterbank IS
   SIGNAL pmbus_sda           : STD_LOGIC;
 
   -- back transceivers
-  SIGNAL JESD204B_SERIAL_DATA              : STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w * c_unb2b_board_tr_jesd204b.nof_bus)-1 downto 0);
-  SIGNAL JESD204B_REFCLK         : STD_LOGIC := '1';
+  SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w * c_unb2b_board_tr_jesd204b.nof_bus)-1 downto 0);
+  SIGNAL JESD204B_REFCLK      : STD_LOGIC := '1';
 
   -- jesd204b syncronization signals
   SIGNAL jesd204b_sysref     : STD_LOGIC;
   SIGNAL jesd204b_sync_n     : STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.nof_bus * c_unb2b_board_tr_jesd204b.bus_w)-1 DOWNTO 0);
 
-
 BEGIN
 
-
   ----------------------------------------------------------------------------
   -- System setup
   ----------------------------------------------------------------------------
@@ -108,14 +177,15 @@ BEGIN
   ------------------------------------------------------------------------------  
   proc_common_gen_pulse(1, c_pps_period, '1', pps_rst, ext_clk, pps);
   jesd204b_sysref <= pps;
+  ext_pps <= pps;
 
   ------------------------------------------------------------------------------
   -- DUT
   ------------------------------------------------------------------------------
   u_lofar_unb2b_filterbank : ENTITY work.lofar2_unb2b_filterbank
   GENERIC MAP (
-    g_design_name => "lofar2_unb2b_filterbank_one_node",
-    g_design_note => "Lofar2 adc with one node",
+    g_design_name => "lofar2_unb2b_filterbank_full",
+    g_design_note => "Lofar2 adc full",
     g_sim         => c_sim,
     g_sim_unb_nr  => c_unb_nr,
     g_sim_node_nr => c_node_nr
@@ -158,12 +228,112 @@ BEGIN
     JESD204B_SYNC_N => jesd204b_sync_n
   );
 
-
   ------------------------------------------------------------------------------
-  -- Simulation end
+  -- MM slave accesses via file IO
   ------------------------------------------------------------------------------
-  sim_done <= '0', '1' AFTER 1 us;
+  tb_clk  <= NOT tb_clk AFTER c_tb_clk_period/2;    -- Testbench MM clock
+  
+  p_mm_stimuli : PROCESS
+    VARIABLE v_bsn                   : NATURAL;
+    VARIABLE v_sp_power_sum          : REAL;
+  BEGIN
+    -- Wait for DUT power up after reset
+    WAIT FOR 1 us;
+    
+    proc_common_wait_until_hi_lo(ext_clk, ext_pps);
+        
+    ----------------------------------------------------------------------------
+    -- Enable BS
+    ----------------------------------------------------------------------------
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_source, 3,                    0, tb_clk);
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_source, 2,                    0, tb_clk);  -- Init BSN = 0
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_source, 1, c_nof_block_per_sync, tb_clk);  -- nof_block_per_sync
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_source, 0,         16#00000003#, tb_clk);  -- Enable BS at PPS
+    
+    ----------------------------------------------------------------------------
+    -- Enable WG
+    ----------------------------------------------------------------------------
+    --   0 : mode[7:0]           --> off=0, calc=1, repeat=2, single=3)
+    --       nof_samples[31:16]  --> <= c_ram_wg_size=1024
+    --   1 : phase[15:0]
+    --   2 : freq[30:0]
+    --   3 : ampl[16:0]
+    mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 0, 1024*2**16 + 1, tb_clk);  -- nof_samples, mode calc
+    mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 1, INTEGER(  0.0 * c_diag_wg_phase_unit), tb_clk);  -- phase offset in degrees
+    mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 2, INTEGER(c_subband_sp * c_wg_subband_freq_unit), tb_clk);  -- freq
+    mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 3, INTEGER(REAL(c_ampl_sp) * c_wg_ampl_lsb), tb_clk);  -- ampl
+    
+    -- Read current BSN
+    mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO  0), tb_clk);
+    mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk);
+    proc_common_wait_some_cycles(tb_clk, 1);
+    
+    -- Write scheduler BSN to trigger start of WG at next block
+    v_bsn := TO_UINT(current_bsn_wg) + 2;
+    ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
+    v_bsn := c_bsn_start_wg;
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, v_bsn, tb_clk);  -- first write low then high part
+    mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1,     0, tb_clk);  -- assume v_bsn < 2**31-1
+    
+    -- Wait for ADUH monitor to have filled with WG data
+    WAIT FOR c_subband_period*c_nof_taps;
+    WAIT FOR c_subband_period*2;
+
+    ----------------------------------------------------------------------------
+    -- WG data : read ADUH monitor buffer
+    ----------------------------------------------------------------------------
+    -- Wait for start of sync interval 
+    mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0,                  -- read BSN low
+                            "UNSIGNED", rd_data, ">=", c_nof_block_per_sync*2,  -- this is the wait until condition
+                            c_subband_period, tb_clk);
+    
+    WAIT FOR c_subband_period;  -- ensure that one block of samples has filled the ADUH monitor buffer after the sync
+
+    -- Read via MM    
+    FOR I IN 0 TO c_mon_buffer_nof_words-1 LOOP
+      mmf_mm_bus_rd(c_mm_file_ram_aduh_mon, I, rd_data, tb_clk);
+      sp_samples(I) <= TO_SINT(rd_data(15 DOWNTO 0)); 
+    END LOOP;
+    
+    -- Play to have waveform in time to allow viewing as analogue in the Wave Window
+    FOR I IN 0 TO c_mon_buffer_nof_words-1 LOOP
+      proc_common_wait_some_cycles(ext_clk, 1);
+      sp_sample <= sp_samples(I);
+    END LOOP;
+ 
+    WAIT FOR c_subband_period*3;
 
-  proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end);
+    ---------------------------------------------------------------------------
+    -- Read ADUH monitor power sum 
+    ---------------------------------------------------------------------------
+    -- Wait for start of sync interval
+    mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0,                   -- read BSN low
+                            "UNSIGNED", rd_data, ">=", c_nof_block_per_sync*3,   -- this is the wait until condition
+                            c_subband_period, tb_clk);
+    
+    -- Read ADUH monitor power sum 
+    mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 2, rd_data, tb_clk);  -- read low part
+    sp_power_sum(31 DOWNTO 0) <= UNSIGNED(rd_data);
+    mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 3, rd_data, tb_clk);  -- read high part
+    sp_power_sum(63 DOWNTO 32) <= UNSIGNED(rd_data);
+    proc_common_wait_some_cycles(tb_clk, 1);
 
+    ---------------------------------------------------------------------------
+    -- Verification 
+    ---------------------------------------------------------------------------
+    -- Convert UNSIGNED sp_power_sum to REAL
+    v_sp_power_sum := REAL(REAL(TO_INTEGER(sp_power_sum(61 DOWNTO 30)))*REAL(2**30) + REAL(TO_INTEGER(sp_power_sum(29 DOWNTO 0)))); 
+
+    ASSERT v_sp_power_sum > c_lo_factor * c_exp_wg_power_sp REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
+    ASSERT v_sp_power_sum < c_hi_factor * c_exp_wg_power_sp REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
+
+    ---------------------------------------------------------------------------
+    -- End Simulation 
+    ---------------------------------------------------------------------------   
+    sim_done <= '1';
+    proc_common_wait_some_cycles(ext_clk, 100);
+    proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end);
+    WAIT;
+  END PROCESS;
+  
 END tb;
-- 
GitLab