GPU_RfO-TCC.sm revision 14184
12330SN/A/*
22330SN/A * Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
32330SN/A * All rights reserved.
42330SN/A *
52330SN/A * For use for simulation and test purposes only
62330SN/A *
72330SN/A * Redistribution and use in source and binary forms, with or without
82330SN/A * modification, are permitted provided that the following conditions are met:
92330SN/A *
102330SN/A * 1. Redistributions of source code must retain the above copyright notice,
112330SN/A * this list of conditions and the following disclaimer.
122330SN/A *
132330SN/A * 2. Redistributions in binary form must reproduce the above copyright notice,
142330SN/A * this list of conditions and the following disclaimer in the documentation
152330SN/A * and/or other materials provided with the distribution.
162330SN/A *
172330SN/A * 3. Neither the name of the copyright holder nor the names of its
182330SN/A * contributors may be used to endorse or promote products derived from this
192330SN/A * software without specific prior written permission.
202330SN/A *
212330SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
222330SN/A * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
232330SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
242330SN/A * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
252330SN/A * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
262330SN/A * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272689Sktlim@umich.edu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
282689Sktlim@umich.edu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
292330SN/A * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
302330SN/A * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312683Sktlim@umich.edu * POSSIBILITY OF SUCH DAMAGE.
322683Sktlim@umich.edu *
332315SN/A * Authors: Lisa Hsu
342315SN/A */
352683Sktlim@umich.edu
362680SN/Amachine(MachineType:TCC, "TCC Cache")
372315SN/A : CacheMemory * L2cache;
382315SN/A   WireBuffer * w_reqToTCCDir;
392330SN/A   WireBuffer * w_respToTCCDir;
402330SN/A   WireBuffer * w_TCCUnblockToTCCDir;
412330SN/A   WireBuffer * w_reqToTCC;
422315SN/A   WireBuffer * w_probeToTCC;
432350SN/A   WireBuffer * w_respToTCC;
442680SN/A   int TCC_select_num_bits;
452680SN/A   Cycles l2_request_latency := 1;
462683Sktlim@umich.edu   Cycles l2_response_latency := 20;
472683Sktlim@umich.edu
482683Sktlim@umich.edu  // To the general response network
492683Sktlim@umich.edu  MessageBuffer * responseFromTCC, network="To", virtual_network="3", vnet_type="response";
502350SN/A
512680SN/A  // From the general response network
522680SN/A  MessageBuffer * responseToTCC, network="From", virtual_network="3", vnet_type="response";
532315SN/A
542315SN/A{
552680SN/A  // EVENTS
562683Sktlim@umich.edu  enumeration(Event, desc="TCC Events") {
572683Sktlim@umich.edu    // Requests coming from the Cores
582330SN/A    RdBlk,                  desc="CPU RdBlk event";
592315SN/A    RdBlkM,                 desc="CPU RdBlkM event";
602315SN/A    RdBlkS,                 desc="CPU RdBlkS event";
612315SN/A    CtoD,                   desc="Change to Dirty request";
622683Sktlim@umich.edu    WrVicBlk,               desc="L1 Victim (dirty)";
632683Sktlim@umich.edu    WrVicBlkShared,               desc="L1 Victim (dirty)";
642680SN/A    ClVicBlk,               desc="L1 Victim (clean)";
652683Sktlim@umich.edu    ClVicBlkShared,               desc="L1 Victim (clean)";
662683Sktlim@umich.edu
672683Sktlim@umich.edu    CPUData,                      desc="WB data from CPU";
682683Sktlim@umich.edu    CPUDataShared,                desc="WB data from CPU, NBReqShared 1";
692683Sktlim@umich.edu    StaleWB,                desc="Stale WB, No data";
702315SN/A
712315SN/A    L2_Repl,             desc="L2 Replacement";
722315SN/A
732315SN/A    // Probes
742680SN/A    PrbInvData,         desc="Invalidating probe, return dirty data";
752315SN/A    PrbInv,             desc="Invalidating probe, no need to return data";
762315SN/A    PrbShrData,         desc="Downgrading probe, return data";
772315SN/A
782680SN/A    // Coming from Memory Controller
792680SN/A    WBAck,                     desc="ack from memory";
802315SN/A
812315SN/A    CancelWB,                   desc="Cancel WB from L2";
822680SN/A  }
832315SN/A
842315SN/A  // STATES
852680SN/A  state_declaration(State, desc="TCC State", default="TCC_State_I") {
862315SN/A    M, AccessPermission:Read_Write, desc="Modified";  // No other cache has copy, memory stale
872680SN/A    O, AccessPermission:Read_Only, desc="Owned";     // Correct most recent copy, others may exist in S
882315SN/A    E, AccessPermission:Read_Write, desc="Exclusive"; // Correct, most recent, and only copy (and == Memory)
892680SN/A    S, AccessPermission:Read_Only, desc="Shared";    // Correct, most recent. If no one in O, then == Memory
902315SN/A    I, AccessPermission:Invalid, desc="Invalid";
912680SN/A
922330SN/A    I_M, AccessPermission:Busy, desc="Invalid, received WrVicBlk, sent Ack, waiting for Data";
932680SN/A    I_O, AccessPermission:Busy, desc="Invalid, received WrVicBlk, sent Ack, waiting for Data";
942690Sktlim@umich.edu    I_E, AccessPermission:Busy, desc="Invalid, receive ClVicBlk, sent Ack, waiting for Data";
952690Sktlim@umich.edu    I_S, AccessPermission:Busy, desc="Invalid, receive ClVicBlk, sent Ack, waiting for Data";
962690Sktlim@umich.edu    S_M, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to M";
972690Sktlim@umich.edu    S_O, AccessPermission:Busy, desc="received WrVicBlkShared, sent Ack, waiting for Data, then go to O";
982690Sktlim@umich.edu    S_E, AccessPermission:Busy, desc="Shared, received ClVicBlk, sent Ack, waiting for Data, then go to E";
992690Sktlim@umich.edu    S_S, AccessPermission:Busy, desc="Shared, received ClVicBlk, sent Ack, waiting for Data, then go to S";
1002690Sktlim@umich.edu    E_M, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to O";
1012315SN/A    E_O, AccessPermission:Busy, desc="received WrVicBlkShared, sent Ack, waiting for Data, then go to O";
1022690Sktlim@umich.edu    E_E, AccessPermission:Busy, desc="received WrVicBlk, sent Ack, waiting for Data, then go to O";
1032690Sktlim@umich.edu    E_S, AccessPermission:Busy, desc="Shared, received WrVicBlk, sent Ack, waiting for Data";
1042680SN/A    O_M, AccessPermission:Busy, desc="...";
1052315SN/A    O_O, AccessPermission:Busy, desc="...";
1062315SN/A    O_E, AccessPermission:Busy, desc="...";
1072680SN/A    M_M, AccessPermission:Busy, desc="...";
1082315SN/A    M_O, AccessPermission:Busy, desc="...";
1092315SN/A    M_E, AccessPermission:Busy, desc="...";
1102330SN/A    M_S, AccessPermission:Busy, desc="...";
1112680SN/A    D_I, AccessPermission:Invalid,  desc="drop WB data on the floor when receive";
1122680SN/A    MOD_I, AccessPermission:Busy, desc="drop WB data on the floor, waiting for WBAck from Mem";
1132330SN/A    MO_I, AccessPermission:Busy, desc="M or O, received L2_Repl, waiting for WBAck from Mem";
1142315SN/A    ES_I, AccessPermission:Busy, desc="E or S, received L2_Repl, waiting for WBAck from Mem";
1152315SN/A    I_C, AccessPermission:Invalid, desc="sent cancel, just waiting to receive mem wb ack so nothing gets confused";
1162315SN/A  }
1172680SN/A
1182315SN/A  enumeration(RequestType, desc="To communicate stats from transitions to recordStats") {
1192315SN/A    DataArrayRead,    desc="Read the data array";
1202680SN/A    DataArrayWrite,   desc="Write the data array";
1212315SN/A    TagArrayRead,     desc="Read the data array";
1222315SN/A    TagArrayWrite,    desc="Write the data array";
1232887Sktlim@umich.edu  }
1242315SN/A
1252315SN/A
1262680SN/A  // STRUCTURES
1272315SN/A
1282315SN/A  structure(Entry, desc="...", interface="AbstractCacheEntry") {
1292680SN/A    State CacheState,           desc="cache state";
1302315SN/A    bool Dirty,                 desc="Is the data dirty (diff from memory?)";
1312315SN/A    DataBlock DataBlk,          desc="Data for the block";
1322680SN/A  }
1332315SN/A
1342680SN/A  structure(TBE, desc="...") {
1352680SN/A    State TBEState,     desc="Transient state";
1362315SN/A    DataBlock DataBlk,  desc="data for the block";
1372315SN/A    bool Dirty,         desc="Is the data dirty?";
1382680SN/A    bool Shared,        desc="Victim hit by shared probe";
1392315SN/A    MachineID From,     desc="Waiting for writeback from...";
1402680SN/A  }
1412315SN/A
1422680SN/A  structure(TBETable, external="yes") {
1432315SN/A    TBE lookup(Addr);
1442315SN/A    void allocate(Addr);
1452680SN/A    void deallocate(Addr);
1462315SN/A    bool isPresent(Addr);
1472680SN/A  }
1482680SN/A
1492315SN/A  TBETable TBEs, template="<TCC_TBE>", constructor="m_number_of_TBEs";
1502680SN/A  int TCC_select_low_bit, default="RubySystem::getBlockSizeBits()";
1512680SN/A
1522315SN/A  void set_cache_entry(AbstractCacheEntry b);
1532315SN/A  void unset_cache_entry();
1542680SN/A  void set_tbe(TBE b);
1552315SN/A  void unset_tbe();
1562315SN/A  void wakeUpAllBuffers();
1572680SN/A  void wakeUpBuffers(Addr a);
1582315SN/A
1592315SN/A
1602680SN/A  // FUNCTION DEFINITIONS
1612315SN/A  Tick clockEdge();
1622680SN/A  Tick cyclesToTicks(Cycles c);
1632680SN/A
1642315SN/A  Entry getCacheEntry(Addr addr), return_by_pointer="yes" {
1652315SN/A    return static_cast(Entry, "pointer", L2cache.lookup(addr));
1662315SN/A  }
1672315SN/A
1682680SN/A  DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
1692680SN/A    return getCacheEntry(addr).DataBlk;
1702315SN/A  }
1712315SN/A
1722315SN/A  bool presentOrAvail(Addr addr) {
1732315SN/A    return L2cache.isTagPresent(addr) || L2cache.cacheAvail(addr);
1742315SN/A  }
1752315SN/A
1762680SN/A  State getState(TBE tbe, Entry cache_entry, Addr addr) {
1772315SN/A    if (is_valid(tbe)) {
1782669SN/A      return tbe.TBEState;
1792680SN/A    } else if (is_valid(cache_entry)) {
1802315SN/A      return cache_entry.CacheState;
1812669SN/A    }
1822680SN/A    return State:I;
1832315SN/A  }
1842669SN/A
1852680SN/A  void setState(TBE tbe, Entry cache_entry, Addr addr, State state) {
1862669SN/A    if (is_valid(tbe)) {
1872669SN/A        tbe.TBEState := state;
1882680SN/A    }
1892315SN/A
1902315SN/A    if (is_valid(cache_entry)) {
1912315SN/A        cache_entry.CacheState := state;
1922680SN/A    }
1932680SN/A  }
1942315SN/A
1952315SN/A  AccessPermission getAccessPermission(Addr addr) {
1962669SN/A    TBE tbe := TBEs.lookup(addr);
1972315SN/A    if(is_valid(tbe)) {
1982680SN/A      return TCC_State_to_permission(tbe.TBEState);
1992680SN/A    }
2002315SN/A
2012315SN/A    Entry cache_entry := getCacheEntry(addr);
2022669SN/A    if(is_valid(cache_entry)) {
2032315SN/A      return TCC_State_to_permission(cache_entry.CacheState);
2042680SN/A    }
2052680SN/A
2062315SN/A    return AccessPermission:NotPresent;
2072315SN/A  }
2082669SN/A
2092315SN/A  void setAccessPermission(Entry cache_entry, Addr addr, State state) {
2102680SN/A    if (is_valid(cache_entry)) {
2112680SN/A      cache_entry.changePermission(TCC_State_to_permission(state));
2122669SN/A    }
2132669SN/A  }
2142669SN/A
2152669SN/A  void functionalRead(Addr addr, Packet *pkt) {
2162680SN/A    TBE tbe := TBEs.lookup(addr);
2172680SN/A    if(is_valid(tbe)) {
2182315SN/A      testAndRead(addr, tbe.DataBlk, pkt);
2192315SN/A    } else {
2202680SN/A      functionalMemoryRead(pkt);
2212315SN/A    }
2222315SN/A  }
2232315SN/A
2242680SN/A  int functionalWrite(Addr addr, Packet *pkt) {
2252680SN/A    int num_functional_writes := 0;
2262315SN/A
2272315SN/A    TBE tbe := TBEs.lookup(addr);
2282315SN/A    if(is_valid(tbe)) {
2292680SN/A      num_functional_writes := num_functional_writes +
2302315SN/A            testAndWrite(addr, tbe.DataBlk, pkt);
2312315SN/A    }
2322315SN/A
2332680SN/A    num_functional_writes := num_functional_writes + functionalMemoryWrite(pkt);
2342680SN/A    return num_functional_writes;
2352315SN/A  }
2362315SN/A
2372315SN/A  void recordRequestType(RequestType request_type, Addr addr) {
2382680SN/A    if (request_type == RequestType:DataArrayRead) {
2392669SN/A        L2cache.recordRequestType(CacheRequestType:DataArrayRead, addr);
2402669SN/A    } else if (request_type == RequestType:DataArrayWrite) {
2412669SN/A        L2cache.recordRequestType(CacheRequestType:DataArrayWrite, addr);
2422680SN/A    } else if (request_type == RequestType:TagArrayRead) {
2432680SN/A        L2cache.recordRequestType(CacheRequestType:TagArrayRead, addr);
2442669SN/A    } else if (request_type == RequestType:TagArrayWrite) {
2452669SN/A        L2cache.recordRequestType(CacheRequestType:TagArrayWrite, addr);
2462669SN/A    }
2472315SN/A  }
2482680SN/A
2492315SN/A  bool checkResourceAvailable(RequestType request_type, Addr addr) {
2502315SN/A    if (request_type == RequestType:DataArrayRead) {
2512680SN/A      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
2522315SN/A    } else if (request_type == RequestType:DataArrayWrite) {
2532315SN/A      return L2cache.checkResourceAvailable(CacheResourceType:DataArray, addr);
2542315SN/A    } else if (request_type == RequestType:TagArrayRead) {
2552680SN/A      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
2562680SN/A    } else if (request_type == RequestType:TagArrayWrite) {
2572315SN/A      return L2cache.checkResourceAvailable(CacheResourceType:TagArray, addr);
2582315SN/A    } else {
2592315SN/A      error("Invalid RequestType type in checkResourceAvailable");
2602315SN/A      return true;
2612680SN/A    }
2622680SN/A  }
2632315SN/A
2642315SN/A
2652315SN/A
2662680SN/A  // OUT PORTS
2672315SN/A  out_port(w_requestNetwork_out, CPURequestMsg, w_reqToTCCDir);
2682315SN/A  out_port(w_TCCResp_out, ResponseMsg, w_respToTCCDir);
2692315SN/A  out_port(responseNetwork_out, ResponseMsg, responseFromTCC);
2702680SN/A  out_port(w_unblockNetwork_out, UnblockMsg, w_TCCUnblockToTCCDir);
2712680SN/A
2722315SN/A  // IN PORTS
2732315SN/A  in_port(TDResponse_in, ResponseMsg, w_respToTCC) {
2742680SN/A    if (TDResponse_in.isReady(clockEdge())) {
2752315SN/A      peek(TDResponse_in, ResponseMsg) {
2762315SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
2772315SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
2782680SN/A        if (in_msg.Type == CoherenceResponseType:TDSysWBAck) {
2792315SN/A          trigger(Event:WBAck, in_msg.addr, cache_entry, tbe);
2802315SN/A        }
2812680SN/A        else {
2822315SN/A          DPRINTF(RubySlicc, "%s\n", in_msg);
2832315SN/A          error("Error on TDResponse Type");
2842315SN/A        }
2852315SN/A      }
2862680SN/A    }
2872680SN/A  }
2882315SN/A
2892315SN/A  // Response Network
2902315SN/A  in_port(responseNetwork_in, ResponseMsg, responseToTCC) {
2912315SN/A    if (responseNetwork_in.isReady(clockEdge())) {
2922680SN/A      peek(responseNetwork_in, ResponseMsg) {
2932680SN/A        Entry cache_entry := getCacheEntry(in_msg.addr);
2942315SN/A        TBE tbe := TBEs.lookup(in_msg.addr);
2952315SN/A        if (in_msg.Type == CoherenceResponseType:CPUData) {
2962680SN/A          if (in_msg.NbReqShared) {
2972315SN/A            trigger(Event:CPUDataShared, in_msg.addr, cache_entry, tbe);
2982669SN/A          } else {
2992669SN/A            trigger(Event:CPUData, in_msg.addr, cache_entry, tbe);
3002669SN/A          }
3012680SN/A        } else if (in_msg.Type == CoherenceResponseType:StaleNotif) {
3022680SN/A            trigger(Event:StaleWB, in_msg.addr, cache_entry, tbe);
3032669SN/A        } else {
3042315SN/A          DPRINTF(RubySlicc, "%s\n", in_msg);
3052315SN/A          error("Error on TDResponse Type");
3062315SN/A        }
307      }
308    }
309  }
310
311  // probe network
312  in_port(probeNetwork_in, TDProbeRequestMsg, w_probeToTCC) {
313    if (probeNetwork_in.isReady(clockEdge())) {
314      peek(probeNetwork_in, TDProbeRequestMsg) {
315        Entry cache_entry := getCacheEntry(in_msg.addr);
316        TBE tbe := TBEs.lookup(in_msg.addr);
317        if (in_msg.Type == ProbeRequestType:PrbInv) {
318          if (in_msg.ReturnData) {
319            trigger(Event:PrbInvData, in_msg.addr, cache_entry, tbe);
320          } else {
321            trigger(Event:PrbInv, in_msg.addr, cache_entry, tbe);
322          }
323        } else if (in_msg.Type == ProbeRequestType:PrbDowngrade) {
324          if (in_msg.ReturnData) {
325            trigger(Event:PrbShrData, in_msg.addr, cache_entry, tbe);
326          } else {
327            error("Don't think I should get any of these");
328          }
329        }
330      }
331    }
332  }
333
334  // Request Network
335  in_port(requestNetwork_in, CPURequestMsg, w_reqToTCC) {
336    if (requestNetwork_in.isReady(clockEdge())) {
337      peek(requestNetwork_in, CPURequestMsg) {
338        assert(in_msg.Destination.isElement(machineID));
339        Entry cache_entry := getCacheEntry(in_msg.addr);
340        TBE tbe := TBEs.lookup(in_msg.addr);
341        if (in_msg.Type == CoherenceRequestType:RdBlk) {
342          trigger(Event:RdBlk, in_msg.addr, cache_entry, tbe);
343        } else if (in_msg.Type == CoherenceRequestType:RdBlkS) {
344          trigger(Event:RdBlkS, in_msg.addr, cache_entry, tbe);
345        } else if (in_msg.Type == CoherenceRequestType:RdBlkM) {
346          trigger(Event:RdBlkM, in_msg.addr, cache_entry, tbe);
347        } else if (in_msg.Type == CoherenceRequestType:VicClean) {
348          if (presentOrAvail(in_msg.addr)) {
349            if (in_msg.Shared) {
350              trigger(Event:ClVicBlkShared, in_msg.addr, cache_entry, tbe);
351            } else {
352              trigger(Event:ClVicBlk, in_msg.addr, cache_entry, tbe);
353            }
354          } else {
355            Addr victim :=  L2cache.cacheProbe(in_msg.addr);
356            trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
357          }
358        } else if (in_msg.Type == CoherenceRequestType:VicDirty) {
359          if (presentOrAvail(in_msg.addr)) {
360            if (in_msg.Shared) {
361              trigger(Event:WrVicBlkShared, in_msg.addr, cache_entry, tbe);
362            } else {
363              trigger(Event:WrVicBlk, in_msg.addr, cache_entry, tbe);
364            }
365          } else {
366            Addr victim := L2cache.cacheProbe(in_msg.addr);
367            trigger(Event:L2_Repl, victim, getCacheEntry(victim), TBEs.lookup(victim));
368          }
369        } else {
370            requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
371        }
372      }
373    }
374  }
375
376  // BEGIN ACTIONS
377
378  action(i_invL2, "i", desc="invalidate TCC cache block") {
379    if (is_valid(cache_entry)) {
380        L2cache.deallocate(address);
381    }
382    unset_cache_entry();
383  }
384
385  action(rm_sendResponseM, "rm", desc="send Modified response") {
386    peek(requestNetwork_in, CPURequestMsg) {
387      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
388        out_msg.addr := address;
389        out_msg.Type := CoherenceResponseType:TDSysResp;
390        out_msg.Sender := machineID;
391        out_msg.Destination.add(in_msg.Requestor);
392        out_msg.DataBlk := cache_entry.DataBlk;
393        out_msg.MessageSize := MessageSizeType:Response_Data;
394        out_msg.Dirty := cache_entry.Dirty;
395        out_msg.State := CoherenceState:Modified;
396        DPRINTF(RubySlicc, "%s\n", out_msg);
397      }
398    }
399  }
400
401  action(rs_sendResponseS, "rs", desc="send Shared response") {
402    peek(requestNetwork_in, CPURequestMsg) {
403      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
404        out_msg.addr := address;
405        out_msg.Type := CoherenceResponseType:TDSysResp;
406        out_msg.Sender := machineID;
407        out_msg.Destination.add(in_msg.Requestor);
408        out_msg.DataBlk := cache_entry.DataBlk;
409        out_msg.MessageSize := MessageSizeType:Response_Data;
410        out_msg.Dirty := cache_entry.Dirty;
411        out_msg.State := CoherenceState:Shared;
412        DPRINTF(RubySlicc, "%s\n", out_msg);
413      }
414    }
415  }
416
417
418  action(r_requestToTD, "r", desc="Miss in L2, pass on") {
419    peek(requestNetwork_in, CPURequestMsg) {
420      enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
421        out_msg.addr := address;
422        out_msg.Type := in_msg.Type;
423        out_msg.Requestor := in_msg.Requestor;
424        out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
425                                TCC_select_low_bit, TCC_select_num_bits));
426        out_msg.Shared := false; // unneeded for this request
427        out_msg.MessageSize := in_msg.MessageSize;
428        DPRINTF(RubySlicc, "%s\n", out_msg);
429      }
430    }
431  }
432
433  action(t_allocateTBE, "t", desc="allocate TBE Entry") {
434    TBEs.allocate(address);
435    set_tbe(TBEs.lookup(address));
436    if (is_valid(cache_entry)) {
437      tbe.DataBlk := cache_entry.DataBlk; // Data only for WBs
438      tbe.Dirty := cache_entry.Dirty;
439    }
440    tbe.From := machineID;
441  }
442
443  action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") {
444    TBEs.deallocate(address);
445    unset_tbe();
446  }
447
448  action(vc_vicClean, "vc", desc="Victimize Clean L2 data") {
449    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
450      out_msg.addr := address;
451      out_msg.Type := CoherenceRequestType:VicClean;
452      out_msg.Requestor := machineID;
453      out_msg.DataBlk := cache_entry.DataBlk;
454      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
455                              TCC_select_low_bit, TCC_select_num_bits));
456      out_msg.MessageSize := MessageSizeType:Response_Data;
457    }
458  }
459
460  action(vd_vicDirty, "vd", desc="Victimize dirty L2 data") {
461    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
462      out_msg.addr := address;
463      out_msg.Type := CoherenceRequestType:VicDirty;
464      out_msg.Requestor := machineID;
465      out_msg.DataBlk := cache_entry.DataBlk;
466      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
467                              TCC_select_low_bit, TCC_select_num_bits));
468      out_msg.MessageSize := MessageSizeType:Response_Data;
469    }
470  }
471
472  action(w_sendResponseWBAck, "w", desc="send WB Ack") {
473    peek(requestNetwork_in, CPURequestMsg) {
474      enqueue(responseNetwork_out, ResponseMsg, l2_response_latency) {
475        out_msg.addr := address;
476        out_msg.Type := CoherenceResponseType:TDSysWBAck;
477        out_msg.Destination.add(in_msg.Requestor);
478        out_msg.Sender := machineID;
479        out_msg.MessageSize := MessageSizeType:Writeback_Control;
480      }
481    }
482  }
483
484  action(pi_sendProbeResponseInv, "pi", desc="send probe ack inv, no data") {
485    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
486      out_msg.addr := address;
487      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
488      out_msg.Sender := machineID;
489      // will this always be ok? probably not for multisocket
490      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
491                              TCC_select_low_bit, TCC_select_num_bits));
492      out_msg.Dirty := false;
493      out_msg.Hit := false;
494      out_msg.Ntsl := true;
495      out_msg.State := CoherenceState:NA;
496      out_msg.MessageSize := MessageSizeType:Response_Control;
497    }
498  }
499
500  action(ph_sendProbeResponseHit, "ph", desc="send probe ack, no data") {
501    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
502      out_msg.addr := address;
503      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
504      out_msg.Sender := machineID;
505      // will this always be ok? probably not for multisocket
506      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
507                              TCC_select_low_bit, TCC_select_num_bits));
508      out_msg.Dirty := false;
509      out_msg.Hit := true;
510      out_msg.Ntsl := false;
511      out_msg.State := CoherenceState:NA;
512      out_msg.MessageSize := MessageSizeType:Response_Control;
513    }
514  }
515
516  action(pm_sendProbeResponseMiss, "pm", desc="send probe ack, no data") {
517    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
518      out_msg.addr := address;
519      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
520      out_msg.Sender := machineID;
521      // will this always be ok? probably not for multisocket
522      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
523                              TCC_select_low_bit, TCC_select_num_bits));
524      out_msg.Dirty := false;
525      out_msg.Hit := false;
526      out_msg.Ntsl := false;
527      out_msg.State := CoherenceState:NA;
528      out_msg.MessageSize := MessageSizeType:Response_Control;
529    }
530  }
531
532  action(pd_sendProbeResponseData, "pd", desc="send probe ack, with data") {
533    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
534      out_msg.addr := address;
535      out_msg.Type := CoherenceResponseType:CPUPrbResp;  // TCC and CPUs respond in same way to probes
536      out_msg.Sender := machineID;
537      // will this always be ok? probably not for multisocket
538      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
539                              TCC_select_low_bit, TCC_select_num_bits));
540      out_msg.DataBlk := cache_entry.DataBlk;
541      //assert(cache_entry.Dirty); Not needed in TCC where TCC can supply clean data
542      out_msg.Dirty := cache_entry.Dirty;
543      out_msg.Hit := true;
544      out_msg.State := CoherenceState:NA;
545      out_msg.MessageSize := MessageSizeType:Response_Data;
546    }
547  }
548
549  action(pdt_sendProbeResponseDataFromTBE, "pdt", desc="send probe ack with data") {
550    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
551      out_msg.addr := address;
552      out_msg.Type := CoherenceResponseType:CPUPrbResp;
553      out_msg.Sender := machineID;
554      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
555                              TCC_select_low_bit, TCC_select_num_bits));
556      out_msg.DataBlk := tbe.DataBlk;
557      //assert(tbe.Dirty);
558      out_msg.Dirty := tbe.Dirty;
559      out_msg.Hit := true;
560      out_msg.MessageSize := MessageSizeType:Response_Data;
561      out_msg.State := CoherenceState:NA;
562      DPRINTF(RubySlicc, "%s\n", out_msg);
563    }
564  }
565
566  action(mc_cancelMemWriteback, "mc", desc="send writeback cancel to memory") {
567    enqueue(w_requestNetwork_out, CPURequestMsg, l2_request_latency) {
568      out_msg.addr := address;
569      out_msg.Type := CoherenceRequestType:WrCancel;
570      out_msg.Requestor := machineID;
571      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
572                              TCC_select_low_bit, TCC_select_num_bits));
573      out_msg.MessageSize := MessageSizeType:Request_Control;
574    }
575  }
576
577  action(a_allocateBlock, "a", desc="allocate TCC block") {
578    if (is_invalid(cache_entry)) {
579      set_cache_entry(L2cache.allocate(address, new Entry));
580    }
581  }
582
583  action(d_writeData, "d", desc="write data to TCC") {
584    peek(responseNetwork_in, ResponseMsg) {
585      if (in_msg.Dirty) {
586        cache_entry.Dirty := in_msg.Dirty;
587      }
588      cache_entry.DataBlk := in_msg.DataBlk;
589      DPRINTF(RubySlicc, "Writing to TCC: %s\n", in_msg);
590    }
591  }
592
593  action(rd_copyDataFromRequest, "rd", desc="write data to TCC") {
594    peek(requestNetwork_in, CPURequestMsg) {
595      cache_entry.DataBlk := in_msg.DataBlk;
596      cache_entry.Dirty := true;
597    }
598  }
599
600  action(f_setFrom, "f", desc="set who WB is expected to come from") {
601    peek(requestNetwork_in, CPURequestMsg) {
602      tbe.From := in_msg.Requestor;
603    }
604  }
605
606  action(rf_resetFrom, "rf", desc="reset From") {
607    tbe.From := machineID;
608  }
609
610  action(wb_data, "wb", desc="write back data") {
611    enqueue(w_TCCResp_out, ResponseMsg, l2_request_latency) {
612      out_msg.addr := address;
613      out_msg.Type := CoherenceResponseType:CPUData;
614      out_msg.Sender := machineID;
615      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
616                              TCC_select_low_bit, TCC_select_num_bits));
617      out_msg.DataBlk := tbe.DataBlk;
618      out_msg.Dirty := tbe.Dirty;
619      if (tbe.Shared) {
620        out_msg.NbReqShared := true;
621      } else {
622        out_msg.NbReqShared := false;
623      }
624      out_msg.State := CoherenceState:Shared; // faux info
625      out_msg.MessageSize := MessageSizeType:Writeback_Data;
626      DPRINTF(RubySlicc, "%s\n", out_msg);
627    }
628  }
629
630  action(wt_writeDataToTBE, "wt", desc="write WB data to TBE") {
631    peek(responseNetwork_in, ResponseMsg) {
632      tbe.DataBlk := in_msg.DataBlk;
633      tbe.Dirty := in_msg.Dirty;
634    }
635  }
636
637  action(uo_sendUnblockOwner, "uo", desc="state changed to E, M, or O, unblock") {
638    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
639      out_msg.addr := address;
640      out_msg.Sender := machineID;
641      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
642                              TCC_select_low_bit, TCC_select_num_bits));
643      out_msg.MessageSize := MessageSizeType:Unblock_Control;
644      out_msg.currentOwner := true;
645      out_msg.valid := true;
646      DPRINTF(RubySlicc, "%s\n", out_msg);
647    }
648  }
649
650  action(us_sendUnblockSharer, "us", desc="state changed to S , unblock") {
651    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
652      out_msg.addr := address;
653      out_msg.Sender := machineID;
654      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
655                              TCC_select_low_bit, TCC_select_num_bits));
656      out_msg.MessageSize := MessageSizeType:Unblock_Control;
657      out_msg.currentOwner := false;
658      out_msg.valid := true;
659      DPRINTF(RubySlicc, "%s\n", out_msg);
660    }
661  }
662
663  action(un_sendUnblockNotValid, "un", desc="state changed toI, unblock") {
664    enqueue(w_unblockNetwork_out, UnblockMsg, l2_request_latency) {
665      out_msg.addr := address;
666      out_msg.Sender := machineID;
667      out_msg.Destination.add(mapAddressToRange(address,MachineType:TCCdir,
668                              TCC_select_low_bit, TCC_select_num_bits));
669      out_msg.MessageSize := MessageSizeType:Unblock_Control;
670      out_msg.currentOwner := false;
671      out_msg.valid := false;
672      DPRINTF(RubySlicc, "%s\n", out_msg);
673    }
674  }
675
676  action(ut_updateTag, "ut", desc="update Tag (i.e. set MRU)") {
677    L2cache.setMRU(address);
678  }
679
680  action(p_popRequestQueue, "p", desc="pop request queue") {
681    requestNetwork_in.dequeue(clockEdge());
682  }
683
684  action(pr_popResponseQueue, "pr", desc="pop response queue") {
685    responseNetwork_in.dequeue(clockEdge());
686  }
687
688  action(pn_popTDResponseQueue, "pn", desc="pop TD response queue") {
689    TDResponse_in.dequeue(clockEdge());
690  }
691
692  action(pp_popProbeQueue, "pp", desc="pop probe queue") {
693    probeNetwork_in.dequeue(clockEdge());
694  }
695
696  action(zz_recycleRequestQueue, "\z", desc="recycle request queue") {
697    requestNetwork_in.recycle(clockEdge(), cyclesToTicks(recycle_latency));
698  }
699
700
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