第六章 SDRAM控制器的设计
介绍的重点:
·动态随机存储介绍
·介绍SDARM的工作原理与Verilog的实现方法
·基本实验:利用基本实例来解释SDRAM控制器顶层模块的设计
·高级实验:利用高级实例来完整的描述SDRAM控制器顶层模块的修改技巧与注意事项
问题:什么是SDRAM 那?
回答:
同步动态随机存储器(Synchronous Dynamic Random Access Memory)
目前很多芯片及系统开发,如影像采集或显示系统,都要用到保存容量大、读写速度高的存储器,本次介绍的SDRAM具有价格低、体积小、容量大、速度快特点,是理想的选择
SDRAM的框架:SDRAM是将存储器单元(Memory Cell)利用矩阵的方式来排列,矩阵中有列地址(Row Address)及行地址(Column Address),为了读出或写入某数据,SDRAM控制器会先传送列的地址,此时RAS信号被设定为Active状态,在存取行的地址前还需要几个执行周期,这段时间为RAS至CAS的延迟时间,而CAS信号则需经过几个时钟周期后,才开始稳定的书写数据,这段时间就是CAS延迟时间(CL)。
6-1 动态随机存储器的介绍
先了解动态随机存储器(Dynamic Random Access Memory,DRAM)其中一个存储器单元的结构
只需要用到 一个电容即可控制MOSFET的通断
而电容的电压会随着时间变化,出现电压下降的问题,保护机制在于读取与写入必须经过放大,另外保存一段时间过后必须将数据读出后再写入一次,这个动作称为DRAM更新,当然会一定的降低效率
为了降低封装成本,减少IC引脚数目,DRAM的地址输出线采用多工方式
同样方式分两次输入,先输入列地址在输入行地址、
最大的存储器单元数目为22n,常见的DRAM芯片容量以4的倍数递增,例如:4M Byte、16M Byte、64M Byte、256M Byte etc
由于DRAM是由MOSFET为主要器件,电路中的杂散电容(Stray Capacitance)对电路的反应时间有很大的影响,更换地址后会进行再次充放电,RAS信号至少要维持一段建立列地址时间(t RAS),外加预充电时间(tRP),因此一个DRAM的存取周期(tRC)的计算公式:
tRC=tRP+tRAS
这样的时间特性使得DRAM在相当长的一段时间内不能作为高速存储器使用,但是万恶的资本家怎么会放过这个赚钱的机会那[狗头],在商业竞争下,经过阶段改良,同步动态随机存储器(SDRAM)产生,是对DRAM功能的改善
由之前的描述可知,DRAM有天生的存放电的缺点,限制了分散数据随机存取的速度,于是SDRAM对于可预测的下一步 突发模式(Burst Mode)采用存储器交错处理(Memory Interleaving)以及多管线(Multi-Pipeline)技术,提升分配时间内读写的信息量,改善了突发模式下的存储时间,同步动态随机存储器
在连续存取的应用中达到与外部时钟同步的频率,故被称为同步动态随机存储器
SDRAM实现了:
1.可以控制突发模式的存取长度(包括1笔、2笔、4笔、8笔与整页的模式)
2.自动更新(Auto Refresh)及自我更新(Self Refresh)的能力
3.更大的容量、更快的存取速度等等要求
4.可以自动预充电与被控制充电
5.待机时的省电设计
6-2 使用Verilog实现SDRAM控制器与SDRAM接口的控制
1.初始化
2.存取储存器单元
3.更新和预充电
4.控制命令
6-3 SDRAM控制器的基本应用设计
SDRAM控制器应用电路设计技巧:
将“SDRAM”比作“自来水厂”
“读出数据缓冲器与数据处理器”比作“水塔”
清水在进入住户之前要先进入水塔
6-4SDRAM控制器的进阶应用设计
快速修改SDRAM满足各种工程的需求,如何同时调用两个SDRAM在应用方面进行详细介绍
6-4-1 同时控制两个SDRAM的应用设计
1.复制工程
2.打开工程
3.修改读出数据缓冲器
4.修改写入数据缓冲器
5.修改SDRAM控制器数据宽度
修改SDRAM控制器的遮罩和数据宽度
.DQ(DRAM_DQ),
.DQM({DRAM_DQM}),
6.编译、烧录与执行
电路已进行修改,但执行起来并不是两个SDRAM的感觉,需要应用到第四章的知识“SignalTapll Logic Analyzer”来实时观察SDRAM的情况,选择写入状态为触发情况
6-4-2 修改FPGA端读写数据宽度的应用设计
1.复制工程
2.打开工程
3.修改读出数据缓冲器
4.修改写入数据缓冲器
可以在数据表中查看pin引脚情况
5.修改SDRAM控制器数据控制宽度
6.编译、烧录与执行
6-4-3 增加SDRAM读写端口的应用设计
1.复制工程
2.打开工程
3.在SDRAM控制器顶层模块增加读端口的输入/出
4.在SDRAM控制器顶层模块增加读出数据缓冲器
5.在SDRAM控制器顶层模块增加读出地址的控制
6.仲裁器的设计
7.工程顶层的修改
8.编译、烧录与执行
贴入代码如下:
module Sdram_Control(// HOST SideREF_CLK,RESET_N,// FIFO Write Side 1WR1_DATA,WR1,WR1_ADDR,WR1_MAX_ADDR,WR1_LENGTH,WR1_LOAD,WR1_CLK,// FIFO Read Side 1RD1_DATA,RD1,RD1_ADDR,RD1_MAX_ADDR,RD1_LENGTH,RD1_LOAD, RD1_CLK,// FIFO Read Side 2RD2_DATA,RD2,RD2_ADDR,RD2_MAX_ADDR,RD2_LENGTH,RD2_LOAD, RD2_CLK,// SDRAM SideSA,BA,CS_N,CKE,RAS_N,CAS_N,WE_N,DQ,DQM,SDR_CLK
);`include "Sdram_Params.h"// HOST Side
input REF_CLK; //System Clock
input RESET_N; //System Reset
// FIFO Write Side 1
input [`DSIZE-1:0] WR1_DATA; //Data input
input WR1; //Write Request
input [`ASIZE-1:0] WR1_ADDR; //Write start address
input [`ASIZE-1:0] WR1_MAX_ADDR; //Write max address
input [8:0] WR1_LENGTH; //Write length
input WR1_LOAD; //Write register load & fifo clear
input WR1_CLK; //Write fifo clock
// FIFO Read Side 1
output [`DSIZE-1:0] RD1_DATA; //Data output
input RD1; //Read Request
input [`ASIZE-1:0] RD1_ADDR; //Read start address
input [`ASIZE-1:0] RD1_MAX_ADDR; //Read max address
input [8:0] RD1_LENGTH; //Read length
input RD1_LOAD; //Read register load & fifo clear
input RD1_CLK; //Read fifo clock
// FIFO Read Side 2
output [`DSIZE-1:0] RD2_DATA; //Data output
input RD2; //Read Request
input [`ASIZE-1:0] RD2_ADDR; //Read start address
input [`ASIZE-1:0] RD2_MAX_ADDR; //Read max address
input [8:0] RD2_LENGTH; //Read length
input RD2_LOAD; //Read register load & fifo clear
input RD2_CLK; //Read fifo clock
// SDRAM Side
output [11:0] SA; //SDRAM address output
output [1:0] BA; //SDRAM bank address
output [1:0] CS_N; //SDRAM Chip Selects
output CKE; //SDRAM clock enable
output RAS_N; //SDRAM Row address Strobe
output CAS_N; //SDRAM Column address Strobe
output WE_N; //SDRAM write enable
inout [`DIOSIZE-1:0] DQ; //SDRAM data bus
output [`DIOSIZE/8-1:0] DQM; //SDRAM data mask lines
output SDR_CLK; //SDRAM clock
// Internal Registers/Wires
// Controller
reg [`ASIZE-1:0] mADDR; //Internal address
reg [8:0] mLENGTH; //Internal length
reg [`ASIZE-1:0] rWR1_ADDR; //Register write address
reg [`ASIZE-1:0] rRD1_ADDR; //Register read address
reg [`ASIZE-1:0] rRD2_ADDR; //Register read address
reg WR_MASK; //Write port active mask
reg [1:0] RD_MASK; //Read port active mask
reg mWR_DONE; //Flag write done, 1 pulse SDR_CLK
reg mRD_DONE; //Flag read done, 1 pulse SDR_CLK
reg mWR,Pre_WR; //Internal WR edge capture
reg mRD,Pre_RD; //Internal RD edge capture
reg [9:0] ST; //Controller status
reg [1:0] CMD; //Controller command
reg PM_STOP; //Flag page mode stop
reg Read; //Flag read active
reg Write; //Flag write active
reg [`DIOSIZE-1:0] mDATAOUT; //Controller Data output
wire [`DIOSIZE-1:0] mDATAIN; //Controller Data input
wire [`DIOSIZE-1:0] mDATAIN1; //Controller Data input 1
wire CMDACK; //Controller command acknowledgement
// DRAM Control
reg [`DIOSIZE/8-1:0] DQM; //SDRAM data mask lines
reg [11:0] SA; //SDRAM address output
reg [1:0] BA; //SDRAM bank address
reg [1:0] CS_N; //SDRAM Chip Selects
reg CKE; //SDRAM clock enable
reg RAS_N; //SDRAM Row address Strobe
reg CAS_N; //SDRAM Column address Strobe
reg WE_N; //SDRAM write enable
wire [11:0] ISA; //SDRAM address output
wire [1:0] IBA; //SDRAM bank address
wire [1:0] ICS_N; //SDRAM Chip Selects
wire ICKE; //SDRAM clock enable
wire IRAS_N; //SDRAM Row address Strobe
wire ICAS_N; //SDRAM Column address Strobe
wire IWE_N; //SDRAM write enable
// FIFO Control
reg OUT_VALID; //Output data request to read side fifo
reg IN_REQ; //Input data request to write side fifo
wire [15:0] write_side_fifo_rusedw1;
wire [15:0] read_side_fifo_wusedw1;
wire [15:0] read_side_fifo_wusedw2;
// DRAM Internal Control
wire [`ASIZE-1:0] saddr;
wire load_mode;
wire nop;
wire reada;
wire writea;
wire refresh;
wire precharge;
wire oe;
wire ref_ack;
wire ref_req;
wire init_req;
wire cm_ack;
wire last_pm;Sdram_PLL u_sdram_pll(.inclk0(REF_CLK),.c0(CLK),.c1(SDR_CLK));control_interface u_control(.CLK(CLK),.RESET_N(RESET_N),.CMD(CMD),.ADDR(mADDR),.REF_ACK(ref_ack),.CM_ACK(cm_ack),.NOP(nop),.READA(reada),.WRITEA(writea),.REFRESH(refresh),.PRECHARGE(precharge),.LOAD_MODE(load_mode),.SADDR(saddr),.REF_REQ(ref_req),.INIT_REQ(init_req),.CMD_ACK(CMDACK));command u_command(.CLK(CLK),.RESET_N(RESET_N),.SADDR(saddr),.NOP(nop),.READA(reada),.WRITEA(writea),.REFRESH(refresh),.LOAD_MODE(load_mode),.PRECHARGE(precharge),.REF_REQ(ref_req),.INIT_REQ(init_req),.REF_ACK(ref_ack),.CM_ACK(cm_ack),.OE(oe),.PM_STOP(PM_STOP),.SA(ISA),.BA(IBA),.CS_N(ICS_N),.CKE(ICKE),.RAS_N(IRAS_N),.CAS_N(ICAS_N),.WE_N(IWE_N));Sdram_WR_FIFO u_write_fifo(.data(WR1_DATA),.wrreq(WR1),.wrclk(WR1_CLK),.aclr(WR1_LOAD),.rdreq(IN_REQ&WR_MASK),.rdclk(CLK),.q(mDATAIN1),.rdusedw(write_side_fifo_rusedw1));Sdram_RD_FIFO u_read_fifo1(.data(mDATAOUT),.wrreq(OUT_VALID&RD_MASK[0]),.wrclk(CLK),.aclr(RD1_LOAD),.rdreq(RD1),.rdclk(RD1_CLK),.q(RD1_DATA),.wrusedw(read_side_fifo_wusedw1));Sdram_RD_FIFO u_read_fifo2(.data(mDATAOUT),.wrreq(OUT_VALID&RD_MASK[1]),.wrclk(CLK),.aclr(RD2_LOAD),.rdreq(RD2),.rdclk(RD2_CLK),.q(RD2_DATA),.wrusedw(read_side_fifo_wusedw2));assign mDATAIN = (WR_MASK) ? mDATAIN1 : `DSIZE'hzzzz;
assign DQ = oe ? mDATAIN : `DSIZE'hzzzz;
assign last_pm = (ST==SC_CL+mLENGTH);always @(posedge CLK)
beginSA <= ISA;BA <= IBA;CS_N <= ICS_N;CKE <= ICKE;RAS_N <= last_pm ? 1'b0 : IRAS_N;CAS_N <= last_pm ? 1'b1 : ICAS_N;WE_N <= last_pm ? 1'b0 : IWE_N; PM_STOP <= last_pm ? 1'b1 : 1'b0;DQM <= (Read || Write) ? 4'b0000 : 4'b1111;mDATAOUT<= DQ;
endalways@(posedge CLK or negedge RESET_N)
beginif(RESET_N==0)beginCMD <= 0;ST <= 0;Pre_RD <= 0;Pre_WR <= 0;Read <= 0;Write <= 0;OUT_VALID <= 0;IN_REQ <= 0;mWR_DONE <= 0;mRD_DONE <= 0;endelsebeginPre_RD <= mRD;Pre_WR <= mWR;case(ST)0: beginif({Pre_RD,mRD}==2'b01)beginRead <= 1;Write <= 0;CMD <= 2'b01;ST <= 1;endelse if({Pre_WR,mWR}==2'b01)beginRead <= 0;Write <= 1;CMD <= 2'b10;ST <= 1;endend1: beginif(CMDACK==1)beginCMD<=2'b00;ST<=2;endenddefault: begin if(ST!=SC_CL+SC_RCD+mLENGTH+1)ST<=ST+1;elseST<=0;endendcaseif(Read)beginif(ST==SC_CL+SC_RCD+1)OUT_VALID <= 1;else if(ST==SC_CL+SC_RCD+mLENGTH+1)beginOUT_VALID <= 0;Read <= 0;mRD_DONE <= 1;endendelsemRD_DONE <= 0;if(Write)beginif(ST==SC_CL-1)IN_REQ <= 1;else if(ST==SC_CL+mLENGTH-1)IN_REQ <= 0;else if(ST==SC_CL+mLENGTH)beginWrite <= 0;mWR_DONE<= 1;endendelsemWR_DONE<= 0;end
end
// Internal Address & Length Control
always@(posedge CLK or negedge RESET_N)
beginif(!RESET_N)beginrWR1_ADDR <= WR1_ADDR;rRD1_ADDR <= RD1_ADDR;rRD2_ADDR <= RD2_ADDR;endelsebegin// Write Side 1if(WR1_LOAD)rWR1_ADDR <= WR1_ADDR;else if(mWR_DONE&WR_MASK)beginif(rWR1_ADDR<WR1_MAX_ADDR-WR1_LENGTH)rWR1_ADDR <= rWR1_ADDR+WR1_LENGTH;elserWR1_ADDR <= WR1_ADDR;end// Read Side 1if(RD1_LOAD)rRD1_ADDR <= RD1_ADDR;else if(mRD_DONE&RD_MASK[0])beginif(rRD1_ADDR<RD1_MAX_ADDR-RD1_LENGTH)rRD1_ADDR <= rRD1_ADDR+RD1_LENGTH;elserRD1_ADDR <= RD1_ADDR;end// Read Side 2if(RD2_LOAD)rRD2_ADDR <= RD2_ADDR;else if(mRD_DONE&RD_MASK[1])beginif(rRD2_ADDR<RD2_MAX_ADDR-RD2_LENGTH)rRD2_ADDR <= rRD2_ADDR+RD2_LENGTH;elserRD2_ADDR <= RD2_ADDR;endend
end
// Auto Read/Write Control
always@(posedge CLK or negedge RESET_N)
beginif(!RESET_N)beginWR_MASK <= 1'b0;RD_MASK <= 2'b0;mWR <= 0;mRD <= 0;endelsebeginif( (mWR==0) && (mRD==0) && (ST==0) &&(WR_MASK==0) && (RD_MASK==0) )begin// Read Side 1if( (read_side_fifo_wusedw1 < RD1_LENGTH) && (RD1_LOAD==0))beginmADDR <= rRD1_ADDR;mLENGTH <= RD1_LENGTH;WR_MASK <= 1'b0;RD_MASK <= 2'b1;mWR <= 0;mRD <= 1; end// Read Side 2else if( (read_side_fifo_wusedw2 < RD2_LENGTH) && (RD2_LOAD==0))beginmADDR <= rRD2_ADDR;mLENGTH <= RD2_LENGTH;WR_MASK <= 1'b0;RD_MASK <= 2'b10;mWR <= 0;mRD <= 1; end// Write Side 1else if( (write_side_fifo_rusedw1 >= WR1_LENGTH) && (WR1_LENGTH!=0) && (WR1_LOAD==0))beginmADDR <= rWR1_ADDR;mLENGTH <= WR1_LENGTH;WR_MASK <= 1'b1;RD_MASK <= 2'b0;mWR <= 1;mRD <= 0;endendif(mWR_DONE)beginWR_MASK <= 0;mWR <= 0;endif(mRD_DONE)beginRD_MASK <= 0;mRD <= 0;endend
endendmodule
1.复制工程
2.在SDRAM控制器顶层模块增加写端口的输入/出
3.在SDRAM控制器顶层模块增加写入数据缓冲器
4.在SDRAM控制器顶层模块增加写入地址的控制
5.仲裁器的设计
第六章 SDRAM控制器的设计相关推荐
- 计算机组成原理的中央控制器,计算机组成原理第六章中央控制器(6-7,8,9).pdf
<计算机组成与结构> --本科生课程教学 计算机学院(许先斌) 计算机学院(许先斌) xbxu@whu.edu.cn xbxu@whu.edu.cn 计算机组成与结构 计算机组成与结构 本 ...
- [k8s] 第六章 Pod控制器详解(Controller-manager)
本章节主要介绍各种Pod控制器的详细使用. Pod控制器介绍 Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类: 自主式pod:kuberne ...
- 第六章 设计程序架构 之 设计实现WebSocket策略
1. 概述 传统网页的通信方式是请求-响应模式,每次请求-响应都是新的连接.连接的建立和断开也是需要消耗资源的. WebSocket是基于TCP协议,实现单个连接上的双向通信. 本章内容包括: 异步读 ...
- 将军今天讲c语言了吗第六,计算机c语言 第六章:函数 教学设计(修改).doc
<C语言程序设计>之 ----- "函数"教学设计 贵州交通技师学院 张 红 <C语言程序设计>之 ----- "函数"教学设计 [教材 ...
- 《Effective C++》第三版 第六章 继承与面向对象设计 32~35条例
文章目录 条款32:确定你的 `public` 继承塑膜出 is-a 关系 故事引入规则 案例说明 小结上代码 公有继承用法 企鹅不会飞 企鹅会飞,但那是错的! 总结 请记住 条款33:避免遮掩继承而 ...
- 【重识云原生】第六章容器6.3.5节——Controller Manager概述
<重识云原生系列>专题索引: 第一章--不谋全局不足以谋一域 第二章计算第1节--计算虚拟化技术总述 第二章计算第2节--主流虚拟化技术之VMare ESXi 第二章计算第3节--主流虚拟 ...
- 【正点原子FPGA连载】第六章Petalinux设计流程实战摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Linux开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...
- 【正点原子FPGA连载】第十六章Petalinux设计流程实战摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Linux开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670 3)全套实验源码+手册+视频下载地址: h ...
- 游戏设计的艺术:一本透镜的书——第二十六章 团队以技术制作出游戏
这是一本游戏设计方面的好书 转自天之虹的博客:http://blog.sina.com.cn/jackiechueng 感谢天之虹的无私奉献 Word版可到本人的资源中下载 第二十六章团队以技术制作出 ...
- 走向ASP.NET架构设计-第六章-服务层设计(中篇)
走向ASP.NET架构设计-第六章-服务层设计(中篇) 前言:上一篇文章介绍了一些服务层的基本知识,而且也简要的介绍了SOA的有关知识,本篇主要是介绍在服务层可以采用的一些模式. 本篇议题如下: F ...
最新文章
- linux启动tomcat很久或者很慢Tomcat启动时卡在“INFO: Deploying web application directory ......”的解决方法...
- JVM中GC的停顿现象
- centos7搭建SVN并配置使用http方式访问SVN服务器
- 面试官:元素排序Comparable和Comparator有什么区别?
- Zabbix3.0安装文档
- 容器编排技术 -- Kubernetes JSONpath Support
- spring多数据源分布式事务的分析与解决方案
- 关于getline的细节
- SRT公网点对点传输及搭建SRT流媒体服务器
- Java基础系列1-Java语言概述
- 完整的省市县三级联动
- 【Android】面试宝典
- BZOJ 4199 品酒大会
- Unity2D游戏程序设计——打地鼠
- 物理计算机技术研究生就业前景,2018物理学专业就业前景和就业方向分析
- SQL注入的攻击与防御(简单篇)
- Flutter: 弹性布局Flex(Expanded)、流式布局Wrap、Flow
- 阿里云IoTStudio中的“移动可视化开发”不见了
- 克鲁斯卡尔算法(Kruskal)求最小生成树(MST)过程详解
- Hbuildx 使用vue打包的App实现微信支付功能
热门文章
- Programer's Tools
- linux新增字符串,字符串添加字符_Linux使用sed命令添加字符串的方法
- CAD贱人工具箱6.0免注册
- C4D R18-R21
- C4D动力学边界是什么意思?
- 微信小程序开发中医药配方小程序药方后台管理系统|前后分离VUE.js
- php长微博,用Word一键发布长微博
- 牛逼,在浏览器中解锁加密的音乐文件
- css文字覆盖线性渐变,利用css使文字渐变
- 当不知轴承型号时如何寻找轴承故障频率_专家总结的齿轮箱滚动轴承故障诊断方法,值得收藏!...