MOESI_AMD_Base.py revision 11308
11689SN/A#
213590Srekai.gonzalezalberquilla@arm.com#  Copyright (c) 2010-2015 Advanced Micro Devices, Inc.
310239Sbinhpham@cs.rutgers.edu#  All rights reserved.
47598Sminkyu.jeong@arm.com#
57598Sminkyu.jeong@arm.com#  For use for simulation and test purposes only
67598Sminkyu.jeong@arm.com#
77598Sminkyu.jeong@arm.com#  Redistribution and use in source and binary forms, with or without
87598Sminkyu.jeong@arm.com#  modification, are permitted provided that the following conditions are met:
97598Sminkyu.jeong@arm.com#
107598Sminkyu.jeong@arm.com#  1. Redistributions of source code must retain the above copyright notice,
117598Sminkyu.jeong@arm.com#  this list of conditions and the following disclaimer.
127598Sminkyu.jeong@arm.com#
137598Sminkyu.jeong@arm.com#  2. Redistributions in binary form must reproduce the above copyright notice,
147598Sminkyu.jeong@arm.com#  this list of conditions and the following disclaimer in the documentation
152326SN/A#  and/or other materials provided with the distribution.
161689SN/A#
171689SN/A#  3. Neither the name of the copyright holder nor the names of its contributors
181689SN/A#  may be used to endorse or promote products derived from this software
191689SN/A#  without specific prior written permission.
201689SN/A#
211689SN/A#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
221689SN/A#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231689SN/A#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241689SN/A#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
251689SN/A#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
261689SN/A#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
271689SN/A#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
281689SN/A#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
291689SN/A#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
301689SN/A#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
311689SN/A#  POSSIBILITY OF SUCH DAMAGE.
321689SN/A#
331689SN/A#  Author: Lisa Hsu
341689SN/A#
351689SN/A
361689SN/Aimport math
371689SN/Aimport m5
381689SN/Afrom m5.objects import *
391689SN/Afrom m5.defines import buildEnv
402665Ssaidi@eecs.umich.edufrom Ruby import create_topology
412665Ssaidi@eecs.umich.edufrom Ruby import send_evicts
421689SN/A
431689SN/Afrom Cluster import Cluster
449944Smatt.horsnell@ARM.comfrom Crossbar import Crossbar
459944Smatt.horsnell@ARM.com
469944Smatt.horsnell@ARM.comclass CntrlBase:
471060SN/A    _seqs = 0
481060SN/A    @classmethod
491689SN/A    def seqCount(cls):
501060SN/A        # Use SeqCount not class since we need global count
511060SN/A        CntrlBase._seqs += 1
521060SN/A        return CntrlBase._seqs - 1
538230Snate@binkert.org
546658Snate@binkert.org    _cntrls = 0
558887Sgeoffrey.blake@arm.com    @classmethod
562292SN/A    def cntrlCount(cls):
571717SN/A        # Use CntlCount not class since we need global count
588229Snate@binkert.org        CntrlBase._cntrls += 1
598232Snate@binkert.org        return CntrlBase._cntrls - 1
609444SAndreas.Sandberg@ARM.com
618232Snate@binkert.org    _version = 0
629527SMatt.Horsnell@arm.com    @classmethod
635529Snate@binkert.org    def versionCount(cls):
641060SN/A        cls._version += 1 # Use count for this particular type
656221Snate@binkert.org        return cls._version - 1
666221Snate@binkert.org
671681SN/Aclass L1DCache(RubyCache):
685529Snate@binkert.org    resourceStalls = False
692873Sktlim@umich.edu    def create(self, options):
704329Sktlim@umich.edu        self.size = MemorySize(options.l1d_size)
714329Sktlim@umich.edu        self.assoc = options.l1d_assoc
724329Sktlim@umich.edu        self.replacement_policy = PseudoLRUReplacementPolicy()
732292SN/A
742292SN/Aclass L1ICache(RubyCache):
752292SN/A    resourceStalls = False
762292SN/A    def create(self, options):
772820Sktlim@umich.edu        self.size = MemorySize(options.l1i_size)
782292SN/A        self.assoc = options.l1i_assoc
7913453Srekai.gonzalezalberquilla@arm.com        self.replacement_policy = PseudoLRUReplacementPolicy()
8013453Srekai.gonzalezalberquilla@arm.com
812820Sktlim@umich.educlass L2Cache(RubyCache):
829444SAndreas.Sandberg@ARM.com    resourceStalls = False
831060SN/A    def create(self, options):
8410172Sdam.sunwoo@arm.com        self.size = MemorySize(options.l2_size)
8510172Sdam.sunwoo@arm.com        self.assoc = options.l2_assoc
8610172Sdam.sunwoo@arm.com        self.replacement_policy = PseudoLRUReplacementPolicy()
8710172Sdam.sunwoo@arm.com
8810172Sdam.sunwoo@arm.comclass CPCntrl(CorePair_Controller, CntrlBase):
8910172Sdam.sunwoo@arm.com
9010172Sdam.sunwoo@arm.com    def create(self, options, ruby_system, system):
9110172Sdam.sunwoo@arm.com        self.version = self.versionCount()
9210172Sdam.sunwoo@arm.com
9310172Sdam.sunwoo@arm.com        self.L1Icache = L1ICache()
9410172Sdam.sunwoo@arm.com        self.L1Icache.create(options)
9510172Sdam.sunwoo@arm.com        self.L1D0cache = L1DCache()
9610172Sdam.sunwoo@arm.com        self.L1D0cache.create(options)
972292SN/A        self.L1D1cache = L1DCache()
982292SN/A        self.L1D1cache.create(options)
992292SN/A        self.L2cache = L2Cache()
1001060SN/A        self.L2cache.create(options)
1011060SN/A
1021060SN/A        self.sequencer = RubySequencer()
1031060SN/A        self.sequencer.icache_hit_latency = 2
1041060SN/A        self.sequencer.dcache_hit_latency = 2
1051060SN/A        self.sequencer.version = self.seqCount()
1061681SN/A        self.sequencer.icache = self.L1Icache
10713453Srekai.gonzalezalberquilla@arm.com        self.sequencer.dcache = self.L1D0cache
1086221Snate@binkert.org        self.sequencer.ruby_system = ruby_system
1096221Snate@binkert.org        self.sequencer.coreid = 0
1102292SN/A        self.sequencer.is_cpu_sequencer = True
1112292SN/A
1122292SN/A        self.sequencer1 = RubySequencer()
1132292SN/A        self.sequencer1.version = self.seqCount()
11410328Smitch.hayenga@arm.com        self.sequencer1.icache = self.L1Icache
1152292SN/A        self.sequencer1.dcache = self.L1D1cache
1162292SN/A        self.sequencer1.icache_hit_latency = 2
1172292SN/A        self.sequencer1.dcache_hit_latency = 2
1182292SN/A        self.sequencer1.ruby_system = ruby_system
1192292SN/A        self.sequencer1.coreid = 1
1202292SN/A        self.sequencer1.is_cpu_sequencer = True
1212292SN/A
1221060SN/A        self.issue_latency = options.cpu_to_dir_latency
1231060SN/A        self.send_evictions = send_evicts(options)
1241681SN/A
1251062SN/A        self.ruby_system = ruby_system
12610023Smatt.horsnell@ARM.com
12710023Smatt.horsnell@ARM.com        if options.recycle_latency:
12810023Smatt.horsnell@ARM.com            self.recycle_latency = options.recycle_latency
12910023Smatt.horsnell@ARM.com
13011246Sradhika.jagtap@ARM.comclass L3Cache(RubyCache):
13111246Sradhika.jagtap@ARM.com    assoc = 8
13211246Sradhika.jagtap@ARM.com    dataArrayBanks = 256
13311246Sradhika.jagtap@ARM.com    tagArrayBanks = 256
13411246Sradhika.jagtap@ARM.com
13511246Sradhika.jagtap@ARM.com    def create(self, options, ruby_system, system):
13611246Sradhika.jagtap@ARM.com        self.size = MemorySize(options.l3_size)
13711246Sradhika.jagtap@ARM.com        self.size.value /= options.num_dirs
13811246Sradhika.jagtap@ARM.com        self.dataArrayBanks /= options.num_dirs
13911246Sradhika.jagtap@ARM.com        self.tagArrayBanks /= options.num_dirs
14011246Sradhika.jagtap@ARM.com        self.dataArrayBanks /= options.num_dirs
14111246Sradhika.jagtap@ARM.com        self.tagArrayBanks /= options.num_dirs
14210023Smatt.horsnell@ARM.com        self.dataAccessLatency = options.l3_data_latency
14310023Smatt.horsnell@ARM.com        self.tagAccessLatency = options.l3_tag_latency
14410023Smatt.horsnell@ARM.com        self.resourceStalls = options.no_resource_stalls
14510023Smatt.horsnell@ARM.com        self.replacement_policy = PseudoLRUReplacementPolicy()
1462292SN/A
1471062SN/Aclass L3Cntrl(L3Cache_Controller, CntrlBase):
1482301SN/A    def create(self, options, ruby_system, system):
1492301SN/A        self.version = self.versionCount()
1501062SN/A        self.L3cache = L3Cache()
1512727Sktlim@umich.edu        self.L3cache.create(options, ruby_system, system)
1521062SN/A
1531062SN/A        self.l3_response_latency = max(self.L3cache.dataAccessLatency,
1541062SN/A                                       self.L3cache.tagAccessLatency)
1551062SN/A        self.ruby_system = ruby_system
1561062SN/A
1571062SN/A        if options.recycle_latency:
1581062SN/A            self.recycle_latency = options.recycle_latency
1591062SN/A
1601062SN/A    def connectWireBuffers(self, req_to_dir, resp_to_dir, l3_unblock_to_dir,
1611062SN/A                           req_to_l3, probe_to_l3, resp_to_l3):
1621062SN/A        self.reqToDir = req_to_dir
1631062SN/A        self.respToDir = resp_to_dir
1641062SN/A        self.l3UnblockToDir = l3_unblock_to_dir
1651062SN/A        self.reqToL3 = req_to_l3
1661062SN/A        self.probeToL3 = probe_to_l3
1671062SN/A        self.respToL3 = resp_to_l3
1681062SN/A
1691062SN/Aclass DirMem(RubyDirectoryMemory, CntrlBase):
1701062SN/A    def create(self, options, ruby_system, system):
1711062SN/A        self.version = self.versionCount()
1721062SN/A
1731062SN/A        phys_mem_size = AddrRange(options.mem_size).size()
1741062SN/A        mem_module_size = phys_mem_size / options.num_dirs
1751062SN/A        dir_size = MemorySize('0B')
1761062SN/A        dir_size.value = mem_module_size
1771062SN/A        self.size = dir_size
1781062SN/A
1791062SN/Aclass DirCntrl(Directory_Controller, CntrlBase):
1801062SN/A    def create(self, options, ruby_system, system):
1811062SN/A        self.version = self.versionCount()
1821062SN/A
1831062SN/A        self.response_latency = 30
1841062SN/A
1851062SN/A        self.directory = DirMem()
1861062SN/A        self.directory.create(options, ruby_system, system)
1871062SN/A
1881062SN/A        self.L3CacheMemory = L3Cache()
1891062SN/A        self.L3CacheMemory.create(options, ruby_system, system)
1901062SN/A
1911062SN/A        self.l3_hit_latency = max(self.L3CacheMemory.dataAccessLatency,
1921062SN/A                                  self.L3CacheMemory.tagAccessLatency)
1932292SN/A
1942292SN/A        self.number_of_TBEs = options.num_tbes
1952292SN/A
1962292SN/A        self.ruby_system = ruby_system
1971062SN/A
1981062SN/A        if options.recycle_latency:
1991062SN/A            self.recycle_latency = options.recycle_latency
2001062SN/A
2011062SN/A        self.CPUonly = True
2021062SN/A
2031062SN/A    def connectWireBuffers(self, req_to_dir, resp_to_dir, l3_unblock_to_dir,
2042292SN/A                           req_to_l3, probe_to_l3, resp_to_l3):
2052292SN/A        self.reqToDir = req_to_dir
2062292SN/A        self.respToDir = resp_to_dir
2072292SN/A        self.l3UnblockToDir = l3_unblock_to_dir
2082292SN/A        self.reqToL3 = req_to_l3
2092292SN/A        self.probeToL3 = probe_to_l3
2102292SN/A        self.respToL3 = resp_to_l3
2112292SN/A
2122292SN/Adef define_options(parser):
2132292SN/A    parser.add_option("--num-subcaches", type="int", default=4)
2142301SN/A    parser.add_option("--l3-data-latency", type="int", default=20)
2152727Sktlim@umich.edu    parser.add_option("--l3-tag-latency", type="int", default=15)
2162353SN/A    parser.add_option("--cpu-to-dir-latency", type="int", default=15)
2172727Sktlim@umich.edu    parser.add_option("--no-resource-stalls", action="store_false",
2182727Sktlim@umich.edu                      default=True)
2192727Sktlim@umich.edu    parser.add_option("--num-tbes", type="int", default=256)
2206221Snate@binkert.org    parser.add_option("--l2-latency", type="int", default=50) # load to use
2212353SN/A
2222727Sktlim@umich.edudef create_system(options, full_system, system, dma_devices, ruby_system):
2232727Sktlim@umich.edu    if buildEnv['PROTOCOL'] != 'MOESI_AMD_Base':
2242727Sktlim@umich.edu        panic("This script requires the MOESI_AMD_Base protocol.")
2252727Sktlim@umich.edu
2262353SN/A    cpu_sequencers = []
2272727Sktlim@umich.edu
2282727Sktlim@umich.edu    #
2292727Sktlim@umich.edu    # The ruby network creation expects the list of nodes in the system to
2306221Snate@binkert.org    # be consistent with the NetDest list.  Therefore the l1 controller
2318240Snate@binkert.org    # nodes must be listed before the directory nodes and directory nodes
2322301SN/A    # before dma nodes, etc.
2332727Sktlim@umich.edu    #
2342301SN/A    l1_cntrl_nodes = []
2352727Sktlim@umich.edu    l3_cntrl_nodes = []
2366221Snate@binkert.org    dir_cntrl_nodes = []
2378240Snate@binkert.org
2382301SN/A    control_count = 0
2392727Sktlim@umich.edu
2402301SN/A    #
2412727Sktlim@umich.edu    # Must create the individual controllers before the network to ensure
2426221Snate@binkert.org    # the controller constructors are called before the network constructor
2438240Snate@binkert.org    #
2442301SN/A
2452727Sktlim@umich.edu    # This is the base crossbar that connects the L3s, Dirs, and cpu
2462301SN/A    # Cluster
2472727Sktlim@umich.edu    mainCluster = Cluster(extBW = 512, intBW = 512) # 1 TB/s
2486221Snate@binkert.org    for i in xrange(options.num_dirs):
2498240Snate@binkert.org
2502301SN/A        dir_cntrl = DirCntrl(TCC_select_num_bits = 0)
2512727Sktlim@umich.edu        dir_cntrl.create(options, ruby_system, system)
2522301SN/A
2532301SN/A        # Connect the Directory controller to the ruby network
2548240Snate@binkert.org        dir_cntrl.requestFromCores = MessageBuffer(ordered = True)
2552301SN/A        dir_cntrl.requestFromCores.slave = ruby_system.network.master
2562727Sktlim@umich.edu
2572727Sktlim@umich.edu        dir_cntrl.responseFromCores = MessageBuffer()
2582727Sktlim@umich.edu        dir_cntrl.responseFromCores.slave = ruby_system.network.master
2592727Sktlim@umich.edu
2608240Snate@binkert.org        dir_cntrl.unblockFromCores = MessageBuffer()
2612727Sktlim@umich.edu        dir_cntrl.unblockFromCores.slave = ruby_system.network.master
2622727Sktlim@umich.edu
2632727Sktlim@umich.edu        dir_cntrl.probeToCore = MessageBuffer()
2642727Sktlim@umich.edu        dir_cntrl.probeToCore.master = ruby_system.network.slave
2652301SN/A
2662301SN/A        dir_cntrl.responseToCore = MessageBuffer()
2676221Snate@binkert.org        dir_cntrl.responseToCore.master = ruby_system.network.slave
2688240Snate@binkert.org
2692301SN/A        dir_cntrl.triggerQueue = MessageBuffer(ordered = True)
2702727Sktlim@umich.edu        dir_cntrl.L3triggerQueue = MessageBuffer(ordered = True)
2712301SN/A        dir_cntrl.responseFromMemory = MessageBuffer()
2722326SN/A
2736221Snate@binkert.org        exec("system.dir_cntrl%d = dir_cntrl" % i)
2748240Snate@binkert.org        dir_cntrl_nodes.append(dir_cntrl)
2752301SN/A
2762727Sktlim@umich.edu        mainCluster.add(dir_cntrl)
2772301SN/A
2782326SN/A    # Technically this config can support an odd number of cpus, but the top
2796221Snate@binkert.org    # level config files, such as the ruby_random_tester, will get confused if
2808240Snate@binkert.org    # the number of cpus does not equal the number of sequencers.  Thus make
2812301SN/A    # sure that an even number of cpus is specified.
2822727Sktlim@umich.edu    assert((options.num_cpus % 2) == 0)
2832301SN/A
2842326SN/A    # For an odd number of CPUs, still create the right number of controllers
2856221Snate@binkert.org    cpuCluster = Cluster(extBW = 512, intBW = 512)  # 1 TB/s
2868240Snate@binkert.org    for i in xrange((options.num_cpus + 1) / 2):
2872301SN/A
2882727Sktlim@umich.edu        cp_cntrl = CPCntrl()
2892301SN/A        cp_cntrl.create(options, ruby_system, system)
2902326SN/A
2918240Snate@binkert.org        exec("system.cp_cntrl%d = cp_cntrl" % i)
2922301SN/A        #
2932727Sktlim@umich.edu        # Add controllers and sequencers to the appropriate lists
2942301SN/A        #
2952326SN/A        cpu_sequencers.extend([cp_cntrl.sequencer, cp_cntrl.sequencer1])
2962301SN/A
2972326SN/A        # Connect the CP controllers and the network
2988240Snate@binkert.org        cp_cntrl.requestFromCore = MessageBuffer()
2992301SN/A        cp_cntrl.requestFromCore.master = ruby_system.network.slave
3002727Sktlim@umich.edu
3012326SN/A        cp_cntrl.responseFromCore = MessageBuffer()
3021062SN/A        cp_cntrl.responseFromCore.master = ruby_system.network.slave
3031062SN/A
3041681SN/A        cp_cntrl.unblockFromCore = MessageBuffer()
3051060SN/A        cp_cntrl.unblockFromCore.master = ruby_system.network.slave
3069427SAndreas.Sandberg@ARM.com
3071060SN/A        cp_cntrl.probeToCore = MessageBuffer()
3086221Snate@binkert.org        cp_cntrl.probeToCore.slave = ruby_system.network.master
3092292SN/A
3102292SN/A        cp_cntrl.responseToCore = MessageBuffer()
3112292SN/A        cp_cntrl.responseToCore.slave = ruby_system.network.master
3122292SN/A
3132292SN/A        cp_cntrl.mandatoryQueue = MessageBuffer()
31410239Sbinhpham@cs.rutgers.edu        cp_cntrl.triggerQueue = MessageBuffer(ordered = True)
31510239Sbinhpham@cs.rutgers.edu
3162292SN/A        cpuCluster.add(cp_cntrl)
3172292SN/A
3188887Sgeoffrey.blake@arm.com    # Assuming no DMA devices
3198733Sgeoffrey.blake@arm.com    assert(len(dma_devices) == 0)
3208850Sandreas.hansson@arm.com
3218887Sgeoffrey.blake@arm.com    # Add cpu/gpu clusters to main cluster
3228733Sgeoffrey.blake@arm.com    mainCluster.add(cpuCluster)
3232733Sktlim@umich.edu
3241060SN/A    ruby_system.network.number_of_virtual_networks = 10
3251060SN/A
3261681SN/A    return (cpu_sequencers, dir_cntrl_nodes, mainCluster)
3271060SN/A