/*
 * Copyright (c) 2021 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// ---- Outbound port definitions ----
// Network interfaces
out_port(reqOutPort, CHIRequestMsg, reqOut);
out_port(snpOutPort, CHIRequestMsg, snpOut);
out_port(rspOutPort, CHIResponseMsg, rspOut);
out_port(datOutPort, CHIDataMsg, datOut);
// Internal output ports
out_port(triggerOutPort, TriggerMsg, triggerQueue);
out_port(retryTriggerOutPort, RetryTriggerMsg, retryTriggerQueue);
out_port(schedRspTriggerOutPort, CHIResponseMsg, schedRspTriggerQueue);
out_port(reqRdyOutPort, CHIRequestMsg, reqRdy);
out_port(snpRdyOutPort, CHIRequestMsg, snpRdy);


// Include helper functions here. Some of them require the outports to be
// already defined
// Notice 'processNextState' and 'wakeupPending*' functions are defined after
// the required input ports. Currently the SLICC compiler does not support
// separate declaration and definition of functions in the .sm files.
include "CHI-dvm-misc-node-funcs.sm";


// Inbound port definitions and internal triggers queues
// Notice we never stall input ports connected to the network
// Incoming data and responses are always consumed.
// Incoming requests/snoop are moved to the respective internal rdy queue
// if a TBE can be allocated, or retried otherwise.

// Response
in_port(rspInPort, CHIResponseMsg, rspIn, rank=11,
        rsc_stall_handler=rspInPort_rsc_stall_handler) {
  if (rspInPort.isReady(clockEdge())) {
    printResources();
    peek(rspInPort, CHIResponseMsg) {
      assert(in_msg.usesTxnId);
      TBE tbe := getCurrentActiveTBE(in_msg.txnId);
      trigger(respToEvent(in_msg.type), in_msg.txnId, tbe);
    }
  }
}
bool rspInPort_rsc_stall_handler() {
  error("rspInPort must never stall\n");
  return false;
}


// Data
in_port(datInPort, CHIDataMsg, datIn, rank=10,
        rsc_stall_handler=datInPort_rsc_stall_handler) {
  if (datInPort.isReady(clockEdge())) {
    printResources();
    peek(datInPort, CHIDataMsg) {
      int received := in_msg.bitMask.count();
      assert((received <= data_channel_size) && (received > 0));
      assert(in_msg.usesTxnId);
      trigger(dataToEvent(in_msg.type), in_msg.txnId, getCurrentActiveTBE(in_msg.txnId));
    }
  }
}
bool datInPort_rsc_stall_handler() {
  error("datInPort must never stall\n");
  return false;
}

// Incoming snoops - should never be used
in_port(snpInPort, CHIRequestMsg, snpIn, rank=8) {
  if (snpInPort.isReady(clockEdge())) {
    printResources();
    peek(snpInPort, CHIRequestMsg) {
      error("MN should not receive snoops");
    }
  }
}
bool snpInPort_rsc_stall_handler() {
  error("snpInPort must never stall\n");
  return false;
}

// Incoming new requests
in_port(reqInPort, CHIRequestMsg, reqIn, rank=2,
        rsc_stall_handler=reqInPort_rsc_stall_handler) {
  if (reqInPort.isReady(clockEdge())) {
    printResources();
    peek(reqInPort, CHIRequestMsg) {
      assert(in_msg.usesTxnId);
      // Make sure we aren't already processing this
      TBE tbe := getCurrentActiveTBE(in_msg.txnId);
      assert(!is_valid(tbe));
      if (in_msg.allowRetry) {
        trigger(Event:AllocRequest, in_msg.txnId, nullTBE());
      } else {
        trigger(Event:AllocRequestWithCredit, in_msg.txnId, nullTBE());
      }
    }
  }
}
bool reqInPort_rsc_stall_handler() {
  error("reqInPort must never stall\n");
  return false;
}


// Incoming new sequencer requests
in_port(seqInPort, RubyRequest, mandatoryQueue, rank=1) {
  if (seqInPort.isReady(clockEdge())) {
    printResources();
    peek(seqInPort, RubyRequest) {
      error("MN should not have sequencer");
    }
  }
}


// Action triggers
in_port(triggerInPort, TriggerMsg, triggerQueue, rank=5,
        rsc_stall_handler=triggerInPort_rsc_stall_handler) {
  if (triggerInPort.isReady(clockEdge())) {
    printResources();
    peek(triggerInPort, TriggerMsg) {
      TBE tbe := getCurrentActiveTBE(in_msg.txnId);
      assert(is_valid(tbe));
      assert(!in_msg.from_hazard);
      trigger(tbe.pendAction, in_msg.txnId, tbe);
    }
  }
}
bool triggerInPort_rsc_stall_handler() {
  DPRINTF(RubySlicc, "Trigger queue resource stall\n");
  triggerInPort.recycle(clockEdge(), cyclesToTicks(stall_recycle_lat));
  return true;
}
void wakeupPendingTgrs(TBE tbe) {
  if (tbe.wakeup_pending_tgr) {
    Addr txnId := tbe.txnId;
    wakeup_port(triggerInPort, txnId);
    tbe.wakeup_pending_tgr := false;
  }
}

// Requests with an allocated TBE
in_port(reqRdyPort, CHIRequestMsg, reqRdy, rank=3,
        rsc_stall_handler=reqRdyPort_rsc_stall_handler) {
  if (reqRdyPort.isReady(clockEdge())) {
    printResources();
    peek(reqRdyPort, CHIRequestMsg) {
      assert(in_msg.usesTxnId);
      TBE tbe := getCurrentActiveTBE(in_msg.txnId);
      assert(!in_msg.is_local_pf);
      // Normal request path
      trigger(reqToEvent(in_msg.type), in_msg.txnId, tbe);
    }
  }
}
bool reqRdyPort_rsc_stall_handler() {
  DPRINTF(RubySlicc, "ReqRdy queue resource stall\n");
  reqRdyPort.recycle(clockEdge(), cyclesToTicks(stall_recycle_lat));
  return true;
}
void wakeupPendingReqs(TBE tbe) {
  if (tbe.wakeup_pending_req) {
    Addr txnId := tbe.txnId;
    wakeup_port(reqRdyPort, txnId);
    tbe.wakeup_pending_req := false;
  }
}


// Retry action triggers
// These are handled separately from other triggers since these events are
// not tied to a TBE
in_port(retryTriggerInPort, RetryTriggerMsg, retryTriggerQueue, rank=7) {
  if (retryTriggerInPort.isReady(clockEdge())) {
    printResources();
    peek(retryTriggerInPort, RetryTriggerMsg) {
      Event ev := in_msg.event;
      TBE tbe := getCurrentActiveTBE(in_msg.txnId);
      assert((ev == Event:SendRetryAck) || (ev == Event:SendPCrdGrant));
      trigger(ev, in_msg.txnId, tbe);
    }
  }
}

// Trigger queue for scheduled responses so transactions don't need to
// block on a response when the rspOutPort is busy
in_port(schedRspTriggerInPort, CHIResponseMsg, schedRspTriggerQueue, rank=6) {
  if (schedRspTriggerInPort.isReady(clockEdge())) {
    printResources();
    peek(schedRspTriggerInPort, CHIResponseMsg) {
      error("Misc Node shouldn't have schedResp");
    }
  }
}

// Enqueues next event depending on the pending actions and the event queue
void processNextState(TBE tbe) {
  assert(is_valid(tbe));
  DPRINTF(RubyProtocol, "GoToNextState state=%d expected_req_resp=%d expected_snp_resp=%d sched_rsp=%d(block=%d) pendAction: %d\n",
                      tbe.state,
                      tbe.expected_req_resp.expected(),
                      tbe.expected_snp_resp.expected(),
                      tbe.sched_responses, tbe.block_on_sched_responses,
                      tbe.pendAction);

  // if no pending trigger and not expecting to receive anything, enqueue
  // next
  bool has_nb_trigger := (tbe.actions.empty() == false) &&
                          tbe.actions.frontNB();
  int expected_msgs := tbe.expected_req_resp.expected() +
                        tbe.expected_snp_resp.expected();
  if (tbe.block_on_sched_responses) {
    expected_msgs := expected_msgs + tbe.sched_responses;
    tbe.block_on_sched_responses := tbe.sched_responses > 0;
  }

  // If we are waiting on other transactions to finish, we shouldn't enqueue Final
  bool would_enqueue_final := tbe.actions.empty();
  bool allowed_to_enqueue_final := !tbe.waiting_on_other_txns;
  // if (would_enqueue_final && !allowed) then DON'T enqueue anything
  // => if (!would_enqueue_final || allowed_to_enqueue_final) then DO
  bool allowed_to_enqueue_action := !would_enqueue_final || allowed_to_enqueue_final;

  if ((tbe.pendAction == Event:null) &&
      ((expected_msgs == 0) || has_nb_trigger) &&
      allowed_to_enqueue_action) {
    Cycles trigger_latency := intToCycles(0);
    if (tbe.delayNextAction > curTick()) {
      trigger_latency := ticksToCycles(tbe.delayNextAction) -
                          ticksToCycles(curTick());
      tbe.delayNextAction := intToTick(0);
    }

    tbe.pendAction := Event:null;
    if (tbe.actions.empty()) {
      // time to go to the final state
      tbe.pendAction := Event:Final;
    } else {
      tbe.pendAction := tbe.actions.front();
      tbe.actions.pop();
    }
    assert(tbe.pendAction != Event:null);
    enqueue(triggerOutPort, TriggerMsg, trigger_latency) {
      out_msg.txnId := tbe.txnId;
      out_msg.from_hazard := false;
    }
  }

  printTBEState(tbe);
}

// Runs at the end of every cycle that takes input, checks `needsToCheckPendingOps`.
// if true, will call updatePendingOps() to check if a new snoop-sender should start.
// We could return bools if we want to be sure we run on the next cycle,
// but we have no reason to do that
void updatePendingOps(), run_on_input_cycle_end="yes" {
  if (needsToCheckPendingOps) {
    needsToCheckPendingOps := false;
    DPRINTF(RubyProtocol, "Misc Node updating pending ops\n");
    TBE newDistributor := dvmTBEs.chooseNewDistributor();
    DPRINTF(RubyProtocol, "Misc Node selected %p\n", newDistributor);
    if (is_valid(newDistributor)) {
      // can return the current distributor, check for that
      if (!hasCurrentDistributor || newDistributor.txnId != currentDistributor) {
        currentDistributor := newDistributor.txnId;
        hasCurrentDistributor := true;

        // make the new distributor start distributing
        // by simply telling it to send the next message
        newDistributor.actions.pushNB(Event:DvmSendNextMessage_P1);
        processNextState(newDistributor);

        // TODO could move into Profile_OutgoingStart_DVM
        // Use a useful event name for profiling
        Event usefulEvent := Event:DvmSync_Initiate;
        if (newDistributor.isNonSync) {
          usefulEvent := Event:DvmTlbi_Initiate;
        }
        outgoingTransactionStart(newDistributor.txnId, usefulEvent, false);
      }
    }
  }
}