diff --git a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_I/unb2c_test_1GbE_I.vhd b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_I/unb2c_test_1GbE_I.vhd index 5df27443699abb821c26211f077555e86edcc8fd..8fe2c8d809f201a13c179274d48bc3b081a745cf 100644 --- a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_I/unb2c_test_1GbE_I.vhd +++ b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_I/unb2c_test_1GbE_I.vhd @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------- -- --- Copyright (C) 2015 +-- Copyright (C) 2022 -- 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 @@ -20,6 +20,10 @@ -- ------------------------------------------------------------------------------- +-- Author: Eric Kooistra +-- Purpose: Test 1GbE-I port using eth_tester +-- Description: + LIBRARY IEEE, common_lib, unb2c_board_lib, unb2c_test_lib, technology_lib; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; diff --git a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/hdllib.cfg b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/hdllib.cfg new file mode 100644 index 0000000000000000000000000000000000000000..93f2cfd2d1fcbb058726abb1094786100b447788 --- /dev/null +++ b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/hdllib.cfg @@ -0,0 +1,111 @@ +hdl_lib_name = unb2c_test_1GbE_II +hdl_library_clause_name = unb2c_test_1GbE_II_lib +hdl_lib_uses_synth = common mm technology unb2c_board unb2c_test +hdl_lib_uses_sim = +hdl_lib_technology = ip_arria10_e2sg +hdl_lib_include_ip = + +synth_files = + unb2c_test_1GbE_II.vhd + +test_bench_files = + tb_unb2c_test_1GbE_II.vhd + +regression_test_vhdl = + + +[modelsim_project_file] +modelsim_copy_files = + + +[quartus_project_file] +synth_top_level_entity = + +quartus_copy_files = + quartus . + ../../quartus . + +quartus_qsf_files = + $RADIOHDL_WORK/boards/uniboard2c/libraries/unb2c_board/quartus/unb2c_board.qsf + +quartus_sdc_pre_files = + $RADIOHDL_WORK/boards/uniboard2c/libraries/unb2c_board/quartus/unb2c_board_pre.sdc + +quartus_sdc_files = + $RADIOHDL_WORK/boards/uniboard2c/libraries/unb2c_board/quartus/unb2c_board.sdc + +quartus_tcl_files = + quartus/unb2c_test_1GbE_II_pins.tcl + +quartus_vhdl_files = + +quartus_qip_files = + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/qsys_unb2c_test/qsys_unb2c_test.qip + +quartus_ip_files = + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_avs2_eth_coe_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_avs2_eth_coe_1.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_clk_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_jesd204b.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_jtag_uart_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_nios2_gen2_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_onchip_memory2_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_pio_jesd_ctrl.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_pio_pps.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_pio_system_info.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_pio_wdi.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_diag_bg_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_diag_data_buffer_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_diag_data_buffer_bsn.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_diag_data_buffer_ddr_MB_II.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_diag_data_buffer_ddr_MB_I.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_ram_scrap.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_bsn_monitor_10GbE.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_bsn_monitor_input.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_bsn_scheduler.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_bsn_source.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_bg_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_data_buffer_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_data_buffer_bsn.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_data_buffer_ddr_MB_II.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_data_buffer_ddr_MB_I.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_rx_seq_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_rx_seq_ddr_MB_II.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_rx_seq_ddr_MB_I.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_tx_seq_10gbe.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_tx_seq_ddr_MB_II.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_diag_tx_seq_ddr_MB_I.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_dpmm_ctrl.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_dpmm_data.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_epcs.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth10g_back0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth10g_back1.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth10g_qsfp_ring.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_fpga_temp_sens.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_fpga_voltage_sens.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_heater.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_io_ddr_MB_II.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_io_ddr_MB_I.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_mmdp_ctrl.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_mmdp_data.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_remu.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_tr_10GbE_back0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_tr_10GbE_back1.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_tr_10GbE_qsfp_ring.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_wdi.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_rom_system_info.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_timer_0.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_bg_ctrl.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_hdr_dat.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_bsn_monitor_v2_tx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_strobe_total_count_tx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_bsn_monitor_v2_rx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_I_strobe_total_count_rx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_bg_ctrl.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_hdr_dat.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_bsn_monitor_v2_tx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_bsn_monitor_v2_rx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_strobe_total_count_tx.ip + $RADIOHDL_BUILD_DIR/unb2c/quartus/unb2c_test_1GbE_II/ip/qsys_unb2c_test/qsys_unb2c_test_reg_eth1g_II_strobe_total_count_rx.ip + +nios2_app_userflags = -DCOMPILE_FOR_GEN2_UNB2 diff --git a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/quartus/unb2c_test_1GbE_II_pins.tcl b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/quartus/unb2c_test_1GbE_II_pins.tcl new file mode 100644 index 0000000000000000000000000000000000000000..ae417258f888c910d593c6ab6e5117615ebbd36f --- /dev/null +++ b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/quartus/unb2c_test_1GbE_II_pins.tcl @@ -0,0 +1,22 @@ +############################################################################### +# +# Copyright (C) 2014 +# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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/>. +# +############################################################################### + +source $::env(RADIOHDL_WORK)/boards/uniboard2c/libraries/unb2c_board/quartus/pinning/unb2c_minimal_pins.tcl diff --git a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/tb_unb2c_test_1GbE_II.vhd b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/tb_unb2c_test_1GbE_II.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fc35af7ba0e294874eb7bd5a57ba6e401401a871 --- /dev/null +++ b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/tb_unb2c_test_1GbE_II.vhd @@ -0,0 +1,83 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2022 +-- 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/>. +-- +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Author: E. Kooistra +-- Purpose: Tb to try loading design in simulator +-- Description: +-- Usage: +-- > run 1 us. + +LIBRARY IEEE; +USE IEEE.std_logic_1164.ALL; + + +ENTITY tb_unb2c_test_1GbE_II IS +END tb_unb2c_test_1GbE_II; + + +ARCHITECTURE tb OF tb_unb2c_test_1GbE_II IS + + SIGNAL clk : STD_LOGIC := '0'; + SIGNAL pps : STD_LOGIC := '0'; + SIGNAL wdi : STD_LOGIC := '0'; + + SIGNAL eth_clk : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; + SIGNAL eth_sgin : STD_LOGIC_VECTOR(1 DOWNTO 0); + SIGNAL eth_sgout : STD_LOGIC_VECTOR(1 DOWNTO 0); + +BEGIN + + clk <= NOT clk AFTER 5 ns; + eth_clk(0) <= NOT eth_clk(0) AFTER 8 ns; + eth_clk(1) <= NOT eth_clk(1) AFTER 8 ns; + + eth_sgin <= eth_sgout; -- loopback eth0 and eth1 + + u_unb2c_test_1GbE_II : ENTITY work.unb2c_test_1GbE_II + GENERIC MAP ( + g_sim => TRUE + ) + PORT MAP ( + -- GENERAL + CLK => clk, + PPS => pps, + WDI => wdi, + INTA => OPEN, + INTB => OPEN, + + -- Others + VERSION => "00", + ID => "00000000", + TESTIO => OPEN, + + + -- 1GbE Control Interface + ETH_CLK => eth_clk, + ETH_SGIN => eth_sgin, + ETH_SGOUT => eth_sgout, + + QSFP_LED => OPEN + ); + +END tb; + diff --git a/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/unb2c_test_1GbE_II.vhd b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/unb2c_test_1GbE_II.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8448d4f3167e3be5b38525bddd746b87345a191d --- /dev/null +++ b/boards/uniboard2c/designs/unb2c_test/revisions/unb2c_test_1GbE_II/unb2c_test_1GbE_II.vhd @@ -0,0 +1,105 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2022 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra +-- Purpose: Test both 1GbE-I and 1GbE-II ports using eth_tester +-- Description: + +LIBRARY IEEE, common_lib, unb2c_board_lib, unb2c_test_lib, technology_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE unb2c_board_lib.unb2c_board_pkg.ALL; +USE technology_lib.technology_pkg.ALL; + + +ENTITY unb2c_test_1GbE_II IS + GENERIC ( + g_design_name : STRING := "unb2c_test_1GbE_II"; + g_design_note : STRING := "Use Eth0 and Eth1"; + g_sim : BOOLEAN := FALSE; --Overridden by TB + g_sim_unb_nr : NATURAL := 0; + g_sim_node_nr : NATURAL := 0; + g_stamp_date : NATURAL := 0; -- Date (YYYYMMDD) -- set by QSF + g_stamp_time : NATURAL := 0; -- Time (HHMMSS) -- set by QSF + g_revision_id : STRING := "" -- revision ID -- set by QSF + ); + PORT ( + -- GENERAL + CLK : IN STD_LOGIC; -- System Clock + PPS : IN STD_LOGIC; -- System Sync + WDI : OUT STD_LOGIC; -- Watchdog Clear + INTA : INOUT STD_LOGIC; -- FPGA interconnect line + INTB : INOUT STD_LOGIC; -- FPGA interconnect line + + -- Others + VERSION : IN STD_LOGIC_VECTOR(c_unb2c_board_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(c_unb2c_board_aux.id_w-1 DOWNTO 0); + TESTIO : INOUT STD_LOGIC_VECTOR(c_unb2c_board_aux.testio_w-1 DOWNTO 0); + + + -- 1GbE Control Interface + ETH_CLK : IN STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0); + ETH_SGIN : IN STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0); + ETH_SGOUT : OUT STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0); + + QSFP_LED : OUT STD_LOGIC_VECTOR(c_unb2c_board_tr_qsfp_nof_leds-1 DOWNTO 0) + ); +END unb2c_test_1GbE_II; + + +ARCHITECTURE str OF unb2c_test_1GbE_II IS + +BEGIN + u_revision : ENTITY unb2c_test_lib.unb2c_test + GENERIC MAP ( + g_design_name => g_design_name, + g_design_note => g_design_note, + g_sim => g_sim, + g_sim_unb_nr => g_sim_unb_nr, + g_sim_node_nr => g_sim_node_nr, + g_stamp_date => g_stamp_date, + g_stamp_time => g_stamp_time, + g_revision_id => g_revision_id + ) + PORT MAP ( + -- GENERAL + CLK => CLK, + PPS => PPS, + WDI => WDI, + INTA => INTA, + INTB => INTB, + + -- Others + VERSION => VERSION, + ID => ID, + TESTIO => TESTIO, + + + -- 1GbE Control Interface + ETH_clk => ETH_clk, + ETH_SGIN => ETH_SGIN, + ETH_SGOUT => ETH_SGOUT, + + QSFP_LED => QSFP_LED + ); +END str; diff --git a/boards/uniboard2c/designs/unb2c_test/src/vhdl/mmm_unb2c_test.vhd b/boards/uniboard2c/designs/unb2c_test/src/vhdl/mmm_unb2c_test.vhd index cb6ec2cfe0e446e3715c51d3fca55246da38d3f8..2b921773c05e099b2ddf736cbe505fdef765e7e1 100644 --- a/boards/uniboard2c/designs/unb2c_test/src/vhdl/mmm_unb2c_test.vhd +++ b/boards/uniboard2c/designs/unb2c_test/src/vhdl/mmm_unb2c_test.vhd @@ -344,11 +344,17 @@ BEGIN PORT MAP(mm_rst, mm_clk, ram_diag_data_buf_ddr_MB_II_mosi, ram_diag_data_buf_ddr_MB_II_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_eth0 : 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") + -- . 1GbE_I with TSE setup by NiosII + u_mm_file_reg_eth0_tse : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_0_TSE") + PORT MAP(mm_rst, mm_clk, eth1g_eth0_tse_mosi, eth1g_eth0_tse_miso); + u_mm_file_reg_eth0_reg : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_0_REG") PORT MAP(mm_rst, mm_clk, i_eth1g_eth0_reg_mosi, eth1g_eth0_reg_miso); - u_mm_file_reg_eth1 : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_1_MMS_REG") - PORT MAP(mm_rst, mm_clk, i_eth1g_eth1_reg_mosi, eth1g_eth1_reg_miso); - + u_mm_file_reg_eth0_ram : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_0_RAM") + PORT MAP(mm_rst, mm_clk, eth1g_eth0_ram_mosi, eth1g_eth0_ram_miso); + -- . 1GbE_II with TSE setup in VHDL + u_mm_file_reg_eth1_tse : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "AVS_ETH_1_TSE") + PORT MAP(mm_rst, mm_clk, eth1g_eth1_tse_mosi, eth1g_eth1_tse_miso); + u_mm_file_reg_tr_10GbE_qsfp_ring : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_TR_10GBE_QSFP_RING") PORT MAP(mm_rst, mm_clk, reg_tr_10GbE_qsfp_ring_mosi, reg_tr_10GbE_qsfp_ring_miso); u_mm_file_reg_tr_10GbE_back0 : mm_file GENERIC MAP(mmf_unb_file_prefix(g_sim_unb_nr, c_sim_node_nr, c_sim_node_type) & "REG_TR_10GBE_BACK0") diff --git a/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test.vhd b/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test.vhd index 8f3ed66cbfd0bba15b5484e037cc4c131816f49e..69aecc3a18e148fd872483a5f087393aa203955c 100644 --- a/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test.vhd +++ b/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test.vhd @@ -268,15 +268,10 @@ ARCHITECTURE str OF unb2c_test IS SIGNAL eth1g_eth0_ram_mosi : t_mem_mosi; -- ETH rx frame and tx frame memory SIGNAL eth1g_eth0_ram_miso : t_mem_miso; - -- eth1g ch1 + -- eth1g ch1 (eth_stream only has MM for TSE MAC) SIGNAL eth1g_eth1_mm_rst : STD_LOGIC; SIGNAL eth1g_eth1_tse_mosi : t_mem_mosi; -- ETH TSE MAC registers SIGNAL eth1g_eth1_tse_miso : t_mem_miso; - SIGNAL eth1g_eth1_reg_mosi : t_mem_mosi; -- ETH control and status registers - SIGNAL eth1g_eth1_reg_miso : t_mem_miso; - SIGNAL eth1g_eth1_reg_interrupt : STD_LOGIC; -- Interrupt - SIGNAL eth1g_eth1_ram_mosi : t_mem_mosi; -- ETH rx frame and tx frame memory - SIGNAL eth1g_eth1_ram_miso : t_mem_miso; -- EPCS read SIGNAL reg_dpmm_data_mosi : t_mem_mosi; @@ -648,7 +643,7 @@ BEGIN reg_ppsh_mosi => reg_ppsh_mosi, reg_ppsh_miso => reg_ppsh_miso, - -- eth1g ch0 + -- eth1g ch0 = 1GbE_I eth1g_eth0_mm_rst => eth1g_eth0_mm_rst, eth1g_eth0_tse_mosi => eth1g_eth0_tse_mosi, eth1g_eth0_tse_miso => eth1g_eth0_tse_miso, @@ -672,15 +667,15 @@ BEGIN reg_eth1g_I_strobe_total_count_rx_copi => reg_eth1g_I_strobe_total_count_rx_copi, reg_eth1g_I_strobe_total_count_rx_cipo => reg_eth1g_I_strobe_total_count_rx_cipo, - -- eth1g ch1 + -- eth1g ch1 = 1GbE_II eth1g_eth1_mm_rst => eth1g_eth1_mm_rst, eth1g_eth1_tse_mosi => eth1g_eth1_tse_mosi, eth1g_eth1_tse_miso => eth1g_eth1_tse_miso, - eth1g_eth1_reg_mosi => eth1g_eth1_reg_mosi, - eth1g_eth1_reg_miso => eth1g_eth1_reg_miso, - eth1g_eth1_reg_interrupt => eth1g_eth1_reg_interrupt, - eth1g_eth1_ram_mosi => eth1g_eth1_ram_mosi, - eth1g_eth1_ram_miso => eth1g_eth1_ram_miso, + eth1g_eth1_reg_mosi => OPEN, + eth1g_eth1_reg_miso => c_mem_cipo_rst, + eth1g_eth1_reg_interrupt => '0', + eth1g_eth1_ram_mosi => OPEN, + eth1g_eth1_ram_miso => c_mem_cipo_rst, reg_eth1g_II_bg_ctrl_copi => reg_eth1g_II_bg_ctrl_copi, reg_eth1g_II_bg_ctrl_cipo => reg_eth1g_II_bg_ctrl_cipo, @@ -805,10 +800,12 @@ BEGIN gen_udp_stream_1GbE : IF c_use_1GbE_I_UDP = TRUE GENERATE + -- Derive MAC/IP/UDP from gn_index gn_eth_src_mac_I <= c_base_mac & func_eth_tester_gn_index_to_mac_15_0(gn_index, 0); gn_ip_src_addr_I <= c_base_ip & func_eth_tester_gn_index_to_ip_15_0(gn_index, 0); gn_udp_src_port_I <= c_base_udp & func_eth_tester_gn_index_to_udp_7_0(gn_index, 0); + -- Generate UDP Tx and monitor UDP Rx u_eth_tester_I : ENTITY eth_lib.eth_tester GENERIC MAP ( g_nof_streams => c_nof_udp_streams_1GbE_I, @@ -852,58 +849,21 @@ BEGIN reg_strobe_total_count_rx_copi => reg_eth1g_I_strobe_total_count_rx_copi, reg_strobe_total_count_rx_cipo => reg_eth1g_I_strobe_total_count_rx_cipo ); + + -- Uses eth.vhd with ETH/TSE interface with UDP streams in ctrl_unb2c_board + -- to stream UDP data via eth0 = 1GbE-I. END GENERATE; - -- Instantiate a second 1GbE to check pinning + -- Instantiate a second 1GbE-II to check pinning and to test UDP data via a + -- dedicated 1GbE port, instead of multiplexed with M&C gen_eth_II: IF c_use_1GbE_II = TRUE GENERATE - - u_eth : ENTITY eth_lib.eth - GENERIC MAP ( - g_technology => g_technology, - g_init_ip_address => c_base_ip & X"0000", -- Last two bytes set by board/FPGA ID. - g_cross_clock_domain => TRUE, - g_frm_discard_en => TRUE - ) - PORT MAP ( - -- Clocks and reset - mm_rst => mm_rst, -- use reset from QSYS - mm_clk => mm_clk, -- use mm_clk direct - --eth_clk => xo_ethclk, -- 125 MHz clock - eth_clk => ETH_CLK(1), - st_rst => dp_rst, - st_clk => dp_clk, - - -- UDP transmit interface - udp_tx_snk_in_arr => (others => c_dp_sosi_rst), - udp_tx_snk_out_arr => open, - -- UDP receive interface - udp_rx_src_in_arr => (others => c_dp_siso_rdy), - udp_rx_src_out_arr => open, - - -- Memory Mapped Slaves - tse_sla_in => c_mem_mosi_rst, - tse_sla_out => open, - reg_sla_in => c_mem_mosi_rst, - reg_sla_out => open, - reg_sla_interrupt => open, - ram_sla_in => c_mem_mosi_rst, - ram_sla_out => open, - - -- PHY interface - eth_txp => ETH_SGOUT(1), - eth_rxp => ETH_SGIN(1), - - -- LED interface - tse_led => open - ); - - -- TODO: Add control and connect for second 1GbE - + -- Derive eth1 MAC/IP/UDP from eth0 gn_eth_src_mac_II <= c_base_mac & func_eth_tester_gn_index_to_mac_15_0(gn_index, 1); gn_ip_src_addr_II <= c_base_ip & func_eth_tester_gn_index_to_ip_15_0(gn_index, 1); gn_udp_src_port_II <= c_base_udp & func_eth_tester_gn_index_to_udp_7_0(gn_index, 1); + -- Generate UDP Tx and monitor UDP Rx u_eth_tester_II : ENTITY eth_lib.eth_tester GENERIC MAP ( g_nof_streams => c_nof_udp_streams_1GbE_II, @@ -947,6 +907,48 @@ BEGIN reg_strobe_total_count_rx_copi => reg_eth1g_II_strobe_total_count_rx_copi, reg_strobe_total_count_rx_cipo => reg_eth1g_II_strobe_total_count_rx_cipo ); + + -- Use eth_stream with ETH/TSE interface for UDP port g_rx_udp_port to + -- stream UDP data via eth1 = 1GbE-II + u_eth_stream : ENTITY eth_lib.eth_stream + GENERIC MAP ( + g_technology => g_technology, + g_rx_udp_port => TO_UINT(c_eth_rx_udp_port), -- = 0x1771 = 6001 + g_jumbo_en => FALSE, + g_sim => g_sim, + g_sim_level => 1 -- 0 = use IP model (equivalent to g_sim = FALSE); 1 = use fast serdes model; + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, -- eth1g_eth1_mm_rst + mm_clk => mm_clk, + eth_clk => ETH_CLK(1), + st_rst => dp_rst, + st_clk => dp_clk, + + -- TSE setup + src_mac => gn_eth_src_mac_II, + setup_done => OPEN, + + -- UDP transmit interface + udp_tx_snk_in => eth1g_II_udp_tx_sosi_arr(0), + udp_tx_snk_out => eth1g_II_udp_tx_siso_arr(0), + + -- UDP receive interface + udp_rx_src_in => c_dp_siso_rdy, + udp_rx_src_out => eth1g_II_udp_rx_sosi_arr(0), + + -- Memory Mapped Slaves + tse_ctlr_copi => eth1g_eth1_tse_mosi, + tse_ctlr_cipo => eth1g_eth1_tse_miso, + + -- PHY interface + eth_txp => ETH_SGOUT(1), + eth_rxp => ETH_SGIN(1), + + -- LED interface + tse_led => OPEN + ); END GENERATE; diff --git a/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test_pkg.vhd b/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test_pkg.vhd index 59c3a9e1cad55c33614bd63587ede07a56104089..af5abbd581802a09607b7494b929966e3713a403 100644 --- a/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test_pkg.vhd +++ b/boards/uniboard2c/designs/unb2c_test/src/vhdl/unb2c_test_pkg.vhd @@ -76,18 +76,20 @@ PACKAGE unb2c_test_pkg IS type_MB_I : t_c_tech_ddr; type_MB_II : t_c_tech_ddr; END RECORD; + -- loop 1GbE 1GbE qsfp ring bk0 jesd DDR4 DDR4 heatr - CONSTANT c_test_minimal : t_unb2c_test_config := (FALSE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); - CONSTANT c_test_10GbE : t_unb2c_test_config := (FALSE, TRUE, TRUE, TRUE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); - CONSTANT c_test_10GbE_qb : t_unb2c_test_config := (FALSE, TRUE, TRUE, TRUE,FALSE, TRUE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); - CONSTANT c_test_ddr : t_unb2c_test_config := (FALSE, TRUE, TRUE,FALSE,FALSE,FALSE,FALSE, TRUE, TRUE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); - CONSTANT c_test_heater : t_unb2c_test_config := (FALSE, TRUE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); - CONSTANT c_test_jesd204b : t_unb2c_test_config := (FALSE, TRUE, TRUE,FALSE,FALSE,FALSE, TRUE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_minimal : t_unb2c_test_config := (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_1GbE_I_UDP : t_unb2c_test_config := (FALSE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_1GbE_II_UDP : t_unb2c_test_config := (FALSE, TRUE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_10GbE : t_unb2c_test_config := (FALSE,FALSE,FALSE, TRUE, TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_10GbE_qb : t_unb2c_test_config := (FALSE,FALSE,FALSE, TRUE,FALSE, TRUE,FALSE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_ddr : t_unb2c_test_config := (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE, TRUE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_heater : t_unb2c_test_config := (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); + CONSTANT c_test_jesd204b : t_unb2c_test_config := (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, TRUE,FALSE,FALSE,FALSE,c_tech_ddr4_8g_1600m, c_tech_ddr4_8g_1600m); -- Function to select the revision configuration. FUNCTION func_sel_revision_rec(g_design_name : STRING) RETURN t_unb2c_test_config; - END unb2c_test_pkg; @@ -95,10 +97,12 @@ PACKAGE BODY unb2c_test_pkg IS FUNCTION func_sel_revision_rec(g_design_name : STRING) RETURN t_unb2c_test_config IS BEGIN - IF g_design_name = "unb2c_test_10GbE" THEN RETURN c_test_10GbE; - ELSIF g_design_name = "unb2c_test_ddr" THEN RETURN c_test_ddr; - ELSIF g_design_name = "unb2c_test_heater" THEN RETURN c_test_heater; - ELSIF g_design_name = "unb2c_test_jesd204b" THEN RETURN c_test_jesd204b; + IF g_design_name = "unb2c_test_10GbE" THEN RETURN c_test_10GbE; + ELSIF g_design_name = "unb2c_test_ddr" THEN RETURN c_test_ddr; + ELSIF g_design_name = "unb2c_test_heater" THEN RETURN c_test_heater; + ELSIF g_design_name = "unb2c_test_jesd204b" THEN RETURN c_test_jesd204b; + ELSIF g_design_name = "unb2c_test_1GbE_I" THEN RETURN c_test_1GbE_I_UDP; + ELSIF g_design_name = "unb2c_test_1GbE_II" THEN RETURN c_test_1GbE_II_UDP; ELSE RETURN c_test_minimal; END IF; END; diff --git a/boards/uniboard2c/designs/unb2c_test/unb2c_test.fpga.yaml b/boards/uniboard2c/designs/unb2c_test/unb2c_test.fpga.yaml index 0b33ed4c02331e284be62af8c60356aebc66870d..0b9e4ee9e907f520e4536c7349178049645881b4 100644 --- a/boards/uniboard2c/designs/unb2c_test/unb2c_test.fpga.yaml +++ b/boards/uniboard2c/designs/unb2c_test/unb2c_test.fpga.yaml @@ -6,9 +6,8 @@ hdl_library_name: unb2c_test fpga_name : unb2c_test fpga_description: "FPGA design unb2c_test" parameters: - - { name: c_nof_streams_1GbE_UDP, value: 2 } - - { name: c_def_1GbE_block_size, value: 20 } - - { name: c_nof_streams_10GbE_UDP, value: 72 } + - { name: c_nof_streams_eth0_UDP, value: 4 } + - { name: c_nof_streams_10GbE_UDP, value: 72 } - { name: c_def_10GbE_block_size, value: 900 } - { name: c_nof_streams_qsfp, value: 24 } - { name: c_nof_streams_ring, value: 24 } @@ -39,6 +38,7 @@ peripherals: - RAM_SCRAP - peripheral_name: eth/eth + peripheral_group: eth0 mm_port_names: - AVS_ETH_0_TSE - AVS_ETH_0_REG @@ -71,47 +71,106 @@ peripherals: mm_port_names: - REG_HEATER - # 1GbE + # 1GbE-I - peripheral_name: diag/diag_block_gen - peripheral_group: eth_1gbe + peripheral_group: eth0_tx parameter_overrides: - - { name: g_nof_streams, value: c_nof_streams_1GbE_UDP } - - { name: g_buf_dat_w, value: 32 } - - { name: g_buf_addr_w, value: ceil_log2(c_def_1GbE_block_size) } + - { name: g_nof_streams, value: c_nof_streams_eth0_UDP } + - { name: g_nof_reg, value: c_nof_streams_eth0_UDP } + - { name: g_buf_addr_w, value: 8 } mm_port_names: - - REG_DIAG_BG_1GBE - - RAM_DIAG_BG_1GBE + - REG_ETH1G_I_BG_CTRL + - RAM_ETH1G_I_BG_CTRL # not used in eth_tester_tx - - peripheral_name: diag/diag_tx_seq - peripheral_group: eth_1gbe + - peripheral_name: eth_tester_offload_hdr_dat + peripheral_group: eth0_tx + number_of_peripherals: c_nof_streams_eth0_UDP + peripheral_span: ceil_pow2(c_nof_streams_eth0_UDP) * 32 * MM_BUS_SIZE # number_of_ports = 4, mm_port_span = 32 words + mm_port_names: + - REG_ETH1G_I_HDR_DAT + + - peripheral_name: dp/dp_bsn_monitor_v2 + peripheral_group: eth0_tx parameter_overrides: - - { name: g_nof_streams, value: c_nof_streams_1GbE_UDP } + - { name: g_nof_streams, value: c_nof_streams_eth0_UDP } mm_port_names: - - REG_DIAG_TX_SEQ_1GBE + - REG_ETH1G_I_BSN_MONITOR_V2_TX - - peripheral_name: dp/dp_bsn_monitor - peripheral_group: eth_1gbe + - peripheral_name: dp/dp_strobe_total_count + peripheral_group: eth0_tx + number_of_peripherals: c_nof_streams_eth0_UDP + peripheral_span: ceil_pow2(c_nof_streams_eth0_UDP) * 32 * MM_BUS_SIZE # number_of_ports = 4, mm_port_span = 32 words parameter_overrides: - - { name: g_nof_streams, value: c_nof_streams_1GbE_UDP } + - { name: g_nof_counts, value: 1 } # actual nof counts, <= g_nof_counts_max = 15 + # 0 = nof_sop mm_port_names: - - REG_BSN_MONITOR_1GBE + - REG_ETH1G_I_STROBE_TOTAL_COUNT_TX - - peripheral_name: diag/diag_data_buffer - peripheral_group: eth_1gbe + - peripheral_name: dp/dp_bsn_monitor_v2 + peripheral_group: eth0_rx parameter_overrides: - - { name: g_nof_streams, value: c_nof_streams_1GbE_UDP } - - { name: g_data_w, value: 32 } - - { name: g_nof_data, value: c_def_1GbE_block_size } + - { name: g_nof_streams, value: c_nof_streams_eth0_UDP } mm_port_names: - - REG_DIAG_DATA_BUFFER_1GBE - - RAM_DIAG_DATA_BUFFER_1GBE + - REG_ETH1G_I_BSN_MONITOR_V2_RX - - peripheral_name: diag/diag_rx_seq - peripheral_group: eth_1gbe + - peripheral_name: dp/dp_strobe_total_count + peripheral_group: eth0_rx + number_of_peripherals: c_nof_streams_eth0_UDP + peripheral_span: ceil_pow2(c_nof_streams_eth0_UDP) * 32 * MM_BUS_SIZE # number_of_ports = 4, mm_port_span = 32 words + parameter_overrides: + - { name: g_nof_counts, value: 3 } # actual nof counts, <= g_nof_counts_max = 15 + # 0 = nof_sop, 1 = nof_valid, 2 = nof_crc_corrupt + mm_port_names: + - REG_ETH1G_I_STROBE_TOTAL_COUNT_RX + + # 1GbE-II + - peripheral_name: eth/eth # eth_stream + peripheral_group: eth1 + mm_port_names: + - AVS_ETH_1_TSE + - AVS_ETH_1_REG # not used for eth_stream + - AVS_ETH_1_RAM # not used for eth_stream + + - peripheral_name: diag/diag_block_gen + peripheral_group: eth1_tx + parameter_overrides: + - { name: g_nof_streams, value: 1 } + - { name: g_nof_reg, value: 1 } + - { name: g_buf_addr_w, value: 8 } + mm_port_names: + - REG_ETH1G_I_BG_CTRL + - RAM_ETH1G_I_BG_CTRL # not used in eth_tester_tx + + - peripheral_name: eth_tester_offload_hdr_dat + peripheral_group: eth1_tx + mm_port_names: + - REG_ETH1G_I_HDR_DAT + + - peripheral_name: dp/dp_bsn_monitor_v2 + peripheral_group: eth1_tx + mm_port_names: + - REG_ETH1G_I_BSN_MONITOR_V2_TX + + - peripheral_name: dp/dp_strobe_total_count + peripheral_group: eth1_tx + parameter_overrides: + - { name: g_nof_counts, value: 1 } # actual nof counts, <= g_nof_counts_max = 15 + # 0 = nof_sop + mm_port_names: + - REG_ETH1G_I_STROBE_TOTAL_COUNT_TX + + - peripheral_name: dp/dp_bsn_monitor_v2 + peripheral_group: eth1_rx + mm_port_names: + - REG_ETH1G_I_BSN_MONITOR_V2_RX + + - peripheral_name: dp/dp_strobe_total_count + peripheral_group: eth1_rx parameter_overrides: - - { name: g_nof_streams, value: c_nof_streams_1GbE_UDP } + - { name: g_nof_counts, value: 3 } # actual nof counts, <= g_nof_counts_max = 15 + # 0 = nof_sop, 1 = nof_valid, 2 = nof_crc_corrupt mm_port_names: - - REG_DIAG_TX_SEQ_1GBE + - REG_ETH1G_I_STROBE_TOTAL_COUNT_RX # 10GbE - peripheral_name: diag/diag_block_gen diff --git a/doc/erko_howto_tools.txt b/doc/erko_howto_tools.txt index 429197e7d13e277f1e30b4d0081f425d09625b9e..c71e6e5067699dfe22e55fe6a16e28c286d721f5 100755 --- a/doc/erko_howto_tools.txt +++ b/doc/erko_howto_tools.txt @@ -128,14 +128,27 @@ during tb simulation load --> fixed by "sudo chmod a+w -R modelsim_altera_libs/1 revision build quartus dir, so all revisions use the same qsys. +# Run command line synthesis for unb2c_test revision +quartus_config unb2c +run_qsys_pro unb2c unb2c_test_1GbE_I; +gen_rom_mmap.py --avalon -d unb2c_test -r unb2c_test_1GbE_I +run_reg unb2c unb2c_test_1GbE_I +run_qcomp unb2c unb2c_test_1GbE_I --clk=CLK +run_rbf unb2c unb2c_test_1GbE_I +quartus_config unb2c +run_qsys_pro unb2c unb2c_test_1GbE_II; +gen_rom_mmap.py --avalon -d unb2c_test -r unb2c_test_1GbE_II +run_reg unb2c unb2c_test_1GbE_II +run_qcomp unb2c unb2c_test_1GbE_II --clk=CLK +run_rbf unb2c unb2c_test_1GbE_II # Run command line synthesis for dts quartus_config unb2c run_qsys_pro unb2c lofar2_unb2c_sdp_station_full; gen_rom_mmap.py --avalon -d lofar2_unb2c_sdp_station -r lofar2_unb2c_sdp_station_full; run_reg unb2c lofar2_unb2c_sdp_station_full; -run_qcomp unb2c lofar2_unb2c_sdp_station_full --clk=CLK; +run_qcomp unb2c lofar2_unb2c_sdp_station_full --clk=CLK run_rbf unb2c lofar2_unb2c_sdp_station_full # Run command line synthesis for sdp-arts diff --git a/libraries/base/common/src/vhdl/common_mem_pkg.vhd b/libraries/base/common/src/vhdl/common_mem_pkg.vhd index 27fcd79466c332fc6ece560e5c5cc34b616407ca..dd26500d83613818ffad93645f699eaf5a229ff3 100644 --- a/libraries/base/common/src/vhdl/common_mem_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_mem_pkg.vhd @@ -109,7 +109,27 @@ PACKAGE common_mem_pkg IS FUNCTION RESIZE_MEM_UDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- unsigned FUNCTION RESIZE_MEM_SDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- sign extended FUNCTION RESIZE_MEM_XDATA( vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR; -- set unused MSBits to 'X' - + + ------------------------------------------------------------------------------ + -- Procedures to access MM bus + -- . no mm_clk, combinatoral inputs only, to allow use in a state machine + -- . similar proc_mem_mm_bus_*() procs in tb_common_mem_pkg.vhd do have + -- mm_clk inputs + -- . if mm_copi.waitrequest is used, then issue the MM access and externaly + -- check and wait for mm_copi.waitrequest = '0' before removing the MM + -- access. + ------------------------------------------------------------------------------ + PROCEDURE proc_mem_bus_wr(CONSTANT wr_addr : IN NATURAL; + CONSTANT wr_data : IN INTEGER; + SIGNAL mm_copi : OUT t_mem_copi); + + PROCEDURE proc_mem_bus_wr(CONSTANT wr_addr : IN NATURAL; + CONSTANT wr_data : IN STD_LOGIC_VECTOR; + SIGNAL mm_copi : OUT t_mem_copi); + + PROCEDURE proc_mem_bus_rd(CONSTANT wr_addr : IN NATURAL; + SIGNAL mm_copi : OUT t_mem_copi); + ------------------------------------------------------------------------------ -- Burst memory access (for DDR access interface) ------------------------------------------------------------------------------ @@ -279,7 +299,32 @@ PACKAGE BODY common_mem_pkg IS v_vec(vec'LENGTH-1 DOWNTO 0) := vec; RETURN v_vec; END RESIZE_MEM_XDATA; - + + -- Procedures to access MM bus + PROCEDURE proc_mem_bus_wr(CONSTANT wr_addr : IN NATURAL; + CONSTANT wr_data : IN INTEGER; + SIGNAL mm_copi : OUT t_mem_copi) IS + BEGIN + mm_copi.address <= TO_MEM_ADDRESS(wr_addr); + mm_copi.wrdata <= TO_MEM_DATA(wr_data); + mm_copi.wr <= '1'; + END proc_mem_bus_wr; + + PROCEDURE proc_mem_bus_wr(CONSTANT wr_addr : IN NATURAL; + CONSTANT wr_data : IN STD_LOGIC_VECTOR; + SIGNAL mm_copi : OUT t_mem_copi) IS + BEGIN + mm_copi.address <= TO_MEM_ADDRESS(wr_addr); + mm_copi.wrdata <= RESIZE_MEM_DATA(wr_data); + mm_copi.wr <= '1'; + END proc_mem_bus_wr; + + PROCEDURE proc_mem_bus_rd(CONSTANT wr_addr : IN NATURAL; + SIGNAL mm_copi : OUT t_mem_copi) IS + BEGIN + mm_copi.address <= TO_MEM_ADDRESS(wr_addr); + mm_copi.rd <= '1'; + END proc_mem_bus_rd; -- Resize functions to fit an integer or an SLV in the corresponding t_mem_miso or t_mem_mosi field width FUNCTION TO_MEM_CTLR_ADDRESS(n : INTEGER) RETURN STD_LOGIC_VECTOR IS diff --git a/libraries/base/diag/diag.peripheral.yaml b/libraries/base/diag/diag.peripheral.yaml index ec4f28671473375570d764b2d7df883483f142e3..5b7932ea9733695a5b0d3ad31e965bfdcfc836d0 100644 --- a/libraries/base/diag/diag.peripheral.yaml +++ b/libraries/base/diag/diag.peripheral.yaml @@ -100,10 +100,11 @@ peripherals: user_width: g_data_w - peripheral_name: diag_block_gen # pi_diag_block_gen.py - peripheral_description: "Block generator (BG)" + peripheral_description: "Block generator (BG) with g_nof_reg = 1 reg shared by all streams or g_nof_reg = g_nof_streams to have one reg per stream" parameters: # Parameters of mms_diag_block_gen.vhd - { name: g_nof_streams, value: 1 } + - { name: g_nof_reg, value: 1 } - { name: g_buf_dat_w, value: 16 } - { name: g_buf_addr_w, value: 7 } mm_ports: @@ -112,7 +113,7 @@ peripherals: mm_port_type: REG mm_port_span: 8 * MM_BUS_SIZE mm_port_description: "Block generator control." - number_of_mm_ports: 1 + number_of_mm_ports: g_nof_reg fields: - - field_name: enable field_description: "Starts the block generator." diff --git a/libraries/base/dp/dp.peripheral.yaml b/libraries/base/dp/dp.peripheral.yaml index 6d38ee172529145bc9e302121ef92abc0b6b0f41..23ed67a9ea89b4d4af72a7c355e6e2ecb07e24b6 100644 --- a/libraries/base/dp/dp.peripheral.yaml +++ b/libraries/base/dp/dp.peripheral.yaml @@ -451,7 +451,7 @@ peripherals: # MM port for dp_strobe_total_count.vhd - mm_port_name: REG_DP_STROBE_TOTAL_COUNT mm_port_type: REG - mm_port_span: ceil_pow2(g_nof_counts_max*2 + 1) * MM_BUS_SIZE + mm_port_span: ceil_pow2(g_nof_counts_max*2 + 1) * MM_BUS_SIZE # = 32 * MM_BUS_SIZE mm_port_description: "" fields: - - field_name: counts diff --git a/libraries/base/dp/src/vhdl/dp_fifo_core.vhd b/libraries/base/dp/src/vhdl/dp_fifo_core.vhd index 083fd11c107e8efa6570a5e4b7ad7c09839be0eb..c8f9cb39db358df72a7a0fbd4ab161343a341e54 100644 --- a/libraries/base/dp/src/vhdl/dp_fifo_core.vhd +++ b/libraries/base/dp/src/vhdl/dp_fifo_core.vhd @@ -111,7 +111,7 @@ ARCHITECTURE str OF dp_fifo_core IS SIGNAL fifo_wr_dat : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0); SIGNAL fifo_wr_req : STD_LOGIC; SIGNAL fifo_wr_ful : STD_LOGIC; - SIGNAL wr_init : STD_LOGIC := '0'; + SIGNAL wr_init : STD_LOGIC := '0'; SIGNAL fifo_wr_usedw : STD_LOGIC_VECTOR(wr_usedw'RANGE); SIGNAL fifo_rd_dat : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0) := (OTHERS=>'0'); @@ -191,6 +191,7 @@ BEGIN usedw => fifo_rd_usedw ); + wr_init <= '0'; -- to avoid no driver warning in synthesis fifo_wr_usedw <= fifo_rd_usedw; END GENERATE; diff --git a/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd b/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd index 62ddba22104d5a5ff2ba355a63bbe5150b39a20e..9d904f89e2cf577428a406bc5ee0fb2b1530b9f6 100644 --- a/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd +++ b/libraries/base/dp/src/vhdl/dp_fifo_fill_eop.vhd @@ -224,8 +224,7 @@ BEGIN -- No need to transfer eop counter across clock domains for single clock gen_rd_eop_cnt_sc : IF g_use_dual_clock=FALSE GENERATE - wr_fifo_usedw <= rd_fifo_usedw; - rd_eop_new <= '1'; + rd_eop_new <= '1'; END GENERATE; -- Set rd_eop_cnt outside generate statements to avoid Modelsim warning "Nonresolved signal 'rd_eop_cnt' may have multiple sources". diff --git a/libraries/base/dp/src/vhdl/dp_stream_pkg.vhd b/libraries/base/dp/src/vhdl/dp_stream_pkg.vhd index 537d5871db8aab4bd9035a22f9567097feff51de..ecd2e6b6fea23856b16269dfba6fa2203f4f6eb3 100644 --- a/libraries/base/dp/src/vhdl/dp_stream_pkg.vhd +++ b/libraries/base/dp/src/vhdl/dp_stream_pkg.vhd @@ -272,6 +272,12 @@ PACKAGE dp_stream_pkg Is FUNCTION TO_DP_SOSI_UNSIGNED(sync, valid, sop, eop : STD_LOGIC; bsn, data, re, im, empty, channel, err : UNSIGNED) RETURN t_dp_sosi_unsigned; + -- Map between array and single element + FUNCTION TO_DP_ARR(sosi : t_dp_sosi) RETURN t_dp_sosi_arr; + FUNCTION TO_DP_ARR(siso : t_dp_siso) RETURN t_dp_siso_arr; + FUNCTION TO_DP_ONE(sosi_arr : t_dp_sosi_arr) RETURN t_dp_sosi; + FUNCTION TO_DP_ONE(siso_arr : t_dp_siso_arr) RETURN t_dp_siso; + -- Keep part of head data and combine part of tail data, use the other sosi from head_sosi FUNCTION func_dp_data_shift_first(head_sosi, tail_sosi : t_dp_sosi; symbol_w, nof_symbols_per_data, nof_symbols_from_tail : NATURAL) RETURN t_dp_sosi; -- Shift and combine part of previous data and this data, use the other sosi from prev_sosi @@ -638,6 +644,30 @@ PACKAGE BODY dp_stream_pkg IS RETURN v_sosi_unsigned; END TO_DP_SOSI_UNSIGNED; + -- Map between array and single element + FUNCTION TO_DP_ARR(sosi : t_dp_sosi) RETURN t_dp_sosi_arr IS + VARIABLE v_sosi_arr : t_dp_sosi_arr(0 DOWNTO 0) := (OTHERS => sosi); + BEGIN + RETURN v_sosi_arr; + END TO_DP_ARR; + + FUNCTION TO_DP_ARR(siso : t_dp_siso) RETURN t_dp_siso_arr IS + VARIABLE v_siso_arr : t_dp_siso_arr(0 DOWNTO 0) := (OTHERS => siso); + BEGIN + RETURN v_siso_arr; + END TO_DP_ARR; + + FUNCTION TO_DP_ONE(sosi_arr : t_dp_sosi_arr) RETURN t_dp_sosi IS + BEGIN + RETURN sosi_arr(0); + END TO_DP_ONE; + + FUNCTION TO_DP_ONE(siso_arr : t_dp_siso_arr) RETURN t_dp_siso IS + BEGIN + RETURN siso_arr(0); + END TO_DP_ONE; + + -- Keep part of head data and combine part of tail data FUNCTION func_dp_data_shift_first(head_sosi, tail_sosi : t_dp_sosi; symbol_w, nof_symbols_per_data, nof_symbols_from_tail : NATURAL) RETURN t_dp_sosi IS VARIABLE vN : NATURAL := nof_symbols_per_data; diff --git a/libraries/io/eth/hdllib.cfg b/libraries/io/eth/hdllib.cfg index 11d97855c2d2c66fc69d0db9120c34e4d56095d3..39fcfc924d6665a6a0352057d1689ac17fb4937a 100644 --- a/libraries/io/eth/hdllib.cfg +++ b/libraries/io/eth/hdllib.cfg @@ -22,6 +22,8 @@ synth_files = src/vhdl/eth_control.vhd src/vhdl/eth_ihl_to_20.vhd src/vhdl/eth.vhd + src/vhdl/eth_stream_udp.vhd + src/vhdl/eth_stream.vhd src/vhdl/eth_tester_pkg.vhd src/vhdl/eth_tester_tx.vhd src/vhdl/eth_tester_rx.vhd @@ -35,8 +37,10 @@ test_bench_files = tb/vhdl/tb_eth.vhd tb/vhdl/tb_eth_tester_pkg.vhd tb/vhdl/tb_eth_tester.vhd + tb/vhdl/tb_eth_stream_udp.vhd tb/vhdl/tb_tb_eth.vhd tb/vhdl/tb_tb_eth_tester.vhd + tb/vhdl/tb_tb_eth_stream_udp.vhd tb/vhdl/tb_eth_udp_offload.vhd tb/vhdl/tb_eth_ihl_to_20.vhd tb/vhdl/tb_tb_tb_eth_regression.vhd @@ -49,6 +53,7 @@ regression_test_vhdl = tb/vhdl/tb_eth_ihl_to_20.vhd tb/vhdl/tb_tb_eth.vhd tb/vhdl/tb_tb_eth_tester.vhd + tb/vhdl/tb_tb_eth_stream_udp.vhd [modelsim_project_file] diff --git a/libraries/io/eth/src/vhdl/eth_pkg.vhd b/libraries/io/eth/src/vhdl/eth_pkg.vhd index eb4f556c1b29f3bd5bc7cb8f949bda396653bc28..632bbb7af95e91fa12763f67831023472e48846d 100644 --- a/libraries/io/eth/src/vhdl/eth_pkg.vhd +++ b/libraries/io/eth/src/vhdl/eth_pkg.vhd @@ -86,6 +86,9 @@ PACKAGE eth_pkg IS CONSTANT c_eth_channel_w : NATURAL := ceil_log2(c_eth_nof_udp_ports + 1); -- + 1 for all other packets that go to the default port CONSTANT c_eth_nof_channels : NATURAL := 2**c_eth_channel_w; + -- Default Rx UDP port for UDP onload + CONSTANT c_eth_rx_udp_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(6001, 16); -- 0x1771 = 6001 + ------------------------------------------------------------------------------ -- MM register map ------------------------------------------------------------------------------ diff --git a/libraries/io/eth/src/vhdl/eth_stream.vhd b/libraries/io/eth/src/vhdl/eth_stream.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ea47c91393a4503900bef921d609bd7a13e26283 --- /dev/null +++ b/libraries/io/eth/src/vhdl/eth_stream.vhd @@ -0,0 +1,179 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2022 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra +-- Purpose: +-- Provide Ethernet access to a node for one UDP stream via TSE. +-- Description: +-- * This eth_stream.vhd is a stripped down version of eth.vhd to offload and +-- onload one UDP stream. +-- . see eth_stream_udp.vhd for UDP offload/onload stream details +-- . contains the TSE +-- . sets up TSE in state machnine and then switch to external mm_ctlr, +-- when setup_done = '1', to allow external monitoring of the TSE +-- . use g_jumbo_en = FALSE to support 1500 octet frames 1518 like in +-- unb_osy/unbos_eth.h, or use g_jumbo_en = TRUE to support 9000 octet +-- frames. With g_jumbo_en = FALSE a 9000 octet packet is received +-- properly, but has rx_src_out.err = 3 indicating invalid length. +-- Use c_jumbo_en = TRUE to avoid invalid length. +-- +-- References: +-- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE + +LIBRARY IEEE, common_lib, dp_lib, technology_lib, tech_tse_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE work.eth_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; + +ENTITY eth_stream IS + GENERIC ( + g_technology : NATURAL := c_tech_select_default; + g_ETH_PHY : STRING := "LVDS"; -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY + g_rx_udp_port : NATURAL := TO_UINT(c_eth_rx_udp_port); + g_jumbo_en : BOOLEAN := FALSE; + g_sim : BOOLEAN := FALSE; + g_sim_level : NATURAL := 0 -- 0 = use IP model (equivalent to g_sim = FALSE); 1 = use fast serdes model; + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; -- reset synchronous with mm_clk + mm_clk : IN STD_LOGIC; -- memory-mapped bus clock + eth_clk : IN STD_LOGIC; -- ethernet phy reference clock + st_rst : IN STD_LOGIC; -- reset synchronous with st_clk + st_clk : IN STD_LOGIC; -- packet stream clock + + cal_rec_clk : IN STD_LOGIC := '0'; -- Calibration & reconfig clock when using XCVR + + -- TSE setup + src_mac : IN STD_LOGIC_VECTOR(c_48-1 DOWNTO 0); + setup_done : OUT STD_LOGIC; + + -- UDP transmit interface + udp_tx_snk_in : IN t_dp_sosi := c_dp_sosi_rst; + udp_tx_snk_out : OUT t_dp_siso; + + -- UDP receive interface + udp_rx_src_in : IN t_dp_siso := c_dp_siso_rdy; + udp_rx_src_out : OUT t_dp_sosi; + + -- Memory Mapped Slaves + tse_ctlr_copi : IN t_mem_mosi; -- ETH TSE MAC registers + tse_ctlr_cipo : OUT t_mem_miso; + + -- PHY interface + eth_txp : OUT STD_LOGIC; + eth_rxp : IN STD_LOGIC; + + -- LED interface + tse_led : OUT t_tech_tse_led + ); +END eth_stream; + + +ARCHITECTURE str OF eth_stream IS + + -- Tx UDP offload stream to TSE + SIGNAL tse_tx_sosi : t_dp_sosi; + SIGNAL tse_tx_siso : t_dp_siso; + + -- Rx stream from TSE (contains the UDP onload packets and possibly other + -- network packets) + SIGNAL tse_rx_sosi : t_dp_sosi; + SIGNAL tse_rx_siso : t_dp_siso; + +BEGIN + + u_eth_stream_udp : ENTITY work.eth_stream_udp + GENERIC MAP ( + g_rx_udp_port => g_rx_udp_port + ) + PORT MAP ( + -- Clocks and reset + st_rst => st_rst, + st_clk => st_clk, + + -- User UDP interface + -- . Tx + udp_tx_sosi => udp_tx_snk_in, + udp_tx_siso => udp_tx_snk_out, + -- . Rx + udp_rx_sosi => udp_rx_src_out, + udp_rx_siso => udp_rx_src_in, + + -- PHY interface + -- . Tx + tse_tx_sosi => tse_tx_sosi, + tse_tx_siso => tse_tx_siso, + -- . Rx + tse_rx_sosi => tse_rx_sosi, + tse_rx_siso => tse_rx_siso + ); + + u_tech_tse_with_setup : ENTITY tech_tse_lib.tech_tse_with_setup + GENERIC MAP ( + g_technology => g_technology, + g_ETH_PHY => g_ETH_PHY, + g_jumbo_en => g_jumbo_en, + g_sim => g_sim, + g_sim_level => g_sim_level + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, -- MM + eth_clk => eth_clk, -- 125 MHz + tx_snk_clk => st_rst, -- DP + rx_src_clk => st_clk, -- DP + + -- TSE setup + src_mac => src_mac, + setup_done => setup_done, + + -- Calibration & reconfig clock + cal_rec_clk => cal_rec_clk, + + -- Memory Mapped Peripheral + mm_ctlr_copi => tse_ctlr_copi, + mm_ctlr_cipo => tse_ctlr_cipo, + + -- MAC transmit interface + -- . ST sink + tx_snk_in => tse_tx_sosi, + tx_snk_out => tse_tx_siso, + + -- MAC receive interface + -- . ST Source + rx_src_in => tse_rx_siso, + rx_src_out => tse_rx_sosi, + + -- PHY interface + eth_txp => eth_txp, + eth_rxp => eth_rxp, + + tse_led => tse_led + ); + +END str; diff --git a/libraries/io/eth/src/vhdl/eth_stream_udp.vhd b/libraries/io/eth/src/vhdl/eth_stream_udp.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a11b6a23e2ad5f6ec34d32d2b5b43bde787e7c69 --- /dev/null +++ b/libraries/io/eth/src/vhdl/eth_stream_udp.vhd @@ -0,0 +1,188 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2022 +-- 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/>. +-- +------------------------------------------------------------------------------- + +-- Author: Eric Kooistra +-- Purpose: +-- Provide Ethernet access to a node for one UDP stream. +-- Description: +-- * This eth_stream_udp.vhd contains the IP/UDP related components of eth.vhd +-- that are needed to send or receive an UDP stream via 1GbE. +-- . support only only UDP offload/onload stream. +-- . the IP checksum is filled in for Tx and checked or Rx. +-- . the Tx only contains UDP stream data, so no need for a dp_mux. +-- . the Rx may contain other packet types, because the 1GbE connects to +-- a network. All Rx packets that are not UDP for g_rx_udp_port are +-- discarded. +-- * Use eth_stream.vhd to have eth_stream_udp in combination with the TSE. +-- +-- References: +-- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE work.eth_pkg.ALL; + +ENTITY eth_stream_udp IS + GENERIC ( + g_rx_udp_port : NATURAL + ); + PORT ( + -- Clocks and reset + st_rst : IN STD_LOGIC; + st_clk : IN STD_LOGIC; + + -- User UDP interface + -- . Tx + udp_tx_sosi : IN t_dp_sosi; + udp_tx_siso : OUT t_dp_siso; + -- . Rx + udp_rx_sosi : OUT t_dp_sosi; + udp_rx_siso : IN t_dp_siso := c_dp_siso_rdy; + + -- PHY interface + -- . Tx + tse_tx_sosi : OUT t_dp_sosi; + tse_tx_siso : IN t_dp_siso; + -- . Rx + tse_rx_sosi : IN t_dp_sosi; + tse_rx_siso : OUT t_dp_siso + ); +END eth_stream_udp; + + +ARCHITECTURE str OF eth_stream_udp IS + + -- ETH Tx + SIGNAL eth_tx_siso : t_dp_siso; + SIGNAL eth_tx_sosi : t_dp_sosi; + + -- ETH Rx + SIGNAL rx_adapt_siso : t_dp_siso; + SIGNAL rx_adapt_sosi : t_dp_sosi; + + SIGNAL rx_hdr_status : t_eth_hdr_status; + SIGNAL rx_hdr_status_complete : STD_LOGIC; + + SIGNAL rx_eth_discard : STD_LOGIC; + SIGNAL rx_eth_discard_val : STD_LOGIC; + +BEGIN + + ------------------------------------------------------------------------------ + -- TX + ------------------------------------------------------------------------------ + + -- Insert IP header checksum + u_tx_ip : ENTITY work.eth_hdr + GENERIC MAP ( + g_header_store_and_forward => TRUE, + g_ip_header_checksum_calculate => TRUE + ) + PORT MAP ( + -- Clocks and reset + rst => st_rst, + clk => st_clk, + + -- Streaming Sink + snk_in => udp_tx_sosi, + snk_out => udp_tx_siso, + + -- Streaming Source + src_in => tse_tx_siso, + src_out => tse_tx_sosi -- with err field value 0 for OK + ); + + ------------------------------------------------------------------------------ + -- RX + ------------------------------------------------------------------------------ + + -- Adapt the TSE RX source ready latency from 2 to 1 + u_adapt : ENTITY dp_lib.dp_latency_adapter + GENERIC MAP ( + g_in_latency => c_eth_rx_ready_latency, -- = 2 + g_out_latency => c_eth_ready_latency -- = 1 + ) + PORT MAP ( + rst => st_rst, + clk => st_clk, + -- ST sink + snk_out => tse_rx_siso, + snk_in => tse_rx_sosi, + -- ST source + src_in => rx_adapt_siso, + src_out => rx_adapt_sosi + ); + + -- Pass on UDP stream for g_rx_udp_port + -- . Verify IP header checksum for IP + u_rx_udp : ENTITY work.eth_hdr + GENERIC MAP ( + g_header_store_and_forward => TRUE, + g_ip_header_checksum_calculate => TRUE + ) + PORT MAP ( + -- Clocks and reset + rst => st_rst, + clk => st_clk, + + -- Streaming Sink + snk_in => rx_adapt_sosi, + snk_out => rx_adapt_siso, + + -- Streaming Source + src_in => udp_rx_siso, + src_out => udp_rx_sosi, + + -- Frame control + frm_discard => rx_eth_discard, + frm_discard_val => rx_eth_discard_val, + + -- Header info + hdr_status => rx_hdr_status, + hdr_status_complete => rx_hdr_status_complete + ); + + -- Discard all Rx data that is not UDP for g_rx_udp_port + p_rx_discard : PROCESS(st_rst, st_clk) + BEGIN + IF st_rst = '1' THEN + rx_eth_discard <= '1'; -- default discard + rx_eth_discard_val <= '0'; + ELSIF rising_edge(st_clk) THEN + -- Default keep rx_eth_discard status (instead of '1'), to more clearly + -- see when a change occurs + IF rx_hdr_status_complete = '1' THEN + rx_eth_discard <= '1'; -- default discard + IF rx_hdr_status.is_ip = '1' AND + rx_hdr_status.is_udp = '1' AND + TO_UINT(rx_hdr_status.udp_port) = g_rx_udp_port THEN + rx_eth_discard <= '0'; -- pass on IP/UDP stream for g_rx_udp_port + END IF; + END IF; + + rx_eth_discard_val <= rx_hdr_status_complete; + END IF; + END PROCESS; + +END str; diff --git a/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd b/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd index 207728be0545d8f11f45451d303960e31546ab05..defeba8d5c5541a777b972d1a5e296eccf172b61 100644 --- a/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester_pkg.vhd @@ -107,6 +107,9 @@ PACKAGE eth_tester_pkg is CONSTANT c_eth_tester_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63"; CONSTANT c_eth_tester_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"E0"; + -- Default eth_tester Rx UDP port for single stream via 1GbE-II + CONSTANT c_eth_tester_eth1g_II_rx_udp_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(6001, 16); -- 0x1771 = 6001 + TYPE t_eth_tester_app_header IS RECORD dp_length : STD_LOGIC_VECTOR(15 DOWNTO 0); dp_reserved : STD_LOGIC_VECTOR(14 DOWNTO 0); diff --git a/libraries/io/eth/src/vhdl/eth_tester_tx.vhd b/libraries/io/eth/src/vhdl/eth_tester_tx.vhd index d1051404ea32694f5633b233db53fafb86f8e364..0ee2539d169bee295d7e9053d505170e88493e00 100644 --- a/libraries/io/eth/src/vhdl/eth_tester_tx.vhd +++ b/libraries/io/eth/src/vhdl/eth_tester_tx.vhd @@ -82,6 +82,7 @@ ARCHITECTURE str OF eth_tester_tx IS CONSTANT c_packet_sz_max : NATURAL := ceil_div(c_eth_tester_bg_block_len_max, c_word_sz); CONSTANT c_fifo_fill : NATURAL := c_packet_sz_max * 11 / 10; CONSTANT c_fifo_size : NATURAL := true_log_pow2(c_fifo_fill + c_packet_sz_max); -- = 8192 + CONSTANT c_fifo_size_w : NATURAL := ceil_log2(c_fifo_size); CONSTANT c_nof_total_counts : NATURAL := 1; -- one to count Tx packets @@ -101,8 +102,10 @@ ARCHITECTURE str OF eth_tester_tx IS SIGNAL tx_fifo_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL tx_fifo_siso : t_dp_siso; SIGNAL tx_fifo_wr_ful : STD_LOGIC; - SIGNAL tx_fifo_wr_usedw : STD_LOGIC_VECTOR(ceil_log2(c_fifo_size)-1 DOWNTO 0); + SIGNAL tx_fifo_wr_usedw : STD_LOGIC_VECTOR(c_fifo_size_w-1 DOWNTO 0); SIGNAL i_tx_fifo_rd_emp : STD_LOGIC; + SIGNAL tx_offload_siso : t_dp_siso; + SIGNAL tx_offload_sosi : t_dp_sosi; SIGNAL i_ref_sync : STD_LOGIC := '0'; SIGNAL in_strobe_arr : STD_LOGIC_VECTOR(c_nof_total_counts-1 DOWNTO 0); @@ -159,9 +162,11 @@ BEGIN -- BG block level flow control, needed in case BG settings result in eth bit -- rate > 1 Gbps, to avoid u_tx_fifo overflow. - p_bg_siso_xon : PROCESS(st_clk) + p_bg_siso_xon : PROCESS(st_rst, st_clk) BEGIN - IF rising_edge(st_clk) THEN + IF st_rst = '1' THEN + bg_siso.xon <= '1'; + ELSIF rising_edge(st_clk) THEN bg_siso.xon <= '1'; IF TO_UINT(tx_fifo_wr_usedw) > c_fifo_fill THEN bg_siso.xon <= '0'; @@ -198,19 +203,19 @@ BEGIN g_fifo_size => c_fifo_size ) PORT MAP ( - wr_rst => st_rst, - wr_clk => st_clk, - rd_rst => st_rst, - rd_clk => st_clk, + wr_rst => st_rst, + wr_clk => st_clk, + rd_rst => st_rst, + rd_clk => st_clk, -- Monitor FIFO filling - wr_ful => tx_fifo_wr_ful, - wr_usedw => tx_fifo_wr_usedw, - rd_emp => i_tx_fifo_rd_emp, + wr_ful => tx_fifo_wr_ful, + wr_usedw => tx_fifo_wr_usedw, + rd_emp => i_tx_fifo_rd_emp, -- ST sink - snk_in => tx_packed_sosi, + snk_in => tx_packed_sosi, -- ST source - src_in => tx_fifo_siso, - src_out => tx_fifo_sosi + src_in => tx_fifo_siso, + src_out => tx_fifo_sosi ); ------------------------------------------------------------------------------- @@ -295,8 +300,8 @@ BEGIN snk_in_arr(0) => tx_fifo_sosi, snk_out_arr(0) => tx_fifo_siso, - src_out_arr(0) => i_tx_udp_sosi, - src_in_arr(0) => tx_udp_siso, + src_out_arr(0) => tx_offload_sosi, + src_in_arr(0) => tx_offload_siso, hdr_fields_in_arr(0) => hdr_fields_slv_in, -- hdr_fields_slv_in_arr(i) is considered valid @ snk_in_arr(i).sop hdr_fields_out_arr(0) => hdr_fields_slv_tx @@ -306,6 +311,22 @@ BEGIN hdr_fields_rec_in <= func_eth_tester_map_header(hdr_fields_slv_in); hdr_fields_rec_tx <= func_eth_tester_map_header(hdr_fields_slv_tx); + + ------------------------------------------------------------------------------- + -- dp_pipeline_ready to ease timing closure + ------------------------------------------------------------------------------- + u_dp_pipeline_ready : ENTITY dp_lib.dp_pipeline_ready + PORT MAP( + rst => st_rst, + clk => st_clk, + + snk_out => tx_offload_siso, + snk_in => tx_offload_sosi, + src_in => tx_udp_siso, + src_out => i_tx_udp_sosi + ); + + ------------------------------------------------------------------------------- -- Tx packet monitors ------------------------------------------------------------------------------- diff --git a/libraries/io/eth/tb/vhdl/tb_eth_stream_udp.vhd b/libraries/io/eth/tb/vhdl/tb_eth_stream_udp.vhd new file mode 100644 index 0000000000000000000000000000000000000000..95bf74ff0c3a07509b35aaf3ab293d9afefea1e5 --- /dev/null +++ b/libraries/io/eth/tb/vhdl/tb_eth_stream_udp.vhd @@ -0,0 +1,436 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2022 +-- 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: E. Kooistra +-- Purpose: Test bench for eth_stream_udp using eth_tester +-- Description: +-- Similar as tb_eth_tester.vhd, but for only one stream and using streaming +-- interface loop back. +-- +-- Usage: +-- > as 8 +-- > run -a +-- +-- References: +-- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE + +LIBRARY IEEE, common_lib, dp_lib, diag_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.common_str_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE common_lib.tb_common_mem_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE work.eth_pkg.ALL; +USE work.eth_tester_pkg.ALL; +USE work.tb_eth_tester_pkg.ALL; + +ENTITY tb_eth_stream_udp IS + GENERIC ( + g_tb_index : NATURAL := 0; -- use to incremental delay logging from tb instances in tb_tb + g_nof_sync : NATURAL := 2; -- number of BG sync intervals to set c_run_time + g_udp_port_match : BOOLEAN := TRUE; + + -- t_diag_block_gen_integer = + -- sl: enable + -- sl: enable_sync + -- nat: samples_per_packet + -- nat: blocks_per_sync + -- nat: gapsize + -- nat: mem_low_adrs + -- nat: mem_high_adrs + -- nat: bsn_init + g_bg_ctrl : t_diag_block_gen_integer := ('1', '1', 50, 3, 200, 0, c_diag_bg_mem_max_adr, 0) -- for first stream + ); +END tb_eth_stream_udp; + + +ARCHITECTURE tb OF tb_eth_stream_udp IS + + CONSTANT c_tb_str : STRING := "tb-" & NATURAL'IMAGE(g_tb_index) & " : "; -- use to distinguish logging from tb instances in tb_tb + CONSTANT mm_clk_period : TIME := 10 ns; -- 100 MHz + CONSTANT c_nof_st_clk_per_s : NATURAL := 200 * 10**6; + CONSTANT st_clk_period : TIME := (10**9 / c_nof_st_clk_per_s) * 1 ns; -- 5 ns, 200 MHz + + CONSTANT c_bg_block_len : NATURAL := g_bg_ctrl.samples_per_packet; + CONSTANT c_bg_slot_len : NATURAL := c_bg_block_len + g_bg_ctrl.gapsize; + CONSTANT c_eth_packet_len : NATURAL := func_eth_tester_eth_packet_length(c_bg_block_len); + + -- Use REAL to avoid NATURAL overflow in bps calculation + CONSTANT c_bg_nof_bps : REAL := REAL(c_bg_block_len * c_octet_w) * REAL(c_nof_st_clk_per_s) / REAL(c_bg_slot_len); + CONSTANT c_bg_sync_period : NATURAL := c_bg_slot_len * g_bg_ctrl.blocks_per_sync; + + CONSTANT c_run_time : NATURAL := g_nof_sync * c_bg_sync_period; + CONSTANT c_nof_sync : NATURAL := c_run_time / c_bg_sync_period; + + -- Destination UDP port + CONSTANT c_rx_udp_port : NATURAL := TO_UINT(c_eth_tester_udp_dst_port); + CONSTANT c_dst_udp_port : NATURAL := sel_a_b(g_udp_port_match, c_rx_udp_port, 17); + + -- Expected Tx --> Rx latency values obtained from a tb run + CONSTANT c_tx_exp_latency : NATURAL := 0; + CONSTANT c_rx_exp_latency_en : BOOLEAN := c_bg_block_len >= 50; + CONSTANT c_rx_exp_latency_st : NATURAL := sel_a_b(g_udp_port_match, 58, 0); + + CONSTANT c_nof_valid_per_packet : NATURAL := c_bg_block_len; + + CONSTANT c_total_count_nof_valid_per_sync : NATURAL := g_bg_ctrl.blocks_per_sync * c_nof_valid_per_packet; + + CONSTANT c_mon_nof_sop_tx : NATURAL := g_bg_ctrl.blocks_per_sync; + CONSTANT c_mon_nof_sop_rx : NATURAL := sel_a_b(g_udp_port_match, c_mon_nof_sop_tx, 0); + CONSTANT c_mon_nof_valid_tx : NATURAL := c_mon_nof_sop_tx * ceil_div(c_bg_block_len * c_octet_w, c_word_w); + CONSTANT c_mon_nof_valid_rx : NATURAL := c_mon_nof_sop_rx * c_nof_valid_per_packet; + + -- Use sim default src MAC, IP, UDP port from eth_tester_pkg.vhd and based on c_gn_index + CONSTANT c_gn_index : NATURAL := 17; -- global node index + CONSTANT c_gn_eth_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := c_eth_tester_eth_src_mac_47_16 & func_eth_tester_gn_index_to_mac_15_0(c_gn_index); + CONSTANT c_gn_ip_src_addr : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0) := c_eth_tester_ip_src_addr_31_16 & func_eth_tester_gn_index_to_ip_15_0(c_gn_index); + CONSTANT c_gn_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := c_eth_tester_udp_src_port_15_8 & TO_UVEC(c_gn_index, 8); + + -- Clocks and reset + SIGNAL mm_rst : STD_LOGIC := '1'; + SIGNAL mm_clk : STD_LOGIC := '1'; + SIGNAL st_rst : STD_LOGIC := '1'; + SIGNAL st_clk : STD_LOGIC := '1'; + SIGNAL st_pps : STD_LOGIC := '0'; + SIGNAL stimuli_end : STD_LOGIC := '0'; + SIGNAL tb_end : STD_LOGIC := '0'; + + SIGNAL tx_fifo_rd_emp : STD_LOGIC; + + -- ETH UDP data path interface + SIGNAL tx_udp_sosi : t_dp_sosi; + SIGNAL tx_udp_siso : t_dp_siso := c_dp_siso_rdy; + SIGNAL rx_udp_sosi : t_dp_sosi; + + -- MM interface + -- . Tx + SIGNAL reg_bg_ctrl_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_bg_ctrl_cipo : t_mem_cipo; + SIGNAL reg_hdr_dat_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_hdr_dat_cipo : t_mem_cipo; + SIGNAL reg_bsn_monitor_v2_tx_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_bsn_monitor_v2_tx_cipo : t_mem_cipo; + SIGNAL reg_strobe_total_count_tx_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_strobe_total_count_tx_cipo : t_mem_cipo; + -- . Rx + SIGNAL reg_bsn_monitor_v2_rx_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_bsn_monitor_v2_rx_cipo : t_mem_cipo; + SIGNAL reg_strobe_total_count_rx_copi : t_mem_copi := c_mem_copi_rst; + SIGNAL reg_strobe_total_count_rx_cipo : t_mem_cipo; + + -- . reg_strobe_total_count + SIGNAL tx_total_count_nof_packet : NATURAL; + SIGNAL rx_total_count_nof_packet : NATURAL; + SIGNAL tx_exp_total_count_nof_packet : NATURAL; + SIGNAL rx_exp_total_count_nof_packet : NATURAL; + + SIGNAL rx_total_count_nof_valid : NATURAL; + SIGNAL rx_exp_total_count_nof_valid : NATURAL; + + -- . reg_bsn_monitor_v2 + SIGNAL tx_mon_nof_sop : NATURAL; + SIGNAL tx_mon_nof_valid : NATURAL; + SIGNAL tx_mon_latency : NATURAL; + SIGNAL rx_mon_nof_sop : NATURAL; + SIGNAL rx_mon_nof_valid : NATURAL; + SIGNAL rx_mon_latency : NATURAL; + + -- ETH stream + SIGNAL tse_tx_sosi : t_dp_sosi; + SIGNAL tse_tx_siso : t_dp_siso; + SIGNAL tse_rx_sosi : t_dp_sosi; + SIGNAL tse_rx_siso : t_dp_siso; + + -- View in Wave window + SIGNAL dbg_g_bg_ctrl : t_diag_block_gen_integer := g_bg_ctrl; + SIGNAL dbg_c_run_time : NATURAL := c_run_time; + SIGNAL dbg_c_mon_nof_sop_tx : NATURAL := c_mon_nof_sop_tx; + SIGNAL dbg_c_mon_nof_sop_rx : NATURAL := c_mon_nof_sop_rx; + SIGNAL dbg_c_mon_nof_valid_tx : NATURAL := c_mon_nof_valid_tx; + SIGNAL dbg_c_mon_nof_valid_rx : NATURAL := c_mon_nof_valid_rx; + +BEGIN + + mm_clk <= (NOT mm_clk) OR tb_end AFTER mm_clk_period/2; + st_clk <= (NOT st_clk) OR tb_end AFTER st_clk_period/2; + mm_rst <= '1', '0' AFTER mm_clk_period*5; + st_rst <= '1', '0' AFTER st_clk_period*5; + + tx_exp_total_count_nof_packet <= c_nof_sync * g_bg_ctrl.blocks_per_sync; + rx_exp_total_count_nof_packet <= sel_a_b(g_udp_port_match, tx_exp_total_count_nof_packet, 0); + + rx_exp_total_count_nof_valid <= sel_a_b(g_udp_port_match, c_nof_sync * c_total_count_nof_valid_per_sync, 0); + + ----------------------------------------------------------------------------- + -- MM control and monitoring + ----------------------------------------------------------------------------- + p_mm : PROCESS + BEGIN + tb_end <= '0'; + + proc_common_wait_until_low(mm_clk, mm_rst); + proc_common_wait_some_cycles(mm_clk, 10); + + --------------------------------------------------------------------------- + -- Rx UDP offload port + --------------------------------------------------------------------------- + -- Set destination MAC/IP/UDP port in tx header + -- The MM addresses follow from byte address_offset // 4 in eth.peripheral.yaml + proc_mem_mm_bus_wr(16#7#, c_dst_udp_port, mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); + proc_mem_mm_bus_wr(16#10#, TO_SINT(c_eth_tester_ip_dst_addr), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(16#18#, TO_SINT(c_eth_tester_eth_dst_mac(31 DOWNTO 0)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(16#19#, TO_UINT(c_eth_tester_eth_dst_mac(47 DOWNTO 32)), mm_clk, reg_hdr_dat_cipo, reg_hdr_dat_copi); + + --------------------------------------------------------------------------- + -- Stimuli + --------------------------------------------------------------------------- + -- Prepare the BG + proc_mem_mm_bus_wr(1, g_bg_ctrl.samples_per_packet, mm_clk, reg_bg_ctrl_copi); + proc_mem_mm_bus_wr(2, g_bg_ctrl.blocks_per_sync, mm_clk, reg_bg_ctrl_copi); + proc_mem_mm_bus_wr(3, g_bg_ctrl.gapsize, mm_clk, reg_bg_ctrl_copi); + proc_mem_mm_bus_wr(4, g_bg_ctrl.mem_low_adrs, mm_clk, reg_bg_ctrl_copi); + proc_mem_mm_bus_wr(5, g_bg_ctrl.mem_high_adrs, mm_clk, reg_bg_ctrl_copi); + proc_mem_mm_bus_wr(6, g_bg_ctrl.bsn_init, mm_clk, reg_bg_ctrl_copi); -- low part + proc_mem_mm_bus_wr(7, 0, mm_clk, reg_bg_ctrl_copi); -- high part + -- Enable the BG at st_pps pulse. + proc_mem_mm_bus_wr(0, 3, mm_clk, reg_bg_ctrl_copi); + proc_common_wait_some_cycles(mm_clk, 10); + -- Issue an st_pps pulse to start the enabled BG + proc_common_gen_pulse(st_clk, st_pps); + + -- Run test + proc_common_wait_some_cycles(st_clk, c_run_time); + + -- Disable the BG + proc_mem_mm_bus_wr(0, 0, mm_clk, reg_bg_ctrl_copi); + + -- Wait until Tx FIFO has emptied for the stream + WHILE tx_fifo_rd_emp /= '1' LOOP + proc_common_wait_some_cycles(st_clk, 1); + END LOOP; + proc_common_wait_some_cycles(st_clk, c_bg_sync_period); + stimuli_end <= '1'; + + -- Delay logging between different tb instances + proc_common_wait_some_cycles(st_clk, g_tb_index * 100); + + -- Print logging + print_str(""); -- log empty line between tb results + print_str(c_tb_str & + "ETH bit rate :" & + " c_bg_nof_bps = " & REAL'IMAGE(c_bg_nof_bps) & " bps"); + ASSERT c_bg_nof_bps < 10.0**9 REPORT "Tx flow control will keep ETH bitrate < 1Gbps." SEVERITY NOTE; + + ------------------------------------------------------------------------- + -- Verification: Total counts + ------------------------------------------------------------------------- + -- . read low part, ignore high part (= 0) of two word total counts + -- Tx total nof packets + proc_mem_mm_bus_rd(0, mm_clk, reg_strobe_total_count_tx_cipo, reg_strobe_total_count_tx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + tx_total_count_nof_packet <= TO_UINT(reg_strobe_total_count_tx_cipo.rddata(c_word_w-1 DOWNTO 0)); + -- Rx total nof packets + proc_mem_mm_bus_rd(0, mm_clk, reg_strobe_total_count_rx_cipo, reg_strobe_total_count_rx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rx_total_count_nof_packet <= TO_UINT(reg_strobe_total_count_rx_cipo.rddata(c_word_w-1 DOWNTO 0)); + -- Rx total nof valids + proc_mem_mm_bus_rd(2, mm_clk, reg_strobe_total_count_rx_cipo, reg_strobe_total_count_rx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rx_total_count_nof_valid <= TO_UINT(reg_strobe_total_count_rx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_common_wait_some_cycles(mm_clk, 1); + + -- Print logging + print_str(c_tb_str & + "Tx total counts monitor :" & + " nof_packet = " & NATURAL'IMAGE(tx_total_count_nof_packet)); + + print_str(c_tb_str & + "Rx total counts monitor :" & + " nof_packet = " & NATURAL'IMAGE(rx_total_count_nof_packet) & + ", nof_valid = " & NATURAL'IMAGE(rx_total_count_nof_valid)); + + -- Verify, only log when wrong + IF c_bg_nof_bps < 10.0**9 THEN + ASSERT tx_total_count_nof_packet = tx_exp_total_count_nof_packet REPORT c_tb_str & + "Wrong Tx total nof packets count, Tx count = " & NATURAL'IMAGE(tx_total_count_nof_packet) & + " /= " & NATURAL'IMAGE(tx_exp_total_count_nof_packet) & + " = Expected count" SEVERITY ERROR; + + ASSERT rx_total_count_nof_packet = rx_exp_total_count_nof_packet REPORT c_tb_str & + "Wrong Rx total nof packets count, Rx count = " & NATURAL'IMAGE(rx_total_count_nof_packet) & + " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_packet) & + " = Expected count" SEVERITY ERROR; + + ASSERT rx_total_count_nof_valid = rx_exp_total_count_nof_valid REPORT c_tb_str & + "Wrong Rx total nof valids count, Rx count = " & NATURAL'IMAGE(rx_total_count_nof_valid) & + " /= " & NATURAL'IMAGE(rx_exp_total_count_nof_valid) & + " = Expected count" SEVERITY ERROR; + END IF; + + ------------------------------------------------------------------------- + -- Verification: BSN monitors (yield same values in every sync interval) + ------------------------------------------------------------------------- + -- 3 = nof_sop + -- 4 = nof_valid + -- 6 = latency + -- . Tx + proc_mem_mm_bus_rd(3, mm_clk, reg_bsn_monitor_v2_tx_cipo, reg_bsn_monitor_v2_tx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + tx_mon_nof_sop <= TO_UINT(reg_bsn_monitor_v2_tx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_mem_mm_bus_rd(4, mm_clk, reg_bsn_monitor_v2_tx_cipo, reg_bsn_monitor_v2_tx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + tx_mon_nof_valid <= TO_UINT(reg_bsn_monitor_v2_tx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_mem_mm_bus_rd(6, mm_clk, reg_bsn_monitor_v2_tx_cipo, reg_bsn_monitor_v2_tx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + tx_mon_latency <= TO_UINT(reg_bsn_monitor_v2_tx_cipo.rddata(c_word_w-1 DOWNTO 0)); + -- . Rx + proc_mem_mm_bus_rd(3, mm_clk, reg_bsn_monitor_v2_rx_cipo, reg_bsn_monitor_v2_rx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rx_mon_nof_sop <= TO_UINT(reg_bsn_monitor_v2_rx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_mem_mm_bus_rd(4, mm_clk, reg_bsn_monitor_v2_rx_cipo, reg_bsn_monitor_v2_rx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rx_mon_nof_valid <= TO_UINT(reg_bsn_monitor_v2_rx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_mem_mm_bus_rd(6, mm_clk, reg_bsn_monitor_v2_rx_cipo, reg_bsn_monitor_v2_rx_copi); + proc_mem_mm_bus_rd_latency(1, mm_clk); + rx_mon_latency <= TO_UINT(reg_bsn_monitor_v2_rx_cipo.rddata(c_word_w-1 DOWNTO 0)); + proc_common_wait_some_cycles(mm_clk, 1); + + -- Print logging + print_str(c_tb_str & + "Tx BSN monitor :" & + " nof_sop = " & NATURAL'IMAGE(tx_mon_nof_sop) & + ", nof_valid = " & NATURAL'IMAGE(tx_mon_nof_valid) & + ", latency = " & NATURAL'IMAGE(tx_mon_latency)); + + print_str(c_tb_str & + "Rx BSN monitor :" & + " nof_sop = " & NATURAL'IMAGE(rx_mon_nof_sop) & + ", nof_valid = " & NATURAL'IMAGE(rx_mon_nof_valid) & + ", latency = " & NATURAL'IMAGE(rx_mon_latency)); + + IF c_bg_nof_bps < 10.0**9 THEN + -- Verify BSN monitors only when the BG sync interval is stable, so + -- the ETH data rate < 1 Gbps and no BG block flow control. + -- Verify, only log when wrong + ASSERT tx_mon_nof_sop = c_mon_nof_sop_tx REPORT c_tb_str & "Wrong tx nof_sop" SEVERITY ERROR; + ASSERT rx_mon_nof_sop = c_mon_nof_sop_rx REPORT c_tb_str & "Wrong rx nof_sop" SEVERITY ERROR; + ASSERT tx_mon_nof_valid = c_mon_nof_valid_tx REPORT c_tb_str & "Wrong tx nof_valid" SEVERITY ERROR; + ASSERT rx_mon_nof_valid = c_mon_nof_valid_rx REPORT c_tb_str & "Wrong rx nof_valid" SEVERITY ERROR; + ASSERT tx_mon_latency = c_tx_exp_latency REPORT c_tb_str & "Wrong tx latency" SEVERITY ERROR; + + -- For short block lengths the Rx latency appears to become less, the + -- exact Rx latency is therefore hard to predetermine. The actual + -- latency is not critical, therefore it is sufficient to only very + -- the latency when it is more or less fixed. + IF c_rx_exp_latency_en THEN + ASSERT almost_equal(rx_mon_latency, c_rx_exp_latency_st, 0) REPORT + c_tb_str & "Wrong rx latency using st interface" SEVERITY ERROR; + END IF; + END IF; + + ------------------------------------------------------------------------- + -- End of test + ------------------------------------------------------------------------- + proc_common_wait_some_cycles(mm_clk, 100); + tb_end <= '1'; + WAIT; + END PROCESS; + + u_eth_tester : ENTITY work.eth_tester + GENERIC MAP ( + g_nof_streams => 1, + g_bg_sync_timeout => c_eth_tester_sync_timeout, + g_remove_crc => FALSE -- no CRC with streaming loopback + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + st_rst => st_rst, + st_clk => st_clk, + st_pps => st_pps, + + -- UDP transmit interface + eth_src_mac => c_gn_eth_src_mac, + ip_src_addr => c_gn_ip_src_addr, + udp_src_port => c_gn_udp_src_port, + + sl(tx_fifo_rd_emp_arr) => tx_fifo_rd_emp, + + TO_DP_ONE(tx_udp_sosi_arr) => tx_udp_sosi, + tx_udp_siso_arr => TO_DP_ARR(tx_udp_siso), + + -- UDP receive interface + rx_udp_sosi_arr => TO_DP_ARR(rx_udp_sosi), + + -- Memory Mapped Slaves (one per stream) + -- . Tx + reg_bg_ctrl_copi => reg_bg_ctrl_copi, + reg_bg_ctrl_cipo => reg_bg_ctrl_cipo, + reg_hdr_dat_copi => reg_hdr_dat_copi, + reg_hdr_dat_cipo => reg_hdr_dat_cipo, + reg_bsn_monitor_v2_tx_copi => reg_bsn_monitor_v2_tx_copi, + reg_bsn_monitor_v2_tx_cipo => reg_bsn_monitor_v2_tx_cipo, + reg_strobe_total_count_tx_copi => reg_strobe_total_count_tx_copi, + reg_strobe_total_count_tx_cipo => reg_strobe_total_count_tx_cipo, + -- . Rx + reg_bsn_monitor_v2_rx_copi => reg_bsn_monitor_v2_rx_copi, + reg_bsn_monitor_v2_rx_cipo => reg_bsn_monitor_v2_rx_cipo, + reg_strobe_total_count_rx_copi => reg_strobe_total_count_rx_copi, + reg_strobe_total_count_rx_cipo => reg_strobe_total_count_rx_cipo + ); + + + -- ETH stream + u_dut : ENTITY work.eth_stream_udp + GENERIC MAP ( + g_rx_udp_port => c_rx_udp_port + ) + PORT MAP ( + -- Clocks and reset + st_rst => st_rst, + st_clk => st_clk, + + -- User UDP interface + -- . Tx + udp_tx_sosi => tx_udp_sosi, + udp_tx_siso => tx_udp_siso, + -- . Rx + udp_rx_sosi => rx_udp_sosi, + udp_rx_siso => c_dp_siso_rdy, + + -- PHY interface + -- . Tx + tse_tx_sosi => tse_tx_sosi, + tse_tx_siso => tse_tx_siso, + -- . Rx + tse_rx_sosi => tse_rx_sosi, + tse_rx_siso => tse_rx_siso + ); + + -- Loopback wire Tx to Rx, register to increasy ready latency from 1 to 2 + tse_rx_sosi <= tse_tx_sosi WHEN rising_edge(st_clk); + tse_tx_siso <= tse_rx_siso; + +END tb; diff --git a/libraries/io/eth/tb/vhdl/tb_eth_tester_pkg.vhd b/libraries/io/eth/tb/vhdl/tb_eth_tester_pkg.vhd index 4705b6f018f3b1f657ee08fd7ee846a909855ef8..93ca1f7791404443c6bcde867d3aada200646a1c 100644 --- a/libraries/io/eth/tb/vhdl/tb_eth_tester_pkg.vhd +++ b/libraries/io/eth/tb/vhdl/tb_eth_tester_pkg.vhd @@ -37,7 +37,7 @@ PACKAGE tb_eth_tester_pkg is CONSTANT c_eth_tester_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"001B217176B9"; -- 001B217176B9 = DOP36-enp2s0 CONSTANT c_eth_tester_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"0A6300FE"; -- 0A6300FE = '10.99.0.254' = DOP36-enp2s0 - CONSTANT c_eth_tester_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(6001, 16); -- 0x1771 = 6001 + CONSTANT c_eth_tester_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_eth_tester_eth1g_II_rx_udp_port; -- Ethernet packet length in octets inclduing eth header and CRC FUNCTION func_eth_tester_eth_packet_length(block_len : NATURAL) RETURN NATURAL; diff --git a/libraries/io/eth/tb/vhdl/tb_tb_eth_stream_udp.vhd b/libraries/io/eth/tb/vhdl/tb_tb_eth_stream_udp.vhd new file mode 100644 index 0000000000000000000000000000000000000000..82b1b5710af83a767611c835c6d6c34005ab299d --- /dev/null +++ b/libraries/io/eth/tb/vhdl/tb_tb_eth_stream_udp.vhd @@ -0,0 +1,80 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2022 +-- 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: E. Kooistra +-- Purpose: Multi test bench for eth_stream_udp +-- Description: +-- +-- Usage: +-- > as 8 +-- > run -all + +LIBRARY IEEE, diag_lib; +USE IEEE.std_logic_1164.ALL; +USE diag_lib.diag_pkg.ALL; +USE work.tb_eth_tester_pkg.ALL; + +ENTITY tb_tb_eth_stream_udp IS +END tb_tb_eth_stream_udp; + +ARCHITECTURE tb OF tb_tb_eth_stream_udp IS + + -- Tb + CONSTANT c_eth_clk_MHz : NATURAL := 125; + CONSTANT c_st_clk_MHz : NATURAL := 200; + CONSTANT c_nof_sync : NATURAL := 2; + CONSTANT c_nof_blk : NATURAL := 3; -- nof_blk per sync + + -- Tx packet size and gap size in octets + CONSTANT c_block_len : NATURAL := 50; + CONSTANT c_link_len : NATURAL := func_eth_tester_eth_packet_on_link_length(c_block_len); + + -- For near maximum 1Gbps link rate the c_block_len + c_gap_len_min time + -- in the st_clk domain equals c_link_len time in eth_clk domain. + CONSTANT c_gap_len_min : NATURAL := c_link_len * c_st_clk_MHz / c_eth_clk_MHz - c_block_len; + + -- Choose c_gap_len somewhat larger to have packet link rate < 1 Gbps + CONSTANT c_gap_len : NATURAL := c_gap_len_min * 2; -- for g_nof_streams = 1 + + -- BG ctrl + CONSTANT c_high : NATURAL := c_diag_bg_mem_max_adr; -- = 2**24 + + CONSTANT c_bg_ctrl : t_diag_block_gen_integer := ('1', '1', c_block_len, c_nof_blk, c_gap_len, 0, c_high, 0); -- for first stream + +BEGIN + +-- g_tb_index : NATURAL := 0; -- use to incremental delay logging from tb instances in tb_tb +-- g_nof_sync : NATURAL := 2; -- number of BG sync intervals to set c_run_time +-- g_udp_port_match : BOOLEAN := TRUE; +-- +-- -- t_diag_block_gen_integer = +-- -- sl: enable +-- -- sl: enable_sync +-- -- nat: samples_per_packet +-- -- nat: blocks_per_sync +-- -- nat: gapsize +-- -- nat: mem_low_adrs +-- -- nat: mem_high_adrs +-- -- nat: bsn_init +-- g_bg_ctrl : t_diag_block_gen_integer := ('1', '1', 50, 3, 200, 0, c_diag_bg_mem_max_adr, 0) -- for first stream + + u_udp : ENTITY work.tb_eth_stream_udp GENERIC MAP (0, c_nof_sync, TRUE, c_bg_ctrl); + u_udp_mismatch : ENTITY work.tb_eth_stream_udp GENERIC MAP (1, c_nof_sync, FALSE, c_bg_ctrl); + +END tb; diff --git a/libraries/technology/tse/hdllib.cfg b/libraries/technology/tse/hdllib.cfg index 5b71fe5191e51bac29016fed57641fab7f0cfcc8..86bd3ec8218f5f562c477a4dde02f407d2a573b8 100644 --- a/libraries/technology/tse/hdllib.cfg +++ b/libraries/technology/tse/hdllib.cfg @@ -29,16 +29,20 @@ synth_files = tech_tse_arria10_e1sg.vhd tech_tse_arria10_e2sg.vhd tech_tse.vhd + tech_tse_setup.vhd + tech_tse_with_setup.vhd tb_tech_tse_pkg.vhd test_bench_files = sim_tse.vhd tb_tech_tse_pkg.vhd tb_tech_tse.vhd + tb_tech_tse_with_setup.vhd tb_tb_tech_tse.vhd regression_test_vhdl = tb_tb_tech_tse.vhd + tb_tech_tse_with_setup.vhd [modelsim_project_file] diff --git a/libraries/technology/tse/tb_tech_tse.vhd b/libraries/technology/tse/tb_tech_tse.vhd index ce074ce5673c8b798bdc26a7f934adb1e5cebddd..5c43594f5cb322abd32f0a8a382cdfd934214401 100644 --- a/libraries/technology/tse/tb_tech_tse.vhd +++ b/libraries/technology/tse/tb_tech_tse.vhd @@ -50,7 +50,7 @@ ENTITY tb_tech_tse IS -- g_data_type = c_tb_tech_tse_data_type_counter = 1 g_data_type : NATURAL := c_tb_tech_tse_data_type_symbols; g_sim : BOOLEAN := TRUE; - g_sim_level : NATURAL := 1; -- 0 = use IP; 1 = use fast serdes model; + g_sim_level : NATURAL := 0; -- 0 = use IP; 1 = use fast serdes model; g_tb_end : BOOLEAN := TRUE -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation ); PORT ( @@ -100,7 +100,9 @@ ARCHITECTURE tb OF tb_tech_tse IS SIGNAL mm_init : STD_LOGIC := '1'; SIGNAL mm_miso : t_mem_miso; SIGNAL mm_mosi : t_mem_mosi; - + SIGNAL mm_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + SIGNAL mm_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + SIGNAL mm_psc_access : STD_LOGIC; -- TSE MAC transmit interface @@ -116,6 +118,7 @@ ARCHITECTURE tb OF tb_tech_tse IS -- . The tb is the ST sink SIGNAL rx_sosi : t_dp_sosi; SIGNAL rx_siso : t_dp_siso; + SIGNAL rx_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window -- . MAC specific SIGNAL rx_mac_out : t_tech_tse_rx_mac; @@ -143,6 +146,10 @@ BEGIN total_header_loopback.eth <= c_eth_header_loopback; total_header_etherlen.eth <= c_eth_header_etherlen; + mm_wrdata <= mm_mosi.wrdata(c_word_w-1 DOWNTO 0); + mm_rddata <= mm_miso.rddata(c_word_w-1 DOWNTO 0); + rx_data <= rx_sosi.data(c_word_w-1 DOWNTO 0); + p_mm_setup : PROCESS BEGIN mm_init <= '1'; diff --git a/libraries/technology/tse/tb_tech_tse_with_setup.vhd b/libraries/technology/tse/tb_tech_tse_with_setup.vhd new file mode 100644 index 0000000000000000000000000000000000000000..988214e6568cbbce51a166b5b883b624f09c93ae --- /dev/null +++ b/libraries/technology/tse/tb_tech_tse_with_setup.vhd @@ -0,0 +1,308 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.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: Testbench for tech_tse for the Tripple Speed Ethernet IP technology +-- wrapper, with setup. +-- Description: +-- Same tb as tb_tech_tse.vhd, but instead: +-- . fixed use TSE IP (c_sim_level = 0) +-- . using TSE setup in DUT +-- . verify external MM access to TSE after setup in p_mm_setup. +-- . use c_jumbo_en = FALSE for maximum 1500 packet size as with unb_osy, a +-- 9000 octet packet is received properly, but has rx_src_out.err = 3 +-- indicating invalid length. Use c_jumbo_en = TRUE to avoid invalid +-- length. +-- Usage: +-- > as 10 +-- > run -all + +LIBRARY IEEE, technology_lib, 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.common_network_layers_pkg.ALL; +USE common_lib.common_network_total_header_pkg.ALL; +USE common_lib.tb_common_pkg.ALL; +USE common_lib.tb_common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE technology_lib.technology_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +USE WORK.tech_tse_pkg.ALL; +USE WORK.tb_tech_tse_pkg.ALL; + + +ENTITY tb_tech_tse_with_setup IS + -- Test bench control parameters + GENERIC ( + g_technology : NATURAL := c_tech_select_default; + -- g_data_type = c_tb_tech_tse_data_type_symbols = 0 + -- g_data_type = c_tb_tech_tse_data_type_counter = 1 + g_data_type : NATURAL := c_tb_tech_tse_data_type_symbols; + g_tb_end : BOOLEAN := TRUE -- when TRUE then tb_end ends this simulation, else a higher multi-testbench will end the simulation + ); + PORT ( + tb_end : OUT STD_LOGIC + ); +END tb_tech_tse_with_setup; + + +ARCHITECTURE tb OF tb_tech_tse_with_setup IS + + CONSTANT c_sim : BOOLEAN := TRUE; + CONSTANT c_sim_level : NATURAL := 0; -- 0 = use IP; 1 = use fast serdes model; + CONSTANT c_jumbo_en : BOOLEAN := TRUE; + + CONSTANT sys_clk_period : TIME := 10 ns; -- 100 MHz + CONSTANT eth_clk_period : TIME := 8 ns; -- 125 MHz + CONSTANT cable_delay : TIME := sel_a_b(c_sim_level=0, 12 ns, 0 ns); + + CONSTANT c_promis_en : BOOLEAN := FALSE; + CONSTANT c_tx_ready_latency : NATURAL := c_tech_tse_tx_ready_latency; -- 0, 1 are supported, must match TSE MAC c_tech_tse_tx_ready_latency + CONSTANT c_nof_tx_not_valid : NATURAL := 0; -- when > 0 then pull tx valid low for c_nof_tx_not_valid beats during tx + + --CONSTANT c_pkt_length_arr : t_nat_natural_arr := (0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1472, 1473, 9000); + CONSTANT c_pkt_length_arr : t_nat_natural_arr := array_init(0, 80, 1) & array_init(1499, 2, 1) & 9000; + CONSTANT c_nof_pkt : NATURAL := c_pkt_length_arr'LENGTH; + + CONSTANT c_dst_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"10FA01020300"; + CONSTANT c_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_slv'RANGE) := X"123456789ABC"; -- = 12-34-56-78-9A-BC + CONSTANT c_ethertype : STD_LOGIC_VECTOR(c_network_eth_type_slv'RANGE) := X"10FA"; + CONSTANT c_etherlen : STD_LOGIC_VECTOR(c_network_eth_type_slv'RANGE) := "0000000000010000"; + + -- Packet headers + CONSTANT c_eth_header_loopback : t_network_eth_header := (c_src_mac, c_src_mac, c_ethertype); + CONSTANT c_eth_header_etherlen : t_network_eth_header := (c_src_mac, c_src_mac, c_etherlen); + + SIGNAL total_header_loopback : t_network_total_header; + SIGNAL total_header_etherlen : t_network_total_header; + + -- Clocks and reset + SIGNAL rx_end : STD_LOGIC := '0'; + SIGNAL eth_clk : STD_LOGIC := '0'; -- tse reference clock + SIGNAL sys_clk : STD_LOGIC := '0'; -- system clock + SIGNAL st_clk : STD_LOGIC; -- stream clock + SIGNAL mm_clk : STD_LOGIC; -- memory-mapped bus clock + SIGNAL mm_rst : STD_LOGIC; -- reset synchronous with mm_clk + + -- TSE MAC control interface + SIGNAL tse_setup_done : STD_LOGIC; + + SIGNAL mm_init : STD_LOGIC := '1'; + SIGNAL mm_copi : t_mem_copi; + SIGNAL mm_cipo : t_mem_cipo; + SIGNAL mm_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + + -- TSE MAC transmit interface + -- . The tb is the ST source + SIGNAL tx_en : STD_LOGIC := '1'; + SIGNAL tx_siso : t_dp_siso; + SIGNAL tx_sosi : t_dp_sosi; + -- . MAC specific + SIGNAL tx_mac_in : t_tech_tse_tx_mac; + SIGNAL tx_mac_out : t_tech_tse_tx_mac; + + -- TSE MAC receive interface + -- . The tb is the ST sink + SIGNAL rx_sosi : t_dp_sosi; + SIGNAL rx_siso : t_dp_siso; + SIGNAL rx_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + -- . MAC specific + SIGNAL rx_mac_out : t_tech_tse_rx_mac; + + -- TSE PHY interface + SIGNAL eth_txp : STD_LOGIC; + SIGNAL eth_rxp : STD_LOGIC; + + SIGNAL tse_led : t_tech_tse_led; + + -- Verification + SIGNAL tx_pkt_cnt : NATURAL := 0; + SIGNAL rx_pkt_cnt : NATURAL := 0; + +BEGIN + + eth_clk <= NOT eth_clk AFTER eth_clk_period/2; -- TSE reference clock + sys_clk <= NOT sys_clk AFTER sys_clk_period/2; -- System clock + + mm_clk <= sys_clk; + st_clk <= sys_clk; + + -- Use signal to leave unused fields 'X' + total_header_loopback.eth <= c_eth_header_loopback; + total_header_etherlen.eth <= c_eth_header_etherlen; + + mm_rddata <= mm_cipo.rddata(c_word_w-1 DOWNTO 0); + rx_data <= rx_sosi.data(c_word_w-1 DOWNTO 0); + + p_mm_setup : PROCESS + BEGIN + mm_init <= '1'; + mm_copi.wr <= '0'; + mm_copi.rd <= '0'; + + -- reset release + mm_rst <= '1'; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP; + mm_rst <= '0'; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(mm_clk); END LOOP; + + -- Wait for tech_tse_with_setup to finish MM access to TSE + proc_common_wait_until_high(mm_clk, tse_setup_done); + proc_common_wait_some_cycles(mm_clk, 10); + + -- Verify external MM access to TSE + proc_mem_mm_bus_rd(16#000#, mm_clk, mm_cipo, mm_copi); -- REV --> CUST_VERSION & 0x0901, 0x1304 + ASSERT UNSIGNED(mm_rddata(c_16-1 DOWNTO 0)) = X"1304" REPORT "Wrong external MM read access result." SEVERITY ERROR; + + -- Wait for link synchronisation + proc_common_wait_until_high(mm_clk, tse_led.link); + proc_common_wait_some_cycles(mm_clk, 10); + + mm_init <= '0'; + WAIT; + END PROCESS; + + + p_ff_transmitter : PROCESS + BEGIN + -- . Avalon ST + tx_sosi.data <= (OTHERS=>'0'); + tx_sosi.valid <= '0'; + tx_sosi.sop <= '0'; + tx_sosi.eop <= '0'; + tx_sosi.empty <= (OTHERS=>'0'); + tx_sosi.err <= (OTHERS=>'0'); + -- . MAC specific + tx_mac_in.crc_fwd <= '0'; -- when '0' then TSE MAC generates the TX CRC field + + WHILE mm_init/='0' LOOP + WAIT UNTIL rising_edge(st_clk); + END LOOP; + FOR I IN 0 TO 9 LOOP WAIT UNTIL rising_edge(st_clk); END LOOP; + + -- Loopback txp->rxp so DST_MAC = c_src_mac to send to itself + + -- TX frame: + -- . I=0 is empty payload, so only 4 words of the ETH header with 46 padding zeros, so empty = 2 + -- . For I=1 to 46 the payload length remains 46 with padding zeros, so empty = 2 + -- . For I>46 the payload length is I and empty = 4 - (I mod 4) + + FOR I IN 0 TO c_nof_pkt-1 LOOP + proc_tech_tse_tx_packet(total_header_loopback, c_pkt_length_arr(I), g_data_type, c_tx_ready_latency, c_nof_tx_not_valid, st_clk, tx_en, tx_siso, tx_sosi); + END LOOP; + + FOR I IN 0 TO 1500 * 2 LOOP WAIT UNTIL rising_edge(st_clk); END LOOP; + rx_end <= '1'; + WAIT; + END PROCESS; + + + p_ff_receiver : PROCESS + BEGIN + -- . Avalon ST + rx_siso.ready <= '0'; + + WHILE mm_init/='0' LOOP + WAIT UNTIL rising_edge(st_clk); + END LOOP; + + -- Receive forever + WHILE TRUE LOOP + proc_tech_tse_rx_packet(total_header_loopback, g_data_type, st_clk, rx_sosi, rx_siso); + END LOOP; + + WAIT; + END PROCESS; + + + dut : ENTITY work.tech_tse_with_setup + GENERIC MAP ( + g_technology => g_technology, + g_ETH_PHY => "LVDS", -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY + g_jumbo_en => c_jumbo_en, + g_sim => c_sim, + g_sim_level => c_sim_level -- 0 = use IP; 1 = use fast serdes model; + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + eth_clk => eth_clk, + tx_snk_clk => st_clk, + rx_src_clk => st_clk, + + -- TSE setup + src_mac => c_src_mac, + setup_done => tse_setup_done, + + -- Memory Mapped Slave + mm_ctlr_copi => mm_copi, + mm_ctlr_cipo => mm_cipo, + + -- MAC transmit interface + -- . ST sink + tx_snk_in => tx_sosi, + tx_snk_out => tx_siso, + + -- MAC receive interface + -- . ST Source + rx_src_in => rx_siso, + rx_src_out => rx_sosi, + + -- PHY interface + eth_txp => eth_txp, + eth_rxp => eth_rxp, + + tse_led => tse_led + ); + + -- Loopback + eth_rxp <= TRANSPORT eth_txp AFTER cable_delay; + + -- Verification + tx_pkt_cnt <= tx_pkt_cnt + 1 WHEN tx_sosi.sop='1' AND rising_edge(st_clk); + rx_pkt_cnt <= rx_pkt_cnt + 1 WHEN rx_sosi.eop='1' AND rising_edge(st_clk); + + p_verify : PROCESS + BEGIN + tb_end <= '0'; + WAIT UNTIL rx_end='1'; + -- Verify that all transmitted packets have been received + IF tx_pkt_cnt=0 THEN + REPORT "No packets were transmitted." SEVERITY ERROR; + ELSIF rx_pkt_cnt=0 THEN + REPORT "No packets were received." SEVERITY ERROR; + ELSIF tx_pkt_cnt/=rx_pkt_cnt THEN + REPORT "Not all transmitted packets were received." SEVERITY ERROR; + END IF; + tb_end <= '1'; + + WAIT FOR 1 ns; + IF g_tb_end=FALSE THEN + REPORT "Tb simulation finished." SEVERITY NOTE; + ELSE + REPORT "Tb simulation finished." SEVERITY FAILURE; + END IF; + WAIT; + END PROCESS; + +END tb; diff --git a/libraries/technology/tse/tech_tse_setup.vhd b/libraries/technology/tse/tech_tse_setup.vhd new file mode 100644 index 0000000000000000000000000000000000000000..fc02da2dc47117ca8647e27f75e60cd68577433b --- /dev/null +++ b/libraries/technology/tse/tech_tse_setup.vhd @@ -0,0 +1,259 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2022 +-- 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: E. Kooistra +-- Purpose: Set up TSE via MM +-- Description: +-- . TSE set up as in tb_tech_tse_pkg, unb_osy/unbos_eth.c and +-- eth1g_master.vhd. Cannot use proc_mem_mm_bus_*() because a synthesis +-- process can only have one rising_edge(mm_clk) statement +-- . After tse_init is done, then connect to external MM controller, to allow +-- external monitoring of the TSE. + +LIBRARY IEEE, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.tech_tse_pkg.ALL; + +ENTITY tech_tse_setup IS + GENERIC ( + g_sim : BOOLEAN; + -- Nios 1GbE-I uses ETH_FRAME_LENGTH = 1518 in inbos_eth.h. Use g_jumbo_en + -- = FALSE for frame_len <= 1500 octets. If frame is longer then this + -- yields invalid length flag in rx_sosi.err, but data is still received. + -- Use g_jumbo_en = TRUE for frame_len <= 9000 octets (jumbo frames). + g_jumbo_en : BOOLEAN := FALSE + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; + + -- TSE setup + src_mac : IN STD_LOGIC_VECTOR(c_48-1 DOWNTO 0); + setup_done : OUT STD_LOGIC; + + -- Memory Mapped Peripheral + -- . Controller side + mm_ctlr_copi : IN t_mem_copi; + mm_ctlr_cipo : OUT t_mem_cipo; + -- . Peripheral side + mm_peri_copi : OUT t_mem_copi; + mm_peri_cipo : IN t_mem_cipo + ); +END tech_tse_setup; + +ARCHITECTURE rtl OF tech_tse_setup IS + + -- FALSE receive only frames for this src_mac and broadcast, TRUE receive all + CONSTANT c_promis_en : BOOLEAN := FALSE; + + -- Access the MM bus + TYPE t_state IS (s_rd_pcs_rev, s_wr_if_mode, s_rd_control, s_rd_status, s_wr_control, + s_rd_mac_rev, s_wr_promis_en, s_wr_mac_0, s_wr_mac_1, s_wr_tx_ipg_len, s_wr_frm_len, + s_wr_rx_section_empty, s_wr_rx_section_full, s_wr_tx_section_empty, s_wr_tx_section_full, + s_wr_rx_almost_empty, s_wr_rx_almost_full, s_wr_tx_almost_empty, s_wr_tx_almost_full, + s_rd_tx_cmd_stat, s_rd_rx_cmd_stat, + s_done); + + SIGNAL state : t_state; + SIGNAL next_state : t_state; + SIGNAL psc_access : STD_LOGIC; -- active during PCS registers access, for view in Wave window + SIGNAL fifo_access : STD_LOGIC; -- active during FIFO registers access, for view in Wave window + + -- Memory Mapped Slave + SIGNAL tse_init : STD_LOGIC := '1'; + SIGNAL tse_ctlr_copi : t_mem_copi; + SIGNAL tse_ctlr_cipo : t_mem_cipo; + SIGNAL tse_waitrequest : STD_LOGIC; + SIGNAL tse_wrdata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + SIGNAL tse_rddata : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- for view in Wave window + + SIGNAL src_mac_0 : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL src_mac_1 : STD_LOGIC_VECTOR(c_16-1 DOWNTO 0); + +BEGIN + + setup_done <= NOT tse_init; + + src_mac_0 <= hton(src_mac(c_48-1 DOWNTO c_16), 4); + src_mac_1 <= hton(src_mac(c_16-1 DOWNTO 0), 2); + + -- Select MM interface controller + -- ___ + -- | | + -- mm_ctlr ----| 0 | + -- | |---- mm_peri + -- tse_ctlr ----| 1 | + -- |___| + -- | + -- tse_init ------/ + -- + mm_peri_copi <= tse_ctlr_copi WHEN tse_init = '1' ELSE mm_ctlr_copi; + mm_ctlr_cipo <= c_mem_cipo_rst WHEN tse_init = '1' ELSE mm_peri_cipo; + tse_ctlr_cipo <= mm_peri_cipo; + tse_waitrequest <= tse_ctlr_cipo.waitrequest; + tse_wrdata <= tse_ctlr_copi.wrdata(c_word_w-1 DOWNTO 0); + tse_rddata <= tse_ctlr_cipo.rddata(c_word_w-1 DOWNTO 0); + + p_state : PROCESS(mm_rst, mm_clk) + BEGIN + IF mm_rst = '1' THEN + state <= s_rd_pcs_rev; + next_state <= s_rd_pcs_rev; + tse_init <= '1'; + tse_ctlr_copi <= c_mem_copi_rst; + psc_access <= '0'; + fifo_access <= '0'; + ELSIF rising_edge(mm_clk) THEN + tse_init <= '1'; + psc_access <= '0'; + fifo_access <= '0'; + + -- Issue MM access + CASE state IS + -- PSC control + WHEN s_rd_pcs_rev => + psc_access <= '1'; + proc_mem_bus_rd(func_tech_tse_map_pcs_addr(16#22#), tse_ctlr_copi); -- REV --> 0x0901, 0x1304 + next_state <= s_wr_if_mode; + + WHEN s_wr_if_mode => + psc_access <= '1'; + proc_mem_bus_wr(func_tech_tse_map_pcs_addr(16#28#), 16#0008#, tse_ctlr_copi); -- IF_MODE <-- Force 1GbE, + next_state <= s_rd_control; + + WHEN s_rd_control => + psc_access <= '1'; + proc_mem_bus_rd(func_tech_tse_map_pcs_addr(16#00#), tse_ctlr_copi); -- CONTROL --> 0x1140 + next_state <= s_rd_status; + + WHEN s_rd_status => + psc_access <= '1'; + proc_mem_bus_rd(func_tech_tse_map_pcs_addr(16#02#), tse_ctlr_copi); -- STATUS --> 0x000D + next_state <= s_wr_control; + + WHEN s_wr_control => + psc_access <= '1'; + IF g_sim = FALSE THEN + proc_mem_bus_wr(func_tech_tse_map_pcs_addr(16#00#), 16#1140#, tse_ctlr_copi); -- CONTROL <-- Keep auto negotiate enabled (is reset default) + ELSE + proc_mem_bus_wr(func_tech_tse_map_pcs_addr(16#00#), 16#0140#, tse_ctlr_copi); -- CONTROL <-- In simulation disable auto negotiate + END IF; + next_state <= s_rd_mac_rev; + + -- MAC control + WHEN s_rd_mac_rev => + proc_mem_bus_rd(16#000#, tse_ctlr_copi); -- REV --> CUST_VERSION & 0x0901 + next_state <= s_wr_promis_en; + + WHEN s_wr_promis_en => + IF c_promis_en = FALSE THEN + proc_mem_bus_wr(16#008#, 16#0100004B#, tse_ctlr_copi); -- COMMAND_CONFIG + ELSE + proc_mem_bus_wr(16#008#, 16#0100005B#, tse_ctlr_copi); + END IF; + next_state <= s_wr_mac_0; + + WHEN s_wr_mac_0 => + proc_mem_bus_wr(16#00C#, src_mac_0, tse_ctlr_copi); -- MAC_0 + next_state <= s_wr_mac_1; + + WHEN s_wr_mac_1 => + proc_mem_bus_wr(16#010#, src_mac_1, tse_ctlr_copi); -- MAC_1 <-- SRC_MAC + next_state <= s_wr_tx_ipg_len; + + WHEN s_wr_tx_ipg_len => + proc_mem_bus_wr(16#05C#, 16#0000000C#, tse_ctlr_copi); -- TX_IPG_LENGTH <-- interpacket gap = 12 + next_state <= s_wr_frm_len; + + WHEN s_wr_frm_len => + IF g_jumbo_en = FALSE THEN + proc_mem_bus_wr(16#014#, 16#000005EE#, tse_ctlr_copi); -- FRM_LENGTH <-- receive max frame length = 1518 + ELSE + proc_mem_bus_wr(16#014#, 16#0000233A#, tse_ctlr_copi); -- FRM_LENGTH <-- receive max frame length = 9018 + END IF; + next_state <= s_wr_rx_section_empty; + + -- MAC FIFO + WHEN s_wr_rx_section_empty => + fifo_access <= '1'; + proc_mem_bus_wr(16#01C#, c_tech_tse_rx_fifo_depth-16, tse_ctlr_copi); -- RX_SECTION_EMPTY <-- default FIFO depth - 16, >3 + next_state <= s_wr_rx_section_full; + + WHEN s_wr_rx_section_full => + fifo_access <= '1'; + proc_mem_bus_wr(16#020#, 16, tse_ctlr_copi); -- RX_SECTION_FULL <-- default 16 + next_state <= s_wr_tx_section_empty; + + WHEN s_wr_tx_section_empty => + fifo_access <= '1'; + proc_mem_bus_wr(16#024#, c_tech_tse_tx_fifo_depth-16, tse_ctlr_copi); -- TX_SECTION_EMPTY <-- default FIFO depth - 16, >3 + next_state <= s_wr_tx_section_full; + + WHEN s_wr_tx_section_full => + fifo_access <= '1'; + proc_mem_bus_wr(16#028#, 16, tse_ctlr_copi); -- TX_SECTION_FULL <-- default 16, >~ 8 otherwise no tx + next_state <= s_wr_rx_almost_empty; + + WHEN s_wr_rx_almost_empty => + fifo_access <= '1'; + proc_mem_bus_wr(16#02C#, 8, tse_ctlr_copi); -- RX_ALMOST_EMPTY <-- default 8 + next_state <= s_wr_rx_almost_full; + + WHEN s_wr_rx_almost_full => + fifo_access <= '1'; + proc_mem_bus_wr(16#030#, 8, tse_ctlr_copi); -- RX_ALMOST_FULL <-- default 8 + next_state <= s_wr_tx_almost_empty; + + WHEN s_wr_tx_almost_empty => + fifo_access <= '1'; + proc_mem_bus_wr(16#034#, 8, tse_ctlr_copi); -- TX_ALMOST_EMPTY <-- default 8 + next_state <= s_wr_tx_almost_full; + + WHEN s_wr_tx_almost_full => + fifo_access <= '1'; + proc_mem_bus_wr(16#038#, c_tech_tse_tx_ready_latency + 3, tse_ctlr_copi); -- TX_ALMOST_FULL <-- default 3 + next_state <= s_rd_tx_cmd_stat; + + -- MAC status + WHEN s_rd_tx_cmd_stat => + proc_mem_bus_rd(16#0E8#, tse_ctlr_copi); -- TX_CMD_STAT --> 0x00040000 : [18]=1 TX_SHIFT16, [17]=0 OMIT_CRC + next_state <= s_rd_rx_cmd_stat; + + WHEN s_rd_rx_cmd_stat => + proc_mem_bus_rd(16#0EC#, tse_ctlr_copi); -- RX_CMD_STAT --> 0x02000000 : [25]=1 RX_SHIFT16 + next_state <= s_done; + + WHEN OTHERS => -- s_done + tse_init <= '0'; + END CASE; + + -- Go to next state when MM access was accepted + IF state /= next_state AND tse_waitrequest = '0' THEN + tse_ctlr_copi.wr <= '0'; + tse_ctlr_copi.rd <= '0'; + state <= next_state; + END IF; + + END IF; + END PROCESS; + +END ARCHITECTURE; diff --git a/libraries/technology/tse/tech_tse_with_setup.vhd b/libraries/technology/tse/tech_tse_with_setup.vhd new file mode 100644 index 0000000000000000000000000000000000000000..41173fa0a9df5c51c9e9a618d751bfb88fed9e2b --- /dev/null +++ b/libraries/technology/tse/tech_tse_with_setup.vhd @@ -0,0 +1,173 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2022 +-- 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: E. Kooistra +-- Purpose: Instantiate and setup TSE via MM +-- Description: +-- . Based on tech_tse instance in eth.vhd +-- . Set up TSE in state machnine and then switch to external mm_ctlr, to +-- allow external monitoring of the TSE. + +LIBRARY IEEE, technology_lib, common_lib, dp_lib; +USE IEEE.std_logic_1164.ALL; +USE technology_lib.technology_pkg.ALL; +USE technology_lib.technology_select_pkg.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE work.tech_tse_pkg.ALL; + +ENTITY tech_tse_with_setup IS + GENERIC ( + g_technology : NATURAL := c_tech_select_default; + g_ETH_PHY : STRING := "LVDS"; -- "LVDS" (default): uses LVDS IOs for ctrl_unb_common, "XCVR": uses tranceiver PHY + g_jumbo_en : BOOLEAN := FALSE; + g_sim : BOOLEAN := FALSE; + g_sim_level : NATURAL := 0; -- 0 = use IP model (equivalent to g_sim = FALSE); 1 = use fast serdes model; + g_sim_tx : BOOLEAN := TRUE; + g_sim_rx : BOOLEAN := TRUE + ); + PORT ( + -- Clocks and reset + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; -- MM + eth_clk : IN STD_LOGIC; -- 125 MHz + tx_snk_clk : IN STD_LOGIC; -- DP + rx_src_clk : IN STD_LOGIC; -- DP + + -- TSE setup + src_mac : IN STD_LOGIC_VECTOR(c_48-1 DOWNTO 0); + setup_done : OUT STD_LOGIC; + + -- Calibration & reconfig clock + cal_rec_clk : IN STD_LOGIC := '0'; + + -- Memory Mapped Peripheral + mm_ctlr_copi : IN t_mem_copi; + mm_ctlr_cipo : OUT t_mem_cipo; + + -- MAC transmit interface + -- . ST sink + tx_snk_in : IN t_dp_sosi; + tx_snk_out : OUT t_dp_siso; + + -- MAC receive interface + -- . ST Source + rx_src_in : IN t_dp_siso; + rx_src_out : OUT t_dp_sosi; + + -- PHY interface + eth_txp : OUT STD_LOGIC; + eth_rxp : IN STD_LOGIC; + + tse_led : OUT t_tech_tse_led + ); +END tech_tse_with_setup; + +ARCHITECTURE str OF tech_tse_with_setup IS + + -- Peripheral side + SIGNAL mm_peri_copi : t_mem_copi; + SIGNAL mm_peri_cipo : t_mem_cipo; + + -- MAC specific + SIGNAL tx_mac_in : t_tech_tse_tx_mac; + SIGNAL tx_mac_out : t_tech_tse_tx_mac; + SIGNAL rx_mac_out : t_tech_tse_rx_mac; + + SIGNAL tx_sosi : t_dp_sosi; + +BEGIN + + -- Set up TSE as in unb_osy/unbos_eth.c + u_tech_tse_setup : ENTITY work.tech_tse_setup + GENERIC MAP ( + g_sim => g_sim, + g_jumbo_en => g_jumbo_en + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + + -- TSE setup + src_mac => src_mac, + setup_done => setup_done, + + -- Memory Mapped Peripheral + -- . Controller side + mm_ctlr_copi => mm_ctlr_copi, + mm_ctlr_cipo => mm_ctlr_cipo, + -- . Peripheral side + mm_peri_copi => mm_peri_copi, + mm_peri_cipo => mm_peri_cipo + ); + + -- Force defaults as in eth.vhd + tx_sosi <= func_dp_stream_error_set(tx_snk_in, 0); -- force err field (value 0 for OK) + + tx_mac_in.crc_fwd <= '0'; -- when '0' then TSE MAC generates the TX CRC field + + u_tech_tse : ENTITY work.tech_tse + GENERIC MAP ( + g_technology => g_technology, + g_ETH_PHY => g_ETH_PHY, + g_sim => g_sim, + g_sim_level => g_sim_level, + g_sim_tx => g_sim_tx, + g_sim_rx => g_sim_rx + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + eth_clk => eth_clk, + tx_snk_clk => tx_snk_clk, + rx_src_clk => rx_src_clk, + + -- Calibration & reconfig clock + cal_rec_clk => cal_rec_clk, + + -- Memory Mapped Peripheral + mm_sla_in => mm_peri_copi, + mm_sla_out => mm_peri_cipo, + + -- MAC transmit interface + -- . ST sink + tx_snk_in => tx_sosi, + tx_snk_out => tx_snk_out, + -- . MAC specific + tx_mac_in => tx_mac_in, + tx_mac_out => tx_mac_out, + + -- MAC receive interface + -- . ST Source + rx_src_in => rx_src_in, + rx_src_out => rx_src_out, + -- . MAC specific + rx_mac_out => rx_mac_out, + + -- PHY interface + eth_txp => eth_txp, + eth_rxp => eth_rxp, + + tse_led => tse_led + ); + +END ARCHITECTURE;