/*
 * Copyright (c) 2019 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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(MachineType:Directory, "Directory protocol")
:  DirectoryMemory * directory;
   Cycles directory_latency := 6;
   Cycles to_memory_controller_latency := 1;

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

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

   MessageBuffer * responseFromMemory;
{
  // 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";

    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="...") {
    Addr 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(Addr);
    void allocate(Addr);
    void deallocate(Addr);
    bool isPresent(Addr);
  }

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

  Tick clockEdge();
  Tick cyclesToTicks(Cycles c);
  void set_tbe(TBE b);
  void unset_tbe();

  Entry getDirectoryEntry(Addr 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, Addr addr) {
    return getDirectoryEntry(addr).DirectoryState;
  }

  void setState(TBE tbe, Addr 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(Addr 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(Addr addr, State state) {
    if (directory.isPresent(addr)) {
      getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state));
    }
  }

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

  int functionalWrite(Addr 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(Addr addr) {
    if (directory.isPresent(addr)) {
      if (getDirectoryEntry(addr).DirectoryState == State:I) {
        return true;
      }
    }
    return false;
  }

  bool isBlockExclusive(Addr 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, rank=2) {
    if (unblockNetwork_in.isReady(clockEdge())) {
      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: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, rank=1) {
    if (requestQueue_in.isReady(clockEdge())) {
      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:WRITEBACK_DIRTY_DATA) {
          trigger(Event:Dirty_Writeback, in_msg.addr,
                  TBEs[in_msg.addr]);
        } else if (in_msg.Type == CoherenceRequestType:WRITEBACK_CLEAN_ACK) {
          trigger(Event:Clean_Writeback, 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, rank=0) {
    if (memQueue_in.isReady(clockEdge())) {
      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(responseNetwork_out, ResponseMsg, directory_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:WB_ACK;
        out_msg.Sender := in_msg.Requestor;
        out_msg.SenderMachine := 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(responseNetwork_out, ResponseMsg, directory_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:WB_NACK;
        out_msg.Sender := in_msg.Requestor;
        out_msg.SenderMachine := 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(clockEdge());
  }

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

  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(clockEdge());
  }

  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_queueMemoryWBFromCacheRequest, "qw", desc="Queue off-chip writeback request") {
    peek(requestQueue_in, RequestMsg) {
      if (is_valid(tbe)) {
        queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
                         in_msg.DataBlk);
      } else {
        queueMemoryWrite(in_msg.Requestor, 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, getOffset(tbe.PhysicalAddress),
                          tbe.Len);
      queueMemoryWrite(tbe.Requestor, address, to_memory_controller_latency,
                       DataBlk);
    }
  }

  action(qw_queueMemoryWBFromDMARequest, "/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(clockEdge(), cyclesToTicks(recycle_latency));
  }

  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_queueMemoryWBFromDMARequest;
    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_queueMemoryWBFromDMARequest;
    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_queueMemoryWBFromCacheRequest;
    i_popIncomingRequestQueue;
  }

  transition(MIS, Dirty_Writeback, S) {
    c_moveOwnerToSharer;
    qw_queueMemoryWBFromCacheRequest;
    i_popIncomingRequestQueue;
  }

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

  transition(OS, Dirty_Writeback, S) {
    c_clearOwner;
    qw_queueMemoryWBFromCacheRequest;
    i_popIncomingRequestQueue;
  }

  transition(OSS, Dirty_Writeback, S) {
    c_moveOwnerToSharer;
    qw_queueMemoryWBFromCacheRequest;
    i_popIncomingRequestQueue;
  }

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

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

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

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

}
