diff --git a/boards/uniboard2b/designs/unb2b_jesd/src/vhdl/unb2b_jesd.vhd b/boards/uniboard2b/designs/unb2b_jesd/src/vhdl/unb2b_jesd.vhd
index 53edf7f7716f2d3ffb993a24d602d8c8da21ef1e..8a9c73c57cf06601bb8f2b3b8ff36b0faf98be44 100644
--- a/boards/uniboard2b/designs/unb2b_jesd/src/vhdl/unb2b_jesd.vhd
+++ b/boards/uniboard2b/designs/unb2b_jesd/src/vhdl/unb2b_jesd.vhd
@@ -87,8 +87,9 @@ ARCHITECTURE str OF unb2b_jesd IS
   CONSTANT c_fw_version             : t_unb2_board_fw_version := (1, 1);
   CONSTANT c_mm_clk_freq            : NATURAL := c_unb2_board_mm_clk_freq_100M;
 
+  signal CLK                   : STD_LOGIC;
+  --signal PPS                   : STD_LOGIC;
   signal jesd204_rx_sysref_n   : STD_LOGIC;
-  signal CLK                   : STD_LOGIC := '0';
 
   -- System
   SIGNAL cs_sim                     : STD_LOGIC;
@@ -100,6 +101,7 @@ ARCHITECTURE str OF unb2b_jesd IS
   
   SIGNAL st_rst                     : STD_LOGIC;
   SIGNAL st_clk                     : STD_LOGIC;
+  SIGNAL st_pps                     : STD_LOGIC;
 
   -- PIOs
   SIGNAL pout_wdi                   : STD_LOGIC;
@@ -200,7 +202,8 @@ BEGIN
     g_eth_clk_freq       => c_unb2_board_eth_clk_freq_125M,
     g_aux                => c_unb2_board_aux,
     g_factory_image      => g_factory_image,
-    g_protect_addr_range => g_protect_addr_range
+    g_protect_addr_range => g_protect_addr_range,
+    g_dp_clk_use_pll     => FALSE
   )
   PORT MAP (
     -- Clock an reset signals
@@ -214,7 +217,7 @@ BEGIN
 
     dp_rst                   => st_rst,
     dp_clk                   => st_clk,
-    dp_pps                   => OPEN,
+    dp_pps                   => st_pps,
     dp_rst_in                => st_rst,
     dp_clk_in                => st_clk,
     
@@ -392,10 +395,12 @@ BEGIN
     jesd204_rx_link_valid    => jesd204_rx_link_valid,
     jesd204_rx_link_ready    => jesd204_rx_link_ready,
     jesd204_rx_sysref        => jesd204_rx_sysref_n,
-    jesd204_device_clk       => jesd204_device_clk
+    jesd204_device_clk       => st_clk
   );
 
   QSFP_LED(0)          <= pll_locked;
+  CLK                  <= jesd204_device_clk;
+  --PPS                  <= jesd204_rx_sysref;
   jesd204_rx_sysref_n  <= NOT jesd204_rx_sysref;
 
   gen_jesd_mon_in : FOR i IN 0 TO 1-1 GENERATE
@@ -412,23 +417,23 @@ BEGIN
     g_technology   => g_technology,
     g_nof_streams  => 1,
     g_data_w       => 32,
-    g_buf_nof_data => 8192,
-    g_buf_use_sync => FALSE,
+    g_buf_nof_data => 16384, --8192,
+    g_buf_use_sync => TRUE, -- when TRUE start filling the buffer at the in_sync, else after the last word was read
     g_use_rx_seq   => FALSE
   )
   PORT MAP (
     mm_rst            => mm_rst,
     mm_clk            => mm_clk,
     dp_rst            => mm_rst,
-    dp_clk            => jesd204_device_clk,
+    dp_clk            => st_clk,
 
     ram_data_buf_mosi => ram_diag_data_buf_jesd_mosi,
     ram_data_buf_miso => ram_diag_data_buf_jesd_miso,
     reg_data_buf_mosi => reg_diag_data_buf_jesd_mosi,
     reg_data_buf_miso => reg_diag_data_buf_jesd_miso,
 
-    in_sosi_arr       => diag_data_buf_snk_in_arr
-    --in_sync           => jesd204_rx_sysref_n
+    in_sosi_arr       => diag_data_buf_snk_in_arr,
+    in_sync           => st_pps
   );
 
 END str;
diff --git a/boards/uniboard2b/designs/unb2b_jesd/tb/python/util_unb2_jesd.py b/boards/uniboard2b/designs/unb2b_jesd/tb/python/util_unb2_jesd.py
new file mode 100644
index 0000000000000000000000000000000000000000..31bf0f5e6d659e3cc3e4b4db67d8085920084b02
--- /dev/null
+++ b/boards/uniboard2b/designs/unb2b_jesd/tb/python/util_unb2_jesd.py
@@ -0,0 +1,400 @@
+#! /usr/bin/env python
+###############################################################################
+#
+# 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/>.
+#
+###############################################################################
+
+"""Test case for util_unb2_jesd
+
+Quickly get started, try this: python util_unb2_jesd.py --unb 1 --fn 0 --seq JESD
+
+Usage:
+
+   --rep = number of intervals that diagnostics results are verified
+   --sim targets a running simulation.
+
+Description:
+   This test case tests:
+   - system info
+   - read sensors
+   - read ppsh
+   - write to wdi to force reload from bank 0
+   - flash access: write image to bank 1
+   - remote update: start image in bank 1
+   - link test between ports on the same FPGA (same XO)
+   - link test between ports on different Uniboards (XO drift)
+   - stable link after image restart
+
+"""
+
+###############################################################################
+# System imports
+import sys
+import signal
+import random
+import test_case
+import node_io
+import pi_system_info
+import pi_unb2_sens
+import pi_unb2_pmbus
+import pi_unb2_i2c_hmc
+import pi_unb_fpga_sens
+import pi_ppsh
+import pi_wdi
+import pi_epcs
+import pi_remu
+import pi_eth
+import pi_bsn_monitor
+import pi_diag_block_gen
+import pi_diag_data_buffer
+import pi_debug_wave
+import matplotlib
+matplotlib.use('tkagg') # to make X11 forwarding work
+import matplotlib.pyplot as plt
+import numpy as np
+
+from tools import *
+from common import *
+from pi_common import *
+
+
+
+def sign_extend(value, bits):
+    sign_bit = 1 << (bits - 1)
+    return (value & (sign_bit - 1)) - (value & sign_bit)
+
+def test_JESD(tc,io,cmd):
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    tc.set_section_id('Read - ')
+    instanceName = 'JESD'
+    blocksize = 16384 #8196
+    Db = pi_diag_data_buffer.PiDiagDataBuffer(tc,io,nofStreams=1,ramSizePerStream=blocksize,instanceName=instanceName)
+
+    ppsh = pi_ppsh.PiPpsh(tc, io)
+    while tc.repeat != 0:
+        ppsh.wait_until_pps(vLevel=6)
+        print 'PPS...'
+
+        db_ram = []
+        samples = []
+        samplesB = []
+        toggle = 0
+        databuf = Db.read_data_buffer(streamNr=0,vLevel=5)
+        for d in databuf[0]:
+            # is 32 bit and has 2 14-bit samples which are interleaved in time
+            msb=sign_extend(((d>>18) & 0xffff),14)
+            lsb=sign_extend(((d>>2) & 0xffff),14)
+            if toggle==0:
+                samples.append(np.int16(msb))
+            else:
+                samples.append(np.int16(lsb))
+            toggle+=1
+            toggle&=1
+            
+        plt.plot(samples[:100])
+        plt.show()
+
+
+
+
+def test_info(tc,io,cmd):
+    tc.set_section_id('Read System Info - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    info = pi_system_info.PiSystemInfo(tc, io)
+    info.read_system_info()
+    tc.append_log(3, '')
+    info.read_use_phy()
+    tc.append_log(3, '')
+    design_name = info.read_design_name()
+    tc.append_log(1, '>>> design_name=%s' % design_name)
+    tc.append_log(3, '')
+    info.read_stamps()
+    tc.append_log(3, '')
+    info.read_design_note()
+    
+    expected_design_name = tc.gpString
+    if expected_design_name != '':
+        tc.set_section_id('Verify System Info - ')
+        compared=True
+        for name in design_name:
+            if (name != expected_design_name): 
+                tc.set_result('FAILED')
+                compared=False
+                tc.append_log(2, '>>> design_name mismatch!! (%s != %s)' % (name,expected_design_name))
+        tc.append_log(1, '>>> Verify design_name == %s: %s' % (expected_design_name,compared))
+
+
+
+def read_regmap(tc,io,cmd):
+    tc.set_section_id('Update REGMAP - ')
+    info = pi_system_info.PiSystemInfo(tc, io)
+    tc.append_log(1, '>>> reading REGMAPs')
+    info.make_register_info()
+    tc.append_log(1, '>>> reload NodeIO class')
+    return node_io.NodeIO(tc.nodeImages, tc.base_ip)
+
+
+    
+def test_sensors(tc,io,cmd):
+    tc.set_section_id('Read sensors - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+    
+    sens = pi_unb2_sens.PiUnbSens(tc, io)
+    pmbus = pi_unb2_pmbus.PiUnbSens(tc, io)
+
+    sens.read_unb_sensors()
+    tc.append_log(3, '')
+
+    pmbus.read_unb_sensors()
+    tc.append_log(3, '')
+
+    fpga_sens = pi_unb_fpga_sens.PiUnbFpgaSens(tc, io)
+    fpga_sens.read_fpga_temperature()
+
+    # Calculate floating point value according PMBus lineair
+def calc_lin_3bytes(data,mode):
+    expo = (mode & 0x1F)
+    if expo > 2**4:
+        expo = expo - 2**5
+    output = (data[1]*256 + data[0]) * 2**expo
+    return output
+
+
+def test_ppsh(tc,io,cmd):
+    tc.set_section_id('Read PPSH capture count - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+    
+    Ppsh = pi_ppsh.PiPpsh(tc, io)
+    Ppsh.read_ppsh_capture_cnt()
+    tc.append_log(3, '')
+
+
+
+def test_wdi(tc,io,cmd):
+    tc.set_section_id('Reset to image in bank 0 using WDI - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    Wdi = pi_wdi.PiWdi(tc, io)
+    Wdi.write_wdi_override()
+    tc.append_log(3, '')
+    tc.append_log(3, '>>> Booting...')
+    tc.sleep(5.0)
+
+
+def test_remu(tc,io,cmd):
+    tc.set_section_id('REMU start image in bank 1 - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    dummy_tc = test_case.Testcase('Dummy TB - ', '',logfilename='REMU-log')
+    dummy_tc.set_result('PASSED')
+
+    Remu = pi_remu.PiRemu(dummy_tc, io)
+    try:
+        Remu.write_user_reconfigure()
+    except:
+        pass # ignoring FAILED
+
+    if dummy_tc.get_result() == 'FAILED':
+        tc.append_log(1, 'Result=%s but ignoring this' % dummy_tc.get_result())
+
+    tc.append_log(3, '>>> Booting...')
+    tc.sleep(5.0)
+    tc.append_log(3, '')
+
+
+def test_eth(tc,io,cmd):
+    tc.set_section_id('ETH status - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+    
+    eth = pi_eth.PiEth(tc, io)
+    hdr=eth.read_hdr(0)
+    eth.disassemble_hdr(hdr)
+    tc.append_log(3, '')
+
+
+def test_flash(tc,io,cmd):
+    tc.set_section_id('Flash write to bank 1 - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    Epcs = pi_epcs.PiEpcs(tc, io)
+    path_to_rbf = instanceName = tc.gpString
+    Epcs.write_ver_raw_binary_file("user", path_to_rbf)
+    tc.append_log(3, '')
+
+def test_factory_flash(tc,io,cmd):
+    tc.set_section_id('Factory Flash write to bank 0 - ')
+    tc.append_log(3, '>>>')
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    tc.append_log(3, '>>>')
+
+    Epcs = pi_epcs.PiEpcs(tc, io)
+    path_to_rbf = instanceName = tc.gpString
+    Epcs.write_ver_raw_binary_file("factory", path_to_rbf)
+    tc.append_log(3, '')
+
+def sleep(tc,io,cmd):
+    tc.set_section_id('%s - ' % cmd)
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+    if cmd == 'sleep1':
+        tc.sleep(1.0)
+    elif cmd == 'sleep5':
+        tc.sleep(5.0)
+
+def show_help(tc,io,cmd):
+    tc.set_section_id('%s - ' % cmd)
+    tc.append_log(1, '>>> %s' % help_text(tc,io,cmd))
+
+
+# Avaliable commands
+Cmd = dict()
+Cmd['REGMAP']  = (read_regmap,  'using pi_system_info to read register info (access PIO_SYSTEM_INFO) and store REGMAPs','')
+Cmd['INFO']    = (test_info,    'using pi_system_info to read system info (access PIO_SYSTEM_INFO)','(-s for expected design_name)')
+Cmd['FLASH']   = (test_flash,   'using pi_epcs to program/verify flash','(-s for .rbf file)')
+Cmd['FACFLASH']= (test_factory_flash,'using pi_epcs to program/verify factory flash','(-s for .rbf file)')
+Cmd['SENSORS'] = (test_sensors, 'using pi_unb_sens to readout sensors (access REG_UNB_SENS)','')
+Cmd['PPSH']    = (test_ppsh,    'using pi_ppsh to read PPSH capture count (access PIO_PPS)','')
+Cmd['ETH']     = (test_eth,     'using pi_eth to read eth status','')
+Cmd['REMU']    = (test_remu,    'using pi_remu to load user image (access REG_REMU)','')
+Cmd['WDI']     = (test_wdi,     'using pi_wdi to reset to image in bank 0 (access REG_WDI)','')
+Cmd['JESD']    = (test_JESD,    'using DB (pi_diag_data_buffer.py)','')
+Cmd['sleep1']  = (sleep,        'Sleep 1 second','')
+Cmd['sleep5']  = (sleep,        'Sleep 5 seconds','')
+Cmd['example'] = (show_help,    'show several example commands','')
+Cmd['help']    = (show_help,    'show help on commands','')
+
+
+def help_text(tc,io,cmd):
+    str=''
+    if cmd == 'help':
+        tc.append_log(0, '\n')
+        tc.append_log(0, '>>> Help:')
+        tc.append_log(0, 'Usage: %s <nodes> <command sequence> [-v..] [--rep ...]' % sys.argv[0])
+        tc.append_log(0, '')
+        tc.append_log(0, '    <nodes>: use: --unb N --fn N --bn N (N is a number or vector) or:')
+        tc.append_log(0, '    <nodes>: use: --gn N (N is a number or vector)')
+        tc.append_log(0, '    <command sequence>: use: --seq <command(s) separated by ",">:')
+        tc.append_log(0, '')
+        for cmd in sorted(Cmd):
+            tc.append_log(0, '    .  %s\t%s  %s' % (cmd,Cmd[cmd][1],Cmd[cmd][2]))
+        tc.append_log(0, '')
+        tc.append_log(0, '    [-vN]: verbose level N (default=5): %s' % tc.verbose_levels())
+        tc.append_log(0, '    [--rep N]: N=number of repeats, where -1 is forever, non-stop')
+        help_text(tc,io,'example')
+    elif cmd == 'example':
+        tc.append_log(0, '')
+        tc.append_log(0, '>>> Examples:')
+        tc.append_log(0, '')
+        tc.append_log(0, 'Getting INFO from all nodes on 1 Uniboard: %s --gn 0:7 --seq INFO' % sys.argv[0])
+        tc.append_log(0, '')
+        tc.append_log(0, '[reset, load user img] sequence: --seq REGMAP,WDI,REGMAP,REMU,REGMAP,INFO')
+        tc.append_log(0, '[flash+start user img] sequence: --seq FLASH,WDI,REGMAP,REMU,REGMAP,INFO -s file.rbf')
+        tc.append_log(0, '[re-read info,sensors] sequence: --seq INFO,PPSH,SENSORS --rep -1 -s expected_design_name')
+        tc.append_log(0, '[reset to factory]     sequence: --seq WDI,REGMAP')
+        tc.append_log(0, '[program user image]   sequence: --seq FLASH -s file.rbf')
+        tc.append_log(0, '[load user image]      sequence: --seq REMU,REGMAP')
+        tc.append_log(0, '[modelsim BG-DB test] arguments: --unb 0 --fn 0 --seq BGDB --sim -r 0:2')
+        tc.append_log(0, '\n')
+    else:
+        str = Cmd[cmd][1]
+    return str
+
+
+def signal_handler(signal, frame):
+    print('You pressed Ctrl+C!')
+    tc.repeat=0
+
+
+##################################################################################################################
+# Main
+#
+# Create a test case object
+tc = test_case.Testcase('TB - ', '')
+tc.set_result('PASSED')
+dgnName = tc.gpString
+tc.append_log(3, '>>>')
+tc.append_log(0, '>>> Title : Test bench (%s) on nodes %s, %s' % (sys.argv[0],tc.unb_nodes_string(''),dgnName))
+tc.append_log(0, '>>> Commandline : %s' % " ".join(sys.argv))
+tc.append_log(3, '>>>')
+
+
+# Create access object for nodes
+io = node_io.NodeIO(tc.nodeImages, tc.base_ip)
+#io.setNofRetries(0)
+signal.signal(signal.SIGINT, signal_handler)
+
+##################################################################################################################
+# Run tests
+if tc.repeat<2: tc.repeat=2
+
+while tc.repeat != 0: # -1 for non-stop
+    tc.repeat -= 1
+    tc.next_run()
+    tc.append_log(3, '')
+    
+    try:
+        for cmd in tc.sequence:
+            tc.set_section_id('Next command: %s ' % cmd)
+            tc.append_log(1, '>>> Testrun %d (@%.02fs) - ' % (tc.get_nof_runs(),tc.get_run_time()))
+
+            if cmd == 'REGMAP': # reload node_io:
+                io = Cmd[cmd][0](tc,io,cmd)
+            else:
+                Cmd[cmd][0](tc,io,cmd)
+
+
+    except KeyError:
+        print 'Unknown command:',cmd
+        cmd='help'
+        Cmd[cmd][0](tc,io,cmd)
+    except:
+        print 'Catched error:',sys.exc_info()[0]
+
+
+
+##################################################################################################################
+# End
+tc.set_section_id('')
+tc.append_log(3, '')
+tc.append_log(3, '>>>')
+tc.append_log(0, '>>> Test bench result: %s' % tc.get_result())
+tc.append_log(0, '>>> Number of runs=%d' % tc.get_nof_runs())
+tc.append_log(0, '>>> Number of errors=%d' % tc.get_nof_errors())
+tc.append_log(0, '>>> Runtime=%f seconds (%f hours)' % (tc.get_run_time(),tc.get_run_time()/3600))
+tc.append_log(3, '>>>')
+
+sys.exit(tc.get_result())
+