Line 1... |
Line 1... |
//////////////////////////////////////////////////////////////////////
|
/*********************************************************************
|
//// ////
|
|
//// YiFive cores common library Module ////
|
This file is part of the sdram controller project
|
//// ////
|
http://www.opencores.org/cores/sdr_ctrl/
|
//// This file is part of the YIFive cores project ////
|
|
//// http://www.opencores.org/cores/yifive/ ////
|
Description: SYNC FIFO
|
//// ////
|
Parameters:
|
//// Description ////
|
W : Width (integer)
|
//// Sync Fifo with full and empty ////
|
D : Depth (integer, power of 2, 4 to 256)
|
//// ////
|
|
//// To Do: ////
|
To Do:
|
//// nothing ////
|
nothing
|
//// ////
|
|
//// Author(s): ////
|
Author(s): Dinesh Annayya, dinesha@opencores.org
|
//// - Dinesh Annayya, dinesha@opencores.org ////
|
|
//// ////
|
Copyright (C) 2000 Authors and OPENCORES.ORG
|
//// Revision : June 7, 2021 ////
|
|
//// ////
|
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
|
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
the original copyright notice and the associated disclaimer.
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
This source file is free software; you can redistribute it
|
//// restriction provided that this copyright statement is not ////
|
and/or modify it under the terms of the GNU Lesser General
|
//// removed from the file and that any derivative work contains ////
|
Public License as published by the Free Software Foundation;
|
//// the original copyright notice and the associated disclaimer. ////
|
either version 2.1 of the License, or (at your option) any
|
//// ////
|
later version.
|
//// This source file is free software; you can redistribute it ////
|
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
This source is distributed in the hope that it will be
|
//// Public License as published by the Free Software Foundation; ////
|
useful, but WITHOUT ANY WARRANTY; without even the implied
|
//// either version 2.1 of the License, or (at your option) any ////
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
//// later version. ////
|
PURPOSE. See the GNU Lesser General Public License for more
|
//// ////
|
details.
|
//// This source is distributed in the hope that it will be ////
|
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
You should have received a copy of the GNU Lesser General
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
Public License along with this source; if not, download it
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
from http://www.opencores.org/lgpl.shtml
|
//// 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,
|
module sync_fifo #(
|
full,
|
parameter DATA_WIDTH = 32, // Data Width
|
empty,
|
parameter ADDR_WIDTH = 1, // Address Width
|
rd_en,
|
parameter FIFO_DEPTH = 2 // FIFO DEPTH
|
rd_data);
|
|
|
)(
|
parameter W = 8;
|
output [DATA_WIDTH-1:0] dout,
|
parameter D = 4;
|
input rstn,
|
|
input clk,
|
parameter AW = (D == 4) ? 2 :
|
input wr_en, // Write
|
(D == 8) ? 3 :
|
input rd_en, // Read
|
(D == 16) ? 4 :
|
input [DATA_WIDTH-1:0] din,
|
(D == 32) ? 5 :
|
output full,
|
(D == 64) ? 6 :
|
output empty
|
(D == 128) ? 7 :
|
);
|
(D == 256) ? 8 : 0;
|
|
|
|
output [W-1 : 0] rd_data;
|
reg [DATA_WIDTH-1:0] ram [FIFO_DEPTH-1:0];
|
input [W-1 : 0] wr_data;
|
reg [ADDR_WIDTH-1:0] wptr; // write ptr
|
input clk, reset_n, wr_en, rd_en;
|
reg [ADDR_WIDTH-1:0] rptr; // write ptr
|
output full, empty;
|
reg [ADDR_WIDTH:0] status_cnt; // status counter
|
|
reg empty;
|
// synopsys translate_off
|
reg full;
|
|
|
initial begin
|
|
if (AW == 0) begin
|
//-----------Code Start---------------------------
|
$display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
|
always @ (negedge rstn or posedge clk)
|
end // if (AW == 0)
|
begin : WRITE_POINTER
|
end // initial begin
|
if (rstn==1'b0) begin
|
|
wptr <= 0;
|
// synopsys translate_on
|
end else if (wr_en ) begin
|
|
wptr <= wptr + 1;
|
|
end
|
reg [W-1 : 0] mem[D-1 : 0];
|
end
|
reg [AW-1 : 0] rd_ptr, wr_ptr;
|
|
reg full, empty;
|
always @ (negedge rstn or posedge clk)
|
|
begin : READ_POINTER
|
wire [W-1 : 0] rd_data;
|
if (rstn==1'b0) begin
|
|
rptr <= 0;
|
always @ (posedge clk or negedge reset_n)
|
end else if (rd_en) begin
|
if (reset_n == 1'b0) begin
|
rptr <= rptr + 1;
|
wr_ptr <= {AW{1'b0}} ;
|
end
|
|
end
|
|
|
|
always @ (negedge rstn or posedge clk)
|
|
begin : STATUS_COUNTER
|
|
if (rstn==1'b0) begin
|
|
status_cnt <= 0;
|
|
// Read but no write.
|
|
end else if (rd_en && (!wr_en) && (status_cnt != 0)) begin
|
|
status_cnt <= status_cnt - 1;
|
|
// Write but no read.
|
|
end else if (wr_en && (!rd_en) && (status_cnt != FIFO_DEPTH)) begin
|
|
status_cnt <= status_cnt + 1;
|
|
end
|
|
end
|
|
|
|
// underflow is not handled
|
|
always @ (negedge rstn or posedge clk)
|
|
begin : EMPTY_FLAG
|
|
if (rstn==1'b0) begin
|
|
empty <= 1;
|
|
// Read but no write.
|
|
end else if (rd_en && (!wr_en) && (status_cnt == 1)) begin
|
|
empty <= 1;
|
|
// Write
|
|
end else if (wr_en) begin
|
|
empty <= 0;
|
|
end else if (status_cnt == 0) begin
|
|
empty <= 1;
|
|
end
|
|
end
|
|
|
|
// overflow is not handled
|
|
always @ (negedge rstn or posedge clk)
|
|
begin : FULL_FLAG
|
|
if (rstn==1'b0) begin
|
|
full <= 0;
|
|
// Write but no read.
|
|
end else if (wr_en && (!rd_en) && (status_cnt == (FIFO_DEPTH-1))) begin
|
|
full <= 1;
|
|
// Read
|
|
end else if (rd_en && (!wr_en) ) begin
|
|
full <= 0;
|
|
end else if (status_cnt == FIFO_DEPTH) begin
|
|
full <= 1;
|
|
end
|
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
|
end
|
assign dout = ram[rptr];
|
|
|
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
if (wr_en)
|
if (wr_en) ram[wptr] <= din;
|
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
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rd_en && empty) begin
|
|
$display("%m : error! sfifo underflow!");
|
|
end
|
|
end
|
|
|
|
// synopsys translate_on
|
|
//---------------------------------------
|
|
|
endmodule
|
endmodule
|
|
|
|
|