From 91a40f870bdce742abd9af4cecd0623fad59f062 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Wed, 1 Jun 2022 15:45:54 +0200
Subject: [PATCH] Extended tb stimuli with JESD_CTRL reset and JESD204B link
 reinit.

---
 .../tb_lofar2_unb2c_sdp_station_adc_jesd.vhd  | 433 +++++++++++++++---
 1 file changed, 381 insertions(+), 52 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd
index 97d29420f3..5cf5c737e6 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd
@@ -25,17 +25,28 @@
 --          rx_clk domain input section in lofar2_unb2c_sdp_station_adc
 --
 -- Description:
+-- * Run JESD204B interface
 --   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
+--     . Reset the AIT rx_clk domain input section via PIO_JESD_CTRL
+--     . Reinit signal input links via JESD204B
 --   END LOOP
--- Issue:
---   For some unknown reason the rx_clk does not stop in sim after applying
---   reset via PIO_JESD_CTRL.
-----
+-- * Uses c_si_dis to view signal input disable via JESD_CTRL.
+--
+-- Conclusion:
+-- * JESD_CTRL reset does reset the JESD204B IP and also the rx_clk and rx_rst,
+--   so it is necessary to first stop the BSN source to avoid that corrupted
+--   data blocks will enter the dp_clk domain, due to rx_rst of the rx_clk/
+--   dp_clk domain FIFO.
+-- * JESD204B link reinit does restart the signal input link. For link reinit
+--   it is not necessary to stop the BSN source, because then the rx_clk
+--   remains running and the rx_rst remains inactive.
+-- It is not clear whether both reset and reinit are needed to recover a link,
+-- (e.g. after RCU2 off/on) or whether one of them is enough.
+--
 -- Usage:
 --   > as 7    # default
---   > as 15   # for detailed debugging of JESD204B IP
+--   > as 16   # for detailed debugging of JESD204B IP
 --   > run -a  
 --
 -------------------------------------------------------------------------------
@@ -67,22 +78,26 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS
   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_si_dis          : NATURAL := 2;   -- disable signal input 2 in range 0:c_sdp_S_pn_1
 
   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_tb_clk_period       : TIME := 10 ns;--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_pps_period          : TIME := c_nof_clk_per_sync * c_ext_clk_period;
+
   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
 
+  -- Tx JESD
+  CONSTANT c_nof_jesd204b_tx      : NATURAL := 3;  -- <= c_sdp_S_pn = 12
+
   -- 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
@@ -135,20 +150,121 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS
   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);
+  SIGNAL JESD204B_SYSREF     : STD_LOGIC;
+  SIGNAL JESD204B_SYNC_N     : STD_LOGIC_VECTOR(c_sdp_N_sync_jesd-1 DOWNTO 0);
+
+  -- Tx jesd204b source
+  CONSTANT c_tx_avs_clk_period       : TIME := 20 ns;
+
+  SIGNAL mm_rst                      : STD_LOGIC := '1';
+  SIGNAL tx_avs_clk                  : STD_LOGIC := '0';
+  SIGNAL tx_avs_rst_n                : STD_LOGIC := '0';
+
+  SIGNAL txlink_clk                  : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 downto 0);
+  SIGNAL dev_sync_n                  : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 downto 0);
+
+  SIGNAL tx_avs_chipselect           : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL tx_avs_address              : t_slv_8_arr(c_nof_jesd204b_tx-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+  SIGNAL tx_avs_read                 : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL tx_avs_readdata             : t_slv_32_arr(c_nof_jesd204b_tx-1 DOWNTO 0);
+
+  SIGNAL txphy_clk                   : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 downto 0);
+  SIGNAL txlink_rst_n                : STD_LOGIC;
+  SIGNAL tx_analogreset              : STD_LOGIC_VECTOR(0 downto 0);
+  SIGNAL tx_digitalreset             : STD_LOGIC_VECTOR(0 downto 0);
+  SIGNAL tx_bonding_clocks           : STD_LOGIC_VECTOR(5 downto 0) := (others => '0');
+  SIGNAL bonding_clock_0             : STD_LOGIC := '0';
+  SIGNAL bonding_clock_1             : STD_LOGIC := '0';
+  SIGNAL bonding_clock_2             : STD_LOGIC := '0';
+  SIGNAL bonding_clock_3             : STD_LOGIC := '0';
+  SIGNAL bonding_clock_4             : STD_LOGIC := '0';
+  SIGNAL bonding_clock_5             : STD_LOGIC := '0';
+  SIGNAL pll_locked                  : STD_LOGIC_VECTOR(0 downto 0);
+
+  SIGNAL jesd204b_tx_link_data_arr   : t_slv_32_arr(c_nof_jesd204b_tx-1 DOWNTO 0);
+  SIGNAL jesd204b_tx_link_valid      : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0);
+  SIGNAL jesd204b_tx_link_ready      : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0);
+  SIGNAL jesd204b_tx_frame_ready     : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0);
+
+  SIGNAL jesd204b_sync_adc_n         : STD_LOGIC_VECTOR(c_nof_jesd204b_tx-1 DOWNTO 0);
+
+  -- Rx jesd204b IP registers
+  SIGNAL reg_jesd204b_rx_err_enable        : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL reg_jesd204b_rx_err_link_reinit   : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL reg_jesd204b_rx_syncn_sysref_ctrl : STD_LOGIC_VECTOR(c_word_w-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
+  -- Rx 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;
 
+  -- Debug signals to track progress of p_stimuli in Wave Window
+  SIGNAL dbg_restart         : NATURAL := 0;
+  SIGNAL dbg_bsn_source_en   : STD_LOGIC := '0';
+  SIGNAL dbg_jesd_ctrl_reset : STD_LOGIC := '0';
+  SIGNAL dbg_read_jesd204b   : STD_LOGIC := '0';
+  SIGNAL dbg_link_reinit     : STD_LOGIC := '0';
+
+  -- Read JESD204B IP status per signal input c_si
+  PROCEDURE proc_read_jesd204b(c_si                        : IN NATURAL;
+                               SIGNAL rd_clk               : IN STD_LOGIC;
+                               SIGNAL rd_data              : INOUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                               SIGNAL dbg_read             : OUT STD_LOGIC;
+                               SIGNAL rx_err_enable        : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                               SIGNAL rx_err_link_reinit   : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                               SIGNAL rx_syncn_sysref_ctrl : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                               SIGNAL rx_err0              : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err0_w-1 DOWNTO 0);
+                               SIGNAL rx_err1              : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err1_w-1 DOWNTO 0);
+                               SIGNAL csr_rbd_count        : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_csr_rbd_count_w-1 DOWNTO 0);
+                               SIGNAL csr_dev_syncn        : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_csr_dev_syncn_w-1 DOWNTO 0)) IS
+    CONSTANT c_offset : NATURAL :=  c_si * tech_jesd204b_port_span;
+  BEGIN
+    dbg_read <= '1';
+    mmf_mm_bus_rd(c_mm_file_jesd204b, 2, c_offset + tech_jesd204b_field_rx_err_enable_adr, rd_data, rd_clk);
+    rx_err_enable <= rd_data;
+    mmf_mm_bus_rd(c_mm_file_jesd204b, c_offset + tech_jesd204b_field_rx_err_link_reinit_adr, rd_data, rd_clk);
+    rx_err_link_reinit <= rd_data;
+    mmf_mm_bus_rd(c_mm_file_jesd204b, c_offset + tech_jesd204b_field_rx_syncn_sysref_ctrl_adr, rd_data, rd_clk);
+    rx_syncn_sysref_ctrl <= rd_data;
+    mmf_mm_bus_rd(c_mm_file_jesd204b, c_offset + tech_jesd204b_field_rx_err0_adr, rd_data, rd_clk);
+    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, c_offset + tech_jesd204b_field_rx_err1_adr, rd_data, rd_clk);
+    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, c_offset + tech_jesd204b_field_csr_rbd_count_adr, rd_data, rd_clk);
+    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, c_offset + tech_jesd204b_field_csr_dev_syncn_adr, rd_data, rd_clk);
+    csr_dev_syncn <= rd_data(tech_jesd204b_field_csr_dev_syncn_hi DOWNTO tech_jesd204b_field_csr_dev_syncn_lo);
+    dbg_read <= '0';
+  END;
+
+  PROCEDURE proc_read_jesd204b_arr(SIGNAL rd_clk               : IN STD_LOGIC;
+                                   SIGNAL rd_data              : INOUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                                   SIGNAL dbg_read             : OUT STD_LOGIC;
+                                   SIGNAL rx_err_enable        : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                                   SIGNAL rx_err_link_reinit   : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                                   SIGNAL rx_syncn_sysref_ctrl : OUT STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+                                   SIGNAL rx_err0              : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err0_w-1 DOWNTO 0);
+                                   SIGNAL rx_err1              : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_rx_err1_w-1 DOWNTO 0);
+                                   SIGNAL csr_rbd_count        : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_csr_rbd_count_w-1 DOWNTO 0);
+                                   SIGNAL csr_dev_syncn        : OUT STD_LOGIC_VECTOR(tech_jesd204b_field_csr_dev_syncn_w-1 DOWNTO 0)) IS
+  BEGIN
+    FOR I IN 0 TO c_sdp_S_pn-1 LOOP
+      proc_read_jesd204b(I, rd_clk, rd_data, dbg_read,
+                         rx_err_enable,
+                         rx_err_link_reinit,
+                         rx_syncn_sysref_ctrl,
+                         rx_err0,
+                         rx_err1,
+                         csr_rbd_count,
+                         csr_dev_syncn);
+    END LOOP;
+  END;
+
 BEGIN
 
   ----------------------------------------------------------------------------
@@ -164,12 +280,12 @@ BEGIN
   ------------------------------------------------------------------------------
   -- External PPS
   ------------------------------------------------------------------------------  
-  proc_common_gen_pulse(10, c_pps_period, '1', pps_rst, ext_clk, gen_pps);
-  jesd204b_sysref <= gen_pps;
+  proc_common_gen_pulse(10, c_nof_clk_per_sync, '1', pps_rst, ext_clk, gen_pps);
+  JESD204B_SYSREF <= gen_pps;
   ext_pps <= gen_pps;
 
   ------------------------------------------------------------------------------
-  -- DUT
+  -- DUT with JESD204B Rx
   ------------------------------------------------------------------------------
   u_lofar_unb2c_sdp_station_adc : ENTITY lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station
   GENERIC MAP (
@@ -207,22 +323,156 @@ BEGIN
     JESD204B_REFCLK      => JESD204B_REFCLK,
   
     -- jesd204b syncronization signals
-    JESD204B_SYSREF => jesd204b_sysref,
-    JESD204B_SYNC_N => jesd204b_sync_n
+    JESD204B_SYSREF => JESD204B_SYSREF,
+    JESD204B_SYNC_N => JESD204B_SYNC_N
   );
 
+  -----------------------------------------------------------------------------
+  -- Use a JESD204b Tx instance to model the ADCs
+  -- . copied from tb_tech_jesd204b.vhd
+  -----------------------------------------------------------------------------
+
+  -- Clocks and resets
+  tx_avs_clk <= NOT tx_avs_clk AFTER c_tx_avs_clk_period/2;
+
+  mm_rst <= '1', '0' after 800 ns;
+  tx_avs_rst_n <= '0', '1' after 23500 ns;
+  tx_analogreset(0) <= '1', '0' after 18500 ns;
+  tx_digitalreset(0) <= '1', '0' after 23000 ns;
+  txlink_rst_n <= '0', '1' after 25500 ns;
+  pll_locked(0) <= '0', '1' after 1000 ns;
+
+  -- Create bonding clocks
+  bonding_clock_5 <= not bonding_clock_5 after 250 ps;
+  bonding_clock_4 <= not bonding_clock_4 after 250 ps;
+  bonding_clock_3 <= not bonding_clock_3 after 500 ps;
+  bonding_clock_2 <= not bonding_clock_2 after 500 ps;
+  bonding_clock_0 <= not bonding_clock_0 after 2500 ps;
+
+  bonding_clock_1_process : process
+  begin
+    bonding_clock_1 <= '0';
+    wait for 4000 ps;
+    bonding_clock_1 <= '1';
+    wait for 1000 ps;
+  end process;
+
+  tx_bonding_clocks(5) <= transport bonding_clock_5 after 4890 ps;
+  tx_bonding_clocks(4) <= transport bonding_clock_4 after 4640 ps;
+  tx_bonding_clocks(3) <= transport bonding_clock_3 after 4920 ps;
+  tx_bonding_clocks(2) <= transport bonding_clock_2 after 4930 ps;
+  tx_bonding_clocks(1) <= transport bonding_clock_1 after 7490 ps;
+  tx_bonding_clocks(0) <= transport bonding_clock_0 after 4000 ps;
+
+  gen_jesd204b_tx : FOR i IN 0 TO c_nof_jesd204b_tx-1 GENERATE
+    -- Tb DAC
+    u_tech_jesd204b_tx : ENTITY tech_jesd204b_lib.tech_jesd204b_tx
+    PORT MAP (
+      csr_cf                     => OPEN,
+      csr_cs                     => OPEN,
+      csr_f                      => OPEN,
+      csr_hd                     => OPEN,
+      csr_k                      => OPEN,
+      csr_l                      => OPEN,
+      csr_lane_powerdown         => open, --out
+      csr_m                      => OPEN,
+      csr_n                      => OPEN,
+      csr_np                     => OPEN,
+      csr_tx_testmode            => OPEN,
+      csr_tx_testpattern_a       => OPEN,
+      csr_tx_testpattern_b       => OPEN,
+      csr_tx_testpattern_c       => OPEN,
+      csr_tx_testpattern_d       => OPEN,
+      csr_s                      => OPEN,
+      dev_sync_n                 => dev_sync_n(i), --out
+      jesd204_tx_avs_chipselect  => tx_avs_chipselect(i),
+      jesd204_tx_avs_address     => tx_avs_address(i),
+      jesd204_tx_avs_read        => tx_avs_read(i),
+      jesd204_tx_avs_readdata    => tx_avs_readdata(i),
+      jesd204_tx_avs_waitrequest => open,
+      jesd204_tx_avs_write       => '0',
+      jesd204_tx_avs_writedata   => (others => '0'),
+      jesd204_tx_avs_clk         => tx_avs_clk,
+      jesd204_tx_avs_rst_n       => tx_avs_rst_n,
+      jesd204_tx_dlb_data        => open, -- debug/loopback testing
+      jesd204_tx_dlb_kchar_data  => open, -- debug/loopback testing
+      jesd204_tx_frame_ready     => jesd204b_tx_frame_ready(i),
+      jesd204_tx_frame_error     => '0',
+      jesd204_tx_int             => OPEN,            -- Connected to status IO in example design
+      jesd204_tx_link_data       => jesd204b_tx_link_data_arr(i),              --in
+      jesd204_tx_link_valid      => jesd204b_tx_link_valid(i),             --in
+      jesd204_tx_link_ready      => jesd204b_tx_link_ready(i),             --out
+      mdev_sync_n                => dev_sync_n(i), --in
+      pll_locked                 => pll_locked, --in
+      sync_n                     => jesd204b_sync_adc_n(i), --in
+      tx_analogreset             => tx_analogreset,
+      tx_bonding_clocks          => tx_bonding_clocks,--: in  std_logic_vector(5 downto 0)  := (others => 'X'); -- clk
+      tx_cal_busy                => open,
+      tx_digitalreset            => tx_digitalreset,
+      tx_serial_data             => JESD204B_SERIAL_DATA(i downto i),
+      txlink_clk                 => txlink_clk(i),
+      txlink_rst_n_reset_n       => txlink_rst_n,
+      txphy_clk                  => txphy_clk(i downto i),
+      somf                       => OPEN,
+      sysref                     => JESD204B_SYSREF
+    );
+
+    -- One JESD204B_SYNC_N per RCU2
+    jesd204b_sync_adc_n(i) <= JESD204B_SYNC_N(i / c_sdp_S_rcu);
+
+    -- Generate same test pattern for all ADC
+    p_tx_data : PROCESS (JESD204B_REFCLK, mm_rst)
+      VARIABLE v_data  : INTEGER := 0;
+      VARIABLE v_even_sample : BOOLEAN := TRUE;
+    BEGIN
+      IF mm_rst = '1' THEN
+         jesd204b_tx_link_data_arr(i) <= (others => '0');
+         jesd204b_tx_link_valid(i) <= '0';
+         txlink_clk(i) <= '0';
+         v_data := 0;
+         v_even_sample := TRUE;
+       ELSIF rising_edge(JESD204B_REFCLK) THEN
+         txlink_clk(i) <= not txlink_clk(i);
+
+         -- Incrementing data in c_sdp_W_adc_jesd = 16 bits
+         -- . use range c_sdp_W_adc_jesd-1 to avoid simulation warnings:
+         --   Warning: NUMERIC_STD.TO_SIGNED: vector truncated
+         --   Time: 164635 ns  Iteration: 0  Region: /tb_lofar2_unb2c_sdp_station_adc_jesd/gen_jesd204b_tx(2)
+         v_data := (v_data + 1) MOD 2**(c_sdp_W_adc_jesd-1);
+
+         -- Frame the data to 32 bits at half the rate
+         IF jesd204b_tx_link_ready(i) = '0' THEN
+           v_even_sample := TRUE;
+         ELSE
+           v_even_sample := not v_even_sample;
+         END IF;
+         IF v_even_sample = TRUE THEN
+           jesd204b_tx_link_data_arr(i)(c_sdp_W_adc_jesd-1 downto 0) <= TO_SVEC(v_data, c_sdp_W_adc_jesd);
+           jesd204b_tx_link_valid(i) <= '0';
+         ELSE
+           jesd204b_tx_link_data_arr(i)(2*c_sdp_W_adc_jesd-1 downto c_sdp_W_adc_jesd) <= TO_SVEC(v_data, c_sdp_W_adc_jesd);
+           jesd204b_tx_link_valid(i) <= '1';
+         END IF;
+       END IF;
+    END PROCESS;
+
+  END GENERATE;
+
   ------------------------------------------------------------------------------
   -- 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_word                  : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+    VARIABLE v_int                   : INTEGER;
     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
+    dbg_restart <= 0;
     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;
@@ -238,24 +488,7 @@ BEGIN
       -- 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;
+      dbg_bsn_source_en <= '1';  -- marker in wave window
 
       ---------------------------------------------------------------------------
       -- Read JESD_CTRL register
@@ -300,6 +533,31 @@ BEGIN
                               "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 JESD204B IP status per signal input
+      ----------------------------------------------------------------------------
+      FOR I IN 0 TO c_sdp_S_pn-1 LOOP
+        proc_read_jesd204b(I, tb_clk, rd_data, dbg_read_jesd204b,
+                           reg_jesd204b_rx_err_enable,
+                           reg_jesd204b_rx_err_link_reinit,
+                           reg_jesd204b_rx_syncn_sysref_ctrl,
+                           reg_jesd204b_rx_err0,
+                           reg_jesd204b_rx_err1,
+                           reg_jesd204b_csr_rbd_count,
+                           reg_jesd204b_csr_dev_syncn);
+        proc_common_wait_some_cycles(tb_clk, 10);
+
+        -----------------------------------------------------------------------
+        -- Verify expected Rx JESD204B IP values for active signal inputs
+        -----------------------------------------------------------------------
+        IF I < c_nof_jesd204b_tx THEN
+          ASSERT UNSIGNED(reg_jesd204b_rx_err_enable) = tech_jesd204b_field_rx_err_enable_reset
+            REPORT "Wrong rx_err_enable_reset: " & INTEGER'IMAGE(TO_SINT(reg_jesd204b_rx_err_enable)) & " /= " & INTEGER'IMAGE(tech_jesd204b_field_rx_err_enable_reset) SEVERITY ERROR;
+          ASSERT UNSIGNED(reg_jesd204b_rx_err_link_reinit) = tech_jesd204b_field_rx_err_link_reinit_reset
+            REPORT "Wrong rx_err_link_reinit_reset: " & INTEGER'IMAGE(TO_SINT(reg_jesd204b_rx_err_link_reinit)) & " /= " & INTEGER'IMAGE(tech_jesd204b_field_rx_err_link_reinit_reset) SEVERITY ERROR;
+        END IF;
+      END LOOP;
+
       ---------------------------------------------------------------------------
       -- Read ADUH monitor power sum
       ---------------------------------------------------------------------------
