114184Sgabeblack@google.com/*
214184Sgabeblack@google.com * Copyright (c) 2019 ARM Limited
314184Sgabeblack@google.com * All rights reserved
414184Sgabeblack@google.com *
514184Sgabeblack@google.com * The license below extends only to copyright in the software and shall
614184Sgabeblack@google.com * not be construed as granting a license to any other intellectual
714184Sgabeblack@google.com * property including but not limited to intellectual property relating
814184Sgabeblack@google.com * to a hardware implementation of the functionality of the software
914184Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1014184Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1114184Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1214184Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1314184Sgabeblack@google.com *
1414184Sgabeblack@google.com * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood
1514184Sgabeblack@google.com * All rights reserved.
1614184Sgabeblack@google.com *
1714184Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1814184Sgabeblack@google.com * modification, are permitted provided that the following conditions are
1914184Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
2014184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2114184Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2214184Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2314184Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2414184Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2514184Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2614184Sgabeblack@google.com * this software without specific prior written permission.
2714184Sgabeblack@google.com *
2814184Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2914184Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3014184Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3114184Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3214184Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3314184Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3414184Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3514184Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3614184Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3714184Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3814184Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3914184Sgabeblack@google.com */
4014184Sgabeblack@google.com
4114184Sgabeblack@google.commachine(MachineType:L1Cache, "L1 cache protocol")
4214184Sgabeblack@google.com : Sequencer * sequencer;
4314184Sgabeblack@google.com   CacheMemory * L1Icache;
4414184Sgabeblack@google.com   CacheMemory * L1Dcache;
4514184Sgabeblack@google.com   Cycles request_latency := 1;
4614184Sgabeblack@google.com   Cycles response_latency := 1;
4714184Sgabeblack@google.com   Cycles use_timeout_latency := 50;
4814184Sgabeblack@google.com   bool send_evictions;
4914184Sgabeblack@google.com
5014184Sgabeblack@google.com   // Message Queues
5114184Sgabeblack@google.com   // From this node's L1 cache TO the network
5214184Sgabeblack@google.com   // a local L1 -> this L2 bank, currently ordered with directory forwarded requests
5314184Sgabeblack@google.com   MessageBuffer * requestFromL1Cache, network="To", virtual_network="0",
5414184Sgabeblack@google.com        vnet_type="request";
5514184Sgabeblack@google.com   // a local L1 -> this L2 bank
5614184Sgabeblack@google.com   MessageBuffer * responseFromL1Cache, network="To", virtual_network="2",
5714184Sgabeblack@google.com        vnet_type="response";
5814184Sgabeblack@google.com
5914184Sgabeblack@google.com   // To this node's L1 cache FROM the network
6014184Sgabeblack@google.com   // a L2 bank -> this L1
6114184Sgabeblack@google.com   MessageBuffer * requestToL1Cache, network="From", virtual_network="0",
6214184Sgabeblack@google.com        vnet_type="request";
6314184Sgabeblack@google.com   // a L2 bank -> this L1
6414184Sgabeblack@google.com   MessageBuffer * responseToL1Cache, network="From", virtual_network="2",
6514184Sgabeblack@google.com        vnet_type="response";
6614184Sgabeblack@google.com
6714184Sgabeblack@google.com   MessageBuffer * triggerQueue;
6814184Sgabeblack@google.com
6914184Sgabeblack@google.com   MessageBuffer * mandatoryQueue;
7014184Sgabeblack@google.com{
7114184Sgabeblack@google.com  // STATES
7214184Sgabeblack@google.com  state_declaration(State, desc="Cache states", default="L1Cache_State_I") {
7314184Sgabeblack@google.com    // Base states
7414184Sgabeblack@google.com    I, AccessPermission:Invalid, desc="Idle";
7514184Sgabeblack@google.com    S, AccessPermission:Read_Only, desc="Shared";
7614184Sgabeblack@google.com    O, AccessPermission:Read_Only, desc="Owned";
7714184Sgabeblack@google.com    M, AccessPermission:Read_Only, desc="Modified (dirty)";
7814184Sgabeblack@google.com    M_W, AccessPermission:Read_Only, desc="Modified (dirty)";
7914184Sgabeblack@google.com    MM, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
8014184Sgabeblack@google.com    MM_W, AccessPermission:Read_Write, desc="Modified (dirty and locally modified)";
8114184Sgabeblack@google.com
8214184Sgabeblack@google.com    // Transient States
8314184Sgabeblack@google.com    IM, AccessPermission:Busy, "IM", desc="Issued GetX";
8414184Sgabeblack@google.com    SM, AccessPermission:Read_Only, "SM", desc="Issued GetX, we still have an old copy of the line";
8514184Sgabeblack@google.com    OM, AccessPermission:Read_Only, "SM", desc="Issued GetX, received data";
8614184Sgabeblack@google.com    IS, AccessPermission:Busy, "IS", desc="Issued GetS";
8714184Sgabeblack@google.com    SI, AccessPermission:Busy, "OI", desc="Issued PutS, waiting for ack";
8814184Sgabeblack@google.com    OI, AccessPermission:Busy, "OI", desc="Issued PutO, waiting for ack";
8914184Sgabeblack@google.com    MI, AccessPermission:Busy, "MI", desc="Issued PutX, waiting for ack";
9014184Sgabeblack@google.com    II, AccessPermission:Busy, "II", desc="Issued PutX/O, saw Fwd_GETS or Fwd_GETX, waiting for ack";
9114184Sgabeblack@google.com  }
9214184Sgabeblack@google.com
9314184Sgabeblack@google.com  // EVENTS
9414184Sgabeblack@google.com  enumeration(Event, desc="Cache events") {
9514184Sgabeblack@google.com    Load,            desc="Load request from the processor";
9614184Sgabeblack@google.com    Ifetch,          desc="I-fetch request from the processor";
9714184Sgabeblack@google.com    Store,           desc="Store request from the processor";
9814184Sgabeblack@google.com    L1_Replacement,  desc="Replacement";
9914184Sgabeblack@google.com
10014184Sgabeblack@google.com    // Requests
10114184Sgabeblack@google.com    Own_GETX,      desc="We observe our own GetX forwarded back to us";
10214184Sgabeblack@google.com    Fwd_GETX,      desc="A GetX from another processor";
10314184Sgabeblack@google.com    Fwd_GETS,      desc="A GetS from another processor";
10414184Sgabeblack@google.com    Fwd_DMA,      desc="A GetS from another processor";
10514184Sgabeblack@google.com    Inv,           desc="Invalidations from the directory";
10614184Sgabeblack@google.com
10714184Sgabeblack@google.com    // Responses
10814184Sgabeblack@google.com    Ack,             desc="Received an ack message";
10914184Sgabeblack@google.com    Data,            desc="Received a data message, responder has a shared copy";
11014184Sgabeblack@google.com    Exclusive_Data,  desc="Received a data message";
11114184Sgabeblack@google.com
11214184Sgabeblack@google.com    Writeback_Ack,   desc="Writeback O.K. from directory";
11314184Sgabeblack@google.com    Writeback_Ack_Data,   desc="Writeback O.K. from directory";
11414184Sgabeblack@google.com    Writeback_Nack,  desc="Writeback not O.K. from directory";
11514184Sgabeblack@google.com
11614184Sgabeblack@google.com    // Triggers
11714184Sgabeblack@google.com    All_acks,                  desc="Received all required data and message acks";
11814184Sgabeblack@google.com
11914184Sgabeblack@google.com    // Timeouts
12014184Sgabeblack@google.com    Use_Timeout, desc="lockout period ended";
12114184Sgabeblack@google.com  }
12214184Sgabeblack@google.com
12314184Sgabeblack@google.com  // TYPES
12414184Sgabeblack@google.com
12514184Sgabeblack@google.com  // CacheEntry
12614184Sgabeblack@google.com  structure(Entry, desc="...", interface="AbstractCacheEntry") {
12714184Sgabeblack@google.com    State CacheState,        desc="cache state";
12814184Sgabeblack@google.com    bool Dirty,              desc="Is the data dirty (different than memory)?";
12914184Sgabeblack@google.com    DataBlock DataBlk,       desc="data for the block";
13014184Sgabeblack@google.com  }
13114184Sgabeblack@google.com
13214184Sgabeblack@google.com  // TBE fields
13314184Sgabeblack@google.com  structure(TBE, desc="...") {
13414184Sgabeblack@google.com    Addr addr,         desc="Physical address for this TBE";
13514184Sgabeblack@google.com    State TBEState,          desc="Transient state";
13614184Sgabeblack@google.com    DataBlock DataBlk,       desc="data for the block, required for concurrent writebacks";
13714184Sgabeblack@google.com    bool Dirty,              desc="Is the data dirty (different than memory)?";
13814184Sgabeblack@google.com    int NumPendingMsgs, default="0",     desc="Number of acks/data messages that this processor is waiting for";
13914184Sgabeblack@google.com  }
14014184Sgabeblack@google.com
14114184Sgabeblack@google.com  structure(TBETable, external ="yes") {
14214184Sgabeblack@google.com    TBE lookup(Addr);
14314184Sgabeblack@google.com    void allocate(Addr);
14414184Sgabeblack@google.com    void deallocate(Addr);
14514184Sgabeblack@google.com    bool isPresent(Addr);
14614184Sgabeblack@google.com  }
14714184Sgabeblack@google.com
14814184Sgabeblack@google.com  Tick clockEdge();
14914184Sgabeblack@google.com  Tick cyclesToTicks(Cycles c);
15014184Sgabeblack@google.com  void set_cache_entry(AbstractCacheEntry b);
15114184Sgabeblack@google.com  void unset_cache_entry();
15214184Sgabeblack@google.com  void set_tbe(TBE b);
15314184Sgabeblack@google.com  void unset_tbe();
15414184Sgabeblack@google.com  MachineID mapAddressToMachine(Addr addr, MachineType mtype);
15514184Sgabeblack@google.com
15614184Sgabeblack@google.com  TBETable TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs";
15714184Sgabeblack@google.com  TimerTable useTimerTable;
15814184Sgabeblack@google.com
15914184Sgabeblack@google.com  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
16014184Sgabeblack@google.com    Entry L1Dcache_entry := static_cast(Entry, "pointer", L1Dcache.lookup(addr));
16114184Sgabeblack@google.com    if(is_valid(L1Dcache_entry)) {
16214184Sgabeblack@google.com      return L1Dcache_entry;
16314184Sgabeblack@google.com    }
16414184Sgabeblack@google.com
16514184Sgabeblack@google.com    Entry L1Icache_entry := static_cast(Entry, "pointer", L1Icache.lookup(addr));
16614184Sgabeblack@google.com    return L1Icache_entry;
16714184Sgabeblack@google.com  }
16814184Sgabeblack@google.com
16914184Sgabeblack@google.com  Entry getL1DCacheEntry(Addr addr), return_by_pointer="yes" {
17014184Sgabeblack@google.com    return static_cast(Entry, "pointer", L1Dcache.lookup(addr));
17114184Sgabeblack@google.com  }
17214184Sgabeblack@google.com
17314184Sgabeblack@google.com  Entry getL1ICacheEntry(Addr addr), return_by_pointer="yes" {
17414184Sgabeblack@google.com    return static_cast(Entry, "pointer", L1Icache.lookup(addr));
17514184Sgabeblack@google.com  }
17614184Sgabeblack@google.com
17714184Sgabeblack@google.com  State getState(TBE tbe, Entry cache_entry, Addr addr) {
17814184Sgabeblack@google.com    if(is_valid(tbe)) {
17914184Sgabeblack@google.com      return tbe.TBEState;
18014184Sgabeblack@google.com    } else if (is_valid(cache_entry)) {
18114184Sgabeblack@google.com      return cache_entry.CacheState;
18214184Sgabeblack@google.com    }
18314184Sgabeblack@google.com    return State:I;
18414184Sgabeblack@google.com  }
18514184Sgabeblack@google.com
18614184Sgabeblack@google.com  // L1 hit latency
18714184Sgabeblack@google.com  Cycles mandatoryQueueLatency(RubyRequestType type) {
18814184Sgabeblack@google.com    if (type == RubyRequestType:IFETCH) {
18914184Sgabeblack@google.com      return L1Icache.getTagLatency();
19014184Sgabeblack@google.com    } else {
19114184Sgabeblack@google.com      return L1Dcache.getTagLatency();
19214184Sgabeblack@google.com    }
19314184Sgabeblack@google.com  }
19414184Sgabeblack@google.com
19514184Sgabeblack@google.com  // Latency for responses that fetch data from cache
19614184Sgabeblack@google.com  Cycles cacheResponseLatency() {
19714184Sgabeblack@google.com    if (L1Dcache.getTagLatency() > response_latency) {
19814184Sgabeblack@google.com      return L1Dcache.getTagLatency();
19914184Sgabeblack@google.com    } else {
20014184Sgabeblack@google.com      return response_latency;
20114184Sgabeblack@google.com    }
20214184Sgabeblack@google.com  }
20314184Sgabeblack@google.com
20414184Sgabeblack@google.com  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
20514184Sgabeblack@google.com    assert((L1Dcache.isTagPresent(addr) && L1Icache.isTagPresent(addr)) == false);
20614184Sgabeblack@google.com
20714184Sgabeblack@google.com    if (is_valid(tbe)) {
20814184Sgabeblack@google.com      tbe.TBEState := state;
20914184Sgabeblack@google.com    }
21014184Sgabeblack@google.com
21114184Sgabeblack@google.com    if (is_valid(cache_entry)) {
21214184Sgabeblack@google.com      if ( ((cache_entry.CacheState != State:M) && (state == State:M)) ||
21314184Sgabeblack@google.com         ((cache_entry.CacheState != State:MM) && (state == State:MM)) ||
21414184Sgabeblack@google.com         ((cache_entry.CacheState != State:S) && (state == State:S)) ||
21514184Sgabeblack@google.com         ((cache_entry.CacheState != State:O) && (state == State:O)) ) {
21614184Sgabeblack@google.com
21714184Sgabeblack@google.com        cache_entry.CacheState := state;
21814184Sgabeblack@google.com        sequencer.checkCoherence(addr);
21914184Sgabeblack@google.com      }
22014184Sgabeblack@google.com      else {
22114184Sgabeblack@google.com        cache_entry.CacheState := state;
22214184Sgabeblack@google.com      }
22314184Sgabeblack@google.com    }
22414184Sgabeblack@google.com  }
22514184Sgabeblack@google.com
22614184Sgabeblack@google.com  AccessPermission getAccessPermission(Addr addr) {
22714184Sgabeblack@google.com    TBE tbe := TBEs[addr];
22814184Sgabeblack@google.com    if(is_valid(tbe)) {
22914184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(tbe.TBEState));
23014184Sgabeblack@google.com      return L1Cache_State_to_permission(tbe.TBEState);
23114184Sgabeblack@google.com    }
23214184Sgabeblack@google.com
23314184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
23414184Sgabeblack@google.com    if(is_valid(cache_entry)) {
23514184Sgabeblack@google.com      DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(cache_entry.CacheState));
23614184Sgabeblack@google.com      return L1Cache_State_to_permission(cache_entry.CacheState);
23714184Sgabeblack@google.com    }
23814184Sgabeblack@google.com
23914184Sgabeblack@google.com    DPRINTF(RubySlicc, "AccessPermission_NotPresent\n");
24014184Sgabeblack@google.com    return AccessPermission:NotPresent;
24114184Sgabeblack@google.com  }
24214184Sgabeblack@google.com
24314184Sgabeblack@google.com  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
24414184Sgabeblack@google.com    if (is_valid(cache_entry)) {
24514184Sgabeblack@google.com      cache_entry.changePermission(L1Cache_State_to_permission(state));
24614184Sgabeblack@google.com    }
24714184Sgabeblack@google.com  }
24814184Sgabeblack@google.com
24914184Sgabeblack@google.com  void functionalRead(Addr addr, Packet *pkt) {
25014184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
25114184Sgabeblack@google.com    if(is_valid(cache_entry)) {
25214184Sgabeblack@google.com      testAndRead(addr, cache_entry.DataBlk, pkt);
25314184Sgabeblack@google.com    } else {
25414184Sgabeblack@google.com      TBE tbe := TBEs[addr];
25514184Sgabeblack@google.com      if(is_valid(tbe)) {
25614184Sgabeblack@google.com        testAndRead(addr, tbe.DataBlk, pkt);
25714184Sgabeblack@google.com      } else {
25814184Sgabeblack@google.com        error("Data block missing!");
25914184Sgabeblack@google.com      }
26014184Sgabeblack@google.com    }
26114184Sgabeblack@google.com  }
26214184Sgabeblack@google.com
26314184Sgabeblack@google.com  int functionalWrite(Addr addr, Packet *pkt) {
26414184Sgabeblack@google.com    int num_functional_writes := 0;
26514184Sgabeblack@google.com
26614184Sgabeblack@google.com    Entry cache_entry := getCacheEntry(addr);
26714184Sgabeblack@google.com    if(is_valid(cache_entry)) {
26814184Sgabeblack@google.com      num_functional_writes := num_functional_writes +
26914184Sgabeblack@google.com        testAndWrite(addr, cache_entry.DataBlk, pkt);
27014184Sgabeblack@google.com      return num_functional_writes;
27114184Sgabeblack@google.com    }
27214184Sgabeblack@google.com
27314184Sgabeblack@google.com    TBE tbe := TBEs[addr];
27414184Sgabeblack@google.com    num_functional_writes := num_functional_writes +
27514184Sgabeblack@google.com        testAndWrite(addr, tbe.DataBlk, pkt);
27614184Sgabeblack@google.com    return num_functional_writes;
27714184Sgabeblack@google.com  }
27814184Sgabeblack@google.com
27914184Sgabeblack@google.com  Event mandatory_request_type_to_event(RubyRequestType type) {
28014184Sgabeblack@google.com    if (type == RubyRequestType:LD) {
28114184Sgabeblack@google.com      return Event:Load;
28214184Sgabeblack@google.com    } else if (type == RubyRequestType:IFETCH) {
28314184Sgabeblack@google.com      return Event:Ifetch;
28414184Sgabeblack@google.com    } else if ((type == RubyRequestType:ST) || (type == RubyRequestType:ATOMIC)) {
28514184Sgabeblack@google.com      return Event:Store;
28614184Sgabeblack@google.com    } else {
28714184Sgabeblack@google.com      error("Invalid RubyRequestType");
28814184Sgabeblack@google.com    }
28914184Sgabeblack@google.com  }
29014184Sgabeblack@google.com
29114184Sgabeblack@google.com  // ** OUT_PORTS **
29214184Sgabeblack@google.com
29314184Sgabeblack@google.com  out_port(requestNetwork_out, RequestMsg, requestFromL1Cache);
29414184Sgabeblack@google.com  out_port(responseNetwork_out, ResponseMsg, responseFromL1Cache);
29514184Sgabeblack@google.com  out_port(triggerQueue_out, TriggerMsg, triggerQueue);
29614184Sgabeblack@google.com
29714184Sgabeblack@google.com  // ** IN_PORTS **
29814184Sgabeblack@google.com
29914184Sgabeblack@google.com  // Use Timer
30014184Sgabeblack@google.com  in_port(useTimerTable_in, Addr, useTimerTable, rank=4) {
30114184Sgabeblack@google.com    if (useTimerTable_in.isReady(clockEdge())) {
30214184Sgabeblack@google.com        Addr readyAddress := useTimerTable.nextAddress();
30314184Sgabeblack@google.com        trigger(Event:Use_Timeout, readyAddress, getCacheEntry(readyAddress),
30414184Sgabeblack@google.com                TBEs.lookup(readyAddress));
30514184Sgabeblack@google.com    }
30614184Sgabeblack@google.com  }
30714184Sgabeblack@google.com
30814184Sgabeblack@google.com  // Trigger Queue
30914184Sgabeblack@google.com  in_port(triggerQueue_in, TriggerMsg, triggerQueue, rank=3) {
31014184Sgabeblack@google.com    if (triggerQueue_in.isReady(clockEdge())) {
31114184Sgabeblack@google.com      peek(triggerQueue_in, TriggerMsg) {
31214184Sgabeblack@google.com        if (in_msg.Type == TriggerType:ALL_ACKS) {
31314184Sgabeblack@google.com          trigger(Event:All_acks, in_msg.addr,
31414184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
31514184Sgabeblack@google.com        } else {
31614184Sgabeblack@google.com          error("Unexpected message");
31714184Sgabeblack@google.com        }
31814184Sgabeblack@google.com      }
31914184Sgabeblack@google.com    }
32014184Sgabeblack@google.com  }
32114184Sgabeblack@google.com
32214184Sgabeblack@google.com  // Response Network
32314184Sgabeblack@google.com  in_port(responseToL1Cache_in, ResponseMsg, responseToL1Cache, rank=2) {
32414184Sgabeblack@google.com    if (responseToL1Cache_in.isReady(clockEdge())) {
32514184Sgabeblack@google.com      peek(responseToL1Cache_in, ResponseMsg, block_on="addr") {
32614184Sgabeblack@google.com        if (in_msg.Type == CoherenceResponseType:ACK) {
32714184Sgabeblack@google.com          trigger(Event:Ack, in_msg.addr,
32814184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
32914184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:DATA) {
33014184Sgabeblack@google.com          trigger(Event:Data, in_msg.addr,
33114184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
33214184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
33314184Sgabeblack@google.com          trigger(Event:Exclusive_Data, in_msg.addr,
33414184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
33514184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:WB_ACK) {
33614184Sgabeblack@google.com          trigger(Event:Writeback_Ack, in_msg.addr,
33714184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
33814184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:WB_ACK_DATA) {
33914184Sgabeblack@google.com          trigger(Event:Writeback_Ack_Data, in_msg.addr,
34014184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
34114184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceResponseType:WB_NACK) {
34214184Sgabeblack@google.com          trigger(Event:Writeback_Nack, in_msg.addr,
34314184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
34414184Sgabeblack@google.com        } else {
34514184Sgabeblack@google.com          error("Unexpected message");
34614184Sgabeblack@google.com        }
34714184Sgabeblack@google.com      }
34814184Sgabeblack@google.com    }
34914184Sgabeblack@google.com  }
35014184Sgabeblack@google.com
35114184Sgabeblack@google.com
35214184Sgabeblack@google.com  // Request Network
35314184Sgabeblack@google.com  in_port(requestNetwork_in, RequestMsg, requestToL1Cache, rank=1) {
35414184Sgabeblack@google.com    if (requestNetwork_in.isReady(clockEdge())) {
35514184Sgabeblack@google.com      peek(requestNetwork_in, RequestMsg, block_on="addr") {
35614184Sgabeblack@google.com        assert(in_msg.Destination.isElement(machineID));
35714184Sgabeblack@google.com        DPRINTF(RubySlicc, "L1 received: %s\n", in_msg.Type);
35814184Sgabeblack@google.com
35914184Sgabeblack@google.com        if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
36014184Sgabeblack@google.com          if (in_msg.Requestor == machineID && in_msg.RequestorMachine == MachineType:L1Cache) {
36114184Sgabeblack@google.com            trigger(Event:Own_GETX, in_msg.addr,
36214184Sgabeblack@google.com                    getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
36314184Sgabeblack@google.com          } else {
36414184Sgabeblack@google.com            trigger(Event:Fwd_GETX, in_msg.addr,
36514184Sgabeblack@google.com                    getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
36614184Sgabeblack@google.com          }
36714184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:GETS) {
36814184Sgabeblack@google.com          trigger(Event:Fwd_GETS, in_msg.addr,
36914184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
37014184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
37114184Sgabeblack@google.com          trigger(Event:Fwd_DMA, in_msg.addr,
37214184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
37314184Sgabeblack@google.com        } else if (in_msg.Type == CoherenceRequestType:INV) {
37414184Sgabeblack@google.com          trigger(Event:Inv, in_msg.addr,
37514184Sgabeblack@google.com                  getCacheEntry(in_msg.addr), TBEs[in_msg.addr]);
37614184Sgabeblack@google.com        } else {
37714184Sgabeblack@google.com          error("Unexpected message");
37814184Sgabeblack@google.com        }
37914184Sgabeblack@google.com      }
38014184Sgabeblack@google.com    }
38114184Sgabeblack@google.com  }
38214184Sgabeblack@google.com
38314184Sgabeblack@google.com  // Mandatory Queue betweens Node's CPU and it's L1 caches
38414184Sgabeblack@google.com  in_port(mandatoryQueue_in, RubyRequest, mandatoryQueue, rank=0) {
38514184Sgabeblack@google.com    if (mandatoryQueue_in.isReady(clockEdge())) {
38614184Sgabeblack@google.com      peek(mandatoryQueue_in, RubyRequest, block_on="LineAddress") {
38714184Sgabeblack@google.com
38814184Sgabeblack@google.com        // Check for data access to blocks in I-cache and ifetchs to blocks in D-cache
38914184Sgabeblack@google.com
39014184Sgabeblack@google.com        if (in_msg.Type == RubyRequestType:IFETCH) {
39114184Sgabeblack@google.com          // ** INSTRUCTION ACCESS ***
39214184Sgabeblack@google.com
39314184Sgabeblack@google.com          Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
39414184Sgabeblack@google.com          if (is_valid(L1Icache_entry)) {
39514184Sgabeblack@google.com            // The tag matches for the L1, so the L1 asks the L2 for it.
39614184Sgabeblack@google.com            trigger(mandatory_request_type_to_event(in_msg.Type),
39714184Sgabeblack@google.com                    in_msg.LineAddress, L1Icache_entry,
39814184Sgabeblack@google.com                    TBEs[in_msg.LineAddress]);
39914184Sgabeblack@google.com          } else {
40014184Sgabeblack@google.com
40114184Sgabeblack@google.com            Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
40214184Sgabeblack@google.com            // Check to see if it is in the OTHER L1
40314184Sgabeblack@google.com            if (is_valid(L1Dcache_entry)) {
40414184Sgabeblack@google.com              // The block is in the wrong L1, put the request on the queue to the shared L2
40514184Sgabeblack@google.com              trigger(Event:L1_Replacement, in_msg.LineAddress, L1Dcache_entry,
40614184Sgabeblack@google.com                      TBEs[in_msg.LineAddress]);
40714184Sgabeblack@google.com            }
40814184Sgabeblack@google.com            if (L1Icache.cacheAvail(in_msg.LineAddress)) {
40914184Sgabeblack@google.com              // L1 does't have the line, but we have space for it in the L1 so let's see if the L2 has it
41014184Sgabeblack@google.com              trigger(mandatory_request_type_to_event(in_msg.Type),
41114184Sgabeblack@google.com                      in_msg.LineAddress, L1Icache_entry,
41214184Sgabeblack@google.com                      TBEs[in_msg.LineAddress]);
41314184Sgabeblack@google.com            } else {
41414184Sgabeblack@google.com              // No room in the L1, so we need to make room in the L1
41514184Sgabeblack@google.com              // Check if the line we want to evict is not locked
41614184Sgabeblack@google.com              Addr addr := L1Icache.cacheProbe(in_msg.LineAddress);
41714184Sgabeblack@google.com              check_on_cache_probe(mandatoryQueue_in, addr);
41814184Sgabeblack@google.com              trigger(Event:L1_Replacement,
41914184Sgabeblack@google.com                      addr,
42014184Sgabeblack@google.com                      getL1ICacheEntry(addr),
42114184Sgabeblack@google.com                      TBEs[addr]);
42214184Sgabeblack@google.com            }
42314184Sgabeblack@google.com          }
42414184Sgabeblack@google.com        } else {
42514184Sgabeblack@google.com          // *** DATA ACCESS ***
42614184Sgabeblack@google.com
42714184Sgabeblack@google.com          Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
42814184Sgabeblack@google.com          if (is_valid(L1Dcache_entry)) {
42914184Sgabeblack@google.com            // The tag matches for the L1, so the L1 ask the L2 for it
43014184Sgabeblack@google.com            trigger(mandatory_request_type_to_event(in_msg.Type),
43114184Sgabeblack@google.com                    in_msg.LineAddress, L1Dcache_entry,
43214184Sgabeblack@google.com                    TBEs[in_msg.LineAddress]);
43314184Sgabeblack@google.com          } else {
43414184Sgabeblack@google.com
43514184Sgabeblack@google.com            Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
43614184Sgabeblack@google.com            // Check to see if it is in the OTHER L1
43714184Sgabeblack@google.com            if (is_valid(L1Icache_entry)) {
43814184Sgabeblack@google.com              // The block is in the wrong L1, put the request on the queue to the shared L2
43914184Sgabeblack@google.com              trigger(Event:L1_Replacement, in_msg.LineAddress,
44014184Sgabeblack@google.com                      L1Icache_entry, TBEs[in_msg.LineAddress]);
44114184Sgabeblack@google.com            }
44214184Sgabeblack@google.com            if (L1Dcache.cacheAvail(in_msg.LineAddress)) {
44314184Sgabeblack@google.com              // L1 does't have the line, but we have space for it in the L1 let's see if the L2 has it
44414184Sgabeblack@google.com              trigger(mandatory_request_type_to_event(in_msg.Type),
44514184Sgabeblack@google.com                      in_msg.LineAddress, L1Dcache_entry,
44614184Sgabeblack@google.com                      TBEs[in_msg.LineAddress]);
44714184Sgabeblack@google.com            } else {
44814184Sgabeblack@google.com              // No room in the L1, so we need to make room in the L1
44914184Sgabeblack@google.com              // Check if the line we want to evict is not locked
45014184Sgabeblack@google.com              Addr addr := L1Dcache.cacheProbe(in_msg.LineAddress);
45114184Sgabeblack@google.com              check_on_cache_probe(mandatoryQueue_in, addr);
45214184Sgabeblack@google.com              trigger(Event:L1_Replacement,
45314184Sgabeblack@google.com                      addr,
45414184Sgabeblack@google.com                      getL1DCacheEntry(addr),
45514184Sgabeblack@google.com                      TBEs[addr]);
45614184Sgabeblack@google.com            }
45714184Sgabeblack@google.com          }
45814184Sgabeblack@google.com        }
45914184Sgabeblack@google.com      }
46014184Sgabeblack@google.com    }
46114184Sgabeblack@google.com  }
46214184Sgabeblack@google.com
46314184Sgabeblack@google.com
46414184Sgabeblack@google.com  // ACTIONS
46514184Sgabeblack@google.com
46614184Sgabeblack@google.com  action(a_issueGETS, "a", desc="Issue GETS") {
46714184Sgabeblack@google.com    peek(mandatoryQueue_in, RubyRequest) {
46814184Sgabeblack@google.com      enqueue(requestNetwork_out, RequestMsg,  request_latency) {
46914184Sgabeblack@google.com        out_msg.addr := address;
47014184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:GETS;
47114184Sgabeblack@google.com        out_msg.Requestor := machineID;
47214184Sgabeblack@google.com        out_msg.RequestorMachine := MachineType:L1Cache;
47314184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address,
47414184Sgabeblack@google.com                                                    MachineType:L2Cache));
47514184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
47614184Sgabeblack@google.com        out_msg.AccessMode := in_msg.AccessMode;
47714184Sgabeblack@google.com        out_msg.Prefetch := in_msg.Prefetch;
47814184Sgabeblack@google.com      }
47914184Sgabeblack@google.com    }
48014184Sgabeblack@google.com  }
48114184Sgabeblack@google.com
48214184Sgabeblack@google.com  action(b_issueGETX, "b", desc="Issue GETX") {
48314184Sgabeblack@google.com    peek(mandatoryQueue_in, RubyRequest) {
48414184Sgabeblack@google.com      enqueue(requestNetwork_out, RequestMsg, request_latency) {
48514184Sgabeblack@google.com        out_msg.addr := address;
48614184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:GETX;
48714184Sgabeblack@google.com        out_msg.Requestor := machineID;
48814184Sgabeblack@google.com        out_msg.RequestorMachine := MachineType:L1Cache;
48914184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address,
49014184Sgabeblack@google.com                                                    MachineType:L2Cache));
49114184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Request_Control;
49214184Sgabeblack@google.com        out_msg.AccessMode := in_msg.AccessMode;
49314184Sgabeblack@google.com        out_msg.Prefetch := in_msg.Prefetch;
49414184Sgabeblack@google.com      }
49514184Sgabeblack@google.com    }
49614184Sgabeblack@google.com  }
49714184Sgabeblack@google.com
49814184Sgabeblack@google.com  action(d_issuePUTX, "d", desc="Issue PUTX") {
49914184Sgabeblack@google.com    enqueue(requestNetwork_out, RequestMsg, request_latency) {
50014184Sgabeblack@google.com      out_msg.addr := address;
50114184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:PUTX;
50214184Sgabeblack@google.com      out_msg.Requestor := machineID;
50314184Sgabeblack@google.com      out_msg.RequestorMachine := MachineType:L1Cache;
50414184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
50514184Sgabeblack@google.com                                                  MachineType:L2Cache));
50614184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Control;
50714184Sgabeblack@google.com    }
50814184Sgabeblack@google.com  }
50914184Sgabeblack@google.com
51014184Sgabeblack@google.com  action(dd_issuePUTO, "\d", desc="Issue PUTO") {
51114184Sgabeblack@google.com    enqueue(requestNetwork_out, RequestMsg, request_latency) {
51214184Sgabeblack@google.com      out_msg.addr := address;
51314184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:PUTO;
51414184Sgabeblack@google.com      out_msg.Requestor := machineID;
51514184Sgabeblack@google.com      out_msg.RequestorMachine := MachineType:L1Cache;
51614184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
51714184Sgabeblack@google.com                                                  MachineType:L2Cache));
51814184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Control;
51914184Sgabeblack@google.com    }
52014184Sgabeblack@google.com  }
52114184Sgabeblack@google.com
52214184Sgabeblack@google.com  action(dd_issuePUTS, "\ds", desc="Issue PUTS") {
52314184Sgabeblack@google.com    enqueue(requestNetwork_out, RequestMsg, request_latency) {
52414184Sgabeblack@google.com      out_msg.addr := address;
52514184Sgabeblack@google.com      out_msg.Type := CoherenceRequestType:PUTS;
52614184Sgabeblack@google.com      out_msg.Requestor := machineID;
52714184Sgabeblack@google.com      out_msg.RequestorMachine := MachineType:L1Cache;
52814184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
52914184Sgabeblack@google.com                                                  MachineType:L2Cache));
53014184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Control;
53114184Sgabeblack@google.com    }
53214184Sgabeblack@google.com  }
53314184Sgabeblack@google.com
53414184Sgabeblack@google.com  action(e_sendData, "e", desc="Send data from cache to requestor") {
53514184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
53614184Sgabeblack@google.com      assert(is_valid(cache_entry));
53714184Sgabeblack@google.com      if (in_msg.RequestorMachine == MachineType:L2Cache) {
53814184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) {
53914184Sgabeblack@google.com          out_msg.addr := address;
54014184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA;
54114184Sgabeblack@google.com          out_msg.Sender := machineID;
54214184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
54314184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address,
54414184Sgabeblack@google.com                                                      MachineType:L2Cache));
54514184Sgabeblack@google.com          out_msg.DataBlk := cache_entry.DataBlk;
54614184Sgabeblack@google.com          // out_msg.Dirty := cache_entry.Dirty;
54714184Sgabeblack@google.com          out_msg.Dirty := false;
54814184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
54914184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Data;
55014184Sgabeblack@google.com        }
55114184Sgabeblack@google.com        DPRINTF(RubySlicc, "Sending data to L2: %#x\n", in_msg.addr);
55214184Sgabeblack@google.com      }
55314184Sgabeblack@google.com      else {
55414184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) {
55514184Sgabeblack@google.com          out_msg.addr := address;
55614184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA;
55714184Sgabeblack@google.com          out_msg.Sender := machineID;
55814184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
55914184Sgabeblack@google.com          out_msg.Destination.add(in_msg.Requestor);
56014184Sgabeblack@google.com          out_msg.DataBlk := cache_entry.DataBlk;
56114184Sgabeblack@google.com          // out_msg.Dirty := cache_entry.Dirty;
56214184Sgabeblack@google.com          out_msg.Dirty := false;
56314184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
56414184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
56514184Sgabeblack@google.com        }
56614184Sgabeblack@google.com        DPRINTF(RubySlicc, "Sending data to L1\n");
56714184Sgabeblack@google.com      }
56814184Sgabeblack@google.com    }
56914184Sgabeblack@google.com  }
57014184Sgabeblack@google.com
57114184Sgabeblack@google.com  action(ee_sendDataExclusive, "\e", desc="Send data from cache to requestor, don't keep a shared copy") {
57214184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
57314184Sgabeblack@google.com      assert(is_valid(cache_entry));
57414184Sgabeblack@google.com      if (in_msg.RequestorMachine == MachineType:L2Cache) {
57514184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) {
57614184Sgabeblack@google.com          out_msg.addr := address;
57714184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
57814184Sgabeblack@google.com          out_msg.Sender := machineID;
57914184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
58014184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address,
58114184Sgabeblack@google.com                                                      MachineType:L2Cache));
58214184Sgabeblack@google.com          out_msg.DataBlk := cache_entry.DataBlk;
58314184Sgabeblack@google.com          out_msg.Dirty := cache_entry.Dirty;
58414184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
58514184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Data;
58614184Sgabeblack@google.com        }
58714184Sgabeblack@google.com        DPRINTF(RubySlicc, "Sending exclusive data to L2\n");
58814184Sgabeblack@google.com      }
58914184Sgabeblack@google.com      else {
59014184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, cacheResponseLatency()) {
59114184Sgabeblack@google.com          out_msg.addr := address;
59214184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
59314184Sgabeblack@google.com          out_msg.Sender := machineID;
59414184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
59514184Sgabeblack@google.com          out_msg.Destination.add(in_msg.Requestor);
59614184Sgabeblack@google.com          out_msg.DataBlk := cache_entry.DataBlk;
59714184Sgabeblack@google.com          out_msg.Dirty := cache_entry.Dirty;
59814184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
59914184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
60014184Sgabeblack@google.com        }
60114184Sgabeblack@google.com        DPRINTF(RubySlicc, "Sending exclusive data to L1\n");
60214184Sgabeblack@google.com      }
60314184Sgabeblack@google.com    }
60414184Sgabeblack@google.com  }
60514184Sgabeblack@google.com
60614184Sgabeblack@google.com  action(f_sendAck, "f", desc="Send ack from cache to requestor") {
60714184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
60814184Sgabeblack@google.com      if (in_msg.RequestorMachine == MachineType:L1Cache) {
60914184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
61014184Sgabeblack@google.com          out_msg.addr := address;
61114184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:ACK;
61214184Sgabeblack@google.com          out_msg.Sender := machineID;
61314184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
61414184Sgabeblack@google.com          out_msg.Destination.add(in_msg.Requestor);
61514184Sgabeblack@google.com          out_msg.Acks := 0 - 1; // -1
61614184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Control;
61714184Sgabeblack@google.com        }
61814184Sgabeblack@google.com      }
61914184Sgabeblack@google.com      else {
62014184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
62114184Sgabeblack@google.com          out_msg.addr := address;
62214184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:ACK;
62314184Sgabeblack@google.com          out_msg.Sender := machineID;
62414184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
62514184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address,
62614184Sgabeblack@google.com                                                      MachineType:L2Cache));
62714184Sgabeblack@google.com          out_msg.Acks := 0 - 1; // -1
62814184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Control;
62914184Sgabeblack@google.com        }
63014184Sgabeblack@google.com      }
63114184Sgabeblack@google.com    }
63214184Sgabeblack@google.com  }
63314184Sgabeblack@google.com
63414184Sgabeblack@google.com  action(g_sendUnblock, "g", desc="Send unblock to memory") {
63514184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, response_latency) {
63614184Sgabeblack@google.com      out_msg.addr := address;
63714184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:UNBLOCK;
63814184Sgabeblack@google.com      out_msg.Sender := machineID;
63914184Sgabeblack@google.com      out_msg.SenderMachine := MachineType:L1Cache;
64014184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
64114184Sgabeblack@google.com                                                  MachineType:L2Cache));
64214184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Unblock_Control;
64314184Sgabeblack@google.com    }
64414184Sgabeblack@google.com  }
64514184Sgabeblack@google.com
64614184Sgabeblack@google.com  action(gg_sendUnblockExclusive, "\g", desc="Send unblock exclusive to memory") {
64714184Sgabeblack@google.com    enqueue(responseNetwork_out, ResponseMsg, response_latency) {
64814184Sgabeblack@google.com      out_msg.addr := address;
64914184Sgabeblack@google.com      out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
65014184Sgabeblack@google.com      out_msg.Sender := machineID;
65114184Sgabeblack@google.com      out_msg.SenderMachine := MachineType:L1Cache;
65214184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
65314184Sgabeblack@google.com                                                  MachineType:L2Cache));
65414184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Unblock_Control;
65514184Sgabeblack@google.com    }
65614184Sgabeblack@google.com  }
65714184Sgabeblack@google.com
65814184Sgabeblack@google.com  action(h_load_hit, "hd", desc="Notify sequencer the load completed.") {
65914184Sgabeblack@google.com    assert(is_valid(cache_entry));
66014184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
66114184Sgabeblack@google.com    L1Dcache.setMRU(cache_entry);
66214184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk);
66314184Sgabeblack@google.com  }
66414184Sgabeblack@google.com
66514184Sgabeblack@google.com  action(h_ifetch_hit, "hi", desc="Notify the sequencer about ifetch completion.") {
66614184Sgabeblack@google.com    assert(is_valid(cache_entry));
66714184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
66814184Sgabeblack@google.com    L1Icache.setMRU(cache_entry);
66914184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk);
67014184Sgabeblack@google.com  }
67114184Sgabeblack@google.com
67214184Sgabeblack@google.com  action(hx_load_hit, "hx", desc="Notify sequencer the load completed.") {
67314184Sgabeblack@google.com    assert(is_valid(cache_entry));
67414184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
67514184Sgabeblack@google.com    L1Icache.setMRU(address);
67614184Sgabeblack@google.com    L1Dcache.setMRU(address);
67714184Sgabeblack@google.com    sequencer.readCallback(address, cache_entry.DataBlk, true);
67814184Sgabeblack@google.com  }
67914184Sgabeblack@google.com
68014184Sgabeblack@google.com  action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
68114184Sgabeblack@google.com    assert(is_valid(cache_entry));
68214184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
68314184Sgabeblack@google.com    L1Dcache.setMRU(cache_entry);
68414184Sgabeblack@google.com    sequencer.writeCallback(address, cache_entry.DataBlk);
68514184Sgabeblack@google.com    cache_entry.Dirty := true;
68614184Sgabeblack@google.com  }
68714184Sgabeblack@google.com
68814184Sgabeblack@google.com  action(xx_store_hit, "\xx", desc="Notify sequencer that store completed.") {
68914184Sgabeblack@google.com    assert(is_valid(cache_entry));
69014184Sgabeblack@google.com    DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
69114184Sgabeblack@google.com    L1Icache.setMRU(address);
69214184Sgabeblack@google.com    L1Dcache.setMRU(address);
69314184Sgabeblack@google.com    sequencer.writeCallback(address, cache_entry.DataBlk, true);
69414184Sgabeblack@google.com    cache_entry.Dirty := true;
69514184Sgabeblack@google.com  }
69614184Sgabeblack@google.com
69714184Sgabeblack@google.com  action(i_allocateTBE, "i", desc="Allocate TBE") {
69814184Sgabeblack@google.com    check_allocate(TBEs);
69914184Sgabeblack@google.com    TBEs.allocate(address);
70014184Sgabeblack@google.com    set_tbe(TBEs[address]);
70114184Sgabeblack@google.com    assert(is_valid(cache_entry));
70214184Sgabeblack@google.com    tbe.DataBlk := cache_entry.DataBlk; // Data only used for writebacks
70314184Sgabeblack@google.com    tbe.Dirty := cache_entry.Dirty;
70414184Sgabeblack@google.com  }
70514184Sgabeblack@google.com
70614184Sgabeblack@google.com  action(j_popTriggerQueue, "j", desc="Pop trigger queue.") {
70714184Sgabeblack@google.com    triggerQueue_in.dequeue(clockEdge());
70814184Sgabeblack@google.com  }
70914184Sgabeblack@google.com
71014184Sgabeblack@google.com  action(jj_unsetUseTimer, "\jj", desc="Unset use timer.") {
71114184Sgabeblack@google.com    useTimerTable.unset(address);
71214184Sgabeblack@google.com  }
71314184Sgabeblack@google.com
71414184Sgabeblack@google.com  action(k_popMandatoryQueue, "k", desc="Pop mandatory queue.") {
71514184Sgabeblack@google.com    mandatoryQueue_in.dequeue(clockEdge());
71614184Sgabeblack@google.com  }
71714184Sgabeblack@google.com
71814184Sgabeblack@google.com  action(l_popForwardQueue, "l", desc="Pop forwarded request queue.") {
71914184Sgabeblack@google.com    requestNetwork_in.dequeue(clockEdge());
72014184Sgabeblack@google.com  }
72114184Sgabeblack@google.com
72214184Sgabeblack@google.com  action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") {
72314184Sgabeblack@google.com    peek(responseToL1Cache_in, ResponseMsg) {
72414184Sgabeblack@google.com      assert(is_valid(tbe));
72514184Sgabeblack@google.com      DPRINTF(RubySlicc, "L1 decrementNumberOfMessages: %d\n", in_msg.Acks);
72614184Sgabeblack@google.com      tbe.NumPendingMsgs := tbe.NumPendingMsgs - in_msg.Acks;
72714184Sgabeblack@google.com    }
72814184Sgabeblack@google.com  }
72914184Sgabeblack@google.com
73014184Sgabeblack@google.com  action(mm_decrementNumberOfMessages, "\m", desc="Decrement the number of messages for which we're waiting") {
73114184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
73214184Sgabeblack@google.com      assert(is_valid(tbe));
73314184Sgabeblack@google.com      tbe.NumPendingMsgs := tbe.NumPendingMsgs - in_msg.Acks;
73414184Sgabeblack@google.com    }
73514184Sgabeblack@google.com  }
73614184Sgabeblack@google.com
73714184Sgabeblack@google.com  action(n_popResponseQueue, "n", desc="Pop response queue") {
73814184Sgabeblack@google.com    responseToL1Cache_in.dequeue(clockEdge());
73914184Sgabeblack@google.com  }
74014184Sgabeblack@google.com
74114184Sgabeblack@google.com  action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") {
74214184Sgabeblack@google.com    assert(is_valid(tbe));
74314184Sgabeblack@google.com    if (tbe.NumPendingMsgs == 0) {
74414184Sgabeblack@google.com      enqueue(triggerQueue_out, TriggerMsg) {
74514184Sgabeblack@google.com        out_msg.addr := address;
74614184Sgabeblack@google.com        out_msg.Type := TriggerType:ALL_ACKS;
74714184Sgabeblack@google.com      }
74814184Sgabeblack@google.com    }
74914184Sgabeblack@google.com  }
75014184Sgabeblack@google.com
75114184Sgabeblack@google.com  action(o_scheduleUseTimeout, "oo", desc="Schedule a use timeout.") {
75214184Sgabeblack@google.com    useTimerTable.set(address,
75314184Sgabeblack@google.com                      clockEdge() + cyclesToTicks(use_timeout_latency));
75414184Sgabeblack@google.com  }
75514184Sgabeblack@google.com
75614184Sgabeblack@google.com  action(ub_dmaUnblockL2Cache, "ub", desc="Send dma ack to l2 cache") {
75714184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
75814184Sgabeblack@google.com      enqueue(responseNetwork_out, ResponseMsg, response_latency) {
75914184Sgabeblack@google.com        out_msg.addr := address;
76014184Sgabeblack@google.com        out_msg.Type := CoherenceResponseType:DMA_ACK;
76114184Sgabeblack@google.com        out_msg.Sender := machineID;
76214184Sgabeblack@google.com        out_msg.SenderMachine := MachineType:L1Cache;
76314184Sgabeblack@google.com        out_msg.Destination.add(mapAddressToMachine(address,
76414184Sgabeblack@google.com                                                    MachineType:L2Cache));
76514184Sgabeblack@google.com        out_msg.Dirty := false;
76614184Sgabeblack@google.com        out_msg.Acks := 1;
76714184Sgabeblack@google.com        out_msg.MessageSize := MessageSizeType:Response_Control;
76814184Sgabeblack@google.com      }
76914184Sgabeblack@google.com    }
77014184Sgabeblack@google.com  }
77114184Sgabeblack@google.com
77214184Sgabeblack@google.com  action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") {
77314184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
77414184Sgabeblack@google.com      assert(is_valid(tbe));
77514184Sgabeblack@google.com      if (in_msg.RequestorMachine == MachineType:L1Cache ||
77614184Sgabeblack@google.com          in_msg.RequestorMachine == MachineType:DMA) {
77714184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
77814184Sgabeblack@google.com          out_msg.addr := address;
77914184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA;
78014184Sgabeblack@google.com          out_msg.Sender := machineID;
78114184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
78214184Sgabeblack@google.com          out_msg.Destination.add(in_msg.Requestor);
78314184Sgabeblack@google.com          out_msg.DataBlk := tbe.DataBlk;
78414184Sgabeblack@google.com          // out_msg.Dirty := tbe.Dirty;
78514184Sgabeblack@google.com          out_msg.Dirty := false;
78614184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
78714184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
78814184Sgabeblack@google.com        }
78914184Sgabeblack@google.com      }
79014184Sgabeblack@google.com      else {
79114184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
79214184Sgabeblack@google.com          out_msg.addr := address;
79314184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA;
79414184Sgabeblack@google.com          out_msg.Sender := machineID;
79514184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
79614184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address,
79714184Sgabeblack@google.com                                                      MachineType:L2Cache));
79814184Sgabeblack@google.com          out_msg.DataBlk := tbe.DataBlk;
79914184Sgabeblack@google.com          // out_msg.Dirty := tbe.Dirty;
80014184Sgabeblack@google.com          out_msg.Dirty := false;
80114184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
80214184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Data;
80314184Sgabeblack@google.com        }
80414184Sgabeblack@google.com      }
80514184Sgabeblack@google.com    }
80614184Sgabeblack@google.com  }
80714184Sgabeblack@google.com
80814184Sgabeblack@google.com  action(q_sendExclusiveDataFromTBEToCache, "qq", desc="Send data from TBE to cache") {
80914184Sgabeblack@google.com    peek(requestNetwork_in, RequestMsg) {
81014184Sgabeblack@google.com      assert(is_valid(tbe));
81114184Sgabeblack@google.com      if (in_msg.RequestorMachine == MachineType:L1Cache) {
81214184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
81314184Sgabeblack@google.com          out_msg.addr := address;
81414184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
81514184Sgabeblack@google.com          out_msg.Sender := machineID;
81614184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
81714184Sgabeblack@google.com          out_msg.Destination.add(in_msg.Requestor);
81814184Sgabeblack@google.com          out_msg.DataBlk := tbe.DataBlk;
81914184Sgabeblack@google.com          out_msg.Dirty := tbe.Dirty;
82014184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
82114184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
82214184Sgabeblack@google.com        }
82314184Sgabeblack@google.com      }
82414184Sgabeblack@google.com      else {
82514184Sgabeblack@google.com        enqueue(responseNetwork_out, ResponseMsg, response_latency) {
82614184Sgabeblack@google.com          out_msg.addr := address;
82714184Sgabeblack@google.com          out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
82814184Sgabeblack@google.com          out_msg.Sender := machineID;
82914184Sgabeblack@google.com          out_msg.SenderMachine := MachineType:L1Cache;
83014184Sgabeblack@google.com          out_msg.Destination.add(mapAddressToMachine(address,
83114184Sgabeblack@google.com                                                      MachineType:L2Cache));
83214184Sgabeblack@google.com          out_msg.DataBlk := tbe.DataBlk;
83314184Sgabeblack@google.com          out_msg.Dirty := tbe.Dirty;
83414184Sgabeblack@google.com          out_msg.Acks := in_msg.Acks;
83514184Sgabeblack@google.com          out_msg.MessageSize := MessageSizeType:Response_Data;
83614184Sgabeblack@google.com        }
83714184Sgabeblack@google.com      }
83814184Sgabeblack@google.com    }
83914184Sgabeblack@google.com  }
84014184Sgabeblack@google.com
84114184Sgabeblack@google.com  // L2 will usually request data for a writeback
84214184Sgabeblack@google.com  action(qq_sendWBDataFromTBEToL2, "\q", desc="Send data from TBE to L2") {
84314184Sgabeblack@google.com    enqueue(requestNetwork_out, RequestMsg, request_latency) {
84414184Sgabeblack@google.com      assert(is_valid(tbe));
84514184Sgabeblack@google.com      out_msg.addr := address;
84614184Sgabeblack@google.com      out_msg.Requestor := machineID;
84714184Sgabeblack@google.com      out_msg.RequestorMachine := MachineType:L1Cache;
84814184Sgabeblack@google.com      out_msg.Destination.add(mapAddressToMachine(address,
84914184Sgabeblack@google.com                                                  MachineType:L2Cache));
85014184Sgabeblack@google.com      if (tbe.Dirty) {
85114184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:WRITEBACK_DIRTY_DATA;
85214184Sgabeblack@google.com      } else {
85314184Sgabeblack@google.com        out_msg.Type := CoherenceRequestType:WRITEBACK_CLEAN_DATA;
85414184Sgabeblack@google.com      }
85514184Sgabeblack@google.com      out_msg.DataBlk := tbe.DataBlk;
85614184Sgabeblack@google.com      out_msg.MessageSize := MessageSizeType:Writeback_Data;
85714184Sgabeblack@google.com    }
85814184Sgabeblack@google.com  }
85914184Sgabeblack@google.com
86014184Sgabeblack@google.com  action(s_deallocateTBE, "s", desc="Deallocate TBE") {
86114184Sgabeblack@google.com    TBEs.deallocate(address);
86214184Sgabeblack@google.com    unset_tbe();
86314184Sgabeblack@google.com  }
86414184Sgabeblack@google.com
86514184Sgabeblack@google.com  action(u_writeDataToCache, "u", desc="Write data to cache") {
86614184Sgabeblack@google.com    peek(responseToL1Cache_in, ResponseMsg) {
86714184Sgabeblack@google.com      assert(is_valid(cache_entry));
86814184Sgabeblack@google.com      cache_entry.DataBlk := in_msg.DataBlk;
86914184Sgabeblack@google.com      cache_entry.Dirty := in_msg.Dirty;
87014184Sgabeblack@google.com
87114184Sgabeblack@google.com      if (in_msg.Type == CoherenceResponseType:DATA) {
87214184Sgabeblack@google.com        //assert(in_msg.Dirty == false);
87314184Sgabeblack@google.com      }
87414184Sgabeblack@google.com    }
87514184Sgabeblack@google.com  }
87614184Sgabeblack@google.com
87714184Sgabeblack@google.com  action(kk_deallocateL1CacheBlock, "\k", desc="Deallocate cache block.  Sets the cache to invalid, allowing a replacement in parallel with a fetch.") {
87814184Sgabeblack@google.com    if (L1Dcache.isTagPresent(address)) {
87914184Sgabeblack@google.com      L1Dcache.deallocate(address);
88014184Sgabeblack@google.com    } else {
88114184Sgabeblack@google.com      L1Icache.deallocate(address);
88214184Sgabeblack@google.com    }
88314184Sgabeblack@google.com    unset_cache_entry();
88414184Sgabeblack@google.com  }
88514184Sgabeblack@google.com
88614184Sgabeblack@google.com  action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
88714184Sgabeblack@google.com    if ((is_invalid(cache_entry))) {
88814184Sgabeblack@google.com      set_cache_entry(L1Dcache.allocate(address, new Entry));
88914184Sgabeblack@google.com    }
89014184Sgabeblack@google.com  }
89114184Sgabeblack@google.com
89214184Sgabeblack@google.com  action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") {
89314184Sgabeblack@google.com    if ((is_invalid(cache_entry))) {
89414184Sgabeblack@google.com      set_cache_entry(L1Icache.allocate(address, new Entry));
89514184Sgabeblack@google.com    }
89614184Sgabeblack@google.com  }
89714184Sgabeblack@google.com
89814184Sgabeblack@google.com  action(forward_eviction_to_cpu, "\cc", desc="sends eviction information to the processor") {
89914184Sgabeblack@google.com    if (send_evictions) {
90014184Sgabeblack@google.com      DPRINTF(RubySlicc, "Sending invalidation for %#x to the CPU\n", address);
90114184Sgabeblack@google.com      sequencer.evictionCallback(address);
90214184Sgabeblack@google.com    }
90314184Sgabeblack@google.com  }
90414184Sgabeblack@google.com
90514184Sgabeblack@google.com  action(uu_profileInstMiss, "\uim", desc="Profile the demand miss") {
90614184Sgabeblack@google.com      ++L1Icache.demand_misses;
90714184Sgabeblack@google.com  }
90814184Sgabeblack@google.com
90914184Sgabeblack@google.com  action(uu_profileInstHit, "\uih", desc="Profile the demand hit") {
91014184Sgabeblack@google.com      ++L1Icache.demand_hits;
91114184Sgabeblack@google.com  }
91214184Sgabeblack@google.com
91314184Sgabeblack@google.com  action(uu_profileDataMiss, "\udm", desc="Profile the demand miss") {
91414184Sgabeblack@google.com      ++L1Dcache.demand_misses;
91514184Sgabeblack@google.com  }
91614184Sgabeblack@google.com
91714184Sgabeblack@google.com  action(uu_profileDataHit, "\udh", desc="Profile the demand hit") {
91814184Sgabeblack@google.com      ++L1Dcache.demand_hits;
91914184Sgabeblack@google.com  }
92014184Sgabeblack@google.com
92114184Sgabeblack@google.com  action(z_recycleRequestQueue, "z", desc="Send the head of the mandatory queue to the back of the queue.") {
92214184Sgabeblack@google.com    requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
92314184Sgabeblack@google.com  }
92414184Sgabeblack@google.com
92514184Sgabeblack@google.com  action(zz_recycleMandatoryQueue, "\z", desc="Send the head of the mandatory queue to the back of the queue.") {
92614184Sgabeblack@google.com    mandatoryQueue_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
92714184Sgabeblack@google.com  }
92814184Sgabeblack@google.com
92914184Sgabeblack@google.com  //*****************************************************
93014184Sgabeblack@google.com  // TRANSITIONS
93114184Sgabeblack@google.com  //*****************************************************
93214184Sgabeblack@google.com
93314184Sgabeblack@google.com  // Transitions for Load/Store/L2_Replacement from transient states
93414184Sgabeblack@google.com  transition({IM, SM, OM, IS, OI, SI, MI, II}, {Store, L1_Replacement}) {
93514184Sgabeblack@google.com    zz_recycleMandatoryQueue;
93614184Sgabeblack@google.com  }
93714184Sgabeblack@google.com
93814184Sgabeblack@google.com  transition({M_W, MM_W}, L1_Replacement) {
93914184Sgabeblack@google.com    zz_recycleMandatoryQueue;
94014184Sgabeblack@google.com  }
94114184Sgabeblack@google.com
94214184Sgabeblack@google.com  transition({M_W, MM_W}, {Fwd_GETS, Fwd_DMA, Fwd_GETX, Own_GETX, Inv}) {
94314184Sgabeblack@google.com    z_recycleRequestQueue;
94414184Sgabeblack@google.com  }
94514184Sgabeblack@google.com
94614184Sgabeblack@google.com  transition({IM, IS, OI, MI, SI, II}, {Load, Ifetch}) {
94714184Sgabeblack@google.com    zz_recycleMandatoryQueue;
94814184Sgabeblack@google.com  }
94914184Sgabeblack@google.com
95014184Sgabeblack@google.com  // Transitions from Idle
95114184Sgabeblack@google.com  transition(I, Load, IS) {
95214184Sgabeblack@google.com    ii_allocateL1DCacheBlock;
95314184Sgabeblack@google.com    i_allocateTBE;
95414184Sgabeblack@google.com    a_issueGETS;
95514184Sgabeblack@google.com    uu_profileDataMiss;
95614184Sgabeblack@google.com    k_popMandatoryQueue;
95714184Sgabeblack@google.com  }
95814184Sgabeblack@google.com
95914184Sgabeblack@google.com  transition(I, Ifetch, IS) {
96014184Sgabeblack@google.com    jj_allocateL1ICacheBlock;
96114184Sgabeblack@google.com    i_allocateTBE;
96214184Sgabeblack@google.com    a_issueGETS;
96314184Sgabeblack@google.com    uu_profileInstMiss;
96414184Sgabeblack@google.com    k_popMandatoryQueue;
96514184Sgabeblack@google.com  }
96614184Sgabeblack@google.com
96714184Sgabeblack@google.com  transition(I, Store, IM) {
96814184Sgabeblack@google.com    ii_allocateL1DCacheBlock;
96914184Sgabeblack@google.com    i_allocateTBE;
97014184Sgabeblack@google.com    b_issueGETX;
97114184Sgabeblack@google.com    uu_profileDataMiss;
97214184Sgabeblack@google.com    k_popMandatoryQueue;
97314184Sgabeblack@google.com  }
97414184Sgabeblack@google.com
97514184Sgabeblack@google.com  transition(I, L1_Replacement) {
97614184Sgabeblack@google.com    kk_deallocateL1CacheBlock;
97714184Sgabeblack@google.com  }
97814184Sgabeblack@google.com
97914184Sgabeblack@google.com  transition(I, Inv) {
98014184Sgabeblack@google.com    f_sendAck;
98114184Sgabeblack@google.com    l_popForwardQueue;
98214184Sgabeblack@google.com  }
98314184Sgabeblack@google.com
98414184Sgabeblack@google.com  transition({S, SM, O, OM, MM, MM_W, M, M_W}, Load) {
98514184Sgabeblack@google.com    h_load_hit;
98614184Sgabeblack@google.com    uu_profileDataHit;
98714184Sgabeblack@google.com    k_popMandatoryQueue;
98814184Sgabeblack@google.com  }
98914184Sgabeblack@google.com
99014184Sgabeblack@google.com  transition({S, SM, O, OM, MM, MM_W, M, M_W}, Ifetch) {
99114184Sgabeblack@google.com    h_ifetch_hit;
99214184Sgabeblack@google.com    uu_profileInstHit;
99314184Sgabeblack@google.com    k_popMandatoryQueue;
99414184Sgabeblack@google.com  }
99514184Sgabeblack@google.com
99614184Sgabeblack@google.com  // Transitions from Shared
99714184Sgabeblack@google.com  transition(S, Store, SM) {
99814184Sgabeblack@google.com    i_allocateTBE;
99914184Sgabeblack@google.com    b_issueGETX;
100014184Sgabeblack@google.com    uu_profileDataMiss;
100114184Sgabeblack@google.com    k_popMandatoryQueue;
100214184Sgabeblack@google.com  }
100314184Sgabeblack@google.com
100414184Sgabeblack@google.com  transition(S, L1_Replacement, SI) {
100514184Sgabeblack@google.com    i_allocateTBE;
100614184Sgabeblack@google.com    dd_issuePUTS;
100714184Sgabeblack@google.com    forward_eviction_to_cpu;
100814184Sgabeblack@google.com    kk_deallocateL1CacheBlock;
100914184Sgabeblack@google.com  }
101014184Sgabeblack@google.com
101114184Sgabeblack@google.com  transition(S, Inv, I) {
101214184Sgabeblack@google.com    f_sendAck;
101314184Sgabeblack@google.com    forward_eviction_to_cpu;
101414184Sgabeblack@google.com    l_popForwardQueue;
101514184Sgabeblack@google.com  }
101614184Sgabeblack@google.com
101714184Sgabeblack@google.com  transition(S, Fwd_GETS) {
101814184Sgabeblack@google.com    e_sendData;
101914184Sgabeblack@google.com    l_popForwardQueue;
102014184Sgabeblack@google.com  }
102114184Sgabeblack@google.com
102214184Sgabeblack@google.com  transition(S, Fwd_DMA) {
102314184Sgabeblack@google.com    e_sendData;
102414184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
102514184Sgabeblack@google.com    l_popForwardQueue;
102614184Sgabeblack@google.com  }
102714184Sgabeblack@google.com
102814184Sgabeblack@google.com  // Transitions from Owned
102914184Sgabeblack@google.com  transition(O, Store, OM) {
103014184Sgabeblack@google.com    i_allocateTBE;
103114184Sgabeblack@google.com    b_issueGETX;
103214184Sgabeblack@google.com    uu_profileDataMiss;
103314184Sgabeblack@google.com    k_popMandatoryQueue;
103414184Sgabeblack@google.com  }
103514184Sgabeblack@google.com
103614184Sgabeblack@google.com  transition(O, L1_Replacement, OI) {
103714184Sgabeblack@google.com    i_allocateTBE;
103814184Sgabeblack@google.com    dd_issuePUTO;
103914184Sgabeblack@google.com    forward_eviction_to_cpu;
104014184Sgabeblack@google.com    kk_deallocateL1CacheBlock;
104114184Sgabeblack@google.com  }
104214184Sgabeblack@google.com
104314184Sgabeblack@google.com  transition(O, Fwd_GETX, I) {
104414184Sgabeblack@google.com    ee_sendDataExclusive;
104514184Sgabeblack@google.com    forward_eviction_to_cpu;
104614184Sgabeblack@google.com    l_popForwardQueue;
104714184Sgabeblack@google.com  }
104814184Sgabeblack@google.com
104914184Sgabeblack@google.com  transition(O, Fwd_GETS) {
105014184Sgabeblack@google.com    e_sendData;
105114184Sgabeblack@google.com    l_popForwardQueue;
105214184Sgabeblack@google.com  }
105314184Sgabeblack@google.com
105414184Sgabeblack@google.com  transition(O, Fwd_DMA) {
105514184Sgabeblack@google.com    e_sendData;
105614184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
105714184Sgabeblack@google.com    l_popForwardQueue;
105814184Sgabeblack@google.com  }
105914184Sgabeblack@google.com
106014184Sgabeblack@google.com  // Transitions from MM
106114184Sgabeblack@google.com  transition({MM, MM_W}, Store) {
106214184Sgabeblack@google.com    hh_store_hit;
106314184Sgabeblack@google.com    uu_profileDataHit;
106414184Sgabeblack@google.com    k_popMandatoryQueue;
106514184Sgabeblack@google.com  }
106614184Sgabeblack@google.com
106714184Sgabeblack@google.com  transition(MM, L1_Replacement, MI) {
106814184Sgabeblack@google.com    i_allocateTBE;
106914184Sgabeblack@google.com    d_issuePUTX;
107014184Sgabeblack@google.com    forward_eviction_to_cpu;
107114184Sgabeblack@google.com    kk_deallocateL1CacheBlock;
107214184Sgabeblack@google.com  }
107314184Sgabeblack@google.com
107414184Sgabeblack@google.com  transition(MM, Fwd_GETX, I) {
107514184Sgabeblack@google.com    ee_sendDataExclusive;
107614184Sgabeblack@google.com    forward_eviction_to_cpu;
107714184Sgabeblack@google.com    l_popForwardQueue;
107814184Sgabeblack@google.com  }
107914184Sgabeblack@google.com
108014184Sgabeblack@google.com  transition(MM, Fwd_GETS, I) {
108114184Sgabeblack@google.com    ee_sendDataExclusive;
108214184Sgabeblack@google.com    forward_eviction_to_cpu;
108314184Sgabeblack@google.com    l_popForwardQueue;
108414184Sgabeblack@google.com  }
108514184Sgabeblack@google.com
108614184Sgabeblack@google.com  transition(MM, Fwd_DMA, MM) {
108714184Sgabeblack@google.com    e_sendData;
108814184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
108914184Sgabeblack@google.com    l_popForwardQueue;
109014184Sgabeblack@google.com  }
109114184Sgabeblack@google.com
109214184Sgabeblack@google.com  // Transitions from M
109314184Sgabeblack@google.com  transition(M, Store, MM) {
109414184Sgabeblack@google.com    hh_store_hit;
109514184Sgabeblack@google.com    uu_profileDataHit;
109614184Sgabeblack@google.com    k_popMandatoryQueue;
109714184Sgabeblack@google.com  }
109814184Sgabeblack@google.com
109914184Sgabeblack@google.com  transition(M_W, Store, MM_W) {
110014184Sgabeblack@google.com    hh_store_hit;
110114184Sgabeblack@google.com    uu_profileDataHit;
110214184Sgabeblack@google.com    k_popMandatoryQueue;
110314184Sgabeblack@google.com  }
110414184Sgabeblack@google.com
110514184Sgabeblack@google.com  transition(M, L1_Replacement, MI) {
110614184Sgabeblack@google.com    i_allocateTBE;
110714184Sgabeblack@google.com    d_issuePUTX;
110814184Sgabeblack@google.com    forward_eviction_to_cpu;
110914184Sgabeblack@google.com    kk_deallocateL1CacheBlock;
111014184Sgabeblack@google.com  }
111114184Sgabeblack@google.com
111214184Sgabeblack@google.com  transition(M, Fwd_GETX, I) {
111314184Sgabeblack@google.com    // e_sendData;
111414184Sgabeblack@google.com    ee_sendDataExclusive;
111514184Sgabeblack@google.com    forward_eviction_to_cpu;
111614184Sgabeblack@google.com    l_popForwardQueue;
111714184Sgabeblack@google.com  }
111814184Sgabeblack@google.com
111914184Sgabeblack@google.com  transition(M, Fwd_GETS, O) {
112014184Sgabeblack@google.com    e_sendData;
112114184Sgabeblack@google.com    l_popForwardQueue;
112214184Sgabeblack@google.com  }
112314184Sgabeblack@google.com
112414184Sgabeblack@google.com  transition(M, Fwd_DMA) {
112514184Sgabeblack@google.com    e_sendData;
112614184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
112714184Sgabeblack@google.com    l_popForwardQueue;
112814184Sgabeblack@google.com  }
112914184Sgabeblack@google.com
113014184Sgabeblack@google.com  // Transitions from IM
113114184Sgabeblack@google.com
113214184Sgabeblack@google.com  transition(IM, Inv) {
113314184Sgabeblack@google.com    f_sendAck;
113414184Sgabeblack@google.com    l_popForwardQueue;
113514184Sgabeblack@google.com  }
113614184Sgabeblack@google.com
113714184Sgabeblack@google.com  transition(IM, Ack) {
113814184Sgabeblack@google.com    m_decrementNumberOfMessages;
113914184Sgabeblack@google.com    o_checkForCompletion;
114014184Sgabeblack@google.com    n_popResponseQueue;
114114184Sgabeblack@google.com  }
114214184Sgabeblack@google.com
114314184Sgabeblack@google.com  transition(IM, {Exclusive_Data, Data}, OM) {
114414184Sgabeblack@google.com    u_writeDataToCache;
114514184Sgabeblack@google.com    m_decrementNumberOfMessages;
114614184Sgabeblack@google.com    o_checkForCompletion;
114714184Sgabeblack@google.com    n_popResponseQueue;
114814184Sgabeblack@google.com  }
114914184Sgabeblack@google.com
115014184Sgabeblack@google.com  // Transitions from SM
115114184Sgabeblack@google.com  transition(SM, Inv, IM) {
115214184Sgabeblack@google.com    f_sendAck;
115314184Sgabeblack@google.com    forward_eviction_to_cpu;
115414184Sgabeblack@google.com    l_popForwardQueue;
115514184Sgabeblack@google.com  }
115614184Sgabeblack@google.com
115714184Sgabeblack@google.com  transition(SM, Ack) {
115814184Sgabeblack@google.com    m_decrementNumberOfMessages;
115914184Sgabeblack@google.com    o_checkForCompletion;
116014184Sgabeblack@google.com    n_popResponseQueue;
116114184Sgabeblack@google.com  }
116214184Sgabeblack@google.com
116314184Sgabeblack@google.com  transition(SM, {Data, Exclusive_Data}, OM) {
116414184Sgabeblack@google.com    // v_writeDataToCacheVerify;
116514184Sgabeblack@google.com    m_decrementNumberOfMessages;
116614184Sgabeblack@google.com    o_checkForCompletion;
116714184Sgabeblack@google.com    n_popResponseQueue;
116814184Sgabeblack@google.com  }
116914184Sgabeblack@google.com
117014184Sgabeblack@google.com  transition(SM, Fwd_GETS) {
117114184Sgabeblack@google.com    e_sendData;
117214184Sgabeblack@google.com    l_popForwardQueue;
117314184Sgabeblack@google.com  }
117414184Sgabeblack@google.com
117514184Sgabeblack@google.com  transition(SM, Fwd_DMA) {
117614184Sgabeblack@google.com    e_sendData;
117714184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
117814184Sgabeblack@google.com    l_popForwardQueue;
117914184Sgabeblack@google.com  }
118014184Sgabeblack@google.com
118114184Sgabeblack@google.com  // Transitions from OM
118214184Sgabeblack@google.com  transition(OM, Own_GETX) {
118314184Sgabeblack@google.com    mm_decrementNumberOfMessages;
118414184Sgabeblack@google.com    o_checkForCompletion;
118514184Sgabeblack@google.com    l_popForwardQueue;
118614184Sgabeblack@google.com  }
118714184Sgabeblack@google.com
118814184Sgabeblack@google.com
118914184Sgabeblack@google.com  // transition(OM, Fwd_GETX, OMF) {
119014184Sgabeblack@google.com  transition(OM, Fwd_GETX, IM) {
119114184Sgabeblack@google.com    ee_sendDataExclusive;
119214184Sgabeblack@google.com    l_popForwardQueue;
119314184Sgabeblack@google.com  }
119414184Sgabeblack@google.com
119514184Sgabeblack@google.com  transition(OM, Fwd_GETS) {
119614184Sgabeblack@google.com    e_sendData;
119714184Sgabeblack@google.com    l_popForwardQueue;
119814184Sgabeblack@google.com  }
119914184Sgabeblack@google.com
120014184Sgabeblack@google.com  transition(OM, Fwd_DMA) {
120114184Sgabeblack@google.com    e_sendData;
120214184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
120314184Sgabeblack@google.com    l_popForwardQueue;
120414184Sgabeblack@google.com  }
120514184Sgabeblack@google.com
120614184Sgabeblack@google.com  //transition({OM, OMF}, Ack) {
120714184Sgabeblack@google.com  transition(OM, Ack) {
120814184Sgabeblack@google.com    m_decrementNumberOfMessages;
120914184Sgabeblack@google.com    o_checkForCompletion;
121014184Sgabeblack@google.com    n_popResponseQueue;
121114184Sgabeblack@google.com  }
121214184Sgabeblack@google.com
121314184Sgabeblack@google.com  transition(OM, All_acks, MM_W) {
121414184Sgabeblack@google.com    xx_store_hit;
121514184Sgabeblack@google.com    gg_sendUnblockExclusive;
121614184Sgabeblack@google.com    s_deallocateTBE;
121714184Sgabeblack@google.com    o_scheduleUseTimeout;
121814184Sgabeblack@google.com    j_popTriggerQueue;
121914184Sgabeblack@google.com  }
122014184Sgabeblack@google.com
122114184Sgabeblack@google.com  transition(MM_W, Use_Timeout, MM) {
122214184Sgabeblack@google.com    jj_unsetUseTimer;
122314184Sgabeblack@google.com  }
122414184Sgabeblack@google.com
122514184Sgabeblack@google.com  // Transitions from IS
122614184Sgabeblack@google.com
122714184Sgabeblack@google.com  transition(IS, Inv) {
122814184Sgabeblack@google.com    f_sendAck;
122914184Sgabeblack@google.com    l_popForwardQueue;
123014184Sgabeblack@google.com  }
123114184Sgabeblack@google.com
123214184Sgabeblack@google.com  transition(IS, Data, S) {
123314184Sgabeblack@google.com    u_writeDataToCache;
123414184Sgabeblack@google.com    m_decrementNumberOfMessages;
123514184Sgabeblack@google.com    hx_load_hit;
123614184Sgabeblack@google.com    g_sendUnblock;
123714184Sgabeblack@google.com    s_deallocateTBE;
123814184Sgabeblack@google.com    n_popResponseQueue;
123914184Sgabeblack@google.com  }
124014184Sgabeblack@google.com
124114184Sgabeblack@google.com  transition(IS, Exclusive_Data, M_W) {
124214184Sgabeblack@google.com    u_writeDataToCache;
124314184Sgabeblack@google.com    m_decrementNumberOfMessages;
124414184Sgabeblack@google.com    hx_load_hit;
124514184Sgabeblack@google.com    gg_sendUnblockExclusive;
124614184Sgabeblack@google.com    o_scheduleUseTimeout;
124714184Sgabeblack@google.com    s_deallocateTBE;
124814184Sgabeblack@google.com    n_popResponseQueue;
124914184Sgabeblack@google.com  }
125014184Sgabeblack@google.com
125114184Sgabeblack@google.com  transition(M_W, Use_Timeout, M) {
125214184Sgabeblack@google.com    jj_unsetUseTimer;
125314184Sgabeblack@google.com  }
125414184Sgabeblack@google.com
125514184Sgabeblack@google.com  // Transitions from OI/MI
125614184Sgabeblack@google.com
125714184Sgabeblack@google.com  transition(MI, Fwd_GETS, OI) {
125814184Sgabeblack@google.com    q_sendDataFromTBEToCache;
125914184Sgabeblack@google.com    l_popForwardQueue;
126014184Sgabeblack@google.com  }
126114184Sgabeblack@google.com
126214184Sgabeblack@google.com  transition(MI, Fwd_DMA) {
126314184Sgabeblack@google.com    q_sendDataFromTBEToCache;
126414184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
126514184Sgabeblack@google.com    l_popForwardQueue;
126614184Sgabeblack@google.com  }
126714184Sgabeblack@google.com
126814184Sgabeblack@google.com  transition(MI, Fwd_GETX, II) {
126914184Sgabeblack@google.com    q_sendExclusiveDataFromTBEToCache;
127014184Sgabeblack@google.com    l_popForwardQueue;
127114184Sgabeblack@google.com  }
127214184Sgabeblack@google.com
127314184Sgabeblack@google.com  transition({SI, OI}, Fwd_GETS) {
127414184Sgabeblack@google.com    q_sendDataFromTBEToCache;
127514184Sgabeblack@google.com    l_popForwardQueue;
127614184Sgabeblack@google.com  }
127714184Sgabeblack@google.com
127814184Sgabeblack@google.com  transition({SI, OI}, Fwd_DMA) {
127914184Sgabeblack@google.com    q_sendDataFromTBEToCache;
128014184Sgabeblack@google.com    ub_dmaUnblockL2Cache;
128114184Sgabeblack@google.com    l_popForwardQueue;
128214184Sgabeblack@google.com  }
128314184Sgabeblack@google.com
128414184Sgabeblack@google.com  transition(OI, Fwd_GETX, II) {
128514184Sgabeblack@google.com    q_sendExclusiveDataFromTBEToCache;
128614184Sgabeblack@google.com    l_popForwardQueue;
128714184Sgabeblack@google.com  }
128814184Sgabeblack@google.com
128914184Sgabeblack@google.com  transition({SI, OI, MI}, Writeback_Ack_Data, I) {
129014184Sgabeblack@google.com    qq_sendWBDataFromTBEToL2;  // always send data
129114184Sgabeblack@google.com    s_deallocateTBE;
129214184Sgabeblack@google.com    n_popResponseQueue;
129314184Sgabeblack@google.com  }
129414184Sgabeblack@google.com
129514184Sgabeblack@google.com  transition({SI, OI, MI}, Writeback_Ack, I) {
129614184Sgabeblack@google.com    g_sendUnblock;
129714184Sgabeblack@google.com    s_deallocateTBE;
129814184Sgabeblack@google.com    n_popResponseQueue;
129914184Sgabeblack@google.com  }
130014184Sgabeblack@google.com
130114184Sgabeblack@google.com  transition({MI, OI}, Writeback_Nack, OI) {
130214184Sgabeblack@google.com    // FIXME: This might cause deadlock by re-using the writeback
130314184Sgabeblack@google.com    // channel, we should handle this case differently.
130414184Sgabeblack@google.com    dd_issuePUTO;
130514184Sgabeblack@google.com    n_popResponseQueue;
130614184Sgabeblack@google.com  }
130714184Sgabeblack@google.com
130814184Sgabeblack@google.com  // Transitions from II
130914184Sgabeblack@google.com  transition(II, {Writeback_Ack, Writeback_Ack_Data}, I) {
131014184Sgabeblack@google.com    g_sendUnblock;
131114184Sgabeblack@google.com    s_deallocateTBE;
131214184Sgabeblack@google.com    n_popResponseQueue;
131314184Sgabeblack@google.com  }
131414184Sgabeblack@google.com
131514184Sgabeblack@google.com  // transition({II, SI}, Writeback_Nack, I) {
131614184Sgabeblack@google.com  transition(II, Writeback_Nack, I) {
131714184Sgabeblack@google.com    s_deallocateTBE;
131814184Sgabeblack@google.com    n_popResponseQueue;
131914184Sgabeblack@google.com  }
132014184Sgabeblack@google.com
132114184Sgabeblack@google.com  transition(SI, Writeback_Nack) {
132214184Sgabeblack@google.com    dd_issuePUTS;
132314184Sgabeblack@google.com    n_popResponseQueue;
132414184Sgabeblack@google.com  }
132514184Sgabeblack@google.com
132614184Sgabeblack@google.com  transition(II, Inv) {
132714184Sgabeblack@google.com    f_sendAck;
132814184Sgabeblack@google.com    l_popForwardQueue;
132914184Sgabeblack@google.com  }
133014184Sgabeblack@google.com
133114184Sgabeblack@google.com  transition(SI, Inv, II) {
133214184Sgabeblack@google.com    f_sendAck;
133314184Sgabeblack@google.com    l_popForwardQueue;
133414184Sgabeblack@google.com  }
133514184Sgabeblack@google.com}
1336