FIFO简介:First in First out,先进先出的数据结构。只能顺序的读入数据,顺序的读出数据。

使用RAM进行建模。设计相应的控制模块,控制RAM中的数据写入和读取,先写入的数据先读取。

深度为16的FIFO,将读写指针位宽设置为5位,但是取低四位作为读取RAM的地址。原因如下:

当读写指针相等时,可以得出FIFO为空。

当继续读取数据,读指针达到15之后,如果再继续写入数据,写指针最高位第五位会变为1,由于取其第四位作为RAM地址,会返回到第0位写入数据,直到写入到地址2。

继续读取数据,直到读指针为11100,此时读写指针低四位相等,最高位相反,可以得出FIFO为满。

具体代码:

`timescale 1ns / 1ns

module Syn_FIFO #(

parameter DEPTH = 16,//FIFO深度

parameter WIDTH = 8,//FIFO内数据位宽

parameter P_WIDTH = 5//读写指针位宽

)

(

input rst_n

,input clk

,input [WIDTH-1:0] Data_Write //写入的数据值

,input Write_Sig//写入数据使能

,input Read_Sig//读取数据使能

,output wire [WIDTH-1:0] Data_Read //读取的数据值

,output wire Full_Sig//FIFO为空信号

,output wire Empty_Sig//FIFO为满信号

);

reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];

reg [P_WIDTH-1:0] Read_pointer;

reg [P_WIDTH-1:0] Write_pointer;

reg [WIDTH-1:0] rData_Read;

assign Full_Sig = ((Read_pointer[P_WIDTH-2:0]==Write_pointer[P_WIDTH-2:0])

&&(Read_pointer[P_WIDTH-1] != Write_pointer[P_WIDTH-1]))? 1'd1:1'd0;

assign Empty_Sig = (Read_pointer[P_WIDTH-1:0]==Write_pointer[P_WIDTH-1:0])? 1'd1:1'd0;

always @(negedge rst_n or posedge clk) begin

if (!rst_n)

begin

rData_Read <= 0;

Read_pointer <= 0;

Write_pointer <= 0;

end

else begin

if (~Full_Sig && ~Empty_Sig && Read_Sig && Write_Sig ) //非空非满时同时读写

begin

rData_Read <= RAM_MEM[Read_pointer[P_WIDTH-2:0]];

RAM_MEM[Write_pointer[P_WIDTH-2:0]] <= Data_Write;

Read_pointer <= Read_pointer + 1'd1;

Write_pointer <= Write_pointer + 1'd1;

end //

else if (~Empty_Sig && Read_Sig )//非空时读数据

begin

rData_Read <= RAM_MEM[Read_pointer[P_WIDTH-2:0]];

Read_pointer <= Read_pointer + 1'd1;

end

else if (~Full_Sig && Write_Sig)//非满时写数据

begin

RAM_MEM[Write_pointer[P_WIDTH-2:0]] <= Data_Write;

Write_pointer <= Write_pointer + 1'd1;

end

end // else

end // always

assign Data_Read = rData_Read;

endmodule

testbench中的数据读写task如下,完整文件查看源码:

//testbench写数据的task

task Write_Data(input reg Write_en,input reg [7:0] Data_in);

begin

@(posedge clk)

if(Full_Sig) begin //testbench检测到FIFO为满,关闭写使能

Write_Sig <= 1'b0;

Data_Write <= 8'd0;

end

else begin

Write_Sig <= Write_en; //testbench检测到FIFO不满,写入数据

Data_Write <= Data_in;

end

end

endtask

//testbench读数据的task

task Read_Data(input reg Read_en);

begin

@(posedge clk)

if(Empty_Sig)

Read_Sig <= 1'b0;

else Read_Sig <= Read_en;

end

endtask

Testbench通过检测FIFO的Full_Sig和Empty_Sig判断FIFO的空满状态,来判断数据是否写入读取,还是应该关闭读\写的使能。

上图波形图中,考虑连续写入FIFO 16个数据的情形,在1处时钟上升沿,第16个数据192被写入,读指针和写指针相等,在这个时钟上升沿之后,2处Full_Sig被拉高。

但是对于Testbench而言,在1处的时钟上升沿,Testbench检测出Full_Sig还是为0(因为这个时钟上升沿之后,Full_Sig才被拉高),所以Testbench得出的判断是此时FIFO还没满,所以在时钟上升沿之后驱动Write_Sig继续为高,驱动Data_Write为204,计划再写入一个数据进去。

但是在3处时钟上升沿,对于FIFO而言,检测到Full_Sig已经被拉高,所以1处Testbench驱动的数据204并不会被FIFO采集并写入FIFO。

由此错误的判断便导致数据204的丢失,即Testbench以为把数据写入FIFO了,然而其实没有写入,如果Testbench替换为其他设计模块,也会导致这样的问题

对于读FIFO也是如此,从满FIFO中连续读取16个数据,在1处时钟上升沿,第16个数据被读出,即192。在该时钟上升沿之后,Empty_Sig被拉高,2处。

但是对于Testbench而言,在1处时钟上升沿,Testbench检测到Empty_Sig为低,所以驱动Read_Sig继续为高,到3处时钟上升沿之后,Read_Sig才被拉低。

在3处时钟上升沿,由于Read_Sig还是为高,所以对于Testbench而言,他以为自己从FIFO中读取又读取了一个数据192,但实际上是重复读取的FIFO中最后的一个数值。

结论:对于同步FIFO,空满信号时“假的”,并不能给外部读写的其他模块一个准确的判断。

同步fifo的串并_同步FIFO笔记相关推荐

  1. 同步fifo的串并_同步FIFO设计Spec(示例代码)

    为什么要写Spec文档: 记得刚进公司实习的时候,导师安排我写一个SM4算法AHB接口模块,要求写代码前 写出详细的设计文档,详细到什么程度呢,看着文档就能把代码写好,作为一个只 在学校写过数字钟的小 ...

  2. 同步fifo的串并_同步fifo

    利用verilog实现FIFO 摘要:本文先介绍了一下关于FIFO的基本概念,工作原理,功能,同步与异步的分类等.然后基于RAM实现了一个同步FIFO.该FIFO通过巧妙地应用地址位和状态位的结合实现 ...

  3. 同步电复律英文_同步电复律与非同步电复律有什么区别?

    展开全部 同步电除颤的适应症是治疗--房颤.房扑.室32313133353236313431303231363533e59b9ee7ad9431333365653161上速.室速等快速心律失常,经电除 ...

  4. 同步电复律英文_同步电复律操作规程

    同步电复律操作规程 目的 中止血液波动力学不稳定的心动过速性心律失常, 同时也可将血液动力 学稳定的房颤或房扑转为窦律. 相关知识 1 同步电复律是指同步触发装置能利用患者心电图中 R 波来触发 放电 ...

  5. java 同步与异步区别_同步和异步有何异同,在什么情况下分别使用它们?

    2015-05-12 06:30:01 阅读( 4 ) 通俗版:举个例子:普通B/S模式(同步)AJAX技术(异步) 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器 ...

  6. 7 centos 时钟跟物理机同步_同步FIFO和异步FIFO

    1.定义 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出 ...

  7. 74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码

    1.  异步FIFO的概念 异步FIFO为读取与写入采用不同的时钟,使用异步FIFO用于在不同的时钟域传输数据,主要用于跨时钟域传输多bit数据. 2.  异步FIFO的设计难点 同步异步信号,避免亚 ...

  8. java同步互斥功能检测_猿考研之操作系统篇三(进程同步,管程,死锁)

    进程同步 进程具有异步性的特征.异步性是指,各并发执行的进程以各自独立的.不可预知的速度向前推进. 同步机制应遵循的准则 空闲让进:其他进程均不处于临界区: 忙则等待:已有进程处于其临界区: 有限等待 ...

  9. PIC单片机入门_同步/异步通信技术基础

    1.前言 通用同步 / 异步收发器 (Universal Synchronous/Asynchronous Receiver/Transmitter, USART) 模块是两个串行 I/O 模块之一 ...

最新文章

  1. 栖息在生态办公室,裸心社与USGBC达成战略合作
  2. hdfs 数据迁移_基于JindoFS+OSS构建高效数据湖
  3. android 点击图片事件,android图文混排点击事件
  4. python语言的数字类型_基本数据类型数字
  5. 震惊世界的亚洲8大奇迹,你都知道几个?
  6. python模块学习(1)
  7. 将ESXi加入到vCenter中进行管理
  8. java集群解析文件_java相关:springboot整合redis集群过程解析
  9. 百度AI开放平台学习——EasyDL经典版-图像分类模型训练与验证
  10. 无需重装系统,Windows Server 2019系统硬盘无损从MBR转换为GPT格式
  11. openharmony容器组件之Panel
  12. [保姆级教程] 从原理到应用,超级详细的MPU6050传感器整理,看完这一篇就够了
  13. kettle 9.1 连接hadoop clusters (CDH 6.2)
  14. blender合并物体后材质丢失问题的解决办法
  15. DEL命令居然无法删除文件夹!
  16. Rectangle用法简介
  17. mysql sleep详解_MySQL Sleep进程
  18. (一 附)多进程 多线程 与 cpu 、操作系统
  19. oracle to char中文乱码,Oracle to_char函数的使用方法
  20. C语言判断读取的文件内容字符编码是UTF-8还是GBK

热门文章

  1. vue+webpack实践
  2. 虚拟机中加载物理机的硬盘和分区
  3. Struts2,在Action中使用session
  4. 联想亮出智能手机全面投身移动互联网
  5. Linux 命令(132)—— groupadd 命令
  6. 2018年全国多校算法寒假训练营练习比赛(第四场)F:Call to your teacher
  7. CANopen笔记2
  8. Angular2 管道
  9. python vimIDE环境
  10. JavaScript获取文本框光标的像素位置(转载)