基于FPGA的SDRAM开发-进阶篇

一、SDRAM是什么

SDRAM 英文全称**"Synchronous Dynamic Random Access Memory",** 中文全称同步动态随机存储器。

**同步(Synchronous):**SDRAM有一个同步接口,其工作时钟的时钟频率与对应控制器(CPU/FPGA)的时钟频率相同,并且SDRAM内部的命令发送与数据传输都是以此时钟为基准,实现指令或数据的同步操作;

**动态(Dynamic):**SDRAM需要不断的刷新,来给电容进行充放电,如果原本电容里所存储的数据为1,则需要不断地刷新进行充电;如果原本电容里所存储的数据为0,则需要不断地刷新进行放电。保证存储阵列内数据不丢失;

**随机(Random):**数据在 SDRAM 中可以自由指定地址进行数据的读写。

二、SDRAM的发展史

随着时代的不断发展、技术的不断更新,SDRAM的更新历经五代,分别是:第一代SDR SDRAM,第二代DDR SDRAM,第 三代DDR2 SDRAM,第四代DDR3 SDRAM,第五代,DDR4 SDRAM。

SDR是single data rate,单数据速率,只在时钟的上升沿进行数据采样;

DDR是double data rate,双倍数据速率,在时钟的上升沿和下降沿都进行数据采样;

SDR SDRAM到DDR SDRAM的区别:DDR SDRAM的读写速度快、功耗低、内核电压越来越低(SDR:3.3V 、DDR:2.5V、DDR2:1.8V、DDR3:1.5V、DDR4:1.2V)。

三、应用场景

1、电脑内存条

2、FPGA开发板,用于扩大FPGA芯片的存储容量,缓存图像数据和高速接口的数据。(FPGA内部的BRAM资源很少,也很宝贵)

四、SDRAM数据存取原理

1、数据存储架构及工作原理

SDRAM 内部可以理解为一个存储阵列,如下图。我们将 SDRAM 内部存储阵列类比成一张表格,表格中的每一个单元格 可以类比为存储阵列的单个存储单元。 这个存储阵列我们称之为一个Bank,一般情况下,我们会设计多个bank,用来扩展FPGA芯片的存储容量。因为FPGA芯片的BRAM资源是很少的,也很宝贵。

在对 SDRAM 进行数据存取时,要先确定 Bank 地址,定位到指定逻辑 Bank,再依次确定行地址(Row Address)列地址 (Column Address),选中存储单元,进而进行数据的存取操作,而且一次只能对一个Bank的一个存储单元进行操作。

SDRAM的一个存储单元的容量有若干个 Bit,每个Bit存放于一个单独的存储体中,该存储体利用电容能够保持电荷以及可充放电的特性来存储0/1,主要由行选通三极管列选通三极管存储电容 以及刷新放大器 构成,如下图。电容所存储的电荷会随时间慢慢释放,这就需要不断的动态刷新为电容充放电,以保证存储数据可靠性。

将每个存储单元简化为单 Bit 的存储体,再将若干存储体排列为矩阵,同一行将行地 址线相连,同一列将列地址线相连,就构成了一个存储阵列的简化模型。SDRAM 内部存储阵列的简化模型,具体见图 53-3。

2、SDRAM总存储容量计算

如上表,我们知道了行地址位宽为15bit,列地址位宽为10bit,每个存储单元大小为16bit,一共有8个bank。那么该芯片的存储容量为:2^15 * 2^10 * 16bit * 8=2^32 bit=2^12Mbit=2^9 MB= 512MB.

五、SDR SDRAM和DDR3 SDRAM区别对比

1、硬件图纸

SDR SDRAM的硬件图纸:

DDR3 SDRAM的硬件图纸:

由硬件图纸可以发现,SDR SDRAM的供电电压为3.3V,而DDR3 SDRAM的供电电压为1.5V。

且DDR3 SDRAM多了参考电压VREFCA、VREFDQ。

2、信号线

SDR SDRAM的信号线:

DDR3 SDRAM相对于SDR SDRAM多了几根信号线:

**(1)DQSL、DQSL_N:**为低字节数据选通信号,输出时与读取数据边缘对齐,输入时与写入数据中心对齐。

**(2)DQSU、DQSU_N:**为高字节数据选通信号,输出时与读取数据边缘对齐,输入时与写入数据中心对齐。

