diff --git a/modules/genrams/altera/Manifest.py b/modules/genrams/altera/Manifest.py
index d6297cad34ca5e91e2e430a4d3c01d3e1ce4d01e..c86aa8ff89d004160f519e2199c41c586acb25a3 100644
--- a/modules/genrams/altera/Manifest.py
+++ b/modules/genrams/altera/Manifest.py
@@ -1,5 +1,6 @@
 files = [
 "generic_async_fifo.vhd",
+"generic_simple_dpram.vhd",
 "generic_dpram.vhd",
 "generic_spram.vhd",
 "generic_sync_fifo.vhd"]
diff --git a/modules/genrams/altera/generic_dpram.vhd b/modules/genrams/altera/generic_dpram.vhd
index 1df91c324a3e3b44e5efac06e518e6c048276ea5..294015358f8fe58ca72dccc2dbad25d72948e222 100644
--- a/modules/genrams/altera/generic_dpram.vhd
+++ b/modules/genrams/altera/generic_dpram.vhd
@@ -3,25 +3,25 @@
 -- Project    : Generics RAMs and FIFOs collection
 -------------------------------------------------------------------------------
 -- File       : generic_dpram.vhd
--- Author     : Tomasz Wlostowski
--- Company    : CERN BE-CO-HT
+-- Author     : Wesley W. Terpstra
+-- Company    : GSI
 -- Created    : 2011-01-25
--- Last update: 2012-01-20
+-- Last update: 2013-03-04
 -- Platform   : 
 -- Standard   : VHDL'93
 -------------------------------------------------------------------------------
 -- Description: True dual-port synchronous RAM for Altera FPGAs with:
 -- - configurable address and data bus width
 -- - byte-addressing mode (data bus width restricted to multiple of 8 bits)
--- Todo:
--- - loading initial contents from file
 -------------------------------------------------------------------------------
 -- Copyright (c) 2011 CERN
+-- Copyright (c) 2013 GSI
 -------------------------------------------------------------------------------
 -- Revisions  :
 -- Date        Version  Author          Description
 -- 2011-01-25  1.0      twlostow        Created
 -- 2012-03-13  1.1      wterpstra       Added initial value as array
+-- 2013-03-04  2.0      wterpstra       Rewrote using altsyncram
 -------------------------------------------------------------------------------
 
 
@@ -31,23 +31,20 @@ use ieee.numeric_std.all;
 
 library work;
 use work.genram_pkg.all;
-use work.memory_loader_pkg.all;
 
-entity generic_dpram is
+library altera_mf;
+use altera_mf.altera_mf_components.all;
 
