基于FPGA的DDR学习——1.基础知识

1.简述

DDR(Double Data Rate SDRAM)双倍速率的SDRAM

DDR在SDARAM的基础上改进而来,SDRAM在一个CLK周期传输一次数据,而DDR在一个CLK周期传输两次数据,分别在上升沿和下降沿各传输一次数据。该概念称为预取,在描述DDR速度的时候一般使用MT/S单位,也就是每秒多少兆次数据传输。

2.DDR

SDRAM发展了四代:第一代SDR SDRAM,第二代DDR SDRAM,第三代DDR2 SDRAM,第四代DDR3 SDRAM,现在已经发展到DDR5S DRAM。

⚪ DDR SDRAM是Double Data Rate Synchronous Dynamic Random Access Memory(双数据速率同步动态随机存储器)的简称,是由VIA等公司为了与RDRAM相抗衡而提出的内存标准,为第二代SDRAM标准。其常见标准有DDR 266、DDR 333、DDR 400。其对于SDRAM,主要它允许在时钟脉冲的上升沿和下降沿传输数据,这样不需要提高时钟的频率就能实现双倍的SDRAM速度,例如DDR266内存与PC133 SDRAM内存相比,工作频率同样是133MHZ,但在内存带宽上前者比后者高一倍。这种做法相当于把单车道更换为双车道,内存的数据传输性能自然可以翻倍。

⚪DDR2(Double Data Rate2)SDRAM是由JEDEC(电子设备工程联合委员会)开发的第三代SDRAM内存技术标准,1.8V工作电压,240线接口,提供了相较于DDR SDRAM更高的运行效能与更低的电压,同样采用在时钟的上升/下降沿同时进行数据传输的基本方式,但拥有两倍于上一代DDR内存预读取能力(即4bit数据预取能力),其常见的频率规范有DDR2 400\533\667\800\1066\1333等,总线频率553MHZ的DDR2内存只需133MHZ的工作频率。

⚪DDR3 SDRAM相比于DDR2具备更低的工作电压(1.5V),240线接口,支持8bit预读,只需133MHZ的工作频率便可实现1066MHZ的总线频率。

⚪DDR4相比DDR3最大的区别有三点:16bit预取机制,同样内核频率下理论速度是DDR3的两倍;更可靠的传输规范,数据可靠性进一步提升;工作电压降为1.2V,更节能。

主要区别是在于传输速率的不同,随着时钟周期的不断降低,传输率也不断提高。电压也越来越低。

3.DDR区别

DDR到DDR5的主要变化,可以看到,为了配合整体行业对于性能,容量和省电的不断追求,规范的工作电压越来越低,芯片容量越来越大,IO的速率也越来越高。

靠着prefetch来实现用比较低的核心传输频率来满足日益高涨的高速IO传输速率的需求。

从DDR开始到DDR3,Prefetch相当于DRAM core同时修了多条高速公路连到外面的IO口,来解决IO速率比内部核心速率快的问题,IO数据速率跟核心频率的倍数关系就是prefetch。

Burst length的长度跟CPU的cache line大小有关。Burst length的长度有可能大于或者等于prefetch。但是如果prefetch的长度大于burst length的长度,就有可能造成数据浪费,因为CPU一次用不了那么多。所以从DDR3到DDR4,如果在保持DDR4内存data lane还是64的前提下,继续采用增加prefetch的方式来提高IO速率的话,一次prefetch取到的数据就会大于一个cache line的大小(512bits),对于目前的CPU系统,反而会带来性能问题。

从DDR4出现了Bank Group,这就是DDR4在不断改变prefetch的情况下,能继续提升IO速率的秘密武器。DDR4利用Bank group的interleave,实现IO速率在DDR3基础上进一步提升。

4.内存原理

从内存控制器到内存颗粒内部逻辑,笼统上从大到小:

Channel>DIMM>rank>chip>bank>row/column

实际上每个格子的存储宽度是内存颗粒(Chip)的位宽,在这里由8个Chip组成一个Rank,而CPU寻址宽度是64bit,所以64/8=8bit,即每个格子是一个字节。选择每个格子也不是简单的两组信号,是由一系列信号组成,以2GB DDR3为例:

其引脚按照功能可以分为7类:前三类为电源、地址、配置

PIN分类

名称

方向

功能描述

电源

VDD

PI

芯片主电源输入(1.2V)

电源

VDDQ

PI

DQ信号线电源供电(1.2V)

电源

VPP

PI

DRAM激活电压(2.5V)

电源

VREFCA

PI

控制/命令/地址信号参考电平

电源

VSS

-

主地

电源

VSSQ

-

DQ信号参考地

电源

ZQ

-

阻抗匹配(ODT)标准参考,接240欧电阻到地

后4类为:控制信号、时钟信号、地址信号、数据信号

PIN分类

名称

方向

功能描述

控制信号

ALERT_N

OUT

报警信号,若命令/地址出现奇偶校验错误或者CRC错误,该PIN脚拉低,告知DDR Controller

控制信号

TEN

IN

