我们在很多地方都能看到SDR SDRAM(同步动态随机存储器)的身影,现在可以找到很多成熟的IP核,但对于熟悉FPGA或者AISC设计,或是学习HDL,写个SDRAM控制器是个很好的练习机会,同时也顺便熟悉一下DRAM厂商的产品内部结构,看看与书本上写的有何变化,对于日后使用DRAM积累知识。
上图是一张经典的DRAM内部组织方式,对于DRAM内部的结构和组织方式,列位可以参考相关书中所讲。对于DDR SDRAM,其实组织方式大同小异,只是工作电压一般要比SDRAM低(2.5V、1.8V等)。在数据端口有IO Buffer,通过DQS/DQSn实现了双倍数据速率的读写。
上图是各个操作命令对应的真值表,来自海力士半导体HY57V641620芯片的Datasheet。
初始化
输入稳定:等待200us,空命令
所有L-Bank预充电
刷新:两次即可
设置模式寄存器(MRS):下图是模式寄存器的说明:
其中读的模式只能是突发模式,写操作可以突发模式或者单一模式。当然了,突发的长度可以是1,也就是说单一的读写也没问题。突发长度(Burst Length)根据实际需要设置。当然了必要时可以通过发送Burst Stop命令终止当前的突发操作。笔者在实际调试时发现,如果完成了当前的BL长度的读写,可以发送Burst Stop命令停止,如果当前是读突发结束,如果不发送Burst Stop命令,DRAM的DQ数据端口将继续循环输出数据,不知道是个体差异还是SDRAM本身就是这样设计的,这个还需要继续了解。而且突发读写后,也不是必须发送Burst Stop命令,可以紧接着发送预充电命令后继续进行正确读写操作。
激活行(Row):
初始化完成后,要想对一个L-Bank中的阵列进行寻址,首先就要确定行处于活动状态(Active),然后再确定列。虽然之前要进行片选和L-Bank的定址,但它们与行有效可以同时进行,置行有效并发送行地址。
列有效并读写
读操作时序图如下:
写操作时序图:
上图所示的时许参数tRCD = 2CLK,tRC = 3CLK,tCL = 2CLK预充电,tRP = 3
自动预充电时的开始时间与此图一样,只是没有了单独的预充电命令,并在发出读取命令时,A10地址线要设为高电平(允许自动预充电)。控制好预充电启动时间很重要,它可以在读取操作结束后立刻进入新行的寻址,保证运行效率。刷新,tRC = 3CLK
之所以称为DRAM,就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是DRAM最重要的操作。具体的时许操作因不同芯片而已,看DataSheet;目前公认的标准是,存储体中电容的数据有效保存期上限是64ms,也就是说每一行刷新的循环周期是64ms。这样刷新速度就是:行数量/64ms。我们在看内存规格时,经常会看到4096 Refresh Cycles/64ms或8192 Refresh Cycles/64ms的标识,这里的4096与8192就代表这个芯片中每个L-Bank的行数。刷新命令一次对一行有效,发送间隔也是随总行数而变化,4096行时为15.625μs,8192行时就为7.8125μs。
对于SDRAM的CLK信号,为了保证数据读写的建立时间和保持时间的要求,SDRAM的输入时钟CLK要与控制器的工作时钟保持一定的相位差。
所以在使用DRAM的时候,如果你是使用带有DRAM控制器的SoC芯片的时候,只要通过CPU设置好其各个时序控制寄存器的相关参数和硬件的连接方式,确定物理地址范围,就可以使用了。
如果是ASIC或者FPGA进行SDRAM的读写时,RTL的设计可以分为三个模块,命令产生、命令执行、数据路径。整个工作过程由一个状态机控制。