相关文章:
1.Altera的单时钟同步FIFO,带almost_empty和almost_full端口https://blog.csdn.net/qq_39485231/article/details/105345164
2.Altera的单时钟同步FIFO,带empty和full端口https://blog.csdn.net/qq_39485231/article/details/105351146
3.Altera的异步FIFO,读写用同频不同相时钟https://blog.csdn.net/qq_39485231/article/details/105352597
4.Altera的异步FIFO学习心得https://blog.csdn.net/qq_39485231/article/details/105364241
Altera的单时钟同步FIFO,带empty和full端口
程序
程序可以参考我的另外一篇文章: Altera的单时钟同步FIFO,带almost_empty和almost_full端口
只需要修改一下顶层文件的端口连接,和删除FIFO的部分接口。
单时钟同步FIFO,带empty和full端口
首先让Quartus根据我们的需要生成FIFO
1. full置位时
这里我们来看用ModelSim仿真的结果:
可以从图中发现当usedw等于0后,立马把full置位。置位一个时钟周期后,wrreq被拉低,rdreq被拉高,这也与程序的定义吻合。
大家可以发现一个问题,当usedw记到255之后,再写入一个就变成0了,这也是FIFO的特点。想知道详细的原因可以查阅相关资料。在仿真图可以看到当usedw为0,即FIFO写满后,wrreq还持续了一个T,所以这个时候仍然在写入,但是数据是没有写进去的。这也是为什么有almost_empty和almost_full端口的意义
2. empty置位时
这里我们来看用ModelSim仿真的结果:
可以从图中发现当usedw等于0后,立马把empty置位。置位一个时钟周期后,wrreq被拉高,rdreq被拉低,这也与程序的定义吻合。
大家可以发现一个问题,在仿真图可以看到当usedw为0,即FIFO读空后,rdreq还持续了一个T,所以这个时候仍然在读出,数据是保持上次的输出值,但其实这个时候读出的是无效数据,因为FIFO已经空了。
3. 总结
- 单时钟同步FIFO在读写时都有一个时钟周期延时,即wrreq置位后不能立马写入数据,一个T后,数据才会成功写进FIFO;当rdreq置位后不能立马读出数据,一个T后,数据才会成功从FIFO中读出,可以发现和RAM的机制类似。
- usedw和写入、读出数据是同步更新的,当读出最后一个数据,usedw同时也复位为0,写入时同理。当FIFO写满时usedw是为0的,当FIFO读空时,usedw也是0,但两个0代表值不同.
- 这个程序在读数据时,当读空FIFO之后还多读了一个T,这个读出是错误的数据; 这个程序在写数据时,当写满FIFO之后还多写了一个T,此时数据并没有写入。
解决办法1:添加almost_empty和almost_full端口,用这两个端口控制起始,而不用empty和full信号!!!以后写程序尽量都用almost_empty和almost_full端口
解决办法2:直接用usedw来控制,虽然和almost_empty和almost_full的机制一致,但是各有优缺点,根据不同的场合进行选择。
以后写程序不用empty和full信号控制FIFO的读写起始 - 在向FIFO写数据时,他的输出端q会保持最后一次输出的值。
- full置位是在FIFO写满,usedw变为0的时刻,此时记满溢出;empty置位是在FIFO读空,usedw变为0的时刻。