From: hadaq Date: Tue, 19 Jan 2010 15:54:25 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=c7560901adad2192ce54af397791309eda5abe3a;p=trbv2.git *** empty log message *** --- diff --git a/sdram_controller.vhd b/sdram_controller.vhd new file mode 100644 index 0000000..fec2cc3 --- /dev/null +++ b/sdram_controller.vhd @@ -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;