【Sync FIFO介绍及基于Verilog的实现】


本篇博客介绍无论是编码过程中经常用到的逻辑–FIFO;该FIFO是基于单时钟下的同步FIFO;
FiFO分类:同步FiFO VS 异步FiFO;

1 Intro

FIFO可以自己实现,但是因为FiFO太常用,为了减少造轮子和出错率,基本上每个公司都有自己的CBB库,直接调用即可;
个人认为,自己作为入门者,学习尤其亲自实践造轮子,对自己的技能提升很有帮助;
FiFO是first in first out的数据行为;相比SRAM来说可能是少了灵活性,但是在设计逻辑上却是最经常用到FIFO的行为逻辑;
FIFO基于sram上wrapper控制逻辑的module;

2 Achieve

三种基本读写场景:

  • push && !pop
  • psh && pop
  • pop && !push

2.1 DFD

通过wr_ptr和rd_ptr来进行以动array的index;
!](https://img-blog.csdnimg.cn/direct/83dce5833ef1442aa970a44eec2e2af2.png)
在这里插入图片描述

2.2 Intf

下图是Sync_fifo的上下游接口框图;
在这里插入图片描述

2.3 Module

以下为伪代码实现,还未经过语法编译和功能验证,供大家思路参考

//--Auther	:colonel
//--Date		:2024-05-23
//--Function:sync_fifo meet
//--History	:Description
//--05/22	:Firstly create the file
//
module sync_fifo#(
	parameter DEPTH = 4,
	parameter WIDTH = 8,
	parameter PTR_WIDTH = 2
)(
	input clk,
	input rst_n,

	input push,
	input wire[WIDTH -1:0] data_in,
	output full, 


	input pop,
	output empty,
	output reg[WIDTH -1:0] data_out 
);

reg[WIDTH -1:0][DEPTH -1:0] fifo;		//sync_fifo based on the register
reg[PTR_WIDTH -1:0] cnt;

reg[DEPTH -1:0] wr_ptr;
reg[DEPTH -1:0] rd_ptr;

//--waddr 
always@(posedge clk or negedge rst_n) begin:waddr_logic
	if(!rst_n) begin
		wr_ptr <= 0;
	end else begin
		if(push && ! full) begin
			wr_ptr <= wr_ptr + 1;
		end else begin
			wr_ptr <= wr_ptr;
		end
	end
end

//--raddr
always@(posedge clk or negedge rst_n) begin:raddr_logic
	if(!rst_n) begin
		rd_ptr <= 0;
	end else begin
		if(pop && !empty ) begin
			rd_ptr <= rd_ptr + 1;
		end else begin
			rd_ptr <= rd_ptr;
		end
	end
end

//--wdata
integer i;
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		for(i=0;i<DEPTH;i=i+1) begin
			fifo[i] <= 0;
		end
	end else begin
		if(push) begin
			fifo[wr_ptr] <= data_in;
		end else begin
			fifo[wr_ptr] <= fifo[wr_ptr];
		end
	end
end

//--rdata
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		data_out <= 0;
	end else begin
		if(pop) begin
			data_out <= fifo[rd_ptr];
		end else begin
			data_out <= data_out;
		end
	end
end

//--cnt logic
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cnt <= 0;
	end else begin
		if(push && !pop && !full) begin
			cnt <= cnt + 1;
		end else if(!push && pop && !empty) begin
			cnt <= cnt - 1;
		end else begin
			cnt <= cnt;
		end
	end
end

//full && empty logic
assign empty = (cnt==0) ? 1:0; 
assign full = (cnt==DEPTH) ? 1:0; 

endmodule


【Reference】
[1] https://blog.csdn.net/zyp626/article/details/131620099

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值