mem-ruby: Sequencer can be used without cache
[gem5.git] / configs / ruby / GPU_VIPER_Region.py
index 5f8293bbe7e83157abb5ed30c1a8e8169cbf23a2..1d63cb0e4a0faf3227b4aecdeb31cb3015473c18 100644 (file)
@@ -1,46 +1,49 @@
+# Copyright (c) 2015 Advanced Micro Devices, Inc.
+# All rights reserved.
 #
-#  Copyright (c) 2015 Advanced Micro Devices, Inc.
-#  All rights reserved.
+# For use for simulation and test purposes only
 #
-#  For use for simulation and test purposes only
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
 #
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
 #
-#  1. Redistributions of source code must retain the above copyright notice,
-#  this list of conditions and the following disclaimer.
+# 2. 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.
 #
-#  2. 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.
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
 #
-#  3. Neither the name of the copyright holder 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 HOLDER 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.
-#
-#  Author: Sooraj Puthoor
-#
-
+# 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 HOLDER 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.
+
+import six
 import math
 import m5
 from m5.objects import *
 from m5.defines import buildEnv
-from Ruby import send_evicts
+from m5.util import addToPath
+from .Ruby import send_evicts
+
+addToPath('../')
 
 from topologies.Cluster import Cluster
 
+if six.PY3:
+    long = int
+
 class CntrlBase:
     _seqs = 0
     @classmethod
@@ -74,7 +77,7 @@ class L1Cache(RubyCache):
     def create(self, size, assoc, options):
         self.size = MemorySize(size)
         self.assoc = assoc
-        self.replacement_policy = PseudoLRUReplacementPolicy()
+        self.replacement_policy = TreePLRURP()
 
 class L2Cache(RubyCache):
     resourceStalls = False
@@ -84,7 +87,7 @@ class L2Cache(RubyCache):
     def create(self, size, assoc, options):
         self.size = MemorySize(size)
         self.assoc = assoc
-        self.replacement_policy = PseudoLRUReplacementPolicy()
+        self.replacement_policy = TreePLRURP()
 
 class CPCntrl(CorePair_Controller, CntrlBase):
 
@@ -102,7 +105,6 @@ class CPCntrl(CorePair_Controller, CntrlBase):
 
         self.sequencer = RubySequencer()
         self.sequencer.version = self.seqCount()
-        self.sequencer.icache = self.L1Icache
         self.sequencer.dcache = self.L1D0cache
         self.sequencer.ruby_system = ruby_system
         self.sequencer.coreid = 0
@@ -110,7 +112,6 @@ class CPCntrl(CorePair_Controller, CntrlBase):
 
         self.sequencer1 = RubySequencer()
         self.sequencer1.version = self.seqCount()
-        self.sequencer1.icache = self.L1Icache
         self.sequencer1.dcache = self.L1D1cache
         self.sequencer1.ruby_system = ruby_system
         self.sequencer1.coreid = 1
@@ -138,7 +139,7 @@ class TCPCache(RubyCache):
         self.dataAccessLatency = 4
         self.tagAccessLatency = 1
         self.resourceStalls = options.no_tcc_resource_stalls
-        self.replacement_policy = PseudoLRUReplacementPolicy(assoc = self.assoc)
+        self.replacement_policy = TreePLRURP(num_leaves = self.assoc)
 
 class TCPCntrl(TCP_Controller, CntrlBase):
 
@@ -155,10 +156,14 @@ class TCPCntrl(TCP_Controller, CntrlBase):
         self.coalescer.ruby_system = ruby_system
         self.coalescer.support_inst_reqs = False
         self.coalescer.is_cpu_sequencer = False
+        if options.tcp_deadlock_threshold:
+          self.coalescer.deadlock_threshold = \
+            options.tcp_deadlock_threshold
+        self.coalescer.max_coalesces_per_cycle = \
+            options.max_coalesces_per_cycle
 
         self.sequencer = RubySequencer()
         self.sequencer.version = self.seqCount()
-        self.sequencer.icache = self.L1cache
         self.sequencer.dcache = self.L1cache
         self.sequencer.ruby_system = ruby_system
         self.sequencer.is_cpu_sequencer = True
@@ -178,7 +183,7 @@ class SQCCache(RubyCache):
     def create(self, options):
         self.size = MemorySize(options.sqc_size)
         self.assoc = options.sqc_assoc
-        self.replacement_policy = PseudoLRUReplacementPolicy(assoc = self.assoc)
+        self.replacement_policy = TreePLRURP(num_leaves = self.assoc)
 
 class SQCCntrl(SQC_Controller, CntrlBase):
 
