/*
 * 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, "Directory protocol")
:  DirectoryMemory * directory;
   Cycles directory_latency := 6;
   Cycles to_memory_controller_latency := 1;

   // Message Queues
   MessageBuffer * requestToDir, network="From", virtual_network="1",
        ordered="false", vnet_type="request";  // a mod-L2 bank -> this Dir
   MessageBuffer * responseToDir, network="From", virtual_network="2",
        ordered="false", vnet_type="response";  // a mod-L2 bank -> this Dir

   MessageBuffer * forwardFromDir, network="To", virtual_network="1",
        ordered="false", vnet_type="forward";
   MessageBuffer * responseFromDir, network="To", virtual_network="2",
        ordered="false", vnet_type="response";  // Dir -> mod-L2 bank

{
  // STATES
  state_declaration(State, desc="Directory states", default="Directory_State_I") {
    // Base states
    I, AccessPermission:Read_Write, desc="Invalid";
    S, AccessPermission:Read_Only, desc="Shared";
    O, AccessPermission:Maybe_Stale, desc="Owner";
    M, AccessPermission:Maybe_Stale, desc="Modified";

    IS, AccessPermission:Busy, desc="Blocked, was in idle";
    SS, AccessPermission:Read_Only, desc="Blocked, was in shared";
    OO, AccessPermission:Busy, desc="Blocked, was in owned";
    MO, AccessPermission:Busy, desc="Blocked, going to owner or maybe modified";
    MM, AccessPermission:Busy, desc="Blocked, going to modified";
    MM_DMA, AccessPermission:Busy, desc="Blocked, going to I";

    MI, AccessPermission:Busy, desc="Blocked on a writeback";
    MIS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";
    OS, AccessPermission:Busy, desc="Blocked on a writeback";
    OSS, AccessPermission:Busy, desc="Blocked on a writeback, but don't remove from sharers when received";

    XI_M, AccessPermission:Busy, desc="In a stable state, going to I, waiting for the memory controller";
    XI_U, AccessPermission:Busy, desc="In a stable state, going to I, waiting for an unblock";
    OI_D, AccessPermission:Busy, desc="In O, going to I, waiting for data";

    OD, AccessPermission:Busy, desc="In O, waiting for dma ack from L2";
    MD, AccessPermission:Busy, desc="In M, waiting for dma ack from L2";
  }

  // Events
  enumeration(Event, desc="Directory events") {
    GETX, desc="A GETX arrives";
    GETS, desc="A GETS arrives";
    PUTX, desc="A PUTX arrives";
    PUTO, desc="A PUTO arrives";
    PUTO_SHARERS, desc="A PUTO arrives, but don't remove from sharers list";
    Unblock, desc="An unblock message arrives";
    Last_Unblock, desc="An unblock message arrives, we're not waiting for any additional unblocks";
    Exclusive_Unblock, desc="The processor become the exclusive owner (E or M) of the line";
    Clean_Writeback, desc="The final message as part of a PutX/PutS, no data";
    Dirty_Writeback, desc="The final message as part of a PutX/PutS, contains data";
    Memory_Data,   desc="Fetched data from memory arrives";
    Memory_Ack,    desc="Writeback Ack from memory arrives";
    DMA_READ,      desc="DMA Read";
    DMA_WRITE,     desc="DMA Write";
    DMA_ACK,       desc="DMA Ack";
    Data,          desc="Data to directory";
  }

  // TYPES

  // DirectoryEntry
  structure(Entry, desc="...", interface='AbstractEntry') {
    State DirectoryState,          desc="Directory state";
    NetDest Sharers,                   desc="Sharers for this block";
    NetDest Owner,                     desc="Owner of this block";
    int WaitingUnblocks,           desc="Number of acks we're waiting for";
  }

  structure(TBE, desc="...") {
    Address PhysicalAddress,   desc="Physical address for this entry";
    int Len,           desc="Length of request";
    DataBlock DataBlk, desc="DataBlk";
    MachineID Requestor, desc="original requestor";
  }

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

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

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

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

  void setState(TBE tbe, Address addr, State state) {
    if (directory.isPresent(addr)) {

      if (state == State:I) {
        assert(getDirectoryEntry(addr).Owner.count() == 0);
        assert(getDirectoryEntry(addr).Sharers.count() == 0);
      }

      if (state == State:S) {
        assert(getDirectoryEntry(addr).Owner.count() == 0);
      }

      if (state == State:O) {
        assert(getDirectoryEntry(addr).Owner.count() == 1);
        assert(getDirectoryEntry(addr).Sharers.isSuperset(getDirectoryEntry(addr).Owner) == false);
      }

      if (state == State:M) {
        assert(getDirectoryEntry(addr).Owner.count() == 1);
        assert(getDirectoryEntry(addr).Sharers.count() == 0);
      }

      if ((state != State:SS) && (state != State:OO)) {
        assert(getDirectoryEntry(addr).WaitingUnblocks == 0);
      }

      if ( (getDirectoryEntry(addr).DirectoryState != State:I) && (state == State:I) ) {
        getDirectoryEntry(addr).DirectoryState := state;
         // disable coherence checker
        // sequencer.checkCoherence(addr);
      }
      else {
        getDirectoryEntry(addr).DirectoryState := state;
      }
    }
  }

  AccessPermission getAccessPermission(Address addr) {
    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) {
    if (directory.isPresent(addr)) {
      getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state));
    }
  }

  void functionalRead(Address addr, Packet *pkt) {
    functionalMemoryRead(pkt);
  }

  int functionalWrite(Address addr, Packet *pkt) {
    int num_functional_writes := 0;
    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
    return num_functional_writes;
  }

  // if no sharers, then directory can be considered
  // both a sharer and exclusive w.r.t. coherence checking
  bool isBlockShared(Address addr) {
    if (directory.isPresent(addr)) {
      if (getDirectoryEntry(addr).DirectoryState == State:I) {
        return true;
      }
    }
    return false;
  }

  bool isBlockExclusive(Address addr) {
    if (directory.isPresent(addr)) {
      if (getDirectoryEntry(addr).DirectoryState == State:I) {
        return true;
      }
    }
    return false;
  }


  // ** OUT_PORTS **
  out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
  out_port(responseNetwork_out, ResponseMsg, responseFromDir);

  // ** IN_PORTS **

  in_port(unblockNetwork_in, ResponseMsg, responseToDir) {
    if (unblockNetwork_in.isReady()) {
      peek(unblockNetwork_in, ResponseMsg) {
        if (in_msg.Type == CoherenceResponseType:UNBLOCK) {
          if (getDirectoryEntry(in_msg.Addr).WaitingUnblocks == 1) {
            trigger(Event:Last_Unblock, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          } else {
            trigger(Event:Unblock, in_msg.Addr,
                    TBEs[in_msg.Addr]);
          }
        } else if (in_msg.Type == CoherenceResponseType:UNBLOCK_EXCLUSIVE) {
          trigger(Event:Exclusive_Unblock, in_msg.Addr,
                  TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) {
          trigger(Event:Dirty_Writeback, in_msg.Addr,
                  TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceResponseType:WRITEBACK_CLEAN_ACK) {
          trigger(Event:Clean_Writeback, in_msg.Addr,
                  TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
          trigger(Event:Data, in_msg.Addr,
                  TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceResponseType:DMA_ACK) {
          trigger(Event:DMA_ACK, in_msg.Addr,
                  TBEs[in_msg.Addr]);
        } else {
          error("Invalid message");
        }
      }
    }
  }

  in_port(requestQueue_in, RequestMsg, requestToDir) {
    if (requestQueue_in.isReady()) {
      peek(requestQueue_in, RequestMsg) {
        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 if (in_msg.Type == CoherenceRequestType:PUTX) {
          trigger(Event:PUTX, in_msg.Addr, TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceRequestType:PUTO) {
          trigger(Event:PUTO, in_msg.Addr, TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceRequestType:PUTO_SHARERS) {
          trigger(Event:PUTO_SHARERS, in_msg.Addr, TBEs[in_msg.Addr]);
        } else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
          trigger(Event:DMA_READ, makeLineAddress(in_msg.Addr),
                  TBEs[makeLineAddress(in_msg.Addr)]);
        } else if (in_msg.Type == CoherenceRequestType:DMA_WRITE) {
          trigger(Event:DMA_WRITE, makeLineAddress(in_msg.Addr),
                  TBEs[makeLineAddress(in_msg.Addr)]);
        } else {
          error("Invalid message");
        }
      }
    }
  }

  // off-chip memory request/response is done
  in_port(memQueue_in, MemoryMsg, responseFromMemory) {
    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");
        }
      }
    }
  }

  // Actions

  action(a_sendWriteBackAck, "a", desc="Send writeback ack to requestor") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceRequestType:WB_ACK;
        out_msg.Requestor := in_msg.Requestor;
        out_msg.RequestorMachine := MachineType:Directory;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(b_sendWriteBackNack, "b", desc="Send writeback nack to requestor") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.Addr := address;
        out_msg.Type := CoherenceRequestType:WB_NACK;
        out_msg.Requestor := in_msg.Requestor;
        out_msg.RequestorMachine := MachineType:Directory;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(c_clearOwner, "c", desc="Clear the owner field") {
    getDirectoryEntry(address).Owner.clear();
  }

  action(c_moveOwnerToSharer, "cc", desc="Move owner to sharers") {
    getDirectoryEntry(address).Sharers.addNetDest(getDirectoryEntry(address).Owner);
    getDirectoryEntry(address).Owner.clear();
  }

  action(cc_clearSharers, "\c", desc="Clear the sharers field") {
    getDirectoryEntry(address).Sharers.clear();
  }

  action(d_sendDataMsg, "d", desc="Send data to requestor") {
    peek(memQueue_in, MemoryMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.Addr := address;
        out_msg.Sender := machineID;
        out_msg.SenderMachine := MachineType:Directory;
        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Dirty := false; // By definition, the block is now clean
        out_msg.Acks := in_msg.Acks;
        if (in_msg.ReadX) {
          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
        } else {
          out_msg.Type := CoherenceResponseType:DATA;
        }
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

  action(p_fwdDataToDMA, "\d", desc="Send data to requestor") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.Addr := address;
        out_msg.Sender := machineID;
        out_msg.SenderMachine := MachineType:Directory;
        out_msg.Destination.add(in_msg.Requestor);
        out_msg.Dirty := false; // By definition, the block is now clean
        out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

  action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") {
    peek(unblockNetwork_in, ResponseMsg) {
      getDirectoryEntry(address).Owner.clear();
      getDirectoryEntry(address).Owner.add(in_msg.Sender);
    }
  }

  action(f_forwardRequest, "f", desc="Forward request to owner") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.Addr := address;
        out_msg.Type := in_msg.Type;
        out_msg.Requestor := in_msg.Requestor;
        out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
        out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Addr).Owner);
        out_msg.Acks := getDirectoryEntry(address).Sharers.count();
        if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
          out_msg.Acks := out_msg.Acks - 1;
        }
        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
      }
    }
  }

  action(f_forwardRequestDirIsRequestor, "\f", desc="Forward request to owner") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.Addr := address;
        out_msg.Type := in_msg.Type;
        out_msg.Requestor := machineID;
        out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
        out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Addr).Owner);
        out_msg.Acks := getDirectoryEntry(address).Sharers.count();
        if (getDirectoryEntry(address).Sharers.isElement(in_msg.Requestor)) {
          out_msg.Acks := out_msg.Acks - 1;
        }
        out_msg.MessageSize := MessageSizeType:Forwarded_Control;
      }
    }
  }

  action(g_sendInvalidations, "g", desc="Send invalidations to sharers, not including the requester") {
    peek(requestQueue_in, RequestMsg) {
      if ((getDirectoryEntry(in_msg.Addr).Sharers.count() > 1) ||
          ((getDirectoryEntry(in_msg.Addr).Sharers.count() > 0) &&
           (getDirectoryEntry(in_msg.Addr).Sharers.isElement(in_msg.Requestor) == false))) {
        enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
          out_msg.Addr := address;
          out_msg.Type := CoherenceRequestType:INV;
          out_msg.Requestor := in_msg.Requestor;
          out_msg.RequestorMachine := machineIDToMachineType(in_msg.Requestor);
          // out_msg.Destination := getDirectoryEntry(in_msg.Addr).Sharers;
          out_msg.Destination.addNetDest(getDirectoryEntry(in_msg.Addr).Sharers);
          out_msg.Destination.remove(in_msg.Requestor);
          out_msg.MessageSize := MessageSizeType:Invalidate_Control;
        }
      }
    }
  }

  action(i_popIncomingRequestQueue, "i", desc="Pop incoming request queue") {
    requestQueue_in.dequeue();
  }

  action(j_popIncomingUnblockQueue, "j", desc="Pop incoming unblock queue") {
    unblockNetwork_in.dequeue();
  }

  action(m_addUnlockerToSharers, "m", desc="Add the unlocker to the sharer list") {
    peek(unblockNetwork_in, ResponseMsg) {
      getDirectoryEntry(address).Sharers.add(in_msg.Sender);
    }
  }

  action(n_incrementOutstanding, "n", desc="Increment outstanding requests") {
    getDirectoryEntry(address).WaitingUnblocks := getDirectoryEntry(address).WaitingUnblocks + 1;
  }

  action(o_decrementOutstanding, "o", desc="Decrement outstanding requests") {
    getDirectoryEntry(address).WaitingUnblocks := getDirectoryEntry(address).WaitingUnblocks - 1;
    assert(getDirectoryEntry(address).WaitingUnblocks >= 0);
  }

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

  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
    peek(requestQueue_in, RequestMsg) {
      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
    }
  }

  action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
    peek(unblockNetwork_in, ResponseMsg) {
      if (is_valid(tbe)) {
        queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
                         in_msg.DataBlk);
      } else {
        queueMemoryWrite(in_msg.Sender, address, to_memory_controller_latency,
                         in_msg.DataBlk);
      }
    }
  }

  action(qw_queueMemoryWBRequestFromMessageAndTBE, "qwmt",
    desc="Queue off-chip writeback request") {
    peek(unblockNetwork_in, ResponseMsg) {
      DataBlock DataBlk := in_msg.DataBlk;
      DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress),
                          tbe.Len);
      queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
                       DataBlk);
    }
  }

  action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") {
    peek(requestQueue_in, RequestMsg) {
      queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
                       in_msg.DataBlk);
    }
  }

  action(zz_recycleRequest, "\z", desc="Recycle the request queue") {
    requestQueue_in.recycle();
  }

  action(a_sendDMAAck, "\a", desc="Send DMA Ack that write completed, along with Inv Ack count") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
      out_msg.Addr := address;
      out_msg.Sender := machineID;
      out_msg.SenderMachine := MachineType:Directory;
      out_msg.Destination.add(in_msg.Requestor);
      out_msg.DataBlk := in_msg.DataBlk;
      out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
      out_msg.Type := CoherenceResponseType:DMA_ACK;
      out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(a_sendDMAAck2, "\aa", desc="Send DMA Ack that write completed, along with Inv Ack count") {
    peek(unblockNetwork_in, ResponseMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
      out_msg.Addr := address;
      out_msg.Sender := machineID;
      out_msg.SenderMachine := MachineType:Directory;
      if (is_valid(tbe)) {
        out_msg.Destination.add(tbe.Requestor);
      }
      out_msg.DataBlk := in_msg.DataBlk;
      out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
      out_msg.Type := CoherenceResponseType:DMA_ACK;
      out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(v_allocateTBE, "v", desc="Allocate TBE entry") {
    peek (requestQueue_in, RequestMsg) {
      TBEs.allocate(address);
      set_tbe(TBEs[address]);
      tbe.PhysicalAddress := in_msg.Addr;
      tbe.Len := in_msg.Len;
      tbe.DataBlk := in_msg.DataBlk;
      tbe.Requestor := in_msg.Requestor;
    }
  }

  action(w_deallocateTBE, "w", desc="Deallocate TBE entry") {
    TBEs.deallocate(address);
    unset_tbe();
  }


  // TRANSITIONS
  transition(I, GETX, MM) {
    qf_queueMemoryFetchRequest;
    i_popIncomingRequestQueue;
  }

  transition(I, DMA_READ, XI_M) {
    qf_queueMemoryFetchRequest;
    i_popIncomingRequestQueue;
  }

  transition(I, DMA_WRITE, XI_U) {
    qw_queueMemoryWBRequest2;
    a_sendDMAAck;  // ack count may be zero
    i_popIncomingRequestQueue;
  }

  transition(XI_M, Memory_Data, I) {
    d_sendDataMsg;  // ack count may be zero
    q_popMemQueue;
  }

  transition(XI_U, Exclusive_Unblock, I) {
    cc_clearSharers;
    c_clearOwner;
    j_popIncomingUnblockQueue;
  }

  transition(S, GETX, MM) {
    qf_queueMemoryFetchRequest;
    g_sendInvalidations;
    i_popIncomingRequestQueue;
  }

  transition(S, DMA_READ) {
    //qf_queueMemoryFetchRequest;
    p_fwdDataToDMA;
    //g_sendInvalidations;  // the DMA will collect the invalidations then send an Unblock Exclusive
    i_popIncomingRequestQueue;
  }

  transition(S, DMA_WRITE, XI_U) {
    qw_queueMemoryWBRequest2;
    a_sendDMAAck;  // ack count may be zero
    g_sendInvalidations;  // the DMA will collect invalidations
    i_popIncomingRequestQueue;
  }

  transition(I, GETS, IS) {
    qf_queueMemoryFetchRequest;
    i_popIncomingRequestQueue;
  }

  transition({S, SS}, GETS, SS) {
    qf_queueMemoryFetchRequest;
    n_incrementOutstanding;
    i_popIncomingRequestQueue;
  }

  transition({I, S}, PUTO) {
    b_sendWriteBackNack;
    i_popIncomingRequestQueue;
  }

  transition({I, S, O}, PUTX) {
    b_sendWriteBackNack;
    i_popIncomingRequestQueue;
  }

  transition(O, GETX, MM) {
    f_forwardRequest;
    g_sendInvalidations;
    i_popIncomingRequestQueue;
  }

  transition(O, DMA_READ, OD) {
    f_forwardRequest;     // this will cause the data to go to DMA directly
    //g_sendInvalidations;  // this will cause acks to be sent to the DMA
    i_popIncomingRequestQueue;
  }

  transition(OD, DMA_ACK, O) {
    j_popIncomingUnblockQueue;
  }

  transition({O,M}, DMA_WRITE, OI_D) {
    f_forwardRequestDirIsRequestor;    // need the modified data before we can proceed
    g_sendInvalidations;               // these go to the DMA Controller
    v_allocateTBE;
    i_popIncomingRequestQueue;
  }

  transition(OI_D, Data, XI_U) {
    qw_queueMemoryWBRequestFromMessageAndTBE;
    a_sendDMAAck2;  // ack count may be zero
    w_deallocateTBE;
    j_popIncomingUnblockQueue;
  }

  transition({O, OO}, GETS, OO) {
    f_forwardRequest;
    n_incrementOutstanding;
    i_popIncomingRequestQueue;
  }

  transition(M, GETX, MM) {
    f_forwardRequest;
    i_popIncomingRequestQueue;
  }

  // no exclusive unblock will show up to the directory
  transition(M, DMA_READ, MD) {
    f_forwardRequest;     // this will cause the data to go to DMA directly
    i_popIncomingRequestQueue;
  }

  transition(MD, DMA_ACK, M) {
    j_popIncomingUnblockQueue;
  }

  transition(M, GETS, MO) {
    f_forwardRequest;
    i_popIncomingRequestQueue;
  }

  transition(M, PUTX, MI) {
    a_sendWriteBackAck;
    i_popIncomingRequestQueue;
  }

  // happens if M->O transition happens on-chip
  transition(M, PUTO, MI) {
    a_sendWriteBackAck;
    i_popIncomingRequestQueue;
  }

  transition(M, PUTO_SHARERS, MIS) {
    a_sendWriteBackAck;
    i_popIncomingRequestQueue;
  }

  transition(O, PUTO, OS) {
    a_sendWriteBackAck;
    i_popIncomingRequestQueue;
  }

  transition(O, PUTO_SHARERS, OSS) {
    a_sendWriteBackAck;
    i_popIncomingRequestQueue;
  }


  transition({MM, MO, MI, MIS, OS, OSS, XI_M, XI_U, OI_D, OD, MD}, {GETS, GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
    zz_recycleRequest;
  }

  transition({MM, MO}, Exclusive_Unblock, M) {
    cc_clearSharers;
    e_ownerIsUnblocker;
    j_popIncomingUnblockQueue;
  }

  transition(MO, Unblock, O) {
    m_addUnlockerToSharers;
    j_popIncomingUnblockQueue;
  }

  transition({IS, SS, OO}, {GETX, PUTO, PUTO_SHARERS, PUTX, DMA_READ, DMA_WRITE}) {
    zz_recycleRequest;
  }

  transition(IS, GETS) {
    zz_recycleRequest;
  }

  transition(IS, Unblock, S) {
    m_addUnlockerToSharers;
    j_popIncomingUnblockQueue;
  }

  transition(IS, Exclusive_Unblock, M) {
    cc_clearSharers;
    e_ownerIsUnblocker;
    j_popIncomingUnblockQueue;
  }

  transition(SS, Unblock) {
    m_addUnlockerToSharers;
    o_decrementOutstanding;
    j_popIncomingUnblockQueue;
  }

  transition(SS, Last_Unblock, S) {
    m_addUnlockerToSharers;
    o_decrementOutstanding;
    j_popIncomingUnblockQueue;
  }

  transition(OO, Unblock) {
    m_addUnlockerToSharers;
    o_decrementOutstanding;
    j_popIncomingUnblockQueue;
  }

  transition(OO, Last_Unblock, O) {
    m_addUnlockerToSharers;
    o_decrementOutstanding;
    j_popIncomingUnblockQueue;
  }

  transition(MI, Dirty_Writeback, I) {
    c_clearOwner;
    cc_clearSharers;
    qw_queueMemoryWBRequest;
    j_popIncomingUnblockQueue;
  }

  transition(MIS, Dirty_Writeback, S) {
    c_moveOwnerToSharer;
    qw_queueMemoryWBRequest;
    j_popIncomingUnblockQueue;
  }

  transition(MIS, Clean_Writeback, S) {
    c_moveOwnerToSharer;
    j_popIncomingUnblockQueue;
  }

  transition(OS, Dirty_Writeback, S) {
    c_clearOwner;
    qw_queueMemoryWBRequest;
    j_popIncomingUnblockQueue;
  }

  transition(OSS, Dirty_Writeback, S) {
    c_moveOwnerToSharer;
    qw_queueMemoryWBRequest;
    j_popIncomingUnblockQueue;
  }

  transition(OSS, Clean_Writeback, S) {
    c_moveOwnerToSharer;
    j_popIncomingUnblockQueue;
  }

  transition(MI, Clean_Writeback, I) {
    c_clearOwner;
    cc_clearSharers;
    j_popIncomingUnblockQueue;
  }

  transition(OS, Clean_Writeback, S) {
    c_clearOwner;
    j_popIncomingUnblockQueue;
  }

  transition({MI, MIS}, Unblock, M) {
    j_popIncomingUnblockQueue;
  }

  transition({OS, OSS}, Unblock, O) {
    j_popIncomingUnblockQueue;
  }

  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS}, Memory_Data) {
    d_sendDataMsg;
    q_popMemQueue;
  }

  transition({I, S, O, M, IS, SS, OO, MO, MM, MI, MIS, OS, OSS, XI_U, XI_M}, Memory_Ack) {
    //a_sendAck;
    q_popMemQueue;
  }

}
