/*
 * 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(Directory, "Token protocol")
 : DirectoryMemory * directory;
   MemoryControl * memBuffer;
   int l2_select_num_bits;
   Cycles directory_latency := 5;
   bool distributed_persistent := "True";
   Cycles fixed_timeout_latency := 100;
   Cycles reissue_wakeup_latency := 10;

   // Message Queues from dir to other controllers / network
   MessageBuffer * dmaResponseFromDir, network="To", virtual_network="5",
        ordered="true", vnet_type="response";

   MessageBuffer * responseFromDir, network="To", virtual_network="4",
        ordered="false", vnet_type="response";

   MessageBuffer * persistentFromDir, network="To", virtual_network="3",
        ordered="true", vnet_type="persistent";

   MessageBuffer * requestFromDir, network="To", virtual_network="1",
        ordered="false", vnet_type="request";
 
   // Message Queues to dir from other controllers / network
   MessageBuffer * responseToDir, network="From", virtual_network="4",
        ordered="false", vnet_type="response";

   MessageBuffer * persistentToDir, network="From", virtual_network="3",
        ordered="true", vnet_type="persistent";
   
   MessageBuffer * requestToDir, network="From", virtual_network="2",
        ordered="false", vnet_type="request";
   
   MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
        ordered="true", vnet_type="request";

{
  // STATES
  state_declaration(State, desc="Directory states", default="Directory_State_O") {
    // Base states
    O, AccessPermission:Read_Only, desc="Owner, memory has valid data, but not necessarily all the tokens";
    NO, AccessPermission:Maybe_Stale, desc="Not Owner";
    L, AccessPermission:Busy, desc="Locked";

    // Memory wait states - can block all messages including persistent requests
    O_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory write";
    L_O_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, could eventually return to O";
    L_NO_W, AccessPermission:Busy, desc="transitioning to Locked, waiting for memory read, eventually return to NO";
    DR_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA read, waiting for memory data";
    DW_L_W, AccessPermission:Busy, desc="transitioning to Locked underneath a DMA write, waiting for memory ack";
    NO_W, AccessPermission:Busy, desc="transitioning to Not Owner, waiting for memory read";
    O_DW_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA ack";
    O_DR_W, AccessPermission:Busy, desc="transitioning to Owner, waiting for memory before DMA data";

    // DMA request transient states - must respond to persistent requests
    O_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens";
    NO_DW, AccessPermission:Busy, desc="issued GETX for DMA write, waiting for all tokens";
    NO_DR, AccessPermission:Busy, desc="issued GETS for DMA read, waiting for data";

    // DMA request in progress - competing with a CPU persistent request
    DW_L, AccessPermission:Busy, desc="issued GETX for DMA write, CPU persistent request must complete first";
    DR_L, AccessPermission:Busy, desc="issued GETS for DMA read, CPU persistent request must complete first";

  }

  // Events
  enumeration(Event, desc="Directory events") {
    GETX, desc="A GETX arrives";
    GETS, desc="A GETS arrives";
    Lockdown, desc="A lockdown request arrives";
    Unlockdown, desc="An un-lockdown request arrives";
    Own_Lock_or_Unlock, desc="own lock or unlock";
    Own_Lock_or_Unlock_Tokens, desc="own lock or unlock with tokens";
    Data_Owner, desc="Data arrive";
    Data_All_Tokens, desc="Data and all tokens";
    Ack_Owner, desc="Owner token arrived without data because it was clean";
    Ack_Owner_All_Tokens, desc="All tokens including owner arrived without data because it was clean";
    Tokens, desc="Tokens arrive";
    Ack_All_Tokens, desc="All_Tokens arrive";
    Request_Timeout, desc="A DMA request has timed out";

    // Memory Controller
    Memory_Data, desc="Fetched data from memory arrives";
    Memory_Ack, desc="Writeback Ack from memory arrives";

    // DMA requests
    DMA_READ, desc="A DMA Read memory request";
    DMA_WRITE, desc="A DMA Write memory request";
    DMA_WRITE_All_Tokens, desc="A DMA Write memory request, directory has all tokens";
  }

  // TYPES

  // DirectoryEntry
  structure(Entry, desc="...", interface="AbstractEntry") {
    State DirectoryState,          desc="Directory state";
    DataBlock DataBlk,             desc="data for the block";
    int Tokens, default="max_tokens()", desc="Number of tokens for the line we're holding";

    // The following state is provided to allow for bandwidth
    // efficient directory-like operation.  However all of this state
    // is 'soft state' that does not need to be correct (as long as
    // you're eventually willing to resort to broadcast.)

    Set Owner,                     desc="Probable Owner of the line.  More accurately, the set of processors who need to see a GetS or GetO.  We use a Set for convenience, but only one bit is set at a time.";
    Set Sharers,                   desc="Probable sharers of the line.  More accurately, the set of processors who need to see a GetX";
  }

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

  // TBE entries for DMA requests
  structure(TBE, desc="TBE entries for outstanding DMA requests") {
    Address PhysicalAddress, desc="physical address";
    State TBEState,        desc="Transient State";
    DataBlock DmaDataBlk,  desc="DMA Data to be written.  Partial blocks need to merged with system memory";
    DataBlock DataBlk,     desc="The current view of system memory";
    int Len,               desc="...";
    MachineID DmaRequestor, desc="DMA requestor";
    bool WentPersistent,   desc="Did the DMA request require a persistent request";
  }

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

  // ** OBJECTS **

  PersistentTable persistentTable;
  TimerTable reissueTimerTable;

  TBETable TBEs, template="<Directory_TBE>", constructor="m_number_of_TBEs";

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

  void set_tbe(TBE b);
  void unset_tbe();

  Entry getDirectoryEntry(Address addr), return_by_pointer="yes" {
    Entry dir_entry := static_cast(Entry, "pointer", directory[addr]);

    if (is_valid(dir_entry)) {
      return dir_entry;
    }

    dir_entry :=  static_cast(Entry, "pointer",
                              directory.allocate(addr, new Entry));
    return dir_entry;
  }

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

  State getState(TBE tbe, Address addr) {
    if (is_valid(tbe)) {
      return tbe.TBEState;
    } else {
      return getDirectoryEntry(addr).DirectoryState;
    }
  }

  void setState(TBE tbe, Address addr, State state) {
    if (is_valid(tbe)) {
      tbe.TBEState := state;
    }
    getDirectoryEntry(addr).DirectoryState := state;

    if (state == State:L || state == State:DW_L || state == State:DR_L) {
      assert(getDirectoryEntry(addr).Tokens == 0);
    }

    // We have one or zero owners
    assert((getDirectoryEntry(addr).Owner.count() == 0) || (getDirectoryEntry(addr).Owner.count() == 1));

    // Make sure the token count is in range
    assert(getDirectoryEntry(addr).Tokens >= 0);
    assert(getDirectoryEntry(addr).Tokens <= max_tokens());

    if (state == State:O || state == State:O_W || state == State:O_DW) {
      assert(getDirectoryEntry(addr).Tokens >= 1); // Must have at least one token
      // assert(getDirectoryEntry(addr).Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold
    }
  }

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

    if (directory.isPresent(addr)) {
      DPRINTF(RubySlicc, "%s\n", Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState));
      return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
    }

    DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
    return AccessPermission:NotPresent;
  }

  void setAccessPermission(Address addr, State state) {
    getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state));
  }

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

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

  // ** OUT_PORTS **
  out_port(responseNetwork_out, ResponseMsg, responseFromDir);
  out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
  out_port(requestNetwork_out, RequestMsg, requestFromDir);
  out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);

  //
  // Memory buffer for memory controller to DIMM communication
  //
  out_port(memQueue_out, MemoryMsg, memBuffer);

  // ** IN_PORTS **

  // off-chip memory request/response is done
  in_port(memQueue_in, MemoryMsg, memBuffer) {
    if (memQueue_in.isReady()) {
      peek(memQueue_in, MemoryMsg) {
        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
          trigger(Event:Memory_Data, in_msg.Addr, TBEs[in_msg.Addr]);
        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
          trigger(Event:Memory_Ack, in_msg.Addr, TBEs[in_msg.Addr]);
        } else {
          DPRINTF(RubySlicc, "%s\n", in_msg.Type);
          error("Invalid message");
        }
      }
    }
  }

  // Reissue Timer
  in_port(reissueTimerTable_in, Address, reissueTimerTable) {
    if (reissueTimerTable_in.isReady()) {
      trigger(Event:Request_Timeout, reissueTimerTable.readyAddress(),
              TBEs[reissueTimerTable.readyAddress()]);
    }
  }

  in_port(responseNetwork_in, ResponseMsg, responseToDir) {
    if (responseNetwork_in.isReady()) {
      peek(responseNetwork_in, ResponseMsg) {
        assert(in_msg.Destination.isElement(machineID));
        if (getDirectoryEntry(in_msg.Addr).Tokens + in_msg.Tokens == max_tokens()) {
          if ((in_msg.Type == CoherenceResponseType:DATA_OWNER) ||
              (in_msg.Type == CoherenceResponseType:DATA_SHARED)) {
            trigger(Event:Data_All_Tokens, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) {
            trigger(Event:Ack_Owner_All_Tokens, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else if (in_msg.Type == CoherenceResponseType:ACK) {
            trigger(Event:Ack_All_Tokens, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else {
            DPRINTF(RubySlicc, "%s\n", in_msg.Type);
            error("Invalid message");
          }
        } else {
          if (in_msg.Type == CoherenceResponseType:DATA_OWNER) {
            trigger(Event:Data_Owner, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else if ((in_msg.Type == CoherenceResponseType:ACK) ||
                     (in_msg.Type == CoherenceResponseType:DATA_SHARED)) {
            trigger(Event:Tokens, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else if (in_msg.Type == CoherenceResponseType:ACK_OWNER) {
            trigger(Event:Ack_Owner, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else {
            DPRINTF(RubySlicc, "%s\n", in_msg.Type);
            error("Invalid message");
          }
        }
      }
    }
  }

  in_port(persistentNetwork_in, PersistentMsg, persistentToDir) {
    if (persistentNetwork_in.isReady()) {
      peek(persistentNetwork_in, PersistentMsg) {
        assert(in_msg.Destination.isElement(machineID));

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

          // React to the message based on the current state of the table
          if (persistentTable.isLocked(in_msg.Addr)) {
            if (persistentTable.findSmallest(in_msg.Addr) == machineID) {
              if (getDirectoryEntry(in_msg.Addr).Tokens > 0) {
                trigger(Event:Own_Lock_or_Unlock_Tokens, in_msg.Addr,
                        TBEs[in_msg.Addr]);
              } else {
                trigger(Event:Own_Lock_or_Unlock, in_msg.Addr,
                        TBEs[in_msg.Addr]);
              }
            } else {
              // locked
              trigger(Event:Lockdown, in_msg.Addr, TBEs[in_msg.Addr]);
            }
          } else {
            // unlocked
            trigger(Event:Unlockdown, in_msg.Addr, TBEs[in_msg.Addr]);
          }
        }
        else {
          if (persistentTable.findSmallest(in_msg.Addr) == machineID) {
              if (getDirectoryEntry(in_msg.Addr).Tokens > 0) {
                trigger(Event:Own_Lock_or_Unlock_Tokens, in_msg.Addr,
                        TBEs[in_msg.Addr]);
              } else {
                trigger(Event:Own_Lock_or_Unlock, in_msg.Addr,
                        TBEs[in_msg.Addr]);
              }
          } else if (in_msg.Type == PersistentRequestType:GETX_PERSISTENT) {
            // locked
            trigger(Event:Lockdown, in_msg.Addr, TBEs[in_msg.Addr]);
          } else if (in_msg.Type == PersistentRequestType:GETS_PERSISTENT) {
            // locked
            trigger(Event:Lockdown, in_msg.Addr, TBEs[in_msg.Addr]);
          } else if (in_msg.Type == PersistentRequestType:DEACTIVATE_PERSISTENT) {
            // unlocked
            trigger(Event:Unlockdown, in_msg.Addr, TBEs[in_msg.Addr]);
          } else {
            error("Invalid message");
          }
        }
      }
    }
  }

  in_port(requestNetwork_in, RequestMsg, requestToDir) {
    if (requestNetwork_in.isReady()) {
      peek(requestNetwork_in, RequestMsg) {
        assert(in_msg.Destination.isElement(machineID));
        if (in_msg.Type == CoherenceRequestType:GETS) {
          trigger(Event:GETS, in_msg.Addr, TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceRequestType:GETX) {
          trigger(Event:GETX, in_msg.Addr, TBEs[in_msg.Addr]);
        } else {
          error("Invalid message");
        }
      }
    }
  }

  in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
    if (dmaRequestQueue_in.isReady()) {
      peek(dmaRequestQueue_in, DMARequestMsg) {
        if (in_msg.Type == DMARequestType:READ) {
          trigger(Event:DMA_READ, in_msg.LineAddress, TBEs[in_msg.LineAddress]);
        } else if (in_msg.Type == DMARequestType:WRITE) {
          if (getDirectoryEntry(in_msg.LineAddress).Tokens == max_tokens()) {
            trigger(Event:DMA_WRITE_All_Tokens, in_msg.LineAddress,
                    TBEs[in_msg.LineAddress]);
          } else {
            trigger(Event:DMA_WRITE, in_msg.LineAddress,
                    TBEs[in_msg.LineAddress]);
          }
        } else {
          error("Invalid message");
        }
      }
    }
  }

  // Actions

  action(a_sendTokens, "a", desc="Send tokens to requestor") {
    // Only send a message if we have tokens to send
    if (getDirectoryEntry(address).Tokens > 0) {
      peek(requestNetwork_in, RequestMsg) {
        enqueue(responseNetwork_out, ResponseMsg, directory_latency) {// FIXME?
          out_msg.Addr := address;
          out_msg.Type := CoherenceResponseType:ACK;
          out_msg.Sender := machineID;
          out_msg.Destination.add(in_msg.Requestor);
          out_msg.Tokens := getDirectoryEntry(in_msg.Addr).Tokens;
          out_msg.MessageSize := MessageSizeType:Response_Control;
        }
      }
      getDirectoryEntry(address).Tokens := 0;
    }
  }

  action(px_tryIssuingPersistentGETXRequest, "px", desc="...") {
    if (okToIssueStarving(address, machineID) && (starving == false)) {
      enqueue(persistentNetwork_out, PersistentMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := PersistentRequestType:GETX_PERSISTENT;
        out_msg.Requestor := machineID;
        out_msg.Destination.broadcast(MachineType:L1Cache);

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

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

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

      tbe.WentPersistent := true;

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

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

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

  action(bw_broadcastWrite, "bw", desc="Broadcast GETX if we need tokens") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      //
      // Assser that we only send message if we don't already have all the tokens
      //
      assert(getDirectoryEntry(address).Tokens != max_tokens());
      enqueue(requestNetwork_out, RequestMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceRequestType:GETX;
        out_msg.Requestor := machineID;

        //
        // Since only one chip, assuming all L1 caches are local
        //
        out_msg.Destination.broadcast(MachineType:L1Cache);
        out_msg.Destination.add(mapAddressToRange(address,
                                  MachineType:L2Cache, l2_select_low_bit,
                                  l2_select_num_bits, intToID(0)));

        out_msg.RetryNum := 0;
        out_msg.MessageSize := MessageSizeType:Broadcast_Control;
        out_msg.Prefetch := PrefetchBit:No;
        out_msg.AccessMode := RubyAccessMode:Supervisor;
      }
    }
  }

  action(ps_tryIssuingPersistentGETSRequest, "ps", desc="...") {
    if (okToIssueStarving(address, machineID) && (starving == false)) {
      enqueue(persistentNetwork_out, PersistentMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := PersistentRequestType:GETS_PERSISTENT;
        out_msg.Requestor := machineID;
        out_msg.Destination.broadcast(MachineType:L1Cache);

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

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

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

      tbe.WentPersistent := true;

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

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

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

  action(br_broadcastRead, "br", desc="Broadcast GETS for data") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      enqueue(requestNetwork_out, RequestMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceRequestType:GETS;
        out_msg.Requestor := machineID;

        //
        // Since only one chip, assuming all L1 caches are local
        //
        out_msg.Destination.broadcast(MachineType:L1Cache);
        out_msg.Destination.add(mapAddressToRange(address,
                                  MachineType:L2Cache, l2_select_low_bit,
                                  l2_select_num_bits, intToID(0)));

        out_msg.RetryNum := 0;
        out_msg.MessageSize := MessageSizeType:Broadcast_Control;
        out_msg.Prefetch := PrefetchBit:No;
        out_msg.AccessMode := RubyAccessMode:Supervisor;
      }
    }
  }

  action(aa_sendTokensToStarver, "\a", desc="Send tokens to starver") {
    // Only send a message if we have tokens to send
    if (getDirectoryEntry(address).Tokens > 0) {
      enqueue(responseNetwork_out, ResponseMsg, directory_latency) {// FIXME?
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:ACK;
        out_msg.Sender := machineID;
        out_msg.Destination.add(persistentTable.findSmallest(address));
        out_msg.Tokens := getDirectoryEntry(address).Tokens;
        out_msg.MessageSize := MessageSizeType:Response_Control;
      }
      getDirectoryEntry(address).Tokens := 0;
    }
  }

  action(d_sendMemoryDataWithAllTokens, "d", desc="Send data and tokens to requestor") {
    peek(memQueue_in, MemoryMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceResponseType:DATA_OWNER;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
        assert(getDirectoryEntry(address).Tokens > 0);
        out_msg.Tokens := getDirectoryEntry(in_msg.Addr).Tokens;
        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
        out_msg.Dirty := false;
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
    getDirectoryEntry(address).Tokens := 0;
  }

  action(dd_sendMemDataToStarver, "\d", desc="Send data and tokens to starver") {
    peek(memQueue_in, MemoryMsg) {
      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));
        assert(getDirectoryEntry(address).Tokens > 0);
        out_msg.Tokens := getDirectoryEntry(address).Tokens;
        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
        out_msg.Dirty := false;
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
    getDirectoryEntry(address).Tokens := 0;
  }

  action(de_sendTbeDataToStarver, "de", desc="Send data and tokens to starver") {
    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));
      assert(getDirectoryEntry(address).Tokens > 0);
      out_msg.Tokens := getDirectoryEntry(address).Tokens;
      out_msg.DataBlk := tbe.DataBlk;
      out_msg.Dirty := false;
      out_msg.MessageSize := MessageSizeType:Response_Data;
    }
    getDirectoryEntry(address).Tokens := 0;
  }

  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
    peek(requestNetwork_in, RequestMsg) {
      enqueue(memQueue_out, MemoryMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_READ;
        out_msg.Sender := machineID;
        out_msg.OriginalRequestorMachId := in_msg.Requestor;
        out_msg.MessageSize := in_msg.MessageSize;
        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
        DPRINTF(RubySlicc, "%s\n", out_msg);
      }
    }
  }

  action(qp_queueMemoryForPersistent, "qp", desc="Queue off-chip fetch request") {
    enqueue(memQueue_out, MemoryMsg, 1) {
      out_msg.Addr := address;
      out_msg.Type := MemoryRequestType:MEMORY_READ;
      out_msg.Sender := machineID;
      out_msg.OriginalRequestorMachId := persistentTable.findSmallest(address);
      out_msg.MessageSize := MessageSizeType:Request_Control;
      out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
  }

  action(fd_memoryDma, "fd", desc="Queue off-chip fetch request") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      enqueue(memQueue_out, MemoryMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_READ;
        out_msg.Sender := machineID;
        out_msg.OriginalRequestorMachId := in_msg.Requestor;
        out_msg.MessageSize := in_msg.MessageSize;
        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
        DPRINTF(RubySlicc, "%s\n", out_msg);
      }
    }
  }

  action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
    enqueue(memQueue_out, MemoryMsg, 1) {
      out_msg.Addr := address;
      out_msg.Type := MemoryRequestType:MEMORY_WB;
      out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
  }

  action(ld_queueMemoryDmaWriteFromTbe, "ld", desc="Write DMA data to memory") {
    enqueue(memQueue_out, MemoryMsg, 1) {
      out_msg.Addr := address;
      out_msg.Type := MemoryRequestType:MEMORY_WB;
      // first, initialize the data blk to the current version of system memory
      out_msg.DataBlk := tbe.DataBlk;
      // then add the dma write data
      out_msg.DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
  }

  action(lr_queueMemoryDmaReadWriteback, "lr", desc="Write DMA data from read to memory") {
    enqueue(memQueue_out, MemoryMsg, 1) {
      out_msg.Addr := address;
      out_msg.Type := MemoryRequestType:MEMORY_WB;
      // first, initialize the data blk to the current version of system memory
      out_msg.DataBlk := tbe.DataBlk;
      DPRINTF(RubySlicc, "%s\n", out_msg);
    }
  }

  action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      TBEs.allocate(address);
      set_tbe(TBEs[address]);
      tbe.DmaDataBlk := in_msg.DataBlk;
      tbe.PhysicalAddress := in_msg.PhysicalAddress;
      tbe.Len := in_msg.Len;
      tbe.DmaRequestor := in_msg.Requestor;
      tbe.WentPersistent := false;
    }
  }

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

    if (tbe.WentPersistent) {
      assert(starving);

      enqueue(persistentNetwork_out, PersistentMsg, 1) {
        out_msg.Addr := address;
        out_msg.Type := PersistentRequestType:DEACTIVATE_PERSISTENT;
        out_msg.Requestor := machineID;
        out_msg.Destination.broadcast(MachineType:L1Cache);

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

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

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

    TBEs.deallocate(address);
    unset_tbe();
  }

  action(rd_recordDataInTbe, "rd", desc="Record data in TBE") {
    peek(responseNetwork_in, ResponseMsg) {
      tbe.DataBlk := in_msg.DataBlk;
    }
  }

  action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") {
    tbe.DataBlk := getDirectoryEntry(address).DataBlk;
  }

  action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
    getDirectoryEntry(address).DataBlk := tbe.DataBlk;
    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
  }

  action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(in_msg.Tokens >= 1);
      getDirectoryEntry(address).Tokens := getDirectoryEntry(address).Tokens + in_msg.Tokens;
    }
  }

  action(aat_assertAllTokens, "aat", desc="assert that we have all tokens") {
    assert(getDirectoryEntry(address).Tokens == max_tokens());
  }

  action(j_popIncomingRequestQueue, "j", desc="Pop incoming request queue") {
    requestNetwork_in.dequeue();
  }

  action(z_recycleRequest, "z", desc="Recycle the request queue") {
    requestNetwork_in.recycle();
  }

  action(k_popIncomingResponseQueue, "k", desc="Pop incoming response queue") {
    responseNetwork_in.dequeue();
  }

  action(kz_recycleResponse, "kz", desc="Recycle incoming response queue") {
    responseNetwork_in.recycle();
  }

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

  action(p_popDmaRequestQueue, "pd", desc="pop dma request queue") {
    dmaRequestQueue_in.dequeue();
  }

  action(y_recycleDmaRequestQueue, "y", desc="recycle dma request queue") {
    dmaRequestQueue_in.recycle();
  }

  action(l_popMemQueue, "q", desc="Pop off-chip request queue") {
    memQueue_in.dequeue();
  }

  action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
    peek(responseNetwork_in, ResponseMsg) {
      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
              in_msg.Addr, in_msg.DataBlk);
    }
  }

  action(n_checkData, "n", desc="Check incoming clean data message") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(getDirectoryEntry(in_msg.Addr).DataBlk == in_msg.DataBlk);
    }
  }

  action(r_bounceResponse, "r", desc="Bounce response to starving processor") {
    peek(responseNetwork_in, ResponseMsg) {
      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.MessageSize := in_msg.MessageSize;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Dirty := in_msg.Dirty;
      }
    }
  }

  action(rs_resetScheduleTimeout, "rs", desc="Reschedule Schedule Timeout") {
    //
    // currently only support a fixed timeout latency
    //
    if (reissueTimerTable.isSet(address)) {
      reissueTimerTable.unset(address);
      reissueTimerTable.set(address, fixed_timeout_latency);
    }
  }

  action(st_scheduleTimeout, "st", desc="Schedule Timeout") {
    //
    // currently only support a fixed timeout latency
    //
    reissueTimerTable.set(address, fixed_timeout_latency);
  }

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

  action(bd_bounceDatalessOwnerToken, "bd", desc="Bounce clean owner token to starving processor") {
    peek(responseNetwork_in, ResponseMsg) {
      assert(in_msg.Type == CoherenceResponseType:ACK_OWNER);
      assert(in_msg.Dirty == false);
      assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);

      // NOTE: The following check would not be valid in a real
      // implementation.  We include the data in the "dataless"
      // message so we can assert the clean data matches the datablock
      // in memory
      assert(getDirectoryEntry(in_msg.Addr).DataBlk == in_msg.DataBlk);

      // Bounce the message, but "re-associate" the data and the owner
      // token.  In essence we're converting an ACK_OWNER message to a
      // DATA_OWNER message, keeping the number of tokens the same.
      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 := getDirectoryEntry(in_msg.Addr).DataBlk;
        out_msg.Dirty := in_msg.Dirty;
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

  action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") {
    enqueue(dmaResponseNetwork_out, DMAResponseMsg, 1) {
      out_msg.PhysicalAddress := address;
      out_msg.LineAddress := address;
      out_msg.Type := DMAResponseType:ACK;
      out_msg.Destination.add(tbe.DmaRequestor);
      out_msg.MessageSize := MessageSizeType:Writeback_Control;
    }
  }

  action(dm_sendMemoryDataToDma, "dm", desc="Send Data to DMA controller from memory") {
    peek(memQueue_in, MemoryMsg) {
      enqueue(dmaResponseNetwork_out, DMAResponseMsg, 1) {
        out_msg.PhysicalAddress := address;
        out_msg.LineAddress := address;
        out_msg.Type := DMAResponseType:DATA;
        //
        // we send the entire data block and rely on the dma controller to
        // split it up if need be
        //
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Destination.add(tbe.DmaRequestor);
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

  action(dd_sendDmaData, "dd", desc="Send Data to DMA controller") {
    peek(responseNetwork_in, ResponseMsg) {
      enqueue(dmaResponseNetwork_out, DMAResponseMsg, 1) {
        out_msg.PhysicalAddress := address;
        out_msg.LineAddress := address;
        out_msg.Type := DMAResponseType:DATA;
        //
        // we send the entire data block and rely on the dma controller to
        // split it up if need be
        //
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Destination.add(tbe.DmaRequestor);
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

  // TRANSITIONS

  //
  // Trans. from base state O
  // the directory has valid data
  //
  transition(O, GETX, NO_W) {
    qf_queueMemoryFetchRequest;
    j_popIncomingRequestQueue;
  }

  transition(O, DMA_WRITE, O_DW) {
    vd_allocateDmaRequestInTBE;
    cd_writeCleanDataToTbe;
    bw_broadcastWrite;
    st_scheduleTimeout;
    p_popDmaRequestQueue;
  }

  transition(O, DMA_WRITE_All_Tokens, O_DW_W) {
    vd_allocateDmaRequestInTBE;
    cd_writeCleanDataToTbe;
    dwt_writeDmaDataFromTBE;
    ld_queueMemoryDmaWriteFromTbe;
    p_popDmaRequestQueue;
  }

  transition(O, GETS, NO_W) {
    qf_queueMemoryFetchRequest;
    j_popIncomingRequestQueue;
  }

  transition(O, DMA_READ, O_DR_W) {
    vd_allocateDmaRequestInTBE;
    fd_memoryDma;
    st_scheduleTimeout;
    p_popDmaRequestQueue;
  }

  transition(O, Lockdown, L_O_W) {
    qp_queueMemoryForPersistent;
    l_popIncomingPersistentQueue;
  }

  transition(O, {Tokens, Ack_All_Tokens}) {
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  transition(O, {Data_Owner, Data_All_Tokens}) {
    n_checkData;
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  transition({O, NO}, Unlockdown) {
    l_popIncomingPersistentQueue;
  }

  //
  // transitioning to Owner, waiting for memory before DMA ack
  // All other events should recycle/stall
  //
  transition(O_DR_W, Memory_Data, O) {
    dm_sendMemoryDataToDma;
    ut_unsetReissueTimer;
    s_deallocateTBE;
    l_popMemQueue;
  }

  //
  // issued GETX for DMA write, waiting for all tokens
  //
  transition(O_DW, Request_Timeout) {
    ut_unsetReissueTimer;
    px_tryIssuingPersistentGETXRequest;
  }

  transition(O_DW, Tokens) {
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  transition(O_DW, Data_Owner) {
    f_incrementTokens;
    rd_recordDataInTbe;
    k_popIncomingResponseQueue;
  }

  transition(O_DW, Ack_Owner) {
    f_incrementTokens;
    cd_writeCleanDataToTbe;
    k_popIncomingResponseQueue;
  }

  transition(O_DW, Lockdown, DW_L) {
    de_sendTbeDataToStarver;
    l_popIncomingPersistentQueue;
  }

  transition({NO_DW, O_DW}, Data_All_Tokens, O_DW_W) {
    f_incrementTokens;
    rd_recordDataInTbe;
    dwt_writeDmaDataFromTBE;
    ld_queueMemoryDmaWriteFromTbe;
    ut_unsetReissueTimer;
    k_popIncomingResponseQueue;
  }

  transition(O_DW, Ack_All_Tokens, O_DW_W) {
    f_incrementTokens;
    dwt_writeDmaDataFromTBE;
    ld_queueMemoryDmaWriteFromTbe;
    ut_unsetReissueTimer;
    k_popIncomingResponseQueue;
  }

  transition(O_DW, Ack_Owner_All_Tokens, O_DW_W) {
    f_incrementTokens;
    cd_writeCleanDataToTbe;
    dwt_writeDmaDataFromTBE;
    ld_queueMemoryDmaWriteFromTbe;
    ut_unsetReissueTimer;
    k_popIncomingResponseQueue;
  }

  transition(O_DW_W, Memory_Ack, O) {
    da_sendDmaAck;
    s_deallocateTBE;
    l_popMemQueue;
  }

  //
  // Trans. from NO
  // The direcotry does not have valid data, but may have some tokens
  //
  transition(NO, GETX) {
    a_sendTokens;
    j_popIncomingRequestQueue;
  }

  transition(NO, DMA_WRITE, NO_DW) {
    vd_allocateDmaRequestInTBE;
    bw_broadcastWrite;
    st_scheduleTimeout;
    p_popDmaRequestQueue;
  }

  transition(NO, GETS) {
    j_popIncomingRequestQueue;
  }

  transition(NO, DMA_READ, NO_DR) {
    vd_allocateDmaRequestInTBE;
    br_broadcastRead;
    st_scheduleTimeout;
    p_popDmaRequestQueue;
  }

  transition(NO, Lockdown, L) {
    aa_sendTokensToStarver;
    l_popIncomingPersistentQueue;
  }

  transition(NO, {Data_Owner, Data_All_Tokens}, O_W) {
    m_writeDataToMemory;
    f_incrementTokens;
    lq_queueMemoryWbRequest;
    k_popIncomingResponseQueue;
  }

  transition(NO, {Ack_Owner, Ack_Owner_All_Tokens}, O) {
    n_checkData;
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  transition(NO, Tokens) {
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  transition(NO_W, Memory_Data, NO) {
    d_sendMemoryDataWithAllTokens;
    l_popMemQueue;
  }

  // Trans. from NO_DW
  transition(NO_DW, Request_Timeout) {
    ut_unsetReissueTimer;
    px_tryIssuingPersistentGETXRequest;
  }

  transition(NO_DW, Lockdown, DW_L) {
    aa_sendTokensToStarver;
    l_popIncomingPersistentQueue;
  }

  // Note: NO_DW, Data_All_Tokens transition is combined with O_DW
  // Note: NO_DW should not receive the action Ack_All_Tokens because the
  // directory does not have valid data

  transition(NO_DW, Data_Owner, O_DW) {
    f_incrementTokens;
    rd_recordDataInTbe;
    k_popIncomingResponseQueue;
  }

  transition({NO_DW, NO_DR}, Tokens) {
    f_incrementTokens;
    k_popIncomingResponseQueue;
  }

  // Trans. from NO_DR
  transition(NO_DR, Request_Timeout) {
    ut_unsetReissueTimer;
    ps_tryIssuingPersistentGETSRequest;
  }

  transition(NO_DR, Lockdown, DR_L) {
    aa_sendTokensToStarver;
    l_popIncomingPersistentQueue;
  }

  transition(NO_DR, {Data_Owner, Data_All_Tokens}, O_W) {
    m_writeDataToMemory;
    f_incrementTokens;
    dd_sendDmaData;
    lr_queueMemoryDmaReadWriteback;
    ut_unsetReissueTimer;
    s_deallocateTBE;
    k_popIncomingResponseQueue;
  }

  // Trans. from L
  transition({L, DW_L, DR_L}, {GETX, GETS}) {
    j_popIncomingRequestQueue;
  }

  transition({L, DW_L, DR_L, L_O_W, L_NO_W, DR_L_W, DW_L_W}, Lockdown) {
    l_popIncomingPersistentQueue;
  }

  //
  // Received data for lockdown blocks
  // For blocks with outstanding dma requests to them
  // ...we could change this to write the data to memory and send it cleanly
  // ...we could also proactively complete our DMA requests
  // However, to keep my mind from spinning out-of-control, we won't for now :)
  //
  transition({DW_L, DR_L, L}, {Data_Owner, Data_All_Tokens}) {
    r_bounceResponse;
    k_popIncomingResponseQueue;
  }

  transition({DW_L, DR_L, L}, Tokens) {
    r_bounceResponse;
    k_popIncomingResponseQueue;
  }

  transition({DW_L, DR_L, L}, {Ack_Owner_All_Tokens, Ack_Owner}) {
    bd_bounceDatalessOwnerToken;
    k_popIncomingResponseQueue;
  }

  transition(L, {Unlockdown, Own_Lock_or_Unlock}, NO) {
    l_popIncomingPersistentQueue;
  }

  transition(L, Own_Lock_or_Unlock_Tokens, O) {
    l_popIncomingPersistentQueue;
  }

  transition({L_NO_W, L_O_W}, Memory_Data, L) {
    dd_sendMemDataToStarver;
    l_popMemQueue;
  }

  transition(L_O_W, Memory_Ack) {
    qp_queueMemoryForPersistent;
    l_popMemQueue;
  }

  transition(L_O_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_W) {
    l_popIncomingPersistentQueue;
  }

  transition(L_NO_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_W) {
    l_popIncomingPersistentQueue;
  }

  transition(DR_L_W, Memory_Data, DR_L) {
    dd_sendMemDataToStarver;
    l_popMemQueue;
  }

  transition(DW_L_W, Memory_Ack, L) {
    aat_assertAllTokens;
    da_sendDmaAck;
    s_deallocateTBE;
    dd_sendMemDataToStarver;
    l_popMemQueue;
  }

  transition(DW_L, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_DW) {
    l_popIncomingPersistentQueue;
  }

  transition(DR_L_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_DR_W) {
    l_popIncomingPersistentQueue;
  }

  transition(DW_L_W, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, O_DW_W) {
    l_popIncomingPersistentQueue;
  }

  transition({DW_L, DR_L_W, DW_L_W}, Request_Timeout) {
    ut_unsetReissueTimer;
    px_tryIssuingPersistentGETXRequest;
  }

  transition(DR_L, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}, NO_DR) {
    l_popIncomingPersistentQueue;
  }

  transition(DR_L, Request_Timeout) {
    ut_unsetReissueTimer;
    ps_tryIssuingPersistentGETSRequest;
  }

  //
  // The O_W + Memory_Data > O transistion is confusing, but it can happen if a
  // presistent request is issued and resolve before memory returns with data
  //
  transition(O_W, {Memory_Ack, Memory_Data}, O) {
    l_popMemQueue;
  }

  transition({O, NO}, {Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}) {
    l_popIncomingPersistentQueue;
  }

  // Blocked states
  transition({NO_W, O_W, L_O_W, L_NO_W, DR_L_W, DW_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR}, {GETX, GETS}) {
    z_recycleRequest;
  }

  transition({NO_W, O_W, L_O_W, L_NO_W, DR_L_W, DW_L_W, O_DW_W, O_DR_W, O_DW, NO_DW, NO_DR, L, DW_L, DR_L}, {DMA_READ, DMA_WRITE, DMA_WRITE_All_Tokens}) {
    y_recycleDmaRequestQueue;
  }

  transition({NO_W, O_W, L_O_W, L_NO_W, DR_L_W, DW_L_W, O_DW_W, O_DR_W}, {Data_Owner, Ack_Owner, Tokens, Data_All_Tokens, Ack_All_Tokens}) {
    kz_recycleResponse;
  }

  //
  // If we receive a request timeout while waiting for memory, it is likely that
  // the request will be satisfied and issuing a presistent request will do us
  // no good.  Just wait.
  //
  transition({O_DW_W, O_DR_W}, Request_Timeout) {
    rs_resetScheduleTimeout;
  }

  transition(NO_W, Lockdown, L_NO_W) {
    l_popIncomingPersistentQueue;
  }

  transition(O_W, Lockdown, L_O_W) {
    l_popIncomingPersistentQueue;
  }

  transition(O_DR_W, Lockdown, DR_L_W) {
    l_popIncomingPersistentQueue;
  }

  transition(O_DW_W, Lockdown, DW_L_W) {
    l_popIncomingPersistentQueue;
  }

  transition({NO_W, O_W, O_DR_W, O_DW_W, O_DW, NO_DR, NO_DW}, {Unlockdown, Own_Lock_or_Unlock, Own_Lock_or_Unlock_Tokens}) {
    l_popIncomingPersistentQueue;
  }
}
