MemConfig.py revision 9836
111308Santhony.gutierrez@amd.com# Copyright (c) 2013 ARM Limited 211308Santhony.gutierrez@amd.com# All rights reserved. 311308Santhony.gutierrez@amd.com# 411308Santhony.gutierrez@amd.com# The license below extends only to copyright in the software and shall 511308Santhony.gutierrez@amd.com# not be construed as granting a license to any other intellectual 611308Santhony.gutierrez@amd.com# property including but not limited to intellectual property relating 711308Santhony.gutierrez@amd.com# to a hardware implementation of the functionality of the software 811308Santhony.gutierrez@amd.com# licensed hereunder. You may use the software subject to the license 911308Santhony.gutierrez@amd.com# terms below provided that you ensure that this notice is replicated 1011308Santhony.gutierrez@amd.com# unmodified and in its entirety in all distributions of the software, 1111308Santhony.gutierrez@amd.com# modified or unmodified, in source code or in binary form. 1211308Santhony.gutierrez@amd.com# 1311308Santhony.gutierrez@amd.com# Redistribution and use in source and binary forms, with or without 1411308Santhony.gutierrez@amd.com# modification, are permitted provided that the following conditions are 1511308Santhony.gutierrez@amd.com# met: redistributions of source code must retain the above copyright 1611308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer; 1711308Santhony.gutierrez@amd.com# redistributions in binary form must reproduce the above copyright 1811308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer in the 1911308Santhony.gutierrez@amd.com# documentation and/or other materials provided with the distribution; 2011308Santhony.gutierrez@amd.com# neither the name of the copyright holders nor the names of its 2111308Santhony.gutierrez@amd.com# contributors may be used to endorse or promote products derived from 2211308Santhony.gutierrez@amd.com# this software without specific prior written permission. 2311308Santhony.gutierrez@amd.com# 2411308Santhony.gutierrez@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2511308Santhony.gutierrez@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2611308Santhony.gutierrez@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2711308Santhony.gutierrez@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2811308Santhony.gutierrez@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2911308Santhony.gutierrez@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3011308Santhony.gutierrez@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3111308Santhony.gutierrez@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3211308Santhony.gutierrez@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3311308Santhony.gutierrez@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3411308Santhony.gutierrez@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3511308Santhony.gutierrez@amd.com# 3611308Santhony.gutierrez@amd.com# Authors: Andreas Sandberg 3711308Santhony.gutierrez@amd.com# Andreas Hansson 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.comimport m5.objects 4011308Santhony.gutierrez@amd.comimport inspect 4111308Santhony.gutierrez@amd.comimport sys 4211308Santhony.gutierrez@amd.comfrom textwrap import TextWrapper 4311308Santhony.gutierrez@amd.com 4411308Santhony.gutierrez@amd.com# Dictionary of mapping names of real memory controller models to 4511308Santhony.gutierrez@amd.com# classes. 4611308Santhony.gutierrez@amd.com_mem_classes = {} 4711308Santhony.gutierrez@amd.com 4811308Santhony.gutierrez@amd.com# Memory aliases. We make sure they exist before we add them to the 4911308Santhony.gutierrez@amd.com# fina; list. A target may be specified as a tuple, in which case the 5011308Santhony.gutierrez@amd.com# first available memory controller model in the tuple will be used. 5111308Santhony.gutierrez@amd.com_mem_aliases_all = [ 5211308Santhony.gutierrez@amd.com ("simple_mem", "SimpleMemory"), 5312126Sspwilson2@wisc.edu ("ddr3_1600_x64", "DDR3_1600_x64"), 5412126Sspwilson2@wisc.edu ("lpddr2_s4_1066_x32", "LPDDR2_S4_1066_x32"), 5512126Sspwilson2@wisc.edu ("lpddr3_1600_x32", "LPDDR3_1600_x32"), 5611308Santhony.gutierrez@amd.com ("wio_200_x128", "WideIO_200_x128"), 5711308Santhony.gutierrez@amd.com ] 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com# Filtered list of aliases. Only aliases for existing memory 6011308Santhony.gutierrez@amd.com# controllers exist in this list. 6111308Santhony.gutierrez@amd.com_mem_aliases = {} 6211308Santhony.gutierrez@amd.com 6311308Santhony.gutierrez@amd.com 6411308Santhony.gutierrez@amd.comdef is_mem_class(cls): 6511308Santhony.gutierrez@amd.com """Determine if a class is a memory controller that can be instantiated""" 6611308Santhony.gutierrez@amd.com 6711308Santhony.gutierrez@amd.com # We can't use the normal inspect.isclass because the ParamFactory 6811308Santhony.gutierrez@amd.com # and ProxyFactory classes have a tendency to confuse it. 6911308Santhony.gutierrez@amd.com try: 7011308Santhony.gutierrez@amd.com return issubclass(cls, m5.objects.AbstractMemory) and \ 7111308Santhony.gutierrez@amd.com not cls.abstract 7211308Santhony.gutierrez@amd.com except TypeError: 7311308Santhony.gutierrez@amd.com return False 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.comdef get(name): 7611308Santhony.gutierrez@amd.com """Get a memory class from a user provided class name or alias.""" 7711308Santhony.gutierrez@amd.com 7811308Santhony.gutierrez@amd.com real_name = _mem_aliases.get(name, name) 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.com try: 8111308Santhony.gutierrez@amd.com mem_class = _mem_classes[real_name] 8211308Santhony.gutierrez@amd.com return mem_class 8311308Santhony.gutierrez@amd.com except KeyError: 8411308Santhony.gutierrez@amd.com print "%s is not a valid memory controller." % (name,) 8511308Santhony.gutierrez@amd.com sys.exit(1) 8611308Santhony.gutierrez@amd.com 8711308Santhony.gutierrez@amd.comdef print_mem_list(): 8811308Santhony.gutierrez@amd.com """Print a list of available memory classes including their aliases.""" 8911308Santhony.gutierrez@amd.com 9011308Santhony.gutierrez@amd.com print "Available memory classes:" 9111308Santhony.gutierrez@amd.com doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") 9211308Santhony.gutierrez@amd.com for name, cls in _mem_classes.items(): 9311308Santhony.gutierrez@amd.com print "\t%s" % name 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.com # Try to extract the class documentation from the class help 9611308Santhony.gutierrez@amd.com # string. 9711308Santhony.gutierrez@amd.com doc = inspect.getdoc(cls) 9811308Santhony.gutierrez@amd.com if doc: 9911308Santhony.gutierrez@amd.com for line in doc_wrapper.wrap(doc): 10011308Santhony.gutierrez@amd.com print line 10111308Santhony.gutierrez@amd.com 10211308Santhony.gutierrez@amd.com if _mem_aliases: 10311308Santhony.gutierrez@amd.com print "\nMemory aliases:" 10411308Santhony.gutierrez@amd.com for alias, target in _mem_aliases.items(): 10511308Santhony.gutierrez@amd.com print "\t%s => %s" % (alias, target) 10611308Santhony.gutierrez@amd.com 10711308Santhony.gutierrez@amd.comdef mem_names(): 10811308Santhony.gutierrez@amd.com """Return a list of valid memory names.""" 10911308Santhony.gutierrez@amd.com return _mem_classes.keys() + _mem_aliases.keys() 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com# Add all memory controllers in the object hierarchy. 11211308Santhony.gutierrez@amd.comfor name, cls in inspect.getmembers(m5.objects, is_mem_class): 11311308Santhony.gutierrez@amd.com _mem_classes[name] = cls 11411308Santhony.gutierrez@amd.com 11511308Santhony.gutierrez@amd.comfor alias, target in _mem_aliases_all: 11611308Santhony.gutierrez@amd.com if isinstance(target, tuple): 11711308Santhony.gutierrez@amd.com # Some aliases contain a list of memory controller models 11811308Santhony.gutierrez@amd.com # sorted in priority order. Use the first target that's 11911308Santhony.gutierrez@amd.com # available. 12011308Santhony.gutierrez@amd.com for t in target: 12111308Santhony.gutierrez@amd.com if t in _mem_classes: 12211308Santhony.gutierrez@amd.com _mem_aliases[alias] = t 12311308Santhony.gutierrez@amd.com break 12411308Santhony.gutierrez@amd.com elif target in _mem_classes: 12511308Santhony.gutierrez@amd.com # Normal alias 12611308Santhony.gutierrez@amd.com _mem_aliases[alias] = target 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.comdef config_mem(options, system): 12911308Santhony.gutierrez@amd.com """ 13011308Santhony.gutierrez@amd.com Create the memory controllers based on the options and attach them. 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com If requested, we make a multi-channel configuration of the 13311308Santhony.gutierrez@amd.com selected memory controller class by creating multiple instances of 13411308Santhony.gutierrez@amd.com the specific class. The individual controllers have their 13511308Santhony.gutierrez@amd.com parameters set such that the address range is interleaved between 13611308Santhony.gutierrez@amd.com them. 13711308Santhony.gutierrez@amd.com """ 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com nbr_mem_ctrls = options.mem_channels 14011308Santhony.gutierrez@amd.com import math 14111308Santhony.gutierrez@amd.com from m5.util import fatal 14211308Santhony.gutierrez@amd.com intlv_bits = int(math.log(nbr_mem_ctrls, 2)) 14311308Santhony.gutierrez@amd.com if 2 ** intlv_bits != nbr_mem_ctrls: 14411308Santhony.gutierrez@amd.com fatal("Number of memory channels must be a power of 2") 14511308Santhony.gutierrez@amd.com cls = get(options.mem_type) 14611308Santhony.gutierrez@amd.com mem_ctrls = [] 14711308Santhony.gutierrez@amd.com 14811308Santhony.gutierrez@amd.com # The default behaviour is to interleave on cache line granularity 14911308Santhony.gutierrez@amd.com cache_line_bit = int(math.log(system.cache_line_size.value, 2)) - 1 15011308Santhony.gutierrez@amd.com intlv_low_bit = cache_line_bit 15111308Santhony.gutierrez@amd.com 15211308Santhony.gutierrez@amd.com # For every range (most systems will only have one), create an 15311308Santhony.gutierrez@amd.com # array of controllers and set their parameters to match their 15411308Santhony.gutierrez@amd.com # address mapping in the case of a DRAM 15511308Santhony.gutierrez@amd.com for r in system.mem_ranges: 15611308Santhony.gutierrez@amd.com for i in xrange(nbr_mem_ctrls): 15711308Santhony.gutierrez@amd.com # Create an instance so we can figure out the address 15811308Santhony.gutierrez@amd.com # mapping and row-buffer size 15911308Santhony.gutierrez@amd.com ctrl = cls() 16011308Santhony.gutierrez@amd.com 16111308Santhony.gutierrez@amd.com # Only do this for DRAMs 16211308Santhony.gutierrez@amd.com if issubclass(cls, m5.objects.SimpleDRAM): 16311308Santhony.gutierrez@amd.com # Inform each controller how many channels to account 16411308Santhony.gutierrez@amd.com # for 16511308Santhony.gutierrez@amd.com ctrl.channels = nbr_mem_ctrls 16611308Santhony.gutierrez@amd.com 16711308Santhony.gutierrez@amd.com # If the channel bits are appearing after the column 16811308Santhony.gutierrez@amd.com # bits, we need to add the appropriate number of bits 16911308Santhony.gutierrez@amd.com # for the row buffer size 17011308Santhony.gutierrez@amd.com if ctrl.addr_mapping.value == 'RaBaChCo': 17111308Santhony.gutierrez@amd.com # This computation only really needs to happen 17211308Santhony.gutierrez@amd.com # once, but as we rely on having an instance we 17311308Santhony.gutierrez@amd.com # end up having to repeat it for each and every 17411308Santhony.gutierrez@amd.com # one 17511308Santhony.gutierrez@amd.com rowbuffer_size = ctrl.device_rowbuffer_size.value * \ 17611308Santhony.gutierrez@amd.com ctrl.devices_per_rank.value 17711308Santhony.gutierrez@amd.com 17811308Santhony.gutierrez@amd.com intlv_low_bit = int(math.log(rowbuffer_size, 2)) - 1 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.com # We got all we need to configure the appropriate address 18111308Santhony.gutierrez@amd.com # range 18211308Santhony.gutierrez@amd.com ctrl.range = m5.objects.AddrRange(r.start, size = r.size(), 18311308Santhony.gutierrez@amd.com intlvHighBit = \ 18411308Santhony.gutierrez@amd.com intlv_low_bit + intlv_bits, 18511308Santhony.gutierrez@amd.com intlvBits = intlv_bits, 18611308Santhony.gutierrez@amd.com intlvMatch = i) 18711308Santhony.gutierrez@amd.com mem_ctrls.append(ctrl) 18811308Santhony.gutierrez@amd.com 18911308Santhony.gutierrez@amd.com system.mem_ctrls = mem_ctrls 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.com # Connect the controllers to the membus 19211308Santhony.gutierrez@amd.com for i in xrange(nbr_mem_ctrls): 19311308Santhony.gutierrez@amd.com system.mem_ctrls[i].port = system.membus.master 19411308Santhony.gutierrez@amd.com