GPU_RfO-TCC.sm revision 14184
1803SN/A/*
21363SN/A * Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
3803SN/A * All rights reserved.
4803SN/A *
5803SN/A * For use for simulation and test purposes only
6803SN/A *
7803SN/A * Redistribution and use in source and binary forms, with or without
8803SN/A * modification, are permitted provided that the following conditions are met:
9803SN/A *
10803SN/A * 1. Redistributions of source code must retain the above copyright notice,
11803SN/A * this list of conditions and the following disclaimer.
12803SN/A *
13803SN/A * 2. Redistributions in binary form must reproduce the above copyright notice,
14803SN/A * this list of conditions and the following disclaimer in the documentation
15803SN/A * and/or other materials provided with the distribution.
16803SN/A *
17803SN/A * 3. Neither the name of the copyright holder nor the names of its
18803SN/A * contributors may be used to endorse or promote products derived from this
19803SN/A * software without specific prior written permission.
20803SN/A *
21803SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22803SN/A * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23803SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24803SN/A * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25803SN/A * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26803SN/A * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272665SN/A * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
282665SN/A * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
292665SN/A * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
302665SN/A * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31803SN/A * POSSIBILITY OF SUCH DAMAGE.
32768SN/A *
331730SN/A * Authors: Lisa Hsu
34773SN/A */
35768SN/A
36768SN/Amachine(MachineType:TCC, "TCC Cache")
37773SN/A : CacheMemory * L2cache;
38773SN/A   WireBuffer * w_reqToTCCDir;
39768SN/A   WireBuffer * w_respToTCCDir;
40768SN/A   WireBuffer * w_TCCUnblockToTCCDir;
41768SN/A   WireBuffer * w_reqToTCC;
42768SN/A   WireBuffer * w_probeToTCC;
43768SN/A   WireBuffer * w_respToTCC;
442542SN/A   int TCC_select_num_bits;
452542SN/A   Cycles l2_request_latency := 1;
463540Sgblack@eecs.umich.edu   Cycles l2_response_latency := 20;
473540Sgblack@eecs.umich.edu
483540Sgblack@eecs.umich.edu  // To the general response network
493540Sgblack@eecs.umich.edu  MessageBuffer * responseFromTCC, network="To", virtual_network="3", vnet_type="response";
503348SN/A
513348SN/A  // From the general response network
522542SN/A  MessageBuffer * responseToTCC, network="From", virtual_network="3", vnet_type="response";
53768SN/A
542542SN/A{
55768SN/A  // EVENTS
56768SN/A  enumeration(Event, desc="TCC Events") {
572107SN/A    // Requests coming from the Cores
582107SN/A    RdBlk,                  desc="CPU RdBlk event";
59773SN/A    RdBlkM,                 desc="CPU RdBlkM event";
603932Sbinkertn@umich.edu    RdBlkS,                 desc="CPU RdBlkS event";
613932Sbinkertn@umich.edu    CtoD,                   desc="Change to Dirty request";
623932Sbinkertn@umich.edu    WrVicBlk,               desc="L1 Victim (dirty)";
631817SN/A    WrVicBlkShared,               desc="L1 Victim (dirty)";
641817SN/A    ClVicBlk,               desc="L1 Victim (clean)";
651817SN/A    ClVicBlkShared,               desc="L1 Victim (clean)";
661817SN/A
67773SN/A    CPUData,                      desc="WB data from CPU";
683943Sbinkertn@umich.edu    CPUDataShared,                desc="WB data from CPU, NBReqShared 1";
693943Sbinkertn@umich.edu    StaleWB,                desc="Stale WB, No data";
703943Sbinkertn@umich.edu
713943Sbinkertn@umich.edu    L2_Repl,             desc="L2 Replacement";
723943Sbinkertn@umich.edu
733932Sbinkertn@umich.edu    // Probes
743943Sbinkertn@umich.edu    PrbInvData,         desc="Invalidating probe, return dirty data";
753943Sbinkertn@umich.edu    PrbInv,             desc="Invalidating probe, no need to return data";
763943Sbinkertn@umich.edu    PrbShrData,         desc="Downgrading probe, return data";
773943Sbinkertn@umich.edu
783943Sbinkertn@umich.edu    // Coming from Memory Controller
793943Sbinkertn@umich.edu    WBAck,                     desc="ack from memory";
803932Sbinkertn@umich.edu
813932Sbinkertn@umich.edu    CancelWB,                   desc="Cancel WB from L2";
823932Sbinkertn@umich.edu  }
833943Sbinkertn@umich.edu
843943Sbinkertn@umich.edu  // STATES
853943Sbinkertn@umich.edu  state_declaration(State, desc="TCC State", default="TCC_State_I") {
863943Sbinkertn@umich.edu    M, AccessPermission:Read_Write, desc="Modified";  // No other cache has copy, memory stale
873943Sbinkertn@umich.edu    O, AccessPermission:Read_Only, desc="Owned";     // Correct most recent copy, others may exist in S
883943Sbinkertn@umich.edu    E, AccessPermission:Read_Write, desc="Exclusive"; // Correct, most recent, and only copy (and == Memory)
893932Sbinkertn@umich.edu    S, AccessPermission:Read_Only, desc="Shared";    // Correct, most recent. If no one in O, then == Memory
903943Sbinkertn@umich.edu    I, AccessPermission:Invalid, desc="Invalid";
913943Sbinkertn@umich.edu
923932Sbinkertn@umich.edu    I_M, AccessPermission:Busy, desc="Invalid, received WrVicBlk, sent Ack, waiting for Data";
933943Sbinkertn@umich.edu    I_O, AccessPermission:Busy, desc="Invalid, received WrVicBlk, sent Ack, waiting for Data";
941817SN/A    I_E, AccessPermission:Busy, desc="Invalid, receive ClVicBlk, sent Ack, waiting for Data";
951817SN/A    I_S, AccessPermission:Busy, desc="Invalid, receive ClVicBlk, sent Ack, waiting for Data";
961817SN/A    S_M, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to M";
972539SN/A    S_O, AccessPermission:Busy, desc="received WrVicBlkShared, sent Ack, waiting for Data, then go to O";
981817SN/A    S_E, AccessPermission:Busy, desc="Shared, received ClVicBlk, sent Ack, waiting for Data, then go to E";
992542SN/A    S_S, AccessPermission:Busy, desc="Shared, received ClVicBlk, sent Ack, waiting for Data, then go to S";
1002539SN/A    E_M, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to O";
1011817SN/A    E_O, AccessPermission:Busy, desc="received WrVicBlkShared, sent Ack, waiting for Data, then go to O";
1021817SN/A    E_E, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to O";
1031817SN/A    E_S, AccessPermission:Busy, desc="Shared, received WrVicBlk, sent Ack, waiting for Data";
1041817SN/A    O_M, AccessPermission:Busy, desc="...";
1051817SN/A    O_O, AccessPermission:Busy, desc="...";
1062539SN/A    O_E, AccessPermission:Busy, desc="...";
1071817SN/A    M_M, AccessPermission:Busy, desc="...";
1081817SN/A    M_O, AccessPermission:Busy, desc="...";
1092539SN/A    M_E, AccessPermission:Busy, desc="...";
1101817SN/A    M_S, AccessPermission:Busy, desc="...";
1111817SN/A    D_I, AccessPermission:Invalid,  desc="drop WB data on the floor when receive";
1121817SN/A    MOD_I, AccessPermission:Busy, desc="drop WB data on the floor, waiting for WBAck from Mem";
1132539SN/A    MO_I, AccessPermission:Busy, desc="M or O, received L2_Repl, waiting for WBAck from Mem";
1141817SN/A    ES_I, AccessPermission:Busy, desc="E or S, received L2_Repl, waiting for WBAck from Mem";
1152542SN/A    I_C, AccessPermission:Invalid, desc="sent cancel, just waiting to receive mem wb ack so nothing gets confused";
1161817SN/A  }
1171817SN/A
1182539SN/A  enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
1191817SN/A    DataArrayRead,    desc="Read the data array";
1201817SN/A    DataArrayWrite,   desc="Write the data array";
1212542SN/A    TagArrayRead,     desc="Read the data array";
1221817SN/A    TagArrayWrite,    desc="Write the data array";
1231817SN/A  }
1241817SN/A
1251817SN/A
1261817SN/A  // STRUCTURES
1271817SN/A
1282539SN/A  structure(Entry, desc="...", interface="AbstractCacheEntry") {
1291817SN/A    State CacheState,           desc="cache state";
1301817SN/A    bool Dirty,                 desc="Is the data dirty (diff from memory?)";
1311817SN/A    DataBlock DataBlk,          desc="Data for the block";
1321817SN/A  }
1331817SN/A
1341817SN/A  structure(TBE, desc="...") {
1351817SN/A    State TBEState,     desc="Transient state";
1361817SN/A    DataBlock DataBlk,  desc="data for the block";
1371817SN/A    bool Dirty,         desc="Is the data dirty?";
1382648SN/A    bool Shared,        desc="Victim hit by shared probe";
1392648SN/A    MachineID From,     desc="Waiting for writeback from...";
1401817SN/A  }
1411817SN/A
1422648SN/A  structure(TBETable, external="yes") {
1431817SN/A    TBE lookup(Addr);
1441817SN/A    void allocate(Addr);
1451817SN/A    void deallocate(Addr);
1461817SN/A    bool isPresent(Addr);
1471817SN/A  }
1482648SN/A
1491817SN/A  TBETable TBEs, template="<TCC_TBE>", constructor="m_number_of_TBEs";
1501817SN/A  int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()";
1512648SN/A
1521817SN/A  void set_cache_entry(AbstractCacheEntry b);
1531817SN/A  void unset_cache_entry();
1541817SN/A  void set_tbe(TBE b);
1552648SN/A  void unset_tbe();
1561817SN/A  void wakeUpAllBuffers();
1572648SN/A  void wakeUpBuffers(Addr a);
1582648SN/A
1591817SN/A
1601817SN/A  // FUNCTION DEFINITIONS
1611817SN/A  Tick clockEdge();
1621817SN/A  Tick cyclesToTicks(Cycles c);
1631817SN/A
1641854SN/A  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
1651817SN/A    return static_cast(Entry, "pointer", L2cache.lookup(addr));
1661854SN/A  }
1671854SN/A
1681854SN/A  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
1691854SN/A    return getCacheEntry(addr).DataBlk;
1701817SN/A  }
1711817SN/A
1721817SN/A  bool presentOrAvail(Addr addr) {
1731854SN/A    return L2cache.isTagPresent(addr) || L2cache.cacheAvail(addr);
1741854SN/A  }
1751817SN/A
1761854SN/A  State getState(TBE tbe, Entry cache_entry, Addr addr) {
1771854SN/A    if (is_valid(tbe)) {
1781854SN/A      return tbe.TBEState;
1791854SN/A    } else if (is_valid(cache_entry)) {
1801854SN/A      return cache_entry.CacheState;
1811817SN/A    }
1821854SN/A    return State:I;
1831854SN/A  }
1841854SN/A
1851854SN/A  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
1861817SN/A    if (is_valid(tbe)) {
1871817SN/A        tbe.TBEState := state;
1881817SN/A    }
1891634SN/A
190772SN/A    if (is_valid(cache_entry)) {
191773SN/A        cache_entry.CacheState := state;
1921634SN/A    }
193772SN/A  }
194772SN/A
195772SN/A  AccessPermission getAccessPermission(Addr addr) {
1961817SN/A    TBE tbe := TBEs.lookup(addr);
1971817SN/A    if(is_valid(tbe)) {
1981817SN/A      return TCC_State_to_permission(tbe.TBEState);
1991817SN/A    }
2001817SN/A
2011817SN/A    Entry cache_entry := getCacheEntry(addr);
2021817SN/A    if(is_valid(cache_entry)) {
203772SN/A      return TCC_State_to_permission(cache_entry.CacheState);
204776SN/A    }
2051634SN/A
206773SN/A    return AccessPermission:NotPresent;
207831SN/A  }
208772SN/A
209772SN/A  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
210772SN/A    if (is_valid(cache_entry)) {
2111817SN/A      cache_entry.changePermission(TCC_State_to_permission(state));
212772SN/A    }
2131634SN/A  }
214772SN/A
215772SN/A  void functionalRead(Addr addr, Packet *pkt) {
2161854SN/A    TBE tbe := TBEs.lookup(addr);
2171854SN/A    if(is_valid(tbe)) {
2181854SN/A      testAndRead(addr, tbe.DataBlk, pkt);
219918SN/A    } else {
2201854SN/A      functionalMemoryRead(pkt);
2211854SN/A    }
2221854SN/A  }
223771SN/A
224771SN/A  int functionalWrite(Addr addr, Packet *pkt) {
225771SN/A    int num_functional_writes := 0;
2262539SN/A
227771SN/A    TBE tbe := TBEs.lookup(addr);
2281817SN/A    if(is_valid(tbe)) {
2291817SN/A      num_functional_writes := num_functional_writes +
2301817SN/A            testAndWrite(addr, tbe.DataBlk, pkt);
2312539SN/A    }
2321817SN/A
2331817SN/A    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
2341817SN/A    return num_functional_writes;
2351817SN/A  }
2362542SN/A
2371817SN/A  void recordRequestType(RequestType request_type, Addr addr) {
2381817SN/A    if (request_type == RequestType:DataArrayRead) {
2391854SN/A        L2cache.recordRequestType(CacheRequestType:DataArrayRead, addr);
2401817SN/A    } else if (request_type == RequestType:DataArrayWrite) {
2411854SN/A        L2cache.recordRequestType(CacheRequestType:DataArrayWrite, addr);
2422539SN/A    } else if (request_type == RequestType:TagArrayRead) {
2432539SN/A        L2cache.recordRequestType(CacheRequestType:TagArrayRead, addr);
2441817SN/A    } else if (request_type == RequestType:TagArrayWrite) {
245771SN/A        L2cache.recordRequestType(CacheRequestType:TagArrayWrite, addr);
246771SN/A    }
247771SN/A  }
2481854SN/A
249771SN/A  bool checkResourceAvailable(RequestType request_type, Addr addr) {
2501817SN/A    if (request_type == RequestType:DataArrayRead) {
2511854SN/A      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
2521854SN/A    } else if (request_type == RequestType:DataArrayWrite) {
2531854SN/A      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
2541817SN/A    } else if (request_type == RequestType:TagArrayRead) {
2551817SN/A      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
2561817SN/A    } else if (request_type == RequestType:TagArrayWrite) {
2571854SN/A      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
2581854SN/A    } else {
2591817SN/A      error("Invalid RequestType type in checkResourceAvailable");
2601817SN/A      return true;
2611854SN/A    }
2621854SN/A  }
2631854SN/A
2641817SN/A
2651817SN/A
2661854SN/A  // OUT PORTS
2671854SN/A  out_port(w_requestNetwork_out, CPURequestMsg, w_reqToTCCDir);
2681817SN/A  out_port(w_TCCResp_out, ResponseMsg, w_respToTCCDir);
2691817SN/A  out_port(responseNetwork_out, ResponseMsg, responseFromTCC);
2701817SN/A  out_port(w_unblockNetwork_out, UnblockMsg, w_TCCUnblockToTCCDir);
2711817SN/A
2721817SN/A  // IN PORTS
2731817SN/A  in_port(TDResponse_in, ResponseMsg, w_respToTCC) {
2741817SN/A    if (TDResponse_in.isReady(clockEdge())) {
2751817SN/A      peek(TDResponse_in, ResponseMsg) {
2761817SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
2771817SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
2781817SN/A        if (in_msg.Type == CoherenceResponseType:TDSysWBAck) {
2791817SN/A          trigger(Event:WBAck, in_msg.addr, cache_entry, tbe);
2801817SN/A        }
2811817SN/A        else {
2821817SN/A          DPRINTF(RubySlicc, "%s\n", in_msg);
2831817SN/A          error("Error on TDResponse Type");
2841817SN/A        }
2852648SN/A      }
2862648SN/A    }
2871817SN/A  }
2881817SN/A
2891817SN/A  // Response Network
2901817SN/A  in_port(responseNetwork_in, ResponseMsg, responseToTCC) {
2911817SN/A    if (responseNetwork_in.isReady(clockEdge())) {
2922648SN/A      peek(responseNetwork_in, ResponseMsg) {
2931817SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
2941817SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
2951817SN/A        if (in_msg.Type == CoherenceResponseType:CPUData) {
2961817SN/A          if (in_msg.NbReqShared) {
2972648SN/A            trigger(Event:CPUDataShared, in_msg.addr, cache_entry, tbe);
2981817SN/A          } else {
2992648SN/A            trigger(Event:CPUData, in_msg.addr, cache_entry, tbe);
3002648SN/A          }
3011817SN/A        } else if (in_msg.Type == CoherenceResponseType:StaleNotif) {
3021817SN/A            trigger(Event:StaleWB, in_msg.addr, cache_entry, tbe);
3031817SN/A        } else {
3041817SN/A          DPRINTF(RubySlicc, "%s\n", in_msg);
3051817SN/A          error("Error on TDResponse Type");
3062648SN/A        }
3071817SN/A      }
3081817SN/A    }
3091817SN/A  }
3102648SN/A
3111817SN/A  // probe network
3122648SN/A  in_port(probeNetwork_in, TDProbeRequestMsg, w_probeToTCC) {
3132648SN/A    if (probeNetwork_in.isReady(clockEdge())) {
3141817SN/A      peek(probeNetwork_in, TDProbeRequestMsg) {
3151817SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
3161817SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
3171817SN/A        if (in_msg.Type == ProbeRequestType:PrbInv) {
3181817SN/A          if (in_msg.ReturnData) {
3192539SN/A            trigger(Event:PrbInvData, in_msg.addr, cache_entry, tbe);
3201817SN/A          } else {
3211817SN/A            trigger(Event:PrbInv, in_msg.addr, cache_entry, tbe);
3221817SN/A          }
3232539SN/A        } else if (in_msg.Type == ProbeRequestType:PrbDowngrade) {
3241817SN/A          if (in_msg.ReturnData) {
3251817SN/A            trigger(Event:PrbShrData, in_msg.addr, cache_entry, tbe);
3261817SN/A          } else {
3271817SN/A            error("Don't think I should get any of these");
3281817SN/A          }
3291817SN/A        }
3301817SN/A      }
3311817SN/A    }
3322539SN/A  }
3331817SN/A
3341817SN/A  // Request Network
3351817SN/A  in_port(requestNetwork_in, CPURequestMsg, w_reqToTCC) {
3361854SN/A    if (requestNetwork_in.isReady(clockEdge())) {
3371854SN/A      peek(requestNetwork_in, CPURequestMsg) {
3381817SN/A        assert(in_msg.Destination.isElement(machineID));
3391817SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
3401817SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
3411817SN/A        if (in_msg.Type == CoherenceRequestType:RdBlk) {
3421817SN/A          trigger(Event:RdBlk, in_msg.addr, cache_entry, tbe);
3431817SN/A        } else if (in_msg.Type == CoherenceRequestType:RdBlkS) {
3441817SN/A          trigger(Event:RdBlkS, in_msg.addr, cache_entry, tbe);
3451817SN/A        } else if (in_msg.Type == CoherenceRequestType:RdBlkM) {
3461817SN/A          trigger(Event:RdBlkM, in_msg.addr, cache_entry, tbe);
3471817SN/A        } else if (in_msg.Type == CoherenceRequestType:VicClean) {
3481817SN/A          if (presentOrAvail(in_msg.addr)) {
3491817SN/A            if (in_msg.Shared) {
3501817SN/A              trigger(Event:ClVicBlkShared, in_msg.addr, cache_entry, tbe);
3511817SN/A            } else {
3521817SN/A              trigger(Event:ClVicBlk, in_msg.addr, cache_entry, tbe);
3531817SN/A            }
3541817SN/A          } else {
3551817SN/A            Addr victim :=  L2cache.cacheProbe(in_msg.addr);
3561817SN/A            trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
3571817SN/A          }
3581817SN/A        } else if (in_msg.Type == CoherenceRequestType:VicDirty) {
3591817SN/A          if (presentOrAvail(in_msg.addr)) {
3601817SN/A            if (in_msg.Shared) {
3611817SN/A              trigger(Event:WrVicBlkShared, in_msg.addr, cache_entry, tbe);
3621817SN/A            } else {
3631817SN/A              trigger(Event:WrVicBlk, in_msg.addr, cache_entry, tbe);
3641817SN/A            }
3651817SN/A          } else {
3661817SN/A            Addr victim := L2cache.cacheProbe(in_msg.addr);
3671817SN/A            trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
3681817SN/A          }
3691817SN/A        } else {
3701817SN/A            requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
3711817SN/A        }
3721817SN/A      }
3731817SN/A    }
3741817SN/A  }
3751817SN/A
3761854SN/A  // BEGIN ACTIONS
3771817SN/A
3781854SN/A  action(i_invL2, "i", desc="invalidate TCC cache block") {
3791854SN/A    if (is_valid(cache_entry)) {
3801854SN/A        L2cache.deallocate(address);
3811854SN/A    }
3821854SN/A    unset_cache_entry();
3831854SN/A  }
3841854SN/A
3851854SN/A  action(rm_sendResponseM, "rm", desc="send Modified response") {
3861817SN/A    peek(requestNetwork_in, CPURequestMsg) {
3871854SN/A      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
3881854SN/A        out_msg.addr := address;
3891854SN/A        out_msg.Type := CoherenceResponseType:TDSysResp;
3901854SN/A        out_msg.Sender := machineID;
3911817SN/A        out_msg.Destination.add(in_msg.Requestor);
3921817SN/A        out_msg.DataBlk := cache_entry.DataBlk;
3931817SN/A        out_msg.MessageSize := MessageSizeType:Response_Data;
3941854SN/A        out_msg.Dirty := cache_entry.Dirty;
3951854SN/A        out_msg.State := CoherenceState:Modified;
3961817SN/A        DPRINTF(RubySlicc, "%s\n", out_msg);
3971854SN/A      }
3981854SN/A    }
3991854SN/A  }
4001854SN/A
4011854SN/A  action(rs_sendResponseS, "rs", desc="send Shared response") {
4021854SN/A    peek(requestNetwork_in, CPURequestMsg) {
4031854SN/A      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
4041854SN/A        out_msg.addr := address;
4051817SN/A        out_msg.Type := CoherenceResponseType:TDSysResp;
4061854SN/A        out_msg.Sender := machineID;
4071854SN/A        out_msg.Destination.add(in_msg.Requestor);
4081854SN/A        out_msg.DataBlk := cache_entry.DataBlk;
4091854SN/A        out_msg.MessageSize := MessageSizeType:Response_Data;
4101817SN/A        out_msg.Dirty := cache_entry.Dirty;
4111817SN/A        out_msg.State := CoherenceState:Shared;
4121817SN/A        DPRINTF(RubySlicc, "%s\n", out_msg);
4131817SN/A      }
4141817SN/A    }
4151817SN/A  }
4161817SN/A
4171817SN/A
4181817SN/A  action(r_requestToTD, "r", desc="Miss in L2, pass on") {
4191817SN/A    peek(requestNetwork_in, CPURequestMsg) {
4201817SN/A      enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
4211817SN/A        out_msg.addr := address;
4221817SN/A        out_msg.Type := in_msg.Type;
4231817SN/A        out_msg.Requestor := in_msg.Requestor;
4241817SN/A        out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
4251817SN/A                                TCC_select_low_bit, TCC_select_num_bits));
4261817SN/A        out_msg.Shared := false; // unneeded for this request
4271817SN/A        out_msg.MessageSize := in_msg.MessageSize;
4281817SN/A        DPRINTF(RubySlicc, "%s\n", out_msg);
4291817SN/A      }
4301817SN/A    }
4311817SN/A  }
432771SN/A
433771SN/A  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
434771SN/A    TBEs.allocate(address);
4351817SN/A    set_tbe(TBEs.lookup(address));
436771SN/A    if (is_valid(cache_entry)) {
437771SN/A      tbe.DataBlk := cache_entry.DataBlk; // Data only for WBs
438771SN/A      tbe.Dirty := cache_entry.Dirty;
439771SN/A    }
4402539SN/A    tbe.From := machineID;
4412539SN/A  }
4423932Sbinkertn@umich.edu
4433932Sbinkertn@umich.edu  action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") {
444768SN/A    TBEs.deallocate(address);
4453846Shsul@eecs.umich.edu    unset_tbe();
446909SN/A  }
447803SN/A
448803SN/A  action(vc_vicClean, "vc", desc="Victimize Clean L2 data") {
449803SN/A    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
450771SN/A      out_msg.addr := address;
451777SN/A      out_msg.Type := CoherenceRequestType:VicClean;
452777SN/A      out_msg.Requestor := machineID;
453773SN/A      out_msg.DataBlk := cache_entry.DataBlk;
454773SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
4551634SN/A                              TCC_select_low_bit, TCC_select_num_bits));
4561634SN/A      out_msg.MessageSize := MessageSizeType:Response_Data;
4571634SN/A    }
4582539SN/A  }
4591634SN/A
4601634SN/A  action(vd_vicDirty, "vd", desc="Victimize dirty L2 data") {
4612542SN/A    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
4623349SN/A      out_msg.addr := address;
463768SN/A      out_msg.Type := CoherenceRequestType:VicDirty;
4642641SN/A      out_msg.Requestor := machineID;
465768SN/A      out_msg.DataBlk := cache_entry.DataBlk;
4662641SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
467865SN/A                              TCC_select_low_bit, TCC_select_num_bits));
4682641SN/A      out_msg.MessageSize := MessageSizeType:Response_Data;
4692641SN/A    }
470771SN/A  }
4712630SN/A
4722539SN/A  action(w_sendResponseWBAck, "w", desc="send WB Ack") {
4732641SN/A    peek(requestNetwork_in, CPURequestMsg) {
474803SN/A      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
4751817SN/A        out_msg.addr := address;
4761817SN/A        out_msg.Type := CoherenceResponseType:TDSysWBAck;
4772630SN/A        out_msg.Destination.add(in_msg.Requestor);
4782539SN/A        out_msg.Sender := machineID;
4791817SN/A        out_msg.MessageSize := MessageSizeType:Writeback_Control;
4802630SN/A      }
4812539SN/A    }
482865SN/A  }
483865SN/A
484865SN/A  action(pi_sendProbeResponseInv, "pi", desc="send probe ack inv, no data") {
485865SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
4862630SN/A      out_msg.addr := address;
4872539SN/A      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
488865SN/A      out_msg.Sender := machineID;
489865SN/A      // will this always be ok? probably not for multisocket
4902630SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
4912539SN/A                              TCC_select_low_bit, TCC_select_num_bits));
4921817SN/A      out_msg.Dirty := false;
4932648SN/A      out_msg.Hit := false;
4942542SN/A      out_msg.Ntsl := true;
4951817SN/A      out_msg.State := CoherenceState:NA;
4962648SN/A      out_msg.MessageSize := MessageSizeType:Response_Control;
4972542SN/A    }
4981817SN/A  }
4992648SN/A
5002539SN/A  action(ph_sendProbeResponseHit, "ph", desc="send probe ack, no data") {
501803SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
5022648SN/A      out_msg.addr := address;
5032539SN/A      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
5041817SN/A      out_msg.Sender := machineID;
5051817SN/A      // will this always be ok? probably not for multisocket
5062630SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
5071817SN/A                              TCC_select_low_bit, TCC_select_num_bits));
5082630SN/A      out_msg.Dirty := false;
5092539SN/A      out_msg.Hit := true;
510803SN/A      out_msg.Ntsl := false;
5112641SN/A      out_msg.State := CoherenceState:NA;
512803SN/A      out_msg.MessageSize := MessageSizeType:Response_Control;
5132641SN/A    }
5142539SN/A  }
5152630SN/A
5162539SN/A  action(pm_sendProbeResponseMiss, "pm", desc="send probe ack, no data") {
5172539SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
5182641SN/A      out_msg.addr := address;
5192539SN/A      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
5202641SN/A      out_msg.Sender := machineID;
521771SN/A      // will this always be ok? probably not for multisocket
5224870Sstever@eecs.umich.edu      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
5232539SN/A                              TCC_select_low_bit, TCC_select_num_bits));
524768SN/A      out_msg.Dirty := false;
525768SN/A      out_msg.Hit := false;
5262539SN/A      out_msg.Ntsl := false;
5273349SN/A      out_msg.State := CoherenceState:NA;
528768SN/A      out_msg.MessageSize := MessageSizeType:Response_Control;
5292641SN/A    }
5302641SN/A  }
531779SN/A
532779SN/A  action(pd_sendProbeResponseData, "pd", desc="send probe ack, with data") {
5332641SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
534768SN/A      out_msg.addr := address;
5352641SN/A      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
536769SN/A      out_msg.Sender := machineID;
5372539SN/A      // will this always be ok? probably not for multisocket
5382539SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
5392630SN/A                              TCC_select_low_bit, TCC_select_num_bits));
5402539SN/A      out_msg.DataBlk := cache_entry.DataBlk;
5412539SN/A      //assert(cache_entry.Dirty); Not needed in TCC where TCC can supply clean data
5422539SN/A      out_msg.Dirty := cache_entry.Dirty;
5432539SN/A      out_msg.Hit := true;
544803SN/A      out_msg.State := CoherenceState:NA;
5452539SN/A      out_msg.MessageSize := MessageSizeType:Response_Data;
5462539SN/A    }
5472539SN/A  }
5482539SN/A
5492539SN/A  action(pdt_sendProbeResponseDataFromTBE, "pdt", desc="send probe ack with data") {
5502539SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
5512539SN/A      out_msg.addr := address;
5522630SN/A      out_msg.Type := CoherenceResponseType:CPUPrbResp;
5532539SN/A      out_msg.Sender := machineID;
5542539SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
5552539SN/A                              TCC_select_low_bit, TCC_select_num_bits));
5562539SN/A      out_msg.DataBlk := tbe.DataBlk;
5572630SN/A      //assert(tbe.Dirty);
5582539SN/A      out_msg.Dirty := tbe.Dirty;
5592539SN/A      out_msg.Hit := true;
5602539SN/A      out_msg.MessageSize := MessageSizeType:Response_Data;
5612539SN/A      out_msg.State := CoherenceState:NA;
5622630SN/A      DPRINTF(RubySlicc, "%s\n", out_msg);
5632539SN/A    }
5642539SN/A  }
5652630SN/A
5662539SN/A  action(mc_cancelMemWriteback, "mc", desc="send writeback cancel to memory") {
5672539SN/A    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
5682630SN/A      out_msg.addr := address;
5692539SN/A      out_msg.Type := CoherenceRequestType:WrCancel;
5702539SN/A      out_msg.Requestor := machineID;
5712630SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
5722539SN/A                              TCC_select_low_bit, TCC_select_num_bits));
5732539SN/A      out_msg.MessageSize := MessageSizeType:Request_Control;
5742630SN/A    }
5752539SN/A  }
5762539SN/A
5772630SN/A  action(a_allocateBlock, "a", desc="allocate TCC block") {
5782539SN/A    if (is_invalid(cache_entry)) {
5792539SN/A      set_cache_entry(L2cache.allocate(address, new Entry));
5802630SN/A    }
5812539SN/A  }
5822539SN/A
5832630SN/A  action(d_writeData, "d", desc="write data to TCC") {
5842539SN/A    peek(responseNetwork_in, ResponseMsg) {
5852539SN/A      if (in_msg.Dirty) {
5862539SN/A        cache_entry.Dirty := in_msg.Dirty;
5872539SN/A      }
5882539SN/A      cache_entry.DataBlk := in_msg.DataBlk;
5892539SN/A      DPRINTF(RubySlicc, "Writing to TCC: %s\n", in_msg);
5902539SN/A    }
5912539SN/A  }
5922539SN/A
5932539SN/A  action(rd_copyDataFromRequest, "rd", desc="write data to TCC") {
5942539SN/A    peek(requestNetwork_in, CPURequestMsg) {
5952539SN/A      cache_entry.DataBlk := in_msg.DataBlk;
5962539SN/A      cache_entry.Dirty := true;
597803SN/A    }
5982641SN/A  }
599769SN/A
600769SN/A  action(f_setFrom, "f", desc="set who WB is expected to come from") {
6014870Sstever@eecs.umich.edu    peek(requestNetwork_in, CPURequestMsg) {
6022539SN/A      tbe.From := in_msg.Requestor;
603768SN/A    }
604768SN/A  }
605768SN/A
606777SN/A  action(rf_resetFrom, "rf", desc="reset From") {
607777SN/A    tbe.From := machineID;
608777SN/A  }
609777SN/A
610865SN/A  action(wb_data, "wb", desc="write back data") {
611817SN/A    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
612777SN/A      out_msg.addr := address;
613777SN/A      out_msg.Type := CoherenceResponseType:CPUData;
614777SN/A      out_msg.Sender := machineID;
615777SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
616777SN/A                              TCC_select_low_bit, TCC_select_num_bits));
617777SN/A      out_msg.DataBlk := tbe.DataBlk;
618777SN/A      out_msg.Dirty := tbe.Dirty;
619777SN/A      if (tbe.Shared) {
620777SN/A        out_msg.NbReqShared := true;
621777SN/A      } else {
622817SN/A        out_msg.NbReqShared := false;
623777SN/A      }
624777SN/A      out_msg.State := CoherenceState:Shared; // faux info
625777SN/A      out_msg.MessageSize := MessageSizeType:Writeback_Data;
626777SN/A      DPRINTF(RubySlicc, "%s\n", out_msg);
627777SN/A    }
6281854SN/A  }
629768SN/A
630811SN/A  action(wt_writeDataToTBE, "wt", desc="write WB data to TBE") {
631899SN/A    peek(responseNetwork_in, ResponseMsg) {
632899SN/A      tbe.DataBlk := in_msg.DataBlk;
633899SN/A      tbe.Dirty := in_msg.Dirty;
634899SN/A    }
635811SN/A  }
636811SN/A
637811SN/A  action(uo_sendUnblockOwner, "uo", desc="state changed to E, M, or O, unblock") {
638919SN/A    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
6391854SN/A      out_msg.addr := address;
6401854SN/A      out_msg.Sender := machineID;
641768SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
642768SN/A                              TCC_select_low_bit, TCC_select_num_bits));
643768SN/A      out_msg.MessageSize := MessageSizeType:Unblock_Control;
6441854SN/A      out_msg.currentOwner := true;
645768SN/A      out_msg.valid := true;
646811SN/A      DPRINTF(RubySlicc, "%s\n", out_msg);
647899SN/A    }
648899SN/A  }
649899SN/A
650899SN/A  action(us_sendUnblockSharer, "us", desc="state changed to S , unblock") {
651811SN/A    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
652811SN/A      out_msg.addr := address;
653919SN/A      out_msg.Sender := machineID;
654919SN/A      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
6551854SN/A                              TCC_select_low_bit, TCC_select_num_bits));
6561854SN/A      out_msg.MessageSize := MessageSizeType:Unblock_Control;
657768SN/A      out_msg.currentOwner := false;
658768SN/A      out_msg.valid := true;
659770SN/A      DPRINTF(RubySlicc, "%s\n", out_msg);
660768SN/A    }
6612539SN/A  }
6622539SN/A
6632539SN/A  action(un_sendUnblockNotValid, "un", desc="state changed toI, unblock") {
6642539SN/A    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
6652539SN/A      out_msg.addr := address;
6663932Sbinkertn@umich.edu      out_msg.Sender := machineID;
6673932Sbinkertn@umich.edu      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
668775SN/A                              TCC_select_low_bit, TCC_select_num_bits));
669768SN/A      out_msg.MessageSize := MessageSizeType:Unblock_Control;
670770SN/A      out_msg.currentOwner := false;
671768SN/A      out_msg.valid := false;
672770SN/A      DPRINTF(RubySlicc, "%s\n", out_msg);
673768SN/A    }
6742539SN/A  }
6752539SN/A
6762542SN/A  action(ut_updateTag, "ut", desc="update Tag (i.e. set MRU)") {
6772539SN/A    L2cache.setMRU(address);
6782539SN/A  }
6791634SN/A
6803932Sbinkertn@umich.edu  action(p_popRequestQueue, "p", desc="pop request queue") {
6812539SN/A    requestNetwork_in.dequeue(clockEdge());
682768SN/A  }
683770SN/A
684768SN/A  action(pr_popResponseQueue, "pr", desc="pop response queue") {
685770SN/A    responseNetwork_in.dequeue(clockEdge());
686768SN/A  }
6872539SN/A
6882539SN/A  action(pn_popTDResponseQueue, "pn", desc="pop TD response queue") {
6892539SN/A    TDResponse_in.dequeue(clockEdge());
6902539SN/A  }
6912539SN/A
6922539SN/A  action(pp_popProbeQueue, "pp", desc="pop probe queue") {
6932539SN/A    probeNetwork_in.dequeue(clockEdge());
6942539SN/A  }
6953932Sbinkertn@umich.edu
6962539SN/A  action(zz_recycleRequestQueue, "\z", desc="recycle request queue") {
6972539SN/A    requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
698768SN/A  }
699768SN/A
700770SN/A
701  // END ACTIONS
702
703  // BEGIN TRANSITIONS
704
705  // transitions from base
706
707  transition({I, I_C}, {RdBlk, RdBlkS, RdBlkM, CtoD}){TagArrayRead} {
708    // TCCdir already knows that the block is not here. This is to allocate and get the block.
709    r_requestToTD;
710    p_popRequestQueue;
711  }
712
713// check
714  transition({M, O}, RdBlk, O){TagArrayRead, TagArrayWrite} {
715    rs_sendResponseS;
716    ut_updateTag;
717    // detect 2nd chancing
718    p_popRequestQueue;
719  }
720
721//check
722  transition({E, S}, RdBlk, S){TagArrayRead, TagArrayWrite} {
723    rs_sendResponseS;
724    ut_updateTag;
725    // detect 2nd chancing
726    p_popRequestQueue;
727  }
728
729// check
730  transition({M, O}, RdBlkS, O){TagArrayRead, TagArrayWrite} {
731    rs_sendResponseS;
732    ut_updateTag;
733    // detect 2nd chance sharing
734    p_popRequestQueue;
735  }
736
737//check
738  transition({E, S}, RdBlkS, S){TagArrayRead, TagArrayWrite} {
739    rs_sendResponseS;
740    ut_updateTag;
741    // detect 2nd chance sharing
742    p_popRequestQueue;
743  }
744
745// check
746  transition(M, RdBlkM, I){TagArrayRead, TagArrayWrite} {
747    rm_sendResponseM;
748    i_invL2;
749    p_popRequestQueue;
750  }
751
752  //check
753  transition(E, RdBlkM, I){TagArrayRead, TagArrayWrite} {
754    rm_sendResponseM;
755    i_invL2;
756    p_popRequestQueue;
757  }
758
759// check
760  transition({I}, WrVicBlk, I_M){TagArrayRead} {
761    a_allocateBlock;
762    t_allocateTBE;
763    f_setFrom;
764    w_sendResponseWBAck;
765    p_popRequestQueue;
766  }
767
768  transition(I_C, {WrVicBlk, WrVicBlkShared, ClVicBlk, ClVicBlkShared}) {
769    zz_recycleRequestQueue;
770  }
771
772//check
773  transition({I}, WrVicBlkShared, I_O) {TagArrayRead}{
774    a_allocateBlock;
775    t_allocateTBE;
776    f_setFrom;
777//    rd_copyDataFromRequest;
778    w_sendResponseWBAck;
779    p_popRequestQueue;
780  }
781
782//check
783  transition(S, WrVicBlkShared, S_O){TagArrayRead} {
784    t_allocateTBE;
785    f_setFrom;
786    w_sendResponseWBAck;
787    p_popRequestQueue;
788  }
789
790// a stale writeback
791 transition(S, WrVicBlk, S_S){TagArrayRead} {
792   t_allocateTBE;
793   f_setFrom;
794   w_sendResponseWBAck;
795   p_popRequestQueue;
796 }
797
798// a stale writeback
799  transition(E, WrVicBlk, E_E){TagArrayRead} {
800    t_allocateTBE;
801    f_setFrom;
802    w_sendResponseWBAck;
803    p_popRequestQueue;
804  }
805
806// a stale writeback
807  transition(E, WrVicBlkShared, E_E){TagArrayRead} {
808    t_allocateTBE;
809    f_setFrom;
810    w_sendResponseWBAck;
811    p_popRequestQueue;
812  }
813
814// a stale writeback
815  transition(O, WrVicBlk, O_O){TagArrayRead} {
816    t_allocateTBE;
817    f_setFrom;
818    w_sendResponseWBAck;
819    p_popRequestQueue;
820  }
821
822// a stale writeback
823 transition(O, WrVicBlkShared, O_O){TagArrayRead} {
824   t_allocateTBE;
825   f_setFrom;
826   w_sendResponseWBAck;
827   p_popRequestQueue;
828 }
829
830// a stale writeback
831  transition(M, WrVicBlk, M_M){TagArrayRead} {
832    t_allocateTBE;
833    f_setFrom;
834    w_sendResponseWBAck;
835    p_popRequestQueue;
836  }
837
838// a stale writeback
839  transition(M, WrVicBlkShared, M_O){TagArrayRead} {
840    t_allocateTBE;
841    f_setFrom;
842    w_sendResponseWBAck;
843    p_popRequestQueue;
844  }
845
846//check
847  transition({I}, ClVicBlk, I_E){TagArrayRead} {
848    t_allocateTBE;
849    f_setFrom;
850    a_allocateBlock;
851    w_sendResponseWBAck;
852    p_popRequestQueue;
853  }
854
855  transition({I}, ClVicBlkShared, I_S){TagArrayRead} {
856    t_allocateTBE;
857    f_setFrom;
858    a_allocateBlock;
859    w_sendResponseWBAck;
860    p_popRequestQueue;
861  }
862
863//check
864  transition(S, ClVicBlkShared, S_S){TagArrayRead} {
865    t_allocateTBE;
866    f_setFrom;
867    w_sendResponseWBAck;
868    p_popRequestQueue;
869  }
870
871// a stale writeback
872  transition(E, ClVicBlk, E_E){TagArrayRead} {
873    t_allocateTBE;
874    f_setFrom;
875    w_sendResponseWBAck;
876    p_popRequestQueue;
877  }
878
879// a stale writeback
880  transition(E, ClVicBlkShared, E_S){TagArrayRead} {
881    t_allocateTBE;
882    f_setFrom;
883    w_sendResponseWBAck;
884    p_popRequestQueue;
885  }
886
887// a stale writeback
888 transition(O, ClVicBlk, O_O){TagArrayRead} {
889   t_allocateTBE;
890   f_setFrom;
891   w_sendResponseWBAck;
892   p_popRequestQueue;
893 }
894
895// check. Original L3 ahd it going from O to O_S. Something can go from O to S only on writeback.
896  transition(O, ClVicBlkShared, O_O){TagArrayRead} {
897    t_allocateTBE;
898    f_setFrom;
899    w_sendResponseWBAck;
900    p_popRequestQueue;
901  }
902
903// a stale writeback
904 transition(M, ClVicBlk, M_E){TagArrayRead} {
905   t_allocateTBE;
906   f_setFrom;
907   w_sendResponseWBAck;
908   p_popRequestQueue;
909 }
910
911// a stale writeback
912 transition(M, ClVicBlkShared, M_S){TagArrayRead} {
913   t_allocateTBE;
914   f_setFrom;
915   w_sendResponseWBAck;
916   p_popRequestQueue;
917 }
918
919
920  transition({MO_I}, {RdBlk, RdBlkS, RdBlkM, CtoD}) {
921    a_allocateBlock;
922    t_allocateTBE;
923    f_setFrom;
924    r_requestToTD;
925    p_popRequestQueue;
926  }
927
928  transition(MO_I, {WrVicBlkShared, WrVicBlk, ClVicBlk, ClVicBlkShared}, MOD_I) {
929    f_setFrom;
930    w_sendResponseWBAck;
931    p_popRequestQueue;
932  }
933
934  transition(I_M, CPUData, M){TagArrayWrite} {
935    uo_sendUnblockOwner;
936    dt_deallocateTBE;
937    d_writeData;
938    pr_popResponseQueue;
939  }
940
941  transition(I_M, CPUDataShared, O){TagArrayWrite, DataArrayWrite} {
942    uo_sendUnblockOwner;
943    dt_deallocateTBE;
944    d_writeData;
945    pr_popResponseQueue;
946  }
947
948  transition(I_O, {CPUData, CPUDataShared}, O){TagArrayWrite, DataArrayWrite}  {
949    uo_sendUnblockOwner;
950    dt_deallocateTBE;
951    d_writeData;
952    pr_popResponseQueue;
953  }
954
955  transition(I_E, CPUData, E){TagArrayWrite, DataArrayWrite}  {
956    uo_sendUnblockOwner;
957    dt_deallocateTBE;
958    d_writeData;
959    pr_popResponseQueue;
960  }
961
962  transition(I_E, CPUDataShared, S){TagArrayWrite, DataArrayWrite}  {
963    us_sendUnblockSharer;
964    dt_deallocateTBE;
965    d_writeData;
966    pr_popResponseQueue;
967  }
968
969  transition(I_S, {CPUData, CPUDataShared}, S){TagArrayWrite, DataArrayWrite}  {
970    us_sendUnblockSharer;
971    dt_deallocateTBE;
972    d_writeData;
973    pr_popResponseQueue;
974  }
975
976  transition(S_M, CPUDataShared, O){TagArrayWrite, DataArrayWrite}  {
977    uo_sendUnblockOwner;
978    dt_deallocateTBE;
979    d_writeData;
980    ut_updateTag;  // update tag on writeback hits.
981    pr_popResponseQueue;
982  }
983
984  transition(S_O, {CPUData, CPUDataShared}, O){TagArrayWrite, DataArrayWrite}  {
985    uo_sendUnblockOwner;
986    dt_deallocateTBE;
987    d_writeData;
988    ut_updateTag;  // update tag on writeback hits.
989    pr_popResponseQueue;
990  }
991
992  transition(S_E, CPUDataShared, S){TagArrayWrite, DataArrayWrite}  {
993    us_sendUnblockSharer;
994    dt_deallocateTBE;
995    d_writeData;
996    ut_updateTag;  // update tag on writeback hits.
997    pr_popResponseQueue;
998  }
999
1000  transition(S_S, {CPUData, CPUDataShared}, S){TagArrayWrite, DataArrayWrite}  {
1001    us_sendUnblockSharer;
1002    dt_deallocateTBE;
1003    d_writeData;
1004    ut_updateTag;  // update tag on writeback hits.
1005    pr_popResponseQueue;
1006  }
1007
1008  transition(O_E, CPUDataShared, O){TagArrayWrite, DataArrayWrite}  {
1009    uo_sendUnblockOwner;
1010    dt_deallocateTBE;
1011    d_writeData;
1012    ut_updateTag;  // update tag on writeback hits.
1013    pr_popResponseQueue;
1014  }
1015
1016  transition(O_O, {CPUData, CPUDataShared}, O){TagArrayWrite, DataArrayWrite}  {
1017    uo_sendUnblockOwner;
1018    dt_deallocateTBE;
1019    d_writeData;
1020    ut_updateTag;  // update tag on writeback hits.
1021    pr_popResponseQueue;
1022  }
1023
1024  transition({D_I}, {CPUData, CPUDataShared}, I){TagArrayWrite}  {
1025    un_sendUnblockNotValid;
1026    dt_deallocateTBE;
1027    pr_popResponseQueue;
1028  }
1029
1030  transition(MOD_I, {CPUData, CPUDataShared}, MO_I) {
1031    un_sendUnblockNotValid;
1032    rf_resetFrom;
1033    pr_popResponseQueue;
1034  }
1035
1036  transition({O,S,I}, CPUData) {
1037    pr_popResponseQueue;
1038  }
1039
1040  transition({M, O}, L2_Repl, MO_I){TagArrayRead, DataArrayRead} {
1041    t_allocateTBE;
1042    vd_vicDirty;
1043    i_invL2;
1044  }
1045
1046  transition({E, S,}, L2_Repl, ES_I){TagArrayRead, DataArrayRead} {
1047    t_allocateTBE;
1048    vc_vicClean;
1049    i_invL2;
1050  }
1051
1052  transition({I_M, I_O, S_M, S_O, E_M, E_O}, L2_Repl) {
1053    zz_recycleRequestQueue;
1054  }
1055
1056  transition({O_M, O_O, O_E, M_M, M_O, M_E, M_S}, L2_Repl) {
1057    zz_recycleRequestQueue;
1058  }
1059
1060  transition({I_E, I_S, S_E, S_S, E_E, E_S}, L2_Repl) {
1061    zz_recycleRequestQueue;
1062  }
1063
1064  transition({M, O}, PrbInvData, I){TagArrayRead, TagArrayWrite} {
1065    pd_sendProbeResponseData;
1066    i_invL2;
1067    pp_popProbeQueue;
1068  }
1069
1070  transition(I, PrbInvData){TagArrayRead, TagArrayWrite}  {
1071    pi_sendProbeResponseInv;
1072    pp_popProbeQueue;
1073  }
1074
1075  transition({E, S}, PrbInvData, I){TagArrayRead, TagArrayWrite}  {
1076    pd_sendProbeResponseData;
1077    i_invL2;
1078    pp_popProbeQueue;
1079  }
1080
1081  transition({M, O, E, S, I}, PrbInv, I){TagArrayRead, TagArrayWrite}  {
1082    pi_sendProbeResponseInv;
1083    i_invL2; // nothing will happen in I
1084    pp_popProbeQueue;
1085  }
1086
1087  transition({M, O}, PrbShrData, O){TagArrayRead, TagArrayWrite}  {
1088    pd_sendProbeResponseData;
1089    pp_popProbeQueue;
1090  }
1091
1092  transition({E, S}, PrbShrData, S){TagArrayRead, TagArrayWrite}  {
1093    pd_sendProbeResponseData;
1094    pp_popProbeQueue;
1095  }
1096
1097  transition(I, PrbShrData){TagArrayRead}  {
1098    pm_sendProbeResponseMiss;
1099    pp_popProbeQueue;
1100  }
1101
1102  transition(MO_I, PrbInvData, I_C) {
1103    pdt_sendProbeResponseDataFromTBE;
1104    pp_popProbeQueue;
1105  }
1106
1107  transition(ES_I, PrbInvData, I_C) {
1108    pi_sendProbeResponseInv;
1109    pp_popProbeQueue;
1110  }
1111
1112  transition({ES_I,MO_I}, PrbInv, I_C) {
1113    pi_sendProbeResponseInv;
1114    pp_popProbeQueue;
1115  }
1116
1117  transition({ES_I, MO_I}, PrbShrData) {
1118    pdt_sendProbeResponseDataFromTBE;
1119    pp_popProbeQueue;
1120  }
1121
1122  transition(I_C, {PrbInvData, PrbInv}) {
1123    pi_sendProbeResponseInv;
1124    pp_popProbeQueue;
1125  }
1126
1127  transition(I_C, PrbShrData) {
1128    pm_sendProbeResponseMiss;
1129    pp_popProbeQueue;
1130  }
1131
1132  transition(MOD_I, WBAck, D_I) {
1133    pn_popTDResponseQueue;
1134  }
1135
1136  transition(MO_I, WBAck, I){TagArrayWrite} {
1137    dt_deallocateTBE;
1138    pn_popTDResponseQueue;
1139  }
1140
1141  // this can only be a spurious CPUData from a shared block.
1142  transition(MO_I, CPUData) {
1143    pr_popResponseQueue;
1144  }
1145
1146  transition(ES_I, WBAck, I){TagArrayWrite} {
1147    dt_deallocateTBE;
1148    pn_popTDResponseQueue;
1149  }
1150
1151  transition(I_C, {WBAck}, I){TagArrayWrite} {
1152    dt_deallocateTBE;
1153    pn_popTDResponseQueue;
1154  }
1155
1156  transition({I_M, I_O, I_E, I_S}, StaleWB, I){TagArrayWrite} {
1157    un_sendUnblockNotValid;
1158    dt_deallocateTBE;
1159    i_invL2;
1160    pr_popResponseQueue;
1161  }
1162
1163  transition({S_S, S_O, S_M, S_E}, StaleWB, S){TagArrayWrite} {
1164    us_sendUnblockSharer;
1165    dt_deallocateTBE;
1166    pr_popResponseQueue;
1167  }
1168
1169  transition({E_M, E_O, E_E, E_S}, StaleWB, E){TagArrayWrite} {
1170    uo_sendUnblockOwner;
1171    dt_deallocateTBE;
1172    pr_popResponseQueue;
1173  }
1174
1175  transition({O_M, O_O, O_E}, StaleWB, O){TagArrayWrite} {
1176    uo_sendUnblockOwner;
1177    dt_deallocateTBE;
1178    pr_popResponseQueue;
1179  }
1180
1181  transition({M_M, M_O, M_E, M_S}, StaleWB, M){TagArrayWrite} {
1182    uo_sendUnblockOwner;
1183    dt_deallocateTBE;
1184    pr_popResponseQueue;
1185  }
1186
1187  transition(D_I, StaleWB, I) {TagArrayWrite}{
1188    un_sendUnblockNotValid;
1189    dt_deallocateTBE;
1190    pr_popResponseQueue;
1191  }
1192
1193  transition(MOD_I, StaleWB, MO_I) {
1194    un_sendUnblockNotValid;
1195    rf_resetFrom;
1196    pr_popResponseQueue;
1197  }
1198
1199}
1200