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

  void functionalRead(Address addr, Packet *pkt) {
    testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
  }

  int functionalWrite(Address addr, Packet *pkt) {
    int num_functional_writes := 0;
    num_functional_writes := num_functional_writes +
        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
    return num_functional_writes;
  }

  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)) {
      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) {
        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)) {
      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
        enqueue(globalRequestNetwork_out, RequestMsg, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 && 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, 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(responseNetwork_out, ResponseMsg, 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, 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(responseNetwork_out, ResponseMsg, 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, 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, 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;
  }
}
