alt

捋清楚逻辑,主要分为5块来写,

第一块Binary Logic:判断二进制Pointer什么时候+1,生成ptr_bin_next信号

assign wptr_bin_next = wptr_bin + (winc & (!wfull));

第二块Gray Logic:由Binary Pointer生成Gary Pointer,其实这里根据经典AFIFO论文里应该是用新的wptr_bin_next生成wptr_gray_next,这样wptr_bin和wptr_gray可以同步更新,这里为了Pass测试案例,所以用 wptr_bin生成

assign wptr_gray_next = wptr_bin ^ (wptr_bin >> 1);

新态逻辑写完后赋值给Reg变量

{wptr_bin,wptr_gray} <= {wptr_bin_next, wptr_gray_next};

第三块Empty Logic:将wptr_gray在read时钟域打2拍,做空判断

assign rempty =  rptr_gray == wptr_gray_rr2;

第四块Full Logic:将rptr_gray在write时钟域打2拍,做满判断

assign wfull = wptr_gray == {~rptr_gray_wr2[ADDR_WIDTH:ADDR_WIDTH-1], rptr_gray_wr2[ADDR_WIDTH-2:0]};

第五块Full Logic:例化RAM,addr为ptr_bin次高位到最低位

完整代码

`timescale 1ns/1ns

/***************************************RAM*****************************************/
module dual_port_RAM #(parameter DEPTH = 16,
					   parameter WIDTH = 8)(
	 input wclk
	,input wenc
	,input [$clog2(DEPTH)-1:0] waddr  //深度对2取对数,得到地址的位宽。
	,input [WIDTH-1:0] wdata      	//数据写入
	,input rclk
	,input renc
	,input [$clog2(DEPTH)-1:0] raddr  //深度对2取对数,得到地址的位宽。
	,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  

/***************************************AFIFO*****************************************/
module asyn_fifo#(
	parameter	WIDTH = 8,
	parameter 	DEPTH = 16
)(
	input 					wclk	, 
	input 					rclk	,   
	input 					wrstn	,
	input					rrstn	,
	input 					winc	,
	input 			 		rinc	,
	input 		[WIDTH-1:0]	wdata	,

	output wire				wfull	,
	output wire				rempty	,
	output wire [WIDTH-1:0]	rdata
);
	parameter ADDR_WIDTH = $clog2(DEPTH);
/***************************************Bin Logic*****************************************/
	reg [ADDR_WIDTH:0] wptr_bin;
	reg [ADDR_WIDTH:0] rptr_bin;
	wire [ADDR_WIDTH:0] wptr_bin_next;
	wire [ADDR_WIDTH:0] rptr_bin_next;
	
	assign wptr_bin_next = wptr_bin + (winc & (!wfull));
	assign rptr_bin_next = rptr_bin + (rinc & (!rempty));
	
/***************************************Gray Logic*****************************************/
	reg [ADDR_WIDTH:0] wptr_gray;
	reg [ADDR_WIDTH:0] rptr_gray;
	wire [ADDR_WIDTH:0] wptr_gray_next;
	wire [ADDR_WIDTH:0] rptr_gray_next;
	
	assign wptr_gray_next = wptr_bin ^ (wptr_bin >> 1);
	assign rptr_gray_next = rptr_bin ^ (rptr_bin >> 1);
	
	always @ (posedge wclk or negedge wrstn) begin
		if (!wrstn) begin
			{wptr_bin,wptr_gray} <= 'd0;
		end
		else
			{wptr_bin,wptr_gray} <= {wptr_bin_next, wptr_gray_next};
	end
	
	always @ (posedge rclk or negedge rrstn) begin
		if (!rrstn) begin
			{rptr_bin,rptr_gray} <= 'd0;
		end
		else
			{rptr_bin,rptr_gray} <= {rptr_bin_next, rptr_gray_next};
	end
/***************************************Full Logic*****************************************/
	reg [ADDR_WIDTH:0] rptr_gray_wr,rptr_gray_wr2;
	
	always @ (posedge wclk or negedge wrstn) begin
		if (!wrstn) begin
			{rptr_gray_wr,rptr_gray_wr2} <= 'd0;
		end
		else
			{rptr_gray_wr2,rptr_gray_wr} <= {rptr_gray_wr,rptr_gray};
	end
	
	assign wfull = wptr_gray == {~rptr_gray_wr2[ADDR_WIDTH:ADDR_WIDTH-1], rptr_gray_wr2[ADDR_WIDTH-2:0]};
/***************************************Empty Logic*****************************************/
	reg [ADDR_WIDTH:0] wptr_gray_rr,wptr_gray_rr2;
	
	always @ (posedge rclk or negedge rrstn) begin
		if (!rrstn) begin
			{wptr_gray_rr2,wptr_gray_rr} <= 'd0;
		end
		else
			{wptr_gray_rr2,wptr_gray_rr} <= {wptr_gray_rr,wptr_gray};
	end
	
	assign rempty =  rptr_gray == wptr_gray_rr2;
/***************************************Dual RAM*****************************************/
	wire wenc, renc;
	wire [ADDR_WIDTH-1:0] raddr, waddr;
	
	assign wenc = winc & !wfull;
	assign renc = rinc & !rempty;
	
	assign raddr = rptr_bin[ADDR_WIDTH-1:0];
	assign waddr = wptr_bin[ADDR_WIDTH-1:0];
	
	dual_port_RAM #(.DEPTH(DEPTH), .WIDTH(WIDTH)) 
				u_dual_port_RAM (
				.wclk(wclk), 
				.rclk(rclk), 
				.wenc(wenc), 
				.renc(renc),
				.raddr(raddr),
				.waddr(waddr),
				.wdata(wdata),
				.rdata(rdata)
				);
/***************************************AFIFO*****************************************/    
endmodule