/*
 * 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 ((test_mask.cmpMask(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;
}