-  generic (
+entity generic_dpram is
+  generic(
     -- standard parameters
     g_data_width               : natural;
     g_size                     : natural;
     g_with_byte_enable         : boolean := false;
-    g_addr_conflict_resolution : string := "read_first";
-    g_init_file                : string := "";
-    g_init_value               : t_generic_ram_init := c_generic_ram_nothing;
-    g_dual_clock               : boolean := true;
-    g_fail_if_file_not_found : boolean := true
-    );
-
-  port (
+    g_addr_conflict_resolution : string := "dont_care";
+    g_init_file                : string := "none";
+    g_dual_clock               : boolean := true);
+  port(
     rst_n_i : in std_logic := '1';      -- synchronous reset, active LO
 
     -- Port A
@@ -57,8 +54,8 @@ entity generic_dpram is
     aa_i   : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
     da_i   : in  std_logic_vector(g_data_width-1 downto 0);
     qa_o   : out std_logic_vector(g_data_width-1 downto 0);
+    
     -- Port B
-
     clkb_i : in  std_logic;
     bweb_i : in  std_logic_vector((g_data_width+7)/8-1 downto 0);
     web_i  : in  std_logic;
@@ -71,203 +68,237 @@ end generic_dpram;
 
 architecture syn of generic_dpram is
 
-  constant c_num_bytes : integer := g_data_width/8;
-
-  type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
-  type t_ram_word_bs is array (0 to 7) of std_logic_vector(7 downto 0);
-  type t_ram_type_bs is array (0 to g_size - 1) of t_ram_word_bs;
-
-  function f_memarray_to_ramtype(arr : t_meminit_array) return t_ram_type is
-    variable tmp    : t_ram_type := (others => (others => '0'));
-    variable n, pos : integer;
+  function f_sameport_order(x : string) return string is
   begin
-    pos := 0;
-    while(pos < g_size)loop
-      n := 0;
-      -- avoid ISE loop iteration limit
-      while (pos < g_size and n < 4096) loop
-        for i in 0 to g_data_width-1 loop
-          tmp(pos)(i) := arr(pos, i);
-        end loop;  -- i
-        n := n+1;
-        pos := pos + 1;
-      end loop;
-    end loop;
-    return tmp;
-  end f_memarray_to_ramtype;
-
-  function f_memarray_to_ramtype_bs(arr : t_meminit_array) return t_ram_type_bs is
-    variable tmp    : t_ram_type_bs := (others => (others => (others => '0')));
-    variable n, pos : integer;
+    if x = "read_first" then
+      return "OLD_DATA";
+    elsif x = "write_first" then
+      --return "NEW_DATA_NO_NBE_READ"; -- unwritten bytes='X'
+      return "NEW_DATA_WITH_NBE_READ"; -- unwritten bytes=OLD_DATA (ie: whole result = NEW_DATA)
+    elsif x = "dont_care" then
+      return "DONT_CARE";
+    else
+      assert (false) report "generic_dpram: g_addr_conflict_resolution must be: read_first, write_first, dont_care" severity failure;
+    end if;
+  end f_sameport_order;
+  
+  function f_diffport_order(x : string) return string is
   begin
-    pos := 0;
-    while(pos < g_size)loop
-      n := 0;
-      -- avoid ISE loop iteration limit
-      while (pos < g_size and n < 4096) loop
-        for i in 0 to g_data_width-1 loop
-          tmp(pos)(i/8)(i mod 8) := arr(pos, i);
-        end loop;  -- i
-        n := n+1;
-        pos := pos + 1;
-      end loop;
-    end loop;
-    return tmp;
-  end f_memarray_to_ramtype_bs;
-
-  function f_file_contents return t_meminit_array is
+    if x = "read_first" then
+      return "OLD_DATA";
+    elsif x = "write_first" then
+      return "DONT_CARE"; -- "NEW_DATA" is unsupported; we use a bypass MUX in this case
+    elsif x = "dont_care" then
+      return "DONT_CARE";
+    else
+      assert (false) report "generic_dpram: g_addr_conflict_resolution must be: read_first, write_first, dont_care" severity failure;
+    end if;
+  end f_diffport_order;
+  
+  function f_filename(x : string) return string is
   begin
-    if g_init_value'length > 0 then
-      return g_init_value;
+    if x'length = 0 or x = "none" then
+      return "UNUSED";
     else
-      return f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
+      return x;
     end if;
-  end f_file_contents;
+  end f_filename;
   
-  signal ram    : t_ram_type    := f_memarray_to_ramtype   (f_file_contents);
-  signal ram_bs : t_ram_type_bs := f_memarray_to_ramtype_bs(f_file_contents);
+  constant c_num_bytes    : integer := (g_data_width+7)/8;
+  constant c_addr_width   : integer := f_log2_size(g_size);
+  constant sameport_order : string  := f_sameport_order(g_addr_conflict_resolution);
+  constant diffport_order : string  := f_diffport_order(g_addr_conflict_resolution);
+  constant c_init_file    : string  := f_filename(g_init_file);
   
-  signal q_local_a       : t_ram_word_bs;
-  signal q_local_b       : t_ram_word_bs;
-
-  signal bwe_int_a : std_logic_vector(7 downto 0);
-  signal bwe_int_b : std_logic_vector(7 downto 0);
-
-  signal clka_int : std_logic;
-  signal clkb_int : std_logic;
+  signal qa : std_logic_vector(g_data_width-1 downto 0);
+  signal qb : std_logic_vector(g_data_width-1 downto 0);
+  signal da : std_logic_vector(g_data_width-1 downto 0);
+  signal db : std_logic_vector(g_data_width-1 downto 0);
+  signal nba : boolean;
+  signal nbb : boolean;
   
 begin
-  assert (g_addr_conflict_resolution = "read_first")
-    report "generic_dpram: Altera template supports only read-first mode." severity failure;
-  assert (((g_data_width / 8) * 8) = g_data_width) or (g_with_byte_enable = false)
-    report "generic_dpram: in byte-enabled mode the data width must be a multiple of 8" severity failure;
-  assert(g_data_width <= 64 or g_with_byte_enable = false)
-    report "generic_dpram: byte-selectable memories can be have 64-bit data width due to synthesis tool limitation" severity failure;
-
-
-
-  --gen_single_clock : if(g_dual_clock = false) generate
-  --  clka_int <= clka_i  after 1ns;
-  --  clkb_int <= clka_i  after 1ns;
-  --end generate gen_single_clock;
-
-  --gen_dual_clock : if(g_dual_clock = true) generate
-  --  clka_int <= clka_i  after 1ns;
-  --  clkb_int <= clkb_i after 1ns;
-  --end generate gen_dual_clock;
-
-
-
-  gen_with_byte_enable : if(g_with_byte_enable = true) generate
-  bwe_int_a <= std_logic_vector(to_unsigned(0, 8-bwea_i'length)) & bwea_i;
-  bwe_int_b <= std_logic_vector(to_unsigned(0, 8-bweb_i'length)) & bweb_i;
 
-    unpack : for i in 0 to c_num_bytes - 1 generate
-      qa_o(8*(i+1) - 1 downto 8*i) <= q_local_a(i);
-      qb_o(8*(i+1) - 1 downto 8*i) <= q_local_b(i);
-    end generate unpack;
-
-    process(clka_i)
-    begin
-      if(rising_edge(clka_i)) then
-        if(wea_i = '1') then
-
--- I know the code below is stupid, but it's the only way to make Quartus
--- recongnize it as a memory block
-          if(bwe_int_a(0) = '1' and g_data_width >= 8) then
-            ram_bs(to_integer(unsigned(aa_i)))(0) <= da_i(7 downto 0);
-          end if;
-          if(bwe_int_a(1) = '1' and g_data_width >= 16) then
-            ram_bs(to_integer(unsigned(aa_i)))(1) <= da_i(15 downto 8);
-          end if;
-          if(bwe_int_a(2) = '1' and g_data_width >= 24) then
-            ram_bs(to_integer(unsigned(aa_i)))(2) <= da_i(23 downto 16);
-          end if;
-          if(bwe_int_a(3) = '1' and g_data_width >= 32) then
-            ram_bs(to_integer(unsigned(aa_i)))(3) <= da_i(31 downto 24);
-          end if;
-          if(bwe_int_a(4) = '1' and g_data_width >= 40) then
-            ram_bs(to_integer(unsigned(aa_i)))(4) <= da_i(39 downto 32);
-          end if;
-          if(bwe_int_a(5) = '1' and g_data_width >= 48) then
-            ram_bs(to_integer(unsigned(aa_i)))(5) <= da_i(47 downto 40);
-          end if;
-          if(bwe_int_a(6) = '1' and g_data_width >= 56) then
-            ram_bs(to_integer(unsigned(aa_i)))(6) <= da_i(55 downto 48);
-          end if;
-          if(bwe_int_a(7) = '1' and g_data_width = 64) then
-            ram_bs(to_integer(unsigned(aa_i)))(7) <= da_i(64 downto 57);
-          end if;
-        end if;
-        q_local_a <= ram_bs(to_integer(unsigned(aa_i)));
-      end if;
-    end process;
-
-    process(clkb_i)
-    begin
-      if(rising_edge(clkb_i)) then
-        if(web_i = '1') then
-
--- I know the code below is stupid, but it's the only way to make Quartus
--- recongnize it as a memory block
-          if(bwe_int_b(0) = '1' and g_data_width >= 8) then
-            ram_bs(to_integer(unsigned(ab_i)))(0) <= db_i(7 downto 0);
-          end if;
-          if(bwe_int_b(1) = '1' and g_data_width >= 16) then
-            ram_bs(to_integer(unsigned(ab_i)))(1) <= db_i(15 downto 8);
-          end if;
-          if(bwe_int_b(2) = '1' and g_data_width >= 24) then
-            ram_bs(to_integer(unsigned(ab_i)))(2) <= db_i(23 downto 16);
-          end if;
-          if(bwe_int_b(3) = '1' and g_data_width >= 32) then
-            ram_bs(to_integer(unsigned(ab_i)))(3) <= db_i(31 downto 24);
-          end if;
-          if(bwe_int_b(4) = '1' and g_data_width >= 40) then
-            ram_bs(to_integer(unsigned(ab_i)))(4) <= db_i(39 downto 32);
-          end if;
-          if(bwe_int_b(5) = '1' and g_data_width >= 48) then
-            ram_bs(to_integer(unsigned(ab_i)))(5) <= db_i(47 downto 40);
-          end if;
-          if(bwe_int_b(6) = '1' and g_data_width >= 56) then
-            ram_bs(to_integer(unsigned(ab_i)))(6) <= db_i(55 downto 48);
-          end if;
-          if(bwe_int_b(7) = '1' and g_data_width = 64) then
-            ram_bs(to_integer(unsigned(ab_i)))(7) <= db_i(64 downto 57);
-          end if;
-        end if;
-        q_local_b <= ram_bs(to_integer(unsigned(ab_i)));
-      end if;
-    end process;
-
-
-  end generate gen_with_byte_enable;
-
-
-  gen_without_byte_enable_readfirst : if(g_with_byte_enable = false) generate
-    process(clka_i)
+  assert (g_addr_conflict_resolution /= "write_first" or (g_dual_clock = false and g_with_byte_enable = false))
+  report "generic_dpram: write_first is only possible when dual_clock and g_with_byte_enable are false"
+  severity failure;
+  
+  assert (g_addr_conflict_resolution /= "read_first" or g_dual_clock = false)
+  report "generic_dpram: read_first is only possible when dual_clock is false"
+  severity failure;
+  
+  assert (g_addr_conflict_resolution /= "write_first")
+  report "generic_dpram: write_first requires a bypass MUX"
+  severity note;
+  
+  case_qb_raw : if (g_addr_conflict_resolution /= "write_first") generate
+    qa_o <= qa;
+    qb_o <= qb;
+  end generate;
+  
+  case_qb_bypass : if (g_addr_conflict_resolution = "write_first") generate
+    qa_o <= qa when nba else db;
+    qb_o <= qb when nbb else da;
+    
+    memoize : process(clka_i) is
     begin
       if rising_edge(clka_i) then
-        if(wea_i = '1') then
-          ram(to_integer(unsigned(aa_i))) <= da_i;
-          qa_o <= da_i; -- Arria5 must have "new data" for a port RW conflict
-        else
-          qa_o <= ram(to_integer(unsigned(aa_i)));
-        end if;
+        nba <= aa_i /= ab_i or web_i = '0';
+        nbb <= aa_i /= ab_i or wea_i = '0';
+        da <= da_i;
+        db <= db_i;
       end if;
     end process;
-
-    process(clkb_i)
-    begin
-      if rising_edge(clkb_i) then
-        if(web_i = '1') then
-          ram(to_integer(unsigned(ab_i))) <= db_i;
-          qb_o <= db_i; -- Arria5 must have "new data" for a port RW conflict
-        else
-          qb_o <= ram(to_integer(unsigned(ab_i)));
-        end if;
-      end if;
-    end process;
-  end generate gen_without_byte_enable_readfirst;
+  end generate;
   
-
+  case_be_dual : if (g_with_byte_enable = true and g_dual_clock = true) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        width_byteena_a                    => c_num_bytes,
+        width_byteena_b                    => c_num_bytes,
+        operation_mode                     => "BIDIR_DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        read_during_write_mode_port_a      => sameport_order,
+        read_during_write_mode_port_b      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK1",
+        wrcontrol_wraddress_reg_b          => "CLOCK1",
+        byteena_reg_b                      => "CLOCK1",
+        indata_reg_b                       => "CLOCK1",
+        rdcontrol_reg_b                    => "CLOCK1",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        byteena_a => bwea_i,
+        q_a       => qa,
+        
+        clock1    => clkb_i,
+        wren_b    => web_i,
+        address_b => ab_i,
+        data_b    => db_i,
+        byteena_b => bweb_i,
+        q_b       => qb);
+  end generate;
+    
+  case_be_single : if (g_with_byte_enable = true and g_dual_clock = false) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        width_byteena_a                    => c_num_bytes,
+        width_byteena_b                    => c_num_bytes,
+        operation_mode                     => "BIDIR_DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        read_during_write_mode_port_a      => sameport_order,
+        read_during_write_mode_port_b      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK0",
+        wrcontrol_wraddress_reg_b          => "CLOCK0",
+        byteena_reg_b                      => "CLOCK0",
+        indata_reg_b                       => "CLOCK0",
+        rdcontrol_reg_b                    => "CLOCK0",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        byteena_a => bwea_i,
+        q_a       => qa,
+        
+        wren_b    => web_i,
+        address_b => ab_i,
+        data_b    => db_i,
+        byteena_b => bweb_i,
+        q_b       => qb);
+  end generate;
+    
+  case_nobe_dual : if (g_with_byte_enable = false and g_dual_clock = true) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        operation_mode                     => "BIDIR_DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        read_during_write_mode_port_a      => sameport_order,
+        read_during_write_mode_port_b      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK1",
+        wrcontrol_wraddress_reg_b          => "CLOCK1",
+        byteena_reg_b                      => "CLOCK1",
+        indata_reg_b                       => "CLOCK1",
+        rdcontrol_reg_b                    => "CLOCK1",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        q_a       => qa,
+        
+        clock1    => clkb_i,
+        wren_b    => web_i,
+        address_b => ab_i,
+        data_b    => db_i,
+        q_b       => qb);
+  end generate;
+    
+  case_nobe_single : if (g_with_byte_enable = false and g_dual_clock = false) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        operation_mode                     => "BIDIR_DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        read_during_write_mode_port_a      => sameport_order,
+        read_during_write_mode_port_b      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK0",
+        wrcontrol_wraddress_reg_b          => "CLOCK0",
+        byteena_reg_b                      => "CLOCK0",
+        indata_reg_b                       => "CLOCK0",
+        rdcontrol_reg_b                    => "CLOCK0",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        q_a       => qa,
+        
+        wren_b    => web_i,
+        address_b => ab_i,
+        data_b    => db_i,
+        q_b       => qb);
+  end generate;
+    
 end syn;
diff --git a/modules/genrams/altera/generic_simple_dpram.vhd b/modules/genrams/altera/generic_simple_dpram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f89efa136e4f68c9ec0efe9f69848c5e55d65621
--- /dev/null
+++ b/modules/genrams/altera/generic_simple_dpram.vhd
@@ -0,0 +1,249 @@
+-------------------------------------------------------------------------------
+-- Title      : Parametrizable dual-port synchronous RAM (Altera version)
+-- Project    : Generics RAMs and FIFOs collection
+-------------------------------------------------------------------------------
+-- File       : generic_simple_dpram.vhd
+-- Author     : Wesley W. Terpstra
+-- Company    : GSI
+-- Created    : 2013-03-04
+-- Last update: 2013-03-04
+-- Platform   : 
+-- Standard   : VHDL'93
+-------------------------------------------------------------------------------
+-- Description: Simple dual-port synchronous RAM for Altera FPGAs with:
+-- - configurable address and data bus width
+-- - byte-addressing mode (data bus width restricted to multiple of 8 bits)
+-------------------------------------------------------------------------------
+-- Copyright (c) 2013 GSI
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2013-03-04  1.0      wterpstra       Adapted from generic_dpram.vhd
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.genram_pkg.all;
+
+library altera_mf;
+use altera_mf.altera_mf_components.all;
+
+entity generic_simple_dpram is
+  generic(
+    g_data_width               : natural;
+    g_size                     : natural;
+    g_with_byte_enable         : boolean := false;
+    g_addr_conflict_resolution : string := "dont_care";
+    g_init_file                : string := "none";
+    g_dual_clock               : boolean := true);
+  port(
+    rst_n_i : in std_logic := '1';      -- synchronous reset, active LO
+
+    -- Port A
+    clka_i : in  std_logic;
+    bwea_i : in  std_logic_vector((g_data_width+7)/8-1 downto 0);
+    wea_i  : in  std_logic;
+    aa_i   : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+    da_i   : in  std_logic_vector(g_data_width-1 downto 0);
+    
+    -- Port B
+    clkb_i : in  std_logic;
+    ab_i   : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+    qb_o   : out std_logic_vector(g_data_width-1 downto 0)
+    );
+
+end generic_simple_dpram;
+
+architecture syn of generic_simple_dpram is
+
+  function f_diffport_order(x : string) return string is
+  begin
+    if x = "read_first" then
+      return "OLD_DATA";
+    elsif x = "write_first" then
+      return "DONT_CARE"; -- "NEW_DATA" is unsupported; we use a bypass MUX in this case
+    elsif x = "dont_care" then
+      return "DONT_CARE";
+    else
+      assert (false) report "generic_simple_dpram: g_addr_conflict_resolution must be: read_first, write_first, dont_care" severity failure;
+    end if;
+  end f_diffport_order;
+  
+  function f_filename(x : string) return string is
+  begin
+    if x'length = 0 or x = "none" then
+      return "UNUSED";
+    else
+      return x;
+    end if;
+  end f_filename;
+  
+  constant c_num_bytes    : integer := (g_data_width+7)/8;
+  constant c_addr_width   : integer := f_log2_size(g_size);
+  constant diffport_order : string  := f_diffport_order(g_addr_conflict_resolution);
+  constant c_init_file    : string  := f_filename(g_init_file);
+  
+  signal qb : std_logic_vector(g_data_width-1 downto 0);
+  signal da : std_logic_vector(g_data_width-1 downto 0);
+  signal nbb : boolean;
+  
+begin
+
+  assert (g_addr_conflict_resolution /= "write_first" or (g_dual_clock = false and g_with_byte_enable = false))
+  report "generic_simple_dpram: write_first is only possible when dual_clock and g_with_byte_enable are false"
+  severity failure;
+  
+  assert (g_addr_conflict_resolution /= "read_first" or g_dual_clock = false)
+  report "generic_simple_dpram: read_first is only possible when dual_clock is false"
+  severity failure;
+  
+  assert (g_addr_conflict_resolution /= "write_first")
+  report "generic_simple_dpram: write_first requires a bypass MUX"
+  severity note;
+  
+  case_qb_raw : if (g_addr_conflict_resolution /= "write_first") generate
+    qb_o <= qb;
+  end generate;
+  
+  case_qb_bypass : if (g_addr_conflict_resolution = "write_first") generate
+    qb_o <= qb when nbb else da;
+    
+    memoize : process(clka_i) is
+    begin
+      if rising_edge(clka_i) then
+        nbb <= aa_i /= ab_i or wea_i = '0';
+        da <= da_i;
+      end if;
+    end process;
+  end generate;
+  
+  case_be_dual : if (g_with_byte_enable = true and g_dual_clock = true) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        width_byteena_a                    => c_num_bytes,
+        operation_mode                     => "DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK1",
+        wrcontrol_wraddress_reg_b          => "CLOCK1",
+        byteena_reg_b                      => "CLOCK1",
+        indata_reg_b                       => "CLOCK1",
+        rdcontrol_reg_b                    => "CLOCK1",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        byteena_a => bwea_i,
+        
+        clock1    => clkb_i,
+        address_b => ab_i,
+        q_b       => qb);
+  end generate;
+    
+  case_be_single : if (g_with_byte_enable = true and g_dual_clock = false) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        width_byteena_a                    => c_num_bytes,
+        operation_mode                     => "DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK0",
+        wrcontrol_wraddress_reg_b          => "CLOCK0",
+        byteena_reg_b                      => "CLOCK0",
+        indata_reg_b                       => "CLOCK0",
+        rdcontrol_reg_b                    => "CLOCK0",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        byteena_a => bwea_i,
+        
+        address_b => ab_i,
+        q_b       => qb);
+  end generate;
+    
+  case_nobe_dual : if (g_with_byte_enable = false and g_dual_clock = true) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        operation_mode                     => "DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK1",
+        wrcontrol_wraddress_reg_b          => "CLOCK1",
+        byteena_reg_b                      => "CLOCK1",
+        indata_reg_b                       => "CLOCK1",
+        rdcontrol_reg_b                    => "CLOCK1",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        
+        clock1    => clkb_i,
+        address_b => ab_i,
+        q_b       => qb);
+  end generate;
+    
+  case_nobe_single : if (g_with_byte_enable = false and g_dual_clock = false) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        numwords_b                         => g_size,
+        widthad_a                          => c_addr_width,
+        widthad_b                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_b                            => g_data_width,
+        operation_mode                     => "DUAL_PORT",
+        read_during_write_mode_mixed_ports => diffport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        outdata_reg_b                      => "UNREGISTERED",
+        address_reg_b                      => "CLOCK0",
+        wrcontrol_wraddress_reg_b          => "CLOCK0",
+        byteena_reg_b                      => "CLOCK0",
+        indata_reg_b                       => "CLOCK0",
+        rdcontrol_reg_b                    => "CLOCK0",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clka_i,
+        wren_a    => wea_i,
+        address_a => aa_i,
+        data_a    => da_i,
+        
+        address_b => ab_i,
+        q_b       => qb);
+  end generate;
+    
+end syn;
diff --git a/modules/genrams/altera/generic_spram.vhd b/modules/genrams/altera/generic_spram.vhd
index 8bc1875dec41b44dda509f1c8970d9fac7e33371..1df90af25bd52ff17a87a290d376a15a90daa7a7 100644
--- a/modules/genrams/altera/generic_spram.vhd
+++ b/modules/genrams/altera/generic_spram.vhd
@@ -3,24 +3,23 @@
 -- Project    : Generics RAMs and FIFOs collection
 -------------------------------------------------------------------------------
 -- File       : generic_spram.vhd
