/*
 * 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.
 */


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

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

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

void incomingTransactionStart(Addr, Event, State, bool);
void incomingTransactionEnd(Addr, State);
void outgoingTransactionStart(Addr, Event);
void outgoingTransactionEnd(Addr, bool);
Event curTransitionEvent();
State curTransitionNextState();

// Placeholders for future prefetch support
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) { }

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

CacheEntry getCacheEntry(Addr addr), return_by_pointer="yes" {
  return static_cast(CacheEntry, "pointer", cache.lookup(addr));
}

DirEntry getDirEntry(Addr addr), return_by_pointer = "yes" {
  if (directory.isTagPresent(addr)) {
    return directory.lookup(addr);
  } else {
    return OOD;
  }
}

State getState(TBE tbe, CacheEntry cache_entry, Addr addr) {
  if (is_valid(tbe)) {
      return tbe.state;
  } else if (is_valid(cache_entry)) {
    return cache_entry.state;
  } else {
      DirEntry dir_entry := getDirEntry(addr);
      if (is_valid(dir_entry)) {
        return dir_entry.state;
      } else {
        return State:I;
      }
  }
}

void setState(TBE tbe, CacheEntry cache_entry, Addr addr, State state) {
  if (is_valid(tbe)) {
    tbe.state := state;
  }
  if (is_valid(cache_entry)) {
    cache_entry.state := state;
  }
  DirEntry dir_entry := getDirEntry(addr);
  if (is_valid(dir_entry)) {
    dir_entry.state := state;
  }
}

TBE getCurrentActiveTBE(Addr addr), return_by_pointer="yes" {
  // snoops take precedence over wbs and reqs
  // it's invalid to have a replacement and a req active at the same time
  // for the same line
  TBE snp_tbe := snpTBEs[addr];
  if (is_valid(snp_tbe)) {
    return snp_tbe;
  }
  TBE req_tbe := TBEs[addr];
  TBE repl_tbe := replTBEs[addr];
  if (is_valid(req_tbe)) {
    assert(is_invalid(repl_tbe));
    return req_tbe;
  }
  if (is_valid(repl_tbe)) {
    assert(is_invalid(req_tbe));
    return repl_tbe;
  }
  return OOD;
}

AccessPermission getAccessPermission(Addr addr) {
  TBE tbe := getCurrentActiveTBE(addr);
  if(is_valid(tbe)) {
    assert(Cache_State_to_permission(tbe.state) == AccessPermission:Busy);
    if (tbe.expected_req_resp.hasExpected() ||
        tbe.expected_snp_resp.hasExpected()) {
      DPRINTF(RubySlicc, "%x %s,%s\n", addr, tbe.state, AccessPermission:Busy);
      return AccessPermission:Busy;
    }
    else if (tbe.dataValid && (tbe.dataMaybeDirtyUpstream == false)) {
      if (tbe.dataUnique) {
        DPRINTF(RubySlicc, "%x %s,%s\n", addr, tbe.state, AccessPermission:Read_Write);
        return AccessPermission:Read_Write;
      } else {
        DPRINTF(RubySlicc, "%x %s,%s\n", addr, tbe.state, AccessPermission:Read_Only);
        return AccessPermission:Read_Only;
      }
    } else {
      DPRINTF(RubySlicc, "%x %s,%s\n", addr, tbe.state, AccessPermission:Busy);
      return AccessPermission:Busy;
    }
  }
  CacheEntry cache_entry := getCacheEntry(addr);
  if(is_valid(cache_entry)) {
      DPRINTF(RubySlicc, "%x %s,%s\n", addr, cache_entry.state, Cache_State_to_permission(cache_entry.state));
      return Cache_State_to_permission(cache_entry.state);
  }
  DPRINTF(RubySlicc, "%x %s,%s\n", addr, State:I, AccessPermission:NotPresent);
  return AccessPermission:NotPresent;
}

void setAccessPermission(CacheEntry cache_entry, Addr addr, State state) {
  if (is_valid(cache_entry)) {
      cache_entry.changePermission(Cache_State_to_permission(state));
  }
}

void functionalRead(Addr addr, Packet *pkt, WriteMask &mask) {
  // read if bitmask has bytes not in mask or if data is dirty

  TBE tbe := getCurrentActiveTBE(addr);
  CacheEntry cache_entry := getCacheEntry(addr);
  DPRINTF(RubySlicc, "functionalRead %x\n", addr);
  WriteMask read_mask;
  bool dirty := false;
  bool from_tbe := false;

  if (is_valid(tbe)) {
    from_tbe := true;
    dirty := tbe.dataDirty;
    if (tbe.dataValid) {
      read_mask.fillMask();
    } else {
      read_mask := tbe.dataBlkValid;
      // could have received dirty data but tbe.dataDirty not set yet because
      // some data is pending, so check for dirty received message types
      dirty := dirty ||
            tbe.expected_req_resp.receivedDataType(CHIDataType:CompData_UD_PD) ||
            tbe.expected_req_resp.receivedDataType(CHIDataType:CompData_SD_PD) ||
            tbe.expected_req_resp.receivedDataType(CHIDataType:CBWrData_UD_PD) ||
            tbe.expected_req_resp.receivedDataType(CHIDataType:CBWrData_SD_PD) ||
            tbe.expected_req_resp.receivedDataType(CHIDataType:NCBWrData) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_I_PD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_SC_PD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_SD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_UD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_SC_Fwded_SD_PD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_SC_PD_Fwded_SC) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_I_Fwded_SD_PD) ||
            tbe.expected_snp_resp.receivedDataType(CHIDataType:SnpRespData_I_PD_Fwded_SC);
    }
  } else if (is_valid(cache_entry) &&
             ((Cache_State_to_permission(cache_entry.state) == AccessPermission:Read_Write) ||
              (Cache_State_to_permission(cache_entry.state) == AccessPermission:Read_Only))) {
    from_tbe := false;
    read_mask.fillMask();
    dirty := (cache_entry.state == State:UD) || (cache_entry.state == State:UD_RSC) ||
             (cache_entry.state == State:SD) || (cache_entry.state == State:SD_RSC) ||
             (cache_entry.state == State:UD_RU) || (cache_entry.state == State:UD_RSD) ||
             (cache_entry.state == State:SD_RSD) || (cache_entry.state == State:UD_T);
  }

  WriteMask test_mask := mask;
  test_mask.orMask(read_mask);
  if ((mask.containsMask(test_mask) == false) || dirty) {
    if (from_tbe) {
      if(testAndReadMask(addr, tbe.dataBlk, read_mask, pkt)) {
        DPRINTF(RubySlicc, "functionalRead tbe %x %s dirty=%d %s %s\n", addr, tbe.dataBlk, tbe.dataDirty, read_mask, mask);
        mask.orMask(read_mask);
      }
    } else {
      if (testAndReadMask(addr, cache_entry.DataBlk, read_mask, pkt)) {
        DPRINTF(RubySlicc, "functionalRead cache %x %s dirty=%d %s %s\n", addr, cache_entry.DataBlk, dirty, read_mask, mask);
        mask.orMask(read_mask);
      }
    }
  }
}

