diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -73,6 +73,12 @@ TBETable TBEs, template_hack=""; + // PROTOTYPES + void set_cache_entry(Entry a, AbstractCacheEntry b); + void unset_cache_entry(Entry a); + void set_tbe(TBE b); + void unset_tbe(); + Entry getCacheEntry(Address address); // FUNCTIONS @@ -88,35 +94,31 @@ } } - Entry getCacheEntry(Address addr), return_by_ref="yes" { - return static_cast(Entry, cacheMemory[addr]); - } + State getState(TBE tbe, Entry cacheMemory_entry, Address addr) { - State getState(Address addr) { - - if (TBEs.isPresent(addr)) { - return TBEs[addr].TBEState; + if (is_valid_ptr(tbe_ptr)) { + return tbe.TBEState; } - else if (cacheMemory.isTagPresent(addr)) { - return getCacheEntry(addr).CacheState; + else if (is_valid_ptr(cacheMemory_entry_ptr)) { + return cacheMemory_entry.CacheState; } else { return State:I; } } - void setState(Address addr, State state) { + void setState(TBE tbe, Entry cacheMemory_entry, Address addr, State state) { - if (TBEs.isPresent(addr)) { - TBEs[addr].TBEState := state; + if (is_valid_ptr(tbe_ptr)) { + tbe.TBEState := state; } - if (cacheMemory.isTagPresent(addr)) { - getCacheEntry(addr).CacheState := state; + if (is_valid_ptr(cacheMemory_entry_ptr)) { + cacheMemory_entry.CacheState := state; if (state == State:M) { - cacheMemory.changePermission(addr, AccessPermission:Read_Write); + cacheMemory_entry.changePermission(AccessPermission:Read_Write); } else { - cacheMemory.changePermission(addr, AccessPermission:Invalid); + cacheMemory_entry.changePermission(AccessPermission:Invalid); } } } @@ -141,6 +143,10 @@ in_port(forwardRequestNetwork_in, RequestMsg, forwardToCache) { if (forwardRequestNetwork_in.isReady()) { peek(forwardRequestNetwork_in, RequestMsg, block_on="Address") { + + set_cache_entry(cacheMemory_entry_ptr, cacheMemory.lookup(in_msg.Address)); + set_tbe(TBEs[in_msg.Address]); + if (in_msg.Type == CoherenceRequestType:GETX) { trigger(Event:Fwd_GETX, in_msg.Address); } @@ -163,6 +169,10 @@ in_port(responseNetwork_in, ResponseMsg, responseToCache) { if (responseNetwork_in.isReady()) { peek(responseNetwork_in, ResponseMsg, block_on="Address") { + + set_cache_entry(cacheMemory_entry_ptr, cacheMemory.lookup(in_msg.Address)); + set_tbe(TBEs[in_msg.Address]); + if (in_msg.Type == CoherenceResponseType:DATA) { trigger(Event:Data, in_msg.Address); } @@ -178,14 +188,18 @@ if (mandatoryQueue_in.isReady()) { peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") { + set_cache_entry(cacheMemory_entry_ptr, cacheMemory.lookup(in_msg.LineAddress)); + set_tbe(TBEs[in_msg.LineAddress]); - if (cacheMemory.isTagPresent(in_msg.LineAddress) == false && - cacheMemory.cacheAvail(in_msg.LineAddress) == false ) { - // make room for the block - trigger(Event:Replacement, cacheMemory.cacheProbe(in_msg.LineAddress)); + if (is_valid_ptr(cacheMemory_entry_ptr) || + cacheMemory.cacheAvail(in_msg.LineAddress)) { + trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); } else { - trigger(mandatory_request_type_to_event(in_msg.Type), in_msg.LineAddress); + // make room for the block + set_cache_entry(cacheMemory_entry_ptr, cacheMemory.lookup(cacheMemory.cacheProbe(in_msg.LineAddress))); + set_tbe(TBEs[cacheMemory.cacheProbe(in_msg.LineAddress)]); + trigger(Event:Replacement, cacheMemory.cacheProbe(in_msg.LineAddress)); } } } @@ -209,7 +223,7 @@ out_msg.Type := CoherenceRequestType:PUTX; out_msg.Requestor := machineID; out_msg.Destination.add(map_Address_to_Directory(address)); - out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.DataBlk := cacheMemory_entry.DataBlk; out_msg.MessageSize := MessageSizeType:Data; } } @@ -222,7 +236,7 @@ out_msg.Type := CoherenceResponseType:DATA; out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); - out_msg.DataBlk := getCacheEntry(address).DataBlk; + out_msg.DataBlk := cacheMemory_entry.DataBlk; out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -235,22 +249,23 @@ out_msg.Type := CoherenceResponseType:DATA; out_msg.Sender := machineID; out_msg.Destination.add(in_msg.Requestor); - out_msg.DataBlk := TBEs[address].DataBlk; + out_msg.DataBlk := tbe.DataBlk; out_msg.MessageSize := MessageSizeType:Response_Data; } } } - action(i_allocateL1CacheBlock, "i", desc="Allocate a cache block") { - if (cacheMemory.isTagPresent(address) == false) { - cacheMemory.allocate(address, new Entry); + if (is_valid_ptr(cacheMemory_entry_ptr)) { + } else { + set_cache_entry(cacheMemory_entry_ptr, cacheMemory.allocate(address, new Entry)); } } action(h_deallocateL1CacheBlock, "h", desc="deallocate a cache block") { - if (cacheMemory.isTagPresent(address) == true) { + if (is_valid_ptr(cacheMemory_entry_ptr)) { cacheMemory.deallocate(address); + unset_cache_entry(cacheMemory_entry_ptr); } } @@ -273,55 +288,57 @@ } action(r_load_hit, "r", desc="Notify sequencer the load completed.") { - DPRINTF(RubySlicc,"%s\n", getCacheEntry(address).DataBlk); + DPRINTF(RubySlicc,"%s\n", cacheMemory_entry.DataBlk); sequencer.readCallback(address, GenericMachineType:L1Cache, - getCacheEntry(address).DataBlk); + cacheMemory_entry.DataBlk); } action(rx_load_hit, "rx", desc="External load completed.") { peek(responseNetwork_in, ResponseMsg) { - DPRINTF(RubySlicc,"%s\n", getCacheEntry(address).DataBlk); + DPRINTF(RubySlicc,"%s\n", cacheMemory_entry.DataBlk); sequencer.readCallback(address, getNondirectHitMachType(in_msg.Sender), - getCacheEntry(address).DataBlk); + cacheMemory_entry.DataBlk); } } action(s_store_hit, "s", desc="Notify sequencer that store completed.") { - DPRINTF(RubySlicc,"%s\n", getCacheEntry(address).DataBlk); + DPRINTF(RubySlicc,"%s\n", cacheMemory_entry.DataBlk); sequencer.writeCallback(address, GenericMachineType:L1Cache, - getCacheEntry(address).DataBlk); + cacheMemory_entry.DataBlk); } action(sx_store_hit, "sx", desc="External store completed.") { peek(responseNetwork_in, ResponseMsg) { - DPRINTF(RubySlicc,"%s\n", getCacheEntry(address).DataBlk); + DPRINTF(RubySlicc,"%s\n", cacheMemory_entry.DataBlk); sequencer.writeCallback(address, getNondirectHitMachType(in_msg.Sender), - getCacheEntry(address).DataBlk); + cacheMemory_entry.DataBlk); } } action(u_writeDataToCache, "u", desc="Write data to the cache") { peek(responseNetwork_in, ResponseMsg) { - getCacheEntry(address).DataBlk := in_msg.DataBlk; + cacheMemory_entry.DataBlk := in_msg.DataBlk; } } action(v_allocateTBE, "v", desc="Allocate TBE") { TBEs.allocate(address); + set_tbe(TBEs[address]); } action(w_deallocateTBE, "w", desc="Deallocate TBE") { TBEs.deallocate(address); + unset_tbe(); } action(x_copyDataFromCacheToTBE, "x", desc="Copy data from cache to TBE") { - TBEs[address].DataBlk := getCacheEntry(address).DataBlk; + tbe.DataBlk := cacheMemory_entry.DataBlk; } action(z_stall, "z", desc="stall") { diff --git a/src/mem/protocol/MI_example-dir.sm b/src/mem/protocol/MI_example-dir.sm --- a/src/mem/protocol/MI_example-dir.sm +++ b/src/mem/protocol/MI_example-dir.sm @@ -76,13 +76,16 @@ // ** OBJECTS ** TBETable TBEs, template_hack=""; + void set_tbe(TBE b); + void unset_tbe(); + Entry getDirectoryEntry(Address addr), return_by_ref="yes" { return static_cast(Entry, directory[addr]); } - State getState(Address addr) { - if (TBEs.isPresent(addr)) { - return TBEs[addr].TBEState; + State getState(TBE tbe, Address addr) { + if (is_valid_ptr(tbe_ptr)) { + return tbe.TBEState; } else if (directory.isPresent(addr)) { return getDirectoryEntry(addr).DirectoryState; } else { @@ -90,10 +93,10 @@ } } - void setState(Address addr, State state) { + void setState(TBE tbe, Address addr, State state) { - if (TBEs.isPresent(addr)) { - TBEs[addr].TBEState := state; + if (is_valid_ptr(tbe_ptr)) { + tbe.TBEState := state; } if (directory.isPresent(addr)) { @@ -126,6 +129,7 @@ in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) { if (dmaRequestQueue_in.isReady()) { peek(dmaRequestQueue_in, DMARequestMsg) { + set_tbe(TBEs[in_msg.LineAddress]); if (in_msg.Type == DMARequestType:READ) { trigger(Event:DMA_READ, in_msg.LineAddress); } else if (in_msg.Type == DMARequestType:WRITE) { @@ -140,6 +144,7 @@ in_port(requestQueue_in, RequestMsg, requestToDir) { if (requestQueue_in.isReady()) { peek(requestQueue_in, RequestMsg) { + set_tbe(TBEs[in_msg.Address]); if (in_msg.Type == CoherenceRequestType:GETS) { trigger(Event:GETS, in_msg.Address); } else if (in_msg.Type == CoherenceRequestType:GETX) { @@ -162,6 +167,7 @@ in_port(memQueue_in, MemoryMsg, memBuffer) { if (memQueue_in.isReady()) { peek(memQueue_in, MemoryMsg) { + set_tbe(TBEs[in_msg.Address]); if (in_msg.Type == MemoryRequestType:MEMORY_READ) { trigger(Event:Memory_Data, in_msg.Address); } else if (in_msg.Type == MemoryRequestType:MEMORY_WB) { @@ -236,7 +242,7 @@ out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.Destination.add(tbe.DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -251,7 +257,7 @@ out_msg.LineAddress := address; out_msg.Type := DMAResponseType:DATA; out_msg.DataBlk := in_msg.DataBlk; // we send the entire data block and rely on the dma controller to split it up if need be - out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.Destination.add(tbe.DmaRequestor); out_msg.MessageSize := MessageSizeType:Response_Data; } } @@ -262,7 +268,7 @@ out_msg.PhysicalAddress := address; out_msg.LineAddress := address; out_msg.Type := DMAResponseType:ACK; - out_msg.Destination.add(TBEs[address].DmaRequestor); + out_msg.Destination.add(tbe.DmaRequestor); out_msg.MessageSize := MessageSizeType:Writeback_Control; } } @@ -320,35 +326,39 @@ } action(dwt_writeDMADataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { - getDirectoryEntry(address).DataBlk.copyPartial(TBEs[address].DataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len); } action(v_allocateTBE, "v", desc="Allocate TBE") { peek(dmaRequestQueue_in, DMARequestMsg) { TBEs.allocate(address); - TBEs[address].DataBlk := in_msg.DataBlk; - TBEs[address].PhysicalAddress := in_msg.PhysicalAddress; - TBEs[address].Len := in_msg.Len; - TBEs[address].DmaRequestor := in_msg.Requestor; + set_tbe(TBEs[address]); + tbe.DataBlk := in_msg.DataBlk; + tbe.PhysicalAddress := in_msg.PhysicalAddress; + tbe.Len := in_msg.Len; + tbe.DmaRequestor := in_msg.Requestor; } } action(r_allocateTbeForDmaRead, "\r", desc="Allocate TBE for DMA Read") { peek(dmaRequestQueue_in, DMARequestMsg) { TBEs.allocate(address); - TBEs[address].DmaRequestor := in_msg.Requestor; + set_tbe(TBEs[address]); + tbe.DmaRequestor := in_msg.Requestor; } } action(v_allocateTBEFromRequestNet, "\v", desc="Allocate TBE") { peek(requestQueue_in, RequestMsg) { TBEs.allocate(address); - TBEs[address].DataBlk := in_msg.DataBlk; + set_tbe(TBEs[address]); + tbe.DataBlk := in_msg.DataBlk; } } action(w_deallocateTBE, "w", desc="Deallocate TBE") { TBEs.deallocate(address); + unset_tbe(); } action(z_recycleRequestQueue, "z", desc="recycle request queue") { @@ -412,7 +422,7 @@ out_msg.OriginalRequestorMachId := in_msg.Requestor; // get incoming data // out_msg.DataBlk := in_msg.DataBlk; - out_msg.DataBlk.copyPartial(TBEs[address].DataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + out_msg.DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len); out_msg.MessageSize := in_msg.MessageSize; //out_msg.Prefetch := in_msg.Prefetch; @@ -445,9 +455,9 @@ action(w_writeDataToMemoryFromTBE, "\w", desc="Write date to directory memory from TBE") { //getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk; - getDirectoryEntry(address).DataBlk.copyPartial(TBEs[address].DataBlk, - addressOffset(TBEs[address].PhysicalAddress), - TBEs[address].Len); + getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, + addressOffset(tbe.PhysicalAddress), + tbe.Len); }