diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2014-02-20 17:27:17 -0600 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2014-02-20 17:27:17 -0600 |
commit | 0ce8c2591941fa7899ad7fff445391ec089e974c (patch) | |
tree | 3bbfa08fe6e56c183832292f5f249174e087d39e /src/mem/protocol/MESI_Three_Level-L1.cache | |
parent | db5b3d37fe9628dfe32c1114177d68ebadcea894 (diff) | |
download | gem5-0ce8c2591941fa7899ad7fff445391ec089e974c.tar.xz |
ruby: mesi three level: rename incorrectly named files
Two files had been incorrectly named with a .cache suffix.
--HG--
rename : src/mem/protocol/MESI_Three_Level-L0.cache => src/mem/protocol/MESI_Three_Level-L0cache.sm
rename : src/mem/protocol/MESI_Three_Level-L1.cache => src/mem/protocol/MESI_Three_Level-L1cache.sm
Diffstat (limited to 'src/mem/protocol/MESI_Three_Level-L1.cache')
-rw-r--r-- | src/mem/protocol/MESI_Three_Level-L1.cache | 1046 |
1 files changed, 0 insertions, 1046 deletions
diff --git a/src/mem/protocol/MESI_Three_Level-L1.cache b/src/mem/protocol/MESI_Three_Level-L1.cache deleted file mode 100644 index 2b6d0662f..000000000 --- a/src/mem/protocol/MESI_Three_Level-L1.cache +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * Copyright (c) 1999-2013 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -machine(L1Cache, "MESI Directory L1 Cache CMP") - : CacheMemory * cache, - int l2_select_num_bits, - Cycles l1_request_latency = 2, - Cycles l1_response_latency = 2, - Cycles to_l2_latency = 1, -{ - // From this node's L1 cache TO the network - // a local L1 -> this L2 bank, currently ordered with directory forwarded requests - MessageBuffer requestFromCache, network="To", virtual_network="0", ordered="false", vnet_type="request"; - // a local L1 -> this L2 bank - MessageBuffer responseFromCache, network="To", virtual_network="1", ordered="false", vnet_type="response"; - MessageBuffer unblockFromCache, network="To", virtual_network="2", ordered="false", vnet_type="unblock"; - - - // To this node's L1 cache FROM the network - // a L2 bank -> this L1 - MessageBuffer requestToCache, network="From", virtual_network="0", ordered="false", vnet_type="request"; - // a L2 bank -> this L1 - MessageBuffer responseToCache, network="From", virtual_network="1", ordered="false", vnet_type="response"; - - // Message Buffers between the L1 and the L0 Cache - // From the L1 cache to the L0 cache - MessageBuffer bufferFromL1ToL0, network="To", physical_network="0", ordered="true"; - // From the L0 cache to the L1 cache - MessageBuffer bufferToL1FromL0, network="From", physical_network="0", ordered="true"; - - // STATES - state_declaration(State, desc="Cache states", default="L1Cache_State_I") { - // Base states - NP, AccessPermission:Invalid, desc="Not present in either cache"; - I, AccessPermission:Invalid, desc="a L1 cache entry Idle"; - S, AccessPermission:Read_Only, desc="a L1 cache entry Shared"; - SS, AccessPermission:Read_Only, desc="a L1 cache entry Shared"; - E, AccessPermission:Read_Only, desc="a L1 cache entry Exclusive"; - EE, AccessPermission:Read_Write, desc="a L1 cache entry Exclusive"; - M, AccessPermission:Maybe_Stale, desc="a L1 cache entry Modified", format="!b"; - MM, AccessPermission:Read_Write, desc="a L1 cache entry Modified", format="!b"; - - // Transient States - IS, AccessPermission:Busy, desc="L1 idle, issued GETS, have not seen response yet"; - IM, AccessPermission:Busy, desc="L1 idle, issued GETX, have not seen response yet"; - SM, AccessPermission:Read_Only, desc="L1 idle, issued GETX, have not seen response yet"; - IS_I, AccessPermission:Busy, desc="L1 idle, issued GETS, saw Inv before data because directory doesn't block on GETS hit"; - - M_I, AccessPermission:Busy, desc="L1 replacing, waiting for ACK"; - SINK_WB_ACK, AccessPermission:Busy, desc="This is to sink WB_Acks from L2"; - - // For all of the following states, invalidate - // message has been sent to L0 cache. The response - // from the L0 cache has not been seen yet. - S_IL0, AccessPermission:Busy; - E_IL0, AccessPermission:Busy; - M_IL0, AccessPermission:Busy; - MM_IL0, AccessPermission:Read_Write; - SM_IL0, AccessPermission:Busy; - } - - // EVENTS - enumeration(Event, desc="Cache events") { - // Requests from the L0 cache - Load, desc="Load request"; - Store, desc="Store request"; - WriteBack, desc="Writeback request"; - - // Responses from the L0 Cache - // L0 cache received the invalidation message - // and has sent the data. - L0_DataAck; - - Inv, desc="Invalidate request from L2 bank"; - - // internal generated request - // Invalidate the line in L0 due to own requirements - L0_Invalidate_Own; - // Invalidate the line in L0 due to some other cache's requirements - L0_Invalidate_Else; - // Invalidate the line in the cache due to some one else / space needs. - L1_Replacement; - - // other requests - Fwd_GETX, desc="GETX from other processor"; - Fwd_GETS, desc="GETS from other processor"; - - Data, desc="Data for processor"; - Data_Exclusive, desc="Data for processor"; - DataS_fromL1, desc="data for GETS request, need to unblock directory"; - Data_all_Acks, desc="Data for processor, all acks"; - - L0_Ack, desc="Ack for processor"; - Ack, desc="Ack for processor"; - Ack_all, desc="Last ack for processor"; - - WB_Ack, desc="Ack for replacement"; - } - - // TYPES - - // CacheEntry - structure(Entry, desc="...", interface="AbstractCacheEntry" ) { - State CacheState, desc="cache state"; - DataBlock DataBlk, desc="data for the block"; - bool Dirty, default="false", desc="data is dirty"; - } - - // TBE fields - structure(TBE, desc="...") { - Address Addr, desc="Physical address for this TBE"; - State TBEState, desc="Transient state"; - DataBlock DataBlk, desc="Buffer for the data block"; - bool Dirty, default="false", desc="data is dirty"; - int pendingAcks, default="0", desc="number of pending acks"; - } - - structure(TBETable, external="yes") { - TBE lookup(Address); - void allocate(Address); - void deallocate(Address); - bool isPresent(Address); - } - - TBETable TBEs, template="<L1Cache_TBE>", constructor="m_number_of_TBEs"; - - int l2_select_low_bit, default="RubySystem::getBlockSizeBits()"; - - void set_cache_entry(AbstractCacheEntry a); - void unset_cache_entry(); - void set_tbe(TBE a); - void unset_tbe(); - void wakeUpBuffers(Address a); - void wakeUpAllBuffers(Address a); - void profileMsgDelay(int virtualNetworkType, Cycles c); - - // inclusive cache returns L1 entries only - Entry getCacheEntry(Address addr), return_by_pointer="yes" { - Entry cache_entry := static_cast(Entry, "pointer", cache[addr]); - return cache_entry; - } - - State getState(TBE tbe, Entry cache_entry, Address addr) { - if(is_valid(tbe)) { - return tbe.TBEState; - } else if (is_valid(cache_entry)) { - return cache_entry.CacheState; - } - return State:NP; - } - - void setState(TBE tbe, Entry cache_entry, Address addr, State state) { - // MUST CHANGE - if(is_valid(tbe)) { - tbe.TBEState := state; - } - - if (is_valid(cache_entry)) { - cache_entry.CacheState := state; - } - } - - AccessPermission getAccessPermission(Address addr) { - TBE tbe := TBEs[addr]; - if(is_valid(tbe)) { - DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(tbe.TBEState)); - return L1Cache_State_to_permission(tbe.TBEState); - } - - Entry cache_entry := getCacheEntry(addr); - if(is_valid(cache_entry)) { - DPRINTF(RubySlicc, "%s\n", L1Cache_State_to_permission(cache_entry.CacheState)); - return L1Cache_State_to_permission(cache_entry.CacheState); - } - - DPRINTF(RubySlicc, "%s\n", AccessPermission:NotPresent); - return AccessPermission:NotPresent; - } - - DataBlock getDataBlock(Address addr), return_by_ref="yes" { - TBE tbe := TBEs[addr]; - if(is_valid(tbe)) { - return tbe.DataBlk; - } - - return getCacheEntry(addr).DataBlk; - } - - void setAccessPermission(Entry cache_entry, Address addr, State state) { - if (is_valid(cache_entry)) { - cache_entry.changePermission(L1Cache_State_to_permission(state)); - } - } - - Event mandatory_request_type_to_event(CoherenceClass type) { - if (type == CoherenceClass:GETS) { - return Event:Load; - } else if ((type == CoherenceClass:GETX) || - (type == CoherenceClass:UPGRADE)) { - return Event:Store; - } else if (type == CoherenceClass:PUTX) { - return Event:WriteBack; - } else { - error("Invalid RequestType"); - } - } - - int getPendingAcks(TBE tbe) { - return tbe.pendingAcks; - } - - bool inL0Cache(State state) { - if (state == State:S || state == State:E || state == State:M || - state == State:S_IL0 || state == State:E_IL0 || - state == State:M_IL0 || state == State:SM_IL0) { - return true; - } - - return false; - } - - out_port(requestNetwork_out, RequestMsg, requestFromCache); - out_port(responseNetwork_out, ResponseMsg, responseFromCache); - out_port(unblockNetwork_out, ResponseMsg, unblockFromCache); - out_port(bufferToL0_out, CoherenceMsg, bufferFromL1ToL0); - - // Response From the L2 Cache to this L1 cache - in_port(responseNetwork_in, ResponseMsg, responseToCache, rank = 3) { - if (responseNetwork_in.isReady()) { - peek(responseNetwork_in, ResponseMsg) { - assert(in_msg.Destination.isElement(machineID)); - - Entry cache_entry := getCacheEntry(in_msg.Addr); - TBE tbe := TBEs[in_msg.Addr]; - - if(in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) { - trigger(Event:Data_Exclusive, in_msg.Addr, cache_entry, tbe); - } else if(in_msg.Type == CoherenceResponseType:DATA) { - if ((getState(tbe, cache_entry, in_msg.Addr) == State:IS || - getState(tbe, cache_entry, in_msg.Addr) == State:IS_I) && - machineIDToMachineType(in_msg.Sender) == MachineType:L1Cache) { - - trigger(Event:DataS_fromL1, in_msg.Addr, cache_entry, tbe); - - } else if ( (getPendingAcks(tbe) - in_msg.AckCount) == 0 ) { - trigger(Event:Data_all_Acks, in_msg.Addr, cache_entry, tbe); - } else { - trigger(Event:Data, in_msg.Addr, cache_entry, tbe); - } - } else if (in_msg.Type == CoherenceResponseType:ACK) { - if ( (getPendingAcks(tbe) - in_msg.AckCount) == 0 ) { - trigger(Event:Ack_all, in_msg.Addr, cache_entry, tbe); - } else { - trigger(Event:Ack, in_msg.Addr, cache_entry, tbe); - } - } else if (in_msg.Type == CoherenceResponseType:WB_ACK) { - trigger(Event:WB_Ack, in_msg.Addr, cache_entry, tbe); - } else { - error("Invalid L1 response type"); - } - } - } - } - - // Request to this L1 cache from the shared L2 - in_port(requestNetwork_in, RequestMsg, requestToCache, rank = 2) { - if(requestNetwork_in.isReady()) { - peek(requestNetwork_in, RequestMsg) { - assert(in_msg.Destination.isElement(machineID)); - Entry cache_entry := getCacheEntry(in_msg.Addr); - TBE tbe := TBEs[in_msg.Addr]; - - if (in_msg.Type == CoherenceRequestType:INV) { - if (is_valid(cache_entry) && inL0Cache(cache_entry.CacheState)) { - trigger(Event:L0_Invalidate_Else, in_msg.Addr, - cache_entry, tbe); - } else { - trigger(Event:Inv, in_msg.Addr, cache_entry, tbe); - } - } else if (in_msg.Type == CoherenceRequestType:GETX || - in_msg.Type == CoherenceRequestType:UPGRADE) { - if (is_valid(cache_entry) && inL0Cache(cache_entry.CacheState)) { - trigger(Event:L0_Invalidate_Else, in_msg.Addr, - cache_entry, tbe); - } else { - trigger(Event:Fwd_GETX, in_msg.Addr, cache_entry, tbe); - } - } else if (in_msg.Type == CoherenceRequestType:GETS) { - if (is_valid(cache_entry) && inL0Cache(cache_entry.CacheState)) { - trigger(Event:L0_Invalidate_Else, in_msg.Addr, - cache_entry, tbe); - } else { - trigger(Event:Fwd_GETS, in_msg.Addr, cache_entry, tbe); - } - } else { - error("Invalid forwarded request type"); - } - } - } - } - - // Requests to this L1 cache from the L0 cache. - in_port(messageBufferFromL0_in, CoherenceMsg, bufferToL1FromL0, rank = 0) { - if (messageBufferFromL0_in.isReady()) { - peek(messageBufferFromL0_in, CoherenceMsg) { - Entry cache_entry := getCacheEntry(in_msg.Addr); - TBE tbe := TBEs[in_msg.Addr]; - - if(in_msg.Class == CoherenceClass:INV_DATA) { - trigger(Event:L0_DataAck, in_msg.Addr, cache_entry, tbe); - } else if (in_msg.Class == CoherenceClass:INV_ACK) { - trigger(Event:L0_Ack, in_msg.Addr, cache_entry, tbe); - } else { - if (is_valid(cache_entry)) { - trigger(mandatory_request_type_to_event(in_msg.Class), - in_msg.Addr, cache_entry, tbe); - } else { - if (cache.cacheAvail(in_msg.Addr)) { - // L1 does't have the line, but we have space for it - // in the L1 let's see if the L2 has it - trigger(mandatory_request_type_to_event(in_msg.Class), - in_msg.Addr, cache_entry, tbe); - } else { - // No room in the L1, so we need to make room in the L1 - Entry victim_entry := - getCacheEntry(cache.cacheProbe(in_msg.Addr)); - TBE victim_tbe := TBEs[cache.cacheProbe(in_msg.Addr)]; - - if (is_valid(victim_entry) && inL0Cache(victim_entry.CacheState)) { - trigger(Event:L0_Invalidate_Own, - cache.cacheProbe(in_msg.Addr), - victim_entry, victim_tbe); - } else { - trigger(Event:L1_Replacement, - cache.cacheProbe(in_msg.Addr), - victim_entry, victim_tbe); - } - } - } - } - } - } - } - - // ACTIONS - action(a_issueGETS, "a", desc="Issue GETS") { - peek(messageBufferFromL0_in, CoherenceMsg) { - enqueue(requestNetwork_out, RequestMsg, latency=l1_request_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceRequestType:GETS; - out_msg.Requestor := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - DPRINTF(RubySlicc, "address: %s, destination: %s\n", - address, out_msg.Destination); - out_msg.MessageSize := MessageSizeType:Control; - out_msg.AccessMode := in_msg.AccessMode; - } - } - } - - action(b_issueGETX, "b", desc="Issue GETX") { - peek(messageBufferFromL0_in, CoherenceMsg) { - enqueue(requestNetwork_out, RequestMsg, latency=l1_request_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceRequestType:GETX; - out_msg.Requestor := machineID; - DPRINTF(RubySlicc, "%s\n", machineID); - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - DPRINTF(RubySlicc, "address: %s, destination: %s\n", - address, out_msg.Destination); - out_msg.MessageSize := MessageSizeType:Control; - out_msg.AccessMode := in_msg.AccessMode; - } - } - } - - action(c_issueUPGRADE, "c", desc="Issue GETX") { - peek(messageBufferFromL0_in, CoherenceMsg) { - enqueue(requestNetwork_out, RequestMsg, latency= l1_request_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceRequestType:UPGRADE; - out_msg.Requestor := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - DPRINTF(RubySlicc, "address: %s, destination: %s\n", - address, out_msg.Destination); - out_msg.MessageSize := MessageSizeType:Control; - out_msg.AccessMode := in_msg.AccessMode; - } - } - } - - action(d_sendDataToRequestor, "d", desc="send data to requestor") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - } - - action(d2_sendDataToL2, "d2", desc="send data to the L2 cache because of M downgrade") { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - - action(dt_sendDataToRequestor_fromTBE, "dt", desc="send data to requestor") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(tbe)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := tbe.DataBlk; - out_msg.Dirty := tbe.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - } - - action(d2t_sendDataToL2_fromTBE, "d2t", desc="send data to the L2 cache") { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(tbe)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := tbe.DataBlk; - out_msg.Dirty := tbe.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - - action(e_sendAckToRequestor, "e", desc="send invalidate ack to requestor (could be L2 or L1)") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:ACK; - out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.MessageSize := MessageSizeType:Response_Control; - } - } - } - - action(f_sendDataToL2, "f", desc="send data to the L2 cache") { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Writeback_Data; - } - } - - action(ft_sendDataToL2_fromTBE, "ft", desc="send data to the L2 cache") { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - assert(is_valid(tbe)); - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:DATA; - out_msg.DataBlk := tbe.DataBlk; - out_msg.Dirty := tbe.Dirty; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Writeback_Data; - } - } - - action(fi_sendInvAck, "fi", desc="send data to the L2 cache") { - peek(requestNetwork_in, RequestMsg) { - enqueue(responseNetwork_out, ResponseMsg, latency=l1_response_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:ACK; - out_msg.Sender := machineID; - out_msg.Destination.add(in_msg.Requestor); - out_msg.MessageSize := MessageSizeType:Response_Control; - out_msg.AckCount := 1; - } - } - } - - action(forward_eviction_to_L0, "\cc", desc="sends eviction information to the processor") { - enqueue(bufferToL0_out, CoherenceMsg, latency=l1_request_latency) { - out_msg.Addr := address; - out_msg.Class := CoherenceClass:INV; - out_msg.Sender := machineID; - out_msg.Destination := createMachineID(MachineType:L0Cache, version); - out_msg.MessageSize := MessageSizeType:Control; - } - } - - action(g_issuePUTX, "g", desc="send data to the L2 cache") { - enqueue(requestNetwork_out, RequestMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - out_msg.Addr := address; - out_msg.Type := CoherenceRequestType:PUTX; - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.Requestor:= machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - if (cache_entry.Dirty) { - out_msg.MessageSize := MessageSizeType:Writeback_Data; - } else { - out_msg.MessageSize := MessageSizeType:Writeback_Control; - } - } - } - - action(j_sendUnblock, "j", desc="send unblock to the L2 cache") { - enqueue(unblockNetwork_out, ResponseMsg, latency=to_l2_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:UNBLOCK; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Response_Control; - DPRINTF(RubySlicc, "%s\n", address); - } - } - - action(jj_sendExclusiveUnblock, "\j", desc="send unblock to the L2 cache") { - enqueue(unblockNetwork_out, ResponseMsg, latency=to_l2_latency) { - out_msg.Addr := address; - out_msg.Type := CoherenceResponseType:EXCLUSIVE_UNBLOCK; - out_msg.Sender := machineID; - out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache, - l2_select_low_bit, l2_select_num_bits, clusterID)); - out_msg.MessageSize := MessageSizeType:Response_Control; - DPRINTF(RubySlicc, "%s\n", address); - - } - } - - action(h_data_to_l0, "h", desc="If not prefetch, send data to the L0 cache.") { - enqueue(bufferToL0_out, CoherenceMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - - out_msg.Addr := address; - out_msg.Class := CoherenceClass:DATA; - out_msg.Sender := machineID; - out_msg.Destination := createMachineID(MachineType:L0Cache, version); - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - - action(h_stale_data_to_l0, "hs", desc="If not prefetch, send data to the L0 cache.") { - enqueue(bufferToL0_out, CoherenceMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - - out_msg.Addr := address; - out_msg.Class := CoherenceClass:STALE_DATA; - out_msg.Sender := machineID; - out_msg.Destination := createMachineID(MachineType:L0Cache, version); - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.MessageSize := MessageSizeType:Response_Data; - } - } - - action(hh_xdata_to_l0, "\h", desc="If not prefetch, notify sequencer that store completed.") { - enqueue(bufferToL0_out, CoherenceMsg, latency=l1_response_latency) { - assert(is_valid(cache_entry)); - - out_msg.Addr := address; - out_msg.Class := CoherenceClass:DATA_EXCLUSIVE; - out_msg.Sender := machineID; - out_msg.Destination := createMachineID(MachineType:L0Cache, version); - out_msg.DataBlk := cache_entry.DataBlk; - out_msg.Dirty := cache_entry.Dirty; - out_msg.MessageSize := MessageSizeType:Response_Data; - - cache_entry.Dirty := true; - } - } - - action(i_allocateTBE, "i", desc="Allocate TBE (number of invalidates=0)") { - check_allocate(TBEs); - assert(is_valid(cache_entry)); - TBEs.allocate(address); - set_tbe(TBEs[address]); - tbe.Dirty := cache_entry.Dirty; - tbe.DataBlk := cache_entry.DataBlk; - } - - action(k_popL0RequestQueue, "k", desc="Pop mandatory queue.") { - messageBufferFromL0_in.dequeue(); - } - - action(l_popL2RequestQueue, "l", - desc="Pop incoming request queue and profile the delay within this virtual network") { - profileMsgDelay(2, requestNetwork_in.dequeue_getDelayCycles()); - } - - action(o_popL2ResponseQueue, "o", - desc="Pop Incoming Response queue and profile the delay within this virtual network") { - profileMsgDelay(1, responseNetwork_in.dequeue_getDelayCycles()); - } - - action(s_deallocateTBE, "s", desc="Deallocate TBE") { - TBEs.deallocate(address); - unset_tbe(); - } - - action(u_writeDataFromL0Request, "ureql0", desc="Write data to cache") { - peek(messageBufferFromL0_in, CoherenceMsg) { - assert(is_valid(cache_entry)); - cache_entry.DataBlk := in_msg.DataBlk; - cache_entry.Dirty := in_msg.Dirty; - } - } - - action(u_writeDataFromL2Response, "uresl2", desc="Write data to cache") { - peek(responseNetwork_in, ResponseMsg) { - assert(is_valid(cache_entry)); - cache_entry.DataBlk := in_msg.DataBlk; - cache_entry.Dirty := in_msg.Dirty; - } - } - - action(u_writeDataFromL0Response, "uresl0", desc="Write data to cache") { - peek(messageBufferFromL0_in, CoherenceMsg) { - assert(is_valid(cache_entry)); - cache_entry.DataBlk := in_msg.DataBlk; - cache_entry.Dirty := in_msg.Dirty; - } - } - - action(q_updateAckCount, "q", desc="Update ack count") { - peek(responseNetwork_in, ResponseMsg) { - assert(is_valid(tbe)); - tbe.pendingAcks := tbe.pendingAcks - in_msg.AckCount; - APPEND_TRANSITION_COMMENT(in_msg.AckCount); - APPEND_TRANSITION_COMMENT(" p: "); - APPEND_TRANSITION_COMMENT(tbe.pendingAcks); - } - } - - action(ff_deallocateCacheBlock, "\f", - desc="Deallocate L1 cache block.") { - if (cache.isTagPresent(address)) { - cache.deallocate(address); - } - unset_cache_entry(); - } - - action(oo_allocateCacheBlock, "\o", desc="Set cache tag equal to tag of block B.") { - if (is_invalid(cache_entry)) { - set_cache_entry(cache.allocate(address, new Entry)); - } - } - - action(z0_stallAndWaitL0Queue, "\z0", desc="recycle L0 request queue") { - stall_and_wait(messageBufferFromL0_in, address); - } - - action(z2_stallAndWaitL2Queue, "\z2", desc="recycle L2 request queue") { - stall_and_wait(requestNetwork_in, address); - } - - action(kd_wakeUpDependents, "kd", desc="wake-up dependents") { - wakeUpAllBuffers(address); - } - - action(uu_profileMiss, "\um", desc="Profile the demand miss") { - ++cache.demand_misses; - } - - action(uu_profileHit, "\uh", desc="Profile the demand hit") { - ++cache.demand_hits; - } - - - //***************************************************** - // TRANSITIONS - //***************************************************** - - // Transitions for Load/Store/Replacement/WriteBack from transient states - transition({IS, IM, IS_I, M_I, SM, SINK_WB_ACK, S_IL0, M_IL0, E_IL0, MM_IL0}, - {Load, Store, L1_Replacement}) { - z0_stallAndWaitL0Queue; - } - - // Transitions from Idle - transition({NP,I}, L1_Replacement) { - ff_deallocateCacheBlock; - } - - transition({NP,I}, Load, IS) { - oo_allocateCacheBlock; - i_allocateTBE; - a_issueGETS; - uu_profileMiss; - k_popL0RequestQueue; - } - - transition({NP,I}, Store, IM) { - oo_allocateCacheBlock; - i_allocateTBE; - b_issueGETX; - uu_profileMiss; - k_popL0RequestQueue; - } - - transition({NP, I}, Inv) { - fi_sendInvAck; - l_popL2RequestQueue; - } - - // Transitions from Shared - transition({S,SS}, Load, S) { - h_data_to_l0; - uu_profileHit; - k_popL0RequestQueue; - } - - transition(EE, Load, E) { - hh_xdata_to_l0; - uu_profileHit; - k_popL0RequestQueue; - } - - transition(MM, Load, M) { - hh_xdata_to_l0; - uu_profileHit; - k_popL0RequestQueue; - } - - transition({S,SS}, Store, SM) { - i_allocateTBE; - c_issueUPGRADE; - uu_profileMiss; - k_popL0RequestQueue; - } - - transition(SS, L1_Replacement, I) { - ff_deallocateCacheBlock; - } - - transition(S, {L0_Invalidate_Own, L0_Invalidate_Else}, S_IL0) { - forward_eviction_to_L0; - } - - transition(SS, Inv, I) { - fi_sendInvAck; - ff_deallocateCacheBlock; - l_popL2RequestQueue; - } - - // Transitions from Exclusive - - transition({EE,MM}, Store, M) { - hh_xdata_to_l0; - uu_profileHit; - k_popL0RequestQueue; - } - - transition(EE, L1_Replacement, M_I) { - // silent E replacement?? - i_allocateTBE; - g_issuePUTX; // send data, but hold in case forwarded request - ff_deallocateCacheBlock; - } - - transition(EE, Inv, I) { - // don't send data - fi_sendInvAck; - ff_deallocateCacheBlock; - l_popL2RequestQueue; - } - - transition(EE, Fwd_GETX, I) { - d_sendDataToRequestor; - ff_deallocateCacheBlock; - l_popL2RequestQueue; - } - - transition(EE, Fwd_GETS, SS) { - d_sendDataToRequestor; - d2_sendDataToL2; - l_popL2RequestQueue; - } - - transition(E, {L0_Invalidate_Own, L0_Invalidate_Else}, E_IL0) { - forward_eviction_to_L0; - } - - // Transitions from Modified - transition(MM, L1_Replacement, M_I) { - i_allocateTBE; - g_issuePUTX; // send data, but hold in case forwarded request - ff_deallocateCacheBlock; - } - - transition({M,E}, WriteBack, MM) { - u_writeDataFromL0Request; - k_popL0RequestQueue; - } - - transition(M_I, WB_Ack, I) { - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition(MM, Inv, I) { - f_sendDataToL2; - ff_deallocateCacheBlock; - l_popL2RequestQueue; - } - - transition(M_I, Inv, SINK_WB_ACK) { - ft_sendDataToL2_fromTBE; - l_popL2RequestQueue; - } - - transition(MM, Fwd_GETX, I) { - d_sendDataToRequestor; - l_popL2RequestQueue; - } - - transition(MM, Fwd_GETS, SS) { - d_sendDataToRequestor; - d2_sendDataToL2; - l_popL2RequestQueue; - } - - transition(M, {L0_Invalidate_Own, L0_Invalidate_Else}, M_IL0) { - forward_eviction_to_L0; - } - - transition(M_I, Fwd_GETX, SINK_WB_ACK) { - dt_sendDataToRequestor_fromTBE; - l_popL2RequestQueue; - } - - transition(M_I, Fwd_GETS, SINK_WB_ACK) { - dt_sendDataToRequestor_fromTBE; - d2t_sendDataToL2_fromTBE; - l_popL2RequestQueue; - } - - // Transitions from IS - transition({IS,IS_I}, Inv, IS_I) { - fi_sendInvAck; - l_popL2RequestQueue; - } - - transition(IS, Data_all_Acks, S) { - u_writeDataFromL2Response; - h_data_to_l0; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition(IS_I, Data_all_Acks, I) { - u_writeDataFromL2Response; - h_stale_data_to_l0; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition(IS, DataS_fromL1, S) { - u_writeDataFromL2Response; - j_sendUnblock; - h_data_to_l0; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition(IS_I, DataS_fromL1, I) { - u_writeDataFromL2Response; - j_sendUnblock; - h_stale_data_to_l0; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - // directory is blocked when sending exclusive data - transition(IS, Data_Exclusive, E) { - u_writeDataFromL2Response; - hh_xdata_to_l0; - jj_sendExclusiveUnblock; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - // directory is blocked when sending exclusive data - transition(IS_I, Data_Exclusive, E) { - u_writeDataFromL2Response; - hh_xdata_to_l0; - jj_sendExclusiveUnblock; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - // Transitions from IM - transition({IM,SM}, Inv, IM) { - fi_sendInvAck; - l_popL2RequestQueue; - } - - transition(IM, Data, SM) { - u_writeDataFromL2Response; - q_updateAckCount; - o_popL2ResponseQueue; - } - - transition(IM, Data_all_Acks, M) { - u_writeDataFromL2Response; - hh_xdata_to_l0; - jj_sendExclusiveUnblock; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition({SM, IM}, Ack) { - q_updateAckCount; - o_popL2ResponseQueue; - } - - transition(SM, Ack_all, M) { - jj_sendExclusiveUnblock; - hh_xdata_to_l0; - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition(SM, L0_Invalidate_Else, SM_IL0) { - forward_eviction_to_L0; - } - - transition(SINK_WB_ACK, Inv){ - fi_sendInvAck; - l_popL2RequestQueue; - } - - transition(SINK_WB_ACK, WB_Ack, I){ - s_deallocateTBE; - o_popL2ResponseQueue; - kd_wakeUpDependents; - } - - transition({M_IL0, E_IL0}, WriteBack, MM_IL0) { - u_writeDataFromL0Request; - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition({M_IL0, E_IL0}, L0_DataAck, MM) { - u_writeDataFromL0Response; - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition({M_IL0, MM_IL0}, L0_Ack, MM) { - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition(E_IL0, L0_Ack, EE) { - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition(S_IL0, L0_Ack, SS) { - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition(SM_IL0, L0_Ack, IM) { - k_popL0RequestQueue; - kd_wakeUpDependents; - } - - transition({S_IL0, M_IL0, E_IL0, SM_IL0, SM}, L0_Invalidate_Own) { - z0_stallAndWaitL0Queue; - } - - transition({S_IL0, M_IL0, E_IL0, SM_IL0}, L0_Invalidate_Else) { - z2_stallAndWaitL2Queue; - } - - transition({S_IL0, M_IL0, E_IL0, MM_IL0}, {Inv, Fwd_GETX, Fwd_GETS}) { - z2_stallAndWaitL2Queue; - } -} |