int functionalWrite(Addr addr, Packet *pkt) {
  int num_functional_writes := 0;
  TBE tbe := getCurrentActiveTBE(addr);
  if(is_valid(tbe)) {
    num_functional_writes := num_functional_writes +
      testAndWrite(addr, tbe.dataBlk, pkt);
    DPRINTF(RubySlicc, "functionalWrite tbe %x %s\n", addr, tbe.dataBlk);
  }
  CacheEntry cache_entry := getCacheEntry(addr);
  if (is_valid(cache_entry)) {
    num_functional_writes := num_functional_writes +
      testAndWrite(addr, cache_entry.DataBlk, pkt);
    DPRINTF(RubySlicc, "functionalWrite cache %x %s\n", addr, cache_entry.DataBlk);
  }
  return num_functional_writes;
}

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

Cycles tagLatency(bool from_sequencer) {
  if (from_sequencer) {
    //mandatoryQueueLatency accounts for 1 cy
    return cache.getTagLatency() - intToCycles(1);
  } else {
    return cache.getTagLatency();
  }
}

Cycles dataLatency() {
  return cache.getDataLatency();
}

bool inCache(Addr addr) {
  CacheEntry entry := getCacheEntry(makeLineAddress(addr));
  // NOTE: we consider data for the addr to be in cache if it exists in local,
  // upstream, or both caches.
  if ((is_valid(entry) == false) || (entry.state == State:I)) {
    return false;
  } else {
    return true;
  }
}

bool hasBeenPrefetched(Addr addr) {
  CacheEntry entry := getCacheEntry(makeLineAddress(addr));
  if (is_valid(entry)) {
    return entry.HWPrefetched;
  } else {
    return false;
  }
}

bool inMissQueue(Addr addr) {
  Addr line_addr := makeLineAddress(addr);
  TBE tbe := getCurrentActiveTBE(line_addr);
  return is_valid(tbe);
}

void notifyCoalesced(Addr addr, RubyRequestType type, RequestPtr req,
                     DataBlock data_blk, bool was_miss) {
  DPRINTF(RubySlicc, "notifyCoalesced(addr=%#x, type=%s, was_miss=%d)\n",
                      addr, type, was_miss);
  if (was_miss) {
    cache.profileDemandMiss();
  } else {
    cache.profileDemandHit();
  }
  if (use_prefetcher) {
    bool is_read := (type == RubyRequestType:LD) ||
                    (type == RubyRequestType:Load_Linked) ||
                    (type == RubyRequestType:IFETCH);
    if (was_miss) {
      notifyPfMiss(req, is_read, data_blk);
    } else {
      notifyPfHit(req, is_read, data_blk);
    }
  }
}


////////////////////////////////////////////////////////////////////////////
// Helper functions


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 addr, int storSlot) {
  assert(is_valid(tbe));

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

  tbe.addr := addr;

  tbe.storSlot := storSlot;

  clearExpectedReqResp(tbe);
  clearExpectedSnpResp(tbe);
  tbe.defer_expected_comp := false;

  tbe.requestorToBeOwner := false;
  tbe.requestorToBeExclusiveOwner := false;
  tbe.updateDirOnCompAck := true;

  tbe.dataToBeInvalid := false;
  tbe.dataToBeSharedClean := false;

  tbe.doCacheFill := false;

  tbe.pendReqType := CHIRequestType:null;

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

  tbe.is_stale := false;
}

TBE allocateRequestTBE(Addr addr, CHIRequestMsg in_msg), return_by_pointer="yes" {
  // We must have reserved resources for this allocation
  storTBEs.decrementReserved();
  assert(storTBEs.areNSlotsAvailable(1));

  TBEs.allocate(addr);
  TBE tbe := TBEs[addr];

  initializeTBE(tbe, addr, storTBEs.addEntryToNewSlot());

  assert(tbe.is_snp_tbe == false);
  assert(tbe.is_repl_tbe == false);
  tbe.is_req_tbe := true;

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

  tbe.isSeqReqValid := in_msg.isSeqReqValid;
  tbe.seqReq := in_msg.seqReq;
  tbe.is_local_pf := in_msg.is_local_pf;
  tbe.is_remote_pf := in_msg.is_remote_pf;

  tbe.use_DMT := false;
  tbe.use_DCT := false;

  tbe.hasUseTimeout := false;

  return tbe;
}


