]> jspc29.x-matter.uni-frankfurt.de Git - trbv2.git/commitdiff
*** empty log message ***
authorhadaq <hadaq>
Tue, 19 Jan 2010 15:54:25 +0000 (15:54 +0000)
committerhadaq <hadaq>
Tue, 19 Jan 2010 15:54:25 +0000 (15:54 +0000)
sdram_controller.vhd [new file with mode: 0644]

diff --git a/sdram_controller.vhd b/sdram_controller.vhd
new file mode 100644 (file)
index 0000000..fec2cc3
--- /dev/null
@@ -0,0 +1,751 @@
+library IEEE; --, UNISIM;
+use IEEE.std_logic_1164.all;
+use IEEE.std_logic_unsigned.all;
+use IEEE.numeric_std.all;
+
+
+
+
+
+entity sdram_controller is
+  port(
+    -- host side
+    --write
+    CLK                  : in std_logic;
+    RESET                : in    std_logic;  
+    DATA_CLK_IN          : in    std_logic;  
+    DATA_WRITE           : in    std_logic;  
+    WRITE_READY          : out   std_logic;
+    WRITE_DATA_IN        : in    std_logic_vector(31 downto 0);
+    WRITE_BUSY           : out   std_logic;
+    --read
+    DATA_READ            : in    std_logic;
+    DATA_READ_REQUEST    : in    std_logic;
+    READ_READY           : out   std_logic;
+    READ_DATA_OUT        : out   std_logic_vector(31 downto 0);
+    READ_BUSY            : out   std_logic;
+    --debug
+    RAM_DEBUG_00            : out   std_logic_vector(31 downto 0);
+    RAM_DEBUG_01            : out   std_logic_vector(31 downto 0);
+    RAM_DEBUG_02            : out   std_logic_vector(31 downto 0);          
+    -- SDRAM side
+    SDARM_CLK                : out   std_logic;  -- clock to SDRAM
+    CKE                  : out   std_logic;  -- clock-enable to SDRAM
+    CE                 : out   std_logic;  -- chip-select to SDRAM
+    RAS                : out   std_logic;  -- SDRAM row address strobe
+    CAS                : out   std_logic;  -- SDRAM column address strobe
+    WE                 : out   std_logic;  -- SDRAM write enable
+    BA                   : out   std_logic_vector(1 downto 0);              -- SDRAM bank address
+    ADDR                : out   std_logic_vector(12 downto 0);  -- SDRAM row/column address
+    DATA                : inout std_logic_vector(31 downto 0);   -- data to/from SDRAM
+    DQMH                 : out   std_logic;  -- enable upper-byte of SDRAM databus if true
+    DQML                 : out   std_logic   -- enable lower-byte of SDRAM databus if true
+    );
+end sdram_controller;
+
+architecture sdram_controller of sdram_controller is
+
+  component up_down_counter
+    generic (
+      NUMBER_OF_BITS : positive);
+    port (
+      CLK       : in  std_logic;
+      RESET     : in  std_logic;
+      COUNT_OUT : out std_logic_vector(NUMBER_OF_BITS-1 downto 0);
+      UP_IN     : in  std_logic;
+      DOWN_IN   : in  std_logic);
+  end component;
+
+  component data_address_to_sdram_fifo
+    port (
+      din           : IN  std_logic_VECTOR(64 downto 0);
+      rd_clk        : IN  std_logic;
+      rd_en         : IN  std_logic;
+      rst           : IN  std_logic;
+      wr_clk        : IN  std_logic;
+      wr_en         : IN  std_logic;
+      dout          : OUT std_logic_VECTOR(64 downto 0);
+      empty         : OUT std_logic;
+      full          : OUT std_logic;
+      rd_data_count : OUT std_logic_VECTOR(11 downto 0);
+      wr_data_count : OUT std_logic_VECTOR(11 downto 0));
+  end component;
+
+  component fifo_from_sdram
+    port (
+      din           : IN  std_logic_VECTOR(33 downto 0);
+      rd_clk        : IN  std_logic;
+      rd_en         : IN  std_logic;
+      rst           : IN  std_logic;
+      wr_clk        : IN  std_logic;
+      wr_en         : IN  std_logic;
+      dout          : OUT std_logic_VECTOR(33 downto 0);
+      empty         : OUT std_logic;
+      full          : OUT std_logic;
+      rd_data_count : OUT std_logic_VECTOR(11 downto 0);
+      wr_data_count : OUT std_logic_VECTOR(11 downto 0));
+  end component;
+  
+  type SDRAM_FSM is (INIT, PRECHARGE, NOP_1, AUTO_REFRESH_1, NOP_2, AUTO_REFRESH_2, NOP_3, MODE_REGISTER, IDLE, REFRESH_SDRAM, REFRESH_NOP, WRITE_SDRAM_ACTIVE, WRITE_SDRAM_WAIT, WRITE_SDRAM, WRITE_INTERRUPT_NOP_1, WRITE_INTERRUPT_PRECHARGE, WRITE_INTERRUPT_NOP, WRITE_SDRAM_REFRESH, WRITE_REFRESH_NOP, READ_SDRAM_ACTIVE, READ_SDRAM_WAIT, READ_SDRAM, READ_INTERRUPT_NOP_1, READ_INTERRUPT_PRECHARGE, READ_INTERRUPT_NOP, READ_SDRAM_REFRESH, READ_REFRESH_NOP);
+  signal SDRAM_FSM_CURRENT, SDRAM_FSM_NEXT : SDRAM_FSM;
+
+  constant NOP_CMD    : std_logic_vector(5 downto 0) := "011100";
+  constant ACTIVE_CMD : std_logic_vector(5 downto 0) := "001100";
+  constant READ_CMD   : std_logic_vector(5 downto 0) := "010100";
+  constant WRITE_CMD  : std_logic_vector(5 downto 0) := "010000";
+  constant PCHG_CMD   : std_logic_vector(5 downto 0) := "001011";
+  constant MODE_CMD   : std_logic_vector(5 downto 0) := "000011";
+  constant RFSH_CMD   : std_logic_vector(5 downto 0) := "000111";
+
+  constant SDRAM_MODE : std_logic_vector(12 downto 0) := "000" & "0" & "00" & "011" & "0" & "000";
+  
+  signal command : std_logic_vector(5 downto 0);
+  signal command_fsm : std_logic_vector(5 downto 0);
+  signal bank_address : std_logic_vector(1 downto 0);
+  signal bank_address_fsm : std_logic_vector(1 downto 0);
+  signal sdram_address : std_logic_vector(12 downto 0);
+  signal sdram_address_fsm : std_logic_vector(12 downto 0);
+  signal refresh_request : std_logic;
+
+  signal ram_debug_i : std_logic_vector(7 downto 0);
+  signal ram_debug_fsm : std_logic_vector(7 downto 0);
+  signal reset_main_sdram_counter : std_logic;
+  signal reset_main_sdram_counter_fsm : std_logic;
+  signal main_sdram_counter : std_logic_vector(15 downto 0);
+  signal rw_sdram_counter : std_logic_vector(3 downto 0);
+  signal reset_rw_sdram_counter : std_logic;
+  signal reset_rw_sdram_counter_fsm : std_logic;
+
+  signal drive_data : std_logic;
+  signal drive_data_fsm : std_logic;
+
+  -- host -> fifo -> sdram
+  signal fifo_to_sdram_data_in : std_logic_vector(64 downto 0);
+  signal fifo_to_sdram_data_out : std_logic_vector(64 downto 0);
+  signal fifo_to_sdram_rd_en : std_logic;
+  signal fifo_to_sdram_rd_en_fsm : std_logic;
+  signal fifo_to_sdram_empty : std_logic;
+  signal fifo_to_sdram_full : std_logic;
+  signal fifo_to_sdram_rd_data_count : std_logic_vector(11 downto 0);
+  signal fifo_to_sdram_wr_data_count : std_logic_vector(11 downto 0);
+  signal write_address : std_logic_vector(24 downto 0);
+  signal data_to_sdram : std_logic_vector(31 downto 0);
+  -- sdram -> fifo -> host
+  signal fifo_from_sdram_data_in : std_logic_vector(33 downto 0);
+  signal fifo_from_sdram_data_out : std_logic_vector(33 downto 0);
+  signal fifo_from_sdram_wr : std_logic;
+  signal fifo_from_sdram_wr_synch : std_logic;
+  signal fifo_from_sdram_wr_synch_synch : std_logic;
+  signal fifo_from_sdram_empty : std_logic;
+  signal fifo_from_sdram_full : std_logic;
+  signal fifo_from_sdram_rd_data_count : std_logic_vector(11 downto 0);
+  signal fifo_from_sdram_wr_data_count : std_logic_vector(11 downto 0);
+  signal fifo_from_sdram_rd_en : std_logic;
+  signal how_many_data_in_fifo : std_logic_vector(15 downto 0);
+  signal how_many_waiting_read_requests : std_logic_vector(15 downto 0);
+  signal read_done : std_logic;
+  signal read_address : std_logic_vector(24 downto 0);
+  
+  signal row_bank_saved : std_logic_vector(14 downto 0);
+  signal data_fsm : std_logic_vector(31 downto 0);
+
+-- simulation for sdram
+--sim-- signal A_sim : std_logic_vector(12 downto 0);
+--sim-- signal A_sim_long : std_logic_vector(24 downto 0);
+--sim-- signal data_out_i : std_logic_vector(31 downto 0);
+--sim--  type mem_block;
+--sim--  type mem_block_ptr is access mem_block;
+--sim--  type mem_block is array(0 to 1023) of std_logic_vector(31 downto 0);
+--sim-- --this defines a small portion (10 bit addressable) of memory
+--sim--  type mem_storage_t is array(0 to 255) of mem_block_ptr;
+--sim-- --this is the entire memory array type
+--sim--  type memory_t is protected
+--sim--    impure function read( addr : std_logic_vector ) return std_logic_vector;
+--sim--  procedure write(addr : std_logic_vector;
+--sim--                    data : std_logic_vector);
+--sim--  end protected memory_t;
+--sim-- --this stores and gives access to an entire memory
+--sim-- --this memory is broken into rows of 1024 words.
+--sim--  type memory_t is protected body
+--sim--    variable mem_storage : mem_storage_t;
+--sim--  impure function read(addr : std_logic_vector ) return
+--sim--    std_logic_vector is
+--sim--    variable row : integer;
+--sim--    variable col : integer;
+--sim--    variable ret_slv : std_logic_vector(31 downto 0);
+--sim--  begin
+--sim--    row := to_integer(unsigned(addr(18 downto 10) ) );
+--sim--    col := to_integer(unsigned(addr(9 downto 0) ) );
+--sim-- --break down the address so you can index into the 2D array
+--sim--    if mem_storage(row) = null then
+--sim--      ret_slv := (others => 'X');
+--sim-- --no memory allocated here yet
+--sim--    else
+--sim--      ret_slv := mem_storage(row)(col);
+--sim-- --get the memory value
+--sim--    end if;
+--sim--    return ret_slv;
+--sim--  end function read;
+--sim--  procedure write(addr : std_logic_vector;
+--sim--                  data : std_logic_vector ) is
+--sim--    variable row : integer;
+--sim--    variable col : integer;
+--sim--  begin
+--sim--    row := to_integer(unsigned(addr(18 downto 10) ) );
+--sim--    col := to_integer(unsigned(addr(9 downto 0) ) );
+--sim--    if mem_storage(row) = null then
+--sim--      mem_storage(row) := new mem_block;
+--sim-- --dynamically create some more ram
+--sim-- --initialise all of the memory that were just allocated
+--sim--      for i in 0 to 1023 loop
+--sim--        mem_storage(row)(i) := (others => 'X');
+--sim--      end loop;
+--sim--    end if;
+--sim--    mem_storage(row)(col) := data;
+--sim--  end procedure write;
+--sim--  end protected body memory_t;
+--sim-- --This is the varaible you actually use.
+--sim--  shared variable my_memory : memory_t;
+
+  
+begin  -- sdram_controller
+
+  THE_MAIN_COUNTER: up_down_counter
+    generic map (
+        NUMBER_OF_BITS => 16)
+    port map (
+        CLK       => CLK,
+        RESET     => reset_main_sdram_counter,
+        COUNT_OUT => main_sdram_counter,
+        UP_IN     => '1',
+        DOWN_IN   => '0');
+
+  RW_COUNTER: up_down_counter
+    generic map (
+        NUMBER_OF_BITS => 4)
+    port map (
+        CLK       => CLK,
+        RESET     => reset_rw_sdram_counter,
+        COUNT_OUT => rw_sdram_counter,
+        UP_IN     => '1',
+        DOWN_IN   => '0');
+
+  (CE, RAS, CAS, WE, DQMH, DQML) <= command;
+  CKE <= '1';
+  SDARM_CLK <= CLK;
+  RAM_DEBUG_00(7 downto 0) <= ram_debug_i;
+  RAM_DEBUG_00(15 downto 8) <= bank_address & command;
+--  RAM_DEBUG_00(19 downto 16) <= data_fsm(31 downto 28);
+  
+  DATA_SYNCH_IN : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        RAM_DEBUG_00(23 downto 16) <= (others => '0');
+      else
+        RAM_DEBUG_00(23 downto 16) <= DATA(23 downto 16);
+      end if;
+    end if;
+  end process DATA_SYNCH_IN;
+
+  RAM_DEBUG_00(27 downto 24) <= fifo_from_sdram_data_out(31 downto 28);
+  
+  RAM_DEBUG_00(28) <= fifo_from_sdram_wr_synch_synch;
+  RAM_DEBUG_00(29) <= write_address(0);
+  RAM_DEBUG_00(30) <= read_address(0);
+  RAM_DEBUG_00(31) <= fifo_from_sdram_empty;
+  RAM_DEBUG_01(0) <= fifo_from_sdram_rd_en;
+  RAM_DEBUG_01(1) <= fifo_to_sdram_rd_en;
+  RAM_DEBUG_01(2) <= drive_data;
+  RAM_DEBUG_01(3) <= sdram_address(0);
+  RAM_DEBUG_01(4) <= DATA_WRITE;
+  RAM_DEBUG_01(5) <= DATA_READ_REQUEST;
+  RAM_DEBUG_01(6) <= '1' when SDRAM_FSM_CURRENT = READ_SDRAM else '0';
+  RAM_DEBUG_01(7) <= '1' when SDRAM_FSM_CURRENT = WRITE_SDRAM else '0';
+
+  
+  BA <= bank_address;
+  ADDR <= sdram_address;
+  
+--  DRIVE_DATA_TO_FROM_SDRAM : process (CLK, RESET)
+--  begin
+--    if rising_edge(CLK) then
+--      if RESET = '1' then 
+--        DATA <= (others => 'Z');
+--      elsif drive_data_fsm = '0' then
+--        DATA <= (others => 'Z');
+--      else
+--        DATA <= data_fsm;
+--      end if;
+--    end if;
+--  end process DRIVE_DATA_TO_FROM_SDRAM;
+
+  DATA <= data_to_sdram when drive_data = '1'
+          else (others => 'Z');
+
+--           else x"ffffff" when SDRAM_FSM_CURRENT = IDLE
+--    DATA <= x"aaaa" & "000" &  sdram_address when drive_data = '1' else (others => 'Z');
+            
+  SDRAM_FSM_CLOCK : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        SDRAM_FSM_CURRENT   <= INIT;    --no_sim--
+--sim-- SDRAM_FSM_CURRENT   <= IDLE;    --no_sim--
+        ram_debug_i <= (others => '0');
+        command <= NOP_CMD;
+        reset_main_sdram_counter <= '1';
+        drive_data <= '0';
+        bank_address <= (others => '0');
+        reset_rw_sdram_counter <= '0';
+        sdram_address <= (others => '0');
+        fifo_to_sdram_rd_en <= '0';
+        data_to_sdram <= (others => '0');
+      else
+        SDRAM_FSM_CURRENT   <= SDRAM_FSM_NEXT;
+        ram_debug_i <= ram_debug_fsm;
+        command <= command_fsm;
+        reset_main_sdram_counter <= reset_main_sdram_counter_fsm;
+        drive_data <= drive_data_fsm;
+        bank_address <= bank_address_fsm;
+        reset_rw_sdram_counter <= reset_rw_sdram_counter_fsm;
+        sdram_address <= sdram_address_fsm;
+        fifo_to_sdram_rd_en <= fifo_to_sdram_rd_en_fsm;
+        data_to_sdram <= data_fsm;
+      end if;
+    end if;
+  end process SDRAM_FSM_CLOCK;
+
+  SDRAM_FSM_PROC : process (CLK)
+  begin
+    command_fsm <= NOP_CMD;
+    ram_debug_fsm <= (others => '0');
+    reset_main_sdram_counter_fsm <= '0';
+    sdram_address_fsm <= (others => '0');
+    bank_address_fsm <=  (others => '0');
+    drive_data_fsm <= '0';
+    reset_rw_sdram_counter_fsm <= '1';
+    fifo_to_sdram_rd_en_fsm <= '0';
+    data_fsm <= (others => '0');
+    
+    case (SDRAM_FSM_CURRENT) is
+      when INIT      =>
+        ram_debug_fsm <= x"01";
+        command_fsm <= NOP_CMD;
+        if main_sdram_counter = x"ffff" then
+          SDRAM_FSM_NEXT <= PRECHARGE;
+        else
+          SDRAM_FSM_NEXT <= INIT;
+        end if;
+          
+      when PRECHARGE =>
+        ram_debug_fsm <= x"02";
+        reset_main_sdram_counter_fsm <= '1'; 
+        command_fsm <= PCHG_CMD;
+        sdram_address_fsm(10) <= '1';
+        SDRAM_FSM_NEXT <= NOP_1;
+          
+      when NOP_1 =>
+        ram_debug_fsm <= x"03";
+        command_fsm <= NOP_CMD;
+        if main_sdram_counter = x"0004" then
+          SDRAM_FSM_NEXT <= AUTO_REFRESH_1;
+        else
+          SDRAM_FSM_NEXT <= NOP_1;
+        end if;
+          
+      when AUTO_REFRESH_1 =>
+        ram_debug_fsm <= x"04";
+        reset_main_sdram_counter_fsm <= '1'; 
+        command_fsm <= RFSH_CMD;  
+        SDRAM_FSM_NEXT <= NOP_2;
+        
+      when NOP_2 =>
+        ram_debug_fsm <= x"05";
+        command_fsm <= NOP_CMD;
+        if main_sdram_counter = x"0004" then
+          SDRAM_FSM_NEXT <= AUTO_REFRESH_2;
+        else
+          SDRAM_FSM_NEXT <= NOP_2;
+        end if;
+
+      when AUTO_REFRESH_2 =>
+        ram_debug_fsm <= x"06";
+        reset_main_sdram_counter_fsm <= '1'; 
+        command_fsm <= RFSH_CMD;  
+        SDRAM_FSM_NEXT <= NOP_3;
+
+      when NOP_3 =>
+        ram_debug_fsm <= x"07";
+        command_fsm <= NOP_CMD;
+        if main_sdram_counter = x"0004" then
+          SDRAM_FSM_NEXT <= MODE_REGISTER;
+        else
+          SDRAM_FSM_NEXT <= NOP_3;
+        end if;
+
+      when MODE_REGISTER =>
+        ram_debug_fsm <= x"08";
+        command_fsm <= MODE_CMD;
+        sdram_address_fsm <= SDRAM_MODE;
+        SDRAM_FSM_NEXT <= IDLE;
+--main
+      when IDLE =>
+        ram_debug_fsm <= x"09";
+        command_fsm <= NOP_CMD;
+        if refresh_request = '1' then
+          SDRAM_FSM_NEXT <= REFRESH_SDRAM;
+        elsif fifo_to_sdram_empty = '0' then
+          SDRAM_FSM_NEXT <= WRITE_SDRAM_ACTIVE;
+        elsif how_many_waiting_read_requests > 0 then
+          SDRAM_FSM_NEXT <= READ_SDRAM_ACTIVE;
+        else
+          SDRAM_FSM_NEXT <= IDLE;
+        end if;
+
+      when REFRESH_SDRAM =>
+        reset_main_sdram_counter_fsm <= '1';
+        ram_debug_fsm <= x"0a";
+        command_fsm <= RFSH_CMD;
+        SDRAM_FSM_NEXT <= REFRESH_NOP;          
+
+      when REFRESH_NOP =>
+        ram_debug_fsm <= x"0b";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" then
+          SDRAM_FSM_NEXT <= IDLE;
+        else
+          SDRAM_FSM_NEXT <= REFRESH_NOP;
+        end if;
+--write
+      when WRITE_SDRAM_ACTIVE =>
+        ram_debug_fsm <= x"0b";
+        sdram_address_fsm <= fifo_to_sdram_data_out(24 downto 12);
+        bank_address_fsm <= fifo_to_sdram_data_out(11 downto 10);
+        command_fsm <= ACTIVE_CMD;
+        SDRAM_FSM_NEXT <= WRITE_SDRAM_WAIT;
+        
+      when WRITE_SDRAM_WAIT =>
+        ram_debug_fsm <= x"0c";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        drive_data_fsm <= '1';
+        if rw_sdram_counter= x"3" then
+          SDRAM_FSM_NEXT <= WRITE_SDRAM;
+        else
+          SDRAM_FSM_NEXT <= WRITE_SDRAM_WAIT;
+        end if;
+
+      when WRITE_SDRAM =>
+        ram_debug_fsm <= x"0d";
+        fifo_to_sdram_rd_en_fsm <= not fifo_to_sdram_empty;
+        sdram_address_fsm <= "000" & fifo_to_sdram_data_out(9 downto 0);
+        bank_address_fsm <= fifo_to_sdram_data_out(11 downto 10);
+        drive_data_fsm <= '1';
+        data_fsm <= fifo_to_sdram_data_out(63 downto 32);
+        if (fifo_to_sdram_data_out(24 downto 10) /= row_bank_saved) then
+          command_fsm <= NOP_CMD;     
+          SDRAM_FSM_NEXT <= WRITE_INTERRUPT_NOP_1;
+        elsif fifo_to_sdram_empty = '1' or (refresh_request = '1') or (fifo_to_sdram_empty = '1') then
+          command_fsm <= WRITE_CMD;     
+          SDRAM_FSM_NEXT <= WRITE_INTERRUPT_NOP_1;
+        else
+          command_fsm <= WRITE_CMD;
+          SDRAM_FSM_NEXT <= WRITE_SDRAM;
+        end if;
+
+      when WRITE_INTERRUPT_NOP_1 => 
+        ram_debug_fsm <= x"0e";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" then
+          SDRAM_FSM_NEXT <= WRITE_INTERRUPT_PRECHARGE;
+        else
+          SDRAM_FSM_NEXT <= WRITE_INTERRUPT_NOP_1;
+        end if;
+     
+
+      when WRITE_INTERRUPT_PRECHARGE =>
+        ram_debug_fsm <= x"0f";
+        sdram_address_fsm(10) <= '1';
+        command_fsm <= PCHG_CMD;
+        SDRAM_FSM_NEXT <= WRITE_INTERRUPT_NOP;
+
+         
+      when WRITE_INTERRUPT_NOP => 
+        ram_debug_fsm <= x"10";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" then
+          SDRAM_FSM_NEXT <= WRITE_SDRAM_REFRESH;
+        else
+          SDRAM_FSM_NEXT <= WRITE_INTERRUPT_NOP;
+        end if;
+        
+      when WRITE_SDRAM_REFRESH => 
+        reset_main_sdram_counter_fsm <= '1';
+        ram_debug_fsm <= x"11";
+        command_fsm <= RFSH_CMD;
+        SDRAM_FSM_NEXT <= WRITE_REFRESH_NOP;          
+
+      when WRITE_REFRESH_NOP =>
+        ram_debug_fsm <= x"12";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" and fifo_to_sdram_empty = '1' then
+          SDRAM_FSM_NEXT <= IDLE;
+        elsif rw_sdram_counter = x"3" and fifo_to_sdram_empty = '0' then
+          SDRAM_FSM_NEXT <=  WRITE_SDRAM_ACTIVE;
+        else
+          SDRAM_FSM_NEXT <= WRITE_REFRESH_NOP;
+        end if;
+--read
+        
+      when READ_SDRAM_ACTIVE =>
+        ram_debug_fsm <= x"13";
+        sdram_address_fsm <= read_address(24 downto 12);
+        bank_address_fsm <= read_address(11 downto 10);
+        command_fsm <= ACTIVE_CMD;
+        SDRAM_FSM_NEXT <= READ_SDRAM_WAIT;
+        
+      when READ_SDRAM_WAIT =>
+        ram_debug_fsm <= x"14";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter= x"3" then
+          SDRAM_FSM_NEXT <= READ_SDRAM;
+        else
+          SDRAM_FSM_NEXT <= READ_SDRAM_WAIT;
+        end if;
+
+      when READ_SDRAM =>
+        ram_debug_fsm <= x"15";
+     --   fifo_from_sdram_rd_en_fsm <= not fifo_from_sdram_empty;
+        sdram_address_fsm <= "000" & read_address(9 downto 0);
+        bank_address_fsm <= read_address(11 downto 10);
+        if (read_address(24 downto 10) /= row_bank_saved) or (refresh_request = '1') or (how_many_waiting_read_requests = x"0001") then
+          --command_fsm <= NOP_CMD;
+          command_fsm <= READ_CMD;     
+          SDRAM_FSM_NEXT <= READ_INTERRUPT_NOP_1;
+        else
+          command_fsm <= READ_CMD;
+          SDRAM_FSM_NEXT <= READ_SDRAM;
+        end if;
+
+      when READ_INTERRUPT_NOP_1 => 
+        ram_debug_fsm <= x"16";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" then
+          SDRAM_FSM_NEXT <= READ_INTERRUPT_PRECHARGE;
+        else
+          SDRAM_FSM_NEXT <= READ_INTERRUPT_NOP_1;
+        end if;
+        
+      when READ_INTERRUPT_PRECHARGE =>
+        ram_debug_fsm <= x"17";
+        sdram_address_fsm(10) <= '1';
+        command_fsm <= PCHG_CMD;
+        SDRAM_FSM_NEXT <= READ_INTERRUPT_NOP;
+                
+      when READ_INTERRUPT_NOP => 
+        ram_debug_fsm <= x"18";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" then
+          SDRAM_FSM_NEXT <= READ_SDRAM_REFRESH;
+        else
+          SDRAM_FSM_NEXT <= READ_INTERRUPT_NOP;
+        end if;
+        
+      when READ_SDRAM_REFRESH => 
+        reset_main_sdram_counter_fsm <= '1';
+        ram_debug_fsm <= x"19";
+        command_fsm <= RFSH_CMD;
+        SDRAM_FSM_NEXT <= READ_REFRESH_NOP;          
+
+      when READ_REFRESH_NOP =>
+        ram_debug_fsm <= x"1a";
+        command_fsm <= NOP_CMD;
+        reset_rw_sdram_counter_fsm <= '0';
+        if rw_sdram_counter = x"3" and how_many_waiting_read_requests = 0 then
+          SDRAM_FSM_NEXT <= IDLE;
+        elsif  rw_sdram_counter = x"3"  then
+          SDRAM_FSM_NEXT <= READ_SDRAM_ACTIVE;
+        else
+          SDRAM_FSM_NEXT <= READ_REFRESH_NOP;
+        end if;
+        
+      when others    =>
+        ram_debug_fsm <= x"00";
+        SDRAM_FSM_NEXT <= INIT;
+          
+    end case;
+  end process SDRAM_FSM_PROC;
+
+--sim--  WRITE_TO_SIMULATION_RAM: process
+--sim--  begin
+--sim--  while command = WRITE_CMD loop  
+--sim--    my_memory.write(fifo_to_sdram_data_out(24 downto 0),fifo_to_sdram_data_out(63 downto 32));
+--sim--    wait for 10 ns;
+--sim--    end loop;
+--sim--  if SDRAM_FSM_CURRENT = READ_SDRAM  then
+--sim--    wait for 40 ns;  
+--sim--    data_out_i   <= my_memory.read(read_address);
+--sim--    end if;
+--sim--  wait for 10 ns;
+--sim--  data_out_i <= (others => 'Z');
+--sim--  end process WRITE_TO_SIMULATION_RAM;
+  
+  SAVE_ROW : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        row_bank_saved <= (others => '0');
+      elsif SDRAM_FSM_CURRENT = WRITE_SDRAM_ACTIVE then
+        row_bank_saved <= fifo_to_sdram_data_out(24 downto 10);
+      elsif SDRAM_FSM_CURRENT = READ_SDRAM_ACTIVE then
+        row_bank_saved <= read_address(24 downto 10);
+      else
+        row_bank_saved <= row_bank_saved;
+      end if;
+    end if;
+  end process SAVE_ROW;
+
+  SAVE_REFRESH_REQUEST : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' or  SDRAM_FSM_CURRENT = READ_SDRAM_REFRESH or SDRAM_FSM_CURRENT = WRITE_SDRAM_REFRESH or SDRAM_FSM_CURRENT = REFRESH_SDRAM then 
+        refresh_request <= '0';
+      elsif main_sdram_counter > x"1ff" then
+        refresh_request <= '1';
+      else
+        refresh_request <= refresh_request;
+      end if;
+    end if;
+  end process SAVE_REFRESH_REQUEST;
+
+  WRITE_ADDRESS_COUNTER: up_down_counter
+    generic map (
+        NUMBER_OF_BITS => 25)
+    port map (
+        CLK       => DATA_CLK_IN,
+        RESET     => RESET,
+        COUNT_OUT => write_address,
+        UP_IN     => DATA_WRITE,
+        DOWN_IN   => '0');
+  
+  fifo_to_sdram_data_in <= "0" & WRITE_DATA_IN & "0000000"  & write_address;
+  
+  THE_DATA_ADDRESS_TO_SDRAM_FIFO: data_address_to_sdram_fifo
+    port map (
+      din           => fifo_to_sdram_data_in,
+      rd_clk        => CLK,
+      rd_en         => fifo_to_sdram_rd_en,
+      rst           => RESET,
+      wr_clk        => DATA_CLK_IN,
+      wr_en         => DATA_WRITE,
+      dout          => fifo_to_sdram_data_out,
+      empty         => fifo_to_sdram_empty,
+      full          => fifo_to_sdram_full,
+      rd_data_count => fifo_to_sdram_rd_data_count,
+      wr_data_count => fifo_to_sdram_wr_data_count);
+
+  UPDATE_READ_ADDRESS : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        read_address <= '0' & x"000001";--(others => '0');
+        read_done <= '0';
+      elsif SDRAM_FSM_CURRENT = READ_SDRAM then
+        read_address <= read_address + 1;
+        read_done <= '1';
+      else
+        read_address <= read_address;
+        read_done <= '0';
+      end if;
+    end if;
+  end process UPDATE_READ_ADDRESS;
+
+  READ_COUNTER: up_down_counter
+    generic map (
+        NUMBER_OF_BITS => 16)
+    port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        COUNT_OUT => how_many_waiting_read_requests,
+        UP_IN     => DATA_READ_REQUEST,
+        DOWN_IN   => read_done);
+  
+  SAVE_DATA_FROM_SDRAM : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        fifo_from_sdram_wr <= '0';
+      elsif command = READ_CMD then
+        fifo_from_sdram_wr <= '1';
+      else
+        fifo_from_sdram_wr <= '0';
+      end if;
+    end if;
+  end process SAVE_DATA_FROM_SDRAM;
+
+  SYNHC_FIFO_WRITE_WITH_SDRAM_DATA : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        fifo_from_sdram_wr_synch <= '0';
+        fifo_from_sdram_wr_synch_synch <= '0';
+      else
+        fifo_from_sdram_wr_synch <= fifo_from_sdram_wr;
+        fifo_from_sdram_wr_synch_synch <= fifo_from_sdram_wr_synch;
+      end if;
+    end if;
+  end process SYNHC_FIFO_WRITE_WITH_SDRAM_DATA;
+
+  fifo_from_sdram_data_in <= "00" & DATA;  --no_sim--
+--sim--  fifo_from_sdram_data_in <= "00" &  data_out_i;
+  
+  THE_FIFO_FROM_SDRAM: fifo_from_sdram
+    port map (
+      din           => fifo_from_sdram_data_in,
+      rd_clk        => CLK,
+      rd_en         => fifo_from_sdram_rd_en,
+      rst           => RESET,
+      wr_clk        => CLK,
+      wr_en         => fifo_from_sdram_wr_synch_synch,
+      dout          => fifo_from_sdram_data_out,
+      empty         => fifo_from_sdram_empty,
+      full          => fifo_from_sdram_full,
+      rd_data_count => fifo_from_sdram_rd_data_count,
+      wr_data_count => fifo_from_sdram_wr_data_count);
+  fifo_from_sdram_rd_en <= not fifo_from_sdram_empty;
+  READ_DATA_OUT <= fifo_from_sdram_data_out(31 downto 0);
+  
+  READ_DIFF_COUNTER: up_down_counter
+    generic map (
+        NUMBER_OF_BITS => 16)
+    port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        COUNT_OUT => how_many_data_in_fifo,
+        UP_IN     => DATA_READ_REQUEST,
+        DOWN_IN   => fifo_from_sdram_wr_synch_synch);
+  
+  SET_READ_READY : process (CLK, RESET)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        READ_READY <= '0';
+      elsif how_many_data_in_fifo > 0 then
+        READ_READY <= '1';
+      else
+        READ_READY <= '0';
+      end if;
+    end if;
+  end process SET_READ_READY;
+
+  
+  
+end sdram_controller;