网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> EDA >> HDL >> 文章正文
  一个很快且不用状态机的动态RAM接口           ★★★ 【字体:
一个很快且不用状态机的动态RAM接口
作者:Free    文章来源:Free    点击数:    更新时间:2007-12-30    

动态RAM速度快容量大,被广泛应用,但接口比SRAM复杂.

最近在一个设计中用到SDRAM通过看资料和反复修改

 

基本思路是:

  SDRAM的接口需要许多命令,若用状态机实现则需要至少十多个状态

所以占资源多,且速度慢。若改用先把命令装入移位寄存器然后再一个一个移出到

命令控制引脚,则时间延迟小逻辑简单。在读写等操作前先把操作时序波形存入移位寄存器

然后启动移位寄存器开始移位,产生所需操作时序。

 

次接口已在实际中应用,速度100兆,运行稳定

 

以下是源代码

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

 

--if In simulation mode Uncomment

--library UNISIM;

--use UNISIM.VCOMPONENTS.ALL;

--else IN Synthesize mode comment

 

entity controled_pipe is

    port(

        Clk : In std_logic;

        rst : In std_logic;

        sd_initialized : In std_logic;

        write : In std_logic;

        read : In std_logic;

        refr : In std_logic;

        pre : In std_logic;

        lmr : In std_logic;

        rfrs : In std_logic;

        ras_shift : out std_logic;

        cas_shift : out std_logic;

        ras_le : out std_logic;

        cas_le : out std_logic;

        we_shift : out std_logic;

        wr_dat : out std_logic;

        wr_tri : out std_logic;

        rd_dat : out std_logic;

        write_flag : out std_logic;

        working : out std_logic

    );

 

end entity;

 

architecture arch_controled_pipe of controled_pipe is

 

constant rcw_shift_len : integer := 4;

constant rc_le_len : integer := 3;

 

constant rd_dat_shift_len : integer := 14;

constant wt_shift_len : integer := 12;

constant working_shift_len : integer := 14;

 

signal ras_code : std_logic_vector(rcw_shift_len-1 downto 0);

signal cas_code : std_logic_vector(rcw_shift_len-1 downto 0);

signal ras_le_code : std_logic_vector(rc_le_len-1 downto 0);

signal cas_le_code : std_logic_vector(rc_le_len-1 downto 0);

 

signal working_code : std_logic_vector(working_shift_len-1 downto 0);

signal we_code : std_logic_vector(rcw_shift_len-1 downto 0);

signal wr_tri_code : std_logic_vector(wt_shift_len-1 downto 0);

signal wr_dat_code : std_logic_vector(wt_shift_len-1 downto 0);

 

signal rd_data_code : std_logic_vector(rd_dat_shift_len-1 downto 0);

 

signal trig_en : std_logic;

 

signal ras_shift_reg : std_logic_vector(rcw_shift_len-1 downto 0);

signal cas_shift_reg : std_logic_vector(rcw_shift_len-1 downto 0);

signal we_shift_reg : std_logic_vector(rcw_shift_len-1 downto 0);

signal working_shift_reg : std_logic_vector(working_shift_len-1 downto 0);

signal ras_addr_le : std_logic_vector(rc_le_len-1 downto 0);

signal cas_addr_le : std_logic_vector(rc_le_len-1 downto 0);

signal wr_tri_reg : std_logic_vector(wt_shift_len-1 downto 0);

signal wr_dat_reg : std_logic_vector(wt_shift_len-1 downto 0);

signal rd_dat_reg : std_logic_vector(rd_dat_shift_len-1 downto 0);

 

signal ld_1 : std_logic;

signal ld_2 : std_logic;

 

begin

 

process(Clk,rst)

 

variable internal_write : std_logic;

 

begin

    if rst = '1' then

        ld_1 <='0';

        ld_2 <='0';

        internal_write := '0';

        working_shift_reg <= (others => '1');

        ras_shift_reg <= (others => '1');

        cas_shift_reg <= (others => '1');

        ras_addr_le <= (others => '0');

        cas_addr_le <= (others => '0');

        we_shift_reg <= (others => '1');

        wr_dat_reg <= (others => '0');

        wr_tri_reg <= (others => '1');

        rd_dat_reg <= (others => '0');

    elsif rising_edge(Clk) then

        if working_shift_reg(working_shift_len-2) = '1' and working_shift_reg(working_shift_len-1) = '0' then

            ld_1 <= '0';

            ld_2 <= '0';

        end if;

        if trig_en = '1' and ld_1 = '0' then

            ld_1 <= '1';

            working_shift_reg <= working_code;

            ras_shift_reg <= ras_code;

            cas_shift_reg <= cas_code;

            ras_addr_le <= ras_le_code;

            cas_addr_le <= cas_le_code;

            we_shift_reg <= we_code;

            wr_dat_reg <= wr_dat_code;

            wr_tri_reg <= wr_tri_code;

            rd_dat_reg <= rd_data_code;

        elsif trig_en = '1' and ld_2 = '0' then

            ld_2 <= '1';

            working_shift_reg <= working_code;

            ras_shift_reg <= ras_code;

            cas_shift_reg <= cas_code;

            ras_addr_le <= ras_le_code;

            cas_addr_le <= cas_le_code;

            we_shift_reg <= we_code;

            wr_dat_reg <= wr_dat_code;

            wr_tri_reg <= wr_tri_code;

            rd_dat_reg <= rd_data_code;

           if write = '1' then

               internal_write := '1';

           elsif read = '1' then

               internal_write := '0';

           end if;   

        elsif ld_1 = '1' and ld_2 = '1' then

            working_shift_reg <= working_shift_reg(working_shift_len-2 downto 0)&'1';

            ras_shift_reg <= ras_shift_reg(rcw_shift_len-2 downto 0)&'1';

            cas_shift_reg <= cas_shift_reg(rcw_shift_len-2 downto 0)&'1';

            ras_addr_le <= ras_addr_le(rc_le_len-2 downto 0)&'0';

            cas_addr_le <= cas_addr_le(rc_le_len-2 downto 0)&'0';

            we_shift_reg <= we_shift_reg(rcw_shift_len-2 downto 0)&'1';

            wr_dat_reg <= wr_dat_reg(wt_shift_len-2 downto 0)&'0';

            wr_tri_reg <= wr_tri_reg(wt_shift_len-2 downto 0)&'1';

            rd_dat_reg <= rd_dat_reg(rd_dat_shift_len-2 downto 0)&'0';

        end if;

    end if;

    working <= working_shift_reg(working_shift_len-1);

    ras_shift <= ras_shift_reg(rcw_shift_len-1);

    cas_shift <= cas_shift_reg(rcw_shift_len-1);

    we_shift <= we_shift_reg(rcw_shift_len-1);

    ras_le <= ras_addr_le(rc_le_len-1);

    cas_le <= cas_addr_le(rc_le_len-1);

    wr_dat <= wr_dat_reg(wt_shift_len-1);

    wr_tri <= wr_tri_reg(wt_shift_len-1);

    write_flag <= internal_write;

    rd_dat <= rd_dat_reg(rd_dat_shift_len-1);

