verilog 实现异步fifo

理论知识参考

异步FIFO_Verilog实现_verilog实现异步fifo_Crazzy_M的博客-CSDN博客

代码

/*
位宽8bit, 位深8
*/
module async_fifo#(parameter FIFO_DEPTH = 8,parameter FIFO_WIDTH = 8
)
(input       rst_n,input       wr_clk,input       wr_en,input [FIFO_WIDTH - 1:0] din,input    rd_clk,input    rd_en,output reg [FIFO_WIDTH - 1:0] dout,output     wire    full,output     wire    empty
);reg [FIFO_WIDTH - 1:0] mem [FIFO_DEPTH - 1:0];//地址的位数要满足fifo的位深
wire [2:0] wr_addr;
wire [2:0] rd_addr;//指针的位数和格雷码的位数要比地址位数大1位
reg [3:0] wr_addr_ptr;
reg [3:0] rd_addr_ptr;wire [3:0] wr_gray;
reg [3:0] wr_gray1;
reg [3:0] wr_gray2;wire [3:0] rd_gray;
reg [3:0] rd_gray1;
reg [3:0] rd_gray2;assign wr_addr = wr_addr_ptr;
assign rd_addr = rd_addr_ptr;//二进制转格雷码
assign wr_gray = (wr_addr_ptr >> 1) ^ wr_addr_ptr;
assign rd_gray = (rd_addr_ptr >> 1) ^ rd_addr_ptr;//判断异步FIFO空的条件:读写地址(格雷码)完全相同
assign empty = rd_gray == wr_gray2 ? 1'b1 :1'b0;//判断异步FIFO满的条件:读写地址(格雷码)的高2位不同,其余位均相同
assign full = ((wr_gray[3:2] != rd_gray2[3:2]) && (wr_gray[1:0] == rd_gray2[1:0])) ? 1'b1 : 1'b0;//写
always @(posedge wr_clk) beginif(wr_en && ~full)mem[wr_addr] <= din;else mem[wr_addr] <= mem[wr_addr];
endalways @(posedge wr_clk or negedge rst_n) beginif(!rst_n)wr_addr_ptr <= 0;else if(wr_en && ~full)wr_addr_ptr <= wr_addr_ptr + 1'b1;else wr_addr_ptr <= wr_addr_ptr; 
end//读
always@ (posedge rd_clk or negedge rst_n)if(!rst_n)rd_addr_ptr <= 0;else if(rd_en && ~empty)rd_addr_ptr <= rd_addr_ptr + 1'b1;elserd_addr_ptr <= rd_addr_ptr;always@ (posedge rd_clk or negedge rst_n)if(!rst_n)dout <= 11;else if(rd_en && ~empty)dout <= mem[rd_addr];else dout <= 11;//读地址格雷码同步到写时钟域
always @(posedge wr_clk or negedge rst_n)if(!rst_n) beginrd_gray1 <= 0;rd_gray2 <= 0;endelse beginrd_gray1 <= rd_gray;rd_gray2 <= rd_gray1;end//写地址格雷码同步到读时钟域
always@ (posedge rd_clk or negedge rst_n)if(!rst_n) beginwr_gray1 <= 0;wr_gray2 <= 0;endelse beginwr_gray1 <= wr_gray;wr_gray2 <= wr_gray1;endendmodule

testbench

