diff --git a/libraries/technology/ddr/tech_ddr_pkg.vhd b/libraries/technology/ddr/tech_ddr_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..33b251f5cdb9e291ce4e54697ccd98eb920f33f2
--- /dev/null
+++ b/libraries/technology/ddr/tech_ddr_pkg.vhd
@@ -0,0 +1,128 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2014
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+
+PACKAGE tech_ddr_pkg IS  
+  
+  -- DDR3
+  TYPE t_c_tech_ddr_phy IS RECORD
+    a_w                               : NATURAL;  -- = 16;
+    a_row_w                           : NATURAL;  -- = 16;  --  = a_w, row address width, via a_w lines
+    a_col_w                           : NATURAL;  -- = 10;  -- <= a_w, col address width, via a_w lines
+    ba_w                              : NATURAL;  -- = 3;
+    dq_w                              : NATURAL;  -- = 64;
+    dqs_w                             : NATURAL;  -- = 8;   --  = dq_w / nof_dq_per_dqs;
+    dm_w                              : NATURAL;  -- = 8;
+    cs_w                              : NATURAL;  -- = 2;
+    clk_w                             : NATURAL;  -- = 2;
+  END RECORD;
+
+  CONSTANT c_tech_ddr_phy                 : t_c_tech_ddr_phy := (16, 16, 10, 3, 64, 8, 8, 2, 2);
+  CONSTANT c_tech_ddr_phy_4g              : t_c_tech_ddr_phy := (15, 15, 10, 3, 64, 8, 8, 2, 2);
+
+  TYPE t_tech_ddr_phy_in IS RECORD  
+    evt              : STD_LOGIC;
+    oct_rup          : STD_LOGIC;
+    oct_rdn          : STD_LOGIC;
+  END RECORD;
+  
+  TYPE t_tech_ddr_phy_io IS RECORD
+    dq               : STD_LOGIC_VECTOR(c_tech_ddr_phy.dq_w-1 DOWNTO 0);   -- data bus
+    dqs              : STD_LOGIC_VECTOR(c_tech_ddr_phy.dqs_w-1 DOWNTO 0);  -- data strobe bus
+    dqs_n            : STD_LOGIC_VECTOR(c_tech_ddr_phy.dqs_w-1 DOWNTO 0);
+    clk              : STD_LOGIC_VECTOR(c_tech_ddr_phy.clk_w-1 DOWNTO 0);  -- clock, positive edge clock
+    clk_n            : STD_LOGIC_VECTOR(c_tech_ddr_phy.clk_w-1 DOWNTO 0);  -- clock, negative edge clock
+    scl              : STD_LOGIC;                                          -- I2C
+    sda              : STD_LOGIC;
+  END RECORD;
+  
+  TYPE t_tech_ddr_phy_ou IS RECORD  
+    a                : STD_LOGIC_VECTOR(c_tech_ddr_phy.a_w-1 DOWNTO 0);    -- row and column address
+    ba               : STD_LOGIC_VECTOR(c_tech_ddr_phy.ba_w-1 DOWNTO 0);   -- bank address
+    dm               : STD_LOGIC_VECTOR(c_tech_ddr_phy.dm_w-1 DOWNTO 0);   -- data mask bus
+    cas_n            : STD_LOGIC;                                          -- column address strobe
+    ras_n            : STD_LOGIC;                                          -- row address strobe
+    we_n             : STD_LOGIC;                                          -- write enable signal
+    reset_n          : STD_LOGIC;                                          -- reset signal
+    odt              : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0);   -- on-die termination control signal
+    cke              : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0);   -- clock enable
+    cs_n             : STD_LOGIC_VECTOR(c_tech_ddr_phy.cs_w-1 DOWNTO 0);   -- chip select
+  END RECORD;
+
+  CONSTANT c_tech_ddr_phy_in_rst   : t_tech_ddr_phy_in := ('0', 'X', 'X', 'X');
+  CONSTANT c_tech_ddr_phy_io_rst   : t_tech_ddr_phy_io := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0');
+  CONSTANT c_tech_ddr_phy_ou_rst   : t_tech_ddr_phy_ou := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0', '0', '0', (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'));
+
+  TYPE t_tech_ddr_phy_in_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_in;
+  TYPE t_tech_ddr_phy_io_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_io; 
+  TYPE t_tech_ddr_phy_ou_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_phy_ou;
+
+  TYPE t_tech_ddr_addr IS RECORD 
+    chip      : STD_LOGIC_VECTOR(ceil_log2(c_tech_ddr_phy.cs_w)  -1 DOWNTO 0);  -- Use ceil_log2() because the controller interprets the chip address as logical address (NOT individual chip select lines)
+    bank      : STD_LOGIC_VECTOR(          c_tech_ddr_phy.ba_w   -1 DOWNTO 0);
+    row       : STD_LOGIC_VECTOR(          c_tech_ddr_phy.a_row_w-1 DOWNTO 0); 
+    column    : STD_LOGIC_VECTOR(          c_tech_ddr_phy.a_col_w-1 DOWNTO 0);
+  END RECORD;
+
+  TYPE t_tech_ddr_addr_arr IS ARRAY(NATURAL RANGE <>) OF t_tech_ddr_addr; 
+
+  TYPE t_c_tech_ddr_ctlr IS RECORD  --   DDR3
+    rsl              : NATURAL;     -- = 4       = 2 (use both PHY clock edges) * 2 (PHY transfer at double rate), resolution
+    rsl_w            : NATURAL;     -- = 2       = ceil_log2(rsl)
+    address_w        : NATURAL;     -- = 32      = (2**32)*c_tech_ddr_phy.dq_w/c_byte_w bytes
+    data_w           : NATURAL;     -- = 256     = rsl * c_tech_ddr_phy.dq_w
+    maxburstsize     : NATURAL;     -- = 64
+    maxburstsize_w   : NATURAL;     -- = 8       = ceil_log2(maxburstsize+1)
+  END RECORD;
+  
+  CONSTANT c_tech_ddr_ctlr            : t_c_tech_ddr_ctlr := (4, 2, 256, 64, 9);
+  
+  CONSTANT c_tech_ddr_ctrl_nof_latent_reads : NATURAL := 100;  -- Due to having a command cue, even after de-asserting read requests, the PHY keeps processing the cued read requests. 
+                                                          -- This makes sure 100 words are still available in the read FIFO after it de-asserted its siso.ready signal towards the ddr3 read side.
+                                                          
+  CONSTANT c_tech_ddr_addr_lo         : t_tech_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'));
+  CONSTANT c_tech_ddr_addr_hi_4gb     : t_tech_ddr_addr := ((OTHERS=>'1'), (OTHERS=>'1'), (OTHERS=>'1'), TO_UVEC(2**c_tech_ddr_phy_4g.a_col_w - c_tech_ddr_ctlr.rsl, c_tech_ddr_phy_4g.a_col_w));
+  CONSTANT c_tech_ddr_addr_hi_sim     : t_tech_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), TO_UVEC(3, c_tech_ddr_phy.a_row_w),  TO_UVEC(2**c_tech_ddr_phy_4g.a_col_w - c_tech_ddr_ctlr.rsl, c_tech_ddr_phy_4g.a_col_w));
+  
+  TYPE t_tech_ddr_miso IS RECORD  
+    rddata           : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.data_w-1 DOWNTO 0);
+    rd               : STD_LOGIC;
+    waitrequest_n    : STD_LOGIC;
+  END RECORD;
+  
+  TYPE t_tech_ddr_mosi IS RECORD  
+    address          : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.address_w-1 DOWNTO 0);
+    wrdata           : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.data_w-1 DOWNTO 0);
+    wr               : STD_LOGIC;
+    rd               : STD_LOGIC;
+    burstbegin       : STD_LOGIC;
+    burstsize        : STD_LOGIC_VECTOR(c_tech_ddr_ctlr.maxburstsize_w-1 DOWNTO 0);
+  END RECORD;
+    
+END tech_ddr_pkg;
+
+PACKAGE BODY tech_ddr_pkg IS
+END tech_ddr_pkg;
+