@@ -320,43 +578,114 @@ BEGIN
 
       ----------------------------------------------------------------------------
       -- Restart AIT
+      -- . JESD_CTRL reset stops JESD204B OUT rx_clk and asserts JESD204B OUT
+      --   rx_rst, so it is necessary to stop the BSN source, to ensure that
+      --   the rx_clk/dp_clk domain FIFO runs empty before rx_rst is asserted, so
+      --   that no corrupt data blocks will enter the dp_clk domain.
       ----------------------------------------------------------------------------
-      -- . Disable BSN source to allow rx_clk/dp_clk domain FIFO to empty
+
+      -- 1) Disable BSN source to allow rx_clk/dp_clk domain FIFO to run 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
+      -- . 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);
+      dbg_bsn_source_en <= '0';  -- marker in wave window
+
+      -- 2) Reset via JESD_CTRL c_sdp_jesd_ctrl_reset_bi = 31 and read back
+      --   Note: Awkward way to set MSbit without negative integer warning, using TO_SINT(v_word).
+      dbg_jesd_ctrl_reset <= '1';  -- marker in wave window
+      v_word := (OTHERS => '0');
+      v_word(c_sdp_jesd_ctrl_reset_bi) := '1';  -- reset
+      mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, TO_SINT(v_word), 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);
+      -- Read Rx JESD_204B IP status during reset
+      proc_read_jesd204b_arr(tb_clk, rd_data, dbg_read_jesd204b,
+                             reg_jesd204b_rx_err_enable,
+                             reg_jesd204b_rx_err_link_reinit,
+                             reg_jesd204b_rx_syncn_sysref_ctrl,
+                             reg_jesd204b_rx_err0,
+                             reg_jesd204b_rx_err1,
+                             reg_jesd204b_csr_rbd_count,
+                             reg_jesd204b_csr_dev_syncn);
+
+      -- Hold JESD_CTRL reset for > one sync period, so also during a JESD204B_SYSREF pulse,
+      -- to see that JESD_CTRL reset stops JESD204B OUT rx_sysref too.
+      WAIT FOR c_pps_period;
+
+      -- . Re-enable via JESD_CTRL and read back
+      v_word := (OTHERS => '0');  -- release reset
+      v_word(c_si_dis) := '1';   -- disable one signal input
+      mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, TO_SINT(v_word), 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);
+      dbg_jesd_ctrl_reset <= '0';  -- marker in wave window
+
+      -- Wait for a JESD204B_SYSREF pulse
+      WAIT FOR c_pps_period;
+      -- Read Rx JESD_204B IP status
+      proc_read_jesd204b_arr(tb_clk, rd_data, dbg_read_jesd204b,
+                             reg_jesd204b_rx_err_enable,
+                             reg_jesd204b_rx_err_link_reinit,
+                             reg_jesd204b_rx_syncn_sysref_ctrl,
+                             reg_jesd204b_rx_err0,
+                             reg_jesd204b_rx_err1,
+                             reg_jesd204b_csr_rbd_count,
+                             reg_jesd204b_csr_dev_syncn);
+
+      -- 3) Reinit the JESD204B link per signal input
+      dbg_link_reinit <= '1';  -- marker in wave window
+      FOR I IN 0 TO c_sdp_S_pn-1 LOOP
+        v_int := tech_jesd204b_field_rx_syncn_sysref_ctrl_link_reinit +
+                 tech_jesd204b_field_rx_syncn_sysref_ctrl_sysref_alwayson;
+        mmf_mm_bus_wr(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_rx_syncn_sysref_ctrl_adr, v_int, tb_clk);
+      END LOOP;
 