TBE allocateSnoopTBE(Addr addr, CHIRequestMsg in_msg), return_by_pointer="yes" {
  // We must have reserved resources for this allocation
  storSnpTBEs.decrementReserved();
  assert(storSnpTBEs.areNSlotsAvailable(1));

  snpTBEs.allocate(addr);
  TBE tbe := snpTBEs[addr];
  initializeTBE(tbe, addr, storSnpTBEs.addEntryToNewSlot());

  assert(tbe.is_req_tbe == false);
  assert(tbe.is_repl_tbe == false);
  tbe.is_snp_tbe := true;

  tbe.accAddr := addr;
  tbe.accSize := blockSize;
  tbe.requestor := in_msg.requestor;
  tbe.fwdRequestor := in_msg.fwdRequestor;
  tbe.reqType := in_msg.type;

  tbe.snpNeedsData := in_msg.retToSrc;

  tbe.use_DMT := false;
  tbe.use_DCT := false;

  return tbe;
}


TBE _allocateReplacementTBE(Addr addr, int storSlot), return_by_pointer="yes" {
  TBE tbe := replTBEs[addr];
  initializeTBE(tbe, addr, storSlot);

  assert(tbe.is_req_tbe == false);
  assert(tbe.is_snp_tbe == false);
  tbe.is_repl_tbe := true;

  tbe.accAddr := addr;
  tbe.accSize := blockSize;
  tbe.requestor := machineID;
  tbe.reqType := CHIRequestType:null;

  tbe.use_DMT := false;
  tbe.use_DCT := false;

  return tbe;
}

TBE allocateReplacementTBE(Addr addr), return_by_pointer="yes" {
  // We must have resources for this allocation
  assert(storReplTBEs.areNSlotsAvailable(1));

  replTBEs.allocate(addr);
  return _allocateReplacementTBE(addr, storReplTBEs.addEntryToNewSlot());
}

TBE allocateReplacementTBEOnSlot(Addr addr, int slot), return_by_pointer="yes" {
  // only when reusing slot from main TBE table
  assert(unify_repl_TBEs);
  storTBEs.addEntryToSlot(slot);

  replTBEs.allocate(addr);
  return _allocateReplacementTBE(addr, slot);
}

TBE getHazardTBE(TBE tbe), return_by_pointer="yes" {
  assert(is_valid(tbe));
  assert(tbe.is_snp_tbe);
  TBE hazard_tbe := TBEs[tbe.addr];
  if (tbe.is_req_hazard) {
    assert(tbe.is_repl_hazard == false);
  } else {
    assert(tbe.is_repl_hazard);
    hazard_tbe := replTBEs[tbe.addr];
  }
  assert(is_valid(hazard_tbe));
  return hazard_tbe;
}

void scheduleSendData(TBE tbe, int when) {
  if (tbe.snd_pendBytes.count() > 0) {
    assert(tbe.snd_pendEv == false);
    tbe.snd_pendEv := true;
    // enqueue send event
    tbe.pendAction := Event:TX_Data;
    enqueue(triggerOutPort, TriggerMsg, intToCycles(when)) {
      out_msg.addr := tbe.addr;
      out_msg.from_hazard := tbe.is_req_hazard || tbe.is_repl_hazard;
    }
  }
}

void setupPendingSend(TBE tbe) {
  assert(blockSize >= data_channel_size);
  assert((blockSize % data_channel_size) == 0);
  // data must be complete in the TBE
  assert(tbe.dataBlkValid.isFull());
  tbe.snd_pendBytes.fillMask();
  scheduleSendData(tbe, 0);
}

void setupPendingPartialSend(TBE tbe) {
  assert(blockSize >= data_channel_size);
  assert((blockSize % data_channel_size) == 0);
  // data must be complete in the TBE
  assert(tbe.dataBlkValid.count() > 0);
  tbe.snd_pendBytes := tbe.dataBlkValid;
  scheduleSendData(tbe, 0);
}

// common code for downstream requests
void prepareRequest(TBE tbe, CHIRequestType type, CHIRequestMsg & out_msg) {
  out_msg.addr := tbe.addr;
  out_msg.accAddr := tbe.addr;
  out_msg.accSize := blockSize;
  out_msg.requestor := machineID;
  out_msg.fwdRequestor := tbe.requestor;
  out_msg.type := type;
  out_msg.allowRetry := false;
  tbe.pendReqAllowRetry := false;
  tbe.rcvdRetryAck := false;
  tbe.rcvdRetryCredit := false;
  tbe.pendReqType := type;
  out_msg.isSeqReqValid := tbe.isSeqReqValid;
  out_msg.seqReq := tbe.seqReq;
  out_msg.is_local_pf := false;
  out_msg.is_remote_pf := tbe.is_local_pf || tbe.is_remote_pf;
}

void allowRequestRetry(TBE tbe, CHIRequestMsg & out_msg) {
  out_msg.allowRetry := true;
  tbe.pendReqAllowRetry := true;
  tbe.pendReqAccAddr := out_msg.accAddr;
  tbe.pendReqAccSize := out_msg.accSize;
  tbe.pendReqDest := out_msg.Destination;
  tbe.pendReqD2OrigReq := out_msg.dataToFwdRequestor;
  tbe.pendReqRetToSrc := out_msg.retToSrc;
}

void prepareRequestRetry(TBE tbe, CHIRequestMsg & out_msg) {
  assert(tbe.pendReqAllowRetry);
  tbe.pendReqAllowRetry := false;
  out_msg.allowRetry := false;

  out_msg.addr := tbe.addr;
  out_msg.requestor := machineID;
  out_msg.fwdRequestor := tbe.requestor;
  out_msg.accAddr := tbe.pendReqAccAddr;
  out_msg.accSize := tbe.pendReqAccSize;
  out_msg.type := tbe.pendReqType;
  out_msg.Destination := tbe.pendReqDest;
  out_msg.dataToFwdRequestor := tbe.pendReqD2OrigReq;
  out_msg.retToSrc := tbe.pendReqRetToSrc;
  out_msg.isSeqReqValid := tbe.isSeqReqValid;
  out_msg.seqReq := tbe.seqReq;
  out_msg.is_local_pf := false;
  out_msg.is_remote_pf := tbe.is_local_pf || tbe.is_remote_pf;
}

