114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2009 Advanced Micro Devices, Inc.
314184Sgabeblack@google.com * All rights reserved.
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
614184Sgabeblack@google.com * modification, are permitted provided that the following conditions are
714184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
814184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
914184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1114184Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1214184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1314184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1414184Sgabeblack@google.com * this software without specific prior written permission.
1514184Sgabeblack@google.com *
1614184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1714184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1814184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1914184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2014184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2114184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2214184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2314184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2414184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2514184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2614184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2714184Sgabeblack@google.com *
2814184Sgabeblack@google.com *
2914184Sgabeblack@google.com * Authors: Brad Beckmann
3014184Sgabeblack@google.com *          Tushar Krishna
3114184Sgabeblack@google.com */
3214184Sgabeblack@google.com
3314184Sgabeblack@google.com
3414184Sgabeblack@google.commachine(MachineType:L1Cache, "Garnet_standalone L1 Cache")
3514184Sgabeblack@google.com    : Sequencer * sequencer;
3614184Sgabeblack@google.com      Cycles issue_latency := 2;
3714184Sgabeblack@google.com
3814184Sgabeblack@google.com      // NETWORK BUFFERS
3914184Sgabeblack@google.com      MessageBuffer * requestFromCache, network="To", virtual_network="0",
4014184Sgabeblack@google.com            vnet_type = "request";
4114184Sgabeblack@google.com      MessageBuffer * forwardFromCache, network="To", virtual_network="1",
4214184Sgabeblack@google.com            vnet_type = "forward";
4314184Sgabeblack@google.com      MessageBuffer * responseFromCache, network="To", virtual_network="2",
4414184Sgabeblack@google.com            vnet_type = "response";
4514184Sgabeblack@google.com
4614184Sgabeblack@google.com      MessageBuffer * mandatoryQueue;
4714184Sgabeblack@google.com{
4814184Sgabeblack@google.com  // STATES
4914184Sgabeblack@google.com  state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
5014184Sgabeblack@google.com    I,  AccessPermission:Invalid, desc="Not Present/Invalid";
5114184Sgabeblack@google.com  }
5214184Sgabeblack@google.com
5314184Sgabeblack@google.com  // EVENTS
5414184Sgabeblack@google.com  enumeration(Event, desc="Cache events") {
5514184Sgabeblack@google.com    // From processor
5614184Sgabeblack@google.com    Request,    desc="Request from Garnet_standalone";
5714184Sgabeblack@google.com    Forward,    desc="Forward from Garnet_standalone";
5814184Sgabeblack@google.com    Response,   desc="Response from Garnet_standalone";
5914184Sgabeblack@google.com  }
6014184Sgabeblack@google.com
6114184Sgabeblack@google.com  // STRUCTURE DEFINITIONS
6214184Sgabeblack@google.com  DataBlock dummyData;
6314184Sgabeblack@google.com
6414184Sgabeblack@google.com  // CacheEntry
6514184Sgabeblack@google.com  structure(Entry, desc="...", interface="AbstractCacheEntry") {
6614184Sgabeblack@google.com    State CacheState,        desc="cache state";
6714184Sgabeblack@google.com    DataBlock DataBlk,       desc="Data in the block";
6814184Sgabeblack@google.com  }
6914184Sgabeblack@google.com
7014184Sgabeblack@google.com  // FUNCTIONS
7114184Sgabeblack@google.com  Tick clockEdge();
7214184Sgabeblack@google.com  MachineID mapAddressToMachine(Addr addr, MachineType mtype);
7314184Sgabeblack@google.com
7414184Sgabeblack@google.com  // cpu/testers/networktest/networktest.cc generates packets of the type
7514184Sgabeblack@google.com  // ReadReq, INST_FETCH, and WriteReq.
7614184Sgabeblack@google.com  // These are converted to LD, IFETCH and ST by mem/ruby/system/RubyPort.cc.
7714184Sgabeblack@google.com  // These are then sent to the sequencer, which sends them here.
7814184Sgabeblack@google.com  // Garnet_standalone-cache.sm tags LD, IFETCH and ST as Request, Forward,
7914184Sgabeblack@google.com  // and Response Events respectively, which are then injected into
8014184Sgabeblack@google.com  // virtual networks 0, 1 and 2 respectively.
8114184Sgabeblack@google.com  // This models traffic of different types within the network.
8214184Sgabeblack@google.com  //
8314184Sgabeblack@google.com  // Note that requests and forwards are MessageSizeType:Control,
8414184Sgabeblack@google.com  // while responses are MessageSizeType:Data.
8514184Sgabeblack@google.com  //
8614184Sgabeblack@google.com  Event mandatory_request_type_to_event(RubyRequestType type) {
8714184Sgabeblack@google.com    if (type == RubyRequestType:LD) {
8814184Sgabeblack@google.com      return Event:Request;
8914184Sgabeblack@google.com    } else if (type == RubyRequestType:IFETCH) {
9014184Sgabeblack@google.com      return Event:Forward;
9114184Sgabeblack@google.com    } else if (type == RubyRequestType:ST) {
9214184Sgabeblack@google.com      return Event:Response;
9314184Sgabeblack@google.com    } else {
9414184Sgabeblack@google.com      error("Invalid RubyRequestType");
9514184Sgabeblack@google.com    }
9614184Sgabeblack@google.com  }
9714184Sgabeblack@google.com
9814184Sgabeblack@google.com
9914184Sgabeblack@google.com  State getState(Entry cache_entry, Addr addr) {
10014184Sgabeblack@google.com    return State:I;
10114184Sgabeblack@google.com  }
10214184Sgabeblack@google.com
10314184Sgabeblack@google.com  void setState(Entry cache_entry, Addr addr, State state) {
10414184Sgabeblack@google.com
10514184Sgabeblack@google.com  }
10614184Sgabeblack@google.com
10714184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
10814184Sgabeblack@google.com    return AccessPermission:NotPresent;
10914184Sgabeblack@google.com  }
11014184Sgabeblack@google.com
11114184Sgabeblack@google.com  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
11214184Sgabeblack@google.com  }
11314184Sgabeblack@google.com
11414184Sgabeblack@google.com  Entry getCacheEntry(Addr address), return_by_pointer="yes" {
11514184Sgabeblack@google.com    return OOD;
11614184Sgabeblack@google.com  }
11714184Sgabeblack@google.com
11814184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
11914184Sgabeblack@google.com    error("Garnet_standalone does not support functional read.");
12014184Sgabeblack@google.com  }
12114184Sgabeblack@google.com
12214184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
12314184Sgabeblack@google.com    error("Garnet_standalone does not support functional write.");
12414184Sgabeblack@google.com  }
12514184Sgabeblack@google.com
12614184Sgabeblack@google.com  // NETWORK PORTS
12714184Sgabeblack@google.com
12814184Sgabeblack@google.com  out_port(requestNetwork_out, RequestMsg, requestFromCache);
12914184Sgabeblack@google.com  out_port(forwardNetwork_out, RequestMsg, forwardFromCache);
13014184Sgabeblack@google.com  out_port(responseNetwork_out, RequestMsg, responseFromCache);
13114184Sgabeblack@google.com
13214184Sgabeblack@google.com  // Mandatory Queue
13314184Sgabeblack@google.com  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...") {
13414184Sgabeblack@google.com    if (mandatoryQueue_in.isReady(clockEdge())) {
13514184Sgabeblack@google.com      peek(mandatoryQueue_in, RubyRequest) {
13614184Sgabeblack@google.com        trigger(mandatory_request_type_to_event(in_msg.Type),
13714184Sgabeblack@google.com                in_msg.LineAddress, getCacheEntry(in_msg.LineAddress));
13814184Sgabeblack@google.com      }
13914184Sgabeblack@google.com    }
14014184Sgabeblack@google.com  }
14114184Sgabeblack@google.com
14214184Sgabeblack@google.com  // ACTIONS
14314184Sgabeblack@google.com
14414184Sgabeblack@google.com  // The destination directory of the packets is embedded in the address
14514184Sgabeblack@google.com  // map_Address_to_Directory is used to retrieve it.
14614184Sgabeblack@google.com
14714184Sgabeblack@google.com  action(a_issueRequest, "a", desc="Issue a request") {
14814184Sgabeblack@google.com    enqueue(requestNetwork_out, RequestMsg, issue_latency) {
14914184Sgabeblack@google.com      out_msg.addr := address;
15014184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:MSG;
15114184Sgabeblack@google.com      out_msg.Requestor := machineID;
15214184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
15314184Sgabeblack@google.com
15414184Sgabeblack@google.com      // To send broadcasts in vnet0 (to emulate broadcast-based protocols),
15514184Sgabeblack@google.com      // replace the above line by the following:
15614184Sgabeblack@google.com      // out_msg.Destination := broadcast(MachineType:Directory);
15714184Sgabeblack@google.com
15814184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Control;
15914184Sgabeblack@google.com    }
16014184Sgabeblack@google.com  }
16114184Sgabeblack@google.com
16214184Sgabeblack@google.com  action(b_issueForward, "b", desc="Issue a forward") {
16314184Sgabeblack@google.com    enqueue(forwardNetwork_out, RequestMsg, issue_latency) {
16414184Sgabeblack@google.com      out_msg.addr := address;
16514184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:MSG;
16614184Sgabeblack@google.com      out_msg.Requestor := machineID;
16714184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
16814184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Control;
16914184Sgabeblack@google.com    }
17014184Sgabeblack@google.com  }
17114184Sgabeblack@google.com
17214184Sgabeblack@google.com  action(c_issueResponse, "c", desc="Issue a response") {
17314184Sgabeblack@google.com    enqueue(responseNetwork_out, RequestMsg, issue_latency) {
17414184Sgabeblack@google.com      out_msg.addr := address;
17514184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:MSG;
17614184Sgabeblack@google.com      out_msg.Requestor := machineID;
17714184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
17814184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Data;
17914184Sgabeblack@google.com    }
18014184Sgabeblack@google.com  }
18114184Sgabeblack@google.com
18214184Sgabeblack@google.com  action(m_popMandatoryQueue, "m", desc="Pop the mandatory request queue") {
18314184Sgabeblack@google.com    mandatoryQueue_in.dequeue(clockEdge());
18414184Sgabeblack@google.com  }
18514184Sgabeblack@google.com
18614184Sgabeblack@google.com  action(r_load_hit, "r", desc="Notify sequencer the load completed.") {
18714184Sgabeblack@google.com    sequencer.readCallback(address, dummyData);
18814184Sgabeblack@google.com  }
18914184Sgabeblack@google.com
19014184Sgabeblack@google.com  action(s_store_hit, "s", desc="Notify sequencer that store completed.") {
19114184Sgabeblack@google.com    sequencer.writeCallback(address, dummyData);
19214184Sgabeblack@google.com  }
19314184Sgabeblack@google.com
19414184Sgabeblack@google.com
19514184Sgabeblack@google.com  // TRANSITIONS
19614184Sgabeblack@google.com
19714184Sgabeblack@google.com  // sequencer hit call back is performed after injecting the packets.
19814184Sgabeblack@google.com  // The goal of the Garnet_standalone protocol is only to inject packets into
19914184Sgabeblack@google.com  // the network, not to keep track of them via TBEs.
20014184Sgabeblack@google.com
20114184Sgabeblack@google.com  transition(I, Response) {
20214184Sgabeblack@google.com    s_store_hit;
20314184Sgabeblack@google.com    c_issueResponse;
20414184Sgabeblack@google.com    m_popMandatoryQueue;
20514184Sgabeblack@google.com  }
20614184Sgabeblack@google.com
20714184Sgabeblack@google.com  transition(I, Request) {
20814184Sgabeblack@google.com    r_load_hit;
20914184Sgabeblack@google.com    a_issueRequest;
21014184Sgabeblack@google.com    m_popMandatoryQueue;
21114184Sgabeblack@google.com  }
21214184Sgabeblack@google.com  transition(I, Forward) {
21314184Sgabeblack@google.com    r_load_hit;
21414184Sgabeblack@google.com    b_issueForward;
21514184Sgabeblack@google.com    m_popMandatoryQueue;
21614184Sgabeblack@google.com  }
21714184Sgabeblack@google.com
21814184Sgabeblack@google.com}
219