diff -r c5a0889733eb -r 0da5f7f0cf48 configs/example/ruby_mem_test.py --- a/configs/example/ruby_mem_test.py Wed Oct 03 23:12:47 2012 -0500 +++ b/configs/example/ruby_mem_test.py Wed Oct 03 23:14:11 2012 -0500 @@ -43,7 +43,6 @@ # Get paths we might need. It's expected this file is in m5/configs/example. config_path = os.path.dirname(os.path.abspath(__file__)) config_root = os.path.dirname(config_path) -m5_root = os.path.dirname(config_root) parser = optparse.OptionParser() Options.addCommonOptions(parser) diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -201,7 +201,13 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { - return getCacheEntry(addr).DataBlk; + TBE tbe := L1_TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + + Entry cache_entry := getCacheEntry(addr); + return cache_entry.DataBlk; } void setAccessPermission(Entry cache_entry, Address addr, State state) { diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MESI_CMP_directory-L2cache.sm --- a/src/mem/protocol/MESI_CMP_directory-L2cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MESI_CMP_directory-L2cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -232,6 +232,11 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { + TBE tbe := L2_TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + return getCacheEntry(addr).DataBlk; } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MESI_CMP_directory-dir.sm --- a/src/mem/protocol/MESI_CMP_directory-dir.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MESI_CMP_directory-dir.sm Wed Oct 03 23:14:11 2012 -0500 @@ -110,7 +110,7 @@ void set_tbe(TBE tbe); void unset_tbe(); void wakeUpBuffers(Address a); - + Entry getDirectoryEntry(Address addr), return_by_pointer="yes" { Entry dir_entry := static_cast(Entry, "pointer", directory[addr]); @@ -170,6 +170,11 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + return getDirectoryEntry(addr).DataBlk; } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MESI_CMP_directory-msg.sm --- a/src/mem/protocol/MESI_CMP_directory-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MESI_CMP_directory-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -70,6 +70,18 @@ int Len; bool Dirty, default="false", desc="Dirty bit"; PrefetchBit Prefetch, desc="Is this a prefetch request"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceRequestType:PUTX) { + return testAndRead(Address, DataBlk, pkt); + } + + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } // ResponseMsg @@ -82,4 +94,19 @@ bool Dirty, default="false", desc="Dirty bit"; int AckCount, default="0", desc="number of acks in this message"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceResponseType:DATA || + Type == CoherenceResponseType:DATA_EXCLUSIVE || + Type == CoherenceResponseType:MEMORY_DATA) { + + return testAndRead(Address, DataBlk, pkt); + } + + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MI_example-cache.sm --- a/src/mem/protocol/MI_example-cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MI_example-cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -168,6 +168,11 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + return getCacheEntry(addr).DataBlk; } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MI_example-dir.sm --- a/src/mem/protocol/MI_example-dir.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MI_example-dir.sm Wed Oct 03 23:14:11 2012 -0500 @@ -172,6 +172,11 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + return getDirectoryEntry(addr).DataBlk; } @@ -506,7 +511,6 @@ out_msg.OriginalRequestorMachId := in_msg.Requestor; out_msg.DataBlk := in_msg.DataBlk; out_msg.MessageSize := in_msg.MessageSize; - //out_msg.Prefetch := in_msg.Prefetch; DPRINTF(RubySlicc,"%s\n", out_msg); } @@ -518,12 +522,8 @@ } action(w_writeDataToMemoryFromTBE, "\w", desc="Write date to directory memory from TBE") { - //getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk; assert(is_valid(tbe)); - getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, - addressOffset(tbe.PhysicalAddress), - tbe.Len); - + getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk; } // TRANSITIONS @@ -633,7 +633,6 @@ } transition(M, PUTX, MI) { - l_writeDataToMemory; c_clearOwner; v_allocateTBEFromRequestNet; l_queueMemoryWBRequest; diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MI_example-msg.sm --- a/src/mem/protocol/MI_example-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MI_example-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -31,11 +31,9 @@ GETX, desc="Get eXclusive"; GETS, desc="Get Shared"; PUTX, desc="Put eXclusive"; - PUTO, desc="Put Owned"; WB_ACK, desc="Writeback ack"; WB_NACK, desc="Writeback neg. ack"; INV, desc="Invalidation"; - FWD, desc="Generic FWD"; } // CoherenceResponseType @@ -59,6 +57,17 @@ NetDest Destination, desc="Multicast destination mask"; DataBlock DataBlk, desc="data for the cache line"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceRequestType:PUTX) { + return testAndRead(Address, DataBlk, pkt); + } + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } // ResponseMsg (and also unblock requests) @@ -70,6 +79,14 @@ DataBlock DataBlk, desc="data for the cache line"; bool Dirty, desc="Is the data dirty (different than memory)?"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(Address, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { @@ -93,6 +110,14 @@ DataBlock DataBlk, desc="DataBlk attached to this request"; int Len, desc="The length of the request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(LineAddress, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { @@ -102,4 +127,12 @@ NetDest Destination, desc="Destination"; DataBlock DataBlk, desc="DataBlk attached to this request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(LineAddress, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_directory-L1cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -219,7 +219,17 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { - return getCacheEntry(addr).DataBlk; + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return cache_entry.DataBlk; + } + + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + + error("Data block missing!"); } Event mandatory_request_type_to_event(RubyRequestType type) { diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_directory-L2cache.sm --- a/src/mem/protocol/MOESI_CMP_directory-L2cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_directory-L2cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -193,7 +193,7 @@ // TBE fields structure(TBE, desc="...") { - Address Address, desc="Physical address for this TBE"; + Address address, desc="Physical address for this TBE"; State TBEState, desc="Transient state"; Address PC, desc="Program counter of request"; DataBlock DataBlk, desc="Buffer for the data block"; @@ -512,11 +512,6 @@ return L2Cache_State_to_permission(cache_entry.CacheState); } - else if (localDirectory.isTagPresent(addr)) { - DPRINTF(RubySlicc, "%s\n", L2Cache_State_to_permission(localDirectory[addr].DirState)); - return L2Cache_State_to_permission(localDirectory[addr].DirState); - } - DPRINTF(RubySlicc, "AccessPermission_NotPresent\n"); return AccessPermission:NotPresent; } @@ -528,7 +523,13 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { - return getCacheEntry(addr).DataBlk; + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + + Entry cache_entry := getCacheEntry(addr); + return cache_entry.DataBlk; } MessageBuffer triggerQueue, ordered="true"; @@ -1451,6 +1452,8 @@ peek(responseNetwork_in, ResponseMsg) { assert(is_valid(cache_entry)); cache_entry.DataBlk := in_msg.DataBlk; + DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n", + address, cache_entry.DataBlk); if ((cache_entry.Dirty == false) && in_msg.Dirty) { cache_entry.Dirty := in_msg.Dirty; } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_directory-dir.sm --- a/src/mem/protocol/MOESI_CMP_directory-dir.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_directory-dir.sm Wed Oct 03 23:14:11 2012 -0500 @@ -473,6 +473,9 @@ // implementation. We include the data in the "dataless" // message so we can assert the clean data matches the datablock // in memory + DPRINTF(RubySlicc, "Address: %s, MsgDataBlock: %s MemoryDataBlock: %s\n", + in_msg.Address, in_msg.DataBlk, + getDirectoryEntry(in_msg.Address).DataBlk); assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk); } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_directory-msg.sm --- a/src/mem/protocol/MOESI_CMP_directory-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_directory-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -71,6 +71,14 @@ structure(TriggerMsg, desc="...", interface="Message") { Address Address, desc="Physical address for this request"; TriggerType Type, desc="Type of trigger"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return false; + } } // RequestMsg (and also forwarded requests) @@ -86,6 +94,18 @@ MessageSizeType MessageSize, desc="size category of the message"; RubyAccessMode AccessMode, desc="user/supervisor access type"; PrefetchBit Prefetch, desc="Is this a prefetch request"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceRequestType:DMA_READ || + Type == CoherenceRequestType:DMA_WRITE) { + return testAndRead(Address, DataBlk, pkt); + } + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } // ResponseMsg (and also unblock requests) @@ -99,4 +119,18 @@ bool Dirty, desc="Is the data dirty (different than memory)?"; int Acks, desc="How many acks to expect"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceResponseType:DATA || + Type == CoherenceResponseType:DATA_EXCLUSIVE || + Type == CoherenceResponseType:WRITEBACK_CLEAN_DATA || + Type == CoherenceResponseType:WRITEBACK_DIRTY_DATA) { + return testAndRead(Address, DataBlk, pkt); + } + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_token-L1cache.sm --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -139,7 +139,7 @@ // TBE fields structure(TBE, desc="...") { - Address Address, desc="Physical address for this TBE"; + Address address, desc="Physical address for this TBE"; State TBEState, desc="Transient state"; int IssueCount, default="0", desc="The number of times we've issued a request for this line."; Address PC, desc="Program counter of request"; diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_token-dir.sm --- a/src/mem/protocol/MOESI_CMP_token-dir.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm Wed Oct 03 23:14:11 2012 -0500 @@ -677,6 +677,7 @@ enqueue(memQueue_out, MemoryMsg, latency="1") { out_msg.Address := address; out_msg.Type := MemoryRequestType:MEMORY_WB; + out_msg.DataBlk := getDirectoryEntry(address).DataBlk; DPRINTF(RubySlicc, "%s\n", out_msg); } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_CMP_token-msg.sm --- a/src/mem/protocol/MOESI_CMP_token-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_CMP_token-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -66,6 +66,14 @@ MessageSizeType MessageSize, desc="size category of the message"; RubyAccessMode AccessMode, desc="user/supervisor access type"; PrefetchBit Prefetch, desc="Is this a prefetch request"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return false; + } } // RequestMsg @@ -79,6 +87,14 @@ MessageSizeType MessageSize, desc="size category of the message"; RubyAccessMode AccessMode, desc="user/supervisor access type"; PrefetchBit Prefetch, desc="Is this a prefetch request"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return false; + } } // ResponseMsg @@ -91,6 +107,14 @@ DataBlock DataBlk, desc="data for the cache line"; bool Dirty, desc="Is the data dirty (different than memory)?"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(Address, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { @@ -114,6 +138,14 @@ DataBlock DataBlk, desc="DataBlk attached to this request"; int Len, desc="The length of the request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { @@ -123,4 +155,12 @@ NetDest Destination, desc="Destination"; DataBlock DataBlk, desc="DataBlk attached to this request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_hammer-cache.sm --- a/src/mem/protocol/MOESI_hammer-cache.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_hammer-cache.sm Wed Oct 03 23:14:11 2012 -0500 @@ -198,7 +198,17 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { - return getCacheEntry(addr).DataBlk; + Entry cache_entry := getCacheEntry(addr); + if(is_valid(cache_entry)) { + return cache_entry.DataBlk; + } + + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + + error("Missing data block"); } Entry getL2CacheEntry(Address address), return_by_pointer="yes" { @@ -879,6 +889,7 @@ tbe.ForwardRequestTime, tbe.FirstResponseTime); } + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); cache_entry.Dirty := true; } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_hammer-dir.sm --- a/src/mem/protocol/MOESI_hammer-dir.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_hammer-dir.sm Wed Oct 03 23:14:11 2012 -0500 @@ -199,7 +199,17 @@ } DataBlock getDataBlock(Address addr), return_by_ref="yes" { - return getDirectoryEntry(addr).DataBlk; + Entry dir_entry := getDirectoryEntry(addr); + if(is_valid(dir_entry)) { + return dir_entry.DataBlk; + } + + TBE tbe := TBEs[addr]; + if(is_valid(tbe)) { + return tbe.DataBlk; + } + + error("Data block missing!"); } PfEntry getProbeFilterEntry(Address addr), return_by_pointer="yes" { @@ -222,7 +232,7 @@ return getDirectoryEntry(addr).DirectoryState; } } - + void setState(TBE tbe, PfEntry pf_entry, Address addr, State state) { if (is_valid(tbe)) { tbe.TBEState := state; diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/MOESI_hammer-msg.sm --- a/src/mem/protocol/MOESI_hammer-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/MOESI_hammer-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -73,6 +73,14 @@ structure(TriggerMsg, desc="...", interface="Message") { Address Address, desc="Physical address for this request"; TriggerType Type, desc="Type of trigger"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return false; + } } // RequestMsg (and also forwarded requests) @@ -87,6 +95,14 @@ Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache"; Time ForwardRequestTime, default="0", desc="time the dir forwarded the request"; int SilentAcks, default="0", desc="silent acks from the full-bit directory"; + + bool functionalRead(Packet *pkt) { + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return false; + } } // ResponseMsg (and also unblock requests) @@ -103,6 +119,22 @@ Time InitialRequestTime, default="0", desc="time the initial requests was sent from the L1Cache"; Time ForwardRequestTime, default="0", desc="time the dir forwarded the request"; int SilentAcks, default="0", desc="silent acks from the full-bit directory"; + + bool functionalRead(Packet *pkt) { + if (Type == CoherenceResponseType:DATA || + Type == CoherenceResponseType:DATA_SHARED || + Type == CoherenceResponseType:DATA_EXCLUSIVE || + Type == CoherenceResponseType:WB_DIRTY || + Type == CoherenceResponseType:WB_EXCLUSIVE_DIRTY) { + return testAndRead(Address, DataBlk, pkt); + } + + return false; + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } enumeration(DMARequestType, desc="...", default="DMARequestType_NULL") { @@ -126,6 +158,14 @@ DataBlock DataBlk, desc="DataBlk attached to this request"; int Len, desc="The length of the request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(LineAddress, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } structure(DMAResponseMsg, desc="...", interface="NetworkMessage") { @@ -135,4 +175,12 @@ NetDest Destination, desc="Destination"; DataBlock DataBlk, desc="DataBlk attached to this request"; MessageSizeType MessageSize, desc="size category of the message"; + + bool functionalRead(Packet *pkt) { + return testAndRead(LineAddress, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(LineAddress, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/Network_test-msg.sm --- a/src/mem/protocol/Network_test-msg.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/Network_test-msg.sm Wed Oct 03 23:14:11 2012 -0500 @@ -40,4 +40,8 @@ NetDest Destination, desc="Multicast destination mask"; DataBlock DataBlk, desc="data for the cache line"; MessageSizeType MessageSize, desc="size category of the message"; + + void functionalWrite(PacketPtr pkt) { + error("Network test does not support functional accesses!"); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/RubySlicc_Exports.sm --- a/src/mem/protocol/RubySlicc_Exports.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/RubySlicc_Exports.sm Wed Oct 03 23:14:11 2012 -0500 @@ -27,24 +27,23 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * $Id$ - * - */ - -// defines +// Declarations of external types that are common to all protocols external_type(int, primitive="yes", default="0"); external_type(bool, primitive="yes", default="false"); external_type(std::string, primitive="yes"); external_type(uint64, primitive="yes"); external_type(Time, primitive="yes", default="0"); +external_type(PacketPtr, primitive="yes"); +external_type(Packet, primitive="yes"); external_type(Address); + structure(DataBlock, external = "yes", desc="..."){ void clear(); void copyPartial(DataBlock, int, int); } -// Declarations of external types that are common to all protocols +bool testAndRead(Address addr, DataBlock datablk, Packet *pkt); +bool testAndWrite(Address addr, DataBlock datablk, PacketPtr pkt); // AccessPermission // The following five states define the access permission of all memory blocks. @@ -265,6 +264,14 @@ DataBlock DataBlk, desc="Data"; int Len, desc="size in bytes of access"; PrefetchBit Prefetch, desc="Is this a prefetch request"; + + bool functionalRead(Packet *pkt) { + return testAndRead(PhysicalAddress, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(PhysicalAddress, DataBlk, pkt); + } } // MaskPredictorType diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/protocol/RubySlicc_MemControl.sm --- a/src/mem/protocol/RubySlicc_MemControl.sm Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/protocol/RubySlicc_MemControl.sm Wed Oct 03 23:14:11 2012 -0500 @@ -61,4 +61,12 @@ PrefetchBit Prefetch, desc="Is this a prefetch request"; bool ReadX, desc="Exclusive"; int Acks, desc="How many acks to expect"; + + bool functionalRead(Packet *pkt) { + return testAndRead(Address, DataBlk, pkt); + } + + bool functionalWrite(PacketPtr pkt) { + return testAndWrite(Address, DataBlk, pkt); + } } diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/buffers/MessageBuffer.hh --- a/src/mem/ruby/buffers/MessageBuffer.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/buffers/MessageBuffer.hh Wed Oct 03 23:14:11 2012 -0500 @@ -41,10 +41,10 @@ #include #include +#include "mem/packet.hh" #include "mem/ruby/buffers/MessageBufferNode.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/Message.hh" class MessageBuffer @@ -65,12 +65,7 @@ void stallMessage(const Address& addr); // TRUE if head of queue timestamp <= SystemTime - bool - isReady() const - { - return ((m_prio_heap.size() > 0) && - (m_prio_heap.front().m_time <= g_system_ptr->getTime())); - } + bool isReady() const; void delayHead() @@ -145,6 +140,9 @@ void setIncomingLink(int link_id) { m_input_link_id = link_id; } void setVnet(int net) { m_vnet_id = net; } + bool functionalRead(PacketPtr& pkt); + uint32_t functionalWrite(const PacketPtr& pkt); + private: //added by SS int m_recycle_latency; diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/buffers/MessageBuffer.cc --- a/src/mem/ruby/buffers/MessageBuffer.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/buffers/MessageBuffer.cc Wed Oct 03 23:14:11 2012 -0500 @@ -435,3 +435,67 @@ out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter << " full:" << m_not_avail_count << endl; } + +bool +MessageBuffer::isReady() const +{ + return ((m_prio_heap.size() > 0) && + (m_prio_heap.front().m_time <= g_system_ptr->getTime())); +} + +bool +MessageBuffer::functionalRead(PacketPtr& pkt) +{ + for (unsigned int i = 0; i < m_prio_heap.size(); ++i) { + Message *msg = m_prio_heap[i].m_msgptr.get(); + if (msg->functionalRead(pkt)) return true; + } + + // Read the messages in the stall queue that correspond + // to the address in the packet. + for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin(); + map_iter != m_stall_msg_map.end(); + ++map_iter) { + + for (std::list::iterator it = (map_iter->second).begin(); + it != (map_iter->second).end(); ++it) { + + Message *msg = (*it).get(); + if (msg->functionalRead(pkt)) return true; + } + } + return false; +} + +uint32_t +MessageBuffer::functionalWrite(const PacketPtr& pkt) +{ + uint32_t num_functional_writes = 0; + + // Check the priority heap and write any messages that may + // correspond to the address in the packet. + for (unsigned int i = 0; i < m_prio_heap.size(); ++i) { + Message *msg = m_prio_heap[i].m_msgptr.get(); + if (msg->functionalWrite(pkt)) { + num_functional_writes++; + } + } + + // Check the stall queue and write any messages that may + // correspond to the address in the packet. + for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin(); + map_iter != m_stall_msg_map.end(); + ++map_iter) { + + for (std::list::iterator it = (map_iter->second).begin(); + it != (map_iter->second).end(); ++it) { + + Message *msg = (*it).get(); + if (msg->functionalWrite(pkt)) { + num_functional_writes++; + } + } + } + + return num_functional_writes; +} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/buffers/MessageBufferNode.hh --- a/src/mem/ruby/buffers/MessageBufferNode.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/buffers/MessageBufferNode.hh Wed Oct 03 23:14:11 2012 -0500 @@ -31,7 +31,6 @@ #include -#include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/Message.hh" class MessageBufferNode diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/Network.hh --- a/src/mem/ruby/network/Network.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/Network.hh Wed Oct 03 23:14:11 2012 -0500 @@ -44,6 +44,7 @@ #include #include +#include "mem/packet.hh" #include "mem/protocol/LinkDirection.hh" #include "mem/protocol/MessageSizeType.hh" #include "mem/ruby/common/TypeDefines.hh" @@ -81,7 +82,7 @@ bool isReconfiguration) = 0; virtual void makeInLink(NodeID src, SwitchID dest, BasicLink* link, LinkDirection direction, - const NetDest& routing_table_entry, + const NetDest& routing_table_entry, bool isReconfiguration) = 0; virtual void makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link, LinkDirection direction, @@ -94,6 +95,11 @@ virtual void clearStats() = 0; virtual void print(std::ostream& out) const = 0; + virtual bool functionalRead(Packet *pkt) + { fatal("Functional read not implemented.\n"); } + virtual uint32_t functionalWrite(Packet *pkt) + { fatal("Functional write not implemented.\n"); } + protected: // Private copy constructor and assignment operator Network(const Network& obj); diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/simple/PerfectSwitch.cc --- a/src/mem/ruby/network/simple/PerfectSwitch.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/simple/PerfectSwitch.cc Wed Oct 03 23:14:11 2012 -0500 @@ -343,4 +343,3 @@ { out << "[PerfectSwitch " << m_switch_id << "]"; } - diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/simple/SimpleNetwork.hh --- a/src/mem/ruby/network/simple/SimpleNetwork.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/simple/SimpleNetwork.hh Wed Oct 03 23:14:11 2012 -0500 @@ -86,6 +86,9 @@ void print(std::ostream& out) const; + bool functionalRead(Packet *pkt); + uint32_t functionalWrite(Packet *pkt); + private: void checkNetworkAllocation(NodeID id, bool ordered, int network_num); void addLink(SwitchID src, SwitchID dest, int link_latency); diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/simple/SimpleNetwork.cc --- a/src/mem/ruby/network/simple/SimpleNetwork.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc Wed Oct 03 23:14:11 2012 -0500 @@ -327,3 +327,36 @@ { return new SimpleNetwork(this); } + +bool +SimpleNetwork::functionalRead(Packet *pkt) +{ + for (int i = 0; i < m_switch_ptr_vector.size(); i++) { + if (m_switch_ptr_vector[i]->functionalRead(pkt)) { + return true; + } + } + + for (int i = 0; i < m_buffers_to_free.size(); ++i) { + if (m_buffers_to_free[i]->functionalRead(pkt)) { + return true; + } + } + + return false; +} + +uint32_t +SimpleNetwork::functionalWrite(Packet *pkt) +{ + uint32_t num_functional_writes = 0; + + for (int i = 0; i < m_switch_ptr_vector.size(); i++) { + num_functional_writes += m_switch_ptr_vector[i]->functionalWrite(pkt); + } + + for (int i = 0; i < m_buffers_to_free.size(); ++i) { + num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); + } + return num_functional_writes; +} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/simple/Switch.hh --- a/src/mem/ruby/network/simple/Switch.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/simple/Switch.hh Wed Oct 03 23:14:11 2012 -0500 @@ -74,6 +74,9 @@ void print(std::ostream& out) const; void init_net_ptr(SimpleNetwork* net_ptr) { m_network_ptr = net_ptr; } + bool functionalRead(Packet *); + uint32_t functionalWrite(Packet *); + private: // Private copy constructor and assignment operator Switch(const Switch& obj); diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/network/simple/Switch.cc --- a/src/mem/ruby/network/simple/Switch.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/network/simple/Switch.cc Wed Oct 03 23:14:11 2012 -0500 @@ -218,6 +218,27 @@ out << "[Switch]"; } +bool +Switch::functionalRead(Packet *pkt) +{ + for (int i = 0; i < m_buffers_to_free.size(); ++i) { + if (m_buffers_to_free[i]->functionalRead(pkt)) { + return true; + } + } + return false; +} + +uint32_t +Switch::functionalWrite(Packet *pkt) +{ + uint32_t num_functional_writes = 0; + for (int i = 0; i < m_buffers_to_free.size(); ++i) { + num_functional_writes += m_buffers_to_free[i]->functionalWrite(pkt); + } + return num_functional_writes; +} + Switch * SwitchParams::create() { diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/AbstractController.hh --- a/src/mem/ruby/slicc_interface/AbstractController.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/AbstractController.hh Wed Oct 03 23:14:11 2012 -0500 @@ -32,6 +32,7 @@ #include #include +#include "mem/packet.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" @@ -68,6 +69,9 @@ virtual void clearStats() = 0; virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0; virtual Sequencer* getSequencer() const = 0; + + virtual bool functionalReadBuffers(PacketPtr&) = 0; + virtual uint32_t functionalWriteBuffers(const PacketPtr&) = 0; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/Message.hh --- a/src/mem/ruby/slicc_interface/Message.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/Message.hh Wed Oct 03 23:14:11 2012 -0500 @@ -61,6 +61,11 @@ virtual void setIncomingLink(int) {} virtual void setVnet(int) {} + virtual bool functionalRead(Packet *pkt) + { fatal("Read functional access not implemented!"); } + virtual bool functionalWrite(const PacketPtr& pkt) + { fatal("Write functional access not implemented!"); } + void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; } const int& getDelayedCycles() const {return m_DelayedCycles;} int& getDelayedCycles() {return m_DelayedCycles;} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/NetworkMessage.hh --- a/src/mem/ruby/slicc_interface/NetworkMessage.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/NetworkMessage.hh Wed Oct 03 23:14:11 2012 -0500 @@ -33,7 +33,6 @@ #include "base/refcnt.hh" #include "mem/protocol/MessageSizeType.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/slicc_interface/Message.hh" diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/RubyRequest.hh --- a/src/mem/ruby/slicc_interface/RubyRequest.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/RubyRequest.hh Wed Oct 03 23:14:11 2012 -0500 @@ -126,6 +126,9 @@ } void print(std::ostream& out) const; + + bool functionalRead(Packet *pkt); + bool functionalWrite(const PacketPtr& pkt); }; inline std::ostream& diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/RubyRequest.cc --- a/src/mem/ruby/slicc_interface/RubyRequest.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/RubyRequest.cc Wed Oct 03 23:14:11 2012 -0500 @@ -18,3 +18,29 @@ // out << "Time = " << getTime() << " "; out << "]"; } + +bool +RubyRequest::functionalRead(Packet *pkt) +{ + return false; +} + +bool +RubyRequest::functionalWrite(const PacketPtr& pkt) +{ + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + if (pktLineAddr == m_LineAddress) { + uint8_t *pktData = pkt->getPtr(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - m_LineAddress.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + data[i + startByte] = pktData[i]; + } + + return true; + } + return false; +} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/slicc_interface/RubySlicc_Util.hh --- a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh Wed Oct 03 23:14:11 2012 -0500 @@ -35,6 +35,7 @@ #include +#include "debug/RubySlicc.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" @@ -129,4 +130,48 @@ return val % mod; } +inline bool +testAndRead(Address addr, DataBlock& blk, Packet *pkt) +{ + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + Address lineAddr = addr; + lineAddr.makeLineAddress(); + + if (pktLineAddr == lineAddr) { + uint8_t *data = pkt->getPtr(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - lineAddr.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + data[i] = blk.getByte(i + startByte); + } + return true; + } + return false; +} + +inline bool +testAndWrite(Address addr, DataBlock& blk, PacketPtr pkt) +{ + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + Address lineAddr = addr; + lineAddr.makeLineAddress(); + + if (pktLineAddr == lineAddr) { + uint8_t *data = pkt->getPtr(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - lineAddr.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + blk.setByte(i + startByte, data[i]); + } + return true; + } + return false; +} + #endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__ diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/system/MemoryControl.hh --- a/src/mem/ruby/system/MemoryControl.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/system/MemoryControl.hh Wed Oct 03 23:14:11 2012 -0500 @@ -35,19 +35,14 @@ #include #include "mem/protocol/MemoryControlRequestType.hh" -#include "mem/protocol/MemoryMsg.hh" #include "mem/ruby/common/Consumer.hh" -#include "mem/ruby/profiler/MemCntrlProfiler.hh" #include "mem/ruby/slicc_interface/Message.hh" #include "mem/ruby/system/MemoryNode.hh" -#include "mem/ruby/system/System.hh" #include "params/MemoryControl.hh" #include "sim/clocked_object.hh" ////////////////////////////////////////////////////////////////////////////// -class Consumer; - class MemoryControl : public ClockedObject, public Consumer { public: @@ -97,6 +92,11 @@ virtual void recordRequestType(MemoryControlRequestType requestType); + virtual bool functionalReadBuffers(Packet *pkt) + { fatal("Functional read access not implemented!");} + virtual uint32_t functionalWriteBuffers(Packet *pkt) + { fatal("Functional read access not implemented!");} + protected: class MemCntrlEvent : public Event { diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/system/MemoryControl.cc --- a/src/mem/ruby/system/MemoryControl.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/system/MemoryControl.cc Wed Oct 03 23:14:11 2012 -0500 @@ -27,18 +27,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "base/cast.hh" -#include "base/cprintf.hh" #include "debug/RubyStats.hh" -#include "mem/ruby/common/Address.hh" -#include "mem/ruby/common/Consumer.hh" #include "mem/ruby/common/Global.hh" -#include "mem/ruby/network/Network.hh" -#include "mem/ruby/profiler/Profiler.hh" -#include "mem/ruby/slicc_interface/NetworkMessage.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/system/MemoryControl.hh" -#include "mem/ruby/system/RubyMemoryControl.hh" #include "mem/ruby/system/System.hh" using namespace std; @@ -55,9 +47,3 @@ DPRINTF(RubyStats, "Recorded request: %s\n", MemoryControlRequestType_to_string(request)); } - -RubyMemoryControl * -RubyMemoryControlParams::create() -{ - return new RubyMemoryControl(this); -} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/system/RubyMemoryControl.hh --- a/src/mem/ruby/system/RubyMemoryControl.hh Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/system/RubyMemoryControl.hh Wed Oct 03 23:14:11 2012 -0500 @@ -96,6 +96,8 @@ int getRanksPerDimm() { return m_ranks_per_dimm; }; int getDimmsPerChannel() { return m_dimms_per_channel; } + bool functionalReadBuffers(Packet *pkt); + uint32_t functionalWriteBuffers(Packet *pkt); private: void enqueueToDirectory(MemoryNode req, int latency); diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/system/RubyMemoryControl.cc --- a/src/mem/ruby/system/RubyMemoryControl.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/system/RubyMemoryControl.cc Wed Oct 03 23:14:11 2012 -0500 @@ -708,3 +708,74 @@ } } +bool +RubyMemoryControl::functionalReadBuffers(Packet *pkt) +{ + for (std::list::iterator it = m_input_queue.begin(); + it != m_input_queue.end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalRead(pkt)) { + return true; + } + } + + for (std::list::iterator it = m_response_queue.begin(); + it != m_response_queue.end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalRead(pkt)) { + return true; + } + } + + for (uint32_t bank = 0; bank < m_total_banks; ++bank) { + for (std::list::iterator it = m_bankQueues[bank].begin(); + it != m_bankQueues[bank].end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalRead(pkt)) { + return true; + } + } + } + + return false; +} + +uint32_t +RubyMemoryControl::functionalWriteBuffers(Packet *pkt) +{ + uint32_t num_functional_writes = 0; + + for (std::list::iterator it = m_input_queue.begin(); + it != m_input_queue.end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalWrite(pkt)) { + num_functional_writes++; + } + } + + for (std::list::iterator it = m_response_queue.begin(); + it != m_response_queue.end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalWrite(pkt)) { + num_functional_writes++; + } + } + + for (uint32_t bank = 0; bank < m_total_banks; ++bank) { + for (std::list::iterator it = m_bankQueues[bank].begin(); + it != m_bankQueues[bank].end(); ++it) { + Message* msg_ptr = (*it).m_msgptr.get(); + if (msg_ptr->functionalWrite(pkt)) { + num_functional_writes++; + } + } + } + + return num_functional_writes; +} + +RubyMemoryControl * +RubyMemoryControlParams::create() +{ + return new RubyMemoryControl(this); +} diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/ruby/system/System.cc --- a/src/mem/ruby/system/System.cc Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/ruby/system/System.cc Wed Oct 03 23:14:11 2012 -0500 @@ -466,7 +466,7 @@ return true; } } - } else { + } else if (num_ro > 0 || num_rw == 1) { // In Broadcast/Snoop protocols, this covers if you know the block // exists somewhere in the caching hierarchy, then you want to read any // valid RO or RW block. In directory protocols, same thing, you want @@ -492,6 +492,22 @@ } } } + + for (int i = 0; i < num_controllers;++i) { + if (m_abs_cntrl_vec[i]->functionalReadBuffers(pkt)) { + return true; + } + } + + for (int i = 0; i < m_memory_controller_vec.size(); ++i) { + if (m_memory_controller_vec[i]->functionalReadBuffers(pkt)) { + return true; + } + } + + if (m_network_ptr->functionalRead(pkt)) { + return true; + } return false; } @@ -540,34 +556,41 @@ // hierarchy at all, we still want to do the write to the memory // (Backing_Store) instead of failing. - DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n", - num_busy, num_ro, num_rw); + DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d," + "num_invalid = %d, num_backing_store = %d\n", + num_busy, num_ro, num_rw, num_invalid, num_backing_store); assert(num_rw <= 1); uint8_t *data = pkt->getPtr(true); unsigned int size_in_bytes = pkt->getSize(); unsigned startByte = addr.getAddress() - line_addr.getAddress(); - if ((num_busy == 0 && num_ro > 0) || num_rw == 1 || - (num_invalid == (num_controllers - 1) && num_backing_store == 1)) { - for (int i = 0; i < num_controllers;++i) { - access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr); - if (access_perm == AccessPermission_Read_Only || - access_perm == AccessPermission_Read_Write|| - access_perm == AccessPermission_Maybe_Stale || - access_perm == AccessPermission_Backing_Store) { + for (int i = 0; i < num_controllers;++i) { + m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt); - DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr); - DPRINTF(RubySystem, "%s\n",block); - for (unsigned i = 0; i < size_in_bytes; ++i) { - block.setByte(i + startByte, data[i]); - } - DPRINTF(RubySystem, "%s\n",block); + access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr); + if (access_perm != AccessPermission_Invalid && + access_perm != AccessPermission_NotPresent) { + + DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr); + DPRINTF(RubySystem, "%s\n",block); + for (unsigned i = 0; i < size_in_bytes; ++i) { + block.setByte(i + startByte, data[i]); } + DPRINTF(RubySystem, "%s\n",block); } - return true; } - return false; + + uint32_t M5_VAR_USED num_functional_writes = 0; + for (int i = 0; i < m_memory_controller_vec.size() ;++i) { + num_functional_writes += + m_memory_controller_vec[i]->functionalWriteBuffers(pkt); + } + + num_functional_writes += m_network_ptr->functionalWrite(pkt); + DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes); + + return true; } #ifdef CHECK_COHERENCE diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/slicc/ast/TypeDeclAST.py --- a/src/mem/slicc/ast/TypeDeclAST.py Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/slicc/ast/TypeDeclAST.py Wed Oct 03 23:14:11 2012 -0500 @@ -60,7 +60,10 @@ machine.addType(new_type) self.symtab.newSymbol(new_type) + self.symtab.pushFrame() # Add all of the fields of the type to it for field in self.field_asts: field.generate(new_type) + + self.symtab.popFrame() diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/slicc/symbols/StateMachine.py --- a/src/mem/slicc/symbols/StateMachine.py Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/slicc/symbols/StateMachine.py Wed Oct 03 23:14:11 2012 -0500 @@ -269,6 +269,9 @@ void recordCacheTrace(int cntrl, CacheRecorder* tr); Sequencer* getSequencer() const; + bool functionalReadBuffers(PacketPtr&); + uint32_t functionalWriteBuffers(const PacketPtr&); + private: ''') @@ -987,6 +990,39 @@ for func in self.functions: code(func.generateCode()) + # Function for functional reads from messages buffered in the controller + code(''' +bool +$c_ident::functionalReadBuffers(PacketPtr& pkt) +{ +''') + for var in self.objects: + vtype = var.type + if vtype.isBuffer: + vid = "m_%s_ptr" % var.c_ident + code('if ($vid->functionalRead(pkt)) { return true; }') + code(''' + return false; +} +''') + + # Function for functional writes to messages buffered in the controller + code(''' +uint32_t +$c_ident::functionalWriteBuffers(const PacketPtr& pkt) +{ + uint32_t num_functional_writes = 0; +''') + for var in self.objects: + vtype = var.type + if vtype.isBuffer: + vid = "m_%s_ptr" % var.c_ident + code('num_functional_writes += $vid->functionalWrite(pkt);') + code(''' + return num_functional_writes; +} +''') + code.write(path, "%s.cc" % c_ident) def printCWakeup(self, path, includes): diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/slicc/symbols/SymbolTable.py --- a/src/mem/slicc/symbols/SymbolTable.py Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/slicc/symbols/SymbolTable.py Wed Oct 03 23:14:11 2012 -0500 @@ -81,8 +81,7 @@ if types is not None: if not isinstance(symbol, types): symbol.error("Symbol '%s' is not of types '%s'.", - symbol, - types) + symbol, types) return symbol diff -r c5a0889733eb -r 0da5f7f0cf48 src/mem/slicc/symbols/Type.py --- a/src/mem/slicc/symbols/Type.py Wed Oct 03 23:12:47 2012 -0500 +++ b/src/mem/slicc/symbols/Type.py Wed Oct 03 23:14:11 2012 -0500 @@ -29,6 +29,7 @@ from slicc.util import PairContainer from slicc.symbols.Symbol import Symbol +from slicc.symbols.Var import Var class DataMember(PairContainer): def __init__(self, ident, type, pairs, init_code): @@ -151,6 +152,9 @@ member = DataMember(ident, type, pairs, init_code) self.data_members[ident] = member + var = Var(self.symtab, ident, self.location, type, + "m_%s" % ident, {}, None) + self.symtab.registerSym(ident, var) return True def dataMemberType(self, ident): @@ -412,6 +416,7 @@ #include #include "mem/protocol/${{self.c_ident}}.hh" +#include "mem/ruby/slicc_interface/RubySlicc_Util.hh" using namespace std; ''')