/*
 * Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 *
 * Authors: Jason Power
 */

machine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol")
: CacheMemory *cacheMemory; // stores only region addresses. Must set block size same as below
  bool isOnCPU;
  int blocksPerRegion := 64; // 4k regions
  Cycles toDirLatency := 5;     // Latency to fwd requests to directory
  Cycles toRegionDirLatency := 5; // Latency for requests and acks to directory
  Cycles nextEvictLatency := 1;   // latency added between each block while evicting region
  bool noTCCdir := "False";
  int TCC_select_num_bits := 1;

  // From the Cores
  MessageBuffer * requestFromCore, network="From", virtual_network="0", vnet_type="request";
  MessageBuffer * responseFromCore, network="From", virtual_network="2", vnet_type="response";

  // Requests to the cores or directory
  MessageBuffer * requestToNetwork, network="To", virtual_network="0", vnet_type="request";

  // From Region-Dir
  MessageBuffer * notifyFromRegionDir, network="From", virtual_network="7", vnet_type="request";
  MessageBuffer * probeFromRegionDir, network="From", virtual_network="8", vnet_type="request";

  // From the directory
  MessageBuffer * unblockFromDir, network="From", virtual_network="4", vnet_type="unblock";

  // To the region-Dir
  MessageBuffer * responseToRegDir, network="To", virtual_network="2", vnet_type="response";

  MessageBuffer * triggerQueue;
{

  // States
  state_declaration(State, desc="Region states", default="RegionBuffer_State_NP") {
    NP, AccessPermission:Invalid,       desc="Not present in region directory";
    P,  AccessPermission:Invalid,       desc="Region is private to the cache";
    S,  AccessPermission:Invalid,       desc="Region is possibly shared with others";

    NP_PS, AccessPermission:Invalid,    desc="Intermediate state waiting for notify from r-dir";
    S_P,  AccessPermission:Invalid,     desc="Intermediate state while upgrading region";

    P_NP, AccessPermission:Invalid,     desc="Intermediate state while evicting all lines in region";
    P_S,  AccessPermission:Invalid,     desc="Intermediate state while downgrading all lines in region";

    S_NP_PS, AccessPermission:Invalid,  desc="Got an inv in S_P, waiting for all inv acks, then going to since the write is already out there NP_PS";
    P_NP_NP,  AccessPermission:Invalid,    desc="Evicting region on repl, then got an inv. Need to re-evict";

    P_NP_O, AccessPermission:Invalid,     desc="Waiting for all outstanding requests";
    P_S_O,  AccessPermission:Invalid,     desc="Waiting for all outstanding requests";
    S_O,  AccessPermission:Invalid,       desc="Waiting for all outstanding requests";
    S_NP_PS_O, AccessPermission:Invalid,  desc="Waiting for all outstanding requests";

    SS_P, AccessPermission:Invalid,  desc="Waiting for CPU write that we know is there";

    P_NP_W, AccessPermission:Invalid,     desc="Waiting for writeback ack";

    NP_W, AccessPermission:Invalid,     desc="Got a done ack before request, waiting for that victim";
  }

  enumeration(Event, desc="Region directory events") {
    CPURead,        desc="Access from CPU core";
    CPUWrite,       desc="Access from CPU core";
    CPUWriteback,       desc="Writeback request from CPU core";

    ReplRegion,     desc="Start a replace on a region";

    PrivateNotify,  desc="Update entry to private state";
    SharedNotify,   desc="Update entry to shared state";
    WbNotify,       desc="Writeback notification received";
    InvRegion,      desc="Start invalidating a region";
    DowngradeRegion,desc="Start invalidating a region";

    InvAck,         desc="Ack from core";

    DoneAck,        desc="Ack from core that request has finished";
    AllOutstanding, desc="All outstanding requests have now finished";

    Evict,          desc="Loopback to evict each block";
    LastAck_PrbResp, desc="Done eviciting all the blocks, got the last ack from core, now respond to region dir";
    LastAck_CleanWb, desc="Done eviciting all the blocks, got the last ack from core, now start clean writeback (note the dir has already been updated)";

    StallAccess,    desc="Wait for the done ack on the address before proceeding";
    StallDoneAck,   desc="Wait for the access on the address before proceeding";

    StaleRequest,   desc="Got a stale victim from the cache, fwd it without incrementing outstanding";
  }

  enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
    TagArrayRead,     desc="Read the data array";
    TagArrayWrite,    desc="Write the data array";
  }

  structure(BoolVec, external="yes") {
    bool at(int);
    void resize(int);
    void clear();
    int size();
  }

  structure(Entry, desc="Region entry", interface="AbstractCacheEntry") {
    Addr addr,        desc="Base address of this region";
    State RegionState,      desc="Region state";
    DataBlock DataBlk,      desc="Data for the block (always empty in region buffer)";
    BoolVec ValidBlocks,    desc="A vector to keep track of valid blocks";
    int NumValidBlocks,     desc="Number of trues in ValidBlocks to avoid iterating";
    BoolVec UsedBlocks,     desc="A vector to keep track of blocks ever valid";
    bool dirty,           desc="Dirty as best known by the region buffer";
    // This is needed so we don't ack an invalidate until all requests are ordered
    int NumOutstandingReqs,    desc="Total outstanding private/shared requests";
    BoolVec OutstandingReqs,   desc="Blocks that have outstanding private/shared requests";
    bool MustDowngrade,     desc="Set when we got a downgrade before the shd or pvt permissions";
    Cycles ProbeRequestTime, default="Cycles(0)", desc="Time region dir started the probe";
    Cycles InitialRequestTime, default="Cycles(0)", desc="Time message was sent to region dir";
    bool MsgSentToDir,      desc="True if the current request required a message to the dir";
    bool clearOnDone, default="false", desc="clear valid bit when request completes";
    Addr clearOnDoneAddr, desc="clear valid bit when request completes";
  }

  structure(TBE, desc="...") {
    State TBEState,         desc="Transient state";
    //int NumValidBlocks,     desc="Number of blocks valid so we don't have to count a BoolVec";
    BoolVec ValidBlocks,    desc="A vector to keep track of valid blocks";
    bool AllAcksReceived,   desc="Got all necessary acks from dir";
    bool DoneEvicting,      desc="Done iterating through blocks checking for valids";
    BoolVec AcksReceived,   desc="Received acks for theses blocks\n";
    bool SendAck,           desc="If true, send an ack to the r-dir at end of inv";
    ProbeRequestType MsgType, desc="Type of message to send while 'evicting' ";
    int NumOutstandingReqs,    desc="Total outstanding private/shared requests";
    BoolVec OutstandingReqs,   desc="Blocks that have outstanding private/shared requests";
    MachineID Requestor,    desc="Requestor for three hop transactions";
    bool DemandRequest, default="false", desc="Associated with a demand request";
    Addr DemandAddress,  desc="Address for the demand request";
    bool DoneAckReceived, default="false", desc="True if the done ack arrived before the message";
    Addr DoneAckAddr,     desc="Address of the done ack received early";
    int OutstandingThreshold, desc="Number of outstanding requests to trigger AllOutstanding on";

    ProbeRequestType NewMsgType, desc="Type of message to send while 'evicting' ";
    MachineID NewRequestor,    desc="Requestor for three hop transactions";
    bool NewDemandRequest, default="false", desc="Associated with a demand request";
    Addr NewDemandAddress,  desc="Address for the demand request";
    bool dirty, desc="dirty";
    bool AllOutstandingTriggered, default="false", desc="bit for only one all outstanding";
    int OutstandingAcks, default="0", desc="number of acks to wait for";
  }

  structure(TBETable, external="yes") {
    TBE lookup(Addr);
    void allocate(Addr);
    void deallocate(Addr);
    bool isPresent(Addr);
  }

  // Stores only region addresses
  TBETable TBEs, template="<RegionBuffer_TBE>", constructor="m_number_of_TBEs";
  int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()";

  Tick clockEdge();
  Tick cyclesToTicks(Cycles c);

  void set_cache_entry(AbstractCacheEntry b);
  void unset_cache_entry();
  void set_tbe(TBE b);
  void unset_tbe();
  void wakeUpAllBuffers();
  void wakeUpBuffers(Addr a);
  Cycles curCycle();
  MachineID mapAddressToMachine(Addr addr, MachineType mtype);

  int blockBits,  default="RubySystem::getBlockSizeBits()";
  int blockBytes, default="RubySystem::getBlockSizeBytes()";
  int regionBits, default="log2(m_blocksPerRegion)";

  // Functions

  int getRegionOffset(Addr addr) {
    if (blocksPerRegion > 1) {
      Addr offset := bitSelect(addr, blockBits, regionBits+blockBits-1);
      int ret := addressToInt(offset);
      assert(ret < blocksPerRegion);
      return ret;
    } else {
      return 0;
    }
  }

  Addr getRegionBase(Addr addr) {
    return maskLowOrderBits(addr, blockBits+regionBits);
  }

  Addr getNextBlock(Addr addr) {
    Addr a := addr;
    return makeNextStrideAddress(a, 1);
  }

  MachineID getPeer(MachineID mach, Addr address) {
    if (isOnCPU) {
      return createMachineID(MachineType:CorePair, intToID(0));
    } else if (noTCCdir) {
      return mapAddressToRange(address,MachineType:TCC,
                                  TCC_select_low_bit, TCC_select_num_bits);
    } else {
      return createMachineID(MachineType:TCCdir, intToID(0));
    }
  }

  bool isOutstanding(TBE tbe, Entry cache_entry, Addr addr) {
      if (is_valid(tbe) && tbe.OutstandingReqs.size() > 0) {
          DPRINTF(RubySlicc, " outstanding tbe reqs %s %s %d %d\n",
                  tbe.OutstandingReqs, addr, getRegionOffset(addr),
                  tbe.OutstandingReqs.at(getRegionOffset(addr)));
          return tbe.OutstandingReqs.at(getRegionOffset(addr));
      } else if (is_valid(cache_entry)) {
          DPRINTF(RubySlicc, " outstanding cache reqs %s %s %d %d\n",
                  cache_entry.OutstandingReqs, addr, getRegionOffset(addr),
                  cache_entry.OutstandingReqs.at(getRegionOffset(addr)));
          return cache_entry.OutstandingReqs.at(getRegionOffset(addr));
      } else {
          return false;
      }
  }

  bool isOnGPU() {
    if (isOnCPU) {
      return false;
    }
    return true;
  }

  bool isRead(CoherenceRequestType type) {
    return (type == CoherenceRequestType:RdBlk || type == CoherenceRequestType:RdBlkS ||
            type == CoherenceRequestType:VicClean);
  }

  bool presentOrAvail(Addr addr) {
    return cacheMemory.isTagPresent(getRegionBase(addr)) || cacheMemory.cacheAvail(getRegionBase(addr));
  }

  // Returns a region entry!
  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
    return static_cast(Entry, "pointer", cacheMemory.lookup(getRegionBase(addr)));
  }

  TBE getTBE(Addr addr), return_by_pointer="yes" {
    return TBEs.lookup(getRegionBase(addr));
  }

  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
    return getCacheEntry(getRegionBase(addr)).DataBlk;
  }

  State getState(TBE tbe, Entry cache_entry, Addr addr) {
    if (is_valid(tbe)) {
      return tbe.TBEState;
    } else if (is_valid(cache_entry)) {
      return cache_entry.RegionState;
    }
    return State:NP;
  }

  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
    if (is_valid(tbe)) {
        tbe.TBEState := state;
    }
    if (is_valid(cache_entry)) {
        cache_entry.RegionState := state;
    }
  }

  AccessPermission getAccessPermission(Addr addr) {
    TBE tbe := getTBE(addr);
    if(is_valid(tbe)) {
      return RegionBuffer_State_to_permission(tbe.TBEState);
    }
    Entry cache_entry := getCacheEntry(addr);
    if(is_valid(cache_entry)) {
      return RegionBuffer_State_to_permission(cache_entry.RegionState);
    }
    return AccessPermission:NotPresent;
  }

  void functionalRead(Addr addr, Packet *pkt) {
    functionalMemoryRead(pkt);
  }

  int functionalWrite(Addr addr, Packet *pkt) {
    if (functionalMemoryWrite(pkt)) {
      return 1;
    } else {
      return 0;
    }
  }

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

  void recordRequestType(RequestType stat, Addr addr) {
    if (stat == RequestType:TagArrayRead) {
        cacheMemory.recordRequestType(CacheRequestType:TagArrayRead, addr);
    } else if (stat == RequestType:TagArrayWrite) {
        cacheMemory.recordRequestType(CacheRequestType:TagArrayWrite, addr);
    }
  }

  bool checkResourceAvailable(RequestType request_type, Addr addr) {
    if (request_type == RequestType:TagArrayRead) {
      return cacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else if (request_type == RequestType:TagArrayWrite) {
      return cacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr);
    } else {
      error("Invalid RequestType type in checkResourceAvailable");
      return true;
    }
  }

  out_port(triggerQueue_out, TriggerMsg, triggerQueue);

  // Overloaded outgoing request nework for both probes to cores and reqeusts
  // to the directory.
  // Fix Me: These forwarded requests need to be on a separate virtual channel
  // to avoid deadlock!
  out_port(requestNetwork_out, CPURequestMsg, requestToNetwork);
  out_port(probeNetwork_out, NBProbeRequestMsg, requestToNetwork);

  out_port(responseNetwork_out, ResponseMsg, responseToRegDir);

  in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=4) {
    if (triggerQueue_in.isReady(clockEdge())) {
      peek(triggerQueue_in, TriggerMsg) {
        Entry cache_entry := getCacheEntry(in_msg.addr);
        TBE tbe := getTBE(in_msg.addr);
        DPRINTF(RubySlicc, "trigger msg: %s (%s)\n", in_msg, getRegionBase(in_msg.addr));
        assert(is_valid(tbe));
        if (in_msg.Type == TriggerType:AcksComplete) {
            if (tbe.SendAck) {
                trigger(Event:LastAck_PrbResp, in_msg.addr, cache_entry, tbe);
            } else {
                trigger(Event:LastAck_CleanWb, in_msg.addr, cache_entry, tbe);
            }
        } else if (in_msg.Type == TriggerType:AllOutstanding) {
          trigger(Event:AllOutstanding, in_msg.addr, cache_entry, tbe);
        } else {
          assert(in_msg.Type == TriggerType:InvNext);
          trigger(Event:Evict, in_msg.addr, cache_entry, tbe);
        }
      }
    }
  }

  in_port(unblockNetwork_in, UnblockMsg, unblockFromDir, rank=3) {
    if (unblockNetwork_in.isReady(clockEdge())) {
      peek(unblockNetwork_in, UnblockMsg) {
        TBE tbe := getTBE(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        if (in_msg.DoneAck) {
          if (isOutstanding(tbe, cache_entry, in_msg.addr)) {
            trigger(Event:DoneAck, in_msg.addr, cache_entry, tbe);
          } else {
            trigger(Event:StallDoneAck, in_msg.addr, cache_entry, tbe);
          }
        } else {
          assert(is_valid(tbe));
          trigger(Event:InvAck, in_msg.addr, cache_entry, tbe);
        }
      }
    }
  }

  in_port(probeNetwork_in, NBProbeRequestMsg, probeFromRegionDir, rank=2) {
    if (probeNetwork_in.isReady(clockEdge())) {
      peek(probeNetwork_in, NBProbeRequestMsg) {
        TBE tbe := getTBE(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        assert(getRegionBase(in_msg.addr) == in_msg.addr);
        if (in_msg.Type == ProbeRequestType:PrbInv) {
          trigger(Event:InvRegion, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Type == ProbeRequestType:PrbDowngrade) {
          trigger(Event:DowngradeRegion, in_msg.addr, cache_entry, tbe);
        } else {
          error("Unknown probe message\n");
        }
      }
    }
  }

  in_port(notifyNetwork_in, CPURequestMsg, notifyFromRegionDir, rank=1) {
    if (notifyNetwork_in.isReady(clockEdge())) {
      peek(notifyNetwork_in, CPURequestMsg) {
        TBE tbe := getTBE(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        //Fix Me...add back in: assert(is_valid(cache_entry));
        if (in_msg.Type == CoherenceRequestType:WbNotify) {
          trigger(Event:WbNotify, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Type == CoherenceRequestType:SharedNotify) {
          trigger(Event:SharedNotify, in_msg.addr, cache_entry, tbe);
        } else if (in_msg.Type == CoherenceRequestType:PrivateNotify) {
          trigger(Event:PrivateNotify, in_msg.addr, cache_entry, tbe);
        } else {
          error("Unknown notify message\n");
        }
      }
    }
  }

  // In from cores
  // NOTE: We get the cache / TBE entry based on the region address,
  //       but pass the block address to the actions
  in_port(requestNetwork_in, CPURequestMsg, requestFromCore, rank=0) {
    if (requestNetwork_in.isReady(clockEdge())) {
      peek(requestNetwork_in, CPURequestMsg) {
        TBE tbe := getTBE(in_msg.addr);
        Entry cache_entry := getCacheEntry(in_msg.addr);
        if (is_valid(tbe) && tbe.DoneAckReceived && tbe.DoneAckAddr == in_msg.addr) {
            DPRINTF(RubySlicc, "Stale/Stall request %s\n", in_msg.Type);
          if (in_msg.Type == CoherenceRequestType:VicDirty || in_msg.Type == CoherenceRequestType:VicClean )
          {
            trigger(Event:StaleRequest, in_msg.addr, cache_entry, tbe);
          } else {
            trigger(Event:StallAccess, in_msg.addr, cache_entry, tbe);
          }
        } else if (isOutstanding(tbe, cache_entry, in_msg.addr)) {
          DPRINTF(RubySlicc, "Stall outstanding request %s\n", in_msg.Type);
          trigger(Event:StallAccess, in_msg.addr, cache_entry, tbe);
        } else {
        if (presentOrAvail(in_msg.addr)) {
          if (in_msg.Type == CoherenceRequestType:RdBlkM ) {
            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
          } else if (in_msg.Type == CoherenceRequestType:WriteThrough ) {
            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
          } else if (in_msg.Type == CoherenceRequestType:Atomic ) {
            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
          } else {
              if (in_msg.Type == CoherenceRequestType:VicDirty ||
                  in_msg.Type == CoherenceRequestType:VicClean) {
                  trigger(Event:CPUWriteback, in_msg.addr, cache_entry, tbe);
              } else {
                  trigger(Event:CPURead, in_msg.addr, cache_entry, tbe);
              }
          }
        } else {
          Addr victim := cacheMemory.cacheProbe(getRegionBase(in_msg.addr));
          TBE victim_tbe := getTBE(victim);
          Entry victim_entry := getCacheEntry(victim);
          DPRINTF(RubySlicc, "Replacing region %s for %s(%s)\n", victim, in_msg.addr, getRegionBase(in_msg.addr));
          trigger(Event:ReplRegion, victim, victim_entry, victim_tbe);
        }
        }
      }
    }
  }

  // Actions
  action(f_fwdReqToDir, "f", desc="Forward CPU request to directory") {
    peek(requestNetwork_in, CPURequestMsg) {
      enqueue(requestNetwork_out, CPURequestMsg, toDirLatency) {
        out_msg.addr := in_msg.addr;
        out_msg.Type := in_msg.Type;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Dirty := in_msg.Dirty;
        out_msg.Requestor := in_msg.Requestor;
        out_msg.WTRequestor := in_msg.WTRequestor;
        out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory));
        out_msg.Shared := in_msg.Shared;
        out_msg.MessageSize := in_msg.MessageSize;
        out_msg.Private := true;
        out_msg.InitialRequestTime := curCycle();
        out_msg.ProbeRequestStartTime := curCycle();
        if (getState(tbe, cache_entry, address) == State:S) {
          out_msg.ForceShared := true;
        }
        DPRINTF(RubySlicc, "Fwd: %s\n", out_msg);
        //assert(getState(tbe, cache_entry, address) == State:P || getState(tbe, cache_entry, address) == State:S);
        if (getState(tbe, cache_entry, address) == State:NP_W) {
          APPEND_TRANSITION_COMMENT(" fwding stale request: ");
          APPEND_TRANSITION_COMMENT(out_msg.Type);
        }
      }
    }
  }

  action(u_updateRegionEntry, "u", desc="Update the entry for profiling") {
    peek(requestNetwork_in, CPURequestMsg) {
      if (is_valid(cache_entry)) {
        if (in_msg.CtoDSinked == false) {
          APPEND_TRANSITION_COMMENT(" incr outstanding ");
          cache_entry.NumOutstandingReqs := 1 + cache_entry.NumOutstandingReqs;
          assert(cache_entry.OutstandingReqs.at(getRegionOffset(address)) == false);
          cache_entry.OutstandingReqs.at(getRegionOffset(address)) := true;
          assert(cache_entry.NumOutstandingReqs == countBoolVec(cache_entry.OutstandingReqs));
        } else {
          APPEND_TRANSITION_COMMENT(" NOT incr outstanding ");
          assert(in_msg.Type == CoherenceRequestType:RdBlkM || in_msg.Type == CoherenceRequestType:RdBlkS);
        }
        APPEND_TRANSITION_COMMENT(cache_entry.NumOutstandingReqs);
        if (in_msg.Type == CoherenceRequestType:RdBlkM || in_msg.Type == CoherenceRequestType:Atomic ||
            in_msg.Type == CoherenceRequestType:WriteThrough )
        {
          cache_entry.dirty := true;
        }
        if (in_msg.Type == CoherenceRequestType:VicDirty ||
            in_msg.Type == CoherenceRequestType:VicClean) {
            DPRINTF(RubySlicc, "Got %s for addr %s\n", in_msg.Type, address);
            //assert(cache_entry.ValidBlocks.at(getRegionOffset(address)));
            // can in fact be inv if core got an inv after a vicclean before it got here
            if (cache_entry.ValidBlocks.at(getRegionOffset(address))) {
                cache_entry.clearOnDone := true;
                cache_entry.clearOnDoneAddr := address;
                //cache_entry.ValidBlocks.at(getRegionOffset(address)) := false;
                //cache_entry.NumValidBlocks := cache_entry.NumValidBlocks - 1;
            }
        } else {
            if (cache_entry.ValidBlocks.at(getRegionOffset(address)) == false) {
              cache_entry.NumValidBlocks := cache_entry.NumValidBlocks + 1;
            }
            DPRINTF(RubySlicc, "before valid addr %s bits %s\n",
                    in_msg.Type, address, cache_entry.ValidBlocks);
            cache_entry.ValidBlocks.at(getRegionOffset(address)) := true;
            DPRINTF(RubySlicc, "after valid addr %s bits %s\n",
                    in_msg.Type, address, cache_entry.ValidBlocks);
            cache_entry.UsedBlocks.at(getRegionOffset(address)) := true;
        }
        assert(cache_entry.NumValidBlocks <= blocksPerRegion);
        assert(cache_entry.NumValidBlocks >= 0);
        APPEND_TRANSITION_COMMENT(" valid blocks ");
        APPEND_TRANSITION_COMMENT(cache_entry.ValidBlocks);
      } else {
        error("This shouldn't happen anymore I think");
        //tbe.ValidBlocks.at(getRegionOffest(address)) := true;
        assert(getState(tbe, cache_entry, address) == State:P_NP);
      }
    }
  }

  action(uw_updatePossibleWriteback, "uw", desc="writeback request complete") {
      peek(unblockNetwork_in, UnblockMsg) {
          if (is_valid(cache_entry) && in_msg.validToInvalid &&
              cache_entry.clearOnDone && cache_entry.clearOnDoneAddr == address) {
              DPRINTF(RubySlicc, "I have no idea what is going on here\n");
              cache_entry.ValidBlocks.at(getRegionOffset(address)) := false;
              cache_entry.NumValidBlocks := cache_entry.NumValidBlocks - 1;
              cache_entry.clearOnDone := false;
          }
      }
  }


  action(rp_requestPrivate, "rp", desc="Send private request r-dir") {
      peek(requestNetwork_in, CPURequestMsg) {
          // No need to send acks on replacements
          assert(is_invalid(tbe));
          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
              out_msg.DemandAddress := address;
              out_msg.Type := CoherenceRequestType:PrivateRequest;
              out_msg.OriginalType := in_msg.Type;
              out_msg.Requestor := machineID;
              out_msg.WTRequestor := in_msg.WTRequestor;
              out_msg.InitialRequestTime := curCycle();
              // will this always be ok? probably not for multisocket
              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
              out_msg.MessageSize := MessageSizeType:Request_Control;
              DPRINTF(RubySlicc, "Private request %s\n", out_msg);
          }
          cache_entry.ProbeRequestTime := curCycle();
          cache_entry.MsgSentToDir := true;
          APPEND_TRANSITION_COMMENT(getRegionBase(address));
      }
  }

  action(ru_requestUpgrade, "ru", desc="Send upgrade request r-dir") {
      peek(requestNetwork_in, CPURequestMsg) {
          // No need to send acks on replacements
          assert(is_invalid(tbe));
          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
              out_msg.Type := CoherenceRequestType:UpgradeRequest;
              out_msg.OriginalType := in_msg.Type;
              out_msg.Requestor := machineID;
              out_msg.WTRequestor := in_msg.WTRequestor;
              out_msg.InitialRequestTime := curCycle();
              // will this always be ok? probably not for multisocket
              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
              out_msg.MessageSize := MessageSizeType:Request_Control;
          }
          cache_entry.ProbeRequestTime := curCycle();
          cache_entry.MsgSentToDir := true;
          APPEND_TRANSITION_COMMENT(getRegionBase(address));
      }
  }

  action(rw_requestWriteback, "rq", desc="Send writeback request") {
    // No need to send acks on replacements
    enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
        out_msg.addr := getRegionBase(address); // use the actual address so the demand request can be fulfilled
        out_msg.Type := CoherenceRequestType:CleanWbRequest;
        out_msg.Requestor := machineID;
        // will this always be ok? probably not for multisocket
        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
        out_msg.MessageSize := MessageSizeType:Request_Control;
        out_msg.Dirty := tbe.dirty;
          APPEND_TRANSITION_COMMENT(getRegionBase(address));
    }
  }

  action(rs_requestShared, "rs", desc="Send shared request r-dir") {
      peek(requestNetwork_in, CPURequestMsg) {
          // No need to send acks on replacements
          assert(is_invalid(tbe));
          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
              out_msg.Type := CoherenceRequestType:SharedRequest;
              out_msg.OriginalType := in_msg.Type;
              out_msg.Requestor := machineID;
              out_msg.WTRequestor := in_msg.WTRequestor;
              out_msg.InitialRequestTime := curCycle();
              // will this always be ok? probably not for multisocket
              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
              out_msg.MessageSize := MessageSizeType:Request_Control;
          }
          cache_entry.ProbeRequestTime := curCycle();
          cache_entry.MsgSentToDir := true;
          APPEND_TRANSITION_COMMENT(getRegionBase(address));
      }
  }

  action(ai_ackRegionInv, "ai", desc="Send ack to r-dir on region inv if tbe says so") {
    // No need to send acks on replacements
    assert(is_valid(tbe));
    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
        out_msg.addr := getRegionBase(address);
        out_msg.Type := CoherenceResponseType:CPUPrbResp;
        out_msg.Sender := machineID;
        // will this always be ok? probably not for multisocket
        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
        out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }

  action(ad_ackDircetory, "ad", desc="send probe response to directory") {
    if (noTCCdir && tbe.MsgType == ProbeRequestType:PrbDowngrade && isOnGPU()) { //VIPER tcc doesnt understand PrbShrData
      assert(tbe.DemandRequest);                                    //So, let RegionBuffer take care of sending back ack
      enqueue(responseNetwork_out, ResponseMsg, toDirLatency) {
          out_msg.addr := tbe.DemandAddress;
          out_msg.Type := CoherenceResponseType:CPUPrbResp;  // L3 and CPUs respond in same way to probes
          out_msg.Sender := getPeer(machineID,address);
          // will this always be ok? probably not for multisocket
          out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
          out_msg.Dirty := false;  // only true if sending back data i think
          out_msg.Hit := false;
          out_msg.Ntsl := false;
          out_msg.State := CoherenceState:NA;
          out_msg.NoAckNeeded := true;
          out_msg.MessageSize := MessageSizeType:Response_Control;
          DPRINTF(RubySlicc, "%s\n", out_msg);
      }
    }
  }

  action(aie_ackRegionExclusiveInv, "aie", desc="Send ack to r-dir on region inv if tbe says so") {
    // No need to send acks on replacements
    assert(is_valid(tbe));
    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
        out_msg.addr := getRegionBase(address);
        out_msg.Type := CoherenceResponseType:CPUPrbResp;
        out_msg.Sender := machineID;
        out_msg.NotCached := true;
        // will this always be ok? probably not for multisocket
        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
        out_msg.MessageSize := MessageSizeType:Response_Control;
        out_msg.Dirty := tbe.dirty;
    }
  }

  action(ain_ackRegionInvNow, "ain", desc="Send ack to r-dir on region inv") {
    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
      out_msg.addr := getRegionBase(address);
      out_msg.Type := CoherenceResponseType:CPUPrbResp;
      out_msg.Sender := machineID;
      // will this always be ok? probably not for multisocket
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
      out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }

  action(aine_ackRegionInvExlusiveNow, "aine", desc="Send ack to r-dir on region inv with exlusive permission") {
    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
      out_msg.addr := getRegionBase(address);
      out_msg.Type := CoherenceResponseType:CPUPrbResp;
      out_msg.Sender := machineID;
      out_msg.NotCached := true;
       // will this always be ok? probably not for multisocket
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
      out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }

  action(ap_ackPrivateNotify, "ap", desc="Send ack to r-dir on private notify") {
    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
      out_msg.addr := getRegionBase(address);
      out_msg.Type := CoherenceResponseType:PrivateAck;
      out_msg.Sender := machineID;
      // will this always be ok? probably not for multisocket
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
      out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }

  action(aw_ackWbNotify, "aw", desc="Send ack to r-dir on writeback notify") {
    peek(notifyNetwork_in, CPURequestMsg) {
      if (in_msg.NoAckNeeded == false) {
        enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
          out_msg.addr := getRegionBase(address);
          out_msg.Type := CoherenceResponseType:RegionWbAck;
          out_msg.Sender := machineID;
          // will this always be ok? probably not for multisocket
          out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
          out_msg.MessageSize := MessageSizeType:Response_Control;
        }
      }
    }
  }

  action(e_evictCurrent, "e", desc="Evict this block in the region") {
    // send force invalidate message to directory to invalidate this block
    // must invalidate all blocks since region buffer could have privitized it
      if (tbe.ValidBlocks.at(getRegionOffset(address)) &&
          (tbe.DemandRequest == false || tbe.DemandAddress != address)) {
          DPRINTF(RubySlicc, "trying to evict address %s (base: %s, offset: %d)\n", address, getRegionBase(address), getRegionOffset(address));
          DPRINTF(RubySlicc, "tbe valid blocks %s\n", tbe.ValidBlocks);

        enqueue(probeNetwork_out, NBProbeRequestMsg, 1) {
            out_msg.addr := address;
            out_msg.Type := tbe.MsgType;
            out_msg.ReturnData := true;
            if (address == tbe.DemandAddress) {
                out_msg.DemandRequest := true;
            }
            out_msg.MessageSize := MessageSizeType:Control;
            out_msg.Destination.add(getPeer(machineID,address));
            DPRINTF(RubySlicc, "%s\n", out_msg);
        }
        APPEND_TRANSITION_COMMENT(" current ");
        APPEND_TRANSITION_COMMENT(tbe.ValidBlocks.at(getRegionOffset(address)));
        tbe.AllAcksReceived := false;
      } else {
          DPRINTF(RubySlicc, "Not evicting demand %s\n", address);
      }
  }

  action(ed_evictDemand, "ed", desc="Evict the demand request if it's valid") {
    if (noTCCdir && tbe.MsgType == ProbeRequestType:PrbDowngrade && isOnGPU()) {
      tbe.OutstandingAcks := 0;
      tbe.AllAcksReceived := true;
      tbe.DoneEvicting := true;
      enqueue(triggerQueue_out, TriggerMsg, 1) {
          out_msg.Type := TriggerType:AcksComplete;
          out_msg.addr := getRegionBase(address);
      }
    } else if (tbe.DemandRequest) {
      enqueue(probeNetwork_out, NBProbeRequestMsg, 1) {
        out_msg.addr := tbe.DemandAddress;
        out_msg.Type := tbe.MsgType;
        out_msg.ReturnData := true;
        out_msg.DemandRequest := true;
        out_msg.MessageSize := MessageSizeType:Control;
        out_msg.Destination.add(getPeer(machineID,address));
        DPRINTF(RubySlicc, "%s\n", out_msg);
        tbe.AllAcksReceived := false;
      }
      if (tbe.ValidBlocks.at(getRegionOffset(tbe.DemandAddress)) == false) {
          tbe.OutstandingAcks := tbe.OutstandingAcks + 1;
      }
      APPEND_TRANSITION_COMMENT("Evicting demand ");
      APPEND_TRANSITION_COMMENT(tbe.DemandAddress);
    }
    APPEND_TRANSITION_COMMENT("waiting acks ");
    APPEND_TRANSITION_COMMENT(tbe.OutstandingAcks);
  }

  action(adp_AckDemandProbe, "fp", desc="forward demand probe even if we know that the core is invalid") {
    peek(probeNetwork_in, NBProbeRequestMsg) {
        if (in_msg.DemandRequest) {
            enqueue(responseNetwork_out, ResponseMsg, toDirLatency) {
                out_msg.addr := in_msg.DemandAddress;
                out_msg.Type := CoherenceResponseType:CPUPrbResp;  // L3 and CPUs respond in same way to probes
                out_msg.Sender := getPeer(machineID,address);
                // will this always be ok? probably not for multisocket
                out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
                out_msg.Dirty := false;  // only true if sending back data i think
                out_msg.Hit := false;
                out_msg.Ntsl := false;
                out_msg.State := CoherenceState:NA;
                out_msg.NoAckNeeded := true;
                out_msg.MessageSize := MessageSizeType:Response_Control;
                DPRINTF(RubySlicc, "%s\n", out_msg);
            }
        }
    }
  }

  action(en_enqueueNextEvict, "en", desc="Queue evict the next block in the region") {
    // increment in_msg.addr by blockSize bytes and enqueue on triggerPort
    // Only enqueue if the next address doesn't overrun the region bound
    if (getRegionBase(getNextBlock(address)) == getRegionBase(address)) {
        enqueue(triggerQueue_out, TriggerMsg, nextEvictLatency) {
            out_msg.Type := TriggerType:InvNext;
            out_msg.addr := getNextBlock(address);
        }
    } else {
        tbe.DoneEvicting := true;
        DPRINTF(RubySlicc, "Done evicing region %s\n", getRegionBase(address));
        DPRINTF(RubySlicc, "Waiting for %s acks\n", tbe.OutstandingAcks);
        if (tbe.AllAcksReceived == true) {
            enqueue(triggerQueue_out, TriggerMsg, 1) {
                out_msg.Type := TriggerType:AcksComplete;
                out_msg.addr := getRegionBase(address);
            }
        }
    }
  }

  action(ef_enqueueFirstEvict, "ef", desc="Queue the first block in the region to be evicted") {
    if (tbe.DoneEvicting == false) {
      enqueue(triggerQueue_out, TriggerMsg, nextEvictLatency) {
          out_msg.Type := TriggerType:InvNext;
          out_msg.addr := getRegionBase(address);
      }
    }
  }

  action(ra_receiveAck, "ra", desc="Mark TBE entry as received this ack") {
      DPRINTF(RubySlicc, "received ack for %s reg: %s vec: %s pos: %d\n",
              address, getRegionBase(address), tbe.ValidBlocks, getRegionOffset(address));
      peek(unblockNetwork_in, UnblockMsg) {
          //
          // Note the tbe ValidBlock vec will be a conservative list of the
          // valid blocks since the cache entry ValidBlock vec is set on the
          // request
          //
          if (in_msg.wasValid) {
              assert(tbe.ValidBlocks.at(getRegionOffset(address)));
          }
      }
      tbe.OutstandingAcks := tbe.OutstandingAcks - 1;
      tbe.AcksReceived.at(getRegionOffset(address)) := true;
      assert(tbe.OutstandingAcks >= 0);
      if (tbe.OutstandingAcks == 0) {
          tbe.AllAcksReceived := true;
          if (tbe.DoneEvicting) {
              enqueue(triggerQueue_out, TriggerMsg, 1) {
                  out_msg.Type := TriggerType:AcksComplete;
                  out_msg.addr := getRegionBase(address);
              }
          }
      }

      APPEND_TRANSITION_COMMENT(getRegionBase(address));
      APPEND_TRANSITION_COMMENT(" Acks left receive ");
      APPEND_TRANSITION_COMMENT(tbe.OutstandingAcks);
  }

  action(do_decrementOutstanding, "do", desc="Decrement outstanding requests") {
    APPEND_TRANSITION_COMMENT(" decr outstanding ");
    if (is_valid(cache_entry)) {
      cache_entry.NumOutstandingReqs := cache_entry.NumOutstandingReqs - 1;
      assert(cache_entry.OutstandingReqs.at(getRegionOffset(address)));
      cache_entry.OutstandingReqs.at(getRegionOffset(address)) := false;
      assert(cache_entry.NumOutstandingReqs >= 0);
      assert(cache_entry.NumOutstandingReqs == countBoolVec(cache_entry.OutstandingReqs));
      APPEND_TRANSITION_COMMENT(cache_entry.NumOutstandingReqs);
    }
    if (is_valid(tbe)) {
      tbe.NumOutstandingReqs := tbe.NumOutstandingReqs - 1;
      assert(tbe.OutstandingReqs.at(getRegionOffset(address)));
      tbe.OutstandingReqs.at(getRegionOffset(address)) := false;
      assert(tbe.NumOutstandingReqs >= 0);
      assert(tbe.NumOutstandingReqs == countBoolVec(tbe.OutstandingReqs));
      APPEND_TRANSITION_COMMENT(tbe.NumOutstandingReqs);
    }
  }

  action(co_checkOutstanding, "co", desc="check if there are no more outstanding requests") {
    assert(is_valid(tbe));
    if ((tbe.NumOutstandingReqs <= tbe.OutstandingThreshold) &&
        (tbe.AllOutstandingTriggered == false)) {
      APPEND_TRANSITION_COMMENT(" no more outstanding: ");
      APPEND_TRANSITION_COMMENT(tbe.NumOutstandingReqs);
      APPEND_TRANSITION_COMMENT(tbe.OutstandingThreshold);
      enqueue(triggerQueue_out, TriggerMsg, 1) {
          out_msg.Type := TriggerType:AllOutstanding;
          if (tbe.DemandRequest) {
              out_msg.addr := tbe.DemandAddress;
          } else {
              out_msg.addr := getRegionBase(address);
          }
          DPRINTF(RubySlicc, "co enqueuing %s\n", out_msg);
          tbe.AllOutstandingTriggered := true;
      }
    } else {
      APPEND_TRANSITION_COMMENT(" still more outstanding ");
    }
  }

  action(ro_resetAllOutstanding, "ro", desc="Reset all outstanding") {
      tbe.AllOutstandingTriggered := false;
  }

  action(so_setOutstandingCheckOne, "so", desc="Check outstanding is waiting for 1, not 0") {
    // Need this for S_P because one request is outstanding between here and r-dir
    tbe.OutstandingThreshold := 1;
  }

  action(a_allocateRegionEntry, "a", desc="Allocate a new entry") {
    set_cache_entry(cacheMemory.allocate(getRegionBase(address), new Entry));
    cache_entry.ValidBlocks.clear();
    cache_entry.ValidBlocks.resize(blocksPerRegion);
    cache_entry.UsedBlocks.clear();
    cache_entry.UsedBlocks.resize(blocksPerRegion);
    cache_entry.dirty := false;
    cache_entry.NumOutstandingReqs := 0;
    cache_entry.OutstandingReqs.clear();
    cache_entry.OutstandingReqs.resize(blocksPerRegion);
  }

  action(d_deallocateRegionEntry, "d", desc="Deallocate region entry") {
    cacheMemory.deallocate(getRegionBase(address));
    unset_cache_entry();
  }

  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
    check_allocate(TBEs);
    TBEs.allocate(getRegionBase(address));
    set_tbe(getTBE(address));
    tbe.OutstandingAcks := 0;
    tbe.AllAcksReceived := true; // starts true since the region could be empty
    tbe.DoneEvicting := false;
    tbe.AcksReceived.clear();
    tbe.AcksReceived.resize(blocksPerRegion);
    tbe.SendAck := false;
    tbe.OutstandingThreshold := 0;
    if (is_valid(cache_entry)) {
      tbe.NumOutstandingReqs := cache_entry.NumOutstandingReqs;
      tbe.OutstandingReqs := cache_entry.OutstandingReqs;
      assert(tbe.NumOutstandingReqs == countBoolVec(tbe.OutstandingReqs));
      tbe.dirty := cache_entry.dirty;
      tbe.ValidBlocks := cache_entry.ValidBlocks;
      tbe.OutstandingAcks := countBoolVec(tbe.ValidBlocks);
      APPEND_TRANSITION_COMMENT(" tbe valid blocks ");
      APPEND_TRANSITION_COMMENT(tbe.ValidBlocks);
      APPEND_TRANSITION_COMMENT(" cache valid blocks ");
      APPEND_TRANSITION_COMMENT(cache_entry.ValidBlocks);
    } else {
      tbe.dirty := false;
    }
  }

  action(m_markSendAck, "m", desc="Mark TBE that we need to ack at end") {
    assert(is_valid(tbe));
    tbe.SendAck := true;
  }

  action(db_markDirtyBit, "db", desc="Mark TBE dirty bit") {
      peek(unblockNetwork_in, UnblockMsg) {
          if (is_valid(tbe)) {
              tbe.dirty := tbe.dirty || in_msg.Dirty;
          }
      }
  }

  action(dr_markDoneAckReceived, "dr", desc="Mark TBE that a done ack has been received") {
    assert(is_valid(tbe));
    tbe.DoneAckReceived := true;
    tbe.DoneAckAddr := address;
    APPEND_TRANSITION_COMMENT(" marking done ack on TBE ");
  }

  action(se_setTBE, "se", desc="Set msg type to evict") {
    peek(probeNetwork_in, NBProbeRequestMsg) {
        tbe.MsgType := in_msg.Type;
        tbe.Requestor := in_msg.Requestor;
        tbe.DemandAddress := in_msg.DemandAddress;
        tbe.DemandRequest := in_msg.DemandRequest;
    }
  }

  action(sne_setNewTBE, "sne", desc="Set msg type to evict") {
    peek(probeNetwork_in, NBProbeRequestMsg) {
        tbe.NewMsgType := in_msg.Type;
        tbe.NewRequestor := in_msg.Requestor;
        tbe.NewDemandAddress := in_msg.DemandAddress;
        tbe.NewDemandRequest := in_msg.DemandRequest;
    }
  }

  action(soe_setOldTBE, "soe", desc="Set msg type to evict") {
    tbe.MsgType := tbe.NewMsgType;
    tbe.Requestor := tbe.NewRequestor;
    tbe.DemandAddress := tbe.NewDemandAddress;
    tbe.DemandRequest := tbe.NewDemandRequest;
    tbe.OutstandingAcks :=  countBoolVec(tbe.ValidBlocks);
    tbe.AllAcksReceived := true; // starts true since the region could be empty
    tbe.DoneEvicting := false;
    tbe.AcksReceived.clear();
    tbe.AcksReceived.resize(blocksPerRegion);
    tbe.SendAck := false;
  }

  action(ser_setTBE, "ser", desc="Set msg type to evict repl") {
    tbe.MsgType := ProbeRequestType:PrbInv;
  }

  action(md_setMustDowngrade, "md", desc="When permissions finally get here, must be shared") {
    assert(is_valid(cache_entry));
    cache_entry.MustDowngrade := true;
  }

  action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") {
    TBEs.deallocate(getRegionBase(address));
    unset_tbe();
  }

  action(p_popRequestQueue, "p", desc="Pop the request queue") {
    requestNetwork_in.dequeue(clockEdge());
  }

  action(pl_popUnblockQueue, "pl", desc="Pop the unblock queue") {
    unblockNetwork_in.dequeue(clockEdge());
  }

  action(pn_popNotifyQueue, "pn", desc="Pop the notify queue") {
    notifyNetwork_in.dequeue(clockEdge());
  }

  action(pp_popProbeQueue, "pp", desc="Pop the probe queue") {
    probeNetwork_in.dequeue(clockEdge());
  }

  action(pt_popTriggerQueue, "pt", desc="Pop the trigger queue") {
    DPRINTF(RubySlicc, "Trigger Before Contents: %s\n", triggerQueue_in);
    triggerQueue_in.dequeue(clockEdge());
    DPRINTF(RubySlicc, "Trigger After Contents: %s\n", triggerQueue_in);
  }

  // Must always use wake all, since non-region address wait on region addresses
  action(wa_wakeUpAllDependents, "wa", desc="Wake up any requests waiting for this region") {
    wakeUpAllBuffers();
  }

  action(zz_stallAndWaitRequestQueue, "\z", desc="recycle request queue") {
    Addr regAddr := getRegionBase(address);
    DPRINTF(RubySlicc, "Stalling address %s\n", regAddr);
    stall_and_wait(requestNetwork_in, regAddr);
  }

  action(yy_stallAndWaitProbeQueue, "\y", desc="stall probe queue") {
    Addr regAddr := getRegionBase(address);
    stall_and_wait(probeNetwork_in, regAddr);
  }

  action(yyy_recycleProbeQueue, "\yy", desc="recycle probe queue") {
    probeNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
  }

  action(zzz_recycleRequestQueue, "\zz", desc="recycle request queue") {
    requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
  }

  action(www_recycleUnblockNetwork, "\ww", desc="recycle unblock queue") {
    unblockNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
  }

  action(z_stall, "z", desc="stall request queue") {
    // fake state
  }

  action(mru_setMRU, "mru", desc="set MRU") {
    cacheMemory.setMRU(address, cache_entry.NumValidBlocks);
  }

  // Transitions

  transition({NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, P_NP_W, P_NP_NP, NP_W}, {CPURead, CPUWriteback, CPUWrite}) {} {
    zz_stallAndWaitRequestQueue;
  }

  transition(SS_P, {CPURead, CPUWriteback}) {
    zz_stallAndWaitRequestQueue;
  }

  transition({NP, S, P, NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P, NP_W, P_NP_NP}, StallAccess) {} {
    zz_stallAndWaitRequestQueue;
  }

  transition({S, P, NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P, P_NP_W, P_NP_NP, NP_W}, StallDoneAck) {
    www_recycleUnblockNetwork;
  }

  transition(NP, StallDoneAck, NP_W) {
    t_allocateTBE;
    db_markDirtyBit;
    dr_markDoneAckReceived;
    pl_popUnblockQueue;
  }

  transition(NP_W, StaleRequest, NP) {
    f_fwdReqToDir;
    dt_deallocateTBE;
    wa_wakeUpAllDependents;
    p_popRequestQueue;
  }

  transition(P_NP_O, DowngradeRegion) {} {
    z_stall; // should stall and wait
  }

  transition({NP_PS, S_NP_PS, S_P, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P}, ReplRegion) {} {
    zz_stallAndWaitRequestQueue; // can't let things get out of order!
  }

  transition({P_NP_O, S_O, SS_P}, InvRegion) {} {
    yyy_recycleProbeQueue; // can't be z_stall because there could be a RdBlkM in the requestQueue which has the sinked flag which is blocking the inv
  }

  transition(P_NP, {InvRegion, DowngradeRegion}, P_NP_NP) {} {
    sne_setNewTBE;
    pp_popProbeQueue;
  }

  transition(S_P, DowngradeRegion) {} {
    adp_AckDemandProbe;
    ain_ackRegionInvNow;
    pp_popProbeQueue;
  }

  transition(P_NP_W, InvRegion) {
    adp_AckDemandProbe;
    ain_ackRegionInvNow;
    pp_popProbeQueue;
  }

  transition(P_NP_W, DowngradeRegion) {
    adp_AckDemandProbe;
    aine_ackRegionInvExlusiveNow;
    pp_popProbeQueue;
  }

  transition({P, S}, {CPURead, CPUWriteback}) {TagArrayRead, TagArrayWrite} {
    mru_setMRU;
    f_fwdReqToDir;
    u_updateRegionEntry;
    p_popRequestQueue;
  }

  transition(P, CPUWrite) {TagArrayRead, TagArrayWrite} {
    mru_setMRU;
    f_fwdReqToDir;
    u_updateRegionEntry;
    p_popRequestQueue;
  }

  transition(S, CPUWrite, S_O) {TagArrayRead} {
    mru_setMRU;
    t_allocateTBE;
    co_checkOutstanding;
    zz_stallAndWaitRequestQueue;
  }

  transition(S_O, AllOutstanding, SS_P) {
    wa_wakeUpAllDependents;
    ro_resetAllOutstanding;
    pt_popTriggerQueue;
  }

  transition(SS_P, CPUWrite, S_P) {
    mru_setMRU;
    dt_deallocateTBE;
    ru_requestUpgrade;
    u_updateRegionEntry;
    p_popRequestQueue;
  }

  transition(NP, {CPURead, CPUWriteback}, NP_PS) {TagArrayRead, TagArrayWrite} {
    a_allocateRegionEntry;
    rs_requestShared;
    u_updateRegionEntry;
    p_popRequestQueue;//zz_stallAndWaitRequestQueue;
  }

  transition(NP, CPUWrite, NP_PS) {TagArrayRead, TagArrayWrite} {
    a_allocateRegionEntry;
    rp_requestPrivate;
    u_updateRegionEntry;
    p_popRequestQueue;//zz_stallAndWaitRequestQueue;
  }

  transition(NP_PS, PrivateNotify, P) {} {
    ap_ackPrivateNotify;
    wa_wakeUpAllDependents;
    pn_popNotifyQueue;
  }

  transition(S_P, PrivateNotify, P) {} {
    ap_ackPrivateNotify;
    wa_wakeUpAllDependents;
    pn_popNotifyQueue;
  }

  transition(NP_PS, SharedNotify, S) {} {
    ap_ackPrivateNotify;
    wa_wakeUpAllDependents;
    pn_popNotifyQueue;
  }

  transition(P_NP_W, WbNotify, NP) {} {
    aw_ackWbNotify;
    wa_wakeUpAllDependents;
    dt_deallocateTBE;
    pn_popNotifyQueue;
  }

  transition({P, S}, ReplRegion, P_NP_O) {TagArrayRead, TagArrayWrite} {
    t_allocateTBE;
    ser_setTBE;
    d_deallocateRegionEntry;
    co_checkOutstanding;
  }

  transition({P, S}, InvRegion, P_NP_O) {TagArrayRead, TagArrayWrite} {
    t_allocateTBE;
    se_setTBE;
    m_markSendAck;
    d_deallocateRegionEntry;
    co_checkOutstanding;
    pp_popProbeQueue;
  }

  transition(P_NP_O, AllOutstanding, P_NP) {} {
    ed_evictDemand;
    ef_enqueueFirstEvict;
    ro_resetAllOutstanding;
    pt_popTriggerQueue;
  }

  transition(S_P, InvRegion, S_NP_PS_O) {TagArrayRead} {
    t_allocateTBE;
    se_setTBE;
    m_markSendAck;
    so_setOutstandingCheckOne;
    co_checkOutstanding;
    pp_popProbeQueue;
  }

  transition(S_NP_PS_O, AllOutstanding, S_NP_PS) {
    ed_evictDemand;
    ef_enqueueFirstEvict;
    ro_resetAllOutstanding;
    pt_popTriggerQueue;
  }

  transition(P, DowngradeRegion, P_S_O) {TagArrayRead, TagArrayWrite} {
    t_allocateTBE;
    se_setTBE;
    m_markSendAck;
    co_checkOutstanding;
    pp_popProbeQueue;
  }

  transition(P_S_O, AllOutstanding, P_S) {} {
    ed_evictDemand;
    ef_enqueueFirstEvict;
    ro_resetAllOutstanding;
    pt_popTriggerQueue;
  }

  transition({P, S}, DoneAck) {TagArrayWrite} {
    do_decrementOutstanding;
    wa_wakeUpAllDependents;
    db_markDirtyBit;
    uw_updatePossibleWriteback;
    pl_popUnblockQueue;
  }

  transition({S_P, NP_PS, S_NP_PS}, DoneAck) {TagArrayWrite} {
      www_recycleUnblockNetwork;
  }

  transition({P_NP_O, S_NP_PS_O, P_S_O, S_O}, DoneAck) {} {
    do_decrementOutstanding;
    co_checkOutstanding;
    db_markDirtyBit;
    uw_updatePossibleWriteback;
    pl_popUnblockQueue;
  }

  transition({P_NP, P_S, S_NP_PS, P_NP_NP}, Evict) {} {
    e_evictCurrent;
    en_enqueueNextEvict;
    pt_popTriggerQueue;
  }

  transition({P_NP, P_S, S_NP_PS, P_NP_NP}, InvAck) {} {
    ra_receiveAck;
    db_markDirtyBit;
    pl_popUnblockQueue;
  }

  transition(P_NP, LastAck_CleanWb, P_NP_W) {} {
      rw_requestWriteback;
      pt_popTriggerQueue;
  }

  transition(P_NP_NP, LastAck_CleanWb, P_NP) {} {
    soe_setOldTBE;
    m_markSendAck;
    ed_evictDemand;
    ef_enqueueFirstEvict;
    pt_popTriggerQueue;
  }

  transition(P_NP, LastAck_PrbResp, NP) {} {
    aie_ackRegionExclusiveInv;
    dt_deallocateTBE;
    wa_wakeUpAllDependents;
    pt_popTriggerQueue;
  }

  transition(S_NP_PS, LastAck_PrbResp, NP_PS) {} {
    aie_ackRegionExclusiveInv;
    dt_deallocateTBE;
    wa_wakeUpAllDependents;
    pt_popTriggerQueue;
  }

  transition(P_S, LastAck_PrbResp, S) {} {
    ai_ackRegionInv;
    ad_ackDircetory;
    dt_deallocateTBE;
    wa_wakeUpAllDependents;
    pt_popTriggerQueue;
  }

}

