114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
314184Sgabeblack@google.com * All rights reserved.
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * For use for simulation and test purposes only
614184Sgabeblack@google.com *
714184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
814184Sgabeblack@google.com * modification, are permitted provided that the following conditions are met:
914184Sgabeblack@google.com *
1014184Sgabeblack@google.com * 1. Redistributions of source code must retain the above copyright notice,
1114184Sgabeblack@google.com * this list of conditions and the following disclaimer.
1214184Sgabeblack@google.com *
1314184Sgabeblack@google.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1414184Sgabeblack@google.com * this list of conditions and the following disclaimer in the documentation
1514184Sgabeblack@google.com * and/or other materials provided with the distribution.
1614184Sgabeblack@google.com *
1714184Sgabeblack@google.com * 3. Neither the name of the copyright holder nor the names of its
1814184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from this
1914184Sgabeblack@google.com * software without specific prior written permission.
2014184Sgabeblack@google.com *
2114184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2214184Sgabeblack@google.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2314184Sgabeblack@google.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2414184Sgabeblack@google.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2514184Sgabeblack@google.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2614184Sgabeblack@google.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2714184Sgabeblack@google.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2814184Sgabeblack@google.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2914184Sgabeblack@google.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3014184Sgabeblack@google.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3114184Sgabeblack@google.com * POSSIBILITY OF SUCH DAMAGE.
3214184Sgabeblack@google.com *
3314184Sgabeblack@google.com * Authors: Jason Power
3414184Sgabeblack@google.com */
3514184Sgabeblack@google.com
3614184Sgabeblack@google.commachine(MachineType:RegionBuffer, "Region Buffer for AMD_Base-like protocol")
3714184Sgabeblack@google.com: CacheMemory *cacheMemory; // stores only region addresses. Must set block size same as below
3814184Sgabeblack@google.com  bool isOnCPU;
3914184Sgabeblack@google.com  int blocksPerRegion := 64; // 4k regions
4014184Sgabeblack@google.com  Cycles toDirLatency := 5;     // Latency to fwd requests to directory
4114184Sgabeblack@google.com  Cycles toRegionDirLatency := 5; // Latency for requests and acks to directory
4214184Sgabeblack@google.com  Cycles nextEvictLatency := 1;   // latency added between each block while evicting region
4314184Sgabeblack@google.com  bool noTCCdir := "False";
4414184Sgabeblack@google.com  int TCC_select_num_bits := 1;
4514184Sgabeblack@google.com
4614184Sgabeblack@google.com  // From the Cores
4714184Sgabeblack@google.com  MessageBuffer * requestFromCore, network="From", virtual_network="0", vnet_type="request";
4814184Sgabeblack@google.com  MessageBuffer * responseFromCore, network="From", virtual_network="2", vnet_type="response";
4914184Sgabeblack@google.com
5014184Sgabeblack@google.com  // Requests to the cores or directory
5114184Sgabeblack@google.com  MessageBuffer * requestToNetwork, network="To", virtual_network="0", vnet_type="request";
5214184Sgabeblack@google.com
5314184Sgabeblack@google.com  // From Region-Dir
5414184Sgabeblack@google.com  MessageBuffer * notifyFromRegionDir, network="From", virtual_network="7", vnet_type="request";
5514184Sgabeblack@google.com  MessageBuffer * probeFromRegionDir, network="From", virtual_network="8", vnet_type="request";
5614184Sgabeblack@google.com
5714184Sgabeblack@google.com  // From the directory
5814184Sgabeblack@google.com  MessageBuffer * unblockFromDir, network="From", virtual_network="4", vnet_type="unblock";
5914184Sgabeblack@google.com
6014184Sgabeblack@google.com  // To the region-Dir
6114184Sgabeblack@google.com  MessageBuffer * responseToRegDir, network="To", virtual_network="2", vnet_type="response";
6214184Sgabeblack@google.com
6314184Sgabeblack@google.com  MessageBuffer * triggerQueue;
6414184Sgabeblack@google.com{
6514184Sgabeblack@google.com
6614184Sgabeblack@google.com  // States
6714184Sgabeblack@google.com  state_declaration(State, desc="Region states", default="RegionBuffer_State_NP") {
6814184Sgabeblack@google.com    NP, AccessPermission:Invalid,       desc="Not present in region directory";
6914184Sgabeblack@google.com    P,  AccessPermission:Invalid,       desc="Region is private to the cache";
7014184Sgabeblack@google.com    S,  AccessPermission:Invalid,       desc="Region is possibly shared with others";
7114184Sgabeblack@google.com
7214184Sgabeblack@google.com    NP_PS, AccessPermission:Invalid,    desc="Intermediate state waiting for notify from r-dir";
7314184Sgabeblack@google.com    S_P,  AccessPermission:Invalid,     desc="Intermediate state while upgrading region";
7414184Sgabeblack@google.com
7514184Sgabeblack@google.com    P_NP, AccessPermission:Invalid,     desc="Intermediate state while evicting all lines in region";
7614184Sgabeblack@google.com    P_S,  AccessPermission:Invalid,     desc="Intermediate state while downgrading all lines in region";
7714184Sgabeblack@google.com
7814184Sgabeblack@google.com    S_NP_PS, AccessPermission:Invalid,  desc="Got an inv in S_P, waiting for all inv acks, then going to since the write is already out there NP_PS";
7914184Sgabeblack@google.com    P_NP_NP,  AccessPermission:Invalid,    desc="Evicting region on repl, then got an inv. Need to re-evict";
8014184Sgabeblack@google.com
8114184Sgabeblack@google.com    P_NP_O, AccessPermission:Invalid,     desc="Waiting for all outstanding requests";
8214184Sgabeblack@google.com    P_S_O,  AccessPermission:Invalid,     desc="Waiting for all outstanding requests";
8314184Sgabeblack@google.com    S_O,  AccessPermission:Invalid,       desc="Waiting for all outstanding requests";
8414184Sgabeblack@google.com    S_NP_PS_O, AccessPermission:Invalid,  desc="Waiting for all outstanding requests";
8514184Sgabeblack@google.com
8614184Sgabeblack@google.com    SS_P, AccessPermission:Invalid,  desc="Waiting for CPU write that we know is there";
8714184Sgabeblack@google.com
8814184Sgabeblack@google.com    P_NP_W, AccessPermission:Invalid,     desc="Waiting for writeback ack";
8914184Sgabeblack@google.com
9014184Sgabeblack@google.com    NP_W, AccessPermission:Invalid,     desc="Got a done ack before request, waiting for that victim";
9114184Sgabeblack@google.com  }
9214184Sgabeblack@google.com
9314184Sgabeblack@google.com  enumeration(Event, desc="Region directory events") {
9414184Sgabeblack@google.com    CPURead,        desc="Access from CPU core";
9514184Sgabeblack@google.com    CPUWrite,       desc="Access from CPU core";
9614184Sgabeblack@google.com    CPUWriteback,       desc="Writeback request from CPU core";
9714184Sgabeblack@google.com
9814184Sgabeblack@google.com    ReplRegion,     desc="Start a replace on a region";
9914184Sgabeblack@google.com
10014184Sgabeblack@google.com    PrivateNotify,  desc="Update entry to private state";
10114184Sgabeblack@google.com    SharedNotify,   desc="Update entry to shared state";
10214184Sgabeblack@google.com    WbNotify,       desc="Writeback notification received";
10314184Sgabeblack@google.com    InvRegion,      desc="Start invalidating a region";
10414184Sgabeblack@google.com    DowngradeRegion,desc="Start invalidating a region";
10514184Sgabeblack@google.com
10614184Sgabeblack@google.com    InvAck,         desc="Ack from core";
10714184Sgabeblack@google.com
10814184Sgabeblack@google.com    DoneAck,        desc="Ack from core that request has finished";
10914184Sgabeblack@google.com    AllOutstanding, desc="All outstanding requests have now finished";
11014184Sgabeblack@google.com
11114184Sgabeblack@google.com    Evict,          desc="Loopback to evict each block";
11214184Sgabeblack@google.com    LastAck_PrbResp, desc="Done eviciting all the blocks, got the last ack from core, now respond to region dir";
11314184Sgabeblack@google.com    LastAck_CleanWb, desc="Done eviciting all the blocks, got the last ack from core, now start clean writeback (note the dir has already been updated)";
11414184Sgabeblack@google.com
11514184Sgabeblack@google.com    StallAccess,    desc="Wait for the done ack on the address before proceeding";
11614184Sgabeblack@google.com    StallDoneAck,   desc="Wait for the access on the address before proceeding";
11714184Sgabeblack@google.com
11814184Sgabeblack@google.com    StaleRequest,   desc="Got a stale victim from the cache, fwd it without incrementing outstanding";
11914184Sgabeblack@google.com  }
12014184Sgabeblack@google.com
12114184Sgabeblack@google.com  enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
12214184Sgabeblack@google.com    TagArrayRead,     desc="Read the data array";
12314184Sgabeblack@google.com    TagArrayWrite,    desc="Write the data array";
12414184Sgabeblack@google.com  }
12514184Sgabeblack@google.com
12614184Sgabeblack@google.com  structure(BoolVec, external="yes") {
12714184Sgabeblack@google.com    bool at(int);
12814184Sgabeblack@google.com    void resize(int);
12914184Sgabeblack@google.com    void clear();
13014184Sgabeblack@google.com    int size();
13114184Sgabeblack@google.com  }
13214184Sgabeblack@google.com
13314184Sgabeblack@google.com  structure(Entry, desc="Region entry", interface="AbstractCacheEntry") {
13414184Sgabeblack@google.com    Addr addr,        desc="Base address of this region";
13514184Sgabeblack@google.com    State RegionState,      desc="Region state";
13614184Sgabeblack@google.com    DataBlock DataBlk,      desc="Data for the block (always empty in region buffer)";
13714184Sgabeblack@google.com    BoolVec ValidBlocks,    desc="A vector to keep track of valid blocks";
13814184Sgabeblack@google.com    int NumValidBlocks,     desc="Number of trues in ValidBlocks to avoid iterating";
13914184Sgabeblack@google.com    BoolVec UsedBlocks,     desc="A vector to keep track of blocks ever valid";
14014184Sgabeblack@google.com    bool dirty,           desc="Dirty as best known by the region buffer";
14114184Sgabeblack@google.com    // This is needed so we don't ack an invalidate until all requests are ordered
14214184Sgabeblack@google.com    int NumOutstandingReqs,    desc="Total outstanding private/shared requests";
14314184Sgabeblack@google.com    BoolVec OutstandingReqs,   desc="Blocks that have outstanding private/shared requests";
14414184Sgabeblack@google.com    bool MustDowngrade,     desc="Set when we got a downgrade before the shd or pvt permissions";
14514184Sgabeblack@google.com    Cycles ProbeRequestTime, default="Cycles(0)", desc="Time region dir started the probe";
14614184Sgabeblack@google.com    Cycles InitialRequestTime, default="Cycles(0)", desc="Time message was sent to region dir";
14714184Sgabeblack@google.com    bool MsgSentToDir,      desc="True if the current request required a message to the dir";
14814184Sgabeblack@google.com    bool clearOnDone, default="false", desc="clear valid bit when request completes";
14914184Sgabeblack@google.com    Addr clearOnDoneAddr, desc="clear valid bit when request completes";
15014184Sgabeblack@google.com  }
15114184Sgabeblack@google.com
15214184Sgabeblack@google.com  structure(TBE, desc="...") {
15314184Sgabeblack@google.com    State TBEState,         desc="Transient state";
15414184Sgabeblack@google.com    //int NumValidBlocks,     desc="Number of blocks valid so we don't have to count a BoolVec";
15514184Sgabeblack@google.com    BoolVec ValidBlocks,    desc="A vector to keep track of valid blocks";
15614184Sgabeblack@google.com    bool AllAcksReceived,   desc="Got all necessary acks from dir";
15714184Sgabeblack@google.com    bool DoneEvicting,      desc="Done iterating through blocks checking for valids";
15814184Sgabeblack@google.com    BoolVec AcksReceived,   desc="Received acks for theses blocks\n";
15914184Sgabeblack@google.com    bool SendAck,           desc="If true, send an ack to the r-dir at end of inv";
16014184Sgabeblack@google.com    ProbeRequestType MsgType, desc="Type of message to send while 'evicting' ";
16114184Sgabeblack@google.com    int NumOutstandingReqs,    desc="Total outstanding private/shared requests";
16214184Sgabeblack@google.com    BoolVec OutstandingReqs,   desc="Blocks that have outstanding private/shared requests";
16314184Sgabeblack@google.com    MachineID Requestor,    desc="Requestor for three hop transactions";
16414184Sgabeblack@google.com    bool DemandRequest, default="false", desc="Associated with a demand request";
16514184Sgabeblack@google.com    Addr DemandAddress,  desc="Address for the demand request";
16614184Sgabeblack@google.com    bool DoneAckReceived, default="false", desc="True if the done ack arrived before the message";
16714184Sgabeblack@google.com    Addr DoneAckAddr,     desc="Address of the done ack received early";
16814184Sgabeblack@google.com    int OutstandingThreshold, desc="Number of outstanding requests to trigger AllOutstanding on";
16914184Sgabeblack@google.com
17014184Sgabeblack@google.com    ProbeRequestType NewMsgType, desc="Type of message to send while 'evicting' ";
17114184Sgabeblack@google.com    MachineID NewRequestor,    desc="Requestor for three hop transactions";
17214184Sgabeblack@google.com    bool NewDemandRequest, default="false", desc="Associated with a demand request";
17314184Sgabeblack@google.com    Addr NewDemandAddress,  desc="Address for the demand request";
17414184Sgabeblack@google.com    bool dirty, desc="dirty";
17514184Sgabeblack@google.com    bool AllOutstandingTriggered, default="false", desc="bit for only one all outstanding";
17614184Sgabeblack@google.com    int OutstandingAcks, default="0", desc="number of acks to wait for";
17714184Sgabeblack@google.com  }
17814184Sgabeblack@google.com
17914184Sgabeblack@google.com  structure(TBETable, external="yes") {
18014184Sgabeblack@google.com    TBE lookup(Addr);
18114184Sgabeblack@google.com    void allocate(Addr);
18214184Sgabeblack@google.com    void deallocate(Addr);
18314184Sgabeblack@google.com    bool isPresent(Addr);
18414184Sgabeblack@google.com  }
18514184Sgabeblack@google.com
18614184Sgabeblack@google.com  // Stores only region addresses
18714184Sgabeblack@google.com  TBETable TBEs, template="<RegionBuffer_TBE>", constructor="m_number_of_TBEs";
18814184Sgabeblack@google.com  int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()";
18914184Sgabeblack@google.com
19014184Sgabeblack@google.com  Tick clockEdge();
19114184Sgabeblack@google.com  Tick cyclesToTicks(Cycles c);
19214184Sgabeblack@google.com
19314184Sgabeblack@google.com  void set_cache_entry(AbstractCacheEntry b);
19414184Sgabeblack@google.com  void unset_cache_entry();
19514184Sgabeblack@google.com  void set_tbe(TBE b);
19614184Sgabeblack@google.com  void unset_tbe();
19714184Sgabeblack@google.com  void wakeUpAllBuffers();
19814184Sgabeblack@google.com  void wakeUpBuffers(Addr a);
19914184Sgabeblack@google.com  Cycles curCycle();
20014184Sgabeblack@google.com  MachineID mapAddressToMachine(Addr addr, MachineType mtype);
20114184Sgabeblack@google.com
20214184Sgabeblack@google.com  int blockBits,  default="RubySystem::getBlockSizeBits()";
20314184Sgabeblack@google.com  int blockBytes, default="RubySystem::getBlockSizeBytes()";
20414184Sgabeblack@google.com  int regionBits, default="log2(m_blocksPerRegion)";
20514184Sgabeblack@google.com
20614184Sgabeblack@google.com  // Functions
20714184Sgabeblack@google.com
20814184Sgabeblack@google.com  int getRegionOffset(Addr addr) {
20914184Sgabeblack@google.com    if (blocksPerRegion > 1) {
21014184Sgabeblack@google.com      Addr offset := bitSelect(addr, blockBits, regionBits+blockBits-1);
21114184Sgabeblack@google.com      int ret := addressToInt(offset);
21214184Sgabeblack@google.com      assert(ret < blocksPerRegion);
21314184Sgabeblack@google.com      return ret;
21414184Sgabeblack@google.com    } else {
21514184Sgabeblack@google.com      return 0;
21614184Sgabeblack@google.com    }
21714184Sgabeblack@google.com  }
21814184Sgabeblack@google.com
21914184Sgabeblack@google.com  Addr getRegionBase(Addr addr) {
22014184Sgabeblack@google.com    return maskLowOrderBits(addr, blockBits+regionBits);
22114184Sgabeblack@google.com  }
22214184Sgabeblack@google.com
22314184Sgabeblack@google.com  Addr getNextBlock(Addr addr) {
22414184Sgabeblack@google.com    Addr a := addr;
22514184Sgabeblack@google.com    return makeNextStrideAddress(a, 1);
22614184Sgabeblack@google.com  }
22714184Sgabeblack@google.com
22814184Sgabeblack@google.com  MachineID getPeer(MachineID mach, Addr address) {
22914184Sgabeblack@google.com    if (isOnCPU) {
23014184Sgabeblack@google.com      return createMachineID(MachineType:CorePair, intToID(0));
23114184Sgabeblack@google.com    } else if (noTCCdir) {
23214184Sgabeblack@google.com      return mapAddressToRange(address,MachineType:TCC,
23314184Sgabeblack@google.com                                  TCC_select_low_bit, TCC_select_num_bits);
23414184Sgabeblack@google.com    } else {
23514184Sgabeblack@google.com      return createMachineID(MachineType:TCCdir, intToID(0));
23614184Sgabeblack@google.com    }
23714184Sgabeblack@google.com  }
23814184Sgabeblack@google.com
23914184Sgabeblack@google.com  bool isOutstanding(TBE tbe, Entry cache_entry, Addr addr) {
24014184Sgabeblack@google.com      if (is_valid(tbe) && tbe.OutstandingReqs.size() > 0) {
24114184Sgabeblack@google.com          DPRINTF(RubySlicc, " outstanding tbe reqs %s %s %d %d\n",
24214184Sgabeblack@google.com                  tbe.OutstandingReqs, addr, getRegionOffset(addr),
24314184Sgabeblack@google.com                  tbe.OutstandingReqs.at(getRegionOffset(addr)));
24414184Sgabeblack@google.com          return tbe.OutstandingReqs.at(getRegionOffset(addr));
24514184Sgabeblack@google.com      } else if (is_valid(cache_entry)) {
24614184Sgabeblack@google.com          DPRINTF(RubySlicc, " outstanding cache reqs %s %s %d %d\n",
24714184Sgabeblack@google.com                  cache_entry.OutstandingReqs, addr, getRegionOffset(addr),
24814184Sgabeblack@google.com                  cache_entry.OutstandingReqs.at(getRegionOffset(addr)));
24914184Sgabeblack@google.com          return cache_entry.OutstandingReqs.at(getRegionOffset(addr));
25014184Sgabeblack@google.com      } else {
25114184Sgabeblack@google.com          return false;
25214184Sgabeblack@google.com      }
25314184Sgabeblack@google.com  }
25414184Sgabeblack@google.com
25514184Sgabeblack@google.com  bool isOnGPU() {
25614184Sgabeblack@google.com    if (isOnCPU) {
25714184Sgabeblack@google.com      return false;
25814184Sgabeblack@google.com    }
25914184Sgabeblack@google.com    return true;
26014184Sgabeblack@google.com  }
26114184Sgabeblack@google.com
26214184Sgabeblack@google.com  bool isRead(CoherenceRequestType type) {
26314184Sgabeblack@google.com    return (type == CoherenceRequestType:RdBlk || type == CoherenceRequestType:RdBlkS ||
26414184Sgabeblack@google.com            type == CoherenceRequestType:VicClean);
26514184Sgabeblack@google.com  }
26614184Sgabeblack@google.com
26714184Sgabeblack@google.com  bool presentOrAvail(Addr addr) {
26814184Sgabeblack@google.com    return cacheMemory.isTagPresent(getRegionBase(addr)) || cacheMemory.cacheAvail(getRegionBase(addr));
26914184Sgabeblack@google.com  }
27014184Sgabeblack@google.com
27114184Sgabeblack@google.com  // Returns a region entry!
27214184Sgabeblack@google.com  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
27314184Sgabeblack@google.com    return static_cast(Entry, "pointer", cacheMemory.lookup(getRegionBase(addr)));
27414184Sgabeblack@google.com  }
27514184Sgabeblack@google.com
27614184Sgabeblack@google.com  TBE getTBE(Addr addr), return_by_pointer="yes" {
27714184Sgabeblack@google.com    return TBEs.lookup(getRegionBase(addr));
27814184Sgabeblack@google.com  }
27914184Sgabeblack@google.com
28014184Sgabeblack@google.com  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
28114184Sgabeblack@google.com    return getCacheEntry(getRegionBase(addr)).DataBlk;
28214184Sgabeblack@google.com  }
28314184Sgabeblack@google.com
28414184Sgabeblack@google.com  State getState(TBE tbe, Entry cache_entry, Addr addr) {
28514184Sgabeblack@google.com    if (is_valid(tbe)) {
28614184Sgabeblack@google.com      return tbe.TBEState;
28714184Sgabeblack@google.com    } else if (is_valid(cache_entry)) {
28814184Sgabeblack@google.com      return cache_entry.RegionState;
28914184Sgabeblack@google.com    }
29014184Sgabeblack@google.com    return State:NP;
29114184Sgabeblack@google.com  }
29214184Sgabeblack@google.com
29314184Sgabeblack@google.com  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
29414184Sgabeblack@google.com    if (is_valid(tbe)) {
29514184Sgabeblack@google.com        tbe.TBEState := state;
29614184Sgabeblack@google.com    }
29714184Sgabeblack@google.com    if (is_valid(cache_entry)) {
29814184Sgabeblack@google.com        cache_entry.RegionState := state;
29914184Sgabeblack@google.com    }
30014184Sgabeblack@google.com  }
30114184Sgabeblack@google.com
30214184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
30314184Sgabeblack@google.com    TBE tbe := getTBE(addr);
30414184Sgabeblack@google.com    if(is_valid(tbe)) {
30514184Sgabeblack@google.com      return RegionBuffer_State_to_permission(tbe.TBEState);
30614184Sgabeblack@google.com    }
30714184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
30814184Sgabeblack@google.com    if(is_valid(cache_entry)) {
30914184Sgabeblack@google.com      return RegionBuffer_State_to_permission(cache_entry.RegionState);
31014184Sgabeblack@google.com    }
31114184Sgabeblack@google.com    return AccessPermission:NotPresent;
31214184Sgabeblack@google.com  }
31314184Sgabeblack@google.com
31414184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
31514184Sgabeblack@google.com    functionalMemoryRead(pkt);
31614184Sgabeblack@google.com  }
31714184Sgabeblack@google.com
31814184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
31914184Sgabeblack@google.com    if (functionalMemoryWrite(pkt)) {
32014184Sgabeblack@google.com      return 1;
32114184Sgabeblack@google.com    } else {
32214184Sgabeblack@google.com      return 0;
32314184Sgabeblack@google.com    }
32414184Sgabeblack@google.com  }
32514184Sgabeblack@google.com
32614184Sgabeblack@google.com  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
32714184Sgabeblack@google.com    if (is_valid(cache_entry)) {
32814184Sgabeblack@google.com      cache_entry.changePermission(RegionBuffer_State_to_permission(state));
32914184Sgabeblack@google.com    }
33014184Sgabeblack@google.com  }
33114184Sgabeblack@google.com
33214184Sgabeblack@google.com  void recordRequestType(RequestType stat, Addr addr) {
33314184Sgabeblack@google.com    if (stat == RequestType:TagArrayRead) {
33414184Sgabeblack@google.com        cacheMemory.recordRequestType(CacheRequestType:TagArrayRead, addr);
33514184Sgabeblack@google.com    } else if (stat == RequestType:TagArrayWrite) {
33614184Sgabeblack@google.com        cacheMemory.recordRequestType(CacheRequestType:TagArrayWrite, addr);
33714184Sgabeblack@google.com    }
33814184Sgabeblack@google.com  }
33914184Sgabeblack@google.com
34014184Sgabeblack@google.com  bool checkResourceAvailable(RequestType request_type, Addr addr) {
34114184Sgabeblack@google.com    if (request_type == RequestType:TagArrayRead) {
34214184Sgabeblack@google.com      return cacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr);
34314184Sgabeblack@google.com    } else if (request_type == RequestType:TagArrayWrite) {
34414184Sgabeblack@google.com      return cacheMemory.checkResourceAvailable(CacheResourceType:TagArray, addr);
34514184Sgabeblack@google.com    } else {
34614184Sgabeblack@google.com      error("Invalid RequestType type in checkResourceAvailable");
34714184Sgabeblack@google.com      return true;
34814184Sgabeblack@google.com    }
34914184Sgabeblack@google.com  }
35014184Sgabeblack@google.com
35114184Sgabeblack@google.com  out_port(triggerQueue_out, TriggerMsg, triggerQueue);
35214184Sgabeblack@google.com
35314184Sgabeblack@google.com  // Overloaded outgoing request nework for both probes to cores and reqeusts
35414184Sgabeblack@google.com  // to the directory.
35514184Sgabeblack@google.com  // Fix Me: These forwarded requests need to be on a separate virtual channel
35614184Sgabeblack@google.com  // to avoid deadlock!
35714184Sgabeblack@google.com  out_port(requestNetwork_out, CPURequestMsg, requestToNetwork);
35814184Sgabeblack@google.com  out_port(probeNetwork_out, NBProbeRequestMsg, requestToNetwork);
35914184Sgabeblack@google.com
36014184Sgabeblack@google.com  out_port(responseNetwork_out, ResponseMsg, responseToRegDir);
36114184Sgabeblack@google.com
36214184Sgabeblack@google.com  in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=4) {
36314184Sgabeblack@google.com    if (triggerQueue_in.isReady(clockEdge())) {
36414184Sgabeblack@google.com      peek(triggerQueue_in, TriggerMsg) {
36514184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
36614184Sgabeblack@google.com        TBE tbe := getTBE(in_msg.addr);
36714184Sgabeblack@google.com        DPRINTF(RubySlicc, "trigger msg: %s (%s)\n", in_msg, getRegionBase(in_msg.addr));
36814184Sgabeblack@google.com        assert(is_valid(tbe));
36914184Sgabeblack@google.com        if (in_msg.Type == TriggerType:AcksComplete) {
37014184Sgabeblack@google.com            if (tbe.SendAck) {
37114184Sgabeblack@google.com                trigger(Event:LastAck_PrbResp, in_msg.addr, cache_entry, tbe);
37214184Sgabeblack@google.com            } else {
37314184Sgabeblack@google.com                trigger(Event:LastAck_CleanWb, in_msg.addr, cache_entry, tbe);
37414184Sgabeblack@google.com            }
37514184Sgabeblack@google.com        } else if (in_msg.Type == TriggerType:AllOutstanding) {
37614184Sgabeblack@google.com          trigger(Event:AllOutstanding, in_msg.addr, cache_entry, tbe);
37714184Sgabeblack@google.com        } else {
37814184Sgabeblack@google.com          assert(in_msg.Type == TriggerType:InvNext);
37914184Sgabeblack@google.com          trigger(Event:Evict, in_msg.addr, cache_entry, tbe);
38014184Sgabeblack@google.com        }
38114184Sgabeblack@google.com      }
38214184Sgabeblack@google.com    }
38314184Sgabeblack@google.com  }
38414184Sgabeblack@google.com
38514184Sgabeblack@google.com  in_port(unblockNetwork_in, UnblockMsg, unblockFromDir, rank=3) {
38614184Sgabeblack@google.com    if (unblockNetwork_in.isReady(clockEdge())) {
38714184Sgabeblack@google.com      peek(unblockNetwork_in, UnblockMsg) {
38814184Sgabeblack@google.com        TBE tbe := getTBE(in_msg.addr);
38914184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
39014184Sgabeblack@google.com        if (in_msg.DoneAck) {
39114184Sgabeblack@google.com          if (isOutstanding(tbe, cache_entry, in_msg.addr)) {
39214184Sgabeblack@google.com            trigger(Event:DoneAck, in_msg.addr, cache_entry, tbe);
39314184Sgabeblack@google.com          } else {
39414184Sgabeblack@google.com            trigger(Event:StallDoneAck, in_msg.addr, cache_entry, tbe);
39514184Sgabeblack@google.com          }
39614184Sgabeblack@google.com        } else {
39714184Sgabeblack@google.com          assert(is_valid(tbe));
39814184Sgabeblack@google.com          trigger(Event:InvAck, in_msg.addr, cache_entry, tbe);
39914184Sgabeblack@google.com        }
40014184Sgabeblack@google.com      }
40114184Sgabeblack@google.com    }
40214184Sgabeblack@google.com  }
40314184Sgabeblack@google.com
40414184Sgabeblack@google.com  in_port(probeNetwork_in, NBProbeRequestMsg, probeFromRegionDir, rank=2) {
40514184Sgabeblack@google.com    if (probeNetwork_in.isReady(clockEdge())) {
40614184Sgabeblack@google.com      peek(probeNetwork_in, NBProbeRequestMsg) {
40714184Sgabeblack@google.com        TBE tbe := getTBE(in_msg.addr);
40814184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
40914184Sgabeblack@google.com        assert(getRegionBase(in_msg.addr) == in_msg.addr);
41014184Sgabeblack@google.com        if (in_msg.Type == ProbeRequestType:PrbInv) {
41114184Sgabeblack@google.com          trigger(Event:InvRegion, in_msg.addr, cache_entry, tbe);
41214184Sgabeblack@google.com        } else if (in_msg.Type == ProbeRequestType:PrbDowngrade) {
41314184Sgabeblack@google.com          trigger(Event:DowngradeRegion, in_msg.addr, cache_entry, tbe);
41414184Sgabeblack@google.com        } else {
41514184Sgabeblack@google.com          error("Unknown probe message\n");
41614184Sgabeblack@google.com        }
41714184Sgabeblack@google.com      }
41814184Sgabeblack@google.com    }
41914184Sgabeblack@google.com  }
42014184Sgabeblack@google.com
42114184Sgabeblack@google.com  in_port(notifyNetwork_in, CPURequestMsg, notifyFromRegionDir, rank=1) {
42214184Sgabeblack@google.com    if (notifyNetwork_in.isReady(clockEdge())) {
42314184Sgabeblack@google.com      peek(notifyNetwork_in, CPURequestMsg) {
42414184Sgabeblack@google.com        TBE tbe := getTBE(in_msg.addr);
42514184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
42614184Sgabeblack@google.com        //Fix Me...add back in: assert(is_valid(cache_entry));
42714184Sgabeblack@google.com        if (in_msg.Type == CoherenceRequestType:WbNotify) {
42814184Sgabeblack@google.com          trigger(Event:WbNotify, in_msg.addr, cache_entry, tbe);
42914184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:SharedNotify) {
43014184Sgabeblack@google.com          trigger(Event:SharedNotify, in_msg.addr, cache_entry, tbe);
43114184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:PrivateNotify) {
43214184Sgabeblack@google.com          trigger(Event:PrivateNotify, in_msg.addr, cache_entry, tbe);
43314184Sgabeblack@google.com        } else {
43414184Sgabeblack@google.com          error("Unknown notify message\n");
43514184Sgabeblack@google.com        }
43614184Sgabeblack@google.com      }
43714184Sgabeblack@google.com    }
43814184Sgabeblack@google.com  }
43914184Sgabeblack@google.com
44014184Sgabeblack@google.com  // In from cores
44114184Sgabeblack@google.com  // NOTE: We get the cache / TBE entry based on the region address,
44214184Sgabeblack@google.com  //       but pass the block address to the actions
44314184Sgabeblack@google.com  in_port(requestNetwork_in, CPURequestMsg, requestFromCore, rank=0) {
44414184Sgabeblack@google.com    if (requestNetwork_in.isReady(clockEdge())) {
44514184Sgabeblack@google.com      peek(requestNetwork_in, CPURequestMsg) {
44614184Sgabeblack@google.com        TBE tbe := getTBE(in_msg.addr);
44714184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
44814184Sgabeblack@google.com        if (is_valid(tbe) && tbe.DoneAckReceived && tbe.DoneAckAddr == in_msg.addr) {
44914184Sgabeblack@google.com            DPRINTF(RubySlicc, "Stale/Stall request %s\n", in_msg.Type);
45014184Sgabeblack@google.com          if (in_msg.Type == CoherenceRequestType:VicDirty || in_msg.Type == CoherenceRequestType:VicClean )
45114184Sgabeblack@google.com          {
45214184Sgabeblack@google.com            trigger(Event:StaleRequest, in_msg.addr, cache_entry, tbe);
45314184Sgabeblack@google.com          } else {
45414184Sgabeblack@google.com            trigger(Event:StallAccess, in_msg.addr, cache_entry, tbe);
45514184Sgabeblack@google.com          }
45614184Sgabeblack@google.com        } else if (isOutstanding(tbe, cache_entry, in_msg.addr)) {
45714184Sgabeblack@google.com          DPRINTF(RubySlicc, "Stall outstanding request %s\n", in_msg.Type);
45814184Sgabeblack@google.com          trigger(Event:StallAccess, in_msg.addr, cache_entry, tbe);
45914184Sgabeblack@google.com        } else {
46014184Sgabeblack@google.com        if (presentOrAvail(in_msg.addr)) {
46114184Sgabeblack@google.com          if (in_msg.Type == CoherenceRequestType:RdBlkM ) {
46214184Sgabeblack@google.com            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
46314184Sgabeblack@google.com          } else if (in_msg.Type == CoherenceRequestType:WriteThrough ) {
46414184Sgabeblack@google.com            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
46514184Sgabeblack@google.com          } else if (in_msg.Type == CoherenceRequestType:Atomic ) {
46614184Sgabeblack@google.com            trigger(Event:CPUWrite, in_msg.addr, cache_entry, tbe);
46714184Sgabeblack@google.com          } else {
46814184Sgabeblack@google.com              if (in_msg.Type == CoherenceRequestType:VicDirty ||
46914184Sgabeblack@google.com                  in_msg.Type == CoherenceRequestType:VicClean) {
47014184Sgabeblack@google.com                  trigger(Event:CPUWriteback, in_msg.addr, cache_entry, tbe);
47114184Sgabeblack@google.com              } else {
47214184Sgabeblack@google.com                  trigger(Event:CPURead, in_msg.addr, cache_entry, tbe);
47314184Sgabeblack@google.com              }
47414184Sgabeblack@google.com          }
47514184Sgabeblack@google.com        } else {
47614184Sgabeblack@google.com          Addr victim := cacheMemory.cacheProbe(getRegionBase(in_msg.addr));
47714184Sgabeblack@google.com          TBE victim_tbe := getTBE(victim);
47814184Sgabeblack@google.com          Entry victim_entry := getCacheEntry(victim);
47914184Sgabeblack@google.com          DPRINTF(RubySlicc, "Replacing region %s for %s(%s)\n", victim, in_msg.addr, getRegionBase(in_msg.addr));
48014184Sgabeblack@google.com          trigger(Event:ReplRegion, victim, victim_entry, victim_tbe);
48114184Sgabeblack@google.com        }
48214184Sgabeblack@google.com        }
48314184Sgabeblack@google.com      }
48414184Sgabeblack@google.com    }
48514184Sgabeblack@google.com  }
48614184Sgabeblack@google.com
48714184Sgabeblack@google.com  // Actions
48814184Sgabeblack@google.com  action(f_fwdReqToDir, "f", desc="Forward CPU request to directory") {
48914184Sgabeblack@google.com    peek(requestNetwork_in, CPURequestMsg) {
49014184Sgabeblack@google.com      enqueue(requestNetwork_out, CPURequestMsg, toDirLatency) {
49114184Sgabeblack@google.com        out_msg.addr := in_msg.addr;
49214184Sgabeblack@google.com        out_msg.Type := in_msg.Type;
49314184Sgabeblack@google.com        out_msg.DataBlk := in_msg.DataBlk;
49414184Sgabeblack@google.com        out_msg.Dirty := in_msg.Dirty;
49514184Sgabeblack@google.com        out_msg.Requestor := in_msg.Requestor;
49614184Sgabeblack@google.com        out_msg.WTRequestor := in_msg.WTRequestor;
49714184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(in_msg.addr, MachineType:Directory));
49814184Sgabeblack@google.com        out_msg.Shared := in_msg.Shared;
49914184Sgabeblack@google.com        out_msg.MessageSize := in_msg.MessageSize;
50014184Sgabeblack@google.com        out_msg.Private := true;
50114184Sgabeblack@google.com        out_msg.InitialRequestTime := curCycle();
50214184Sgabeblack@google.com        out_msg.ProbeRequestStartTime := curCycle();
50314184Sgabeblack@google.com        if (getState(tbe, cache_entry, address) == State:S) {
50414184Sgabeblack@google.com          out_msg.ForceShared := true;
50514184Sgabeblack@google.com        }
50614184Sgabeblack@google.com        DPRINTF(RubySlicc, "Fwd: %s\n", out_msg);
50714184Sgabeblack@google.com        //assert(getState(tbe, cache_entry, address) == State:P || getState(tbe, cache_entry, address) == State:S);
50814184Sgabeblack@google.com        if (getState(tbe, cache_entry, address) == State:NP_W) {
50914184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(" fwding stale request: ");
51014184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(out_msg.Type);
51114184Sgabeblack@google.com        }
51214184Sgabeblack@google.com      }
51314184Sgabeblack@google.com    }
51414184Sgabeblack@google.com  }
51514184Sgabeblack@google.com
51614184Sgabeblack@google.com  action(u_updateRegionEntry, "u", desc="Update the entry for profiling") {
51714184Sgabeblack@google.com    peek(requestNetwork_in, CPURequestMsg) {
51814184Sgabeblack@google.com      if (is_valid(cache_entry)) {
51914184Sgabeblack@google.com        if (in_msg.CtoDSinked == false) {
52014184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(" incr outstanding ");
52114184Sgabeblack@google.com          cache_entry.NumOutstandingReqs := 1 + cache_entry.NumOutstandingReqs;
52214184Sgabeblack@google.com          assert(cache_entry.OutstandingReqs.at(getRegionOffset(address)) == false);
52314184Sgabeblack@google.com          cache_entry.OutstandingReqs.at(getRegionOffset(address)) := true;
52414184Sgabeblack@google.com          assert(cache_entry.NumOutstandingReqs == countBoolVec(cache_entry.OutstandingReqs));
52514184Sgabeblack@google.com        } else {
52614184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(" NOT incr outstanding ");
52714184Sgabeblack@google.com          assert(in_msg.Type == CoherenceRequestType:RdBlkM || in_msg.Type == CoherenceRequestType:RdBlkS);
52814184Sgabeblack@google.com        }
52914184Sgabeblack@google.com        APPEND_TRANSITION_COMMENT(cache_entry.NumOutstandingReqs);
53014184Sgabeblack@google.com        if (in_msg.Type == CoherenceRequestType:RdBlkM || in_msg.Type == CoherenceRequestType:Atomic ||
53114184Sgabeblack@google.com            in_msg.Type == CoherenceRequestType:WriteThrough )
53214184Sgabeblack@google.com        {
53314184Sgabeblack@google.com          cache_entry.dirty := true;
53414184Sgabeblack@google.com        }
53514184Sgabeblack@google.com        if (in_msg.Type == CoherenceRequestType:VicDirty ||
53614184Sgabeblack@google.com            in_msg.Type == CoherenceRequestType:VicClean) {
53714184Sgabeblack@google.com            DPRINTF(RubySlicc, "Got %s for addr %s\n", in_msg.Type, address);
53814184Sgabeblack@google.com            //assert(cache_entry.ValidBlocks.at(getRegionOffset(address)));
53914184Sgabeblack@google.com            // can in fact be inv if core got an inv after a vicclean before it got here
54014184Sgabeblack@google.com            if (cache_entry.ValidBlocks.at(getRegionOffset(address))) {
54114184Sgabeblack@google.com                cache_entry.clearOnDone := true;
54214184Sgabeblack@google.com                cache_entry.clearOnDoneAddr := address;
54314184Sgabeblack@google.com                //cache_entry.ValidBlocks.at(getRegionOffset(address)) := false;
54414184Sgabeblack@google.com                //cache_entry.NumValidBlocks := cache_entry.NumValidBlocks - 1;
54514184Sgabeblack@google.com            }
54614184Sgabeblack@google.com        } else {
54714184Sgabeblack@google.com            if (cache_entry.ValidBlocks.at(getRegionOffset(address)) == false) {
54814184Sgabeblack@google.com              cache_entry.NumValidBlocks := cache_entry.NumValidBlocks + 1;
54914184Sgabeblack@google.com            }
55014184Sgabeblack@google.com            DPRINTF(RubySlicc, "before valid addr %s bits %s\n",
55114184Sgabeblack@google.com                    in_msg.Type, address, cache_entry.ValidBlocks);
55214184Sgabeblack@google.com            cache_entry.ValidBlocks.at(getRegionOffset(address)) := true;
55314184Sgabeblack@google.com            DPRINTF(RubySlicc, "after valid addr %s bits %s\n",
55414184Sgabeblack@google.com                    in_msg.Type, address, cache_entry.ValidBlocks);
55514184Sgabeblack@google.com            cache_entry.UsedBlocks.at(getRegionOffset(address)) := true;
55614184Sgabeblack@google.com        }
55714184Sgabeblack@google.com        assert(cache_entry.NumValidBlocks <= blocksPerRegion);
55814184Sgabeblack@google.com        assert(cache_entry.NumValidBlocks >= 0);
55914184Sgabeblack@google.com        APPEND_TRANSITION_COMMENT(" valid blocks ");
56014184Sgabeblack@google.com        APPEND_TRANSITION_COMMENT(cache_entry.ValidBlocks);
56114184Sgabeblack@google.com      } else {
56214184Sgabeblack@google.com        error("This shouldn't happen anymore I think");
56314184Sgabeblack@google.com        //tbe.ValidBlocks.at(getRegionOffest(address)) := true;
56414184Sgabeblack@google.com        assert(getState(tbe, cache_entry, address) == State:P_NP);
56514184Sgabeblack@google.com      }
56614184Sgabeblack@google.com    }
56714184Sgabeblack@google.com  }
56814184Sgabeblack@google.com
56914184Sgabeblack@google.com  action(uw_updatePossibleWriteback, "uw", desc="writeback request complete") {
57014184Sgabeblack@google.com      peek(unblockNetwork_in, UnblockMsg) {
57114184Sgabeblack@google.com          if (is_valid(cache_entry) && in_msg.validToInvalid &&
57214184Sgabeblack@google.com              cache_entry.clearOnDone && cache_entry.clearOnDoneAddr == address) {
57314184Sgabeblack@google.com              DPRINTF(RubySlicc, "I have no idea what is going on here\n");
57414184Sgabeblack@google.com              cache_entry.ValidBlocks.at(getRegionOffset(address)) := false;
57514184Sgabeblack@google.com              cache_entry.NumValidBlocks := cache_entry.NumValidBlocks - 1;
57614184Sgabeblack@google.com              cache_entry.clearOnDone := false;
57714184Sgabeblack@google.com          }
57814184Sgabeblack@google.com      }
57914184Sgabeblack@google.com  }
58014184Sgabeblack@google.com
58114184Sgabeblack@google.com
58214184Sgabeblack@google.com  action(rp_requestPrivate, "rp", desc="Send private request r-dir") {
58314184Sgabeblack@google.com      peek(requestNetwork_in, CPURequestMsg) {
58414184Sgabeblack@google.com          // No need to send acks on replacements
58514184Sgabeblack@google.com          assert(is_invalid(tbe));
58614184Sgabeblack@google.com          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
58714184Sgabeblack@google.com              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
58814184Sgabeblack@google.com              out_msg.DemandAddress := address;
58914184Sgabeblack@google.com              out_msg.Type := CoherenceRequestType:PrivateRequest;
59014184Sgabeblack@google.com              out_msg.OriginalType := in_msg.Type;
59114184Sgabeblack@google.com              out_msg.Requestor := machineID;
59214184Sgabeblack@google.com              out_msg.WTRequestor := in_msg.WTRequestor;
59314184Sgabeblack@google.com              out_msg.InitialRequestTime := curCycle();
59414184Sgabeblack@google.com              // will this always be ok? probably not for multisocket
59514184Sgabeblack@google.com              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
59614184Sgabeblack@google.com              out_msg.MessageSize := MessageSizeType:Request_Control;
59714184Sgabeblack@google.com              DPRINTF(RubySlicc, "Private request %s\n", out_msg);
59814184Sgabeblack@google.com          }
59914184Sgabeblack@google.com          cache_entry.ProbeRequestTime := curCycle();
60014184Sgabeblack@google.com          cache_entry.MsgSentToDir := true;
60114184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(getRegionBase(address));
60214184Sgabeblack@google.com      }
60314184Sgabeblack@google.com  }
60414184Sgabeblack@google.com
60514184Sgabeblack@google.com  action(ru_requestUpgrade, "ru", desc="Send upgrade request r-dir") {
60614184Sgabeblack@google.com      peek(requestNetwork_in, CPURequestMsg) {
60714184Sgabeblack@google.com          // No need to send acks on replacements
60814184Sgabeblack@google.com          assert(is_invalid(tbe));
60914184Sgabeblack@google.com          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
61014184Sgabeblack@google.com              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
61114184Sgabeblack@google.com              out_msg.Type := CoherenceRequestType:UpgradeRequest;
61214184Sgabeblack@google.com              out_msg.OriginalType := in_msg.Type;
61314184Sgabeblack@google.com              out_msg.Requestor := machineID;
61414184Sgabeblack@google.com              out_msg.WTRequestor := in_msg.WTRequestor;
61514184Sgabeblack@google.com              out_msg.InitialRequestTime := curCycle();
61614184Sgabeblack@google.com              // will this always be ok? probably not for multisocket
61714184Sgabeblack@google.com              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
61814184Sgabeblack@google.com              out_msg.MessageSize := MessageSizeType:Request_Control;
61914184Sgabeblack@google.com          }
62014184Sgabeblack@google.com          cache_entry.ProbeRequestTime := curCycle();
62114184Sgabeblack@google.com          cache_entry.MsgSentToDir := true;
62214184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(getRegionBase(address));
62314184Sgabeblack@google.com      }
62414184Sgabeblack@google.com  }
62514184Sgabeblack@google.com
62614184Sgabeblack@google.com  action(rw_requestWriteback, "rq", desc="Send writeback request") {
62714184Sgabeblack@google.com    // No need to send acks on replacements
62814184Sgabeblack@google.com    enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
62914184Sgabeblack@google.com        out_msg.addr := getRegionBase(address); // use the actual address so the demand request can be fulfilled
63014184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:CleanWbRequest;
63114184Sgabeblack@google.com        out_msg.Requestor := machineID;
63214184Sgabeblack@google.com        // will this always be ok? probably not for multisocket
63314184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
63414184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
63514184Sgabeblack@google.com        out_msg.Dirty := tbe.dirty;
63614184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(getRegionBase(address));
63714184Sgabeblack@google.com    }
63814184Sgabeblack@google.com  }
63914184Sgabeblack@google.com
64014184Sgabeblack@google.com  action(rs_requestShared, "rs", desc="Send shared request r-dir") {
64114184Sgabeblack@google.com      peek(requestNetwork_in, CPURequestMsg) {
64214184Sgabeblack@google.com          // No need to send acks on replacements
64314184Sgabeblack@google.com          assert(is_invalid(tbe));
64414184Sgabeblack@google.com          enqueue(requestNetwork_out, CPURequestMsg, toRegionDirLatency) {
64514184Sgabeblack@google.com              out_msg.addr := address; // use the actual address so the demand request can be fulfilled
64614184Sgabeblack@google.com              out_msg.Type := CoherenceRequestType:SharedRequest;
64714184Sgabeblack@google.com              out_msg.OriginalType := in_msg.Type;
64814184Sgabeblack@google.com              out_msg.Requestor := machineID;
64914184Sgabeblack@google.com              out_msg.WTRequestor := in_msg.WTRequestor;
65014184Sgabeblack@google.com              out_msg.InitialRequestTime := curCycle();
65114184Sgabeblack@google.com              // will this always be ok? probably not for multisocket
65214184Sgabeblack@google.com              out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
65314184Sgabeblack@google.com              out_msg.MessageSize := MessageSizeType:Request_Control;
65414184Sgabeblack@google.com          }
65514184Sgabeblack@google.com          cache_entry.ProbeRequestTime := curCycle();
65614184Sgabeblack@google.com          cache_entry.MsgSentToDir := true;
65714184Sgabeblack@google.com          APPEND_TRANSITION_COMMENT(getRegionBase(address));
65814184Sgabeblack@google.com      }
65914184Sgabeblack@google.com  }
66014184Sgabeblack@google.com
66114184Sgabeblack@google.com  action(ai_ackRegionInv, "ai", desc="Send ack to r-dir on region inv if tbe says so") {
66214184Sgabeblack@google.com    // No need to send acks on replacements
66314184Sgabeblack@google.com    assert(is_valid(tbe));
66414184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
66514184Sgabeblack@google.com        out_msg.addr := getRegionBase(address);
66614184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:CPUPrbResp;
66714184Sgabeblack@google.com        out_msg.Sender := machineID;
66814184Sgabeblack@google.com        // will this always be ok? probably not for multisocket
66914184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
67014184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
67114184Sgabeblack@google.com    }
67214184Sgabeblack@google.com  }
67314184Sgabeblack@google.com
67414184Sgabeblack@google.com  action(ad_ackDircetory, "ad", desc="send probe response to directory") {
67514184Sgabeblack@google.com    if (noTCCdir && tbe.MsgType == ProbeRequestType:PrbDowngrade && isOnGPU()) { //VIPER tcc doesnt understand PrbShrData
67614184Sgabeblack@google.com      assert(tbe.DemandRequest);                                    //So, let RegionBuffer take care of sending back ack
67714184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, toDirLatency) {
67814184Sgabeblack@google.com          out_msg.addr := tbe.DemandAddress;
67914184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:CPUPrbResp;  // L3 and CPUs respond in same way to probes
68014184Sgabeblack@google.com          out_msg.Sender := getPeer(machineID,address);
68114184Sgabeblack@google.com          // will this always be ok? probably not for multisocket
68214184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
68314184Sgabeblack@google.com          out_msg.Dirty := false;  // only true if sending back data i think
68414184Sgabeblack@google.com          out_msg.Hit := false;
68514184Sgabeblack@google.com          out_msg.Ntsl := false;
68614184Sgabeblack@google.com          out_msg.State := CoherenceState:NA;
68714184Sgabeblack@google.com          out_msg.NoAckNeeded := true;
68814184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Control;
68914184Sgabeblack@google.com          DPRINTF(RubySlicc, "%s\n", out_msg);
69014184Sgabeblack@google.com      }
69114184Sgabeblack@google.com    }
69214184Sgabeblack@google.com  }
69314184Sgabeblack@google.com
69414184Sgabeblack@google.com  action(aie_ackRegionExclusiveInv, "aie", desc="Send ack to r-dir on region inv if tbe says so") {
69514184Sgabeblack@google.com    // No need to send acks on replacements
69614184Sgabeblack@google.com    assert(is_valid(tbe));
69714184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
69814184Sgabeblack@google.com        out_msg.addr := getRegionBase(address);
69914184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:CPUPrbResp;
70014184Sgabeblack@google.com        out_msg.Sender := machineID;
70114184Sgabeblack@google.com        out_msg.NotCached := true;
70214184Sgabeblack@google.com        // will this always be ok? probably not for multisocket
70314184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
70414184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
70514184Sgabeblack@google.com        out_msg.Dirty := tbe.dirty;
70614184Sgabeblack@google.com    }
70714184Sgabeblack@google.com  }
70814184Sgabeblack@google.com
70914184Sgabeblack@google.com  action(ain_ackRegionInvNow, "ain", desc="Send ack to r-dir on region inv") {
71014184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
71114184Sgabeblack@google.com      out_msg.addr := getRegionBase(address);
71214184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:CPUPrbResp;
71314184Sgabeblack@google.com      out_msg.Sender := machineID;
71414184Sgabeblack@google.com      // will this always be ok? probably not for multisocket
71514184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
71614184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Control;
71714184Sgabeblack@google.com    }
71814184Sgabeblack@google.com  }
71914184Sgabeblack@google.com
72014184Sgabeblack@google.com  action(aine_ackRegionInvExlusiveNow, "aine", desc="Send ack to r-dir on region inv with exlusive permission") {
72114184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
72214184Sgabeblack@google.com      out_msg.addr := getRegionBase(address);
72314184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:CPUPrbResp;
72414184Sgabeblack@google.com      out_msg.Sender := machineID;
72514184Sgabeblack@google.com      out_msg.NotCached := true;
72614184Sgabeblack@google.com       // will this always be ok? probably not for multisocket
72714184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
72814184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Control;
72914184Sgabeblack@google.com    }
73014184Sgabeblack@google.com  }
73114184Sgabeblack@google.com
73214184Sgabeblack@google.com  action(ap_ackPrivateNotify, "ap", desc="Send ack to r-dir on private notify") {
73314184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
73414184Sgabeblack@google.com      out_msg.addr := getRegionBase(address);
73514184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:PrivateAck;
73614184Sgabeblack@google.com      out_msg.Sender := machineID;
73714184Sgabeblack@google.com      // will this always be ok? probably not for multisocket
73814184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
73914184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Control;
74014184Sgabeblack@google.com    }
74114184Sgabeblack@google.com  }
74214184Sgabeblack@google.com
74314184Sgabeblack@google.com  action(aw_ackWbNotify, "aw", desc="Send ack to r-dir on writeback notify") {
74414184Sgabeblack@google.com    peek(notifyNetwork_in, CPURequestMsg) {
74514184Sgabeblack@google.com      if (in_msg.NoAckNeeded == false) {
74614184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, toRegionDirLatency) {
74714184Sgabeblack@google.com          out_msg.addr := getRegionBase(address);
74814184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:RegionWbAck;
74914184Sgabeblack@google.com          out_msg.Sender := machineID;
75014184Sgabeblack@google.com          // will this always be ok? probably not for multisocket
75114184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address, MachineType:RegionDir));
75214184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Control;
75314184Sgabeblack@google.com        }
75414184Sgabeblack@google.com      }
75514184Sgabeblack@google.com    }
75614184Sgabeblack@google.com  }
75714184Sgabeblack@google.com
75814184Sgabeblack@google.com  action(e_evictCurrent, "e", desc="Evict this block in the region") {
75914184Sgabeblack@google.com    // send force invalidate message to directory to invalidate this block
76014184Sgabeblack@google.com    // must invalidate all blocks since region buffer could have privitized it
76114184Sgabeblack@google.com      if (tbe.ValidBlocks.at(getRegionOffset(address)) &&
76214184Sgabeblack@google.com          (tbe.DemandRequest == false || tbe.DemandAddress != address)) {
76314184Sgabeblack@google.com          DPRINTF(RubySlicc, "trying to evict address %s (base: %s, offset: %d)\n", address, getRegionBase(address), getRegionOffset(address));
76414184Sgabeblack@google.com          DPRINTF(RubySlicc, "tbe valid blocks %s\n", tbe.ValidBlocks);
76514184Sgabeblack@google.com
76614184Sgabeblack@google.com        enqueue(probeNetwork_out, NBProbeRequestMsg, 1) {
76714184Sgabeblack@google.com            out_msg.addr := address;
76814184Sgabeblack@google.com            out_msg.Type := tbe.MsgType;
76914184Sgabeblack@google.com            out_msg.ReturnData := true;
77014184Sgabeblack@google.com            if (address == tbe.DemandAddress) {
77114184Sgabeblack@google.com                out_msg.DemandRequest := true;
77214184Sgabeblack@google.com            }
77314184Sgabeblack@google.com            out_msg.MessageSize := MessageSizeType:Control;
77414184Sgabeblack@google.com            out_msg.Destination.add(getPeer(machineID,address));
77514184Sgabeblack@google.com            DPRINTF(RubySlicc, "%s\n", out_msg);
77614184Sgabeblack@google.com        }
77714184Sgabeblack@google.com        APPEND_TRANSITION_COMMENT(" current ");
77814184Sgabeblack@google.com        APPEND_TRANSITION_COMMENT(tbe.ValidBlocks.at(getRegionOffset(address)));
77914184Sgabeblack@google.com        tbe.AllAcksReceived := false;
78014184Sgabeblack@google.com      } else {
78114184Sgabeblack@google.com          DPRINTF(RubySlicc, "Not evicting demand %s\n", address);
78214184Sgabeblack@google.com      }
78314184Sgabeblack@google.com  }
78414184Sgabeblack@google.com
78514184Sgabeblack@google.com  action(ed_evictDemand, "ed", desc="Evict the demand request if it's valid") {
78614184Sgabeblack@google.com    if (noTCCdir && tbe.MsgType == ProbeRequestType:PrbDowngrade && isOnGPU()) {
78714184Sgabeblack@google.com      tbe.OutstandingAcks := 0;
78814184Sgabeblack@google.com      tbe.AllAcksReceived := true;
78914184Sgabeblack@google.com      tbe.DoneEvicting := true;
79014184Sgabeblack@google.com      enqueue(triggerQueue_out, TriggerMsg, 1) {
79114184Sgabeblack@google.com          out_msg.Type := TriggerType:AcksComplete;
79214184Sgabeblack@google.com          out_msg.addr := getRegionBase(address);
79314184Sgabeblack@google.com      }
79414184Sgabeblack@google.com    } else if (tbe.DemandRequest) {
79514184Sgabeblack@google.com      enqueue(probeNetwork_out, NBProbeRequestMsg, 1) {
79614184Sgabeblack@google.com        out_msg.addr := tbe.DemandAddress;
79714184Sgabeblack@google.com        out_msg.Type := tbe.MsgType;
79814184Sgabeblack@google.com        out_msg.ReturnData := true;
79914184Sgabeblack@google.com        out_msg.DemandRequest := true;
80014184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Control;
80114184Sgabeblack@google.com        out_msg.Destination.add(getPeer(machineID,address));
80214184Sgabeblack@google.com        DPRINTF(RubySlicc, "%s\n", out_msg);
80314184Sgabeblack@google.com        tbe.AllAcksReceived := false;
80414184Sgabeblack@google.com      }
80514184Sgabeblack@google.com      if (tbe.ValidBlocks.at(getRegionOffset(tbe.DemandAddress)) == false) {
80614184Sgabeblack@google.com          tbe.OutstandingAcks := tbe.OutstandingAcks + 1;
80714184Sgabeblack@google.com      }
80814184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT("Evicting demand ");
80914184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.DemandAddress);
81014184Sgabeblack@google.com    }
81114184Sgabeblack@google.com    APPEND_TRANSITION_COMMENT("waiting acks ");
81214184Sgabeblack@google.com    APPEND_TRANSITION_COMMENT(tbe.OutstandingAcks);
81314184Sgabeblack@google.com  }
81414184Sgabeblack@google.com
81514184Sgabeblack@google.com  action(adp_AckDemandProbe, "fp", desc="forward demand probe even if we know that the core is invalid") {
81614184Sgabeblack@google.com    peek(probeNetwork_in, NBProbeRequestMsg) {
81714184Sgabeblack@google.com        if (in_msg.DemandRequest) {
81814184Sgabeblack@google.com            enqueue(responseNetwork_out, ResponseMsg, toDirLatency) {
81914184Sgabeblack@google.com                out_msg.addr := in_msg.DemandAddress;
82014184Sgabeblack@google.com                out_msg.Type := CoherenceResponseType:CPUPrbResp;  // L3 and CPUs respond in same way to probes
82114184Sgabeblack@google.com                out_msg.Sender := getPeer(machineID,address);
82214184Sgabeblack@google.com                // will this always be ok? probably not for multisocket
82314184Sgabeblack@google.com                out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
82414184Sgabeblack@google.com                out_msg.Dirty := false;  // only true if sending back data i think
82514184Sgabeblack@google.com                out_msg.Hit := false;
82614184Sgabeblack@google.com                out_msg.Ntsl := false;
82714184Sgabeblack@google.com                out_msg.State := CoherenceState:NA;
82814184Sgabeblack@google.com                out_msg.NoAckNeeded := true;
82914184Sgabeblack@google.com                out_msg.MessageSize := MessageSizeType:Response_Control;
83014184Sgabeblack@google.com                DPRINTF(RubySlicc, "%s\n", out_msg);
83114184Sgabeblack@google.com            }
83214184Sgabeblack@google.com        }
83314184Sgabeblack@google.com    }
83414184Sgabeblack@google.com  }
83514184Sgabeblack@google.com
83614184Sgabeblack@google.com  action(en_enqueueNextEvict, "en", desc="Queue evict the next block in the region") {
83714184Sgabeblack@google.com    // increment in_msg.addr by blockSize bytes and enqueue on triggerPort
83814184Sgabeblack@google.com    // Only enqueue if the next address doesn't overrun the region bound
83914184Sgabeblack@google.com    if (getRegionBase(getNextBlock(address)) == getRegionBase(address)) {
84014184Sgabeblack@google.com        enqueue(triggerQueue_out, TriggerMsg, nextEvictLatency) {
84114184Sgabeblack@google.com            out_msg.Type := TriggerType:InvNext;
84214184Sgabeblack@google.com            out_msg.addr := getNextBlock(address);
84314184Sgabeblack@google.com        }
84414184Sgabeblack@google.com    } else {
84514184Sgabeblack@google.com        tbe.DoneEvicting := true;
84614184Sgabeblack@google.com        DPRINTF(RubySlicc, "Done evicing region %s\n", getRegionBase(address));
84714184Sgabeblack@google.com        DPRINTF(RubySlicc, "Waiting for %s acks\n", tbe.OutstandingAcks);
84814184Sgabeblack@google.com        if (tbe.AllAcksReceived == true) {
84914184Sgabeblack@google.com            enqueue(triggerQueue_out, TriggerMsg, 1) {
85014184Sgabeblack@google.com                out_msg.Type := TriggerType:AcksComplete;
85114184Sgabeblack@google.com                out_msg.addr := getRegionBase(address);
85214184Sgabeblack@google.com            }
85314184Sgabeblack@google.com        }
85414184Sgabeblack@google.com    }
85514184Sgabeblack@google.com  }
85614184Sgabeblack@google.com
85714184Sgabeblack@google.com  action(ef_enqueueFirstEvict, "ef", desc="Queue the first block in the region to be evicted") {
85814184Sgabeblack@google.com    if (tbe.DoneEvicting == false) {
85914184Sgabeblack@google.com      enqueue(triggerQueue_out, TriggerMsg, nextEvictLatency) {
86014184Sgabeblack@google.com          out_msg.Type := TriggerType:InvNext;
86114184Sgabeblack@google.com          out_msg.addr := getRegionBase(address);
86214184Sgabeblack@google.com      }
86314184Sgabeblack@google.com    }
86414184Sgabeblack@google.com  }
86514184Sgabeblack@google.com
86614184Sgabeblack@google.com  action(ra_receiveAck, "ra", desc="Mark TBE entry as received this ack") {
86714184Sgabeblack@google.com      DPRINTF(RubySlicc, "received ack for %s reg: %s vec: %s pos: %d\n",
86814184Sgabeblack@google.com              address, getRegionBase(address), tbe.ValidBlocks, getRegionOffset(address));
86914184Sgabeblack@google.com      peek(unblockNetwork_in, UnblockMsg) {
87014184Sgabeblack@google.com          //
87114184Sgabeblack@google.com          // Note the tbe ValidBlock vec will be a conservative list of the
87214184Sgabeblack@google.com          // valid blocks since the cache entry ValidBlock vec is set on the
87314184Sgabeblack@google.com          // request
87414184Sgabeblack@google.com          //
87514184Sgabeblack@google.com          if (in_msg.wasValid) {
87614184Sgabeblack@google.com              assert(tbe.ValidBlocks.at(getRegionOffset(address)));
87714184Sgabeblack@google.com          }
87814184Sgabeblack@google.com      }
87914184Sgabeblack@google.com      tbe.OutstandingAcks := tbe.OutstandingAcks - 1;
88014184Sgabeblack@google.com      tbe.AcksReceived.at(getRegionOffset(address)) := true;
88114184Sgabeblack@google.com      assert(tbe.OutstandingAcks >= 0);
88214184Sgabeblack@google.com      if (tbe.OutstandingAcks == 0) {
88314184Sgabeblack@google.com          tbe.AllAcksReceived := true;
88414184Sgabeblack@google.com          if (tbe.DoneEvicting) {
88514184Sgabeblack@google.com              enqueue(triggerQueue_out, TriggerMsg, 1) {
88614184Sgabeblack@google.com                  out_msg.Type := TriggerType:AcksComplete;
88714184Sgabeblack@google.com                  out_msg.addr := getRegionBase(address);
88814184Sgabeblack@google.com              }
88914184Sgabeblack@google.com          }
89014184Sgabeblack@google.com      }
89114184Sgabeblack@google.com
89214184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(getRegionBase(address));
89314184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" Acks left receive ");
89414184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.OutstandingAcks);
89514184Sgabeblack@google.com  }
89614184Sgabeblack@google.com
89714184Sgabeblack@google.com  action(do_decrementOutstanding, "do", desc="Decrement outstanding requests") {
89814184Sgabeblack@google.com    APPEND_TRANSITION_COMMENT(" decr outstanding ");
89914184Sgabeblack@google.com    if (is_valid(cache_entry)) {
90014184Sgabeblack@google.com      cache_entry.NumOutstandingReqs := cache_entry.NumOutstandingReqs - 1;
90114184Sgabeblack@google.com      assert(cache_entry.OutstandingReqs.at(getRegionOffset(address)));
90214184Sgabeblack@google.com      cache_entry.OutstandingReqs.at(getRegionOffset(address)) := false;
90314184Sgabeblack@google.com      assert(cache_entry.NumOutstandingReqs >= 0);
90414184Sgabeblack@google.com      assert(cache_entry.NumOutstandingReqs == countBoolVec(cache_entry.OutstandingReqs));
90514184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(cache_entry.NumOutstandingReqs);
90614184Sgabeblack@google.com    }
90714184Sgabeblack@google.com    if (is_valid(tbe)) {
90814184Sgabeblack@google.com      tbe.NumOutstandingReqs := tbe.NumOutstandingReqs - 1;
90914184Sgabeblack@google.com      assert(tbe.OutstandingReqs.at(getRegionOffset(address)));
91014184Sgabeblack@google.com      tbe.OutstandingReqs.at(getRegionOffset(address)) := false;
91114184Sgabeblack@google.com      assert(tbe.NumOutstandingReqs >= 0);
91214184Sgabeblack@google.com      assert(tbe.NumOutstandingReqs == countBoolVec(tbe.OutstandingReqs));
91314184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.NumOutstandingReqs);
91414184Sgabeblack@google.com    }
91514184Sgabeblack@google.com  }
91614184Sgabeblack@google.com
91714184Sgabeblack@google.com  action(co_checkOutstanding, "co", desc="check if there are no more outstanding requests") {
91814184Sgabeblack@google.com    assert(is_valid(tbe));
91914184Sgabeblack@google.com    if ((tbe.NumOutstandingReqs <= tbe.OutstandingThreshold) &&
92014184Sgabeblack@google.com        (tbe.AllOutstandingTriggered == false)) {
92114184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" no more outstanding: ");
92214184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.NumOutstandingReqs);
92314184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.OutstandingThreshold);
92414184Sgabeblack@google.com      enqueue(triggerQueue_out, TriggerMsg, 1) {
92514184Sgabeblack@google.com          out_msg.Type := TriggerType:AllOutstanding;
92614184Sgabeblack@google.com          if (tbe.DemandRequest) {
92714184Sgabeblack@google.com              out_msg.addr := tbe.DemandAddress;
92814184Sgabeblack@google.com          } else {
92914184Sgabeblack@google.com              out_msg.addr := getRegionBase(address);
93014184Sgabeblack@google.com          }
93114184Sgabeblack@google.com          DPRINTF(RubySlicc, "co enqueuing %s\n", out_msg);
93214184Sgabeblack@google.com          tbe.AllOutstandingTriggered := true;
93314184Sgabeblack@google.com      }
93414184Sgabeblack@google.com    } else {
93514184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" still more outstanding ");
93614184Sgabeblack@google.com    }
93714184Sgabeblack@google.com  }
93814184Sgabeblack@google.com
93914184Sgabeblack@google.com  action(ro_resetAllOutstanding, "ro", desc="Reset all outstanding") {
94014184Sgabeblack@google.com      tbe.AllOutstandingTriggered := false;
94114184Sgabeblack@google.com  }
94214184Sgabeblack@google.com
94314184Sgabeblack@google.com  action(so_setOutstandingCheckOne, "so", desc="Check outstanding is waiting for 1, not 0") {
94414184Sgabeblack@google.com    // Need this for S_P because one request is outstanding between here and r-dir
94514184Sgabeblack@google.com    tbe.OutstandingThreshold := 1;
94614184Sgabeblack@google.com  }
94714184Sgabeblack@google.com
94814184Sgabeblack@google.com  action(a_allocateRegionEntry, "a", desc="Allocate a new entry") {
94914184Sgabeblack@google.com    set_cache_entry(cacheMemory.allocate(getRegionBase(address), new Entry));
95014184Sgabeblack@google.com    cache_entry.ValidBlocks.clear();
95114184Sgabeblack@google.com    cache_entry.ValidBlocks.resize(blocksPerRegion);
95214184Sgabeblack@google.com    cache_entry.UsedBlocks.clear();
95314184Sgabeblack@google.com    cache_entry.UsedBlocks.resize(blocksPerRegion);
95414184Sgabeblack@google.com    cache_entry.dirty := false;
95514184Sgabeblack@google.com    cache_entry.NumOutstandingReqs := 0;
95614184Sgabeblack@google.com    cache_entry.OutstandingReqs.clear();
95714184Sgabeblack@google.com    cache_entry.OutstandingReqs.resize(blocksPerRegion);
95814184Sgabeblack@google.com  }
95914184Sgabeblack@google.com
96014184Sgabeblack@google.com  action(d_deallocateRegionEntry, "d", desc="Deallocate region entry") {
96114184Sgabeblack@google.com    cacheMemory.deallocate(getRegionBase(address));
96214184Sgabeblack@google.com    unset_cache_entry();
96314184Sgabeblack@google.com  }
96414184Sgabeblack@google.com
96514184Sgabeblack@google.com  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
96614184Sgabeblack@google.com    check_allocate(TBEs);
96714184Sgabeblack@google.com    TBEs.allocate(getRegionBase(address));
96814184Sgabeblack@google.com    set_tbe(getTBE(address));
96914184Sgabeblack@google.com    tbe.OutstandingAcks := 0;
97014184Sgabeblack@google.com    tbe.AllAcksReceived := true; // starts true since the region could be empty
97114184Sgabeblack@google.com    tbe.DoneEvicting := false;
97214184Sgabeblack@google.com    tbe.AcksReceived.clear();
97314184Sgabeblack@google.com    tbe.AcksReceived.resize(blocksPerRegion);
97414184Sgabeblack@google.com    tbe.SendAck := false;
97514184Sgabeblack@google.com    tbe.OutstandingThreshold := 0;
97614184Sgabeblack@google.com    if (is_valid(cache_entry)) {
97714184Sgabeblack@google.com      tbe.NumOutstandingReqs := cache_entry.NumOutstandingReqs;
97814184Sgabeblack@google.com      tbe.OutstandingReqs := cache_entry.OutstandingReqs;
97914184Sgabeblack@google.com      assert(tbe.NumOutstandingReqs == countBoolVec(tbe.OutstandingReqs));
98014184Sgabeblack@google.com      tbe.dirty := cache_entry.dirty;
98114184Sgabeblack@google.com      tbe.ValidBlocks := cache_entry.ValidBlocks;
98214184Sgabeblack@google.com      tbe.OutstandingAcks := countBoolVec(tbe.ValidBlocks);
98314184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" tbe valid blocks ");
98414184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.ValidBlocks);
98514184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" cache valid blocks ");
98614184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(cache_entry.ValidBlocks);
98714184Sgabeblack@google.com    } else {
98814184Sgabeblack@google.com      tbe.dirty := false;
98914184Sgabeblack@google.com    }
99014184Sgabeblack@google.com  }
99114184Sgabeblack@google.com
99214184Sgabeblack@google.com  action(m_markSendAck, "m", desc="Mark TBE that we need to ack at end") {
99314184Sgabeblack@google.com    assert(is_valid(tbe));
99414184Sgabeblack@google.com    tbe.SendAck := true;
99514184Sgabeblack@google.com  }
99614184Sgabeblack@google.com
99714184Sgabeblack@google.com  action(db_markDirtyBit, "db", desc="Mark TBE dirty bit") {
99814184Sgabeblack@google.com      peek(unblockNetwork_in, UnblockMsg) {
99914184Sgabeblack@google.com          if (is_valid(tbe)) {
100014184Sgabeblack@google.com              tbe.dirty := tbe.dirty || in_msg.Dirty;
100114184Sgabeblack@google.com          }
100214184Sgabeblack@google.com      }
100314184Sgabeblack@google.com  }
100414184Sgabeblack@google.com
100514184Sgabeblack@google.com  action(dr_markDoneAckReceived, "dr", desc="Mark TBE that a done ack has been received") {
100614184Sgabeblack@google.com    assert(is_valid(tbe));
100714184Sgabeblack@google.com    tbe.DoneAckReceived := true;
100814184Sgabeblack@google.com    tbe.DoneAckAddr := address;
100914184Sgabeblack@google.com    APPEND_TRANSITION_COMMENT(" marking done ack on TBE ");
101014184Sgabeblack@google.com  }
101114184Sgabeblack@google.com
101214184Sgabeblack@google.com  action(se_setTBE, "se", desc="Set msg type to evict") {
101314184Sgabeblack@google.com    peek(probeNetwork_in, NBProbeRequestMsg) {
101414184Sgabeblack@google.com        tbe.MsgType := in_msg.Type;
101514184Sgabeblack@google.com        tbe.Requestor := in_msg.Requestor;
101614184Sgabeblack@google.com        tbe.DemandAddress := in_msg.DemandAddress;
101714184Sgabeblack@google.com        tbe.DemandRequest := in_msg.DemandRequest;
101814184Sgabeblack@google.com    }
101914184Sgabeblack@google.com  }
102014184Sgabeblack@google.com
102114184Sgabeblack@google.com  action(sne_setNewTBE, "sne", desc="Set msg type to evict") {
102214184Sgabeblack@google.com    peek(probeNetwork_in, NBProbeRequestMsg) {
102314184Sgabeblack@google.com        tbe.NewMsgType := in_msg.Type;
102414184Sgabeblack@google.com        tbe.NewRequestor := in_msg.Requestor;
102514184Sgabeblack@google.com        tbe.NewDemandAddress := in_msg.DemandAddress;
102614184Sgabeblack@google.com        tbe.NewDemandRequest := in_msg.DemandRequest;
102714184Sgabeblack@google.com    }
102814184Sgabeblack@google.com  }
102914184Sgabeblack@google.com
103014184Sgabeblack@google.com  action(soe_setOldTBE, "soe", desc="Set msg type to evict") {
103114184Sgabeblack@google.com    tbe.MsgType := tbe.NewMsgType;
103214184Sgabeblack@google.com    tbe.Requestor := tbe.NewRequestor;
103314184Sgabeblack@google.com    tbe.DemandAddress := tbe.NewDemandAddress;
103414184Sgabeblack@google.com    tbe.DemandRequest := tbe.NewDemandRequest;
103514184Sgabeblack@google.com    tbe.OutstandingAcks :=  countBoolVec(tbe.ValidBlocks);
103614184Sgabeblack@google.com    tbe.AllAcksReceived := true; // starts true since the region could be empty
103714184Sgabeblack@google.com    tbe.DoneEvicting := false;
103814184Sgabeblack@google.com    tbe.AcksReceived.clear();
103914184Sgabeblack@google.com    tbe.AcksReceived.resize(blocksPerRegion);
104014184Sgabeblack@google.com    tbe.SendAck := false;
104114184Sgabeblack@google.com  }
104214184Sgabeblack@google.com
104314184Sgabeblack@google.com  action(ser_setTBE, "ser", desc="Set msg type to evict repl") {
104414184Sgabeblack@google.com    tbe.MsgType := ProbeRequestType:PrbInv;
104514184Sgabeblack@google.com  }
104614184Sgabeblack@google.com
104714184Sgabeblack@google.com  action(md_setMustDowngrade, "md", desc="When permissions finally get here, must be shared") {
104814184Sgabeblack@google.com    assert(is_valid(cache_entry));
104914184Sgabeblack@google.com    cache_entry.MustDowngrade := true;
105014184Sgabeblack@google.com  }
105114184Sgabeblack@google.com
105214184Sgabeblack@google.com  action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") {
105314184Sgabeblack@google.com    TBEs.deallocate(getRegionBase(address));
105414184Sgabeblack@google.com    unset_tbe();
105514184Sgabeblack@google.com  }
105614184Sgabeblack@google.com
105714184Sgabeblack@google.com  action(p_popRequestQueue, "p", desc="Pop the request queue") {
105814184Sgabeblack@google.com    requestNetwork_in.dequeue(clockEdge());
105914184Sgabeblack@google.com  }
106014184Sgabeblack@google.com
106114184Sgabeblack@google.com  action(pl_popUnblockQueue, "pl", desc="Pop the unblock queue") {
106214184Sgabeblack@google.com    unblockNetwork_in.dequeue(clockEdge());
106314184Sgabeblack@google.com  }
106414184Sgabeblack@google.com
106514184Sgabeblack@google.com  action(pn_popNotifyQueue, "pn", desc="Pop the notify queue") {
106614184Sgabeblack@google.com    notifyNetwork_in.dequeue(clockEdge());
106714184Sgabeblack@google.com  }
106814184Sgabeblack@google.com
106914184Sgabeblack@google.com  action(pp_popProbeQueue, "pp", desc="Pop the probe queue") {
107014184Sgabeblack@google.com    probeNetwork_in.dequeue(clockEdge());
107114184Sgabeblack@google.com  }
107214184Sgabeblack@google.com
107314184Sgabeblack@google.com  action(pt_popTriggerQueue, "pt", desc="Pop the trigger queue") {
107414184Sgabeblack@google.com    DPRINTF(RubySlicc, "Trigger Before Contents: %s\n", triggerQueue_in);
107514184Sgabeblack@google.com    triggerQueue_in.dequeue(clockEdge());
107614184Sgabeblack@google.com    DPRINTF(RubySlicc, "Trigger After Contents: %s\n", triggerQueue_in);
107714184Sgabeblack@google.com  }
107814184Sgabeblack@google.com
107914184Sgabeblack@google.com  // Must always use wake all, since non-region address wait on region addresses
108014184Sgabeblack@google.com  action(wa_wakeUpAllDependents, "wa", desc="Wake up any requests waiting for this region") {
108114184Sgabeblack@google.com    wakeUpAllBuffers();
108214184Sgabeblack@google.com  }
108314184Sgabeblack@google.com
108414184Sgabeblack@google.com  action(zz_stallAndWaitRequestQueue, "\z", desc="recycle request queue") {
108514184Sgabeblack@google.com    Addr regAddr := getRegionBase(address);
108614184Sgabeblack@google.com    DPRINTF(RubySlicc, "Stalling address %s\n", regAddr);
108714184Sgabeblack@google.com    stall_and_wait(requestNetwork_in, regAddr);
108814184Sgabeblack@google.com  }
108914184Sgabeblack@google.com
109014184Sgabeblack@google.com  action(yy_stallAndWaitProbeQueue, "\y", desc="stall probe queue") {
109114184Sgabeblack@google.com    Addr regAddr := getRegionBase(address);
109214184Sgabeblack@google.com    stall_and_wait(probeNetwork_in, regAddr);
109314184Sgabeblack@google.com  }
109414184Sgabeblack@google.com
109514184Sgabeblack@google.com  action(yyy_recycleProbeQueue, "\yy", desc="recycle probe queue") {
109614184Sgabeblack@google.com    probeNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
109714184Sgabeblack@google.com  }
109814184Sgabeblack@google.com
109914184Sgabeblack@google.com  action(zzz_recycleRequestQueue, "\zz", desc="recycle request queue") {
110014184Sgabeblack@google.com    requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
110114184Sgabeblack@google.com  }
110214184Sgabeblack@google.com
110314184Sgabeblack@google.com  action(www_recycleUnblockNetwork, "\ww", desc="recycle unblock queue") {
110414184Sgabeblack@google.com    unblockNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
110514184Sgabeblack@google.com  }
110614184Sgabeblack@google.com
110714184Sgabeblack@google.com  action(z_stall, "z", desc="stall request queue") {
110814184Sgabeblack@google.com    // fake state
110914184Sgabeblack@google.com  }
111014184Sgabeblack@google.com
111114184Sgabeblack@google.com  action(mru_setMRU, "mru", desc="set MRU") {
111214184Sgabeblack@google.com    cacheMemory.setMRU(address, cache_entry.NumValidBlocks);
111314184Sgabeblack@google.com  }
111414184Sgabeblack@google.com
111514184Sgabeblack@google.com  // Transitions
111614184Sgabeblack@google.com
111714184Sgabeblack@google.com  transition({NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, P_NP_W, P_NP_NP, NP_W}, {CPURead, CPUWriteback, CPUWrite}) {} {
111814184Sgabeblack@google.com    zz_stallAndWaitRequestQueue;
111914184Sgabeblack@google.com  }
112014184Sgabeblack@google.com
112114184Sgabeblack@google.com  transition(SS_P, {CPURead, CPUWriteback}) {
112214184Sgabeblack@google.com    zz_stallAndWaitRequestQueue;
112314184Sgabeblack@google.com  }
112414184Sgabeblack@google.com
112514184Sgabeblack@google.com  transition({NP, S, P, NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P, NP_W, P_NP_NP}, StallAccess) {} {
112614184Sgabeblack@google.com    zz_stallAndWaitRequestQueue;
112714184Sgabeblack@google.com  }
112814184Sgabeblack@google.com
112914184Sgabeblack@google.com  transition({S, P, NP_PS, S_P, S_NP_PS, P_NP, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P, P_NP_W, P_NP_NP, NP_W}, StallDoneAck) {
113014184Sgabeblack@google.com    www_recycleUnblockNetwork;
113114184Sgabeblack@google.com  }
113214184Sgabeblack@google.com
113314184Sgabeblack@google.com  transition(NP, StallDoneAck, NP_W) {
113414184Sgabeblack@google.com    t_allocateTBE;
113514184Sgabeblack@google.com    db_markDirtyBit;
113614184Sgabeblack@google.com    dr_markDoneAckReceived;
113714184Sgabeblack@google.com    pl_popUnblockQueue;
113814184Sgabeblack@google.com  }
113914184Sgabeblack@google.com
114014184Sgabeblack@google.com  transition(NP_W, StaleRequest, NP) {
114114184Sgabeblack@google.com    f_fwdReqToDir;
114214184Sgabeblack@google.com    dt_deallocateTBE;
114314184Sgabeblack@google.com    wa_wakeUpAllDependents;
114414184Sgabeblack@google.com    p_popRequestQueue;
114514184Sgabeblack@google.com  }
114614184Sgabeblack@google.com
114714184Sgabeblack@google.com  transition(P_NP_O, DowngradeRegion) {} {
114814184Sgabeblack@google.com    z_stall; // should stall and wait
114914184Sgabeblack@google.com  }
115014184Sgabeblack@google.com
115114184Sgabeblack@google.com  transition({NP_PS, S_NP_PS, S_P, P_S, P_NP_O, S_NP_PS_O, P_S_O, S_O, SS_P}, ReplRegion) {} {
115214184Sgabeblack@google.com    zz_stallAndWaitRequestQueue; // can't let things get out of order!
115314184Sgabeblack@google.com  }
115414184Sgabeblack@google.com
115514184Sgabeblack@google.com  transition({P_NP_O, S_O, SS_P}, InvRegion) {} {
115614184Sgabeblack@google.com    yyy_recycleProbeQueue; // can't be z_stall because there could be a RdBlkM in the requestQueue which has the sinked flag which is blocking the inv
115714184Sgabeblack@google.com  }
115814184Sgabeblack@google.com
115914184Sgabeblack@google.com  transition(P_NP, {InvRegion, DowngradeRegion}, P_NP_NP) {} {
116014184Sgabeblack@google.com    sne_setNewTBE;
116114184Sgabeblack@google.com    pp_popProbeQueue;
116214184Sgabeblack@google.com  }
116314184Sgabeblack@google.com
116414184Sgabeblack@google.com  transition(S_P, DowngradeRegion) {} {
116514184Sgabeblack@google.com    adp_AckDemandProbe;
116614184Sgabeblack@google.com    ain_ackRegionInvNow;
116714184Sgabeblack@google.com    pp_popProbeQueue;
116814184Sgabeblack@google.com  }
116914184Sgabeblack@google.com
117014184Sgabeblack@google.com  transition(P_NP_W, InvRegion) {
117114184Sgabeblack@google.com    adp_AckDemandProbe;
117214184Sgabeblack@google.com    ain_ackRegionInvNow;
117314184Sgabeblack@google.com    pp_popProbeQueue;
117414184Sgabeblack@google.com  }
117514184Sgabeblack@google.com
117614184Sgabeblack@google.com  transition(P_NP_W, DowngradeRegion) {
117714184Sgabeblack@google.com    adp_AckDemandProbe;
117814184Sgabeblack@google.com    aine_ackRegionInvExlusiveNow;
117914184Sgabeblack@google.com    pp_popProbeQueue;
118014184Sgabeblack@google.com  }
118114184Sgabeblack@google.com
118214184Sgabeblack@google.com  transition({P, S}, {CPURead, CPUWriteback}) {TagArrayRead, TagArrayWrite} {
118314184Sgabeblack@google.com    mru_setMRU;
118414184Sgabeblack@google.com    f_fwdReqToDir;
118514184Sgabeblack@google.com    u_updateRegionEntry;
118614184Sgabeblack@google.com    p_popRequestQueue;
118714184Sgabeblack@google.com  }
118814184Sgabeblack@google.com
118914184Sgabeblack@google.com  transition(P, CPUWrite) {TagArrayRead, TagArrayWrite} {
119014184Sgabeblack@google.com    mru_setMRU;
119114184Sgabeblack@google.com    f_fwdReqToDir;
119214184Sgabeblack@google.com    u_updateRegionEntry;
119314184Sgabeblack@google.com    p_popRequestQueue;
119414184Sgabeblack@google.com  }
119514184Sgabeblack@google.com
119614184Sgabeblack@google.com  transition(S, CPUWrite, S_O) {TagArrayRead} {
119714184Sgabeblack@google.com    mru_setMRU;
119814184Sgabeblack@google.com    t_allocateTBE;
119914184Sgabeblack@google.com    co_checkOutstanding;
120014184Sgabeblack@google.com    zz_stallAndWaitRequestQueue;
120114184Sgabeblack@google.com  }
120214184Sgabeblack@google.com
120314184Sgabeblack@google.com  transition(S_O, AllOutstanding, SS_P) {
120414184Sgabeblack@google.com    wa_wakeUpAllDependents;
120514184Sgabeblack@google.com    ro_resetAllOutstanding;
120614184Sgabeblack@google.com    pt_popTriggerQueue;
120714184Sgabeblack@google.com  }
120814184Sgabeblack@google.com
120914184Sgabeblack@google.com  transition(SS_P, CPUWrite, S_P) {
121014184Sgabeblack@google.com    mru_setMRU;
121114184Sgabeblack@google.com    dt_deallocateTBE;
121214184Sgabeblack@google.com    ru_requestUpgrade;
121314184Sgabeblack@google.com    u_updateRegionEntry;
121414184Sgabeblack@google.com    p_popRequestQueue;
121514184Sgabeblack@google.com  }
121614184Sgabeblack@google.com
121714184Sgabeblack@google.com  transition(NP, {CPURead, CPUWriteback}, NP_PS) {TagArrayRead, TagArrayWrite} {
121814184Sgabeblack@google.com    a_allocateRegionEntry;
121914184Sgabeblack@google.com    rs_requestShared;
122014184Sgabeblack@google.com    u_updateRegionEntry;
122114184Sgabeblack@google.com    p_popRequestQueue;//zz_stallAndWaitRequestQueue;
122214184Sgabeblack@google.com  }
122314184Sgabeblack@google.com
122414184Sgabeblack@google.com  transition(NP, CPUWrite, NP_PS) {TagArrayRead, TagArrayWrite} {
122514184Sgabeblack@google.com    a_allocateRegionEntry;
122614184Sgabeblack@google.com    rp_requestPrivate;
122714184Sgabeblack@google.com    u_updateRegionEntry;
122814184Sgabeblack@google.com    p_popRequestQueue;//zz_stallAndWaitRequestQueue;
122914184Sgabeblack@google.com  }
123014184Sgabeblack@google.com
123114184Sgabeblack@google.com  transition(NP_PS, PrivateNotify, P) {} {
123214184Sgabeblack@google.com    ap_ackPrivateNotify;
123314184Sgabeblack@google.com    wa_wakeUpAllDependents;
123414184Sgabeblack@google.com    pn_popNotifyQueue;
123514184Sgabeblack@google.com  }
123614184Sgabeblack@google.com
123714184Sgabeblack@google.com  transition(S_P, PrivateNotify, P) {} {
123814184Sgabeblack@google.com    ap_ackPrivateNotify;
123914184Sgabeblack@google.com    wa_wakeUpAllDependents;
124014184Sgabeblack@google.com    pn_popNotifyQueue;
124114184Sgabeblack@google.com  }
124214184Sgabeblack@google.com
124314184Sgabeblack@google.com  transition(NP_PS, SharedNotify, S) {} {
124414184Sgabeblack@google.com    ap_ackPrivateNotify;
124514184Sgabeblack@google.com    wa_wakeUpAllDependents;
124614184Sgabeblack@google.com    pn_popNotifyQueue;
124714184Sgabeblack@google.com  }
124814184Sgabeblack@google.com
124914184Sgabeblack@google.com  transition(P_NP_W, WbNotify, NP) {} {
125014184Sgabeblack@google.com    aw_ackWbNotify;
125114184Sgabeblack@google.com    wa_wakeUpAllDependents;
125214184Sgabeblack@google.com    dt_deallocateTBE;
125314184Sgabeblack@google.com    pn_popNotifyQueue;
125414184Sgabeblack@google.com  }
125514184Sgabeblack@google.com
125614184Sgabeblack@google.com  transition({P, S}, ReplRegion, P_NP_O) {TagArrayRead, TagArrayWrite} {
125714184Sgabeblack@google.com    t_allocateTBE;
125814184Sgabeblack@google.com    ser_setTBE;
125914184Sgabeblack@google.com    d_deallocateRegionEntry;
126014184Sgabeblack@google.com    co_checkOutstanding;
126114184Sgabeblack@google.com  }
126214184Sgabeblack@google.com
126314184Sgabeblack@google.com  transition({P, S}, InvRegion, P_NP_O) {TagArrayRead, TagArrayWrite} {
126414184Sgabeblack@google.com    t_allocateTBE;
126514184Sgabeblack@google.com    se_setTBE;
126614184Sgabeblack@google.com    m_markSendAck;
126714184Sgabeblack@google.com    d_deallocateRegionEntry;
126814184Sgabeblack@google.com    co_checkOutstanding;
126914184Sgabeblack@google.com    pp_popProbeQueue;
127014184Sgabeblack@google.com  }
127114184Sgabeblack@google.com
127214184Sgabeblack@google.com  transition(P_NP_O, AllOutstanding, P_NP) {} {
127314184Sgabeblack@google.com    ed_evictDemand;
127414184Sgabeblack@google.com    ef_enqueueFirstEvict;
127514184Sgabeblack@google.com    ro_resetAllOutstanding;
127614184Sgabeblack@google.com    pt_popTriggerQueue;
127714184Sgabeblack@google.com  }
127814184Sgabeblack@google.com
127914184Sgabeblack@google.com  transition(S_P, InvRegion, S_NP_PS_O) {TagArrayRead} {
128014184Sgabeblack@google.com    t_allocateTBE;
128114184Sgabeblack@google.com    se_setTBE;
128214184Sgabeblack@google.com    m_markSendAck;
128314184Sgabeblack@google.com    so_setOutstandingCheckOne;
128414184Sgabeblack@google.com    co_checkOutstanding;
128514184Sgabeblack@google.com    pp_popProbeQueue;
128614184Sgabeblack@google.com  }
128714184Sgabeblack@google.com
128814184Sgabeblack@google.com  transition(S_NP_PS_O, AllOutstanding, S_NP_PS) {
128914184Sgabeblack@google.com    ed_evictDemand;
129014184Sgabeblack@google.com    ef_enqueueFirstEvict;
129114184Sgabeblack@google.com    ro_resetAllOutstanding;
129214184Sgabeblack@google.com    pt_popTriggerQueue;
129314184Sgabeblack@google.com  }
129414184Sgabeblack@google.com
129514184Sgabeblack@google.com  transition(P, DowngradeRegion, P_S_O) {TagArrayRead, TagArrayWrite} {
129614184Sgabeblack@google.com    t_allocateTBE;
129714184Sgabeblack@google.com    se_setTBE;
129814184Sgabeblack@google.com    m_markSendAck;
129914184Sgabeblack@google.com    co_checkOutstanding;
130014184Sgabeblack@google.com    pp_popProbeQueue;
130114184Sgabeblack@google.com  }
130214184Sgabeblack@google.com
130314184Sgabeblack@google.com  transition(P_S_O, AllOutstanding, P_S) {} {
130414184Sgabeblack@google.com    ed_evictDemand;
130514184Sgabeblack@google.com    ef_enqueueFirstEvict;
130614184Sgabeblack@google.com    ro_resetAllOutstanding;
130714184Sgabeblack@google.com    pt_popTriggerQueue;
130814184Sgabeblack@google.com  }
130914184Sgabeblack@google.com
131014184Sgabeblack@google.com  transition({P, S}, DoneAck) {TagArrayWrite} {
131114184Sgabeblack@google.com    do_decrementOutstanding;
131214184Sgabeblack@google.com    wa_wakeUpAllDependents;
131314184Sgabeblack@google.com    db_markDirtyBit;
131414184Sgabeblack@google.com    uw_updatePossibleWriteback;
131514184Sgabeblack@google.com    pl_popUnblockQueue;
131614184Sgabeblack@google.com  }
131714184Sgabeblack@google.com
131814184Sgabeblack@google.com  transition({S_P, NP_PS, S_NP_PS}, DoneAck) {TagArrayWrite} {
131914184Sgabeblack@google.com      www_recycleUnblockNetwork;
132014184Sgabeblack@google.com  }
132114184Sgabeblack@google.com
132214184Sgabeblack@google.com  transition({P_NP_O, S_NP_PS_O, P_S_O, S_O}, DoneAck) {} {
132314184Sgabeblack@google.com    do_decrementOutstanding;
132414184Sgabeblack@google.com    co_checkOutstanding;
132514184Sgabeblack@google.com    db_markDirtyBit;
132614184Sgabeblack@google.com    uw_updatePossibleWriteback;
132714184Sgabeblack@google.com    pl_popUnblockQueue;
132814184Sgabeblack@google.com  }
132914184Sgabeblack@google.com
133014184Sgabeblack@google.com  transition({P_NP, P_S, S_NP_PS, P_NP_NP}, Evict) {} {
133114184Sgabeblack@google.com    e_evictCurrent;
133214184Sgabeblack@google.com    en_enqueueNextEvict;
133314184Sgabeblack@google.com    pt_popTriggerQueue;
133414184Sgabeblack@google.com  }
133514184Sgabeblack@google.com
133614184Sgabeblack@google.com  transition({P_NP, P_S, S_NP_PS, P_NP_NP}, InvAck) {} {
133714184Sgabeblack@google.com    ra_receiveAck;
133814184Sgabeblack@google.com    db_markDirtyBit;
133914184Sgabeblack@google.com    pl_popUnblockQueue;
134014184Sgabeblack@google.com  }
134114184Sgabeblack@google.com
134214184Sgabeblack@google.com  transition(P_NP, LastAck_CleanWb, P_NP_W) {} {
134314184Sgabeblack@google.com      rw_requestWriteback;
134414184Sgabeblack@google.com      pt_popTriggerQueue;
134514184Sgabeblack@google.com  }
134614184Sgabeblack@google.com
134714184Sgabeblack@google.com  transition(P_NP_NP, LastAck_CleanWb, P_NP) {} {
134814184Sgabeblack@google.com    soe_setOldTBE;
134914184Sgabeblack@google.com    m_markSendAck;
135014184Sgabeblack@google.com    ed_evictDemand;
135114184Sgabeblack@google.com    ef_enqueueFirstEvict;
135214184Sgabeblack@google.com    pt_popTriggerQueue;
135314184Sgabeblack@google.com  }
135414184Sgabeblack@google.com
135514184Sgabeblack@google.com  transition(P_NP, LastAck_PrbResp, NP) {} {
135614184Sgabeblack@google.com    aie_ackRegionExclusiveInv;
135714184Sgabeblack@google.com    dt_deallocateTBE;
135814184Sgabeblack@google.com    wa_wakeUpAllDependents;
135914184Sgabeblack@google.com    pt_popTriggerQueue;
136014184Sgabeblack@google.com  }
136114184Sgabeblack@google.com
136214184Sgabeblack@google.com  transition(S_NP_PS, LastAck_PrbResp, NP_PS) {} {
136314184Sgabeblack@google.com    aie_ackRegionExclusiveInv;
136414184Sgabeblack@google.com    dt_deallocateTBE;
136514184Sgabeblack@google.com    wa_wakeUpAllDependents;
136614184Sgabeblack@google.com    pt_popTriggerQueue;
136714184Sgabeblack@google.com  }
136814184Sgabeblack@google.com
136914184Sgabeblack@google.com  transition(P_S, LastAck_PrbResp, S) {} {
137014184Sgabeblack@google.com    ai_ackRegionInv;
137114184Sgabeblack@google.com    ad_ackDircetory;
137214184Sgabeblack@google.com    dt_deallocateTBE;
137314184Sgabeblack@google.com    wa_wakeUpAllDependents;
137414184Sgabeblack@google.com    pt_popTriggerQueue;
137514184Sgabeblack@google.com  }
137614184Sgabeblack@google.com
137714184Sgabeblack@google.com}
137814184Sgabeblack@google.com
1379