void enqueueDoRetry(TBE tbe) {
  if (tbe.rcvdRetryAck && tbe.rcvdRetryCredit) {
    enqueue(retryTriggerOutPort, RetryTriggerMsg, 0) {
      out_msg.addr := tbe.addr;
      out_msg.event := Event:DoRetry;
    }
    destsWaitingRetry.removeNetDest(tbe.pendReqDest);
  }
}

void processRetryQueue() {
  // send credit if requestor waiting for it and we have resources
  bool has_avail := storTBEs.areNSlotsAvailable(1);
  assert(unify_repl_TBEs || has_avail);
  // the slot might still be used by a replacement if unify_repl_TBEs is set
  if (retryQueue.empty() == false && has_avail) {
    storTBEs.incrementReserved();
    RetryQueueEntry e := retryQueue.next();
    retryQueue.pop();
    enqueue(retryTriggerOutPort, RetryTriggerMsg, 0) {
      out_msg.addr := e.addr;
      out_msg.retryDest := e.retryDest;
      out_msg.event := Event:SendPCrdGrant;
    }
  }
}

void printResources() {
  if (unify_repl_TBEs) {
    assert(storReplTBEs.size() == 0);
    assert(storReplTBEs.reserved() == 0);
    DPRINTF(RubySlicc, "Resources(used/rsvd/max): TBEs=%d/%d/%d snpTBEs=%d/%d/%d replTBEs=%d/%d/%d\n",
                  storTBEs.size(), storTBEs.reserved(), storTBEs.capacity(),
                  storSnpTBEs.size(), storSnpTBEs.reserved(), storSnpTBEs.capacity(),
                  storTBEs.size(), storTBEs.reserved(), storTBEs.capacity());
  } else {
    DPRINTF(RubySlicc, "Resources(used/rsvd/max): TBEs=%d/%d/%d snpTBEs=%d/%d/%d replTBEs=%d/%d/%d\n",
                  storTBEs.size(), storTBEs.reserved(), storTBEs.capacity(),
                  storSnpTBEs.size(), storSnpTBEs.reserved(), storSnpTBEs.capacity(),
                  storReplTBEs.size(), storReplTBEs.reserved(), storReplTBEs.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()));
}

bool needCacheEntry(CHIRequestType req_type,
                    CacheEntry cache_entry, DirEntry dir_entry,
                    bool is_prefetch) {
  // never allocates:
  // - if entry already valid
  // - if using DMT; the request is a Read*; and dir entry is invalid
  // oterwise follow config params
  if (is_valid(cache_entry) ||
      (enable_DMT && is_invalid(dir_entry) &&
       ((req_type == CHIRequestType:ReadShared) ||
        (req_type == CHIRequestType:ReadUnique) ||
        (req_type == CHIRequestType:ReadOnce)))) {
    return false;
  } else {
    return is_prefetch ||
           (alloc_on_readshared && ((req_type == CHIRequestType:ReadShared) ||
                                    (req_type == CHIRequestType:ReadNotSharedDirty))) ||
           (alloc_on_readunique && (req_type == CHIRequestType:ReadUnique)) ||
           (alloc_on_readonce && (req_type == CHIRequestType:ReadOnce)) ||
           (alloc_on_writeback && ((req_type == CHIRequestType:WriteBackFull) ||
                                   (req_type == CHIRequestType:WriteCleanFull) ||
                                   (req_type == CHIRequestType:WriteEvictFull) ||
                                   (is_HN && (req_type == CHIRequestType:WriteUniqueFull)))) ||
           (alloc_on_seq_acc && ((req_type == CHIRequestType:Load) ||
                                 (req_type == CHIRequestType:Store))) ||
           (alloc_on_seq_line_write && (req_type == CHIRequestType:StoreLine));
  }
}

bool needDeallocCacheEntry(CHIRequestType req_type) {
  return (dealloc_on_shared && ((req_type == CHIRequestType:ReadShared) ||
                                (req_type == CHIRequestType:ReadNotSharedDirty))) ||
         (dealloc_on_unique && ((req_type == CHIRequestType:ReadUnique) ||
                                (req_type == CHIRequestType:CleanUnique)));
}

bool upstreamHasUnique(State state) {
  return (state == State:RU) || (state == State:UD_RU) || (state == State:UC_RU);
}

bool upstreamHasShared(State state) {
  return (state == State:RSC) || (state == State:RSD) ||
         (state == State:RUSD) || (state == State:RUSC) ||
         (state == State:UD_RSD) || (state == State:SD_RSD) ||
         (state == State:UD_RSC) || (state == State:SD_RSC) ||
         (state == State:UC_RSC) || (state == State:SC_RSC);
}

void printTBEState(TBE tbe) {
  DPRINTF(RubySlicc, "STATE: addr: %#x data present=%d valid=%d unique=%d dirty=%d mu_dirty=%d dir ownerV=%d ownerE=%d sharers=%d tobe_I=%d tobe_SC=%d doFill=%d pendAction=%s\n",
                      tbe.addr, tbe.dataBlkValid.isFull(), tbe.dataValid, tbe.dataUnique,
                      tbe.dataDirty, tbe.dataMaybeDirtyUpstream, tbe.dir_ownerExists,
                      tbe.dir_ownerIsExcl,tbe.dir_sharers.count(),
                      tbe.dataToBeInvalid, tbe.dataToBeSharedClean,
                      tbe.doCacheFill, tbe.pendAction);
  DPRINTF(RubySlicc, "dataBlkValid = %s\n", tbe.dataBlkValid);
}

void copyCacheAndDir(CacheEntry cache_entry, DirEntry dir_entry,
                     TBE tbe, State initialState) {
  assert(is_valid(tbe));

  // have dir entry
  if (is_valid(dir_entry)) {
    assert((initialState == State:UD_RSC) || (initialState == State:SD_RSC) ||
            (initialState == State:UC_RSC) || (initialState == State:SC_RSC) ||
            (initialState == State:UD_RU) || (initialState == State:UC_RU) ||
            (initialState == State:RU) || (initialState == State:RSC) ||
            (initialState == State:RSD) || (initialState == State:RUSD) ||
            (initialState == State:RUSC) ||
            (initialState == State:UD_RSD) || (initialState == State:SD_RSD));
    tbe.dir_sharers := dir_entry.sharers;
    tbe.dir_owner := dir_entry.owner;
    tbe.dir_ownerExists := dir_entry.ownerExists;
    tbe.dir_ownerIsExcl := dir_entry.ownerIsExcl;
    assert(tbe.dir_sharers.count() > 0);
  } else {
    tbe.dir_sharers.clear();
    tbe.dir_ownerExists := false;
  }
  // Sanity checks
  assert((tbe.dir_ownerExists && tbe.dir_ownerIsExcl) ==
          ((initialState == State:UD_RU) || (initialState == State:UC_RU) ||
          (initialState == State:RU)));
  assert((tbe.dir_ownerExists && (tbe.dir_ownerIsExcl == false)) ==
          ((initialState == State:RSD) || (initialState == State:RUSD) ||
           (initialState == State:UD_RSD) || (initialState == State:SD_RSD)));

  // have usable data
  if (is_valid(cache_entry) &&
      ((initialState == State:UD) || (initialState == State:SD) ||
        (initialState == State:UC) || (initialState == State:SC) ||
        (initialState == State:UD_RSC) || (initialState == State:SD_RSC) ||
        (initialState == State:UC_RSC) || (initialState == State:SC_RSC) ||
        (initialState == State:UD_RSD) || (initialState == State:SD_RSD) ||
        (initialState == State:UD_T))) {
    tbe.dataBlk := cache_entry.DataBlk;
    tbe.dataBlkValid.fillMask();
    tbe.dataValid := true;
    DPRINTF(RubySlicc, "Cached data %s\n", tbe.dataBlk);
  } else {
    assert(is_invalid(cache_entry) ||
            (is_valid(cache_entry) && (initialState == State:UD_RU) ||
                                      (initialState == State:UC_RU)));
    tbe.dataBlkValid.clear();
    tbe.dataValid := false;
  }

  // set MRU for accessed block
  if (is_valid(cache_entry) && ((tbe.is_local_pf || tbe.is_remote_pf) == false)) {
    cache.setMRU(cache_entry);
  }

  // data is dirty here
  tbe.dataDirty := (initialState == State:UD) || (initialState == State:UD_RSC) ||
                   (initialState == State:SD) || (initialState == State:SD_RSC) ||
                   (initialState == State:UD_RU) || (initialState == State:UD_RSD) ||
                   (initialState == State:SD_RSD) || (initialState == State:UD_T);

  // maybe dirty upstream
  tbe.dataMaybeDirtyUpstream := (initialState == State:UD_RU) || (initialState == State:UC_RU) ||
                                (initialState == State:UD_RSD) || (initialState == State:SD_RSD) ||
                                (initialState == State:RU) || (initialState == State:RSD) ||
                                (initialState == State:RUSD);
  assert(tbe.dir_ownerExists == tbe.dataMaybeDirtyUpstream);

  // data is unique here or upstream
  tbe.dataUnique := (initialState == State:UD) || (initialState == State:UD_RSC) ||
                    (initialState == State:UD_RU) || (initialState == State:UC) ||
                    (initialState == State:UC_RSC) || (initialState == State:UC_RU) ||
                    (initialState == State:RU) || (initialState == State:RUSD) ||
                    (initialState == State:RUSC) ||
                    (initialState == State:UD_RSD) || (initialState == State:UD_T);

  // it is locked until timeout ?
  tbe.hasUseTimeout := initialState == State:UD_T;

  tbe.dataToBeSharedClean := false;
  tbe.dataToBeInvalid := false;

  printTBEState(tbe);
}

void copyCacheAndDirTBEs(TBE src, TBE dst) {
  assert(is_valid(src));
  assert(is_valid(dst));
  dst.dataBlk := src.dataBlk;
  dst.dataBlkValid := src.dataBlkValid;
  dst.dataValid := src.dataValid;
  dst.dataDirty := src.dataDirty;
  dst.dataMaybeDirtyUpstream := src.dataMaybeDirtyUpstream;
  dst.dataUnique := src.dataUnique;
  dst.dir_sharers := src.dir_sharers;
  dst.dir_owner := src.dir_owner;
  dst.dir_ownerExists := src.dir_ownerExists;
  dst.dir_ownerIsExcl := src.dir_ownerIsExcl;
  printTBEState(dst);
}

void deallocateReqTBE(TBE tbe) {
  assert(is_valid(tbe));
  assert(tbe.is_req_tbe);
  storTBEs.removeEntryFromSlot(tbe.storSlot);
  TBEs.deallocate(tbe.addr);
}

void deallocateSnpTBE(TBE tbe) {
  assert(is_valid(tbe));
  assert(tbe.is_snp_tbe);
  storSnpTBEs.removeEntryFromSlot(tbe.storSlot);
  snpTBEs.deallocate(tbe.addr);
}

void deallocateReplacementTBE(TBE tbe) {
  assert(is_valid(tbe));
  assert(tbe.is_repl_tbe);
  if (unify_repl_TBEs) {
    storTBEs.removeEntryFromSlot(tbe.storSlot);
  } else {
    storReplTBEs.removeEntryFromSlot(tbe.storSlot);
  }
  replTBEs.deallocate(tbe.addr);
}

void setDataToBeStates(TBE tbe) {
  assert(is_valid(tbe));
  if (tbe.dataToBeInvalid) {
    tbe.dataValid := false;
    tbe.dataBlkValid.clear();
  }
  if (tbe.dataToBeSharedClean) {
    tbe.dataUnique := false;
    tbe.dataDirty := false;
    assert(tbe.dataMaybeDirtyUpstream == false);
  }
  tbe.dataToBeInvalid := false;
  tbe.dataToBeSharedClean := false;
}

void setExpectedForInvSnoop(TBE tbe, bool expectCleanWB) {
  assert(tbe.expected_snp_resp.hasExpected() == false);
  assert(tbe.dir_sharers.count() > 0);
  clearExpectedSnpResp(tbe);
  if (expectCleanWB) {
    tbe.expected_snp_resp.addExpectedDataType(CHIDataType:SnpRespData_I);
  }
  if (tbe.dataMaybeDirtyUpstream) {
    assert(tbe.dir_ownerExists);
    tbe.expected_snp_resp.addExpectedDataType(CHIDataType:SnpRespData_I_PD);
    if ((expectCleanWB == false) || (tbe.dir_sharers.count() > 1)) {
      tbe.expected_snp_resp.addExpectedRespType(CHIResponseType:SnpResp_I);
    }
  } else {
    tbe.expected_snp_resp.addExpectedRespType(CHIResponseType:SnpResp_I);
  }
  tbe.expected_snp_resp.setExpectedCount(tbe.dir_sharers.count());
}

State makeFinalStateHelper(State cs, State ds) {
  if (ds == State:RSC) {
    if (cs == State:UD) {
      return State:UD_RSC;
    } else if (cs == State:SD) {
      return State:SD_RSC;
    } else if (cs == State:UC) {
      return State:UC_RSC;
    } else if (cs == State:SC) {
      return State:SC_RSC;
    } else {
      return State:RSC;
    }
  } else if (ds == State:RU) {
    if (cs == State:UD) {
      return State:UD_RU;
    } else if (cs == State:UC) {
      return State:UC_RU;
    } else {
      assert(cs != State:SC);
      assert(cs != State:SD);
      return State:RU;
    }
  } else if (ds == State:RSD) {
    if (cs == State:UD) {
      return State:UD_RSD;
    } else if (cs == State:SD) {
      return State:SD_RSD;
    } else {
      assert(cs == State:I);
      return State:RSD;
    }
  } else if (ds == State:RUSD) {
    if (cs == State:UD) {
      return State:UD_RSD;
    } else {
      assert(cs == State:I);
      return State:RUSD;
    }
  } else if (ds == State:RUSC) {
    if (cs == State:UC) {
      return State:UC_RSC;
    } else if (cs == State:UD) {
      return State:UD_RSC;
    } else {
      assert(cs == State:I);
      return State:RUSC;
    }
  } else {
    assert(ds == State:I);
    return cs;
  }
}

State makeFinalState(TBE tbe, CacheEntry cache_entry, DirEntry dir_entry) {
  setDataToBeStates(tbe);
  printTBEState(tbe);

  State cache_state := State:I;
  State dir_state := State:I;

  if (tbe.dir_ownerExists) {
    assert(is_valid(dir_entry));
    assert(tbe.dataMaybeDirtyUpstream);
    if (tbe.dir_ownerIsExcl) {
      assert(tbe.dir_sharers.count() == 1);
      dir_state := State:RU;
    } else {
      assert(tbe.dir_sharers.count() >= 1);
      if (tbe.dataUnique) {
        dir_state := State:RUSD;
      } else {
        dir_state := State:RSD;
      }
    }
  } else if (tbe.dir_sharers.count() > 0) {
    assert(is_valid(dir_entry));
    assert(tbe.dataMaybeDirtyUpstream == false);
    if (tbe.dataUnique) {
      dir_state := State:RUSC;
    } else {
      dir_state := State:RSC;
    }
  }

  if (tbe.dataValid && is_valid(cache_entry)) {
    if (tbe.dataUnique && tbe.dataDirty) {
      if (tbe.hasUseTimeout) {
        cache_state := State:UD_T;
      } else {
        cache_state := State:UD;
      }
    } else if (tbe.dataUnique && (tbe.dataDirty == false)) {
      cache_state := State:UC;
    } else if ((tbe.dataUnique == false) && tbe.dataDirty) {
      assert(allow_SD);
      cache_state := State:SD;
    } else {
      cache_state := State:SC;
    }
  }

  return makeFinalStateHelper(cache_state, dir_state);
}

// This is used only with the finalization transitions
State getNextState(Addr address) {
  TBE tbe := getCurrentActiveTBE(address);
  assert(is_valid(tbe));
  assert(tbe.pendAction == Event:Final);
  tbe.finalState := makeFinalState(tbe, getCacheEntry(address), getDirEntry(address));
  assert(tbe.finalState != State:null);
  return tbe.finalState;
}


int scLockLatency() {
  return sc_lock_multiplier * sc_lock_base_latency_cy;
}

void scLockIncLatency()
{
  sc_lock_multiplier := sc_lock_multiplier + sc_lock_multiplier_inc;
  if (sc_lock_multiplier > sc_lock_multiplier_max) {
    sc_lock_multiplier := sc_lock_multiplier_max;
  }
  DPRINTF(LLSC, "SC lock latency increased to %d cy\n", scLockLatency());
}

void scLockDecayLatency()
{
  sc_lock_multiplier := sc_lock_multiplier - sc_lock_multiplier_decay;
  if (sc_lock_multiplier < 0) {
    sc_lock_multiplier := 0;
  }
  DPRINTF(LLSC, "SC lock latency decayed to %d cy\n", scLockLatency());
}

void clearPendingAction(TBE tbe) {
  // only clear pendAction if snd_pendEv not set
  if (tbe.snd_pendEv) {
    assert(tbe.pendAction == Event:TX_Data);
  } else {
    tbe.pendAction := Event:null;
  }
}

bool isReadReqType(CHIRequestType type) {
  if (type == CHIRequestType:Load ||
      type == CHIRequestType:ReadShared ||
      type == CHIRequestType:ReadNotSharedDirty ||
      type == CHIRequestType:ReadOnce) {
    return true;
  }
  return false;
}

bool isWriteReqType(CHIRequestType type) {
  if (type == CHIRequestType:Store ||
      type == CHIRequestType:StoreLine ||
      type == CHIRequestType:WriteUniquePtl ||
      type == CHIRequestType:WriteUniqueFull ||
      type == CHIRequestType:ReadUnique) {
    return true;
  }
  return false;
}

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

Event reqToEvent(CHIRequestType type, bool is_prefetch) {
  if (type == CHIRequestType:Load) {
    if (is_prefetch == false) {
      return Event:Load;
    } else {
      return Event:Prefetch;
    }
  } else if (type == CHIRequestType:Store) {
    return Event:Store;
  } else if (type == CHIRequestType:StoreLine) {
    return Event:Store;
  } else if (type == CHIRequestType:ReadShared) {
    return Event:ReadShared;
  } else if (type == CHIRequestType:ReadNotSharedDirty) {
    return Event:ReadNotSharedDirty;
  } else if (type == CHIRequestType:ReadUnique) {
    if (is_HN) {
      return Event:ReadUnique_PoC;
    } else {
      return Event:ReadUnique;
    }
  } else if (type == CHIRequestType:CleanUnique) {
    return Event:CleanUnique;
  } else if (type == CHIRequestType:ReadOnce) {
    return Event:ReadOnce;
  } else if (type == CHIRequestType:Evict) {
    return Event:Evict;
  } else if (type == CHIRequestType:WriteBackFull) {
    return Event:WriteBackFull;
  } else if (type == CHIRequestType:WriteEvictFull) {
    return Event:WriteEvictFull;
  } else if (type == CHIRequestType:WriteCleanFull) {
    return Event:WriteCleanFull;
  } else if (type == CHIRequestType:WriteUniquePtl) {
    if (is_HN) {
      return Event:WriteUniquePtl_PoC;
    } else {
      return Event:WriteUnique; // all WriteUnique handled the same when ~PoC
    }
  } else if (type == CHIRequestType:WriteUniqueFull) {
    if (is_HN && alloc_on_writeback) {
      return Event:WriteUniqueFull_PoC_Alloc;
    } else if (is_HN) {
      return Event:WriteUniqueFull_PoC;
    } else {
      return Event:WriteUnique; // all WriteUnique handled the same when ~PoC
    }
  } else {
    error("Invalid CHIRequestType");
  }
}

Event respToEvent (CHIResponseType type, TBE tbe) {
  bool on_hazard := is_valid(tbe) && (tbe.is_req_hazard || tbe.is_repl_hazard);
  if (type == CHIResponseType:Comp_I) {
    return Event:Comp_I;
  } else if (type == CHIResponseType:Comp_UC) {
    return Event:Comp_UC;
  } else if (type == CHIResponseType:Comp_SC) {
    return Event:Comp_SC;
  } else if (type == CHIResponseType:CompDBIDResp) {
    return Event:CompDBIDResp;
  } else if (type == CHIResponseType:DBIDResp) {
    return Event:DBIDResp;
  } else if (type == CHIResponseType:Comp) {
    return Event:Comp;
  } else if (type == CHIResponseType:CompAck) {
    return Event:CompAck;
  } else if (type == CHIResponseType:ReadReceipt) {
    return Event:ReadReceipt;
  } else if (type == CHIResponseType:RespSepData) {
    return Event:RespSepData;
  } else if (type == CHIResponseType:SnpResp_I) {
    return Event:SnpResp_I;
  } else if (type == CHIResponseType:SnpResp_I_Fwded_UC) {
    return Event:SnpResp_I_Fwded_UC;
  } else if (type == CHIResponseType:SnpResp_I_Fwded_UD_PD) {
    return Event:SnpResp_I_Fwded_UD_PD;
  } else if (type == CHIResponseType:SnpResp_SC) {
    return Event:SnpResp_SC;
  } else if (type == CHIResponseType:SnpResp_SC_Fwded_SC) {
    return Event:SnpResp_SC_Fwded_SC;
  } else if (type == CHIResponseType:SnpResp_SC_Fwded_SD_PD) {
    return Event:SnpResp_SC_Fwded_SD_PD;
  } else if (type == CHIResponseType:SnpResp_SD_Fwded_I) {
    return Event:SnpResp_SD_Fwded_I;
  } else if (type == CHIResponseType:SnpResp_SC_Fwded_I) {
    return Event:SnpResp_SC_Fwded_I;
  } else if (type == CHIResponseType:SnpResp_UD_Fwded_I) {
    return Event:SnpResp_UD_Fwded_I;
  } else if (type == CHIResponseType:SnpResp_UC_Fwded_I) {
    return Event:SnpResp_UC_Fwded_I;
  } else if (type == CHIResponseType:RetryAck) {
    if (is_HN) {
      if (on_hazard) {
        return Event:RetryAck_PoC_Hazard;
      } else {
        return Event:RetryAck_PoC;
      }
    } else {
      if (on_hazard) {
        return Event:RetryAck_Hazard;
      } else {
        return Event:RetryAck;
      }
    }
  } else if (type == CHIResponseType:PCrdGrant) {
    if (is_HN) {
      if (on_hazard) {
        return Event:PCrdGrant_PoC_Hazard;
      } else {
        return Event:PCrdGrant_PoC;
      }
    } else {
      if (on_hazard) {
        return Event:PCrdGrant_Hazard;
      } else {
        return Event:PCrdGrant;
      }
    }
  } else {
    error("Invalid CHIResponseType");
  }
}

Event dataToEvent (CHIDataType type) {
  if (type == CHIDataType:CompData_I) {
    return Event:CompData_I;
  } else if (type == CHIDataType:CompData_UC) {
    return Event:CompData_UC;
  } else if (type == CHIDataType:CompData_SC) {
    return Event:CompData_SC;
  } else if (type == CHIDataType:CompData_UD_PD) {
    return Event:CompData_UD_PD;
  } else if (type == CHIDataType:CompData_SD_PD) {
    return Event:CompData_SD_PD;
  } else if (type == CHIDataType:DataSepResp_UC) {
    return Event:DataSepResp_UC;
  } else if (type == CHIDataType:CBWrData_I) {
    return Event:CBWrData_I;
  } else if (type == CHIDataType:CBWrData_UC) {
    return Event:CBWrData_UC;
  } else if (type == CHIDataType:CBWrData_SC) {
    return Event:CBWrData_SC;
  } else if (type == CHIDataType:CBWrData_UD_PD) {
    return Event:CBWrData_UD_PD;
  } else if (type == CHIDataType:CBWrData_SD_PD) {
    return Event:CBWrData_SD_PD;
  } else if (type == CHIDataType:NCBWrData) {
    return Event:NCBWrData;
  } else if (type == CHIDataType:SnpRespData_I_PD) {
    return Event:SnpRespData_I_PD;
  } else if (type == CHIDataType:SnpRespData_I) {
    return Event:SnpRespData_I;
  } else if (type == CHIDataType:SnpRespData_SC_PD) {
    return Event:SnpRespData_SC_PD;
  } else if (type == CHIDataType:SnpRespData_SC) {
    return Event:SnpRespData_SC;
  } else if (type == CHIDataType:SnpRespData_SD) {
    return Event:SnpRespData_SD;
  } else if (type == CHIDataType:SnpRespData_UC) {
    return Event:SnpRespData_UC;
  } else if (type == CHIDataType:SnpRespData_UD) {
    return Event:SnpRespData_UD;
  } else if (type == CHIDataType:SnpRespData_SC_Fwded_SC) {
    return Event:SnpRespData_SC_Fwded_SC;
  } else if (type == CHIDataType:SnpRespData_SC_Fwded_SD_PD) {
    return Event:SnpRespData_SC_Fwded_SD_PD;
  } else if (type == CHIDataType:SnpRespData_SC_PD_Fwded_SC) {
    return Event:SnpRespData_SC_PD_Fwded_SC;
  } else if (type == CHIDataType:SnpRespData_I_Fwded_SD_PD) {
    return Event:SnpRespData_I_Fwded_SD_PD;
  } else if (type == CHIDataType:SnpRespData_I_PD_Fwded_SC) {
    return Event:SnpRespData_I_PD_Fwded_SC;
  } else if (type == CHIDataType:SnpRespData_I_Fwded_SC) {
    return Event:SnpRespData_I_Fwded_SC;
  } else {
    error("Invalid CHIDataType");
  }
}

Event snpToEvent (CHIRequestType type) {
  if (type == CHIRequestType:SnpCleanInvalid) {
    return Event:SnpCleanInvalid;
  } else if (type == CHIRequestType:SnpShared) {
    return Event:SnpShared;
  } else if (type == CHIRequestType:SnpUnique) {
    return Event:SnpUnique;
  } else if (type == CHIRequestType:SnpSharedFwd) {
    return Event:SnpSharedFwd;
  } else if (type == CHIRequestType:SnpNotSharedDirtyFwd) {
    return Event:SnpNotSharedDirtyFwd;
  } else if (type == CHIRequestType:SnpUniqueFwd) {
    return Event:SnpUniqueFwd;
  } else if (type == CHIRequestType:SnpOnce) {
    return Event:SnpOnce;
  } else if (type == CHIRequestType:SnpOnceFwd) {
    return Event:SnpOnceFwd;
  } else {
    error("Invalid CHIRequestType");
  }
}

//////////////////////////////////////////
// Cache bank utilization tracking

enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
  TagArrayRead,    desc="Read or write the dir/cache tag/data array";
  TagArrayWrite,    desc="Read or write the dir/cache tag/data array";
  DataArrayRead,    desc="Read or write the dir/cache tag/data array";
  DataArrayWrite,    desc="Read or write the dir/cache tag/data array";

  DestinationAvailable, desc="Check if there is a pending retry from the destination";

  ReplTBEAvailable, desc="Check if a replacement TBE is available";
}

void recordRequestType(RequestType request_type, Addr addr) {
  if (request_type == RequestType:DataArrayRead) {
    cache.recordRequestType(CacheRequestType:DataArrayRead, addr);
  } else if (request_type == RequestType:DataArrayWrite) {
    cache.recordRequestType(CacheRequestType:DataArrayWrite, addr);
  } else if (request_type == RequestType:TagArrayRead) {
    cache.recordRequestType(CacheRequestType:TagArrayRead, addr);
  } else if (request_type == RequestType:TagArrayWrite) {
    cache.recordRequestType(CacheRequestType:TagArrayWrite, addr);
  }
}

bool _checkResourceAvailable(RequestType request_type, Addr addr) {
  if (request_type == RequestType:DataArrayRead) {
    return cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
  } else if (request_type == RequestType:DataArrayWrite) {
    return cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
  } else if (request_type == RequestType:TagArrayRead) {
    return cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
  } else if (request_type == RequestType:TagArrayWrite) {
    return cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
  } else if (request_type == RequestType:DestinationAvailable) {
    if (throttle_req_on_retry) {
      MachineID dest := mapAddressToDownstreamMachine(addr);
      DPRINTF(RubySlicc, "Checking %s for addr %#x dest %s\n", request_type, addr, dest);
      return destsWaitingRetry.isElement(dest) == false;
    } else {
      return true;
    }
  } else if (request_type == RequestType:ReplTBEAvailable) {
    // if unify_repl_TBEs the replacement uses the same slot as the request
    // that initiated it, so the resource is always available
    return unify_repl_TBEs || storReplTBEs.areNSlotsAvailable(1);
  } else {
    error("Invalid RequestType type in checkResourceAvailable");
    return true;
  }
}

bool checkResourceAvailable(RequestType request_type, Addr addr) {
  bool avail := _checkResourceAvailable(request_type, addr);
  if (avail == false) {
    DPRINTF(RubySlicc, "Resource %s not available for addr: %#x\n", request_type, addr);
  }
  return avail;
}
