题解 | #同步FIFO#

同步FIFO

https://www.nowcoder.com/practice/e5e86054a0ce4355b9dfc08238f25f5f

`timescale 1ns/1ns

/**********************************RAM************************************/
module dual_port_RAM #(parameter DEPTH = 16,
					   parameter WIDTH = 8)(
	 input wclk
	,input wenc
	,input [$clog2(DEPTH)-1:0] waddr  
	,input [WIDTH-1:0] wdata      	
	,input rclk
	,input renc
	,input [$clog2(DEPTH)-1:0] raddr  
	,output reg [WIDTH-1:0] rdata 		
);

reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1];

always @(posedge wclk) begin
	if(wenc)
		RAM_MEM[waddr] <= wdata;
end 

always @(posedge rclk) begin
	if(renc)
		rdata <= RAM_MEM[raddr];
end 

endmodule  

/**********************************SFIFO************************************/
module sfifo#(
	parameter	WIDTH = 8,
	parameter 	DEPTH = 16
)(
	input 					clk		, 
	input 					rst_n	,
	input 					winc	,
	input 			 		rinc	,
	input 		[WIDTH-1:0]	wdata	,

	output reg				wfull	,
	output reg				rempty	,
	output wire [WIDTH-1:0]	rdata
);

// 写地址
reg [4:0] waddr;
reg [4:0] raddr;
reg [3:0] w_gap;
reg [3:0] r_gap;
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
	waddr<=0;
	else if(winc&~wfull)
	waddr<=waddr+1;
	else
	waddr<=waddr;
end
// 读地址
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
	raddr<=0;
	else if(rinc&~rempty)
	raddr<=raddr+1;
	else
	raddr<=raddr;
end

// always @(posedge clk or negedge rst_n)begin
// 	if(!rst_n)
// 	r_gap<=0;
// 	else if(waddr[4]==raddr[4])
// 	r_gap<=waddr[3:0]-raddr[3:0];
// 	else 
// 	r_gap<=DEPTH-(raddr[3:0]-waddr[3:0]);
// end

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
	rempty<=0;
	else if(waddr==raddr)
	rempty<=1;
	else 
	rempty<=0;
end


// always @(posedge clk or negedge rst_n)begin
// 	if(!rst_n)
// 	w_gap<=0;
// 	else if(waddr[4]==1&&raddr[4]==0)
// 	w_gap<=raddr[3:0]-waddr[3:0];
// 	else 
// 	w_gap<=DEPTH-(waddr[3:0]-raddr[3:0]);
// end

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
	wfull<=0;
	else if((waddr[4]!=raddr[4])&&(raddr[3:0]==waddr[3:0]))
	wfull<=1;
	else 
	wfull<=0;
end


dual_port_RAM uut(
     .wclk(clk),
	 .wenc(winc&~wfull),
     .waddr(waddr[3:0]),
     .wdata(wdata),   	
	 .rclk(clk),
	 .renc(rinc&~rempty),
     .raddr(raddr[3:0]),
     .rdata(rdata)	
);

    
endmodule

同步FIFO的好处是读写数据都使用的同一个时钟,可以不用使用格雷码同步。使用时接入了一个双端口的RAM。FIFO full产生的情况:如果地址的最高位都是相同的,那么一定不会写满,因为写地址的指针一定会领先于读指针(不然的话就读空了)吗,而在地址最高位不同的时候,是有可能写满的,有可能写指针追赶上了读指针。在读的时候,读空的情况发生在地址完全相同的时候,如果地址最高位不同,读指针是追赶不上写指针的。只有在地址最高为相同的时候,读指针有追上写指针的可能。

全部评论

相关推荐

求问!考研下岸,打算参加春招,我这个bg能进啥厂,或者需要搞点深度项目再投吗
Java抽象带篮子_...:直接海投,可以看看我的考研失利速成冲春招贴,里面详细写了简历怎么写,学哪些项目可以速成
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务