From ca1dff9a0fd80f449e741fda6d69e4949c49e1af Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Thu, 8 Oct 2020 18:05:33 +0200
Subject: [PATCH] Initial commit of tb_mms_dp_scale.vhd

---
 libraries/base/dp/hdllib.cfg                  |   2 +
 libraries/base/dp/tb/vhdl/tb_mms_dp_scale.vhd | 189 ++++++++++++++++++
 2 files changed, 191 insertions(+)
 create mode 100644 libraries/base/dp/tb/vhdl/tb_mms_dp_scale.vhd

diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index d238389b5a..93a162a26a 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -297,6 +297,7 @@ test_bench_files =
     tb/vhdl/tb_dp_offload_tx_v3.vhd
     tb/vhdl/tb_dp_offload_rx_filter.vhd
     tb/vhdl/tb_dp_selector_arr.vhd
+    tb/vhdl/tb_mms_dp_scale.vhd
 
 regression_test_vhdl = 
     tb/vhdl/tb_dp_fifo_to_mm.vhd
@@ -351,6 +352,7 @@ regression_test_vhdl =
     tb/vhdl/tb_tb_dp_throttle_xon.vhd
     tb/vhdl/tb_tb_dp_xonoff.vhd
     tb/vhdl/tb_dp_selector_arr.vhd
+    tb/vhdl/tb_mms_dp_scale.vhd
 
 [modelsim_project_file]
 
