diff -r 0398959a1903 -r 58028cf7d15a src/cpu/BaseCPU.py --- a/src/cpu/BaseCPU.py Fri Jun 17 11:47:10 2016 -0300 +++ b/src/cpu/BaseCPU.py Fri Jun 17 11:48:44 2016 -0300 @@ -263,12 +263,7 @@ uncached_bus = cached_bus self.connectUncachedPorts(uncached_bus) - def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None): - self.icache = ic - self.dcache = dc - self.icache_port = ic.cpu_side - self.dcache_port = dc.cpu_side - self._cached_ports = ['icache.mem_side', 'dcache.mem_side'] + def addTLBPorts(self, iwc, dwc, i_bus = None, d_bus = None): if buildEnv['TARGET_ISA'] in ['x86', 'arm']: if iwc and dwc: self.itb_walker_cache = iwc @@ -277,6 +272,9 @@ self.dtb.walker.port = dwc.cpu_side self._cached_ports += ["itb_walker_cache.mem_side", \ "dtb_walker_cache.mem_side"] + elif i_bus and d_bus: + self.dtb.walker.port = d_bus.slave + self.itb.walker.port = i_bus.slave else: self._cached_ports += ["itb.walker.port", "dtb.walker.port"] @@ -286,6 +284,51 @@ self._cached_ports += ["checker.itb.walker.port", \ "checker.dtb.walker.port"] + def _attachPrivateSplitL1Caches(self, ic, dc): + self.icache = ic + self.dcache = dc + self.icache_port = ic.cpu_side + self.dcache_port = dc.cpu_side + + def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None): + self._attachPrivateSplitL1Caches(ic, dc) + self._cached_ports = ['icache.mem_side', 'dcache.mem_side'] + + self.addTLBPorts(iwc, dwc) + + def addPrivateL2Cache(self, ic, dc, l2c, iwc, dwc): + self._attachPrivateSplitL1Caches(ic, dc) + self.l2_cache = l2c + self.icache.mem_side = self.tol2bus.slave + self.dcache.mem_side = self.tol2bus.slave + self.l2_cache.cpu_side = self.tol2bus.master + self._cached_ports = ['l2_cache.mem_side'] + + self.addTLBPorts(iwc, dwc, self.tol2bus, self.tol2bus) + + def addPrivateSplitL2Caches(self, ic, dc, l2ic, l2dc, iwc, dwc): + self._attachPrivateSplitL1Caches(ic, dc) + self.l2cache_i = l2ic + self.l2cache_d = l2dc + self.icache.mem_side = self.tol2ibus.slave + self.dcache.mem_side = self.tol2dbus.slave + self.l2cache_i.cpu_side = self.tol2ibus.master + self.l2cache_d.cpu_side = self.tol2dbus.master + self._cached_ports = ['l2cache_i.mem_side', 'l2cache_d.mem_side'] + + self.addTLBPorts(iwc, dwc, self.tol2ibus, self.tol2dbus) + + def addSplitL2Caches(self, ic, dc, l2i_bus, l2d_bus, iwc=None, dwc=None): + self._attachPrivateSplitL1Caches(ic, dc) + self.icache.mem_side = l2i_bus.slave + self.dcache.mem_side = l2d_bus.slave + self._cached_ports = [] + + self.addTLBPorts(iwc, dwc, l2i_bus, l2d_bus) + + def addPairedL2Caches(self, ic, dc, l2_bus, iwc = None, dwc = None): + self.addSplitL2Caches(ic, dc, l2_bus, l2_bus, iwc, dwc) + def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc = None, dwc = None): self.addPrivateSplitL1Caches(ic, dc, iwc, dwc) self.toL2Bus = L2XBar() diff -r 0398959a1903 -r 58028cf7d15a configs/common/Options.py --- a/configs/common/Options.py Fri Jun 17 11:47:10 2016 -0300 +++ b/configs/common/Options.py Fri Jun 17 11:48:44 2016 -0300 @@ -129,20 +129,44 @@ help="use private L1 caches") parser.add_option("--l2cache", action="store_true", help="""use a shared and centralized L2 cache + (configurable through --l2_hit, l2_mshr) + (classic memory system)""") + parser.add_option("--l2cache_id", action="store_true", + help="""use shared and centralized L2 inst/data caches + (configurable through --l2d_hit, --l2d_hit, --l2d_mshr, + --l2i-mshr) (classic memory system)""") + parser.add_option("--l2cache_private", action="store_true", + help="""use a private and distributed L2 cache per + core (configurable through --l2_hit, --l2_mshr) + (classic memory system)""") + parser.add_option("--l2cache_private_id", action="store_true", + help="""use private and distributed L2 inst/data + caches per core (configurable through --l2d_hit, + --l2i_hit, --l2d_mshr, --l2i_mshr) + (classic memory system)""") + parser.add_option("--l2cache_paired", type="int", default=0, + help="""Number of paired L2 caches + (configurable through --l2_hit, --l2_mshr) (classic memory system)""") parser.add_option("--fastmem", action="store_true") parser.add_option("--num-dirs", type="int", default=1, - help="Specify the number of directories (Ruby only)") + help="Specify the number of directories (Ruby)") parser.add_option("--num-l2caches", type="int", default=1, - help="Specify the number of L2 caches (Ruby only)") + help="Specify the number of L2 caches (Ruby)") parser.add_option("--num-l3caches", type="int", default=1, - help="Specify the number of L3 caches (Ruby only)") + help="Specify the number of L3 caches (Ruby)") parser.add_option("--l1d_size", type="string", default="64kB", help="Specify the data L1 cache size") parser.add_option("--l1i_size", type="string", default="32kB", help="Specify the instruction L1 cache size") parser.add_option("--l2_size", type="string", default="2MB", help="Specify the L2 cache size") + parser.add_option("--l2d_size", type="string", default="1MB", + help="""Specify the L2 data cache size + (classic memory system)""") + parser.add_option("--l2i_size", type="string", default="1MB", + help="""Specify the L2 inst. cache size + (classic memory system)""") parser.add_option("--l3_size", type="string", default="16MB", help="Specify the L3 cache size") parser.add_option("--l1d_assoc", type="int", default=2, @@ -151,16 +175,34 @@ help="Specify the instruction L1 cache associativity") parser.add_option("--l2_assoc", type="int", default=8, help="Specify the L2 cache associativity") + parser.add_option("--l2d_assoc", type="int", default=8, + help="""Specify the L2 data cache associativity + (classic memory system)""") + parser.add_option("--l2i_assoc", type="int", default=8, + help="""Specify the L2 inst. cache associativity + (classic memory system)""") parser.add_option("--l3_assoc", type="int", default=16, help="Specify the L3 cache associativity") parser.add_option("--cacheline_size", type="int", default=64, help="Specify the cacheline size") parser.add_option("--l2_hit", type="int", default=20, help="""Specify hit latency for L2 cache - (classic memory system only)""") + (classic memory system)""") + parser.add_option("--l2d_hit", type="int", default=10, + help="""Specify hit latency for L2 data cache + (classic memory system)""") + parser.add_option("--l2i_hit", type="int", default=10, + help="""Specify hit latency for L2 inst. cache + (classic memory system)""") parser.add_option("--l2_mshr", type="int", default=20, help="""Specify MSHR queue size for L2 cache - (classic memory system only)""") + (classic memory system)""") + parser.add_option("--l2d_mshr", type="int", default=10, + help="""Specify MSHR queue size for L2 data cache + (classic memory system)""") + parser.add_option("--l2i_mshr", type="int", default=10, + help="""Specify MSHR queue size for L2 inst. cache + (classic memory system)""") # Enable Ruby parser.add_option("--ruby", action="store_true") # HG changeset patch # Parent 0398959a19035a32304d124a8e9e628268e51214 config, mem: add new L2 cache architectures for the classic memory system diff -r 0398959a1903 -r 58028cf7d15a configs/common/CacheConfig.py --- a/configs/common/CacheConfig.py Fri Jun 17 11:47:10 2016 -0300 +++ b/configs/common/CacheConfig.py Fri Jun 17 11:48:44 2016 -0300 @@ -76,7 +76,11 @@ if options.l2cache and options.elastic_trace_en: fatal("When elastic trace is enabled, do not configure L2 caches.") - if options.l2cache: + # private caches will be instantiated later with L1 caches + if options.l2cache_private or options.l2cache_private_id: + pass + + elif options.l2cache: # Provide a clock for the L2 and the L1-to-L2 bus here as they # are not connected using addTwoLevelCacheHierarchy. Use the # same clock as the CPUs. @@ -91,6 +95,50 @@ system.l2.cpu_side = system.tol2bus.master system.l2.mem_side = system.membus.slave + elif options.l2cache_id: + system.l2i = l2_cache_class(clk_domain=system.cpu_clk_domain, + size=options.l2i_size, + assoc=options.l2i_assoc, + hit_latency=options.l2i_hit, + response_latency=options.l2i_hit, + mshrs=options.l2i_mshr) + + system.l2d = l2_cache_class(clk_domain=system.cpu_clk_domain, + size=options.l2d_size, + assoc=options.l2d_assoc, + hit_latency=options.l2d_hit, + response_latency=options.l2d_hit, + mshrs=options.l2d_mshr) + + # L2I bus + system.tol2ibus = L2XBar(clk_domain=system.cpu_clk_domain) + system.l2i.cpu_side = system.tol2ibus.master + # L2D bus + system.tol2dbus = L2XBar(clk_domain=system.cpu_clk_domain) + system.l2d.cpu_side = system.tol2dbus.master + + system.l2i.mem_side = system.membus.slave + system.l2d.mem_side = system.membus.slave + + elif options.l2cache_paired: + if options.num_cpus % options.l2cache_paired != 0: + fatal("Number of CPUs must be divisible by l2cache_paired.") + + for i in xrange(options.l2cache_paired): + # Unfortunately, the number of paired L2 caches are only + # determined at runtime. As such, exec is used. + exec('system.l2_%d = l2_cache_class(\ + clk_domain=system.cpu_clk_domain,\ + size=options.l2_size,\ + assoc=options.l2_assoc,\ + hit_latency=options.l2_hit,\ + response_latency=options.l2_hit,\ + mshrs=options.l2_mshr)' % i) + + exec('system.tol2bus_%d = L2XBar(\ + clk_domain=system.cpu_clk_domain)' % i) + exec('system.l2_%d.cpu_side = system.tol2bus_%d.master' % (i, i)) + exec('system.l2_%d.mem_side = system.membus.slave' % i) if options.memchecker: system.memchecker = MemChecker() @@ -101,6 +149,32 @@ dcache = dcache_class(size=options.l1d_size, assoc=options.l1d_assoc) + # private L2 caches instantiation + if options.l2cache_private: + l2cache = l2_cache_class(size=options.l2_size, + assoc=options.l2_assoc, + hit_latency=options.l2_hit, + response_latency=options.l2_hit, + mshrs=options.l2_mshr) + + system.cpu[i].tol2bus = L2XBar( + clk_domain=system.cpu_clk_domain) + elif options.l2cache_private_id: + l2cache_i = l2_cache_class(size=options.l2i_size, + assoc=options.l2i_assoc, + hit_latency=options.l2i_hit, + response_latency=options.l2i_hit, + mshrs=options.l2i_mshr) + l2cache_d = l2_cache_class(size=options.l2d_size, + assoc=options.l2d_assoc, + hit_latency=options.l2d_hit, + response_latency=options.l2d_hit, + mshrs=options.l2d_mshr) + system.cpu[i].tol2ibus = L2XBar( + clk_domain=system.cpu_clk_domain) + system.cpu[i].tol2dbus = L2XBar( + clk_domain=system.cpu_clk_domain) + if options.memchecker: dcache_mon = MemCheckerMonitor(warn_only=True) dcache_real = dcache @@ -119,11 +193,37 @@ # When connecting the caches, the clock is also inherited # from the CPU in question if buildEnv['TARGET_ISA'] == 'x86': + wc_1 = PageTableWalkerCache() + wc_2 = PageTableWalkerCache() + else: + wc_1 = None + wc_2 = None + + # check for private/paired L2 Caches + if options.l2cache_private: + system.cpu[i].addPrivateL2Cache(icache, dcache, l2cache, + wc_1, wc_2) + + elif options.l2cache_private_id: + system.cpu[i].addPrivateSplitL2Caches(icache, dcache, + l2cache_i, l2cache_d, + wc_1, wc_2) + + elif options.l2cache_id: + system.cpu[i].addSplitL2Caches(icache, dcache, system.tol2ibus, + system.tol2dbus, wc_1, wc_2) + + elif options.l2cache_paired: + # find l2 pair + l2_idx = i // (options.num_cpus/options.l2cache_paired) + exec('l2bus_mux = system.tol2bus_%d' % l2_idx) + system.cpu[i].addPairedL2Caches(icache, dcache, l2bus_mux, + wc_1, wc_2) + + else: + # shared L2 cache system.cpu[i].addPrivateSplitL1Caches(icache, dcache, - PageTableWalkerCache(), - PageTableWalkerCache()) - else: - system.cpu[i].addPrivateSplitL1Caches(icache, dcache) + wc_1, wc_2) if options.memchecker: # The mem_side ports of the caches haven't been connected yet. @@ -137,6 +237,11 @@ # on these names. For simplicity, we would advise configuring # it to use this naming scheme; if this isn't possible, change # the names below. + if options.l2cache_private or options.l2cache_id or\ + options.l2cache_private_id or options.l2cache_paired: + fatal("External memory system is limited to private L1 caches\ + and a single shared L2 cache") + if buildEnv['TARGET_ISA'] in ['x86', 'arm']: system.cpu[i].addPrivateSplitL1Caches( ExternalCache("cpu%d.icache" % i), @@ -151,6 +256,9 @@ system.cpu[i].createInterruptController() if options.l2cache: system.cpu[i].connectAllPorts(system.tol2bus, system.membus) + elif options.l2cache_id: + system.cpu[i].connectAllPorts(system.tol2dbus, system.membus) + system.cpu[i].connectAllPorts(system.tol2ibus, system.membus) elif options.external_memory_system: system.cpu[i].connectUncachedPorts(system.membus) else: