上一篇博客基于System verilog的同步FIFO实现(一)
通过设置一个计数器,来判断FIFO的空或满状态,该方法由于多设置了一个计数器,因此会产生额外的资源,当fifo比较大时,会降低fifo最终可以达到的速度。本文则通过另一种方式生成full与empty信号:比较读指针和写指针
判断方法:
1.当FIFO复位之后,读指针和写指针的都指向第0个位置,此时FIFO为空;
2.当写指针绕了一圈又追上读指针后,即wr_ptr=rd_ptr,此时FIFO为满;
3.当读指针也绕了一圈追上写指针后,即wr_ptr=rd_ptr,此时FIFO为空。
鉴于上述判断方法,为了区分到底是满状态还是空状态,可以采用以下方法进行电路的设计:
在指针中添加一个额外的位(extra bit),当写指针增加并越过最后一个FIFO地址时,就将写指针这个未用的MSB加1,其它位回零。对读指针也进行同样的操作。此时,对于深度为2n2^n2n的FIFO,需要的读/写指针位宽为(n+1)(n+1)(n+1)位,如对于深度为8的FIFO,需要采用4bit的计数器,MSB作为折回标志位,而低3位作为地址指针。
如果两个指针的MSB不同,说明写指针比读指针多折回了一次,FIFO为满。
如果两个指针的MSB相同,则说明两个指针折回的次数相等。其余位相等,说明FIFO为空。

代码如下:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/22 00:05:11
// Design Name:
// Module Name: sync_fifo
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module sync_fifo
#(parameter DATA_WIDTH = 32,parameter FIFO_DEPTH = 32)
(
input logic clk,
input logic rst,
input logic wr_en,
input logic [DATA_WIDTH-1:0] wdata,
input logic rd_en,
output logic [DATA_WIDTH-1:0] rdata,
output logic full,
output logic empty);
logic [$clog2(FIFO_DEPTH)-1:0] wr_ptr;                  //指向下一个要写的地址
logic [$clog2(FIFO_DEPTH)-1:0] rd_ptr;                  //指向下一个要读的地址
logic [$clog2(FIFO_DEPTH):0] wr_addr;                   //最高位用来标记空满
logic [$clog2(FIFO_DEPTH):0] rd_addr;                   //最高位用来标记空满
//
assign wr_ptr=wr_addr[$clog2(FIFO_DEPTH)-1:0];
assign rd_ptr=rd_addr[$clog2(FIFO_DEPTH)-1:0];
//
logic [DATA_WIDTH-1:0] FIFO [0:FIFO_DEPTH-1];
//wr_addr
always_ff@(posedge clk,posedge rst)
if(rst)wr_addr<=0;                                    //复位时写指针为0
else if(wr_en&&~full)                             //写使能信号有效且fifo未满wr_addr<=wr_addr+1;
//rd_addr
always_ff@(posedge clk,posedge rst)
if(rst)rd_addr<=0;
else if(rd_en&&~empty)                            //写使能信号有效且FIFO非空rd_addr<=rd_addr+1;
//flag
assign full=(rd_addr=={~wr_addr[$clog2(FIFO_DEPTH)],wr_ptr})?1'b1:1'b0;
assign empty=(rd_addr==wr_addr)?1'b1:1'b0;
//write
always_ff@(posedge clk)
if(wr_en&&~full)FIFO[wr_ptr]<=wdata;
//read
always_ff@(posedge clk,posedge rst)          //rd_en拉高后的下一个周期读出
if(rst)rdata<=0;
else if(rd_en&&~empty)rdata<=FIFO[rd_ptr];
endmodule

测试平台如下,error信号为高说明fifo出错:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/22 00:27:44
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module test;
parameter DATA_WIDTH = 32;
parameter FIFO_DEPTH = 32;
logic wr_en_r;
logic rd_en_r;
logic clk;
logic rst;
logic wr_en;
logic rd_en;
logic [DATA_WIDTH-1:0] wdata;
logic [DATA_WIDTH-1:0] rdata;
logic empty;
logic full;
logic [DATA_WIDTH-1:0] ref_data;
logic rd_en_ff1;
logic error;
//ref_data
always_ff@(posedge clk,posedge rst)
if(rst)ref_data<=0;
else if(rd_en_ff1)ref_data<=ref_data+1;
//rd_en_ff1
always_ff@(posedge clk)rd_en_ff1<=rd_en;
//wr_en,rd_en
assign wr_en=(~full)?wr_en_r:1'b0;
assign rd_en=(~empty)?rd_en_r:1'b0;
//clk
initial beginclk=0;forever begin#5 clk=~clk;end
end
//rst
initial
beginrst=1;#20rst=0;
end
//wdata
always_ff@(posedge clk,posedge rst)
if(rst)wdata<=0;
else if(wr_en&&~full)                //每写入一个数据,加1wdata<=wdata+1;
//wr_en
always_ff@(posedge clk,posedge rst)
if(rst)wr_en_r<=0;
else if($random%100<80)               //有60%的几率写数据,衡量数据写入速率wr_en_r<=1'b1;
elsewr_en_r<=1'b0;
//rd_en
always_ff@(posedge clk,posedge rst)
if(rst)rd_en_r<=0;
else if($random%100<40)                //有40%的几率读数据,衡量数据读出速率rd_en_r<=1'b1;
else rd_en_r<=1'b0;
//check result
always_comb
if(rd_en_ff1&&ref_data!=rdata)error=1;
elseerror=0;//inst
sync_fifo
#(
.DATA_WIDTH(32),
.FIFO_DEPTH(32)
)
U
(.*);
// input logic clk,
// input logic rst,
// input logic wr_en,
// input logic [DATA_WIDTH-1:0] wdata,
// input logic rd_en,
// output logic [DATA_WIDTH-1:0] rdata,
// output logic full,
// empty
endmodule

仿真波形如下图所示,可以看到error信号始终为低电平,说明设计无误。

基于System verilog的同步FIFO实现(二)相关推荐

  1. 跨时钟域信号处理(二)——异步fifo的Verilog实现(附同步fifo的实现)

    需要回答几个问题: 1.什么是异步FIFO,异步FIFO有什么功能? 跨时钟域的数据交换,防止亚稳态. 2.在产生写满与读空信号时需要进行跨时钟域如何做的,且如何能正确指示空满状态? 寄存器打两拍+格 ...

  2. 同步FIFO和异步FIFO的Verilog实现

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

  3. 【FPGA——基础篇】同步FIFO与异步FIFO——Verilog实现

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

  4. 01 【Verilog实战】同步FIFO的设计(附源码RTL/TB)

    虚拟机:VMware -14.0.0.24051 环 境:ubuntu 18.04.1 脚 本:makefile(点击查看) 应用工具:vcs 和 verdi 写在前面 这个专栏的内容记录的是个人学习 ...

  5. 手把手Verilog HDL同步Vaild-Ready握手FIFO机制

    这里写目录标题 一级目录 二级目录 三级目录 1.V-R握手FIFO简介 2.先实现一个同步FIFO 2.1 FIFO简介 2.2 同步FIFO指标 2.3 同步FIFO设计 2.4 计数器法实现同步 ...

  6. 【FPGA】FIFO的Verilog设计之同步FIFO的设计

    这个同步FIFO的设计方法是调用异步读写双端口RAM来实现的. 关于异步读写双端口RAM的设计,前面博文已经讲到过了:[FPGA]双端口RAM的设计(异步读写) 此时使用双端口RAM来设计FIFO,可 ...

  7. (28)System Verilog进程间同步(事件event)

    (28)System Verilog进程间同步(事件event) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog进程间同步(事件eve ...

  8. (30)System Verilog进程间同步(邮箱mailbox)

    (30)System Verilog进程间同步(邮箱mailbox) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog进程间同步(邮箱m ...

  9. (29)System Verilog进程间同步(旗语semaphore)

    (29)System Verilog进程间同步(旗语semaphore) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog进程间同步(旗 ...

最新文章

  1. 2021年大数据Flink(十二):流批一体API Transformation
  2. 跨工厂物料状态/特定工厂的物料状态
  3. HTML5实战 学习笔记
  4. 微信小程序自定义组件
  5. UVA621 Secret Research【水题】
  6. 数据分析必备算法(算数平均值,加权平均值,最值,中位数,标准差,时间数据处理 ,数组的轴向汇总, 移动均线 ,卷积(简单概念))
  7. 黑盒测试和白盒测试的基本原理/区别是什么?
  8. 7个月吐血整理!Android面试相关文章及Github学习资料(标星3.2K)
  9. Maven项目集成cxf框架发布WebService
  10. 重磅!这可能是史上最全的AI产业链地图了
  11. 要成为游戏开发人员需要有以下书籍(二)
  12. 微信小程序:购物车总结(商品左右联动)
  13. 用命令提示符运行java_怎么用命令提示符运行java程序?
  14. STM32F407ZG 实现DMA收发数据
  15. VR全景照片拍摄小技巧分享
  16. MySQL Workbench构建ER图(实体关系图)
  17. 机器学习 逻辑回归算法应用案例
  18. MTK-手机锁等相关密码配置
  19. 全自动加药装置特点和组成部分以及操作过程介绍
  20. 飞鸽传书网,打造精准化生活搜索

热门文章

  1. 无效的 ProgID“ShockwaveFlash.ShockwaveFlash” 导入 progid 时遇到错误: “ShockwaveFlash.ShockwaveFlash”
  2. 俊成码付出修复版源码
  3. 如何做好项目工时管理?
  4. nginx 反向代理到域名
  5. 卡尔曼滤波与组合导航原理_基于RAEKF的GPS/INS紧组合导航方法研究
  6. 大教堂终将倒下,但集市永存
  7. Ros结合科大讯飞linuxSDK进行离线语唤醒、命令识别
  8. 001.网络TCP/IP工程知识点
  9. 肖锰:浪潮GS开发平台学习札记(五)——数据对象和数据模型
  10. java计算机毕业设计医护人员排班系统源码+系统+lw+数据库+调试运行