-- https://fpga4u.epfl.ch/wiki/FPGA4U_Description
-- The SDRAM is an ISSI IS42S32800B. With bits data bus, validated by SDRAM_DQM<..> signals,
-- one for each Byte of data bus SDRAM_DQ<..>.
-- This memory is a synchronous SDRAM, validating address and control signals with the rising edge of SDRAM_CLK,
-- while SDRAM_CKE activated (''). The organisation is banks selected by SDRAM_BA<..>.
-- Each bank as ^ Row and ^ Column selected by SDRAM_AD<11.0>, with bits words
-- (SDRAM_DQ<..> (^ * ^ * ^ = * 2M x = 8Mx32 = 32MBytes).
-- In SOPC Builder, with the SDRAM Controller, select:
-- Banks
-- Rows addresses lines
-- Columns addresses lines library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; entity fpga4u_sdram_controller is
port(
--Avalon slave interface (pipelined, variable latency)
signal clk, reset : in std_logic;
signal as_address : in std_logic_vector( downto );
signal as_read, as_write : in std_logic;
signal as_byteenable : in std_logic_vector( downto );
signal as_readdata : out std_logic_vector( downto );
signal as_writedata : in std_logic_vector( downto );
signal as_waitrequest : out std_logic;
signal as_readdatavalid : out std_logic; --SDRAM interface to FPGA4U SDRAM
signal ram_addr : out std_logic_vector( downto );
signal ram_ba : out std_logic_vector( downto );
signal ram_cas_n : out std_logic;
signal ram_cke : out std_logic;
signal ram_cs_n : out std_logic;
signal ram_dq : inout std_logic_vector( downto );
signal ram_dqm : out std_logic_vector( downto );
signal ram_ras_n : out std_logic;
signal ram_we_n : out std_logic
);
end entity; architecture arch of fpga4u_sdram_controller is
--Initialisation signals
type init_state_t is (init_reset, init_pre, init_wait_pre, init_ref, init_wait_ref, init_mode, init_wait_mode, init_done);
signal init_state : init_state_t := init_reset;
signal init_wait_counter : unsigned( downto );
signal init_ref_counter : unsigned( downto ); --Main state machine
type state_t is (idle, ref, wait_ref, act, wait_act, read, spin_read, write, spin_write, precharge_all, wait_precharge);
signal state : state_t := idle;
signal ref_counter : unsigned( downto );
signal ref_req : std_logic;
signal wait_counter : unsigned( downto ); --Active transaction signals
signal int_address : std_logic_vector( downto );
signal int_readdata : std_logic_vector( downto );
signal int_writedata : std_logic_vector( downto );
signal int_byteenable : std_logic_vector( downto );
signal int_writeop : std_logic; --open bank and row
signal open_bank : std_logic_vector( downto );
signal open_row : std_logic_vector( downto ); --readdata ready pipeline
signal readdata_ready : std_logic_vector( downto ); signal ram_cmd : std_logic_vector( downto );
begin
--State machine to handle SDRAM initialization
INITSTATE : process(clk, reset)
begin
if reset = '' then
init_state <= init_reset;
--power up delay
init_wait_counter <= to_unsigned(,init_wait_counter'length);
--number refresh cycles before mode register write
init_ref_counter <= to_unsigned(,init_ref_counter'length);
elsif rising_edge(clk) then
--count down when not
if init_wait_counter /= then
init_wait_counter <= init_wait_counter - ;
end if;
case init_state is
when init_reset =>
if init_wait_counter = then
init_state <= init_pre;
end if;
--do a precharge
when init_pre =>
init_wait_counter <= to_unsigned(,init_wait_counter'length);
init_state <= init_wait_pre;
when init_wait_pre =>
if init_wait_counter = then
init_state <= init_ref;
end if;
--do a refresh
when init_ref =>
init_wait_counter <= to_unsigned(,init_wait_counter'length);
init_ref_counter <= init_ref_counter - ;
init_state <= init_wait_ref;
when init_wait_ref =>
if init_wait_counter = then
if init_ref_counter = then
init_state <= init_mode;
else
init_state <= init_ref;
end if;
end if;
--set the mode register
when init_mode =>
init_wait_counter <= to_unsigned(,init_wait_counter'length);
init_state <= init_wait_mode;
when init_wait_mode =>
if init_wait_counter = then
init_state <= init_done;
end if;
when others =>
null;
end case;
end if;
end process; --Asynchronous waitrequest to allow one transfer per cycle (critical path)
as_waitrequest <= '' when (state = idle and ref_req = '' and (as_read = '' or as_write = ''))
or ((state = read or state = spin_read) and ref_req = '' and as_read = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank)
or ((state = write or state = spin_write) and ref_req = '' and as_write = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank)
else ''; --Main state machine
make_state : process(clk, reset)
begin
if reset = '' then
state <= idle;
ref_counter <= (others=>'');
ref_req <= ''; --begin with a refresh
wait_counter <= (others=>'');
readdata_ready <= (others=>'');
elsif rising_edge(clk) then
--counters for delays and refresh generation
if wait_counter /= then
wait_counter <= wait_counter - ;
end if;
if ref_counter /= then
ref_counter <= ref_counter - ;
else
ref_req <= '';
ref_counter <= to_unsigned(,ref_counter'length);
end if;
--main state machine runs when the initialization is done
if init_state = init_done then
case state is
when idle =>
if ref_req = '' then --go do a refresh
ref_req <= '';
state <= ref;
elsif as_write = '' or as_read = '' then --accept the request and go to open the row
int_address <= as_address;
int_writedata <= as_writedata;
int_byteenable <= as_byteenable;
int_writeop <= as_write;
state <= act;
end if;
when ref =>
wait_counter <= to_unsigned(,wait_counter'length);
state <= wait_ref;
when wait_ref =>
if wait_counter = then
state <= idle;
end if;
when act => --save the open bank and row
open_bank <= int_address( downto );
open_row <= int_address( downto );
wait_counter <= to_unsigned(,wait_counter'length);
state <= wait_act;
when wait_act =>
if wait_counter = then
if int_writeop = '' then
state <= read;
else
state <= write;
end if;
end if;
when read => --issue a read command, feed a one in the readdata_ready pipeline, when it exits data is ready for the master
as_readdata <= int_readdata;
as_readdatavalid <= readdata_ready();
readdata_ready <= readdata_ready( downto )&'';
if ref_req = '' and as_read = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank then
int_address <= as_address;
state <= read;
else
state <= spin_read;
end if;
when spin_read => --wait for reads to complete and eventually issue more compatible reads
as_readdata <= int_readdata;
as_readdatavalid <= readdata_ready();
readdata_ready <= readdata_ready( downto )&'';
if readdata_ready = "" and (ref_req = '' or as_write = '') then
state <= precharge_all;
elsif ref_req = '' and as_read = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank then
int_address <= as_address;
state <= read;
elsif readdata_ready = "" and as_read = '' then
state <= precharge_all;
end if;
when write => --the same as read, except there is no pipeline as data is presented to the SDRAM on the same cycle as the command
wait_counter <= to_unsigned(,wait_counter'length);
if ref_req = '' and as_write = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank then
int_address <= as_address;
int_writedata <= as_writedata;
int_byteenable <= as_byteenable;
state <= write;
else
state <= spin_write;
end if;
when spin_write => --same as for read
if wait_counter = and (ref_req = '' or as_read = '') then
state <= precharge_all;
elsif ref_req = '' and as_write = '' and as_address( downto ) = open_row and as_address( downto ) = open_bank then
int_address <= as_address;
int_writedata <= as_writedata;
int_byteenable <= as_byteenable;
state <= write;
elsif wait_counter = and as_write = '' then
state <= precharge_all;
end if;
when precharge_all =>
state <= wait_precharge;
when wait_precharge =>
state <= idle;
when others=>
null;
end case;
end if;
end if;
end process; --data from the ram needs to be sampled on the falling edge of the controller clock for proper operation
process(clk)
begin
if falling_edge(clk) then
int_readdata <= ram_dq;
end if;
end process; --process generating the command sequence for the SDRAM
ram_cke <= '';
ram_cs_n <= ram_cmd();
ram_ras_n <= ram_cmd();
ram_cas_n <= ram_cmd();
ram_we_n <= ram_cmd();
OUTPUTS : process(clk, reset)
begin
if reset = '' then
ram_addr <= (others=>'');
ram_cmd <= "";
ram_ba <= (others=>'');
ram_dq <= (others=>'Z');
ram_dqm <= (others=>'');
elsif rising_edge(clk) then
if init_state = init_pre then
ram_cmd <= ""; --precharge
ram_addr <= (=>'', others=>'');
elsif init_state = init_ref then
ram_cmd <= ""; --refresh
elsif init_state = init_mode then
ram_cmd <= ""; --mode set
ram_addr <= ""; --no burst, three cycles latency
elsif init_state = init_done then
if state = ref then
ram_cmd <= ""; --refresh
elsif state = act then
ram_cmd <= ""; --activate
ram_addr <= int_address( downto );
ram_ba <= int_address( downto );
elsif state = read then
ram_cmd <= ""; --read
ram_addr <= ""&int_address( downto );
ram_dqm <= "";
elsif state = write then
ram_cmd <= ""; --write
ram_addr <= ""&int_address( downto );
ram_dq <= int_writedata;
ram_dqm <= not int_byteenable;
elsif state = precharge_all then
ram_cmd <= ""; --precharge
ram_addr <= ""&int_address( downto );
ram_dqm <= "";
else
ram_cmd <= ""; --nop
ram_dq <= (others=>'Z');
end if;
else
ram_cmd <= ""; --nop
end if;
end if;
end process;
end arch;

最新文章

  1. 配置ASP.NET Web应用程序, 使之运行在medium trust
  2. linux中快速清空文件内容的几种方法
  3. DBA日常工作内容和职责
  4. 电子词典的相关子函数db.c程序
  5. WPF小记——DockPanel使用不当引起界面显示问题
  6. PHP PC端接入支付宝和微信感悟
  7. EF中限制字段显示长度
  8. ServiceStack.Redis常用操作 - 事务、并发锁
  9. 关于QuartusII对ram块的综合
  10. 编写可维护的Javascript读书笔记
  11. 【Unity3D】Unity3D开发《我的世界》之一、创建一个面
  12. git branch 分支
  13. Django学习之二:Django 项目创建 和 应用创建
  14. servlet 会话技术
  15. 01++ Bookshelf 2
  16. 吴裕雄 20-MySQL NULL 值处理
  17. oracle dba
  18. ie浏览器总跳转到 http://hao.360.cn
  19. How to convert int [12] to array&lt;int, 12&gt;
  20. PTA (Advanced Level) 1021 Deepest Root

热门文章

  1. final review 报告
  2. 可拖拽的ListView
  3. 使用scala开发spark入门总结
  4. XAF How to show custom forms and controls in XAF (Example)
  5. DevExpress 13.1.8全面支持VS2013
  6. Collections的应用
  7. Nginx下Magento伪静态规则,适用于LNMP一键包
  8. 用tcc遇到的一个大坑
  9. MySQL日期时间函数大全
  10. background-clip
  11. vs2015启动iis express失败
  12. XMLHttpRequest函数封装
  13. SDL 2.0 如何在 windows 上使用?
  14. bzoj5251 [2018多省省队联测]劈配
  15. servelet基础
  16. Python系列之环境安装
  17. 坑人的 Javascript 模块化编程 require.js
  18. vim上次和下次光标位置
  19. 跟我学SharePoint 2013视频培训课程—— 审批、拒绝列表项(13)
  20. Is it possible to create @Around Aspect for feign.Client