114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
314184Sgabeblack@google.com * All rights reserved.
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
614184Sgabeblack@google.com * modification, are permitted provided that the following conditions are
714184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
814184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
914184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1114184Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1214184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1314184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1414184Sgabeblack@google.com * this software without specific prior written permission.
1514184Sgabeblack@google.com *
1614184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1714184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1814184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1914184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2014184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2114184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2214184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2314184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2414184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2514184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2614184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2714184Sgabeblack@google.com */
2814184Sgabeblack@google.com
2914184Sgabeblack@google.commachine(MachineType:L2Cache, "MESI Directory L2 Cache CMP")
3014184Sgabeblack@google.com : CacheMemory * L2cache;
3114184Sgabeblack@google.com   Cycles l2_request_latency := 2;
3214184Sgabeblack@google.com   Cycles l2_response_latency := 2;
3314184Sgabeblack@google.com   Cycles to_l1_latency := 1;
3414184Sgabeblack@google.com
3514184Sgabeblack@google.com  // Message Queues
3614184Sgabeblack@google.com  // From local bank of L2 cache TO the network
3714184Sgabeblack@google.com  MessageBuffer * DirRequestFromL2Cache, network="To", virtual_network="0",
3814184Sgabeblack@google.com    vnet_type="request";  // this L2 bank -> Memory
3914184Sgabeblack@google.com
4014184Sgabeblack@google.com  MessageBuffer * L1RequestFromL2Cache, network="To", virtual_network="2",
4114184Sgabeblack@google.com    vnet_type="request";  // this L2 bank -> a local L1
4214184Sgabeblack@google.com
4314184Sgabeblack@google.com  MessageBuffer * responseFromL2Cache, network="To", virtual_network="1",
4414184Sgabeblack@google.com    vnet_type="response";  // this L2 bank -> a local L1 || Memory
4514184Sgabeblack@google.com
4614184Sgabeblack@google.com  // FROM the network to this local bank of L2 cache
4714184Sgabeblack@google.com  MessageBuffer * unblockToL2Cache, network="From", virtual_network="2",
4814184Sgabeblack@google.com    vnet_type="unblock";  // a local L1 || Memory -> this L2 bank
4914184Sgabeblack@google.com
5014184Sgabeblack@google.com  MessageBuffer * L1RequestToL2Cache, network="From", virtual_network="0",
5114184Sgabeblack@google.com    vnet_type="request";  // a local L1 -> this L2 bank
5214184Sgabeblack@google.com
5314184Sgabeblack@google.com  MessageBuffer * responseToL2Cache, network="From", virtual_network="1",
5414184Sgabeblack@google.com    vnet_type="response";  // a local L1 || Memory -> this L2 bank
5514184Sgabeblack@google.com{
5614184Sgabeblack@google.com  // STATES
5714184Sgabeblack@google.com  state_declaration(State, desc="L2 Cache states", default="L2Cache_State_NP") {
5814184Sgabeblack@google.com    // Base states
5914184Sgabeblack@google.com    NP, AccessPermission:Invalid, desc="Not present in either cache";
6014184Sgabeblack@google.com    SS, AccessPermission:Read_Only, desc="L2 cache entry Shared, also present in one or more L1s";
6114184Sgabeblack@google.com    M, AccessPermission:Read_Write, desc="L2 cache entry Modified, not present in any L1s", format="!b";
6214184Sgabeblack@google.com    MT, AccessPermission:Maybe_Stale, desc="L2 cache entry Modified in a local L1, assume L2 copy stale", format="!b";
6314184Sgabeblack@google.com
6414184Sgabeblack@google.com    // L2 replacement
6514184Sgabeblack@google.com    M_I, AccessPermission:Busy, desc="L2 cache replacing, have all acks, sent dirty data to memory, waiting for ACK from memory";
6614184Sgabeblack@google.com    MT_I, AccessPermission:Busy, desc="L2 cache replacing, getting data from exclusive";
6714184Sgabeblack@google.com    MCT_I, AccessPermission:Busy, desc="L2 cache replacing, clean in L2, getting data or ack from exclusive";
6814184Sgabeblack@google.com    I_I, AccessPermission:Busy, desc="L2 replacing clean data, need to inv sharers and then drop data";
6914184Sgabeblack@google.com    S_I, AccessPermission:Busy, desc="L2 replacing dirty data, collecting acks from L1s";
7014184Sgabeblack@google.com
7114184Sgabeblack@google.com    // Transient States for fetching data from memory
7214184Sgabeblack@google.com    ISS, AccessPermission:Busy, desc="L2 idle, got single L1_GETS, issued memory fetch, have not seen response yet";
7314184Sgabeblack@google.com    IS, AccessPermission:Busy, desc="L2 idle, got L1_GET_INSTR or multiple L1_GETS, issued memory fetch, have not seen response yet";
7414184Sgabeblack@google.com    IM, AccessPermission:Busy, desc="L2 idle, got L1_GETX, issued memory fetch, have not seen response(s) yet";
7514184Sgabeblack@google.com
7614184Sgabeblack@google.com    // Blocking states
7714184Sgabeblack@google.com    SS_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from SS";
7814184Sgabeblack@google.com    MT_MB, AccessPermission:Busy, desc="Blocked for L1_GETX from MT";
7914184Sgabeblack@google.com
8014184Sgabeblack@google.com    MT_IIB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, waiting for unblock and data";
8114184Sgabeblack@google.com    MT_IB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got unblock, waiting for data";
8214184Sgabeblack@google.com    MT_SB, AccessPermission:Busy, desc="Blocked for L1_GETS from MT, got data,  waiting for unblock";
8314184Sgabeblack@google.com
8414184Sgabeblack@google.com  }
8514184Sgabeblack@google.com
8614184Sgabeblack@google.com  // EVENTS
8714184Sgabeblack@google.com  enumeration(Event, desc="L2 Cache events") {
8814184Sgabeblack@google.com    // L2 events
8914184Sgabeblack@google.com
9014184Sgabeblack@google.com    // events initiated by the local L1s
9114184Sgabeblack@google.com    L1_GET_INSTR,            desc="a L1I GET INSTR request for a block maped to us";
9214184Sgabeblack@google.com    L1_GETS,                 desc="a L1D GETS request for a block maped to us";
9314184Sgabeblack@google.com    L1_GETX,                 desc="a L1D GETX request for a block maped to us";
9414184Sgabeblack@google.com    L1_UPGRADE,                 desc="a L1D GETX request for a block maped to us";
9514184Sgabeblack@google.com
9614184Sgabeblack@google.com    L1_PUTX,                 desc="L1 replacing data";
9714184Sgabeblack@google.com    L1_PUTX_old,             desc="L1 replacing data, but no longer sharer";
9814184Sgabeblack@google.com
9914184Sgabeblack@google.com    // events initiated by this L2
10014184Sgabeblack@google.com    L2_Replacement,     desc="L2 Replacement", format="!r";
10114184Sgabeblack@google.com    L2_Replacement_clean,     desc="L2 Replacement, but data is clean", format="!r";
10214184Sgabeblack@google.com
10314184Sgabeblack@google.com    // events from memory controller
10414184Sgabeblack@google.com    Mem_Data,     desc="data from memory", format="!r";
10514184Sgabeblack@google.com    Mem_Ack,     desc="ack from memory", format="!r";
10614184Sgabeblack@google.com
10714184Sgabeblack@google.com    // M->S data writeback
10814184Sgabeblack@google.com    WB_Data,  desc="data from L1";
10914184Sgabeblack@google.com    WB_Data_clean,  desc="clean data from L1";
11014184Sgabeblack@google.com    Ack,      desc="writeback ack";
11114184Sgabeblack@google.com    Ack_all,      desc="writeback ack";
11214184Sgabeblack@google.com
11314184Sgabeblack@google.com    Unblock, desc="Unblock from L1 requestor";
11414184Sgabeblack@google.com    Exclusive_Unblock, desc="Unblock from L1 requestor";
11514184Sgabeblack@google.com
11614184Sgabeblack@google.com    MEM_Inv, desc="Invalidation from directory";
11714184Sgabeblack@google.com  }
11814184Sgabeblack@google.com
11914184Sgabeblack@google.com  // TYPES
12014184Sgabeblack@google.com
12114184Sgabeblack@google.com  // CacheEntry
12214184Sgabeblack@google.com  structure(Entry, desc="...", interface="AbstractCacheEntry") {
12314184Sgabeblack@google.com    State CacheState,          desc="cache state";
12414184Sgabeblack@google.com    NetDest Sharers,               desc="tracks the L1 shares on-chip";
12514184Sgabeblack@google.com    MachineID Exclusive,          desc="Exclusive holder of block";
12614184Sgabeblack@google.com    DataBlock DataBlk,       desc="data for the block";
12714184Sgabeblack@google.com    bool Dirty, default="false", desc="data is dirty";
12814184Sgabeblack@google.com  }
12914184Sgabeblack@google.com
13014184Sgabeblack@google.com  // TBE fields
13114184Sgabeblack@google.com  structure(TBE, desc="...") {
13214184Sgabeblack@google.com    Addr addr,            desc="Physical address for this TBE";
13314184Sgabeblack@google.com    State TBEState,             desc="Transient state";
13414184Sgabeblack@google.com    DataBlock DataBlk,          desc="Buffer for the data block";
13514184Sgabeblack@google.com    bool Dirty, default="false", desc="Data is Dirty";
13614184Sgabeblack@google.com
13714184Sgabeblack@google.com    NetDest L1_GetS_IDs,            desc="Set of the internal processors that want the block in shared state";
13814184Sgabeblack@google.com    MachineID L1_GetX_ID,          desc="ID of the L1 cache to forward the block to once we get a response";
13914184Sgabeblack@google.com    int pendingAcks,            desc="number of pending acks for invalidates during writeback";
14014184Sgabeblack@google.com  }
14114184Sgabeblack@google.com
14214184Sgabeblack@google.com  structure(TBETable, external="yes") {
14314184Sgabeblack@google.com    TBE lookup(Addr);
14414184Sgabeblack@google.com    void allocate(Addr);
14514184Sgabeblack@google.com    void deallocate(Addr);
14614184Sgabeblack@google.com    bool isPresent(Addr);
14714184Sgabeblack@google.com  }
14814184Sgabeblack@google.com
14914184Sgabeblack@google.com  TBETable TBEs, template="<L2Cache_TBE>", constructor="m_number_of_TBEs";
15014184Sgabeblack@google.com
15114184Sgabeblack@google.com  Tick clockEdge();
15214184Sgabeblack@google.com  Tick cyclesToTicks(Cycles c);
15314184Sgabeblack@google.com  Cycles ticksToCycles(Tick t);
15414184Sgabeblack@google.com
15514184Sgabeblack@google.com  void set_cache_entry(AbstractCacheEntry a);
15614184Sgabeblack@google.com  void unset_cache_entry();
15714184Sgabeblack@google.com  void set_tbe(TBE a);
15814184Sgabeblack@google.com  void unset_tbe();
15914184Sgabeblack@google.com  void wakeUpBuffers(Addr a);
16014184Sgabeblack@google.com  void profileMsgDelay(int virtualNetworkType, Cycles c);
16114184Sgabeblack@google.com  MachineID mapAddressToMachine(Addr addr, MachineType mtype);
16214184Sgabeblack@google.com
16314184Sgabeblack@google.com  // inclusive cache, returns L2 entries only
16414184Sgabeblack@google.com  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
16514184Sgabeblack@google.com    return static_cast(Entry, "pointer", L2cache[addr]);
16614184Sgabeblack@google.com  }
16714184Sgabeblack@google.com
16814184Sgabeblack@google.com  bool isSharer(Addr addr, MachineID requestor, Entry cache_entry) {
16914184Sgabeblack@google.com    if (is_valid(cache_entry)) {
17014184Sgabeblack@google.com      return cache_entry.Sharers.isElement(requestor);
17114184Sgabeblack@google.com    } else {
17214184Sgabeblack@google.com      return false;
17314184Sgabeblack@google.com    }
17414184Sgabeblack@google.com  }
17514184Sgabeblack@google.com
17614184Sgabeblack@google.com  void addSharer(Addr addr, MachineID requestor, Entry cache_entry) {
17714184Sgabeblack@google.com    assert(is_valid(cache_entry));
17814184Sgabeblack@google.com    DPRINTF(RubySlicc, "machineID: %s, requestor: %s, address: %#x\n",
17914184Sgabeblack@google.com            machineID, requestor, addr);
18014184Sgabeblack@google.com    cache_entry.Sharers.add(requestor);
18114184Sgabeblack@google.com  }
18214184Sgabeblack@google.com
18314184Sgabeblack@google.com  State getState(TBE tbe, Entry cache_entry, Addr addr) {
18414184Sgabeblack@google.com    if(is_valid(tbe)) {
18514184Sgabeblack@google.com      return tbe.TBEState;
18614184Sgabeblack@google.com    } else if (is_valid(cache_entry)) {
18714184Sgabeblack@google.com      return cache_entry.CacheState;
18814184Sgabeblack@google.com    }
18914184Sgabeblack@google.com    return State:NP;
19014184Sgabeblack@google.com  }
19114184Sgabeblack@google.com
19214184Sgabeblack@google.com  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
19314184Sgabeblack@google.com    // MUST CHANGE
19414184Sgabeblack@google.com    if (is_valid(tbe)) {
19514184Sgabeblack@google.com      tbe.TBEState := state;
19614184Sgabeblack@google.com    }
19714184Sgabeblack@google.com
19814184Sgabeblack@google.com    if (is_valid(cache_entry)) {
19914184Sgabeblack@google.com      cache_entry.CacheState := state;
20014184Sgabeblack@google.com    }
20114184Sgabeblack@google.com  }
20214184Sgabeblack@google.com
20314184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
20414184Sgabeblack@google.com    TBE tbe := TBEs[addr];
20514184Sgabeblack@google.com    if(is_valid(tbe)) {
20614184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(tbe.TBEState));
20714184Sgabeblack@google.com      return L2Cache_State_to_permission(tbe.TBEState);
20814184Sgabeblack@google.com    }
20914184Sgabeblack@google.com
21014184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
21114184Sgabeblack@google.com    if(is_valid(cache_entry)) {
21214184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(cache_entry.CacheState));
21314184Sgabeblack@google.com      return L2Cache_State_to_permission(cache_entry.CacheState);
21414184Sgabeblack@google.com    }
21514184Sgabeblack@google.com
21614184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
21714184Sgabeblack@google.com    return AccessPermission:NotPresent;
21814184Sgabeblack@google.com  }
21914184Sgabeblack@google.com
22014184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
22114184Sgabeblack@google.com    TBE tbe := TBEs[addr];
22214184Sgabeblack@google.com    if(is_valid(tbe)) {
22314184Sgabeblack@google.com      testAndRead(addr, tbe.DataBlk, pkt);
22414184Sgabeblack@google.com    } else {
22514184Sgabeblack@google.com      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
22614184Sgabeblack@google.com    }
22714184Sgabeblack@google.com  }
22814184Sgabeblack@google.com
22914184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
23014184Sgabeblack@google.com    int num_functional_writes := 0;
23114184Sgabeblack@google.com
23214184Sgabeblack@google.com    TBE tbe := TBEs[addr];
23314184Sgabeblack@google.com    if(is_valid(tbe)) {
23414184Sgabeblack@google.com      num_functional_writes := num_functional_writes +
23514184Sgabeblack@google.com        testAndWrite(addr, tbe.DataBlk, pkt);
23614184Sgabeblack@google.com      return num_functional_writes;
23714184Sgabeblack@google.com    }
23814184Sgabeblack@google.com
23914184Sgabeblack@google.com    num_functional_writes := num_functional_writes +
24014184Sgabeblack@google.com        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
24114184Sgabeblack@google.com    return num_functional_writes;
24214184Sgabeblack@google.com  }
24314184Sgabeblack@google.com
24414184Sgabeblack@google.com  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
24514184Sgabeblack@google.com    if (is_valid(cache_entry)) {
24614184Sgabeblack@google.com      cache_entry.changePermission(L2Cache_State_to_permission(state));
24714184Sgabeblack@google.com    }
24814184Sgabeblack@google.com  }
24914184Sgabeblack@google.com
25014184Sgabeblack@google.com  Event L1Cache_request_type_to_event(CoherenceRequestType type, Addr addr,
25114184Sgabeblack@google.com                                      MachineID requestor, Entry cache_entry) {
25214184Sgabeblack@google.com    if(type == CoherenceRequestType:GETS) {
25314184Sgabeblack@google.com      return Event:L1_GETS;
25414184Sgabeblack@google.com    } else if(type == CoherenceRequestType:GET_INSTR) {
25514184Sgabeblack@google.com      return Event:L1_GET_INSTR;
25614184Sgabeblack@google.com    } else if (type == CoherenceRequestType:GETX) {
25714184Sgabeblack@google.com      return Event:L1_GETX;
25814184Sgabeblack@google.com    } else if (type == CoherenceRequestType:UPGRADE) {
25914184Sgabeblack@google.com      if ( is_valid(cache_entry) && cache_entry.Sharers.isElement(requestor) ) {
26014184Sgabeblack@google.com        return Event:L1_UPGRADE;
26114184Sgabeblack@google.com      } else {
26214184Sgabeblack@google.com        return Event:L1_GETX;
26314184Sgabeblack@google.com      }
26414184Sgabeblack@google.com    } else if (type == CoherenceRequestType:PUTX) {
26514184Sgabeblack@google.com      if (isSharer(addr, requestor, cache_entry)) {
26614184Sgabeblack@google.com        return Event:L1_PUTX;
26714184Sgabeblack@google.com      } else {
26814184Sgabeblack@google.com        return Event:L1_PUTX_old;
26914184Sgabeblack@google.com      }
27014184Sgabeblack@google.com    } else {
27114184Sgabeblack@google.com      DPRINTF(RubySlicc, "address: %#x, Request Type: %s\n", addr, type);
27214184Sgabeblack@google.com      error("Invalid L1 forwarded request type");
27314184Sgabeblack@google.com    }
27414184Sgabeblack@google.com  }
27514184Sgabeblack@google.com
27614184Sgabeblack@google.com  int getPendingAcks(TBE tbe) {
27714184Sgabeblack@google.com    return tbe.pendingAcks;
27814184Sgabeblack@google.com  }
27914184Sgabeblack@google.com
28014184Sgabeblack@google.com  bool isDirty(Entry cache_entry) {
28114184Sgabeblack@google.com    assert(is_valid(cache_entry));
28214184Sgabeblack@google.com    return cache_entry.Dirty;
28314184Sgabeblack@google.com  }
28414184Sgabeblack@google.com
28514184Sgabeblack@google.com  // ** OUT_PORTS **
28614184Sgabeblack@google.com
28714184Sgabeblack@google.com  out_port(L1RequestL2Network_out, RequestMsg, L1RequestFromL2Cache);
28814184Sgabeblack@google.com  out_port(DirRequestL2Network_out, RequestMsg, DirRequestFromL2Cache);
28914184Sgabeblack@google.com  out_port(responseL2Network_out, ResponseMsg, responseFromL2Cache);
29014184Sgabeblack@google.com
29114184Sgabeblack@google.com
29214184Sgabeblack@google.com  in_port(L1unblockNetwork_in, ResponseMsg, unblockToL2Cache, rank = 2) {
29314184Sgabeblack@google.com    if(L1unblockNetwork_in.isReady(clockEdge())) {
29414184Sgabeblack@google.com      peek(L1unblockNetwork_in,  ResponseMsg) {
29514184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
29614184Sgabeblack@google.com        TBE tbe := TBEs[in_msg.addr];
29714184Sgabeblack@google.com        DPRINTF(RubySlicc, "Addr: %#x State: %s Sender: %s Type: %s Dest: %s\n",
29814184Sgabeblack@google.com                in_msg.addr, getState(tbe, cache_entry, in_msg.addr),
29914184Sgabeblack@google.com                in_msg.Sender, in_msg.Type, in_msg.Destination);
30014184Sgabeblack@google.com
30114184Sgabeblack@google.com        assert(in_msg.Destination.isElement(machineID));
30214184Sgabeblack@google.com        if (in_msg.Type == CoherenceResponseType:EXCLUSIVE_UNBLOCK) {
30314184Sgabeblack@google.com          trigger(Event:Exclusive_Unblock, in_msg.addr, cache_entry, tbe);
30414184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:UNBLOCK) {
30514184Sgabeblack@google.com          trigger(Event:Unblock, in_msg.addr, cache_entry, tbe);
30614184Sgabeblack@google.com        } else {
30714184Sgabeblack@google.com          error("unknown unblock message");
30814184Sgabeblack@google.com        }
30914184Sgabeblack@google.com      }
31014184Sgabeblack@google.com    }
31114184Sgabeblack@google.com  }
31214184Sgabeblack@google.com
31314184Sgabeblack@google.com  // Response  L2 Network - response msg to this particular L2 bank
31414184Sgabeblack@google.com  in_port(responseL2Network_in, ResponseMsg, responseToL2Cache, rank = 1) {
31514184Sgabeblack@google.com    if (responseL2Network_in.isReady(clockEdge())) {
31614184Sgabeblack@google.com      peek(responseL2Network_in, ResponseMsg) {
31714184Sgabeblack@google.com        // test wether it's from a local L1 or an off chip source
31814184Sgabeblack@google.com        assert(in_msg.Destination.isElement(machineID));
31914184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
32014184Sgabeblack@google.com        TBE tbe := TBEs[in_msg.addr];
32114184Sgabeblack@google.com
32214184Sgabeblack@google.com        if(machineIDToMachineType(in_msg.Sender) == MachineType:L1Cache) {
32314184Sgabeblack@google.com          if(in_msg.Type == CoherenceResponseType:DATA) {
32414184Sgabeblack@google.com            if (in_msg.Dirty) {
32514184Sgabeblack@google.com              trigger(Event:WB_Data, in_msg.addr, cache_entry, tbe);
32614184Sgabeblack@google.com            } else {
32714184Sgabeblack@google.com              trigger(Event:WB_Data_clean, in_msg.addr, cache_entry, tbe);
32814184Sgabeblack@google.com            }
32914184Sgabeblack@google.com          } else if (in_msg.Type == CoherenceResponseType:ACK) {
33014184Sgabeblack@google.com            if ((getPendingAcks(tbe) - in_msg.AckCount) == 0) {
33114184Sgabeblack@google.com              trigger(Event:Ack_all, in_msg.addr, cache_entry, tbe);
33214184Sgabeblack@google.com            } else {
33314184Sgabeblack@google.com              trigger(Event:Ack, in_msg.addr, cache_entry, tbe);
33414184Sgabeblack@google.com            }
33514184Sgabeblack@google.com          } else {
33614184Sgabeblack@google.com            error("unknown message type");
33714184Sgabeblack@google.com          }
33814184Sgabeblack@google.com
33914184Sgabeblack@google.com        } else { // external message
34014184Sgabeblack@google.com          if(in_msg.Type == CoherenceResponseType:MEMORY_DATA) {
34114184Sgabeblack@google.com              trigger(Event:Mem_Data, in_msg.addr, cache_entry, tbe);
34214184Sgabeblack@google.com          } else if(in_msg.Type == CoherenceResponseType:MEMORY_ACK) {
34314184Sgabeblack@google.com              trigger(Event:Mem_Ack, in_msg.addr, cache_entry, tbe);
34414184Sgabeblack@google.com          } else if(in_msg.Type == CoherenceResponseType:INV) {
34514184Sgabeblack@google.com              trigger(Event:MEM_Inv, in_msg.addr, cache_entry, tbe);
34614184Sgabeblack@google.com          } else {
34714184Sgabeblack@google.com            error("unknown message type");
34814184Sgabeblack@google.com          }
34914184Sgabeblack@google.com        }
35014184Sgabeblack@google.com      }
35114184Sgabeblack@google.com    }  // if not ready, do nothing
35214184Sgabeblack@google.com  }
35314184Sgabeblack@google.com
35414184Sgabeblack@google.com  // L1 Request
35514184Sgabeblack@google.com  in_port(L1RequestL2Network_in, RequestMsg, L1RequestToL2Cache, rank = 0) {
35614184Sgabeblack@google.com    if(L1RequestL2Network_in.isReady(clockEdge())) {
35714184Sgabeblack@google.com      peek(L1RequestL2Network_in,  RequestMsg) {
35814184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
35914184Sgabeblack@google.com        TBE tbe := TBEs[in_msg.addr];
36014184Sgabeblack@google.com
36114184Sgabeblack@google.com        DPRINTF(RubySlicc, "Addr: %#x State: %s Req: %s Type: %s Dest: %s\n",
36214184Sgabeblack@google.com                in_msg.addr, getState(tbe, cache_entry, in_msg.addr),
36314184Sgabeblack@google.com                in_msg.Requestor, in_msg.Type, in_msg.Destination);
36414184Sgabeblack@google.com
36514184Sgabeblack@google.com        assert(machineIDToMachineType(in_msg.Requestor) == MachineType:L1Cache);
36614184Sgabeblack@google.com        assert(in_msg.Destination.isElement(machineID));
36714184Sgabeblack@google.com
36814184Sgabeblack@google.com        if (is_valid(cache_entry)) {
36914184Sgabeblack@google.com          // The L2 contains the block, so proceeded with handling the request
37014184Sgabeblack@google.com          trigger(L1Cache_request_type_to_event(in_msg.Type, in_msg.addr,
37114184Sgabeblack@google.com                                                in_msg.Requestor, cache_entry),
37214184Sgabeblack@google.com                  in_msg.addr, cache_entry, tbe);
37314184Sgabeblack@google.com        } else {
37414184Sgabeblack@google.com          if (L2cache.cacheAvail(in_msg.addr)) {
37514184Sgabeblack@google.com            // L2 does't have the line, but we have space for it in the L2
37614184Sgabeblack@google.com            trigger(L1Cache_request_type_to_event(in_msg.Type, in_msg.addr,
37714184Sgabeblack@google.com                                                  in_msg.Requestor, cache_entry),
37814184Sgabeblack@google.com                    in_msg.addr, cache_entry, tbe);
37914184Sgabeblack@google.com          } else {
38014184Sgabeblack@google.com            // No room in the L2, so we need to make room before handling the request
38114300Sjqu32@wisc.edu            Addr victim := L2cache.cacheProbe(in_msg.addr);
38214300Sjqu32@wisc.edu            Entry L2cache_entry := getCacheEntry(victim);
38314184Sgabeblack@google.com            if (isDirty(L2cache_entry)) {
38414300Sjqu32@wisc.edu              trigger(Event:L2_Replacement, victim, L2cache_entry, TBEs[victim]);
38514184Sgabeblack@google.com            } else {
38614300Sjqu32@wisc.edu              trigger(Event:L2_Replacement_clean,
38714300Sjqu32@wisc.edu                      victim, L2cache_entry, TBEs[victim]);
38814184Sgabeblack@google.com            }
38914184Sgabeblack@google.com          }
39014184Sgabeblack@google.com        }
39114184Sgabeblack@google.com      }
39214184Sgabeblack@google.com    }
39314184Sgabeblack@google.com  }
39414184Sgabeblack@google.com
39514184Sgabeblack@google.com
39614184Sgabeblack@google.com  // ACTIONS
39714184Sgabeblack@google.com
39814184Sgabeblack@google.com  action(a_issueFetchToMemory, "a", desc="fetch data from memory") {
39914184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
40014184Sgabeblack@google.com      enqueue(DirRequestL2Network_out, RequestMsg, l2_request_latency) {
40114184Sgabeblack@google.com        out_msg.addr := address;
40214184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:GETS;
40314184Sgabeblack@google.com        out_msg.Requestor := machineID;
40414184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
40514184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Control;
40614184Sgabeblack@google.com      }
40714184Sgabeblack@google.com    }
40814184Sgabeblack@google.com  }
40914184Sgabeblack@google.com
41014184Sgabeblack@google.com  action(b_forwardRequestToExclusive, "b", desc="Forward request to the exclusive L1") {
41114184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
41214184Sgabeblack@google.com      enqueue(L1RequestL2Network_out, RequestMsg, to_l1_latency) {
41314184Sgabeblack@google.com        assert(is_valid(cache_entry));
41414184Sgabeblack@google.com        out_msg.addr := address;
41514184Sgabeblack@google.com        out_msg.Type := in_msg.Type;
41614184Sgabeblack@google.com        out_msg.Requestor := in_msg.Requestor;
41714184Sgabeblack@google.com        out_msg.Destination.add(cache_entry.Exclusive);
41814184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
41914184Sgabeblack@google.com      }
42014184Sgabeblack@google.com    }
42114184Sgabeblack@google.com  }
42214184Sgabeblack@google.com
42314184Sgabeblack@google.com  action(c_exclusiveReplacement, "c", desc="Send data to memory") {
42414184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
42514184Sgabeblack@google.com      assert(is_valid(cache_entry));
42614184Sgabeblack@google.com      out_msg.addr := address;
42714184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:MEMORY_DATA;
42814184Sgabeblack@google.com      out_msg.Sender := machineID;
42914184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
43014184Sgabeblack@google.com      out_msg.DataBlk := cache_entry.DataBlk;
43114184Sgabeblack@google.com      out_msg.Dirty := cache_entry.Dirty;
43214184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Data;
43314184Sgabeblack@google.com    }
43414184Sgabeblack@google.com  }
43514184Sgabeblack@google.com
43614184Sgabeblack@google.com  action(c_exclusiveCleanReplacement, "cc", desc="Send ack to memory for clean replacement") {
43714184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
43814184Sgabeblack@google.com      out_msg.addr := address;
43914184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:ACK;
44014184Sgabeblack@google.com      out_msg.Sender := machineID;
44114184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
44214184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Control;
44314184Sgabeblack@google.com    }
44414184Sgabeblack@google.com  }
44514184Sgabeblack@google.com
44614184Sgabeblack@google.com  action(ct_exclusiveReplacementFromTBE, "ct", desc="Send data to memory") {
44714184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
44814184Sgabeblack@google.com      assert(is_valid(tbe));
44914184Sgabeblack@google.com      out_msg.addr := address;
45014184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:MEMORY_DATA;
45114184Sgabeblack@google.com      out_msg.Sender := machineID;
45214184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address, MachineType:Directory));
45314184Sgabeblack@google.com      out_msg.DataBlk := tbe.DataBlk;
45414184Sgabeblack@google.com      out_msg.Dirty := tbe.Dirty;
45514184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Data;
45614184Sgabeblack@google.com    }
45714184Sgabeblack@google.com  }
45814184Sgabeblack@google.com
45914184Sgabeblack@google.com  action(d_sendDataToRequestor, "d", desc="Send data from cache to reqeustor") {
46014184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
46114184Sgabeblack@google.com      enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
46214184Sgabeblack@google.com        assert(is_valid(cache_entry));
46314184Sgabeblack@google.com        out_msg.addr := address;
46414184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:DATA;
46514184Sgabeblack@google.com        out_msg.Sender := machineID;
46614184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
46714184Sgabeblack@google.com        out_msg.DataBlk := cache_entry.DataBlk;
46814184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Data;
46914184Sgabeblack@google.com
47014184Sgabeblack@google.com        out_msg.AckCount := 0 - cache_entry.Sharers.count();
47114184Sgabeblack@google.com        if (cache_entry.Sharers.isElement(in_msg.Requestor)) {
47214184Sgabeblack@google.com          out_msg.AckCount := out_msg.AckCount + 1;
47314184Sgabeblack@google.com        }
47414184Sgabeblack@google.com      }
47514184Sgabeblack@google.com    }
47614184Sgabeblack@google.com  }
47714184Sgabeblack@google.com
47814184Sgabeblack@google.com  action(dd_sendExclusiveDataToRequestor, "dd", desc="Send data from cache to reqeustor") {
47914184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
48014184Sgabeblack@google.com      enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
48114184Sgabeblack@google.com        assert(is_valid(cache_entry));
48214184Sgabeblack@google.com        out_msg.addr := address;
48314184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
48414184Sgabeblack@google.com        out_msg.Sender := machineID;
48514184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
48614184Sgabeblack@google.com        out_msg.DataBlk := cache_entry.DataBlk;
48714184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Data;
48814184Sgabeblack@google.com
48914184Sgabeblack@google.com        out_msg.AckCount := 0 - cache_entry.Sharers.count();
49014184Sgabeblack@google.com        if (cache_entry.Sharers.isElement(in_msg.Requestor)) {
49114184Sgabeblack@google.com          out_msg.AckCount := out_msg.AckCount + 1;
49214184Sgabeblack@google.com        }
49314184Sgabeblack@google.com      }
49414184Sgabeblack@google.com    }
49514184Sgabeblack@google.com  }
49614184Sgabeblack@google.com
49714184Sgabeblack@google.com  action(ds_sendSharedDataToRequestor, "ds", desc="Send data from cache to reqeustor") {
49814184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
49914184Sgabeblack@google.com      enqueue(responseL2Network_out, ResponseMsg, l2_response_latency) {
50014184Sgabeblack@google.com        assert(is_valid(cache_entry));
50114184Sgabeblack@google.com        out_msg.addr := address;
50214184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:DATA;
50314184Sgabeblack@google.com        out_msg.Sender := machineID;
50414184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
50514184Sgabeblack@google.com        out_msg.DataBlk := cache_entry.DataBlk;
50614184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Data;
50714184Sgabeblack@google.com        out_msg.AckCount := 0;
50814184Sgabeblack@google.com      }
50914184Sgabeblack@google.com    }
51014184Sgabeblack@google.com  }
51114184Sgabeblack@google.com
51214184Sgabeblack@google.com  action(e_sendDataToGetSRequestors, "e", desc="Send data from cache to all GetS IDs") {
51314184Sgabeblack@google.com    assert(is_valid(tbe));
51414184Sgabeblack@google.com    assert(tbe.L1_GetS_IDs.count() > 0);
51514184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, to_l1_latency) {
51614184Sgabeblack@google.com      assert(is_valid(cache_entry));
51714184Sgabeblack@google.com      out_msg.addr := address;
51814184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:DATA;
51914184Sgabeblack@google.com      out_msg.Sender := machineID;
52014184Sgabeblack@google.com      out_msg.Destination := tbe.L1_GetS_IDs;  // internal nodes
52114184Sgabeblack@google.com      out_msg.DataBlk := cache_entry.DataBlk;
52214184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Data;
52314184Sgabeblack@google.com    }
52414184Sgabeblack@google.com  }
52514184Sgabeblack@google.com
52614184Sgabeblack@google.com  action(ex_sendExclusiveDataToGetSRequestors, "ex", desc="Send data from cache to all GetS IDs") {
52714184Sgabeblack@google.com    assert(is_valid(tbe));
52814184Sgabeblack@google.com    assert(tbe.L1_GetS_IDs.count() == 1);
52914184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, to_l1_latency) {
53014184Sgabeblack@google.com      assert(is_valid(cache_entry));
53114184Sgabeblack@google.com      out_msg.addr := address;
53214184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
53314184Sgabeblack@google.com      out_msg.Sender := machineID;
53414184Sgabeblack@google.com      out_msg.Destination := tbe.L1_GetS_IDs;  // internal nodes
53514184Sgabeblack@google.com      out_msg.DataBlk := cache_entry.DataBlk;
53614184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Data;
53714184Sgabeblack@google.com    }
53814184Sgabeblack@google.com  }
53914184Sgabeblack@google.com
54014184Sgabeblack@google.com  action(ee_sendDataToGetXRequestor, "ee", desc="Send data from cache to GetX ID") {
54114184Sgabeblack@google.com    enqueue(responseL2Network_out, ResponseMsg, to_l1_latency) {
54214184Sgabeblack@google.com      assert(is_valid(tbe));
54314184Sgabeblack@google.com      assert(is_valid(cache_entry));
54414184Sgabeblack@google.com      out_msg.addr := address;
54514184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:DATA;
54614184Sgabeblack@google.com      out_msg.Sender := machineID;
54714184Sgabeblack@google.com      out_msg.Destination.add(tbe.L1_GetX_ID);
54814184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", out_msg.Destination);
54914184Sgabeblack@google.com      out_msg.DataBlk := cache_entry.DataBlk;
55014184Sgabeblack@google.com      DPRINTF(RubySlicc, "Address: %#x, Destination: %s, DataBlock: %s\n",
55114184Sgabeblack@google.com              out_msg.addr, out_msg.Destination, out_msg.DataBlk);
55214184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Response_Data;
55314184Sgabeblack@google.com    }
55414184Sgabeblack@google.com  }
55514184Sgabeblack@google.com
55614184Sgabeblack@google.com  action(f_sendInvToSharers, "f", desc="invalidate sharers for L2 replacement") {
55714184Sgabeblack@google.com    enqueue(L1RequestL2Network_out, RequestMsg, to_l1_latency) {
55814184Sgabeblack@google.com      assert(is_valid(cache_entry));
55914184Sgabeblack@google.com      out_msg.addr := address;
56014184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:INV;
56114184Sgabeblack@google.com      out_msg.Requestor := machineID;
56214184Sgabeblack@google.com      out_msg.Destination := cache_entry.Sharers;
56314184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Request_Control;
56414184Sgabeblack@google.com    }
56514184Sgabeblack@google.com  }
56614184Sgabeblack@google.com
56714184Sgabeblack@google.com  action(fw_sendFwdInvToSharers, "fw", desc="invalidate sharers for request") {
56814184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
56914184Sgabeblack@google.com      enqueue(L1RequestL2Network_out, RequestMsg, to_l1_latency) {
57014184Sgabeblack@google.com        assert(is_valid(cache_entry));
57114184Sgabeblack@google.com        out_msg.addr := address;
57214184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:INV;
57314184Sgabeblack@google.com        out_msg.Requestor := in_msg.Requestor;
57414184Sgabeblack@google.com        out_msg.Destination := cache_entry.Sharers;
57514184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
57614184Sgabeblack@google.com      }
57714184Sgabeblack@google.com    }
57814184Sgabeblack@google.com  }
57914184Sgabeblack@google.com
58014184Sgabeblack@google.com  action(fwm_sendFwdInvToSharersMinusRequestor, "fwm", desc="invalidate sharers for request, requestor is sharer") {
58114184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
58214184Sgabeblack@google.com      enqueue(L1RequestL2Network_out, RequestMsg, to_l1_latency) {
58314184Sgabeblack@google.com        assert(is_valid(cache_entry));
58414184Sgabeblack@google.com        out_msg.addr := address;
58514184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:INV;
58614184Sgabeblack@google.com        out_msg.Requestor := in_msg.Requestor;
58714184Sgabeblack@google.com        out_msg.Destination := cache_entry.Sharers;
58814184Sgabeblack@google.com        out_msg.Destination.remove(in_msg.Requestor);
58914184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
59014184Sgabeblack@google.com      }
59114184Sgabeblack@google.com    }
59214184Sgabeblack@google.com  }
59314184Sgabeblack@google.com
59414184Sgabeblack@google.com  // OTHER ACTIONS
59514184Sgabeblack@google.com  action(i_allocateTBE, "i", desc="Allocate TBE for request") {
59614184Sgabeblack@google.com    check_allocate(TBEs);
59714184Sgabeblack@google.com    assert(is_valid(cache_entry));
59814184Sgabeblack@google.com    TBEs.allocate(address);
59914184Sgabeblack@google.com    set_tbe(TBEs[address]);
60014184Sgabeblack@google.com    tbe.L1_GetS_IDs.clear();
60114184Sgabeblack@google.com    tbe.DataBlk := cache_entry.DataBlk;
60214184Sgabeblack@google.com    tbe.Dirty := cache_entry.Dirty;
60314184Sgabeblack@google.com    tbe.pendingAcks := cache_entry.Sharers.count();
60414184Sgabeblack@google.com  }
60514184Sgabeblack@google.com
60614184Sgabeblack@google.com  action(s_deallocateTBE, "s", desc="Deallocate external TBE") {
60714184Sgabeblack@google.com    TBEs.deallocate(address);
60814184Sgabeblack@google.com    unset_tbe();
60914184Sgabeblack@google.com  }
61014184Sgabeblack@google.com
61114184Sgabeblack@google.com  action(jj_popL1RequestQueue, "\j", desc="Pop incoming L1 request queue") {
61214184Sgabeblack@google.com    Tick delay := L1RequestL2Network_in.dequeue(clockEdge());
61314184Sgabeblack@google.com    profileMsgDelay(0, ticksToCycles(delay));
61414184Sgabeblack@google.com  }
61514184Sgabeblack@google.com
61614184Sgabeblack@google.com  action(k_popUnblockQueue, "k", desc="Pop incoming unblock queue") {
61714184Sgabeblack@google.com    Tick delay := L1unblockNetwork_in.dequeue(clockEdge());
61814184Sgabeblack@google.com    profileMsgDelay(0, ticksToCycles(delay));
61914184Sgabeblack@google.com  }
62014184Sgabeblack@google.com
62114184Sgabeblack@google.com  action(o_popIncomingResponseQueue, "o", desc="Pop Incoming Response queue") {
62214184Sgabeblack@google.com    Tick delay := responseL2Network_in.dequeue(clockEdge());
62314184Sgabeblack@google.com    profileMsgDelay(1, ticksToCycles(delay));
62414184Sgabeblack@google.com  }
62514184Sgabeblack@google.com
62614184Sgabeblack@google.com  action(m_writeDataToCache, "m", desc="Write data from response queue to cache") {
62714184Sgabeblack@google.com    peek(responseL2Network_in, ResponseMsg) {
62814184Sgabeblack@google.com      assert(is_valid(cache_entry));
62914184Sgabeblack@google.com      cache_entry.DataBlk := in_msg.DataBlk;
63014184Sgabeblack@google.com      if (in_msg.Dirty) {
63114184Sgabeblack@google.com        cache_entry.Dirty := in_msg.Dirty;
63214184Sgabeblack@google.com      }
63314184Sgabeblack@google.com    }
63414184Sgabeblack@google.com  }
63514184Sgabeblack@google.com
63614184Sgabeblack@google.com  action(mr_writeDataToCacheFromRequest, "mr", desc="Write data from response queue to cache") {
63714184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
63814184Sgabeblack@google.com      assert(is_valid(cache_entry));
63914184Sgabeblack@google.com      if (in_msg.Dirty) {
64014184Sgabeblack@google.com        cache_entry.DataBlk := in_msg.DataBlk;
64114184Sgabeblack@google.com        cache_entry.Dirty := in_msg.Dirty;
64214184Sgabeblack@google.com      }
64314184Sgabeblack@google.com    }
64414184Sgabeblack@google.com  }
64514184Sgabeblack@google.com
64614184Sgabeblack@google.com  action(q_updateAck, "q", desc="update pending ack count") {
64714184Sgabeblack@google.com    peek(responseL2Network_in, ResponseMsg) {
64814184Sgabeblack@google.com      assert(is_valid(tbe));
64914184Sgabeblack@google.com      tbe.pendingAcks := tbe.pendingAcks - in_msg.AckCount;
65014184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(in_msg.AckCount);
65114184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(" p: ");
65214184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT(tbe.pendingAcks);
65314184Sgabeblack@google.com    }
65414184Sgabeblack@google.com  }
65514184Sgabeblack@google.com
65614184Sgabeblack@google.com  action(qq_writeDataToTBE, "\qq", desc="Write data from response queue to TBE") {
65714184Sgabeblack@google.com    peek(responseL2Network_in, ResponseMsg) {
65814184Sgabeblack@google.com      assert(is_valid(tbe));
65914184Sgabeblack@google.com      tbe.DataBlk := in_msg.DataBlk;
66014184Sgabeblack@google.com      tbe.Dirty := in_msg.Dirty;
66114184Sgabeblack@google.com    }
66214184Sgabeblack@google.com  }
66314184Sgabeblack@google.com
66414184Sgabeblack@google.com  action(ss_recordGetSL1ID, "\s", desc="Record L1 GetS for load response") {
66514184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
66614184Sgabeblack@google.com      assert(is_valid(tbe));
66714184Sgabeblack@google.com      tbe.L1_GetS_IDs.add(in_msg.Requestor);
66814184Sgabeblack@google.com    }
66914184Sgabeblack@google.com  }
67014184Sgabeblack@google.com
67114184Sgabeblack@google.com  action(xx_recordGetXL1ID, "\x", desc="Record L1 GetX for store response") {
67214184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
67314184Sgabeblack@google.com      assert(is_valid(tbe));
67414184Sgabeblack@google.com      tbe.L1_GetX_ID := in_msg.Requestor;
67514184Sgabeblack@google.com    }
67614184Sgabeblack@google.com  }
67714184Sgabeblack@google.com
67814184Sgabeblack@google.com  action(set_setMRU, "\set", desc="set the MRU entry") {
67914184Sgabeblack@google.com    L2cache.setMRU(address);
68014184Sgabeblack@google.com  }
68114184Sgabeblack@google.com
68214184Sgabeblack@google.com  action(qq_allocateL2CacheBlock, "\q", desc="Set L2 cache tag equal to tag of block B.") {
68314184Sgabeblack@google.com    if (is_invalid(cache_entry)) {
68414184Sgabeblack@google.com      set_cache_entry(L2cache.allocate(address, new Entry));
68514184Sgabeblack@google.com    }
68614184Sgabeblack@google.com  }
68714184Sgabeblack@google.com
68814184Sgabeblack@google.com  action(rr_deallocateL2CacheBlock, "\r", desc="Deallocate L2 cache block.  Sets the cache to not present, allowing a replacement in parallel with a fetch.") {
68914184Sgabeblack@google.com    L2cache.deallocate(address);
69014184Sgabeblack@google.com    unset_cache_entry();
69114184Sgabeblack@google.com  }
69214184Sgabeblack@google.com
69314184Sgabeblack@google.com  action(t_sendWBAck, "t", desc="Send writeback ACK") {
69414184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
69514184Sgabeblack@google.com      enqueue(responseL2Network_out, ResponseMsg, to_l1_latency) {
69614184Sgabeblack@google.com        out_msg.addr := address;
69714184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:WB_ACK;
69814184Sgabeblack@google.com        out_msg.Sender := machineID;
69914184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
70014184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
70114184Sgabeblack@google.com      }
70214184Sgabeblack@google.com    }
70314184Sgabeblack@google.com  }
70414184Sgabeblack@google.com
70514184Sgabeblack@google.com  action(ts_sendInvAckToUpgrader, "ts", desc="Send ACK to upgrader") {
70614184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
70714184Sgabeblack@google.com      enqueue(responseL2Network_out, ResponseMsg, to_l1_latency) {
70814184Sgabeblack@google.com        assert(is_valid(cache_entry));
70914184Sgabeblack@google.com        out_msg.addr := address;
71014184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:ACK;
71114184Sgabeblack@google.com        out_msg.Sender := machineID;
71214184Sgabeblack@google.com        out_msg.Destination.add(in_msg.Requestor);
71314184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
71414184Sgabeblack@google.com        // upgrader doesn't get ack from itself, hence the + 1
71514184Sgabeblack@google.com        out_msg.AckCount := 0 - cache_entry.Sharers.count() + 1;
71614184Sgabeblack@google.com      }
71714184Sgabeblack@google.com    }
71814184Sgabeblack@google.com  }
71914184Sgabeblack@google.com
72014184Sgabeblack@google.com  action(uu_profileMiss, "\um", desc="Profile the demand miss") {
72114184Sgabeblack@google.com      ++L2cache.demand_misses;
72214184Sgabeblack@google.com  }
72314184Sgabeblack@google.com
72414184Sgabeblack@google.com  action(uu_profileHit, "\uh", desc="Profile the demand hit") {
72514184Sgabeblack@google.com      ++L2cache.demand_hits;
72614184Sgabeblack@google.com  }
72714184Sgabeblack@google.com
72814184Sgabeblack@google.com  action(nn_addSharer, "\n", desc="Add L1 sharer to list") {
72914184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
73014184Sgabeblack@google.com      assert(is_valid(cache_entry));
73114184Sgabeblack@google.com      addSharer(address, in_msg.Requestor, cache_entry);
73214184Sgabeblack@google.com      APPEND_TRANSITION_COMMENT( cache_entry.Sharers );
73314184Sgabeblack@google.com    }
73414184Sgabeblack@google.com  }
73514184Sgabeblack@google.com
73614184Sgabeblack@google.com  action(nnu_addSharerFromUnblock, "\nu", desc="Add L1 sharer to list") {
73714184Sgabeblack@google.com    peek(L1unblockNetwork_in, ResponseMsg) {
73814184Sgabeblack@google.com      assert(is_valid(cache_entry));
73914184Sgabeblack@google.com      addSharer(address, in_msg.Sender, cache_entry);
74014184Sgabeblack@google.com    }
74114184Sgabeblack@google.com  }
74214184Sgabeblack@google.com
74314184Sgabeblack@google.com  action(kk_removeRequestSharer, "\k", desc="Remove L1 Request sharer from list") {
74414184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
74514184Sgabeblack@google.com      assert(is_valid(cache_entry));
74614184Sgabeblack@google.com      cache_entry.Sharers.remove(in_msg.Requestor);
74714184Sgabeblack@google.com    }
74814184Sgabeblack@google.com  }
74914184Sgabeblack@google.com
75014184Sgabeblack@google.com  action(ll_clearSharers, "\l", desc="Remove all L1 sharers from list") {
75114184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
75214184Sgabeblack@google.com      assert(is_valid(cache_entry));
75314184Sgabeblack@google.com      cache_entry.Sharers.clear();
75414184Sgabeblack@google.com    }
75514184Sgabeblack@google.com  }
75614184Sgabeblack@google.com
75714184Sgabeblack@google.com  action(mm_markExclusive, "\m", desc="set the exclusive owner") {
75814184Sgabeblack@google.com    peek(L1RequestL2Network_in, RequestMsg) {
75914184Sgabeblack@google.com      assert(is_valid(cache_entry));
76014184Sgabeblack@google.com      cache_entry.Sharers.clear();
76114184Sgabeblack@google.com      cache_entry.Exclusive := in_msg.Requestor;
76214184Sgabeblack@google.com      addSharer(address, in_msg.Requestor, cache_entry);
76314184Sgabeblack@google.com    }
76414184Sgabeblack@google.com  }
76514184Sgabeblack@google.com
76614184Sgabeblack@google.com  action(mmu_markExclusiveFromUnblock, "\mu", desc="set the exclusive owner") {
76714184Sgabeblack@google.com    peek(L1unblockNetwork_in, ResponseMsg) {
76814184Sgabeblack@google.com      assert(is_valid(cache_entry));
76914184Sgabeblack@google.com      cache_entry.Sharers.clear();
77014184Sgabeblack@google.com      cache_entry.Exclusive := in_msg.Sender;
77114184Sgabeblack@google.com      addSharer(address, in_msg.Sender, cache_entry);
77214184Sgabeblack@google.com    }
77314184Sgabeblack@google.com  }
77414184Sgabeblack@google.com
77514184Sgabeblack@google.com  action(zz_stallAndWaitL1RequestQueue, "zz", desc="recycle L1 request queue") {
77614184Sgabeblack@google.com    stall_and_wait(L1RequestL2Network_in, address);
77714184Sgabeblack@google.com  }
77814184Sgabeblack@google.com
77914184Sgabeblack@google.com  action(zn_recycleResponseNetwork, "zn", desc="recycle memory request") {
78014184Sgabeblack@google.com    responseL2Network_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
78114184Sgabeblack@google.com  }
78214184Sgabeblack@google.com
78314184Sgabeblack@google.com  action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
78414184Sgabeblack@google.com    wakeUpBuffers(address);
78514184Sgabeblack@google.com  }
78614184Sgabeblack@google.com
78714184Sgabeblack@google.com  //*****************************************************
78814184Sgabeblack@google.com  // TRANSITIONS
78914184Sgabeblack@google.com  //*****************************************************
79014184Sgabeblack@google.com
79114184Sgabeblack@google.com
79214184Sgabeblack@google.com  //===============================================
79314184Sgabeblack@google.com  // BASE STATE - I
79414184Sgabeblack@google.com
79514184Sgabeblack@google.com  // Transitions from I (Idle)
79614184Sgabeblack@google.com  transition({NP, IS, ISS, IM, SS, M, M_I, I_I, S_I, MT_IB, MT_SB}, L1_PUTX) {
79714184Sgabeblack@google.com    t_sendWBAck;
79814184Sgabeblack@google.com    jj_popL1RequestQueue;
79914184Sgabeblack@google.com  }
80014184Sgabeblack@google.com
80114184Sgabeblack@google.com  transition({NP, SS, M, MT, M_I, I_I, S_I, IS, ISS, IM, MT_IB, MT_SB}, L1_PUTX_old) {
80214184Sgabeblack@google.com    t_sendWBAck;
80314184Sgabeblack@google.com    jj_popL1RequestQueue;
80414184Sgabeblack@google.com  }
80514184Sgabeblack@google.com
80614184Sgabeblack@google.com  transition({IM, IS, ISS, SS_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, {L2_Replacement, L2_Replacement_clean}) {
80714184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
80814184Sgabeblack@google.com  }
80914184Sgabeblack@google.com
81014184Sgabeblack@google.com  transition({IM, IS, ISS, SS_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, MEM_Inv) {
81114184Sgabeblack@google.com    zn_recycleResponseNetwork;
81214184Sgabeblack@google.com  }
81314184Sgabeblack@google.com
81414184Sgabeblack@google.com  transition({I_I, S_I, M_I, MT_I, MCT_I, NP}, MEM_Inv) {
81514184Sgabeblack@google.com    o_popIncomingResponseQueue;
81614184Sgabeblack@google.com  }
81714184Sgabeblack@google.com
81814184Sgabeblack@google.com
81914184Sgabeblack@google.com  transition({SS_MB, MT_MB, MT_IIB, MT_IB, MT_SB}, {L1_GETS, L1_GET_INSTR, L1_GETX, L1_UPGRADE}) {
82014184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
82114184Sgabeblack@google.com  }
82214184Sgabeblack@google.com
82314184Sgabeblack@google.com
82414184Sgabeblack@google.com  transition(NP, L1_GETS,  ISS) {
82514184Sgabeblack@google.com    qq_allocateL2CacheBlock;
82614184Sgabeblack@google.com    ll_clearSharers;
82714184Sgabeblack@google.com    nn_addSharer;
82814184Sgabeblack@google.com    i_allocateTBE;
82914184Sgabeblack@google.com    ss_recordGetSL1ID;
83014184Sgabeblack@google.com    a_issueFetchToMemory;
83114184Sgabeblack@google.com    uu_profileMiss;
83214184Sgabeblack@google.com    jj_popL1RequestQueue;
83314184Sgabeblack@google.com  }
83414184Sgabeblack@google.com
83514184Sgabeblack@google.com  transition(NP, L1_GET_INSTR, IS) {
83614184Sgabeblack@google.com    qq_allocateL2CacheBlock;
83714184Sgabeblack@google.com    ll_clearSharers;
83814184Sgabeblack@google.com    nn_addSharer;
83914184Sgabeblack@google.com    i_allocateTBE;
84014184Sgabeblack@google.com    ss_recordGetSL1ID;
84114184Sgabeblack@google.com    a_issueFetchToMemory;
84214184Sgabeblack@google.com    uu_profileMiss;
84314184Sgabeblack@google.com    jj_popL1RequestQueue;
84414184Sgabeblack@google.com  }
84514184Sgabeblack@google.com
84614184Sgabeblack@google.com  transition(NP, L1_GETX, IM) {
84714184Sgabeblack@google.com    qq_allocateL2CacheBlock;
84814184Sgabeblack@google.com    ll_clearSharers;
84914184Sgabeblack@google.com    // nn_addSharer;
85014184Sgabeblack@google.com    i_allocateTBE;
85114184Sgabeblack@google.com    xx_recordGetXL1ID;
85214184Sgabeblack@google.com    a_issueFetchToMemory;
85314184Sgabeblack@google.com    uu_profileMiss;
85414184Sgabeblack@google.com    jj_popL1RequestQueue;
85514184Sgabeblack@google.com  }
85614184Sgabeblack@google.com
85714184Sgabeblack@google.com
85814184Sgabeblack@google.com  // transitions from IS/IM
85914184Sgabeblack@google.com
86014184Sgabeblack@google.com  transition(ISS, Mem_Data, MT_MB) {
86114184Sgabeblack@google.com    m_writeDataToCache;
86214184Sgabeblack@google.com    ex_sendExclusiveDataToGetSRequestors;
86314184Sgabeblack@google.com    s_deallocateTBE;
86414184Sgabeblack@google.com    o_popIncomingResponseQueue;
86514184Sgabeblack@google.com  }
86614184Sgabeblack@google.com
86714184Sgabeblack@google.com  transition(IS, Mem_Data, SS) {
86814184Sgabeblack@google.com    m_writeDataToCache;
86914184Sgabeblack@google.com    e_sendDataToGetSRequestors;
87014184Sgabeblack@google.com    s_deallocateTBE;
87114184Sgabeblack@google.com    o_popIncomingResponseQueue;
87214184Sgabeblack@google.com    kd_wakeUpDependents;
87314184Sgabeblack@google.com  }
87414184Sgabeblack@google.com
87514184Sgabeblack@google.com  transition(IM, Mem_Data, MT_MB) {
87614184Sgabeblack@google.com    m_writeDataToCache;
87714184Sgabeblack@google.com    ee_sendDataToGetXRequestor;
87814184Sgabeblack@google.com    s_deallocateTBE;
87914184Sgabeblack@google.com    o_popIncomingResponseQueue;
88014184Sgabeblack@google.com  }
88114184Sgabeblack@google.com
88214184Sgabeblack@google.com  transition({IS, ISS}, {L1_GETS, L1_GET_INSTR}, IS) {
88314184Sgabeblack@google.com    nn_addSharer;
88414184Sgabeblack@google.com    ss_recordGetSL1ID;
88514184Sgabeblack@google.com    uu_profileMiss;
88614184Sgabeblack@google.com    jj_popL1RequestQueue;
88714184Sgabeblack@google.com  }
88814184Sgabeblack@google.com
88914184Sgabeblack@google.com  transition({IS, ISS}, L1_GETX) {
89014184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
89114184Sgabeblack@google.com  }
89214184Sgabeblack@google.com
89314184Sgabeblack@google.com  transition(IM, {L1_GETX, L1_GETS, L1_GET_INSTR}) {
89414184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
89514184Sgabeblack@google.com  }
89614184Sgabeblack@google.com
89714184Sgabeblack@google.com  // transitions from SS
89814184Sgabeblack@google.com  transition(SS, {L1_GETS, L1_GET_INSTR}) {
89914184Sgabeblack@google.com    ds_sendSharedDataToRequestor;
90014184Sgabeblack@google.com    nn_addSharer;
90114184Sgabeblack@google.com    set_setMRU;
90214184Sgabeblack@google.com    uu_profileHit;
90314184Sgabeblack@google.com    jj_popL1RequestQueue;
90414184Sgabeblack@google.com  }
90514184Sgabeblack@google.com
90614184Sgabeblack@google.com
90714184Sgabeblack@google.com  transition(SS, L1_GETX, SS_MB) {
90814184Sgabeblack@google.com    d_sendDataToRequestor;
90914184Sgabeblack@google.com    // fw_sendFwdInvToSharers;
91014184Sgabeblack@google.com    fwm_sendFwdInvToSharersMinusRequestor;
91114184Sgabeblack@google.com    set_setMRU;
91214184Sgabeblack@google.com    uu_profileHit;
91314184Sgabeblack@google.com    jj_popL1RequestQueue;
91414184Sgabeblack@google.com  }
91514184Sgabeblack@google.com
91614184Sgabeblack@google.com  transition(SS, L1_UPGRADE, SS_MB) {
91714184Sgabeblack@google.com    fwm_sendFwdInvToSharersMinusRequestor;
91814184Sgabeblack@google.com    ts_sendInvAckToUpgrader;
91914184Sgabeblack@google.com    set_setMRU;
92014184Sgabeblack@google.com    uu_profileHit;
92114184Sgabeblack@google.com    jj_popL1RequestQueue;
92214184Sgabeblack@google.com  }
92314184Sgabeblack@google.com
92414184Sgabeblack@google.com  transition(SS, L2_Replacement_clean, I_I) {
92514184Sgabeblack@google.com    i_allocateTBE;
92614184Sgabeblack@google.com    f_sendInvToSharers;
92714184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
92814184Sgabeblack@google.com  }
92914184Sgabeblack@google.com
93014184Sgabeblack@google.com  transition(SS, {L2_Replacement, MEM_Inv}, S_I) {
93114184Sgabeblack@google.com    i_allocateTBE;
93214184Sgabeblack@google.com    f_sendInvToSharers;
93314184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
93414184Sgabeblack@google.com  }
93514184Sgabeblack@google.com
93614184Sgabeblack@google.com
93714184Sgabeblack@google.com  transition(M, L1_GETX, MT_MB) {
93814184Sgabeblack@google.com    d_sendDataToRequestor;
93914184Sgabeblack@google.com    set_setMRU;
94014184Sgabeblack@google.com    uu_profileHit;
94114184Sgabeblack@google.com    jj_popL1RequestQueue;
94214184Sgabeblack@google.com  }
94314184Sgabeblack@google.com
94414184Sgabeblack@google.com  transition(M, L1_GET_INSTR, SS) {
94514184Sgabeblack@google.com    d_sendDataToRequestor;
94614184Sgabeblack@google.com    nn_addSharer;
94714184Sgabeblack@google.com    set_setMRU;
94814184Sgabeblack@google.com    uu_profileHit;
94914184Sgabeblack@google.com    jj_popL1RequestQueue;
95014184Sgabeblack@google.com  }
95114184Sgabeblack@google.com
95214184Sgabeblack@google.com  transition(M, L1_GETS, MT_MB) {
95314184Sgabeblack@google.com    dd_sendExclusiveDataToRequestor;
95414184Sgabeblack@google.com    set_setMRU;
95514184Sgabeblack@google.com    uu_profileHit;
95614184Sgabeblack@google.com    jj_popL1RequestQueue;
95714184Sgabeblack@google.com  }
95814184Sgabeblack@google.com
95914184Sgabeblack@google.com  transition(M, {L2_Replacement, MEM_Inv}, M_I) {
96014184Sgabeblack@google.com    i_allocateTBE;
96114184Sgabeblack@google.com    c_exclusiveReplacement;
96214184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
96314184Sgabeblack@google.com  }
96414184Sgabeblack@google.com
96514184Sgabeblack@google.com  transition(M, L2_Replacement_clean, M_I) {
96614184Sgabeblack@google.com    i_allocateTBE;
96714184Sgabeblack@google.com    c_exclusiveCleanReplacement;
96814184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
96914184Sgabeblack@google.com  }
97014184Sgabeblack@google.com
97114184Sgabeblack@google.com
97214184Sgabeblack@google.com  // transitions from MT
97314184Sgabeblack@google.com
97414184Sgabeblack@google.com  transition(MT, L1_GETX, MT_MB) {
97514184Sgabeblack@google.com    b_forwardRequestToExclusive;
97614184Sgabeblack@google.com    uu_profileMiss;
97714184Sgabeblack@google.com    set_setMRU;
97814184Sgabeblack@google.com    jj_popL1RequestQueue;
97914184Sgabeblack@google.com  }
98014184Sgabeblack@google.com
98114184Sgabeblack@google.com
98214184Sgabeblack@google.com  transition(MT, {L1_GETS, L1_GET_INSTR}, MT_IIB) {
98314184Sgabeblack@google.com    b_forwardRequestToExclusive;
98414184Sgabeblack@google.com    uu_profileMiss;
98514184Sgabeblack@google.com    set_setMRU;
98614184Sgabeblack@google.com    jj_popL1RequestQueue;
98714184Sgabeblack@google.com  }
98814184Sgabeblack@google.com
98914184Sgabeblack@google.com  transition(MT, {L2_Replacement, MEM_Inv}, MT_I) {
99014184Sgabeblack@google.com    i_allocateTBE;
99114184Sgabeblack@google.com    f_sendInvToSharers;
99214184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
99314184Sgabeblack@google.com  }
99414184Sgabeblack@google.com
99514184Sgabeblack@google.com  transition(MT, L2_Replacement_clean, MCT_I) {
99614184Sgabeblack@google.com    i_allocateTBE;
99714184Sgabeblack@google.com    f_sendInvToSharers;
99814184Sgabeblack@google.com    rr_deallocateL2CacheBlock;
99914184Sgabeblack@google.com  }
100014184Sgabeblack@google.com
100114184Sgabeblack@google.com  transition(MT, L1_PUTX, M) {
100214184Sgabeblack@google.com    ll_clearSharers;
100314184Sgabeblack@google.com    mr_writeDataToCacheFromRequest;
100414184Sgabeblack@google.com    t_sendWBAck;
100514184Sgabeblack@google.com    jj_popL1RequestQueue;
100614184Sgabeblack@google.com  }
100714184Sgabeblack@google.com
100814184Sgabeblack@google.com  transition({SS_MB,MT_MB}, Exclusive_Unblock, MT) {
100914184Sgabeblack@google.com    // update actual directory
101014184Sgabeblack@google.com    mmu_markExclusiveFromUnblock;
101114184Sgabeblack@google.com    k_popUnblockQueue;
101214184Sgabeblack@google.com    kd_wakeUpDependents;
101314184Sgabeblack@google.com  }
101414184Sgabeblack@google.com
101514184Sgabeblack@google.com  transition(MT_IIB, {L1_PUTX, L1_PUTX_old}){
101614184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
101714184Sgabeblack@google.com  }
101814184Sgabeblack@google.com
101914184Sgabeblack@google.com  transition(MT_IIB, Unblock, MT_IB) {
102014184Sgabeblack@google.com    nnu_addSharerFromUnblock;
102114184Sgabeblack@google.com    k_popUnblockQueue;
102214184Sgabeblack@google.com  }
102314184Sgabeblack@google.com
102414184Sgabeblack@google.com  transition(MT_IIB, {WB_Data, WB_Data_clean}, MT_SB) {
102514184Sgabeblack@google.com    m_writeDataToCache;
102614184Sgabeblack@google.com    o_popIncomingResponseQueue;
102714184Sgabeblack@google.com  }
102814184Sgabeblack@google.com
102914184Sgabeblack@google.com  transition(MT_IB, {WB_Data, WB_Data_clean}, SS) {
103014184Sgabeblack@google.com    m_writeDataToCache;
103114184Sgabeblack@google.com    o_popIncomingResponseQueue;
103214184Sgabeblack@google.com    kd_wakeUpDependents;
103314184Sgabeblack@google.com  }
103414184Sgabeblack@google.com
103514184Sgabeblack@google.com  transition(MT_SB, Unblock, SS) {
103614184Sgabeblack@google.com    nnu_addSharerFromUnblock;
103714184Sgabeblack@google.com    k_popUnblockQueue;
103814184Sgabeblack@google.com    kd_wakeUpDependents;
103914184Sgabeblack@google.com  }
104014184Sgabeblack@google.com
104114184Sgabeblack@google.com  // writeback states
104214184Sgabeblack@google.com  transition({I_I, S_I, MT_I, MCT_I, M_I}, {L1_GETX, L1_UPGRADE, L1_GETS, L1_GET_INSTR}) {
104314184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
104414184Sgabeblack@google.com  }
104514184Sgabeblack@google.com
104614184Sgabeblack@google.com  transition(I_I, Ack) {
104714184Sgabeblack@google.com    q_updateAck;
104814184Sgabeblack@google.com    o_popIncomingResponseQueue;
104914184Sgabeblack@google.com  }
105014184Sgabeblack@google.com
105114184Sgabeblack@google.com  transition(I_I, Ack_all, M_I) {
105214184Sgabeblack@google.com    c_exclusiveCleanReplacement;
105314184Sgabeblack@google.com    o_popIncomingResponseQueue;
105414184Sgabeblack@google.com  }
105514184Sgabeblack@google.com
105614184Sgabeblack@google.com  transition({MT_I, MCT_I}, WB_Data, M_I) {
105714184Sgabeblack@google.com    qq_writeDataToTBE;
105814184Sgabeblack@google.com    ct_exclusiveReplacementFromTBE;
105914184Sgabeblack@google.com    o_popIncomingResponseQueue;
106014184Sgabeblack@google.com  }
106114184Sgabeblack@google.com
106214184Sgabeblack@google.com  transition(MCT_I, {WB_Data_clean, Ack_all}, M_I) {
106314184Sgabeblack@google.com    c_exclusiveCleanReplacement;
106414184Sgabeblack@google.com    o_popIncomingResponseQueue;
106514184Sgabeblack@google.com  }
106614184Sgabeblack@google.com
106714184Sgabeblack@google.com  transition(MCT_I,  {L1_PUTX, L1_PUTX_old}){
106814184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
106914184Sgabeblack@google.com  }
107014184Sgabeblack@google.com
107114184Sgabeblack@google.com  // L1 never changed Dirty data
107214184Sgabeblack@google.com  transition(MT_I, {WB_Data_clean, Ack_all}, M_I) {
107314184Sgabeblack@google.com    ct_exclusiveReplacementFromTBE;
107414184Sgabeblack@google.com    o_popIncomingResponseQueue;
107514184Sgabeblack@google.com  }
107614184Sgabeblack@google.com
107714184Sgabeblack@google.com  transition(MT_I, {L1_PUTX, L1_PUTX_old}){
107814184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
107914184Sgabeblack@google.com  }
108014184Sgabeblack@google.com
108114184Sgabeblack@google.com  // possible race between unblock and immediate replacement
108214184Sgabeblack@google.com  transition({MT_MB,SS_MB}, {L1_PUTX, L1_PUTX_old}) {
108314184Sgabeblack@google.com    zz_stallAndWaitL1RequestQueue;
108414184Sgabeblack@google.com  }
108514184Sgabeblack@google.com
108614184Sgabeblack@google.com  transition(S_I, Ack) {
108714184Sgabeblack@google.com    q_updateAck;
108814184Sgabeblack@google.com    o_popIncomingResponseQueue;
108914184Sgabeblack@google.com  }
109014184Sgabeblack@google.com
109114184Sgabeblack@google.com  transition(S_I, Ack_all, M_I) {
109214184Sgabeblack@google.com    ct_exclusiveReplacementFromTBE;
109314184Sgabeblack@google.com    o_popIncomingResponseQueue;
109414184Sgabeblack@google.com  }
109514184Sgabeblack@google.com
109614184Sgabeblack@google.com  transition(M_I, Mem_Ack, NP) {
109714184Sgabeblack@google.com    s_deallocateTBE;
109814184Sgabeblack@google.com    o_popIncomingResponseQueue;
109914184Sgabeblack@google.com    kd_wakeUpDependents;
110014184Sgabeblack@google.com  }
110114184Sgabeblack@google.com}
1102