diff --git a/libraries/base/ring/hdllib.cfg b/libraries/base/ring/hdllib.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d4452e8b64c7013b3bed1dca2884f3fa2bb58ae6
--- /dev/null
+++ b/libraries/base/ring/hdllib.cfg
@@ -0,0 +1,21 @@
+hdl_lib_name = ring
+hdl_library_clause_name = ring_lib
+hdl_lib_uses_synth = common dp technology mm dp diag
+hdl_lib_uses_sim = 
+hdl_lib_technology = 
+
+synth_files = 
+    src/vhdl/ring_pkg.vhd
+    src/vhdl/ring_lane_info_reg.vhd
+    src/vhdl/ring_lane_info.vhd
+test_bench_files =
+    tb/vhdl/tb_ring_lane_info.vhd
+
+regression_test_vhdl = 
+    tb/vhdl/tb_ring_lane_info.vhd
+
+[modelsim_project_file]
+
+
+[quartus_project_file]
+
diff --git a/libraries/base/ring/ring.peripheral.yaml b/libraries/base/ring/ring.peripheral.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dfa91403a1e74a2d3be813f1f2b2f9227a2b54ee
--- /dev/null
+++ b/libraries/base/ring/ring.peripheral.yaml
@@ -0,0 +1,22 @@
+schema_name: args
+schema_version: 1.0
+schema_type: peripheral
+
+hdl_library_name: ring
+hdl_library_description: "Ring for UniBoard2"
+
+peripherals:
+  - peripheral_name: ring_lane_info    # pi_ring_lane_info.py
+    peripheral_description: "Ring lane info."
+    mm_ports:
+      # MM port for ring_lane+info.vhd
+      - mm_port_name: REG_RING_LANE_INFO
+        mm_port_type: REG
+        mm_port_span: 4 * MM_BUS_SIZE
+        mm_port_description: |
+          "The ring lane info contains information about the ring lanes."
+        fields:
+          - - { field_name: transport_nof_hops, mm_width: 32, access_mode: RW, address_offset: 0xC  }
+          - - { field_name: lane_direction,     mm_width:  1, access_mode: RO, address_offset: 0x8  }
+          - - { field_name: tx_select,          mm_width:  1, access_mode: RW, address_offset: 0x4  }
+          - - { field_name: rx_select,          mm_width:  1, access_mode: RW, address_offset: 0x0  }
diff --git a/libraries/base/ring/src/vhdl/ring_lane_info.vhd b/libraries/base/ring/src/vhdl/ring_lane_info.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..64404d410a087d7813cc50869846790c141b316a
--- /dev/null
+++ b/libraries/base/ring/src/vhdl/ring_lane_info.vhd
@@ -0,0 +1,86 @@
+-------------------------------------------------------------------------------
+--
+-- 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: R. van der Walle
+
+-- Purpose:
+-- . Ring lane info register
+-- Description:
+-- See ring_pkg.vhd
+-- Remark:
+-- .
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.common_field_pkg.ALL;
+USE work.ring_pkg.ALL;
+
+ENTITY ring_lane_info IS
+  PORT (
+    -- Clocks and reset
+    mm_rst             : IN  STD_LOGIC;   -- reset synchronous with mm_clk
+    mm_clk             : IN  STD_LOGIC;   -- memory-mapped bus clock
+
+    dp_clk             : IN  STD_LOGIC;
+    dp_rst             : IN  STD_LOGIC;
+
+    reg_mosi           : IN  t_mem_mosi;
+    reg_miso           : OUT t_mem_miso;
+
+    -- inputs from other blocks
+    lane_direction     : IN STD_LOGIC;
+
+    -- sdp info
+    lane_info          : OUT t_lane_info
+  );
+END ring_lane_info;
+
+
+ARCHITECTURE str OF ring_lane_info IS
+
+  SIGNAL lane_info_ro: t_lane_info;  -- ro = read only
+
+BEGIN
+
+  u_mm_fields: ENTITY work.ring_lane_info_reg
+  PORT MAP (
+
+    mm_clk    => mm_clk,
+    mm_rst    => mm_rst,
+
+    dp_clk    => dp_clk,
+    dp_rst    => dp_rst,
+
+    reg_mosi  => reg_mosi,
+    reg_miso  => reg_miso,
+
+    lane_info_ro => lane_info_ro,
+    lane_info    => lane_info
+  );
+
+  
+  lane_info_ro.lane_direction <= lane_direction;
+
+END str;
diff --git a/libraries/base/ring/src/vhdl/ring_lane_info_reg.vhd b/libraries/base/ring/src/vhdl/ring_lane_info_reg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..cc805353e543a1948f9d33736934bb15fc86d759
--- /dev/null
+++ b/libraries/base/ring/src/vhdl/ring_lane_info_reg.vhd
@@ -0,0 +1,110 @@
+-------------------------------------------------------------------------------
+--
+-- 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: R. van der Walle
+
+-- Purpose:
+-- . Ring lane info register
+-- Description:
+-- See ring_pkg.vhd
+-- Remark:
+-- .
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, mm_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.common_field_pkg.ALL;
+USE work.ring_pkg.ALL;
+
+ENTITY ring_lane_info_reg IS
+  PORT (
+    -- Clocks and reset
+    mm_rst     : IN  STD_LOGIC;   -- reset synchronous with mm_clk
+    mm_clk     : IN  STD_LOGIC;   -- memory-mapped bus clock
+
+    dp_clk     : IN  STD_LOGIC;
+    dp_rst     : IN  STD_LOGIC;
+
+    reg_mosi : IN  t_mem_mosi;
+    reg_miso : OUT t_mem_miso;
+
+    -- sdp info
+    lane_info_ro : IN  t_lane_info;  -- ro = read only
+    lane_info    : OUT t_lane_info
+  );
+END ring_lane_info_reg;
+
+
+ARCHITECTURE str OF ring_lane_info_reg IS
+
+  SIGNAL mm_fields_in  : STD_LOGIC_VECTOR(field_slv_in_len(c_lane_info_field_arr)-1 DOWNTO 0);
+  SIGNAL mm_fields_out : STD_LOGIC_VECTOR(field_slv_out_len(c_lane_info_field_arr)-1 DOWNTO 0);
+
+  SIGNAL lane_info_rd : t_lane_info;
+  SIGNAL lane_info_wr : t_lane_info;
+
+BEGIN
+
+  lane_info    <= lane_info_rd;
+
+  p_lane_info_rd : PROCESS(lane_info_wr, lane_info_ro)
+  BEGIN
+    -- default write assign all fields 
+    lane_info_rd <= lane_info_wr;
+    
+    -- overrule the read only fields 
+    lane_info_rd.lane_direction <= lane_info_ro.lane_direction;
+  END PROCESS;
+
+
+  u_mm_fields: ENTITY mm_lib.mm_fields
+  GENERIC MAP(
+    g_use_slv_in_val  => FALSE,    -- use FALSE to save logic when always slv_in_val='1'
+    g_field_arr       => c_lane_info_field_arr
+  )
+  PORT MAP (
+    mm_clk     => mm_clk,
+    mm_rst     => mm_rst,
+
+    mm_mosi    => reg_mosi,
+    mm_miso    => reg_miso,
+
+    slv_clk    => dp_clk,
+    slv_rst    => dp_rst,
+
+    slv_in     => mm_fields_in,
+    slv_in_val => '1',
+
+    slv_out    => mm_fields_out
+  );
+
+  -- add "RO" fields to mm_fields  
+  mm_fields_in(field_hi(c_lane_info_field_arr, "lane_direction") DOWNTO field_lo(c_lane_info_field_arr, "lane_direction")) <= slv(lane_info_rd.lane_direction);
+
+  -- get "RW" fields from mm_fields
+  lane_info_wr.transport_nof_hops <= mm_fields_out(field_hi(c_lane_info_field_arr, "transport_nof_hops") DOWNTO field_lo(c_lane_info_field_arr, "transport_nof_hops"));
+  lane_info_wr.tx_select          <= sl(mm_fields_out(field_hi(c_lane_info_field_arr, "tx_select") DOWNTO field_lo(c_lane_info_field_arr, "tx_select")));
+  lane_info_wr.rx_select          <= sl(mm_fields_out(field_hi(c_lane_info_field_arr, "rx_select") DOWNTO field_lo(c_lane_info_field_arr, "rx_select")));
+
+END str;
diff --git a/libraries/base/ring/src/vhdl/ring_pkg.vhd b/libraries/base/ring/src/vhdl/ring_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..4786e34fb59f1d07cbb733e64246272ec20a5e3a
--- /dev/null
+++ b/libraries/base/ring/src/vhdl/ring_pkg.vhd
@@ -0,0 +1,87 @@
+-------------------------------------------------------------------------------
+--
+-- 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: R. van der Walle
+-- Purpose: 
+-- . This package contains ring specific constants.
+-- Description:
+-- Remark:
+-------------------------------------------------------------------------------
+LIBRARY ieee, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.common_field_pkg.ALL;
+
+PACKAGE ring_pkg is
+-- lane info, see https://support.astron.nl/confluence/x/jyu7Ag
+-- +====================+========+==============================================================================+===========================+
+-- |       Field        | Access |                                   Description                                |          Remark           |
+-- +====================+========+==============================================================================+===========================+
+-- | transport_nof_hops | RW     | Number of hops (N_transport_hops) to transport a packet. The RN will remove  | Same setting for all RN   |
+-- |                    |        | packets that have traveled N_transport_hops hops. If                         |                           |
+-- |                    |        | N_transport_hops >= N_rn, then the ring cannot remove the packet, because    |                           |
+-- |                    |        | then it cannot distinguish between a packet that just starts or that has     |                           |
+-- |                    |        | has already been transported along the entire ring, so then the application  |                           |
+-- |                    |        | has to take care of removing the packet from the ring (or let it cycle along |                           |
+-- |                    |        |  the ring 'forever').                                                        |                           |
+-- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+
+-- | lane_direction     | RO     | 1 = transport in positive RN index direction on lanes with even lane index. 0| Same setting for all RN   |
+-- |                    |        | = transport in negative RN index direction on lanes with odd lane index.     |                           | 
+-- |                    |        | Hence for N_lanes = 8, lanes 0, 2, 4, and 6 will transport in positive       |                           |
+-- |                    |        | direction, and lanes 1, 3, 5, 7 will transport in opposite (= negative)      |                           |
+-- |                    |        | direction. The lane direction is fixed per lane and therefore read only.     |                           |
+-- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+
+-- | tx_select          | RW     | 0 = transmit via on board port, 1 = transmit via cable (QSFP) port. Default  | Individual setting per RN |
+-- |                    |        | in firmware assume cable between RN on different UniBoard2 and assume cable  |                           |
+-- |                    |        | to close the ring defined by ring_info. The programmable tx_select allows    |                           |
+-- |                    |        | using cables between other RN in the ring.                                   |                           |
+-- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+
+-- | rx_select          | RW     | 0 = receive via on board port, 1 = receive via cable (QSFP) port. Default in | Individual setting per RN |
+-- |                    |        | firmware assume cable between RN on different UniBoard2 and assume cable to  |                           |
+-- |                    |        | close the ring defined by ring_info. The programmable rx_select allows using |                           |
+-- |                    |        | cables between other RN in the ring.                                         |                           |
+-- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+
+
+  TYPE t_lane_info IS RECORD
+    transport_nof_hops : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+    lane_direction     : STD_LOGIC; 
+    tx_select          : STD_LOGIC;   
+    rx_select          : STD_LOGIC;      
+  END RECORD;   
+
+  CONSTANT c_lane_info_rst : t_lane_info := 
+      ( (OTHERS => '0'), '0', '0', '0' );  
+
+  CONSTANT c_lane_info_field_arr : t_common_field_arr(3 DOWNTO 0) := 
+      ( (field_name_pad("transport_nof_hops"), "RW", 32, field_default(0)),
+        (field_name_pad("lane_direction"),     "RO",  1, field_default(0)),
+        (field_name_pad("tx_select"),          "RW",  1, field_default(0)),
+        (field_name_pad("rx_select"),          "RW",  1, field_default(0)) );
+
+ END PACKAGE ring_pkg;
+
+PACKAGE BODY ring_pkg IS
+
+  
+END ring_pkg;
+
diff --git a/libraries/base/ring/tb/vhdl/tb_ring_lane_info.vhd b/libraries/base/ring/tb/vhdl/tb_ring_lane_info.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7744465c7ab13d171cc7d1fde94f8754c59bcbd5
--- /dev/null
+++ b/libraries/base/ring/tb/vhdl/tb_ring_lane_info.vhd
@@ -0,0 +1,154 @@
+-------------------------------------------------------------------------------
+--
+-- 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: R. van der Walle
+
+-- Purpose:
+-- . test bench for ring_lane_info.vhd (and ring_lane_info_reg.vhd)
+-- Description:
+--
+-- Remark:
+-- .
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_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.ring_pkg.ALL;
+
+
+ENTITY tb_ring_lane_info IS
+END tb_ring_lane_info;
+
+ARCHITECTURE tb OF tb_ring_lane_info IS
+  CONSTANT c_dp_clk_period        : TIME := 5 ns;     -- 200 MHz
+  CONSTANT c_mm_clk_period        : TIME := 20 ns;    -- 50 MHz
+
+  CONSTANT c_cross_clock_domain_latency : NATURAL := 20;
+
+  -- used mm_adresses on mm bus
+  CONSTANT c_mm_addr_rx_select               : NATURAL := 0; 
+  CONSTANT c_mm_addr_tx_select               : NATURAL := 1; 
+  CONSTANT c_mm_addr_lane_direction          : NATURAL := 2; 
+  CONSTANT c_mm_addr_transport_nof_hops      : NATURAL := 3; 
+  
+  SIGNAL tb_end              : STD_LOGIC := '0';
+  SIGNAL tb_mm_reg_end       : STD_LOGIC := '0';
+
+  SIGNAL dp_clk              : STD_LOGIC := '1';   -- digital data path clock = 200 MHz (deser factor 4);
+  SIGNAL dp_rst              : STD_LOGIC;
+
+  SIGNAL mm_clk              : STD_LOGIC := '1';   -- MM control clock = 50 MHz
+  SIGNAL mm_rst              : STD_LOGIC;
+  
+  SIGNAL reg_mosi            : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_miso            : t_mem_miso;
+
+  -- signals used to change settings of ring_lane_info 
+  SIGNAL lane_direction     : STD_LOGIC := '0'; 
+
+  SIGNAL lane_info  : t_lane_info; 
+
+  -- signals used for response of mm bus
+  SIGNAL mm_natural_response : NATURAL;
+BEGIN
+  dp_rst <= '1', '0' AFTER c_dp_clk_period*7;
+  dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2;
+  
+  mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
+  mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
+
+  p_mm_reg_stimuli : PROCESS
+  BEGIN
+    reg_mosi <= c_mem_mosi_rst;
+
+    -- initialyze
+    proc_common_wait_until_low(mm_clk, mm_rst);
+    proc_common_wait_some_cycles(mm_clk, 100);
+
+    -- default all register hold value 0, try to write 1 in all registers
+    proc_mem_mm_bus_wr(c_mm_addr_transport_nof_hops     ,11 ,mm_clk, reg_miso, reg_mosi); 
+    proc_mem_mm_bus_wr(c_mm_addr_lane_direction         ,1  ,mm_clk, reg_miso, reg_mosi); -- RO
+    proc_mem_mm_bus_wr(c_mm_addr_tx_select              ,1  ,mm_clk, reg_miso, reg_mosi);
+    proc_mem_mm_bus_wr(c_mm_addr_rx_select              ,1  ,mm_clk, reg_miso, reg_mosi);
+    proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
+
+
+    proc_mem_mm_bus_rd(c_mm_addr_transport_nof_hops, mm_clk, reg_mosi);  proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+    mm_natural_response <= TO_UINT(reg_miso.rddata);  proc_common_wait_some_cycles(mm_clk, 1);
+    ASSERT mm_natural_response = 11 REPORT "wrong c_mm_addr_transport_nof_hops" SEVERITY ERROR;
+
+    proc_mem_mm_bus_rd(c_mm_addr_lane_direction, mm_clk, reg_mosi);  proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+    mm_natural_response <= TO_UINT(reg_miso.rddata);  proc_common_wait_some_cycles(mm_clk, 1);
+    ASSERT mm_natural_response /= 1 REPORT "wrong lane_direction (not read only)" SEVERITY ERROR;
+
+    proc_mem_mm_bus_rd(c_mm_addr_tx_select, mm_clk, reg_mosi);  proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+    mm_natural_response <= TO_UINT(reg_miso.rddata);  proc_common_wait_some_cycles(mm_clk, 1);
+    ASSERT mm_natural_response = 1 REPORT "wrong tx_select" SEVERITY ERROR;
+
+    proc_mem_mm_bus_rd(c_mm_addr_rx_select, mm_clk, reg_mosi);  proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+    mm_natural_response <= TO_UINT(reg_miso.rddata);  proc_common_wait_some_cycles(mm_clk, 1);
+    ASSERT mm_natural_response = 1 REPORT "wrong rx_select" SEVERITY ERROR;
+
+    proc_common_wait_some_cycles(mm_clk, 100);
+    tb_mm_reg_end <= '1';
+    WAIT;
+
+  END PROCESS;
+
+  -- check if values in lane_info match with expected values
+  p_lane_info_stimuli : PROCESS
+  BEGIN
+    proc_common_wait_until_high(mm_clk, tb_mm_reg_end); -- wait for p_mm_reg_stimuli done
+
+    ASSERT TO_UINT(lane_info.transport_nof_hops) =  11 REPORT "wrong lane_info.transport_nof_hops value"  SEVERITY ERROR;
+    ASSERT lane_info.lane_direction              = '0' REPORT "wrong lane_info.lane_direction value"      SEVERITY ERROR;
+    ASSERT lane_info.tx_select                   = '1' REPORT "wrong lane_info.tx_select value"           SEVERITY ERROR;
+    ASSERT lane_info.rx_select                   = '1' REPORT "wrong lane_info.rx_select value"           SEVERITY ERROR;
+
+    proc_common_wait_some_cycles(mm_clk, 100);
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;
+
+
+  -- SDP info
+  u_dut: ENTITY work.ring_lane_info
+    PORT MAP (
+      mm_clk    => mm_clk,
+      mm_rst    => mm_rst,
+
+      dp_clk    => dp_clk,
+      dp_rst    => dp_rst,
+
+      reg_mosi  => reg_mosi,
+      reg_miso  => reg_miso,
+
+      lane_direction => lane_direction,
+
+      lane_info => lane_info
+    );
+
+END tb;