blob: e027d2411827bc337fc46063d65a8e930acedc51 [file] [log] [blame] [edit]
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T1 Processor File: dbl_buf.v
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
////////////////////////////////////////////////////////////////////////
/*
// Module Name: dbl_buf
// Description: A simple double buffer
// First-in first-out. Asserts full when both entries
// are occupied.
*/
////////////////////////////////////////////////////////////////////////
// Global header file includes
////////////////////////////////////////////////////////////////////////
`include "sys.h" // system level definition file which
// contains the time scale definition
////////////////////////////////////////////////////////////////////////
// Local header file includes / local defines
////////////////////////////////////////////////////////////////////////
module dbl_buf (/*AUTOARG*/
// Outputs
dout, vld, full,
// Inputs
clk, rst_l, wr, rd, din
);
// synopsys template
parameter BUF_WIDTH = 64; // width of the buffer
// Globals
input clk;
input rst_l;
// Buffer Input
input wr;
input rd;
input [BUF_WIDTH-1:0] din;
// Buffer Output
output [BUF_WIDTH-1:0] dout;
output vld;
output full;
// Buffer Output
wire wr_buf0;
wire wr_buf1;
wire buf0_vld;
wire buf1_vld;
wire buf1_older;
wire rd_buf0;
wire rd_buf1;
wire rd_buf;
wire en_vld0;
wire en_vld1;
wire [BUF_WIDTH-1:0] buf0_obj;
wire [BUF_WIDTH-1:0] buf1_obj;
////////////////////////////////////////////////////////////////////////
// Code starts here
////////////////////////////////////////////////////////////////////////
// if both entries are empty, write to entry pointed to by the older pointer
// if only one entry is empty, then write to the empty entry (duh!)
assign wr_buf0 = wr &
(buf1_vld | (~buf0_vld & ~buf1_older));
assign wr_buf1 = wr &
(buf0_vld | (~buf1_vld & buf1_older));
// read from the older entry
assign rd_buf0 = rd & ~buf1_older;
assign rd_buf1 = rd & buf1_older;
// flip older pointer when an entry is read
assign rd_buf = rd & (buf0_vld | buf1_vld);
dffrle_ns buf1_older_ff (.din(~buf1_older),
.rst_l(rst_l),
.en(rd_buf),
.clk(clk),
.q(buf1_older));
// set valid bit for writes and reset for reads
assign en_vld0 = wr_buf0 | rd_buf0;
assign en_vld1 = wr_buf1 | rd_buf1;
// the actual buffers
dffrle_ns buf0_vld_ff (.din(wr_buf0),
.rst_l(rst_l),
.en(en_vld0),
.clk(clk),
.q(buf0_vld));
dffrle_ns buf1_vld_ff (.din(wr_buf1),
.rst_l(rst_l),
.en(en_vld1),
.clk(clk),
.q(buf1_vld));
dffe_ns #(BUF_WIDTH) buf0_obj_ff (.din(din),
.en(wr_buf0),
.clk(clk),
.q(buf0_obj));
dffe_ns #(BUF_WIDTH) buf1_obj_ff (.din(din),
.en(wr_buf1),
.clk(clk),
.q(buf1_obj));
// mux out the older entry
assign dout = (buf1_older) ? buf1_obj:buf0_obj;
assign vld = buf0_vld | buf1_vld;
assign full = buf0_vld & buf1_vld;
endmodule // dbl_buf
// Local Variables:
// verilog-library-directories:(".")
// End: