// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dmu_clu_ctm_bufmgr.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This 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 program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
module dmu_clu_ctm_bufmgr
// tmu: diu buffer mgr port
// rmu : dou dma buffer rel port
// dou buffer ctl/sts port
// diu buffer ctl/sts port
// synopsys sync_set_reset "rst_l"
// >>>>>>>>>>>>>>>>>>>>>>>>> Parameter Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
parameter DOU_DADDR_WDTH = 5;
parameter DOU_DADDR_NUM = 32;
// >>>>>>>>>>>>>>>>>>>>>>>>> Port Declarations <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
// DIU Buffer Manager Port
output [(`FIRE_DLC_DMA_RPTR_WDTH - 1):0] cl2tm_dma_rptr;
output [(`FIRE_DLC_INT_RPTR_WDTH - 1):0] cl2tm_int_rptr;
input [(`FIRE_DLC_DMA_WPTR_WDTH - 1):0] tm2cl_dma_wptr;
input [(`FIRE_DLC_PIO_WPTR_WDTH - 1):0] tm2cl_pio_wptr;
// --------------------------------------------------------
// --------------------------------------------------------
// DOU DMA Buffer Release Port
input [(`FIRE_DLC_DOU_REL_WDTH - 1):0] rm2cl_bufrel;
// --------------------------------------------------------
// --------------------------------------------------------
output [(`FIRE_DLC_CRD_ADDR_WDTH - 1):0] cl2di_addr;
// --------------------------------------------------------
// DOU Buffer Manager Control Port
// --------------------------------------------------------
output [(DOU_DADDR_WDTH - 1):0] dma_dptr;
// --------------------------------------------------------
// DIU Buffer Manager Control Port
// --------------------------------------------------------
// --------------------------------------------------------
// --------------------------------------------------------
output dou_dptr_pool_full;
// >>>>>>>>>>>>>>>>>>>>>>>>> Data Type Declarations <<<<<<<<<<<<<<<<<<<<<<<<<
// ~~~~~~~~~~~~~~~~~~~~~~~~~ REGISTERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ********** Flops **********
reg [(DOU_DADDR_WDTH - 1):0] dma_dptr;
reg [(DOU_DADDR_NUM - 1):0] dou_sts_vctr;
// ********** Non-Flops ******
reg [6:0] nxt_diu_addr_8to2;
reg [(DOU_DADDR_NUM - 1):0] dcd_vec0;
reg [(DOU_DADDR_NUM - 1):0] dptr_ret_dcd;
reg [(DOU_DADDR_NUM - 1):0] dcd_vec1;
reg [(DOU_DADDR_NUM - 1):0] dptr_consume_dcd;
// ~~~~~~~~~~~~~~~~~~~~~~~~~ NETS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
wire [(DOU_DADDR_NUM - 1):0] nxt_dou_sts_vctr;
// >>>>>>>>>>>>>>>>>>>>>>>>> 0-in Checkers <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// 0in max -var eqw_blk_addr -val 4'hB
// 0in kndr -var {tm2cl_dma_wptr, tm2cl_pio_wptr}
// 0in decode -in rm2cl_bufrel -out dcd_vec0
// 0in decode -in dma_dptr -out dcd_vec1
// >>>>>>>>>>>>>>>>>>>>>>>>> RTL Model <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------
// --------------------------------------------------------
assign dou_dptr_pool_full = &dou_sts_vctr;
// --------------------------------------------------------
// --------------------------------------------------------
// ----- dma buffer management ----------------------------------------------
{dma_wrp_flag, dma_blk_addr} <= 6'b0;
else if (inc_dma_blk_addr)
{dma_wrp_flag, dma_blk_addr} <= {dma_wrp_flag, dma_blk_addr} + 1'b1;
assign diu_dma_empty = ({dma_wrp_flag, dma_blk_addr} == tm2cl_dma_wptr);
// clu-tmu diu buff management
assign cl2tm_dma_rptr = {dma_wrp_flag, dma_blk_addr};
// ----- pio buffer management ----------------------------------------------
{pio_wrp_flag, pio_blk_addr} <= 5'b0;
else if (inc_pio_blk_addr)
{pio_wrp_flag, pio_blk_addr} <= {pio_wrp_flag, pio_blk_addr} + 1'b1;
assign diu_pio_empty = ({pio_wrp_flag, pio_blk_addr} == tm2cl_pio_wptr);
// ----- eqw buffer management ----------------------------------------------
// diu eqw addr wrap ctl : eqw consumes diu int addr 0x0-0xB
assign wrp_eqw_blk_addr = (eqw_blk_addr == 4'hB);
else if (inc_eqw_blk_addr)
eqw_wrp_flag <= eqw_wrp_flag ^ wrp_eqw_blk_addr;
eqw_blk_addr <= (eqw_blk_addr + 1'b1) & {4{~wrp_eqw_blk_addr}};
// clu-tmu diu buff management
assign cl2tm_int_rptr = {eqw_wrp_flag, eqw_blk_addr};
// ----- mdo buffer management ----------------------------------------------
else if (inc_mdo_blk_addr)
mdo_blk_addr <= mdo_blk_addr + 1'b1;
// ----- diu read addr generation -------------------------------------------
// diu blk addr select : dma, pio, int (eqw), int (mdo)
always @(dma_blk_addr or pio_blk_addr or eqw_blk_addr or mdo_blk_addr or
case (diu_typ_sel) // synopsys infer_mux
nxt_diu_addr_8to2 = {2'b00, dma_blk_addr};
// nxt_diu_addr_8to2 = {2'b01, 1'b0, pio_blk_addr};
nxt_diu_addr_8to2 = {2'b01, 1'b0, 2'b00, pio_blk_addr[3:2]};
nxt_diu_addr_8to2 = {2'b10, 1'b0, eqw_blk_addr};
nxt_diu_addr_8to2 = {2'b10, 1'b0, 2'b11, mdo_blk_addr};
diu_addr_8to2 <= nxt_diu_addr_8to2;
else if ( ld_diu_addr & (diu_typ_sel == 2'b01))
diu_addr_1to0 <= pio_blk_addr[1:0] ;
else if (inc_diu_row_ptr | ld_diu_addr)
diu_addr_1to0 <= (diu_addr_1to0 + 1'b1) & {2{~ld_diu_addr}};
assign cl2di_addr = {diu_addr_8to2, diu_addr_1to0};
// --------------------------------------------------------
// --------------------------------------------------------
// ----- dou dma dptr management --------------------------------------------
// dou dma dptr generator
dma_dptr <= {DOU_DADDR_WDTH{1'b0}};
dma_dptr <= dma_dptr + 1'b1;
// decoder : dou dma dptr retire
always @(rm2cl_bufrel or rm2cl_bufrel_enq)
dcd_vec0 = {DOU_DADDR_NUM{1'b0}};
dcd_vec0[rm2cl_bufrel] = 1'b1;
dptr_ret_dcd = dcd_vec0 & {DOU_DADDR_NUM{rm2cl_bufrel_enq}};
// decoder : dou dma dptr consume
always @(dma_dptr or dma_dptr_req)
dcd_vec1 = {DOU_DADDR_NUM{1'b0}};
dcd_vec1[dma_dptr] = 1'b1;
dptr_consume_dcd = dcd_vec1 & {DOU_DADDR_NUM{dma_dptr_req}};
// generate "next dou status" vector
assign nxt_dou_sts_vctr = ((dptr_ret_dcd | dou_sts_vctr) &
// dou status vector: 1 = avail, 0 = used
dou_sts_vctr <= {DOU_DADDR_NUM{1'b1}};
dou_sts_vctr <= nxt_dou_sts_vctr;
// ----- dou status check ---------------------------------------------------
// scan dou status vector
assign {tmp_a, dou_sts_scan} = {dou_sts_vctr[7:0], dou_sts_vctr} >> dma_dptr;
assign {dou_sts_chk, tmp_b} = {dou_sts_scan, 8'hFF} << (4'h9 - dma_cltot);
assign dou_space_avail = &dou_sts_chk;
endmodule // dmu_clu_ctm_bufmgr