@@ -189,11 +194,14 @@ class SQCCntrl(SQC_Controller, CntrlBase):
         self.L1cache.resourceStalls = False
         self.sequencer = RubySequencer()
         self.sequencer.version = self.seqCount()
-        self.sequencer.icache = self.L1cache
         self.sequencer.dcache = self.L1cache
         self.sequencer.ruby_system = ruby_system
         self.sequencer.support_data_reqs = False
         self.sequencer.is_cpu_sequencer = False
+        if options.sqc_deadlock_threshold:
+          self.sequencer.deadlock_threshold = \
+            options.sqc_deadlock_threshold
+
         self.ruby_system = ruby_system
         if options.recycle_latency:
             self.recycle_latency = options.recycle_latency
@@ -222,7 +230,7 @@ class TCC(RubyCache):
             self.size.value = long(128 * self.assoc)
         self.start_index_bit = math.log(options.cacheline_size, 2) + \
                                math.log(options.num_tccs, 2)
-        self.replacement_policy = PseudoLRUReplacementPolicy(assoc = self.assoc)
+        self.replacement_policy = TreePLRURP(num_leaves = self.assoc)
 
 class TCCCntrl(TCC_Controller, CntrlBase):
     def create(self, options, ruby_system, system):
@@ -248,7 +256,7 @@ class L3Cache(RubyCache):
         self.dataAccessLatency = options.l3_data_latency
         self.tagAccessLatency = options.l3_tag_latency
         self.resourceStalls = False
-        self.replacement_policy = PseudoLRUReplacementPolicy(assoc = self.assoc)
+        self.replacement_policy = TreePLRURP(num_leaves = self.assoc)
 
 class L3Cntrl(L3Cache_Controller, CntrlBase):
     def create(self, options, ruby_system, system):
@@ -270,31 +278,19 @@ class L3Cntrl(L3Cache_Controller, CntrlBase):
         self.probeToL3 = probe_to_l3
         self.respToL3 = resp_to_l3
 
-# Directory memory: Directory memory of infinite size which is
-# used by directory controller to store the "states" of the
-# state machine. The state machine is implemented per cache block
-class DirMem(RubyDirectoryMemory, CntrlBase):
-    def create(self, options, ruby_system, system):
-        self.version = self.versionCount()
-        phys_mem_size = AddrRange(options.mem_size).size()
-        mem_module_size = phys_mem_size / options.num_dirs
-        dir_size = MemorySize('0B')
-        dir_size.value = mem_module_size
-        self.size = dir_size
-
-# Directory controller: Contains directory memory, L3 cache and associated state
-# machine which is used to accurately redirect a data request to L3 cache or to
-# memory. The permissions requests do not come to this directory for region
+# Directory controller: Contains directory memory, L3 cache and associated
+# state machine which is used to accurately redirect a data request to L3 cache
+# or memory. The permissions requests do not come to this directory for region
 # based protocols as they are handled exclusively by the region directory.
 # However, region directory controller uses this directory controller for
 # sending probe requests and receiving probe responses.
 class DirCntrl(Directory_Controller, CntrlBase):
-    def create(self, options, ruby_system, system):
+    def create(self, options, dir_ranges, ruby_system, system):
         self.version = self.versionCount()
         self.response_latency = 25
         self.response_latency_regionDir = 1
-        self.directory = DirMem()
-        self.directory.create(options, ruby_system, system)
+        self.addr_ranges = dir_ranges
+        self.directory = RubyDirectoryMemory()
         self.L3CacheMemory = L3Cache()
         self.L3CacheMemory.create(options, ruby_system, system)
         self.l3_hit_latency = \
@@ -327,7 +323,7 @@ class RegionDir(RubyCache):
         self.dataAccessLatency = 1
         self.resourceStalls = options.no_resource_stalls
         self.start_index_bit = 6 + int(math.log(options.blocks_per_region, 2))
-        self.replacement_policy = PseudoLRUReplacementPolicy(assoc = self.assoc)
+        self.replacement_policy = TreePLRURP(num_leaves = self.assoc)
 # Region directory controller : Contains region directory and associated state
 # machine for dealing with region coherence requests.
 class RegionCntrl(RegionDir_Controller, CntrlBase):
@@ -385,7 +381,7 @@ class RBCntrl(RegionBuffer_Controller, CntrlBase):
         if options.recycle_latency:
             self.recycle_latency = options.recycle_latency
         self.cacheMemory.replacement_policy = \
