SDRAM读写一字

系统设计

SDRAM指令

指令

常量名

CKE

CSn

RAS

CASn

WEn

备注

空操作

NOP

1

0

1

1

1

 

行激活

ACTIVE

1

0

0

1

1

 

读操作

READ

1

0

1

0

1

 

写操作

WRITE

1

0

1

0

0

 

预充电

PR

1

0

0

1

0

 

自刷新

AR

1

0

0

0

1

 

设置寄存器

LMR

1

0

0

0

0

 

突发停止

BURST_STOP

1

0

1

1

0

1

SDRAM初始化

SDRAM控制模块发送初始化使能信号,使能SDRAM初始化模块,然后进行初始化操作,初始化操作完成后,发出初始化完成信号到SDRAM控制模块,SDRAM控制模块进入下一步操作。

Init_start用于启动SDRAM初始化模块进行初始化,done_init用于反馈SDRAM初始化模块初始化完成。在SDRAM初始化的过程中,根据初始化的每一个步骤,进行输出指令和SDRAM_address信号。

初始化时序

初始化操作流程图

SDRAM初始化代码

该工程的时钟频率为20MHz

module sdram_init(

clk,

reset_n,

init_start,

init_done,

sdram_command,

sdram_address

);

//参数定义

parameter T200US = 12'd3999; //上电延迟200us

//端口定义

input clk; //时钟信号20MHz

input reset_n; //复位信号

input init_start; //初始化开始信号,高电平有效

output init_done; //初始化完成信号,输出,高电平有效

output [4:0] sdram_command; //cke、cs_n、ras、cas_n、we_n,SDRAM指令信号

output [13:0] sdram_address; //[13:12]BA , [11:0]Addr,SDRAM地址信号

//常量定义

parameter NOP = 5'b10111, //空操作

ACTIVE = 5'b10011, //行激活

READ = 5'b10101, //读操作

WRITE = 5'b10100, //写操作

PR = 5'b10010, //预充电

AR = 5'b10001, //自刷新

LMR = 5'b10000; //设置寄存器

parameter SET_MODE_REG = {4'd0, 1'b0, 2'd0, 3'b010, 1'b0, 3'b011};

//突发读写,潜伏期为2,顺序操作,突发长度为8

//寄存器定义

reg [11:0] time_cnt; //上电延迟计数寄存器

reg [4:0] sdram_command_reg; //SDRAM指令寄存器

reg [13:0] sdram_address_reg; //SDRAM地址信号寄存器,{bank,address}

reg init_done_reg; //初始化完成信号寄存器

reg [3:0] state_cnt; //状态机计数器,用于控制状态跳转

//*****************************************************************************

// 模块名称:SDRAM初始化模块

// 功能描述:在初始化开始控制信号的控制下进行初始化操作,操作完成后发出初始化完成信号

//*****************************************************************************

always @(posedge clk or negedge reset_n)

begin

