From 2c2c7df815ca2f34aac317949d730779fd4fa9ca Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Thu, 12 Feb 2015 13:19:29 +0000
Subject: [PATCH] Added tb_diag_pkg.vhd and multi tb_tb_mms_diag_seq.vhd

---
 libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd   | 308 ++++++++++++++++++
 .../base/diag/tb/vhdl/tb_tb_mms_diag_seq.vhd  |  45 +++
 2 files changed, 353 insertions(+)
 create mode 100644 libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd
 create mode 100644 libraries/base/diag/tb/vhdl/tb_tb_mms_diag_seq.vhd

diff --git a/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd b/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd
new file mode 100644
index 0000000000..d93e0f02aa
--- /dev/null
+++ b/libraries/base/diag/tb/vhdl/tb_diag_pkg.vhd
@@ -0,0 +1,308 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2015
+-- 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/>.
+--
+--------------------------------------------------------------------------------
+
+-- Purpose: Test bench package for diag library
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;    
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE dp_lib.tb_dp_pkg.ALL;
+USE work.diag_pkg.ALL;
+
+PACKAGE tb_diag_pkg IS
+  
+  -- Test modes for diag seq
+  TYPE t_tb_diag_seq_mode_enum IS (
+    s_off,
+    s_expect_ok,
+    s_expect_error,
+    s_expect_no_result
+  );
+
+  PROCEDURE proc_diag_seq_read_all(CONSTANT c_stream : IN  NATURAL;
+                                   SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                   SIGNAL   tx_miso  : IN  t_mem_miso;
+                                   SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                   SIGNAL   rx_miso  : IN  t_mem_miso;
+                                   SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                   SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg); -- read all MM reg
+                                        
+  PROCEDURE proc_diag_seq_tx_enable(CONSTANT c_stream  : IN  NATURAL;
+                                    CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                                    CONSTANT c_tx_init : IN  NATURAL;
+                                    SIGNAL   mm_clk    : IN  STD_LOGIC;
+                                    SIGNAL   dp_clk    : IN  STD_LOGIC;
+                                    SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                                    SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                                    SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rd_reg    : OUT t_diag_seq_mm_reg); -- read all MM reg
+                                    
+  PROCEDURE proc_diag_seq_rx_enable(CONSTANT c_stream  : IN  NATURAL;
+                                    CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                                    SIGNAL   mm_clk    : IN  STD_LOGIC;
+                                    SIGNAL   dp_clk    : IN  STD_LOGIC;
+                                    SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                                    SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                                    SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rd_reg    : OUT t_diag_seq_mm_reg); -- read all MM reg
+                                    
+  PROCEDURE proc_diag_seq_tx_disable(CONSTANT c_stream : IN  NATURAL;
+                                     SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                     SIGNAL   dp_clk   : IN  STD_LOGIC;
+                                     SIGNAL   tx_miso  : IN  t_mem_miso;  -- tx ctrl
+                                     SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rx_miso  : IN  t_mem_miso;  -- rx ctrl
+                                     SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg); -- read all MM reg
+  
+  PROCEDURE proc_diag_seq_rx_disable(CONSTANT c_stream : IN  NATURAL;
+                                     SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                     SIGNAL   dp_clk   : IN  STD_LOGIC;
+                                     SIGNAL   tx_miso  : IN  t_mem_miso;  -- tx ctrl
+                                     SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rx_miso  : IN  t_mem_miso;  -- rx ctrl
+                                     SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg); -- read all MM reg
+
+  PROCEDURE proc_diag_seq_verify(CONSTANT c_stream  : IN    NATURAL;
+                                 SIGNAL   mm_clk    : IN    STD_LOGIC;
+                                 SIGNAL   tx_miso   : IN    t_mem_miso;
+                                 SIGNAL   tx_mosi   : OUT   t_mem_mosi;
+                                 SIGNAL   rx_miso   : IN    t_mem_miso;
+                                 SIGNAL   rx_mosi   : OUT   t_mem_mosi;
+                                 SIGNAL   tb_mode   : INOUT t_tb_diag_seq_mode_enum;
+                                 SIGNAL   tb_verify : OUT   STD_LOGIC;
+                                 SIGNAL   rd_reg    : INOUT t_diag_seq_mm_reg); -- read all MM reg
+END tb_diag_pkg;
+
+PACKAGE BODY tb_diag_pkg IS
+
+  PROCEDURE proc_diag_seq_read_all(CONSTANT c_stream : IN  NATURAL;
+                                   SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                   SIGNAL   tx_miso  : IN  t_mem_miso;
+                                   SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                   SIGNAL   rx_miso  : IN  t_mem_miso;
+                                   SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                   SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg) IS  -- read all MM reg
+    CONSTANT c_tx_offset : NATURAL := c_stream * 2**c_diag_seq_tx_reg_adr_w;
+    CONSTANT c_rx_offset : NATURAL := c_stream * 2**c_diag_seq_rx_reg_adr_w;
+  BEGIN
+    ---------------------------------------------------------------------------
+    -- Readback ctrl
+    ---------------------------------------------------------------------------
+    -- . read back Tx data init
+    proc_mem_mm_bus_rd(c_tx_offset + 1, mm_clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.tx_init <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- . read back Tx control
+    proc_mem_mm_bus_rd(c_tx_offset + 0, mm_clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.tx_ctrl <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- . read back Rx control
+    proc_mem_mm_bus_rd(c_rx_offset + 0, mm_clk, rx_miso, rx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.rx_ctrl <= rx_miso.rddata(c_word_w-1 DOWNTO 0);
+    
+    ---------------------------------------------------------------------------
+    -- Read cnt and stat
+    ---------------------------------------------------------------------------
+    -- . read rx_stat
+    proc_mem_mm_bus_rd(c_rx_offset + 1, mm_clk, rx_miso, rx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.rx_stat <= rx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- . read rx_cnt
+    proc_mem_mm_bus_rd(c_rx_offset + 2, mm_clk, rx_miso, rx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.rx_cnt <= rx_miso.rddata(c_word_w-1 DOWNTO 0);
+    -- . read tx_cnt
+    proc_mem_mm_bus_rd(c_tx_offset + 2, mm_clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    rd_reg.tx_cnt <= tx_miso.rddata(c_word_w-1 DOWNTO 0);
+  END proc_diag_seq_read_all;
+                                        
+  PROCEDURE proc_diag_seq_tx_enable(CONSTANT c_stream  : IN  NATURAL;
+                                    CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                                    CONSTANT c_tx_init : IN  NATURAL;
+                                    SIGNAL   mm_clk    : IN  STD_LOGIC;
+                                    SIGNAL   dp_clk    : IN  STD_LOGIC;
+                                    SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                                    SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                                    SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rd_reg    : OUT t_diag_seq_mm_reg) IS  -- read all MM reg
+    CONSTANT c_tx_offset : NATURAL := c_stream * 2**c_diag_seq_tx_reg_adr_w;
+    CONSTANT c_en        : NATURAL := 1;
+    VARIABLE v_sel       : NATURAL;
+    VARIABLE v_ctlr      : NATURAL;
+  BEGIN
+    IF c_pattern="PSRG" THEN
+      v_sel  := 0;  -- pseudo random data
+    ELSE
+      v_sel  := 1;  -- counter data
+    END IF;
+    v_ctlr := v_sel * 2 + c_en;  -- bits [1:0]
+    -- Enable Tx
+    proc_mem_mm_bus_wr(c_tx_offset + 0, v_ctlr, mm_clk, tx_miso, tx_mosi);
+    proc_mem_mm_bus_wr(c_tx_offset + 1, c_tx_init, mm_clk, tx_miso, tx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+  END proc_diag_seq_tx_enable;
+  
+  PROCEDURE proc_diag_seq_rx_enable(CONSTANT c_stream  : IN  NATURAL;
+                                    CONSTANT c_pattern : IN  STRING;    -- "PSRG", "CNTR"
+                                    SIGNAL   mm_clk    : IN  STD_LOGIC;
+                                    SIGNAL   dp_clk    : IN  STD_LOGIC;
+                                    SIGNAL   tx_miso   : IN  t_mem_miso;  -- tx ctrl
+                                    SIGNAL   tx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rx_miso   : IN  t_mem_miso;  -- rx ctrl
+                                    SIGNAL   rx_mosi   : OUT t_mem_mosi;
+                                    SIGNAL   rd_reg    : OUT t_diag_seq_mm_reg) IS  -- read all MM reg
+    CONSTANT c_rx_offset : NATURAL := c_stream * 2**c_diag_seq_rx_reg_adr_w;
+    CONSTANT c_en        : NATURAL := 1;
+    VARIABLE v_sel       : NATURAL;
+    VARIABLE v_ctlr      : NATURAL;
+  BEGIN
+    IF c_pattern="PSRG" THEN
+      v_sel  := 0;  -- pseudo random data
+    ELSE
+      v_sel  := 1;  -- counter data
+    END IF;
+    v_ctlr := v_sel * 2 + c_en;  -- bits [1:0]
+    proc_mem_mm_bus_wr(c_rx_offset + 0, v_ctlr, mm_clk, rx_miso, rx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+  END proc_diag_seq_rx_enable;
+  
+  PROCEDURE proc_diag_seq_tx_disable(CONSTANT c_stream : IN  NATURAL;
+                                     SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                     SIGNAL   dp_clk   : IN  STD_LOGIC;
+                                     SIGNAL   tx_miso  : IN  t_mem_miso;  -- tx ctrl
+                                     SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rx_miso  : IN  t_mem_miso;  -- rx ctrl
+                                     SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg) IS  -- read all MM reg
+    CONSTANT c_tx_offset : NATURAL := c_stream * 2**c_diag_seq_tx_reg_adr_w;
+  BEGIN
+    proc_mem_mm_bus_wr(c_tx_offset + 0, 0, mm_clk, tx_miso, tx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+  END proc_diag_seq_tx_disable;
+  
+  PROCEDURE proc_diag_seq_rx_disable(CONSTANT c_stream : IN  NATURAL;
+                                     SIGNAL   mm_clk   : IN  STD_LOGIC;
+                                     SIGNAL   dp_clk   : IN  STD_LOGIC;
+                                     SIGNAL   tx_miso  : IN  t_mem_miso;  -- tx ctrl
+                                     SIGNAL   tx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rx_miso  : IN  t_mem_miso;  -- rx ctrl
+                                     SIGNAL   rx_mosi  : OUT t_mem_mosi;
+                                     SIGNAL   rd_reg   : OUT t_diag_seq_mm_reg) IS -- read all MM reg
+    CONSTANT c_rx_offset : NATURAL := c_stream * 2**c_diag_seq_rx_reg_adr_w;
+  BEGIN
+    proc_mem_mm_bus_wr(c_rx_offset + 0, 0, mm_clk, rx_miso, rx_mosi);
+    proc_common_wait_some_cycles(mm_clk, dp_clk, 10);  -- wait for clock domain crossing
+    proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+  END proc_diag_seq_rx_disable;
+
+  PROCEDURE proc_diag_seq_verify(CONSTANT c_stream  : IN    NATURAL;
+                                 SIGNAL   mm_clk    : IN    STD_LOGIC;
+                                 SIGNAL   tx_miso   : IN    t_mem_miso;
+                                 SIGNAL   tx_mosi   : OUT   t_mem_mosi;
+                                 SIGNAL   rx_miso   : IN    t_mem_miso;
+                                 SIGNAL   rx_mosi   : OUT   t_mem_mosi;
+                                 SIGNAL   tb_mode   : INOUT t_tb_diag_seq_mode_enum;
+                                 SIGNAL   tb_verify : OUT   STD_LOGIC;
+                                 SIGNAL   rd_reg    : INOUT t_diag_seq_mm_reg) IS  -- read all MM reg
+   VARIABLE v_rx_stat : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+   VARIABLE v_rx_cnt  : NATURAL;
+   VARIABLE v_tx_cnt  : NATURAL;
+  BEGIN
+    -- Read all
+    proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+    proc_common_wait_some_cycles(mm_clk, 1);
+    v_rx_stat := rd_reg.rx_stat;
+    v_rx_cnt  := TO_UINT(rd_reg.rx_cnt);
+    v_tx_cnt  := TO_UINT(rd_reg.tx_cnt);
+    
+    -- Issue tb_verify pulse eg. to easy recognition in Wave window
+    tb_verify <= '1';
+    proc_common_wait_some_cycles(mm_clk, 1);
+    tb_verify <= '0';
+    
+    -- Verify
+    IF tb_mode=s_expect_ok THEN
+      IF v_rx_stat(1)/='0' THEN
+        REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
+      ELSIF v_rx_stat(0)/='0' THEN
+        REPORT "Wrong diag result: one or more data errors." SEVERITY ERROR;
+      END IF;
+      -- Read rx_cnt and tx_cnt again after some cycles
+      proc_diag_seq_read_all(c_stream, mm_clk, tx_miso, tx_mosi, rx_miso, rx_mosi, rd_reg);
+      proc_common_wait_some_cycles(mm_clk, 1);
+      IF v_rx_cnt = 0 THEN
+        REPORT "Wrong diag result: rx_cnt = 0." SEVERITY ERROR;
+      ELSIF v_rx_cnt >= TO_UINT(rd_reg.rx_cnt) THEN
+        REPORT "Wrong diag result: rx_cnt did not increase." SEVERITY ERROR;
+      END IF;
+      IF v_tx_cnt = 0 THEN
+        REPORT "Wrong diag result: tx_cnt = 0." SEVERITY ERROR;
+      ELSIF v_tx_cnt >= TO_UINT(rd_reg.tx_cnt) THEN
+        REPORT "Wrong diag result: tx_cnt did not increase." SEVERITY ERROR;
+      END IF;
+    ELSIF tb_mode=s_expect_error THEN
+      IF v_rx_stat(1)/='0' THEN
+        REPORT "Wrong diag result: no valid result." SEVERITY ERROR;
+      ELSIF v_rx_stat(0)/='1' THEN
+        REPORT "Wrong diag result: must detect data errors." SEVERITY ERROR;
+      END IF;
+      IF v_rx_cnt = 0 THEN
+        REPORT "Wrong diag result: rx_cnt = 0." SEVERITY ERROR;
+      END IF;
+      IF v_tx_cnt = 0 THEN
+        REPORT "Wrong diag result: tx_cnt = 0." SEVERITY ERROR;
+      END IF;
+    ELSIF tb_mode=s_expect_no_result THEN
+      IF v_rx_stat(1)/='1' THEN
+        REPORT "Wrong diag result: must indicate no valid result." SEVERITY ERROR;
+      END IF;
+      IF v_rx_cnt /= 0 THEN
+        REPORT "Wrong diag result: rx_cnt /= 0." SEVERITY ERROR;
+      END IF;
+    ELSIF tb_mode=s_off THEN
+      IF v_rx_cnt /= 0 THEN
+        REPORT "Wrong diag result: rx_cnt /= 0." SEVERITY ERROR;
+      END IF;
+      IF v_tx_cnt /= 0 THEN
+        REPORT "Wrong diag result: tx_cnt /= 0." SEVERITY ERROR;
+      END IF;
+    ELSE
+      REPORT "Unknown verify mode" SEVERITY FAILURE;
+    END IF;
+  END proc_diag_seq_verify;
+  
+END tb_diag_pkg;
diff --git a/libraries/base/diag/tb/vhdl/tb_tb_mms_diag_seq.vhd b/libraries/base/diag/tb/vhdl/tb_tb_mms_diag_seq.vhd
new file mode 100644
index 0000000000..074a7c104c
--- /dev/null
+++ b/libraries/base/diag/tb/vhdl/tb_tb_mms_diag_seq.vhd
@@ -0,0 +1,45 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2014
+-- 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/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE dp_lib.tb_dp_pkg.ALL;
+
+ENTITY tb_tb_mms_diag_seq IS
+END tb_tb_mms_diag_seq;
+
+
+ARCHITECTURE tb OF tb_tb_mms_diag_seq IS
+BEGIN
+
+  -- g_flow_control_verify  : t_dp_flow_control_enum := e_active;  -- always active or random flow control
+  -- g_nof_streams          : NATURAL := 2;
+  -- g_mm_broadcast_tx      : BOOLEAN := TRUE;
+  -- g_data_w               : NATURAL := 40;  -- >= g_seq_dat_w
+  -- g_seq_dat_w            : NATURAL := 32
+  
+  u_1_mm_equal_dat_w    : ENTITY work.tb_mms_diag_seq GENERIC MAP (e_active, 1, FALSE, 32, 32);
+  u_1_mm_random         : ENTITY work.tb_mms_diag_seq GENERIC MAP (e_random, 1, FALSE, 40, 32);
+  u_2_mm_broadcast      : ENTITY work.tb_mms_diag_seq GENERIC MAP (e_active, 2, TRUE,  40, 32);
+  u_2_mm_multiplex      : ENTITY work.tb_mms_diag_seq GENERIC MAP (e_active, 2, FALSE, 40, 32);
+  
+END tb;
-- 
GitLab