// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dmu_dsn_ucb_in32.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_in32 (
output [127:0] indata_buf;
wire [3:0] indata_vec_next;
wire [127:0] indata_buf_next;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/************************************************************
* UCB bus interface flops
* This is to make signals going between NCU and UCB flop-to-flop
************************************************************/
dffre #(1) vld_d1_ff (.d(vld),
dffe #(32) data_d1_ff (.d(data[31:0]),
dffr #(1) stall_ff (.d(stall_a1),
dffr #(1) stall_d1_ff (.d(stall),
always @(posedge enl2clk ) begin
if (~stall_d1) vld_d1 <= vld;
always @(posedge enl2clk )
if (~stall_d1) data_d1[31:0] <= data[31:0];
/************************************************************
* We need a two deep skid buffer to handle stalling.
************************************************************/
// Assertion: stall has to be deasserted for more than 1 cycle
// ie time between two separate stalls has to be
// at least two cycles. Otherwise, contents from
// skid buffer will be lost.
assign skid_buf0_en = stall_a1 & ~stall;
dffre #(1) vld_buf0_ff (.d(vld_d1),
dffe #(32) data_buf0_ff (.d(data_d1[31:0]),
dffr #(1) skid_buf1_en_ff (.d(skid_buf0_en),
dffre #(1) vld_buf1_ff (.d(vld_d1),
dffe #(32) data_buf1_ff (.d(data_d1[31:0]),
always @(posedge enl2clk ) begin
if (skid_buf0_en) vld_buf0 <= vld_d1;
skid_buf1_en <= skid_buf0_en;
if (skid_buf1_en) vld_buf1 <= vld_d1;
always @(posedge enl2clk )
if (skid_buf0_en) data_buf0[31:0]<= data_d1[31:0];
if (skid_buf1_en) data_buf1[31:0]<= data_d1[31:0];
/************************************************************
* Mux between skid buffer and interface flop
************************************************************/
// Assertion: stall has to be deasserted for more than 1 cycle
// ie time between two separate stalls has to be
// at least two cycles. Otherwise, contents from
// skid buffer will be lost.
assign skid_buf0_sel = ~stall_a1 & stall;
dffr #(1) skid_buf1_sel_ff (.d(skid_buf0_sel),
always @(posedge enl2clk ) begin
skid_buf1_sel <= skid_buf0_sel;
assign vld_mux = skid_buf0_sel ? vld_buf0 :
skid_buf1_sel ? vld_buf1 : vld_d1;
assign data_mux[31:0] = skid_buf0_sel ? data_buf0[31:0] :
skid_buf1_sel ? data_buf1[31:0] : data_d1[31:0];
/************************************************************
************************************************************/
assign indata_vec_next[3:0] = {vld_mux,indata_vec[3:1]};
assign stall_a1_inv = ~stall_a1 ;
dffre #(4) indata_vec_ff (.d(indata_vec_next[3:0]),
assign indata_buf_next[127:0] = {data_mux[31:0],indata_buf[127:32]};
dffe #(128) indata_buf_ff (.d(indata_buf_next[127:0]),
dffre #(1) indata_vec0_d1_ff (.d(indata_vec[0]),
always @(posedge enl2clk )
if (stall_a1_inv) indata_vec[3:0] <= indata_vec_next[3:0];
if (stall_a1_inv) indata_vec0_d1 <= indata_vec[0];
always @(posedge enl2clk )
indata_buf[127:0]<= 128'b0;
if (stall_a1_inv) indata_buf[127:0]<= indata_buf_next[127:0];
assign indata_buf_vld = indata_vec[0] & ~indata_vec0_d1;
endmodule // dmu_dsn_ucb_in32