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

📄 sm.vhd

📁 SDRAM控制器,对SDRAM进行页写和对SDRAM进行页读的快速读写。是一个很好的SDRAM控制器
💻 VHD
字号:
-- --------------------------------------------------------------------
-- >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
-- --------------------------------------------------------------------
-- Copyright (c) 2001 by Lattice Semiconductor Corporation
-- --------------------------------------------------------------------
--
-- Permission:
--
--   Lattice Semiconductor grants permission to use this code for use
--   in synthesis for any Lattice programmable logic product.  Other
--   use of this code, including the selling or duplication of any
--   portion is strictly prohibited.
--
-- Disclaimer:
--
--   This VHDL or Verilog source code is intended as a design reference
--   which illustrates how these types of functions can be implemented.
--   It is the user's responsibility to verify their design for
--   consistency and functionality through the use of formal
--   verification methods.  Lattice Semiconductor provides no warranty
--   regarding the use or functionality of this code.
--
-- --------------------------------------------------------------------
--           
--                     Lattice Semiconductor Corporation
--                     5555 NE Moore Court
--                     Hillsboro, OR 97214
--                     U.S.A
--
--                     TEL: 1-800-Lattice (USA and Canada)
--                          408-826-6000 (other locations)
--
--                     web: http://www.latticesemi.com/
--                     email: techsupport@latticesemi.com
--
-- --------------------------------------------------------------------
--
-- This is the state machine module of the FPM DRAM controller reference
-- design.
--
-- --------------------------------------------------------------------
--
-- --------------------------------------------------------------------
--
-- Revision History :
-- --------------------------------------------------------------------
--   Ver  :| Author            :| Mod. Date :| Changes Made:
--   V1.0 :| K.L.              :| 09/16/98  :| Pre-Release
--   V2.0 :| J.R.              :| 12/17/01  :| Converted to VHDL
-- --------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity sm is port(
  clk             : in    std_logic;      -- Processor clock
  dramsel         : in    std_logic;      -- DRAM access in process when asserted
  resetb          : in    std_logic;      -- Reset signal
  page_hit        : in    std_logic;      -- Indicates page mode cycles requested
  bnk1,bnk2       : in    std_logic;      -- Indicates which DRAM bank is addressed
  upd, lod        : in    std_logic;      -- Byte lane decodes
  rwb             : in    std_logic;      -- Processor Read/Write signal
  ras1,ras2       : out   std_logic;      -- DRAM RAS signals
  ucas,lcas       : out   std_logic;      -- DRAM CAS signals
  we              : out   std_logic;      -- DRAM write enable signal
  dsack1          : out   std_logic;      -- Data size/ack signals to CPU
  dsack0          : out   std_logic);
end sm;

architecture behavioral of sm is

-- Asynchronous versions of outputs to be synchronized to clk in the "sync_ctl" process
signal  ras1a, ras2a     : std_logic;
signal  ucasa, lcasa     : std_logic;
signal  dsack1a, dsack0a : std_logic;
signal  wea, refacka     : std_logic;

-- Other internal signals
signal  refreq          : std_logic;                    -- Refresh Request
signal  tc              : std_logic;                    -- Refresh counter terminal count signal
signal  q               : std_logic_vector(8 downto 0); -- The refresh counter
signal  pras1, pras2    : std_logic;                    -- Page mode RAS signals, used to hold
                                                        -- the RASx signal active between accesses
signal  refack          : std_logic;
signal  ps, ns          : std_logic_vector(3 downto 0);
--state declarations
constant idle   : std_logic_vector(3 downto 0) := "0000";
constant rw1    : std_logic_vector(3 downto 0) := "0001";
constant rw2    : std_logic_vector(3 downto 0) := "0011";
constant rw3    : std_logic_vector(3 downto 0) := "0010";
constant cbr1   : std_logic_vector(3 downto 0) := "0111";
constant cbr2   : std_logic_vector(3 downto 0) := "0101";
constant cbr3   : std_logic_vector(3 downto 0) := "0100";
constant cbr4   : std_logic_vector(3 downto 0) := "1000";
constant prechg : std_logic_vector(3 downto 0) := "1001";
constant page1  : std_logic_vector(3 downto 0) := "1011";
constant page2  : std_logic_vector(3 downto 0) := "1010";
constant page3  : std_logic_vector(3 downto 0) := "1110";
constant dummy1 : std_logic_vector(3 downto 0) := "1111";
constant dummy2 : std_logic_vector(3 downto 0) := "1101";
constant dummy3 : std_logic_vector(3 downto 0) := "1100";
constant dummy4 : std_logic_vector(3 downto 0) := "0110";

