summaryrefslogtreecommitdiff
path: root/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/protocol/MOESI_CMP_directory-L1cache.sm')
-rw-r--r--src/mem/protocol/MOESI_CMP_directory-L1cache.sm313
1 files changed, 170 insertions, 143 deletions
diff --git a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
index 31de269a9..4082f23c9 100644
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm
@@ -136,6 +136,10 @@ machine(L1Cache, "Directory protocol")
bool isPresent(Address);
}
+ void set_cache_entry(AbstractCacheEntry b);
+ void unset_cache_entry();
+ void set_tbe(TBE b);
+ void unset_tbe();
MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true";
@@ -143,102 +147,69 @@ machine(L1Cache, "Directory protocol")
TimerTable useTimerTable;
int l2_select_low_bit, default="RubySystem::getBlockSizeBits()";
- Entry getCacheEntry(Address addr), return_by_ref="yes" {
- if (L1DcacheMemory.isTagPresent(addr)) {
- return static_cast(Entry, L1DcacheMemory[addr]);
- } else {
- return static_cast(Entry, L1IcacheMemory[addr]);
+ Entry getCacheEntry(Address addr), return_by_pointer="yes" {
+ Entry L1Dcache_entry := static_cast(Entry, "pointer", L1DcacheMemory.lookup(addr));
+ if(is_valid(L1Dcache_entry)) {
+ return L1Dcache_entry;
}
- }
- void changePermission(Address addr, AccessPermission permission) {
- if (L1DcacheMemory.isTagPresent(addr)) {
- return L1DcacheMemory.changePermission(addr, permission);
- } else {
- return L1IcacheMemory.changePermission(addr, permission);
- }
+ Entry L1Icache_entry := static_cast(Entry, "pointer", L1IcacheMemory.lookup(addr));
+ return L1Icache_entry;
}
- bool isCacheTagPresent(Address addr) {
- return (L1DcacheMemory.isTagPresent(addr) || L1IcacheMemory.isTagPresent(addr));
+ Entry getL1DCacheEntry(Address addr), return_by_pointer="yes" {
+ return static_cast(Entry, "pointer", L1DcacheMemory.lookup(addr));
}
- State getState(Address addr) {
- assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false);
+ Entry getL1ICacheEntry(Address addr), return_by_pointer="yes" {
+ return static_cast(Entry, "pointer", L1IcacheMemory.lookup(addr));
+ }
- if(TBEs.isPresent(addr)) {
- return TBEs[addr].TBEState;
- } else if (isCacheTagPresent(addr)) {
- return getCacheEntry(addr).CacheState;
+ 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:I;
}
- void setState(Address addr, State state) {
+ void setState(TBE tbe, Entry cache_entry, Address addr, State state) {
assert((L1DcacheMemory.isTagPresent(addr) && L1IcacheMemory.isTagPresent(addr)) == false);
- if (TBEs.isPresent(addr)) {
- TBEs[addr].TBEState := state;
+ if (is_valid(tbe)) {
+ tbe.TBEState := state;
}
- if (isCacheTagPresent(addr)) {
- if ( ((getCacheEntry(addr).CacheState != State:M) && (state == State:M)) ||
- ((getCacheEntry(addr).CacheState != State:MM) && (state == State:MM)) ||
- ((getCacheEntry(addr).CacheState != State:S) && (state == State:S)) ||
- ((getCacheEntry(addr).CacheState != State:O) && (state == State:O)) ) {
+ if (is_valid(cache_entry)) {
+ if ( ((cache_entry.CacheState != State:M) && (state == State:M)) ||
+ ((cache_entry.CacheState != State:MM) && (state == State:MM)) ||
+ ((cache_entry.CacheState != State:S) && (state == State:S)) ||
+ ((cache_entry.CacheState != State:O) && (state == State:O)) ) {
- getCacheEntry(addr).CacheState := state;
+ cache_entry.CacheState := state;
sequencer.checkCoherence(addr);
}
else {
- getCacheEntry(addr).CacheState := state;
+ cache_entry.CacheState := state;
}
// Set permission
if (state == State:MM || state == State:MM_W) {
- changePermission(addr, AccessPermission:Read_Write);
+ cache_entry.changePermission(AccessPermission:Read_Write);
} else if ((state == State:S) ||
(state == State:O) ||
(state == State:M) ||
(state == State:M_W) ||
(state == State:SM) ||
(state == State:OM)) {
- changePermission(addr, AccessPermission:Read_Only);
+ cache_entry.changePermission(AccessPermission:Read_Only);
} else {
- changePermission(addr, AccessPermission:Invalid);
+ cache_entry.changePermission(AccessPermission:Invalid);
}
}
}
- bool isBlockExclusive(Address addr) {
-
- if (isCacheTagPresent(addr)) {
- if ( (getCacheEntry(addr).CacheState == State:M) || (getCacheEntry(addr).CacheState == State:MM)
- || (getCacheEntry(addr).CacheState == State:MI) || (getCacheEntry(addr).CacheState == State:MM_W)
- ) {
- return true;
- }
- }
-
- return false;
- }
-
- bool isBlockShared(Address addr) {
- if (isCacheTagPresent(addr)) {
- if ( (getCacheEntry(addr).CacheState == State:S) || (getCacheEntry(addr).CacheState == State:O)
- || (getCacheEntry(addr).CacheState == State:SM)
- || (getCacheEntry(addr).CacheState == State:OI)
- || (getCacheEntry(addr).CacheState == State:SI)
- || (getCacheEntry(addr).CacheState == State:OM)
- ) {
- return true;
- }
- }
-
- return false;
- }
-
-
Event mandatory_request_type_to_event(CacheRequestType type) {
if (type == CacheRequestType:LD) {
return Event:Load;
@@ -265,7 +236,9 @@ machine(L1Cache, "Directory protocol")
// Use Timer
in_port(useTimerTable_in, Address, useTimerTable) {
if (useTimerTable_in.isReady()) {
- trigger(Event:Use_Timeout, useTimerTable.readyAddress());
+ trigger(Event:Use_Timeout, useTimerTable.readyAddress(),
+ getCacheEntry(useTimerTable.readyAddress()),
+ TBEs[useTimerTable.readyAddress()]);
}
}
@@ -283,7 +256,8 @@ machine(L1Cache, "Directory protocol")
if (triggerQueue_in.isReady()) {
peek(triggerQueue_in, TriggerMsg) {
if (in_msg.Type == TriggerType:ALL_ACKS) {
- trigger(Event:All_acks, in_msg.Address);
+ trigger(Event:All_acks, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else {
error("Unexpected message");
}
@@ -299,24 +273,33 @@ machine(L1Cache, "Directory protocol")
peek(requestNetwork_in, RequestMsg, block_on="Address") {
assert(in_msg.Destination.isElement(machineID));
DPRINTF(RubySlicc, "L1 received: %s\n", in_msg.Type);
-if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
+
+ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestType:DMA_WRITE) {
if (in_msg.Requestor == machineID && in_msg.RequestorMachine == MachineType:L1Cache) {
- trigger(Event:Own_GETX, in_msg.Address);
+ trigger(Event:Own_GETX, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else {
- trigger(Event:Fwd_GETX, in_msg.Address);
+ trigger(Event:Fwd_GETX, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
}
} else if (in_msg.Type == CoherenceRequestType:GETS) {
- trigger(Event:Fwd_GETS, in_msg.Address);
+ trigger(Event:Fwd_GETS, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceRequestType:DMA_READ) {
- trigger(Event:Fwd_DMA, in_msg.Address);
+ trigger(Event:Fwd_DMA, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceRequestType:WB_ACK) {
- trigger(Event:Writeback_Ack, in_msg.Address);
+ trigger(Event:Writeback_Ack, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceRequestType:WB_ACK_DATA) {
- trigger(Event:Writeback_Ack_Data, in_msg.Address);
+ trigger(Event:Writeback_Ack_Data, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceRequestType:WB_NACK) {
- trigger(Event:Writeback_Nack, in_msg.Address);
+ trigger(Event:Writeback_Nack, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceRequestType:INV) {
- trigger(Event:Inv, in_msg.Address);
+ trigger(Event:Inv, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else {
error("Unexpected message");
}
@@ -329,11 +312,14 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
if (responseToL1Cache_in.isReady()) {
peek(responseToL1Cache_in, ResponseMsg, block_on="Address") {
if (in_msg.Type == CoherenceResponseType:ACK) {
- trigger(Event:Ack, in_msg.Address);
+ trigger(Event:Ack, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceResponseType:DATA) {
- trigger(Event:Data, in_msg.Address);
+ trigger(Event:Data, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
- trigger(Event:Exclusive_Data, in_msg.Address);
+ trigger(Event:Exclusive_Data, in_msg.Address,
+ getCacheEntry(in_msg.Address), TBEs[in_msg.Address]);
} else {
error("Unexpected message");
}
@@ -352,41 +338,63 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
if (in_msg.Type == CacheRequestType:IFETCH) {
// ** INSTRUCTION ACCESS ***
+ Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
// Check to see if it is in the OTHER L1
- if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ if (is_valid(L1Dcache_entry)) {
// The block is in the wrong L1, put the request on the queue to the shared L2
- trigger(Event:L1_Replacement, in_msg.LineAddress);
+ trigger(Event:L1_Replacement, in_msg.LineAddress, L1Dcache_entry,
+ TBEs[in_msg.LineAddress]);
}
- if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
+
+ Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
+ if (is_valid(L1Icache_entry)) {
// The tag matches for the L1, so the L1 asks the L2 for it.
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
+ in_msg.LineAddress, L1Icache_entry,
+ TBEs[in_msg.LineAddress]);
} else {
if (L1IcacheMemory.cacheAvail(in_msg.LineAddress)) {
// L1 does't have the line, but we have space for it in the L1 so let's see if the L2 has it
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
+ in_msg.LineAddress, L1Icache_entry,
+ TBEs[in_msg.LineAddress]);
} else {
// No room in the L1, so we need to make room in the L1
- trigger(Event:L1_Replacement, L1IcacheMemory.cacheProbe(in_msg.LineAddress));
+ trigger(Event:L1_Replacement,
+ L1IcacheMemory.cacheProbe(in_msg.LineAddress),
+ getL1ICacheEntry(L1IcacheMemory.cacheProbe(in_msg.LineAddress)),
+ TBEs[L1IcacheMemory.cacheProbe(in_msg.LineAddress)]);
}
}
} else {
// *** DATA ACCESS ***
+ Entry L1Icache_entry := getL1ICacheEntry(in_msg.LineAddress);
// Check to see if it is in the OTHER L1
- if (L1IcacheMemory.isTagPresent(in_msg.LineAddress)) {
+ if (is_valid(L1Icache_entry)) {
// The block is in the wrong L1, put the request on the queue to the shared L2
- trigger(Event:L1_Replacement, in_msg.LineAddress);
+ trigger(Event:L1_Replacement, in_msg.LineAddress,
+ L1Icache_entry, TBEs[in_msg.LineAddress]);
}
- if (L1DcacheMemory.isTagPresent(in_msg.LineAddress)) {
+
+ Entry L1Dcache_entry := getL1DCacheEntry(in_msg.LineAddress);
+ if (is_valid(L1Dcache_entry)) {
// The tag matches for the L1, so the L1 ask the L2 for it
- trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
+ in_msg.LineAddress, L1Dcache_entry,
+ TBEs[in_msg.LineAddress]);
} else {
if (L1DcacheMemory.cacheAvail(in_msg.LineAddress)) {
// 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.Type), in_msg.LineAddress);
+ trigger(mandatory_request_type_to_event(in_msg.Type),
+ in_msg.LineAddress, L1Dcache_entry,
+ TBEs[in_msg.LineAddress]);
} else {
// No room in the L1, so we need to make room in the L1
- trigger(Event:L1_Replacement, L1DcacheMemory.cacheProbe(in_msg.LineAddress));
+ trigger(Event:L1_Replacement,
+ L1DcacheMemory.cacheProbe(in_msg.LineAddress),
+ getL1DCacheEntry(L1DcacheMemory.cacheProbe(in_msg.LineAddress)),
+ TBEs[L1DcacheMemory.cacheProbe(in_msg.LineAddress)]);
}
}
}
@@ -404,7 +412,7 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
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));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.AccessMode := in_msg.AccessMode;
out_msg.Prefetch := in_msg.Prefetch;
@@ -418,8 +426,9 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:GETX;
out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Request_Control;
out_msg.AccessMode := in_msg.AccessMode;
out_msg.Prefetch := in_msg.Prefetch;
@@ -433,8 +442,9 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Address := address;
out_msg.Type := CoherenceRequestType:PUTX;
out_msg.Requestor := machineID;
+ out_msg.RequestorMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
@@ -446,7 +456,7 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Type := CoherenceRequestType:PUTO;
out_msg.Requestor := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
@@ -458,22 +468,23 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Type := CoherenceRequestType:PUTS;
out_msg.Requestor := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Writeback_Control;
}
}
action(e_sendData, "e", desc="Send data from cache to requestor") {
peek(requestNetwork_in, RequestMsg) {
+ assert(is_valid(cache_entry));
if (in_msg.RequestorMachine == MachineType:L2Cache) {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA;
out_msg.Sender := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.DataBlk := getCacheEntry(address).DataBlk;
- // out_msg.Dirty := getCacheEntry(address).Dirty;
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.DataBlk := cache_entry.DataBlk;
+ // out_msg.Dirty := cache_entry.Dirty;
out_msg.Dirty := false;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:Response_Data;
@@ -486,8 +497,8 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Type := CoherenceResponseType:DATA;
out_msg.Sender := machineID;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.DataBlk := getCacheEntry(address).DataBlk;
- // out_msg.Dirty := getCacheEntry(address).Dirty;
+ out_msg.DataBlk := cache_entry.DataBlk;
+ // out_msg.Dirty := cache_entry.Dirty;
out_msg.Dirty := false;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
@@ -499,13 +510,14 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(e_sendDataToL2, "ee", desc="Send data from cache to requestor") {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
+ assert(is_valid(cache_entry));
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA;
out_msg.Sender := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.DataBlk := getCacheEntry(address).DataBlk;
- out_msg.Dirty := getCacheEntry(address).Dirty;
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.DataBlk := cache_entry.DataBlk;
+ out_msg.Dirty := cache_entry.Dirty;
out_msg.Acks := 0; // irrelevant
out_msg.MessageSize := MessageSizeType:Response_Data;
}
@@ -514,6 +526,7 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(ee_sendDataExclusive, "\e", desc="Send data from cache to requestor, don't keep a shared copy") {
peek(requestNetwork_in, RequestMsg) {
+ assert(is_valid(cache_entry));
if (in_msg.RequestorMachine == MachineType:L2Cache) {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
out_msg.Address := address;
@@ -521,9 +534,9 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.DataBlk := getCacheEntry(address).DataBlk;
- out_msg.Dirty := getCacheEntry(address).Dirty;
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.DataBlk := cache_entry.DataBlk;
+ out_msg.Dirty := cache_entry.Dirty;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:Response_Data;
}
@@ -536,8 +549,8 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.DataBlk := getCacheEntry(address).DataBlk;
- out_msg.Dirty := getCacheEntry(address).Dirty;
+ out_msg.DataBlk := cache_entry.DataBlk;
+ out_msg.Dirty := cache_entry.Dirty;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
}
@@ -566,7 +579,7 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.Acks := 0 - 1; // -1
out_msg.MessageSize := MessageSizeType:Response_Control;
}
@@ -580,7 +593,7 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
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));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Unblock_Control;
}
}
@@ -590,28 +603,33 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:UNBLOCK_EXCLUSIVE;
out_msg.Sender := machineID;
+ out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
+ l2_select_low_bit, l2_select_num_bits));
out_msg.MessageSize := MessageSizeType:Unblock_Control;
}
}
action(h_load_hit, "h", desc="Notify sequencer the load completed.") {
- DPRINTF(RubySlicc, "%s\n", getCacheEntry(address).DataBlk);
- sequencer.readCallback(address, getCacheEntry(address).DataBlk);
+ assert(is_valid(cache_entry));
+ DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
+ sequencer.readCallback(address, cache_entry.DataBlk);
}
action(hh_store_hit, "\h", desc="Notify sequencer that store completed.") {
- DPRINTF(RubySlicc, "%s\n", getCacheEntry(address).DataBlk);
- sequencer.writeCallback(address, getCacheEntry(address).DataBlk);
- getCacheEntry(address).Dirty := true;
+ assert(is_valid(cache_entry));
+ DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk);
+ sequencer.writeCallback(address, cache_entry.DataBlk);
+ cache_entry.Dirty := true;
}
action(i_allocateTBE, "i", desc="Allocate TBE") {
check_allocate(TBEs);
TBEs.allocate(address);
- TBEs[address].DataBlk := getCacheEntry(address).DataBlk; // Data only used for writebacks
- TBEs[address].Dirty := getCacheEntry(address).Dirty;
+ set_tbe(TBEs[address]);
+ assert(is_valid(cache_entry));
+ tbe.DataBlk := cache_entry.DataBlk; // Data only used for writebacks
+ tbe.Dirty := cache_entry.Dirty;
}
action(j_popTriggerQueue, "j", desc="Pop trigger queue.") {
@@ -632,14 +650,16 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(m_decrementNumberOfMessages, "m", desc="Decrement the number of messages for which we're waiting") {
peek(responseToL1Cache_in, ResponseMsg) {
+ assert(is_valid(tbe));
DPRINTF(RubySlicc, "L1 decrementNumberOfMessages: %d\n", in_msg.Acks);
- TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks;
+ tbe.NumPendingMsgs := tbe.NumPendingMsgs - in_msg.Acks;
}
}
action(mm_decrementNumberOfMessages, "\m", desc="Decrement the number of messages for which we're waiting") {
peek(requestNetwork_in, RequestMsg) {
- TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - in_msg.Acks;
+ assert(is_valid(tbe));
+ tbe.NumPendingMsgs := tbe.NumPendingMsgs - in_msg.Acks;
}
}
@@ -648,7 +668,8 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
}
action(o_checkForCompletion, "o", desc="Check if we have received all the messages required for completion") {
- if (TBEs[address].NumPendingMsgs == 0) {
+ assert(is_valid(tbe));
+ if (tbe.NumPendingMsgs == 0) {
enqueue(triggerQueue_out, TriggerMsg) {
out_msg.Address := address;
out_msg.Type := TriggerType:ALL_ACKS;
@@ -663,14 +684,15 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(q_sendDataFromTBEToCache, "q", desc="Send data from TBE to cache") {
peek(requestNetwork_in, RequestMsg) {
+ assert(is_valid(tbe));
if (in_msg.RequestorMachine == MachineType:L1Cache) {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA;
out_msg.Sender := machineID;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.DataBlk := TBEs[address].DataBlk;
- // out_msg.Dirty := TBEs[address].Dirty;
+ out_msg.DataBlk := tbe.DataBlk;
+ // out_msg.Dirty := tbe.Dirty;
out_msg.Dirty := false;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
@@ -682,9 +704,9 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Type := CoherenceResponseType:DATA;
out_msg.Sender := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.DataBlk := TBEs[address].DataBlk;
- // out_msg.Dirty := TBEs[address].Dirty;
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.DataBlk := tbe.DataBlk;
+ // out_msg.Dirty := tbe.Dirty;
out_msg.Dirty := false;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:Response_Data;
@@ -695,14 +717,15 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(q_sendExclusiveDataFromTBEToCache, "qq", desc="Send data from TBE to cache") {
peek(requestNetwork_in, RequestMsg) {
+ assert(is_valid(tbe));
if (in_msg.RequestorMachine == MachineType:L1Cache) {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
out_msg.Address := address;
out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
out_msg.Sender := machineID;
out_msg.Destination.add(in_msg.Requestor);
- out_msg.DataBlk := TBEs[address].DataBlk;
- out_msg.Dirty := TBEs[address].Dirty;
+ out_msg.DataBlk := tbe.DataBlk;
+ out_msg.Dirty := tbe.Dirty;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:ResponseLocal_Data;
}
@@ -713,9 +736,9 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
out_msg.Sender := machineID;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.DataBlk := TBEs[address].DataBlk;
- out_msg.Dirty := TBEs[address].Dirty;
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.DataBlk := tbe.DataBlk;
+ out_msg.Dirty := tbe.Dirty;
out_msg.Acks := in_msg.Acks;
out_msg.MessageSize := MessageSizeType:Response_Data;
}
@@ -727,30 +750,33 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
// L2 will usually request data for a writeback
action(qq_sendWBDataFromTBEToL2, "\q", desc="Send data from TBE to L2") {
enqueue(responseNetwork_out, ResponseMsg, latency=request_latency) {
+ assert(is_valid(tbe));
out_msg.Address := address;
out_msg.Sender := machineID;
out_msg.SenderMachine := MachineType:L1Cache;
out_msg.Destination.add(mapAddressToRange(address, MachineType:L2Cache,
- l2_select_low_bit, l2_select_num_bits));
- out_msg.Dirty := TBEs[address].Dirty;
- if (TBEs[address].Dirty) {
+ l2_select_low_bit, l2_select_num_bits));
+ out_msg.Dirty := tbe.Dirty;
+ if (tbe.Dirty) {
out_msg.Type := CoherenceResponseType:WRITEBACK_DIRTY_DATA;
} else {
out_msg.Type := CoherenceResponseType:WRITEBACK_CLEAN_DATA;
}
- out_msg.DataBlk := TBEs[address].DataBlk;
+ out_msg.DataBlk := tbe.DataBlk;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
}
}
action(s_deallocateTBE, "s", desc="Deallocate TBE") {
TBEs.deallocate(address);
+ unset_tbe();
}
action(u_writeDataToCache, "u", desc="Write data to cache") {
peek(responseToL1Cache_in, ResponseMsg) {
- getCacheEntry(address).DataBlk := in_msg.DataBlk;
- getCacheEntry(address).Dirty := in_msg.Dirty;
+ assert(is_valid(cache_entry));
+ cache_entry.DataBlk := in_msg.DataBlk;
+ cache_entry.Dirty := in_msg.Dirty;
if (in_msg.Type == CoherenceResponseType:DATA) {
//assert(in_msg.Dirty == false);
@@ -761,9 +787,10 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
action(v_writeDataToCacheVerify, "v", desc="Write data to cache, assert it was same as before") {
peek(responseToL1Cache_in, ResponseMsg) {
- assert(getCacheEntry(address).DataBlk == in_msg.DataBlk);
- getCacheEntry(address).DataBlk := in_msg.DataBlk;
- getCacheEntry(address).Dirty := in_msg.Dirty;
+ assert(is_valid(cache_entry));
+ assert(cache_entry.DataBlk == in_msg.DataBlk);
+ cache_entry.DataBlk := in_msg.DataBlk;
+ cache_entry.Dirty := in_msg.Dirty;
}
}
@@ -773,17 +800,18 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
} else {
L1IcacheMemory.deallocate(address);
}
+ unset_cache_entry();
}
action(ii_allocateL1DCacheBlock, "\i", desc="Set L1 D-cache tag equal to tag of block B.") {
- if (L1DcacheMemory.isTagPresent(address) == false) {
- L1DcacheMemory.allocate(address, new Entry);
+ if ((is_invalid(cache_entry))) {
+ set_cache_entry(L1DcacheMemory.allocate(address, new Entry));
}
}
action(jj_allocateL1ICacheBlock, "\j", desc="Set L1 I-cache tag equal to tag of block B.") {
- if (L1IcacheMemory.isTagPresent(address) == false) {
- L1IcacheMemory.allocate(address, new Entry);
+ if ((is_invalid(cache_entry))) {
+ set_cache_entry(L1IcacheMemory.allocate(address, new Entry));
}
}
@@ -1173,4 +1201,3 @@ if (in_msg.Type == CoherenceRequestType:GETX || in_msg.Type == CoherenceRequestT
l_popForwardQueue;
}
}
-