convert.py revision 12251
11736SN/A# Copyright (c) 2005 The Regents of The University of Michigan
27778Sgblack@eecs.umich.edu# Copyright (c) 2010 Advanced Micro Devices, Inc.
31736SN/A# All rights reserved.
41736SN/A#
51736SN/A# Redistribution and use in source and binary forms, with or without
61736SN/A# modification, are permitted provided that the following conditions are
71736SN/A# met: redistributions of source code must retain the above copyright
81736SN/A# notice, this list of conditions and the following disclaimer;
91736SN/A# redistributions in binary form must reproduce the above copyright
101736SN/A# notice, this list of conditions and the following disclaimer in the
111736SN/A# documentation and/or other materials provided with the distribution;
121736SN/A# neither the name of the copyright holders nor the names of its
131736SN/A# contributors may be used to endorse or promote products derived from
141736SN/A# this software without specific prior written permission.
151736SN/A#
161736SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171736SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181736SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191736SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201736SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211736SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221736SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231736SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241736SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251736SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261736SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A#
282665SN/A# Authors: Nathan Binkert
297778Sgblack@eecs.umich.edu#          Gabe Black
301736SN/A
311519SN/A# metric prefixes
3212247Sgabeblack@google.comatto  = 1.0e-18
3312247Sgabeblack@google.comfemto = 1.0e-15
3412247Sgabeblack@google.compico  = 1.0e-12
3512247Sgabeblack@google.comnano  = 1.0e-9
3612247Sgabeblack@google.commicro = 1.0e-6
3712247Sgabeblack@google.commilli = 1.0e-3
3812247Sgabeblack@google.com
3912247Sgabeblack@google.comkilo = 1.0e3
4012247Sgabeblack@google.commega = 1.0e6
4112247Sgabeblack@google.comgiga = 1.0e9
4212247Sgabeblack@google.comtera = 1.0e12
4312247Sgabeblack@google.competa = 1.0e15
441519SN/Aexa  = 1.0e18
451519SN/A
461519SN/A# power of 2 prefixes
471519SN/Akibi = 1024
481519SN/Amebi = kibi * 1024
491519SN/Agibi = mebi * 1024
501519SN/Atebi = gibi * 1024
511519SN/Apebi = tebi * 1024
521519SN/Aexbi = pebi * 1024
531519SN/A
5412247Sgabeblack@google.commetric_prefixes = {
5512247Sgabeblack@google.com    'Ei': exbi,
5612247Sgabeblack@google.com    'E': exa,
5712247Sgabeblack@google.com    'Pi': pebi,
5812247Sgabeblack@google.com    'P': peta,
5912247Sgabeblack@google.com    'Ti': tebi,
6012247Sgabeblack@google.com    'T': tera,
6112247Sgabeblack@google.com    'Gi': gibi,
6212247Sgabeblack@google.com    'G': giga,
6312247Sgabeblack@google.com    'M': mega,
6412247Sgabeblack@google.com    'ki': kibi,
6512247Sgabeblack@google.com    'k': kilo,
6612247Sgabeblack@google.com    'Mi': mebi,
6712247Sgabeblack@google.com    'm': milli,
6812247Sgabeblack@google.com    'u': micro,
6912247Sgabeblack@google.com    'n': nano,
7012247Sgabeblack@google.com    'p': pico,
7112247Sgabeblack@google.com    'f': femto,
7212247Sgabeblack@google.com    'a': atto,
7312247Sgabeblack@google.com}
7412247Sgabeblack@google.com
7512247Sgabeblack@google.combinary_prefixes = {
7612247Sgabeblack@google.com    'Ei': exbi,
7712247Sgabeblack@google.com    'E' : exbi,
7812247Sgabeblack@google.com    'Pi': pebi,
7912247Sgabeblack@google.com    'P' : pebi,
8012247Sgabeblack@google.com    'Ti': tebi,
8112247Sgabeblack@google.com    'T' : tebi,
8212247Sgabeblack@google.com    'Gi': gibi,
8312247Sgabeblack@google.com    'G' : gibi,
8412247Sgabeblack@google.com    'Mi': mebi,
8512247Sgabeblack@google.com    'M' : mebi,
8612247Sgabeblack@google.com    'ki': kibi,
8712247Sgabeblack@google.com    'k' : kibi,
8812247Sgabeblack@google.com}
8912247Sgabeblack@google.com
9012247Sgabeblack@google.comdef assertStr(value):
911519SN/A    if not isinstance(value, str):
921606SN/A        raise TypeError, "wrong type '%s' should be str" % type(value)
931606SN/A
9412247Sgabeblack@google.com
9512247Sgabeblack@google.com# memory size configuration stuff
9612247Sgabeblack@google.comdef toFloat(value, target_type='float', units=None, prefixes=[]):
9712247Sgabeblack@google.com    assertStr(value)
9812247Sgabeblack@google.com
9912247Sgabeblack@google.com    if units and not value.endswith(units):
10012247Sgabeblack@google.com        units = None
10112247Sgabeblack@google.com    if not units:
10212247Sgabeblack@google.com        try:
10312247Sgabeblack@google.com            return float(value)
10412247Sgabeblack@google.com        except ValueError:
10512247Sgabeblack@google.com            raise ValueError, "cannot convert '%s' to %s" % \
10612247Sgabeblack@google.com                    (value, target_type)
10712247Sgabeblack@google.com
10812247Sgabeblack@google.com    value = value[:-len(units)]
10912247Sgabeblack@google.com
11012247Sgabeblack@google.com    prefix = next((p for p in prefixes.keys() if value.endswith(p)), None)
11112247Sgabeblack@google.com    if not prefix:
1121606SN/A        return float(value)
11312247Sgabeblack@google.com    value = value[:-len(prefix)]
1141606SN/A
11512247Sgabeblack@google.com    return float(value) * prefixes[prefix]
11612247Sgabeblack@google.com
11712247Sgabeblack@google.comdef toMetricFloat(value, target_type='float', units=None):
11812247Sgabeblack@google.com    return toFloat(value, target_type, units, metric_prefixes)
11912247Sgabeblack@google.com
12012247Sgabeblack@google.comdef toBinaryFloat(value, target_type='float', units=None):
12112247Sgabeblack@google.com    return toFloat(value, target_type, units, binary_prefixes)
12212247Sgabeblack@google.com
12312247Sgabeblack@google.comdef toInteger(value, target_type='integer', units=None, prefixes=[]):
12412247Sgabeblack@google.com    value = toFloat(value, target_type, units, prefixes)
1251944SN/A    result = long(value)
1261606SN/A    if value != result:
12712247Sgabeblack@google.com        raise ValueError, "cannot convert '%s' to integer %s" % \
12812247Sgabeblack@google.com                (value, target_type)
1291519SN/A
1301606SN/A    return result
1311606SN/A
13212247Sgabeblack@google.comdef toMetricInteger(value, target_type='integer', units=None):
13312247Sgabeblack@google.com    return toInteger(value, target_type, units, metric_prefixes)
13412247Sgabeblack@google.com
13512247Sgabeblack@google.comdef toBinaryInteger(value, target_type='integer', units=None):
13612247Sgabeblack@google.com    return toInteger(value, target_type, units, binary_prefixes)
1371858SN/A
1381606SN/Adef toBool(value):
13912247Sgabeblack@google.com    assertStr(value)
1401606SN/A
1411606SN/A    value = value.lower()
14212247Sgabeblack@google.com    if value in ('true', 't', 'yes', 'y', '1'):
14312247Sgabeblack@google.com        return True
14412247Sgabeblack@google.com    if value in ('false', 'f', 'no', 'n', '0'):
14512247Sgabeblack@google.com        return False
1461858SN/A    return result
1471519SN/A
1481589SN/Adef toFrequency(value):
14912247Sgabeblack@google.com    return toMetricFloat(value, 'frequency', 'Hz')
1501519SN/A
1511589SN/Adef toLatency(value):
15212247Sgabeblack@google.com    return toMetricFloat(value, 'latency', 's')
1531606SN/A
1544167SN/Adef anyToLatency(value):
1551606SN/A    """result is a clock period"""
1561606SN/A    try:
15712247Sgabeblack@google.com        return 1 / toFrequency(value)
15812247Sgabeblack@google.com    except ValueError, ZeroDivisionError:
1591606SN/A        pass
1601606SN/A
1611606SN/A    try:
16212247Sgabeblack@google.com        return toLatency(value)
1631606SN/A    except ValueError:
1641606SN/A        pass
1651606SN/A
1661606SN/A    raise ValueError, "cannot convert '%s' to clock period" % value
1671606SN/A
1684167SN/Adef anyToFrequency(value):
1694167SN/A    """result is a clock period"""
1704167SN/A    try:
17112247Sgabeblack@google.com        return toFrequency(value)
1724167SN/A    except ValueError:
1734167SN/A        pass
1744167SN/A
1754167SN/A    try:
17612247Sgabeblack@google.com        return 1 / toLatency(value)
17712247Sgabeblack@google.com    except ValueError, ZeroDivisionError:
1784167SN/A        pass
1794167SN/A
1804167SN/A    raise ValueError, "cannot convert '%s' to clock period" % value
1811519SN/A
1821589SN/Adef toNetworkBandwidth(value):
18312247Sgabeblack@google.com    return toMetricFloat(value, 'network bandwidth', 'bps')
1841519SN/A
1851589SN/Adef toMemoryBandwidth(value):
18612247Sgabeblack@google.com    return toBinaryFloat(value, 'memory bandwidth', 'B/s')
1871519SN/A
1881589SN/Adef toMemorySize(value):
18912247Sgabeblack@google.com    return toBinaryInteger(value, 'memory size', 'B')
1907777Sgblack@eecs.umich.edu
1917777Sgblack@eecs.umich.edudef toIpAddress(value):
1927777Sgblack@eecs.umich.edu    if not isinstance(value, str):
1937777Sgblack@eecs.umich.edu        raise TypeError, "wrong type '%s' should be str" % type(value)
1947777Sgblack@eecs.umich.edu
1957777Sgblack@eecs.umich.edu    bytes = value.split('.')
1967777Sgblack@eecs.umich.edu    if len(bytes) != 4:
1977777Sgblack@eecs.umich.edu        raise ValueError, 'invalid ip address %s' % value
1987777Sgblack@eecs.umich.edu
1997777Sgblack@eecs.umich.edu    for byte in bytes:
2007777Sgblack@eecs.umich.edu        if not 0 <= int(byte) <= 0xff:
2017777Sgblack@eecs.umich.edu            raise ValueError, 'invalid ip address %s' % value
2027777Sgblack@eecs.umich.edu
2037777Sgblack@eecs.umich.edu    return (int(bytes[0]) << 24) | (int(bytes[1]) << 16) | \
2047777Sgblack@eecs.umich.edu           (int(bytes[2]) << 8)  | (int(bytes[3]) << 0)
2057777Sgblack@eecs.umich.edu
2067777Sgblack@eecs.umich.edudef toIpNetmask(value):
2077777Sgblack@eecs.umich.edu    if not isinstance(value, str):
2087777Sgblack@eecs.umich.edu        raise TypeError, "wrong type '%s' should be str" % type(value)
2097777Sgblack@eecs.umich.edu
2107777Sgblack@eecs.umich.edu    (ip, netmask) = value.split('/')
2117777Sgblack@eecs.umich.edu    ip = toIpAddress(ip)
2127777Sgblack@eecs.umich.edu    netmaskParts = netmask.split('.')
2137777Sgblack@eecs.umich.edu    if len(netmaskParts) == 1:
2147777Sgblack@eecs.umich.edu        if not 0 <= int(netmask) <= 32:
2157777Sgblack@eecs.umich.edu            raise ValueError, 'invalid netmask %s' % netmask
2167777Sgblack@eecs.umich.edu        return (ip, int(netmask))
2177777Sgblack@eecs.umich.edu    elif len(netmaskParts) == 4:
2187777Sgblack@eecs.umich.edu        netmaskNum = toIpAddress(netmask)
2197777Sgblack@eecs.umich.edu        if netmaskNum == 0:
2207777Sgblack@eecs.umich.edu            return (ip, 0)
2217777Sgblack@eecs.umich.edu        testVal = 0
2227777Sgblack@eecs.umich.edu        for i in range(32):
2237777Sgblack@eecs.umich.edu            testVal |= (1 << (31 - i))
2247777Sgblack@eecs.umich.edu            if testVal == netmaskNum:
2257777Sgblack@eecs.umich.edu                return (ip, i + 1)
2267777Sgblack@eecs.umich.edu        raise ValueError, 'invalid netmask %s' % netmask
2277777Sgblack@eecs.umich.edu    else:
2287777Sgblack@eecs.umich.edu        raise ValueError, 'invalid netmask %s' % netmask
2297777Sgblack@eecs.umich.edu
2307777Sgblack@eecs.umich.edudef toIpWithPort(value):
2317777Sgblack@eecs.umich.edu    if not isinstance(value, str):
2327777Sgblack@eecs.umich.edu        raise TypeError, "wrong type '%s' should be str" % type(value)
2337777Sgblack@eecs.umich.edu
2347777Sgblack@eecs.umich.edu    (ip, port) = value.split(':')
2357777Sgblack@eecs.umich.edu    ip = toIpAddress(ip)
2367777Sgblack@eecs.umich.edu    if not 0 <= int(port) <= 0xffff:
2377777Sgblack@eecs.umich.edu        raise ValueError, 'invalid port %s' % port
2387777Sgblack@eecs.umich.edu    return (ip, int(port))
2399827Sakash.bagdia@arm.com
2409827Sakash.bagdia@arm.comdef toVoltage(value):
24112247Sgabeblack@google.com    return toMetricFloat(value, 'voltage', 'V')
2429827Sakash.bagdia@arm.com
24310427Sandreas.hansson@arm.comdef toCurrent(value):
24412247Sgabeblack@google.com    return toMetricFloat(value, 'current', 'A')
24512251Sgabeblack@google.com
24612251Sgabeblack@google.comdef toEnergy(value):
24712251Sgabeblack@google.com    return toMetricFloat(value, 'energy', 'J')
248