diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd
index 78c7bd3c0780d789b4f968750c8ebb0f09cbcecd..9157289e2e4fab3607d1972a8d9173296a4b759e 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd
@@ -234,7 +234,8 @@ ARCHITECTURE str OF io_ddr IS
   CONSTANT c_wr_use_ctrl       : BOOLEAN := sel_a_b(g_wr_flush_mode="SOP", TRUE, FALSE);
   CONSTANT c_wr_fifo_use_ctrl  : BOOLEAN := c_wr_use_sync OR c_wr_use_ctrl;
   
-  CONSTANT c_ddr_gigabytes           : NATURAL := func_tech_ddr_module_size(g_tech_ddr);  -- units GiByte
+  CONSTANT c_ddr_nofbytes_w          : NATURAL := func_tech_ddr_module_nofbytes_w(g_tech_ddr);  -- log2(number of bytes)
+  CONSTANT c_ddr_gigabytes           : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);  -- units value GiByte when value > 1 or 2**value GiByte when value < 0
   CONSTANT c_ctlr_nof_bytes_per_word : NATURAL := func_tech_ddr_ctlr_ip_data_w(g_tech_ddr) / c_byte_w;  -- unit byte
 
   CONSTANT c_ctlr_address_w    : NATURAL := func_tech_ddr_ctlr_address_w(g_tech_ddr);
@@ -523,7 +524,7 @@ BEGIN
   mm_reg_io_ddr <= RESIZE_UVEC(rd_fifo_full_reg & wr_fifo_full_reg, c_mem_reg_dat_w) & 
                    RESIZE_UVEC(ctlr_wr_fifo_usedw, c_mem_reg_dat_w) & 
                    RESIZE_UVEC(ctlr_rd_fifo_usedw, c_mem_reg_dat_w) & 