-            PseudoLRUReplacementPolicy(assoc = self.cacheMemory.assoc)
+            TreePLRURP(num_leaves = self.cacheMemory.assoc)
 
 def define_options(parser):
     parser.add_option("--num-subcaches", type="int", default=4)
@@ -406,6 +402,8 @@ def define_options(parser):
                       help="SQC cache size")
     parser.add_option("--sqc-assoc", type='int', default=8,
                       help="SQC cache assoc")
+    parser.add_option("--sqc-deadlock-threshold", type='int',
+                      help="Set the SQC deadlock threshold to some value")
 
     parser.add_option("--WB_L1", action="store_true",
         default=False, help="L2 Writeback Cache")
@@ -421,6 +419,10 @@ def define_options(parser):
                       help="tcc assoc")
     parser.add_option("--tcp-size", type='string', default='16kB',
                       help="tcp size")
+    parser.add_option("--tcp-deadlock-threshold", type='int',
+                      help="Set the TCP deadlock threshold to some value")
+    parser.add_option("--max-coalesces-per-cycle", type="int", default=1,
+                      help="Maximum insts that may coalesce in a cycle");
 
     parser.add_option("--dir-tag-latency", type="int", default=4)
     parser.add_option("--dir-tag-banks", type="int", default=4)
@@ -468,7 +470,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
     # For an odd number of CPUs, still create the right number of controllers
     crossbar_bw = 16 * options.num_compute_units #Assuming a 2GHz clock
     cpuCluster = Cluster(extBW = (crossbar_bw), intBW=crossbar_bw)
-    for i in xrange((options.num_cpus + 1) / 2):
+    for i in range((options.num_cpus + 1) // 2):
 
         cp_cntrl = CPCntrl()
         cp_cntrl.create(options, ruby_system, system)
@@ -534,7 +536,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
         cpuCluster.add(rb_cntrl)
 
     gpuCluster = Cluster(extBW = (crossbar_bw), intBW = crossbar_bw)
-    for i in xrange(options.num_compute_units):
+    for i in range(options.num_compute_units):
 
         tcp_cntrl = TCPCntrl(TCC_select_num_bits = TCC_bits,
                              issue_latency = 1,
@@ -570,7 +572,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
 
         gpuCluster.add(tcp_cntrl)
 
-    for i in xrange(options.num_sqc):
+    for i in range(options.num_sqc):
 
         sqc_cntrl = SQCCntrl(TCC_select_num_bits = TCC_bits)
         sqc_cntrl.create(options, ruby_system, system)
@@ -598,7 +600,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
 
     numa_bit = 6
 
-    for i in xrange(options.num_tccs):
+    for i in range(options.num_tccs):
 
         tcc_cntrl = TCCCntrl()
         tcc_cntrl.create(options, ruby_system, system)
@@ -677,8 +679,26 @@ def create_system(options, full_system, system, dma_devices, bootmem,
     # Clusters
     mainCluster = Cluster(intBW = crossbar_bw)
 
+    if options.numa_high_bit:
+        numa_bit = options.numa_high_bit
+    else:
+        # if the numa_bit is not specified, set the directory bits as the
+        # lowest bits above the block offset bits, and the numa_bit as the
+        # highest of those directory bits
+        dir_bits = int(math.log(options.num_dirs, 2))
+        block_size_bits = int(math.log(options.cacheline_size, 2))
+        numa_bit = block_size_bits + dir_bits - 1
+
+    dir_ranges = []
+    for r in system.mem_ranges:
+        addr_range = m5.objects.AddrRange(r.start, size = r.size(),
+                                          intlvHighBit = numa_bit,
+                                          intlvBits = dir_bits,
+                                          intlvMatch = i)
+        dir_ranges.append(addr_range)
+
     dir_cntrl = DirCntrl()
-    dir_cntrl.create(options, ruby_system, system)
+    dir_cntrl.create(options, dir_ranges, ruby_system, system)
     dir_cntrl.number_of_TBEs = 2560 * options.num_compute_units
     dir_cntrl.useL3OnWT = options.use_L3_on_WT
 
@@ -712,6 +732,7 @@ def create_system(options, full_system, system, dma_devices, bootmem,
 
     dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
     dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
+    dir_cntrl.requestToMemory = MessageBuffer()
     dir_cntrl.responseFromMemory = MessageBuffer()
 
     exec("system.dir_cntrl%d = dir_cntrl" % i)