异步FIFO总结(附代码与测试代码)

本文探讨了异步FIFO在设计时存在的健壮性问题,特别是主机在full信号发出后仍尝试写入导致的数据错误。提出了通过额外检测机制确保数据完整性的解决方案,并提供了测试代码和仿真结果,展示新方案如何有效防止数据覆盖和错误判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在复习异步fifo,看来不少博客写的代码,自己写起来仿真时候发现了不少博客有些错误。

语法上的错误就不说了。
在这里插入图片描述
在这里插入图片描述
注意到这两处的问题,很多代码是用打了一拍后的empty和full,这样有什么问题?
在主机根据full和empty的信号调整wen,ren时候没有什么问题,但是作为代码健壮性时候需要考虑到主机如果由于逻辑问题,在full信号发出后仍然wen=1时候,这样的代码会出现仍然将地址+1,于是下一个时钟由于地址变化,会误判full信号为0,这样会导致全部逻辑错误,新的数据会覆盖以前的数据。正常的fifo在判满后,当检测到主机仍然将wen=1时候,会停止写入数据。同理,读数据一样的检测方式。

module Asynfifo
#(
	parameter Wsize=8,
	parameter Dsize=16,//必须为2的幂次方
	parameter Addsize=4
)
(
	input rstn,
	input w_clk,
	input wen,
	input [Wsize-1:0]Din,
	input r_clk,
	input ren,
	output reg [Wsize-1:0]Dout,
	output reg empty,
	output reg full
);

reg [Wsize-1:0] RAM [Dsize-1:0];//寄存器组当SRAM
wire [Addsize-1:0] wadd,radd;
wire [Addsize:0] wgray,rgray;
reg  [Addsize:0] w2r_d1,w2r_d2;//写时钟格雷码同步到读时钟
reg  [Addsize:0] r2w_d1,r2w_d2;//读时钟格雷码同步到写时钟
wire rempty_val,wfull_val;
reg [Addsize:0] wp,rp;//读写指针(比地址多一位,用于判断读/写地址绕圈)

always@(posedge w_clk or negedge rstn)
	if(!rstn)begin
	wp<={
   
   Addsize{
   
   1'b0}};
	end
	else if(wen&&(!wfull_val))begin
	wp<=wp+1'd1;
	RAM[wadd]<=Din;
	end	
	else begin
	wp<=wp;
	RAM[wadd]<=RAM[wadd];
	end

always@(posedge r_clk or negedge rstn)
	if(!rstn)begin
	rp<={
   
   Addsize{
   
   1'b0}};
	Dout<={
   
   Addsize{
   
   1'b0}}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值