/*
 * 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="AbstractEntry") {
    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;
    qf_queueMemoryFetchRequest;
    e_ownerIsRequestor;
    i_popIncomingRequestQueue;
  }

  transition(IM, Memory_Data, M) {
    d_sendData;
    //e_ownerIsRequestor;
    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;
  }
}
