diff --git a/libraries/io/i2c/tb/vhdl/dev_pmbus.vhd b/libraries/io/i2c/tb/vhdl/dev_pmbus.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..15754ab7edc2c6d2a63a891110557c529c46df27
--- /dev/null
+++ b/libraries/io/i2c/tb/vhdl/dev_pmbus.vhd
@@ -0,0 +1,112 @@
+-------------------------------------------------------------------------------
+--
+-- 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/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+USE work.i2c_dev_unb2_pkg.ALL;
+
+
+ENTITY dev_pmbus IS
+  GENERIC(
+    g_address   : STD_LOGIC_VECTOR(6 DOWNTO 0)
+  );
+  PORT(
+    scl         : IN    STD_LOGIC;
+    sda         : INOUT STD_LOGIC;
+    vin         : IN    INTEGER;
+    vout        : IN    INTEGER;
+    iout        : IN    INTEGER;
+    vcap        : IN    INTEGER;
+    temp        : IN    INTEGER
+  );
+END dev_pmbus;
+
+
+ARCHITECTURE beh OF dev_pmbus IS
+
+  SIGNAL enable    : STD_LOGIC;                       --enable
+  SIGNAL stop      : STD_LOGIC;                       --stop
+  SIGNAL wr_dat    : STD_LOGIC_VECTOR(7 DOWNTO 0);    --I2C write data
+  SIGNAL wr_val    : STD_LOGIC;
+  SIGNAL rd_dat    : STD_LOGIC_VECTOR(7 DOWNTO 0);    --I2C read data
+  SIGNAL rd_req    : STD_LOGIC;
+
+  SIGNAL cmd_en    : STD_LOGIC := '0';
+  SIGNAL cmd       : NATURAL;                         --device command
+  
+  SIGNAL config_reg   : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00001000";
+  SIGNAL status_reg   : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
+  SIGNAL temp_hi_reg  : STD_LOGIC_VECTOR(7 DOWNTO 0) := "01111111";
+  SIGNAL temp_lo_reg  : STD_LOGIC_VECTOR(7 DOWNTO 0) := "11001001";
+  
+BEGIN
+
+  i2c_slv_device : ENTITY work.i2c_slv_device
+  GENERIC MAP (
+    g_address => g_address
+  )
+  PORT MAP (
+    scl   	=> scl,
+    sda     => sda,
+    en      => enable,
+    p       => stop,
+    wr_dat  => wr_dat,
+    wr_val  => wr_val,
+    rd_req  => rd_req,
+    rd_dat  => rd_dat
+  );
+  
+  
+  p_write : PROCESS (enable, wr_val)  --first write byte is treated as command
+  BEGIN
+    IF RISING_EDGE(enable) THEN
+      cmd_en <= '1';
+    ELSIF FALLING_EDGE(enable) THEN
+      cmd_en <= '0';
+    END IF;
+    IF RISING_EDGE(wr_val) THEN
+      cmd_en <= '0';
+      IF cmd_en='1' THEN
+        cmd <= TO_INTEGER(UNSIGNED(wr_dat));
+      ELSE
+        CASE cmd IS  -- add write cmd later
+          WHEN OTHERS                        => NULL;
+        END CASE;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  p_read : PROCESS (rd_req)
+  BEGIN
+    IF RISING_EDGE(rd_req) THEN
+      CASE cmd IS  --only model some read cmd
+        WHEN PMBUS_REG_READ_VIN      => rd_dat <= STD_LOGIC_VECTOR(TO_SIGNED(vin,8));
+        WHEN PMBUS_REG_READ_VOUT     => rd_dat <= STD_LOGIC_VECTOR(TO_SIGNED(vout,8));
+        WHEN PMBUS_REG_READ_IOUT     => rd_dat <= STD_LOGIC_VECTOR(TO_SIGNED(iout,8));
+        WHEN PMBUS_REG_READ_VCAP     => rd_dat <= STD_LOGIC_VECTOR(TO_SIGNED(vcap,8));
+        WHEN PMBUS_REG_READ_TEMP     => rd_dat <= STD_LOGIC_VECTOR(TO_SIGNED(temp,8));
+        WHEN OTHERS                  => rd_dat <= (OTHERS => '1');
+      END CASE;
+    END IF;
+  END PROCESS;
+
+END beh;
diff --git a/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_pmbus.vhd b/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_pmbus.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..56443c9f0e351f9ff70b8eb094cba8bc70d73aea
--- /dev/null
+++ b/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_pmbus.vhd
@@ -0,0 +1,437 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- 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: Verify the i2c_commander and create a u_protocol_ram init file
+--
+-- Description:
+--   The protocols for the I2C slaves on UNB are stored in the dev_unb_pkg.
+--   The protocols for the I2C slaves on ADU are stored in the dev_adu_pkg.
+--   This tb can model both via g_board = "unb" or "adu". The protocols for the
+--   board are concatenated into c_protocol_ram_init.
+--   The p_mm_stimuli writes the c_protocol_ram_init bytes to u_protocol_ram
+--   and in parallel they get written to a file by u_protocol_ram_init_file:
+--
+--     data/adu_protocol_ram_init.txt
+--   or
+--     data/unb_protocol_ram_init.txt
+--
+--   See data/how_to_create_memory_init_hex_file.txt for how to
+--   create a memory initialization hex file from this.
+--
+--   The p_mm_stimuli continues with executing all protocol lists and checking
+--   the expected results and ASSERTs ERROR if an access went not OK and in
+--   case of read data if the read data value was not OK.
+--
+-- Remark:
+-- . Use c_protocol_ram_init_file="UNUSED" to initialize the u_protocol_ram
+--   with the c_protocol_ram_init sequence,
+--   else use the actual protocol_ram_init.hex file and verify that it contains
+--   the same as the c_protocol_ram_init sequence.
+--
+-- Usage:
+--   > do wave_i2c_commander.do
+--   > run -all
+--   In the Wave Window view the signal u_commander/protocol_index to observe
+--   the progress
+--
+-- Uniboard2 version derived from tb_i2c_commander November 2015
+--   this version tests the PMBUS bus
+
+
+ENTITY tb_i2c_commander_unb2_pmbus IS
+  GENERIC (
+    g_board      : STRING := "unb2" -- only works with UniBoard2 
+  );
+END tb_i2c_commander_unb2_pmbus;
+
+LIBRARY IEEE, common_lib, tst_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL;
+USE work.i2c_smbus_pkg.ALL;
+USE work.i2c_dev_max1617_pkg.ALL;
+USE work.i2c_dev_unb2_pkg.ALL;
+USE work.i2c_pkg.ALL;
+USE work.i2c_commander_pkg.ALL;
+USE work.i2c_commander_unb2_sens_pkg.ALL;
+USE work.i2c_commander_unb2_pmbus_pkg.ALL; -- in case we can add the PMBUS later
+
+
+ARCHITECTURE tb OF tb_i2c_commander_unb2_pmbus IS
+
+  --CONSTANT c_protocol_ram_init_file : STRING := "data/unb2_sens_protocol_ram_init.hex";
+  --CONSTANT c_protocol_ram_init_file : STRING := "data/unb2_pmbus_protocol_ram_init.hex";
+  CONSTANT c_protocol_ram_init_file : STRING := "UNUSED"; -- start with this, then make a hex file from the txt file?
+   
+  CONSTANT c_use_result_ram       : BOOLEAN := TRUE;
+  CONSTANT c_sim                  : BOOLEAN := TRUE;  --FALSE
+  CONSTANT c_clk_freq_in_MHz      : NATURAL := 100;  -- 100 MHz
+  CONSTANT c_clk_period           : TIME    := (10**3/c_clk_freq_in_MHz) * 1 ns;
+  CONSTANT c_rst_period           : TIME    := 4 * c_clk_period;
+  
+  CONSTANT c_phy_i2c              : t_c_i2c_phy := func_i2c_sel_a_b(c_sim, c_i2c_phy_sim, func_i2c_calculate_phy(c_clk_freq_in_MHz));
+  
+
+  --CONSTANT c_pmbus_temp_address    : STD_LOGIC_VECTOR := TO_UVEC(MAX1617_ADR_LOW_LOW, 7);  -- use other slave address to force I2C errors
+  CONSTANT c_pmbus_core_address      : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_CORE_BMR464_ADR, 7); 
+  CONSTANT c_pmbus_vccram_address    : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_VCCRAM_BMR461_ADR, 7); 
+  CONSTANT c_pmbus_tcvr0_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_TCVR0_BMR461_ADR, 7); 
+  CONSTANT c_pmbus_tcvr1_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_TCVR1_BMR461_ADR, 7); 
+  CONSTANT c_pmbus_ctrl_address      : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_CTRL_BMR461_ADR, 7); 
+  CONSTANT c_pmbus_fpgaio_address    : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_PMB_FPGAIO_BMR461_ADR, 7); 
+  CONSTANT c_max1618_temp            : INTEGER := 60;
+
+  
+  -- Select the expected read data arrays for the result data (the read data values are tb dependent, so therefore they are not obtained from a package)
+
+  TYPE t_i2c_unb2_natural_arr IS ARRAY (INTEGER RANGE 0 TO 31) OF NATURAL; -- needto test some long protocol lists
+  TYPE t_i2c_unb2_natural_mat IS ARRAY (INTEGER RANGE <>) OF t_i2c_unb2_natural_arr;
+  
+  CONSTANT c_default_expected_data_arr             : t_i2c_unb2_natural_arr := (  others => 254);  
+                                                                           
+  CONSTANT c_expected_data_mat : t_i2c_unb2_natural_mat(0 TO c_i2c_unb2_nof_protocol_lists-1) := (c_default_expected_data_arr,
+                                                                                                  c_default_expected_data_arr,
+                                                                                                  c_default_expected_data_arr,
+                                                                                                  c_default_expected_data_arr);                                                   
+
+  -- RAM sizes
+  CONSTANT c_mem_i2c              : t_c_i2c_mm := c_i2c_cmdr_unb2_pmbus_i2c_mm;
+  
+  -- Commander parameters
+  CONSTANT c_protocol_ram_init    : t_nat_natural_arr := c_i2c_cmdr_unb2_pmbus_protocol_ram_init;
+  CONSTANT c_nof_result_data_arr  : t_nat_natural_arr := c_i2c_cmdr_unb2_pmbus_nof_result_data_arr;
+  
+  CONSTANT c_protocol_commander   : t_c_i2c_cmdr_commander := c_i2c_cmdr_unb2_pmbus_protocol_commander;
+  
+  -- Commander MM register word indexes
+  CONSTANT c_protocol_status_wi   : NATURAL := 3*c_protocol_commander.nof_protocols;
+  CONSTANT c_result_error_cnt_wi  : NATURAL := 3*c_protocol_commander.nof_protocols + 1;
+  CONSTANT c_result_data_wi       : NATURAL := 3*c_protocol_commander.nof_protocols + 2;
+
+  
+  -- Test bench PHY
+  SIGNAL tb_end            : STD_LOGIC := '0';
+  SIGNAL clk               : STD_LOGIC := '0';
+  SIGNAL rst               : STD_LOGIC := '1';
+  SIGNAL sync              : STD_LOGIC := '1';
+ 
+  SIGNAL scl_stretch       : STD_LOGIC := 'Z';
+  SIGNAL scl               : STD_LOGIC;
+  SIGNAL sda               : STD_LOGIC;  
+
+  -- File interface
+  SIGNAL file_miso         : t_mem_miso;
+  SIGNAL file_mosi         : t_mem_mosi;
+  
+  -- MM registers interface
+  SIGNAL commander_miso    : t_mem_miso;
+  SIGNAL commander_mosi    : t_mem_mosi;
+  SIGNAL protocol_miso     : t_mem_miso;
+  SIGNAL protocol_mosi     : t_mem_mosi;
+  SIGNAL result_miso       : t_mem_miso;
+  SIGNAL result_mosi       : t_mem_mosi;
+  
+  -- Commander results
+  SIGNAL protocol_data     : NATURAL;
+  SIGNAL protocol_status   : NATURAL;
+  SIGNAL result_data       : NATURAL;
+  SIGNAL result_error_cnt  : NATURAL;
+  
+BEGIN
+
+  -- run -all
+
+  rst <= '0' AFTER 4*c_clk_period;
+  clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
+  
+  -- I2C bus
+  scl <= 'H';   -- model I2C pull up
+  sda <= 'H';   -- model I2C pull up, use '0' and '1' to verify SDA forced low or high error
+
+  scl <= scl_stretch;
+
+  sens_clk_stretch : PROCESS (scl)
+  BEGIN
+    IF falling_edge(scl) THEN
+      scl_stretch <= '0', 'Z' AFTER 50 ns;   -- < 10 ns to effectively disable stretching, >= 50 ns to enable it
+    END IF;
+  END PROCESS;
+  
+  u_protocol_ram_init_file : ENTITY tst_lib.tst_output
+  GENERIC MAP (
+    g_file_name   => "data/" & g_board & "_protocol_ram_init.txt",
+    g_nof_data    => 1,
+    g_data_width  => c_byte_w,
+    g_data_type   => "UNSIGNED"
+  )
+  PORT MAP (
+    clk      => clk,
+    rst      => rst,
+    in_dat   => file_mosi.wrdata(c_byte_w-1 DOWNTO 0),
+    in_val   => file_mosi.wr
+  );
+  
+  p_mm_stimuli : PROCESS
+  BEGIN
+    -- Wait for reset release
+    commander_mosi <= c_mem_mosi_rst;
+    file_mosi      <= c_mem_mosi_rst;
+    protocol_mosi  <= c_mem_mosi_rst;
+    result_mosi    <= c_mem_mosi_rst;
+    proc_common_wait_until_low(clk, rst);
+    proc_common_wait_some_cycles(clk, 10);
+    
+    ----------------------------------------------------------------------------
+    -- Initialize the u_protocol_ram or verify its default contents
+    ----------------------------------------------------------------------------
+    
+    IF c_protocol_ram_init_file="UNUSED" THEN
+      -- Write
+      FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+        proc_mem_mm_bus_wr(I, c_protocol_ram_init(I), clk, protocol_miso, protocol_mosi);  -- fill u_protocol_ram
+      END LOOP;
+      FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+        proc_mem_mm_bus_wr(I, SMBUS_C_END, clk, protocol_miso, protocol_mosi);             -- fill remainder of u_protocol_ram with default
+      END LOOP;
+      
+    ELSE
+      -- Read and verify
+      FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+        proc_mem_mm_bus_rd(I, clk, protocol_miso, protocol_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_data <= TO_UINT(protocol_miso.rddata(c_byte_w-1 DOWNTO 0));
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT c_protocol_ram_init(I)=protocol_data
+          REPORT "Unexpected protocol data" SEVERITY ERROR;
+      END LOOP;
+      FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+        proc_mem_mm_bus_rd(I, clk, protocol_miso, protocol_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_data <= TO_UINT(protocol_miso.rddata(c_byte_w-1 DOWNTO 0));
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT SMBUS_C_END=protocol_data
+          REPORT "Unexpected protocol end data" SEVERITY ERROR;
+      END LOOP;
+    END IF;
+    
+    proc_common_wait_some_cycles(clk, 10);
+    
+    
+    ----------------------------------------------------------------------------
+    -- Create the u_protocol_ram_init_file
+    ----------------------------------------------------------------------------
+    
+    FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+      proc_mem_mm_bus_wr(I, c_protocol_ram_init(I), clk, file_miso, file_mosi);  -- fill u_protocol_ram_init_file
+    END LOOP;
+    FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+      proc_mem_mm_bus_wr(I, SMBUS_C_END, clk, file_miso, file_mosi);             -- fill remainder of u_protocol_ram_init_file with default
+    END LOOP;
+    
+    proc_common_wait_some_cycles(clk, 10);
+    
+    
+    ----------------------------------------------------------------------------
+    -- Try and verify all commander protocols
+    ----------------------------------------------------------------------------
+    
+    FOR P IN 0 TO c_protocol_commander.nof_protocols-1 LOOP
+    
+      -- Issue protocol list P
+      proc_mem_mm_bus_wr(P, 1, clk, commander_miso, commander_mosi);
+  
+      -- Wait for protocol done
+      WHILE protocol_status/=c_i2c_cmdr_state_done LOOP
+        -- read commander protocol status register
+        proc_mem_mm_bus_rd(c_protocol_status_wi, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_status <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+      END LOOP;
+      
+      -- Read commander result error count
+      proc_mem_mm_bus_rd(c_result_error_cnt_wi, clk, commander_miso, commander_mosi);
+      proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+      result_error_cnt <= TO_UINT(commander_miso.rddata);
+      proc_common_wait_some_cycles(clk, 1);
+      ASSERT result_error_cnt=0
+        REPORT "The result error count is not 0" SEVERITY ERROR;
+      
+      -- Read commander result data
+      FOR I IN 0 TO c_nof_result_data_arr(P)-1 LOOP
+        proc_mem_mm_bus_rd(c_result_data_wi+I, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        result_data <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT c_expected_data_mat(P)(I)=result_data
+          REPORT "Unexpected result data" SEVERITY WARNING;
+      END LOOP;
+    
+      -- Wait for protocol idle
+      WHILE protocol_status/=c_i2c_cmdr_state_idle LOOP
+        -- read commander protocol status register
+        proc_mem_mm_bus_rd(c_protocol_status_wi, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_status <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+      END LOOP;
+      
+      -- Wait some time between the protocols
+      proc_common_wait_some_cycles(clk, 100);
+    END LOOP;
+    
+    ----------------------------------------------------------------------------
+    -- The end
+    ----------------------------------------------------------------------------
+    
+    proc_common_wait_some_cycles(clk, 100);
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;
+  
+  
+  -- I2C commander
+  u_commander : ENTITY work.i2c_commander
+  GENERIC MAP (
+    g_sim                    => c_sim,
+    g_i2c_cmdr               => c_protocol_commander,
+    g_i2c_mm                 => c_mem_i2c,
+    g_i2c_phy                => c_phy_i2c,
+    g_protocol_ram_init_file => c_protocol_ram_init_file,
+    g_use_result_ram         => c_use_result_ram
+  )
+  PORT MAP (
+    rst               => rst,
+    clk               => clk,
+    sync              => sync,
+    
+    ---------------------------------------------------------------------------
+    -- Memory Mapped slave interfaces
+    ---------------------------------------------------------------------------
+    commander_mosi    => commander_mosi,
+    commander_miso    => commander_miso,
+
+    -- If the default protocol list in u_protocol_ram is fine, then the protocol slave port can be left no connected
+    protocol_mosi     => protocol_mosi,
+    protocol_miso     => protocol_miso,
+    
+    -- Typically the commander status registers are sufficient, so then the results slave port can be left no connected
+    result_mosi       => result_mosi,
+    result_miso       => result_miso,
+    
+    ---------------------------------------------------------------------------
+    -- I2C interface
+    ---------------------------------------------------------------------------
+    scl               => scl,
+    sda               => sda
+  );
+    
+  -- I2C slaves
+  u_pmbus_core : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_core_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 9,
+    iout      => 10,
+    vcap      => 0,
+    temp      => 34
+  );
+  
+  u_pmbus_vccram : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_vccram_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 91,
+    vout      => 12,
+    iout      => 11,
+    vcap      => 75,
+    temp      => 35
+  );
+
+  u_pmbus_tcvr0 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_tcvr0_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 92,
+    vout      => 18,
+    iout      => 12,
+    vcap      => 0,
+    temp      => 36
+  );
+
+  u_pmbus_tcvr1 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_tcvr1_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 93,
+    vout      => 18,
+    iout      => 13,
+    vcap      => 0,
+    temp      => 37
+  );
+
+  u_pmbus_ctrl : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_ctrl_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 94,
+    vout      => 33,
+    iout      => 14,
+    vcap      => 0,
+    temp      => 38
+  );
+
+  u_pmbus_fpgaio : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_pmbus_fpgaio_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 33,
+    iout      => 15,
+    vcap      => 0,
+    temp      => 39
+  );
+
+  
+END tb;
+
diff --git a/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_sens.vhd b/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_sens.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..8e6559b64388aa127e6a8fe5fb77cac769cd51d2
--- /dev/null
+++ b/libraries/io/i2c/tb/vhdl/tb_i2c_commander_unb2_sens.vhd
@@ -0,0 +1,467 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- 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: Verify the i2c_commander and create a u_protocol_ram init file
+--
+-- Description:
+--   The protocols for the I2C slaves on UNB are stored in the dev_unb_pkg.
+--   The protocols for the I2C slaves on ADU are stored in the dev_adu_pkg.
+--   This tb can model both via g_board = "unb" or "adu". The protocols for the
+--   board are concatenated into c_protocol_ram_init.
+--   The p_mm_stimuli writes the c_protocol_ram_init bytes to u_protocol_ram
+--   and in parallel they get written to a file by u_protocol_ram_init_file:
+--
+--     data/adu_protocol_ram_init.txt
+--   or
+--     data/unb_protocol_ram_init.txt
+--
+--   See data/how_to_create_memory_init_hex_file.txt for how to
+--   create a memory initialization hex file from this.
+--
+--   The p_mm_stimuli continues with executing all protocol lists and checking
+--   the expected results and ASSERTs ERROR if an access went not OK and in
+--   case of read data if the read data value was not OK.
+--
+-- Remark:
+-- . Use c_protocol_ram_init_file="UNUSED" to initialize the u_protocol_ram
+--   with the c_protocol_ram_init sequence,
+--   else use the actual protocol_ram_init.hex file and verify that it contains
+--   the same as the c_protocol_ram_init sequence.
+--
+-- Usage:
+--   > do wave_i2c_commander.do
+--   > run -all
+--   In the Wave Window view the signal u_commander/protocol_index to observe
+--   the progress
+--
+-- Uniboard2 version derived from tb_i2c_commander November 2015
+--   this version tests the SENS bus
+
+
+ENTITY tb_i2c_commander_unb2_sens IS
+  GENERIC (
+    g_board      : STRING := "unb2" -- only works with UniBoard2 
+  );
+END tb_i2c_commander_unb2_sens;
+
+LIBRARY IEEE, common_lib, tst_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL;
+USE work.i2c_smbus_pkg.ALL;
+USE work.i2c_dev_max1617_pkg.ALL;
+USE work.i2c_dev_unb2_pkg.ALL;
+USE work.i2c_pkg.ALL;
+USE work.i2c_commander_pkg.ALL;
+USE work.i2c_commander_unb2_sens_pkg.ALL;
+USE work.i2c_commander_unb2_pmbus_pkg.ALL; -- in case we can add the PMBUS later
+
+
+ARCHITECTURE tb OF tb_i2c_commander_unb2_sens IS
+
+  --CONSTANT c_protocol_ram_init_file : STRING := "data/unb2_sens_protocol_ram_init.hex";
+  --CONSTANT c_protocol_ram_init_file : STRING := "data/unb2_pmbus_protocol_ram_init.hex";
+  CONSTANT c_protocol_ram_init_file : STRING := "UNUSED"; -- start with this, then make a hex file from the txt file?
+   
+  CONSTANT c_use_result_ram       : BOOLEAN := TRUE;
+  CONSTANT c_sim                  : BOOLEAN := TRUE;  --FALSE
+  CONSTANT c_clk_freq_in_MHz      : NATURAL := 100;  -- 100 MHz
+  CONSTANT c_clk_period           : TIME    := (10**3/c_clk_freq_in_MHz) * 1 ns;
+  CONSTANT c_rst_period           : TIME    := 4 * c_clk_period;
+  
+  CONSTANT c_phy_i2c              : t_c_i2c_phy := func_i2c_sel_a_b(c_sim, c_i2c_phy_sim, func_i2c_calculate_phy(c_clk_freq_in_MHz));
+  
+
+  --CONSTANT c_sens_temp_address    : STD_LOGIC_VECTOR := TO_UVEC(MAX1617_ADR_LOW_LOW, 7);  -- use other slave address to force I2C errors
+  CONSTANT c_sens_temp_address    : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_TEMP_MAX1617_ADR, 7); 
+  CONSTANT c_sens_dcdc_address    : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_DCDC_BMR456_ADR, 7); 
+  CONSTANT c_sens_pim_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_PIM_PIM4328PD_ADR, 7); 
+  CONSTANT c_sens_1v2_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_1V2_BMR461_ADR, 7); 
+  CONSTANT c_sens_3v3_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_3V3_BMR461_ADR, 7); 
+  CONSTANT c_sens_clk_address     : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_CLK_BMR461_ADR, 7); 
+  CONSTANT c_sens_qsfp0_address   : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_QSFP0_BMR464_ADR, 7); 
+  CONSTANT c_sens_qsfp1_address   : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_QSFP1_BMR464_ADR, 7); 
+  CONSTANT c_sens_eeprom_address  : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_EEPROM_CAT24C02_ADR, 7); 
+  CONSTANT c_sens_temp2_address   : STD_LOGIC_VECTOR := TO_UVEC(I2C_UNB2_SENS_TEMP_TMP451_ADR, 7); 
+  CONSTANT c_max1618_temp         : INTEGER := 60;
+
+  
+  -- Select the expected read data arrays for the result data (the read data values are tb dependent, so therefore they are not obtained from a package)
+
+  TYPE t_i2c_unb2_natural_arr IS ARRAY (INTEGER RANGE 0 TO 31) OF NATURAL; -- needto test some long protocol lists
+  TYPE t_i2c_unb2_natural_mat IS ARRAY (INTEGER RANGE <>) OF t_i2c_unb2_natural_arr;
+  
+  CONSTANT c_max1618_expected_data_read_temp_arr   : t_i2c_unb2_natural_arr := (c_max1618_temp,   others => 254);  
+  CONSTANT c_default_expected_data_arr             : t_i2c_unb2_natural_arr := (  others => 254);  
+                                                                           
+  CONSTANT c_expected_data_mat : t_i2c_unb2_natural_mat(0 TO c_i2c_unb2_nof_protocol_lists-1) := (c_max1618_expected_data_read_temp_arr,
+                                                                                                  c_default_expected_data_arr,
+                                                                                                  c_default_expected_data_arr,
+                                                                                                  c_default_expected_data_arr);                                                   
+
+  -- RAM sizes
+  CONSTANT c_mem_i2c              : t_c_i2c_mm := c_i2c_cmdr_unb2_sens_i2c_mm;
+  
+  -- Commander parameters
+  CONSTANT c_protocol_ram_init    : t_nat_natural_arr := c_i2c_cmdr_unb2_sens_protocol_ram_init;
+  CONSTANT c_nof_result_data_arr  : t_nat_natural_arr := c_i2c_cmdr_unb2_sens_nof_result_data_arr;
+  
+  CONSTANT c_protocol_commander   : t_c_i2c_cmdr_commander := c_i2c_cmdr_unb2_sens_protocol_commander;
+  
+  -- Commander MM register word indexes
+  CONSTANT c_protocol_status_wi   : NATURAL := 3*c_protocol_commander.nof_protocols;
+  CONSTANT c_result_error_cnt_wi  : NATURAL := 3*c_protocol_commander.nof_protocols + 1;
+  CONSTANT c_result_data_wi       : NATURAL := 3*c_protocol_commander.nof_protocols + 2;
+
+  
+  -- Test bench PHY
+  SIGNAL tb_end            : STD_LOGIC := '0';
+  SIGNAL clk               : STD_LOGIC := '0';
+  SIGNAL rst               : STD_LOGIC := '1';
+  SIGNAL sync              : STD_LOGIC := '1';
+ 
+  SIGNAL scl_stretch       : STD_LOGIC := 'Z';
+  SIGNAL scl               : STD_LOGIC;
+  SIGNAL sda               : STD_LOGIC;  
+
+  -- File interface
+  SIGNAL file_miso         : t_mem_miso;
+  SIGNAL file_mosi         : t_mem_mosi;
+  
+  -- MM registers interface
+  SIGNAL commander_miso    : t_mem_miso;
+  SIGNAL commander_mosi    : t_mem_mosi;
+  SIGNAL protocol_miso     : t_mem_miso;
+  SIGNAL protocol_mosi     : t_mem_mosi;
+  SIGNAL result_miso       : t_mem_miso;
+  SIGNAL result_mosi       : t_mem_mosi;
+  
+  -- Commander results
+  SIGNAL protocol_data     : NATURAL;
+  SIGNAL protocol_status   : NATURAL;
+  SIGNAL result_data       : NATURAL;
+  SIGNAL result_error_cnt  : NATURAL;
+  
+BEGIN
+
+  -- run -all
+
+  rst <= '0' AFTER 4*c_clk_period;
+  clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
+  
+  -- I2C bus
+  scl <= 'H';   -- model I2C pull up
+  sda <= 'H';   -- model I2C pull up, use '0' and '1' to verify SDA forced low or high error
+
+  scl <= scl_stretch;
+
+  sens_clk_stretch : PROCESS (scl)
+  BEGIN
+    IF falling_edge(scl) THEN
+      scl_stretch <= '0', 'Z' AFTER 50 ns;   -- < 10 ns to effectively disable stretching, >= 50 ns to enable it
+    END IF;
+  END PROCESS;
+  
+  u_protocol_ram_init_file : ENTITY tst_lib.tst_output
+  GENERIC MAP (
+    g_file_name   => "data/" & g_board & "_protocol_ram_init.txt",
+    g_nof_data    => 1,
+    g_data_width  => c_byte_w,
+    g_data_type   => "UNSIGNED"
+  )
+  PORT MAP (
+    clk      => clk,
+    rst      => rst,
+    in_dat   => file_mosi.wrdata(c_byte_w-1 DOWNTO 0),
+    in_val   => file_mosi.wr
+  );
+  
+  p_mm_stimuli : PROCESS
+  BEGIN
+    -- Wait for reset release
+    commander_mosi <= c_mem_mosi_rst;
+    file_mosi      <= c_mem_mosi_rst;
+    protocol_mosi  <= c_mem_mosi_rst;
+    result_mosi    <= c_mem_mosi_rst;
+    proc_common_wait_until_low(clk, rst);
+    proc_common_wait_some_cycles(clk, 10);
+    
+    ----------------------------------------------------------------------------
+    -- Initialize the u_protocol_ram or verify its default contents
+    ----------------------------------------------------------------------------
+    
+    IF c_protocol_ram_init_file="UNUSED" THEN
+      -- Write
+      FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+        proc_mem_mm_bus_wr(I, c_protocol_ram_init(I), clk, protocol_miso, protocol_mosi);  -- fill u_protocol_ram
+      END LOOP;
+      FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+        proc_mem_mm_bus_wr(I, SMBUS_C_END, clk, protocol_miso, protocol_mosi);             -- fill remainder of u_protocol_ram with default
+      END LOOP;
+      
+    ELSE
+      -- Read and verify
+      FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+        proc_mem_mm_bus_rd(I, clk, protocol_miso, protocol_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_data <= TO_UINT(protocol_miso.rddata(c_byte_w-1 DOWNTO 0));
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT c_protocol_ram_init(I)=protocol_data
+          REPORT "Unexpected protocol data" SEVERITY ERROR;
+      END LOOP;
+      FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+        proc_mem_mm_bus_rd(I, clk, protocol_miso, protocol_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_data <= TO_UINT(protocol_miso.rddata(c_byte_w-1 DOWNTO 0));
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT SMBUS_C_END=protocol_data
+          REPORT "Unexpected protocol end data" SEVERITY ERROR;
+      END LOOP;
+    END IF;
+    
+    proc_common_wait_some_cycles(clk, 10);
+    
+    
+    ----------------------------------------------------------------------------
+    -- Create the u_protocol_ram_init_file
+    ----------------------------------------------------------------------------
+    
+    FOR I IN 0 TO c_protocol_ram_init'LENGTH-1 LOOP
+      proc_mem_mm_bus_wr(I, c_protocol_ram_init(I), clk, file_miso, file_mosi);  -- fill u_protocol_ram_init_file
+    END LOOP;
+    FOR I IN c_protocol_ram_init'LENGTH TO c_mem_i2c.protocol_nof_dat-1 LOOP
+      proc_mem_mm_bus_wr(I, SMBUS_C_END, clk, file_miso, file_mosi);             -- fill remainder of u_protocol_ram_init_file with default
+    END LOOP;
+    
+    proc_common_wait_some_cycles(clk, 10);
+    
+    
+    ----------------------------------------------------------------------------
+    -- Try and verify all commander protocols
+    ----------------------------------------------------------------------------
+    
+    FOR P IN 0 TO c_protocol_commander.nof_protocols-1 LOOP
+    
+      -- Issue protocol list P
+      proc_mem_mm_bus_wr(P, 1, clk, commander_miso, commander_mosi);
+  
+      -- Wait for protocol done
+      WHILE protocol_status/=c_i2c_cmdr_state_done LOOP
+        -- read commander protocol status register
+        proc_mem_mm_bus_rd(c_protocol_status_wi, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_status <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+      END LOOP;
+      
+      -- Read commander result error count
+      proc_mem_mm_bus_rd(c_result_error_cnt_wi, clk, commander_miso, commander_mosi);
+      proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+      result_error_cnt <= TO_UINT(commander_miso.rddata);
+      proc_common_wait_some_cycles(clk, 1);
+      ASSERT result_error_cnt=0
+        REPORT "The result error count is not 0" SEVERITY ERROR;
+      
+      -- Read commander result data
+      FOR I IN 0 TO c_nof_result_data_arr(P)-1 LOOP
+        proc_mem_mm_bus_rd(c_result_data_wi+I, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        result_data <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+        ASSERT c_expected_data_mat(P)(I)=result_data
+          REPORT "Unexpected result data" SEVERITY WARNING;
+      END LOOP;
+    
+      -- Wait for protocol idle
+      WHILE protocol_status/=c_i2c_cmdr_state_idle LOOP
+        -- read commander protocol status register
+        proc_mem_mm_bus_rd(c_protocol_status_wi, clk, commander_miso, commander_mosi);
+        proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, clk);
+        protocol_status <= TO_UINT(commander_miso.rddata);
+        proc_common_wait_some_cycles(clk, 1);
+      END LOOP;
+      
+      -- Wait some time between the protocols
+      proc_common_wait_some_cycles(clk, 100);
+    END LOOP;
+    
+    ----------------------------------------------------------------------------
+    -- The end
+    ----------------------------------------------------------------------------
+    
+    proc_common_wait_some_cycles(clk, 100);
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;
+  
+  
+  -- I2C commander
+  u_commander : ENTITY work.i2c_commander
+  GENERIC MAP (
+    g_sim                    => c_sim,
+    g_i2c_cmdr               => c_protocol_commander,
+    g_i2c_mm                 => c_mem_i2c,
+    g_i2c_phy                => c_phy_i2c,
+    g_protocol_ram_init_file => c_protocol_ram_init_file,
+    g_use_result_ram         => c_use_result_ram
+  )
+  PORT MAP (
+    rst               => rst,
+    clk               => clk,
+    sync              => sync,
+    
+    ---------------------------------------------------------------------------
+    -- Memory Mapped slave interfaces
+    ---------------------------------------------------------------------------
+    commander_mosi    => commander_mosi,
+    commander_miso    => commander_miso,
+
+    -- If the default protocol list in u_protocol_ram is fine, then the protocol slave port can be left no connected
+    protocol_mosi     => protocol_mosi,
+    protocol_miso     => protocol_miso,
+    
+    -- Typically the commander status registers are sufficient, so then the results slave port can be left no connected
+    result_mosi       => result_mosi,
+    result_miso       => result_miso,
+    
+    ---------------------------------------------------------------------------
+    -- I2C interface
+    ---------------------------------------------------------------------------
+    scl               => scl,
+    sda               => sda
+  );
+    
+  -- I2C slaves
+  u_sens_dcdc : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_dcdc_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 48,
+    vout      => 9,
+    iout      => 5,
+    vcap      => 0,
+    temp      => 34
+  );
+  
+  u_sens_pim : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_pim_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 48,
+    vout      => 0,
+    iout      => 12,
+    vcap      => 75,
+    temp      => 35
+  );
+
+  u_sens_1v2 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_1v2_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 12,
+    iout      => 20,
+    vcap      => 0,
+    temp      => 36
+  );
+
+  u_sens_3v3 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_3v3_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 33,
+    iout      => 20,
+    vcap      => 0,
+    temp      => 37
+  );
+
+  u_sens_clk : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_clk_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 25,
+    iout      => 20,
+    vcap      => 0,
+    temp      => 38
+  );
+
+  u_sens_qsfp0 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_qsfp0_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 32,
+    iout      => 11,
+    vcap      => 0,
+    temp      => 39
+  );
+
+  u_sens_qsfp1 : ENTITY work.dev_pmbus 
+  GENERIC MAP (
+    g_address => c_sens_qsfp1_address
+  )
+  PORT MAP (
+    scl       => scl,
+    sda       => sda,
+    vin       => 90,
+    vout      => 34,
+    iout      => 10,
+    vcap      => 0,
+    temp      => 40
+  );
+
+
+  u_sens_temp : ENTITY work.dev_max1618   -- both on "unb" and on "adu"
+  GENERIC MAP (
+    g_address => c_sens_temp_address
+  )
+  PORT MAP (
+    scl  => scl,
+    sda  => sda,
+    temp => c_max1618_temp
+  );
+
+  
+END tb;
+