end process;

 

process(sd_initialized,write,read,refr,pre,lmr,rfrs)

 

constant RAS_LE_CMD_CODE : std_logic_vector(rc_le_len-1 downto 0) := "100";

constant CAS_LE_CMD_CODE : std_logic_vector(rc_le_len-1 downto 0) := "001";

 

constant WORKING_REF_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"07f";

constant RAS_REF_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1010";

constant CAS_REF_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1110";

constant WE_REF_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

 

constant WORKING_WR_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"003";

constant RAS_WR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant CAS_WR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1110";

constant WE_WR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1110";

constant DAT_WR_CODE : std_logic_vector(wt_shift_len-1 downto 0) := X"7f8";

constant TRI_WR_CODE : std_logic_vector(wt_shift_len-1 downto 0) := X"c01";

 

constant WORKING_RD_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"001";

constant RAS_RD_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant CAS_RD_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1110";

constant WE_RD_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1111";

constant DAT_RD_CODE : std_logic_vector(rd_dat_shift_len-1 downto 0) := X"03f"&"11";

 

constant WORKING_RFRS_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"03f";

constant RAS_RFRS_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant CAS_RFRS_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant WE_RFRS_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1111";

 

constant WORKING_PRE_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"03f";

constant RAS_PRE_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant CAS_PRE_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1111";

constant WE_PRE_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

 

constant WORKING_LMR_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X"03f";

constant RAS_LMR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant CAS_LMR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

constant WE_LMR_CODE : std_logic_vector(rcw_shift_len-1 downto 0) := "1011";

 

begin

   ras_le_code <= (others => '0');

   cas_le_code <= (others => '0');

    wr_dat_code <= (others => '0');

    wr_tri_code <= (others => '1');

    rd_data_code <= (others => '0');

    if  rfrs = '1' then

            working_code <= WORKING_RFRS_CODE;

            ras_code <= RAS_RFRS_CODE;

            cas_code <= CAS_RFRS_CODE;

            we_code <= WE_RFRS_CODE;

    elsif  pre = '1' then

            working_code <= WORKING_PRE_CODE;

            ras_code <= RAS_PRE_CODE;

            cas_code <= CAS_PRE_CODE;

            we_code <= WE_PRE_CODE;

            ras_le_code <= RAS_LE_CMD_CODE;

    elsif  lmr = '1' then

            working_code <= WORKING_LMR_CODE;

            ras_code <= RAS_LMR_CODE;

            cas_code <= CAS_LMR_CODE;

            we_code <= WE_LMR_CODE;

            ras_le_code <= RAS_LE_CMD_CODE;

    elsif  refr = '1' then

            working_code <= WORKING_REF_CODE;

            ras_code <= RAS_REF_CODE;

            cas_code <= CAS_REF_CODE;

            we_code <= WE_REF_CODE;

    elsif  write = '1' then

            working_code <= WORKING_WR_CODE;

            ras_code <= RAS_WR_CODE;

            cas_code <= CAS_WR_CODE;

            we_code <= WE_WR_CODE;

            ras_le_code <= RAS_LE_CMD_CODE;

            cas_le_code <= CAS_LE_CMD_CODE;

            wr_dat_code <= DAT_WR_CODE;

            wr_tri_code <= TRI_WR_CODE;

    elsif  read = '1' then

            working_code <= WORKING_RD_CODE;

            ras_code <= RAS_RD_CODE;

            cas_code <= CAS_RD_CODE;

            we_code <= WE_RD_CODE;

            ras_le_code <= RAS_LE_CMD_CODE;

            cas_le_code <= CAS_LE_CMD_CODE;

            rd_data_code <= DAT_RD_CODE;

    else

            working_code <= (others => '1');

            ras_code <= (others => '1');

            cas_code <= (others => '1');

            we_code <= (others => '1');

            ras_le_code <= (others => '0');

            cas_le_code <= (others => '0');

            rd_data_code <= (others => '0');

    end if;

    if sd_initialized = '1' then

       trig_en <=  write or read or refr;

    else  

       trig_en <=  rfrs or lmr or pre;

    end if;

end process;

 

end architecture;

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号