begin

-- The DRAM controller state machine is implemented as a two-process FSM.
-- The first process is the asynchronous one that determines the next state
-- based upon current state and other inputs.  Internal control signal levels
-- are also set in this process.
-- The second process is a small synchronous process that synchronizes the
-- state transitions and control signal outputs to the system clock.

---------------------------------------
------ Asynchronous process -----------
---------------------------------------

        
as_cont: process (dramsel, page_hit, refreq, ps, bnk1, bnk2, upd, lod, rwb, pras1, pras2)
begin

case ps is
  when idle =>
    ucasa   <= '1';
    lcasa   <= '1';
    dsack0a <= '1';
    refacka <= '0';
    wea     <= rwb;
    if (refreq = '1') then 
      ns      <= cbr1;         -- do a refresh cycle
      wea     <= '1';
      dsack1a <= '1';
      ras1a   <= '1';
      ras2a   <= '1';
    elsif (dramsel = '1') then 
      ns      <= rw1;          -- do a normal read/write cycle
      wea     <= rwb;
      dsack1a <= '0';
      ras1a   <= not bnk1;
      ras2a   <= not bnk2;
    else 
      ns      <= idle;
      wea     <= '1';
      dsack1a <= '1';
      ras1a   <= not bnk1;
      ras2a   <= not bnk2;
    end if;

  when rw1 =>                  --dram access start
    ras1a   <= not bnk1;
    ras2a   <= not bnk2;
    ucasa   <= not upd;
    lcasa   <= not lod;
    dsack1a <= '1';            --signal termination after one wait state
    dsack0a <= '1';
    refacka <= '0';
    wea     <= rwb;
    ns      <= rw2;

  when rw2 =>                  --dsackx sampled at start of this state
    ras1a   <= not bnk1;
    ras2a   <= not bnk2;
    ucasa   <= '1';
    lcasa   <= '1';
    dsack1a <= '1';
    dsack0a <= '1';
    refacka <= '0';
    wea     <= rwb;
    ns      <= rw3;

  when rw3 =>                  -- Read data sampled at start of this state
    ucasa   <= '1';            -- Write data written to DRAM on rising edge
    lcasa   <= '1';            -- of CAS.
    dsack0a <= '1';
    refacka <= '0';
    if (page_hit = '1') then
      ns      <= page1;        --goto page mode access
      dsack1a <= '0';
      ras1a   <= pras1;
      ras2a   <= pras2;
      wea     <= rwb;
    else
      ns <= prechg;            --goto dram access ready mode
      dsack1a <= '1';
      ras1a   <= '1';
      ras2a   <= '1';
      wea     <= '1';
    end if;

  when page1 =>
    ras1a    <= pras1;
    ras2a    <= pras2;
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= rwb;
    if (dramsel = '1') then
      ns <= page2;
      ucasa    <= not upd;
      lcasa    <= not lod;     --data access in page mode
      dsack1a  <= '1';         --page mode use asynchronous dsack 
    else
      ns <= page1;
      ucasa    <= '1';
      lcasa    <= '1';
      dsack1a  <= '0';         --page mode use asynchronous dsack 
    end if;

  when page2=>
    ras1a    <= pras1;
    ras2a    <= pras2;
    ucasa    <= '1';
    lcasa    <= '1';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= rwb;
    ns       <= page3;

  when page3 =>

    ucasa    <= '1';
    lcasa    <= '1';           --casb precharge
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= rwb;
    if (page_hit = '1') then
      ns       <= page1;       --goto page1 state
      dsack1a  <= '0';
      ras1a    <= pras1;
      ras2a    <= pras2;
    else 
      ns <= prechg;            --goto precharge state
      dsack1a  <= '1';
      ras1a    <= '1';
      ras2a    <= '1';
    end if;         

  when cbr1 =>                 --cbr(casb before rasb refresh) mode start
    ras1a    <= '1';
    ras2a    <= '1';
    ucasa    <= '0';           --cas starts for refresh
    lcasa    <= '0';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '1';           --refresh request register clear
    wea      <= '1';           --refresh mode
    ns       <= cbr2;

  when cbr2 =>
    ras1a    <= '0';           --ras follows next
    ras2a    <= '0';
    ucasa    <= '0';
    lcasa    <= '0';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= '1';
    ns       <= cbr3;

  when cbr3 =>
    ras1a    <= '0';
    ras2a    <= '0';
    ucasa    <= '1';           -- deassert cas
    lcasa    <= '1';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= '1';
    ns       <= cbr4;

  when cbr4 =>
    ras1a    <= '1';           -- deassert ras
    ras2a    <= '1';
    ucasa    <= '1';
    lcasa    <= '1';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= '1';
    ns       <= prechg;

  when prechg =>
    ras1a    <= '1';
    ras2a    <= '1';
    ucasa    <= '1';
    lcasa    <= '1';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= '1';
    ns       <= idle;
  when others =>
    ras1a    <= '1';
    ras2a    <= '1';
    ucasa    <= '1';
    lcasa    <= '1';
    dsack1a  <= '1';
    dsack0a  <= '1';
    refacka  <= '0';
    wea      <= rwb;
    ns       <= idle;
end case;
end process;

---------------------------------------------
-------- Synchronous Process  ---------------
---------------------------------------------
sync_ctl: process (clk, resetb)            -- This is the synchronous process that controlls
begin                                      -- the DRAM state machine.
  if(resetb = '0') then
    ps      <= idle;
    ras1    <= '1';
    ras2    <= '1';
    ucas    <= '1';
    lcas    <= '1';
    dsack1  <= '1';
    dsack0  <= '1';
    we      <= '1';
    refack  <= '0';
  elsif(clk'event and clk = '0') then      -- state machine clocked on falling edge
    ps <= ns;                              -- update the state machine state
    ras1    <= ras1a;                      -- and assert the synchronous outputs
    ras2    <= ras2a;
    ucas    <= ucasa;
    lcas    <= lcasa;
    dsack1  <= dsack1a;
    dsack0  <= dsack0a;
    we      <= wea;
    refack  <= refacka;
  end if;
end process;

---------------------------------------
----    refresh counter 
----    9bits 15.6us interval
---------------------------------------

rfcnt: process(clk, refack, resetb)
begin
  if (resetb = '0') then
    q <= "000000000";
  elsif (clk'event and clk = '0') then
    if(refack = '1') then
      q <= "000000000";
    else
      q <= q + 1;
    end if;
  end if;
end process;

-- 186hex = 110000110 binary = 390 decimal
-- assuming 25 MHz clock (40ns clock period)
-- 40ns (tCYC) x 390 = 15.6us is the refresh request rate.

tc <=   '1' when q = "110000110" else
        '0';

rreq: process (clk, tc, refack, resetb)
begin
  if (resetb = '0') then
     refreq <= '0';
  elsif(clk'event and clk = '0') then
    if refack = '1' then
      refreq <= '0';
    elsif tc = '1' then                    -- assert refreq when the terminal count (tc) is reached
      refreq <= '1';
    end if;
  end if;
end process;

-- The PRASx signals are used to maintain the RASOx outputs
-- between the actual CPU accesses of a page mode access.
pras: process (clk, resetb)
begin
  if (resetb = '0') then
    pras1 <= '1';
    pras2 <= '1';
  elsif (clk'event and clk = '0') then
    if ((ps = rw1) or (ps = page2)) then
      pras1 <= not bnk1;
      pras2 <= not bnk2;
    end if;
  end if;
end process;

end behavioral;

⌨️ 快捷键说明

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