/*
 * 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.
 */


machine(MachineType:L1Cache, "Garnet_standalone L1 Cache")
    : Sequencer * sequencer;
      Cycles issue_latency := 2;

      // NETWORK BUFFERS
      MessageBuffer * requestFromCache, network="To", virtual_network="0",
            vnet_type = "request";
      MessageBuffer * forwardFromCache, network="To", virtual_network="1",
            vnet_type = "forward";
      MessageBuffer * responseFromCache, network="To", virtual_network="2",
            vnet_type = "response";

      MessageBuffer * mandatoryQueue;
{
  // STATES
  state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
    I,  AccessPermission:Invalid, desc="Not Present/Invalid";
  }

  // EVENTS
  enumeration(Event, desc="Cache events") {
    // From processor
    Request,    desc="Request from Garnet_standalone";
    Forward,    desc="Forward from Garnet_standalone";
    Response,   desc="Response from Garnet_standalone";
  }

  // STRUCTURE DEFINITIONS
  DataBlock dummyData;

  // CacheEntry
  structure(Entry, desc="...", interface="AbstractCacheEntry") {
    State CacheState,        desc="cache state";
    DataBlock DataBlk,       desc="Data in the block";
  }

  // FUNCTIONS
  Tick clockEdge();
  MachineID mapAddressToMachine(Addr addr, MachineType mtype);

  // cpu/testers/networktest/networktest.cc generates packets of the type
  // ReadReq, INST_FETCH, and WriteReq.
  // These are converted to LD, IFETCH and ST by mem/ruby/system/RubyPort.cc.
  // These are then sent to the sequencer, which sends them here.
  // Garnet_standalone-cache.sm tags LD, IFETCH and ST as Request, Forward,
  // and Response Events respectively, which are then injected into
  // virtual networks 0, 1 and 2 respectively.
  // This models traffic of different types within the network.
  //
  // Note that requests and forwards are MessageSizeType:Control,
  // while responses are MessageSizeType:Data.
  //
  Event mandatory_request_type_to_event(RubyRequestType type) {
    if (type == RubyRequestType:LD) {
      return Event:Request;
    } else if (type == RubyRequestType:IFETCH) {
      return Event:Forward;
    } else if (type == RubyRequestType:ST) {
      return Event:Response;
    } else {
      error("Invalid RubyRequestType");
    }
  }


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

  void setState(Entry cache_entry, Addr addr, State state) {

  }

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

  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
  }

  Entry getCacheEntry(Addr address), return_by_pointer="yes" {
    return OOD;
  }

  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.");
  }

  // NETWORK PORTS

  out_port(requestNetwork_out, RequestMsg, requestFromCache);
  out_port(forwardNetwork_out, RequestMsg, forwardFromCache);
  out_port(responseNetwork_out, RequestMsg, responseFromCache);

  // Mandatory Queue
  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") {
    if (mandatoryQueue_in.isReady(clockEdge())) {
      peek(mandatoryQueue_in, RubyRequest) {
        trigger(mandatory_request_type_to_event(in_msg.Type),
                in_msg.LineAddress, getCacheEntry(in_msg.LineAddress));
      }
    }
  }

  // ACTIONS

  // The destination directory of the packets is embedded in the address
  // map_Address_to_Directory is used to retrieve it.

  action(a_issueRequest, "a", desc="Issue a request") {
    enqueue(requestNetwork_out, RequestMsg, issue_latency) {
      out_msg.addr := address;
      out_msg.Type := CoherenceRequestType:MSG;
      out_msg.Requestor := machineID;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));

      // To send broadcasts in vnet0 (to emulate broadcast-based protocols),
      // replace the above line by the following:
      // out_msg.Destination := broadcast(MachineType:Directory);

      out_msg.MessageSize := MessageSizeType:Control;
    }
  }

  action(b_issueForward, "b", desc="Issue a forward") {
    enqueue(forwardNetwork_out, RequestMsg, issue_latency) {
      out_msg.addr := address;
      out_msg.Type := CoherenceRequestType:MSG;
      out_msg.Requestor := machineID;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
      out_msg.MessageSize := MessageSizeType:Control;
    }
  }

  action(c_issueResponse, "c", desc="Issue a response") {
    enqueue(responseNetwork_out, RequestMsg, issue_latency) {
      out_msg.addr := address;
      out_msg.Type := CoherenceRequestType:MSG;
      out_msg.Requestor := machineID;
      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
      out_msg.MessageSize := MessageSizeType:Data;
    }
  }

  action(m_popMandatoryQueue, "m", desc="Pop the mandatory request queue") {
    mandatoryQueue_in.dequeue(clockEdge());
  }

  action(r_load_hit, "r", desc="Notify sequencer the load completed.") {
    sequencer.readCallback(address, dummyData);
  }

  action(s_store_hit, "s", desc="Notify sequencer that store completed.") {
    sequencer.writeCallback(address, dummyData);
  }


  // TRANSITIONS

  // sequencer hit call back is performed after injecting the packets.
  // The goal of the Garnet_standalone protocol is only to inject packets into
  // the network, not to keep track of them via TBEs.

  transition(I, Response) {
    s_store_hit;
    c_issueResponse;
    m_popMandatoryQueue;
  }

  transition(I, Request) {
    r_load_hit;
    a_issueRequest;
    m_popMandatoryQueue;
  }
  transition(I, Forward) {
    r_load_hit;
    b_issueForward;
    m_popMandatoryQueue;
  }

}
