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
#!/usr/bin/python
2019-12-12 07:23:35 -06:00
print " SOURCE CapacitorMatrix "
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
import sys
from Hurricane import *
from CRL import *
from math import sqrt , ceil
from helpers . io import ErrorMessage as Error
from helpers import trace
from CapacitorUnit import CapacitorUnit
import helpers
import oroshi
import numpy
## Draws the layout of a compact capacitor or a matrix of adjacent identical capacitors. The matrix can be composed of one type of capacitors, either Poly-Poly or Metal-Metal in 350 nm AMS CMOS technology.
# When matching mode is off, every adjacent plates of any consecutive elementary capacitors are connected to each other using vertical routing layers.
# Otherwise, when matching mode is on, any of elementary capacitors can belong to, \f$ C_1 \f$ or \f$ C_2 \f$ according to the entered matching scheme. Thus, routing is not done in this class.
# In both modes, the complete routing process is done using the \c RoutCapacitor class.
class CapacitorStack ( CapacitorUnit ) :
rules = oroshi . getRules ( )
## This is the class constructor. Basically, the class there are three categories of attributes. There are the ones related to the capacitor caracteristics, its type, dimensions. Also, there are attributes to parametrize the class into matching mode or not and there are other attributes realted to the layout varibales. The class has defaut input values, thus, in this constructor, there are two "sub-constructors" according to the entered input parameters. The class attributes are :
#
# \param device The Hurricane AMS device into which the layout is drawn.
# \param capacitance The value of the capacitor, expressed in femto Farad (fF).
# \param capacitorType Can be MIM or PIP type capacitor.
# \param abutmentPosition Refers to the abscissa (XMin) of the bottom left corner of the abutment Box.
# \param abutmentBoxYMin Refers to the ordinate (YMin) of the bottom left corner of the abutment Box.
#
# Except the two last arguments, all the parameters are common with the CapacitorUnit class because the \c CapacitorStack constructor calls the mother class constructor to create either a compact capacitor of \c capacitance value or \c rowNumber* \c columnNumber unity capacitors.
#
# \param rowNumber Number of rows in the matrix of capacitors.
# \param columnNumber Number of columns in the matrix of capacitors.
def __init__ ( self , device , capacitance , capacitorType , abutmentBoxPosition , nets , unitCap = 0 , matrixDim = [ 1 , 1 ] , matchingMode = False , matchingScheme = [ ] , dummyRing = False , dummyElement = False ) :
self . device = device
self . capacitorType = capacitorType
2019-12-12 07:23:35 -06:00
print ( " self.capacitorType0 " , self . capacitorType )
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
self . matrixDim = { " columns " : matrixDim [ 1 ] , " rows " : matrixDim [ 0 ] }
2019-12-12 07:23:35 -06:00
self . unitCapDim = self . __computeCapDim__ ( unitCap , capacitorType )
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
2019-12-12 07:23:35 -06:00
self . doMatrix = False
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
self . abutmentBox = Box ( )
self . abutmentBoxPosition = { " XMin " : abutmentBoxPosition [ 0 ] , " YMin " : abutmentBoxPosition [ 1 ] }
self . nets = nets
self . matchingMode = matchingMode
self . dummyRing = dummyRing
self . dummyElement = dummyElement
self . capacitorsNumber = len ( capacitance )
self . matchingScheme = matchingScheme
self . dummyRingPosition = { }
self . abutmentBox_spacing = 0
self . vRoutingTrack_width = 0
if self . __areInputDataOK__ ( capacitance ) == True :
2019-12-12 07:23:35 -06:00
if self . matchingMode == False :
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
self . compactCapDim = self . __computeCapDim__ ( capacitance [ 0 ] , capacitorType )
if unitCap == 0 :
self . __initGivenZeroUnitCap__ ( capacitance [ 0 ] )
elif unitCap < > 0 and CapacitorUnit . __isCapacitorUnitOK__ ( self , self . unitCapDim ) :
self . __initGivenNonZeroUnitCap__ ( capacitance [ 0 ] , unitCap )
else : raise Error ( 1 , ' __init__(): Impossible to draw the unit capacitor, dimensions are either too large or too small, " %s " . ' % self . unitCapDim )
else :
if unitCap == 0 :
self . __initGivenZeroUnitCapInMatchingMode__ ( capacitance )
elif unitCap < > 0 and CapacitorUnit . __isCapacitorUnitOK__ ( self , self . unitCapDim ) :
self . __initGivenNonZeroUnitCapInMatchingMode__ ( capacitance , unitCap )
else : raise Error ( 1 , ' __init__(): Impossible to draw the unit capacitor, dimensions are either too large or too small, " %s " . ' % self . unitCapDim )
return
def setRules ( self ) :
CapacitorUnit . setRules ( self )
CapacitorUnit . __setattr__ ( self , " minWidth_vRoutingTrack " , CapacitorStack . rules . minWidth_metal3 )
CapacitorUnit . __setattr__ ( self , " minSpacing_vRoutingTrack " , CapacitorStack . rules . minSpacingWide1_metal3 )
CapacitorUnit . __setattr__ ( self , " minWidth_vRoutingTrackCut " , CapacitorStack . rules . minWidth_cut2 )
CapacitorUnit . __setattr__ ( self , " minSpacing_vRoutingTrackCut " , CapacitorStack . rules . minSpacing_cut2 )
CapacitorUnit . __setattr__ ( self , " minEnclosure_vRoutingTrackCut " , CapacitorStack . rules . minEnclosure_metal3_cut2 )
if self . capacitorType == ' MIMCap ' :
CapacitorUnit . __setattr__ ( self , " minWidth_hRoutingLayer_topPlate_cut " , CapacitorStack . rules . minWidth_cut2 )
CapacitorUnit . __setattr__ ( self , " minEnclosure_hRoutingLayer_topPlate_cut " , CapacitorStack . rules . minEnclosure_metal2_cut2 )
elif self . capacitorType == ' PIPCap ' :
CapacitorUnit . __setattr__ ( self , " minWidth_hRoutingLayer_topPlate_cut " , CapacitorStack . rules . minWidth_cut1 )
CapacitorUnit . __setattr__ ( self , " minEnclosure_hRoutingLayer_topPlate_cut " , CapacitorStack . rules . minEnclosure_metal2_cut1 )
else : raise Error ( 1 , ' setRules() : Unsupported capacitor type : %s . ' % self . capacitorType )
return
def __initMatchingMode__ ( self ) :
self . vRoutingTrack_width = max ( self . minWidth_vRoutingTrack , 2 * self . minEnclosure_vRoutingTrackCut + self . minWidth_vRoutingTrackCut , self . minWidth_hRoutingLayer_topPlate_cut + 2 * self . minEnclosure_hRoutingLayer_topPlate_cut )
2019-12-12 07:23:35 -06:00
if ( self . capacitorsNumber % 2 == 0 ) : [ factor1 , factor2 ] = [ self . capacitorsNumber , ( self . capacitorsNumber + 1 ) ]
if ( self . capacitorsNumber % 2 != 0 ) : [ factor1 , factor2 ] = [ self . capacitorsNumber + 1 , self . capacitorsNumber + 2 ]
self . abutmentBox_spacing = factor1 * self . vRoutingTrack_width + factor2 * self . minSpacing_vRoutingTrack
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
return
def __initMatrixMode__ ( self , capacitance , unitCap ) :
[ self . capacitance , self . unitCapacitance , self . doMatrix ] = [ capacitance , unitCap , True ]
return
def __initGivenZeroUnitCap__ ( self , capacitance ) :
if ( self . matrixDim . values ( ) == [ 1 , 1 ] and CapacitorUnit . __isCapacitorUnitOK__ ( self , self . compactCapDim ) ) :
[ self . capacitance , self . unitCapDim ] = [ capacitance , self . compactCapDim ]
2019-12-12 07:23:35 -06:00
elif ( self . matrixDim . values ( ) == [ 1 , 1 ] and not ( CapacitorUnit . __isCapacitorUnitOK__ ( self , self . compactCapDim ) ) ) :
raise Error ( 1 , ' __init__(): Impossible to draw the capacitor, dimensions are either too large or too small, " %s " . ' % self . compactCapDim ) #com2 : use to physical
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
elif ( self . matrixDim [ " columns " ] > 1 or self . matrixDim [ " rows " ] > 1 ) :
unitCapacitance = capacitance / ( self . matrixDim [ " columns " ] * self . matrixDim [ " rows " ] )
unitCapDim = self . __computeCapDim__ ( unitCapacitance , self . capacitorType )
if CapacitorUnit . __isCapacitorUnitOK__ ( self , unitCapDim ) == True :
self . unitCapDim = unitCapDim
[ self . unitCapacitance , self . capacitance , self . doMatrix ] = [ unitCapacitance , capacitance , True ]
else : raise Error ( 1 , ' __init__(): Impossible to draw the unit capacitor, dimensions are either too large or too small, " %s " . ' % self . unitCapDim ) #com2 : use to physical
return
def __initGivenNonZeroUnitCap__ ( self , capacitance , unitCap ) :
if ( self . matrixDim [ " columns " ] > 1 or self . matrixDim [ " rows " ] > 1 ) : # jai donne les dim de la matrice
if self . matrixDim . values ( ) [ 0 ] * self . matrixDim . values ( ) [ 1 ] == capacitance / unitCap :
self . __initMatrixMode__ ( capacitance , unitCap )
else : raise Error ( 1 , ' __init__() : Matrix dimensions and unit capacitance are not compatible : " capacitance %d divides by unit capacitance %s <> columns %d * rows %d " . ' % ( capacitance , unitCap , self . matrixDim [ " columns " ] , self . matrixDim [ " rows " ] ) )
else : # self.matrixDim.values() == [1,1] : # jai donne ou jai ps donne
if capacitance == unitCap : #compact
[ self . capacitance , self . unitCapDim ] = [ capacitance , self . compactCapDim ]
print ( " capa " , capacitance )
elif capacitance < > unitCap : #matrice
self . __initMatrixMode__ ( capacitance , unitCap )
self . matrixDim = { " columns " : int ( sqrt ( capacitance / unitCap ) ) , " rows " : int ( sqrt ( capacitance / unitCap ) ) } # ici mettre toutes les combi si matching mode = [] sinon utiliser la meme combi que matching scheme
else : raise Error ( 1 , ' __initGivenNonZeroUnitCap__ : capacitance must be multiple of unit capacitance ' )
return
def __initGivenZeroUnitCapInMatchingMode__ ( self , capacitance ) :
if self . matrixDim . values ( ) == [ 1 , 1 ] or ( self . matrixDim [ " columns " ] == len ( self . matchingScheme [ 0 ] ) and self . matrixDim [ " rows " ] == len ( self . matchingScheme ) ) :
unitCapList = self . computeUnitCap ( capacitance )
if len ( list ( numpy . unique ( unitCapList ) ) ) == 1 :
unitCapDim = self . __computeCapDim__ ( unitCapList [ 0 ] , self . capacitorType )
if CapacitorUnit . __isCapacitorUnitOK__ ( self , unitCapDim ) == True :
self . unitCapDim = unitCapDim
self . __initMatrixMode__ ( capacitance , unitCapList [ 0 ] )
if self . matrixDim . values ( ) == [ 1 , 1 ] : self . matrixDim = { " columns " : len ( self . matchingScheme [ 0 ] ) , " rows " : len ( self . matchingScheme ) }
else : raise Error ( 1 , ' __initGivenZeroUnitCapInMatchingMode__() : Impossible to draw unit capacitor, dimensions are either too large or too small, " %s " . ' % unitCapDim )
else : raise Error ( 1 , ' __initGivenZeroUnitCapInMatchingMode__() : Not all capacitances are multiple of the unit capacitor. ' )
else : raise Error ( 1 , ' __initGivenZeroUnitCapInMatchingMode__() : Please check compatibility between matrix dimensions and matching scheme dimensions. Both must be equal. ' )
return
def __initGivenNonZeroUnitCapInMatchingMode__ ( self , capacitance , unitCap ) :
if CapacitorUnit . __isCapacitorUnitOK__ ( self , self . unitCapDim ) == True :
if self . matrixDim . values ( ) == [ 1 , 1 ] or ( self . matrixDim [ " columns " ] == len ( self . matchingScheme [ 0 ] ) and self . matrixDim [ " rows " ] == len ( self . matchingScheme ) ) :
if self . evaluateUnitCap ( capacitance , unitCap ) == True :
self . __initMatrixMode__ ( capacitance , unitCap )
if self . matrixDim . values ( ) == [ 1 , 1 ] : self . matrixDim = { " columns " : len ( self . matchingScheme [ 0 ] ) , " rows " : len ( self . matchingScheme ) }
else : raise Error ( 1 , ' __initGivenNonZeroUnitCapInMatchingMode__() : Non valid unit capacitor value considering the entered matching scheme. Please make sure that capacitors values are all multiples of unit capacitor. ' )
else : raise Error ( 1 , ' __initGivenNonZeroUnitCapInMatchingMode__() : Please check compatibility between matrix dimensions and matching scheme dimensions. Both must be equal. ' )
else : raise Error ( 1 , ' __initGivenNonZeroUnitCapInMatchingMode__() : Impossible to draw unit capacitor, dimensions are either too large or too small, " %s " . ' % self . unitCapDim )
return
def __areMatrixDimOK__ ( self ) : return True if self . matrixDim . values ( ) > 0 else False
def computeUnitCap ( self , capacitance ) :
unitCapList = [ ]
for k in range ( 0 , self . capacitorsNumber ) :
unitCapList . append ( capacitance [ k ] / self . capacitorIdOccurence ( k ) )
return unitCapList
def evaluateUnitCap ( self , capacitance , unitCap ) :
state = True
for k in range ( 0 , self . capacitorsNumber ) :
print ( ' self.capacitorIdOccurence( k ) ' , self . capacitorIdOccurence ( k ) )
factor = capacitance [ k ] / unitCap
print ( ' factor ' , factor )
if factor != self . capacitorIdOccurence ( k ) : state = False
return state
## \return True if the drawn capacitor is a compact one. This function is useful when an instance is called in another class. \b Example : when the matrix or the compact capacitors are to be fully routed.
def __isUnitCap__ ( self ) : return True if not self . doMatrix else False
## \return \c True if the matching scheme specifications are correct. Specifications are :
# - Similar number of elements as total number of elementary capacitor in the matrix.
# - Equal number of affected capacitors to C1 as to C2.
# - Capacitor identifiers equal to '1' or '2' only.
# - Otherwise, the function returns \c False.
def __isMatchingSchemeOK__ ( self ) :
state = True
columsElementsNumber = [ len ( self . matchingScheme [ k ] ) for k in range ( 0 , len ( self . matchingScheme ) ) ]
if len ( list ( numpy . unique ( columsElementsNumber ) ) ) > 1 :
state = False
else :
[ matrixDim , matchingSchemeDim ] = [ self . matrixDim [ " columns " ] * self . matrixDim [ " rows " ] , len ( self . matchingScheme ) * len ( self . matchingScheme [ 0 ] ) ]
comparaison = [ self . matrixDim [ key ] > 1 for key in self . matrixDim . keys ( ) ]
if ( True in comparaison ) and ( matchingSchemeDim != matrixDim ) : state = False
return state
## \return occurence of capacitor identifier in the entered matching scheme. This is useful to verify that \c self.matchingScheme is correct.
def capacitorIdOccurence ( self , capacitorIdentifier ) :
occurence = sum ( element . count ( capacitorIdentifier ) for element in self . matchingScheme )
return occurence
def __areInputDataOK__ ( self , capacitance ) :
state = False
if ( self . __areMatrixDimOK__ ( ) == True ) :
if self . matchingMode in [ False , True ] and self . dummyRing in [ False , True ] and self . dummyElement in [ False , True ] :
[ matchingSchemeCapIds , capacitanceIds ] = [ list ( numpy . unique ( self . matchingScheme ) ) , range ( 0 , self . capacitorsNumber ) ]
if ( self . matchingScheme != [ ] and set ( matchingSchemeCapIds ) == set ( capacitanceIds ) ) or ( self . matchingScheme == [ ] and len ( capacitance ) == 1 ) :
2019-12-12 07:23:35 -06:00
print ( " len(self.nets) " , len ( self . nets ) )
print ( " self.capacitorsNumber + 1 " , self . capacitorsNumber + 1 )
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
if ( len ( self . nets ) == self . capacitorsNumber + 1 and self . dummyElement == False and self . dummyRing == True ) or ( len ( self . nets ) == self . capacitorsNumber and self . dummyElement == False and self . dummyRing == False ) or ( len ( self . nets ) == self . capacitorsNumber and self . dummyElement == True and self . dummyRing == True ) or ( len ( self . nets ) == self . capacitorsNumber and self . dummyElement == True and self . dummyRing == False ) :
if ( self . matchingMode == True and self . __isMatchingSchemeOK__ ( ) ) or ( self . matchingMode == False and self . matchingScheme == [ ] ) :
state = True
else : raise Error ( 1 , ' __areInputDataOK__(): Please check compatibility of the entered parameters (Matching mode, matching scheme, capacitance). It must be either equal to (False, [], one capacitance value) or ( True, matching scheme, capacitance values as much as there are capacitor ids in matching scheme ). The entered parameters are ( %s , %s , %s ). ' % ( self . matchingMode , self . matchingScheme , capacitance ) ) #com2 : tester
2019-12-12 07:23:35 -06:00
else : raise Error ( 1 , ' __areInputDataOK__() : Nets number, %s , is incompatible with number of capacitors to be drawn, %s . ' % ( self . netsNumber , self . capacitorsNumber ) )
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
else : raise Error ( 1 , ' __areInputDataOK__() : Please check compatibility between matching scheme elements, %s , and capacitance indexes, %s . They must be identical. Otherwise, when matching scheme is " False " , capacitance indexes must be [0]. ' % ( matchingSchemeCapIds , capacitanceIds ) )
else : raise Error ( 1 , ' __areInputDataOK__() : Matching mode, %s , dummy ring, %s , and dummy element, %s , must be all either " True " or " False " . ' % ( self . matchingMode , self . dummyRing , self . dummyElement ) )
else : raise Error ( 1 , ' __areInputDataOK__(): Both matrix dimensions " %s " must be positive. ' % self . matrixDim . keys ( ) )
return state
## Draw the compact or matrix of capacitors. First, . Second, . Finally, .
def create ( self , bbMode = False ) :
UpdateSession . open ( )
drawnCapacitor = { }
self . setRules ( )
if self . matchingMode == True :
self . __initMatchingMode__ ( )
self . drawAbutmentBox ( self . abutmentBox_spacing )
if bbMode == True :
output = self . computeBondingBoxDimensions ( )
print ( ' output ' , output )
elif bbMode == False :
drawnCapacitor = self . drawCapacitorStack ( )
output = drawnCapacitor
else : raise Error ( 1 , ' create(): The bonding box mode parameter, " bbMode " must be either True or False : %s . ' % bbMode )
UpdateSession . close ( )
return output
def drawCapacitorStack ( self ) :
drawnCapacitor = [ ]
bottomPlateRLayer = CapacitorUnit . getLayers ( self ) [ " bottomPlateRLayer " ]
topPlateRLayer = CapacitorUnit . getLayers ( self ) [ " topPlateRLayer " ]
if self . doMatrix == True :
drawnCapacitor = self . capacitorMatrix ( self . abutmentBox_spacing )
if self . matchingMode == False :
if self . dummyRing == True :
drawnActiveCapacitor = [ drawnCapacitor [ 1 ] [ 1 : len ( drawnCapacitor [ 1 ] ) - 1 ] ]
for i in range ( 2 , self . matrixDim [ " rows " ] + 1 ) :
drawnActiveCapacitor . append ( drawnCapacitor [ i ] [ 1 : len ( drawnCapacitor [ 1 ] ) - 1 ] )
else : drawnActiveCapacitor = drawnCapacitor
self . drawBottomPlatesRLayers ( bottomPlateRLayer , drawnActiveCapacitor )
self . drawTopPlatesRLayers ( topPlateRLayer , drawnActiveCapacitor )
else :
drawnCapacitor = CapacitorUnit ( self . device , self . capacitance , self . capacitorType , [ self . abutmentBoxPosition [ " XMin " ] , self . abutmentBoxPosition [ " YMin " ] ] )
drawnCapacitor . create ( self . nets [ 0 ] [ 0 ] , self . nets [ 0 ] [ 1 ] )
return drawnCapacitor
## Iteratively draws a horizontal or vertical line of capacitors according to the \c direction parameter. An exception is raised if the specified direction is different from \c {'horizontal','vertical'}. At every iteration, an instance of the CapacitorUnit class is created and its layout is drawn.
# \return a list containing the drawn capacitors.
# \param dy the vertical position of the first cut in cut line.
# \remarks An exception is raised if the specified direction is different from \c {'horizontal','vertical'}
def capacitorLine ( self , dy , abutmentBox_spacing , matchingSchemeRowIndex = 0 ) :
2019-12-12 07:23:35 -06:00
print ( " self.capacitorType " , self . capacitorType )
line = [ CapacitorUnit ( self . device , self . capacitorType , [ self . abutmentBoxPosition [ " XMin " ] , dy ] , capacitance = self . unitCapacitance ) ]
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
self . createElementInCapacitorLine ( line , matchingSchemeRowIndex , 0 )
limit = self . matrixDim [ " columns " ] + 2 if self . dummyRing == True else self . matrixDim [ " columns " ]
for j in range ( 1 , limit ) :
2019-12-12 07:23:35 -06:00
line . append ( CapacitorUnit ( self . device , self . capacitorType , [ line [ j - 1 ] . abutmentBox . getXMax ( ) + abutmentBox_spacing , dy ] , capacitance = self . unitCapacitance ) )
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
self . createElementInCapacitorLine ( line , matchingSchemeRowIndex , j )
return line
def createElementInCapacitorLine ( self , capacitorList , matchingSchemeRowIndex , capListIndex ) :
if self . matchingMode == False :
capacitorList [ capListIndex ] . create ( self . nets [ 0 ] [ 0 ] , self . nets [ 0 ] [ 1 ] )
else :
if self . dummyRing == True :
if ( matchingSchemeRowIndex == 0 or matchingSchemeRowIndex == self . matrixDim [ " rows " ] + 1 or capListIndex == 0 or capListIndex == self . matrixDim [ " columns " ] + 1 ) :
[ t , b ] = [ self . nets [ - 1 ] [ 0 ] , self . nets [ - 1 ] [ 1 ] ]
else :
k = self . matchingScheme [ matchingSchemeRowIndex - 1 ] [ capListIndex - 1 ]
[ t , b ] = [ self . nets [ k ] [ 0 ] , self . nets [ k ] [ 1 ] ]
else :
k = self . matchingScheme [ matchingSchemeRowIndex ] [ capListIndex ]
[ t , b ] = [ self . nets [ k ] [ 0 ] , self . nets [ k ] [ 1 ] ]
capacitorList [ capListIndex ] . create ( t , b )
return
## Draws a matrix of identical capacitors. The matrix is iterativelly constructed. At every iteration, a new horizontal line of capacitors is drawn.
# \return a nested list of elementary capacitors.
def capacitorMatrix ( self , abutmentBox_spacing = 0 ) :
#print("capMatrix", nets)
matrix = [ self . capacitorLine ( self . abutmentBoxPosition [ " YMin " ] , abutmentBox_spacing , 0 ) ]
limit = self . matrixDim [ " rows " ] + 2 if self . dummyRing == True else self . matrixDim [ " rows " ]
for i in range ( 1 , limit ) :
matrix . append ( self . capacitorLine ( matrix [ i - 1 ] [ - 1 ] . abutmentBox . getYMax ( ) + abutmentBox_spacing , abutmentBox_spacing , i ) )
return matrix
def dummyLine ( self , direction , dx , dy ) :
2019-12-12 07:23:35 -06:00
dummyList = [ CapacitorUnit ( self . device , self . capacitorType , [ dx , dy ] , capacitance = self . unitCapacitance ) ]
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
dummyList [ 0 ] . create ( self . nets [ - 1 ] [ 0 ] , self . nets [ - 1 ] [ 1 ] )
if direction == ' vertical ' :
for i in range ( 1 , self . matrixDim [ " rows " ] + 2 ) :
2019-12-12 07:23:35 -06:00
dummyList . append ( CapacitorUnit ( self . device , self . capacitorType , [ dx , dummyList [ i - 1 ] . abutmentBox . getYMax ( ) + self . abutmentBox_spacing ] , capacitance = self . unitCapacitance ) )
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
dummyList [ i ] . create ( self . nets [ - 1 ] [ 0 ] , self . nets [ - 1 ] [ 1 ] )
elif direction == ' horizontal ' :
for j in range ( 1 , self . matrixDim [ " columns " ] + 2 ) :
print ( ' j ' , j )
2019-12-12 07:23:35 -06:00
dummyList . append ( CapacitorUnit ( self . device , self . capacitorType , [ dummyList [ j - 1 ] . abutmentBox . getXMax ( ) + self . abutmentBox_spacing , dy ] , capacitance = self . unitCapacitance ) )
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
dummyList [ j ] . create ( self . nets [ - 1 ] [ 0 ] , self . nets [ - 1 ] [ 1 ] )
else : raise Error ( 1 , ' dummyLine() : Direction must be either " horizontal " or " vertical " . ' % direction )
return dummyList
def computeAbutmentBoxDimensions ( self , abutmentBox_spacing ) :
abutmentBoxDimensions = { }
capDim = self . getCapDim ( )
[ widthFactor1 , widthFactor2 ] = [ self . matrixDim [ " columns " ] , ( self . matrixDim [ " columns " ] - 1 ) ] if self . dummyRing == False else [ self . matrixDim [ " columns " ] + 2 , ( self . matrixDim [ " columns " ] + 1 ) ]
[ heightFactor1 , heightFactor2 ] = [ self . matrixDim [ " rows " ] , ( self . matrixDim [ " rows " ] - 1 ) ] if self . dummyRing == False else [ self . matrixDim [ " rows " ] + 2 , ( self . matrixDim [ " rows " ] + 1 ) ]
abutmentBoxDimElement = CapacitorUnit . computeAbutmentBoxDimensions ( self , capDim )
abutmentBoxWidth = widthFactor1 * abutmentBoxDimElement [ " width " ] + widthFactor2 * abutmentBox_spacing
abutmentBoxHeight = heightFactor1 * abutmentBoxDimElement [ " height " ] + heightFactor2 * abutmentBox_spacing
abutmentBoxDimensions = { " XMin " : self . abutmentBoxPosition [ " XMin " ] , " YMin " : self . abutmentBoxPosition [ " YMin " ] , " width " : abutmentBoxWidth , " height " : abutmentBoxHeight , " surface " : abutmentBoxWidth * abutmentBoxHeight }
return abutmentBoxDimensions
## Draws the abutment box of the matrix or campact capacitor.
def drawAbutmentBox ( self , abutmentBox_spacing = 0 ) :
abutmentBoxDimensions = self . computeAbutmentBoxDimensions ( abutmentBox_spacing )
self . abutmentBox = Box ( self . abutmentBoxPosition [ " XMin " ] , self . abutmentBoxPosition [ " YMin " ] , abutmentBoxDimensions [ " width " ] + self . abutmentBoxPosition [ " XMin " ] , abutmentBoxDimensions [ " height " ] + self . abutmentBoxPosition [ " YMin " ] )
self . device . setAbutmentBox ( self . abutmentBox )
return
def computeBondingBoxDimensions ( self ) :
bondingBoxDimensions = { }
abutmentBoxDimensions = self . computeAbutmentBoxDimensions ( self . abutmentBox_spacing )
for key in abutmentBoxDimensions :
if key != " XMin " and key != " YMin " : bondingBoxDimensions [ key ] = abutmentBoxDimensions [ key ]
return bondingBoxDimensions
## Draws the routing layers connecting the bottom plate in the matrix of capacitors. First, the relative positions of the routing layer is of the is extracted from the elementary capacitor instance. Then, its width is computed in a way to connect adjacent plates. Then, the routing layers are iterativelly drawn.
# The two borders are .
def drawBottomPlatesRLayers ( self , bottomPlateRLayer , drawnCapacitor ) :
[ dySourceBottom , dyTargetBottom ] = [ drawnCapacitor [ 0 ] [ 0 ] . getBotPlateRLayerYMin ( ) , drawnCapacitor [ - 1 ] [ 0 ] . getBotPlateRLayerYMax ( ) ]
if ( self . matrixDim [ " columns " ] > 1 ) :
bottomPlateRLayer_width = ( drawnCapacitor [ 0 ] [ 1 ] . getBotPlateLeftRLayerXMax ( ) - drawnCapacitor [ 0 ] [ 0 ] . getBotPlateRightRLayerXMin ( ) )
bottomMetalXCenters = [ ]
for j in range ( 0 , self . matrixDim [ " columns " ] - 1 ) :
bottomMetalXCenters . append ( drawnCapacitor [ 0 ] [ j ] . getBotPlateRightRLayerXMin ( ) + bottomPlateRLayer_width / 2 )
Vertical . create ( self . nets [ 0 ] [ 1 ] , bottomPlateRLayer , bottomMetalXCenters [ j ] , bottomPlateRLayer_width , dySourceBottom , dyTargetBottom )
bordersXMin = [ drawnCapacitor [ 0 ] [ 0 ] . getBottomPlateLeftCutXMin ( ) , drawnCapacitor [ 0 ] [ - 1 ] . getBottomPlateRightCutXMin ( ) ]
for j in range ( 0 , 2 ) :
Vertical . create ( self . nets [ 0 ] [ 1 ] , bottomPlateRLayer , bordersXMin [ j ] , drawnCapacitor [ 0 ] [ 0 ] . getBotPlateRLayerWidth ( ) , dySourceBottom , dyTargetBottom )
return
## Draws the routing layers connecting the top plates in the matrix of capacitors. First, the relative positions of the routing layers is of the is extracted from the elementary capacitor instance. Then, its width is computed in a way to connect adjacent plates. Then, the routing layers are iterativelly drawn.
# The two borders are .
# \remarks An exception is raised if the number of rows in the matrix is lower than 2.
def drawTopPlatesRLayers ( self , topPlateRLayer , drawnCapacitor ) :
if ( self . matrixDim [ " rows " ] > 1 ) :
for j in range ( 0 , self . matrixDim [ " columns " ] ) :
Vertical . create ( self . nets [ 0 ] [ 0 ] , topPlateRLayer , drawnCapacitor [ 0 ] [ j ] . getTopPlateRLayerXCenter ( ) , drawnCapacitor [ 0 ] [ j ] . getTopPlateRLayerWidth ( ) , drawnCapacitor [ 0 ] [ 0 ] . getTopPlateRLayerYMin ( ) , drawnCapacitor [ - 1 ] [ 0 ] . getTopPlateRLayerYMax ( ) )
#else : print('The matrix does not contain enough rows') #com4 verify if this else is needed
return
## \return The width of the vertical routing tracks in matching mode.
# \remark This function is useful in matching mode, ie., in \C RoutCapacitor class, when routing the two capacitors.
def getVerticalRoutingTrack_width ( self ) : return self . vRoutingTrack_width
def getAbutmentBox_spacing ( self ) : return self . abutmentBox_spacing
## \return A dictionary contaning capacitor matrix's dimensions
def getMatrixDim ( self ) : return self . matrixDim
def getCapDim ( self ) : return self . unitCapDim if self . doMatrix == True else self . compactCapDim
# def getMatchingMode ( self ) : return self.matchingMode
def getVRoutingTrack_spacing ( self ) : return self . minSpacing_vRoutingTrack
def getvRoutingTrack_width ( self ) : return self . vRoutingTrack_width
## \return the matching scheme. The function is useful in \c RoutMatchedCapacitor class to load \c self.matchingScheme attribute.
def getMatchingScheme ( self ) : return self . matchingScheme
def ScriptMain ( * * kw ) :
editor = None
if kw . has_key ( ' editor ' ) and kw [ ' editor ' ] :
editor = kw [ ' editor ' ]
UpdateSession . open ( )
device = AllianceFramework . get ( ) . createCell ( ' capacitor ' )
device . setTerminal ( True )
bottomPlate_net0 = Net . create ( device , ' b0 ' )
bottomPlate_net1 = Net . create ( device , ' b1 ' )
bottomPlate_net2 = Net . create ( device , ' b2 ' )
bottomPlate_net3 = Net . create ( device , ' b3 ' )
bottomPlate_net0 . setExternal ( True )
bottomPlate_net1 . setExternal ( True )
bottomPlate_net2 . setExternal ( True )
bottomPlate_net3 . setExternal ( True )
b0 = device . getNet ( " b0 " )
b1 = device . getNet ( " b1 " )
b2 = device . getNet ( " b2 " )
b3 = device . getNet ( " b3 " )
topPlate_net0 = Net . create ( device , ' t0 ' )
topPlate_net1 = Net . create ( device , ' t1 ' )
topPlate_net2 = Net . create ( device , ' t2 ' )
topPlate_net3 = Net . create ( device , ' t3 ' )
topPlate_net0 . setExternal ( True )
topPlate_net1 . setExternal ( True )
topPlate_net2 . setExternal ( True )
topPlate_net3 . setExternal ( True )
t0 = device . getNet ( " t0 " )
t1 = device . getNet ( " t1 " )
t2 = device . getNet ( " t2 " )
t3 = device . getNet ( " t3 " )
if editor :
UpdateSession . close ( )
editor . setCell ( device )
editor . fit ( )
UpdateSession . open ( )
2019-12-12 07:23:35 -06:00
nets = [ [ t0 , b0 ] , [ t1 , b1 ] , [ t2 , b2 ] ] # [t3, b3] ]
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
capacitorInstance = CapacitorStack ( device , [ 750 , 750 ] , ' MIMCap ' , [ 0 , 0 ] , nets , unitCap = 93 , matrixDim = [ 4 , 4 ] , matchingMode = True , matchingScheme = [ [ 1 , 0 , 1 , 0 ] , [ 0 , 1 , 0 , 1 ] , [ 1 , 0 , 1 , 0 ] , [ 0 , 1 , 0 , 1 ] ] , dummyRing = True )
#capacitorInstance = CapacitorStack( device, [1488], 'MIMCap', [0,0], nets,unitCap = 93, matrixDim = [4,4], dummyRing = True)
#capacitorInstance = CapacitorStack( device, {"C1" : 558, "C2" : 558, "C3" : 372}, 'MIMCap', [0,0], nets, unitCap = 93, matrixDim = [4,4], matchingMode = True, matchingScheme = [ ['C2','C1','C2','C1'] , ['C1','C2','C1','C2'] , ['C2','C1','C2','C1'] , ['C3','C3','C3','C3'] ])
#capacitorInstance = CapacitorStack( device, {"C1" : 558, "C2" : 558, "C3" : 186, "C4" : 186}, 'MIMCap', [0,0], nets, unitCap = 93, matrixDim = [4,4], matchingMode = True, matchingScheme = [ ['C2','C1','C2','C1'] , ['C1','C2','C1','C2'] , ['C2','C1','C2','C1'] , ['C3','C3','C4','C4'] ])
capacitor = capacitorInstance . create ( )
print ( capacitor )
AllianceFramework . get ( ) . saveCell ( device , Catalog . State . Views )
return True