if(reset_n == 1'b0)

begin

time_cnt <= #1 12'd0; //上电延迟计数寄存器清零

state_cnt <= #1 4'd0; //状态计数器初始化

init_done_reg <= #1 1'b0; //初始化完成寄存器清零

sdram_command_reg <= #1 NOP; //SDRAM指令寄存器初始化

sdram_address_reg <= #1 14'h3fff; //SDRAM地址信号寄存器进行置高

end

else

begin

if(init_start == 1'b1)

case (state_cnt)

4'd0://上电延迟200us

begin

if(time_cnt == T200US) //判断200us延迟是否结束

begin

state_cnt <= #1 state_cnt + 1'b1;

time_cnt <= #1 12'd0;

end

else

time_cnt <= #1 time_cnt + 1'b1;

end

4'd1://预充电操作

begin

sdram_command_reg <= #1 PR;

sdram_address_reg <= #1 14'h3fff;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd2://空操作

begin

sdram_command_reg <= #1 NOP;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd3://自动刷新

begin

sdram_command_reg <= #1 AR;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd4,4'd5://空操作

begin

sdram_command_reg <= #1 NOP;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd6://自动刷新

begin

sdram_command_reg <= #1 AR;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd7,4'd8://空操作

begin

sdram_command_reg <= #1 NOP;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd9://设置寄存器

begin

sdram_command_reg <= #1 LMR;

state_cnt <= #1 state_cnt + 1'b1;

sdram_address_reg <= #1 SET_MODE_REG;

end

4'd10,4'd11://空操作

begin

sdram_command_reg <= #1 NOP;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd12://设置初始化完成信号

begin

init_done_reg <= #1 1'b1;

state_cnt <= #1 state_cnt + 1'b1;

end

4'd14://恢复初始化完成信号

begin

state_cnt <= #1 4'd0;

end

default://其他状态,恢复到初始状态

begin

state_cnt <= #1 4'd0;

sdram_command_reg <= #1 NOP;

end

endcase

end

end

//*****************************************************************************

assign init_done = init_done_reg;

assign sdram_command = sdram_command_reg;

assign sdram_address = sdram_address_reg;

endmodule

SDRAM读写模块

state_signal: 状态信号,用于控制对SDRAM进行读写和自刷新;

sdram_bank_addr:SDRAM最小单元地址,[21:20]块地址+[19:8]行地址Row+[7:0]列地址Column;

write_data: 写入SDRAM的数据;

rw_done_signal: 读写完成信号;

ar_done_signal: 自动刷新完成信号;

read_data: 从SDRAM读出的数据;

sdram_command:SDRAM指令,cke、cs_n、ras、cas_n、we_n,SDRAM指令信号;

sdram_address: SDRAM读写地址;

sdram_dqm: SDRAM数据掩码;

sdram_data: SDRAM读写数据;

state_signal有四种状态,分别为自刷新、读、写、空操作。Sdram读写控制模块根据state_signal的信号对SDRAM发出控制信息,同时接收数据和发送数据、地址。

当处于自刷新状态时,向SDRAM发送自刷新命令,自刷新完成后ar_done_signal信号有效,表明自刷新操作完成。

当处于读状态时,向SDRAM发送读数据命令、读取数据的地址sdram_bank_addr,读操作完成后rw_done_signal信号有效,表明读操作完成,这时可以从read_data读取从sdram读取的数据。

当处于写状态时,向SDRAM发送写数据命令,同时将写入的数据送往write_data,写入的地址送往sdram_bank_addr,写操作完成后rw_done_signal信号有效,表明写操作完成。

当处于空操作时向sdram发送NOP指令。

sdram_dqm为sdram的数据掩码信号,在对sdram进行读写操作时,其电平状态要与指令sdram_command相配合操作。

自刷新操作

存储体中电容的数据有效保存期上限是64ms,也就是说每一行刷新的循环周期是64ms。这样刷新速度就是:行数量/64ms 。我们在看内存规格时,经常会看到4096 Refresh Cycles/64ms 或8192 Refresh Cycles/64ms的标识,这里的4096与8192就代表这个芯片中每个L-Bank的行数。刷新命令一次对一行有效,发送间隔也是随总行数而变化,4096行时为15.625 μs。

由此每隔15us需要自刷新一次。

刷新操作采样简单的操作:

  1. 发送AutoRefresh命令,命SDRAM刷新内部逻辑的内容
  2. 相关操作需要消耗时间tRFC-63ns

    自刷新时序:

自刷新代码:

读操作

读操作过程

  1. 发送Active命令、行(Row)和库(Bank)地址。
  2. 满足时间要求tRCD-20ns。
  3. 发送Read命令、列(Column)和库(Bank)地址,DQM拉低,拉高A10一个时钟,表示读操作后自动释放资源库(With Auto Precharge)。
  4. 满足CAS Latency时间要求
  5. CAS Latency满足之后,接下来满足时间要求tAC-6ns、tRP-20ns,然后读取数据。

读操作代码

写操作

操作过程

  1. 发送Active命令,发送库(Bank)和行(Row)地址信息。
  2. 满足tRCD时间要求,至少20ns。
  3. 发送Write命令、库(Bank)和列(Column)地址;A10拉高代表With Auto Precharge;
  4. 同时写入的一字数据。这时候DQM必须拉低。
  5. 满足tWR(tDPL)时间要求,至少2个时钟。
  6. 满足tRP时间要求,至少20ns。
  7. 经过时间tWR(tDPL)以后,一字数据就成功被写入。随后SDRAM开始执行Auto Precharge的操作,释放当前相关的资源库。最后经过tRP以后(Auto Precharge的操作完成)

时序图

写操作代码

大西瓜FPGA-->https://daxiguafpga.taobao.com

博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号“科乎”。

转载于:https://www.cnblogs.com/logic3/p/5239338.html

SDRAM读写一字(上)相关推荐

  1. 【GD32】从零开始学GD32单片机高级篇——外部存储器控制器EXMC详解+SDRAM读写例程

    目录 简介 外部设备地址映射 NOR和PSRAM的地址映射 NAND/PC Card地址映射 SDRAM地址映射 NOR/PSRAM控制器 接口描述 控制时序 模式1 模式2 NAND Flash或P ...

  2. 【FPGA】基于Avalon_MM接口的SDRAM读写

    1.SDRAM 1.1 SDRAM简介 C4开发板上的SDRAM芯片是海力士生产,有256Mbits容量. SDRAM是同步动态随机存储器(存储阵列不断刷新). SDRAM寻址基本原理:行列寻址 SD ...

  3. SDRAM读写控制器

    第1节 –作者:小黑同学 本文为明德扬原创及录用文章,转载请注明出处! 1.1 总体设计 1.1.1 概述 同步动态随机存取内存(synchronous dynamic randon-access m ...

  4. [WinError 10038] 在一个非套接字上尝试了一个操作

    [WinError 10038] 在一个非套接字上尝试了一个操作 socket先close再调recv就会报错. 解决方法:可以判断一下是否关闭了再操作: if not tcpCliSock._clo ...

  5. C语言 socket shutdown()函数(将与 sockfd 关联的套接字上的全双工连接全部或部分关闭)

    man 2 文档 [root@ubuntu /arnold_test/20220324_hikflow_demo__socket_server_test]102# man -f shutdown sh ...

  6. C语言socket connect()函数(初始化套接字上的连接)(未完)(如何测试socket是否已经断开,如何判断socket是否断开)

    参考文章:C网络编程socket之connect函数 需研究下这个函数超时多久才返回... 文章目录 项目中注释解释 man 2 文档解释 关于上面man 2 手册中所提到的connect()案例,在 ...

  7. 疑难杂症--由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

    在巡检数据库时发现,数据库备份作业失败,查看错误日志发现以下提示: 已以用户 WIN2008-JH122\SYSTEM 的身份执行. Microsoft (R) SQL Server 执行包实用工具  ...

  8. 怎样在拼打日语汉字时,在字上同时显示假名

    怎样在拼打日语汉字时,在字上同时显示假名 word 中选中你要标假名的汉字,格式-中文版式-拼音指南 然后在拼音文字上输入假名就可以啦 posted on 2011-12-09 16:20  SunB ...

  9. SQL Server 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

    1.查询分析器无法正常连接 SQL Server数据库时的错误: 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作 2.此情况一般是服务器端的端口用尽的表现,解决办法,执行以下命令行,查看端口 ...

最新文章

  1. Activiti 开始流程时存储发起人员USERID
  2. Metasploit reload命令使用技巧
  3. 软件官网与memcached介绍
  4. 剑指 Offer 43. 1~n 整数中 1 出现的次数(数位dp)
  5. 02=windows下安装PostgreSQL(The database cluster initialisation failed)
  6. 模式三工厂——开花结果
  7. 【c++】笔记:输入带空格的字符串
  8. Java 原生 JAXB 解析 XML 深入剖析
  9. ValidationKey
  10. CPU的平均指令周期 怎么算,如何计算处理器的机器周期
  11. Kotlin学习笔记八-数据代理类型,接口与抽象类
  12. FTP 在局域网搭建ftp服务器-共享文件资料
  13. centos 6.5 mysql 5.5 安装,centos6.5 安装mysql-5.5
  14. 消息中间件 - ActiveMQ高级特性和用法-Mirrored Queue 镜像队列(了解即可)(十)
  15. 心心念特斯拉电动皮卡?现在可以下单了,只要1000块
  16. mysql中防呆是什么_别让用户发呆——设计中的防呆策略
  17. 如何从iCloud共享iWork文档
  18. c语言设计课程期末上机考试海大,(海大试卷.docx
  19. [规范资料]Excel文件格式
  20. 安卓备忘:跳转系统页面以及常见APP相应页面

热门文章

  1. 构建论文框架的八条原则
  2. 临床预测模型开发checklist详解
  3. 修改某个用户名和密码
  4. CentOS下C++开发环境搭建
  5. 计算机视觉与深度学习 | 视觉SLAM详解及应用(中文版)
  6. 问题 | FileNotFoundError: [Errno 2] No such file or directory: 'null'
  7. php 获取汉字,php 获取汉字长度
  8. linux 网卡配置不一致,linux环境下,双网卡配置不同网段后,路由问题
  9. 关于“指针的指针”的认识(值传递、指针传递区分)
  10. jmeter服务器测试项目,JMeter-项目测试