diff --git a/libraries/base/common/src/vhdl/common_paged_ram_rw_rw.vhd b/libraries/base/common/src/vhdl/common_paged_ram_rw_rw.vhd
index 22dc9992af4ac0225fe7caa13e1f6f108312a1b3..4e4405a92ab196a72c53327c42d766a1e572ca85 100644
--- a/libraries/base/common/src/vhdl/common_paged_ram_rw_rw.vhd
+++ b/libraries/base/common/src/vhdl/common_paged_ram_rw_rw.vhd
@@ -1,48 +1,70 @@
--------------------------------------------------------------------------------
+-- -----------------------------------------------------------------------------
 --
--- Copyright (C) 2011
+-- Copyright 2011-2023
 -- 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.
+-- 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
 --
--- 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.
+-- http://www.apache.org/licenses/LICENSE-2.0
 --
--- You should have received a copy of the GNU General Public License
--- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-- 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.
 --
--------------------------------------------------------------------------------
-
--- Purpose: Multi page memory
+-- -----------------------------------------------------------------------------
+--
+-- Author: 
+--   -
+-- Changed by:
+--   D.F. Brouwer
+-- Purpose:
+--   Multi page memory
 -- Description:
 --   When next_page_* pulses then the next access will occur in the next page.
 -- Remarks:
--- . See common_paged_ram_crw_crw for details.
+-- . There are three architecture variants (default use "use_adr"):
+--   . use_mux : Use multiplexer logic and one RAM per page
+--   . use_adr : Use MSbit address lines and one buf RAM for all pages
+--   . use_ofs : Use address offset adders and one buf RAM for all pages
+-- . The "use_mux" variant requires the multiplexer logic but can be more
+--   efficient regarding RAM usage than the "use_adr" variant.
+--   The "use_ofs" variant requires address adder logic, but is optimal
+--   regarding RAM usage in case the page size is not a power of 2, because the
+--   pages are then mapped at subsequent addresses in the buf RAM.
+-- . The "use_adr" variant is optimal for speed, so that is set as default.
+--
+-- . The crw_crw RAM covers all other variants, which were utilized by other
+--   common RAM variant files. However, because the crw_crw IP is no longer
+--   supported as it was previously used for previous FPGA technology identifiers
+--   (device types) by the Agilex 7 (agi027_xxxx), the rw_rw IP should be used.
+--   As a result, this file has been modified. [1]
+-- Reference:
+--   [1] Based on the architecture of common_paged_ram_crw_crw.vhd.
 
 library IEEE, technology_lib;
 use IEEE.std_logic_1164.all;
 use IEEE.numeric_std.all;
 library common_lib;
 use work.common_pkg.all;
+use work.common_mem_pkg.all;
 use technology_lib.technology_select_pkg.all;
 
 entity common_paged_ram_rw_rw is
   generic (
-    g_technology      : natural := c_tech_select_default;
-    g_str             : string := "use_adr";
-    g_data_w          : natural;
-    g_nof_pages       : natural := 2;  -- >= 2
-    g_page_sz         : natural;
-    g_start_page_a    : natural := 0;
-    g_start_page_b    : natural := 0;
-    g_rd_latency      : natural := 1;
-    g_true_dual_port  : boolean := true
+    g_technology     : natural := c_tech_select_default;
+    g_str            : string := "use_adr";
+    g_data_w         : natural;
+    g_nof_pages      : natural := 2;  -- >= 2
+    g_page_sz        : natural;
+    g_start_page_a   : natural := 0;
+    g_start_page_b   : natural := 0;
+    g_rd_latency     : natural := 1;
+    g_true_dual_port : boolean := true
   );
   port (
     rst         : in  std_logic;
@@ -65,40 +87,254 @@ entity common_paged_ram_rw_rw is
   );
 end common_paged_ram_rw_rw;
 
