2020-10-07 08:07:16 -05:00
|
|
|
# -*- mode:Python -*-
|
2020-08-02 11:09:02 -05:00
|
|
|
#
|
|
|
|
# This file is part of the Coriolis Software.
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
2020-08-02 11:09:02 -05:00
|
|
|
#
|
|
|
|
# +-----------------------------------------------------------------+
|
|
|
|
# | C O R I O L I S |
|
2020-10-07 08:07:16 -05:00
|
|
|
# | Alliance / Hurricane Interface |
|
2020-08-02 11:09:02 -05:00
|
|
|
# | |
|
|
|
|
# | Author : Jean-Paul Chaput |
|
|
|
|
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
|
|
# | =============================================================== |
|
|
|
|
# | Python : "./crlcore/helpers/overlay.py" |
|
|
|
|
# +-----------------------------------------------------------------+
|
|
|
|
#
|
|
|
|
# Those classes are based on the work of Jock Tanner from Libre-SOC.
|
|
|
|
|
2020-04-08 04:24:42 -05:00
|
|
|
|
|
|
|
"""
|
|
|
|
Overlay to make some C++ objects provide a more Pythonic interface.
|
|
|
|
Contains:
|
|
|
|
|
|
|
|
* ``overlay.UpdateSession`` : to be used in ``with`` construct.
|
2020-08-02 11:09:02 -05:00
|
|
|
* ``overlay.Configuration`` : to be used in ``with`` construct.
|
|
|
|
* ``overlay.CfgCache`` : A cache for Cfg parameters.
|
2020-04-08 04:24:42 -05:00
|
|
|
"""
|
|
|
|
|
|
|
|
import Cfg
|
|
|
|
import Hurricane
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateSession ( object ):
|
|
|
|
"""
|
|
|
|
Context manager for a GO update session. See Hurricane reference manual
|
|
|
|
for an info on Hurricane::UpdateSession class.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __enter__ ( self ):
|
|
|
|
Hurricane.UpdateSession.open()
|
|
|
|
|
|
|
|
def __exit__( self, *args ):
|
|
|
|
Hurricane.UpdateSession.close()
|
|
|
|
|
|
|
|
|
|
|
|
class Configuration:
|
|
|
|
"""
|
|
|
|
Allow access to Cfg parameter as attributes. For attribute syntax,
|
|
|
|
the dot (.) used in C++ or raw access is replaced by an underscore (_)
|
|
|
|
in Python mode.
|
|
|
|
|
|
|
|
Also provides a context manager.
|
|
|
|
"""
|
|
|
|
|
|
|
|
PRIORITY_USE_DEFAULT = Cfg.Parameter.Priority.UseDefault
|
|
|
|
PRIORITY_APPLICATION_BUILTIN = Cfg.Parameter.Priority.ApplicationBuiltin
|
|
|
|
PRIORITY_CONFIGURATION_FILE = Cfg.Parameter.Priority.ConfigurationFile
|
|
|
|
PRIORITY_USER_FILE = Cfg.Parameter.Priority.UserFile
|
|
|
|
PRIORITY_COMMAND_LINE = Cfg.Parameter.Priority.CommandLine
|
|
|
|
PRIORITY_INTERACTIVE = Cfg.Parameter.Priority.Interactive
|
|
|
|
|
|
|
|
def __init__ ( self, priority=None ):
|
|
|
|
self._priority = priority
|
|
|
|
|
|
|
|
def __enter__( self ):
|
|
|
|
if self._priority is not None:
|
|
|
|
Cfg.Configuration.pushDefaultPriority( self._priority )
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __setattr__( self, attr, val ):
|
|
|
|
if attr.startswith("_"):
|
|
|
|
self.__dict__[attr] = val
|
|
|
|
return
|
|
|
|
attr = attr.replace("_", ".")
|
|
|
|
if isinstance(val, bool):
|
|
|
|
Cfg.getParamBool(attr).setBool( val )
|
|
|
|
elif isinstance(val, int):
|
|
|
|
p = Cfg.getParamInt( attr ) # all params have a type
|
|
|
|
if p.type == 'Enumerate':
|
|
|
|
Cfg.getParamEnumerate(attr).setInt( val )
|
|
|
|
else:
|
|
|
|
Cfg.getParamInt(attr).setInt( val )
|
2020-06-16 14:33:33 -05:00
|
|
|
elif isinstance(val, float):
|
|
|
|
p = Cfg.getParamDouble( attr ).setDouble( val )
|
2020-04-08 04:24:42 -05:00
|
|
|
elif '%' in val:
|
|
|
|
Cfg.getParamPercentage(attr).setPercentage( float(val[:-1]) )
|
|
|
|
else:
|
|
|
|
Cfg.getParamString(attr).setString( val )
|
|
|
|
|
|
|
|
def __exit__( self, *args ):
|
|
|
|
if self._priority is not None:
|
|
|
|
Cfg.Configuration.popDefaultPriority()
|
|
|
|
|
2020-10-16 04:20:38 -05:00
|
|
|
|
|
|
|
class CachedParameter ( object ):
|
|
|
|
|
|
|
|
def __init__ ( self, path, v ):
|
|
|
|
self.path = path
|
|
|
|
self._v = None
|
|
|
|
self.v = v
|
|
|
|
self.vRange = [ None, None ]
|
|
|
|
self.vEnum = []
|
|
|
|
self.create = True
|
|
|
|
self.cacheRead()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def v ( self ): return self._v
|
|
|
|
|
|
|
|
@v.setter
|
|
|
|
def v ( self, value ):
|
|
|
|
if value is not None: self._v = value
|
|
|
|
|
|
|
|
def __str__ ( self ):
|
|
|
|
if isinstance(self.v,str): s = '"{}"'.format(self.v)
|
|
|
|
else: s = '{}'.format(self.v)
|
|
|
|
if self.vRange[0] is not None or self.vRange[1] is not None:
|
|
|
|
s += ' [{}:{}]'.format(self.vRange[0],self.vRange[1])
|
|
|
|
if self.vEnum:
|
|
|
|
s += ' ('
|
|
|
|
for i in range(len(self.vEnum)):
|
|
|
|
if i: s += ', '
|
|
|
|
s += '{}:"{}"'.format(self.vEnum[i][1],self.vEnum[i][0])
|
|
|
|
s += ')'
|
|
|
|
return s
|
|
|
|
|
|
|
|
def cacheWrite ( self ):
|
|
|
|
""""
|
|
|
|
Commit the value of parameter ``self.path`` to ``self.v`` in Cfg.
|
|
|
|
Percentage are set as Double and Enumerate as Int.
|
|
|
|
"""
|
|
|
|
if Cfg.hasParameter(self.path):
|
|
|
|
confDb = Cfg.Configuration.get()
|
|
|
|
p = confDb.getParameter( self.path )
|
|
|
|
else:
|
|
|
|
if len(self.vEnum): p = Cfg.getParamEnumerate( self.path )
|
|
|
|
elif isinstance(self.v,bool ): p = Cfg.getParamBool ( self.path )
|
|
|
|
elif isinstance(self.v,int ): p = Cfg.getParamInt ( self.path )
|
|
|
|
elif isinstance(self.v,float): p = Cfg.getParamDouble ( self.path )
|
|
|
|
else: p = Cfg.getParamString ( self.path )
|
|
|
|
if p.type == Cfg.Parameter.Type.Enumerate: p.setInt ( self.v )
|
|
|
|
elif p.type == Cfg.Parameter.Type.Int: p.setInt ( self.v )
|
|
|
|
elif p.type == Cfg.Parameter.Type.Bool: p.setBool ( self.v )
|
|
|
|
elif p.type == Cfg.Parameter.Type.Double: p.setDouble ( self.v )
|
|
|
|
elif p.type == Cfg.Parameter.Type.Percentage: p.setDouble ( self.v*100.0 )
|
|
|
|
else: p.setString ( str(self.v) )
|
|
|
|
if self.create:
|
|
|
|
if len(self.vEnum):
|
|
|
|
for item in self.vEnum:
|
|
|
|
p.addValue( item[0], item[1] )
|
|
|
|
if self.vRange[0] is not None: p.setMin( self.vRange[0] )
|
|
|
|
if self.vRange[1] is not None: p.setMax( self.vRange[1] )
|
|
|
|
|
|
|
|
def cacheRead ( self ):
|
|
|
|
""""Get the value of parameter ``self.path`` from Cfg."""
|
|
|
|
if not Cfg.hasParameter(self.path):
|
|
|
|
self.create = True
|
|
|
|
return
|
|
|
|
if self.v is not None: return
|
|
|
|
confDb = Cfg.Configuration.get()
|
|
|
|
p = confDb.getParameter( self.path )
|
|
|
|
if p:
|
2020-10-18 16:16:22 -05:00
|
|
|
if p.type == Cfg.Parameter.Type.Enumerate: self.v = p.asInt()
|
|
|
|
elif p.type == Cfg.Parameter.Type.Int:
|
|
|
|
self.v = p.asInt()
|
|
|
|
elif p.type == Cfg.Parameter.Type.Bool: self.v = p.asBool()
|
|
|
|
elif p.type == Cfg.Parameter.Type.String: self.v = p.asString()
|
|
|
|
elif p.type == Cfg.Parameter.Type.Double: self.v = p.asDouble()
|
|
|
|
elif p.type == Cfg.Parameter.Type.Percentage: self.v = p.asDouble()/100.0
|
|
|
|
else: self.v = p.asString()
|
2020-10-16 04:20:38 -05:00
|
|
|
|
2020-08-02 11:09:02 -05:00
|
|
|
|
|
|
|
class CfgCache ( object ):
|
|
|
|
"""
|
|
|
|
CgfCache cache a set of configuration parameters. The values of the
|
|
|
|
parameters are not set in the system *until* the ``apply()`` function
|
|
|
|
is called.
|
|
|
|
|
|
|
|
If a parameter do not exists in the ``Cfg`` module, it is created
|
|
|
|
when ``apply()`` is called. Be aware that it is not able to guess
|
|
|
|
the right type between Double and Percentage or Int and Enumerate.
|
|
|
|
It will, by default, only create Double or Int. So, when setting
|
|
|
|
Percentage or Enumerate, be sure that they exists beforehand in
|
|
|
|
the ``Cfg`` module.
|
|
|
|
|
|
|
|
The attributes of CfgCache exactly mimic the behavior of the
|
|
|
|
``Cfg`` parameter string identifiers. For example:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
# Direct access to a Cfg parameter.
|
|
|
|
p = Cfg.getParamInt('katana.eventsLimit').setInt( 4000000 )
|
|
|
|
|
|
|
|
# Setup of a CfgCache parameter.
|
|
|
|
cache = CfgCache('')
|
|
|
|
cache.katana.eventsLimit = 4000000
|
|
|
|
|
|
|
|
# ...
|
|
|
|
# Effective setting of the Cfg parameter.
|
|
|
|
cache.apply()
|
|
|
|
|
2020-10-14 08:06:42 -05:00
|
|
|
If a cache parameter is assigned to ``None``, it triggers the
|
|
|
|
loading of the value from the disk, it it exists.
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
# Setup of a CfgCache parameter.
|
|
|
|
cache = CfgCache('')
|
|
|
|
cache.katana.eventsLimit = None
|
|
|
|
# The parameter will read it's value from the disk (4000000).
|
|
|
|
|
2020-08-02 11:09:02 -05:00
|
|
|
|
|
|
|
This is done by overloading ``__setattr__()`` and ``__getattr__()``
|
|
|
|
which recursively create CfgCache objects for intermediate levels
|
|
|
|
attributes (in the previous example, a CfgCache for ``katana``
|
|
|
|
will automatically be created). To separate between attributes
|
|
|
|
that are part of configuration parameters and attributes belonging
|
|
|
|
to CfgCache itself, we prepend a '_' to the laters.
|
|
|
|
|
|
|
|
.. note:: It is important to understand the difference of behavior
|
|
|
|
with ``Configuration``, the former set the parameters
|
|
|
|
at once, it directly act on the ``Cfg`` settings.
|
|
|
|
The later keep a state and set the ``Cfg`` parameters
|
|
|
|
*only* when ``apply()`` is called.
|
|
|
|
"""
|
|
|
|
|
2020-08-04 18:25:48 -05:00
|
|
|
def __enter__( self ):
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __exit__( self, *args ):
|
|
|
|
self.apply()
|
|
|
|
self.display()
|
|
|
|
|
|
|
|
def __init__ ( self, path='', priority=None ):
|
2020-08-02 11:09:02 -05:00
|
|
|
"""Create a new CfgCache with a ``path`` as parent path."""
|
2020-08-04 18:25:48 -05:00
|
|
|
self._priority = priority
|
|
|
|
self._path = path
|
|
|
|
self._rattr = {}
|
2020-08-02 11:09:02 -05:00
|
|
|
|
|
|
|
def __setattr__ ( self, attr, v ):
|
|
|
|
"""
|
|
|
|
Recursively set an attribute. Attributes names starting by an '_' are
|
|
|
|
treated as belonging to *this* object (self).
|
|
|
|
|
|
|
|
How does the recursive attributes/CfgCache works? Assumes that we
|
|
|
|
are doing:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
# Setup of a CfgCache parameter.
|
|
|
|
cache = CfgCache('')
|
|
|
|
cache.katana.eventsLimit = 4000000
|
|
|
|
|
|
|
|
The explicit call sequence will be:
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
cache.__getattr__('katana').__setattr__( 'eventsLimit', 4000000 )
|
|
|
|
|
|
|
|
1. For the intermediate hierarchy level ``katana``, it is __getattr__()
|
|
|
|
which is called, if the attribute do not exists, we create a new
|
|
|
|
CfgCache().
|
|
|
|
|
|
|
|
2. Second, and only then, __setattr__() is called, which will create a
|
|
|
|
parameter entry named ``eventsLimit``.
|
|
|
|
|
|
|
|
The decision of whether create a parameter entry *or* a CfgCache
|
|
|
|
intermediate level will always be correctly handled because prior
|
|
|
|
to any access, an attribute needs to be set. So we always have
|
|
|
|
first a call chain of __getattr__() with one final __setattr__().
|
|
|
|
For any subsequent access to ``cache.katana.eventsLimit``, as
|
|
|
|
the attribute already exists, there is no type creation problem.
|
|
|
|
"""
|
|
|
|
if attr[0] == '_':
|
|
|
|
object.__setattr__( self, attr, v )
|
|
|
|
return
|
2020-10-16 04:20:38 -05:00
|
|
|
vRange = None
|
|
|
|
vEnum = None
|
|
|
|
if isinstance(v,list ): vRange = v; v = None
|
|
|
|
if isinstance(v,tuple): vEnum = v; v = None
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
if not attr in self._rattr:
|
2020-10-16 04:20:38 -05:00
|
|
|
self._rattr[ attr ] = CachedParameter( self._path+'.'+attr, v )
|
2020-10-18 16:16:22 -05:00
|
|
|
if vRange is not None: self._rattr[ attr ].vRange = vRange
|
|
|
|
elif vEnum is not None: self._rattr[ attr ].vEnum = vEnum
|
|
|
|
else: self._rattr[ attr ].v = v
|
2020-08-02 11:09:02 -05:00
|
|
|
|
|
|
|
def __getattr__ ( self, attr ):
|
|
|
|
"""
|
|
|
|
Get an attribute, if it doesn't exists, then we are in an intermediate
|
|
|
|
level like ``katana``, so create a new sub CfgCache for that attribute.
|
|
|
|
"""
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
if not attr in self._rattr:
|
2020-08-02 11:09:02 -05:00
|
|
|
path = self._path+'.'+attr if len(self._path) else attr
|
2020-08-04 18:25:48 -05:00
|
|
|
self._rattr[attr] = CfgCache( path, self._priority )
|
2020-10-18 16:16:22 -05:00
|
|
|
if isinstance(self._rattr[attr],CachedParameter):
|
|
|
|
return self._rattr[attr].v
|
2020-08-02 11:09:02 -05:00
|
|
|
return self._rattr[attr]
|
|
|
|
|
2020-10-14 08:06:42 -05:00
|
|
|
def _hasCachedParam ( self, elements ):
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
if not elements[0] in self._rattr:
|
2020-10-14 08:06:42 -05:00
|
|
|
return False
|
|
|
|
if len(elements) == 1:
|
|
|
|
return True
|
|
|
|
rattr = self._rattr[ elements[0] ]
|
|
|
|
if not isinstance(rattr,CfgCache):
|
|
|
|
return False
|
|
|
|
return rattr._hasCachedParam( elements[1:] )
|
|
|
|
|
|
|
|
def hasCachedParam ( self, attr ):
|
|
|
|
return self._hasCachedParam( attr.split('.') )
|
|
|
|
|
2020-08-04 18:25:48 -05:00
|
|
|
def apply ( self, priority=None ):
|
2020-08-02 11:09:02 -05:00
|
|
|
"""Apply the parameters values stored in the cache to the ``Cfg`` database."""
|
2020-08-04 18:25:48 -05:00
|
|
|
if priority is None: priority = self._priority
|
|
|
|
if not len(self._path) and priority is not None:
|
2020-08-02 11:09:02 -05:00
|
|
|
Cfg.Configuration.pushDefaultPriority( priority )
|
|
|
|
for attrName in self._rattr.keys():
|
|
|
|
if isinstance(self._rattr[attrName],CfgCache):
|
|
|
|
self._rattr[attrName].apply()
|
|
|
|
continue
|
2020-10-16 04:20:38 -05:00
|
|
|
self._rattr[attrName].cacheWrite()
|
2020-08-04 18:25:48 -05:00
|
|
|
if not len(self._path) and priority is not None:
|
2020-08-02 11:09:02 -05:00
|
|
|
Cfg.Configuration.popDefaultPriority()
|
2020-08-11 07:47:03 -05:00
|
|
|
#self.display()
|
2020-08-02 11:09:02 -05:00
|
|
|
|
|
|
|
def display ( self ):
|
|
|
|
"""Print all the parameters stored in that CfgCache."""
|
|
|
|
if not len(self._path):
|
2020-08-04 18:25:48 -05:00
|
|
|
print( ' o Applying configuration (CfgCache):' )
|
2020-08-02 11:09:02 -05:00
|
|
|
for attrName in self._rattr.keys():
|
|
|
|
if isinstance(self._rattr[attrName],CfgCache):
|
|
|
|
self._rattr[attrName].display()
|
|
|
|
continue
|
2020-08-04 18:25:48 -05:00
|
|
|
print( ' - {}.{} = {}'.format(self._path,attrName,self._rattr[attrName]) )
|
2020-08-02 11:09:02 -05:00
|
|
|
|