+      WAIT FOR 1 us;
+      -- Read Rx JESD_204B IP status
+      proc_read_jesd204b_arr(tb_clk, rd_data, dbg_read_jesd204b,
+                             reg_jesd204b_rx_err_enable,
+                             reg_jesd204b_rx_err_link_reinit,
+                             reg_jesd204b_rx_syncn_sysref_ctrl,
+                             reg_jesd204b_rx_err0,
+                             reg_jesd204b_rx_err1,
+                             reg_jesd204b_csr_rbd_count,
+                             reg_jesd204b_csr_dev_syncn);
+
+      FOR I IN 0 TO c_sdp_S_pn-1 LOOP
+        v_int := tech_jesd204b_field_rx_syncn_sysref_ctrl_sysref_alwayson;
+        mmf_mm_bus_wr(c_mm_file_jesd204b, v_offset + tech_jesd204b_field_rx_syncn_sysref_ctrl_adr, v_int, tb_clk);
+      END LOOP;
+      dbg_link_reinit <= '0';  -- marker in wave window
+
+      -- Wait for a JESD204B_SYSREF pulse
+      WAIT FOR c_pps_period;
+      -- Read Rx JESD_204B IP status
+      proc_read_jesd204b_arr(tb_clk, rd_data, dbg_read_jesd204b,
+                             reg_jesd204b_rx_err_enable,
+                             reg_jesd204b_rx_err_link_reinit,
+                             reg_jesd204b_rx_syncn_sysref_ctrl,
+                             reg_jesd204b_rx_err0,
+                             reg_jesd204b_rx_err1,
+                             reg_jesd204b_csr_rbd_count,
+                             reg_jesd204b_csr_dev_syncn);
+      -- Count restart loops
+      dbg_restart <= dbg_restart + 1;
     END LOOP;
 
     ---------------------------------------------------------------------------
     -- End Simulation 
     ---------------------------------------------------------------------------   
+    WAIT FOR 10 us;
     sim_done <= '1';
     proc_common_wait_some_cycles(ext_clk, 100);
     proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end);
-- 
GitLab