双口RAM输出数据丢失问题
在实验室培训过程留下的作业中有一道题是用RAM实现乒乓操作,然后我们在设计完成进行仿真时,发现每次读数据的最后总会出问题,总会丢失最后一个写入的数据,经过不断地尝试和检查,在解决掉其他小问题后发现真双口RAM在输出数据时,会丢掉最后一个数据。(仿真写入5个数据,从向地址4写入11开始)
首先问题可能出现在两个地方,写部分或读部分出错。
1.写部分出错
该种情况下,我们将RAMA和RAMB读使能始终拉高,观察数据是否依然存在该情况,若没有丢失说明在读数据使能的时候出现问题,若问题依然出现那写数据部分出错,同时也不能保证读数据没有问题。
修改代码仿真后,观察doutA和doutB,可以发现数据是按预想中读出,且最后输出数据正确。因此将问题定位到读数据部分。
2.读数据出错
经过观察读地址和读数据会发现数据会晚于读使能信号两拍,正常情况下晚一拍即可。
观察发现读完第四个数据不读了,于是我们试图将读使能信号拉长一个cycle,操作方法是将读信号与读信号打拍之后的结果进行或,如此发现输出数据完整。
同时查阅资料后发现,在生成双口RAM时,勾选了Primitives Output Regeister,输出会进行一级寄存。
取消勾选重新生成IP核后,把读使能也改回原来的样子(不采用拉长一个cycle,读使能为高的时间依然是对应数据个数的cycle,实验中为5),输出数据完整。
再看看原来勾选时的波形,观察后发现,其实并不是丢掉数据,而是0被作为第一个读出来的数。
那么问题来了,如果只是进行一次寄存,那数据应该也只是晚一拍才到,为什么会直接丢掉最后一个数据15(从11开始写的)呢?并且在RAM里面其实并没有写入0这个数据。
我们猜想读使能信号的作用域可能有如下两种情况:
(1)读使能作用于RAM
这种情况下,进入寄存器的数据由如下数据构成{data4,…,data0},这样每一个时钟边沿到来后,数据就会被送出到寄存器的输出端口,顺序依次是data0、data1、…、data4,这里不用管还没使能时寄存器的数据输入端口为0,因为复位后的下一个时钟沿数据已经被送出去,只要data数据到来下一个上升沿直接将{data4,…,data0}送出。这种情况下数据应该是正常的完整的,所以可能不是此种结构。
(2)读使能同时作用于用来缓冲的寄存器
这种结构下,读使能rd_en同时作用于寄存器,因此因此当rd_en到达后,寄存器将复位后或初始状态时寄存器数据输入端口的0读出来,同时data0从RAM中读到寄存器的输入端口,此时已经消耗掉rd_en的一个周期,因此接下来只剩下4个周期用来读数据,所以最终只能读出data0-data3。
最后可参考下文,其中也内嵌了其他参考文章的链接。
双口RAM的读数据延迟
评论记录:
回复评论: