经典的,可配置的单时钟FIFO实现
已经经历过流片验证。
module sc_fifo#(
parameter AW = 5 ,
parameter DW = 64
)(
input clk,rst_n,
input [ DW-1:0] din,
input wr,rd,
output full,empty,
output reg valid, // data is now valid in dout bus , rd act as ack.
output reg [ DW-1:0] dout
);
reg [ AW:0] fifo_cntr ;
localparam MAX_FIFO_LEN = (1<<AW ) ;
reg [ DW-1:0] buff[0: MAX_FIFO_LEN -1] ;
reg [ AW-1:0] wr_ptr ;
reg [AW-1:0] rd_ptr ;
assign full = fifo_cntr >= ( MAX_FIFO_LEN - 2) ;
assign empty = fifo_cntr == 0 ;
always @ (posedge clk) valid<=~empty ;
wire valid_rd = ( ~empty ) & rd ;
wire valid_wr = ( ~full ) & wr ;
always@(posedge clk) if (~rst_n) wr_ptr <= 0;else if(valid_wr)wr_ptr<=wr_ptr+1;
always@(posedge clk) if (~rst_n)rd_ptr <= 0 ;else if (valid_rd)rd_ptr <= rd_ptr+1;
always@(posedge clk)
casex ({rst_n,valid_wr,valid_rd})
3'b0xx : fifo_cntr<=0;
3'b110 : fifo_cntr<=fifo_cntr+1;
3'b101 : fifo_cntr<=fifo_cntr-1;
3'b111 ,3'b100 :fifo_cntr<=fifo_cntr ;
endcase
always@(posedge clk) if (valid_wr) buff[wr_ptr] <=din ;
always@(posedge clk) dout <= buff[rd_ptr] ;
endmodule