/*
 * 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 * 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);

  // ** 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) {
      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
    }
  }

  action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      queueMemoryRead(in_msg.Requestor, address, to_memory_controller_latency);
    }
  }

  action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
    peek(dmaRequestQueue_in, DMARequestMsg) {
      queueMemoryWritePartial(in_msg.Requestor, address,
                              to_memory_controller_latency, in_msg.DataBlk,
                              in_msg.Len);
    }
  }

  action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
    peek(requestQueue_in, RequestMsg) {
      queueMemoryWritePartial(in_msg.Requestor, address,
                              to_memory_controller_latency, tbe.DataBlk,
                              tbe.Len);
    }
  }

  action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
    peek(requestQueue_in, RequestMsg) {
      queueMemoryWrite(in_msg.Requestor, address, to_memory_controller_latency,
                       in_msg.DataBlk);
    }
  }

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