// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dmu_dsn_ucb_flow.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_dsn_ucb_flow (
// Downstream Path from NCU //
// Upstream Path to NCU //
// Local CSR Read Retruns //
input [31:0] ncu_dmu_data;
output [31:0] dmu_ncu_data;
// Ack/Nack from local unit
output [`FIRE_DEBUG_WDTH-1:0] ucb2ctl_dbg_grp_a_1;
wire [2:0] unconnected_size_in;
wire [1:0] buf_head_next;
wire [1:0] buf_tail_next;
wire [127:0] outdata_buf_in;
wire [3:0] outdata_vec_in;
wire [12:0] addr_in_spare;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/************************************************************
************************************************************/
dmu_dsn_ucb_in32 dmu_dsn_ucb_in32 (.reset(reset),
.data(ncu_dmu_data[31:0]),
.indata_buf_vld(indata_buf_vld),
.indata_buf(indata_buf[127:0]),
.stall_a1(dmu_ncu_stall_a1));
/************************************************************
* Decode inbound packet type
************************************************************/
assign read_pending = (indata_buf[3:0] == 4'b0100) & indata_buf_vld;
assign write_pending = (indata_buf[3:0] == 4'b0101) & indata_buf_vld;
assign dmu_ncu_stall_a1 = (read_pending | write_pending) & buf_full;
/************************************************************
************************************************************/
assign rd_buf = req_acpted;
assign buf_head_next[1:0] = reset ? 2'b01 :
rd_buf ? {buf_head[0],buf_head[1]} : buf_head[1:0];
dff #(2) buf_head_ff (.d(buf_head_next[1:0]),
always @(posedge enl2clk )
buf_head[1:0] <= buf_head_next[1:0];
assign wr_buf = (read_pending | write_pending) & ~buf_full;
assign buf_tail_next[1:0] = reset ? 2'b01 :
wr_buf ? {buf_tail[0], buf_tail[1]} : buf_tail[1:0];
dff #(2) buf_tail_ff (.d(buf_tail_next[1:0]),
always @(posedge enl2clk )
buf_tail[1:0] <= buf_tail_next[1:0];
assign buf_full_next = (buf_head_next[1:0] == buf_tail_next[1:0]) & wr_buf;
dffre #(1) buf_full_ff (.d(buf_full_next),
always @(posedge enl2clk ) begin
if (rd_buf|wr_buf) buf_full <= buf_full_next;
assign buf_empty_next = ((buf_head_next[1:0] == buf_tail_next[1:0]) & rd_buf) | reset;
dffe #(1) buf_empty_ff (.d(buf_empty_next),
.en(rd_buf|wr_buf|reset),
always @(posedge enl2clk )
if (rd_buf|wr_buf|reset) buf_empty <= buf_empty_next;
assign req_in[116:0] = {indata_buf[127:64],
assign buf0_en = buf_tail[0] & wr_buf;
dffe #(117) buf0_ff (.d(req_in[116:0]),
always @(posedge enl2clk )
if (buf0_en) buf0[116:0] <= req_in[116:0];
assign buf1_en = buf_tail[1] & wr_buf;
dffe #(117) buf1_ff (.d(req_in[116:0]),
always @(posedge enl2clk )
if (buf1_en) buf1[116:0] <= req_in[116:0];
assign req_out[116:0] = buf_head[0] ? buf0[116:0] :
buf_head[1] ? buf1[116:0] : 117'b0;
/************************************************************
* Inbound interface to local unit
************************************************************/
addr_in_spare[12:0],addr_in[26:0],
unconnected_size_in[2:0],
rd_req_vld_nq} = req_out[116:0];
assign rd_req_vld = rd_req_vld_nq & ~buf_empty;
assign wr_req_vld = wr_req_vld_nq & ~buf_empty;
/************************************************************
************************************************************/
assign ack_buf_wr = rd_ack_vld | rd_nack_vld;
assign ack_buf_vld_next = ack_buf_wr ? 1'b1 :
ack_buf_rd ? 1'b0 : ack_buf_vld;
dffr #(1) ack_buf_vld_ff (.d(ack_buf_vld_next),
dffe #(1) ack_buf_is_nack_ff (.d(rd_nack_vld),
always @(posedge enl2clk ) begin
ack_buf_vld <= ack_buf_vld_next;
always @(posedge enl2clk )
if (ack_buf_wr) ack_buf_is_nack <= rd_nack_vld;
assign ack_typ_out[3:0] = rd_ack_vld ? 4'b0001: //UCB_READ_ACK
assign ack_buf_in[75:0] = {data_out[63:0],
dffe #(76) ack_buf_ff (.d(ack_buf_in[75:0]),
always @(posedge enl2clk )
if (ack_buf_wr) ack_buf[75:0] <= ack_buf_in[75:0];
assign ack_buf_vec[3:0] = ack_buf_is_nack ? {2'b00,2'b11} : {4'b1111} ;
assign ack_busy = ack_buf_vld;
assign ack_buf_rd = ~outdata_buf_busy & ack_buf_vld ;
assign outdata_buf_wr = ack_buf_rd ;
assign outdata_buf_in[127:0] = {ack_buf[75:12], //payload 64bit
40'h00_0000_0000, //40bit addr [54:15]
ack_buf[11:10], //buf_id 2bit
ack_buf[9:4], //thr_id 6bit
ack_buf[3:0]}; //type 4bit
assign outdata_vec_in[3:0] = ack_buf_vec[3:0] ;
dmu_dsn_ucb_out32 dmu_dsn_ucb_out32 (.reset(reset),
.data(dmu_ncu_data[31:0]),
.outdata_buf_busy(outdata_buf_busy),
.outdata_buf_wr(outdata_buf_wr),
.outdata_buf_in(outdata_buf_in[127:0]),
.outdata_vec_in(outdata_vec_in[3:0]) );
/************************************************************
* debug-- dbg signals for a sub_sel 1
************************************************************/
assign ucb2ctl_dbg_grp_a_1[`FIRE_DEBUG_WDTH-1:0] = {ncu_dmu_vld,dmu_ncu_stall,read_pending,write_pending,
dmu_ncu_stall_a1,rd_nack_vld,dmu_ncu_vld,ncu_dmu_stall};
endmodule // dmu_dsn_ucb_flow