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