`timescale 1ns/1psmodule fifo_tb ();reg rst_n;reg [7:0] data_in;reg wr_clk;reg rd_clk;reg wr_en;reg rd_en;wire [7:0]data_out;wire full;wire empty;async_fifo fifo(.wr_clk(wr_clk),//写时钟.rd_clk(rd_clk),//读时钟.rst_n(rst_n),//复位信号.wr_en(wr_en),//写使能.rd_en(rd_en),//读使能.din(data_in),//写入的数据.dout(data_out),//读出的数据.empty(empty),//读空信号.full(full)//写满信号);initial wr_clk = 0;//产生写时钟always #10 wr_clk = ~wr_clk;initial rd_clk = 0;//产生读时钟always #30 rd_clk = ~rd_clk;always@(posedge wr_clk or negedge rst_n)//产生写入的数据if(!rst_n)data_in <= 0;else if (wr_en) begindata_in <= data_in + 1'b1;endelsedata_in <= data_in;initial beginrst_n = 0;wr_en = 0;rd_en = 0;#200;rst_n = 1;wr_en = 1;#200;rd_en = 1;#200wr_en = 0;#1100rd_en = 0;#20000;$stop; endendmodule

觉得还不错请点赞,有建议请留言^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/66557.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker通用镜像方法,程序更新时不用重新构建镜像

docker通用镜像方法&#xff0c;程序更新时不用重新构建镜像。更新可执行文件后&#xff0c;重新启动容器就可运行。 功能 1、在demo目录下添加脚本文件start.sh&#xff0c;里面执行demo.jar文件。 2、将demo目录映射到镜像下的 /workspace目录。 3、Dockerfile文件中默认…

自动化更新导致的各种问题解决办法

由于最近自动化频频更新导致出现各种问题&#xff0c;因此在创建驱动对象代码时改成这种方式 我最近就遇到了由于更新而导致的代码报错&#xff0c;报错信息如下&#xff1a; 复制内容如下&#xff1a; Exception in thread “main” org.openqa.selenium.remote.http.Connecti…

JVM笔记 —— 出现内存溢出错误时时如何排查

一、出现内存溢出的几种情况 内存溢出错误分为StackOverflowError和OutOfMemoryError&#xff0c;前者是栈中出现溢出&#xff0c;后者一般是堆或方法区出现溢出&#xff0c;简称OOM 1. 栈溢出 StackOverflowError 栈溢出一般都是因为没有正确的结束递归导致的&#xff0c;无…

大数据课程I1——Kafka的概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Kafka的概念; ⚪ 掌握Kafka的配置与启动; 一、简介 1. 基本概念 Apache kafka 是一个分布式数据流平台。可以从如下几个层面来理解: 1. 我们可以向Kafka发布数据以及从Kafka订阅…

ARM--day2(cpsr、spsr、数据搬移指令、移位操作指令、位运算操作指令、算数运算指令、比较指令、跳转指令)

.text .global _gcd _gcd:mov r0,#9mov r1,#15b loop loop:cmp r0,r1beq stopsubhi r0,r1bhi loopsubcc r1,r0bcc loopstop:b stop.end用for循环实现1~100之间和5050 .text .global _gcd _gcd:mov r0,#0x0mov r1,#0x1mov r2,#0x64b loop loop:cmp r1,r2bhi stopadd r0,r0,r1ad…

Linux Day07

一、僵死进程 1.1僵死进程产生的原因 子进程先于父进程结束, 而父进程没有获取子进程退出码&#xff0c;释放子进程占用的资源&#xff0c;此时子进程将成为一个僵死进程。 在第一个框这里时父进程子进程都没有结束&#xff0c;显示其pid 父进程是2349&#xff0c;子进程是235…

MySQL高阶知识点(一)一条SQL【更新】语句是如何执行的

一条SQL【更新】语句是如何执行的 首先&#xff0c;可以确定的说&#xff0c;【查询】语句的那一套流程&#xff0c;【更新】语句也是同样会走一遍&#xff0c;与查询流程不一样的是&#xff0c; 更新语句涉及到【事务】&#xff0c;就必须保证事务的四大特性&#xff1a;ACID&…

【Megatron-DeepSpeed】张量并行工具代码mpu详解(四):张量并行版Embedding层及交叉熵的实现及测试

相关博客 【Megatron-DeepSpeed】张量并行工具代码mpu详解(四)&#xff1a;张量并行版Embedding层及交叉熵的实现及测试 【Megatron-DeepSpeed】张量并行工具代码mpu详解(三)&#xff1a;张量并行层的实现及测试 【Megatron-DeepSpeed】张量并行工具代码mpu详解(一)&#xff1a…

【C++】开源:abseil-cpp基础组件库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍abseil-cpp基础组件库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#…

小程序具体开发

window 导航栏 属性名类型默认值作用navigationBarTitleText string字字符串导航栏标题内容navigationBarBackgroundColorHexcolor#000000设置导航栏背景颜色&#xff08;比如荧黄色 #ffa&#xff09;navigationBarTextStylestringwhite设置导航栏标题的颜色&#xff08;仅含有…

在 Windows 上安装 OpenCV – C++ / Python

在这篇博文中&#xff0c;我们将在 Windows 上安装适用于 C 和 Python 的 OpenCV。 C 安装是在自定义安装 exe 文件的帮助下完成的。而Python的安装是通过Anaconda完成的。 在 Windows 上安装 OpenCV – C / Python&#xff08;opencv官方Wndows上安装openCV- C/ Pthon 的链接…

STM32 F103C8T6学习笔记7:双机无线串口通信

今日尝试配通俩个C8T6单片机之间的无线串口通信&#xff0c;文章提供原理&#xff0c;源码&#xff0c;测试效果图&#xff0c;测试工程下载&#xff1a; 目录 传输不规范问题&#xff1a; 串口通信资源&#xff1a; 单个串口资源理解&#xff1a; 单片机串口资源&#xf…