-                   RESIZE_UVEC(TO_UVEC(c_ddr_gigabytes, 8) &
+                   RESIZE_UVEC(TO_SVEC(c_ddr_gigabytes, 8) &
                                TO_UVEC(c_ctlr_nof_bytes_per_word, 8) &
                                ctlr_tech_mosi.wr & ctlr_tech_miso.rdval & ctlr_tech_miso.cal_fail      & ctlr_tech_miso.cal_ok &
                                ctlr_rst_out_i    & ctlr_wr_flush_en     & ctlr_tech_miso.waitrequest_n & ctlr_tech_miso.done, c_mem_reg_dat_w);   
diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
index eac49482da7a7b38127631a97b3feea871207b58..5c217994f010833d8342a25fd6bfea7e1c75fc8d 100644
--- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
@@ -69,10 +69,11 @@ ARCHITECTURE str of tb_io_ddr IS
 
   -- Select DDR3 or DDR4 dependent on the technology and sim model
   CONSTANT c_mem_ddr                  : t_c_tech_ddr := func_tech_sel_ddr(g_technology, g_tech_ddr3, g_tech_ddr4);
-  CONSTANT c_sim_ddr                  : t_c_tech_ddr := func_tech_sel_ddr(g_technology, c_tech_ddr3_sim_16k, c_tech_ddr4_sim_16k);
+  CONSTANT c_sim_ddr                  : t_c_tech_ddr := func_tech_sel_ddr(g_technology, c_tech_ddr3_sim_16k, c_tech_ddr4_sim_4k);
   CONSTANT c_tech_ddr                 : t_c_tech_ddr := func_tech_sel_ddr(g_sim_model, c_sim_ddr, c_mem_ddr);
   
-  CONSTANT c_exp_gigabytes            : NATURAL := func_tech_ddr_module_size(c_tech_ddr);
+  CONSTANT c_exp_gigabytes            : INTEGER := func_tech_ddr_module_gigabytes(c_tech_ddr);
+  CONSTANT c_exp_nofbytes_w           : NATURAL := func_tech_ddr_module_nofbytes_w(c_tech_ddr);
   CONSTANT c_exp_nof_bytes_per_word   : NATURAL := func_tech_ddr_ctlr_ip_data_w(c_tech_ddr) / c_byte_w;
 
   CONSTANT c_dp_clk_period            : TIME := 5 ns;   -- 200 MHz
@@ -166,8 +167,9 @@ ARCHITECTURE str of tb_io_ddr IS
   SIGNAL dbg_c_ctlr_wr_not_rd_arr     : STD_LOGIC_VECTOR(0 TO c_nof_access-1)  := c_ctlr_wr_not_rd_arr;
   
   SIGNAL dbg_c_tech_ddr               : t_c_tech_ddr := c_tech_ddr;
-  SIGNAL dbg_c_exp_gigabytes          : NATURAL := c_exp_gigabytes;  -- = 0 for sim model, else nof GB
-  SIGNAL ddr_gigabytes                : NATURAL;
+  SIGNAL dbg_c_exp_gigabytes          : INTEGER := c_exp_gigabytes;  -- = 0 for sim model, else nof GB
+  SIGNAL dbg_c_exp_nofbytes_w         : NATURAL := c_exp_nofbytes_w;
+  SIGNAL ddr_gigabytes                : INTEGER;
   SIGNAL dbg_c_exp_nof_bytes_per_word : NATURAL := c_exp_nof_bytes_per_word;
   SIGNAL ctlr_nof_bytes_per_word      : NATURAL;
   SIGNAL dbg_c_dp_data_w              : NATURAL := c_dp_data_w;
@@ -274,7 +276,7 @@ BEGIN
     proc_mem_mm_bus_rd(0, mm_clk, reg_io_ddr_miso, reg_io_ddr_mosi);
     proc_mem_mm_bus_rd_latency(1, mm_clk);
     -- . verify ddr_gigabytes
-    ddr_gigabytes <= TO_UINT(reg_io_ddr_miso.rddata(23 DOWNTO 16));
+    ddr_gigabytes <= TO_SINT(reg_io_ddr_miso.rddata(23 DOWNTO 16));
     proc_common_wait_some_cycles(mm_clk, 1);
     ASSERT ddr_gigabytes = c_exp_gigabytes REPORT "Wrong read ddr_gigabytes" SEVERITY ERROR;
     -- . verify ctlr_nof_bytes_per_word
diff --git a/libraries/technology/ddr/tech_ddr_arria10.vhd b/libraries/technology/ddr/tech_ddr_arria10.vhd
index d706440e088df27496efa16f606d261b71ac2141..012b57882e8c25c26255a886863df1931ff395f0 100644
--- a/libraries/technology/ddr/tech_ddr_arria10.vhd
+++ b/libraries/technology/ddr/tech_ddr_arria10.vhd
@@ -71,7 +71,7 @@ END tech_ddr_arria10;
 
 ARCHITECTURE str OF tech_ddr_arria10 IS
 
-  CONSTANT c_gigabytes             : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes             : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   CONSTANT c_ctlr_address_w        : NATURAL := 26; --func_tech_ddr_ctlr_address_w(g_tech_ddr);
   CONSTANT c_ctlr_data_w           : NATURAL := 576;--func_tech_ddr_ctlr_data_w(   g_tech_ddr);
diff --git a/libraries/technology/ddr/tech_ddr_arria10_e1sg.vhd b/libraries/technology/ddr/tech_ddr_arria10_e1sg.vhd
index c59f216e78c90925321dee6602f3f561add69899..ff65a1506508cea6098fc36c1e9242997d438b12 100644
--- a/libraries/technology/ddr/tech_ddr_arria10_e1sg.vhd
+++ b/libraries/technology/ddr/tech_ddr_arria10_e1sg.vhd
@@ -74,7 +74,7 @@ END tech_ddr_arria10_e1sg;
 
 ARCHITECTURE str OF tech_ddr_arria10_e1sg IS
 
-  CONSTANT c_gigabytes             : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes             : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   CONSTANT c_ctlr_address_w        : NATURAL := func_tech_ddr_ctlr_address_w(g_tech_ddr);
   CONSTANT c_ctlr_data_w           : NATURAL := 576;--func_tech_ddr_ctlr_data_w(   g_tech_ddr);
diff --git a/libraries/technology/ddr/tech_ddr_arria10_e2sg.vhd b/libraries/technology/ddr/tech_ddr_arria10_e2sg.vhd
index 5b6f28915746718af3d4a3c20121f74b7c86d320..33876ba09e857050232506109614ffee6ef299d5 100644
--- a/libraries/technology/ddr/tech_ddr_arria10_e2sg.vhd
+++ b/libraries/technology/ddr/tech_ddr_arria10_e2sg.vhd
@@ -73,7 +73,7 @@ END tech_ddr_arria10_e2sg;
 
 ARCHITECTURE str OF tech_ddr_arria10_e2sg IS
 
-  CONSTANT c_gigabytes             : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes             : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   CONSTANT c_ctlr_address_w        : NATURAL := func_tech_ddr_ctlr_address_w(g_tech_ddr);
   CONSTANT c_ctlr_ip_data_w        : NATURAL := func_tech_ddr_ctlr_ip_data_w(g_tech_ddr);
diff --git a/libraries/technology/ddr/tech_ddr_arria10_e3sge3.vhd b/libraries/technology/ddr/tech_ddr_arria10_e3sge3.vhd
index 2a95f000aad9136b9345c1898c400622c569568a..075c74830130f3c61842093ed5831a2ad9eb706c 100644
--- a/libraries/technology/ddr/tech_ddr_arria10_e3sge3.vhd
+++ b/libraries/technology/ddr/tech_ddr_arria10_e3sge3.vhd
@@ -73,7 +73,7 @@ END tech_ddr_arria10_e3sge3;
 
 ARCHITECTURE str OF tech_ddr_arria10_e3sge3 IS
 
-  CONSTANT c_gigabytes             : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes             : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   CONSTANT c_ctlr_address_w        : NATURAL := func_tech_ddr_ctlr_address_w(g_tech_ddr);
   CONSTANT c_ctlr_data_w           : NATURAL := 576;--func_tech_ddr_ctlr_data_w(   g_tech_ddr);
diff --git a/libraries/technology/ddr/tech_ddr_mem_model.vhd b/libraries/technology/ddr/tech_ddr_mem_model.vhd
index c814d05884e16fafa9b6d371d21fb0b606015102..a301052eb7f072407ba160948bbb845e939ed961 100644
--- a/libraries/technology/ddr/tech_ddr_mem_model.vhd
+++ b/libraries/technology/ddr/tech_ddr_mem_model.vhd
@@ -59,10 +59,10 @@ END tech_ddr_memory_model;
 
 ARCHITECTURE str OF tech_ddr_memory_model IS
 
-  CONSTANT c_gigabytes    : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes    : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   SIGNAL dbg_g_tech_ddr   : t_c_tech_ddr := g_tech_ddr;
-  SIGNAL dbg_c_gigabytes  : NATURAL := c_gigabytes;
+  SIGNAL dbg_c_gigabytes  : INTEGER := c_gigabytes;
   
 BEGIN
 
diff --git a/libraries/technology/ddr/tech_ddr_pkg.vhd b/libraries/technology/ddr/tech_ddr_pkg.vhd
index 894e988782ebaf62ed5d9017343291b3f72a6366..fb3400258c6ba7e8620ebc0b21273abb67e44c5c 100644
--- a/libraries/technology/ddr/tech_ddr_pkg.vhd
+++ b/libraries/technology/ddr/tech_ddr_pkg.vhd
@@ -67,7 +67,12 @@ PACKAGE tech_ddr_pkg IS
   FUNCTION func_tech_ddr_ctlr_address_w(c_ddr : t_c_tech_ddr) RETURN NATURAL;  -- return DDR address width for the controller data at the by rsl=4 reduced rate
   FUNCTION func_tech_ddr_ctlr_data_w(   c_ddr : t_c_tech_ddr) RETURN NATURAL;  -- return DDR    data width for the controller data at the by rsl=4 reduced rate
   FUNCTION func_tech_ddr_ctlr_ip_data_w(c_ddr : t_c_tech_ddr) RETURN NATURAL;  -- return DDR    data width for the controller data at the by rsl=4 reduced rate
-  FUNCTION func_tech_ddr_module_size(   c_ddr : t_c_tech_ddr) RETURN NATURAL;  -- return DDR module size in GByte
+
+  -- return DDR module size in log2(number of bytes), because 2**nofbytes_w may not fit in 31 bit NATURAL
+  FUNCTION func_tech_ddr_module_nofbytes_w(c_ddr : t_c_tech_ddr) RETURN NATURAL;
+  -- return DDR module size in GiBytes when >= 1 GByte which is typical on HW, else
+  -- return size as negative value to indicate 2**value fraction of 1GByte which is typical in simulation
+  FUNCTION func_tech_ddr_module_gigabytes(c_ddr : t_c_tech_ddr) RETURN INTEGER;
 
   FUNCTION func_tech_ddr_sim_size(c_ddr : t_c_tech_ddr; sim_ctrl_addr_w : NATURAL) RETURN t_c_tech_ddr; -- derive sim_ddr from c_ddr (or alternatively use predefined c_tech_ddr*_sim)
   FUNCTION func_tech_ddr_rewire_64b_to_72b(c_ddr : t_c_tech_ddr; vec_64b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
@@ -252,20 +257,28 @@ PACKAGE BODY tech_ddr_pkg IS
     RETURN v_ddr;
   END;
   
-  FUNCTION func_tech_ddr_module_size(c_ddr : t_c_tech_ddr) RETURN NATURAL IS
+  FUNCTION func_tech_ddr_module_nofbytes_w(c_ddr : t_c_tech_ddr) RETURN NATURAL IS
     CONSTANT c_dq_address_w       : NATURAL := func_tech_ddr_dq_address_w(c_ddr);
     CONSTANT c_dq_nof_bytes       : NATURAL := 8;  -- both dw_q = 64 and 72 are regarded as having 8 bytes (either with 8 or 9 bits per byte)
     CONSTANT c_dq_nof_bytes_w     : NATURAL := ceil_log2(c_dq_nof_bytes);
     CONSTANT c_module_nof_bytes_w : NATURAL := c_dq_address_w + c_dq_nof_bytes_w;
+  BEGIN
+    RETURN c_module_nof_bytes_w;
+  END;
+  
+  FUNCTION func_tech_ddr_module_gigabytes(c_ddr : t_c_tech_ddr) RETURN INTEGER IS
+    CONSTANT c_module_nof_bytes_w : NATURAL := func_tech_ddr_module_nofbytes_w(c_ddr);
     CONSTANT c_1GB_w              : NATURAL := 30;
   BEGIN
     IF c_module_nof_bytes_w < c_1GB_w THEN
-      RETURN 0;
+      -- Return <= -1 to indicate fraction of 1GByte, so e.g. -1 implies 2**-1 = 0.5 GByte
+      RETURN c_module_nof_bytes_w - c_1GB_w;
     ELSE
-      RETURN 2**(c_module_nof_bytes_w-c_1GB_w);
+      -- Return >= 1 to indicate multiple of 1GByte = number of GByte
+      RETURN 2**(c_module_nof_bytes_w - c_1GB_w);
     END IF;
   END;
-  
+
   FUNCTION func_tech_ddr_rewire_64b_to_72b(c_ddr : t_c_tech_ddr; vec_64b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
     VARIABLE vec_72b : STD_LOGIC_VECTOR(func_tech_ddr_ctlr_ip_data_w(c_ddr) - 1 DOWNTO 0) := (OTHERS => '0');
   BEGIN
diff --git a/libraries/technology/ddr/tech_ddr_stratixiv.vhd b/libraries/technology/ddr/tech_ddr_stratixiv.vhd
index 7e9563ee5667fcd30c7d31c0a9822f999b9e5f6c..2830195512e35b15ac6b8cbb3e3ae8446e0f955e 100644
--- a/libraries/technology/ddr/tech_ddr_stratixiv.vhd
+++ b/libraries/technology/ddr/tech_ddr_stratixiv.vhd
@@ -75,12 +75,12 @@ END tech_ddr_stratixiv;
 
 ARCHITECTURE str OF tech_ddr_stratixiv IS
 
-  CONSTANT c_gigabytes             : NATURAL := func_tech_ddr_module_size(g_tech_ddr);
+  CONSTANT c_gigabytes             : INTEGER := func_tech_ddr_module_gigabytes(g_tech_ddr);
 
   CONSTANT c_ctlr_address_w        : NATURAL := func_tech_ddr_ctlr_address_w(g_tech_ddr);
   CONSTANT c_ctlr_data_w           : NATURAL := func_tech_ddr_ctlr_data_w(   g_tech_ddr);
   
-  SIGNAL dbg_c_gigabytes           : NATURAL := c_gigabytes;
+  SIGNAL dbg_c_gigabytes           : INTEGER := c_gigabytes;
   
   SIGNAL ref_rst_n                 : STD_LOGIC;
   SIGNAL ctlr_gen_rst_n            : STD_LOGIC;