同步FIFO设计

FIFO的英文全称为first in first out,顾名思义就是先进先出的意思。同步fifo表示读写时钟为同源,不存在跨异步处理。

1.1 原理 

1.2 verilog代码

module sync_fifo #(
  parameter DEPTH = 2,
			WIDTH = 8,
			PFCW  = $clog2(DEPTH) + ((1 << $clog2(DEPTH)) == DEPTH)
)(
  input  				clk,
  input 				rst_n,
  
  input 				push_valid,
  input  [WIDTH -1:0] 	push_data,
  output 				push_ready,
  
  output 				pop_valid,
  output [WIDTH -1:0] 	pop_data,
  input 				pop_ready
);

localparam DL = $clog2(DEPTH);
reg  [WIDTH -1:0] 		mem[DEPTH -1:0];//FIFO data restore
reg  [PFCW  -1:0] 		free_cnt; 		//remain space
reg  [PFCW  -1:0] 		pop_cnt; 		//number of data
reg  [DL 	-1:0]		wrptr;			//write pointer
reg  [DL 	-1:0]		rdptr;			//read pointer
reg  [WIDTH -1:0]		wdata; 			//write data
reg  [WIDTH -1:0] 		rdata;			//read data
reg 					write;			//write enable
reg 					read;			//read enable

assign push_ready 	= ~push_full; 		//when fifo not full, write ready is high
assign write 		= push_valid & ~push_full; //write enable when fifo not full
assign wdata 		= push_data;		//write data

assign pop_valid    = ~pop_empty;		//when fifo not empty, read valid is high
assign pop_data 	= rdata;			//read data
assign read 		= pop_valid & ~pop_empty; //read enable when fifo not empty

//FIFO logic
//write side logic
always @(posedge clk or negedge rst_n) begin : write_data
  if(~rst_n)
	mem <= 'd0;
  else if(write)
	mem[wrptr] <= wdata; //write data to memory
end
always @(posedge clk or negedge rst_n) begin : write_pointer
  if(~rst_n) 
	wrptr <= 'd0;
  else if(write)
	wrptr <= (wrptr == DEPTH -1) ? 'd0 : (wrptr +1'b1); 
end

//read side logic
always @(posedge clk or negedge rst_n) begin : read_pointer
  if(~rst_n)
    rdptr <= 'd0;
  else if(read)
	rdptr <= (rdptr == DEPTH -1) ? 'd0 : (rdptr +1'b1); 
end
assign rdata = mem[rdptr]; //from fifo to read data

//status
always @(posedge clk or negedge rst_n) begin : counter_management
  if(~rst_n) begin
    free_cnt 	<= DEPTH;
	pop_cnt 	<= 'd0;
	push_full 	<= 1'b0;
	pop_empty	<= 1'b1;
  end
  else if(read & ~write) begin
    free_cnt 	<= free_cnt + 1'b1;
	pop_cnt 	<= pop_cnt - 1'b1;
	push_full 	<= 1'b0;
	pop_empty 	<= (pop_cnt == 1)
  end
  else if(write & ~read) begin
    free_cnt 	<= free_cnt - 1'b1;
    pop_cnt 	<= pop_cnt + 1'b1;
	push_full   <= (free_cnt == 1);
	pop_empty 	<= 1'b0;
  end
end

endmodule
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值