---------------------------------------------- -- NP1003 SDRAM & USB sample source -- (C) Copyright 2003 Nahitafu Nahitech -- http://www.nahitech.com ---------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity np1003s1 is Port ( CLK0 : in std_logic; CLK1 : in std_logic; CLK2 : in std_logic; CLK3 : in std_logic; USER : inout std_logic_vector(36 downto 0); SD_D : inout std_logic_vector(15 downto 0); SD_A : out std_logic_vector(12 downto 0); SD_BS1 : out std_logic; SD_BS0 : out std_logic; SD_LDQM : out std_logic; SD_UDQM : out std_logic; SD_WEN : out std_logic; SD_RAS : out std_logic; SD_CAS : out std_logic; SD_CLK : out std_logic; SD_CKE : out std_logic; SD_CS : out std_logic; USB_D : inout std_logic_vector(7 downto 0); USB_WR : out std_logic; USB_RD : out std_logic; USB_TXE : in std_logic; USB_RXF : in std_logic; USB_PWREN : in std_logic; USB_RSTO : in std_logic ); end np1003s1; architecture Behavioral of np1003s1 is signal CLK : std_logic; signal logicH : std_logic; signal logicL : std_logic; signal COUNT : std_logic_vector(15 downto 0); signal DataLength : std_logic_vector(15 downto 0); signal USB_STATE : integer range 0 to 15; signal USB_RXF_node : std_logic; signal USB_TXE_node : std_logic; signal USB_RX_Ready : std_logic; signal USB_TX_Ready : std_logic; signal USB_Received : std_logic; signal USB_Transmitted : std_logic; signal USB_Tx_DATA : std_logic_vector(7 downto 0); signal USB_Rx_DATA : std_logic_vector(7 downto 0); constant ClkFreq : integer := 54; -- Clock Frequency in MHz constant RefPeriod : integer := 7; -- Refresh period constant RefTimerMax : integer := ClkFreq * RefPeriod; signal RefTimer : integer range 0 to RefTimerMax; constant VTimerMax : integer := 30; signal VTimer : integer range 0 to VTimerMax; signal SD_CMD : std_logic_vector(3 downto 0); signal SD_ADDR : std_logic_vector(24 downto 0); signal SDState : integer range 0 to 127; signal RefRequest : std_logic; signal VTimerOver : std_logic; -- [CS,RAS,CAS,WEN] constant SDcmd_DESL : std_logic_vector := "1"&"1"&"1"&"1";-- Ignore command constant SDcmd_NOP : std_logic_vector := "0"&"1"&"1"&"1";-- No operation constant SDcmd_ACTV : std_logic_vector := "0"&"0"&"1"&"1";-- Row addr & active constant SDcmd_READ : std_logic_vector := "0"&"1"&"0"&"1";-- Col addr & Read constant SDcmd_WRIT : std_logic_vector := "0"&"1"&"0"&"0";-- Col addr & Write constant SDcmd_PRE : std_logic_vector := "0"&"0"&"1"&"0";-- Precharge select bank constant SDcmd_PALL : std_logic_vector := "0"&"0"&"1"&"0";-- Precharge all bank constant SDcmd_REF : std_logic_vector := "0"&"0"&"0"&"1";-- Refresh self or auto constant SDcmd_MRS : std_logic_vector := "0"&"0"&"0"&"0";-- Mode register set signal SD_WriteReq : std_logic; signal SD_ReadReq : std_logic; signal SD_WriteDone : std_logic; signal SD_ReadDone : std_logic; signal SD_Data : std_logic_vector(7 downto 0); signal SD_DCap : std_logic_vector(7 downto 0); signal GState : integer range 0 to 15; signal GStateL : std_logic_vector(3 downto 0); component CLKDLL port( CLKFB : in std_logic; CLKIN : in std_logic; RST : in std_logic; CLK0 : out std_logic; CLK180 : out std_logic; CLK270 : out std_logic; CLK2X : out std_logic; CLK90 : out std_logic; CLKDV : out std_logic; LOCKED : out std_logic ); end component; component BUFG port( I : in std_logic; O : out std_logic ); end component; signal CLK_I,CLK_O : std_logic; begin GStateL <= conv_std_logic_vector(GState,4); -- bufg01 : BUFG PORT MAP (I=>CLK_O, O=>SD_CLK); -- DLL1 : CLKDLL -- -- PORT MAP (CLKIN=>CLK0, CLKFB=>SD_CLK, RST=>logicl, -- CLK0=>CLK_O, CLK90=>open, CLK180=>open, CLK270=>open, -- CLK2X=>open, CLKDV=>open, LOCKED=>open); CLK <= CLK0; logicH <= '1'; logicL <= '0'; SD_CLK <= not CLK0; SD_CS <= SD_CMD(3); SD_RAS <= SD_CMD(2); SD_CAS <= SD_CMD(1); SD_WEN <= SD_CMD(0); USER(7 downto 0) <= SD_ADDR(7 downto 0); USER(8) <= USB_Tx_Ready; USER(9) <= USB_Transmitted; USER(10) <= USB_Rx_Ready; USER(11) <= USB_Received; USER(23 downto 16) <= SD_DCap; USER(15) <= GStateL(3); USER(14) <= GStateL(2); USER(13) <= GStateL(1); USER(12) <= GStateL(0); USER(24) <= SD_CMD(3); USER(26) <= SD_CMD(2); USER(28) <= SD_CMD(1); USER(30) <= SD_CMD(0); USER(25) <= SD_ReadReq; USER(27) <= SD_ReadDone; USER(29) <= SD_WriteReq; USER(31) <= SD_WriteDone; RefRequest <= '1' when (RefTimer = RefTimerMax) else '0'; VTimerOver <= '1' when (VTimer = VTimerMax ) else '0'; process(CLK) begin if (CLK'event and CLK = '1') then if(RefRequest = '1') then RefTimer <= 0; if(VTimerOver = '1') then VTimer <= 0; else VTimer <= VTimer + 1; end if; else RefTimer <= RefTimer + 1; end if; end if; end process; process(CLK) begin if (CLK'event and CLK = '1') then SD_DCap <= SD_D(15)&SD_D(13)&SD_D(11)&SD_D(9)&SD_D(6)&SD_D(4)&SD_D(2)&SD_D(0); end if; end process; process(CLK) begin if (CLK'event and CLK = '1') then case GState is when 0 => USB_Rx_Ready <= '1'; USB_Tx_Ready <= '0'; SD_WriteReq <= '0'; SD_ReadReq <= '0'; if(USB_Received = '1') then if(USB_Rx_Data = x"01") then -- SDWRITE GState <= 1; elsif(USB_Rx_Data = x"02") then -- SDREAD GState <= 5; elsif(USB_Rx_Data = x"03") then -- ASET GState <= 9; end if; end if; Count <= (others=>'0'); when 1 => if(USB_Received = '1') then DataLength(7 downto 0) <= USB_Rx_Data; GState <= GState + 1; end if; when 2 => if(USB_Received = '1') then DataLength(15 downto 8) <= USB_Rx_Data; GState <= GState + 1; end if; when 3 => if(USB_Received = '1') then USB_Rx_Ready <= '0'; GState <= GState + 1; SD_WriteReq <= '1'; end if; when 4 => if(SD_WriteDone = '1') then SD_WriteReq <= '0'; SD_ADDR <= SD_ADDR + 1; if(Count = DataLength) then GState <= 0; else Count <= Count + 1; USB_Rx_Ready <= '1'; GState <= 3; end if; end if; when 5 => if(USB_Received = '1') then DataLength(7 downto 0) <= USB_Rx_Data; GState <= GState + 1; end if; when 6 => if(USB_Received = '1') then DataLength(15 downto 8) <= USB_Rx_Data; GState <= GState + 1; SD_ReadReq <= '1'; end if; when 7 => if(SD_ReadDone = '1') then SD_ReadReq <= '0'; USB_Tx_Ready <= '1'; USB_Tx_DATA <= SD_Data(7 downto 0); GState <= GState + 1; else SD_ReadReq <= '1'; end if; when 8 => if(USB_Transmitted = '1') then USB_Tx_Ready <= '0'; SD_ADDR <= SD_ADDR + 1; if(Count = DataLength) then GState <= 0; else Count <= Count + 1; GState <= 7; end if; else USB_Tx_Ready <= '1'; end if; when 9 => if(USB_Received = '1') then SD_ADDR(7 downto 0) <= USB_Rx_Data; GState <= GState + 1; end if; when 10 => if(USB_Received = '1') then SD_ADDR(15 downto 8) <= USB_Rx_Data; GState <= GState + 1; end if; when 11 => if(USB_Received = '1') then SD_ADDR(23 downto 16) <= USB_Rx_Data; GState <= GState + 1; end if; when 12 => if(USB_Received = '1') then SD_ADDR(24) <= USB_Rx_Data(0); GState <= 0; end if; when others => GState <= 0; end case; end if; end process; process(CLK) begin if (CLK'event and CLK = '1') then case SDState is when 0 => SD_LDQM <= '0'; SD_UDQM <= '0'; SD_CKE <= '1'; SD_BS1 <= '0'; SD_BS1 <= '0'; SD_A <= (others => '0'); SD_D <= (others => 'Z'); SD_CMD <= SDcmd_DESL; SD_WriteDone <= '0'; SD_ReadDone <= '0'; if(VTimer = 0) then SDState <= SDState + 1; end if; when 1 => SD_CMD <= SDcmd_NOP; -- wait until VTimer is set to non 0 value if(VTimer /= 0) then SDState <= SDState + 1; end if; when 2 => SD_CMD <= SDcmd_NOP; -- wait until VTimer is set to 0 if(VTimer = 0) then SDState <= SDState + 1; end if; when 3 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 4 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 1st time) SDState <= SDState + 1; when 5 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 6 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 2nd time) SDState <= SDState + 1; when 7 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 8 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 3rd time) SDState <= SDState + 1; when 9 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 10 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 4th time) SDState <= SDState + 1; when 11 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 12 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 5th time) SDState <= SDState + 1; when 13 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 14 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 6th time) SDState <= SDState + 1; when 15 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 16 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 7th time) SDState <= SDState + 1; when 17 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 18 => SD_CMD <= SDcmd_PALL; -- Precharge all (the 8th time) SDState <= SDState + 1; when 19 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second if(RefRequest = '1') then SDState <= SDState + 1; end if; when 20 => SD_CMD <= SDcmd_MRS; SD_BS1 <= '0'; SD_BS0 <= '0'; SD_A <= "00010"&"0"&"010"&"0"&"000"; SDState <= SDState + 1; when 21 => SD_CMD <= SDcmd_NOP; -- wait for 8 micro second SD_A <= (others=>'0'); SDState <= SDState + 1; when 22 => SDState <= SDState + 1; when 23 => SDState <= SDState + 1; when 24 => --idle state if(SD_WriteReq = '1') then SDState <= 40; elsif(SD_ReadReq = '1') then SDState <= 32; else SDState <= SDState + 1; end if; when 25 => -- refresh cycle, ref1 SD_CMD <= SDcmd_REF; -- affected at ref2 SDState <= SDState + 1; when 26 => -- ref2 SD_CMD <= SDcmd_NOP; -- affected at ref3 SDState <= SDState + 1; when 27 => -- ref3 SD_CMD <= SDcmd_NOP; -- affected at ref4 SDState <= SDState + 1; when 28 => -- ref4 SD_CMD <= SDcmd_NOP; -- affected at ref5 SDState <= SDState + 1; when 29 => -- ref5 SD_CMD <= SDcmd_NOP; -- affected at idle state SDState <= 24; --sdram read cycle when 32 => --r0 SD_BS1 <= SD_ADDR(11); SD_BS0 <= SD_ADDR(10); SD_A <= SD_ADDR(24 downto 12); SD_D <= (others=>'Z'); SD_CMD <= SDcmd_ACTV; -- affected at r1 SDState <= SDState + 1; when 33 => --r1 SD_CMD <= SDcmd_NOP; -- affected at r2 SDState <= SDState + 1; when 34 => --r2 SD_CMD <= SDcmd_READ; -- affected at r3 SD_BS1 <= SD_ADDR(11); SD_BS0 <= SD_ADDR(10); SD_A <= "001" & SD_ADDR(9 downto 0); -- read with AP SDState <= SDState + 1; when 35 => --r3 SD_CMD <= SDcmd_NOP; -- affected at r4 SDState <= SDState + 1; when 36 => --r4 SD_CMD <= SDcmd_NOP; -- affected at r5 SDState <= SDState + 1; when 37 => --r5 SD_ReadDone <= '1'; SD_CMD <= SDcmd_NOP; -- affected at r6 SD_Data <= SD_D(15)&SD_D(13)&SD_D(11)&SD_D(9)&SD_D(6)&SD_D(4)&SD_D(2)&SD_D(0); SDState <= SDState + 1; when 38 => --r6 SD_ReadDone <= '0'; SD_CMD <= SDcmd_NOP; -- affected at idle state SDState <= 25; --sdram write cycle when 40 => --w0 SD_BS1 <= SD_ADDR(11); SD_BS0 <= SD_ADDR(10); SD_A <= SD_ADDR(24 downto 12); SD_CMD <= SDcmd_ACTV; -- affected at w1 SDState <= SDState + 1; when 41 => --w1 SD_CMD <= SDcmd_NOP; -- affected at w2 SDState <= SDState + 1; when 42 => --w2 SD_CMD <= SDcmd_WRIT; -- affected at w3 SD_BS1 <= SD_ADDR(11); SD_BS0 <= SD_ADDR(10); SD_A <= "001" & SD_ADDR(9 downto 0); -- write with AP SD_D(0) <= USB_Rx_Data(0); SD_D(2) <= USB_Rx_Data(1); SD_D(4) <= USB_Rx_Data(2); SD_D(6) <= USB_Rx_Data(3); SD_D(9) <= USB_Rx_Data(4); SD_D(11)<= USB_Rx_Data(5); SD_D(13)<= USB_Rx_Data(6); SD_D(15)<= USB_Rx_Data(7); SD_WriteDone <= '1'; SDState <= SDState + 1; when 43 => --w3 SD_CMD <= SDcmd_NOP; -- affected at w4 SD_D <= (others=>'Z'); SD_WriteDone <= '0'; SDState <= SDState + 1; when 44 => --w4 SD_CMD <= SDcmd_NOP; -- affected at idle state SDState <= 25; when others=> SDState <= 0; end case; end if; end process; process(CLK) begin if (CLK'event and CLK = '1') then USB_RXF_node <= USB_RXF; USB_TXE_node <= USB_TXE; end if; end process; USB_INT : process(CLK) begin if (CLK'event and CLK = '1') then case USB_STATE is when 0 => USB_D <= (others=>'Z'); USB_Received <= '0'; USB_Transmitted <= '0'; if((USB_RXF_node = '0') and (USB_RX_Ready = '1')) then USB_RD <= '0'; -- at state 1 USB_STATE <= 1; elsif((USB_TXE_node = '0') and (USB_TX_Ready = '1')) then USB_STATE <= 8; else USB_RD <= '1'; USB_WR <= '0'; end if; -- USB read sequence when 1 => USB_STATE <= 2; when 2 => USB_STATE <= 3; when 3 => USB_Rx_Data <= USB_D; -- at state 4 USB_Received <= '1'; USB_STATE <= 4; when 4 => USB_RD <= '1'; -- at state 5 USB_Received <= '0'; USB_STATE <= 5; when 5 => USB_STATE <= 6; when 6 => USB_STATE <= 7; when 7 => USB_RD <= '0'; USB_STATE <= 0; -- USB write sequence when 8 => USB_WR <= '1'; -- at state 9 USB_D <= USB_Tx_DATA;-- at state 9 USB_STATE <= 9; when 9 => USB_STATE <= 10; when 10 => USB_STATE <= 11; when 11 => USB_STATE <= 12; when 12 => USB_WR <= '0'; -- at state 13 USB_Transmitted <= '1'; USB_STATE <= 13; when 13 => USB_D <= (others=>'Z');-- at state 14 USB_Transmitted <= '0'; USB_STATE <= 14; when 14 => USB_STATE <= 15; when 15 => USB_STATE <= 0; when others => USB_STATE <= 0; end case; end if; end process; end Behavioral;