-architecture str of common_paged_ram_rw_rw is
+architecture rtl of common_paged_ram_rw_rw is
+  type t_page_sel_arr is array (integer range <>) of natural range 0 to g_nof_pages - 1;
+
+  constant c_page_addr_w      : natural := ceil_log2(g_page_sz);
+
+  -- g_str = "use_mux" :
+  constant c_page_ram         : t_c_mem := (latency  => g_rd_latency,
+                                            adr_w    => c_page_addr_w,
+                                            dat_w    => g_data_w,
+                                            nof_dat  => g_page_sz,
+                                            init_sl  => '0');
+
+  type t_data_arr is array (integer range <>) of std_logic_vector(g_data_w - 1 downto 0);
+
+  -- g_str = "use_adr" :
+  constant c_mem_nof_pages_w  : natural := true_log2(g_nof_pages);
+  constant c_mem_addr_w       : natural := c_mem_nof_pages_w + c_page_addr_w;
+  constant c_mem_nof_words    : natural := g_nof_pages * 2**c_page_addr_w;  -- <= 2**c_mem_addr_w
+
+  constant c_mem_ram          : t_c_mem := (latency  => g_rd_latency,
+                                            adr_w    => c_mem_addr_w,
+                                            dat_w    => g_data_w,
+                                            nof_dat  => c_mem_nof_words,
+                                            init_sl  => '0');
+
+  -- g_str = "use_ofs" :
+  constant c_buf_addr_w       : natural := ceil_log2(g_nof_pages * g_page_sz);
+  constant c_buf_nof_words    : natural := g_nof_pages * g_page_sz;
+
+  constant c_buf_ram          : t_c_mem := (latency  => g_rd_latency,
+                                            adr_w    => c_buf_addr_w,
+                                            dat_w    => g_data_w,
+                                            nof_dat  => c_buf_nof_words,
+                                            init_sl  => '0');
+
+  -- >>> Page control
+
+  -- g_str = "use_mux" and g_str = "use_adr" :
+  -- . use page_sel direct for wr_en, rd_en, and address
+  signal page_sel_a         : natural range 0 to g_nof_pages - 1;
+  signal nxt_page_sel_a     : natural;
+  signal page_sel_b         : natural range 0 to g_nof_pages - 1;
+  signal nxt_page_sel_b     : natural;
+
+  -- . use page_sel_dly to adjust for g_rd_latency of rd_dat and rd_val
+  signal page_sel_a_dly     : t_page_sel_arr(0 to g_rd_latency - 1);
+  signal nxt_page_sel_a_dly : t_page_sel_arr(0 to g_rd_latency - 1);
+  signal page_sel_b_dly     : t_page_sel_arr(0 to g_rd_latency - 1);
+  signal nxt_page_sel_b_dly : t_page_sel_arr(0 to g_rd_latency - 1);
+
+  -- g_str = "use_ofs" :
+  signal page_ofs_a         : natural range 0 to c_buf_nof_words - 1;
+  signal nxt_page_ofs_a     : natural;
+  signal page_ofs_b         : natural range 0 to c_buf_nof_words - 1;
+  signal nxt_page_ofs_b     : natural;
+
+  -- >>> Access control
+
+  -- g_str = "use_mux" :
+  signal page_wr_en_a       : std_logic_vector(0 to g_nof_pages - 1);
+  signal page_wr_dat_a      : t_data_arr(0 to g_nof_pages - 1);
+  signal page_rd_en_a       : std_logic_vector(0 to g_nof_pages - 1);
+  signal page_rd_dat_a      : t_data_arr(0 to g_nof_pages - 1);
+  signal page_rd_val_a      : std_logic_vector(0 to g_nof_pages - 1);
+
+  signal page_wr_en_b       : std_logic_vector(0 to g_nof_pages - 1);
+  signal page_wr_dat_b      : t_data_arr(0 to g_nof_pages - 1);
+  signal page_rd_en_b       : std_logic_vector(0 to g_nof_pages - 1);
+  signal page_rd_dat_b      : t_data_arr(0 to g_nof_pages - 1);
+  signal page_rd_val_b      : std_logic_vector(0 to g_nof_pages - 1);
+
+  -- g_str = "use_adr" :
+  signal mem_adr_a          : std_logic_vector(c_mem_addr_w - 1 downto 0);
+  signal mem_adr_b          : std_logic_vector(c_mem_addr_w - 1 downto 0);
+
+  -- g_str = "use_ofs" :
+  signal buf_adr_a          : std_logic_vector(c_buf_addr_w - 1 downto 0);
+  signal buf_adr_b          : std_logic_vector(c_buf_addr_w - 1 downto 0);
 begin
