MemConfig.py revision 11818
19665Sandreas.hansson@arm.com# Copyright (c) 2013 ARM Limited
29520SN/A# All rights reserved.
39520SN/A#
49520SN/A# The license below extends only to copyright in the software and shall
59520SN/A# not be construed as granting a license to any other intellectual
69520SN/A# property including but not limited to intellectual property relating
79520SN/A# to a hardware implementation of the functionality of the software
89520SN/A# licensed hereunder.  You may use the software subject to the license
99520SN/A# terms below provided that you ensure that this notice is replicated
109520SN/A# unmodified and in its entirety in all distributions of the software,
119520SN/A# modified or unmodified, in source code or in binary form.
129520SN/A#
139520SN/A# Redistribution and use in source and binary forms, with or without
149520SN/A# modification, are permitted provided that the following conditions are
159520SN/A# met: redistributions of source code must retain the above copyright
169520SN/A# notice, this list of conditions and the following disclaimer;
179520SN/A# redistributions in binary form must reproduce the above copyright
189520SN/A# notice, this list of conditions and the following disclaimer in the
199520SN/A# documentation and/or other materials provided with the distribution;
209520SN/A# neither the name of the copyright holders nor the names of its
219520SN/A# contributors may be used to endorse or promote products derived from
229520SN/A# this software without specific prior written permission.
239520SN/A#
249520SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
259520SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
269520SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
279520SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
289520SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
299520SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
309520SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
319520SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
329520SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
339520SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
349520SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
359520SN/A#
369520SN/A# Authors: Andreas Sandberg
379665Sandreas.hansson@arm.com#          Andreas Hansson
389520SN/A
399520SN/Aimport m5.objects
409520SN/Aimport inspect
419520SN/Aimport sys
4211183Serfan.azarkhish@unibo.itimport HMC
439520SN/Afrom textwrap import  TextWrapper
449520SN/A
459665Sandreas.hansson@arm.com# Dictionary of mapping names of real memory controller models to
469665Sandreas.hansson@arm.com# classes.
479665Sandreas.hansson@arm.com_mem_classes = {}
489520SN/A
499665Sandreas.hansson@arm.comdef is_mem_class(cls):
509665Sandreas.hansson@arm.com    """Determine if a class is a memory controller that can be instantiated"""
519520SN/A
529520SN/A    # We can't use the normal inspect.isclass because the ParamFactory
539520SN/A    # and ProxyFactory classes have a tendency to confuse it.
549520SN/A    try:
559665Sandreas.hansson@arm.com        return issubclass(cls, m5.objects.AbstractMemory) and \
569665Sandreas.hansson@arm.com            not cls.abstract
579520SN/A    except TypeError:
589520SN/A        return False
599520SN/A
609520SN/Adef get(name):
6110789Sandreas.hansson@arm.com    """Get a memory class from a user provided class name."""
629520SN/A
639520SN/A    try:
6410789Sandreas.hansson@arm.com        mem_class = _mem_classes[name]
659665Sandreas.hansson@arm.com        return mem_class
669520SN/A    except KeyError:
679665Sandreas.hansson@arm.com        print "%s is not a valid memory controller." % (name,)
689520SN/A        sys.exit(1)
699520SN/A
709665Sandreas.hansson@arm.comdef print_mem_list():
7110789Sandreas.hansson@arm.com    """Print a list of available memory classes."""
729520SN/A
739665Sandreas.hansson@arm.com    print "Available memory classes:"
749520SN/A    doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t")
759665Sandreas.hansson@arm.com    for name, cls in _mem_classes.items():
769520SN/A        print "\t%s" % name
779520SN/A
789520SN/A        # Try to extract the class documentation from the class help
799520SN/A        # string.
809520SN/A        doc = inspect.getdoc(cls)
819520SN/A        if doc:
829520SN/A            for line in doc_wrapper.wrap(doc):
839520SN/A                print line
849520SN/A
859665Sandreas.hansson@arm.comdef mem_names():
869665Sandreas.hansson@arm.com    """Return a list of valid memory names."""
8710789Sandreas.hansson@arm.com    return _mem_classes.keys()
889520SN/A
899665Sandreas.hansson@arm.com# Add all memory controllers in the object hierarchy.
909665Sandreas.hansson@arm.comfor name, cls in inspect.getmembers(m5.objects, is_mem_class):
919665Sandreas.hansson@arm.com    _mem_classes[name] = cls
929520SN/A
9310675Sandreas.hansson@arm.comdef create_mem_ctrl(cls, r, i, nbr_mem_ctrls, intlv_bits, intlv_size):
9410442Snilay@cs.wisc.edu    """
9510442Snilay@cs.wisc.edu    Helper function for creating a single memoy controller from the given
9610442Snilay@cs.wisc.edu    options.  This function is invoked multiple times in config_mem function
9710442Snilay@cs.wisc.edu    to create an array of controllers.
9810442Snilay@cs.wisc.edu    """
9910442Snilay@cs.wisc.edu
10010442Snilay@cs.wisc.edu    import math
10110675Sandreas.hansson@arm.com    intlv_low_bit = int(math.log(intlv_size, 2))
10210442Snilay@cs.wisc.edu
10310677Sandreas.hansson@arm.com    # Use basic hashing for the channel selection, and preferably use
10410677Sandreas.hansson@arm.com    # the lower tag bits from the last level cache. As we do not know
10510677Sandreas.hansson@arm.com    # the details of the caches here, make an educated guess. 4 MByte
10610677Sandreas.hansson@arm.com    # 4-way associative with 64 byte cache lines is 6 offset bits and
10710677Sandreas.hansson@arm.com    # 14 index bits.
10810677Sandreas.hansson@arm.com    xor_low_bit = 20
10910677Sandreas.hansson@arm.com
11010442Snilay@cs.wisc.edu    # Create an instance so we can figure out the address
11110442Snilay@cs.wisc.edu    # mapping and row-buffer size
11210442Snilay@cs.wisc.edu    ctrl = cls()
11310442Snilay@cs.wisc.edu
11410442Snilay@cs.wisc.edu    # Only do this for DRAMs
11510442Snilay@cs.wisc.edu    if issubclass(cls, m5.objects.DRAMCtrl):
11610442Snilay@cs.wisc.edu        # Inform each controller how many channels to account
11710442Snilay@cs.wisc.edu        # for
11810442Snilay@cs.wisc.edu        ctrl.channels = nbr_mem_ctrls
11910442Snilay@cs.wisc.edu
12010442Snilay@cs.wisc.edu        # If the channel bits are appearing after the column
12110442Snilay@cs.wisc.edu        # bits, we need to add the appropriate number of bits
12210442Snilay@cs.wisc.edu        # for the row buffer size
12310442Snilay@cs.wisc.edu        if ctrl.addr_mapping.value == 'RoRaBaChCo':
12410442Snilay@cs.wisc.edu            # This computation only really needs to happen
12510442Snilay@cs.wisc.edu            # once, but as we rely on having an instance we
12610442Snilay@cs.wisc.edu            # end up having to repeat it for each and every
12710442Snilay@cs.wisc.edu            # one
12810442Snilay@cs.wisc.edu            rowbuffer_size = ctrl.device_rowbuffer_size.value * \
12910442Snilay@cs.wisc.edu                ctrl.devices_per_rank.value
13010442Snilay@cs.wisc.edu
13110675Sandreas.hansson@arm.com            intlv_low_bit = int(math.log(rowbuffer_size, 2))
13210442Snilay@cs.wisc.edu
13310442Snilay@cs.wisc.edu    # We got all we need to configure the appropriate address
13410442Snilay@cs.wisc.edu    # range
13510442Snilay@cs.wisc.edu    ctrl.range = m5.objects.AddrRange(r.start, size = r.size(),
13610442Snilay@cs.wisc.edu                                      intlvHighBit = \
13710675Sandreas.hansson@arm.com                                          intlv_low_bit + intlv_bits - 1,
13810677Sandreas.hansson@arm.com                                      xorHighBit = \
13910677Sandreas.hansson@arm.com                                          xor_low_bit + intlv_bits - 1,
14010442Snilay@cs.wisc.edu                                      intlvBits = intlv_bits,
14110442Snilay@cs.wisc.edu                                      intlvMatch = i)
14210442Snilay@cs.wisc.edu    return ctrl
14310442Snilay@cs.wisc.edu
1449836Sandreas.hansson@arm.comdef config_mem(options, system):
1459836Sandreas.hansson@arm.com    """
1469836Sandreas.hansson@arm.com    Create the memory controllers based on the options and attach them.
1479836Sandreas.hansson@arm.com
1489836Sandreas.hansson@arm.com    If requested, we make a multi-channel configuration of the
1499836Sandreas.hansson@arm.com    selected memory controller class by creating multiple instances of
1509836Sandreas.hansson@arm.com    the specific class. The individual controllers have their
1519836Sandreas.hansson@arm.com    parameters set such that the address range is interleaved between
1529836Sandreas.hansson@arm.com    them.
1539836Sandreas.hansson@arm.com    """
1549836Sandreas.hansson@arm.com
15511183Serfan.azarkhish@unibo.it    if ( options.mem_type == "HMC_2500_x32"):
15611551Sabdul.mutaal@gmail.com        HMChost = HMC.config_host_hmc(options, system)
15711551Sabdul.mutaal@gmail.com        HMC.config_hmc(options, system, HMChost.hmc_host)
15811551Sabdul.mutaal@gmail.com        subsystem = system.hmc_dev
15911551Sabdul.mutaal@gmail.com        xbar = system.hmc_dev.xbar
16011183Serfan.azarkhish@unibo.it    else:
16111183Serfan.azarkhish@unibo.it        subsystem = system
16211183Serfan.azarkhish@unibo.it        xbar = system.membus
16311183Serfan.azarkhish@unibo.it
16410993Sjungma@eit.uni-kl.de    if options.tlm_memory:
16510993Sjungma@eit.uni-kl.de        system.external_memory = m5.objects.ExternalSlave(
16611818SChristian.Menard@tu-dresden.de            port_type="tlm_slave",
16710993Sjungma@eit.uni-kl.de            port_data=options.tlm_memory,
16810993Sjungma@eit.uni-kl.de            port=system.membus.master,
16910993Sjungma@eit.uni-kl.de            addr_ranges=system.mem_ranges)
17010993Sjungma@eit.uni-kl.de        system.kernel_addr_check = False
17110993Sjungma@eit.uni-kl.de        return
17210993Sjungma@eit.uni-kl.de
17310780SCurtis.Dunham@arm.com    if options.external_memory_system:
17411183Serfan.azarkhish@unibo.it        subsystem.external_memory = m5.objects.ExternalSlave(
17510780SCurtis.Dunham@arm.com            port_type=options.external_memory_system,
17611183Serfan.azarkhish@unibo.it            port_data="init_mem0", port=xbar.master,
17710780SCurtis.Dunham@arm.com            addr_ranges=system.mem_ranges)
17811183Serfan.azarkhish@unibo.it        subsystem.kernel_addr_check = False
17910780SCurtis.Dunham@arm.com        return
18010780SCurtis.Dunham@arm.com
1819836Sandreas.hansson@arm.com    nbr_mem_ctrls = options.mem_channels
1829836Sandreas.hansson@arm.com    import math
1839836Sandreas.hansson@arm.com    from m5.util import fatal
1849836Sandreas.hansson@arm.com    intlv_bits = int(math.log(nbr_mem_ctrls, 2))
1859836Sandreas.hansson@arm.com    if 2 ** intlv_bits != nbr_mem_ctrls:
1869836Sandreas.hansson@arm.com        fatal("Number of memory channels must be a power of 2")
18710442Snilay@cs.wisc.edu
1889836Sandreas.hansson@arm.com    cls = get(options.mem_type)
1899836Sandreas.hansson@arm.com    mem_ctrls = []
1909836Sandreas.hansson@arm.com
19111251Sradhika.jagtap@ARM.com    if options.elastic_trace_en and not issubclass(cls, \
19211251Sradhika.jagtap@ARM.com                                                    m5.objects.SimpleMemory):
19311251Sradhika.jagtap@ARM.com        fatal("When elastic trace is enabled, configure mem-type as "
19411251Sradhika.jagtap@ARM.com                "simple-mem.")
19511251Sradhika.jagtap@ARM.com
19610675Sandreas.hansson@arm.com    # The default behaviour is to interleave memory channels on 128
19710675Sandreas.hansson@arm.com    # byte granularity, or cache line granularity if larger than 128
19810675Sandreas.hansson@arm.com    # byte. This value is based on the locality seen across a large
19910675Sandreas.hansson@arm.com    # range of workloads.
20010675Sandreas.hansson@arm.com    intlv_size = max(128, system.cache_line_size.value)
20110675Sandreas.hansson@arm.com
2029836Sandreas.hansson@arm.com    # For every range (most systems will only have one), create an
2039836Sandreas.hansson@arm.com    # array of controllers and set their parameters to match their
2049836Sandreas.hansson@arm.com    # address mapping in the case of a DRAM
2059836Sandreas.hansson@arm.com    for r in system.mem_ranges:
2069836Sandreas.hansson@arm.com        for i in xrange(nbr_mem_ctrls):
20710620Sandreas.hansson@arm.com            mem_ctrl = create_mem_ctrl(cls, r, i, nbr_mem_ctrls, intlv_bits,
20810675Sandreas.hansson@arm.com                                       intlv_size)
20910620Sandreas.hansson@arm.com            # Set the number of ranks based on the command-line
21010620Sandreas.hansson@arm.com            # options if it was explicitly set
21110620Sandreas.hansson@arm.com            if issubclass(cls, m5.objects.DRAMCtrl) and \
21210620Sandreas.hansson@arm.com                    options.mem_ranks:
21310620Sandreas.hansson@arm.com                mem_ctrl.ranks_per_channel = options.mem_ranks
21410620Sandreas.hansson@arm.com
21511251Sradhika.jagtap@ARM.com            if options.elastic_trace_en:
21611251Sradhika.jagtap@ARM.com                mem_ctrl.latency = '1ns'
21711251Sradhika.jagtap@ARM.com                print "For elastic trace, over-riding Simple Memory " \
21811251Sradhika.jagtap@ARM.com                    "latency to 1ns."
21911251Sradhika.jagtap@ARM.com
22010620Sandreas.hansson@arm.com            mem_ctrls.append(mem_ctrl)
2219836Sandreas.hansson@arm.com
22211183Serfan.azarkhish@unibo.it    subsystem.mem_ctrls = mem_ctrls
2239836Sandreas.hansson@arm.com
2249836Sandreas.hansson@arm.com    # Connect the controllers to the membus
22511183Serfan.azarkhish@unibo.it    for i in xrange(len(subsystem.mem_ctrls)):
22611551Sabdul.mutaal@gmail.com        if (options.mem_type == "HMC_2500_x32"):
22711551Sabdul.mutaal@gmail.com            subsystem.mem_ctrls[i].port = xbar[i/4].master
22811551Sabdul.mutaal@gmail.com        else:
22911551Sabdul.mutaal@gmail.com            subsystem.mem_ctrls[i].port = xbar.master
230