--- Author     : Tomasz Wlostowski
--- Company    : CERN BE-Co-HT
+-- Author     : Wesley W. Terpstra
+-- Company    : GSI
 -- Created    : 2011-01-25
--- Last update: 2011-01-25
+-- Last update: 2013-03-04
 -- Platform   : 
 -- Standard   : VHDL'93
 -------------------------------------------------------------------------------
 -- Description: Single-port synchronous RAM for Altera FPGAs with:
 -- - configurable address and data bus width
 -- - byte-addressing mode (data bus width restricted to multiple of 8 bits)
--- Todo:
--- - loading initial contents from file
 -------------------------------------------------------------------------------
 -- Copyright (c) 2011 CERN
 -------------------------------------------------------------------------------
 -- Revisions  :
 -- Date        Version  Author          Description
 -- 2011-01-25  1.0      twlostow        Created
+-- 2013-03-04  2.0      wterpstra       Rewrote using altsyncram
 -------------------------------------------------------------------------------
 
 
@@ -31,122 +30,96 @@ use ieee.numeric_std.all;
 library work;
 use work.genram_pkg.all;
 
-entity generic_spram is
+library altera_mf;
+use altera_mf.altera_mf_components.all;
 
-  generic (
-    -- standard parameters
+entity generic_spram is
+  generic(
     g_data_width               : natural := 32;
     g_size                     : natural := 1024;
     g_with_byte_enable         : boolean := false;
-    g_addr_conflict_resolution : string  := "read_first";
-    g_init_file                : string  := ""
-    );
-
-  port (
-    rst_n_i : in std_logic := '1';      -- synchronous reset, active LO
-    clk_i   : in std_logic;             -- clock input
-
-    -- byte write enable, actiwe when g_with_byte_enable == true
-    bwe_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
-
-    -- global write enable (masked by bwe_i if g_with_byte_enable = true)
-    we_i : in std_logic;
-
-    -- address input
-    a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
-
-    -- data input
-    d_i : in std_logic_vector(g_data_width-1 downto 0);
-
-    -- data output
-    q_o : out std_logic_vector(g_data_width-1 downto 0)
-    );
-
+    g_addr_conflict_resolution : string  := "dont_care";
+    g_init_file                : string  := "");
+  port(
+    rst_n_i : in  std_logic := '1';
+    clk_i   : in  std_logic;
+    bwe_i   : in  std_logic_vector((g_data_width+7)/8-1 downto 0);
+    we_i    : in  std_logic;
+    a_i     : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+    d_i     : in  std_logic_vector(g_data_width-1 downto 0);
+    q_o     : out std_logic_vector(g_data_width-1 downto 0));
 end generic_spram;
 
