MemConfig.py revision 10041
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
429520SN/Afrom textwrap import  TextWrapper
439520SN/A
449665Sandreas.hansson@arm.com# Dictionary of mapping names of real memory controller models to
459665Sandreas.hansson@arm.com# classes.
469665Sandreas.hansson@arm.com_mem_classes = {}
479520SN/A
489665Sandreas.hansson@arm.com# Memory aliases. We make sure they exist before we add them to the
499665Sandreas.hansson@arm.com# fina; list. A target may be specified as a tuple, in which case the
509665Sandreas.hansson@arm.com# first available memory controller model in the tuple will be used.
519665Sandreas.hansson@arm.com_mem_aliases_all = [
529665Sandreas.hansson@arm.com    ("simple_mem", "SimpleMemory"),
539728Sandreas.hansson@arm.com    ("ddr3_1600_x64", "DDR3_1600_x64"),
549728Sandreas.hansson@arm.com    ("lpddr2_s4_1066_x32", "LPDDR2_S4_1066_x32"),
559728Sandreas.hansson@arm.com    ("lpddr3_1600_x32", "LPDDR3_1600_x32"),
569728Sandreas.hansson@arm.com    ("wio_200_x128", "WideIO_200_x128"),
579520SN/A    ]
589520SN/A
599665Sandreas.hansson@arm.com# Filtered list of aliases. Only aliases for existing memory
609665Sandreas.hansson@arm.com# controllers exist in this list.
619665Sandreas.hansson@arm.com_mem_aliases = {}
629520SN/A
639520SN/A
649665Sandreas.hansson@arm.comdef is_mem_class(cls):
659665Sandreas.hansson@arm.com    """Determine if a class is a memory controller that can be instantiated"""
669520SN/A
679520SN/A    # We can't use the normal inspect.isclass because the ParamFactory
689520SN/A    # and ProxyFactory classes have a tendency to confuse it.
699520SN/A    try:
709665Sandreas.hansson@arm.com        return issubclass(cls, m5.objects.AbstractMemory) and \
719665Sandreas.hansson@arm.com            not cls.abstract
729520SN/A    except TypeError:
739520SN/A        return False
749520SN/A
759520SN/Adef get(name):
769665Sandreas.hansson@arm.com    """Get a memory class from a user provided class name or alias."""
779520SN/A
789665Sandreas.hansson@arm.com    real_name = _mem_aliases.get(name, name)
799520SN/A
809520SN/A    try:
819665Sandreas.hansson@arm.com        mem_class = _mem_classes[real_name]
829665Sandreas.hansson@arm.com        return mem_class
839520SN/A    except KeyError:
849665Sandreas.hansson@arm.com        print "%s is not a valid memory controller." % (name,)
859520SN/A        sys.exit(1)
869520SN/A
879665Sandreas.hansson@arm.comdef print_mem_list():
889665Sandreas.hansson@arm.com    """Print a list of available memory classes including their aliases."""
899520SN/A
909665Sandreas.hansson@arm.com    print "Available memory classes:"
919520SN/A    doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t")
929665Sandreas.hansson@arm.com    for name, cls in _mem_classes.items():
939520SN/A        print "\t%s" % name
949520SN/A
959520SN/A        # Try to extract the class documentation from the class help
969520SN/A        # string.
979520SN/A        doc = inspect.getdoc(cls)
989520SN/A        if doc:
999520SN/A            for line in doc_wrapper.wrap(doc):
1009520SN/A                print line
1019520SN/A
1029665Sandreas.hansson@arm.com    if _mem_aliases:
1039665Sandreas.hansson@arm.com        print "\nMemory aliases:"
1049665Sandreas.hansson@arm.com        for alias, target in _mem_aliases.items():
1059520SN/A            print "\t%s => %s" % (alias, target)
1069520SN/A
1079665Sandreas.hansson@arm.comdef mem_names():
1089665Sandreas.hansson@arm.com    """Return a list of valid memory names."""
1099665Sandreas.hansson@arm.com    return _mem_classes.keys() + _mem_aliases.keys()
1109520SN/A
1119665Sandreas.hansson@arm.com# Add all memory controllers in the object hierarchy.
1129665Sandreas.hansson@arm.comfor name, cls in inspect.getmembers(m5.objects, is_mem_class):
1139665Sandreas.hansson@arm.com    _mem_classes[name] = cls
1149520SN/A
1159665Sandreas.hansson@arm.comfor alias, target in _mem_aliases_all:
1169520SN/A    if isinstance(target, tuple):
1179665Sandreas.hansson@arm.com        # Some aliases contain a list of memory controller models
1189665Sandreas.hansson@arm.com        # sorted in priority order. Use the first target that's
1199665Sandreas.hansson@arm.com        # available.
1209520SN/A        for t in target:
1219665Sandreas.hansson@arm.com            if t in _mem_classes:
1229665Sandreas.hansson@arm.com                _mem_aliases[alias] = t
1239520SN/A                break
1249665Sandreas.hansson@arm.com    elif target in _mem_classes:
1259520SN/A        # Normal alias
1269665Sandreas.hansson@arm.com        _mem_aliases[alias] = target
1279836Sandreas.hansson@arm.com
1289836Sandreas.hansson@arm.comdef config_mem(options, system):
1299836Sandreas.hansson@arm.com    """
1309836Sandreas.hansson@arm.com    Create the memory controllers based on the options and attach them.
1319836Sandreas.hansson@arm.com
1329836Sandreas.hansson@arm.com    If requested, we make a multi-channel configuration of the
1339836Sandreas.hansson@arm.com    selected memory controller class by creating multiple instances of
1349836Sandreas.hansson@arm.com    the specific class. The individual controllers have their
1359836Sandreas.hansson@arm.com    parameters set such that the address range is interleaved between
1369836Sandreas.hansson@arm.com    them.
1379836Sandreas.hansson@arm.com    """
1389836Sandreas.hansson@arm.com
1399836Sandreas.hansson@arm.com    nbr_mem_ctrls = options.mem_channels
1409836Sandreas.hansson@arm.com    import math
1419836Sandreas.hansson@arm.com    from m5.util import fatal
1429836Sandreas.hansson@arm.com    intlv_bits = int(math.log(nbr_mem_ctrls, 2))
1439836Sandreas.hansson@arm.com    if 2 ** intlv_bits != nbr_mem_ctrls:
1449836Sandreas.hansson@arm.com        fatal("Number of memory channels must be a power of 2")
1459836Sandreas.hansson@arm.com    cls = get(options.mem_type)
1469836Sandreas.hansson@arm.com    mem_ctrls = []
1479836Sandreas.hansson@arm.com
1489836Sandreas.hansson@arm.com    # The default behaviour is to interleave on cache line granularity
1499836Sandreas.hansson@arm.com    cache_line_bit = int(math.log(system.cache_line_size.value, 2)) - 1
1509836Sandreas.hansson@arm.com    intlv_low_bit = cache_line_bit
1519836Sandreas.hansson@arm.com
1529836Sandreas.hansson@arm.com    # For every range (most systems will only have one), create an
1539836Sandreas.hansson@arm.com    # array of controllers and set their parameters to match their
1549836Sandreas.hansson@arm.com    # address mapping in the case of a DRAM
1559836Sandreas.hansson@arm.com    for r in system.mem_ranges:
1569836Sandreas.hansson@arm.com        for i in xrange(nbr_mem_ctrls):
1579836Sandreas.hansson@arm.com            # Create an instance so we can figure out the address
1589836Sandreas.hansson@arm.com            # mapping and row-buffer size
1599836Sandreas.hansson@arm.com            ctrl = cls()
1609836Sandreas.hansson@arm.com
1619836Sandreas.hansson@arm.com            # Only do this for DRAMs
1629836Sandreas.hansson@arm.com            if issubclass(cls, m5.objects.SimpleDRAM):
1639836Sandreas.hansson@arm.com                # Inform each controller how many channels to account
1649836Sandreas.hansson@arm.com                # for
1659836Sandreas.hansson@arm.com                ctrl.channels = nbr_mem_ctrls
1669836Sandreas.hansson@arm.com
1679836Sandreas.hansson@arm.com                # If the channel bits are appearing after the column
1689836Sandreas.hansson@arm.com                # bits, we need to add the appropriate number of bits
1699836Sandreas.hansson@arm.com                # for the row buffer size
1709836Sandreas.hansson@arm.com                if ctrl.addr_mapping.value == 'RaBaChCo':
1719836Sandreas.hansson@arm.com                    # This computation only really needs to happen
1729836Sandreas.hansson@arm.com                    # once, but as we rely on having an instance we
1739836Sandreas.hansson@arm.com                    # end up having to repeat it for each and every
1749836Sandreas.hansson@arm.com                    # one
1759836Sandreas.hansson@arm.com                    rowbuffer_size = ctrl.device_rowbuffer_size.value * \
1769836Sandreas.hansson@arm.com                        ctrl.devices_per_rank.value
1779836Sandreas.hansson@arm.com
1789836Sandreas.hansson@arm.com                    intlv_low_bit = int(math.log(rowbuffer_size, 2)) - 1
1799836Sandreas.hansson@arm.com
1809836Sandreas.hansson@arm.com            # We got all we need to configure the appropriate address
1819836Sandreas.hansson@arm.com            # range
1829836Sandreas.hansson@arm.com            ctrl.range = m5.objects.AddrRange(r.start, size = r.size(),
1839836Sandreas.hansson@arm.com                                              intlvHighBit = \
1849836Sandreas.hansson@arm.com                                                  intlv_low_bit + intlv_bits,
1859836Sandreas.hansson@arm.com                                              intlvBits = intlv_bits,
1869836Sandreas.hansson@arm.com                                              intlvMatch = i)
1879836Sandreas.hansson@arm.com            mem_ctrls.append(ctrl)
1889836Sandreas.hansson@arm.com
1899836Sandreas.hansson@arm.com    system.mem_ctrls = mem_ctrls
1909836Sandreas.hansson@arm.com
1919836Sandreas.hansson@arm.com    # Connect the controllers to the membus
19210041Snilay@cs.wisc.edu    for i in xrange(len(system.mem_ctrls)):
1939836Sandreas.hansson@arm.com        system.mem_ctrls[i].port = system.membus.master
194