**(3)CK、CK_N:**SDR SDRAM的时钟线是单端的,DDR3 SDRAM的时钟线是差分的。因为SDR SDRAM的工作时钟的时钟频率相对较低(一般为100Mhz),而DDR3 SDRAM的工作时钟的时钟频率比较高(一般为800/900Mhz)。具体时钟频率需要相关的数据手册。

(4)ODT: 控制芯片内部的终端电阻。当ODT引脚为高电平时,启用内部终端电阻;为低电平时,禁用内部终端电阻。这些终端电阻会应用于数据输出引脚(DQ)、数据选通(DQS、DQS_N)和数据掩码(DM)等引脚,以减少信号传输过程中的反射,提高信号完整性。不过,若通过模式寄存器命令禁用ODT功能,此引脚输入将被忽略。

六、SDRAM的各种操作命令

SDRAM的操作命令:

**激活命令:**就是选择要操作的是哪一个bank的哪一行;

**突发终止:**假设我们在模式寄存器中配置了一次突发的长度是10个数据,当我们要在哪一个bank的哪一行的哪一列进行读/写操作,那么当我们进行读/写操作5个数据之后,不希望它继续进行读/写操作了,我么可以发送突发终止命令结束当前的读/写操作。

预充电命令: 假设我们要在多个行里进行读/写操作,先通过激活命令选择操作的哪一个bank的哪一行,然后发送读/写命令选择哪一列,并执行相应的操作,当我们完成了对该行的操作之后,需要换到别的行进行操作,就需要发送**预充电命令,**再一次发送激活命令对别的行进行操作。

配置模式寄存器命令: 可以配置突发长度 、突发类型(顺序/隔行)、**列选通潜伏期(CAS Latency)、**运行模式(Operating Mode)(标准模式/测试模式等)、写模式(控制写操作是否为突发方式)。

七、初始化时序图、读写时序图

1、SDR SDRAM

2、DDR3 SDRAM

3、DDR3 SDRAM-Xilinx MIG IP 核

(1)写时序:

  • clk:系统时钟信号,所有其他信号的采样和状态跳变都同步于该时钟的上升沿。

注意:户千万不能自己用 PLL 去生成这个时钟然后连给它。必须把IP核输出的ui_clk端口直接接到逻辑模块的时钟端口上。

1>命令与地址通道 (Command/Address Interface)

  • app_cmd写/读命令 。输入信号,表明当前要执行的操作类型。3'b000(写入)和3'b001(读出)

  • app_addr写/读地址 。输入信号,表示要写入数据的起始地址。按照结构从高位到低位是rank + bank + row + column

  • app_en命令/地址使能信号 。输入信号,当它为高电平时,表示当前的 app_cmdapp_addr 是有效的。控制器只有检测到 app_en 为高时才会采样命令和地址。

  • app_rdy控制器命令就绪信号 。输出信号。当它为高电平时,表示控制器当前可以接收新的命令。用户必须在 app_enapp_rdy 同时为高的那个时钟周期,命令才会被成功接收(握手成功)。

2>写数据通道 (Write Data Interface)

  • app_wdf_data写数据 。输入信号,表示要写入到 DDR 存储器中的数据(图中依次为 W a0 到 W g0)。

  • app_wdf_mask写数据掩码 。输入信号,用于屏蔽 app_wdf_data 中的某些字节(Byte Mask)。当对应的位为 1 时,该字节的数据不会被写入 DDR。

  • app_wdf_wren写数据使能信号 。输入信号,当它为高电平时,表示 app_wdf_data 总线上的数据是有效的,控制器将对其进行采样。

  • app_wdf_end写数据结束信号 。输入信号,用于指示这是当前突发(Burst)写操作的最后一个有效数据周期。这对于控制器判断何时将数据真正提交到 DDR 内部至关重要。只要让它跟app_wdf_wren一样就行了,一句app_wdf_end = app_wdf_wren 搞定。

  • app_wdf_rdy控制器数据就绪信号 。输出信号。当它为高电平时,表示控制器内部的写数据 FIFO 未满,可以接收用户发来的数据。用户必须在 app_wdf_wrenapp_wdf_rdy 同时为高 时,数据才会被成功写入 FIFO。

(2)读时序:

读时序和写时序在命令通道(app_cmd、app_addr、app_en、app_rdy)上的握手机制完全一样,但最大区别在于数据通道的方向。

