/*
 * Copyright (c) 2021-2022 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.
 */


////////////////////////////////////////////////////////////////////////////
// CHI-cache function definitions
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// External functions

Tick clockEdge();
Tick curTick();
Tick cyclesToTicks(Cycles c);
Cycles ticksToCycles(Tick t);
void set_tbe(TBE b);
void unset_tbe();
MachineID mapAddressToDownstreamMachine(Addr addr);
NetDest allUpstreamDest();

void incomingTransactionStart(Addr, Event, State, bool);
void incomingTransactionEnd(Addr, State);
void outgoingTransactionStart(Addr, Event);
void outgoingTransactionEnd(Addr, bool);
// Overloads for transaction-measuring functions
// final bool = isMemoryAccess
// if false, uses a "global access" table
void incomingTransactionStart(Addr, Event, State, bool, bool);
void incomingTransactionEnd(Addr, State, bool);
void outgoingTransactionStart(Addr, Event, bool);
void outgoingTransactionEnd(Addr, bool, bool);
Event curTransitionEvent();
State curTransitionNextState();

void notifyPfHit(RequestPtr req, bool is_read, DataBlock blk) { }
void notifyPfMiss(RequestPtr req, bool is_read, DataBlock blk) { }
void notifyPfFill(RequestPtr req, DataBlock blk, bool from_pf) { }
void notifyPfEvict(Addr blkAddr, bool hwPrefetched) { }
void notifyPfComplete(Addr addr) { }

void scheduleEvent(Cycles);

////////////////////////////////////////////////////////////////////////////
// Interface functions required by SLICC

int tbePartition(bool is_non_sync) {
    if (is_non_sync) {
        return 1;
    } else {
        return 0;
    }
}

State getState(TBE tbe, Addr txnId) {
  if (is_valid(tbe)) {
      return tbe.state;
  } else {
    return State:Unallocated;
  }
}

void setState(TBE tbe, Addr txnId, State state) {
  if (is_valid(tbe)) {
    tbe.state := state;
  }
}

TBE nullTBE(), return_by_pointer="yes" {
  return OOD;
}

TBE getCurrentActiveTBE(Addr txnId), return_by_pointer="yes" {
  // Current Active TBE for an address
  return dvmTBEs[txnId];
}

AccessPermission getAccessPermission(Addr txnId) {
  // MN has no memory
  return AccessPermission:NotPresent;
}

void setAccessPermission(Addr txnId, State state) {}

void functionalRead(Addr txnId, Packet *pkt, WriteMask &mask) {
  // We don't have any memory, so we can't functionalRead
  // => we don't fill the `mask` argument
}

int functionalWrite(Addr txnId, Packet *pkt) {
  // No memory => no functional writes
  return 0;
}

Cycles mandatoryQueueLatency(RubyRequestType type) {
  return intToCycles(1);
}

Cycles tagLatency(bool from_sequencer) {
  return intToCycles(0);
}

Cycles dataLatency() {
  return intToCycles(0);
}

bool inCache(Addr txnId) {
  return false;
}

bool hasBeenPrefetched(Addr txnId) {
  return false;
}

bool inMissQueue(Addr txnId) {
  return false;
}

void notifyCoalesced(Addr txnId, RubyRequestType type, RequestPtr req,
                     DataBlock data_blk, bool was_miss) {
  DPRINTF(RubySlicc, "Unused notifyCoalesced(txnId=%#x, type=%s, was_miss=%d)\n",
                      txnId, type, was_miss);
}

////////////////////////////////////////////////////////////////////////////
// State->Event converters

Event reqToEvent(CHIRequestType type) {
  if (type == CHIRequestType:DvmOpNonSync) {
    return Event:DvmTlbi_Initiate;
  } else if (type == CHIRequestType:DvmOpSync) {
    return Event:DvmSync_Initiate;
  } else {
    error("Invalid/unexpected CHIRequestType");
  }
}

Event respToEvent (CHIResponseType type) {
  if (type == CHIResponseType:SnpResp_I) {
    return Event:SnpResp_I;
  } else {
    error("Invalid/unexpected CHIResponseType");
  }
}

Event dataToEvent (CHIDataType type) {
  if (type == CHIDataType:NCBWrData) {
    return Event:NCBWrData;
  } else {
    error("Invalid/unexpected CHIDataType");
  }
}

////////////////////////////////////////////////////////////////////////////
// Allocation

void clearExpectedReqResp(TBE tbe) {
  assert(blockSize >= data_channel_size);
  assert((blockSize % data_channel_size) == 0);
  tbe.expected_req_resp.clear(blockSize / data_channel_size);
}

void clearExpectedSnpResp(TBE tbe) {
  assert(blockSize >= data_channel_size);
  assert((blockSize % data_channel_size) == 0);
  tbe.expected_snp_resp.clear(blockSize / data_channel_size);
}

void initializeTBE(TBE tbe, Addr txnId, int storSlot) {
  assert(is_valid(tbe));

  tbe.timestamp := curTick();

  tbe.wakeup_pending_req := false;
  tbe.wakeup_pending_snp := false;
  tbe.wakeup_pending_tgr := false;

  tbe.txnId := txnId;

  tbe.storSlot := storSlot;

  clearExpectedReqResp(tbe);
  clearExpectedSnpResp(tbe);
  // Technically we don't *know* if we're waiting on other transactions,
  // but we need to stop this transaction from errantly being *finished*.
  tbe.waiting_on_other_txns := true;

  tbe.sched_responses := 0;
  tbe.block_on_sched_responses := false;


  tbe.pendAction := Event:null;
  tbe.finalState := State:null;
  tbe.delayNextAction := intToTick(0);

  // The MN uses the list of "upstream destinations"
  // as targets for snoops
  tbe.notSentTargets := allUpstreamDest();
  tbe.pendingTargets.clear();
  tbe.receivedTargets.clear();
}

TBE allocateDvmRequestTBE(Addr txnId, CHIRequestMsg in_msg), return_by_pointer="yes" {
  DPRINTF(RubySlicc, "allocateDvmRequestTBE %x %016llx\n", in_msg.type, txnId);

  bool isNonSync := in_msg.type == CHIRequestType:DvmOpNonSync;

  int partition := tbePartition(isNonSync);
  // We must have reserved resources for this allocation
  storDvmTBEs.decrementReserved(partition);
  assert(storDvmTBEs.areNSlotsAvailable(1, partition));

  dvmTBEs.allocate(txnId);
  TBE tbe := dvmTBEs[txnId];

  // Setting .txnId = txnId
  initializeTBE(tbe, txnId, storDvmTBEs.addEntryToNewSlot(partition));

  tbe.isNonSync := isNonSync;

  tbe.requestor := in_msg.requestor;
  tbe.reqType := in_msg.type;

  // We don't want to send a snoop request to
  // the original requestor
  tbe.notSentTargets.remove(in_msg.requestor);

  return tbe;
}

void deallocateDvmTBE(TBE tbe) {
  assert(is_valid(tbe));
  storDvmTBEs.removeEntryFromSlot(tbe.storSlot, tbePartition(tbe.isNonSync));
  dvmTBEs.deallocate(tbe.txnId);
}

void clearPendingAction(TBE tbe) {
  tbe.pendAction := Event:null;
}

////////////////////////////////////////////////////////////////////////////
// Retry-related

void processRetryQueue() {
  // send credit if requestor waiting for it and we have resources

  // Ask the DVM storage if we have space to retry anything.
  if (storDvmTBEs.hasPossibleRetry()) {
    RetryQueueEntry toRetry := storDvmTBEs.popNextRetryEntry();
    storDvmTBEs.incrementReserved(tbePartition(toRetry.isNonSync));
    enqueue(retryTriggerOutPort, RetryTriggerMsg, crd_grant_latency) {
      out_msg.txnId := toRetry.txnId;
      out_msg.retryDest := toRetry.retryDest;
      out_msg.event := Event:SendPCrdGrant;
    }
  }
}

////////////////////////////////////////////////////////////////////////////
// Other

void printResources() {
  DPRINTF(RubySlicc, "Resources(used/rsvd/max): dvmTBEs=%d/%d/%d\n",
                storDvmTBEs.size(), storDvmTBEs.reserved(), storDvmTBEs.capacity());
  DPRINTF(RubySlicc, "Resources(in/out size): req=%d/%d rsp=%d/%d dat=%d/%d snp=%d/%d trigger=%d\n",
                reqIn.getSize(curTick()), reqOut.getSize(curTick()),
                rspIn.getSize(curTick()), rspOut.getSize(curTick()),
                datIn.getSize(curTick()), datOut.getSize(curTick()),
                snpIn.getSize(curTick()), snpOut.getSize(curTick()),
                triggerQueue.getSize(curTick()));
}

void printTBEState(TBE tbe) {
  DPRINTF(RubySlicc, "STATE: txnId=%#x reqType=%d state=%d pendAction=%s\n",
                      tbe.txnId, tbe.reqType, tbe.state, tbe.pendAction);
}

void prepareRequest(TBE tbe, CHIRequestType type, CHIRequestMsg & out_msg) {
  out_msg.addr := tbe.txnId;
  out_msg.accAddr := tbe.txnId;
  out_msg.accSize := blockSize;
  out_msg.requestor := machineID;
  out_msg.fwdRequestor := tbe.requestor;
  out_msg.type := type;
  out_msg.allowRetry := false;
  out_msg.isSeqReqValid := false;
  out_msg.is_local_pf := false;
  out_msg.is_remote_pf := false;
}
