library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity sdram is generic( freq : integer := 80 ); port( clk : in std_logic; reset : in std_logic; refresh : in std_logic; memAddress : in std_logic_vector(21 downto 0); memDataIn : in std_logic_vector(31 downto 0); memDataOut : out std_logic_vector(31 downto 0); memDataMask : in std_logic_vector(3 downto 0); memWr : in std_logic; memReq : in std_logic; memAck : out std_logic := '0'; memAddress2 : in std_logic_vector(21 downto 0); memDataIn2 : in std_logic_vector(31 downto 0); memDataOut2 : out std_logic_vector(31 downto 0); memDataMask2 : in std_logic_vector(3 downto 0); memWr2 : in std_logic; memReq2 : in std_logic; memAck2 : out std_logic := '0'; -- SD-RAM ports pMemClk : out std_logic; -- SD-RAM Clock pMemCke : out std_logic; -- SD-RAM Clock enable pMemCs_n : out std_logic; -- SD-RAM Chip select pMemRas_n : out std_logic; -- SD-RAM Row/RAS pMemCas_n : out std_logic; -- SD-RAM /CAS pMemWe_n : out std_logic; -- SD-RAM /WE pMemDqm : out std_logic_vector(3 downto 0); -- SD-RAM DQM pMemBa1 : out std_logic; -- SD-RAM Bank select address 1 pMemBa0 : out std_logic; -- SD-RAM Bank select address 0 pMemAdr : out std_logic_vector(11 downto 0); -- SD-RAM Address pMemDat : inout std_logic_vector(31 downto 0) -- SD-RAM Data ); end sdram; architecture rtl of sdram is -- -- SD-RAM control signals signal SdrCmd : std_logic_vector(3 downto 0); signal SdrBa0 : std_logic; signal SdrBa1 : std_logic; signal SdrDqm : std_logic_vector(3 downto 0); signal SdrAdr : std_logic_vector(11 downto 0); signal SdrDat : std_logic_vector(31 downto 0); signal iMemAck : std_logic; signal iMemAck2 : std_logic; constant SdrCmd_de : std_logic_vector(3 downto 0) := "1111"; -- deselect constant SdrCmd_pr : std_logic_vector(3 downto 0) := "0010"; -- precharge all constant SdrCmd_re : std_logic_vector(3 downto 0) := "0001"; -- refresh constant SdrCmd_ms : std_logic_vector(3 downto 0) := "0000"; -- mode regiser set constant SdrCmd_xx : std_logic_vector(3 downto 0) := "0111"; -- no operation constant SdrCmd_ac : std_logic_vector(3 downto 0) := "0011"; -- activate constant SdrCmd_rd : std_logic_vector(3 downto 0) := "0101"; -- read constant SdrCmd_wr : std_logic_vector(3 downto 0) := "0100"; -- write begin memAck <= iMemAck; memAck2 <= iMemAck2; process( clk ) type typSdrRoutine is ( SdrRoutine_Null, SdrRoutine_Init, SdrRoutine_Idle, SdrRoutine_RefreshAll, SdrRoutine_ReadOne, SdrRoutine_WriteOne ); variable SdrRoutine : typSdrRoutine := SdrRoutine_Null; variable SdrRoutineSeq : unsigned(7 downto 0) := X"00"; variable refreshDelayCounter : unsigned(23 downto 0) := x"000000"; variable SdrRefreshCounter : unsigned(15 downto 0) := X"0000"; variable SdrPort : std_logic := '0'; variable SdrAddress : std_logic_vector(21 downto 0); begin if clk'event and clk = '1' then iMemAck <= '0'; iMemAck2 <= '0'; case SdrRoutine is when SdrRoutine_Null => SdrCmd <= SdrCmd_xx; SdrDat <= (others => 'Z'); if refreshDelayCounter = 0 then SdrRoutine := SdrRoutine_Init; end if; when SdrRoutine_Init => if( SdrRoutineSeq = X"0" ) then SdrCmd <= SdrCmd_pr; SdrAdr <= "111111111111"; SdrBa1 <= '0'; SdrBa0 <= '0'; SdrDqm <= "1111"; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"4" or SdrRoutineSeq = X"0C" ) then SdrCmd <= SdrCmd_re; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"14" ) then SdrCmd <= SdrCmd_ms; SdrAdr <= "000" & "0" & "0" & "010" & "0" & "000"; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"17" ) then SdrCmd <= SdrCmd_xx; SdrRoutineSeq := X"00"; SdrRoutine := SdrRoutine_Idle; else SdrCmd <= SdrCmd_xx; SdrRoutineSeq := SdrRoutineSeq + 1; end if; when SdrRoutine_Idle => SdrCmd <= SdrCmd_xx; SdrDat <= (others => 'Z'); if memReq = '1' and iMemAck = '0' then SdrPort := '0'; SdrAddress := memAddress; if( memWr = '1' ) then SdrRoutine := SdrRoutine_WriteOne; else SdrRoutine := SdrRoutine_ReadOne; end if; elsif memReq2 = '1' and iMemAck2 = '0' then SdrPort := '1'; SdrAddress := memAddress2; if( memWr2 = '1' ) then SdrRoutine := SdrRoutine_WriteOne; else SdrRoutine := SdrRoutine_ReadOne; end if; elsif SdrRefreshCounter < 4096 and refresh = '1' then SdrRoutine := SdrRoutine_RefreshAll; SdrRefreshCounter := SdrRefreshCounter + 1; end if; when SdrRoutine_RefreshAll => if( SdrRoutineSeq = X"0" ) then SdrCmd <= SdrCmd_re; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"6" ) then SdrCmd <= SdrCmd_xx; SdrRoutineSeq := X"00"; SdrRoutine := SdrRoutine_Idle; else SdrCmd <= SdrCmd_xx; SdrRoutineSeq := SdrRoutineSeq + 1; end if; when SdrRoutine_ReadOne => if( SdrRoutineSeq = X"0" ) then SdrCmd <= SdrCmd_ac; SdrBa0 <= SdrAddress(20); SdrBa1 <= SdrAddress(21); SdrAdr <= SdrAddress(19 downto 8); SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"2" ) then SdrCmd <= SdrCmd_rd; SdrDqm <= "0000"; SdrAdr(11 downto 8) <= "0100"; SdrAdr(7 downto 0) <= SdrAddress(7 downto 0); SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"5" ) then if( SdrPort = '0' ) then memDataOut <= pMemDat; iMemAck <= '1'; else memDataOut2 <= pMemDat; iMemAck2 <= '1'; end if; SdrCmd <= SdrCmd_xx; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"6" ) then SdrRoutineSeq := X"00"; SdrRoutine := SdrRoutine_Idle; else SdrCmd <= SdrCmd_xx; SdrRoutineSeq := SdrRoutineSeq + 1; end if; when SdrRoutine_WriteOne => if( SdrRoutineSeq = X"0" ) then SdrCmd <= SdrCmd_ac; SdrBa0 <= SdrAddress(20); SdrBa1 <= SdrAddress(21); SdrAdr <= SdrAddress(19 downto 8); SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"2" ) then SdrCmd <= SdrCmd_wr; SdrAdr(11 downto 8) <= "0100"; SdrAdr(7 downto 0) <= SdrAddress(7 downto 0); if( SdrPort = '0' ) then SdrDat <= memDataIn; SdrDqm(0) <= not memDataMask(0); SdrDqm(1) <= not memDataMask(1); SdrDqm(2) <= not memDataMask(2); SdrDqm(3) <= not memDataMask(3); else SdrDat <= memDataIn2; SdrDqm(0) <= not memDataMask2(0); SdrDqm(1) <= not memDataMask2(1); SdrDqm(2) <= not memDataMask2(2); SdrDqm(3) <= not memDataMask2(3); end if; SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"3" ) then if( SdrPort = '0' ) then iMemAck <= '1'; else iMemAck2 <= '1'; end if; SdrCmd <= SdrCmd_xx; SdrDat <= (others => 'Z'); SdrRoutineSeq := SdrRoutineSeq + 1; elsif( SdrRoutineSeq = X"5" ) then SdrRoutineSeq := X"00"; SdrRoutine := SdrRoutine_Idle; else SdrCmd <= SdrCmd_xx; SdrRoutineSeq := SdrRoutineSeq + 1; end if; end case; refreshDelayCounter := refreshDelayCounter + 1; if( refreshDelayCounter >= ( freq * 1000 * 64 ) ) then refreshDelayCounter := x"000000"; SdrRefreshCounter := x"0000"; end if; end if; end process; pMemClk <= not clk; pMemCke <= '1'; pMemCs_n <= SdrCmd(3); pMemRas_n <= SdrCmd(2); pMemCas_n <= SdrCmd(1); pMemWe_n <= SdrCmd(0); pMemDqm <= SdrDqm; pMemBa1 <= SdrBa1; pMemBa0 <= SdrBa0; pMemAdr <= SdrAdr; pMemDat <= SdrDat; end rtl;