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