/*
 * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * 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.
 */

/*
 * $Id: MOESI_CMP_token-L1cache.sm 1.22 05/01/19 15:55:39-06:00 beckmann@s0-28.cs.wisc.edu $
 *
 */

machine(L1Cache, "Token protocol")
 : Sequencer * sequencer,
   CacheMemory * L1Icache,
   CacheMemory * L1Dcache,
   int l2_select_num_bits,
   int N_tokens,

   Cycles l1_request_latency = 2,
   Cycles l1_response_latency = 2,
   int retry_threshold = 1,
   Cycles fixed_timeout_latency = 100,
   Cycles reissue_wakeup_latency = 10,
   Cycles use_timeout_latency = 50,

   bool dynamic_timeout_enabled = true,
   bool no_mig_atomic = true,
   bool send_evictions
{

  // From this node's L1 cache TO the network

  // a local L1 -> this L2 bank
  MessageBuffer responseFromL1Cache, network="To", virtual_network="4", ordered="false", vnet_type="response";
  MessageBuffer persistentFromL1Cache, network="To", virtual_network="3", ordered="true", vnet_type="persistent";
  // a local L1 -> this L2 bank, currently ordered with directory forwarded requests
  MessageBuffer requestFromL1Cache, network="To", virtual_network="1", ordered="false", vnet_type="request";


  // To this node's L1 cache FROM the network
  // a L2 bank -> this L1
  MessageBuffer responseToL1Cache, network="From", virtual_network="4", ordered="false", vnet_type="response";
  MessageBuffer persistentToL1Cache, network="From", virtual_network="3", ordered="true", vnet_type="persistent";
  // a L2 bank -> this L1
  MessageBuffer requestToL1Cache, network="From", virtual_network="1", ordered="false", vnet_type="request";

  // STATES
  state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
    // Base states
    NP, AccessPermission:Invalid, "NP", desc="Not Present";
    I, AccessPermission:Invalid, "I", desc="Idle";
    S, AccessPermission:Read_Only, "S", desc="Shared";
    O, AccessPermission:Read_Only, "O", desc="Owned";
    M, AccessPermission:Read_Only, "M", desc="Modified (dirty)";
    MM, AccessPermission:Read_Write, "MM", desc="Modified (dirty and locally modified)";
    M_W, AccessPermission:Read_Only, "M^W", desc="Modified (dirty), waiting";
    MM_W, AccessPermission:Read_Write, "MM^W", desc="Modified (dirty and locally modified), waiting";

    // Transient States
    IM, AccessPermission:Busy, "IM", desc="Issued GetX";
    SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line";
    OM, AccessPermission:Read_Only, "OM", desc="Issued GetX, received data";
    IS, AccessPermission:Busy, "IS", desc="Issued GetS";

    // Locked states
    I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked";
    S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked";
    IM_L, AccessPermission:Busy, "IM^L", desc="Invalid, Locked, trying to go to Modified";
    SM_L, AccessPermission:Busy, "SM^L", desc="Shared, Locked, trying to go to Modified";
    IS_L, AccessPermission:Busy, "IS^L", desc="Invalid, Locked, trying to go to Shared";
  }

  // EVENTS
  enumeration(Event, desc="Cache events") {
    Load,            desc="Load request from the processor";
    Ifetch,          desc="I-fetch request from the processor";
    Store,           desc="Store request from the processor";
    Atomic,          desc="Atomic request from the processor";
    L1_Replacement,  desc="L1 Replacement";

    // Responses
    Data_Shared,             desc="Received a data message, we are now a sharer";
    Data_Owner,              desc="Received a data message, we are now the owner";
    Data_All_Tokens,   desc="Received a data message, we are now the owner, we now have all the tokens";
    Ack,                     desc="Received an ack message";
    Ack_All_Tokens,          desc="Received an ack message, we now have all the tokens";

    // Requests
    Transient_GETX,  desc="A GetX from another processor";
    Transient_Local_GETX,  desc="A GetX from another processor";
    Transient_GETS,  desc="A GetS from another processor";
    Transient_Local_GETS,  desc="A GetS from another processor";
    Transient_GETS_Last_Token,  desc="A GetS from another processor";
    Transient_Local_GETS_Last_Token,  desc="A GetS from another processor";

    // Lock/Unlock for distributed
    Persistent_GETX,     desc="Another processor has priority to read/write";
    Persistent_GETS,     desc="Another processor has priority to read";
    Persistent_GETS_Last_Token, desc="Another processor has priority to read, no more tokens";
    Own_Lock_or_Unlock,  desc="This processor now has priority";

    // Triggers
    Request_Timeout,         desc="Timeout";
    Use_TimeoutStarverX,             desc="Timeout";
    Use_TimeoutStarverS,             desc="Timeout";
    Use_TimeoutNoStarvers,             desc="Timeout";
    Use_TimeoutNoStarvers_NoMig,     desc="Timeout Don't Migrate";
  }

  // TYPES

  // CacheEntry
  structure(Entry, desc="...", interface="AbstractCacheEntry") {
    State CacheState,        desc="cache state";
    bool Dirty,              desc="Is the data dirty (different than memory)?";
    int Tokens,              desc="The number of tokens we're holding for the line";
    DataBlock DataBlk,       desc="data for the block";
  }


  // TBE fields
  structure(TBE, desc="...") {
    Address Addr,                      desc="Physical address for this TBE";
    State TBEState,                       desc="Transient state";
    int IssueCount,      default="0",     desc="The number of times we've issued a request for this line.";
    Address PC,                           desc="Program counter of request";

    bool WentPersistent, default="false",  desc="Request went persistent";
    bool ExternalResponse, default="false", desc="Response came from an external controller";
    bool IsAtomic, default="false",       desc="Request was an atomic request";

    AccessType TypeOfAccess,                desc="Type of request (used for profiling)";
    Cycles IssueTime,                       desc="Time the request was issued";
    RubyAccessMode AccessMode,    desc="user/supervisor access type";
    PrefetchBit Prefetch,         desc="Is this a prefetch request";
  }

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

  structure(PersistentTable, external="yes") {
    void persistentRequestLock(Address, MachineID, AccessType);
    void persistentRequestUnlock(Address, MachineID);
    bool okToIssueStarving(Address, MachineID);
    MachineID findSmallest(Address);
    AccessType typeOfSmallest(Address);
    void markEntries(Address);
    bool isLocked(Address);
    int countStarvingForAddress(Address);
    int countReadStarvingForAddress(Address);
  }

  void set_cache_entry(AbstractCacheEntry b);
  void unset_cache_entry();
  void set_tbe(TBE b);
  void unset_tbe();
  void wakeUpAllBuffers();
  void wakeUpBuffers(Address a);
  Cycles curCycle();

  TBETable L1_TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";

  MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true";

  bool starving, default="false";
  int l2_select_low_bit, default="RubySystem::getBlockSizeBits()";

  PersistentTable persistentTable;
  TimerTable useTimerTable;
  TimerTable reissueTimerTable;

  int outstandingRequests, default="0";
  int outstandingPersistentRequests, default="0";

  // Constant that provides hysteresis for calculated the estimated average
  int averageLatencyHysteresis, default="(8)";
  Cycles averageLatencyCounter,
        default="(Cycles(500) << (*m_L1Cache_averageLatencyHysteresis_ptr))";

  Cycles averageLatencyEstimate() {
    DPRINTF(RubySlicc, "%d\n",
            (averageLatencyCounter >> averageLatencyHysteresis));
    //profile_average_latency_estimate( (averageLatencyCounter >> averageLatencyHysteresis) );
    return averageLatencyCounter >> averageLatencyHysteresis;
  }

  void updateAverageLatencyEstimate(Cycles latency) {
    DPRINTF(RubySlicc, "%d\n", latency);

    // By subtracting the current average and then adding the most
    // recent sample, we calculate an estimate of the recent average.
    // If we simply used a running sum and divided by the total number
    // of entries, the estimate of the average would adapt very slowly
    // after the execution has run for a long time.
    // averageLatencyCounter := averageLatencyCounter - averageLatencyEstimate() + latency;

    averageLatencyCounter := averageLatencyCounter - averageLatencyEstimate() + latency;
  }

  Entry getCacheEntry(Address addr), return_by_pointer="yes" {
    Entry L1Dcache_entry := static_cast(Entry, "pointer", L1Dcache.lookup(addr));
    if(is_valid(L1Dcache_entry)) {
      return L1Dcache_entry;
    }

    Entry L1Icache_entry := static_cast(Entry, "pointer", L1Icache.lookup(addr));
    return L1Icache_entry;
  }

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

  Entry getL1DCacheEntry(Address addr), return_by_pointer="yes" {
    Entry L1Dcache_entry := static_cast(Entry, "pointer", L1Dcache.lookup(addr));
    return L1Dcache_entry;
  }

  Entry getL1ICacheEntry(Address addr), return_by_pointer="yes" {
    Entry L1Icache_entry := static_cast(Entry, "pointer", L1Icache.lookup(addr));
    return L1Icache_entry;
  }

  int getTokens(Entry cache_entry) {
    if (is_valid(cache_entry)) {
      return cache_entry.Tokens;
    }
    return 0;
  }

  State getState(TBE tbe, Entry cache_entry, Address addr) {

    if (is_valid(tbe)) {
      return tbe.TBEState;
    } else if (is_valid(cache_entry)) {
      return cache_entry.CacheState;
    } else {
      if (persistentTable.isLocked(addr) && (persistentTable.findSmallest(addr) != machineID)) {
      // Not in cache, in persistent table, but this processor isn't highest priority
      return State:I_L;
      } else {
        return State:NP;
      }
    }
  }

  void setState(TBE tbe, Entry cache_entry, Address addr, State state) {
    assert((L1Dcache.isTagPresent(addr) && L1Icache.isTagPresent(addr)) == false);

    if (is_valid(tbe)) {
      assert(state != State:I);
      assert(state != State:S);
      assert(state != State:O);
      assert(state != State:MM);
      assert(state != State:M);
      tbe.TBEState := state;
    }

    if (is_valid(cache_entry)) {
      // Make sure the token count is in range
      assert(cache_entry.Tokens >= 0);
      assert(cache_entry.Tokens <= max_tokens());
      assert(cache_entry.Tokens != (max_tokens() / 2));

      if ((state == State:I_L) ||
          (state == State:IM_L) ||
          (state == State:IS_L)) {
        // Make sure we have no tokens in the "Invalid, locked" states
          assert(cache_entry.Tokens == 0);

        // Make sure the line is locked
        // assert(persistentTable.isLocked(addr));

        // But we shouldn't have highest priority for it
        // assert(persistentTable.findSmallest(addr) != id);

      } else if ((state == State:S_L) ||
                 (state == State:SM_L)) {
        assert(cache_entry.Tokens >= 1);
        assert(cache_entry.Tokens < (max_tokens() / 2));

        // Make sure the line is locked...
        // assert(persistentTable.isLocked(addr));

        // ...But we shouldn't have highest priority for it...
        // assert(persistentTable.findSmallest(addr) != id);

        // ...And it must be a GETS request
        // assert(persistentTable.typeOfSmallest(addr) == AccessType:Read);

      } else {

        // If there is an entry in the persistent table of this block,
        // this processor needs to have an entry in the table for this
        // block, and that entry better be the smallest (highest
        // priority).  Otherwise, the state should have been one of
        // locked states

        //if (persistentTable.isLocked(addr)) {
        //  assert(persistentTable.findSmallest(addr) == id);
        //}
      }

      // in M and E you have all the tokens
      if (state == State:MM || state == State:M || state == State:MM_W || state == State:M_W) {
        assert(cache_entry.Tokens == max_tokens());
      }

      // in NP you have no tokens
      if (state == State:NP) {
        assert(cache_entry.Tokens == 0);
      }

      // You have at least one token in S-like states
      if (state == State:S || state == State:SM) {
        assert(cache_entry.Tokens > 0);
      }

      // You have at least half the token in O-like states
      if (state == State:O && state == State:OM) {
        assert(cache_entry.Tokens > (max_tokens() / 2));
      }

      cache_entry.CacheState := state;
    }
  }

  AccessPermission getAccessPermission(Address addr) {
    TBE tbe := L1_TBEs[addr];
    if(is_valid(tbe)) {
      return L1Cache_State_to_permission(tbe.TBEState);
    }

    Entry cache_entry := getCacheEntry(addr);
    if(is_valid(cache_entry)) {
      return L1Cache_State_to_permission(cache_entry.CacheState);
    }

    return AccessPermission:NotPresent;
  }

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

  Event mandatory_request_type_to_event(RubyRequestType type) {
    if (type == RubyRequestType:LD) {
      return Event:Load;
    } else if (type == RubyRequestType:IFETCH) {
      return Event:Ifetch;
    } else if (type == RubyRequestType:ST) {
      return Event:Store;
    } else if (type == RubyRequestType:ATOMIC) {
      if (no_mig_atomic) {
        return Event:Atomic;
      } else {
        return Event:Store;
      }
    } else {
      error("Invalid RubyRequestType");
    }
  }

  AccessType cache_request_type_to_access_type(RubyRequestType type) {
    if ((type == RubyRequestType:LD) || (type == RubyRequestType:IFETCH)) {
      return AccessType:Read;
    } else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC)) {
      return AccessType:Write;
    } else {
      error("Invalid RubyRequestType");
    }
  }

  // NOTE: direct local hits should not call this function
  bool isExternalHit(Address addr, MachineID sender) {
    if (machineIDToMachineType(sender) == MachineType:L1Cache) {
      return true;
    } else if (machineIDToMachineType(sender) == MachineType:L2Cache) {

      if (sender == mapAddressToRange(addr, MachineType:L2Cache,
                      l2_select_low_bit, l2_select_num_bits, intToID(0))) {
        return false;
      } else {
        return  true;
      }
    }

    return true;
  }

  bool okToIssueStarving(Address addr, MachineID machineID) {
    return persistentTable.okToIssueStarving(addr, machineID);
  }

  void markPersistentEntries(Address addr) {
    persistentTable.markEntries(addr);
  }

  void setExternalResponse(TBE tbe) {
    assert(is_valid(tbe));
    tbe.ExternalResponse := true;
  }

  bool IsAtomic(TBE tbe) {
    assert(is_valid(tbe));
    return tbe.IsAtomic;
  }

  // ** OUT_PORTS **
  out_port(persistentNetwork_out, PersistentMsg, persistentFromL1Cache);
  out_port(requestNetwork_out, RequestMsg, requestFromL1Cache);
  out_port(responseNetwork_out, ResponseMsg, responseFromL1Cache);
  out_port(requestRecycle_out, RequestMsg, requestToL1Cache);

  // ** IN_PORTS **

  // Use Timer
  in_port(useTimerTable_in, Address, useTimerTable, rank=5) {
    if (useTimerTable_in.isReady()) {
      TBE tbe := L1_TBEs[useTimerTable.readyAddress()];

      if (persistentTable.isLocked(useTimerTable.readyAddress()) &&
          (persistentTable.findSmallest(useTimerTable.readyAddress()) != machineID)) {
        if (persistentTable.typeOfSmallest(useTimerTable.readyAddress()) == AccessType:Write) {
          trigger(Event:Use_TimeoutStarverX, useTimerTable.readyAddress(),
                  getCacheEntry(useTimerTable.readyAddress()), tbe);
        } else {
          trigger(Event:Use_TimeoutStarverS, useTimerTable.readyAddress(),
                  getCacheEntry(useTimerTable.readyAddress()), tbe);
        }
      } else {
        if (no_mig_atomic && IsAtomic(tbe)) {
          trigger(Event:Use_TimeoutNoStarvers_NoMig, useTimerTable.readyAddress(),
                  getCacheEntry(useTimerTable.readyAddress()), tbe);
        } else {
          trigger(Event:Use_TimeoutNoStarvers, useTimerTable.readyAddress(),
                  getCacheEntry(useTimerTable.readyAddress()), tbe);
        }
      }
    }
  }

  // Reissue Timer
  in_port(reissueTimerTable_in, Address, reissueTimerTable, rank=4) {
    if (reissueTimerTable_in.isReady()) {
      trigger(Event:Request_Timeout, reissueTimerTable.readyAddress(),
              getCacheEntry(reissueTimerTable.readyAddress()),
              L1_TBEs[reissueTimerTable.readyAddress()]);
    }
  }

  // Persistent Network
  in_port(persistentNetwork_in, PersistentMsg, persistentToL1Cache, rank=3) {
    if (persistentNetwork_in.isReady()) {
      peek(persistentNetwork_in, PersistentMsg, block_on="Addr") {
        assert(in_msg.Destination.isElement(machineID));

        // Apply the lockdown or unlockdown message to the table
        if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) {
          persistentTable.persistentRequestLock(in_msg.Addr, in_msg.Requestor, AccessType:Write);
        } else if (in_msg.Type == PersistentRequestType:GETS_PERSISTENT) {
          persistentTable.persistentRequestLock(in_msg.Addr, in_msg.Requestor, AccessType:Read);
        } else if (in_msg.Type == PersistentRequestType:DEACTIVATE_PERSISTENT) {
          persistentTable.persistentRequestUnlock(in_msg.Addr, in_msg.Requestor);
        } else {
          error("Unexpected message");
        }

        // React to the message based on the current state of the table
        Entry cache_entry := getCacheEntry(in_msg.Addr);
        TBE tbe := L1_TBEs[in_msg.Addr];

        if (persistentTable.isLocked(in_msg.Addr)) {
          if (persistentTable.findSmallest(in_msg.Addr) == machineID) {
            // Our Own Lock - this processor is highest priority
            trigger(Event:Own_Lock_or_Unlock, in_msg.Addr,
                    cache_entry, tbe);
          } else {
            if (persistentTable.typeOfSmallest(in_msg.Addr) == AccessType:Read) {
              if (getTokens(cache_entry) == 1 ||
                  getTokens(cache_entry) == (max_tokens() / 2) + 1) {
                trigger(Event:Persistent_GETS_Last_Token, in_msg.Addr,
                        cache_entry, tbe);
              } else {
                trigger(Event:Persistent_GETS, in_msg.Addr,
                        cache_entry, tbe);
              }
            } else {
              trigger(Event:Persistent_GETX, in_msg.Addr,
                      cache_entry, tbe);
            }
          }
        } else {
          // Unlock case - no entries in the table
          trigger(Event:Own_Lock_or_Unlock, in_msg.Addr,
                  cache_entry, tbe);
        }
      }
    }
  }

  // Response Network
  in_port(responseNetwork_in, ResponseMsg, responseToL1Cache, rank=2) {
    if (responseNetwork_in.isReady()) {
      peek(responseNetwork_in, ResponseMsg, block_on="Addr") {
        assert(in_msg.Destination.isElement(machineID));

        Entry cache_entry := getCacheEntry(in_msg.Addr);
        TBE tbe := L1_TBEs[in_msg.Addr];

        // Mark TBE flag if response received off-chip.  Use this to update average latency estimate
        if ( machineIDToMachineType(in_msg.Sender) == MachineType:L2Cache ) {

          if (in_msg.Sender == mapAddressToRange(in_msg.Addr,
                                 MachineType:L2Cache, l2_select_low_bit,
                                 l2_select_num_bits, intToID(0))) {

            // came from an off-chip L2 cache
            if (is_valid(tbe)) {
               // L1_TBEs[in_msg.Addr].ExternalResponse := true;
               // profile_offchipL2_response(in_msg.Addr);
            }
          }
          else {
               // profile_onchipL2_response(in_msg.Addr );
          }
        } else if ( machineIDToMachineType(in_msg.Sender) == MachineType:Directory ) {
          if (is_valid(tbe)) {
            setExternalResponse(tbe);
            // profile_memory_response( in_msg.Addr);
          }
        } else if ( machineIDToMachineType(in_msg.Sender) == MachineType:L1Cache) {
          //if (isLocalProcessor(machineID, in_msg.Sender) == false) {
            //if (is_valid(tbe)) {
               // tbe.ExternalResponse := true;
               // profile_offchipL1_response(in_msg.Addr );
            //}
          //}
          //else {
               // profile_onchipL1_response(in_msg.Addr );
          //}
        } else {
          error("unexpected SenderMachine");
        }


        if (getTokens(cache_entry) + in_msg.Tokens != max_tokens()) {
          if (in_msg.Type == CoherenceResponseType:ACK) {
            assert(in_msg.Tokens < (max_tokens() / 2));
            trigger(Event:Ack, in_msg.Addr, cache_entry, tbe);
          } else if (in_msg.Type == CoherenceResponseType:DATA_OWNER) {
            trigger(Event:Data_Owner, in_msg.Addr, cache_entry, tbe);
          } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) {
            assert(in_msg.Tokens < (max_tokens() / 2));
            trigger(Event:Data_Shared, in_msg.Addr, cache_entry, tbe);
          } else {
            error("Unexpected message");
          }
        } else {
          if (in_msg.Type == CoherenceResponseType:ACK) {
            assert(in_msg.Tokens < (max_tokens() / 2));
            trigger(Event:Ack_All_Tokens, in_msg.Addr, cache_entry, tbe);
          } else if (in_msg.Type == CoherenceResponseType:DATA_OWNER || in_msg.Type == CoherenceResponseType:DATA_SHARED) {
            trigger(Event:Data_All_Tokens, in_msg.Addr, cache_entry, tbe);
          } else {
            error("Unexpected message");
          }
        }
      }
    }
  }

  // Request Network
  in_port(requestNetwork_in, RequestMsg, requestToL1Cache) {
    if (requestNetwork_in.isReady()) {
      peek(requestNetwork_in, RequestMsg, block_on="Addr") {
        assert(in_msg.Destination.isElement(machineID));

        Entry cache_entry := getCacheEntry(in_msg.Addr);
        TBE tbe := L1_TBEs[in_msg.Addr];

        if (in_msg.Type == CoherenceRequestType:GETX) {
          if (in_msg.isLocal) {
            trigger(Event:Transient_Local_GETX, in_msg.Addr,
                    cache_entry, tbe);
          }
          else {
            trigger(Event:Transient_GETX, in_msg.Addr,
                    cache_entry, tbe);
          }
        } else if (in_msg.Type == CoherenceRequestType:GETS) {
          if (getTokens(cache_entry) == 1 ||
              getTokens(cache_entry) == (max_tokens() / 2) + 1) {
            if (in_msg.isLocal) {
              trigger(Event:Transient_Local_GETS_Last_Token, in_msg.Addr,
                      cache_entry, tbe);
            }
            else {
              trigger(Event:Transient_GETS_Last_Token, in_msg.Addr,
                      cache_entry, tbe);
            }
          }
          else {
            if (in_msg.isLocal) {
              trigger(Event:Transient_Local_GETS, in_msg.Addr,
                      cache_entry, tbe);
            }
            else {
              trigger(Event:Transient_GETS, in_msg.Addr,
                      cache_entry, tbe);
            }
          }
        } else {
          error("Unexpected message");
        }
      }
    }
  }

  // Mandatory Queue
  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...", rank=0) {
    if (mandatoryQueue_in.isReady()) {
      peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
        // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache

        TBE tbe := L1_TBEs[in_msg.LineAddress];

        if (in_msg.Type == RubyRequestType:IFETCH) {
          // ** INSTRUCTION ACCESS ***

          Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
          if (is_valid(L1Icache_entry)) {
            // The tag matches for the L1, so the L1 fetches the line.
            // We know it can't be in the L2 due to exclusion.
            trigger(mandatory_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress, L1Icache_entry, tbe);
          } else {

            // Check to see if it is in the OTHER L1
            Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
            if (is_valid(L1Dcache_entry)) {
              // The block is in the wrong L1, try to write it to the L2
                trigger(Event:L1_Replacement, in_msg.LineAddress,
                        L1Dcache_entry, tbe);
            }

            if (L1Icache.cacheAvail(in_msg.LineAddress)) {
              // L1 does't have the line, but we have space for it in the L1
              trigger(mandatory_request_type_to_event(in_msg.Type),
                      in_msg.LineAddress, L1Icache_entry, tbe);
            } else {
              // No room in the L1, so we need to make room
              trigger(Event:L1_Replacement,
                      L1Icache.cacheProbe(in_msg.LineAddress),
                      getL1ICacheEntry(L1Icache.cacheProbe(in_msg.LineAddress)),
                      L1_TBEs[L1Icache.cacheProbe(in_msg.LineAddress)]);
            }
          }
        } else {
          // *** DATA ACCESS ***

          Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
          if (is_valid(L1Dcache_entry)) {
            // The tag matches for the L1, so the L1 fetches the line.
            // We know it can't be in the L2 due to exclusion.
            trigger(mandatory_request_type_to_event(in_msg.Type),
                    in_msg.LineAddress, L1Dcache_entry, tbe);
          } else {

            // Check to see if it is in the OTHER L1
            Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
            if (is_valid(L1Icache_entry)) {
              // The block is in the wrong L1, try to write it to the L2
              trigger(Event:L1_Replacement, in_msg.LineAddress,
                      L1Icache_entry, tbe);
            }

            if (L1Dcache.cacheAvail(in_msg.LineAddress)) {
              // L1 does't have the line, but we have space for it in the L1
              trigger(mandatory_request_type_to_event(in_msg.Type),
                      in_msg.LineAddress, L1Dcache_entry, tbe);
            } else {
              // No room in the L1, so we need to make room
              trigger(Event:L1_Replacement,
                      L1Dcache.cacheProbe(in_msg.LineAddress),
                      getL1DCacheEntry(L1Dcache.cacheProbe(in_msg.LineAddress)),
                      L1_TBEs[L1Dcache.cacheProbe(in_msg.LineAddress)]);
            }
          }
        }
      }
    }
  }

  // ACTIONS

  action(a_issueReadRequest, "a", desc="Issue GETS") {
      assert(is_valid(tbe));
      if (tbe.IssueCount == 0) {
        // Update outstanding requests
        //profile_outstanding_request(outstandingRequests);
        outstandingRequests := outstandingRequests + 1;
      }

      if (tbe.IssueCount >= retry_threshold) {
        // Issue a persistent request if possible
        if (okToIssueStarving(address, machineID) && (starving == false)) {
          enqueue(persistentNetwork_out, PersistentMsg, l1_request_latency) {
            out_msg.Addr := address;
            out_msg.Type := PersistentRequestType:GETS_PERSISTENT;
            out_msg.Requestor := machineID;
            out_msg.Destination.broadcast(MachineType:L1Cache);

            //
            // Currently the configuration system limits the system to only one
            // chip.  Therefore, if we assume one shared L2 cache, then only one
            // pertinent L2 cache exist.
            //
            //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));

            out_msg.Destination.add(mapAddressToRange(address,
                                      MachineType:L2Cache, l2_select_low_bit,
                                      l2_select_num_bits, intToID(0)));

            out_msg.Destination.add(map_Address_to_Directory(address));
            out_msg.MessageSize := MessageSizeType:Persistent_Control;
            out_msg.Prefetch := tbe.Prefetch;
            out_msg.AccessMode := tbe.AccessMode;
          }
          markPersistentEntries(address);
          starving := true;

          if (tbe.IssueCount == 0) {
            //profile_persistent_prediction(address, tbe.TypeOfAccess);
          }

          // Update outstanding requests
          //profile_outstanding_persistent_request(outstandingPersistentRequests);
          outstandingPersistentRequests := outstandingPersistentRequests + 1;

          // Increment IssueCount
          tbe.IssueCount := tbe.IssueCount + 1;

          tbe.WentPersistent := true;

          // Do not schedule a wakeup, a persistent requests will always complete
        }
        else {

          // We'd like to issue a persistent request, but are not allowed
          // to issue a P.R. right now.  This, we do not increment the
          // IssueCount.

          // Set a wakeup timer
          reissueTimerTable.set(address, reissue_wakeup_latency);

        }
      } else {
        // Make a normal request
        enqueue(requestNetwork_out, RequestMsg, l1_request_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceRequestType:GETS;
          out_msg.Requestor := machineID;
          out_msg.Destination.add(mapAddressToRange(address,
                                    MachineType:L2Cache, l2_select_low_bit,
                                    l2_select_num_bits, intToID(0)));

          out_msg.RetryNum := tbe.IssueCount;
          if (tbe.IssueCount == 0) {
            out_msg.MessageSize := MessageSizeType:Request_Control;
          } else {
            out_msg.MessageSize := MessageSizeType:Reissue_Control;
          }
          out_msg.Prefetch := tbe.Prefetch;
          out_msg.AccessMode := tbe.AccessMode;
        }

        // send to other local L1s, with local bit set
        enqueue(requestNetwork_out, RequestMsg, l1_request_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceRequestType:GETS;
          out_msg.Requestor := machineID;
          //
          // Since only one chip, assuming all L1 caches are local
          //
          //out_msg.Destination := getOtherLocalL1IDs(machineID);
          out_msg.Destination.broadcast(MachineType:L1Cache);
          out_msg.Destination.remove(machineID);

          out_msg.RetryNum := tbe.IssueCount;
          out_msg.isLocal := true;
          if (tbe.IssueCount == 0) {
            out_msg.MessageSize := MessageSizeType:Broadcast_Control;
          } else {
            out_msg.MessageSize := MessageSizeType:Broadcast_Control;
          }
          out_msg.Prefetch := tbe.Prefetch;
          out_msg.AccessMode := tbe.AccessMode;
        }

        // Increment IssueCount
        tbe.IssueCount := tbe.IssueCount + 1;

        // Set a wakeup timer

        if (dynamic_timeout_enabled) {
          reissueTimerTable.set(address, (5 * averageLatencyEstimate()) / 4);
        } else {
          reissueTimerTable.set(address, fixed_timeout_latency);
        }

      }
  }

  action(b_issueWriteRequest, "b", desc="Issue GETX") {

      assert(is_valid(tbe));
      if (tbe.IssueCount == 0) {
        // Update outstanding requests
        //profile_outstanding_request(outstandingRequests);
        outstandingRequests := outstandingRequests + 1;
      }

      if (tbe.IssueCount >= retry_threshold) {
        // Issue a persistent request if possible
        if ( okToIssueStarving(address, machineID) && (starving == false)) {
          enqueue(persistentNetwork_out, PersistentMsg, l1_request_latency) {
            out_msg.Addr := address;
            out_msg.Type := PersistentRequestType:GETX_PERSISTENT;
            out_msg.Requestor := machineID;
            out_msg.Destination.broadcast(MachineType:L1Cache);

            //
            // Currently the configuration system limits the system to only one
            // chip.  Therefore, if we assume one shared L2 cache, then only one
            // pertinent L2 cache exist.
            //
            //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));

            out_msg.Destination.add(mapAddressToRange(address,
                                      MachineType:L2Cache, l2_select_low_bit,
                                      l2_select_num_bits, intToID(0)));

            out_msg.Destination.add(map_Address_to_Directory(address));
            out_msg.MessageSize := MessageSizeType:Persistent_Control;
            out_msg.Prefetch := tbe.Prefetch;
            out_msg.AccessMode := tbe.AccessMode;
          }
          markPersistentEntries(address);
          starving := true;

          // Update outstanding requests
          //profile_outstanding_persistent_request(outstandingPersistentRequests);
          outstandingPersistentRequests := outstandingPersistentRequests + 1;

          if (tbe.IssueCount == 0) {
            //profile_persistent_prediction(address, tbe.TypeOfAccess);
          }

          // Increment IssueCount
          tbe.IssueCount := tbe.IssueCount + 1;

          tbe.WentPersistent := true;

          // Do not schedule a wakeup, a persistent requests will always complete
        }
        else {

          // We'd like to issue a persistent request, but are not allowed
          // to issue a P.R. right now.  This, we do not increment the
          // IssueCount.

          // Set a wakeup timer
          reissueTimerTable.set(address, reissue_wakeup_latency);
        }

      } else  {
        // Make a normal request
        enqueue(requestNetwork_out, RequestMsg, l1_request_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceRequestType:GETX;
          out_msg.Requestor := machineID;

          out_msg.Destination.add(mapAddressToRange(address,
                                    MachineType:L2Cache, l2_select_low_bit,
                                    l2_select_num_bits, intToID(0)));

          out_msg.RetryNum := tbe.IssueCount;

          if (tbe.IssueCount == 0) {
            out_msg.MessageSize := MessageSizeType:Request_Control;
          } else {
            out_msg.MessageSize := MessageSizeType:Reissue_Control;
          }
          out_msg.Prefetch := tbe.Prefetch;
          out_msg.AccessMode := tbe.AccessMode;
        }

        // send to other local L1s too
        enqueue(requestNetwork_out, RequestMsg, l1_request_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceRequestType:GETX;
          out_msg.Requestor := machineID;
          out_msg.isLocal := true;

          //
          // Since only one chip, assuming all L1 caches are local
          //
          //out_msg.Destination := getOtherLocalL1IDs(machineID);
          out_msg.Destination.broadcast(MachineType:L1Cache);
          out_msg.Destination.remove(machineID);

          out_msg.RetryNum := tbe.IssueCount;
          if (tbe.IssueCount == 0) {
            out_msg.MessageSize := MessageSizeType:Broadcast_Control;
          } else {
            out_msg.MessageSize := MessageSizeType:Broadcast_Control;
          }
          out_msg.Prefetch := tbe.Prefetch;
          out_msg.AccessMode := tbe.AccessMode;
        }

        // Increment IssueCount
        tbe.IssueCount := tbe.IssueCount + 1;

        DPRINTF(RubySlicc, "incremented issue count to %d\n",
                tbe.IssueCount);

        // Set a wakeup timer
        if (dynamic_timeout_enabled) {
          reissueTimerTable.set(address, (5 * averageLatencyEstimate()) / 4);
        } else {
          reissueTimerTable.set(address, fixed_timeout_latency);
        }
      }
  }

  action(bb_bounceResponse, "\b", desc="Bounce tokens and data to memory") {
    peek(responseNetwork_in, ResponseMsg) {
      // FIXME, should use a 3rd vnet
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := in_msg.Type;
        out_msg.Sender := machineID;
        out_msg.Destination.add(map_Address_to_Directory(address));
        out_msg.Tokens := in_msg.Tokens;
        out_msg.MessageSize := in_msg.MessageSize;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Dirty := in_msg.Dirty;
      }
    }
  }

  action(c_ownedReplacement, "c", desc="Issue writeback") {
    assert(is_valid(cache_entry));
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
      out_msg.Addr := address;
      out_msg.Sender := machineID;

      out_msg.Destination.add(mapAddressToRange(address,
                                MachineType:L2Cache, l2_select_low_bit,
                                l2_select_num_bits, intToID(0)));

      out_msg.Tokens := cache_entry.Tokens;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.Dirty := cache_entry.Dirty;
      out_msg.Type := CoherenceResponseType:WB_OWNED;

      // always send the data?
      out_msg.MessageSize := MessageSizeType:Writeback_Data;
    }
    cache_entry.Tokens := 0;
  }

  action(cc_sharedReplacement, "\c", desc="Issue shared writeback") {

    // don't send writeback if replacing block with no tokens
    assert(is_valid(cache_entry));
    assert (cache_entry.Tokens > 0);
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Sender := machineID;

        out_msg.Destination.add(mapAddressToRange(address,
                                  MachineType:L2Cache, l2_select_low_bit,
                                  l2_select_num_bits, intToID(0)));

        out_msg.Tokens := cache_entry.Tokens;
        out_msg.DataBlk := cache_entry.DataBlk;
        // assert(cache_entry.Dirty == false);
        out_msg.Dirty := false;

        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.Type := CoherenceResponseType:WB_SHARED_DATA;
    }
    cache_entry.Tokens := 0;
  }

  action(tr_tokenReplacement, "tr", desc="Issue token writeback") {
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Sender := machineID;

        out_msg.Destination.add(mapAddressToRange(address,
                                  MachineType:L2Cache, l2_select_low_bit,
                                  l2_select_num_bits, intToID(0)));

        out_msg.Tokens := cache_entry.Tokens;
        out_msg.DataBlk := cache_entry.DataBlk;
        // assert(cache_entry.Dirty == false);
        out_msg.Dirty := false;

        // always send the data?
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
        out_msg.Type := CoherenceResponseType:WB_TOKENS;
      }
    }
    cache_entry.Tokens := 0;
  }


  action(d_sendDataWithToken, "d", desc="Send data and a token from cache to requestor") {
    assert(is_valid(cache_entry));
    peek(requestNetwork_in, RequestMsg) {
      enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_SHARED;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.Tokens := 1;
        out_msg.DataBlk := cache_entry.DataBlk;
        // out_msg.Dirty := cache_entry.Dirty;
        out_msg.Dirty := false;
        if (in_msg.isLocal) {
          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
        } else {
          out_msg.MessageSize := MessageSizeType:Response_Data;
        }
      }
    }
    cache_entry.Tokens := cache_entry.Tokens - 1;
    assert(cache_entry.Tokens >= 1);
  }

  action(d_sendDataWithNTokenIfAvail, "\dd", desc="Send data and a token from cache to requestor") {
    assert(is_valid(cache_entry));
    peek(requestNetwork_in, RequestMsg) {
      if (cache_entry.Tokens > (N_tokens + (max_tokens() / 2))) {
        enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceResponseType:DATA_SHARED;
          out_msg.Sender := machineID;
          out_msg.Destination.add(in_msg.Requestor);
          out_msg.Tokens := N_tokens;
          out_msg.DataBlk := cache_entry.DataBlk;
          // out_msg.Dirty := cache_entry.Dirty;
          out_msg.Dirty := false;
          if (in_msg.isLocal) {
            out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
          } else {
            out_msg.MessageSize := MessageSizeType:Response_Data;
          }
        }
        cache_entry.Tokens := cache_entry.Tokens - N_tokens;
      }
      else if (cache_entry.Tokens > 1) {
        enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceResponseType:DATA_SHARED;
          out_msg.Sender := machineID;
          out_msg.Destination.add(in_msg.Requestor);
          out_msg.Tokens := 1;
          out_msg.DataBlk := cache_entry.DataBlk;
          // out_msg.Dirty := cache_entry.Dirty;
          out_msg.Dirty := false;
          if (in_msg.isLocal) {
            out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
          } else {
            out_msg.MessageSize := MessageSizeType:Response_Data;
          }
        }
        cache_entry.Tokens := cache_entry.Tokens - 1;
      }
    }
//    assert(cache_entry.Tokens >= 1);
  }

  action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") {
    peek(requestNetwork_in, RequestMsg) {
    assert(is_valid(cache_entry));
      enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.Requestor);
        assert(cache_entry.Tokens > (max_tokens() / 2));
        out_msg.Tokens := cache_entry.Tokens;
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        if (in_msg.isLocal) {
          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
        } else {
          out_msg.MessageSize := MessageSizeType:Response_Data;
        }
      }
    }
    cache_entry.Tokens := 0;
  }

  action(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") {
    // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        if (cache_entry.Tokens > (max_tokens() / 2)) {
          out_msg.Type := CoherenceResponseType:DATA_OWNER;
        } else {
          out_msg.Type := CoherenceResponseType:ACK;
        }
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        assert(cache_entry.Tokens >= 1);
        out_msg.Tokens := cache_entry.Tokens;
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.MessageSize := MessageSizeType:Response_Control;
      }
    }
    cache_entry.Tokens := 0;
  }

  action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") {
    //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
    assert(is_valid(cache_entry));
    assert(cache_entry.Tokens > 0);
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
      out_msg.Addr := address;
      out_msg.Type := CoherenceResponseType:DATA_OWNER;
      out_msg.Sender := machineID;
      out_msg.Destination.add(persistentTable.findSmallest(address));
      assert(cache_entry.Tokens > (max_tokens() / 2));
      out_msg.Tokens := cache_entry.Tokens;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.Dirty := cache_entry.Dirty;
      out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    cache_entry.Tokens := 0;
  }

  action(f_sendAckWithAllButNorOneTokens, "f", desc="Send ack with all our tokens but one to starver.") {
    //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
    assert(is_valid(cache_entry));
    assert(cache_entry.Tokens > 0);
    if (cache_entry.Tokens > 1) {
      enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        if (cache_entry.Tokens > (max_tokens() / 2)) {
          out_msg.Type := CoherenceResponseType:DATA_OWNER;
        } else {
          out_msg.Type := CoherenceResponseType:ACK;
        }
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        assert(cache_entry.Tokens >= 1);
        if (cache_entry.Tokens > N_tokens) {
          out_msg.Tokens := cache_entry.Tokens - N_tokens;
        } else {
          out_msg.Tokens := cache_entry.Tokens - 1;
        }
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.MessageSize := MessageSizeType:Response_Control;
      }
    }
    if (cache_entry.Tokens > N_tokens) {
      cache_entry.Tokens := N_tokens;
    } else {
      cache_entry.Tokens := 1;
    }
  }

  action(ff_sendDataWithAllButNorOneTokens, "\f", desc="Send data and out tokens but one to starver") {
    //assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
    assert(is_valid(cache_entry));
    assert(cache_entry.Tokens > ((max_tokens() / 2) + 1));
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        if (cache_entry.Tokens > (N_tokens + (max_tokens() / 2))) {
          out_msg.Tokens := cache_entry.Tokens - N_tokens;
        } else {
          out_msg.Tokens := cache_entry.Tokens - 1;
        }
        assert(out_msg.Tokens > (max_tokens() / 2));
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    if (cache_entry.Tokens > (N_tokens + (max_tokens() / 2))) {
      cache_entry.Tokens := N_tokens;
    } else {
      cache_entry.Tokens := 1;
    }
  }

  action(fo_sendDataWithOwnerToken, "fo", desc="Send data and owner tokens") {
    assert(is_valid(cache_entry));
    assert(cache_entry.Tokens == ((max_tokens() / 2) + 1));
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        out_msg.Tokens := cache_entry.Tokens;
        assert(out_msg.Tokens > (max_tokens() / 2));
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    cache_entry.Tokens := 0;
  }

  action(g_bounceResponseToStarver, "g", desc="Redirect response to starving processor") {
    // assert(persistentTable.isLocked(address));

    peek(responseNetwork_in, ResponseMsg) {
      // assert(persistentTable.findSmallest(address) != id); // Make sure we never bounce tokens to ourself
      // FIXME, should use a 3rd vnet in some cases
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := in_msg.Type;
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        out_msg.Tokens := in_msg.Tokens;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Dirty := in_msg.Dirty;
        out_msg.MessageSize := in_msg.MessageSize;
      }
    }
  }


  action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
            address, cache_entry.DataBlk);

    sequencer.readCallback(address, cache_entry.DataBlk, false,
                           MachineType:L1Cache);
  }

  action(x_external_load_hit, "x", desc="Notify sequencer the load completed.") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
            address, cache_entry.DataBlk);
    peek(responseNetwork_in, ResponseMsg) {
      sequencer.readCallback(address, cache_entry.DataBlk,
                             isExternalHit(address, in_msg.Sender),
                             machineIDToMachineType(in_msg.Sender));
    }
  }

  action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
            address, cache_entry.DataBlk);

    sequencer.writeCallback(address, cache_entry.DataBlk, false,
                            MachineType:L1Cache);
    cache_entry.Dirty := true;
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
  }

  action(xx_external_store_hit, "\x", desc="Notify sequencer that store completed.") {
    assert(is_valid(cache_entry));
    DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
            address, cache_entry.DataBlk);
    peek(responseNetwork_in, ResponseMsg) {
      sequencer.writeCallback(address, cache_entry.DataBlk,
                              isExternalHit(address, in_msg.Sender),
                              machineIDToMachineType(in_msg.Sender));
    }
    cache_entry.Dirty := true;
    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
  }

  action(i_allocateTBE, "i", desc="Allocate TBE") {
    check_allocate(L1_TBEs);
    L1_TBEs.allocate(address);
    set_tbe(L1_TBEs[address]);
    tbe.IssueCount := 0;
    peek(mandatoryQueue_in, RubyRequest) {
      tbe.PC := in_msg.ProgramCounter;
      tbe.TypeOfAccess := cache_request_type_to_access_type(in_msg.Type);
      if (in_msg.Type == RubyRequestType:ATOMIC) {
        tbe.IsAtomic := true;
      }
      tbe.Prefetch := in_msg.Prefetch;
      tbe.AccessMode := in_msg.AccessMode;
    }
    tbe.IssueTime := curCycle();
  }

  action(ta_traceStalledAddress, "ta", desc="Trace Stalled Address") {
    peek(mandatoryQueue_in, RubyRequest) {
      APPEND_TRANSITION_COMMENT(in_msg.LineAddress);
    }
  }

  action(j_unsetReissueTimer, "j", desc="Unset reissue timer.") {
    if (reissueTimerTable.isSet(address)) {
      reissueTimerTable.unset(address);
    }
  }

  action(jj_unsetUseTimer, "\j", desc="Unset use timer.") {
    useTimerTable.unset(address);
  }

  action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
    mandatoryQueue_in.dequeue();
  }

  action(l_popPersistentQueue, "l", desc="Pop persistent queue.") {
    persistentNetwork_in.dequeue();
  }

  action(m_popRequestQueue, "m", desc="Pop request queue.") {
    requestNetwork_in.dequeue();
  }

  action(n_popResponseQueue, "n", desc="Pop response queue") {
    responseNetwork_in.dequeue();
  }

  action(o_scheduleUseTimeout, "o", desc="Schedule a use timeout.") {
    useTimerTable.set(address, use_timeout_latency);
  }

  action(p_informL2AboutTokenLoss, "p", desc="Inform L2 about loss of all tokens") {
    enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
       out_msg.Addr := address;
       out_msg.Type := CoherenceResponseType:INV;
       out_msg.Tokens := 0;
       out_msg.Sender := machineID;

       out_msg.Destination.add(mapAddressToRange(address,
                                 MachineType:L2Cache, l2_select_low_bit,
                                 l2_select_num_bits, intToID(0)));
       out_msg.MessageSize := MessageSizeType:Response_Control;
    }
  }

  action(q_updateTokensFromResponse, "q", desc="Update the token count based on the incoming response message") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(is_valid(cache_entry));
      assert(in_msg.Tokens != 0);
      DPRINTF(RubySlicc, "L1 received tokens for address: %s, tokens: %d\n",
              in_msg.Addr, in_msg.Tokens);
      cache_entry.Tokens := cache_entry.Tokens + in_msg.Tokens;
      DPRINTF(RubySlicc, "%d\n", cache_entry.Tokens);

      if (cache_entry.Dirty == false && in_msg.Dirty) {
        cache_entry.Dirty := true;
      }
    }
  }

  action(s_deallocateTBE, "s", desc="Deallocate TBE") {

    assert(is_valid(tbe));
    if (tbe.WentPersistent) {
      // assert(starving);
      outstandingRequests := outstandingRequests - 1;
      enqueue(persistentNetwork_out, PersistentMsg, l1_request_latency) {
        out_msg.Addr := address;
        out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT;
        out_msg.Requestor := machineID;
        out_msg.Destination.broadcast(MachineType:L1Cache);

        //
        // Currently the configuration system limits the system to only one
        // chip.  Therefore, if we assume one shared L2 cache, then only one
        // pertinent L2 cache exist.
        //
        //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));

        out_msg.Destination.add(mapAddressToRange(address,
                                  MachineType:L2Cache, l2_select_low_bit,
                                  l2_select_num_bits, intToID(0)));

        out_msg.Destination.add(map_Address_to_Directory(address));
        out_msg.MessageSize := MessageSizeType:Persistent_Control;
      }
      starving := false;
    }

    // Update average latency
    if (tbe.IssueCount <= 1) {
      if (tbe.ExternalResponse) {
        updateAverageLatencyEstimate(curCycle() - tbe.IssueTime);
      }
    }

    // Profile
    //if (tbe.WentPersistent) {
    //  profile_token_retry(address, tbe.TypeOfAccess, 2);
    //}
    //else {
    //  profile_token_retry(address, tbe.TypeOfAccess, 1);
    //}

    //profile_token_retry(address, tbe.TypeOfAccess, tbe.IssueCount);
    L1_TBEs.deallocate(address);
    unset_tbe();
  }

  action(t_sendAckWithCollectedTokens, "t", desc="Send ack with the tokens we've collected thus far.") {
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      peek(requestNetwork_in, RequestMsg) {
        enqueue(responseNetwork_out, ResponseMsg, l1_response_latency) {
          out_msg.Addr := address;
          if (cache_entry.Tokens > (max_tokens() / 2)) {
            out_msg.Type := CoherenceResponseType:DATA_OWNER;
          } else {
            out_msg.Type := CoherenceResponseType:ACK;
          }
          out_msg.Sender := machineID;
          out_msg.Destination.add(in_msg.Requestor);
          assert(cache_entry.Tokens >= 1);
          out_msg.Tokens := cache_entry.Tokens;
          out_msg.DataBlk := cache_entry.DataBlk;
          out_msg.MessageSize := MessageSizeType:Response_Control;
        }
      }
    }
    cache_entry.Tokens := 0;
  }

  action(u_writeDataToCache, "u", desc="Write data to cache") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(is_valid(cache_entry));
      cache_entry.DataBlk := in_msg.DataBlk;
      if (cache_entry.Dirty == false && in_msg.Dirty) {
        cache_entry.Dirty := in_msg.Dirty;
      }

    }
  }

  action(gg_deallocateL1CacheBlock, "\g", desc="Deallocate cache block.  Sets the cache to invalid, allowing a replacement in parallel with a fetch.") {
    assert(getTokens(cache_entry) == 0);
    if (L1Dcache.isTagPresent(address)) {
      L1Dcache.deallocate(address);
    } else {
      L1Icache.deallocate(address);
    }
    unset_cache_entry();
  }

  action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
    if (is_valid(cache_entry)) {
    } else {
      set_cache_entry(L1Dcache.allocate(address, new Entry));
    }
  }

  action(pp_allocateL1ICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") {
    if (is_valid(cache_entry)) {
    } else {
      set_cache_entry(L1Icache.allocate(address, new Entry));
    }
  }

  action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
    if (send_evictions) {
      DPRINTF(RubySlicc, "Sending invalidation for %s to the CPU\n", address);
      sequencer.evictionCallback(address);
    }
  }

  action(uu_profileInstMiss, "\uim", desc="Profile the demand miss") {
      ++L1Icache.demand_misses;
  }

  action(uu_profileInstHit, "\uih", desc="Profile the demand hit") {
      ++L1Icache.demand_hits;
  }

  action(uu_profileDataMiss, "\udm", desc="Profile the demand miss") {
      ++L1Dcache.demand_misses;
  }

  action(uu_profileDataHit, "\udh", desc="Profile the demand hit") {
      ++L1Dcache.demand_hits;
  }

  action(w_assertIncomingDataAndCacheDataMatch, "w", desc="Assert that the incoming data and the data in the cache match") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(is_valid(cache_entry));
      assert(cache_entry.DataBlk == in_msg.DataBlk);
    }
  }

  action(zz_stallAndWaitMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") {
    peek(mandatoryQueue_in, RubyRequest) {
      APPEND_TRANSITION_COMMENT(in_msg.LineAddress);
    }
    stall_and_wait(mandatoryQueue_in, address);
  }

  action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
    wakeUpBuffers(address);
  }

  action(ka_wakeUpAllDependents, "ka", desc="wake-up all dependents") {
    wakeUpAllBuffers();
  }

  //*****************************************************
  // TRANSITIONS
  //*****************************************************

  // Transitions for Load/Store/L2_Replacement from transient states
  transition({IM, SM, OM, IS, IM_L, IS_L, I_L, S_L, SM_L, M_W, MM_W}, L1_Replacement) {
    ta_traceStalledAddress;
    zz_stallAndWaitMandatoryQueue;
  }

  transition({IM, SM, OM, IS, IM_L, IS_L, SM_L}, {Store, Atomic}) {
    zz_stallAndWaitMandatoryQueue;
  }

  transition({IM, IS, IM_L, IS_L}, {Load, Ifetch}) {
    zz_stallAndWaitMandatoryQueue;
  }

  // Lockdowns
  transition({NP, I, S, O, M, MM, M_W, MM_W, IM, SM, OM, IS}, Own_Lock_or_Unlock) {
    l_popPersistentQueue;
  }

  // Transitions from NP
  transition(NP, Load, IS) {
    ii_allocateL1DCacheBlock;
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(NP, Ifetch, IS) {
    pp_allocateL1ICacheBlock;
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileInstMiss;
    k_popMandatoryQueue;
  }

  transition(NP, {Store, Atomic}, IM) {
    ii_allocateL1DCacheBlock;
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(NP, {Ack, Data_Shared, Data_Owner, Data_All_Tokens}) {
    bb_bounceResponse;
    n_popResponseQueue;
  }

  transition(NP, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}) {
    m_popRequestQueue;
  }

  transition(NP, {Persistent_GETX, Persistent_GETS, Persistent_GETS_Last_Token}, I_L) {
    l_popPersistentQueue;
  }

  // Transitions from Idle
  transition(I, Load, IS) {
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(I, Ifetch, IS) {
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileInstMiss;
    k_popMandatoryQueue;
  }

  transition(I, {Store, Atomic}, IM) {
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(I, L1_Replacement) {
    ta_traceStalledAddress;
    tr_tokenReplacement;
    gg_deallocateL1CacheBlock;
    ka_wakeUpAllDependents;
  }

  transition(I, {Transient_GETX, Transient_Local_GETX}) {
    t_sendAckWithCollectedTokens;
    m_popRequestQueue;
  }

  transition(I, {Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS}) {
    m_popRequestQueue;
  }

  transition(I, {Persistent_GETX, Persistent_GETS, Persistent_GETS_Last_Token}, I_L) {
    e_sendAckWithCollectedTokens;
    l_popPersistentQueue;
  }

  transition(I_L, {Persistent_GETX, Persistent_GETS, Persistent_GETS_Last_Token}) {
    l_popPersistentQueue;
  }

  transition(I, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(I, Data_Shared, S) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(I, Data_Owner, O) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(I, Data_All_Tokens, M) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  // Transitions from Shared
  transition({S, SM, S_L, SM_L}, Load) {
    h_load_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition({S, SM, S_L, SM_L}, Ifetch) {
    h_load_hit;
    uu_profileInstHit;
    k_popMandatoryQueue;
  }

  transition(S, {Store, Atomic}, SM) {
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(S, L1_Replacement, I) {
    ta_traceStalledAddress;
    cc_sharedReplacement; // Only needed in some cases
    forward_eviction_to_cpu;
    gg_deallocateL1CacheBlock;
    ka_wakeUpAllDependents;
  }

  transition(S, {Transient_GETX, Transient_Local_GETX}, I) {
    t_sendAckWithCollectedTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    m_popRequestQueue;
  }

  // only owner responds to non-local requests
  transition(S, Transient_GETS) {
    m_popRequestQueue;
  }

  transition(S, Transient_Local_GETS) {
    d_sendDataWithToken;
    m_popRequestQueue;
  }

  transition(S, {Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token}) {
    m_popRequestQueue;
  }

  transition({S, S_L}, Persistent_GETX, I_L) {
    e_sendAckWithCollectedTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(S, {Persistent_GETS, Persistent_GETS_Last_Token}, S_L) {
    f_sendAckWithAllButNorOneTokens;
    l_popPersistentQueue;
  }

  transition(S_L, {Persistent_GETS, Persistent_GETS_Last_Token}) {
    l_popPersistentQueue;
  }

  transition(S, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(S, Data_Shared) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(S, Data_Owner, O) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(S, Data_All_Tokens, M) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  // Transitions from Owned
  transition({O, OM}, Ifetch) {
    h_load_hit;
    uu_profileInstHit;
    k_popMandatoryQueue;
  }

  transition({O, OM}, Load) {
    h_load_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(O, {Store, Atomic}, OM) {
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(O, L1_Replacement, I) {
    ta_traceStalledAddress;
    c_ownedReplacement;
    forward_eviction_to_cpu
    gg_deallocateL1CacheBlock;
    ka_wakeUpAllDependents;
  }

  transition(O, {Transient_GETX, Transient_Local_GETX}, I) {
    dd_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    m_popRequestQueue;
  }

  transition(O, Persistent_GETX, I_L) {
    ee_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(O, Persistent_GETS, S_L) {
    ff_sendDataWithAllButNorOneTokens;
    l_popPersistentQueue;
  }

  transition(O, Persistent_GETS_Last_Token, I_L) {
    fo_sendDataWithOwnerToken;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(O, Transient_GETS) {
    d_sendDataWithToken;
    m_popRequestQueue;
  }

  transition(O, Transient_Local_GETS) {
    d_sendDataWithToken;
    m_popRequestQueue;
  }

  // ran out of tokens, wait for it to go persistent
  transition(O, {Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token}) {
    m_popRequestQueue;
  }

  transition(O, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(O, Ack_All_Tokens, M) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(O, Data_Shared) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(O, Data_All_Tokens, M) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  // Transitions from Modified
  transition({MM, MM_W}, Ifetch) {
    h_load_hit;
    uu_profileInstHit;
    k_popMandatoryQueue;
  }

  transition({MM, MM_W}, Load) {
    h_load_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition({MM_W}, {Store, Atomic}) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(MM, Store) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(MM, Atomic, M) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(MM, L1_Replacement, I) {
    ta_traceStalledAddress;
    c_ownedReplacement;
    forward_eviction_to_cpu
    gg_deallocateL1CacheBlock;
    ka_wakeUpAllDependents;
  }

  transition(MM, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}, I) {
    dd_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    m_popRequestQueue;
  }

  transition({MM_W}, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}) { // Ignore the request
    m_popRequestQueue;
  }

  // Implement the migratory sharing optimization, even for persistent requests
  transition(MM, {Persistent_GETX, Persistent_GETS}, I_L) {
    ee_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  // ignore persistent requests in lockout period
  transition(MM_W, {Persistent_GETX, Persistent_GETS}) {
    l_popPersistentQueue;
  }

  transition(MM_W, Use_TimeoutNoStarvers, MM) {
    s_deallocateTBE;
    jj_unsetUseTimer;
    kd_wakeUpDependents;
  }

  transition(MM_W, Use_TimeoutNoStarvers_NoMig, M) {
    s_deallocateTBE;
    jj_unsetUseTimer;
    kd_wakeUpDependents;
  }

  // Transitions from Dirty Exclusive
  transition({M, M_W}, Ifetch) {
    h_load_hit;
    uu_profileInstHit;
    k_popMandatoryQueue;
  }

  transition({M, M_W}, Load) {
    h_load_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(M, Store, MM) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(M, Atomic) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(M_W, Store, MM_W) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(M_W, Atomic) {
    hh_store_hit;
    uu_profileDataHit;
    k_popMandatoryQueue;
  }

  transition(M, L1_Replacement, I) {
    ta_traceStalledAddress;
    c_ownedReplacement;
    forward_eviction_to_cpu
    gg_deallocateL1CacheBlock;
    ka_wakeUpAllDependents;
  }

  transition(M, {Transient_GETX, Transient_Local_GETX}, I) {
    dd_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    m_popRequestQueue;
  }

  transition(M, Transient_Local_GETS, O) {
    d_sendDataWithToken;
    m_popRequestQueue;
  }

  transition(M, Transient_GETS, O) {
    d_sendDataWithNTokenIfAvail;
    m_popRequestQueue;
  }

  transition(M_W, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_Local_GETS}) { // Ignore the request
    m_popRequestQueue;
  }

  transition(M, Persistent_GETX, I_L) {
    ee_sendDataWithAllTokens;
    p_informL2AboutTokenLoss;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(M, Persistent_GETS, S_L) {
    ff_sendDataWithAllButNorOneTokens;
    l_popPersistentQueue;
  }

  // ignore persistent requests in lockout period
  transition(M_W, {Persistent_GETX, Persistent_GETS}) {
    l_popPersistentQueue;
  }

  transition(M_W, Use_TimeoutStarverS, S_L) {
    s_deallocateTBE;
    ff_sendDataWithAllButNorOneTokens;
    jj_unsetUseTimer;
  }

  // someone unlocked during timeout
  transition(M_W, {Use_TimeoutNoStarvers, Use_TimeoutNoStarvers_NoMig}, M) {
    s_deallocateTBE;
    jj_unsetUseTimer;
    kd_wakeUpDependents;
  }

  transition(M_W, Use_TimeoutStarverX, I_L) {
    s_deallocateTBE;
    ee_sendDataWithAllTokens;
    forward_eviction_to_cpu;
    p_informL2AboutTokenLoss;
    jj_unsetUseTimer;
  }

  // migratory
  transition(MM_W, {Use_TimeoutStarverX, Use_TimeoutStarverS}, I_L) {
    s_deallocateTBE;
    ee_sendDataWithAllTokens;
    forward_eviction_to_cpu;
    p_informL2AboutTokenLoss;
    jj_unsetUseTimer;

  }

  // Transient_GETX and Transient_GETS in transient states
  transition(OM, {Transient_GETX, Transient_Local_GETX, Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS}) {
    m_popRequestQueue;  // Even if we have the data, we can pretend we don't have it yet.
  }

  transition(IS, {Transient_GETX, Transient_Local_GETX}) {
    t_sendAckWithCollectedTokens;
    m_popRequestQueue;
  }

  transition(IS, {Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS}) {
    m_popRequestQueue;
  }

  transition(IS, {Persistent_GETX, Persistent_GETS, Persistent_GETS_Last_Token}, IS_L) {
    e_sendAckWithCollectedTokens;
    l_popPersistentQueue;
  }

  transition(IS_L, {Persistent_GETX, Persistent_GETS}) {
    l_popPersistentQueue;
  }

  transition(IM, {Persistent_GETX, Persistent_GETS, Persistent_GETS_Last_Token}, IM_L) {
    e_sendAckWithCollectedTokens;
    l_popPersistentQueue;
  }

  transition(IM_L, {Persistent_GETX, Persistent_GETS}) {
    l_popPersistentQueue;
  }

  transition({SM, SM_L}, Persistent_GETX, IM_L) {
    e_sendAckWithCollectedTokens;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(SM, {Persistent_GETS, Persistent_GETS_Last_Token}, SM_L) {
    f_sendAckWithAllButNorOneTokens;
    l_popPersistentQueue;
  }

  transition(SM_L, {Persistent_GETS, Persistent_GETS_Last_Token}) {
    l_popPersistentQueue;
  }

  transition(OM, Persistent_GETX, IM_L) {
    ee_sendDataWithAllTokens;
    forward_eviction_to_cpu
    l_popPersistentQueue;
  }

  transition(OM, Persistent_GETS, SM_L) {
    ff_sendDataWithAllButNorOneTokens;
    l_popPersistentQueue;
  }

  transition(OM, Persistent_GETS_Last_Token, IM_L) {
    fo_sendDataWithOwnerToken;
    l_popPersistentQueue;
  }

  // Transitions from IM/SM

  transition({IM, SM}, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(IM, Data_Shared, SM) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(IM, Data_Owner, OM) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(IM, Data_All_Tokens, MM_W) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    xx_external_store_hit;
    o_scheduleUseTimeout;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(SM, Data_Shared) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(SM, Data_Owner, OM) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(SM, Data_All_Tokens, MM_W) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    xx_external_store_hit;
    o_scheduleUseTimeout;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition({IM, SM}, {Transient_GETX, Transient_Local_GETX}, IM) { // We don't have the data yet, but we might have collected some tokens.  We give them up here to avoid livelock
    t_sendAckWithCollectedTokens;
    forward_eviction_to_cpu;
    m_popRequestQueue;
  }

  transition({IM, SM}, {Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS}) {
    m_popRequestQueue;
  }

  transition({IM, SM}, Request_Timeout) {
    j_unsetReissueTimer;
    b_issueWriteRequest;
  }

  // Transitions from OM

  transition(OM, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(OM, Ack_All_Tokens, MM_W) {
    q_updateTokensFromResponse;
    xx_external_store_hit;
    o_scheduleUseTimeout;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(OM, Data_Shared) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(OM, Data_All_Tokens, MM_W) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    xx_external_store_hit;
    o_scheduleUseTimeout;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(OM, Request_Timeout) {
    j_unsetReissueTimer;
    b_issueWriteRequest;
  }

  // Transitions from IS

  transition(IS, Ack) {
    q_updateTokensFromResponse;
    n_popResponseQueue;
  }

  transition(IS, Data_Shared, S) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    s_deallocateTBE;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(IS, Data_Owner, O) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    s_deallocateTBE;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(IS, Data_All_Tokens, M_W) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    o_scheduleUseTimeout;
    j_unsetReissueTimer;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(IS, Request_Timeout) {
    j_unsetReissueTimer;
    a_issueReadRequest;
  }

  // Transitions from I_L

  transition(I_L, Load, IS_L) {
    ii_allocateL1DCacheBlock;
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  transition(I_L, Ifetch, IS_L) {
    pp_allocateL1ICacheBlock;
    i_allocateTBE;
    a_issueReadRequest;
    uu_profileInstMiss;
    k_popMandatoryQueue;
  }

  transition(I_L, {Store, Atomic}, IM_L) {
    ii_allocateL1DCacheBlock;
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }


  // Transitions from S_L

  transition(S_L, {Store, Atomic}, SM_L) {
    i_allocateTBE;
    b_issueWriteRequest;
    uu_profileDataMiss;
    k_popMandatoryQueue;
  }

  // Other transitions from *_L states

  transition({I_L, IM_L, IS_L, S_L, SM_L}, {Transient_GETS, Transient_GETS_Last_Token, Transient_Local_GETS_Last_Token, Transient_Local_GETS, Transient_GETX, Transient_Local_GETX}) {
    m_popRequestQueue;
  }

  transition({I_L, IM_L, IS_L, S_L, SM_L}, Ack) {
    g_bounceResponseToStarver;
    n_popResponseQueue;
  }

  transition({I_L, IM_L, S_L, SM_L}, {Data_Shared, Data_Owner}) {
    g_bounceResponseToStarver;
    n_popResponseQueue;
  }

  transition({I_L, S_L}, Data_All_Tokens) {
    g_bounceResponseToStarver;
    n_popResponseQueue;
  }

  transition(IS_L, Request_Timeout) {
    j_unsetReissueTimer;
    a_issueReadRequest;
  }

  transition({IM_L, SM_L}, Request_Timeout) {
    j_unsetReissueTimer;
    b_issueWriteRequest;
  }

  // Opportunisticly Complete the memory operation in the following
  // cases.  Note: these transitions could just use
  // g_bounceResponseToStarver, but if we have the data and tokens, we
  // might as well complete the memory request while we have the
  // chance (and then immediately forward on the data)

  transition(IM_L, Data_All_Tokens, MM_W) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    xx_external_store_hit;
    j_unsetReissueTimer;
    o_scheduleUseTimeout;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  transition(SM_L, Data_All_Tokens, S_L) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    xx_external_store_hit;
    ff_sendDataWithAllButNorOneTokens;
    s_deallocateTBE;
    j_unsetReissueTimer;
    n_popResponseQueue;
  }

  transition(IS_L, Data_Shared, I_L) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    s_deallocateTBE;
    e_sendAckWithCollectedTokens;
    p_informL2AboutTokenLoss;
    j_unsetReissueTimer;
    n_popResponseQueue;
  }

  transition(IS_L, Data_Owner, I_L) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    ee_sendDataWithAllTokens;
    s_deallocateTBE;
    p_informL2AboutTokenLoss;
    j_unsetReissueTimer;
    n_popResponseQueue;
  }

  transition(IS_L, Data_All_Tokens, M_W) {
    u_writeDataToCache;
    q_updateTokensFromResponse;
    x_external_load_hit;
    j_unsetReissueTimer;
    o_scheduleUseTimeout;
    n_popResponseQueue;
    kd_wakeUpDependents;
  }

  // Own_Lock_or_Unlock

  transition(I_L, Own_Lock_or_Unlock, I) {
    l_popPersistentQueue;
    kd_wakeUpDependents;
  }

  transition(S_L, Own_Lock_or_Unlock, S) {
    l_popPersistentQueue;
    kd_wakeUpDependents;
  }

  transition(IM_L, Own_Lock_or_Unlock, IM) {
    l_popPersistentQueue;
    kd_wakeUpDependents;
  }

  transition(IS_L, Own_Lock_or_Unlock, IS) {
    l_popPersistentQueue;
    kd_wakeUpDependents;
  }

  transition(SM_L, Own_Lock_or_Unlock, SM) {
    l_popPersistentQueue;
    kd_wakeUpDependents;
  }
}
