更新一波代码以及测试,之前的输出没有用寄存器输出。
这次改进的代码加入了将满almost_full以及将空almost_empty信号

Verilog代码

module async_FIFO_01 #(parameter data_width = 8,addr_width = 6,depth = 64,almost_full_gap = 50,almost_empty_gap = 10)(  input rst_n,        //复位input wr_clk,       //写时钟input wr_en,       //写使能信号input [data_width-1:0] data_in,      //外部输入数据input rd_clk,       //读时钟input rd_en,       //读使能output [data_width-1:0] data_out,  //数据输出output reg full,output reg empty,output reg almost_full,output reg almost_empty);reg [addr_width:0] wr_addr_ptr,wr_addr_ptr_next;         //write address pointerreg [addr_width:0] rd_addr_ptr,rd_addr_ptr_next;     //read address pointerwire [addr_width:0] wr_addr_ptr_gray;wire [addr_width:0] rd_addr_ptr_gray;reg [addr_width:0] wr_addr_ptr_gray_1,wr_addr_ptr_gray_2;reg [addr_width:0] rd_addr_ptr_gray_1,rd_addr_ptr_gray_2;reg [addr_width-1:0] wr_addr;                         //write addresswire [addr_width-1:0] wr_addr_next;                  reg [addr_width-1:0] rd_addr;                           //read addresswire [addr_width-1:0] rd_addr_next;               wire full_next,empty_next;wire almost_full_next,almost_empty_next;assign SRAM_wr_en = wr_en && !full_next;assign SRAM_rd_en = rd_en && !empty_next;   //write address pointer updatealways @ (*)if (!rst_n)wr_addr_ptr_next = 'b0;else if (wr_en && !full_next)wr_addr_ptr_next = wr_addr_ptr + 1'b1;elsewr_addr_ptr_next = wr_addr_ptr;//read address pointer updatealways @ (*)if (!rst_n)rd_addr_ptr_next = 'b0;else if (rd_en && !empty_next)rd_addr_ptr_next = rd_addr_ptr + 1'b1;elserd_addr_ptr_next = rd_addr_ptr;//write and read address updateassign wr_addr_next = wr_addr_ptr_next[addr_width-1:0];assign rd_addr_next = rd_addr_ptr_next[addr_width-1:0];//写地址指针格雷码转换assign wr_addr_ptr_gray = (wr_addr_ptr >> 1) ^ wr_addr_ptr;//读地址指针格雷码转换assign rd_addr_ptr_gray = (rd_addr_ptr >> 1) ^ rd_addr_ptr;//写地址指针格雷码同步到读时钟域always @ (posedge rd_clk or negedge rst_n)if (!rst_n)beginwr_addr_ptr_gray_1 <= 'b0;wr_addr_ptr_gray_2 <= 'b0;endelsebeginwr_addr_ptr_gray_1 <= wr_addr_ptr_gray;wr_addr_ptr_gray_2 <= wr_addr_ptr_gray_1;end//读地址指针格雷码同步到写时钟域always @ (posedge wr_clk or negedge rst_n)if (!rst_n)beginrd_addr_ptr_gray_1 <= 'b0;rd_addr_ptr_gray_2 <= 'b0;endelsebeginrd_addr_ptr_gray_1 <= rd_addr_ptr_gray;rd_addr_ptr_gray_2 <= rd_addr_ptr_gray_1;end//同步过后的格雷码进行二进制转换,用于产生将空将满wire [addr_width:0] wr_addr_ptr_gray_to_bin;wire [addr_width:0] rd_addr_ptr_gray_to_bin;assign  wr_addr_ptr_gray_to_bin[addr_width] = wr_addr_ptr_gray_2[addr_width];assign  rd_addr_ptr_gray_to_bin[addr_width] = rd_addr_ptr_gray_2[addr_width];genvar i;generatefor (i=0;i<addr_width;i=i+1)beginassign wr_addr_ptr_gray_to_bin[i] = wr_addr_ptr_gray_2[i]^wr_addr_ptr_gray_to_bin[i+1];assign rd_addr_ptr_gray_to_bin[i] = rd_addr_ptr_gray_2[i]^rd_addr_ptr_gray_to_bin[i+1];endendgenerate//full_next信号产生assign full_next = ({~wr_addr_ptr_gray[addr_width:addr_width-1],wr_addr_ptr_gray[addr_width-2:0]}) == rd_addr_ptr_gray_2 ? 1'b1:1'b0;//empty_next信号产生assign empty_next = wr_addr_ptr_gray_2 == rd_addr_ptr_gray ? 1'b1: 1'b0;reg [addr_width-1:0] data_avail;reg [addr_width-1:0] room_avail;//data_avail信号生成,用于进行将满判断always @ (*)beginif (wr_addr_ptr[addr_width]!=rd_addr_ptr_gray_to_bin[addr_width])beginif (wr_addr_ptr[addr_width-1:0]==rd_addr_ptr_gray_to_bin[addr_width-1:0])data_avail = depth-1;elsedata_avail = depth-(rd_addr_ptr_gray_to_bin[addr_width-1:0]-wr_addr_ptr[addr_width-1:0]);endelsedata_avail = wr_addr_ptr[addr_width-1:0]-rd_addr_ptr_gray_to_bin[addr_width-1:0];endassign almost_full_next = (data_avail >= almost_full_gap)? 1'b1: 1'b0;//room_avail信号生成,用于进行将空判断always @ (*)beginif (rd_addr_ptr[addr_width]==wr_addr_ptr_gray_to_bin[addr_width])beginif (wr_addr_ptr_gray_to_bin[addr_width-1:0]==rd_addr_ptr[addr_width-1:0])room_avail = depth-1;elseroom_avail = depth-(wr_addr_ptr_gray_to_bin[addr_width-1:0]-rd_addr_ptr[addr_width-1:0]);endelseroom_avail = rd_addr_ptr[addr_width-1:0]-wr_addr_ptr_gray_to_bin[addr_width-1:0];endassign almost_empty_next = (room_avail >= (depth-almost_empty_gap))? 1'b1:1'b0;//输出信号打拍always @ (posedge wr_clk or negedge rst_n)if (!rst_n)beginwr_addr_ptr <= 'b0;full <= 'b0;almost_full <= 'b0;wr_addr <= 'b0;endelsebeginwr_addr_ptr <= wr_addr_ptr_next;full <= full_next;almost_full <= almost_full_next;wr_addr <= wr_addr_next;endalways @ (posedge rd_clk or negedge rst_n)if (!rst_n)beginrd_addr_ptr <= 'b0;empty <= 'b0;almost_empty <= 'b0;rd_addr <= 'b0;endelsebeginrd_addr_ptr <= rd_addr_ptr_next;empty <= empty_next;almost_empty <= almost_empty_next;rd_addr <= rd_addr_next;end//模块例化sram m0 (.wr_clk (wr_clk),.wr_en (SRAM_wr_en ),.wr_addr (wr_addr),.rd_clk (rd_clk),.rd_en (SRAM_rd_en ),.rd_addr (rd_addr),.data_in (data_in),.data_out (data_out));
endmodule

