verilog实现同步FIFO_使用verilog语言设计一个同步fifo,宽度为8,深度为16-程序员宅基地

技术标签: fpga开发  硬件工程  FPGA/IC笔试题  开发语言  

verilog实现同步FIFO:


同步FIFO是一种先进先出的数据缓存器,在逻辑设计里面用的非常多,FIFO 设计可以说是逻辑设计人员必须掌握的常识性设计。FIFO 一般用在隔离两边读写带宽不一致,或者位宽不一样的地方。
FIFO 与普通存储器 RAM 的区别是没有外部读写地址线,使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加 1 完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。 FIFO 本质上是由 RAM 加读写控制逻辑构成的一种先进先出的数据缓冲器。

下面设计一个16*8(16是深度,8是位宽)的FIFO:

module syn_fifo(

	input	clk,
	input	rst_n,
	
	input	wr_en,
	input	[7:0]	data_in,
	output	full,
	
	input	rd_en,
	output	reg	[7:0]	data_out,
	output	empty

);

reg	[3:0]	wr_addr;
reg	[3:0]	rd_addr;
reg	[3:0]	cnt;

parameter	max_cnt = 4'd15;
reg	[7:0]	fifo[max_cnt:0]; //16*8(16是深度,8是位宽)的fifo

assign empty = (cnt==4'd0) ? 1'b1:1'b0;
assign full = (cnt==max_cnt) ? 1'b1:1'b0;

//写数据
integer i;
always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		for(i=0;i<max_cnt+1'b1;i=i+1)
			fifo[i] <= 8'd0;
	end
	else if(wr_en && (full==1'b0))
		fifo[wr_addr] <= data_in;
	else
		fifo[wr_addr] <= fifo[wr_addr];
end

//更新写地址
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		wr_addr <= 4'd0;
	else if(wr_en && (full==1'b0))
		wr_addr <= wr_addr + 1'b1;
	else
		wr_addr <= wr_addr;
end

//读数据
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		data_out <= 8'd0;
	else if(rd_en && (empty==1'b0))
		data_out <= fifo[rd_addr];
	else
		data_out <= data_out;
end

//更新读地址
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		rd_addr <= 4'd0;
	else if(rd_en && (empty==1'b0))
		rd_addr <= rd_addr + 1'b1;
	else
		rd_addr <= rd_addr;
end

//更新计数器
always @(posedge clk or negedge rst_n) begin
	if(!rst_n)
		cnt <= 4'd0;
	else begin
		case({
    wr_en,rd_en})
			2'b00: cnt <= cnt;
			2'b01: begin
					if(cnt != 4'd0)
						cnt <= cnt - 1'b1;
					else
						cnt <= cnt;
					end
			2'b10: begin
					if(cnt != max_cnt)
						cnt <= cnt + 1'b1;
					else
						cnt <= cnt;
					end
			2'b11: cnt <= cnt;
			default: ;
		endcase
	end
end

endmodule



仿真代码:


`timescale 1 ps/ 1 ps
module syn_fifo_tb();

reg clk;
reg [7:0] data_in;
reg rd_en;
reg rst_n;
reg wr_en;
                                             
wire [7:0]  data_out;
wire empty;
wire full;


initial	begin 
	clk = 0;
	rst_n = 0;
	rd_en = 0;
	wr_en = 0;
	data_in = 0;
	
	#40 rst_n = 1;
	#35 wr_en = 1;
	#200 rd_en = 1;
	
end     

always #20 data_in <= data_in + 1'b1;

always #10 clk <= ~clk;


syn_fio i1 (
	.clk(clk),
	.data_in(data_in),
	.data_out(data_out),
	.empty(empty),
	.full(full),
	.rd_en(rd_en),
	.rst_n(rst_n),
	.wr_en(wr_en)
);                                                 
endmodule



仿真图片:

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/CHT_1351678030/article/details/123769781

智能推荐

starGAN文章代码学习_stargan代码-程序员宅基地

文章浏览阅读1.5k次。starGAN文章代码学习实验代码代码下载依赖库安装代码运行结果展示文章阅读略读疑问精读翻译疑问解答(个人理解)最终总结实验代码代码下载https://github.com/yunjey/StarGAN依赖库安装利用anaconda创建pytorch和tensorflow的虚拟环境来跑程序,公司可以上外网,框架安装过程以外的顺利。$ conda create -n env_starGA..._stargan代码

成功解决OSError: Looks like you do not have git-lfs installed, please install. 【没有root权限】_oserror: you seem to have cloned a repository with-程序员宅基地

文章浏览阅读1.2k次,点赞3次,收藏3次。LFS是Large File Storage的缩写,用了帮助git管理大的文件原理:不同于git每次保存diff,对于git来说,如果是模型或者一些设计大文件,改变一点,对于仓库来说会增加很大的体积,不一会就能几个G。对于git lfs来说,在使用git lfs track命令后,git push的时候,git lfs会截取要管理的大文件,并将其传至git lfs的服务器中,从而减小仓库的体积。_oserror: you seem to have cloned a repository without having git-lfs install

cpp中的内联函数_c++ inline放到cpp中-程序员宅基地

文章浏览阅读308次。引入内联函数的目的是为了解决程序中函数调用的效率问题,这么说吧,程序在编译器编译的时候,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体进行替换,而对于其他的函数,都是在运行时候才被替代。其实我们要明白的是编译器也很智能,我们将一个函数申明为内联函数的时候,编译器不一定会同意,编译器可能认为这个函数过大,不应该被申明为内联。对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。在类定义中的定义的函数都是内联函数,即使没有使用。_c++ inline放到cpp中

在MyEclipse中快速创建一个Servlet_myeclipse10创建servlet项目-程序员宅基地

文章浏览阅读906次。一、首先进入软件后点击左方Pack下面相对应的白色部分,鼠标右键New一个Web project项目二、随后就会弹出一个Create a Web Project的页面,在Project Name处创建一个项目名即可三、打开刚建的项目,点击src,鼠标右键New一个Servlet四、弹出页面后在Name写入名字,把下面圈住的三个打勾的取消掉五、可以把URL处第二个/前面删除方便以后,也可不删,点击FIinish记即可完成对Servlet的创作!!!..._myeclipse10创建servlet项目

java/php/node.js/python汽车售票网站设计【2024年毕设】-程序员宅基地

文章浏览阅读353次,点赞10次,收藏7次。系统架构图属于系统设计阶段,系统架构图只是这个阶段一个产物,系统的总体架构决定了整个系统的模式,是系统的基础。除了以上作品下面是2023-2024年最新100套计算机专业原创的毕业设计源码+数据库,是近期作品,如果你的题目刚好在下面可以文末领取java源码参考。springboot基于Springboot的某大学运动会管理系统。springboot基于springboot校园一卡通管理系统。springboot基于Web的社区垃圾分类管理系统。ssm基于模块化的校园论坛的设计与实现。

JAVA设计模式之门面模式(外观模式)-程序员宅基地

文章浏览阅读141次。医院的例子现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其"分而治之",把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。首先病人必须先挂号,然后门诊。如果医生要求化验,病人必须首先划价,然后缴费,才可以到化验部门做化验。化验后再回到门诊室。上图描述的是病人在医院里的体验,图中的方框代表_门面模式

随便推点

35岁的leader,毅然放弃工作8年的地方,也许35岁才是新的起点吧_离开8年工作的地方-程序员宅基地

文章浏览阅读534次,点赞2次,收藏3次。到现在为止,自己已经在测试行业8年,毕业后一直从事传统IT项目的黑盒测试,今年8月份从工作了8年的公司离开,加入到现在一家互联网行业中还算的上大的公司,现在已经过去4个月,在新公司的工作开始逐渐熟悉,算是完成了一次从传统转互联网的转变,而自己也即将度过人生的35岁,在这里分享一下自己这一年的感受。_离开8年工作的地方

arduino i2c EEPROM(AT24C02、AT24C08、AT24C16、AT24C32、AT24C64)驱动_at24c64驱动程序-程序员宅基地

文章浏览阅读2.1k次,点赞2次,收藏10次。说明数据手册使用arduino的Wire库来读写at24cxx,可以支持at24c02、at24c08、at24c16、at24c32、at24c64。支持24cxx的随机读写以及顺序读写功能代码at24cxx.c#include <Arduino.h>#include <Wire.h>#include "at24cxx.h"void at24cxx_init(void){ Wire.begin();}static void at24cxx_wait_at24c64驱动程序

Kotlin学习笔记(五)--kotlin的协程_kotlin executorservice-程序员宅基地

文章浏览阅读451次。总结:协程就是 Kotlin 提供的一套线程封装的 APIJava中的并发操作例子:new Thread(new Runnable() { @Override public void run() { //耗时任务 }}).start();kotlin中线程的例子:Thread { //耗时任务}.start()同java一样,不知..._kotlin executorservice

V380固件自动升级失败修复过程_v380摄像头升级包-程序员宅基地

文章浏览阅读5.3k次。此次的问题是固件升级过程中断电(猜测),导致升级失败,flash中有一个分区被擦除了,所以导致不能用。折腾了两天,至于怎么折腾的不写了如何获取更新包下载地址:首先通过tcpdump抓包: 把tcpdump拷贝到sd卡,之后用串口进入shell,这个操作是在其它的V380摄像头上实现的,执行如下命令: tcpdump –w info.cap 之后到手机里V380软件里,点击一下固件版本更新,好,至此包已经被抓下来了。..._v380摄像头升级包

操作系统408真题:共享段表的操作-程序员宅基地

文章浏览阅读5.9k次,点赞32次,收藏44次。在分段存储管理系统中,用共享段表描述所有被共享的段。若进程P1和进程P2共享段S,下列叙述中,错误的是_共享段表

5月《中国数据库行业分析报告》正式发布,首发时序、实时数据库两大【全球产业图谱】_时序数据库 市场分析报告-程序员宅基地

文章浏览阅读697次。墨天轮社区分布的这份行业分析报告梳理了时序数据库、实时数据库的技术原理、应用场景及发展趋势,并发布两类数据库的【全球产业图谱】,一起探索技术发展新趋势!_时序数据库 市场分析报告

推荐文章

热门文章

相关标签