// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: dmu_imu_gcs_csm.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 ============================================
// ISS lookup request signals
// ISS lookup response signals
// Signal to Arbiter to arbitrate again
// LRM Mondo Enqueue Interface
//############################################################################
//############################################################################
//------------------------------------------------------------------------
// Clock and Reset Signals
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// ISS lookup request signals
//------------------------------------------------------------------------
output gcs2iss_tid_req; // Request ot ISS for TID for accepted mondo
output [5:0] gcs2iss_tid_sel; // Select for the TID output mux
output [63:0] gcs2iss_mdo_pending; // ID of mondo that was accecpted
//------------------------------------------------------------------------
// ISS lookup response signals
//------------------------------------------------------------------------
input iss2gcs_tid_ack; // Qualifier for tid of mondo
input [5:0] iss2gcs_tid; // TID of mondo
input iss2gcs_mondo_mode; // Mode of the modo
//------------------------------------------------------------------------
// Signal to Arbiter to arbitrate again
//------------------------------------------------------------------------
output next_arb; // Signal to GC arb to do next arb
//------------------------------------------------------------------------
//------------------------------------------------------------------------
input gc_arb_valid; // Valid signal saying that the arb winner is now valid are ready to be taken
input [5:0] gc_arb_ino; // The ino of winner from arbitration;
input [1:0] gc_arb_id; // ID of the group controller of the arb winner
//-----------------------------------------------------
// Interface for to LRM for Mondo Records
//-----------------------------------------------------
output im2rm_mdo_enq; //Enqueue signal for mondo record
output [`FIRE_DLC_MQR_REC_WDTH-1:0] im2rm_mdo; // Mondo data
//-----------------------------------------------------
//-----------------------------------------------------
output [`FIRE_DEBUG_WDTH-1:0] fsm_dbg;
//############################################################################
//############################################################################
parameter TID_REQ = 2'b01;
parameter TID_ACK = 2'b10;
parameter LRM_ENQ = 2'b11;
//############################################################################
//############################################################################
//------------------------
//------------------------
//-------------------------
// Regs that are NOT flops
//-------------------------
//------------------------
//------------------------
//############################################################################
//############################################################################
//---------------------------------------------------------------------
// One Hot / Bits On Checkers
//---------------------------------------------------------------------
//0in bits_on -var gcs2iss_mdo_pending -max 1
//---------------------------------------------------------------------
// REQ / ACK Interface Checkers
//---------------------------------------------------------------------
//0in req_ack -req gcs2iss_tid_req -ack iss2gcs_tid_ack -req_until_ack -new_req_after_ack -max_ack 1
//0in req_ack -req gc_arb_valid -ack next_arb -req_until_ack -new_req_after_ack -max_ack 1
//---------------------------------------------------------------------
// Known and Constant Checkers
//---------------------------------------------------------------------
//0in known_driven -var gcs2iss_mdo_pending -active gcs2iss_tid_req
//0in constant -var gcs2iss_mdo_pending -active gcs2iss_tid_req
//0in known_driven -var iss2gcs_tid -active iss2gcs_tid_ack
//0in constant -var iss2gcs_tid -active iss2gcs_tid_ack
//0in known_driven -var iss2gcs_mondo_mode -active iss2gcs_tid_ack
//0in constant -var iss2gcs_mondo_mode -active iss2gcs_tid_ack
//0in known_driven -var gc_arb_ino -active gc_arb_valid
//0in constant -var gc_arb_ino -active gc_arb_valid
//0in known_driven -var gc_arb_id -active gc_arb_valid
//0in constant -var gc_arb_id -active gc_arb_valid
//0in known_driven -var im2rm_mdo -active im2rm_mdo_enq
//0in constant -var im2rm_mdo -active im2rm_mdo_enq
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//0in assert_timer -var im2rm_mdo_enq -min 1 -max 1
//---------------------------------------------------------------------
// State Machine Checkers
//---------------------------------------------------------------------
//0in state_transition -var state -val IDLE -next TID_REQ
//0in state_transition -var state -val TID_REQ -next TID_ACK
//0in state_transition -var state -val TID_ACK -next LRM_ENQ
//0in state_transition -var state -val LRM_ENQ -next TID_REQ IDLE
//0in sequence -var state -val TID_REQ TID_ACK LRM_ENQ
//############################################################################
//############################################################################
//----------------------------------------------------------------------
// This function takes as an input a 6 bit vector encodes it to
// a 64 bit vector with one bit set.
// For Example on a 8 bit vector
//-----------------------------------------------------------------------
for (i=7'd0; i<= 7'd63; i=i+7'd1)
if (i[5:0] == vec) decode_vec[i] = 1'b1;
else decode_vec[i] = 1'b0;
//$display($time,": Ecoded value for vec = %0b is %0b\n",vec, enc_vec);
//############################################################################
//############################################################################
//-------------------------------------------------------------------
// Assign the outputs to the ISS
// - req should be assrted in REQ state until gets and ACK back
// - The ino should be the registered version encoded to 64 bits
//-------------------------------------------------------------------
assign gcs2iss_tid_req = (state == TID_REQ) | (state == TID_ACK);
assign gcs2iss_mdo_pending = decode(current_ino);
assign gcs2iss_tid_sel = current_ino;
//-------------------------------------------------------------------
// Assign the outputs to the LRM
// - Enq should be pulsed every LRM_ENQ state
// - Concat the proper registed flops togther.
//-------------------------------------------------------------------
assign im2rm_mdo_enq = (state == LRM_ENQ);
assign im2rm_mdo = {iss2gcs_tid[5],iss2gcs_mondo_mode, current_ino, iss2gcs_tid[4:0], current_id};
//-------------------------------------------------------------------
// Do the internal combination control signals
// - Next arb should happen ever TID req to get the next arb ready and exposed
// - Register the current id and ino before the new values are loaded in on the
//-------------------------------------------------------------------
assign next_arb = (state == TID_REQ);
assign load_new_mondo = (n_state == TID_REQ);
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
assign fsm_dbg = {2'h0, state[1:0], gc_arb_valid, iss2gcs_tid_ack, gc_arb_id[1:0]};
//############################################################################
//############################################################################
//-----------------------------------------------------------------------
// Flop the arb winner's INO and ID
// - Load the new valaue of the winner when appropriate
// or hold the current value
//-----------------------------------------------------------------------
current_ino <= gc_arb_ino;
current_ino <= current_ino;
current_id <= current_id ;
//-----------------------------------------------------------------------
// Next State Logic, Assign next state to current state
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
always @(state or gc_arb_valid or iss2gcs_tid_ack)
case (state) // synopsys parallel_case full_case
//********************************************************
// - Wait here until the arbiter has a mondo which needs
//********************************************************
if (gc_arb_valid) // If there is interrupt waiting arb
else // If there are no interrupts that needs servicing
//********************************************************
// - This state is used to issue the request to the ISS
// to obatin the TID for the mondo which the arbiter
// selected as the winner.
// - This state is also used to trigger the loading of
// the next winner for the arbiter and to latch in
// the value of the current winners before they change
//********************************************************
n_state = TID_ACK; // Stay here for one cycle
//********************************************************
// - Wait in this state until the ISS respons with an
// ACK and the TID of the requested mondo
//********************************************************
if (iss2gcs_tid_ack) // If get granted by the ISS
n_state = TID_ACK; // If still not granted wait here
//********************************************************
// - This state is used to enqueue the request to the
// - If another requests is waiting go handle it
// - If not go back to IDLE
//********************************************************
if (gc_arb_valid) // If another request is waiting
else // Another request is not waiting more waiting