MemConfig.py revision 9836
12929Sktlim@umich.edu# Copyright (c) 2013 ARM Limited 22929Sktlim@umich.edu# All rights reserved. 32932Sktlim@umich.edu# 42929Sktlim@umich.edu# The license below extends only to copyright in the software and shall 52929Sktlim@umich.edu# not be construed as granting a license to any other intellectual 62929Sktlim@umich.edu# property including but not limited to intellectual property relating 72929Sktlim@umich.edu# to a hardware implementation of the functionality of the software 82929Sktlim@umich.edu# licensed hereunder. You may use the software subject to the license 92929Sktlim@umich.edu# terms below provided that you ensure that this notice is replicated 102929Sktlim@umich.edu# unmodified and in its entirety in all distributions of the software, 112929Sktlim@umich.edu# modified or unmodified, in source code or in binary form. 122929Sktlim@umich.edu# 132929Sktlim@umich.edu# Redistribution and use in source and binary forms, with or without 142929Sktlim@umich.edu# modification, are permitted provided that the following conditions are 152929Sktlim@umich.edu# met: redistributions of source code must retain the above copyright 162929Sktlim@umich.edu# notice, this list of conditions and the following disclaimer; 172929Sktlim@umich.edu# redistributions in binary form must reproduce the above copyright 182929Sktlim@umich.edu# notice, this list of conditions and the following disclaimer in the 192929Sktlim@umich.edu# documentation and/or other materials provided with the distribution; 202929Sktlim@umich.edu# neither the name of the copyright holders nor the names of its 212929Sktlim@umich.edu# contributors may be used to endorse or promote products derived from 222929Sktlim@umich.edu# this software without specific prior written permission. 232929Sktlim@umich.edu# 242929Sktlim@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 252929Sktlim@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 262929Sktlim@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 272929Sktlim@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 282932Sktlim@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 292932Sktlim@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 302932Sktlim@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 312929Sktlim@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 326007Ssteve.reinhardt@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 337735SAli.Saidi@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 342929Sktlim@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 352929Sktlim@umich.edu# 362929Sktlim@umich.edu# Authors: Andreas Sandberg 372929Sktlim@umich.edu# Andreas Hansson 382929Sktlim@umich.edu 392929Sktlim@umich.eduimport m5.objects 402929Sktlim@umich.eduimport inspect 418947Sandreas.hansson@arm.comimport sys 428947Sandreas.hansson@arm.comfrom textwrap import TextWrapper 438947Sandreas.hansson@arm.com 442929Sktlim@umich.edu# Dictionary of mapping names of real memory controller models to 452929Sktlim@umich.edu# classes. 462929Sktlim@umich.edu_mem_classes = {} 472929Sktlim@umich.edu 482929Sktlim@umich.edu# Memory aliases. We make sure they exist before we add them to the 492929Sktlim@umich.edu# fina; list. A target may be specified as a tuple, in which case the 506007Ssteve.reinhardt@amd.com# first available memory controller model in the tuple will be used. 516007Ssteve.reinhardt@amd.com_mem_aliases_all = [ 526007Ssteve.reinhardt@amd.com ("simple_mem", "SimpleMemory"), 536007Ssteve.reinhardt@amd.com ("ddr3_1600_x64", "DDR3_1600_x64"), 546007Ssteve.reinhardt@amd.com ("lpddr2_s4_1066_x32", "LPDDR2_S4_1066_x32"), 556007Ssteve.reinhardt@amd.com ("lpddr3_1600_x32", "LPDDR3_1600_x32"), 566007Ssteve.reinhardt@amd.com ("wio_200_x128", "WideIO_200_x128"), 576007Ssteve.reinhardt@amd.com ] 586007Ssteve.reinhardt@amd.com 596007Ssteve.reinhardt@amd.com# Filtered list of aliases. Only aliases for existing memory 606007Ssteve.reinhardt@amd.com# controllers exist in this list. 616007Ssteve.reinhardt@amd.com_mem_aliases = {} 626007Ssteve.reinhardt@amd.com 636007Ssteve.reinhardt@amd.com 646007Ssteve.reinhardt@amd.comdef is_mem_class(cls): 656007Ssteve.reinhardt@amd.com """Determine if a class is a memory controller that can be instantiated""" 669435SAndreas.Sandberg@ARM.com 679435SAndreas.Sandberg@ARM.com # We can't use the normal inspect.isclass because the ParamFactory 689435SAndreas.Sandberg@ARM.com # and ProxyFactory classes have a tendency to confuse it. 696007Ssteve.reinhardt@amd.com try: 706007Ssteve.reinhardt@amd.com return issubclass(cls, m5.objects.AbstractMemory) and \ 716007Ssteve.reinhardt@amd.com not cls.abstract 726007Ssteve.reinhardt@amd.com except TypeError: 736007Ssteve.reinhardt@amd.com return False 746007Ssteve.reinhardt@amd.com 756007Ssteve.reinhardt@amd.comdef get(name): 766007Ssteve.reinhardt@amd.com """Get a memory class from a user provided class name or alias.""" 776007Ssteve.reinhardt@amd.com 786007Ssteve.reinhardt@amd.com real_name = _mem_aliases.get(name, name) 792929Sktlim@umich.edu 802929Sktlim@umich.edu try: 812929Sktlim@umich.edu mem_class = _mem_classes[real_name] 826007Ssteve.reinhardt@amd.com return mem_class 836007Ssteve.reinhardt@amd.com except KeyError: 846007Ssteve.reinhardt@amd.com print "%s is not a valid memory controller." % (name,) 859781Sandreas.hansson@arm.com sys.exit(1) 866007Ssteve.reinhardt@amd.com 876007Ssteve.reinhardt@amd.comdef print_mem_list(): 882929Sktlim@umich.edu """Print a list of available memory classes including their aliases.""" 892929Sktlim@umich.edu 902929Sktlim@umich.edu print "Available memory classes:" 912929Sktlim@umich.edu doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") 922929Sktlim@umich.edu for name, cls in _mem_classes.items(): 936011Ssteve.reinhardt@amd.com print "\t%s" % name 946007Ssteve.reinhardt@amd.com 956007Ssteve.reinhardt@amd.com # Try to extract the class documentation from the class help 966007Ssteve.reinhardt@amd.com # string. 976007Ssteve.reinhardt@amd.com doc = inspect.getdoc(cls) 986007Ssteve.reinhardt@amd.com if doc: 996007Ssteve.reinhardt@amd.com for line in doc_wrapper.wrap(doc): 1006007Ssteve.reinhardt@amd.com print line 1016007Ssteve.reinhardt@amd.com 1026007Ssteve.reinhardt@amd.com if _mem_aliases: 1036007Ssteve.reinhardt@amd.com print "\nMemory aliases:" 1046007Ssteve.reinhardt@amd.com for alias, target in _mem_aliases.items(): 1056007Ssteve.reinhardt@amd.com print "\t%s => %s" % (alias, target) 1066007Ssteve.reinhardt@amd.com 10710384SCurtis.Dunham@arm.comdef mem_names(): 10810384SCurtis.Dunham@arm.com """Return a list of valid memory names.""" 10910384SCurtis.Dunham@arm.com return _mem_classes.keys() + _mem_aliases.keys() 11010384SCurtis.Dunham@arm.com 1116007Ssteve.reinhardt@amd.com# Add all memory controllers in the object hierarchy. 1129781Sandreas.hansson@arm.comfor name, cls in inspect.getmembers(m5.objects, is_mem_class): 1139781Sandreas.hansson@arm.com _mem_classes[name] = cls 1149781Sandreas.hansson@arm.com 1159781Sandreas.hansson@arm.comfor alias, target in _mem_aliases_all: 1167735SAli.Saidi@ARM.com if isinstance(target, tuple): 1176011Ssteve.reinhardt@amd.com # Some aliases contain a list of memory controller models 1186007Ssteve.reinhardt@amd.com # sorted in priority order. Use the first target that's 1199781Sandreas.hansson@arm.com # available. 1206007Ssteve.reinhardt@amd.com for t in target: 1216007Ssteve.reinhardt@amd.com if t in _mem_classes: 1227735SAli.Saidi@ARM.com _mem_aliases[alias] = t 1237735SAli.Saidi@ARM.com break 1247735SAli.Saidi@ARM.com elif target in _mem_classes: 1257735SAli.Saidi@ARM.com # Normal alias 1267735SAli.Saidi@ARM.com _mem_aliases[alias] = target 1277735SAli.Saidi@ARM.com 1287735SAli.Saidi@ARM.comdef config_mem(options, system): 1297735SAli.Saidi@ARM.com """ 1307735SAli.Saidi@ARM.com Create the memory controllers based on the options and attach them. 1317735SAli.Saidi@ARM.com 1327735SAli.Saidi@ARM.com If requested, we make a multi-channel configuration of the 1337735SAli.Saidi@ARM.com selected memory controller class by creating multiple instances of 1347735SAli.Saidi@ARM.com the specific class. The individual controllers have their 1357735SAli.Saidi@ARM.com parameters set such that the address range is interleaved between 1366007Ssteve.reinhardt@amd.com them. 1378599Ssteve.reinhardt@amd.com """ 1388599Ssteve.reinhardt@amd.com 1398599Ssteve.reinhardt@amd.com nbr_mem_ctrls = options.mem_channels 1406007Ssteve.reinhardt@amd.com import math 1416011Ssteve.reinhardt@amd.com from m5.util import fatal 1426007Ssteve.reinhardt@amd.com intlv_bits = int(math.log(nbr_mem_ctrls, 2)) 1436007Ssteve.reinhardt@amd.com if 2 ** intlv_bits != nbr_mem_ctrls: 1446007Ssteve.reinhardt@amd.com fatal("Number of memory channels must be a power of 2") 1456007Ssteve.reinhardt@amd.com cls = get(options.mem_type) 1466007Ssteve.reinhardt@amd.com mem_ctrls = [] 1476007Ssteve.reinhardt@amd.com 1489781Sandreas.hansson@arm.com # The default behaviour is to interleave on cache line granularity 1499781Sandreas.hansson@arm.com cache_line_bit = int(math.log(system.cache_line_size.value, 2)) - 1 1509781Sandreas.hansson@arm.com intlv_low_bit = cache_line_bit 1519781Sandreas.hansson@arm.com 1526007Ssteve.reinhardt@amd.com # For every range (most systems will only have one), create an 1536007Ssteve.reinhardt@amd.com # array of controllers and set their parameters to match their 1546007Ssteve.reinhardt@amd.com # address mapping in the case of a DRAM 1559781Sandreas.hansson@arm.com for r in system.mem_ranges: 1569781Sandreas.hansson@arm.com for i in xrange(nbr_mem_ctrls): 1579781Sandreas.hansson@arm.com # Create an instance so we can figure out the address 1589781Sandreas.hansson@arm.com # mapping and row-buffer size 15910384SCurtis.Dunham@arm.com ctrl = cls() 16010384SCurtis.Dunham@arm.com 16110384SCurtis.Dunham@arm.com # Only do this for DRAMs 1629781Sandreas.hansson@arm.com if issubclass(cls, m5.objects.SimpleDRAM): 1636008Ssteve.reinhardt@amd.com # Inform each controller how many channels to account 1646008Ssteve.reinhardt@amd.com # for 1656008Ssteve.reinhardt@amd.com ctrl.channels = nbr_mem_ctrls 1666008Ssteve.reinhardt@amd.com 1676008Ssteve.reinhardt@amd.com # If the channel bits are appearing after the column 1689401SAndreas.Sandberg@ARM.com # bits, we need to add the appropriate number of bits 1699781Sandreas.hansson@arm.com # for the row buffer size 1709781Sandreas.hansson@arm.com if ctrl.addr_mapping.value == 'RaBaChCo': 1716008Ssteve.reinhardt@amd.com # This computation only really needs to happen 1729781Sandreas.hansson@arm.com # once, but as we rely on having an instance we 1736007Ssteve.reinhardt@amd.com # end up having to repeat it for each and every 1746007Ssteve.reinhardt@amd.com # one 1756007Ssteve.reinhardt@amd.com rowbuffer_size = ctrl.device_rowbuffer_size.value * \ 1766007Ssteve.reinhardt@amd.com ctrl.devices_per_rank.value 1779781Sandreas.hansson@arm.com 1786007Ssteve.reinhardt@amd.com intlv_low_bit = int(math.log(rowbuffer_size, 2)) - 1 1796007Ssteve.reinhardt@amd.com 1802929Sktlim@umich.edu # We got all we need to configure the appropriate address 1812929Sktlim@umich.edu # range 1822929Sktlim@umich.edu ctrl.range = m5.objects.AddrRange(r.start, size = r.size(), 1832929Sktlim@umich.edu intlvHighBit = \ 1846007Ssteve.reinhardt@amd.com intlv_low_bit + intlv_bits, 1856007Ssteve.reinhardt@amd.com intlvBits = intlv_bits, 1862929Sktlim@umich.edu intlvMatch = i) 1872929Sktlim@umich.edu mem_ctrls.append(ctrl) 1886007Ssteve.reinhardt@amd.com 1892929Sktlim@umich.edu system.mem_ctrls = mem_ctrls 1902929Sktlim@umich.edu 1918947Sandreas.hansson@arm.com # Connect the controllers to the membus 1928947Sandreas.hansson@arm.com for i in xrange(nbr_mem_ctrls): 1938947Sandreas.hansson@arm.com system.mem_ctrls[i].port = system.membus.master 1948947Sandreas.hansson@arm.com