-
-
 architecture syn of generic_spram is
 
-
-  constant c_num_bytes : integer := g_data_width/8;
-
-  type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
-  type t_ram_word_bs is array (0 to 7) of std_logic_vector(7 downto 0);
-  type t_ram_type_bs is array (0 to g_size - 1) of t_ram_word_bs;
-
-  signal ram     : t_ram_type    := (others => (others => '0'));
-  signal ram_bs  : t_ram_type_bs := (others => (others => (others => '0')));
-  signal q_local : t_ram_word_bs;
-
-  signal bwe_int : std_logic_vector(7 downto 0);
+  function f_sameport_order(x : string) return string is
+  begin
+    if x = "read_first" then
+      return "OLD_DATA";
+    elsif x = "write_first" then
+      --return "NEW_DATA_NO_NBE_READ"; -- unwritten bytes='X'
+      return "NEW_DATA_WITH_NBE_READ"; -- unwritten bytes=OLD_DATA (ie: whole result = NEW_DATA)
+    elsif x = "dont_care" then
+      return "DONT_CARE";
+    else
+      assert (false) report "generic_spram: g_addr_conflict_resolution must be: read_first, write_first, dont_care" severity failure;
+    end if;
+  end f_sameport_order;
   
-begin
-  assert (g_init_file = "") report "generic_spram: Memory initialization files not supported yet. Sorry :(" severity failure;
-  assert (g_addr_conflict_resolution = "read_first") report "generic_spram: Altera template supports only read-first mode." severity failure;
-  assert (((g_data_width / 8) * 8) = g_data_width) or (g_with_byte_enable = false) report "generic_spram: in byte-enabled mode the data width must be a multiple of 8" severity failure;
-  assert(g_data_width <= 64 or g_with_byte_enable = false) report "generic_spram: byte-selectable memories can be have 64-bit data width due to synthesis tool limitation" severity failure;
-
-  bwe_int <= std_logic_vector(to_unsigned(0, 8-bwe_i'length)) & bwe_i;
-
-
-  gen_with_byte_enable : if(g_with_byte_enable = true) generate
-
-    unpack : for i in 0 to c_num_bytes - 1 generate
-      q_o(8*(i+1) - 1 downto 8*i) <= q_local(i);
-    end generate unpack;
-
-    process(clk_i)
-    begin
-      if(rising_edge(clk_i)) then
-        if(we_i = '1') then
-
--- I know the code below is stupid, but it's the only way to make Quartus
--- recongnize it as a memory block
-          if(bwe_int(0) = '1' and g_data_width >= 8) then
-            ram_bs(to_integer(unsigned(a_i)))(0) <= d_i(7 downto 0);
-          end if;
-          if(bwe_int(1) = '1' and g_data_width >= 16) then
-            ram_bs(to_integer(unsigned(a_i)))(1) <= d_i(15 downto 8);
-          end if;
-          if(bwe_int(2) = '1' and g_data_width >= 24) then
-            ram_bs(to_integer(unsigned(a_i)))(2) <= d_i(23 downto 16);
-          end if;
-          if(bwe_int(3) = '1' and g_data_width >= 32) then
-            ram_bs(to_integer(unsigned(a_i)))(3) <= d_i(31 downto 24);
-          end if;
-          if(bwe_int(4) = '1' and g_data_width >= 40) then
-            ram_bs(to_integer(unsigned(a_i)))(4) <= d_i(39 downto 32);
-          end if;
-          if(bwe_int(5) = '1' and g_data_width >= 48) then
-            ram_bs(to_integer(unsigned(a_i)))(5) <= d_i(47 downto 40);
-          end if;
-          if(bwe_int(6) = '1' and g_data_width >= 56) then
-            ram_bs(to_integer(unsigned(a_i)))(6) <= d_i(55 downto 48);
-          end if;
-          if(bwe_int(7) = '1' and g_data_width >= 64) then
-            ram_bs(to_integer(unsigned(a_i)))(7) <= d_i(64 downto 57);
-          end if;
-
-
-        end if;
-        q_local <= ram_bs(to_integer(unsigned(a_i)));
-      end if;
-    end process;
-  end generate gen_with_byte_enable;
-
-
-  gen_without_byte_enable_readfirst : if(g_with_byte_enable = false) generate
-    process(clk_i)
-    begin
-      if rising_edge(clk_i) then
-        if(we_i = '1') then
-          ram(to_integer(unsigned(a_i))) <= d_i;
-        end if;
-        q_o <= ram(to_integer(unsigned(a_i)));
-      end if;
-    end process;
-  end generate gen_without_byte_enable_readfirst;
+  function f_filename(x : string) return string is
+  begin
+    if x'length = 0 or x = "none" then
+      return "UNUSED";
+    else
+      return x;
+    end if;
+  end f_filename;
+  
+  constant c_num_bytes    : integer := (g_data_width+7)/8;
+  constant c_addr_width   : integer := f_log2_size(g_size);
+  constant sameport_order : string  := f_sameport_order(g_addr_conflict_resolution);
+  constant c_init_file    : string  := f_filename(g_init_file);
   
+begin
 
+  case_be : if (g_with_byte_enable = true) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        widthad_a                          => c_addr_width,
+        width_a                            => g_data_width,
+        width_byteena_a                    => c_num_bytes,
+        operation_mode                     => "SINGLE_PORT",
+        read_during_write_mode_port_a      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clk_i,
+        wren_a    => we_i,
+        address_a => a_i,
+        data_a    => d_i,
+        byteena_a => bwe_i,
+        q_a       => q_o);
+  end generate;
+    
+  case_nobe : if (g_with_byte_enable = false) generate
+    memory : altsyncram
+      generic map(
+        byte_size                          => 8,
+        numwords_a                         => g_size,
+        widthad_a                          => c_addr_width,
+        width_a                            => g_data_width,
+        operation_mode                     => "SINGLE_PORT",
+        read_during_write_mode_port_a      => sameport_order,
+        outdata_reg_a                      => "UNREGISTERED",
+        init_file                          => c_init_file)
+      port map(
+        clock0    => clk_i,
+        wren_a    => we_i,
+        address_a => a_i,
+        data_a    => d_i,
+        q_a       => q_o);
+  end generate;
+    
 end syn;