读数据通道

  • app_rd_data读数据总线输出信号。是从 DDR 内存中成功读取并返回的实际有效数据。

  • app_rd_data_valid读数据有效信号输出信号用户逻辑必须始终检查这个信号。 当它为高电平时,表示当前 app_rd_data 总线上的数据是合法有效的;如果是低电平,则数据无效,用户必须忽略。

注意:1、读潜伏期(Read Latency)2、数据突发(Burst)连续输出。

补充:

这图上显示了123三种情况。1是严格对齐2和3告诉你命令与地址通道 和写数据通道之间稍微有点前后偏差,也是可以接受的。

八、DDR3/4 IP核解决了什么问题

DDR3/4 IP 核,它主要替我们搞定了下面几层:

1. 时序与协议合规

DDR3/4 的命令时序非常严格(tRCDtRPtRFCtFAW 等),还要管理 bank/row 打开与关闭、读写切换、预充电。手写控制器很容易漏掉某个时序约束,而结果不是立即报错,而是偶发的数据错误或系统不稳定。IP 把这些全部做成硬件状态机,保证任何命令组合都满足时序。

2. 上电初始化和刷新

DDR 上电后要按固定流程做初始化、配置模式寄存器(MR0~MR3),之后还要周期性自动刷新,否则数据会丢失。刷新又必须和读写请求穿插调度,不能卡住正常访问。这些 IP 会自动完成。

3. 物理层(PHY)和训练校准

这是纯逻辑最难的部分:高频 DQ/DQS 信号有走线延迟、片内延迟和温度漂移,需要 write leveling、读/写校准、延迟链自动调节,还要处理 ODT 端接和阻抗匹配。IP 会用 FPGA 里专用的延迟资源配合校准逻辑来做,普通 RTL 很难可靠复现。

4. 时钟域和接口转换

内存侧通常是窄位宽、高频率、burst 式的访问,用户不想直接面对这种接口。IP 会转成 AXI4、Native 或 Avalon 这类宽位宽、相对低频、带握手的接口,把寻址、burst 拆分、跨时钟域都屏蔽掉。

5. 性能与可靠性

控制器内部会做 bank 交织、预取调度、写合并等优化,最大化带宽利用;而且 IP 经过厂商验证,带仿真模型和上板参考设计,比从零写控制器省下数人月到数十人月,也大幅降低调试风险。

它不解决的部分也很明确:应用层的缓存/替换策略、多端口仲裁、ECC(部分 IP 可选支持)、PCB 布线质量,以及颗粒型号和频率配置等,仍需要你自己设计或配置。

一句话总结:DDR3/4 IP 把最容易出错、最难调试、耗时最长的协议和物理层问题变成"配置好参数 + 用标准接口读写",让你把精力放在自己的业务逻辑上。

使用vivado配置DDR3 IP核:

链接:

相关推荐
飞猫的边缘AI7 小时前
边缘AI-5: 了解最灵活的计算芯片FPGA
人工智能·fpga开发·ai芯片·边缘ai·计算芯片·边缘ai芯片·titanium edge
badboy1219 小时前
Xilinx Vitis Core Development Kit 2025.2.1_Win+Linux
linux·fpga开发·xilinx
海盐nnn1 天前
面向 AI 的 FPGA 开发流程:别急着让它写代码,先把方向定好
fpga开发
zlinear数据采集卡1 天前
数据采集卡从入门到精通(38):上位机开发实战——Python/QT/LabVIEW的技术选型与分层架构
python·单片机·嵌入式硬件·qt·fpga开发·开源·labview
zlinear数据采集卡1 天前
数据采集卡从入门到精通(42):项目实战三——设备预测性维护系统,从布点到预警
开发语言·单片机·嵌入式硬件·安全·fpga开发
国科安芯2 天前
ASL706S:让 MCU 不再“失忆跑飞“的守护芯片
分布式·单片机·嵌入式硬件·安全·fpga开发·架构
明德扬2 天前
多路MIPI摄像头如何同步聚合?一文看懂FPGA视频汇聚方案
fpga开发·音视频
松小白song2 天前
FPGA开发三大铁律:位宽、逻辑与连接,为何仿真通过上板却挂?
fpga开发
FPGA小徐3 天前
FPGA 时钟频率计算与单位换算
fpga开发