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