/*
 * 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='AbstractCacheEntry', main="false") {
    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;
  }

}
