diff options
-rw-r--r-- | configs/common/Options.py | 1 | ||||
-rw-r--r-- | configs/ruby/MOESI_CMP_token.py | 161 | ||||
-rw-r--r-- | configs/ruby/Ruby.py | 7 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L1cache.sm | 36 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-L2cache.sm | 26 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-dir.sm | 99 | ||||
-rw-r--r-- | src/mem/protocol/MOESI_CMP_token-dma.sm | 4 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Types.sm | 8 |
8 files changed, 245 insertions, 97 deletions
diff --git a/configs/common/Options.py b/configs/common/Options.py index 8b4fc2ce1..ade403fe3 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -36,6 +36,7 @@ parser.add_option("--l2cache", action="store_true") parser.add_option("--fastmem", action="store_true") parser.add_option("--clock", action="store", type="string", default='1GHz') parser.add_option("--num-dirs", type="int", default=1) +parser.add_option("--num-l2caches", type="int", default=1) # Run duration options parser.add_option("-m", "--maxtick", type="int", default=m5.MaxTick, diff --git a/configs/ruby/MOESI_CMP_token.py b/configs/ruby/MOESI_CMP_token.py new file mode 100644 index 000000000..8d7f7a354 --- /dev/null +++ b/configs/ruby/MOESI_CMP_token.py @@ -0,0 +1,161 @@ +# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# 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. +# +# Authors: Brad Beckmann + +import math +import m5 +from m5.objects import * +from m5.defines import buildEnv +from m5.util import addToPath + +# +# Note: the L1 Cache latency is only used by the sequencer on fast path hits +# +class L1Cache(RubyCache): + latency = 3 + +# +# Note: the L2 Cache latency is not currently used +# +class L2Cache(RubyCache): + latency = 15 + +def create_system(options, phys_mem, piobus, dma_devices): + + if buildEnv['PROTOCOL'] != 'MOESI_CMP_token': + panic("This script requires the MOESI_CMP_token protocol to be built.") + + # + # number of tokens that the owner passes to requests so that shared blocks can + # respond to read requests + # + n_tokens = options.num_cpus + 1 + + cpu_sequencers = [] + + # + # The ruby network creation expects the list of nodes in the system to be + # consistent with the NetDest list. Therefore the l1 controller nodes must be + # listed before the directory nodes and directory nodes before dma nodes, etc. + # + l1_cntrl_nodes = [] + l2_cntrl_nodes = [] + dir_cntrl_nodes = [] + dma_cntrl_nodes = [] + + # + # Must create the individual controllers before the network to ensure the + # controller constructors are called before the network constructor + # + + for i in xrange(options.num_cpus): + # + # First create the Ruby objects associated with this cpu + # + l1i_cache = L1Cache(size = options.l1i_size, + assoc = options.l1i_assoc) + l1d_cache = L1Cache(size = options.l1d_size, + assoc = options.l1d_assoc) + + cpu_seq = RubySequencer(icache = l1i_cache, + dcache = l1d_cache, + physMemPort = phys_mem.port, + physmem = phys_mem) + + if piobus != None: + cpu_seq.pio_port = piobus.port + + l1_cntrl = L1Cache_Controller(version = i, + sequencer = cpu_seq, + L1IcacheMemory = l1i_cache, + L1DcacheMemory = l1d_cache, + l2_select_num_bits = \ + math.log(options.num_l2caches, 2), + N_tokens = n_tokens) + # + # Add controllers and sequencers to the appropriate lists + # + cpu_sequencers.append(cpu_seq) + l1_cntrl_nodes.append(l1_cntrl) + + for i in xrange(options.num_l2caches): + # + # First create the Ruby objects associated with this cpu + # + l2_cache = L2Cache(size = options.l2_size, + assoc = options.l2_assoc) + + l2_cntrl = L2Cache_Controller(version = i, + L2cacheMemory = l2_cache, + N_tokens = n_tokens) + + l2_cntrl_nodes.append(l2_cntrl) + + phys_mem_size = long(phys_mem.range.second) - long(phys_mem.range.first) + 1 + mem_module_size = phys_mem_size / options.num_dirs + + for i in xrange(options.num_dirs): + # + # Create the Ruby objects associated with the directory controller + # + + mem_cntrl = RubyMemoryControl(version = i) + + dir_size = MemorySize('0B') + dir_size.value = mem_module_size + + dir_cntrl = Directory_Controller(version = i, + directory = \ + RubyDirectoryMemory(version = i, + size = dir_size), + memBuffer = mem_cntrl, + l2_select_num_bits = \ + math.log(options.num_l2caches, 2)) + + dir_cntrl_nodes.append(dir_cntrl) + + for i, dma_device in enumerate(dma_devices): + # + # Create the Ruby objects associated with the dma controller + # + dma_seq = DMASequencer(version = i, + physMemPort = phys_mem.port, + physmem = phys_mem) + + dma_cntrl = DMA_Controller(version = i, + dma_sequencer = dma_seq) + + dma_cntrl.dma_sequencer.port = dma_device.dma + dma_cntrl_nodes.append(dma_cntrl) + + all_cntrls = l1_cntrl_nodes + \ + l2_cntrl_nodes + \ + dir_cntrl_nodes + \ + dma_cntrl_nodes + + return (cpu_sequencers, dir_cntrl_nodes, all_cntrls) diff --git a/configs/ruby/Ruby.py b/configs/ruby/Ruby.py index 0922dc77e..2b804e4bd 100644 --- a/configs/ruby/Ruby.py +++ b/configs/ruby/Ruby.py @@ -34,6 +34,7 @@ from m5.util import addToPath import MOESI_hammer import MI_example +import MOESI_CMP_token def create_system(options, physmem, piobus = None, dma_devices = []): @@ -51,6 +52,12 @@ def create_system(options, physmem, piobus = None, dma_devices = []): physmem, \ piobus, \ dma_devices) + elif protocol == "MOESI_CMP_token": + (cpu_sequencers, dir_cntrls, all_cntrls) = \ + MOESI_CMP_token.create_system(options, \ + physmem, \ + piobus, \ + dma_devices) else: print "Error: unsupported ruby protocol" sys.exit(1) diff --git a/src/mem/protocol/MOESI_CMP_token-L1cache.sm b/src/mem/protocol/MOESI_CMP_token-L1cache.sm index 3fb4a8862..0ff78f9fc 100644 --- a/src/mem/protocol/MOESI_CMP_token-L1cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L1cache.sm @@ -33,14 +33,16 @@ */ machine(L1Cache, "Token protocol") - : int l1_request_latency, - int l1_response_latency, - int l2_select_low_bit, + : Sequencer * sequencer, + CacheMemory * L1IcacheMemory, + CacheMemory * L1DcacheMemory, int l2_select_num_bits, int N_tokens, - int retry_threshold, - int fixed_timeout_latency, - bool dynamic_timeout_enabled + int l1_request_latency = 2, + int l1_response_latency = 2, + int retry_threshold = 1, + int fixed_timeout_latency = 300, + bool dynamic_timeout_enabled = true { // From this node's L1 cache TO the network @@ -147,16 +149,6 @@ machine(L1Cache, "Token protocol") PrefetchBit Prefetch, desc="Is this a prefetch request"; } - external_type(CacheMemory) { - bool cacheAvail(Address); - Address cacheProbe(Address); - void allocate(Address, Entry); - void deallocate(Address); - Entry lookup(Address); - void changePermission(Address, AccessPermission); - bool isTagPresent(Address); - } - external_type(TBETable) { TBE lookup(Address); void allocate(Address); @@ -177,13 +169,11 @@ machine(L1Cache, "Token protocol") } TBETable L1_TBEs, template_hack="<L1Cache_TBE>"; - CacheMemory L1IcacheMemory, factory='RubySystem::getCache(m_cfg["icache"])'; - CacheMemory L1DcacheMemory, factory='RubySystem::getCache(m_cfg["dcache"])'; MessageBuffer mandatoryQueue, ordered="false", abstract_chip_ptr="true"; - Sequencer sequencer, factory='RubySystem::getSequencer(m_cfg["sequencer"])'; bool starving, default="false"; + int l2_select_low_bit, default="RubySystem::getBlockSizeBits()"; PersistentTable persistentTable; TimerTable useTimerTable; @@ -218,17 +208,17 @@ machine(L1Cache, "Token protocol") Entry getCacheEntry(Address addr), return_by_ref="yes" { if (L1DcacheMemory.isTagPresent(addr)) { - return L1DcacheMemory[addr]; + return static_cast(Entry, L1DcacheMemory[addr]); } else { - return L1IcacheMemory[addr]; + return static_cast(Entry, L1IcacheMemory[addr]); } } int getTokens(Address addr) { if (L1DcacheMemory.isTagPresent(addr)) { - return L1DcacheMemory[addr].Tokens; + return static_cast(Entry, L1DcacheMemory[addr]).Tokens; } else if (L1IcacheMemory.isTagPresent(addr)) { - return L1IcacheMemory[addr].Tokens; + return static_cast(Entry, L1IcacheMemory[addr]).Tokens; } else { return 0; } diff --git a/src/mem/protocol/MOESI_CMP_token-L2cache.sm b/src/mem/protocol/MOESI_CMP_token-L2cache.sm index 9a5c400f2..fb50f6ca2 100644 --- a/src/mem/protocol/MOESI_CMP_token-L2cache.sm +++ b/src/mem/protocol/MOESI_CMP_token-L2cache.sm @@ -33,10 +33,11 @@ */ machine(L2Cache, "Token protocol") - : int l2_request_latency, - int l2_response_latency, + : CacheMemory * L2cacheMemory, int N_tokens, - bool filtering_enabled + int l2_request_latency = 10, + int l2_response_latency = 10, + bool filtering_enabled = true { // L2 BANK QUEUES @@ -125,17 +126,6 @@ machine(L2Cache, "Token protocol") bool exclusive, default="false", desc="if local exclusive is likely"; } - external_type(CacheMemory) { - bool cacheAvail(Address); - Address cacheProbe(Address); - void allocate(Address, Entry); - void deallocate(Address); - Entry lookup(Address); - void changePermission(Address, AccessPermission); - bool isTagPresent(Address); - void setMRU(Address); - } - external_type(PerfectCacheMemory) { void allocate(Address); void deallocate(Address); @@ -154,22 +144,20 @@ machine(L2Cache, "Token protocol") int countReadStarvingForAddress(Address); } - CacheMemory L2cacheMemory, factory='RubySystem::getCache(m_cfg["cache"])'; - PersistentTable persistentTable; PerfectCacheMemory localDirectory, template_hack="<L2Cache_DirEntry>"; Entry getL2CacheEntry(Address addr), return_by_ref="yes" { if (L2cacheMemory.isTagPresent(addr)) { - return L2cacheMemory[addr]; + return static_cast(Entry, L2cacheMemory[addr]); } assert(false); - return L2cacheMemory[addr]; + return static_cast(Entry, L2cacheMemory[addr]); } int getTokens(Address addr) { if (L2cacheMemory.isTagPresent(addr)) { - return L2cacheMemory[addr].Tokens; + return getL2CacheEntry(addr).Tokens; } else { return 0; } diff --git a/src/mem/protocol/MOESI_CMP_token-dir.sm b/src/mem/protocol/MOESI_CMP_token-dir.sm index 7925a8fe0..b8305c486 100644 --- a/src/mem/protocol/MOESI_CMP_token-dir.sm +++ b/src/mem/protocol/MOESI_CMP_token-dir.sm @@ -33,11 +33,12 @@ machine(Directory, "Token protocol") - : int directory_latency, - int l2_select_low_bit, + : DirectoryMemory * directory, + MemoryControl * memBuffer, int l2_select_num_bits, - bool distributed_persistent, - int fixed_timeout_latency + int directory_latency = 6, + bool distributed_persistent = true, + int fixed_timeout_latency = 300 { MessageBuffer dmaResponseFromDir, network="To", virtual_network="0", ordered="true"; @@ -104,7 +105,7 @@ machine(Directory, "Token protocol") // TYPES // DirectoryEntry - structure(Entry, desc="...") { + structure(Entry, desc="...", interface="AbstractEntry") { State DirectoryState, desc="Directory state"; DataBlock DataBlk, desc="data for the block"; int Tokens, default="max_tokens()", desc="Number of tokens for the line we're holding"; @@ -118,15 +119,6 @@ machine(Directory, "Token protocol") Set Sharers, desc="Probable sharers of the line. More accurately, the set of processors who need to see a GetX"; } - external_type(DirectoryMemory) { - Entry lookup(Address); - bool isPresent(Address); - } - - external_type(MemoryControl, inport="yes", outport="yes") { - - } - external_type(PersistentTable) { void persistentRequestLock(Address, MachineID, AccessType); void persistentRequestUnlock(Address, MachineID); @@ -159,22 +151,23 @@ machine(Directory, "Token protocol") // ** OBJECTS ** - DirectoryMemory directory, factory='RubySystem::getDirectory(m_cfg["directory_name"])'; - - MemoryControl memBuffer, factory='RubySystem::getMemoryControl(m_cfg["memory_controller_name"])'; - PersistentTable persistentTable; TimerTable reissueTimerTable; TBETable TBEs, template_hack="<Directory_TBE>"; bool starving, default="false"; + int l2_select_low_bit, default="RubySystem::getBlockSizeBits()"; + + 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; } else { - return directory[addr].DirectoryState; + return getDirectoryEntry(addr).DirectoryState; } } @@ -182,22 +175,22 @@ machine(Directory, "Token protocol") if (TBEs.isPresent(addr)) { TBEs[addr].TBEState := state; } - directory[addr].DirectoryState := state; + getDirectoryEntry(addr).DirectoryState := state; if (state == State:L) { - assert(directory[addr].Tokens == 0); + assert(getDirectoryEntry(addr).Tokens == 0); } // We have one or zero owners - assert((directory[addr].Owner.count() == 0) || (directory[addr].Owner.count() == 1)); + assert((getDirectoryEntry(addr).Owner.count() == 0) || (getDirectoryEntry(addr).Owner.count() == 1)); // Make sure the token count is in range - assert(directory[addr].Tokens >= 0); - assert(directory[addr].Tokens <= max_tokens()); + assert(getDirectoryEntry(addr).Tokens >= 0); + assert(getDirectoryEntry(addr).Tokens <= max_tokens()); if (state == State:O) { - assert(directory[addr].Tokens >= 1); // Must have at least one token - // assert(directory[addr].Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold + assert(getDirectoryEntry(addr).Tokens >= 1); // Must have at least one token + // assert(getDirectoryEntry(addr).Tokens >= (max_tokens() / 2)); // Only mostly true; this might not always hold } } @@ -249,7 +242,7 @@ machine(Directory, "Token protocol") if (responseNetwork_in.isReady()) { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Destination.isElement(machineID)); - if (directory[in_msg.Address].Tokens + in_msg.Tokens == max_tokens()) { + if (getDirectoryEntry(in_msg.Address).Tokens + in_msg.Tokens == max_tokens()) { if ((in_msg.Type == CoherenceResponseType:DATA_OWNER) || (in_msg.Type == CoherenceResponseType:DATA_SHARED)) { trigger(Event:Data_All_Tokens, in_msg.Address); @@ -338,7 +331,7 @@ machine(Directory, "Token protocol") if (in_msg.Type == DMARequestType:READ) { trigger(Event:DMA_READ, in_msg.LineAddress); } else if (in_msg.Type == DMARequestType:WRITE) { - if (directory[in_msg.LineAddress].Tokens == max_tokens()) { + if (getDirectoryEntry(in_msg.LineAddress).Tokens == max_tokens()) { trigger(Event:DMA_WRITE_All_Tokens, in_msg.LineAddress); } else { trigger(Event:DMA_WRITE, in_msg.LineAddress); @@ -354,7 +347,7 @@ machine(Directory, "Token protocol") action(a_sendTokens, "a", desc="Send tokens to requestor") { // Only send a message if we have tokens to send - if (directory[address].Tokens > 0) { + if (getDirectoryEntry(address).Tokens > 0) { peek(requestNetwork_in, RequestMsg) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? @@ -363,11 +356,11 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(in_msg.Requestor); - out_msg.Tokens := directory[in_msg.Address].Tokens; + out_msg.Tokens := getDirectoryEntry(in_msg.Address).Tokens; out_msg.MessageSize := MessageSizeType:Response_Control; } } - directory[address].Tokens := 0; + getDirectoryEntry(address).Tokens := 0; } } @@ -419,7 +412,7 @@ machine(Directory, "Token protocol") // // Assser that we only send message if we don't already have all the tokens // - assert(directory[address].Tokens != max_tokens()); + assert(getDirectoryEntry(address).Tokens != max_tokens()); enqueue(requestNetwork_out, RequestMsg, latency = "1") { out_msg.Address := address; out_msg.Type := CoherenceRequestType:GETX; @@ -513,7 +506,7 @@ machine(Directory, "Token protocol") action(aa_sendTokensToStarver, "\a", desc="Send tokens to starver") { // Only send a message if we have tokens to send - if (directory[address].Tokens > 0) { + if (getDirectoryEntry(address).Tokens > 0) { // enqueue(responseNetwork_out, ResponseMsg, latency="DIRECTORY_CACHE_LATENCY") {// FIXME? enqueue(responseNetwork_out, ResponseMsg, latency=directory_latency) {// FIXME? out_msg.Address := address; @@ -521,10 +514,10 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(persistentTable.findSmallest(address)); - out_msg.Tokens := directory[address].Tokens; + out_msg.Tokens := getDirectoryEntry(address).Tokens; out_msg.MessageSize := MessageSizeType:Response_Control; } - directory[address].Tokens := 0; + getDirectoryEntry(address).Tokens := 0; } } @@ -536,14 +529,14 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(in_msg.OriginalRequestorMachId); - assert(directory[address].Tokens > 0); - out_msg.Tokens := directory[in_msg.Address].Tokens; - out_msg.DataBlk := directory[in_msg.Address].DataBlk; + assert(getDirectoryEntry(address).Tokens > 0); + out_msg.Tokens := getDirectoryEntry(in_msg.Address).Tokens; + out_msg.DataBlk := getDirectoryEntry(in_msg.Address).DataBlk; out_msg.Dirty := false; out_msg.MessageSize := MessageSizeType:Response_Data; } } - directory[address].Tokens := 0; + getDirectoryEntry(address).Tokens := 0; } action(dd_sendDataWithAllTokensToStarver, "\d", desc="Send data and tokens to starver") { @@ -554,14 +547,14 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.SenderMachine := MachineType:Directory; out_msg.Destination.add(persistentTable.findSmallest(address)); - assert(directory[address].Tokens > 0); - out_msg.Tokens := directory[address].Tokens; - out_msg.DataBlk := directory[address].DataBlk; + assert(getDirectoryEntry(address).Tokens > 0); + out_msg.Tokens := getDirectoryEntry(address).Tokens; + out_msg.DataBlk := getDirectoryEntry(address).DataBlk; out_msg.Dirty := false; out_msg.MessageSize := MessageSizeType:Response_Data; } } - directory[address].Tokens := 0; + getDirectoryEntry(address).Tokens := 0; } action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") { @@ -572,7 +565,7 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.OriginalRequestorMachId := in_msg.Requestor; out_msg.MessageSize := in_msg.MessageSize; - out_msg.DataBlk := directory[address].DataBlk; + out_msg.DataBlk := getDirectoryEntry(address).DataBlk; DEBUG_EXPR(out_msg); } } @@ -586,7 +579,7 @@ machine(Directory, "Token protocol") out_msg.Sender := machineID; out_msg.OriginalRequestorMachId := in_msg.Requestor; out_msg.MessageSize := in_msg.MessageSize; - out_msg.DataBlk := directory[address].DataBlk; + out_msg.DataBlk := getDirectoryEntry(address).DataBlk; DEBUG_EXPR(out_msg); } } @@ -673,18 +666,18 @@ machine(Directory, "Token protocol") } action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") { - TBEs[address].DataBlk := directory[address].DataBlk; + TBEs[address].DataBlk := getDirectoryEntry(address).DataBlk; } action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") { - directory[address].DataBlk := TBEs[address].DataBlk; - directory[address].DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); + getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk; + getDirectoryEntry(address).DataBlk.copyPartial(TBEs[address].DmaDataBlk, addressOffset(TBEs[address].PhysicalAddress), TBEs[address].Len); } action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") { peek(responseNetwork_in, ResponseMsg) { assert(in_msg.Tokens >= 1); - directory[address].Tokens := directory[address].Tokens + in_msg.Tokens; + getDirectoryEntry(address).Tokens := getDirectoryEntry(address).Tokens + in_msg.Tokens; } } @@ -722,7 +715,7 @@ machine(Directory, "Token protocol") action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") { peek(responseNetwork_in, ResponseMsg) { - directory[in_msg.Address].DataBlk := in_msg.DataBlk; + getDirectoryEntry(in_msg.Address).DataBlk := in_msg.DataBlk; DEBUG_EXPR(in_msg.Address); DEBUG_EXPR(in_msg.DataBlk); } @@ -730,7 +723,7 @@ machine(Directory, "Token protocol") action(n_checkData, "n", desc="Check incoming clean data message") { peek(responseNetwork_in, ResponseMsg) { - assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); + assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk); } } @@ -773,7 +766,7 @@ machine(Directory, "Token protocol") // implementation. We include the data in the "dataless" // message so we can assert the clean data matches the datablock // in memory - assert(directory[in_msg.Address].DataBlk == in_msg.DataBlk); + assert(getDirectoryEntry(in_msg.Address).DataBlk == in_msg.DataBlk); // Bounce the message, but "re-associate" the data and the owner // token. In essence we're converting an ACK_OWNER message to a @@ -786,7 +779,7 @@ machine(Directory, "Token protocol") out_msg.DestMachine := MachineType:L1Cache; out_msg.Destination.add(persistentTable.findSmallest(address)); out_msg.Tokens := in_msg.Tokens; - out_msg.DataBlk := directory[in_msg.Address].DataBlk; + out_msg.DataBlk := getDirectoryEntry(in_msg.Address).DataBlk; out_msg.Dirty := in_msg.Dirty; out_msg.MessageSize := MessageSizeType:Response_Data; } diff --git a/src/mem/protocol/MOESI_CMP_token-dma.sm b/src/mem/protocol/MOESI_CMP_token-dma.sm index 550a36ae0..d5379a77d 100644 --- a/src/mem/protocol/MOESI_CMP_token-dma.sm +++ b/src/mem/protocol/MOESI_CMP_token-dma.sm @@ -28,7 +28,8 @@ machine(DMA, "DMA Controller") -: int request_latency +: DMASequencer * dma_sequencer, + int request_latency { MessageBuffer responseFromDir, network="From", virtual_network="0", ordered="true", no_vector="true"; @@ -53,7 +54,6 @@ machine(DMA, "DMA Controller") } MessageBuffer mandatoryQueue, ordered="false", no_vector="true"; - DMASequencer dma_sequencer, factory='RubySystem::getDMASequencer(m_cfg["dma_sequencer"])', no_vector="true"; State cur_state, no_vector="true"; State getState(Address addr) { diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index a724b25da..80d0be159 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -29,6 +29,13 @@ // External Types +// +// **PLEASE NOTE!** When adding objects to this file you must also add a line +// in the src/mem/ruby/SConscript file. Otherwise the external object's .hh +// file will not be copied to the protocol directory and you will encounter a +// undefined declaration error. +// + external_type(MessageBuffer, buffer="yes", inport="yes", outport="yes"); external_type(OutPort, primitive="yes"); @@ -117,6 +124,7 @@ external_type(CacheMemory) { void changePermission(Address, AccessPermission); bool isTagPresent(Address); void profileMiss(CacheMsg); + void setMRU(Address); } external_type(MemoryControl, inport="yes", outport="yes") { |