coriolis/crlcore/etc/common/patterns.py

785 lines
29 KiB
Python
Raw Normal View History

Migrating the initialisation system to be completely Python-like. * New: In bootstrap/coriolisEnv.py, add the "etc" directory to the PYTHONPATH as initialization are now Python modules. * New: In Hurricane/analogic, first groundwork for the integration of PIP/MIM/MOM multi-capacitors. Add C++ and Python interface for the allocation matrix and the list of capacities values. * Change: In Hurricane::RegularLayer, add a layer parameter to the constructor so the association between the RegularLayer and it's BasicLayer can readily be done. * Change: In Hurricane::Layer, add a new getCut() accessor to get the cut layer in ViaLayer. * Change: In Hurricane::DataBase::get(), the Python wrapper should no longer consider an error if the data-base has not been created yet. Just return None. * Bug: In Isobar::PyLayer::getEnclosure() wrapper, if the overall enclosure is requested, pass the right parameter to the C++ function. * Change: In AllianceFramework, make public _bindLibraries() and export it to the Python interface. * Change: In AllianceFramework::create(), do not longer call bindLibraries(). This now must be done explicitely and afterwards. * Change: In AllianceFramework::createLibrary() and Environement::addSYSTEM_LIBRARY(), minor bug corrections that I don't recall. * Change: In SearchPath::prepend(), set the selected index to zero and return it. * Change: In CRL::System CTOR, add "etc" to the PYTHONPATH as the configuration files are now organized as Python modules. * New: In PyCRL, export the CRL::System singleton, it's creation is no longer triggered by the one of AllianceFramework. * New: In CRL/etc/, convert most of the configuration files into the Python module format. For now, keep the old ".conf", but that are no longer used. For the real technologies, we cannot keep the directory name as "180" or "45" as it not allowed by Python syntax, so we create "node180" or "node45" instead. Most of the helpers and coriolisInit.py are no longer used now. To be removed in future commits after being sure that everything works... * Bug: In AutoSegment::makeDogleg(AutoContact*), the layer of the contacts where badly computed when one end of the original segment was attached to a non-preferred direction segment (mostly on terminal contacts). Now use the new AutoContact::updateLayer() method. * Bug: In Dijkstra::load(), limit symetric search area only if the net is a symmetric one ! * Change: In Katana/python/katanaInit.py, comply with the new initialisation scheme. * Change: In Unicorn/cgt.py, comply to the new inititalization scheme. * Change: In cumulus various Python scripts remove the call to helpers.staticInitialization() as they are not needed now (we run in only *one* interpreter, so we correctly share all init). In plugins/__init__.py, read the new NDA directory variable. * Bug: In cumulus/plugins/Chip.doCoronafloorplan(), self.railsNb was not correctly managed when there was no clock. * Change: In cumulus/plugins/Configuration.coronaContactArray(), compute the viaPitch from the technology instead of the hard-coded 4.0 lambdas. In Configuration.loadConfiguration(), read the "ioring.py" from the new user's settings module. * Bug: In stratus.dpgen_ADSB2F, gives coordinates translated into DbU to the XY functions. In st_model.Save(), use the VstUseConcat flag to get correct VST files. In st_net.hur_net(), when a net is POWER/GROUND or CLOCK also make it global. * Change: In Oroshi/python/WIP_Transistor.py, encapsulate the generator inside a try/except block to get prettier error (and stop at the first).
2019-10-28 12:09:14 -05:00
# This file is part of the Coriolis Software.
# Copyright (c) UPMC 2019-2019, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/common/patterns.py" |
# +-----------------------------------------------------------------+
import sys
import math
import helpers
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
class Pattern ( object ):
hexaToPatternLUT = { '0':' '
, '1':' X'
, '2':' X '
, '3':' XX'
, '4':' X '
, '5':' X X'
, '6':' XX '
, '7':' XXX'
, '8':'X '
, '9':'X X'
, 'a':'X X '
, 'b':'X XX'
, 'c':'XX '
, 'd':'XX X'
, 'e':'XXX '
, 'f':'XXXX'}
def __init__ ( self, name='noname', bits=[], hexa='' ):
self._name = name
self._bits = []
self._hexa = ''
self._side = 0
if bits: self._setFromBits(bits)
if hexa: self._setFromHexa(hexa)
return
def empty ( self ):
if not self._bits and not self._hexa: return True
return False
def _setName ( self, name ): self._name = name
def _getName ( self ): return self._name
def _toHexa ( self ):
hexasLSB = []
for line in self._bits:
byte = 0
for i in range(len(line)):
if i != 0 and i%4 == 0:
hexasLSB += [ hex(byte)[2:] ]
byte = 0
byte = byte << 1
if line[i] != ' ': byte += 1
hexasLSB += [ hex(byte)[2:] ]
# Convert in MSB mode. Invert the bytes by pairs.
self._hexa = ''
for i in range(len(hexasLSB)/2):
self._hexa += hexasLSB[i*2+1] + hexasLSB[i*2]
return self._hexa
def _fromHexa ( self ):
self._bits = []
side = math.sqrt(4*len(self._hexa))
if pow(side,2) != 4*len(self._hexa):
print '[ERROR] The pattern is not square (%d self._bits).' % (4*len(self._hexa))
return None
side /= 4
# Convert from MSB mode. Invert the bytes by pairs.
hexasLSB = ''
for i in range(len(self._hexa)/2):
hexasLSB += self._hexa[i*2+1] + self._hexa[i*2]
line = ''
for i in range(len(hexasLSB)):
if i != 0 and i%side == 0:
self._bits += [ line ]
line = ''
line += Pattern.hexaToPatternLUT[hexasLSB[i].lower()]
self._bits += [ line ]
#self._bits.reverse()
return self._bits
def _setFromHexa ( self, hexa ):
self._hexa = hexa
self._side = math.sqrt(4*len(self._hexa))
if pow(self._side,2) != 4*len(self._hexa):
raise ErrorMessage( 1, 'The pattern is not square (%d bits).'
% (4*len(self._hexa)) )
return
self._fromHexa()
return
def _setFromBits ( self, bits ):
self._bits = bits
self._side = len(bits)
for line in bits:
if self._side != len(line):
raise ErrorMessage( 1, 'The pattern is not square (%dx%d bits).'
% (len(line),len(self._bits)) )
self._toHexa()
return
def _getHexa ( self ): return self._hexa
def _getBits ( self ): return self._bits
def printBits ( self ):
s = ''
side = len(self._bits[0])
s += '+%s+\n' % ('-'*side)
for line in self._bits:
s += '|%s|\n' % line
s += '+%s+' % ('-'*side)
return s
def printHexa ( self ):
return self._hexa
def __str__ ( self ):
return self._hexa
hexa = property(_getName,_setName)
hexa = property(_getHexa,_setFromHexa)
bits = property(_getBits,_setFromBits)
LUT = {}
def add ( **keywords ):
global LUT
try:
if not keywords.has_key('name'):
raise ErrorMessage(1,['patterns.add(): Malformed pattern, missing "name" argument.', str(keywords) ])
if keywords.has_key('bits') and keywords.has_key('hexa'):
w = WarningMessage( 'patterns.add(): Pattern "%s" has both bits & hexa, ignoring hexa.' % keywords['name'] )
print w
del keywords['hexa']
LUT[ keywords['name'] ] = Pattern( **keywords )
except Exception, e:
helpers.io.catch( e )
return
def toHexa ( key ):
global LUT
if isinstance(key,int) or isinstance(key,long) or not LUT.has_key(key): return key
return LUT[key].hexa
add( name='crux.8'
, bits=[ ' '
, ' X '
, ' X '
, ' XXXXX '
, ' X '
, ' X '
, ' '
, ' ' ] )
add( name='slash.8'
, bits=[ ' X X'
, ' X X '
, ' X X '
, 'X X '
, ' X X'
, ' X X '
, ' X X '
, 'X X ' ] )
add( name='hash.8'
, bits=[ 'XXX XXX '
, 'XX XXX X'
, 'X XXX XX'
, ' XXX XXX'
, 'XXX XXX '
, 'XX XXX X'
, 'X XXX XX'
, ' XXX XXX' ] )
add( name='urgo.8'
, bits=[ 'XXX XXXX' # feffffffefffffff
, 'XXXXXXXX'
, 'XXXXXXXX'
, 'XXXXXXXX'
, 'XXXXXXX '
, 'XXXXXXXX'
, 'XXXXXXXX'
, 'XXXXXXXX' ] )
add( name='antihash0.8'
, bits=[ ' XXX XXX' # 77bbddee77bbddee
, 'X XXX XX'
, 'XX XXX X'
, 'XXX XXX '
, ' XXX XXX'
, 'X XXX XX'
, 'XX XXX X'
, 'XXX XXX ' ] )
add( name='antihash1.8'
, bits=[ 'X XXX XX' # bbddee77bbddee77
, 'XX XXX X'
, 'XXX XXX '
, ' XXX XXX'
, 'X XXX XX'
, 'XX XXX X'
, 'XXX XXX '
, ' XXX XXX' ] )
add( name='poids2.8'
, bits=[ 'X X X X ' # aa55aa55aa55aa55
, ' X X X X'
, 'X X X X '
, ' X X X X'
, 'X X X X '
, ' X X X X'
, 'X X X X '
, ' X X X X' ] )
add( name='poids4.8'
, bits=[ 'X X ' # 8800220088002200
, ' '
, ' X X '
, ' '
, 'X X '
, ' '
, ' X X '
, ' ' ] )
add( name='antipoids2.8'
, bits=[ ' # # # #' # 55aa55aa55aa55aa
, '# # # # '
, ' # # # #'
, '# # # # '
, ' # # # #'
, '# # # # '
, ' # # # #'
, '# # # # ' ] )
add( name='light_antihash0.8'
, bits=[ 'X X ' # 8822882288228822
, ' X X '
, 'X X '
, ' X X '
, 'X X '
, ' X X '
, 'X X '
, ' X X ' ] )
add( name='light_antihash1.8'
, bits=[ ' X X ' # 4411441144114411
, ' X X'
, ' X X '
, ' X X'
, ' X X '
, ' X X'
, ' X X '
, ' X X' ] )
add( name='light_antihash2.8'
, bits=[ ' X X ' # 2288228822882288
, 'X X '
, ' X X '
, 'X X '
, ' X X '
, 'X X '
, ' X X '
, 'X X ' ] )
add( name='light_antislash0.8'
, bits=[ 'X X ' # 8844221188442211
, ' X X '
, ' X X '
, ' X X'
, 'X X '
, ' X X '
, ' X X '
, ' X X' ] )
add( name='urgo.32'
First stage in analog capacitor integration * Bug: In Technology::getPhysicalRule(), if the named layerdo not exists, throw an exception instead of silently putting a NULL pointer inside a rule. * New: In Hurricane/Analog, new parameters classes for capacitor devices: - Analog::Matrix, a matrix of null or positives integers to encode capacitor matrix matching. - Analog::Capacities, a list of float values for all component of a multi-capacitor. * New: In Hurricane::Script, add a "getFileName()" method to get the full path name of the Python module. * Change: In Analog::LayoutGenerator, completly remove the logger utility as it is no longer used. Simply print error messages instead. * Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'. Accessors renamed in "getTopPlate()" & "getBottomPlate()". * New: In Analog::MultiCapacitor, complete rewrite. Makes use of the new parameters "capacities" and "matrix". Dynamically generates it's terminals as we do not know beforehand how many capacitors could be put in it. * Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend a "Py" to class name (so the keep the C++ name). * Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new capacitor generator. * New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0] element to distinguish between transistor, capacitor and resistor. (this is the matrix of values returned to the LayoutGenerator after device generation). Now have one "setGlobalParams()" function per family. * New: In oroshi/python/Rules.py, added DTR rules needed by capacitors. Catch exceptions if something wrong append when we extract the rules from the technology. * New: In Bora, the devices are no longer *only* transistors, so the possibles configurations are no longer defined only by a number of fingers. We must be able to support any kind of range of configuration. So the explicit range of number of fingers is replaced by a base class ParameterRange, and it's derived classes: - Bora::StepParameterRange, to encode the possible number of fingers of a transistor (the former only possibility). - Bora::MatrixParameterRange, to encode all the possible matching scheme for a capacitor. As there is no way to compress it, this is a vector of Matrix (from Analog). * Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set on the right configuration (through the index) before being called. The generation parameters are taken from the active item in the ParameterRange. * Change: In Bora::NodeSets::create(), iterate over the ParameterRange to build all the configuration. Adjustement to the routing gauge pitchs are moved into the DBoxSet CTOR to save a lot of code. Semantic change: the index in the NodeSets is now the index in the associated ParameterRange and no longer the number of fingers of a transistor. Check that the ParameterRange dynamic class is consitent with the device family. * Change: In Bora::DBoxSet, same semantic change as for NodeSets, the number of finger become an index in ParameterRange. In DBoxSet::create(), now also perform the abutment box adjustement to the RoutingGauge, if possible. * New: In Karakaze/python/AnalogDesign.py, add support for Capacitor devices.
2019-11-07 10:05:49 -06:00
, bits=[ 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX'
Migrating the initialisation system to be completely Python-like. * New: In bootstrap/coriolisEnv.py, add the "etc" directory to the PYTHONPATH as initialization are now Python modules. * New: In Hurricane/analogic, first groundwork for the integration of PIP/MIM/MOM multi-capacitors. Add C++ and Python interface for the allocation matrix and the list of capacities values. * Change: In Hurricane::RegularLayer, add a layer parameter to the constructor so the association between the RegularLayer and it's BasicLayer can readily be done. * Change: In Hurricane::Layer, add a new getCut() accessor to get the cut layer in ViaLayer. * Change: In Hurricane::DataBase::get(), the Python wrapper should no longer consider an error if the data-base has not been created yet. Just return None. * Bug: In Isobar::PyLayer::getEnclosure() wrapper, if the overall enclosure is requested, pass the right parameter to the C++ function. * Change: In AllianceFramework, make public _bindLibraries() and export it to the Python interface. * Change: In AllianceFramework::create(), do not longer call bindLibraries(). This now must be done explicitely and afterwards. * Change: In AllianceFramework::createLibrary() and Environement::addSYSTEM_LIBRARY(), minor bug corrections that I don't recall. * Change: In SearchPath::prepend(), set the selected index to zero and return it. * Change: In CRL::System CTOR, add "etc" to the PYTHONPATH as the configuration files are now organized as Python modules. * New: In PyCRL, export the CRL::System singleton, it's creation is no longer triggered by the one of AllianceFramework. * New: In CRL/etc/, convert most of the configuration files into the Python module format. For now, keep the old ".conf", but that are no longer used. For the real technologies, we cannot keep the directory name as "180" or "45" as it not allowed by Python syntax, so we create "node180" or "node45" instead. Most of the helpers and coriolisInit.py are no longer used now. To be removed in future commits after being sure that everything works... * Bug: In AutoSegment::makeDogleg(AutoContact*), the layer of the contacts where badly computed when one end of the original segment was attached to a non-preferred direction segment (mostly on terminal contacts). Now use the new AutoContact::updateLayer() method. * Bug: In Dijkstra::load(), limit symetric search area only if the net is a symmetric one ! * Change: In Katana/python/katanaInit.py, comply with the new initialisation scheme. * Change: In Unicorn/cgt.py, comply to the new inititalization scheme. * Change: In cumulus various Python scripts remove the call to helpers.staticInitialization() as they are not needed now (we run in only *one* interpreter, so we correctly share all init). In plugins/__init__.py, read the new NDA directory variable. * Bug: In cumulus/plugins/Chip.doCoronafloorplan(), self.railsNb was not correctly managed when there was no clock. * Change: In cumulus/plugins/Configuration.coronaContactArray(), compute the viaPitch from the technology instead of the hard-coded 4.0 lambdas. In Configuration.loadConfiguration(), read the "ioring.py" from the new user's settings module. * Bug: In stratus.dpgen_ADSB2F, gives coordinates translated into DbU to the XY functions. In st_model.Save(), use the VstUseConcat flag to get correct VST files. In st_net.hur_net(), when a net is POWER/GROUND or CLOCK also make it global. * Change: In Oroshi/python/WIP_Transistor.py, encapsulate the generator inside a try/except block to get prettier error (and stop at the first).
2019-10-28 12:09:14 -05:00
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
First stage in analog capacitor integration * Bug: In Technology::getPhysicalRule(), if the named layerdo not exists, throw an exception instead of silently putting a NULL pointer inside a rule. * New: In Hurricane/Analog, new parameters classes for capacitor devices: - Analog::Matrix, a matrix of null or positives integers to encode capacitor matrix matching. - Analog::Capacities, a list of float values for all component of a multi-capacitor. * New: In Hurricane::Script, add a "getFileName()" method to get the full path name of the Python module. * Change: In Analog::LayoutGenerator, completly remove the logger utility as it is no longer used. Simply print error messages instead. * Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'. Accessors renamed in "getTopPlate()" & "getBottomPlate()". * New: In Analog::MultiCapacitor, complete rewrite. Makes use of the new parameters "capacities" and "matrix". Dynamically generates it's terminals as we do not know beforehand how many capacitors could be put in it. * Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend a "Py" to class name (so the keep the C++ name). * Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new capacitor generator. * New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0] element to distinguish between transistor, capacitor and resistor. (this is the matrix of values returned to the LayoutGenerator after device generation). Now have one "setGlobalParams()" function per family. * New: In oroshi/python/Rules.py, added DTR rules needed by capacitors. Catch exceptions if something wrong append when we extract the rules from the technology. * New: In Bora, the devices are no longer *only* transistors, so the possibles configurations are no longer defined only by a number of fingers. We must be able to support any kind of range of configuration. So the explicit range of number of fingers is replaced by a base class ParameterRange, and it's derived classes: - Bora::StepParameterRange, to encode the possible number of fingers of a transistor (the former only possibility). - Bora::MatrixParameterRange, to encode all the possible matching scheme for a capacitor. As there is no way to compress it, this is a vector of Matrix (from Analog). * Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set on the right configuration (through the index) before being called. The generation parameters are taken from the active item in the ParameterRange. * Change: In Bora::NodeSets::create(), iterate over the ParameterRange to build all the configuration. Adjustement to the routing gauge pitchs are moved into the DBoxSet CTOR to save a lot of code. Semantic change: the index in the NodeSets is now the index in the associated ParameterRange and no longer the number of fingers of a transistor. Check that the ParameterRange dynamic class is consitent with the device family. * Change: In Bora::DBoxSet, same semantic change as for NodeSets, the number of finger become an index in ParameterRange. In DBoxSet::create(), now also perform the abutment box adjustement to the RoutingGauge, if possible. * New: In Karakaze/python/AnalogDesign.py, add support for Capacitor devices.
2019-11-07 10:05:49 -06:00
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
, ' XXXXXXXXXXXXXXXXXXXXXX '
, ' XXXXXXXXXXXXXXXXXXXXXX '
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX '
Migrating the initialisation system to be completely Python-like. * New: In bootstrap/coriolisEnv.py, add the "etc" directory to the PYTHONPATH as initialization are now Python modules. * New: In Hurricane/analogic, first groundwork for the integration of PIP/MIM/MOM multi-capacitors. Add C++ and Python interface for the allocation matrix and the list of capacities values. * Change: In Hurricane::RegularLayer, add a layer parameter to the constructor so the association between the RegularLayer and it's BasicLayer can readily be done. * Change: In Hurricane::Layer, add a new getCut() accessor to get the cut layer in ViaLayer. * Change: In Hurricane::DataBase::get(), the Python wrapper should no longer consider an error if the data-base has not been created yet. Just return None. * Bug: In Isobar::PyLayer::getEnclosure() wrapper, if the overall enclosure is requested, pass the right parameter to the C++ function. * Change: In AllianceFramework, make public _bindLibraries() and export it to the Python interface. * Change: In AllianceFramework::create(), do not longer call bindLibraries(). This now must be done explicitely and afterwards. * Change: In AllianceFramework::createLibrary() and Environement::addSYSTEM_LIBRARY(), minor bug corrections that I don't recall. * Change: In SearchPath::prepend(), set the selected index to zero and return it. * Change: In CRL::System CTOR, add "etc" to the PYTHONPATH as the configuration files are now organized as Python modules. * New: In PyCRL, export the CRL::System singleton, it's creation is no longer triggered by the one of AllianceFramework. * New: In CRL/etc/, convert most of the configuration files into the Python module format. For now, keep the old ".conf", but that are no longer used. For the real technologies, we cannot keep the directory name as "180" or "45" as it not allowed by Python syntax, so we create "node180" or "node45" instead. Most of the helpers and coriolisInit.py are no longer used now. To be removed in future commits after being sure that everything works... * Bug: In AutoSegment::makeDogleg(AutoContact*), the layer of the contacts where badly computed when one end of the original segment was attached to a non-preferred direction segment (mostly on terminal contacts). Now use the new AutoContact::updateLayer() method. * Bug: In Dijkstra::load(), limit symetric search area only if the net is a symmetric one ! * Change: In Katana/python/katanaInit.py, comply with the new initialisation scheme. * Change: In Unicorn/cgt.py, comply to the new inititalization scheme. * Change: In cumulus various Python scripts remove the call to helpers.staticInitialization() as they are not needed now (we run in only *one* interpreter, so we correctly share all init). In plugins/__init__.py, read the new NDA directory variable. * Bug: In cumulus/plugins/Chip.doCoronafloorplan(), self.railsNb was not correctly managed when there was no clock. * Change: In cumulus/plugins/Configuration.coronaContactArray(), compute the viaPitch from the technology instead of the hard-coded 4.0 lambdas. In Configuration.loadConfiguration(), read the "ioring.py" from the new user's settings module. * Bug: In stratus.dpgen_ADSB2F, gives coordinates translated into DbU to the XY functions. In st_model.Save(), use the VstUseConcat flag to get correct VST files. In st_net.hur_net(), when a net is POWER/GROUND or CLOCK also make it global. * Change: In Oroshi/python/WIP_Transistor.py, encapsulate the generator inside a try/except block to get prettier error (and stop at the first).
2019-10-28 12:09:14 -05:00
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
First stage in analog capacitor integration * Bug: In Technology::getPhysicalRule(), if the named layerdo not exists, throw an exception instead of silently putting a NULL pointer inside a rule. * New: In Hurricane/Analog, new parameters classes for capacitor devices: - Analog::Matrix, a matrix of null or positives integers to encode capacitor matrix matching. - Analog::Capacities, a list of float values for all component of a multi-capacitor. * New: In Hurricane::Script, add a "getFileName()" method to get the full path name of the Python module. * Change: In Analog::LayoutGenerator, completly remove the logger utility as it is no longer used. Simply print error messages instead. * Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'. Accessors renamed in "getTopPlate()" & "getBottomPlate()". * New: In Analog::MultiCapacitor, complete rewrite. Makes use of the new parameters "capacities" and "matrix". Dynamically generates it's terminals as we do not know beforehand how many capacitors could be put in it. * Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend a "Py" to class name (so the keep the C++ name). * Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new capacitor generator. * New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0] element to distinguish between transistor, capacitor and resistor. (this is the matrix of values returned to the LayoutGenerator after device generation). Now have one "setGlobalParams()" function per family. * New: In oroshi/python/Rules.py, added DTR rules needed by capacitors. Catch exceptions if something wrong append when we extract the rules from the technology. * New: In Bora, the devices are no longer *only* transistors, so the possibles configurations are no longer defined only by a number of fingers. We must be able to support any kind of range of configuration. So the explicit range of number of fingers is replaced by a base class ParameterRange, and it's derived classes: - Bora::StepParameterRange, to encode the possible number of fingers of a transistor (the former only possibility). - Bora::MatrixParameterRange, to encode all the possible matching scheme for a capacitor. As there is no way to compress it, this is a vector of Matrix (from Analog). * Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set on the right configuration (through the index) before being called. The generation parameters are taken from the active item in the ParameterRange. * Change: In Bora::NodeSets::create(), iterate over the ParameterRange to build all the configuration. Adjustement to the routing gauge pitchs are moved into the DBoxSet CTOR to save a lot of code. Semantic change: the index in the NodeSets is now the index in the associated ParameterRange and no longer the number of fingers of a transistor. Check that the ParameterRange dynamic class is consitent with the device family. * Change: In Bora::DBoxSet, same semantic change as for NodeSets, the number of finger become an index in ParameterRange. In DBoxSet::create(), now also perform the abutment box adjustement to the RoutingGauge, if possible. * New: In Karakaze/python/AnalogDesign.py, add support for Capacitor devices.
2019-11-07 10:05:49 -06:00
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXXX' ] )
Migrating the initialisation system to be completely Python-like. * New: In bootstrap/coriolisEnv.py, add the "etc" directory to the PYTHONPATH as initialization are now Python modules. * New: In Hurricane/analogic, first groundwork for the integration of PIP/MIM/MOM multi-capacitors. Add C++ and Python interface for the allocation matrix and the list of capacities values. * Change: In Hurricane::RegularLayer, add a layer parameter to the constructor so the association between the RegularLayer and it's BasicLayer can readily be done. * Change: In Hurricane::Layer, add a new getCut() accessor to get the cut layer in ViaLayer. * Change: In Hurricane::DataBase::get(), the Python wrapper should no longer consider an error if the data-base has not been created yet. Just return None. * Bug: In Isobar::PyLayer::getEnclosure() wrapper, if the overall enclosure is requested, pass the right parameter to the C++ function. * Change: In AllianceFramework, make public _bindLibraries() and export it to the Python interface. * Change: In AllianceFramework::create(), do not longer call bindLibraries(). This now must be done explicitely and afterwards. * Change: In AllianceFramework::createLibrary() and Environement::addSYSTEM_LIBRARY(), minor bug corrections that I don't recall. * Change: In SearchPath::prepend(), set the selected index to zero and return it. * Change: In CRL::System CTOR, add "etc" to the PYTHONPATH as the configuration files are now organized as Python modules. * New: In PyCRL, export the CRL::System singleton, it's creation is no longer triggered by the one of AllianceFramework. * New: In CRL/etc/, convert most of the configuration files into the Python module format. For now, keep the old ".conf", but that are no longer used. For the real technologies, we cannot keep the directory name as "180" or "45" as it not allowed by Python syntax, so we create "node180" or "node45" instead. Most of the helpers and coriolisInit.py are no longer used now. To be removed in future commits after being sure that everything works... * Bug: In AutoSegment::makeDogleg(AutoContact*), the layer of the contacts where badly computed when one end of the original segment was attached to a non-preferred direction segment (mostly on terminal contacts). Now use the new AutoContact::updateLayer() method. * Bug: In Dijkstra::load(), limit symetric search area only if the net is a symmetric one ! * Change: In Katana/python/katanaInit.py, comply with the new initialisation scheme. * Change: In Unicorn/cgt.py, comply to the new inititalization scheme. * Change: In cumulus various Python scripts remove the call to helpers.staticInitialization() as they are not needed now (we run in only *one* interpreter, so we correctly share all init). In plugins/__init__.py, read the new NDA directory variable. * Bug: In cumulus/plugins/Chip.doCoronafloorplan(), self.railsNb was not correctly managed when there was no clock. * Change: In cumulus/plugins/Configuration.coronaContactArray(), compute the viaPitch from the technology instead of the hard-coded 4.0 lambdas. In Configuration.loadConfiguration(), read the "ioring.py" from the new user's settings module. * Bug: In stratus.dpgen_ADSB2F, gives coordinates translated into DbU to the XY functions. In st_model.Save(), use the VstUseConcat flag to get correct VST files. In st_net.hur_net(), when a net is POWER/GROUND or CLOCK also make it global. * Change: In Oroshi/python/WIP_Transistor.py, encapsulate the generator inside a try/except block to get prettier error (and stop at the first).
2019-10-28 12:09:14 -05:00
add( name='slash.32'
First stage in analog capacitor integration * Bug: In Technology::getPhysicalRule(), if the named layerdo not exists, throw an exception instead of silently putting a NULL pointer inside a rule. * New: In Hurricane/Analog, new parameters classes for capacitor devices: - Analog::Matrix, a matrix of null or positives integers to encode capacitor matrix matching. - Analog::Capacities, a list of float values for all component of a multi-capacitor. * New: In Hurricane::Script, add a "getFileName()" method to get the full path name of the Python module. * Change: In Analog::LayoutGenerator, completly remove the logger utility as it is no longer used. Simply print error messages instead. * Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'. Accessors renamed in "getTopPlate()" & "getBottomPlate()". * New: In Analog::MultiCapacitor, complete rewrite. Makes use of the new parameters "capacities" and "matrix". Dynamically generates it's terminals as we do not know beforehand how many capacitors could be put in it. * Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend a "Py" to class name (so the keep the C++ name). * Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new capacitor generator. * New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0] element to distinguish between transistor, capacitor and resistor. (this is the matrix of values returned to the LayoutGenerator after device generation). Now have one "setGlobalParams()" function per family. * New: In oroshi/python/Rules.py, added DTR rules needed by capacitors. Catch exceptions if something wrong append when we extract the rules from the technology. * New: In Bora, the devices are no longer *only* transistors, so the possibles configurations are no longer defined only by a number of fingers. We must be able to support any kind of range of configuration. So the explicit range of number of fingers is replaced by a base class ParameterRange, and it's derived classes: - Bora::StepParameterRange, to encode the possible number of fingers of a transistor (the former only possibility). - Bora::MatrixParameterRange, to encode all the possible matching scheme for a capacitor. As there is no way to compress it, this is a vector of Matrix (from Analog). * Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set on the right configuration (through the index) before being called. The generation parameters are taken from the active item in the ParameterRange. * Change: In Bora::NodeSets::create(), iterate over the ParameterRange to build all the configuration. Adjustement to the routing gauge pitchs are moved into the DBoxSet CTOR to save a lot of code. Semantic change: the index in the NodeSets is now the index in the associated ParameterRange and no longer the number of fingers of a transistor. Check that the ParameterRange dynamic class is consitent with the device family. * Change: In Bora::DBoxSet, same semantic change as for NodeSets, the number of finger become an index in ParameterRange. In DBoxSet::create(), now also perform the abutment box adjustement to the RoutingGauge, if possible. * New: In Karakaze/python/AnalogDesign.py, add support for Capacitor devices.
2019-11-07 10:05:49 -06:00
, bits=[ ' XXXX XXX'
, ' XXXX XXXX'
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, 'XXXX XXXX '
, 'XXX XXXX X'
, 'XX XXXX XX'
, 'X XXXX XXX'
, ' XXXX XXXX'
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, ' XXXX XXXX '
, 'XXXX XXXX '
, 'XXX XXXX '
, 'XX XXXX ' ] )
Migrating the initialisation system to be completely Python-like. * New: In bootstrap/coriolisEnv.py, add the "etc" directory to the PYTHONPATH as initialization are now Python modules. * New: In Hurricane/analogic, first groundwork for the integration of PIP/MIM/MOM multi-capacitors. Add C++ and Python interface for the allocation matrix and the list of capacities values. * Change: In Hurricane::RegularLayer, add a layer parameter to the constructor so the association between the RegularLayer and it's BasicLayer can readily be done. * Change: In Hurricane::Layer, add a new getCut() accessor to get the cut layer in ViaLayer. * Change: In Hurricane::DataBase::get(), the Python wrapper should no longer consider an error if the data-base has not been created yet. Just return None. * Bug: In Isobar::PyLayer::getEnclosure() wrapper, if the overall enclosure is requested, pass the right parameter to the C++ function. * Change: In AllianceFramework, make public _bindLibraries() and export it to the Python interface. * Change: In AllianceFramework::create(), do not longer call bindLibraries(). This now must be done explicitely and afterwards. * Change: In AllianceFramework::createLibrary() and Environement::addSYSTEM_LIBRARY(), minor bug corrections that I don't recall. * Change: In SearchPath::prepend(), set the selected index to zero and return it. * Change: In CRL::System CTOR, add "etc" to the PYTHONPATH as the configuration files are now organized as Python modules. * New: In PyCRL, export the CRL::System singleton, it's creation is no longer triggered by the one of AllianceFramework. * New: In CRL/etc/, convert most of the configuration files into the Python module format. For now, keep the old ".conf", but that are no longer used. For the real technologies, we cannot keep the directory name as "180" or "45" as it not allowed by Python syntax, so we create "node180" or "node45" instead. Most of the helpers and coriolisInit.py are no longer used now. To be removed in future commits after being sure that everything works... * Bug: In AutoSegment::makeDogleg(AutoContact*), the layer of the contacts where badly computed when one end of the original segment was attached to a non-preferred direction segment (mostly on terminal contacts). Now use the new AutoContact::updateLayer() method. * Bug: In Dijkstra::load(), limit symetric search area only if the net is a symmetric one ! * Change: In Katana/python/katanaInit.py, comply with the new initialisation scheme. * Change: In Unicorn/cgt.py, comply to the new inititalization scheme. * Change: In cumulus various Python scripts remove the call to helpers.staticInitialization() as they are not needed now (we run in only *one* interpreter, so we correctly share all init). In plugins/__init__.py, read the new NDA directory variable. * Bug: In cumulus/plugins/Chip.doCoronafloorplan(), self.railsNb was not correctly managed when there was no clock. * Change: In cumulus/plugins/Configuration.coronaContactArray(), compute the viaPitch from the technology instead of the hard-coded 4.0 lambdas. In Configuration.loadConfiguration(), read the "ioring.py" from the new user's settings module. * Bug: In stratus.dpgen_ADSB2F, gives coordinates translated into DbU to the XY functions. In st_model.Save(), use the VstUseConcat flag to get correct VST files. In st_net.hur_net(), when a net is POWER/GROUND or CLOCK also make it global. * Change: In Oroshi/python/WIP_Transistor.py, encapsulate the generator inside a try/except block to get prettier error (and stop at the first).
2019-10-28 12:09:14 -05:00
add( name='antihash0.32'
, bits=[ ' XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXXXX XXXXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXXXX XXXXXXXXXXXX'
, 'XXXX XXXXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXXXX XXXXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX '
, ' XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXXXX XXXXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXXXX XXXXXXXXXXXX'
, 'XXXX XXXXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXXXX XXXXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX ' ] )
add( name='antihash1.32'
, bits=[ 'XXXX XXXXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXXXX XXXXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX '
, ' XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXXXX XXXXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXXXX XXXXXXXXXXXX'
, 'XXXX XXXXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXXXX XXXXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX '
, ' XXXXXXXXXXXXXXX XXXXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXXXX XXXXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXXXX XXXXXXXXXXXX' ] )
add( name='poids2.32'
, bits=[ ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' ' ] )
add( name='poids4.32'
, bits=[ ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' '
, ' '
, ' XX XX '
, ' XX XX '
, ' ' ] )
add( name='antipoids2.32'
, bits=[ ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' '
, ' '
, ' XX XX XX XX '
, ' XX XX XX XX '
, ' ' ] )
add( name='antislash.32'
, bits=[ 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X'
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X' ] )
add( name='antislash2.32'
, bits=[ 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X ' ] )
add( name='antislash3.32'
, bits=[ ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X ' ] )
add( name='antislash4.32'
, bits=[ ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X ' ] )
add( name='antislash5.32'
, bits=[ ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, ' X X '
, 'X X ' ] )
add( name='diffusion.32'
, bits=[ 'XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX'
, 'X XXXXXXXXXX XXXXXXXXX'
, 'XX XXXXXXXXXX XXXXXXXX'
, 'XXX XXXXXXXXXX XXXXXXX'
, 'XXXX XXXXXXXXXX XXXXXX'
, 'XXXXX XXXXXXXXXX XXXXX'
, 'XXXXXX XXXXXXXXXX XXXX'
, 'XXXXXXX XXXXXXXXXX XXX'
, 'XXXXXXXX XXXXXXXXXX XX'
, 'XXXXXXXXX XXXXXXXXXX X'
, 'XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX '
, ' XXXXXXXXXX XXXXXXXXXX'
, 'X XXXXXXXXXX XXXXXXXXX'
, 'XX XXXXXXXXXX XXXXXXXX'
, 'XXX XXXXXXXXXX XXXXXXX'
, 'XXXX XXXXXXXXXX XXXXXX'
, 'XXXXX XXXXXXXXXX XXXXX'
, 'XXXXXX XXXXXXXXXX XXXX'
, 'XXXXXXX XXXXXXXXXX XXX'
, 'XXXXXXXX XXXXXXXXXX XX'
, 'XXXXXXXXX XXXXXXXXXX X' ] )
add( name='active.32'
, bits=[ ' XXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXX XXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXX XXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXX '
, ' XXXXXXXXXXXXX XXXXXXXXXXXXX '
, ' XXXXXXXXXXXXX XXXXXXXXXXXXX '
, ' XXXXXXXXXXXXX XXXXXXXXXXXXX'
, 'X XXXXXXXXXXXXX XXXXXXXXXXXX'
, 'XX XXXXXXXXXXXXX XXXXXXXXXXX'
, 'XXX XXXXXXXXXXXXX XXXXXXXXXX'
, 'XXXX XXXXXXXXXXXXX XXXXXXXXX'
, 'XXXXX XXXXXXXXXXXXX XXXXXXXX'
, 'XXXXXX XXXXXXXXXXXXX XXXXXXX'
, 'XXXXXXX XXXXXXXXXXXXX XXXXXX'
, 'XXXXXXXX XXXXXXXXXXXXX XXXXX'
, 'XXXXXXXXX XXXXXXXXXXXXX XXXX'
, 'XXXXXXXXXX XXXXXXXXXXXXX XXX'
, 'XXXXXXXXXXX XXXXXXXXXXXXX XX'
, 'XXXXXXXXXXXX XXXXXXXXXXXXX X'
, 'XXXXXXXXXXXXX XXXXXXXXXXXXX '
, ' XXXXXXXXXXXXX XXXXXXXXXXXXX '
, ' XXXXXXXXXXXXX XXXXXXXXXXXXX ' ] )