params.py (13543:98421d757922) | params.py (13558:2a8d8f64d900) |
---|---|
1# Copyright (c) 2012-2014, 2017 ARM Limited | 1# Copyright (c) 2012-2014, 2017, 2018 ARM Limited |
2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 1228 unchanged lines hidden (view full) --- 1238 # build string->value map from vals sequence 1239 cls.map = {} 1240 for idx,val in enumerate(cls.vals): 1241 cls.map[val] = idx 1242 else: 1243 raise TypeError, "Enum-derived class must define "\ 1244 "attribute 'map' or 'vals'" 1245 | 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated --- 1228 unchanged lines hidden (view full) --- 1238 # build string->value map from vals sequence 1239 cls.map = {} 1240 for idx,val in enumerate(cls.vals): 1241 cls.map[val] = idx 1242 else: 1243 raise TypeError, "Enum-derived class must define "\ 1244 "attribute 'map' or 'vals'" 1245 |
1246 cls.cxx_type = 'Enums::%s' % name | 1246 if cls.is_class: 1247 cls.cxx_type = '%s' % name 1248 else: 1249 cls.cxx_type = 'Enums::%s' % name |
1247 1248 super(MetaEnum, cls).__init__(name, bases, init_dict) 1249 1250 # Generate C++ class declaration for this enum type. 1251 # Note that we wrap the enum in a class/struct to act as a namespace, 1252 # so that the enum strings can be brief w/o worrying about collisions. 1253 def cxx_decl(cls, code): 1254 wrapper_name = cls.wrapper_name 1255 wrapper = 'struct' if cls.wrapper_is_struct else 'namespace' 1256 name = cls.__name__ if cls.enum_name is None else cls.enum_name 1257 idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name) 1258 1259 code('''\ 1260#ifndef $idem_macro 1261#define $idem_macro 1262 | 1250 1251 super(MetaEnum, cls).__init__(name, bases, init_dict) 1252 1253 # Generate C++ class declaration for this enum type. 1254 # Note that we wrap the enum in a class/struct to act as a namespace, 1255 # so that the enum strings can be brief w/o worrying about collisions. 1256 def cxx_decl(cls, code): 1257 wrapper_name = cls.wrapper_name 1258 wrapper = 'struct' if cls.wrapper_is_struct else 'namespace' 1259 name = cls.__name__ if cls.enum_name is None else cls.enum_name 1260 idem_macro = '__ENUM__%s__%s__' % (wrapper_name, name) 1261 1262 code('''\ 1263#ifndef $idem_macro 1264#define $idem_macro 1265 |
1266''') 1267 if cls.is_class: 1268 code('''\ 1269enum class $name { 1270''') 1271 else: 1272 code('''\ |
|
1263$wrapper $wrapper_name { 1264 enum $name { 1265''') | 1273$wrapper $wrapper_name { 1274 enum $name { 1275''') |
1266 code.indent(2) | 1276 code.indent(1) 1277 code.indent(1) |
1267 for val in cls.vals: 1268 code('$val = ${{cls.map[val]}},') 1269 code('Num_$name = ${{len(cls.vals)}}') | 1278 for val in cls.vals: 1279 code('$val = ${{cls.map[val]}},') 1280 code('Num_$name = ${{len(cls.vals)}}') |
1270 code.dedent(2) 1271 code(' };') | 1281 code.dedent(1) 1282 code('};') |
1272 | 1283 |
1273 if cls.wrapper_is_struct: 1274 code(' static const char *${name}Strings[Num_${name}];') 1275 code('};') | 1284 if cls.is_class: 1285 code('''\ 1286extern const char *${name}Strings[static_cast<int>(${name}::Num_${name})]; 1287''') 1288 elif cls.wrapper_is_struct: 1289 code('static const char *${name}Strings[Num_${name}];') |
1276 else: 1277 code('extern const char *${name}Strings[Num_${name}];') | 1290 else: 1291 code('extern const char *${name}Strings[Num_${name}];') |
1278 code('}') | |
1279 | 1292 |
1293 if not cls.is_class: 1294 code.dedent(1) 1295 code('};') 1296 |
|
1280 code() 1281 code('#endif // $idem_macro') 1282 1283 def cxx_def(cls, code): 1284 wrapper_name = cls.wrapper_name 1285 file_name = cls.__name__ 1286 name = cls.__name__ if cls.enum_name is None else cls.enum_name 1287 1288 code('#include "enums/$file_name.hh"') 1289 if cls.wrapper_is_struct: 1290 code('const char *${wrapper_name}::${name}Strings' 1291 '[Num_${name}] =') 1292 else: | 1297 code() 1298 code('#endif // $idem_macro') 1299 1300 def cxx_def(cls, code): 1301 wrapper_name = cls.wrapper_name 1302 file_name = cls.__name__ 1303 name = cls.__name__ if cls.enum_name is None else cls.enum_name 1304 1305 code('#include "enums/$file_name.hh"') 1306 if cls.wrapper_is_struct: 1307 code('const char *${wrapper_name}::${name}Strings' 1308 '[Num_${name}] =') 1309 else: |
1293 code('namespace Enums {') 1294 code.indent(1) 1295 code(' const char *${name}Strings[Num_${name}] =') | 1310 if cls.is_class: 1311 code('''\ 1312const char *${name}Strings[static_cast<int>(${name}::Num_${name})] = 1313''') 1314 else: 1315 code('namespace Enums {') 1316 code.indent(1) 1317 code('const char *${name}Strings[Num_${name}] =') |
1296 1297 code('{') 1298 code.indent(1) 1299 for val in cls.vals: 1300 code('"$val",') 1301 code.dedent(1) 1302 code('};') 1303 | 1318 1319 code('{') 1320 code.indent(1) 1321 for val in cls.vals: 1322 code('"$val",') 1323 code.dedent(1) 1324 code('};') 1325 |
1304 if not cls.wrapper_is_struct: 1305 code('} // namespace $wrapper_name') | 1326 if not cls.wrapper_is_struct and not cls.is_class: |
1306 code.dedent(1) | 1327 code.dedent(1) |
1328 code('} // namespace $wrapper_name') |
|
1307 | 1329 |
1330 |
|
1308 def pybind_def(cls, code): 1309 name = cls.__name__ | 1331 def pybind_def(cls, code): 1332 name = cls.__name__ |
1310 wrapper_name = cls.wrapper_name | |
1311 enum_name = cls.__name__ if cls.enum_name is None else cls.enum_name | 1333 enum_name = cls.__name__ if cls.enum_name is None else cls.enum_name |
1334 wrapper_name = enum_name if cls.is_class else cls.wrapper_name |
|
1312 1313 code('''#include "pybind11/pybind11.h" 1314#include "pybind11/stl.h" 1315 1316#include <sim/init.hh> 1317 1318namespace py = pybind11; 1319 1320static void 1321module_init(py::module &m_internal) 1322{ 1323 py::module m = m_internal.def_submodule("enum_${name}"); 1324 | 1335 1336 code('''#include "pybind11/pybind11.h" 1337#include "pybind11/stl.h" 1338 1339#include <sim/init.hh> 1340 1341namespace py = pybind11; 1342 1343static void 1344module_init(py::module &m_internal) 1345{ 1346 py::module m = m_internal.def_submodule("enum_${name}"); 1347 |
1325 py::enum_<${wrapper_name}::${enum_name}>(m, "enum_${name}") | |
1326''') | 1348''') |
1349 if cls.is_class: 1350 code('py::enum_<${enum_name}>(m, "enum_${name}")') 1351 else: 1352 code('py::enum_<${wrapper_name}::${enum_name}>(m, "enum_${name}")') |
|
1327 1328 code.indent() 1329 code.indent() 1330 for val in cls.vals: 1331 code('.value("${val}", ${wrapper_name}::${val})') 1332 code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})') 1333 code('.export_values()') 1334 code(';') --- 12 unchanged lines hidden (view full) --- 1347 cmd_line_settable = True 1348 1349 # The name of the wrapping namespace or struct 1350 wrapper_name = 'Enums' 1351 1352 # If true, the enum is wrapped in a struct rather than a namespace 1353 wrapper_is_struct = False 1354 | 1353 1354 code.indent() 1355 code.indent() 1356 for val in cls.vals: 1357 code('.value("${val}", ${wrapper_name}::${val})') 1358 code('.value("Num_${name}", ${wrapper_name}::Num_${enum_name})') 1359 code('.export_values()') 1360 code(';') --- 12 unchanged lines hidden (view full) --- 1373 cmd_line_settable = True 1374 1375 # The name of the wrapping namespace or struct 1376 wrapper_name = 'Enums' 1377 1378 # If true, the enum is wrapped in a struct rather than a namespace 1379 wrapper_is_struct = False 1380 |
1381 is_class = False 1382 |
|
1355 # If not None, use this as the enum name rather than this class name 1356 enum_name = None 1357 1358 def __init__(self, value): 1359 if value not in self.map: 1360 raise TypeError, "Enum param got bad value '%s' (not in %s)" \ 1361 % (value, self.vals) 1362 self.value = value --- 22 unchanged lines hidden (view full) --- 1385 def getValue(self): 1386 import m5.internal.params 1387 e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__) 1388 return e(self.map[self.value]) 1389 1390 def __str__(self): 1391 return self.value 1392 | 1383 # If not None, use this as the enum name rather than this class name 1384 enum_name = None 1385 1386 def __init__(self, value): 1387 if value not in self.map: 1388 raise TypeError, "Enum param got bad value '%s' (not in %s)" \ 1389 % (value, self.vals) 1390 self.value = value --- 22 unchanged lines hidden (view full) --- 1413 def getValue(self): 1414 import m5.internal.params 1415 e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__) 1416 return e(self.map[self.value]) 1417 1418 def __str__(self): 1419 return self.value 1420 |
1421# This param will generate a scoped c++ enum and its python bindings. 1422class ScopedEnum(Enum): 1423 __metaclass__ = MetaEnum 1424 vals = [] 1425 cmd_line_settable = True 1426 1427 # The name of the wrapping namespace or struct 1428 wrapper_name = None 1429 1430 # If true, the enum is wrapped in a struct rather than a namespace 1431 wrapper_is_struct = False 1432 1433 # If true, the generated enum is a scoped enum 1434 is_class = True 1435 1436 # If not None, use this as the enum name rather than this class name 1437 enum_name = None 1438 |
|
1393# how big does a rounding error need to be before we warn about it? 1394frequency_tolerance = 0.001 # 0.1% 1395 1396class TickParamValue(NumericParamValue): 1397 cxx_type = 'Tick' 1398 ex_str = "1MHz" 1399 cmd_line_settable = True 1400 --- 635 unchanged lines hidden (view full) --- 2036 2037def clear(): 2038 global allEnums, allParams 2039 2040 allEnums = baseEnums.copy() 2041 allParams = baseParams.copy() 2042 2043__all__ = ['Param', 'VectorParam', | 1439# how big does a rounding error need to be before we warn about it? 1440frequency_tolerance = 0.001 # 0.1% 1441 1442class TickParamValue(NumericParamValue): 1443 cxx_type = 'Tick' 1444 ex_str = "1MHz" 1445 cmd_line_settable = True 1446 --- 635 unchanged lines hidden (view full) --- 2082 2083def clear(): 2084 global allEnums, allParams 2085 2086 allEnums = baseEnums.copy() 2087 allParams = baseParams.copy() 2088 2089__all__ = ['Param', 'VectorParam', |
2044 'Enum', 'Bool', 'String', 'Float', | 2090 'Enum', 'ScopedEnum', 'Bool', 'String', 'Float', |
2045 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 2046 'Int32', 'UInt32', 'Int64', 'UInt64', 2047 'Counter', 'Addr', 'Tick', 'Percent', 2048 'TcpPort', 'UdpPort', 'EthernetAddr', 2049 'IpAddress', 'IpNetmask', 'IpWithPort', 2050 'MemorySize', 'MemorySize32', 2051 'Latency', 'Frequency', 'Clock', 'Voltage', 'Current', 'Energy', 2052 'NetworkBandwidth', 'MemoryBandwidth', 2053 'AddrRange', 2054 'MaxAddr', 'MaxTick', 'AllMemory', 2055 'Time', 2056 'NextEthernetAddr', 'NULL', 2057 'MasterPort', 'SlavePort', 2058 'VectorMasterPort', 'VectorSlavePort'] 2059 2060import SimObject | 2091 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 2092 'Int32', 'UInt32', 'Int64', 'UInt64', 2093 'Counter', 'Addr', 'Tick', 'Percent', 2094 'TcpPort', 'UdpPort', 'EthernetAddr', 2095 'IpAddress', 'IpNetmask', 'IpWithPort', 2096 'MemorySize', 'MemorySize32', 2097 'Latency', 'Frequency', 'Clock', 'Voltage', 'Current', 'Energy', 2098 'NetworkBandwidth', 'MemoryBandwidth', 2099 'AddrRange', 2100 'MaxAddr', 'MaxTick', 'AllMemory', 2101 'Time', 2102 'NextEthernetAddr', 'NULL', 2103 'MasterPort', 'SlavePort', 2104 'VectorMasterPort', 'VectorSlavePort'] 2105 2106import SimObject |