/*
 * Copyright (c) 2009 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.
 *
 *
 * Authors: Brad Beckmann
 *          Tushar Krishna
 */


machine(MachineType:Directory, "Garnet_standalone Directory")
    : MessageBuffer * requestToDir, network="From", virtual_network="0",
            vnet_type = "request";
      MessageBuffer * forwardToDir, network="From", virtual_network="1",
            vnet_type = "forward";
      MessageBuffer * responseToDir, network="From", virtual_network="2",
            vnet_type = "response";
{
  // STATES
  state_declaration(State, desc="Directory states", default="Directory_State_I") {
    // Base states
    I, AccessPermission:Invalid, desc="Invalid";
  }

  // Events
  enumeration(Event, desc="Directory events") {
    // processor requests
    Receive_Request, desc="Receive Message";
    Receive_Forward, desc="Receive Message";
    Receive_Response, desc="Receive Message";
  }

  // TYPES
  // DirectoryEntry
  structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
    State DirectoryState,          desc="Directory state";
    DataBlock DataBlk,             desc="data for the block";
  }

  // ** FUNCTIONS **
  Tick clockEdge();

  State getState(Addr addr) {
    return State:I;
  }

  void setState(Addr addr, State state) {

  }

  AccessPermission getAccessPermission(Addr addr) {
    return AccessPermission:NotPresent;
  }

  void setAccessPermission(Addr addr, State state) {
  }

  void functionalRead(Addr addr, Packet *pkt) {
    error("Garnet_standalone does not support functional read.");
  }

  int functionalWrite(Addr addr, Packet *pkt) {
    error("Garnet_standalone does not support functional write.");
  }

  // ** IN_PORTS **

  in_port(requestQueue_in, RequestMsg, requestToDir) {
    if (requestQueue_in.isReady(clockEdge())) {
      peek(requestQueue_in, RequestMsg) {
        if (in_msg.Type == CoherenceRequestType:MSG) {
          trigger(Event:Receive_Request, in_msg.addr);
        } else {
          error("Invalid message");
        }
      }
    }
  }
  in_port(forwardQueue_in, RequestMsg, forwardToDir) {
    if (forwardQueue_in.isReady(clockEdge())) {
      peek(forwardQueue_in, RequestMsg) {
        if (in_msg.Type == CoherenceRequestType:MSG) {
          trigger(Event:Receive_Forward, in_msg.addr);
        } else {
          error("Invalid message");
        }
      }
    }
  }
  in_port(responseQueue_in, RequestMsg, responseToDir) {
    if (responseQueue_in.isReady(clockEdge())) {
      peek(responseQueue_in, RequestMsg) {
        if (in_msg.Type == CoherenceRequestType:MSG) {
          trigger(Event:Receive_Response, in_msg.addr);
        } else {
          error("Invalid message");
        }
      }
    }
  }

  // Actions

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

  action(f_popIncomingForwardQueue, "f", desc="Pop incoming forward queue") {
    forwardQueue_in.dequeue(clockEdge());
  }

  action(r_popIncomingResponseQueue, "r", desc="Pop incoming response queue") {
    responseQueue_in.dequeue(clockEdge());
  }

  // TRANSITIONS

  // The directory simply drops the received packets.
  // The goal of Garnet_standalone is only to track network stats.

  transition(I, Receive_Request) {
    i_popIncomingRequestQueue;
  }
  transition(I, Receive_Forward) {
    f_popIncomingForwardQueue;
  }
  transition(I, Receive_Response) {
    r_popIncomingResponseQueue;
  }
}
