--- /dev/null
+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;