diff --git a/hdl/rtl/hydra_core.vhd b/hdl/rtl/hydra_core.vhd
index 3ae941ba675ce8b6210d07fb5823757e354262d7..259163b5b18cdc449990e39fdc660ffad48cc5d4 100644
--- a/hdl/rtl/hydra_core.vhd
+++ b/hdl/rtl/hydra_core.vhd
@@ -143,9 +143,11 @@ begin
       else
         reg_dm_load <= dm_load;
         reg_dm_store <= dm_store;
-        reg_dm_addr <= dm_addr;
-        reg_dm_data_s <= dm_data_s;
-        reg_dm_data_select <= dm_data_select;
+        if dm_load = '1' or dm_store = '1' then
+          reg_dm_addr <= dm_addr;
+          reg_dm_data_s <= dm_data_s;
+          reg_dm_data_select <= dm_data_select;
+        end if;
       end if;
     end if;
   end process;
@@ -155,33 +157,48 @@ begin
     constant IRAM_WSIZE : natural := 2 ** (g_IRAM_LOG_SIZE - 2);
     variable iram : t_ram32_type(0 to IRAM_WSIZE - 1);
 --     := f_load_mem32_from_file ("../../../sw/fip_urv/fip_dbg.ram", IRAM_WSIZE, True);
+    variable addr : std_logic_vector (g_IRAM_LOG_SIZE - 1 downto 2);
   begin
     if rising_edge(clk_sys_i) then
       if cpu_rst = '1' then
         if iram_we = '1' then
           iram (to_integer(unsigned(iram_addr))) := iram_data;
         end if;
+        im_valid <= '0';
+        cpu_rst_d <= '1';
       else
-        im_data <= iram (to_integer(unsigned(im_addr(g_IRAM_LOG_SIZE - 1 downto 2))));
+        cpu_rst_d <= cpu_rst;
+        if reg_dm_load = '1' and reg_dm_is_wishbone = '0' and reg_dm_addr (16) = '0' then
+          --  Data read from iram
+          addr := reg_dm_addr(g_IRAM_LOG_SIZE - 1 downto 2);
+          im_valid <= '0';
+        else
+          --  Data read from dram.
+          addr := im_addr(g_IRAM_LOG_SIZE - 1 downto 2);
+          im_valid  <= (not cpu_rst_d);
+        end if;
+        im_data <= iram (to_integer(unsigned(addr)));
       end if;
     end if;
   end process;
 
   -- 1st MByte of the mem is the RAM
+  -- 1st 64KB is the IRAM.
+  -- 2nd 64KB is the DRAM
   reg_dm_is_wishbone <= '1' when reg_dm_addr(31 downto 20) /= x"000" else '0';
-  dm_data_l     <= dm_wb_rdata when dm_select_wb = '1' else dm_mem_rdata;
+  dm_data_l <= dm_wb_rdata when dm_select_wb = '1' else
+               im_data when reg_dm_addr(16) = '0' else
+               dm_mem_rdata;
 
   p_ram: process (clk_sys_i)
   is
     variable dram : t_ram32_type (2**(g_DRAM_LOG_SIZE - 2) - 1 downto 0);
     variable addr : natural range dram'range;
   begin
-    if rising_edge(clk_sys_i) and reg_dm_is_wishbone = '0'
-      and (reg_dm_store or reg_dm_load) = '1'
-    then
+    if rising_edge(clk_sys_i) then
       addr := to_integer(unsigned(reg_dm_addr(g_DRAM_LOG_SIZE - 1 downto 2)));
       dm_mem_rdata <= dram(addr);
-      if reg_dm_store = '1' then
+      if reg_dm_store = '1' and reg_dm_addr(16) = '1' and reg_dm_is_wishbone = '0' then
         for i in 0 to 3 loop
           if reg_dm_data_select (i) = '1' then
             dram(addr)(8*i + 7 downto 8*i) := reg_dm_data_s(8*i + 7 downto 8*i);
@@ -211,18 +228,16 @@ begin
         if dm_cycle_in_progress = '0' then
           if reg_dm_is_wishbone = '0' then
             --  Internal access
