Skip to content
Snippets Groups Projects
Commit 1ac513e6 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Add tb for JESD with AIT.

parent 074b245f
No related branches found
No related tags found
1 merge request!258Shortened sync interval and used pps_rst to make the tb simulate faster (few...
...@@ -9,10 +9,11 @@ hdl_lib_technology = ip_arria10_e2sg ...@@ -9,10 +9,11 @@ hdl_lib_technology = ip_arria10_e2sg
test_bench_files = test_bench_files =
tb_lofar2_unb2c_sdp_station_adc.vhd tb_lofar2_unb2c_sdp_station_adc.vhd
tb_lofar2_unb2c_sdp_station_adc_jesd.vhd
regression_test_vhdl = regression_test_vhdl =
tb_lofar2_unb2c_sdp_station_adc.vhd tb_lofar2_unb2c_sdp_station_adc.vhd
tb_lofar2_unb2c_sdp_station_adc_jesd.vhd
[modelsim_project_file] [modelsim_project_file]
modelsim_copy_files = modelsim_copy_files =
......
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- 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, R. van der Walle
-- Purpose: Self-checking testbench for simulating restart of JESD interface
-- rx_clk domain input section in lofar2_unb2c_sdp_station_adc
--
-- Description:
-- FOR I IN 0 TO c_nof_restarts LOOP
-- . Run WG and ADUH monitor similar as in tb_lofar2_unb2c_sdp_station_adc
-- . Reset the AIT rx_clk somain input section via PIO_JESD_CTRL
-- END LOOP
-- Issue:
-- For some unknown reason the rx_clk does not stop in sim after applying
-- reset via PIO_JESD_CTRL.
----
-- Usage:
-- > as 7 # default
-- > as 15 # for detailed debugging of JESD204B IP
-- > run -a
--
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2c_sdp_station_lib, tech_jesd204b_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
USE IEEE.MATH_REAL.ALL;
USE common_lib.common_pkg.ALL;
USE unb2c_board_lib.unb2c_board_pkg.ALL;
USE common_lib.tb_common_pkg.ALL;
USE common_lib.common_str_pkg.ALL;
USE mm_lib.mm_file_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE mm_lib.mm_file_unb_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE wpfb_lib.wpfb_pkg.ALL;
USE lofar2_sdp_lib.sdp_pkg.ALL;
USE tech_jesd204b_lib.tech_jesd204b_pkg.ALL;
ENTITY tb_lofar2_unb2c_sdp_station_adc_jesd IS
END tb_lofar2_unb2c_sdp_station_adc_jesd;
ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS
CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0
CONSTANT c_node_nr : NATURAL := 0;
CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000";
CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00";
CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0);
CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0
CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard
CONSTANT c_ext_clk_period : TIME := 5 ns;
CONSTANT c_bck_ref_clk_period : TIME := 5 ns;
CONSTANT c_tb_clk_period : TIME := 100 ps; -- use fast tb_clk to speed up M&C
CONSTANT c_nof_restarts : NATURAL := 1;
CONSTANT c_nof_block_per_sync : NATURAL := 7; -- use short interval to speed up simulation
CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft;
CONSTANT c_pps_period : NATURAL := c_nof_clk_per_sync;
CONSTANT c_percentage : REAL := 0.05; -- percentage that actual value may differ from expected value, due to WG rounding
CONSTANT c_lo_factor : REAL := 1.0 - c_percentage; -- lower boundary
CONSTANT c_hi_factor : REAL := 1.0 + c_percentage; -- higher boundary
-- WG
CONSTANT c_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
CONSTANT c_ampl_sp_0 : NATURAL := c_sdp_FS_adc/2; -- = 0.5 * FS, so in number of lsb
CONSTANT c_wg_freq_offset : REAL := 0.0/11.0; -- in freq_unit
CONSTANT c_subband_sp_0 : REAL := 102.0; -- Select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
CONSTANT c_exp_wg_power_sp_0 : REAL := REAL(c_ampl_sp_0**2)/2.0 * REAL(c_nof_clk_per_sync);
-- ADUH
CONSTANT c_mon_buffer_nof_samples : NATURAL := 512; --samples per stream
-- MM
CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS";
CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
CONSTANT c_mm_file_reg_aduh_mon : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_ADUH_MONITOR";
CONSTANT c_mm_file_jesd204b : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "JESD204B";
CONSTANT c_mm_file_pio_jesd_ctrl : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_JESD_CTRL";
-- Tb
SIGNAL tb_end : STD_LOGIC := '0';
SIGNAL sim_done : STD_LOGIC := '0';
SIGNAL tb_clk : STD_LOGIC := '0';
SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
SIGNAL pps_rst : STD_LOGIC := '1';
SIGNAL gen_pps : STD_LOGIC := '0';
-- WG
SIGNAL dbg_c_exp_wg_power_sp_0 : REAL := c_exp_wg_power_sp_0;
SIGNAL sp_samples : t_integer_arr(0 TO c_mon_buffer_nof_samples-1) := (OTHERS=>0);
SIGNAL sp_sample : INTEGER := 0;
SIGNAL sp_power_sum : STD_LOGIC_VECTOR(63 DOWNTO 0);
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
-- DUT
SIGNAL ext_clk : STD_LOGIC := '0';
SIGNAL ext_pps : STD_LOGIC := '0';
SIGNAL WDI : STD_LOGIC;
SIGNAL INTA : STD_LOGIC;
SIGNAL INTB : STD_LOGIC;
SIGNAL eth_clk : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0');
SIGNAL eth_txp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0);
SIGNAL eth_rxp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0);
-- back transceivers
SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0);
SIGNAL JESD204B_REFCLK : STD_LOGIC := '1';
-- jesd204b syncronization signals
SIGNAL jesd204b_sysref : STD_LOGIC;
SIGNAL jesd204b_sync_n : STD_LOGIC_VECTOR(c_sdp_N_sync_jesd-1 DOWNTO 0);
-- jesd204b IP registers
SIGNAL reg_jesd204b_rx_err0 : STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err0_w-1 DOWNTO 0);
SIGNAL reg_jesd204b_rx_err1 : STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err1_w-1 DOWNTO 0);
SIGNAL reg_jesd204b_csr_rbd_count : STD_LOGIC_VECTOR(tech_jesd204b_field_csr_rbd_count_w-1 DOWNTO 0);
SIGNAL reg_jesd204b_csr_dev_syncn : STD_LOGIC_VECTOR(tech_jesd204b_field_csr_dev_syncn_w-1 DOWNTO 0);
-- jesd204b ctrl register
SIGNAL pio_jesd_ctrl : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
SIGNAL pio_jesd_ctrl_enable : STD_LOGIC_VECTOR(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0);
SIGNAL pio_jesd_ctrl_reset : STD_LOGIC;
BEGIN
----------------------------------------------------------------------------
-- System setup
----------------------------------------------------------------------------
ext_clk <= NOT ext_clk AFTER c_ext_clk_period/2; -- External clock (200 MHz)
eth_clk(0) <= NOT eth_clk(0) AFTER c_eth_clk_period/2; -- Ethernet ref clock (125 MHz)
JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2; -- JESD sample clock (200MHz)
INTA <= 'H'; -- pull up
INTB <= 'H'; -- pull up
------------------------------------------------------------------------------
-- External PPS
------------------------------------------------------------------------------
proc_common_gen_pulse(10, c_pps_period, '1', pps_rst, ext_clk, gen_pps);
jesd204b_sysref <= gen_pps;
ext_pps <= gen_pps;
------------------------------------------------------------------------------
-- DUT
------------------------------------------------------------------------------
u_lofar_unb2c_sdp_station_adc : ENTITY lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station
GENERIC MAP (
g_design_name => "lofar2_unb2c_sdp_station_adc",
g_design_note => "",
g_sim => c_sim,
g_sim_unb_nr => c_unb_nr,
g_sim_node_nr => c_node_nr,
g_bsn_nof_clk_per_sync => c_nof_clk_per_sync,
g_scope_selected_subband => NATURAL(c_subband_sp_0)
)
PORT MAP (
-- GENERAL
CLK => ext_clk,
PPS => ext_pps,
WDI => WDI,
INTA => INTA,
INTB => INTB,
-- Others
VERSION => c_version,
ID => c_id,
TESTIO => open,
-- 1GbE Control Interface
ETH_CLK => eth_clk,
ETH_SGIN => eth_rxp,
ETH_SGOUT => eth_txp,
-- LEDs
QSFP_LED => open,
-- back transceivers
JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA,
JESD204B_REFCLK => JESD204B_REFCLK,
-- jesd204b syncronization signals
JESD204B_SYSREF => jesd204b_sysref,
JESD204B_SYNC_N => jesd204b_sync_n
);
------------------------------------------------------------------------------
-- MM slave accesses via file IO
------------------------------------------------------------------------------
tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock
p_mm_stimuli : PROCESS
VARIABLE v_offset : NATURAL;
VARIABLE v_bsn : NATURAL;
VARIABLE v_sp_power_sum_0 : REAL;
VARIABLE v_sp_subband_power : REAL;
VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies
BEGIN
FOR REP IN 0 TO c_nof_restarts LOOP
-- Wait for DUT power up after reset or after AIT rx_clk domain restart
WAIT FOR 1 us;
----------------------------------------------------------------------------
-- Enable BS
----------------------------------------------------------------------------
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, c_init_bsn, tb_clk); -- Init BSN
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); -- Write high part activates the init BSN
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_sync
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BS at PPS
-- Release PPS pulser, to get first PPS now and to start BSN source
WAIT FOR 1 us;
pps_rst <= '0';
---------------------------------------------------------------------------
-- Read JESD204B IP status per signal input
---------------------------------------------------------------------------
-- Note: The IP sim model does not seem to support the mm_clk, so this
-- reads undefined values, see comment in ip_arria10_e2sg_jesd204b.vhd
FOR I IN 0 TO c_sdp_S_pn-1 LOOP
v_offset := I * tech_jesd204b_port_span;
mmf_mm_bus_rd(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_rx_err0_adr, rd_data, tb_clk);
reg_jesd204b_rx_err0 <= rd_data(tech_jesd204b_field_rx_err0_hi DOWNTO tech_jesd204b_field_rx_err0_lo);
mmf_mm_bus_rd(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_rx_err1_adr, rd_data, tb_clk);
reg_jesd204b_rx_err1 <= rd_data(tech_jesd204b_field_rx_err1_hi DOWNTO tech_jesd204b_field_rx_err1_lo);
mmf_mm_bus_rd(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_csr_rbd_count_adr, rd_data, tb_clk);
reg_jesd204b_csr_rbd_count <= rd_data(tech_jesd204b_field_csr_rbd_count_hi DOWNTO tech_jesd204b_field_csr_rbd_count_lo);
mmf_mm_bus_rd(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_csr_dev_syncn_adr, rd_data, tb_clk);
reg_jesd204b_csr_dev_syncn <= rd_data(tech_jesd204b_field_csr_dev_syncn_hi DOWNTO tech_jesd204b_field_csr_dev_syncn_lo);
proc_common_wait_some_cycles(tb_clk, 10);
END LOOP;
---------------------------------------------------------------------------
-- Read JESD_CTRL register
---------------------------------------------------------------------------
-- Note: pio_jesd_ctrl_enable works in fact as disable, so '0' enables
-- signal input and '1' disables it, and read yields
-- pio_jesd_ctrl = 0.
mmf_mm_bus_rd(c_mm_file_pio_jesd_ctrl, 0, rd_data, tb_clk);
pio_jesd_ctrl <= rd_data;
pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0);
pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi);
----------------------------------------------------------------------------
-- Enable WG
----------------------------------------------------------------------------
-- 0 : mode[7:0] --> off=0, calc=1, repeat=2, single=3)
-- nof_samples[31:16] --> <= c_ram_wg_size=1024
-- 1 : phase[15:0]
-- 2 : freq[30:0]
-- 3 : ampl[16:0]
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 1, INTEGER( 0.0 * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 2, INTEGER((c_subband_sp_0 + c_wg_freq_offset) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 3, INTEGER(REAL(c_ampl_sp_0) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl
-- Read current BSN
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk);
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk);
proc_common_wait_some_cycles(tb_clk, 1);
-- Write scheduler BSN to trigger start of WG at next block
v_bsn := TO_UINT(current_bsn_wg) + 2;
ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
v_bsn := c_bsn_start_wg;
mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, v_bsn, tb_clk); -- first write low then high part
mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1
----------------------------------------------------------------------------
-- Wait for enough WG data and start of sync interval
----------------------------------------------------------------------------
mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low
"UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync*2, -- this is the wait until condition
c_sdp_T_sub, tb_clk);
---------------------------------------------------------------------------
-- Read ADUH monitor power sum
---------------------------------------------------------------------------
mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 2, rd_data, tb_clk); -- read low part
sp_power_sum(31 DOWNTO 0) <= rd_data;
mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 3, rd_data, tb_clk); -- read high part
sp_power_sum(63 DOWNTO 32) <= rd_data;
proc_common_wait_some_cycles(tb_clk, 1);
---------------------------------------------------------------------------
-- Verify sp_power_sum
---------------------------------------------------------------------------
-- Convert STD_LOGIC_VECTOR sp_power_sum to REAL
v_sp_power_sum_0 := REAL(REAL(TO_UINT(sp_power_sum(61 DOWNTO 30)))*REAL(2**30) + REAL(TO_UINT(sp_power_sum(29 DOWNTO 0))));
ASSERT v_sp_power_sum_0 > c_lo_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
ASSERT v_sp_power_sum_0 < c_hi_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
----------------------------------------------------------------------------
-- Restart AIT
----------------------------------------------------------------------------
-- . Disable BSN source to allow rx_clk/dp_clk domain FIFO to empty
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000000#, tb_clk);
-- . Wait until BSN source has finished last block, use ext_clk as 200 MHz equivalent for dp_clk,
-- and wait for > 1 block of c_sdp_N_fft samples
proc_common_wait_some_cycles(ext_clk, c_sdp_N_fft * 2);
-- . Reset rx_clk domain via JESD_CTRL and read back
-- Note: Awkward way to set MSbit. Options are:
-- . Use directly 16#80000000#
-- . Use parameter c_sdp_jesd_ctrl_reset_bi = 31 and then INTEGER(-1* REAL(2**31)),
-- to avoid INTEGER overflow warning for +2**31
--mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, INTEGER(-1.0 * 2.0**REAL(c_sdp_jesd_ctrl_reset_bi)), tb_clk);
mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, 16#80000000# + 2, tb_clk);
proc_common_wait_cross_clock_domain_latency(tb_clk, ext_clk);
mmf_mm_bus_rd(c_mm_file_pio_jesd_ctrl, 0, rd_data, tb_clk);
pio_jesd_ctrl <= rd_data;
pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0);
pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi);
-- For some unknown reason the rx_clk does not stop
WAIT FOR 1 us;
-- . Re-enable rx_clk domain via JESD_CTRL and read back
mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, 2, tb_clk);
proc_common_wait_cross_clock_domain_latency(tb_clk, ext_clk);
mmf_mm_bus_rd(c_mm_file_pio_jesd_ctrl, 0, rd_data, tb_clk);
pio_jesd_ctrl <= rd_data;
pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0);
pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi);
END LOOP;
---------------------------------------------------------------------------
-- End Simulation
---------------------------------------------------------------------------
sim_done <= '1';
proc_common_wait_some_cycles(ext_clk, 100);
proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end);
WAIT;
END PROCESS;
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment