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

machine(L2Cache, "Token protocol")
 : CacheMemory * L2cache,
   int N_tokens,
   Cycles l2_request_latency = 5,
   Cycles l2_response_latency = 5,
   bool filtering_enabled = true
{

  // L2 BANK QUEUES
  // From local bank of L2 cache TO the network

  // this L2 bank -> a local L1 || mod-directory
  MessageBuffer responseFromL2Cache, network="To", virtual_network="4", ordered="false", vnet_type="response";
  // this L2 bank -> mod-directory
  MessageBuffer GlobalRequestFromL2Cache, network="To", virtual_network="2", ordered="false", vnet_type="request";
  // this L2 bank -> a local L1
  MessageBuffer L1RequestFromL2Cache, network="To", virtual_network="1", ordered="false", vnet_type="request";


  // FROM the network to this local bank of L2 cache

  // a local L1 || mod-directory -> this L2 bank
  MessageBuffer responseToL2Cache, network="From", virtual_network="4", ordered="false", vnet_type="response";
  MessageBuffer persistentToL2Cache, network="From", virtual_network="3", ordered="true", vnet_type="persistent";
  // mod-directory -> this L2 bank
  MessageBuffer GlobalRequestToL2Cache, network="From", virtual_network="2", ordered="false", vnet_type="request";
  // a local L1 -> this L2 bank
  MessageBuffer L1RequestToL2Cache, network="From", virtual_network="1", ordered="false", vnet_type="request";

  // STATES
  state_declaration(State, desc="L2 Cache states", default="L2Cache_State_I") {
    // Base states
    NP, AccessPermission:Invalid, desc="Not Present";
    I, AccessPermission:Invalid, desc="Idle";
    S, AccessPermission:Read_Only, desc="Shared, not present in any local L1s";
    O, AccessPermission:Read_Only, desc="Owned, not present in any L1s";
    M, AccessPermission:Read_Write, desc="Modified, not present in any L1s";

    // Locked states
    I_L, AccessPermission:Busy, "I^L", desc="Invalid, Locked";
    S_L, AccessPermission:Busy, "S^L", desc="Shared, Locked";
  }

  // EVENTS
  enumeration(Event, desc="Cache events") {

    // Requests
    L1_GETS,             desc="local L1 GETS request";
    L1_GETS_Last_Token,    desc="local L1 GETS request";
    L1_GETX,             desc="local L1 GETX request";
    L1_INV,              desc="L1 no longer has tokens";
    Transient_GETX,      desc="A GetX from another processor";
    Transient_GETS,      desc="A GetS from another processor";
    Transient_GETS_Last_Token,   desc="A GetS from another processor";

    // events initiated by this L2
    L2_Replacement,     desc="L2 Replacement", format="!r";

    // events of external L2 responses

    // Responses
    Writeback_Tokens,               desc="Received a writeback from L1 with only tokens (no data)";
    Writeback_Shared_Data,               desc="Received a writeback from L1 that includes clean data";
    Writeback_All_Tokens,    desc="Received a writeback from L1";
    Writeback_Owned,                desc="Received a writeback from L1";


    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";

    // Lock/Unlock
    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";
    Own_Lock_or_Unlock,  desc="This processor now has priority";
  }

  // 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";
  }

  structure(DirEntry, desc="...") {
    Set Sharers,            desc="Set of the internal processors that want the block in shared state";
    bool exclusive, default="false", desc="if local exclusive is likely";
  }

  structure(PerfectCacheMemory, external="yes") {
    void allocate(Address);
    void deallocate(Address);
    DirEntry lookup(Address);
    bool isTagPresent(Address);
  }

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

  PersistentTable persistentTable;
  PerfectCacheMemory localDirectory, template="<L2Cache_DirEntry>";

  void set_cache_entry(AbstractCacheEntry b);
  void unset_cache_entry();

  Entry getCacheEntry(Address address), return_by_pointer="yes" {
    Entry cache_entry := static_cast(Entry, "pointer", L2cache.lookup(address));
    return cache_entry;
  }

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

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

  State getState(Entry cache_entry, Address addr) {
    if (is_valid(cache_entry)) {
      return cache_entry.CacheState;
    } else if (persistentTable.isLocked(addr) == true) {
      return State:I_L;
    } else {
      return State:NP;
    }
  }

  void setState(Entry cache_entry, Address addr, State 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));

      // Make sure we have no tokens in L
      if ((state == State:I_L) ) {
        assert(cache_entry.Tokens == 0);
      }

      // in M and E you have all the tokens
      if (state == State:M ) {
        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 ) {
        assert(cache_entry.Tokens > 0);
      }

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

      cache_entry.CacheState := state;
    }
  }

  AccessPermission getAccessPermission(Address addr) {
    Entry cache_entry := getCacheEntry(addr);
    if(is_valid(cache_entry)) {
      return L2Cache_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(L2Cache_State_to_permission(state));
    }
  }

  void removeSharer(Address addr, NodeID id) {

    if (localDirectory.isTagPresent(addr)) {
      localDirectory[addr].Sharers.remove(id);
      if (localDirectory[addr].Sharers.count() == 0) {
        localDirectory.deallocate(addr);
      }
    }
  }

  bool sharersExist(Address addr) {
    if (localDirectory.isTagPresent(addr)) {
      if (localDirectory[addr].Sharers.count() > 0) {
        return true;
      }
      else {
        return false;
      }
    }
    else {
      return false;
    }
  }

  bool exclusiveExists(Address addr) {
    if (localDirectory.isTagPresent(addr)) {
      if (localDirectory[addr].exclusive == true) {
        return true;
      }
      else {
        return false;
      }
    }
    else {
      return false;
    }
  }

  // assumes that caller will check to make sure tag is present
  Set getSharers(Address addr) {
    return localDirectory[addr].Sharers;
  }

  void setNewWriter(Address addr, NodeID id) {
    if (localDirectory.isTagPresent(addr) == false) {
      localDirectory.allocate(addr);
    }
    localDirectory[addr].Sharers.clear();
    localDirectory[addr].Sharers.add(id);
    localDirectory[addr].exclusive := true;
  }

  void addNewSharer(Address addr, NodeID id) {
    if (localDirectory.isTagPresent(addr) == false) {
      localDirectory.allocate(addr);
    }
    localDirectory[addr].Sharers.add(id);
    // localDirectory[addr].exclusive := false;
  }

  void clearExclusiveBitIfExists(Address addr) {
    if (localDirectory.isTagPresent(addr) == true) {
      localDirectory[addr].exclusive := false;
    }
  }

  // ** OUT_PORTS **
  out_port(globalRequestNetwork_out, RequestMsg, GlobalRequestFromL2Cache);
  out_port(localRequestNetwork_out, RequestMsg, L1RequestFromL2Cache);
  out_port(responseNetwork_out, ResponseMsg, responseFromL2Cache);



  // ** IN_PORTS **

  // Persistent Network
  in_port(persistentNetwork_in, PersistentMsg, persistentToL2Cache) {
    if (persistentNetwork_in.isReady()) {
      peek(persistentNetwork_in, PersistentMsg) {
        assert(in_msg.Destination.isElement(machineID));

        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");
        }

        Entry cache_entry := getCacheEntry(in_msg.Addr);
        // React to the message based on the current state of the table
        if (persistentTable.isLocked(in_msg.Addr)) {

          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);
            } else {
              trigger(Event:Persistent_GETS, in_msg.Addr, cache_entry);
            }
          } else {
            trigger(Event:Persistent_GETX, in_msg.Addr, cache_entry);
          }
        }
        else {
            trigger(Event:Own_Lock_or_Unlock, in_msg.Addr, cache_entry);
        }
      }
    }
  }


  // Request Network
  in_port(requestNetwork_in, RequestMsg, GlobalRequestToL2Cache) {
    if (requestNetwork_in.isReady()) {
      peek(requestNetwork_in, RequestMsg) {
        assert(in_msg.Destination.isElement(machineID));

        Entry cache_entry := getCacheEntry(in_msg.Addr);
        if (in_msg.Type == CoherenceRequestType:GETX) {
            trigger(Event:Transient_GETX, in_msg.Addr, cache_entry);
        } else if (in_msg.Type == CoherenceRequestType:GETS) {
          if (getTokens(cache_entry) == 1) {
            trigger(Event:Transient_GETS_Last_Token, in_msg.Addr,
                    cache_entry);
          }
          else {
            trigger(Event:Transient_GETS, in_msg.Addr, cache_entry);
          }
        } else {
          error("Unexpected message");
        }
      }
    }
  }

  in_port(L1requestNetwork_in, RequestMsg, L1RequestToL2Cache) {
    if (L1requestNetwork_in.isReady()) {
      peek(L1requestNetwork_in, RequestMsg) {
        assert(in_msg.Destination.isElement(machineID));
        Entry cache_entry := getCacheEntry(in_msg.Addr);
        if (in_msg.Type == CoherenceRequestType:GETX) {
          trigger(Event:L1_GETX, in_msg.Addr, cache_entry);
        } else if (in_msg.Type == CoherenceRequestType:GETS) {
          if (getTokens(cache_entry) == 1 ||
              getTokens(cache_entry) == (max_tokens() / 2) + 1) {
            trigger(Event:L1_GETS_Last_Token, in_msg.Addr, cache_entry);
          }
          else {
            trigger(Event:L1_GETS, in_msg.Addr, cache_entry);
          }
        } else {
          error("Unexpected message");
        }
      }
    }
  }


  // Response Network
  in_port(responseNetwork_in, ResponseMsg, responseToL2Cache) {
    if (responseNetwork_in.isReady()) {
      peek(responseNetwork_in, ResponseMsg) {
        assert(in_msg.Destination.isElement(machineID));
        Entry cache_entry := getCacheEntry(in_msg.Addr);

        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);
          } else if (in_msg.Type == CoherenceResponseType:DATA_OWNER) {
            trigger(Event:Data_Owner, in_msg.Addr, cache_entry);
          } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) {
            trigger(Event:Data_Shared, in_msg.Addr, cache_entry);
          } else if (in_msg.Type == CoherenceResponseType:WB_TOKENS ||
                     in_msg.Type == CoherenceResponseType:WB_OWNED ||
                     in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {

            if (L2cache.cacheAvail(in_msg.Addr) || is_valid(cache_entry)) {

              // either room is available or the block is already present

              if (in_msg.Type == CoherenceResponseType:WB_TOKENS) {
                assert(in_msg.Dirty == false);
                trigger(Event:Writeback_Tokens, in_msg.Addr, cache_entry);
              } else if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {
                assert(in_msg.Dirty == false);
                trigger(Event:Writeback_Shared_Data, in_msg.Addr, cache_entry);
              }
              else if (in_msg.Type == CoherenceResponseType:WB_OWNED) {
                //assert(in_msg.Dirty == false);
                trigger(Event:Writeback_Owned, in_msg.Addr, cache_entry);
              }
            }
            else {
                trigger(Event:L2_Replacement,
                        L2cache.cacheProbe(in_msg.Addr),
                        getCacheEntry(L2cache.cacheProbe(in_msg.Addr)));
            }
          } else if (in_msg.Type == CoherenceResponseType:INV) {
            trigger(Event:L1_INV, in_msg.Addr, cache_entry);
          } 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);
          } else if (in_msg.Type == CoherenceResponseType:DATA_OWNER ||
                     in_msg.Type == CoherenceResponseType:DATA_SHARED) {
            trigger(Event:Data_All_Tokens, in_msg.Addr, cache_entry);
          } else if (in_msg.Type == CoherenceResponseType:WB_TOKENS ||
                     in_msg.Type == CoherenceResponseType:WB_OWNED ||
                     in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {
            if (L2cache.cacheAvail(in_msg.Addr) || is_valid(cache_entry)) {

              // either room is available or the block is already present

              if (in_msg.Type == CoherenceResponseType:WB_TOKENS) {
                assert(in_msg.Dirty == false);
                assert(  (getState(cache_entry, in_msg.Addr) != State:NP)
                      && (getState(cache_entry, in_msg.Addr) != State:I) );
                trigger(Event:Writeback_All_Tokens, in_msg.Addr, cache_entry);
              } else if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {
                assert(in_msg.Dirty == false);
                trigger(Event:Writeback_All_Tokens, in_msg.Addr, cache_entry);
              }
              else if (in_msg.Type == CoherenceResponseType:WB_OWNED) {
                trigger(Event:Writeback_All_Tokens, in_msg.Addr, cache_entry);
              }
            }
            else {
                trigger(Event:L2_Replacement,
                        L2cache.cacheProbe(in_msg.Addr),
                        getCacheEntry(L2cache.cacheProbe(in_msg.Addr)));
            }
          } else if (in_msg.Type == CoherenceResponseType:INV) {
            trigger(Event:L1_INV, in_msg.Addr, cache_entry);
          } else {
            DPRINTF(RubySlicc, "%s\n", in_msg.Type);
            error("Unexpected message");
          }
        }
      }
    }
  }


  // ACTIONS

  action(a_broadcastLocalRequest, "a", desc="broadcast local request globally") {

    peek(L1requestNetwork_in, RequestMsg) {

     // if this is a retry or no local sharers, broadcast normally

     // if (in_msg.RetryNum > 0 || (in_msg.Type == CoherenceRequestType:GETX && exclusiveExists(in_msg.Addr) == false) || (in_msg.Type == CoherenceRequestType:GETS && sharersExist(in_msg.Addr) == false)) {
        enqueue(globalRequestNetwork_out, RequestMsg, latency=l2_request_latency) {
           out_msg.Addr := in_msg.Addr;
           out_msg.Type := in_msg.Type;
           out_msg.Requestor := in_msg.Requestor;
           out_msg.RetryNum := in_msg.RetryNum;

           //
           // If a statically shared L2 cache, then no other L2 caches can
           // store the block
           //
           //out_msg.Destination.broadcast(MachineType:L2Cache);
           //out_msg.Destination.addNetDest(getAllPertinentL2Banks(address));
           //out_msg.Destination.remove(map_L1CacheMachId_to_L2Cache(address, in_msg.Requestor));

           out_msg.Destination.add(map_Address_to_Directory(address));
           out_msg.MessageSize := MessageSizeType:Request_Control;
           out_msg.AccessMode := in_msg.AccessMode;
           out_msg.Prefetch := in_msg.Prefetch;
        } //enqueue
      // } // if

         //profile_filter_action(0);
    } // peek
  } //action


  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, latency="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_cleanReplacement, "c", desc="Issue clean writeback") {
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:ACK;
        out_msg.Sender := machineID;
        out_msg.Destination.add(map_Address_to_Directory(address));
        out_msg.Tokens := cache_entry.Tokens;
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
      cache_entry.Tokens := 0;
    }
  }

  action(cc_dirtyReplacement, "\c", desc="Issue dirty writeback") {
    assert(is_valid(cache_entry));
    enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
      out_msg.Addr := address;
      out_msg.Sender := machineID;
      out_msg.Destination.add(map_Address_to_Directory(address));
      out_msg.Tokens := cache_entry.Tokens;
      out_msg.DataBlk := cache_entry.DataBlk;
      out_msg.Dirty := cache_entry.Dirty;

      if (cache_entry.Dirty) {
        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
      } else {
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
        out_msg.Type := CoherenceResponseType:ACK_OWNER;
      }
    }
    cache_entry.Tokens := 0;
  }

  action(d_sendDataWithTokens, "d", desc="Send data and a token from cache to requestor") {
    peek(requestNetwork_in, RequestMsg) {
      assert(is_valid(cache_entry));
      if (cache_entry.Tokens > (N_tokens + (max_tokens() / 2))) {
        enqueue(responseNetwork_out, ResponseMsg, latency=l2_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 := false;
          out_msg.MessageSize := MessageSizeType:Response_Data;
        }
        cache_entry.Tokens := cache_entry.Tokens - N_tokens;
      }
      else {
        enqueue(responseNetwork_out, ResponseMsg, latency=l2_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 := false;
          out_msg.MessageSize := MessageSizeType:Response_Data;
        }
        cache_entry.Tokens := cache_entry.Tokens - 1;
      }
    }
  }

  action(dd_sendDataWithAllTokens, "\d", desc="Send data and all tokens from cache to requestor") {
    assert(is_valid(cache_entry));
    peek(requestNetwork_in, RequestMsg) {
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_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 >= 1);
        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(e_sendAckWithCollectedTokens, "e", desc="Send ack with the tokens we've collected thus far.") {
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
        out_msg.Addr := address;
        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.MessageSize := MessageSizeType:Response_Control;
      }
    }
    cache_entry.Tokens := 0;
  }

  action(ee_sendDataWithAllTokens, "\e", desc="Send data and all tokens from cache to starver") {
    assert(is_valid(cache_entry));
    enqueue(responseNetwork_out, ResponseMsg, latency=l2_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 >= 1);
      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_sendAckWithAllButOneTokens, "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, latency=l2_response_latency) {
        out_msg.Addr := address;
        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 - 1;
        out_msg.MessageSize := MessageSizeType:Response_Control;
      }
    }
    cache_entry.Tokens := 1;
  }

  action(ff_sendDataWithAllButOneTokens, "\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, latency=l2_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 - 1;
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    cache_entry.Tokens := 1;
  }

  action(fa_sendDataWithAllTokens, "fa", 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, latency=l2_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;
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    cache_entry.Tokens := 0;
  }



  action(gg_bounceResponseToStarver, "\g", desc="Redirect response to starving processor") {
    // assert(persistentTable.isLocked(address));
    peek(responseNetwork_in, ResponseMsg) {
      // FIXME, should use a 3rd vnet in some cases
      enqueue(responseNetwork_out, ResponseMsg, latency="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(gg_bounceWBSharedToStarver, "\gg", desc="Redirect response to starving processor") {
    //assert(persistentTable.isLocked(address));
    peek(responseNetwork_in, ResponseMsg) {
      // FIXME, should use a 3rd vnet in some cases
      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
        out_msg.Addr := address;
        if (in_msg.Type == CoherenceResponseType:WB_SHARED_DATA) {
          out_msg.Type := CoherenceResponseType:DATA_SHARED;
        } else {
          assert(in_msg.Tokens < (max_tokens() / 2));
          out_msg.Type := CoherenceResponseType:ACK;
        }
        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(gg_bounceWBOwnedToStarver, "\ggg", desc="Redirect response to starving processor") {
    // assert(persistentTable.isLocked(address));
    peek(responseNetwork_in, ResponseMsg) {
      // FIXME, should use a 3rd vnet in some cases
      enqueue(responseNetwork_out, ResponseMsg, latency="1") {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        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_updateFilterFromL1HintOrWB, "h", desc="update filter from received writeback") {
    peek(responseNetwork_in, ResponseMsg) {
      removeSharer(in_msg.Addr, machineIDToNodeID(in_msg.Sender));
    }
  }

  action(j_forwardTransientRequestToLocalSharers, "j", desc="Forward external transient request to local sharers") {
    peek(requestNetwork_in, RequestMsg) {
      if (filtering_enabled == true && in_msg.RetryNum == 0 && sharersExist(in_msg.Addr) == false) {
        //profile_filter_action(1);
        DPRINTF(RubySlicc, "filtered message, Retry Num: %d\n",
                in_msg.RetryNum);
      }
      else {
        enqueue(localRequestNetwork_out, RequestMsg, latency=l2_response_latency ) {
           out_msg.Addr := in_msg.Addr;
           out_msg.Requestor := in_msg.Requestor;

           //
           // Currently assuming only one chip so all L1s are local
           //
           //out_msg.Destination := getLocalL1IDs(machineID);
           out_msg.Destination.broadcast(MachineType:L1Cache);
           out_msg.Destination.remove(in_msg.Requestor);

           out_msg.Type := in_msg.Type;
           out_msg.isLocal := false;
           out_msg.MessageSize := MessageSizeType:Broadcast_Control;
           out_msg.AccessMode := in_msg.AccessMode;
           out_msg.Prefetch := in_msg.Prefetch;
        }
        //profile_filter_action(0);
      }
    }
  }

  action(k_dataFromL2CacheToL1Requestor, "k", desc="Send data and a token from cache to L1 requestor") {
    peek(L1requestNetwork_in, RequestMsg) {
      assert(is_valid(cache_entry));
      assert(cache_entry.Tokens > 0);
      //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") {
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_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.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := false;
        out_msg.MessageSize := MessageSizeType:ResponseL2hit_Data;
        out_msg.Tokens := 1;
      }
      cache_entry.Tokens := cache_entry.Tokens - 1;
    }
  }

  action(k_dataOwnerFromL2CacheToL1Requestor, "\k", desc="Send data and a token from cache to L1 requestor") {
    peek(L1requestNetwork_in, RequestMsg) {
      assert(is_valid(cache_entry));
      assert(cache_entry.Tokens == (max_tokens() / 2) + 1);
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:ResponseL2hit_Data;
        out_msg.Tokens := cache_entry.Tokens;
      }
      cache_entry.Tokens := 0;
    }
  }

  action(k_dataAndAllTokensFromL2CacheToL1Requestor, "\kk", desc="Send data and a token from cache to L1 requestor") {
    peek(L1requestNetwork_in, RequestMsg) {
      assert(is_valid(cache_entry));
//      assert(cache_entry.Tokens == max_tokens());
      //enqueue(responseIntraChipL2Network_out, ResponseMsg, latency="L2_to_L1_RESPONSE_LATENCY") {
      enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.DataBlk := cache_entry.DataBlk;
        out_msg.Dirty := cache_entry.Dirty;
        out_msg.MessageSize := MessageSizeType:ResponseL2hit_Data;
        //out_msg.Tokens := max_tokens();
        out_msg.Tokens := cache_entry.Tokens;
      }
      cache_entry.Tokens := 0;
    }
  }

  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_popL1RequestQueue, "o", desc="Pop L1 request queue.") {
    L1requestNetwork_in.dequeue();
  }


  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);
      cache_entry.Tokens := cache_entry.Tokens + in_msg.Tokens;

      // this should ideally be in u_writeDataToCache, but Writeback_All_Tokens
      //  may not trigger this action.
      if ( (in_msg.Type == CoherenceResponseType:DATA_OWNER || in_msg.Type == CoherenceResponseType:WB_OWNED) && in_msg.Dirty) {
        cache_entry.Dirty := true;
      }
    }
  }

  action(r_markNewSharer, "r", desc="Mark the new local sharer from local request message") {
    peek(L1requestNetwork_in, RequestMsg) {
      if (machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) {
        if (in_msg.Type == CoherenceRequestType:GETX) {
          setNewWriter(in_msg.Addr, machineIDToNodeID(in_msg.Requestor));
        } else if (in_msg.Type == CoherenceRequestType:GETS) {
          addNewSharer(in_msg.Addr, machineIDToNodeID(in_msg.Requestor));
        }
      }
    }
  }

  action(r_clearExclusive, "\rrr", desc="clear exclusive bit") {
    clearExclusiveBitIfExists(address);
  }

  action(r_setMRU, "\rr", desc="manually set the MRU bit for cache line" ) {
    peek(L1requestNetwork_in, RequestMsg) {
      if ((machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache) &&
          (is_valid(cache_entry))) {
        L2cache.setMRU(address);
      }
    }
  }

  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, latency=l2_response_latency) {
          out_msg.Addr := address;
          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.MessageSize := MessageSizeType:Response_Control;
        }
      }
    }
    cache_entry.Tokens := 0;
  }

  action(tt_sendLocalAckWithCollectedTokens, "tt", desc="Send ack with the tokens we've collected thus far.") {
    assert(is_valid(cache_entry));
    if (cache_entry.Tokens > 0) {
      peek(L1requestNetwork_in, RequestMsg) {
        enqueue(responseNetwork_out, ResponseMsg, latency=l2_response_latency) {
          out_msg.Addr := address;
          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.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(vv_allocateL2CacheBlock, "\v", desc="Set L2 cache tag equal to tag of block B.") {
    set_cache_entry(L2cache.allocate(address, new Entry));
  }

  action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block.  Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
    L2cache.deallocate(address);
    unset_cache_entry();
  }

  action(uu_profileMiss, "\um", desc="Profile the demand miss") {
      ++L2cache.demand_misses;
  }

  action(uu_profileHit, "\uh", desc="Profile the demand hit") {
      ++L2cache.demand_hits;
  }

  action(w_assertIncomingDataAndCacheDataMatch, "w", desc="Assert that the incoming data and the data in the cache match") {
    peek(responseNetwork_in, ResponseMsg) {
      if (in_msg.Type != CoherenceResponseType:ACK &&
          in_msg.Type != CoherenceResponseType:WB_TOKENS) {
        assert(is_valid(cache_entry));
        assert(cache_entry.DataBlk == in_msg.DataBlk);
      }
    }
  }


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

  transition({NP, I, S, O, M, I_L, S_L}, L1_INV) {

    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition({NP, I, S, O, M}, Own_Lock_or_Unlock) {
    l_popPersistentQueue;
  }


  // Transitions from NP

  transition(NP, {Transient_GETX, Transient_GETS}) {
    // forward message to local sharers
    r_clearExclusive;
    j_forwardTransientRequestToLocalSharers;
    m_popRequestQueue;
  }


  transition(NP,  {L1_GETS, L1_GETX}) {
    a_broadcastLocalRequest;
    r_markNewSharer;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

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

  transition(NP, Writeback_Shared_Data, S) {
    vv_allocateL2CacheBlock;
    u_writeDataToCache;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition(NP, Writeback_Tokens, I) {
    vv_allocateL2CacheBlock;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition(NP, Writeback_All_Tokens, M) {
    vv_allocateL2CacheBlock;
    u_writeDataToCache;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition(NP, Writeback_Owned, O) {
    vv_allocateL2CacheBlock;
    u_writeDataToCache;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }


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

  // Transitions from Idle

  transition(I, {L1_GETS, L1_GETS_Last_Token}) {
    a_broadcastLocalRequest;
    tt_sendLocalAckWithCollectedTokens;  // send any tokens we have collected
    r_markNewSharer;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

  transition(I, L1_GETX) {
    a_broadcastLocalRequest;
    tt_sendLocalAckWithCollectedTokens; // send any tokens we have collected
    r_markNewSharer;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

  transition(I, L2_Replacement) {
    c_cleanReplacement; // Only needed in some cases
    rr_deallocateL2CacheBlock;
  }

  transition(I, {Transient_GETX, Transient_GETS, Transient_GETS_Last_Token}) {
    r_clearExclusive;
    t_sendAckWithCollectedTokens;
    j_forwardTransientRequestToLocalSharers;
    m_popRequestQueue;
  }

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


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

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

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

  transition(I, Writeback_Tokens) {
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

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

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

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


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

  // Transitions from Shared

  transition(S, L2_Replacement, I) {
    c_cleanReplacement;
    rr_deallocateL2CacheBlock;
  }

  transition(S, Transient_GETX, I) {
    r_clearExclusive;
    t_sendAckWithCollectedTokens;
    j_forwardTransientRequestToLocalSharers;
    m_popRequestQueue;
  }

  transition(S, {Transient_GETS, Transient_GETS_Last_Token}) {
    j_forwardTransientRequestToLocalSharers;
    r_clearExclusive;
    m_popRequestQueue;
  }

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


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


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

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

  transition(S, Writeback_Tokens) {
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition(S, Writeback_Shared_Data) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }


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

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

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

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

  transition(S, L1_GETX, I) {
    a_broadcastLocalRequest;
    tt_sendLocalAckWithCollectedTokens;
    r_markNewSharer;
    r_setMRU;
    uu_profileMiss;
    o_popL1RequestQueue;
  }


  transition(S, L1_GETS) {
    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  transition(S, L1_GETS_Last_Token, I) {

    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  // Transitions from Owned

  transition(O, L2_Replacement, I) {
    cc_dirtyReplacement;
    rr_deallocateL2CacheBlock;
  }

  transition(O, Transient_GETX, I) {
    r_clearExclusive;
    dd_sendDataWithAllTokens;
    j_forwardTransientRequestToLocalSharers;
    m_popRequestQueue;
  }

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

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

  transition(O, Persistent_GETS_Last_Token, I_L) {
    fa_sendDataWithAllTokens;
    l_popPersistentQueue;
  }

  transition(O, Transient_GETS) {
    // send multiple tokens
    r_clearExclusive;
    d_sendDataWithTokens;
    m_popRequestQueue;
  }

  transition(O, Transient_GETS_Last_Token) {
    // WAIT FOR IT TO GO PERSISTENT
    r_clearExclusive;
    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, {Writeback_Tokens, Writeback_Shared_Data}) {
    w_assertIncomingDataAndCacheDataMatch;
    q_updateTokensFromResponse;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

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

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

  transition(O, L1_GETS) {
    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  transition(O, L1_GETS_Last_Token, I) {
    k_dataOwnerFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  transition(O, L1_GETX, I) {
    a_broadcastLocalRequest;
    k_dataAndAllTokensFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

  // Transitions from M

  transition(M, L2_Replacement, I) {
    cc_dirtyReplacement;
    rr_deallocateL2CacheBlock;
  }

  // MRM_DEBUG:  Give up all tokens even for GETS? ???
  transition(M, {Transient_GETX, Transient_GETS}, I) {
    r_clearExclusive;
    dd_sendDataWithAllTokens;
    m_popRequestQueue;
  }

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


  transition(M, L1_GETS, O) {
    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  transition(M, L1_GETX, I) {
    k_dataAndAllTokensFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }


  //Transitions from locked states

  transition({I_L, S_L}, Ack) {
    gg_bounceResponseToStarver;
    n_popResponseQueue;
  }

  transition({I_L, S_L}, {Data_Shared, Data_Owner, Data_All_Tokens}) {
    gg_bounceResponseToStarver;
    n_popResponseQueue;
  }

  transition({I_L, S_L}, {Writeback_Tokens, Writeback_Shared_Data}) {
    gg_bounceWBSharedToStarver;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition({I_L, S_L}, {Writeback_Owned, Writeback_All_Tokens}) {
    gg_bounceWBOwnedToStarver;
    h_updateFilterFromL1HintOrWB;
    n_popResponseQueue;
  }

  transition(S_L, L2_Replacement, I) {
    c_cleanReplacement;
    rr_deallocateL2CacheBlock;
  }

  transition(I_L, L2_Replacement, I) {
    rr_deallocateL2CacheBlock;
  }

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

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

  transition({I_L, S_L}, {Transient_GETS_Last_Token, Transient_GETS, Transient_GETX}) {
    r_clearExclusive;
    m_popRequestQueue;
  }

  transition(I_L, {L1_GETX, L1_GETS}) {
    a_broadcastLocalRequest;
    r_markNewSharer;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

  transition(S_L, L1_GETX, I_L) {
    a_broadcastLocalRequest;
    tt_sendLocalAckWithCollectedTokens;
    r_markNewSharer;
    r_setMRU;
    uu_profileMiss;
    o_popL1RequestQueue;
  }

  transition(S_L, L1_GETS) {
    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

  transition(S_L, L1_GETS_Last_Token, I_L) {
    k_dataFromL2CacheToL1Requestor;
    r_markNewSharer;
    r_setMRU;
    uu_profileHit;
    o_popL1RequestQueue;
  }

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

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

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