diff --git a/libraries/base/dp/tb/vhdl/tb_mms_dp_scale.vhd b/libraries/base/dp/tb/vhdl/tb_mms_dp_scale.vhd
new file mode 100644
index 0000000000..02533cd3dc
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_mms_dp_scale.vhd
@@ -0,0 +1,189 @@
+-------------------------------------------------------------------------------
+--
+-- 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.
+--
+-------------------------------------------------------------------------------
+
+-- Author: R. van der Walle
+-- Purpose: Verify mms_dp_scale
+-- Description:
+-- Usage:
+-- > as 10
+-- > run -all
+-- 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_scale IS
+END tb_mms_dp_scale;
+
+
+ARCHITECTURE tb OF tb_mms_dp_scale 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_complex_data : BOOLEAN := TRUE; 
+  CONSTANT c_complex_gain : BOOLEAN := FALSE;
+  CONSTANT c_gain_w       : NATURAL := 8;  
+  CONSTANT c_in_dat_w     : NATURAL := 9; 
+  CONSTANT c_in_length    : INTEGER :=  2**(c_in_dat_w-3)-1; -- Expected sosi does not take clipping into account
+  CONSTANT c_in_max       : INTEGER :=  2**(c_in_dat_w-3)-1;
+  CONSTANT c_in_min       : INTEGER := -2**(c_in_dat_w-3);
+  CONSTANT c_out_dat_w    : NATURAL := c_in_dat_w;  -- skip double sign bit and assume complex gain amplitude <= 1
+  cONSTANT c_lsb_w        : NATURAL := 1;  
+
+  CONSTANT c_gain_re      : INTEGER := 2**2;
+  CONSTANT c_exp_gain_re  : INTEGER := 2**(2-c_lsb_w);
+ 
+  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 stimuli_en       : STD_LOGIC := '0';
+  SIGNAL verify_en        : STD_LOGIC := '0';
+  
+  SIGNAL cnt_re           : STD_LOGIC_VECTOR(c_in_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL cnt_im           : STD_LOGIC_VECTOR(c_in_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL cnt_val          : STD_LOGIC;
+  
+  SIGNAL in_sosi          : t_dp_sosi;
+  SIGNAL in_sosi_dly      : t_dp_sosi;
+  SIGNAL exp_sosi         : t_dp_sosi;
+  SIGNAL out_sosi         : t_dp_sosi;
+  
+  SIGNAL reg_gain_re_mosi   : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_gain_re_miso   : t_mem_miso;
+  SIGNAL reg_gain_im_mosi   : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_gain_im_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;
+  
+  ------------------------------------------------------------------------------
+  -- DATA GENERATION
+  ------------------------------------------------------------------------------
+  proc_dp_cnt_dat(dp_rst, dp_clk, stimuli_en, cnt_val, cnt_re);
+  
+  -- derive cnt_im linearly from cnt_re such that abs(complex(cnt_re, cnt_im)) <= amplitude
+  -- the principle is: suppose re normalized to 1 then im = 1-re when re>=0 else im = -1-re when re<0
+  cnt_im <= TO_SVEC(sel_a_b(TO_SINT(cnt_re)>=0, c_in_max, c_in_min) - TO_SINT(cnt_re), c_in_dat_w); 
+  
+  in_sosi.data  <= RESIZE_DP_SDATA(cnt_re);
+  in_sosi.re    <= RESIZE_DP_DSP_DATA(cnt_re);
+  in_sosi.im    <= RESIZE_DP_DSP_DATA(cnt_im);
+  in_sosi.valid <= cnt_val;
+
+  u_in_sosi_dly : ENTITY work.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 3   -- latency of DUT
+  )
+  PORT MAP (
+    rst      => dp_rst,
+    clk      => dp_clk,
+    snk_in   => in_sosi,
+    src_out  => in_sosi_dly
+  );
+
+  p_mm_stimuli : PROCESS
+  BEGIN              
+    proc_common_wait_until_low(dp_clk, dp_rst);
+    proc_common_wait_some_cycles(dp_clk, 5);
+
+    proc_mem_mm_bus_wr(0, c_gain_re, mm_clk, reg_gain_re_miso, reg_gain_re_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);
+
+    stimuli_en <= '1';
+    proc_common_wait_some_cycles(dp_clk, 4);
+
+    verify_en <= '1';
+    proc_common_wait_some_cycles(dp_clk, c_in_length);
+    verify_en <= '0';
+    
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;  
+  
+  -- Verify out_sosi_arr 
+  p_exp_sosi : PROCESS(in_sosi_dly)
+  BEGIN
+    exp_sosi.re <= TO_DP_DSP_DATA(c_exp_gain_re * TO_SINT(in_sosi_dly.re));
+    exp_sosi.im <= TO_DP_DSP_DATA(c_exp_gain_re * TO_SINT(in_sosi_dly.im));
+  END PROCESS;
+  
+  p_verify : PROCESS(dp_clk)
+  BEGIN
+    IF rising_edge(dp_clk) THEN
+      IF verify_en='1' THEN
+        ASSERT SIGNED(out_sosi.re)=SIGNED(exp_sosi.re) REPORT "Unexpected complex real data, with real gain" SEVERITY ERROR;
+        ASSERT SIGNED(out_sosi.im)=SIGNED(exp_sosi.im) REPORT "Unexpected complex imag data, with real gain" SEVERITY ERROR;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  ------------------------------------------------------------------------------
+  -- DUT 
+  ------------------------------------------------------------------------------
+    u_dut : ENTITY work.mms_dp_scale
+    GENERIC MAP (
+      g_complex_data => c_complex_data,
+      g_complex_gain => c_complex_gain,
+      g_gain_w       => c_gain_w,
+      g_in_dat_w     => c_in_dat_w,
+      g_out_dat_w    => c_out_dat_w,
+      g_lsb_w        => c_lsb_w
+    )
+    PORT MAP (
+      -- Clocks and reset
+      mm_rst            => mm_rst,
+      mm_clk            => mm_clk,
+      dp_rst            => dp_rst,
+      dp_clk            => dp_clk,
+  
+      -- MM access to gain
+      reg_gain_re_mosi  => reg_gain_re_mosi,
+      reg_gain_re_miso  => reg_gain_re_miso,
+      reg_gain_im_mosi  => reg_gain_im_mosi,
+      reg_gain_im_miso  => reg_gain_im_miso,
+  
+      -- ST
+      in_sosi           => in_sosi,
+      out_sosi          => out_sosi
+    );
+  
+END tb;
-- 
GitLab