111923Sandreas.sandberg@arm.com# Copyright (c) 2016 ARM Limited 211923Sandreas.sandberg@arm.com# All rights reserved. 311923Sandreas.sandberg@arm.com# 411923Sandreas.sandberg@arm.com# The license below extends only to copyright in the software and shall 511923Sandreas.sandberg@arm.com# not be construed as granting a license to any other intellectual 611923Sandreas.sandberg@arm.com# property including but not limited to intellectual property relating 711923Sandreas.sandberg@arm.com# to a hardware implementation of the functionality of the software 811923Sandreas.sandberg@arm.com# licensed hereunder. You may use the software subject to the license 911923Sandreas.sandberg@arm.com# terms below provided that you ensure that this notice is replicated 1011923Sandreas.sandberg@arm.com# unmodified and in its entirety in all distributions of the software, 1111923Sandreas.sandberg@arm.com# modified or unmodified, in source code or in binary form. 1211923Sandreas.sandberg@arm.com# 136654Snate@binkert.org# Copyright (c) 2008-2009 The Hewlett-Packard Development Company 146654Snate@binkert.org# Copyright (c) 2004-2006 The Regents of The University of Michigan 155467Snate@binkert.org# All rights reserved. 165467Snate@binkert.org# 175467Snate@binkert.org# Redistribution and use in source and binary forms, with or without 185467Snate@binkert.org# modification, are permitted provided that the following conditions are 195467Snate@binkert.org# met: redistributions of source code must retain the above copyright 205467Snate@binkert.org# notice, this list of conditions and the following disclaimer; 215467Snate@binkert.org# redistributions in binary form must reproduce the above copyright 225467Snate@binkert.org# notice, this list of conditions and the following disclaimer in the 235467Snate@binkert.org# documentation and/or other materials provided with the distribution; 245467Snate@binkert.org# neither the name of the copyright holders nor the names of its 255467Snate@binkert.org# contributors may be used to endorse or promote products derived from 265467Snate@binkert.org# this software without specific prior written permission. 275467Snate@binkert.org# 285467Snate@binkert.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295467Snate@binkert.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 305467Snate@binkert.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 315467Snate@binkert.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 325467Snate@binkert.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 335467Snate@binkert.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 345467Snate@binkert.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 355467Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 365467Snate@binkert.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 375467Snate@binkert.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 385467Snate@binkert.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395467Snate@binkert.org# 405467Snate@binkert.org# Authors: Nathan Binkert 415467Snate@binkert.org 4212563Sgabeblack@google.comfrom __future__ import print_function 4312563Sgabeblack@google.com 446654Snate@binkert.orgimport os 456654Snate@binkert.orgimport re 466654Snate@binkert.orgimport sys 476654Snate@binkert.org 4813714Sandreas.sandberg@arm.comfrom . import convert 4913714Sandreas.sandberg@arm.comfrom . import jobfile 506654Snate@binkert.org 5113714Sandreas.sandberg@arm.comfrom .attrdict import attrdict, multiattrdict, optiondict 5213714Sandreas.sandberg@arm.comfrom .code_formatter import code_formatter 5313714Sandreas.sandberg@arm.comfrom .multidict import multidict 5413714Sandreas.sandberg@arm.comfrom .smartdict import SmartDict 5513714Sandreas.sandberg@arm.comfrom .sorteddict import SortedDict 565873Snate@binkert.org 576654Snate@binkert.org# panic() should be called when something happens that should never 586654Snate@binkert.org# ever happen regardless of what the user does (i.e., an acutal m5 596654Snate@binkert.org# bug). 606654Snate@binkert.orgdef panic(fmt, *args): 6112563Sgabeblack@google.com print('panic:', fmt % args, file=sys.stderr) 626654Snate@binkert.org sys.exit(1) 636654Snate@binkert.org 646654Snate@binkert.org# fatal() should be called when the simulation cannot continue due to 656654Snate@binkert.org# some condition that is the user's fault (bad configuration, invalid 666654Snate@binkert.org# arguments, etc.) and not a simulator bug. 676654Snate@binkert.orgdef fatal(fmt, *args): 6812563Sgabeblack@google.com print('fatal:', fmt % args, file=sys.stderr) 696654Snate@binkert.org sys.exit(1) 706654Snate@binkert.org 719528Ssascha.bischoff@arm.com# warn() should be called when the user should be warned about some condition 729528Ssascha.bischoff@arm.com# that may or may not be the user's fault, but that they should be made aware 739528Ssascha.bischoff@arm.com# of as it may affect the simulation or results. 749528Ssascha.bischoff@arm.comdef warn(fmt, *args): 7512563Sgabeblack@google.com print('warn:', fmt % args, file=sys.stderr) 769528Ssascha.bischoff@arm.com 779528Ssascha.bischoff@arm.com# inform() should be called when the user should be informed about some 789528Ssascha.bischoff@arm.com# condition that they may be interested in. 799528Ssascha.bischoff@arm.comdef inform(fmt, *args): 8012563Sgabeblack@google.com print('info:', fmt % args, file=sys.stdout) 819528Ssascha.bischoff@arm.com 826654Snate@binkert.orgclass Singleton(type): 836654Snate@binkert.org def __call__(cls, *args, **kwargs): 846654Snate@binkert.org if hasattr(cls, '_instance'): 856654Snate@binkert.org return cls._instance 866654Snate@binkert.org 876654Snate@binkert.org cls._instance = super(Singleton, cls).__call__(*args, **kwargs) 886654Snate@binkert.org return cls._instance 896654Snate@binkert.org 906654Snate@binkert.orgdef addToPath(path): 916654Snate@binkert.org """Prepend given directory to system module search path. We may not 926654Snate@binkert.org need this anymore if we can structure our config library more like a 936654Snate@binkert.org Python package.""" 946654Snate@binkert.org 956654Snate@binkert.org # if it's a relative path and we know what directory the current 966654Snate@binkert.org # python script is in, make the path relative to that directory. 976654Snate@binkert.org if not os.path.isabs(path) and sys.path[0]: 986654Snate@binkert.org path = os.path.join(sys.path[0], path) 996654Snate@binkert.org path = os.path.realpath(path) 1006654Snate@binkert.org # sys.path[0] should always refer to the current script's directory, 1016654Snate@binkert.org # so place the new dir right after that. 1026654Snate@binkert.org sys.path.insert(1, path) 1036654Snate@binkert.org 1046654Snate@binkert.org# Apply method to object. 1056654Snate@binkert.org# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>) 1066654Snate@binkert.orgdef applyMethod(obj, meth, *args, **kwargs): 1076654Snate@binkert.org return getattr(obj, meth)(*args, **kwargs) 1086654Snate@binkert.org 1096654Snate@binkert.org# If the first argument is an (non-sequence) object, apply the named 1106654Snate@binkert.org# method with the given arguments. If the first argument is a 1116654Snate@binkert.org# sequence, apply the method to each element of the sequence (a la 1126654Snate@binkert.org# 'map'). 1136654Snate@binkert.orgdef applyOrMap(objOrSeq, meth, *args, **kwargs): 1146654Snate@binkert.org if not isinstance(objOrSeq, (list, tuple)): 1156654Snate@binkert.org return applyMethod(objOrSeq, meth, *args, **kwargs) 1166654Snate@binkert.org else: 1176654Snate@binkert.org return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq] 1186654Snate@binkert.org 1196654Snate@binkert.orgdef compareVersions(v1, v2): 1206654Snate@binkert.org """helper function: compare arrays or strings of version numbers. 1216654Snate@binkert.org E.g., compare_version((1,3,25), (1,4,1)') 1226654Snate@binkert.org returns -1, 0, 1 if v1 is <, ==, > v2 1236654Snate@binkert.org """ 1246654Snate@binkert.org def make_version_list(v): 1256654Snate@binkert.org if isinstance(v, (list,tuple)): 1266654Snate@binkert.org return v 1276654Snate@binkert.org elif isinstance(v, str): 1286654Snate@binkert.org return map(lambda x: int(re.match('\d+', x).group()), v.split('.')) 1296654Snate@binkert.org else: 13013663Sandreas.sandberg@arm.com raise TypeError() 1316654Snate@binkert.org 1326654Snate@binkert.org v1 = make_version_list(v1) 1336654Snate@binkert.org v2 = make_version_list(v2) 1346654Snate@binkert.org # Compare corresponding elements of lists 1356654Snate@binkert.org for n1,n2 in zip(v1, v2): 1366654Snate@binkert.org if n1 < n2: return -1 1376654Snate@binkert.org if n1 > n2: return 1 1386654Snate@binkert.org # all corresponding values are equal... see if one has extra values 1396654Snate@binkert.org if len(v1) < len(v2): return -1 1406654Snate@binkert.org if len(v1) > len(v2): return 1 1416654Snate@binkert.org return 0 1426654Snate@binkert.org 1436654Snate@binkert.orgdef crossproduct(items): 1446654Snate@binkert.org if len(items) == 1: 1456654Snate@binkert.org for i in items[0]: 1466654Snate@binkert.org yield (i,) 1476654Snate@binkert.org else: 1486654Snate@binkert.org for i in items[0]: 1496654Snate@binkert.org for j in crossproduct(items[1:]): 1506654Snate@binkert.org yield (i,) + j 1516654Snate@binkert.org 1526654Snate@binkert.orgdef flatten(items): 1536654Snate@binkert.org while items: 1546654Snate@binkert.org item = items.pop(0) 1556654Snate@binkert.org if isinstance(item, (list, tuple)): 1566654Snate@binkert.org items[0:0] = item 1576654Snate@binkert.org else: 1586654Snate@binkert.org yield item 1596654Snate@binkert.org 1606654Snate@binkert.org# force scalars to one-element lists for uniformity 1616654Snate@binkert.orgdef makeList(objOrList): 1626654Snate@binkert.org if isinstance(objOrList, list): 1636654Snate@binkert.org return objOrList 1646654Snate@binkert.org return [objOrList] 1656654Snate@binkert.org 1666654Snate@binkert.orgdef printList(items, indent=4): 1675873Snate@binkert.org line = ' ' * indent 1685873Snate@binkert.org for i,item in enumerate(items): 1695873Snate@binkert.org if len(line) + len(item) > 76: 17012563Sgabeblack@google.com print(line) 1715873Snate@binkert.org line = ' ' * indent 1725873Snate@binkert.org 1735873Snate@binkert.org if i < len(items) - 1: 1745873Snate@binkert.org line += '%s, ' % item 1755873Snate@binkert.org else: 1765873Snate@binkert.org line += item 17712563Sgabeblack@google.com print(line) 1786654Snate@binkert.org 1796654Snate@binkert.orgdef readCommand(cmd, **kwargs): 1806654Snate@binkert.org """run the command cmd, read the results and return them 1816654Snate@binkert.org this is sorta like `cmd` in shell""" 1826654Snate@binkert.org from subprocess import Popen, PIPE, STDOUT 1836654Snate@binkert.org 1846654Snate@binkert.org if isinstance(cmd, str): 1856654Snate@binkert.org cmd = cmd.split() 1866654Snate@binkert.org 1876654Snate@binkert.org no_exception = 'exception' in kwargs 1886654Snate@binkert.org exception = kwargs.pop('exception', None) 18911320Ssteve.reinhardt@amd.com 1906654Snate@binkert.org kwargs.setdefault('shell', False) 1916654Snate@binkert.org kwargs.setdefault('stdout', PIPE) 1926654Snate@binkert.org kwargs.setdefault('stderr', STDOUT) 1936654Snate@binkert.org kwargs.setdefault('close_fds', True) 1946654Snate@binkert.org try: 1956654Snate@binkert.org subp = Popen(cmd, **kwargs) 19613663Sandreas.sandberg@arm.com except Exception as e: 1976654Snate@binkert.org if no_exception: 1986654Snate@binkert.org return exception 1996654Snate@binkert.org raise 2006654Snate@binkert.org 2016654Snate@binkert.org return subp.communicate()[0] 2028453Snate@binkert.org 2038453Snate@binkert.orgdef makeDir(path): 2048453Snate@binkert.org """Make a directory if it doesn't exist. If the path does exist, 2058453Snate@binkert.org ensure that it is a directory""" 2068453Snate@binkert.org if os.path.exists(path): 2078453Snate@binkert.org if not os.path.isdir(path): 20813663Sandreas.sandberg@arm.com raise AttributeError("%s exists but is not directory" % path) 2098453Snate@binkert.org else: 2108453Snate@binkert.org os.mkdir(path) 21111923Sandreas.sandberg@arm.com 21211923Sandreas.sandberg@arm.comdef isInteractive(): 21311923Sandreas.sandberg@arm.com """Check if the simulator is run interactively or in a batch environment""" 21411923Sandreas.sandberg@arm.com 21511923Sandreas.sandberg@arm.com return sys.__stdin__.isatty() 216