/*
 * 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(L1Cache, "Network_test L1 Cache")
: Sequencer * sequencer,
  Cycles issue_latency = 2
{

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

  // 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 Network_test";
    Forward,    desc="Forward from Network_test";
    Response,   desc="Response from Network_test";
  }

  // STRUCTURE DEFINITIONS

  MessageBuffer mandatoryQueue, ordered="false";
  DataBlock dummyData;


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

  // FUNCTIONS

  // 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.
  // Network_test-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, Address addr) {
    return State:I;
  }

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

  }

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

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

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

  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
    error("Network Test does not support get data block.");
  }

  // 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()) {
      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, latency=issue_latency) {
      out_msg.Addr := address;
      out_msg.Type := CoherenceRequestType:MSG;
      out_msg.Requestor := machineID;
      out_msg.Destination.add(map_Address_to_Directory(address));
      //out_msg.Destination := broadcast(MachineType:Directory);
      out_msg.MessageSize := MessageSizeType:Control;
    }
  }

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

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

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

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

}
