| // ========== 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: |
| |
| |
| |
| |
| |
| |
| |