SRAM模块

module   sram  #(parameter data_width = 8,addr_width = 6,depth = 64,almost_full_gap = 50,almost_empty_gap = 20)(input   wr_clk,input    wr_en,input   [addr_width-1:0] wr_addr,input   rd_clk,input   rd_en,input   [addr_width-1:0] rd_addr,input   [data_width-1:0] data_in,output reg [data_width-1:0] data_out);//存储阵列定义reg [data_width-1:0] SRAM_MEM [depth-1:0];//数据写入always @ (posedge wr_clk)if (wr_en)SRAM_MEM [wr_addr] <= data_in;elseSRAM_MEM [wr_addr] <= SRAM_MEM [wr_addr];//数据读出always @ (posedge rd_clk)if (rd_en)data_out <= SRAM_MEM [rd_addr];elsedata_out <= 'b0;
endmodule

testbench文件


`timescale 1ns / 1psmodule sim_async_FIFO_01;parameter          data_width = 8,addr_width = 6,depth = 64,almost_full_gap = 50,almost_empty_gap = 10;reg rst_n;reg wr_clk;reg wr_en;reg [data_width-1:0] data_in;reg rd_clk;reg rd_en;wire [data_width-1:0] data_out;wire full;wire empty;wire almost_empty;wire almost_full;async_FIFO_01 x1( .rst_n(rst_n),.wr_clk(wr_clk),.wr_en(wr_en),.data_in(data_in),.rd_clk(rd_clk),.rd_en(rd_en),.data_out(data_out),.full(full),.empty(empty),.almost_full(almost_full),.almost_empty(almost_empty));initialbeginwr_clk = 1'b0;rst_n = 1'b0;wr_en = 1'b0;rd_clk = 1'b0;rd_en = 1'b0;data_in = 8'b1111_1111;#40 rst_n = 1'b1;#40 wr_en = 1'b1;#20 data_in = 8'b1001_1011;#20 data_in = 8'b0010_1011;#20 data_in = 8'b1001_0000;#20 data_in = 8'b0000_1011;#20 data_in = 8'b1001_1101;#1200 rd_en = 1'b1;#500 wr_en = 1'b0;#20 data_in = 8'b1001_0000;#20 data_in = 8'b0000_1011;#20 data_in = 8'b0000_0000;#20 data_in = 8'b0010_1011;#20 data_in = 8'b0000_1101;#3000 rd_en = 1'b0;endalways #10 wr_clk = ~wr_clk;always #20 rd_clk = ~rd_clk;endmodule

功能仿真结果

异步FIFO代码(包含almost_full以及almost_empty信号),测试代码,功能仿真结果相关推荐

  1. 异步FIFO的原理以及可综合的Verilog代码

    异步FIFO的原理以及可综合的Verilog代码 一.FIFO的定义 二.FIFO的应用场景 三.FIFO的分类 FIFO的参数 FIFO的设计难点 一.FIFO的定义 _ First In Firs ...

  2. python测试代码怎么写_python unittest编写测试代码

    做开发的朋友在写代码的同时一般都会写测试代码,这对于做运维的同学却很少用. 今天我们就来写写测试代码,用unittest模块. cat test.py import unittest def IsOd ...

  3. linux编译测试代码,rtc在linux上的测试代码

    点击(此处)折叠或打开 rtc在linux上的测试代码 . rtc应用很广泛,在PC机和嵌入式上面几乎都能看到.下面就用最简单的代码做一个演示.相应的分析请看linux源代码中的分析文档.代码如下: ...

  4. 支持异步通知的globalfifo平台设备驱动程序及其测试代码

    驱动: #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #incl ...

  5. 异步fifo的设计与验证

    书接上文,上一篇介绍了略简单的同步fifo,接下来开始较为复杂的异步fifo. 1.同步fifo与异步fifo的区别 当设计中只有一个时钟时,所有的寄存器否用同一个,不会出现传输速度不匹配的情况:但是 ...

  6. IC学习笔记3——异步FIFO

    IC学习笔记3--异步FIFO 异步FIFO的工作内容与同步FIFO类似,但是异步FIFO的控制并不像同步FIFO那么简单,因为异步FIFO工作在不同的时钟域,这将会带来一些问题,比如空满检测?是否还 ...

  7. 跨时钟域方法(同步器、异步FIFO、边沿检测器、脉冲同步器、同步FIFO)

    目录 1.跨时钟域方法的原因 2.跨时钟处理的两种思路 3.跨时钟域分类--单比特信号跨时钟 3.1.1慢时钟---快时钟.(满足三边沿准则,有效事件可以被安全采样) 3.1.2慢时钟---快时钟.( ...

  8. 代码的印象派:写点好代码吧

    最近有一位猎头顾问打电话询问是否有换工作的意向,对推荐的公司和职位的描述为:"我们这里有一家非常关注软件质量的公司,在寻找一位不仅能完成有挑战的软件开发任务,并且还对代码质量有非常高追求的软 ...

  9. mvn编写主代码与测试代码

    maven编写主代码与测试代码 3.2 编写主代码 项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中(比如jar),而测试代码只在运行测试时用到,不会被打包.默认情况下,Maven假设项目 ...

最新文章

  1. 树莓派修改密码(有单独屏幕)
  2. 半导体理论(第1部分)本征半导体
  3. python中实现延时回调普通函数示例代码
  4. html如何调整背景图片大小_如何快速调整证件照背景色和大小!(简单快速)...
  5. 驰骋表单设计器 设计表单案例演示
  6. 【Clickhouse】Clickhouse 普通视图
  7. 征集公开课内容的建议
  8. MyApplicationToast工具类
  9. c226打印机驱动安装_打印机驱动怎么安装?
  10. w ndows7运行命令,如何打开Win7命令提示符cmd.exe窗口
  11. macbook外接键盘后ctrl键设置
  12. C#从sqlite3中读数据到DataTable中报错 :System.Data.ConstraintException:“未能启用约束。一行或多行中包含违反非空、唯一或外键约束的值。
  13. 计算机cpu电源的diy,DIY台式电脑正确选择电源的新方法
  14. 中国象棋AI实现01
  15. 同济大学计算机学院东华大学,东华大学原校长蒋昌俊调任同济大学正局级副校长...
  16. python将图片转成灰度图
  17. 【HTML5】H5新标签大实例
  18. 【店小蜜】基础介绍-全自动模式
  19. 高斯模糊的算法(高斯权重)
  20. linux中文件类型说明及文件权限

热门文章

  1. R语言Logistic回归模型案例(绘制列线图、校正曲线):研究低出生体重婴儿的核心影像因素
  2. 搜题公众号怎么搭建制作(微信公众号查题搭建制作教程)
  3. python实现逻辑回归三种方法_纯Python实现逻辑回归
  4. 手把手教学IOS自定义cell-仿微信消息列表
  5. 32位Windows7上8G内存使用感受+xp 32位下使用8G内存
  6. 【Ubuntu20.04安装出现Turn Off RST错误解决方案】
  7. 微信好友删除了怎么恢复「轻松一键恢复好友」
  8. php 环信easyui_环信即时通讯---php版
  9. Acwing算法基础【1】基础(三)前缀和与差分
  10. 多核cpu应用场景_多核?高频?不同需求哪种CPU最适合自己呢?