![]() |
|
||||||||||||||
| . 网站首页 . 新闻 . 新品 . 方案 . 专访 . 活动 . DSP . EDA . 评测室 . 技术文库 . 会员区 . 商城 . 服务导航 . 邮购 . 资源 . | ||
|
||
|
|||||
| 一个很快且不用状态机的动态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" 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" 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" constant WORKING_RFRS_CODE : std_logic_vector(working_shift_len-1 downto 0) := "00"&X" 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" 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" 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条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|