/*
 * Copyright (c) 2021 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.
 *
 * 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:Memory, "Memory controller interface") :

  // no explicit modeling of allocation latency like the Caches, so add one
  // cycle to the response enqueue latency as default
  Cycles response_latency := 2;
  Cycles data_latency := 1;
  Cycles to_memory_controller_latency := 1;

  int data_channel_size;

  // Interface to the network
  // Note vnet_type is used by Garnet only. "response" type is assumed to
  // have data, so use it for data channels and "none" for the rest.
  // network="To" for outbound queue; network="From" for inbound
  // virtual networks: 0=request, 1=snoop, 2=response, 3=data

  MessageBuffer * reqOut,   network="To", virtual_network="0", vnet_type="none";
  MessageBuffer * snpOut,   network="To", virtual_network="1", vnet_type="none";
  MessageBuffer * rspOut,   network="To", virtual_network="2", vnet_type="none";
  MessageBuffer * datOut,   network="To", virtual_network="3", vnet_type="response";

  MessageBuffer * reqIn,   network="From", virtual_network="0", vnet_type="none";
  MessageBuffer * snpIn,   network="From", virtual_network="1", vnet_type="none";
  MessageBuffer * rspIn,   network="From", virtual_network="2", vnet_type="none";
  MessageBuffer * datIn,   network="From", virtual_network="3", vnet_type="response";

  // Requests that can allocate a TBE
  MessageBuffer * reqRdy;

  // Data/ack to/from memory
  MessageBuffer * requestToMemory;
  MessageBuffer * responseFromMemory;

  // Trigger queue for internal events
  MessageBuffer * triggerQueue;

{

  ////////////////////////////////////////////////////////////////////////////
  // States
  ////////////////////////////////////////////////////////////////////////////

  state_declaration(State, desc="Transaction states", default="Memory_State_READY") {
    // We don't know if the line is cached, so the memory copy is maybe stable
    READY, AccessPermission:Backing_Store, desc="Ready to transfer the line";

    WAITING_NET_DATA, AccessPermission:Backing_Store_Busy, desc="Waiting data from the network";
    SENDING_NET_DATA, AccessPermission:Backing_Store_Busy, desc="Sending data to the network";
    READING_MEM, AccessPermission:Backing_Store_Busy, desc="Waiting data from memory";

    // Null state for debugging; allow writes
    null, AccessPermission:Backing_Store, desc="Null state";
  }


  ////////////////////////////////////////////////////////////////////////////
  // Events
  ////////////////////////////////////////////////////////////////////////////

  enumeration(Event, desc="Memory events") {
    // Checks if a request can allocate a TBE be moved to reqRdy
    CheckAllocTBE, desc="";
    CheckAllocTBE_WithCredit, desc="";

    // Requests
    WriteNoSnpPtl, desc="";
    WriteNoSnp, desc="";
    ReadNoSnp, desc="";
    ReadNoSnpSep, desc="";

    // Data
    WriteData, desc="";

    // Memory side
    MemoryData, desc="";
    MemoryAck, desc="";

    // Internal event triggers
    Trigger_Send, desc="";
    Trigger_SendDone, desc="";
    Trigger_ReceiveDone, desc="";
    Trigger_SendRetry, desc="";
    Trigger_SendPCrdGrant, desc="";
  }


  // Is there a less tedious way to convert messages to events ??

  Event reqToEvent (CHIRequestType type) {
    if (type == CHIRequestType:WriteNoSnpPtl) {
      return Event:WriteNoSnpPtl;
    } else if (type == CHIRequestType:WriteNoSnp) {
      return Event:WriteNoSnp;
    } else if (type == CHIRequestType:ReadNoSnp) {
      return Event:ReadNoSnp;
    } else if (type == CHIRequestType:ReadNoSnpSep) {
      return Event:ReadNoSnpSep;
    } else {
      error("Invalid CHIRequestType");
    }
  }

  Event respToEvent (CHIResponseType type) {
    error("Invalid CHIResponseType");
  }

  Event dataToEvent (CHIDataType type) {
    if (type == CHIDataType:NCBWrData) {
      return Event:WriteData;
    } else {
      error("Invalid CHIDataType");
    }
  }


  ////////////////////////////////////////////////////////////////////////////
  // Data structures
  ////////////////////////////////////////////////////////////////////////////

  // Cache block size
  int blockSize, default="RubySystem::getBlockSizeBytes()";

  // TBE fields
  structure(TBE, desc="...") {
    int storSlot,   desc="Slot in the storage tracker occupied by this entry";
    Addr addr,      desc="Line address for this TBE";
    Addr accAddr,   desc="Original access address. Set only for Write*Ptl";
    int  accSize,   desc="Access size. Set only for Write*Ptl";
    State state,    desc="Current line state";
    DataBlock dataBlk, desc="Transaction data";
    WriteMask dataBlkValid, desc="valid bytes in dataBlk";
    int rxtxBytes, desc="Bytes sent or received";
    MachineID requestor, desc="Requestor that originated this request";
    MachineID destination, desc="Where we are sending data";
    bool useDataSepResp, desc="Replies with DataSepResp instead of CompData";
  }

  structure(TBETable, external ="yes") {
    TBE lookup(Addr);
    void allocate(Addr);
    void deallocate(Addr);
    bool isPresent(Addr);
    bool areNSlotsAvailable(int n, Tick curTime);
  }

  structure(TBEStorage, external ="yes") {
    int size();
    int capacity();
    int reserved();
    int slotsAvailable();
    bool areNSlotsAvailable(int n);
    void incrementReserved();
    void decrementReserved();
    int addEntryToNewSlot();
    void removeEntryFromSlot(int slot);
  }

  TBETable TBEs, template="<Memory_TBE>", constructor="m_number_of_TBEs";
  TBEStorage storTBEs, constructor="this, m_number_of_TBEs";

  // Tracks all pending MemoryAcks (debug purposes only)
  int pendingWrites, default="0";

  structure(TriggerMsg, desc="...", interface="Message") {
    Addr addr;
    Event event;
    MachineID retryDest;

    bool functionalRead(Packet *pkt) { return false; }
    bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
    bool functionalWrite(Packet *pkt) { return false; }
  }

  // Tracks a pending credit request from a retry
  structure(RetryQueueEntry) {
    Addr addr,           desc="Line address";
    MachineID retryDest, desc="Retry destination";
  }

  structure(TriggerQueue, external ="yes") {
    void pop();
    bool empty();
    void emplace(Addr,MachineID);
    RetryQueueEntry next();
  }

  TriggerQueue retryQueue, template="<Memory_RetryQueueEntry>";

  ////////////////////////////////////////////////////////////////////////////
  // External functions
  ////////////////////////////////////////////////////////////////////////////

  Tick clockEdge();
  Tick curTick();
  Tick cyclesToTicks(Cycles c);
  void set_tbe(TBE b);
  void unset_tbe();
  void wakeUpAllBuffers(Addr a);
  bool respondsTo(Addr addr);

  ////////////////////////////////////////////////////////////////////////////
  // Interface functions required by SLICC
  ////////////////////////////////////////////////////////////////////////////

  State getState(TBE tbe, Addr addr) {
    if (is_valid(tbe)) {
        assert(tbe.addr == addr);
        return tbe.state;
    } else {
        return State:READY;
    }
  }

  void setState(TBE tbe, Addr addr, State state) {
    if (is_valid(tbe)) {
      assert(tbe.addr == addr);
      tbe.state := state;
    }
  }

  AccessPermission getAccessPermission(Addr addr) {
    if (respondsTo(addr)) {
      TBE tbe := TBEs[addr];
      if (is_valid(tbe)) {
        DPRINTF(RubySlicc, "%x %s,%s\n", addr, tbe.state, Memory_State_to_permission(tbe.state));
        return Memory_State_to_permission(tbe.state);
      } else {
        DPRINTF(RubySlicc, "%x %s\n", addr, AccessPermission:Backing_Store);
        return AccessPermission:Backing_Store;
      }
    } else {
      DPRINTF(RubySlicc, "%x %s\n", addr, AccessPermission:NotPresent);
      return AccessPermission:NotPresent;
    }
  }

  void setAccessPermission(Addr addr, State state) {
  }

  void functionalRead(Addr addr, Packet *pkt, WriteMask &mask) {
    if (respondsTo(addr)) {
      DPRINTF(RubySlicc, "functionalRead %x\n", addr);
      TBE tbe := TBEs[addr];

      if (mask.isEmpty()) {
        functionalMemoryRead(pkt);
        mask.fillMask();
        DPRINTF(RubySlicc, "functionalRead mem %x %s\n", addr, mask);
      }

      // Update with any transient data
      //TODO additional handling of partial data ??
      if (is_valid(tbe)) {
        WriteMask read_mask;
        read_mask.setMask(addressOffset(tbe.accAddr, tbe.addr), tbe.accSize);
        read_mask.andMask(tbe.dataBlkValid);
        if (read_mask.isEmpty() == false) {
          testAndReadMask(addr, tbe.dataBlk, read_mask, pkt);
          DPRINTF(RubySlicc, "functionalRead tbe %x %s %s %s\n", addr, tbe.dataBlk, read_mask, mask);
          mask.orMask(read_mask);
        }
      }
    }
  }

  int functionalWrite(Addr addr, Packet *pkt) {
    if(respondsTo(addr)) {
      int num_functional_writes := 0;
      TBE tbe := TBEs[addr];
      if (is_valid(tbe)) {
        num_functional_writes := num_functional_writes +
          testAndWrite(addr, tbe.dataBlk, pkt);
        DPRINTF(RubySlicc, "functionalWrite tbe %x %s\n", addr, tbe.dataBlk);
      }
      num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
      DPRINTF(RubySlicc, "functionalWrite mem %x\n", addr);
      return num_functional_writes;
    } else {
      return 0;
    }
  }


  ////////////////////////////////////////////////////////////////////////////
  // Helper functions
  ////////////////////////////////////////////////////////////////////////////

  void printResources() {
    DPRINTF(RubySlicc, "Resources(avail/max): TBEs=%d/%d\n",
                  storTBEs.size(), storTBEs.capacity());
    DPRINTF(RubySlicc, "Resources(in/out size): rdy=%d req=%d/%d rsp=%d/%d dat=%d/%d snp=%d/%d\n",
                  reqRdy.getSize(curTick()),
                  reqIn.getSize(curTick()), reqOut.getSize(curTick()),
                  rspIn.getSize(curTick()), rspOut.getSize(curTick()),
                  datIn.getSize(curTick()), datOut.getSize(curTick()),
                  snpIn.getSize(curTick()), snpOut.getSize(curTick()));
  }

  ////////////////////////////////////////////////////////////////////////////
  // Input/output port definitions
  ////////////////////////////////////////////////////////////////////////////

  // Outbound port definitions

  out_port(reqOutPort, CHIRequestMsg, reqOut);
  out_port(snpOutPort, CHIRequestMsg, snpOut);
  out_port(rspOutPort, CHIResponseMsg, rspOut);
  out_port(datOutPort, CHIDataMsg, datOut);
  out_port(triggerOutPort, TriggerMsg, triggerQueue);
  out_port(memQueue_out, MemoryMsg, requestToMemory);
  out_port(reqRdyOutPort, CHIRequestMsg, reqRdy);

  // Inbound port definitions

  // Response
  in_port(rspInPort, CHIResponseMsg, rspIn, rank=6) {
    if (rspInPort.isReady(clockEdge())) {
      printResources();
      peek(rspInPort, CHIResponseMsg) {
        error("Unexpected message");
      }
    }
  }

  // Data
  in_port(datInPort, CHIDataMsg, datIn, rank=5) {
    if (datInPort.isReady(clockEdge())) {
      printResources();
      peek(datInPort, CHIDataMsg) {
        int received := in_msg.bitMask.count();
        assert((received <= data_channel_size) && (received > 0));
        trigger(dataToEvent(in_msg.type), in_msg.addr, TBEs[in_msg.addr]);
      }
    }
  }

  // Data/Ack from memory

  in_port(memQueue_in, MemoryMsg, responseFromMemory, rank=4) {
    if (memQueue_in.isReady(clockEdge())) {
      printResources();
      peek(memQueue_in, MemoryMsg) {
        Addr addr := makeLineAddress(in_msg.addr);
        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
          trigger(Event:MemoryData, addr, TBEs[addr]);
        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
          trigger(Event:MemoryAck, addr, TBEs[addr]);
        } else {
          error("Invalid message");
        }
      }
    }
  }

   // Trigger
  in_port(triggerInPort, TriggerMsg, triggerQueue, rank=3) {
    if (triggerInPort.isReady(clockEdge())) {
      printResources();
      peek(triggerInPort, TriggerMsg) {
        trigger(in_msg.event, in_msg.addr, TBEs[in_msg.addr]);
      }
    }
  }

  // Snoops
  in_port(snpInPort, CHIRequestMsg, snpIn, rank=2) {
    if (snpInPort.isReady(clockEdge())) {
      printResources();
      peek(snpInPort, CHIRequestMsg) {
        error("Unexpected message");
      }
    }
  }

  // Requests
  in_port(reqRdyInPort, CHIRequestMsg, reqRdy, rank=1) {
    if (reqRdyInPort.isReady(clockEdge())) {
      printResources();
      peek(reqRdyInPort, CHIRequestMsg) {
        trigger(reqToEvent(in_msg.type), in_msg.addr, TBEs[in_msg.addr]);
      }
    }
  }

  in_port(reqInPort, CHIRequestMsg, reqIn, rank=0) {
    if (reqInPort.isReady(clockEdge())) {
      printResources();
      peek(reqInPort, CHIRequestMsg) {
        if (in_msg.allowRetry) {
          trigger(Event:CheckAllocTBE, in_msg.addr, TBEs[in_msg.addr]);
        } else {
          // Only expected requests that do not allow retry are the ones that
          // are being retried after receiving credit
          trigger(Event:CheckAllocTBE_WithCredit,
                  in_msg.addr, TBEs[in_msg.addr]);
        }
      }
    }
  }



  ////////////////////////////////////////////////////////////////////////////
  // Actions
  ////////////////////////////////////////////////////////////////////////////

  action(checkAllocateTBE, desc="") {
    // Move to reqRdy if resources available, otherwise send retry
    if (storTBEs.areNSlotsAvailable(1)) {
      // reserve a slot for this request
      storTBEs.incrementReserved();

      peek(reqInPort, CHIRequestMsg) {
        enqueue(reqRdyOutPort, CHIRequestMsg, 0) {
          out_msg := in_msg;
        }
      }

    } else {
      peek(reqInPort, CHIRequestMsg) {
        assert(in_msg.allowRetry);
        enqueue(triggerOutPort, TriggerMsg, 0) {
          out_msg.addr := in_msg.addr;
          out_msg.event := Event:Trigger_SendRetry;
          out_msg.retryDest := in_msg.requestor;
          retryQueue.emplace(in_msg.addr,in_msg.requestor);
        }
      }
    }
    reqInPort.dequeue(clockEdge());
  }

  action(checkAllocateTBE_withCredit, desc="") {
    // We must have reserved resources for this request
    peek(reqInPort, CHIRequestMsg) {
      assert(in_msg.allowRetry == false);
      enqueue(reqRdyOutPort, CHIRequestMsg, 0) {
        out_msg := in_msg;
      }
    }
    reqInPort.dequeue(clockEdge());
  }

  action(allocateTBE, "atbe", desc="Allocate TBEs for a miss") {
    // We must have reserved resources for this allocation
    storTBEs.decrementReserved();
    assert(storTBEs.areNSlotsAvailable(1));

    TBEs.allocate(address);
    set_tbe(TBEs[address]);
    tbe.storSlot := storTBEs.addEntryToNewSlot();
    tbe.addr := address;
    tbe.rxtxBytes := 0;
    tbe.useDataSepResp := false;
  }

  action(initializeFromReqTBE, "itbe", desc="Initialize TBE fields") {
    peek(reqRdyInPort, CHIRequestMsg) {
      tbe.requestor := in_msg.requestor;
      if (in_msg.dataToFwdRequestor) {
        tbe.destination := in_msg.fwdRequestor;
      } else {
        tbe.destination := in_msg.requestor;
      }
      tbe.accAddr := in_msg.accAddr;
      tbe.accSize := in_msg.accSize;
    }
  }

  action(decWritePending, "dwp", desc="Decrement pending writes") {
    assert(pendingWrites >= 1);
    pendingWrites := pendingWrites - 1;
  }

  action(deallocateTBE, "dtbe", desc="Deallocate TBEs") {
    assert(is_valid(tbe));
    storTBEs.removeEntryFromSlot(tbe.storSlot);
    TBEs.deallocate(address);
    unset_tbe();
    // send credit if requestor waiting for it
    if (retryQueue.empty() == false) {
      assert(storTBEs.areNSlotsAvailable(1));
      storTBEs.incrementReserved();
      RetryQueueEntry e := retryQueue.next();
      retryQueue.pop();
      enqueue(triggerOutPort, TriggerMsg, 0) {
        out_msg.addr := e.addr;
        out_msg.retryDest := e.retryDest;
        out_msg.event := Event:Trigger_SendPCrdGrant;
      }
    }
  }

  action(sendReadReceipt, "sRR", desc="Send receipt to requestor") {
    assert(is_valid(tbe));
    enqueue(rspOutPort, CHIResponseMsg, response_latency) {
      out_msg.addr := address;
      out_msg.type := CHIResponseType:ReadReceipt;
      out_msg.responder := machineID;
      out_msg.Destination.add(tbe.requestor);
    }
    // also send different type of data when ready
    tbe.useDataSepResp := true;
  }

  action(sendCompDBIDResp, "sCbid", desc="Send ack to requestor") {
    assert(is_valid(tbe));
    enqueue(rspOutPort, CHIResponseMsg, response_latency) {
      out_msg.addr := address;
      out_msg.type := CHIResponseType:CompDBIDResp;
      out_msg.responder := machineID;
      out_msg.Destination.add(tbe.requestor);
    }
  }

  action(sendMemoryRead, "smr", desc="Send request to memory") {
    assert(is_valid(tbe));
    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
      out_msg.addr := address;
      out_msg.Type := MemoryRequestType:MEMORY_READ;
      out_msg.Sender := tbe.requestor;
      out_msg.MessageSize := MessageSizeType:Request_Control;
      out_msg.Len := 0;
    }
  }

  action(sendMemoryWrite, "smw", desc="Send request to memory") {
    assert(is_valid(tbe));
    enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
      out_msg.addr := tbe.accAddr;
      out_msg.Type := MemoryRequestType:MEMORY_WB;
      out_msg.Sender := tbe.requestor;
      out_msg.MessageSize := MessageSizeType:Writeback_Data;
      out_msg.DataBlk := tbe.dataBlk;
      out_msg.Len := tbe.accSize;
    }
    tbe.dataBlkValid.clear();
    pendingWrites := pendingWrites + 1;
  }

  action(prepareSend, "ps", desc="Copies received memory data to TBE") {
    assert(is_valid(tbe));
    peek(memQueue_in, MemoryMsg) {
      tbe.dataBlk := in_msg.DataBlk;
    }
    tbe.rxtxBytes := 0;
    tbe.dataBlkValid.setMask(addressOffset(tbe.accAddr, tbe.addr), tbe.accSize);
  }

  action(copyWriteDataToTBE, "cpWDat", desc="Copies received net data to TBE") {
    peek(datInPort, CHIDataMsg) {
      assert(is_valid(tbe));
      tbe.dataBlk.copyPartial(in_msg.dataBlk, in_msg.bitMask);
      tbe.dataBlkValid.orMask(in_msg.bitMask);
      tbe.rxtxBytes := tbe.rxtxBytes + in_msg.bitMask.count();
    }
  }

  action(sendDataAndCheck, "sd", desc="Send received data to requestor") {
    assert(is_valid(tbe));
    assert(tbe.rxtxBytes < blockSize);
    enqueue(datOutPort, CHIDataMsg, data_latency) {
      out_msg.addr := tbe.addr;
      if (tbe.useDataSepResp) {
        out_msg.type := CHIDataType:DataSepResp_UC;
      } else {
        out_msg.type := CHIDataType:CompData_UC;
      }
      out_msg.dataBlk := tbe.dataBlk;
      // Called in order for the whole block so use rxtxBytes as offset
      out_msg.bitMask.setMask(tbe.rxtxBytes, data_channel_size);
      out_msg.Destination.add(tbe.destination);
    }

    //DPRINTF(RubySlicc, "rxtxBytes=%d\n", tbe.rxtxBytes);

    tbe.rxtxBytes := tbe.rxtxBytes + data_channel_size;

    // end or send next chunk next cycle
    Event next := Event:Trigger_SendDone;
    Cycles delay := intToCycles(0);
    if (tbe.rxtxBytes < blockSize) {
        next := Event:Trigger_Send;
        delay := intToCycles(1);
    }
    enqueue(triggerOutPort, TriggerMsg, delay) {
      out_msg.addr := address;
      out_msg.event := next;
    }
  }

  action(checkForReceiveCompletion, "cWc", desc="Check if all data is received") {
    assert(is_valid(tbe));
    DPRINTF(RubySlicc, "rxtxBytes=%d\n", tbe.rxtxBytes);
    assert((tbe.rxtxBytes <= tbe.accSize) && (tbe.rxtxBytes > 0));
    if (tbe.rxtxBytes == tbe.accSize) {
      enqueue(triggerOutPort, TriggerMsg, 0) {
        out_msg.addr := address;
        out_msg.event := Event:Trigger_ReceiveDone;
      }
      tbe.rxtxBytes := 0;
      assert(tbe.dataBlkValid.getMask(addressOffset(tbe.accAddr, tbe.addr), tbe.accSize));
    }
  }

  action(popReqInQueue, "preq", desc="Pop request queue.") {
    reqRdyInPort.dequeue(clockEdge());
  }

  action(popDataInQueue, "pdata", desc="Pop data queue.") {
    datInPort.dequeue(clockEdge());
  }

  action(popTriggerQueue, "ptrigger", desc="Pop trigger queue.") {
    triggerInPort.dequeue(clockEdge());
  }

  action(popMemoryQueue, "pmem", desc="Pop memory queue.") {
    memQueue_in.dequeue(clockEdge());
  }

  // Stall/wake-up only used for requests that arrive when we are on the
  // WAITING_NET_DATA state. For all other case the line should be either
  // ready or we can overlap
  action(stallRequestQueue, "str", desc="Stall and wait on the address") {
    peek(reqRdyInPort, CHIRequestMsg){
      stall_and_wait(reqRdyInPort, address);
    }
  }
  action(wakeUpStalled, "wa", desc="Wake up any requests waiting for this address") {
    wakeUpAllBuffers(address);
  }

  action(sendRetryAck, desc="") {
    peek(triggerInPort, TriggerMsg) {
      enqueue(rspOutPort, CHIResponseMsg, response_latency) {
        out_msg.addr := in_msg.addr;
        out_msg.type := CHIResponseType:RetryAck;
        out_msg.responder := machineID;
        out_msg.Destination.add(in_msg.retryDest);
      }
    }
  }

  action(sendPCrdGrant, desc="") {
    peek(triggerInPort, TriggerMsg) {
      enqueue(rspOutPort, CHIResponseMsg, response_latency) {
        out_msg.addr := in_msg.addr;
        out_msg.type := CHIResponseType:PCrdGrant;
        out_msg.responder := machineID;
        out_msg.Destination.add(in_msg.retryDest);
      }
    }
  }

  ////////////////////////////////////////////////////////////////////////////
  // Transitions
  ////////////////////////////////////////////////////////////////////////////

  transition(READY, ReadNoSnp, READING_MEM) {
    allocateTBE;
    initializeFromReqTBE;
    sendMemoryRead;
    popReqInQueue;
  }

  transition(READY, ReadNoSnpSep, READING_MEM) {
    allocateTBE;
    initializeFromReqTBE;
    sendMemoryRead;
    sendReadReceipt;
    popReqInQueue;
  }

  transition(READING_MEM, MemoryData, SENDING_NET_DATA) {
    prepareSend;
    sendDataAndCheck;
    popMemoryQueue;
  }

  transition(SENDING_NET_DATA, Trigger_Send) {
    sendDataAndCheck;
    popTriggerQueue;
  }

  transition(READY, WriteNoSnpPtl, WAITING_NET_DATA) {
    allocateTBE;
    initializeFromReqTBE;
    sendCompDBIDResp;
    popReqInQueue;
  }

  transition(READY, WriteNoSnp, WAITING_NET_DATA) {
    allocateTBE;
    initializeFromReqTBE;
    sendCompDBIDResp;
    popReqInQueue;
  }

  transition(WAITING_NET_DATA, WriteData) {
    copyWriteDataToTBE;
    checkForReceiveCompletion;
    popDataInQueue;
  }

  transition(WAITING_NET_DATA, Trigger_ReceiveDone, READY) {
    sendMemoryWrite;
    deallocateTBE;
    wakeUpStalled;
    popTriggerQueue;
  }

  transition(SENDING_NET_DATA, Trigger_SendDone, READY) {
    deallocateTBE;
    wakeUpStalled;
    popTriggerQueue;
  }

  // Just sanity check against counter of pending acks
  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA,READY},
              MemoryAck) {
    decWritePending;
    popMemoryQueue;
  }

  // Notice we only use this here and call wakeUp when leaving this state
  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA},
             {ReadNoSnp, ReadNoSnpSep, WriteNoSnpPtl}) {
    stallRequestQueue;
  }

  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA,READY},
              Trigger_SendRetry) {
    sendRetryAck;
    popTriggerQueue;
  }

  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA,READY},
              Trigger_SendPCrdGrant) {
    sendPCrdGrant;
    popTriggerQueue;
  }

  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA,READY},
              CheckAllocTBE) {
    checkAllocateTBE;
  }

  transition({READING_MEM,WAITING_NET_DATA,SENDING_NET_DATA,READY},
              CheckAllocTBE_WithCredit) {
    checkAllocateTBE_withCredit;
  }

}
