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