+            dm_select_wb  <= '0';
             if reg_dm_store = '1' then
               dm_load_done  <= '0';
               dm_store_done <= '1';
-              dm_select_wb  <= '0';
             elsif reg_dm_load = '1' then
               dm_load_done  <= '1';
               dm_store_done <= '0';
-              dm_select_wb  <= '0';
             else
               dm_store_done <= '0';
               dm_load_done  <= '0';
-              dm_select_wb  <= '0';
             end if;
           else
             --  Wishbone access
@@ -267,16 +282,4 @@ begin
     end if;
   end process p_wishbone_master;
 
-  p_im_valid : process(clk_sys_i)
-  begin
-    if rising_edge(clk_sys_i) then
-      if cpu_rst = '1' then
-        im_valid  <= '0';
-        cpu_rst_d <= '1';
-      else
-        cpu_rst_d <= cpu_rst;
-        im_valid  <= (not cpu_rst_d);
-      end if;
-    end if;
-  end process p_im_valid;
 end arch;
diff --git a/hdl/top/sf2-test/sf2_test.vhd b/hdl/top/sf2-test/sf2_test.vhd
index bed17f16c7be081a27da7e06e92f36133b1a32e6..07915219d75f61b38ce6943002c62ac1f4012435 100644
--- a/hdl/top/sf2-test/sf2_test.vhd
+++ b/hdl/top/sf2-test/sf2_test.vhd
@@ -8,7 +8,7 @@ use work.wishbone_pkg.all;
 --use smartfusion2.all;
 
 entity sf2_test is
-    port (
+  port (
     xtl   : in  std_logic;
     devrst_n : in std_logic;
 
@@ -137,6 +137,11 @@ begin
   iram_data <= ahb_rdata;
 
   proc_init: process (clk_100)
+    constant delay : unsigned(27 downto 0) := x"0c0_0000"
+    -- pragma translate off
+    xor x"0c0_0010"
+    -- pragma translate_on
+    ;
   begin
     if rising_edge(clk_100) then
       iahb_start <= '0';
@@ -150,7 +155,7 @@ begin
         case state is
           when INIT_DELAY =>
             iahb_addr <= (others => '0');
-            if counter = x"0c0_0000" then
+            if counter = delay then
               state <= READ_NVM;
               counter <= (others => '0');
             else
diff --git a/sw/sf2-test/main.c b/sw/sf2-test/main.c
index a3a70fc6f5e7614d0eddfc91cff665b0ae2101dc..f6f8af7069b9b5db792cdcb1dde329010b1cc17b 100644
--- a/sw/sf2-test/main.c
+++ b/sw/sf2-test/main.c
@@ -25,14 +25,12 @@ uart_putc (char c)
   uart_raw_putc (c);
 }
 
-#if 0
 static void
 uart_puts (const char *s)
 {
   while (*s)
     uart_putc (*s++);
 }
-#endif
 
 int
 main (void)
@@ -51,9 +49,6 @@ main (void)
   *(volatile unsigned *)UART_LCR = 0x03;
 
   while (1) {
-    uart_putc ('H');
-    uart_putc ('i');
-    uart_putc ('?');
-    uart_putc ('\n');
+    uart_puts ("Hello diot.\n");
   }
 }
diff --git a/sw/sf2-test/ram.ld b/sw/sf2-test/ram.ld
index 06b6b92bd2a95835eb7c39bc93f670e41b359305..32425c86f3c7f2f7bfe2884ed871a72cc7deae56 100644
--- a/sw/sf2-test/ram.ld
+++ b/sw/sf2-test/ram.ld
@@ -20,10 +20,10 @@ SECTIONS
 {
  .boot : { *(.boot) } > rom
  .text : { *(.text .text.*) } > rom =0
+ .rodata : { *(.rodata .rodata.*) } > rom
 
  _gp = .;
 
- .rodata : { *(.rodata .rodata.*) } > empty
  .data : { *(.data .data.*) } > empty
 
  .bss : {