⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdram.vhd

📁 SDRAM基础性控制核 很有用的 VHDL状态机实现
💻 VHD
📖 第 1 页 / 共 2 页
字号:
---SDRAM CONTROL CLOCK 100M---
------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
-------------------------------------------------------------
-------------------------------------------------------------
entity sdram is
port(
     clk:in std_logic;
     reset:in std_logic;
     sig_read:IN STD_LOGIC;
     LEN    :IN STD_LOGIC_VECTOR(3 DOWNTO 0);

     CBE     :IN STD_LOGIC_VECTOR(2 DOWNTO 0);

     sig_write       :IN STD_LOGIC;
     data_in    :in STD_LOGIC_VECTOR(31 DOWNTO 0);
	 TO_LD      : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
     ADDR_FULL     :out STD_LOGIC;
     DATAVALID  :  OUT STD_LOGIC;
     SA         :OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
     BA         :OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
    -- CKE        :OUT STD_LOGIC;
     RAS ,CAS   :OUT STD_LOGIC;
     WE         :OUT STD_LOGIC;
     DQ         :INOUT STD_LOGIC_VECTOR(31 DOWNTO 0)
     --DQM        :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end sdram;
-------------------------------------------------------------
-------------------------------------------------------------
architecture sdram_a of sdram is
component addr
 port( ACLK       :in  std_logic;
       LEN    :IN STD_LOGIC_VECTOR(3 DOWNTO 0);
       ADDRESS    :out std_logic_vector(21 downto 0);
       ADDR_FULL     :OUT STD_LOGIC;
 --      ADDRESSFLAG:IN STD_LOGIC;
       RESET      :IN  STD_LOGIC;
       RESET_ADDR :IN STD_LOGIC);
end component;

COMPONENT SDR_SDRAM
  generic(
         ASIZE          : integer := 22;
         DSIZE          : integer := 32;
         ROWSIZE        : integer := 12;
         COLSIZE        : integer := 8;
         BANKSIZE       : integer := 2;
         ROWSTART       : integer := 8;         
         COLSTART       : integer := 0;         
         BANKSTART      : integer := 20
         );

     port(
     --    PM :      OUT STD_LOGIC;
     --    OE1         : out     std_logic;
         CLK            : in      std_logic;                         --System Clock
         RESET_N        : in      std_logic;                         --System Reset
         ADDR   			: in std_logic_vector(ASIZE-1 downto 0);--Address for controller requests
         CMD            : in      std_logic_vector(2 downto 0);      --Controller command 
         CMDACK         : out     std_logic;        --Controller command acknowledgement
         DATAIN         : in      std_logic_vector(DSIZE-1 downto 0);--Data input
         IDATAOUT       : out     std_logic_vector(DSIZE-1 downto 0);--Data output
        -- DM             : in      std_logic_vector(DSIZE/8-1 downto 0);--Data mask input
         ISA            : out     std_logic_vector(11 downto 0);--SDRAM address output
         IBA            : out     std_logic_vector(1 downto 0);--SDRAM bank address
        -- ICKE           : out     std_logic;--SDRAM clock enable
         IRAS_N         : out     std_logic;--SDRAM Row address Strobe
         ICAS_N         : out     std_logic;--SDRAM Column address Strobe
         IWE_N          : out     std_logic;--SDRAM write enable
         IDQ            : inout   std_logic_vector(DSIZE-1 downto 0);--SDRAM data bus
         --DQM      : out     std_logic_vector(DSIZE/8-1 downto 0);--SDRAM data mask lines

         IDATAVALIDTEMP : out     std_logic);
END COMPONENT;
-----------------------------------------------------------------------
TYPE ISTATE IS (NOP,INI_PRECHARGE,INI_PRECHARGE_NOP,LOADREG1_NOP,LOADMODE,LOADMODE_NOP,LOADREG1,LOADREG2_NOP,LOADREG2,
                INI_REFRESH,INI_REFRESH_NOP);----STATE MACHINE OF SDRAM CONTROLLER
TYPE WSTATE IS(WRITE_IDLE,WRITE_PRE,WRITE_PRE_NOP,WRITE_REFRESH,WRITE_REFRESH_NOP,
               WRITE_TERMINATE,WRITE_TERMINATE_NOP,WRITEa,WRITE_NOP);---STATE MACHINE OF WRITE DATA TO SDRAM
TYPE RSTATE IS(READ_IDLE,READa,READ_NOP,READ_PRE,READ_PRE_NOP,
               READ_TERMINATE,READ_TERMINATE_NOP,READ_REFRESH,READ_REFRESH_NOP);---STATE MACHINE OF READ DATA TO SDRAM
TYPE PSTATE IS(IDLE,SAVE_DATA,READ_DATA);-----USE FOR MACHINE
SIGNAL INISTATE:ISTATE;
SIGNAL WRITESTATE:WSTATE;
SIGNAL READSTATE:RSTATE;
SIGNAL PresentState:PSTATE;

signal address:std_logic_vector(21 downto 0);
SIGNAL FLAG :STD_LOGIC;
-----------------------------------------------------------------
SIGNAL ADDRESSRW:STD_LOGIC_VECTOR(21 DOWNTO 0);

SIGNAL ADDRESSCLK:STD_LOGIC;
signal CMD       :std_logic_vector(2 downto 0);
signal CMDACK    :STD_LOGIC;

--SIGNAL DM        :STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL IDATAVALIDTEMP :STD_LOGIC;
SIGNAL COUNT_DATA:std_logic_vector(8 downto 0);
SIGNAL COUNT_INI :STD_LOGIC_VECTOR(8 DOWNTO 0);--INTEGER RANGE 0 TO 300;
SIGNAL COUNT_READ: std_logic_vector(8 downto 0);



signal STOPAD    :STD_LOGIC;
signal RESET_ADDR :STD_LOGIC;
--SIGNAL IN_LD:STD_LOGIC_VECTOR(31 DOWNTO 0);

signal REFRESHTIME:STD_LOGIC_VECTOR(3 DOWNTO 0);



--SIGNAL DATADELAY:STD_LOGIC_VECTOR(5 DOWNTO 0);
--------------------------------------------------------------
SIGNAL ADDR_FULL_reg : STD_LOGIC;

------------------------------------------------------------------------
begin


ADDR_FULL <=ADDR_FULL_reg;

PROCESS(RESET,CLK)
BEGIN
  IF RESET='0' THEN
     PresentState<=IDLE;
 ELSIF clk='1' and clk'event then
      case cbe is
  when "001" =>
     PresentState<=IDLE;    ---The PresentState Logic should be improved with more functions
  when "010" =>
     PresentState<=SAVE_DATA;
  when "100" =>
     PresentState<=READ_DATA;
  when others =>
     PresentState<=IDLE;
  end case;
 end if;
END PROCESS;


------------------------------------------------------------------------
PROCESS(CLK,reset)
BEGIN
  IF RESET='0' THEN
      COUNT_INI<=(OTHERS=>'0');
  elsif CLK = '1' AND CLK'EVENT THEN
    IF INISTATE = NOP OR INISTATE=INI_REFRESH  THEN
       COUNT_INI <= (OTHERS=>'0');--0;
    ELSE
       COUNT_INI <= COUNT_INI + 1;
    END IF;
  END IF;
END PROCESS;

PROCESS(CLK,RESET)---------------  initialize SDRAM
BEGIN
  IF RESET = '0' THEN
     INISTATE <= NOP;
     REFRESHTIME<="0000";
     FLAG<='0';
  ELSIF CLK = '1' AND CLK'EVENT THEN
      CASE INISTATE IS
        WHEN NOP =>
          IF FLAG = '0' THEN  
             INISTATE <= INI_PRECHARGE;
             FLAG<='1';
          END IF;
        WHEN INI_PRECHARGE =>
          IF CMDACK = '1' THEN
             INISTATE <= INI_PRECHARGE_NOP;
          END IF;
        WHEN INI_PRECHARGE_NOP =>
          IF COUNT_INI = 70 THEN
             INISTATE <= INI_REFRESH;
          END IF;
        WHEN INI_REFRESH =>
          IF CMDACK = '1'  THEN
             REFRESHTIME<=REFRESHTIME+1;
             INISTATE <= INI_REFRESH_NOP;
          END IF;
        WHEN INI_REFRESH_NOP =>
          IF COUNT_INI=5 THEN
                IF REFRESHTIME="1000" THEN
                      INISTATE <= LOADMODE;
                ELSE
                     INISTATE<=INI_REFRESH;
                END IF;
           END IF;
        WHEN LOADMODE =>
          IF CMDACK = '1' THEN
             INISTATE <= LOADMODE_NOP;
          END IF;
        WHEN LOADMODE_NOP =>
          IF COUNT_INI = 90 THEN
             INISTATE <= LOADREG2;
          END IF;
        WHEN LOADREG2 =>
          IF CMDACK = '1' THEN
             INISTATE <= LOADREG2_NOP;
          END IF;
        WHEN LOADREG2_NOP =>
          IF COUNT_INI = 110 THEN
             INISTATE <= LOADREG1;
          END IF;
        WHEN LOADREG1 =>
          IF CMDACK = '1' THEN
             INISTATE <= LOADREG1_NOP;
          END IF;
        WHEN LOADREG1_NOP =>
          IF COUNT_INI = 130 THEN
             INISTATE <= NOP;
          END IF;
        WHEN OTHERS =>
             INISTATE <= NOP;
      END CASE;
  END IF;
END PROCESS;
-------------------------------------------------------------


PROCESS(CLK)
BEGIN
  
  IF CLK = '1' AND CLK'EVENT THEN

      IF WRITESTATE = WRITE_IDLE  OR WRITESTATE = WRITE_PRE OR WRITESTATE = WRITE_REFRESH OR WRITESTATE = WRITEA OR WRITESTATE =WRITE_TERMINATE THEN  
        COUNT_DATA <= (others=>'0');
      ELSE
        COUNT_DATA <= COUNT_DATA + 1;
      END IF;

  END IF;
end process;



PROCESS(RESET,CLK)------------------WRITE SDRAM
BEGIN
 
 IF RESET='0' THEN
     WRITESTATE <= WRITE_IDLE;
  ELSIF CLK = '1' AND CLK'EVENT THEN
      IF PRESENTSTATE = save_data THEN  
       CASE WRITESTATE IS
        WHEN WRITE_IDLE =>
            WRITESTATE <= WRITE_PRE;
        WHEN WRITE_PRE =>
          IF CMDACK = '1' THEN   
            WRITESTATE <= WRITE_PRE_NOP;
          END IF;
        WHEN WRITE_PRE_NOP =>
            IF COUNT_DATA=20 THEN
            WRITESTATE<= WRITE_REFRESH;
            END IF;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -