SDRAM突发读写注意

序言

最近的项目需要在设计一个SDRAM控制器,用于存储一段采样数据,然后等待上位机下发指令,把数据上报。采用连续突发读写模式BL为4,时钟50MHz。

SDRAM器件型号为MT48LC16M16A2。(4M*16*4banks),从上面的信息我们可以了解到,该SDRAM的数据总线为16bit,行地址有13根(8K),列地址为9根,有4个BANK。

 

问题现象

         项目中的SDRAM控制模块,是由原来写好的SDRAM模块移植过来的,原来的代码中读写突发长度都为1的。经过修改后就移植到新的项目当中。一开始当一次采样的数据量比较少的时候,读写正常,但是一旦一次采样数据量大的时候,发现数据有错位。而且有一定的规律,这样可以排除掉是由于时序问题或者管脚设置、或者初始化等原因,初步可以断定时逻辑设计出问题了。

 SDRAM突发读写注意_第1张图片

图1   写入的测试数据

往sdram写入从16’h1---16’h6B35递增数据。

SDRAM突发读写注意_第2张图片

图2   Sdram读出的数据1

 SDRAM突发读写注意_第3张图片

图3   Sdram读出数据2

从上图中可以看出,从SDRAM突发读出来的数据很有规律,感觉上是某个位置的数被覆盖了。例如图3,正常读出的顺序应该,是(2001、2002、2003、2004),但是实际上读出来的是2004、2001、2002、2003;图2也是类似的问题。

 

问题定位

由于数据量少的时候,读写正常,那么就可以排除掉初始化不成功,或者时序不满足的原因,问题很有可能是出在地址上,感觉是某个地址被重复写了。经过测试发现,数据量在2K的样子就开始出现异常了。

SDRAM突发读写注意_第4张图片

图4   地址映射

上图画红线部分的是修改前,突发读写异常的地址映射。其中i_addr_bus地址总线是对应着采样数据依次递增的。原来i_addr_bus总线的低为地址映射到了SDRAM的行地址。也就是说,突发读写的时候,行地址递增了+4,等到行地址写满后,列地址才开始变化,应该是+1。结合数据长度每次到2K左右会出问题。根据突发为4,行地址总线8K。8K/4=2K。刚好是行地址写满后,切换到下一列的时候,部分数据被覆盖掉了。

当然如果突发读写为1的话,这样设计是没问题的。

SDRAM突发读写注意_第5张图片

图5   BUS_Hound检测到的数据

利用检测工具,BUS_Hound检测到的结果也印证了刚才的推断。其中OUT端是上位机下发的读取采样数据的指令,IN端是FPGA上报的内容。

至于为什么被覆盖掉的内容,一开始读出来不是0001、2001、2002、2003而是2004、2001、2002、2003。我猜想是因为当设定好突发长度的时候,SDRAM就根据设定把内容划分为一个一个类似与环形缓存的小模块,防止数据写乱到其他地方。所以当2001被写入到环形缓存的第二个地址时,依次类推,2004被环行写到小模块的第一个地址。而读取的时候是从第一个地址读出来。所以会有2004、2001、….的情况。这只是猜想..

结论

突发读写的时候,SDRAM默认是先把某一行的内容先写满(即列地址自动累加)。也可以理解为横向突发读写。所以在突发读写的时候,地址的映射很关键。逻辑控制的地址的低位应该映射到SDRAM的列地址。

你可能感兴趣的:(FPGA)