blob: 874adb3a17684e51330dc82987a4e0eaf18b9d98 [file] [log] [blame]
/*********************************************************************
This file is part of the sdram controller project
http://www.opencores.org/cores/sdr_ctrl/
Description: SYNC FIFO
Parameters:
W : Width (integer)
D : Depth (integer, power of 2, 4 to 256)
To Do:
nothing
Author(s): Dinesh Annayya, dinesha@opencores.org
Copyright (C) 2000 Authors and OPENCORES.ORG
This source file may be used and distributed without
restriction provided that this copyright statement is not
removed from the file and that any derivative work contains
the original copyright notice and the associated disclaimer.
This source file is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General
Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any
later version.
This source is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General
Public License along with this source; if not, download it
from http://www.opencores.org/lgpl.shtml
*******************************************************************/
module sync_fifo (clk,
reset_n,
wr_en,
wr_data,
full,
empty,
rd_en,
rd_data);
parameter W = 8;
parameter D = 4;
parameter AW = (D == 2) ? 1 :
(D == 4) ? 2 :
(D == 8) ? 3 :
(D == 16) ? 4 :
(D == 32) ? 5 :
(D == 64) ? 6 :
(D == 128) ? 7 :
(D == 256) ? 8 : 0;
output [W-1 : 0] rd_data;
input [W-1 : 0] wr_data;
input clk, reset_n, wr_en, rd_en;
output full, empty;
// synopsys translate_off
initial begin
if (AW == 0) begin
$display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
end // if (AW == 0)
end // initial begin
// synopsys translate_on
reg [W-1 : 0] mem[D-1 : 0];
reg [AW-1 : 0] rd_ptr, wr_ptr;
reg full, empty;
wire [W-1 : 0] rd_data;
always @ (posedge clk or negedge reset_n)
if (reset_n == 1'b0) begin
wr_ptr <= {AW{1'b0}} ;
end
else begin
if (wr_en & !full) begin
wr_ptr <= wr_ptr + 1'b1 ;
end
end
always @ (posedge clk or negedge reset_n)
if (reset_n == 1'b0) begin
rd_ptr <= {AW{1'b0}} ;
end
else begin
if (rd_en & !empty) begin
rd_ptr <= rd_ptr + 1'b1 ;
end
end
always @ (posedge clk or negedge reset_n)
if (reset_n == 1'b0) begin
empty <= 1'b1 ;
end
else begin
empty <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b0}}, 1'b1}) & rd_en & ~wr_en) ? 1'b1 :
((wr_ptr == rd_ptr) & ~rd_en & wr_en) ? 1'b0 : empty ;
end
always @ (posedge clk or negedge reset_n)
if (reset_n == 1'b0) begin
full <= 1'b0 ;
end
else begin
full <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b1}}, 1'b0}) & ~rd_en & wr_en) ? 1'b1 :
(((wr_ptr - rd_ptr) == {AW{1'b1}}) & rd_en & ~wr_en) ? 1'b0 : full ;
end
always @ (posedge clk)
if (wr_en)
mem[wr_ptr] <= wr_data;
assign rd_data = mem[rd_ptr];
// synopsys translate_off
always @(posedge clk) begin
if (wr_en && full) begin
$display("%m : Error! sfifo overflow!");
end
end
always @(posedge clk) begin
if (rd_en && empty) begin
$display("%m : error! sfifo underflow!");
end
end
// synopsys translate_on
//---------------------------------------
endmodule