diff --git a/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/hdllib.cfg b/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/hdllib.cfg index 8ce77c6be85a1c99ba0d33d3583f20ad64433006..2909ebe510cb12940277d5be92fc03c3522c0b89 100644 --- a/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/hdllib.cfg +++ b/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/hdllib.cfg @@ -9,7 +9,10 @@ synth_files = test_bench_files = tb_unb1_minimal_qsys.vhd + tb_unb1_minimal_qsys_stimuli.vhd +regression_test_vhdl = + tb_unb1_minimal_qsys_stimuli.vhd [modelsim_project_file] diff --git a/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/tb_unb1_minimal_qsys_stimuli.vhd b/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/tb_unb1_minimal_qsys_stimuli.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d2dc2c7da55ac31aa2715f4f70cc802c39f1252a --- /dev/null +++ b/boards/uniboard1/designs/unb1_minimal/revisions/unb1_minimal_qsys/tb_unb1_minimal_qsys_stimuli.vhd @@ -0,0 +1,293 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2017 +-- 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 for unb1_minimal_qsys using MM stimuli via file IO. +-- Description: +-- - Verify UNB_SENS +-- - Verify PPSH +-- - The tb is done when tb_end goes high. +-- +-- The tb is self checking, but not self stopping when run-all is used, +-- because some internal DUT signals keep toggling. However in the +-- modelsim_regression_test_vhdl.py test tb_end high is used to stop the +-- simulation. +-- +-- Usage: +-- On command line do: +-- > run_modelsim & (to start Modeslim) +-- +-- In Modelsim do: +-- > lp unb1_minimal_qsys +-- > mk clean all (only first time to clean all libraries) +-- > mk all (to compile all libraries that are needed for unb1_minimal_qsys) +-- . load tb_unb1_minimal_qsys_stimuli simulation by double clicking the tb_unb1_minimal_qsys_stimuli icon +-- > as 10 (to view signals in Wave Window) +-- > run 100 us +-- +LIBRARY IEEE, common_lib, mm_lib, unb1_board_lib, i2c_lib; +USE IEEE.std_logic_1164.ALL; +USE IEEE.numeric_std.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE mm_lib.mm_file_pkg.ALL; +USE mm_lib.mm_file_unb_pkg.ALL; +USE unb1_board_lib.unb1_board_pkg.ALL; + +ENTITY tb_unb1_minimal_qsys_stimuli IS +END tb_unb1_minimal_qsys_stimuli; + +ARCHITECTURE tb OF tb_unb1_minimal_qsys_stimuli IS + + CONSTANT c_sim : BOOLEAN := TRUE; + + CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 + CONSTANT c_node_nr : NATURAL := 7; -- Back node 3 + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_unb_nr, c_unb1_board_nof_uniboard_w) & TO_UVEC(c_node_nr, c_unb1_board_nof_chip_w); + + CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; + CONSTANT c_fw_version : t_unb1_board_fw_version := (1, 0); + + CONSTANT c_cable_delay : TIME := 12 ns; + CONSTANT c_tb_clk_period : TIME := 10 ns; + CONSTANT c_eth_clk_period : TIME := 40 ns; -- 25 MHz XO on UniBoard + CONSTANT c_ext_clk_period : TIME := 5 ns; -- 200 MHz + CONSTANT c_ext_pps_period : NATURAL := 1000; + + CONSTANT c_cross_clock_domain_delay : NATURAL := 50; + CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS"; + CONSTANT c_mm_file_reg_unb_sens : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_UNB_SENS"; + + -- tb + SIGNAL tb_end : STD_LOGIC := '0'; + SIGNAL tb_clk : STD_LOGIC := '0'; + SIGNAL wr_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL rd_fpga_temp : INTEGER; + SIGNAL rd_eth_temp : INTEGER; + SIGNAL rd_voltage : INTEGER; + SIGNAL rd_current : INTEGER; + SIGNAL rd_sens_err : INTEGER; + SIGNAL rd_temp_high : INTEGER; + + SIGNAL rd_ppsh_toggle : STD_LOGIC; + SIGNAL rd_ppsh_stable : STD_LOGIC; + SIGNAL rd_ppsh_capture_cnt : NATURAL; + SIGNAL rd_ppsh_edge : STD_LOGIC; + SIGNAL rd_ppsh_expected_cnt : NATURAL; + + -- DUT + SIGNAL ext_clk : STD_LOGIC := '0'; + SIGNAL ext_rst : STD_LOGIC := '1'; + SIGNAL ext_pps : STD_LOGIC := '0'; + + SIGNAL WDI : STD_LOGIC; + SIGNAL INTA : STD_LOGIC; + SIGNAL INTB : STD_LOGIC; + + SIGNAL eth_clk : STD_LOGIC := '0'; + SIGNAL eth_txp : STD_LOGIC; + SIGNAL eth_rxp : STD_LOGIC; + + SIGNAL VERSION : STD_LOGIC_VECTOR(c_unb1_board_aux.version_w-1 DOWNTO 0) := c_version; + SIGNAL ID : STD_LOGIC_VECTOR(c_unb1_board_aux.id_w-1 DOWNTO 0) := c_id; + SIGNAL TESTIO : STD_LOGIC_VECTOR(c_unb1_board_aux.testio_w-1 DOWNTO 0); + + SIGNAL sens_scl : STD_LOGIC; + SIGNAL sens_sda : STD_LOGIC; + + -- Model I2C sensor slaves as on the UniBoard + CONSTANT c_fpga_temp_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "0011000"; -- MAX1618 address LOW LOW + CONSTANT c_fpga_temp : INTEGER := 60; + CONSTANT c_eth_temp_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "0101001"; -- MAX1618 address MID LOW + CONSTANT c_eth_temp : INTEGER := 40; + CONSTANT c_hot_swap_address : STD_LOGIC_VECTOR(6 DOWNTO 0) := "1000100"; -- LTC4260 address L L L + CONSTANT c_hot_swap_R_sense : REAL := 0.01; -- = 10 mOhm on UniBoard + CONSTANT c_temp_high : INTEGER := 85; + + CONSTANT c_uniboard_current : REAL := 5.0; -- = assume 5.0 A on UniBoard + CONSTANT c_uniboard_supply : REAL := 48.0; -- = assume 48.0 V on UniBoard + CONSTANT c_uniboard_adin : REAL := -1.0; -- = NC on UniBoard + + CONSTANT c_extpected_cnt : NATURAL := (1000 ms) / c_ext_clk_period; +BEGIN + + ---------------------------------------------------------------------------- + -- System setup + ---------------------------------------------------------------------------- + ext_clk <= NOT ext_clk OR tb_end AFTER c_ext_clk_period/2; -- External clock (200 MHz) + ext_rst <= '1', '0' AFTER c_ext_clk_period*10; + + eth_clk <= NOT eth_clk OR tb_end AFTER c_eth_clk_period/2; -- Ethernet ref clock (25 MHz) + + INTA <= 'H'; -- pull up + INTB <= 'H'; -- pull up + + sens_scl <= 'H'; -- pull up + sens_sda <= 'H'; -- pull up + + ------------------------------------------------------------------------------ + -- External PPS + ------------------------------------------------------------------------------ + proc_common_gen_pulse(1, c_ext_pps_period, '1', ext_rst, ext_clk, ext_pps); + + ------------------------------------------------------------------------------ + -- 1GbE Loopback model + ------------------------------------------------------------------------------ + eth_rxp <= TRANSPORT eth_txp AFTER c_cable_delay; + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + u_unb1_minimal_qsys : ENTITY work.unb1_minimal_qsys + GENERIC MAP ( + g_sim => c_sim, + g_sim_unb_nr => c_unb_nr, + g_sim_node_nr => c_node_nr + ) + PORT MAP ( + -- GENERAL + CLK => ext_clk, + PPS => ext_pps, + WDI => WDI, + INTA => INTA, + INTB => INTB, + + sens_sc => sens_scl, + sens_sd => sens_sda, + + -- Others + VERSION => VERSION, + ID => ID, + TESTIO => TESTIO, + + -- 1GbE Control Interface + ETH_clk => eth_clk, + ETH_SGIN => eth_rxp, + ETH_SGOUT => eth_txp + ); + + ------------------------------------------------------------------------------ + -- UniBoard sensors + ------------------------------------------------------------------------------ + -- I2C slaves that are available for each FPGA + u_fpga_temp : ENTITY i2c_lib.dev_max1618 + GENERIC MAP ( + g_address => c_fpga_temp_address + ) + PORT MAP ( + scl => sens_scl, + sda => sens_sda, + temp => c_fpga_temp + ); + + -- I2C slaves that are available only via FPGA back node 3 + u_eth_temp : ENTITY i2c_lib.dev_max1618 + GENERIC MAP ( + g_address => c_eth_temp_address + ) + PORT MAP ( + scl => sens_scl, + sda => sens_sda, + temp => c_eth_temp + ); + + u_power : ENTITY i2c_lib.dev_ltc4260 + GENERIC MAP ( + g_address => c_hot_swap_address, + g_R_sense => c_hot_swap_R_sense + ) + PORT MAP ( + scl => sens_scl, + sda => sens_sda, + ana_current_sense => c_uniboard_current, + ana_volt_source => c_uniboard_supply, + ana_volt_adin => c_uniboard_adin + ); + + ------------------------------------------------------------------------------ + -- MM slave accesses via file IO + ------------------------------------------------------------------------------ + tb_clk <= NOT tb_clk OR tb_end AFTER c_tb_clk_period/2; -- Testbench MM clock + + p_mm_stimuli : PROCESS + VARIABLE v_bsn : NATURAL; + BEGIN + -- Wait for DUT power up after reset + WAIT FOR 1 us; + + ---------------------------------------------------------------------------- + -- Read board sensors + ---------------------------------------------------------------------------- + WAIT FOR 30 us; + + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 0, rd_data, tb_clk); rd_fpga_temp <= TO_SINT(rd_data); + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 1, rd_data, tb_clk); rd_eth_temp <= TO_SINT(rd_data); + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 2, rd_data, tb_clk); rd_voltage <= TO_SINT(rd_data); + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 3, rd_data, tb_clk); rd_current <= TO_SINT(rd_data); + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 4, rd_data, tb_clk); rd_sens_err <= TO_SINT(rd_data); + mmf_mm_bus_rd(c_mm_file_reg_unb_sens, 5, rd_data, tb_clk); rd_temp_high <= TO_SINT(rd_data); + + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT rd_fpga_temp=c_fpga_temp REPORT "REG_UNB_SENS wrong FPGA temperature" SEVERITY ERROR; + ASSERT rd_eth_temp =c_eth_temp REPORT "REG_UNB_SENS wrong ETH temperature" SEVERITY ERROR; + ASSERT rd_sens_err =0 REPORT "REG_UNB_SENS I2C access went wrong" SEVERITY ERROR; + ASSERT rd_temp_high =c_temp_high REPORT "REG_UNB_SENS wrong high temperature" SEVERITY ERROR; + + ---------------------------------------------------------------------------- + -- Read PPSH + ---------------------------------------------------------------------------- + + -- verify PPS toggle + proc_common_wait_until_hi_lo(ext_clk, ext_pps); + mmf_mm_bus_rd(c_mm_file_reg_ppsh, 0, rd_data, tb_clk); + rd_ppsh_toggle <= rd_data(31); + proc_common_wait_until_hi_lo(ext_clk, ext_pps); + mmf_mm_bus_rd(c_mm_file_reg_ppsh, 0, rd_data, tb_clk); + + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT rd_ppsh_toggle=NOT rd_data(31) REPORT "REG_PPHS wrong toggle" SEVERITY ERROR; + + -- verify PPS edge, stable and capture cnt and expected cnt + -- The capture cnt and expected cnt cannot be equal in this simulation so therefore PPS will not become stable + proc_common_wait_until_hi_lo(ext_clk, ext_pps); + proc_common_wait_until_hi_lo(ext_clk, ext_pps); + + mmf_mm_bus_rd(c_mm_file_reg_ppsh, 0, rd_data, tb_clk); + rd_ppsh_toggle <= rd_data(31); + rd_ppsh_stable <= rd_data(30); + rd_ppsh_capture_cnt <= TO_UINT(rd_data(29 DOWNTO 0)); + mmf_mm_bus_rd(c_mm_file_reg_ppsh, 1, rd_data, tb_clk); + rd_ppsh_edge <= rd_data(31); + rd_ppsh_expected_cnt <= TO_UINT(rd_data(30 DOWNTO 0)); + + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT rd_ppsh_stable='0' REPORT "REG_PPHS wrong stable" SEVERITY ERROR; + ASSERT rd_ppsh_capture_cnt=c_ext_pps_period REPORT "REG_PPHS wrong capture count" SEVERITY ERROR; + ASSERT rd_ppsh_edge='0' REPORT "REG_PPHS wrong edge" SEVERITY ERROR; + ASSERT rd_ppsh_expected_cnt=c_extpected_cnt REPORT "REG_PPHS wrong capture count" SEVERITY ERROR; + + proc_common_wait_some_cycles(tb_clk, 10); + tb_end <= '1'; + WAIT; + END PROCESS; + +END tb;