-  u_crw_crw : entity work.common_paged_ram_crw_crw
-  generic map (
-    g_technology     => g_technology,
-    g_str            => g_str,
-    g_data_w         => g_data_w,
-    g_nof_pages      => g_nof_pages,
-    g_page_sz        => g_page_sz,
-    g_start_page_a   => g_start_page_a,
-    g_start_page_b   => g_start_page_b,
-    g_rd_latency     => g_rd_latency,
-    g_true_dual_port => g_true_dual_port
-  )
-  port map (
-    rst_a       => rst,
-    rst_b       => rst,
-    clk_a       => clk,
-    clk_b       => clk,
-    clken_a     => clken,
-    clken_b     => clken,
-    next_page_a => next_page_a,
-    adr_a       => adr_a,
-    wr_en_a     => wr_en_a,
-    wr_dat_a    => wr_dat_a,
-    rd_en_a     => rd_en_a,
-    rd_dat_a    => rd_dat_a,
-    rd_val_a    => rd_val_a,
-    next_page_b => next_page_b,
-    adr_b       => adr_b,
-    wr_en_b     => wr_en_b,
-    wr_dat_b    => wr_dat_b,
-    rd_en_b     => rd_en_b,
-    rd_dat_b    => rd_dat_b,
-    rd_val_b    => rd_val_b
-  );
-end str;
+  -- page select (for all) and page address offset (for use_ofs)
+  p_reg_a : process (rst, clk)
+  begin
+    if rst = '1' then
+      page_sel_a     <=          g_start_page_a;
+      page_sel_a_dly <= (others => g_start_page_a);
+      page_ofs_a     <=          g_start_page_a * g_page_sz;
+    elsif rising_edge(clk) then
+      page_sel_a     <= nxt_page_sel_a;
+      page_sel_a_dly <= nxt_page_sel_a_dly;
+      page_ofs_a     <= nxt_page_ofs_a;
+    end if;
+  end process;
+
+  p_reg_b : process (rst, clk)
+  begin
+    if rst = '1' then
+      page_sel_b     <=          g_start_page_b;
+      page_sel_b_dly <= (others => g_start_page_b);
+      page_ofs_b     <=          g_start_page_b * g_page_sz;
+    elsif rising_edge(clk) then
+      page_sel_b     <= nxt_page_sel_b;
+      page_sel_b_dly <= nxt_page_sel_b_dly;
+      page_ofs_b     <= nxt_page_ofs_b;
+    end if;
+  end process;
+
+  nxt_page_sel_a_dly(0)                   <= page_sel_a;
+  nxt_page_sel_a_dly(1 to g_rd_latency - 1) <= page_sel_a_dly(0 to g_rd_latency - 2);
+  nxt_page_sel_b_dly(0)                   <= page_sel_b;
+  nxt_page_sel_b_dly(1 to g_rd_latency - 1) <= page_sel_b_dly(0 to g_rd_latency - 2);
+
+  p_next_page_a : process(next_page_a, page_sel_a, page_ofs_a)
+  begin
+    nxt_page_sel_a <= page_sel_a;
+    nxt_page_ofs_a <= page_ofs_a;
+    if next_page_a = '1' then
+      if page_sel_a < g_nof_pages - 1 then
+        nxt_page_sel_a <= page_sel_a + 1;
+        nxt_page_ofs_a <= page_ofs_a + g_page_sz;
+      else
+        nxt_page_sel_a <= 0;
+        nxt_page_ofs_a <= 0;
+      end if;
+    end if;
+  end process;
+
+  p_next_page_b : process(next_page_b, page_sel_b, page_ofs_b)
+  begin
+    nxt_page_sel_b <= page_sel_b;
+    nxt_page_ofs_b <= page_ofs_b;
+    if next_page_b = '1' then
+      if page_sel_b < g_nof_pages - 1 then
+        nxt_page_sel_b <= page_sel_b + 1;
+        nxt_page_ofs_b <= page_ofs_b + g_page_sz;
+      else
+        nxt_page_sel_b <= 0;
+        nxt_page_ofs_b <= 0;
+      end if;
+    end if;
+  end process;
+
+  gen_mux : if g_str = "use_mux" generate
+    gen_pages : for I in 0 to g_nof_pages - 1 generate
+      u_ram : entity work.common_ram_rw_rw
+      generic map (
+        g_technology     => g_technology,
+        g_ram            => c_page_ram,
+        g_init_file      => "UNUSED",
+        g_true_dual_port => g_true_dual_port
+      )
+      port map (
+        rst       => rst,
+        clk       => clk,
+        clken     => clken,
+        adr_a     => adr_a,
+        wr_en_a   => page_wr_en_a(I),
+        wr_dat_a  => wr_dat_a,
+        rd_en_a   => page_rd_en_a(I),
+        rd_dat_a  => page_rd_dat_a(I),
+        rd_val_a  => page_rd_val_a(I),
+        adr_b     => adr_b,
+        wr_en_b   => page_wr_en_b(I),
+        wr_dat_b  => wr_dat_b,
+        rd_en_b   => page_rd_en_b(I),
+        rd_dat_b  => page_rd_dat_b(I),
+        rd_val_b  => page_rd_val_b(I)
+      );
+    end generate;
+
+    p_mux : process(page_sel_a, wr_en_a, rd_en_a, page_sel_a_dly, page_rd_dat_a, page_rd_val_a,
+                    page_sel_b, wr_en_b, rd_en_b, page_sel_b_dly, page_rd_dat_b, page_rd_val_b)
+    begin
+      -- use page_sel direct for control
+      page_wr_en_a <= (others => '0');
+      page_wr_en_b <= (others => '0');
+      page_rd_en_a <= (others => '0');
+      page_rd_en_b <= (others => '0');
+      page_wr_en_a(page_sel_a) <= wr_en_a;
+      page_wr_en_b(page_sel_b) <= wr_en_b;
+      page_rd_en_a(page_sel_a) <= rd_en_a;
+      page_rd_en_b(page_sel_b) <= rd_en_b;
+
+      -- use page_sel_dly to account for the RAM read latency
+      rd_dat_a <= page_rd_dat_a(page_sel_a_dly(g_rd_latency - 1));
+      rd_dat_b <= page_rd_dat_b(page_sel_b_dly(g_rd_latency - 1));
+      rd_val_a <= page_rd_val_a(page_sel_a_dly(g_rd_latency - 1));
+      rd_val_b <= page_rd_val_b(page_sel_b_dly(g_rd_latency - 1));
+    end process;
+  end generate;  -- gen_mux
+
+  gen_adr : if g_str = "use_adr" generate
+    u_mem : entity work.common_ram_rw_rw
+    generic map (
+      g_technology     => g_technology,
+      g_ram            => c_mem_ram,
+      g_init_file      => "UNUSED",
+      g_true_dual_port => g_true_dual_port
+    )
+    port map (
+      rst       => rst,
+      clk       => clk,
+      clken     => clken,
+      adr_a     => mem_adr_a,
+      wr_en_a   => wr_en_a,
+      wr_dat_a  => wr_dat_a,
+      rd_en_a   => rd_en_a,
+      rd_dat_a  => rd_dat_a,
+      rd_val_a  => rd_val_a,
+      adr_b     => mem_adr_b,
+      wr_en_b   => wr_en_b,
+      wr_dat_b  => wr_dat_b,
+      rd_en_b   => rd_en_b,
+      rd_dat_b  => rd_dat_b,
+      rd_val_b  => rd_val_b
+    );
+
+    mem_adr_a <= TO_UVEC(page_sel_a, c_mem_nof_pages_w) & adr_a;
+    mem_adr_b <= TO_UVEC(page_sel_b, c_mem_nof_pages_w) & adr_b;
+  end generate;  -- gen_adr
+
+  gen_ofs : if g_str = "use_ofs" generate
+    u_buf : entity work.common_ram_rw_rw
+    generic map (
+      g_technology     => g_technology,
+      g_ram            => c_buf_ram,
+      g_init_file      => "UNUSED",
+      g_true_dual_port => g_true_dual_port
+    )
+    port map (
+      rst       => rst,
+      clk       => clk,
+      clken     => clken,
+      adr_a     => buf_adr_a,
+      wr_en_a   => wr_en_a,
+      wr_dat_a  => wr_dat_a,
+      rd_en_a   => rd_en_a,
+      rd_dat_a  => rd_dat_a,
+      rd_val_a  => rd_val_a,
+      adr_b     => buf_adr_b,
+      wr_en_b   => wr_en_b,
+      wr_dat_b  => wr_dat_b,
+      rd_en_b   => rd_en_b,
+      rd_dat_b  => rd_dat_b,
+      rd_val_b  => rd_val_b
+    );
+
+    buf_adr_a <= INCR_UVEC(RESIZE_UVEC(adr_a, c_buf_addr_w), page_ofs_a);
+    buf_adr_b <= INCR_UVEC(RESIZE_UVEC(adr_b, c_buf_addr_w), page_ofs_b);
+  end generate;  -- gen_ofs
+
+end rtl;