blob: fb934a29a3737cefd0c5d057b215ca1a174448bb [file] [log] [blame]
//////////////////////////////////////////////////////////////////////
//// ////
//// YiFive cores common library Module ////
//// ////
//// This file is part of the YIFive cores project ////
//// http://www.opencores.org/cores/yifive/ ////
//// ////
//// Description ////
//// Sync Fifo with full and empty ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Dinesh Annayya, dinesha@opencores.org ////
//// ////
//// Revision : June 7, 2021 ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// 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 #(
parameter DATA_WIDTH = 32, // Data Width
parameter ADDR_WIDTH = 1, // Address Width
parameter FIFO_DEPTH = 2 // FIFO DEPTH
)(
output [DATA_WIDTH-1:0] dout,
input rstn,
input clk,
input wr_en, // Write
input rd_en, // Read
input [DATA_WIDTH-1:0] din,
output full,
output empty
);
reg [DATA_WIDTH-1:0] ram [FIFO_DEPTH-1:0];
reg [ADDR_WIDTH-1:0] wptr; // write ptr
reg [ADDR_WIDTH-1:0] rptr; // write ptr
reg [ADDR_WIDTH:0] status_cnt; // status counter
reg empty;
reg full;
//-----------Code Start---------------------------
always @ (negedge rstn or posedge clk)
begin : WRITE_POINTER
if (rstn==1'b0) begin
wptr <= 0;
end else if (wr_en ) begin
wptr <= wptr + 1;
end
end
always @ (negedge rstn or posedge clk)
begin : READ_POINTER
if (rstn==1'b0) begin
rptr <= 0;
end else if (rd_en) begin
rptr <= rptr + 1;
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
assign dout = ram[rptr];
always @ (posedge clk)
begin
if (wr_en) ram[wptr] <= din;
end
endmodule