在上篇博客中,我们只是进行突发读写,没有使用读写fifo对ddr3进行读写,因ddr3读写接口都是256位宽,所以ddr3的读写fifo输入和输出都是32位,和ddr3对接的接口都是256位,如下面示意图所示。下面的截图为ddr3的fifo读写功能示意图,本章节侧重于对write_fifo和read_fifo的仿真
调用写fifo
选择Block RAM
设置写宽度为32,读宽度为256,设置高电平复位
选择默认
勾选读写数据计数
点OK,完成fifo配置
点击Generate,生成fifo模块
调用读fifo
选择Block RAM
设置写位宽为256,设置读位宽为32位,并且设置高电平复位
选择默认
勾选读写数据计数
点OK,完成fifo配置
点击Generate,生成fifo模块
仿真工程加入读写fifo,如下图所示
将写fifo模块例化到test_tb仿真工程里,如下图所示
写fifo
可以看到wr_en为1写入了0~15一共16个数据,但fifo的写计数wr_data_count输出为8也就是总数据的一半,而fifo读计数rd_data_count输出为1也就是fifo写计数wr_data_count的8分之一。
ddr的写入和读出宽度都是256,也就是8个32位数据。从上图我们可以看出写入16个32位数据,写fifo的写计数wr_data_count为8,读计数的rd_data_count为1,而我们突发读写章节可以看到,设置4个写突发也就是写入4个256位宽度的数据,也就是32个32位数据,那么fifo写计数wr_data_count为16,而fifo读计数rd_data_count为2。可以看出ddr的突发读写,如果使用fifo读计数的rd_data_count就能和ddr的突发读写对上,比如我们ddr需要突发传输4次也就是4个256位宽的数据,那么只需fifo读计数rd_data_count为2就能刚好fifo写入4个256位数据,当然如果为了更加保险可以让fifo读计数rd_data_count为4再进行一次突发传输。
我们验证一下,写入32个32位数据,看是否和我们计算的一样,从下图可以看出写入0~31一共32个数据,写fifo计数wr_data_count为16,读fifo计数rd_data_count为2,和我们上面计算的一样,所以ddr写突发传输我们使用写fifo计数rd_data_count这个计数值来触发wr_len_en写突发使能信号
验证fifo写入数据和读出数据是否一样,从图中可以看到fifo写入的最后一个数据是1f,rd_data_count为2时产生一个读使能,读出来了四个256位宽的数据,读完成后fifo的empty信号拉高,代表数据都读出为空了。
读出的第一个数据8个32位数据0~7
读出的第二个数据8个32位数据8~f
读出的第三个数据8个32位数据10~17
读出的第四个数据8个32位数据18~1f,可以看到最后一个数据和我们写入的是一样的,都是1f,整个写fifo测试完成
读fifo
从下面的截图我们可以看出,一共写入四个256位宽的数据,fifo的写数据计数wr_data_count为4,fifo的读数据计数rd_data_count为32,我们刚好写入的是32个32位也就是4个256位,所以fifo写计数wr_data_count为实际写入的256位数据的个数,也就是ddr输入接口位宽的数据个数为4,而读计数的rd_data_count为输出接口32位宽的数据的个数为32
可以看到ddr读突发里面输出数据是256位的,所以fifo的输入数据数量,最好使用fifo写计数器wr_data_count的计数值来触发rd_len_en突发读使能信号,这样能刚好和输入的256位宽数据个数对应
再来看写入fifo的数据和读出fifo的数据是否一致,当wr_data_count为4时触发fifo读使能信号,一共读出32个32位数据
读出32位数据,从0~18一共19个数据
读出32位数据,从19~31一共13个数据,可以看出一共读出了32个32位数据,写入的最后一个数据为31化成16进制也就是1f,可以看出读写数据是一致的,并且empty信号拉高,说明fifo数据都读空了。
整体的ddr的读写fifo仿真就到这里,如果哪里写的有问题,欢迎各位指正
如若转载,请注明出处