114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 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:L0Cache, "MESI Directory L0 Cache")
3014184Sgabeblack@google.com : Sequencer * sequencer;
3114184Sgabeblack@google.com   CacheMemory * Icache;
3214184Sgabeblack@google.com   CacheMemory * Dcache;
3314184Sgabeblack@google.com   Cycles request_latency := 2;
3414184Sgabeblack@google.com   Cycles response_latency := 2;
3514184Sgabeblack@google.com   bool send_evictions;
3614184Sgabeblack@google.com
3714184Sgabeblack@google.com   // From this node's L0 cache to the network
3814184Sgabeblack@google.com   MessageBuffer * bufferToL1, network="To";
3914184Sgabeblack@google.com
4014184Sgabeblack@google.com   // To this node's L0 cache FROM the network
4114184Sgabeblack@google.com   MessageBuffer * bufferFromL1, network="From";
4214184Sgabeblack@google.com
4314184Sgabeblack@google.com   // Message queue between this controller and the processor
4414184Sgabeblack@google.com   MessageBuffer * mandatoryQueue;
4514184Sgabeblack@google.com{
4614184Sgabeblack@google.com  // STATES
4714184Sgabeblack@google.com  state_declaration(State, desc="Cache states", default="L0Cache_State_I") {
4814184Sgabeblack@google.com    // Base states
4914184Sgabeblack@google.com
5014184Sgabeblack@google.com    // The cache entry has not been allocated.
5114184Sgabeblack@google.com    I, AccessPermission:Invalid;
5214184Sgabeblack@google.com
5314184Sgabeblack@google.com    // The cache entry is in shared mode. The processor can read this entry
5414184Sgabeblack@google.com    // but it cannot write to it.
5514184Sgabeblack@google.com    S, AccessPermission:Read_Only;
5614184Sgabeblack@google.com
5714184Sgabeblack@google.com    // The cache entry is in exclusive mode. The processor can read this
5814184Sgabeblack@google.com    // entry. It can write to this entry without informing the directory.
5914184Sgabeblack@google.com    // On writing, the entry moves to M state.
6014184Sgabeblack@google.com    E, AccessPermission:Read_Only;
6114184Sgabeblack@google.com
6214184Sgabeblack@google.com    // The processor has read and write permissions on this entry.
6314184Sgabeblack@google.com    M, AccessPermission:Read_Write;
6414184Sgabeblack@google.com
6514184Sgabeblack@google.com    // Transient States
6614184Sgabeblack@google.com
6714184Sgabeblack@google.com    // The cache controller has requested an instruction.  It will be stored
6814184Sgabeblack@google.com    // in the shared state so that the processor can read it.
6914184Sgabeblack@google.com    Inst_IS, AccessPermission:Busy;
7014184Sgabeblack@google.com
7114184Sgabeblack@google.com    // The cache controller has requested that this entry be fetched in
7214184Sgabeblack@google.com    // shared state so that the processor can read it.
7314184Sgabeblack@google.com    IS, AccessPermission:Busy;
7414184Sgabeblack@google.com
7514184Sgabeblack@google.com    // The cache controller has requested that this entry be fetched in
7614184Sgabeblack@google.com    // modify state so that the processor can read/write it.
7714184Sgabeblack@google.com    IM, AccessPermission:Busy;
7814184Sgabeblack@google.com
7914184Sgabeblack@google.com    // The cache controller had read permission over the entry. But now the
8014184Sgabeblack@google.com    // processor needs to write to it. So, the controller has requested for
8114184Sgabeblack@google.com    // write permission.
8214184Sgabeblack@google.com    SM, AccessPermission:Read_Only;
8314184Sgabeblack@google.com  }
8414184Sgabeblack@google.com
8514184Sgabeblack@google.com  // EVENTS
8614184Sgabeblack@google.com  enumeration(Event, desc="Cache events") {
8714184Sgabeblack@google.com    // L0 events
8814184Sgabeblack@google.com    Load,            desc="Load request from the home processor";
8914184Sgabeblack@google.com    Ifetch,          desc="I-fetch request from the home processor";
9014184Sgabeblack@google.com    Store,           desc="Store request from the home processor";
9114184Sgabeblack@google.com
9214184Sgabeblack@google.com    Inv,           desc="Invalidate request from L2 bank";
9314184Sgabeblack@google.com
9414184Sgabeblack@google.com    // internal generated request
9514184Sgabeblack@google.com    L0_Replacement,  desc="L0 Replacement", format="!r";
9614184Sgabeblack@google.com
9714184Sgabeblack@google.com    // other requests
9814184Sgabeblack@google.com    Fwd_GETX,   desc="GETX from other processor";
9914184Sgabeblack@google.com    Fwd_GETS,   desc="GETS from other processor";
10014184Sgabeblack@google.com    Fwd_GET_INSTR,   desc="GET_INSTR from other processor";
10114184Sgabeblack@google.com
10214184Sgabeblack@google.com    Data,               desc="Data for processor";
10314184Sgabeblack@google.com    Data_Exclusive,     desc="Data for processor";
10414184Sgabeblack@google.com    Data_Stale,         desc="Data for processor, but not for storage";
10514184Sgabeblack@google.com
10614184Sgabeblack@google.com    Ack,        desc="Ack for processor";
10714184Sgabeblack@google.com    Ack_all,      desc="Last ack for processor";
10814184Sgabeblack@google.com
10914184Sgabeblack@google.com    WB_Ack,        desc="Ack for replacement";
11014184Sgabeblack@google.com  }
11114184Sgabeblack@google.com
11214184Sgabeblack@google.com  // TYPES
11314184Sgabeblack@google.com
11414184Sgabeblack@google.com  // CacheEntry
11514184Sgabeblack@google.com  structure(Entry, desc="...", interface="AbstractCacheEntry" ) {
11614184Sgabeblack@google.com    State CacheState,        desc="cache state";
11714184Sgabeblack@google.com    DataBlock DataBlk,       desc="data for the block";
11814184Sgabeblack@google.com    bool Dirty, default="false",   desc="data is dirty";
11914184Sgabeblack@google.com  }
12014184Sgabeblack@google.com
12114184Sgabeblack@google.com  // TBE fields
12214184Sgabeblack@google.com  structure(TBE, desc="...") {
12314184Sgabeblack@google.com    Addr addr,              desc="Physical address for this TBE";
12414184Sgabeblack@google.com    State TBEState,        desc="Transient state";
12514184Sgabeblack@google.com    DataBlock DataBlk,                desc="Buffer for the data block";
12614184Sgabeblack@google.com    bool Dirty, default="false",   desc="data is dirty";
12714184Sgabeblack@google.com    int pendingAcks, default="0", desc="number of pending acks";
12814184Sgabeblack@google.com  }
12914184Sgabeblack@google.com
13014184Sgabeblack@google.com  structure(TBETable, external="yes") {
13114184Sgabeblack@google.com    TBE lookup(Addr);
13214184Sgabeblack@google.com    void allocate(Addr);
13314184Sgabeblack@google.com    void deallocate(Addr);
13414184Sgabeblack@google.com    bool isPresent(Addr);
13514184Sgabeblack@google.com  }
13614184Sgabeblack@google.com
13714184Sgabeblack@google.com  TBETable TBEs, template="<L0Cache_TBE>", constructor="m_number_of_TBEs";
13814184Sgabeblack@google.com
13914184Sgabeblack@google.com  Tick clockEdge();
14014184Sgabeblack@google.com  Cycles ticksToCycles(Tick t);
14114184Sgabeblack@google.com  void set_cache_entry(AbstractCacheEntry a);
14214184Sgabeblack@google.com  void unset_cache_entry();
14314184Sgabeblack@google.com  void set_tbe(TBE a);
14414184Sgabeblack@google.com  void unset_tbe();
14514184Sgabeblack@google.com  void wakeUpBuffers(Addr a);
14614184Sgabeblack@google.com  void wakeUpAllBuffers(Addr a);
14714184Sgabeblack@google.com  void profileMsgDelay(int virtualNetworkType, Cycles c);
14814184Sgabeblack@google.com
14914184Sgabeblack@google.com  // inclusive cache returns L0 entries only
15014184Sgabeblack@google.com  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
15114184Sgabeblack@google.com    Entry Dcache_entry := static_cast(Entry, "pointer", Dcache[addr]);
15214184Sgabeblack@google.com    if(is_valid(Dcache_entry)) {
15314184Sgabeblack@google.com      return Dcache_entry;
15414184Sgabeblack@google.com    }
15514184Sgabeblack@google.com
15614184Sgabeblack@google.com    Entry Icache_entry := static_cast(Entry, "pointer", Icache[addr]);
15714184Sgabeblack@google.com    return Icache_entry;
15814184Sgabeblack@google.com  }
15914184Sgabeblack@google.com
16014184Sgabeblack@google.com  Entry getDCacheEntry(Addr addr), return_by_pointer="yes" {
16114184Sgabeblack@google.com    Entry Dcache_entry := static_cast(Entry, "pointer", Dcache[addr]);
16214184Sgabeblack@google.com    return Dcache_entry;
16314184Sgabeblack@google.com  }
16414184Sgabeblack@google.com
16514184Sgabeblack@google.com  Entry getICacheEntry(Addr addr), return_by_pointer="yes" {
16614184Sgabeblack@google.com    Entry Icache_entry := static_cast(Entry, "pointer", Icache[addr]);
16714184Sgabeblack@google.com    return Icache_entry;
16814184Sgabeblack@google.com  }
16914184Sgabeblack@google.com
17014184Sgabeblack@google.com  State getState(TBE tbe, Entry cache_entry, Addr addr) {
17114184Sgabeblack@google.com    assert((Dcache.isTagPresent(addr) && Icache.isTagPresent(addr)) == false);
17214184Sgabeblack@google.com
17314184Sgabeblack@google.com    if(is_valid(tbe)) {
17414184Sgabeblack@google.com      return tbe.TBEState;
17514184Sgabeblack@google.com    } else if (is_valid(cache_entry)) {
17614184Sgabeblack@google.com      return cache_entry.CacheState;
17714184Sgabeblack@google.com    }
17814184Sgabeblack@google.com    return State:I;
17914184Sgabeblack@google.com  }
18014184Sgabeblack@google.com
18114184Sgabeblack@google.com  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
18214184Sgabeblack@google.com    assert((Dcache.isTagPresent(addr) && Icache.isTagPresent(addr)) == false);
18314184Sgabeblack@google.com
18414184Sgabeblack@google.com    // MUST CHANGE
18514184Sgabeblack@google.com    if(is_valid(tbe)) {
18614184Sgabeblack@google.com      tbe.TBEState := state;
18714184Sgabeblack@google.com    }
18814184Sgabeblack@google.com
18914184Sgabeblack@google.com    if (is_valid(cache_entry)) {
19014184Sgabeblack@google.com      cache_entry.CacheState := state;
19114184Sgabeblack@google.com    }
19214184Sgabeblack@google.com  }
19314184Sgabeblack@google.com
19414184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
19514184Sgabeblack@google.com    TBE tbe := TBEs[addr];
19614184Sgabeblack@google.com    if(is_valid(tbe)) {
19714184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L0Cache_State_to_permission(tbe.TBEState));
19814184Sgabeblack@google.com      return L0Cache_State_to_permission(tbe.TBEState);
19914184Sgabeblack@google.com    }
20014184Sgabeblack@google.com
20114184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
20214184Sgabeblack@google.com    if(is_valid(cache_entry)) {
20314184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L0Cache_State_to_permission(cache_entry.CacheState));
20414184Sgabeblack@google.com      return L0Cache_State_to_permission(cache_entry.CacheState);
20514184Sgabeblack@google.com    }
20614184Sgabeblack@google.com
20714184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent);
20814184Sgabeblack@google.com    return AccessPermission:NotPresent;
20914184Sgabeblack@google.com  }
21014184Sgabeblack@google.com
21114184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
21214184Sgabeblack@google.com    TBE tbe := TBEs[addr];
21314184Sgabeblack@google.com    if(is_valid(tbe)) {
21414184Sgabeblack@google.com      testAndRead(addr, tbe.DataBlk, pkt);
21514184Sgabeblack@google.com    } else {
21614184Sgabeblack@google.com      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
21714184Sgabeblack@google.com    }
21814184Sgabeblack@google.com  }
21914184Sgabeblack@google.com
22014184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
22114184Sgabeblack@google.com    int num_functional_writes := 0;
22214184Sgabeblack@google.com
22314184Sgabeblack@google.com    TBE tbe := TBEs[addr];
22414184Sgabeblack@google.com    if(is_valid(tbe)) {
22514184Sgabeblack@google.com      num_functional_writes := num_functional_writes +
22614184Sgabeblack@google.com        testAndWrite(addr, tbe.DataBlk, pkt);
22714184Sgabeblack@google.com      return num_functional_writes;
22814184Sgabeblack@google.com    }
22914184Sgabeblack@google.com
23014184Sgabeblack@google.com    num_functional_writes := num_functional_writes +
23114184Sgabeblack@google.com        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
23214184Sgabeblack@google.com    return num_functional_writes;
23314184Sgabeblack@google.com  }
23414184Sgabeblack@google.com
23514184Sgabeblack@google.com  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
23614184Sgabeblack@google.com    if (is_valid(cache_entry)) {
23714184Sgabeblack@google.com      cache_entry.changePermission(L0Cache_State_to_permission(state));
23814184Sgabeblack@google.com    }
23914184Sgabeblack@google.com  }
24014184Sgabeblack@google.com
24114184Sgabeblack@google.com  Event mandatory_request_type_to_event(RubyRequestType type) {
24214184Sgabeblack@google.com    if (type == RubyRequestType:LD) {
24314184Sgabeblack@google.com      return Event:Load;
24414184Sgabeblack@google.com    } else if (type == RubyRequestType:IFETCH) {
24514184Sgabeblack@google.com      return Event:Ifetch;
24614184Sgabeblack@google.com    } else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC)) {
24714184Sgabeblack@google.com      return Event:Store;
24814184Sgabeblack@google.com    } else {
24914184Sgabeblack@google.com      error("Invalid RubyRequestType");
25014184Sgabeblack@google.com    }
25114184Sgabeblack@google.com  }
25214184Sgabeblack@google.com
25314184Sgabeblack@google.com  int getPendingAcks(TBE tbe) {
25414184Sgabeblack@google.com    return tbe.pendingAcks;
25514184Sgabeblack@google.com  }
25614184Sgabeblack@google.com
25714184Sgabeblack@google.com  out_port(requestNetwork_out, CoherenceMsg, bufferToL1);
25814184Sgabeblack@google.com
25914184Sgabeblack@google.com  // Messages for this L0 cache from the L1 cache
26014184Sgabeblack@google.com  in_port(messgeBuffer_in, CoherenceMsg, bufferFromL1, rank = 1) {
26114184Sgabeblack@google.com    if (messgeBuffer_in.isReady(clockEdge())) {
26214184Sgabeblack@google.com      peek(messgeBuffer_in, CoherenceMsg, block_on="addr") {
26314184Sgabeblack@google.com        assert(in_msg.Dest == machineID);
26414184Sgabeblack@google.com
26514184Sgabeblack@google.com        Entry cache_entry := getCacheEntry(in_msg.addr);
26614184Sgabeblack@google.com        TBE tbe := TBEs[in_msg.addr];
26714184Sgabeblack@google.com
26814184Sgabeblack@google.com        if(in_msg.Class == CoherenceClass:DATA_EXCLUSIVE) {
26914184Sgabeblack@google.com            trigger(Event:Data_Exclusive, in_msg.addr, cache_entry, tbe);
27014184Sgabeblack@google.com        } else if(in_msg.Class == CoherenceClass:DATA) {
27114184Sgabeblack@google.com            trigger(Event:Data, in_msg.addr, cache_entry, tbe);
27214184Sgabeblack@google.com        } else if(in_msg.Class == CoherenceClass:STALE_DATA) {
27314184Sgabeblack@google.com            trigger(Event:Data_Stale, in_msg.addr, cache_entry, tbe);
27414184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:ACK) {
27514184Sgabeblack@google.com            trigger(Event:Ack, in_msg.addr, cache_entry, tbe);
27614184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:WB_ACK) {
27714184Sgabeblack@google.com            trigger(Event:WB_Ack, in_msg.addr, cache_entry, tbe);
27814184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:INV) {
27914184Sgabeblack@google.com          trigger(Event:Inv, in_msg.addr, cache_entry, tbe);
28014184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:GETX ||
28114184Sgabeblack@google.com                   in_msg.Class == CoherenceClass:UPGRADE) {
28214184Sgabeblack@google.com          // upgrade transforms to GETX due to race
28314184Sgabeblack@google.com          trigger(Event:Fwd_GETX, in_msg.addr, cache_entry, tbe);
28414184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:GETS) {
28514184Sgabeblack@google.com          trigger(Event:Fwd_GETS, in_msg.addr, cache_entry, tbe);
28614184Sgabeblack@google.com        } else if (in_msg.Class == CoherenceClass:GET_INSTR) {
28714184Sgabeblack@google.com          trigger(Event:Fwd_GET_INSTR, in_msg.addr, cache_entry, tbe);
28814184Sgabeblack@google.com        } else {
28914184Sgabeblack@google.com          error("Invalid forwarded request type");
29014184Sgabeblack@google.com        }
29114184Sgabeblack@google.com      }
29214184Sgabeblack@google.com    }
29314184Sgabeblack@google.com  }
29414184Sgabeblack@google.com
29514184Sgabeblack@google.com  // Mandatory Queue betweens Node's CPU and it's L0 caches
29614184Sgabeblack@google.com  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, desc="...", rank = 0) {
29714184Sgabeblack@google.com    if (mandatoryQueue_in.isReady(clockEdge())) {
29814184Sgabeblack@google.com      peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
29914184Sgabeblack@google.com
30014184Sgabeblack@google.com        // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache
30114184Sgabeblack@google.com
30214184Sgabeblack@google.com        if (in_msg.Type == RubyRequestType:IFETCH) {
30314184Sgabeblack@google.com          // ** INSTRUCTION ACCESS ***
30414184Sgabeblack@google.com
30514184Sgabeblack@google.com          Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
30614184Sgabeblack@google.com          if (is_valid(Icache_entry)) {
30714184Sgabeblack@google.com            // The tag matches for the L0, so the L0 asks the L2 for it.
30814184Sgabeblack@google.com            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
30914184Sgabeblack@google.com                    Icache_entry, TBEs[in_msg.LineAddress]);
31014184Sgabeblack@google.com          } else {
31114184Sgabeblack@google.com
31214184Sgabeblack@google.com            // Check to see if it is in the OTHER L0
31314184Sgabeblack@google.com            Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);
31414184Sgabeblack@google.com            if (is_valid(Dcache_entry)) {
31514184Sgabeblack@google.com              // The block is in the wrong L0, put the request on the queue to the shared L2
31614184Sgabeblack@google.com              trigger(Event:L0_Replacement, in_msg.LineAddress,
31714184Sgabeblack@google.com                      Dcache_entry, TBEs[in_msg.LineAddress]);
31814184Sgabeblack@google.com            }
31914184Sgabeblack@google.com
32014184Sgabeblack@google.com            if (Icache.cacheAvail(in_msg.LineAddress)) {
32114184Sgabeblack@google.com              // L0 does't have the line, but we have space for it
32214184Sgabeblack@google.com              // in the L0 so let's see if the L2 has it
32314184Sgabeblack@google.com              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
32414184Sgabeblack@google.com                      Icache_entry, TBEs[in_msg.LineAddress]);
32514184Sgabeblack@google.com            } else {
32614184Sgabeblack@google.com              // No room in the L0, so we need to make room in the L0
32714184Sgabeblack@google.com              // Check if the line we want to evict is not locked
32814184Sgabeblack@google.com              Addr addr := Icache.cacheProbe(in_msg.LineAddress);
32914184Sgabeblack@google.com              check_on_cache_probe(mandatoryQueue_in, addr);
33014184Sgabeblack@google.com              trigger(Event:L0_Replacement, addr,
33114184Sgabeblack@google.com                      getICacheEntry(addr),
33214184Sgabeblack@google.com                      TBEs[addr]);
33314184Sgabeblack@google.com            }
33414184Sgabeblack@google.com          }
33514184Sgabeblack@google.com        } else {
33614184Sgabeblack@google.com
33714184Sgabeblack@google.com          // *** DATA ACCESS ***
33814184Sgabeblack@google.com          Entry Dcache_entry := getDCacheEntry(in_msg.LineAddress);
33914184Sgabeblack@google.com          if (is_valid(Dcache_entry)) {
34014184Sgabeblack@google.com            // The tag matches for the L0, so the L0 ask the L1 for it
34114184Sgabeblack@google.com            trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
34214184Sgabeblack@google.com                    Dcache_entry, TBEs[in_msg.LineAddress]);
34314184Sgabeblack@google.com          } else {
34414184Sgabeblack@google.com
34514184Sgabeblack@google.com            // Check to see if it is in the OTHER L0
34614184Sgabeblack@google.com            Entry Icache_entry := getICacheEntry(in_msg.LineAddress);
34714184Sgabeblack@google.com            if (is_valid(Icache_entry)) {
34814184Sgabeblack@google.com              // The block is in the wrong L0, put the request on the queue to the private L1
34914184Sgabeblack@google.com              trigger(Event:L0_Replacement, in_msg.LineAddress,
35014184Sgabeblack@google.com                      Icache_entry, TBEs[in_msg.LineAddress]);
35114184Sgabeblack@google.com            }
35214184Sgabeblack@google.com
35314184Sgabeblack@google.com            if (Dcache.cacheAvail(in_msg.LineAddress)) {
35414184Sgabeblack@google.com              // L1 does't have the line, but we have space for it
35514184Sgabeblack@google.com              // in the L0 let's see if the L1 has it
35614184Sgabeblack@google.com              trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress,
35714184Sgabeblack@google.com                      Dcache_entry, TBEs[in_msg.LineAddress]);
35814184Sgabeblack@google.com            } else {
35914184Sgabeblack@google.com              // No room in the L1, so we need to make room in the L0
36014184Sgabeblack@google.com              // Check if the line we want to evict is not locked
36114184Sgabeblack@google.com              Addr addr := Dcache.cacheProbe(in_msg.LineAddress);
36214184Sgabeblack@google.com              check_on_cache_probe(mandatoryQueue_in, addr);
36314184Sgabeblack@google.com              trigger(Event:L0_Replacement, addr,
36414184Sgabeblack@google.com                      getDCacheEntry(addr),
36514184Sgabeblack@google.com                      TBEs[addr]);
36614184Sgabeblack@google.com            }
36714184Sgabeblack@google.com          }
36814184Sgabeblack@google.com        }
36914184Sgabeblack@google.com      }
37014184Sgabeblack@google.com    }
37114184Sgabeblack@google.com  }
37214184Sgabeblack@google.com
37314184Sgabeblack@google.com  // ACTIONS
37414184Sgabeblack@google.com  action(a_issueGETS, "a", desc="Issue GETS") {
37514184Sgabeblack@google.com    peek(mandatoryQueue_in, RubyRequest) {
37614184Sgabeblack@google.com      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
37714184Sgabeblack@google.com        out_msg.addr := address;
37814184Sgabeblack@google.com        out_msg.Class := CoherenceClass:GETS;
37914184Sgabeblack@google.com        out_msg.Sender := machineID;
38014184Sgabeblack@google.com        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
38114184Sgabeblack@google.com        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
38214184Sgabeblack@google.com                address, out_msg.Dest);
38314184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Control;
38414184Sgabeblack@google.com        out_msg.AccessMode := in_msg.AccessMode;
38514184Sgabeblack@google.com      }
38614184Sgabeblack@google.com    }
38714184Sgabeblack@google.com  }
38814184Sgabeblack@google.com
38914184Sgabeblack@google.com  action(b_issueGETX, "b", desc="Issue GETX") {
39014184Sgabeblack@google.com    peek(mandatoryQueue_in, RubyRequest) {
39114184Sgabeblack@google.com      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
39214184Sgabeblack@google.com        out_msg.addr := address;
39314184Sgabeblack@google.com        out_msg.Class := CoherenceClass:GETX;
39414184Sgabeblack@google.com        out_msg.Sender := machineID;
39514184Sgabeblack@google.com        DPRINTF(RubySlicc, "%s\n", machineID);
39614184Sgabeblack@google.com        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
39714184Sgabeblack@google.com
39814184Sgabeblack@google.com        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
39914184Sgabeblack@google.com                address, out_msg.Dest);
40014184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Control;
40114184Sgabeblack@google.com        out_msg.AccessMode := in_msg.AccessMode;
40214184Sgabeblack@google.com      }
40314184Sgabeblack@google.com    }
40414184Sgabeblack@google.com  }
40514184Sgabeblack@google.com
40614184Sgabeblack@google.com  action(c_issueUPGRADE, "c", desc="Issue GETX") {
40714184Sgabeblack@google.com    peek(mandatoryQueue_in, RubyRequest) {
40814184Sgabeblack@google.com      enqueue(requestNetwork_out, CoherenceMsg, request_latency) {
40914184Sgabeblack@google.com        out_msg.addr := address;
41014184Sgabeblack@google.com        out_msg.Class := CoherenceClass:UPGRADE;
41114184Sgabeblack@google.com        out_msg.Sender := machineID;
41214184Sgabeblack@google.com        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
41314184Sgabeblack@google.com
41414184Sgabeblack@google.com        DPRINTF(RubySlicc, "address: %#x, destination: %s\n",
41514184Sgabeblack@google.com                address, out_msg.Dest);
41614184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Control;
41714184Sgabeblack@google.com        out_msg.AccessMode := in_msg.AccessMode;
41814184Sgabeblack@google.com      }
41914184Sgabeblack@google.com    }
42014184Sgabeblack@google.com  }
42114184Sgabeblack@google.com
42214184Sgabeblack@google.com  action(f_sendDataToL1, "f", desc="send data to the L2 cache") {
42314184Sgabeblack@google.com    enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
42414184Sgabeblack@google.com      assert(is_valid(cache_entry));
42514184Sgabeblack@google.com      out_msg.addr := address;
42614184Sgabeblack@google.com      out_msg.Class := CoherenceClass:INV_DATA;
42714184Sgabeblack@google.com      out_msg.DataBlk := cache_entry.DataBlk;
42814184Sgabeblack@google.com      out_msg.Dirty := cache_entry.Dirty;
42914184Sgabeblack@google.com      out_msg.Sender := machineID;
43014184Sgabeblack@google.com      out_msg.Dest := createMachineID(MachineType:L1Cache, version);
43114184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Data;
43214184Sgabeblack@google.com    }
43314184Sgabeblack@google.com    cache_entry.Dirty := false;
43414184Sgabeblack@google.com  }
43514184Sgabeblack@google.com
43614184Sgabeblack@google.com  action(fi_sendInvAck, "fi", desc="send data to the L2 cache") {
43714184Sgabeblack@google.com    peek(messgeBuffer_in, CoherenceMsg) {
43814184Sgabeblack@google.com      enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
43914184Sgabeblack@google.com        out_msg.addr := address;
44014184Sgabeblack@google.com        out_msg.Class := CoherenceClass:INV_ACK;
44114184Sgabeblack@google.com        out_msg.Sender := machineID;
44214184Sgabeblack@google.com        out_msg.Dest := createMachineID(MachineType:L1Cache, version);
44314184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
44414184Sgabeblack@google.com      }
44514184Sgabeblack@google.com    }
44614184Sgabeblack@google.com  }
44714184Sgabeblack@google.com
44814184Sgabeblack@google.com  action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
44914184Sgabeblack@google.com    if (send_evictions) {
45014184Sgabeblack@google.com      DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address);
45114184Sgabeblack@google.com      sequencer.evictionCallback(address);
45214184Sgabeblack@google.com    }
45314184Sgabeblack@google.com  }
45414184Sgabeblack@google.com
45514184Sgabeblack@google.com  action(g_issuePUTX, "g", desc="send data to the L2 cache") {
45614184Sgabeblack@google.com    enqueue(requestNetwork_out, CoherenceMsg, response_latency) {
45714184Sgabeblack@google.com      assert(is_valid(cache_entry));
45814184Sgabeblack@google.com      out_msg.addr := address;
45914184Sgabeblack@google.com      out_msg.Class := CoherenceClass:PUTX;
46014184Sgabeblack@google.com      out_msg.Dirty := cache_entry.Dirty;
46114184Sgabeblack@google.com      out_msg.Sender:= machineID;
46214184Sgabeblack@google.com      out_msg.Dest := createMachineID(MachineType:L1Cache, version);
46314184Sgabeblack@google.com
46414184Sgabeblack@google.com      if (cache_entry.Dirty) {
46514184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Writeback_Data;
46614184Sgabeblack@google.com        out_msg.DataBlk := cache_entry.DataBlk;
46714184Sgabeblack@google.com      } else {
46814184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Writeback_Control;
46914184Sgabeblack@google.com      }
47014184Sgabeblack@google.com    }
47114184Sgabeblack@google.com  }
47214184Sgabeblack@google.com
47314184Sgabeblack@google.com  action(h_load_hit, "hd", desc="If not prefetch, notify sequencer the load completed.") {
47414184Sgabeblack@google.com    assert(is_valid(cache_entry));
47514184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
47614184Sgabeblack@google.com    Dcache.setMRU(cache_entry);
47714184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk);
47814184Sgabeblack@google.com  }
47914184Sgabeblack@google.com
48014184Sgabeblack@google.com  action(h_ifetch_hit, "hi", desc="If not prefetch, notify sequencer the ifetch completed.") {
48114184Sgabeblack@google.com    assert(is_valid(cache_entry));
48214184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
48314184Sgabeblack@google.com    Icache.setMRU(cache_entry);
48414184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk);
48514184Sgabeblack@google.com  }
48614184Sgabeblack@google.com
48714184Sgabeblack@google.com  action(hx_load_hit, "hxd", desc="notify sequencer the load completed.") {
48814184Sgabeblack@google.com    assert(is_valid(cache_entry));
48914184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
49014184Sgabeblack@google.com    Dcache.setMRU(cache_entry);
49114184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk, true);
49214184Sgabeblack@google.com  }
49314184Sgabeblack@google.com
49414184Sgabeblack@google.com  action(hx_ifetch_hit, "hxi", desc="notify sequencer the ifetch completed.") {
49514184Sgabeblack@google.com    assert(is_valid(cache_entry));
49614184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
49714184Sgabeblack@google.com    Icache.setMRU(cache_entry);
49814184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk, true);
49914184Sgabeblack@google.com  }
50014184Sgabeblack@google.com
50114184Sgabeblack@google.com  action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") {
50214184Sgabeblack@google.com    assert(is_valid(cache_entry));
50314184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
50414184Sgabeblack@google.com    Dcache.setMRU(cache_entry);
50514184Sgabeblack@google.com    sequencer.writeCallback(address, cache_entry.DataBlk);
50614184Sgabeblack@google.com    cache_entry.Dirty := true;
50714184Sgabeblack@google.com  }
50814184Sgabeblack@google.com
50914184Sgabeblack@google.com  action(hhx_store_hit, "\hx", desc="If not prefetch, notify sequencer that store completed.") {
51014184Sgabeblack@google.com    assert(is_valid(cache_entry));
51114184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
51214184Sgabeblack@google.com    Dcache.setMRU(cache_entry);
51314184Sgabeblack@google.com    sequencer.writeCallback(address, cache_entry.DataBlk, true);
51414184Sgabeblack@google.com    cache_entry.Dirty := true;
51514184Sgabeblack@google.com  }
51614184Sgabeblack@google.com
51714184Sgabeblack@google.com  action(i_allocateTBE, "i", desc="Allocate TBE (number of invalidates=0)") {
51814184Sgabeblack@google.com    check_allocate(TBEs);
51914184Sgabeblack@google.com    assert(is_valid(cache_entry));
52014184Sgabeblack@google.com    TBEs.allocate(address);
52114184Sgabeblack@google.com    set_tbe(TBEs[address]);
52214184Sgabeblack@google.com    tbe.Dirty := cache_entry.Dirty;
52314184Sgabeblack@google.com    tbe.DataBlk := cache_entry.DataBlk;
52414184Sgabeblack@google.com  }
52514184Sgabeblack@google.com
52614184Sgabeblack@google.com  action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
52714184Sgabeblack@google.com    mandatoryQueue_in.dequeue(clockEdge());
52814184Sgabeblack@google.com  }
52914184Sgabeblack@google.com
53014184Sgabeblack@google.com  action(l_popRequestQueue, "l",
53114184Sgabeblack@google.com         desc="Pop incoming request queue and profile the delay within this virtual network") {
53214184Sgabeblack@google.com    Tick delay := messgeBuffer_in.dequeue(clockEdge());
53314184Sgabeblack@google.com    profileMsgDelay(2, ticksToCycles(delay));
53414184Sgabeblack@google.com  }
53514184Sgabeblack@google.com
53614184Sgabeblack@google.com  action(o_popIncomingResponseQueue, "o",
53714184Sgabeblack@google.com         desc="Pop Incoming Response queue and profile the delay within this virtual network") {
53814184Sgabeblack@google.com    Tick delay := messgeBuffer_in.dequeue(clockEdge());
53914184Sgabeblack@google.com    profileMsgDelay(1, ticksToCycles(delay));
54014184Sgabeblack@google.com  }
54114184Sgabeblack@google.com
54214184Sgabeblack@google.com  action(s_deallocateTBE, "s", desc="Deallocate TBE") {
54314184Sgabeblack@google.com    TBEs.deallocate(address);
54414184Sgabeblack@google.com    unset_tbe();
54514184Sgabeblack@google.com  }
54614184Sgabeblack@google.com
54714184Sgabeblack@google.com  action(u_writeDataToCache, "u", desc="Write data to cache") {
54814184Sgabeblack@google.com    peek(messgeBuffer_in, CoherenceMsg) {
54914184Sgabeblack@google.com      assert(is_valid(cache_entry));
55014184Sgabeblack@google.com      cache_entry.DataBlk := in_msg.DataBlk;
55114184Sgabeblack@google.com    }
55214184Sgabeblack@google.com  }
55314184Sgabeblack@google.com
55414184Sgabeblack@google.com  action(u_writeInstToCache, "ui", desc="Write data to cache") {
55514184Sgabeblack@google.com    peek(messgeBuffer_in, CoherenceMsg) {
55614184Sgabeblack@google.com      assert(is_valid(cache_entry));
55714184Sgabeblack@google.com      cache_entry.DataBlk := in_msg.DataBlk;
55814184Sgabeblack@google.com    }
55914184Sgabeblack@google.com  }
56014184Sgabeblack@google.com
56114184Sgabeblack@google.com  action(ff_deallocateCacheBlock, "\f",
56214184Sgabeblack@google.com         desc="Deallocate L1 cache block.") {
56314184Sgabeblack@google.com    if (Dcache.isTagPresent(address)) {
56414184Sgabeblack@google.com      Dcache.deallocate(address);
56514184Sgabeblack@google.com    } else {
56614184Sgabeblack@google.com      Icache.deallocate(address);
56714184Sgabeblack@google.com    }
56814184Sgabeblack@google.com    unset_cache_entry();
56914184Sgabeblack@google.com  }
57014184Sgabeblack@google.com
57114184Sgabeblack@google.com  action(oo_allocateDCacheBlock, "\o", desc="Set L1 D-cache tag equal to tag of block B.") {
57214184Sgabeblack@google.com    if (is_invalid(cache_entry)) {
57314184Sgabeblack@google.com      set_cache_entry(Dcache.allocate(address, new Entry));
57414184Sgabeblack@google.com    }
57514184Sgabeblack@google.com  }
57614184Sgabeblack@google.com
57714184Sgabeblack@google.com  action(pp_allocateICacheBlock, "\p", desc="Set L1 I-cache tag equal to tag of block B.") {
57814184Sgabeblack@google.com    if (is_invalid(cache_entry)) {
57914184Sgabeblack@google.com      set_cache_entry(Icache.allocate(address, new Entry));
58014184Sgabeblack@google.com    }
58114184Sgabeblack@google.com  }
58214184Sgabeblack@google.com
58314184Sgabeblack@google.com  action(z_stallAndWaitMandatoryQueue, "\z", desc="recycle cpu request queue") {
58414184Sgabeblack@google.com    stall_and_wait(mandatoryQueue_in, address);
58514184Sgabeblack@google.com  }
58614184Sgabeblack@google.com
58714184Sgabeblack@google.com  action(kd_wakeUpDependents, "kd", desc="wake-up dependents") {
58814184Sgabeblack@google.com    wakeUpAllBuffers(address);
58914184Sgabeblack@google.com  }
59014184Sgabeblack@google.com
59114184Sgabeblack@google.com  action(uu_profileInstMiss, "\ui", desc="Profile the demand miss") {
59214184Sgabeblack@google.com        ++Icache.demand_misses;
59314184Sgabeblack@google.com  }
59414184Sgabeblack@google.com
59514184Sgabeblack@google.com  action(uu_profileInstHit, "\uih", desc="Profile the demand miss") {
59614184Sgabeblack@google.com        ++Icache.demand_hits;
59714184Sgabeblack@google.com  }
59814184Sgabeblack@google.com
59914184Sgabeblack@google.com  action(uu_profileDataMiss, "\ud", desc="Profile the demand miss") {
60014184Sgabeblack@google.com        ++Dcache.demand_misses;
60114184Sgabeblack@google.com  }
60214184Sgabeblack@google.com
60314184Sgabeblack@google.com  action(uu_profileDataHit, "\udh", desc="Profile the demand miss") {
60414184Sgabeblack@google.com        ++Dcache.demand_hits;
60514184Sgabeblack@google.com  }
60614184Sgabeblack@google.com
60714184Sgabeblack@google.com  //*****************************************************
60814184Sgabeblack@google.com  // TRANSITIONS
60914184Sgabeblack@google.com  //*****************************************************
61014184Sgabeblack@google.com
61114184Sgabeblack@google.com  // Transitions for Load/Store/Replacement/WriteBack from transient states
61214184Sgabeblack@google.com  transition({Inst_IS, IS, IM, SM}, {Load, Ifetch, Store, L0_Replacement}) {
61314184Sgabeblack@google.com    z_stallAndWaitMandatoryQueue;
61414184Sgabeblack@google.com  }
61514184Sgabeblack@google.com
61614184Sgabeblack@google.com  // Transitions from Idle
61714184Sgabeblack@google.com  transition(I, Load, IS) {
61814184Sgabeblack@google.com    oo_allocateDCacheBlock;
61914184Sgabeblack@google.com    i_allocateTBE;
62014184Sgabeblack@google.com    a_issueGETS;
62114184Sgabeblack@google.com    uu_profileDataMiss;
62214184Sgabeblack@google.com    k_popMandatoryQueue;
62314184Sgabeblack@google.com  }
62414184Sgabeblack@google.com
62514184Sgabeblack@google.com  transition(I, Ifetch, Inst_IS) {
62614184Sgabeblack@google.com    pp_allocateICacheBlock;
62714184Sgabeblack@google.com    i_allocateTBE;
62814184Sgabeblack@google.com    a_issueGETS;
62914184Sgabeblack@google.com    uu_profileInstMiss;
63014184Sgabeblack@google.com    k_popMandatoryQueue;
63114184Sgabeblack@google.com  }
63214184Sgabeblack@google.com
63314184Sgabeblack@google.com  transition(I, Store, IM) {
63414184Sgabeblack@google.com    oo_allocateDCacheBlock;
63514184Sgabeblack@google.com    i_allocateTBE;
63614184Sgabeblack@google.com    b_issueGETX;
63714184Sgabeblack@google.com    uu_profileDataMiss;
63814184Sgabeblack@google.com    k_popMandatoryQueue;
63914184Sgabeblack@google.com  }
64014184Sgabeblack@google.com
64114184Sgabeblack@google.com  transition({I, IS, IM, Inst_IS}, Inv) {
64214184Sgabeblack@google.com    fi_sendInvAck;
64314184Sgabeblack@google.com    l_popRequestQueue;
64414184Sgabeblack@google.com  }
64514184Sgabeblack@google.com
64614184Sgabeblack@google.com  transition(SM, Inv, IM) {
64714184Sgabeblack@google.com    fi_sendInvAck;
64814184Sgabeblack@google.com    l_popRequestQueue;
64914184Sgabeblack@google.com  }
65014184Sgabeblack@google.com
65114184Sgabeblack@google.com  // Transitions from Shared
65214184Sgabeblack@google.com  transition({S,E,M}, Load) {
65314184Sgabeblack@google.com    h_load_hit;
65414184Sgabeblack@google.com    uu_profileDataHit;
65514184Sgabeblack@google.com    k_popMandatoryQueue;
65614184Sgabeblack@google.com  }
65714184Sgabeblack@google.com
65814184Sgabeblack@google.com  transition({S,E,M}, Ifetch) {
65914184Sgabeblack@google.com    h_ifetch_hit;
66014184Sgabeblack@google.com    uu_profileInstHit;
66114184Sgabeblack@google.com    k_popMandatoryQueue;
66214184Sgabeblack@google.com  }
66314184Sgabeblack@google.com
66414184Sgabeblack@google.com  transition(S, Store, SM) {
66514184Sgabeblack@google.com    i_allocateTBE;
66614184Sgabeblack@google.com    c_issueUPGRADE;
66714184Sgabeblack@google.com    uu_profileDataMiss;
66814184Sgabeblack@google.com    k_popMandatoryQueue;
66914184Sgabeblack@google.com  }
67014184Sgabeblack@google.com
67114184Sgabeblack@google.com  transition(S, L0_Replacement, I) {
67214184Sgabeblack@google.com    forward_eviction_to_cpu;
67314184Sgabeblack@google.com    ff_deallocateCacheBlock;
67414184Sgabeblack@google.com  }
67514184Sgabeblack@google.com
67614184Sgabeblack@google.com  transition(S, Inv, I) {
67714184Sgabeblack@google.com    forward_eviction_to_cpu;
67814184Sgabeblack@google.com    fi_sendInvAck;
67914184Sgabeblack@google.com    ff_deallocateCacheBlock;
68014184Sgabeblack@google.com    l_popRequestQueue;
68114184Sgabeblack@google.com  }
68214184Sgabeblack@google.com
68314184Sgabeblack@google.com  // Transitions from Exclusive
68414184Sgabeblack@google.com  transition({E,M}, Store, M) {
68514184Sgabeblack@google.com    hh_store_hit;
68614184Sgabeblack@google.com    uu_profileDataHit;
68714184Sgabeblack@google.com    k_popMandatoryQueue;
68814184Sgabeblack@google.com  }
68914184Sgabeblack@google.com
69014184Sgabeblack@google.com  transition(E, L0_Replacement, I) {
69114184Sgabeblack@google.com    forward_eviction_to_cpu;
69214184Sgabeblack@google.com    g_issuePUTX;
69314184Sgabeblack@google.com    ff_deallocateCacheBlock;
69414184Sgabeblack@google.com  }
69514184Sgabeblack@google.com
69614184Sgabeblack@google.com  transition(E, {Inv, Fwd_GETX}, I) {
69714184Sgabeblack@google.com    // don't send data
69814184Sgabeblack@google.com    forward_eviction_to_cpu;
69914184Sgabeblack@google.com    fi_sendInvAck;
70014184Sgabeblack@google.com    ff_deallocateCacheBlock;
70114184Sgabeblack@google.com    l_popRequestQueue;
70214184Sgabeblack@google.com  }
70314184Sgabeblack@google.com
70414184Sgabeblack@google.com  transition(E, {Fwd_GETS, Fwd_GET_INSTR}, S) {
70514184Sgabeblack@google.com    f_sendDataToL1;
70614184Sgabeblack@google.com    l_popRequestQueue;
70714184Sgabeblack@google.com  }
70814184Sgabeblack@google.com
70914184Sgabeblack@google.com  // Transitions from Modified
71014184Sgabeblack@google.com  transition(M, L0_Replacement, I) {
71114184Sgabeblack@google.com    forward_eviction_to_cpu;
71214184Sgabeblack@google.com    g_issuePUTX;
71314184Sgabeblack@google.com    ff_deallocateCacheBlock;
71414184Sgabeblack@google.com  }
71514184Sgabeblack@google.com
71614184Sgabeblack@google.com  transition(M, {Inv, Fwd_GETX}, I) {
71714184Sgabeblack@google.com    forward_eviction_to_cpu;
71814184Sgabeblack@google.com    f_sendDataToL1;
71914184Sgabeblack@google.com    ff_deallocateCacheBlock;
72014184Sgabeblack@google.com    l_popRequestQueue;
72114184Sgabeblack@google.com  }
72214184Sgabeblack@google.com
72314184Sgabeblack@google.com  transition(M, {Fwd_GETS, Fwd_GET_INSTR}, S) {
72414184Sgabeblack@google.com    f_sendDataToL1;
72514184Sgabeblack@google.com    l_popRequestQueue;
72614184Sgabeblack@google.com  }
72714184Sgabeblack@google.com
72814184Sgabeblack@google.com  transition(IS, Data, S) {
72914184Sgabeblack@google.com    u_writeDataToCache;
73014184Sgabeblack@google.com    hx_load_hit;
73114184Sgabeblack@google.com    s_deallocateTBE;
73214184Sgabeblack@google.com    o_popIncomingResponseQueue;
73314184Sgabeblack@google.com    kd_wakeUpDependents;
73414184Sgabeblack@google.com  }
73514184Sgabeblack@google.com
73614184Sgabeblack@google.com  transition(IS, Data_Exclusive, E) {
73714184Sgabeblack@google.com    u_writeDataToCache;
73814184Sgabeblack@google.com    hx_load_hit;
73914184Sgabeblack@google.com    s_deallocateTBE;
74014184Sgabeblack@google.com    o_popIncomingResponseQueue;
74114184Sgabeblack@google.com    kd_wakeUpDependents;
74214184Sgabeblack@google.com  }
74314184Sgabeblack@google.com
74414184Sgabeblack@google.com  transition(IS, Data_Stale, I) {
74514184Sgabeblack@google.com    u_writeDataToCache;
74614184Sgabeblack@google.com    hx_load_hit;
74714184Sgabeblack@google.com    s_deallocateTBE;
74814184Sgabeblack@google.com    ff_deallocateCacheBlock;
74914184Sgabeblack@google.com    o_popIncomingResponseQueue;
75014184Sgabeblack@google.com    kd_wakeUpDependents;
75114184Sgabeblack@google.com  }
75214184Sgabeblack@google.com
75314184Sgabeblack@google.com  transition(Inst_IS, Data, S) {
75414184Sgabeblack@google.com    u_writeInstToCache;
75514184Sgabeblack@google.com    hx_ifetch_hit;
75614184Sgabeblack@google.com    s_deallocateTBE;
75714184Sgabeblack@google.com    o_popIncomingResponseQueue;
75814184Sgabeblack@google.com    kd_wakeUpDependents;
75914184Sgabeblack@google.com  }
76014184Sgabeblack@google.com
76114184Sgabeblack@google.com  transition(Inst_IS, Data_Exclusive, E) {
76214184Sgabeblack@google.com    u_writeInstToCache;
76314184Sgabeblack@google.com    hx_ifetch_hit;
76414184Sgabeblack@google.com    s_deallocateTBE;
76514184Sgabeblack@google.com    o_popIncomingResponseQueue;
76614184Sgabeblack@google.com    kd_wakeUpDependents;
76714184Sgabeblack@google.com  }
76814184Sgabeblack@google.com
76914184Sgabeblack@google.com  transition(Inst_IS, Data_Stale, I) {
77014184Sgabeblack@google.com    u_writeInstToCache;
77114184Sgabeblack@google.com    hx_ifetch_hit;
77214184Sgabeblack@google.com    s_deallocateTBE;
77314184Sgabeblack@google.com    ff_deallocateCacheBlock;
77414184Sgabeblack@google.com    o_popIncomingResponseQueue;
77514184Sgabeblack@google.com    kd_wakeUpDependents;
77614184Sgabeblack@google.com  }
77714184Sgabeblack@google.com
77814184Sgabeblack@google.com  transition({IM,SM}, Data_Exclusive, M) {
77914184Sgabeblack@google.com    u_writeDataToCache;
78014184Sgabeblack@google.com    hhx_store_hit;
78114184Sgabeblack@google.com    s_deallocateTBE;
78214184Sgabeblack@google.com    o_popIncomingResponseQueue;
78314184Sgabeblack@google.com    kd_wakeUpDependents;
78414184Sgabeblack@google.com  }
78514184Sgabeblack@google.com}
786