/*
 * Copyright (c) 2009-2012 Mark D. Hill and David A. Wood
 * Copyright (c) 2010-2012 Advanced Micro Devices, Inc.
 * 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 := 12;
      Cycles to_memory_controller_latency := 1;

      MessageBuffer * forwardFromDir, network="To", virtual_network="3",
            vnet_type="forward";
      MessageBuffer * responseFromDir, network="To", virtual_network="4",
            vnet_type="response";
      MessageBuffer * dmaResponseFromDir, network="To", virtual_network="1",
            vnet_type="response";

      MessageBuffer * requestToDir, network="From", virtual_network="2",
            vnet_type="request";
      MessageBuffer * dmaRequestToDir, network="From", virtual_network="0",
            vnet_type="request";

      MessageBuffer * requestToMemory;
      MessageBuffer * responseFromMemory;
{
  // STATES
  state_declaration(State, desc="Directory states", default="Directory_State_I") {
    // Base states
    I, AccessPermission:Read_Write, desc="Invalid";
    M, AccessPermission:Invalid, desc="Modified";

    M_DRD, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA read";
    M_DWR, AccessPermission:Busy, desc="Blocked on an invalidation for a DMA write";

    M_DWRI, AccessPermission:Busy, desc="Intermediate state M_DWR-->I";
    M_DRDI, AccessPermission:Busy, desc="Intermediate state M_DRD-->I";

    IM, AccessPermission:Busy, desc="Intermediate state I-->M";
    MI, AccessPermission:Busy, desc="Intermediate state M-->I";
    ID, AccessPermission:Busy, desc="Intermediate state for DMA_READ when in I";
    ID_W, AccessPermission:Busy, desc="Intermediate state for DMA_WRITE when in I";
  }

  // Events
  enumeration(Event, desc="Directory events") {
    // processor requests
    GETX, desc="A GETX arrives";
    GETS, desc="A GETS arrives";
    PUTX, desc="A PUTX arrives";
    PUTX_NotOwner, desc="A PUTX arrives";

    // DMA requests
    DMA_READ, desc="A DMA Read memory request";
    DMA_WRITE, desc="A DMA Write memory request";

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

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

  // TBE entries for DMA requests
  structure(TBE, desc="TBE entries for outstanding DMA requests") {
    Addr PhysicalAddress, desc="physical address";
    State TBEState,        desc="Transient State";
    DataBlock DataBlk,     desc="Data to be written (DMA write only)";
    int Len,               desc="...";
    MachineID DmaRequestor, desc="DMA 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();
  Cycles ticksToCycles(Tick t);
  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) {
    if (is_valid(tbe)) {
      return tbe.TBEState;
    } else if (directory.isPresent(addr)) {
      return getDirectoryEntry(addr).DirectoryState;
    } else {
      return State:I;
    }
  }

  void setState(TBE tbe, Addr addr, State state) {

    if (is_valid(tbe)) {
      tbe.TBEState := state;
    }

    if (directory.isPresent(addr)) {

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

      getDirectoryEntry(addr).DirectoryState := state;

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

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

    if(directory.isPresent(addr)) {
      return Directory_State_to_permission(getDirectoryEntry(addr).DirectoryState);
    }

    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) {
    TBE tbe := TBEs[addr];
    if(is_valid(tbe)) {
      testAndRead(addr, tbe.DataBlk, pkt);
    } else {
      functionalMemoryRead(pkt);
    }
  }

  int functionalWrite(Addr addr, Packet *pkt) {
    int num_functional_writes := 0;

    TBE tbe := TBEs[addr];
    if(is_valid(tbe)) {
      num_functional_writes := num_functional_writes +
            testAndWrite(addr, tbe.DataBlk, pkt);
    }

    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
    return num_functional_writes;
  }

  // ** OUT_PORTS **
  out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
  out_port(responseNetwork_out, ResponseMsg, responseFromDir);
  out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling requests
  out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
  out_port(memQueue_out, MemoryMsg, requestToMemory);

  // ** IN_PORTS **
  in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
    if (dmaRequestQueue_in.isReady(clockEdge())) {
      peek(dmaRequestQueue_in, DMARequestMsg) {
        TBE tbe := TBEs[in_msg.LineAddress];
        if (in_msg.Type == DMARequestType:READ) {
          trigger(Event:DMA_READ, in_msg.LineAddress, tbe);
        } else if (in_msg.Type == DMARequestType:WRITE) {
          trigger(Event:DMA_WRITE, in_msg.LineAddress, tbe);
        } else {
          error("Invalid message");
        }
      }
    }
  }

  in_port(requestQueue_in, RequestMsg, requestToDir) {
    if (requestQueue_in.isReady(clockEdge())) {
      peek(requestQueue_in, RequestMsg) {
        TBE tbe := TBEs[in_msg.addr];
        if (in_msg.Type == CoherenceRequestType:GETS) {
          trigger(Event:GETS, in_msg.addr, tbe);
        } else if (in_msg.Type == CoherenceRequestType:GETX) {
          trigger(Event:GETX, in_msg.addr, tbe);
        } else if (in_msg.Type == CoherenceRequestType:PUTX) {
          if (getDirectoryEntry(in_msg.addr).Owner.isElement(in_msg.Requestor)) {
            trigger(Event:PUTX, in_msg.addr, tbe);
          } else {
            trigger(Event:PUTX_NotOwner, in_msg.addr, tbe);
          }
        } else {
          error("Invalid message");
        }
      }
    }
  }

//added by SS
  // off-chip memory request/response is done
  in_port(memQueue_in, MemoryMsg, responseFromMemory) {
    if (memQueue_in.isReady(clockEdge())) {
      peek(memQueue_in, MemoryMsg) {
        TBE tbe := TBEs[in_msg.addr];
        if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
          trigger(Event:Memory_Data, in_msg.addr, tbe);
        } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
          trigger(Event:Memory_Ack, in_msg.addr, tbe);
        } 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.Destination.add(in_msg.Requestor);
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(l_sendWriteBackAck, "la", desc="Send writeback ack to requestor") {
    peek(memQueue_in, MemoryMsg) {
      enqueue(forwardNetwork_out, RequestMsg, 1) {
        out_msg.addr := address;
        out_msg.Type := CoherenceRequestType:WB_ACK;
        out_msg.Requestor := in_msg.OriginalRequestorMachId;
        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
        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.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(d_sendData, "d", desc="Send data to requestor") {
    peek(memQueue_in, MemoryMsg) {
      enqueue(responseNetwork_out, ResponseMsg, 1) {
        out_msg.addr := address;
        out_msg.Type := CoherenceResponseType:DATA;
        out_msg.Sender := machineID;
        out_msg.Destination.add(in_msg.OriginalRequestorMachId);
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

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



  action(drp_sendDMAData, "drp", desc="Send Data to DMA controller from incoming PUTX") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(dmaResponseNetwork_out, DMAResponseMsg, 1) {
        assert(is_valid(tbe));
        out_msg.PhysicalAddress := address;
        out_msg.LineAddress := address;
        out_msg.Type := DMAResponseType:DATA;

        // we send the entire data block and rely on the dma controller
        // to split it up if need be
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Destination.add(tbe.DmaRequestor);
        out_msg.MessageSize := MessageSizeType:Response_Data;
      }
    }
  }

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

  action(e_ownerIsRequestor, "e", desc="The owner is now the requestor") {
    peek(requestQueue_in, RequestMsg) {
      getDirectoryEntry(address).Owner.clear();
      getDirectoryEntry(address).Owner.add(in_msg.Requestor);
    }
  }

  action(f_forwardRequest, "f", desc="Forward request to owner") {
    peek(requestQueue_in, RequestMsg) {
      APPEND_TRANSITION_COMMENT("Own: ");
      APPEND_TRANSITION_COMMENT(getDirectoryEntry(in_msg.addr).Owner);
      APPEND_TRANSITION_COMMENT("Req: ");
      APPEND_TRANSITION_COMMENT(in_msg.Requestor);
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.addr := address;
        out_msg.Type := in_msg.Type;
        out_msg.Requestor := in_msg.Requestor;
        out_msg.Destination := getDirectoryEntry(in_msg.addr).Owner;
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

  action(inv_sendCacheInvalidate, "inv", desc="Invalidate a cache block") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      enqueue(forwardNetwork_out, RequestMsg, directory_latency) {
        out_msg.addr := address;
        out_msg.Type := CoherenceRequestType:INV;
        out_msg.Requestor := machineID;
        out_msg.Destination := getDirectoryEntry(in_msg.PhysicalAddress).Owner;
        out_msg.MessageSize := MessageSizeType:Writeback_Control;
      }
    }
  }

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

  action(p_popIncomingDMARequestQueue, "p", desc="Pop incoming DMA queue") {
    dmaRequestQueue_in.dequeue(clockEdge());
  }

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

  action(r_allocateTbeForDmaRead, "\r", desc="Allocate TBE for DMA Read") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      TBEs.allocate(address);
      set_tbe(TBEs[address]);
      tbe.DmaRequestor := in_msg.Requestor;
    }
  }

  action(v_allocateTBEFromRequestNet, "\v", desc="Allocate TBE") {
    peek(requestQueue_in, RequestMsg) {
      TBEs.allocate(address);
      set_tbe(TBEs[address]);
      tbe.DataBlk := in_msg.DataBlk;
    }
  }

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

  action(z_recycleRequestQueue, "z", desc="recycle request queue") {
    requestQueue_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
  }

  action(y_recycleDMARequestQueue, "y", desc="recycle dma request queue") {
    dmaRequestQueue_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
  }


  action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
        out_msg.addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_READ;
        out_msg.Sender := in_msg.Requestor;
        out_msg.MessageSize := MessageSizeType:Request_Control;
        out_msg.Len := 0;
      }
    }
  }

  action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
        out_msg.addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_READ;
        out_msg.Sender := in_msg.Requestor;
        out_msg.MessageSize := MessageSizeType:Request_Control;
        out_msg.Len := 0;
      }
    }
  }

  action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
        out_msg.addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_WB;
        out_msg.Sender := in_msg.Requestor;
        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Len := in_msg.Len;
      }
    }
  }

  action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
        out_msg.addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_WB;
        out_msg.Sender := in_msg.Requestor;
        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.DataBlk := tbe.DataBlk;
        out_msg.Len := tbe.Len;
      }
    }
  }

  action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
    peek(requestQueue_in, RequestMsg) {
      enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
        out_msg.addr := address;
        out_msg.Type := MemoryRequestType:MEMORY_WB;
        out_msg.Sender := in_msg.Requestor;
        out_msg.MessageSize := MessageSizeType:Writeback_Data;
        out_msg.DataBlk := in_msg.DataBlk;
        out_msg.Len := 0;
      }
    }
  }

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

  // TRANSITIONS
  transition({M_DRD, M_DWR, M_DWRI, M_DRDI}, GETX) {
    z_recycleRequestQueue;
  }

  transition({IM, MI, ID, ID_W}, {GETX, GETS, PUTX, PUTX_NotOwner} ) {
    z_recycleRequestQueue;
  }

  transition({IM, MI, ID, ID_W}, {DMA_READ, DMA_WRITE} ) {
    y_recycleDMARequestQueue;
  }


  transition(I, GETX, IM) {
    //d_sendData;
    v_allocateTBEFromRequestNet;
    qf_queueMemoryFetchRequest;
    e_ownerIsRequestor;
    i_popIncomingRequestQueue;
  }

  transition(IM, Memory_Data, M) {
    d_sendData;
    //e_ownerIsRequestor;
    w_deallocateTBE;
    l_popMemQueue;
  }


  transition(I, DMA_READ, ID) {
    //dr_sendDMAData;
    r_allocateTbeForDmaRead;
    qf_queueMemoryFetchRequestDMA;
    p_popIncomingDMARequestQueue;
  }

  transition(ID, Memory_Data, I) {
    dr_sendDMAData;
    //p_popIncomingDMARequestQueue;
    w_deallocateTBE;
    l_popMemQueue;
  }



  transition(I, DMA_WRITE, ID_W) {
    v_allocateTBE;
    qw_queueMemoryWBRequest_partial;
    p_popIncomingDMARequestQueue;
  }

  transition(ID_W, Memory_Ack, I) {
    da_sendDMAAck;
    w_deallocateTBE;
    l_popMemQueue;
  }

  transition(M, DMA_READ, M_DRD) {
    v_allocateTBE;
    inv_sendCacheInvalidate;
    p_popIncomingDMARequestQueue;
  }

  transition(M_DRD, PUTX, M_DRDI) {
    drp_sendDMAData;
    c_clearOwner;
    l_queueMemoryWBRequest;
    i_popIncomingRequestQueue;
  }

  transition(M_DRDI, Memory_Ack, I) {
    l_sendWriteBackAck;
    w_deallocateTBE;
    l_popMemQueue;
  }


  transition(M, DMA_WRITE, M_DWR) {
    v_allocateTBE;
    inv_sendCacheInvalidate;
    p_popIncomingDMARequestQueue;
  }

  transition(M_DWR, PUTX, M_DWRI) {
    qw_queueMemoryWBRequest_partialTBE;
    c_clearOwner;
    i_popIncomingRequestQueue;
  }

  transition(M_DWRI, Memory_Ack, I) {
    l_sendWriteBackAck;
    da_sendDMAAck;
    w_deallocateTBE;
    l_popMemQueue;
  }

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

  transition(M, PUTX, MI) {
    c_clearOwner;
    v_allocateTBEFromRequestNet;
    l_queueMemoryWBRequest;
    i_popIncomingRequestQueue;
  }

  transition(MI, Memory_Ack, I) {
    l_sendWriteBackAck;
    w_deallocateTBE;
    l_popMemQueue;
  }

  transition(M, PUTX_NotOwner, M) {
    b_sendWriteBackNack;
    i_popIncomingRequestQueue;
  }

  transition(I, PUTX_NotOwner, I) {
    b_sendWriteBackNack;
    i_popIncomingRequestQueue;
  }
}