测试模式使能信号,高电平使能测试模式。正常操作过程中,必须拉低

控制信号

RESET_N

IN

DDR复位信号,低电平有效。正常操作过程中,保持高电平

控制信号

PAR

IN

命令/地址信号的奇偶校验使能,可以通过寄存器禁用或者使能

控制信号

CS_N

IN

DDR芯片使能,用于多个RANK时的RANK组选择

控制信号

ODT

IN

阻抗匹配使能

控制信号

CKE

IN

时钟信号使能。通过此电平,可以控制芯片是否进入低功耗模式

控制信号

ACT_N

IN

命令激活信号,这个信号为低电平时,可以通过A[14:16]地址信号线选择激活命令的行地址。为高电平时,Address信号线正常使用

PIN分类

名称

方向

功能描述

时钟信号

CK_N/CK_P

IN

差分时钟信号,由DDR Controller输出

地址信号

BG0

IN

Bank Group地址选择

地址信号

BA[0:1]

IN

Bank地址选择

地址信号

A[0:16]

IN

地址选择信号,其中A16还有RAS_N功能,A15有CAS_N功能,A14有WE_N功能,A12有BC_N功能,A10有AP功能

数据信号

DQ[0:15]

IN/OUT

低8位数据和高8位数据信号线,共16位数据信号线

数据信号

LDM/LDBI

IN/OUT

低8位数据掩码

数据信号

UDM/UDBI

IN/OUT

高8位数据掩码

数据信号

LDQS_N/LDQS_P

IN/OUT

低8位数据选通信号

数据信号

UDQS_N/UDQS_P

IN/OUT

高8位数据选通信号

电源、地、配置信号的功能很简单,在此不再赘述。控制信号主要是用来完成DDR4和DDR4 Controller之间的状态切换。DDR4中最重要的信号就是地址信号和数据信号。

### FPGA DDR接口设计与控制器实现 #### 设计概述 FPGA(Field Programmable Gate Array)是一种可编程逻辑器件,广泛应用于嵌入式系统中作为数据处理的核心组件之一。当需要扩展系统的内存容量时,通常会通过FPGA连接DDR(Double Data Rate SDRAM)。这种组合可以显著提升数据吞吐量和性能。 在实际应用中,Cyclone III系列的FPGA因其丰富的资源和支持高速外设的能力,在DDR2接口设计方面具有独特优势[^1]。具体来说,其Top和Bottom Bank支持高达200 MHz的工作频率,这使得它成为高性能DDR2存储器的理想选择。 #### 接口设计要点 对于基于Cyclone III FPGA的设计而言,合理的Bank分配至关重要。由于仅特定型号下的某些位置能够达到所需工作频段,因此需将四片DDR2芯片均匀分布于顶部及底部四个独立Bank之中[^1]。这样不仅可以平衡负载还能减少信号干扰带来的负面影响。 此外,在硬件层面还需要注意的是关于输出使能路径设置问题。这里涉及到两个重要概念——一个是用于生成DQS写前置脉冲序列;另一个则是用来控制端口处于高阻态持续时间长度调整机制[^2]。这两个功能共同作用以确保符合标准协议规定的时间参数需求。 #### 控制器架构分析 从软件角度来看,则要构建相应的驱动程序来管理这些物理层面上的操作过程。典型的DDR控制器应该具备以下几个主要组成部分: - **命令解码单元**: 负责解析来自处理器或其他主设备发出的各种请求指令,并将其转换成适合目标存储子系统理解的形式。 - **地址映射模块**: 实现虚拟地址到实际物理帧号之间的变换操作,从而允许应用程序访问任意大小范围内的连续区域而无需关心底层细节差异情况如何变化。 - **数据缓冲区管理策略**: 提供临时存放空间给待传输的数据包使用直到完成整个事务流程为止; 同时也要考虑读/写方向切换期间可能存在的冲突规避措施等问题解决办法才行得通哦! 以下是简化版伪代码表示方法展示了一个基本框架思路: ```python class DDRCtrl: def __init__(self): self.cmd_decoder = CommandDecoder() self.addr_mapper = AddressMapper() self.data_buffer = [] def process_request(self, req_type, addr, data=None): cmd = self.cmd_decoder.decode(req_type) phy_addr = self.addr_mapper.map(addr) if cmd == 'READ': return self.read(phy_addr) elif cmd == 'WRITE' and data is not None: self.write(phy_addr, data) def read(self, address): # Simulate reading from buffer or actual memory location. pass def write(self, address, value): # Add to buffer before committing writes. self.data_buffer.append((address, value)) ``` 此代码片段仅为说明目的创建,并未完全体现真实世界复杂度水平上的全部要素特性等内容信息等等之类的话啦哈~ #### 技术术语解释 最后值得一提的是有关名称定义部分。“DDR”代表“双倍资料速率”,意味着在一个完整的时钟周期里可以传送两次资讯 (上升沿与下降沿)[^3]; 而当我们提到具体的种类像"DDR SDRAM"时候,则是指一种改进型别的同步动态随机存取记忆体形式—即所谓的第二代产品线成员之一咯~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值