Capacitor & resistor integration in the Slicing Tree.

* New: In Karakaze/Oceane.py, now also read capacitor & resistors parameters.
    In AnalogDesign.readParameters(), get the capacitor parameters from
    Oceane into the "device spec" (dspec). Translate form OSI unit to
    Coriolis units (F -> pF).
* Bug: In Bora::NodeSets::create(), Capacitor matrix parameters where never
    read due to a misplaced curly brace (at the matrixRange dynamic_cast<>
    test).
* Change: In Bora/PyDSlicingNode, now check that the parameter is either
    a StepParameterRange or a MatrixParameterRange.
      Also add a check that the Instance name exists...
* Bug: In Bora::SlicingPlotWidget::updateSelectedPoint(), as we display
    only the transistor parameters in dynamic labels, do not forget to
    skip resistor and capacitor. Otherwise we end up in out of bound
    access in the vector of labels.
This commit is contained in:
Jean-Paul Chaput 2020-01-23 14:07:19 +01:00
parent eea67a9111
commit 057501a8df
12 changed files with 448 additions and 273 deletions

View File

@ -189,7 +189,10 @@ namespace Bora {
{ {
cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl; cdebug_log(535,1) << "HSlicingNode::updateGlobalsize() - " << this << endl;
for ( SlicingNode* child : _children ) child->updateGlobalSize(); for ( SlicingNode* child : _children ) {
cdebug_log(535,0) << "child: " << child << endl;
child->updateGlobalSize();
}
if (not getMaster()) { if (not getMaster()) {
if (getNbChild() == 1) { if (getNbChild() == 1) {

View File

@ -70,7 +70,8 @@ namespace Bora {
TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell ); TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell );
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() ); StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
if (device) { if (device) {
//cdebug_log(536,0) << "createNodeSets for an Analog Device" << endl; cdebug_log(535,0) << "NodeSets:create(): for a Transistor Analog Device" << endl;
if (not stepRange) { if (not stepRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
, getString(device->getName()).c_str() , getString(device->getName()).c_str()
@ -94,30 +95,36 @@ namespace Bora {
MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() ); MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() );
if (mcapacitor) { if (mcapacitor) {
cdebug_log(535,0) << "NodeSets::create(): for a Capacitor Analog Device" << endl;
if (not matrixRange) { if (not matrixRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s."
, getString(mcapacitor->getName()).c_str() , getString(mcapacitor->getName()).c_str()
, getString(stepRange).c_str() , getString(stepRange).c_str()
); );
matrixRange->reset();
do {
MatrixParameter* mp = NULL;
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
mp->setMatrix( &matrixRange->getValue() );
layoutGenerator->setDevice( mcapacitor );
layoutGenerator->drawLayout();
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
matrixRange->progress();
} while ( matrixRange->isValid() );
} }
matrixRange->reset();
do {
MatrixParameter* mp = NULL;
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("matrix"))) != NULL )
mp->setMatrix( &matrixRange->getValue() );
layoutGenerator->setDevice( mcapacitor );
layoutGenerator->drawLayout();
//cerr << " Create BoxSet for Capacitor " << matrixRange->getValue() << endl;
cerr << " Create BoxSet for Capacitor " << endl;
nodeset->push_back( DBoxSet::create( mcapacitor, matrixRange->getIndex(), rg ) );
matrixRange->progress();
} while ( matrixRange->isValid() );
} else { } else {
ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell ); ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell );
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() ); StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
if (device) { if (device) {
cdebug_log(535,0) << "NodeSets::create(): for a Resistor Analog Device" << endl;
if (not stepRange) { if (not stepRange) {
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s." throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
, getString(device->getName()).c_str() , getString(device->getName()).c_str()

View File

@ -18,6 +18,7 @@
#include "crlcore/PyRoutingGauge.h" #include "crlcore/PyRoutingGauge.h"
#include "bora/PyDSlicingNode.h" #include "bora/PyDSlicingNode.h"
#include "bora/PyStepParameterRange.h" #include "bora/PyStepParameterRange.h"
#include "bora/PyMatrixParameterRange.h"
namespace Bora { namespace Bora {
@ -73,8 +74,9 @@ extern "C" {
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." ); PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." );
return NULL; return NULL;
} }
if (not IsPyStepParameterRange(pyParameterRange)) { if ( not IsPyStepParameterRange(pyParameterRange)
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange." ); and not IsPyMatrixParameterRange(pyParameterRange)) {
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange or MatrixParameterRange." );
return NULL; return NULL;
} }
if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) { if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) {
@ -82,10 +84,18 @@ extern "C" {
return NULL; return NULL;
} }
Cell* cell = PYCELL_O( pyCell ); Cell* cell = PYCELL_O( pyCell );
Instance* instance = cell->getInstance( PyString_AsString(pyInstance) ); Instance* instance = cell->getInstance( PyString_AsString(pyInstance) );
ParameterRange* range = ParameterRangeCast( pyParameterRange ); if (not instance) {
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL; ostringstream message;
message << "DSlicingNode.create(): Cell \"" << cell->getName()
<< "\" has no instance named \"" << PyString_AsString(pyInstance) << "\".";
PyErr_SetString( ConstructorError, message.str().c_str() );
return NULL;
}
ParameterRange* range = ParameterRangeCast( pyParameterRange );
RoutingGauge* rg = (pyRoutingGauge) ? PYROUTINGGAUGE_O(pyRoutingGauge) : NULL;
node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), range, rg ) node = DSlicingNode::create( NodeSets::create( instance->getMasterCell(), range, rg )
, UnknownAlignment , UnknownAlignment

View File

@ -16,6 +16,7 @@
#include "bora/PyParameterRange.h" #include "bora/PyParameterRange.h"
#include "bora/PyStepParameterRange.h" #include "bora/PyStepParameterRange.h"
#include "bora/PyMatrixParameterRange.h"
namespace Bora { namespace Bora {
@ -112,7 +113,8 @@ extern "C" {
# if !defined(__PYTHON_MODULE__) # if !defined(__PYTHON_MODULE__)
ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) { ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) {
if (IsPyStepParameterRange(derivedObject)) return PYSTEPPARAMETERRANGE_O(derivedObject); if (IsPyStepParameterRange (derivedObject)) return PYSTEPPARAMETERRANGE_O (derivedObject);
if (IsPyMatrixParameterRange(derivedObject)) return PYMATRIXPARAMETERRANGE_O(derivedObject);
return NULL; return NULL;
} }

View File

@ -396,12 +396,16 @@ namespace Bora {
for( Instance* iInstance : instances ) { for( Instance* iInstance : instances ) {
Cell* model = iInstance->getMasterCell(); Cell* model = iInstance->getMasterCell();
Device* device = dynamic_cast<Device*>(model); Device* device = dynamic_cast<Device*>(model);
cerr << "device:" << device << endl;
if (device) { if (device) {
TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device ); TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device );
if (tf) _gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) ); cerr << "tf:" << tf << endl;
if (tf) {
_gridLabel[i+5]->setDynamicText ( QString("%1" ).arg( tf->getNfing() ) );
i++;
}
} }
i++;
} }
} }

View File

@ -54,6 +54,9 @@ import Katana
import Bora import Bora
helpers.setTraceLevel( 110 )
NMOS = Transistor.NMOS NMOS = Transistor.NMOS
PMOS = Transistor.PMOS PMOS = Transistor.PMOS
PIP = CapacitorFamily.PIP PIP = CapacitorFamily.PIP
@ -350,8 +353,18 @@ class AnalogDesign ( object ):
if not path: return if not path: return
self.parameters.read( path ); self.parameters.read( path );
for dspec in self.devicesSpecs: for dspec in self.devicesSpecs:
if len(dspec) > 2: if dspec[0] == MultiCapacitor:
Cname = dspec[1]
Cparameters = self.parameters.getCapacitor( Cname )
if not Cparameters:
raise Error( 3, [ 'AnalogDesign.readParameters(): Missing parameters for capacity \"%s\".' % Cname ] )
continue
print dspec[5]
dspec[4] = Cparameters.C * 1e+12
trace( 110, '\t- \"%s\" : C:%fpF\n' % (Cname ,dspec[4]) )
else:
Tname = dspec[1].split('_')[0] Tname = dspec[1].split('_')[0]
Tparameters = self.parameters.getTransistor( Tname ) Tparameters = self.parameters.getTransistor( Tname )
if not Tparameters: if not Tparameters:
@ -410,6 +423,8 @@ class AnalogDesign ( object ):
device = dspec[0].create( self.library, dspec[1], dspec[3], len(capaValues) ) device = dspec[0].create( self.library, dspec[1], dspec[3], len(capaValues) )
device.getParameter( 'Layout Styles' ).setValue( dspec[2] ) device.getParameter( 'Layout Styles' ).setValue( dspec[2] )
print device.getParameter( 'matrix' )
device.getParameter( 'matrix' ).setMatrix( dspec[5] )
for i in range(len(capaValues)): for i in range(len(capaValues)):
device.getParameter( 'capacities' ).setValue( i, capaValues[i] ) device.getParameter( 'capacities' ).setValue( i, capaValues[i] )

View File

@ -7,15 +7,31 @@ class Parameters ( object ):
class Transistor ( object ): class Transistor ( object ):
def __init__ ( self, aName ): def __init__ ( self, aName ):
name = aName self.name = aName
L = 0.0 self.L = 0.0
W = 0.0 self.W = 0.0
M = 0 self.M = 0
return
class Capacitor ( object ):
def __init__ ( self, aName ):
self.name = aName
self.C = 0.0
return
class Resistor ( object ):
def __init__ ( self, aName ):
self.name = aName
self.R = 0.0
return return
def __init__ ( self ): def __init__ ( self ):
self.transistors = { } self.transistors = { }
self.capacitors = { }
self.resistors = { }
self.indexToName = { } self.indexToName = { }
return return
@ -54,13 +70,59 @@ class Parameters ( object ):
#def getTransistorM ( self, ref ): return self.getTransistor(ref)[2] #def getTransistorM ( self, ref ): return self.getTransistor(ref)[2]
def addCapacitor ( self, name, value ):
lname = name.lower()
if self.capacitors.has_key(lname):
print 'Duplicated capacitor "%s" (ignored).' % lname
else:
print 'Add capacitor "%s"' % lname
self.capacitors[ lname ] = Parameters.Capacitor( lname )
self.capacitors[ lname ].C = value
return self.capacitors[ lname ]
def getCapacitor ( self, ref ):
capacitor = None
lname = ref.lower()
if self.capacitors.has_key(lname):
capacitor = self.capacitors[lname]
else:
print 'No capacitor named "%s".' % ref
return capacitor
def addResistor ( self, name, value ):
lname = name.lower()
if self.resistors.has_key(lname):
print 'Duplicated resistor "%s" (ignored).' % lname
else:
self.resistors[ lname ] = Parameters.Resistor( lname )
self.resistors[ lname ].R = value
return self.resistors[ lname ]
def getResistor ( self, ref ):
resistor = None
lname = ref.lower()
if self.capactors.has_key(lname):
resistor = self.capactors[lname]
else:
print 'No resistor named "%s".' % ref
return resistor
def read ( self, file ): def read ( self, file ):
reSpecTran = re.compile( r'^\* SPECIFICATIONS DE M(?P<index>\d+)\s+:\s+(?P<name>\w+) \*$' ) reSpecCapa = re.compile( r'^(?P<name>C\w+)\s+(?P<value>.*)$' )
reSpecL = re.compile( r'L_(?P<index>\d+)\s+(?P<float>[0-9.e-]+)' ) reSpecResis = re.compile( r'^(?P<name>R\w+)\s+(?P<value>.*)$' )
reSpecW = re.compile( r'W_(?P<index>\d+)\s+(?P<float>[0-9.e-]+)' ) reSpecTran = re.compile( r'^\* SPECIFICATIONS DE M(?P<index>\d+)\s+:\s+(?P<name>\w+) \*$' )
reSpecM = re.compile( r'M_(?P<index>\d+)\s+(?P<int>\d+)' ) reSpecL = re.compile( r'L_(?P<index>\d+)\s+(?P<float>[0-9.e-]+)' )
reSpecW = re.compile( r'W_(?P<index>\d+)\s+(?P<float>[0-9.e-]+)' )
reSpecM = re.compile( r'M_(?P<index>\d+)\s+(?P<int>\d+)' )
fd = open( file, 'r' ) fd = open( file, 'r' )
for line in fd.readlines(): for line in fd.readlines():
if line.startswith('REGIME_'): continue
m = reSpecTran.match( line[:-1] ) m = reSpecTran.match( line[:-1] )
if m: if m:
@ -93,4 +155,12 @@ class Parameters ( object ):
self.getTransistor(i).M = M self.getTransistor(i).M = M
self.getTransistor(i).W = M * self.getTransistor(i).W self.getTransistor(i).W = M * self.getTransistor(i).W
m = reSpecCapa.match( line[:-1] )
if m:
self.addCapacitor( m.group('name'), float(m.group('value')) )
m = reSpecResis.match( line[:-1] )
if m:
self.addResistor( m.group('name'), float(m.group('value')) )
fd.close() fd.close()

View File

@ -39,6 +39,8 @@ class CapacitorStack( CapacitorUnit ):
# \param columnNumber Number of columns 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 ): def __init__( self, device, capacitance, capacitorType, abutmentBoxPosition, nets, unitCap = 0, matrixDim = [1,1], matchingMode = False, matchingScheme = [], dummyRing = False, dummyElement = False ):
print 'CapacitorStack.__init__()'
print 'matrixDim:', matrixDim
self.device = device self.device = device
self.capacitorType = capacitorType self.capacitorType = capacitorType
@ -62,6 +64,7 @@ class CapacitorStack( CapacitorUnit ):
self.vRoutingTrack_width = 0 self.vRoutingTrack_width = 0
if self.__areInputDataOK__(capacitance) == True : if self.__areInputDataOK__(capacitance) == True :
print 'Input data are OK'
if self.matchingMode == False : if self.matchingMode == False :
self.compactCapDim = self.__computeCapDim__( capacitance[0] , capacitorType ) self.compactCapDim = self.__computeCapDim__( capacitance[0] , capacitorType )
@ -134,24 +137,29 @@ class CapacitorStack( CapacitorUnit ):
def __initGivenZeroUnitCap__( self, capacitance ): def __initGivenZeroUnitCap__( self, capacitance ):
print '__initGivenZeroUnitCap__'
print self.matrixDim.values()
if ( self.matrixDim.values() == [1,1] and CapacitorUnit.__isCapacitorUnitOK__(self, self.compactCapDim) ): if ( self.matrixDim.values() == [1,1] and CapacitorUnit.__isCapacitorUnitOK__(self, self.compactCapDim) ):
print 'Case 1'
[ self.capacitance , self.unitCapDim ] = [ capacitance , self.compactCapDim ] [ self.capacitance , self.unitCapDim ] = [ capacitance , self.compactCapDim ]
elif ( self.matrixDim.values() == [1,1] and not(CapacitorUnit.__isCapacitorUnitOK__( self, self.compactCapDim)) ): 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 raise Error(1, '__init__(): Impossible to draw the capacitor, dimensions are either too large or too small, "%s".' % self.compactCapDim ) #com2 : use to physical
elif ( self.matrixDim["columns"]>1 or self.matrixDim["rows"]>1) : elif ( self.matrixDim["columns"]>1 or self.matrixDim["rows"]>1) :
unitCapacitance = capacitance / (self.matrixDim["columns"]*self.matrixDim["rows"]) unitCapacitance = capacitance / (self.matrixDim["columns"]*self.matrixDim["rows"])
unitCapDim = self.__computeCapDim__( unitCapacitance, self.capacitorType ) unitCapDim = self.__computeCapDim__( unitCapacitance, self.capacitorType )
if CapacitorUnit.__isCapacitorUnitOK__(self, unitCapDim) == True : if CapacitorUnit.__isCapacitorUnitOK__(self, unitCapDim) == True :
print 'This is a mutlicapacitor'
self.unitCapDim = unitCapDim self.unitCapDim = unitCapDim
[ self.unitCapacitance , self.capacitance, self.doMatrix ] = [ unitCapacitance , capacitance, True ] [ self.unitCapacitance , self.capacitance, self.doMatrix ] = [ unitCapacitance , capacitance, True ]
else:
print 'This is a capacitor unit'
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 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 return
@ -181,6 +189,7 @@ class CapacitorStack( CapacitorUnit ):
def __initGivenZeroUnitCapInMatchingMode__( self, capacitance ): def __initGivenZeroUnitCapInMatchingMode__( self, capacitance ):
print '__initGivenZeroUnitCapInMatchingMode__'
if self.matrixDim.values() == [1,1] or (self.matrixDim["columns"] == len(self.matchingScheme[0]) and self.matrixDim["rows"] == len(self.matchingScheme)) : if self.matrixDim.values() == [1,1] or (self.matrixDim["columns"] == len(self.matchingScheme[0]) and self.matrixDim["rows"] == len(self.matchingScheme)) :
@ -237,6 +246,10 @@ class CapacitorStack( CapacitorUnit ):
for k in range(0, self.capacitorsNumber): for k in range(0, self.capacitorsNumber):
unitCapList.append( capacitance[k]/self.capacitorIdOccurence(k) ) unitCapList.append( capacitance[k]/self.capacitorIdOccurence(k) )
print self.capacitorsNumber
print 'capacitance', capacitance
print 'unitCapList', unitCapList
print '============='
return unitCapList return unitCapList
@ -344,7 +357,8 @@ class CapacitorStack( CapacitorUnit ):
elif bbMode == False : elif bbMode == False :
drawnCapacitor = self.drawCapacitorStack( ) drawnCapacitor = self.drawCapacitorStack( )
output = drawnCapacitor output = drawnCapacitor
else :raise Error(1, 'create(): The bonding box mode parameter, "bbMode" must be either True or False : %s.' %bbMode ) else:
raise Error(1, 'create(): The bonding box mode parameter, "bbMode" must be either True or False : %s.' %bbMode )
UpdateSession.close () UpdateSession.close ()
@ -372,7 +386,7 @@ class CapacitorStack( CapacitorUnit ):
self.drawTopPlatesRLayers ( topPlateRLayer , drawnActiveCapacitor ) self.drawTopPlatesRLayers ( topPlateRLayer , drawnActiveCapacitor )
else: else:
drawnCapacitor = CapacitorUnit( self.device, self.capacitance, self.capacitorType, [self.abutmentBoxPosition["XMin"], self.abutmentBoxPosition["YMin"]] ) drawnCapacitor = CapacitorUnit( self.device, self.capacitorType, [self.abutmentBoxPosition["XMin"], self.abutmentBoxPosition["YMin"]], self.capacitance )
drawnCapacitor.create( self.nets[0][0], self.nets[0][1] ) drawnCapacitor.create( self.nets[0][0], self.nets[0][1] )
return drawnCapacitor return drawnCapacitor

View File

@ -1,20 +1,25 @@
#!/usr/bin/python #!/usr/bin/python
print "SOURCE RouteCapacitorSingle"
import sys import sys
from Hurricane import * import numpy
from CRL import * from Hurricane import *
from math import sqrt, ceil from CRL import *
from math import sqrt, ceil
import helpers import helpers
from helpers import ErrorMessage as Error from helpers.io import ErrorMessage as Error
from helpers import trace from helpers import trace
import oroshi import oroshi
from CapacitorFinal6 import CapacitorUnit from CapacitorUnit import CapacitorUnit
from CapacitorMatrix20 import CapacitorStack from CapacitorMatrix import CapacitorStack
## Routs a compact or a matrix of capacitors by connecting it to routing tracks. For a fixed instance, only one type of capacitor is supported at a time, either the Poly-Poly type or Metal-Metal in 350 nm AMS CMOS technology. ## Routs a compact or a matrix of capacitors by connecting it to routing tracks. For a fixed instance, only one type of capacitor is supported at a time, either the Poly-Poly type or Metal-Metal in 350 nm AMS CMOS technology.
# The dummy mode is also supported. # The dummy mode is also supported.
# The dummyRing mode is not yet supported.
def toDbU ( l ): return DbU.fromPhysical( l, DbU.UnitPowerMicro ) def toDbU ( l ): return DbU.fromPhysical( l, DbU.UnitPowerMicro )
def toPhY ( l ): return DbU.toPhysical ( l, DbU.UnitPowerMicro )
def doBreak( level, message ): def doBreak( level, message ):
UpdateSession.close() UpdateSession.close()
@ -23,7 +28,7 @@ def doBreak( level, message ):
helpers.staticInitialization( True ) helpers.staticInitialization( True )
class RoutCapacitor( CapacitorUnit ): class RouteCapacitorSingle( CapacitorUnit ):
rules = oroshi.getRules() rules = oroshi.getRules()
@ -39,54 +44,54 @@ class RoutCapacitor( CapacitorUnit ):
# \param xPlateRLayer_width A dictionary containing the widths of the top and bottom plates routing layers. # \param xPlateRLayer_width A dictionary containing the widths of the top and bottom plates routing layers.
# \param routingTrack_width The width of a routing track. Is fixed according to technological parameters. # \param routingTrack_width The width of a routing track. Is fixed according to technological parameters.
# \param tracksNumbers A dictionary containing the number of top and bottom tracks. The allowed maximum total number of tracks is two. # \param tracksNumbers A dictionary containing the number of top and bottom tracks. The allowed maximum total number of tracks is two.
# \param topPlateWSpec Routing specifications for the top plates. # \param topPlateWSpec Routing specifications for the top plates.
# \param bottomPlateWSpec Routing specifications for the bottom plates. # \param bottomPlateWSpec Routing specifications for the bottom plates.
# \remarks An exception is raised if the entered routing specifications are invalid. Invalidity can be due to a wrong total number of tracks or bad wiring specifications of top and bottom tracks. More information about the valid specifications is given in \c function. # \remarks An exception is raised if the entered routing specifications are invalid. Invalidity can be due to a wrong total number of tracks or bad wiring specifications of top and bottom tracks. More information about the valid specifications is given in \c function.
def __init__( self, capacitorInstance, capacitor, dummyMode = False, tracksNumbers = [1,1], topPlateWSpec = [1,0] , bottomPlateWSpec = [0,1] ): def __init__( self, capacitorInstance, capacitor, dummyMode = False, tracksNumbers = [1,1], topPlateWSpec = [1,0] , bottomPlateWSpec = [0,1] ):
if (capacitorInstance.matchingMode == True) : raise Error(1,'__init__() : This class is only dedicated to route matrices equivalent to one capacitor. In case of a matched matrix of capacitors, please use <RoutMatchedCapacitor>.') if (capacitorInstance.matchingMode == True) : raise Error(1,'__init__() : This class is only dedicated to route matrices equivalent to one capacitor. In case of a matched matrix of capacitors, please use <RoutMatchedCapacitor>.')
self.device = capacitorInstance.device self.device = capacitorInstance.device
self.capacitorInstance = capacitorInstance self.capacitorInstance = capacitorInstance
self.capacitor = capacitor self.capacitor = capacitor
self.dummyMode = dummyMode self.dummyMode = dummyMode
self.capacitorType = capacitorInstance.capacitorType self.capacitorType = capacitorInstance.capacitorType
self.matrixDim = capacitorInstance.matrixDim self.matrixDim = capacitorInstance.matrixDim
self.abutmentBox = capacitorInstance.abutmentBox self.abutmentBox = capacitorInstance.abutmentBox
self.abutmentBox_spacing = self.capacitorInstance.getAbutmentBox_spacing () self.abutmentBox_spacing = self.capacitorInstance.getAbutmentBox_spacing ()
self.bondingBox = Box() self.bondingBox = Box()
self.capacitorType = capacitorInstance.capacitorType self.capacitorType = capacitorInstance.capacitorType
self.nets = capacitorInstance.nets[0] self.nets = capacitorInstance.nets[0]
self.routingTracksXMinXMax = {} self.routingTracksXMinXMax = {}
self.routingTrackYCenter = { "top": {}, "bottom": {} } self.routingTrackYCenter = { "top": {}, "bottom": {} }
self.xPlateRLayerXCenter = { "top": [], "bottom": [], "bottomBorders" : [] } self.xPlateRLayerXCenter = { "top": [], "bottom": [], "bottomBorders" : [] }
self.xPlateRLayer_width = {} self.xPlateRLayer_width = {}
self.routingTrack_width = 0 self.routingTrack_width = 0
if ( self.__isRoutingTracksNumberOK__( tracksNumbers ) ): if ( self.__isRoutingTracksNumberOK__( tracksNumbers ) ):
self.tracksNumbers = { "top" : tracksNumbers[0] ,"bottom" : tracksNumbers[1] } self.tracksNumbers = { "top" : tracksNumbers[0] ,"bottom" : tracksNumbers[1] }
possibleRoutingSchemes = self.__setPossibleRoutingSchemes__( tracksNumbers ) possibleRoutingSchemes = self.__setPossibleRoutingSchemes__( tracksNumbers )
if dummyMode == True : if dummyMode == True :
if self.connectToTopTracksOnly() : if self.connectToTopTracksOnly() :
self.topPlateWSpec = [1,0] self.topPlateWSpec = [1,0]
elif self.connectToBottomTracksOnly() : elif self.connectToBottomTracksOnly() :
self.topPlateWSpec = [0,1] self.topPlateWSpec = [0,1]
else : else :
self.topPlateWSpec = [1,1] self.topPlateWSpec = [1,1]
self.bottomPlateWSpec = self.topPlateWSpec self.bottomPlateWSpec = self.topPlateWSpec
elif ( dummyMode == False and self.__isWiringSpecOK__(topPlateWSpec, bottomPlateWSpec, possibleRoutingSchemes) ) : elif ( dummyMode == False and self.__isWiringSpecOK__(topPlateWSpec, bottomPlateWSpec, possibleRoutingSchemes) ) :
self.topPlateWSpec = topPlateWSpec self.topPlateWSpec = topPlateWSpec
self.bottomPlateWSpec = bottomPlateWSpec self.bottomPlateWSpec = bottomPlateWSpec
else : raise Error(1,'__init__() : Invalid routing specifications in terms of number, format or routing scheme.') else : raise Error(1,'__init__() : Invalid routing specifications in terms of number, format or routing scheme.')
else : raise Error(1,' __init__() : One routing track on one or both sides of the capacitor is allowed in dummy mode. Otherwise, routing tracks can be drawn one on each side or two on one side : (top trak number : %s, bottom track number : %s and dummy mode is %s). ' %( tracksNumbers[0], tracksNumbers[1], dummyMode )) #com verify the difference between a simple print and the dicitionary self.trackingNumber else : raise Error(1,' __init__() : One routing track on one or both sides of the capacitor is allowed in dummy mode. Otherwise, routing tracks can be drawn one on each side or two on one side : (top trak number : %s, bottom track number : %s and dummy mode is %s). ' %( tracksNumbers[0], tracksNumbers[1], dummyMode )) #com verify the difference between a simple print and the dicitionary self.trackingNumber
@ -96,39 +101,39 @@ class RoutCapacitor( CapacitorUnit ):
# - the capacitor type (ie., cuts2 if MIMCAP, cut1 if PIPCAP ) # - the capacitor type (ie., cuts2 if MIMCAP, cut1 if PIPCAP )
# - routing tracks layers according to the designer specifications. # - routing tracks layers according to the designer specifications.
def rout( self, bbMode = False ): def route( self, bbMode = False ):
UpdateSession.open () UpdateSession.open ()
bondingBox = {} bondingBox = {}
self.setRules () self.setRules ()
self.computeDimensions ( bbMode ) self.computeDimensions ( bbMode )
if bbMode : if bbMode :
bondingBox = self.computeLayoutDimensionsInbbMode() bondingBox = self.computeLayoutDimensionsInbbMode()
if not bbMode: if not bbMode:
routingTracksLayer = DataBase.getDB().getTechnology().getLayer("metal2") routingTracksLayer = DataBase.getDB().getTechnology().getLayer("metal2")
bottomPlateRLayer = CapacitorUnit.getLayers( self )["bottomPlateRLayer"] bottomPlateRLayer = CapacitorUnit.getLayers( self )["bottomPlateRLayer"]
topPlateRLayer = bottomPlateRLayer topPlateRLayer = bottomPlateRLayer
if self.capacitorType == 'MIMCap' : if self.capacitorType == 'MIMCap' :
topbottomCutLayer = DataBase.getDB().getTechnology().getLayer("cut2") topbottomCutLayer = DataBase.getDB().getTechnology().getLayer("cut2")
elif self.capacitorType == 'PIPCap' : elif self.capacitorType == 'PIPCap' :
topbottomCutLayer = DataBase.getDB().getTechnology().getLayer("cut1") topbottomCutLayer = DataBase.getDB().getTechnology().getLayer("cut1")
else : raise Error( 1,'rout() : Unsupported capacitor type : %s.' %self.capacitorType ) else : raise Error( 1,'route() : Unsupported capacitor type : %s.' %self.capacitorType )
self.drawRoutingTracks ( routingTracksLayer ) self.drawRoutingTracks ( routingTracksLayer )
self.drawPlatesVRLayers ( 'topPlate' , topPlateRLayer , self.topPlateWSpec , self.xPlateRLayerXCenter["top" ], self.xPlateRLayer_width["top" ] ) self.drawPlatesVRLayers ( 'topPlate' , topPlateRLayer , self.topPlateWSpec , self.xPlateRLayerXCenter["top" ], self.xPlateRLayer_width["top" ] )
self.drawPlatesVRLayers ( 'bottomPlate' , bottomPlateRLayer , self.bottomPlateWSpec, self.xPlateRLayerXCenter["bottom"], self.xPlateRLayer_width["bottom" ] ) self.drawPlatesVRLayers ( 'bottomPlate' , bottomPlateRLayer , self.bottomPlateWSpec, self.xPlateRLayerXCenter["bottom"], self.xPlateRLayer_width["bottom" ] )
self.drawCuts ( self.nets[0], 'topPlate' , self.topPlateWSpec , topbottomCutLayer , self.xPlateRLayer_width ["top" ], self.xPlateRLayerXCenter["top" ] ) self.drawCuts ( self.nets[0], 'topPlate' , self.topPlateWSpec , topbottomCutLayer , self.xPlateRLayer_width ["top" ], self.xPlateRLayerXCenter["top" ] )
self.drawCuts ( self.nets[1], 'bottomPlate' , self.bottomPlateWSpec, topbottomCutLayer , self.xPlateRLayer_width ["bottom"], self.xPlateRLayerXCenter["bottom"] ) self.drawCuts ( self.nets[1], 'bottomPlate' , self.bottomPlateWSpec, topbottomCutLayer , self.xPlateRLayer_width ["bottom"], self.xPlateRLayerXCenter["bottom"] )
UpdateSession.close () UpdateSession.close ()
return bondingBox return bondingBox
@ -144,24 +149,24 @@ class RoutCapacitor( CapacitorUnit ):
def setRules ( self ): def setRules ( self ):
CapacitorUnit.setRules ( self ) CapacitorUnit.setRules ( self )
CapacitorUnit.__setattr__ ( self, "minSpacing_routingTrackMetal" , RoutCapacitor.rules.minSpacing_metal2 ) CapacitorUnit.__setattr__ ( self, "minSpacing_routingTrackMetal" , RouteCapacitorSingle.rules.minSpacing_metal2 )
if self.capacitorType == 'MIMCap' : if self.capacitorType == 'MIMCap' :
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RoutCapacitor.rules.minWidth_cut2 ) CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut2 )
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RoutCapacitor.rules.minSpacing_cut2 ) CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RouteCapacitorSingle.rules.minSpacing_cut2 )
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RoutCapacitor.rules.minWidth_cut2 ) CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut2 )
elif self.capacitorType == 'PIPCap' : elif self.capacitorType == 'PIPCap' :
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RoutCapacitor.rules.minWidth_cut1 ) CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut1 )
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RoutCapacitor.rules.minSpacing_cut1 ) CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RouteCapacitorSingle.rules.minSpacing_cut1 )
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RoutCapacitor.rules.minWidth_cut1 ) CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut1 )
else : raise Error(1, 'setRules() : Unsupported capacitor type "%s".' % self.capacitorType ) else : raise Error(1, 'setRules() : Unsupported capacitor type "%s".' % self.capacitorType )
return return
## Checks if the wiring specifications are compatible with the possible routing schemes. ## Checks if the wiring specifications are compatible with the possible routing schemes.
@ -172,13 +177,13 @@ class RoutCapacitor( CapacitorUnit ):
def __isWiringSpecOK__ ( self, topPlateWiringSpec, bottomPlateWiringSpec, possibleRoutingSchemes ): def __isWiringSpecOK__ ( self, topPlateWiringSpec, bottomPlateWiringSpec, possibleRoutingSchemes ):
state = False state = False
if len(topPlateWiringSpec ) == len( bottomPlateWiringSpec ) == 2 and [ topPlateWiringSpec, bottomPlateWiringSpec ] in possibleRoutingSchemes : if len(topPlateWiringSpec ) == len( bottomPlateWiringSpec ) == 2 and [ topPlateWiringSpec, bottomPlateWiringSpec ] in possibleRoutingSchemes :
state = True state = True
else : raise Error(1, '__isWiringSpecOK__() : Invalid wiring specifications for top and/or bottom plates, %s and/or %s, respectively. The possible wiring schemes are : %s. ' %(topPlateWiringSpec, bottomPlateWiringSpec, possibleRoutingSchemes) ) else : raise Error(1, '__isWiringSpecOK__() : Invalid wiring specifications for top and/or bottom plates, %s and/or %s, respectively. The possible wiring schemes are : %s. ' %(topPlateWiringSpec, bottomPlateWiringSpec, possibleRoutingSchemes) )
return state return state
@ -189,10 +194,10 @@ class RoutCapacitor( CapacitorUnit ):
def __setPossibleRoutingSchemes__( self, tracksNumbers ): def __setPossibleRoutingSchemes__( self, tracksNumbers ):
[topTrackNumber , bottomTrackNumber] = [tracksNumbers[0] , tracksNumbers[1]] [topTrackNumber , bottomTrackNumber] = [tracksNumbers[0] , tracksNumbers[1]]
possibleRoutingSchemes = None possibleRoutingSchemes = None
if self.dummyMode == False: possibleRoutingSchemes = [ [[0,1],[1,0]], [[1,0],[0,1]] ] if self.dummyMode == False: possibleRoutingSchemes = [ [[0,1],[1,0]], [[1,0],[0,1]] ]
return possibleRoutingSchemes return possibleRoutingSchemes
@ -207,17 +212,17 @@ class RoutCapacitor( CapacitorUnit ):
# \throw <object> Wrong values for routing tracks # \throw <object> Wrong values for routing tracks
def __isRoutingTracksNumberOK__ ( self, tracksNumbers ): def __isRoutingTracksNumberOK__ ( self, tracksNumbers ):
[topTrackNumber , bottomTrackNumber] = [tracksNumbers[0] , tracksNumbers[1]] [topTrackNumber , bottomTrackNumber] = [tracksNumbers[0] , tracksNumbers[1]]
state = False state = False
if self.dummyMode == True: if self.dummyMode == True:
if ( bottomTrackNumber == 1 and topTrackNumber == 0 or bottomTrackNumber == 0 and topTrackNumber == 1 or bottomTrackNumber == 1 and topTrackNumber == 1 ) : if ( bottomTrackNumber == 1 and topTrackNumber == 0 or bottomTrackNumber == 0 and topTrackNumber == 1 or bottomTrackNumber == 1 and topTrackNumber == 1 ) :
state = True state = True
elif self.dummyMode == False: elif self.dummyMode == False:
if ( bottomTrackNumber == 1 and topTrackNumber == 1 or bottomTrackNumber == 0 and topTrackNumber == 2 or bottomTrackNumber == 2 and topTrackNumber == 0 ) : if ( bottomTrackNumber == 1 and topTrackNumber == 1 or bottomTrackNumber == 0 and topTrackNumber == 2 or bottomTrackNumber == 2 and topTrackNumber == 0 ) :
state = True state = True
else : raise Error( 1, '__isRoutingTracksNumberOK__() : Wrong values for routing tracks "%s , %s". ' %(bottomTrackNumber, topTrackNumber) ) #com test this else : raise Error( 1, '__isRoutingTracksNumberOK__() : Wrong values for routing tracks "%s , %s". ' %(bottomTrackNumber, topTrackNumber) ) #com test this
return state return state
@ -228,8 +233,8 @@ class RoutCapacitor( CapacitorUnit ):
# - the routing tracks # - the routing tracks
def computeDimensions( self, bbMode ): def computeDimensions( self, bbMode ):
self.computeRLayersDimensions ( bbMode ) self.computeRLayersDimensions ( bbMode )
self.computeHRoutingTrackDimensions( ) self.computeHRoutingTrackDimensions( )
return return
@ -239,25 +244,25 @@ class RoutCapacitor( CapacitorUnit ):
self.routingTrack_width = 2*self.minEnclo_routingTrackMetal_cut + self.minWidth_routingTrackcut self.routingTrack_width = 2*self.minEnclo_routingTrackMetal_cut + self.minWidth_routingTrackcut
if not bbMode : if not bbMode :
print(self.capacitor) print(self.capacitor)
self.xPlateRLayer_width["top"] = self.capacitor.getTopPlateRLayerWidth() if self.capacitorInstance.matrixDim.values() == [1,1] else self.capacitor[0][0].getTopPlateRLayerWidth() self.xPlateRLayer_width["top"] = self.capacitor.getTopPlateRLayerWidth() if self.capacitorInstance.matrixDim.values() == [1,1] else self.capacitor[0][0].getTopPlateRLayerWidth()
if self.capacitorInstance.__isUnitCap__() : if self.capacitorInstance.__isUnitCap__() :
self.computeRLayersDimensionsCompactCap () self.computeRLayersDimensionsCompactCap ()
else : self.computeRLayersDimensionsMatrixCap() else : self.computeRLayersDimensionsMatrixCap()
return return
def computeRLayersDimensionsCompactCap( self ): def computeRLayersDimensionsCompactCap( self ):
self.bordersRLayerXMin = [ self.capacitor.getBottomPlateLeftCutXMin(), self.capacitor.getBottomPlateRightCutXMin() ] self.bordersRLayerXMin = [ self.capacitor.getBottomPlateLeftCutXMin(), self.capacitor.getBottomPlateRightCutXMin() ]
self.xPlateRLayer_width ["bottomBorders"] = self.capacitor.getBotPlateRLayerWidth () self.xPlateRLayer_width ["bottomBorders"] = self.capacitor.getBotPlateRLayerWidth ()
self.xPlateRLayer_width ["bottom" ] = [] self.xPlateRLayer_width ["bottom" ] = []
self.xPlateRLayerXCenter["bottom" ] = [] self.xPlateRLayerXCenter["bottom" ] = []
self.xPlateRLayerXCenter["top" ].append( self.capacitor.getTopPlateRLayerXCenter () ) self.xPlateRLayerXCenter["top" ].append( self.capacitor.getTopPlateRLayerXCenter () )
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor.getBotPlateLeftRLayerXCenter () ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor.getBotPlateLeftRLayerXCenter () )
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor.getBotPlateRightRLayerXCenter () ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor.getBotPlateRightRLayerXCenter () )
@ -268,14 +273,14 @@ class RoutCapacitor( CapacitorUnit ):
if self.capacitorInstance.matrixDim["columns"] > 1 : if self.capacitorInstance.matrixDim["columns"] > 1 :
self.xPlateRLayer_width["bottom"] = ( self.capacitor[0][1].getBotPlateLeftRLayerXMax() - self.capacitor[0][0].getBotPlateRightRLayerXMin() ) self.xPlateRLayer_width["bottom"] = ( self.capacitor[0][1].getBotPlateLeftRLayerXMax() - self.capacitor[0][0].getBotPlateRightRLayerXMin() )
self.bordersRLayerXMin = [ self.capacitor[0][0].getBottomPlateLeftCutXMin(), self.capacitor[0][-1].getBottomPlateRightCutXMin() ] self.bordersRLayerXMin = [ self.capacitor[0][0].getBottomPlateLeftCutXMin(), self.capacitor[0][-1].getBottomPlateRightCutXMin() ]
elif self.capacitorInstance.matrixDim["columns"] == 1 : elif self.capacitorInstance.matrixDim["columns"] == 1 :
self.bordersRLayerXMin = [ self.capacitor[0][0].getBottomPlateLeftCutXMin(), self.capacitor[0][0].getBottomPlateRightCutXMin() ] self.bordersRLayerXMin = [ self.capacitor[0][0].getBottomPlateLeftCutXMin(), self.capacitor[0][0].getBottomPlateRightCutXMin() ]
else : raise Error( 1, 'computeRLayersDimensionsMatrixCap() : Negative number of columns in the matrix "%s".' % self.capacitorInstance.matrixDim["columns"] ) else : raise Error( 1, 'computeRLayersDimensionsMatrixCap() : Negative number of columns in the matrix "%s".' % self.capacitorInstance.matrixDim["columns"] )
self.xPlateRLayer_width["bottomBorders"] = self.capacitor[0][0].getBotPlateRLayerWidth() self.xPlateRLayer_width["bottomBorders"] = self.capacitor[0][0].getBotPlateRLayerWidth()
for i in range( 0, self.matrixDim["columns"] ): for i in range( 0, self.matrixDim["columns"] ):
self.xPlateRLayerXCenter["top"].append( self.capacitor[0][i].getTopPlateRLayerXCenter() ) self.xPlateRLayerXCenter["top"].append( self.capacitor[0][i].getTopPlateRLayerXCenter() )
@ -283,9 +288,9 @@ class RoutCapacitor( CapacitorUnit ):
self.xPlateRLayerXCenter["bottom"].append( self.capacitor[0][i].getBotPlateRightRLayerXMin() + self.xPlateRLayer_width["bottom"]/2 ) self.xPlateRLayerXCenter["bottom"].append( self.capacitor[0][i].getBotPlateRightRLayerXMin() + self.xPlateRLayer_width["bottom"]/2 )
if self.capacitorInstance.matrixDim["columns"] > 1 : if self.capacitorInstance.matrixDim["columns"] > 1 :
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][ 0].getBotPlateLeftRLayerXCenter () ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][ 0].getBotPlateLeftRLayerXCenter () )
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][-1].getBotPlateRightRLayerXCenter() ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][-1].getBotPlateRightRLayerXCenter() )
else : else :
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][0].getBotPlateLeftRLayerXCenter () ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][0].getBotPlateLeftRLayerXCenter () )
self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][0].getBotPlateRightRLayerXCenter () ) self.xPlateRLayerXCenter["bottomBorders"].append( self.capacitor[0][0].getBotPlateRightRLayerXCenter () )
@ -298,94 +303,94 @@ class RoutCapacitor( CapacitorUnit ):
self.routingTracksXMinXMax = { "XMin" : self.abutmentBox.getXMin() , "XMax" : self.abutmentBox.getXMax() } self.routingTracksXMinXMax = { "XMin" : self.abutmentBox.getXMin() , "XMax" : self.abutmentBox.getXMax() }
if self.dummyMode == True: if self.dummyMode == True:
if self.connectToTopTracksOnly () : if self.connectToTopTracksOnly () :
self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2 self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2
self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2} self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2}
elif self.connectToBottomTracksOnly () : elif self.connectToBottomTracksOnly () :
self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2 self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2
self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2} self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2}
else : else :
self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2 self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2
self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2 self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2
self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2} self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2}
self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2} self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2}
elif self.dummyMode == False: elif self.dummyMode == False:
if self.connectToTopTracksOnly () : if self.connectToTopTracksOnly () :
self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2 self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2
self.routingTrackYCenter["top" ]["upper"] = self.routingTrackYCenter["top"]["lower"] + self.minSpacing_routingTrackMetal + self.routingTrack_width self.routingTrackYCenter["top" ]["upper"] = self.routingTrackYCenter["top"]["lower"] + self.minSpacing_routingTrackMetal + self.routingTrack_width
self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2} self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2}
self.topUpperTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["upper"] + self.routingTrack_width/2} self.topUpperTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["upper"] + self.routingTrack_width/2}
elif self.connectToBottomTracksOnly () : elif self.connectToBottomTracksOnly () :
self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2 self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2
self.routingTrackYCenter["bottom"]["lower"] = self.routingTrackYCenter["bottom"]["upper"] - self.minSpacing_routingTrackMetal - self.routingTrack_width self.routingTrackYCenter["bottom"]["lower"] = self.routingTrackYCenter["bottom"]["upper"] - self.minSpacing_routingTrackMetal - self.routingTrack_width
self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2} self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2}
self.bottomLowerTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["lower"] + self.routingTrack_width/2} self.bottomLowerTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["lower"] + self.routingTrack_width/2}
elif self.connectToTopAndBottomTracks() : elif self.connectToTopAndBottomTracks() :
self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2 self.routingTrackYCenter["top" ]["lower"] = self.abutmentBox.getYMax() + self.minSpacing_botPlate + self.routingTrack_width/2
self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2 self.routingTrackYCenter["bottom"]["upper"] = self.abutmentBox.getYMin() - self.minSpacing_botPlate - self.routingTrack_width/2
self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2} self.topLowerTrackDict = {"YMin" : self.routingTrackYCenter["top" ]["lower"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["top" ]["lower"] + self.routingTrack_width/2}
self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2} self.bottomUpperTrackDict = {"YMin" : self.routingTrackYCenter["bottom"]["upper"] - self.routingTrack_width/2, "YMax" : self.routingTrackYCenter["bottom"]["upper"] + self.routingTrack_width/2}
else : raise Error( 1, ' computeHRoutingTrackDimensions() : Wrong number or values for routing tracks, top : "%s", bottom : "%s". ' %(self.tracksNumbers["top"], self.tracksNumbers["bottom"]) ) else : raise Error( 1, ' computeHRoutingTrackDimensions() : Wrong number or values for routing tracks, top : "%s", bottom : "%s". ' %(self.tracksNumbers["top"], self.tracksNumbers["bottom"]) )
else : raise Error( 1, 'computeHRoutingTrackDimensions() : The dummy mode must be either "True" or "False", "%s". ' % self.dummyMode ) else : raise Error( 1, 'computeHRoutingTrackDimensions() : The dummy mode must be either "True" or "False", "%s". ' % self.dummyMode )
return return
def computeLayoutDimensionsInbbMode( self ): def computeLayoutDimensionsInbbMode( self ):
bondingBoxDict = {} bondingBoxDict = {}
bondingBoxDict ["width" ] = self.routingTracksXMinXMax["XMax"] - self.routingTracksXMinXMax["XMin"] bondingBoxDict ["width" ] = self.routingTracksXMinXMax["XMax"] - self.routingTracksXMinXMax["XMin"]
bondingBoxDict["XMin" ] = self.routingTracksXMinXMax["XMin"] bondingBoxDict["XMin" ] = self.routingTracksXMinXMax["XMin"]
if self.dummyMode == True : if self.dummyMode == True :
if self.connectToTopTracksOnly () : if self.connectToTopTracksOnly () :
bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.abutmentBox.getYMin() bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.abutmentBox.getYMin()
bondingBoxDict["YMin" ] = self.abutmentBox.getYMin() bondingBoxDict["YMin" ] = self.abutmentBox.getYMin()
elif self.connectoToBottomTracksOnly() : elif self.connectoToBottomTracksOnly() :
bondingBoxDict["height" ] = self.abutmentBox.getYMax() - self.bottomUpperTrackDict["YMin"] bondingBoxDict["height" ] = self.abutmentBox.getYMax() - self.bottomUpperTrackDict["YMin"]
bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"] bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"]
else : else :
bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.abutmentBox.getYMin() bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.abutmentBox.getYMin()
bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"] bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"]
elif self.dummyMode == False: elif self.dummyMode == False:
if self.connectToTopTracksOnly () : if self.connectToTopTracksOnly () :
bondingBoxDict["height" ] = self.topUpperTrackDict["YMax"] - self.abutmentBox.getYMin() bondingBoxDict["height" ] = self.topUpperTrackDict["YMax"] - self.abutmentBox.getYMin()
bondingBoxDict["YMin" ] = self.abutmentBox.getYMin() bondingBoxDict["YMin" ] = self.abutmentBox.getYMin()
elif self.connectoToBottomTracksOnly() : elif self.connectoToBottomTracksOnly() :
bondingBoxDict["height" ] = self.abutmentBox.getYMax() - self.bottomLowerTrackDict["YMin"] bondingBoxDict["height" ] = self.abutmentBox.getYMax() - self.bottomLowerTrackDict["YMin"]
bondingBoxDict["YMin" ] = self.bottomLowerTrackDict["YMin"] bondingBoxDict["YMin" ] = self.bottomLowerTrackDict["YMin"]
else: else:
bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.bottomUpperTrackDict["YMin"] bondingBoxDict["height" ] = self.topLowerTrackDict["YMax"] - self.bottomUpperTrackDict["YMin"]
bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"] bondingBoxDict["YMin" ] = self.bottomUpperTrackDict["YMin"]
else : raise Error( 1, 'computeLayoutDimensionsInbbMode() : The dummy mode must be either "True" or "False", "%s". ' % self.dummyMode ) else : raise Error( 1, 'computeLayoutDimensionsInbbMode() : The dummy mode must be either "True" or "False", "%s". ' % self.dummyMode )
bondingBoxDict["surface"] = bondingBoxDict["width"]*bondingBoxDict["height"] bondingBoxDict["surface"] = bondingBoxDict["width"]*bondingBoxDict["height"]
self.bondingBox = Box( bondingBoxDict["XMin"], bondingBoxDict["YMin"], bondingBoxDict["XMin"] + bondingBoxDict["width"] , bondingBoxDict["YMin"] + bondingBoxDict["height"] ) self.bondingBox = Box( bondingBoxDict["XMin"], bondingBoxDict["YMin"], bondingBoxDict["XMin"] + bondingBoxDict["width"] , bondingBoxDict["YMin"] + bondingBoxDict["height"] )
return bondingBoxDict return bondingBoxDict
## Draws routing tracks, above and/or below the capacitor. A maximum total number of two tracks is drawn. In dummy mode, one track is drawn. ## Draws routing tracks, above and/or below the capacitor. A maximum total number of two tracks is drawn. In dummy mode, one track is drawn.
@ -394,45 +399,45 @@ class RoutCapacitor( CapacitorUnit ):
def drawRoutingTracks( self , routingTracksLayer ): def drawRoutingTracks( self , routingTracksLayer ):
self.drawTopOrBottomRoutingTracks ( "top" , routingTracksLayer ) self.drawTopOrBottomRoutingTracks ( "top" , routingTracksLayer )
self.drawTopOrBottomRoutingTracks ( "bottom", routingTracksLayer ) self.drawTopOrBottomRoutingTracks ( "bottom", routingTracksLayer )
return return
def drawTopOrBottomRoutingTracks ( self, tracksPosition, routingTracksLayer ) : def drawTopOrBottomRoutingTracks ( self, tracksPosition, routingTracksLayer ) :
if tracksPosition in ["top","bottom"] : if tracksPosition in ["top","bottom"] :
attribut = ["lower","upper"] attribut = ["lower","upper"]
nets = self.__setNetsDistributionHRTs__() nets = self.__setNetsDistributionHRTs__()
for i in range( 0, self.tracksNumbers[tracksPosition] ): for i in range( 0, self.tracksNumbers[tracksPosition] ):
index = i if tracksPosition == "top" else i-1 index = i if tracksPosition == "top" else i-1
routingtrackYCenter = self.routingTrackYCenter[tracksPosition][attribut[index]] routingtrackYCenter = self.routingTrackYCenter[tracksPosition][attribut[index]]
Horizontal.create ( nets[i] , routingTracksLayer, routingtrackYCenter , self.routingTrack_width , self.routingTracksXMinXMax["XMin"], self.routingTracksXMinXMax["XMax"] ) Horizontal.create ( nets[i] , routingTracksLayer, routingtrackYCenter , self.routingTrack_width , self.routingTracksXMinXMax["XMin"], self.routingTracksXMinXMax["XMax"] )
print("netsi",nets[i]) print("netsi",nets[i])
else : raise Error(1,'drawOneRoutingTrack() : The track position must be either "top" or "bottom" : %s.' %tracksPosition) else : raise Error(1,'drawOneRoutingTrack() : The track position must be either "top" or "bottom" : %s.' %tracksPosition)
return return
def __setNetsDistributionHRTs__( self ): def __setNetsDistributionHRTs__( self ):
if self.dummyMode == False : if self.dummyMode == False :
netsDistribution = self.nets if [self.topPlateWSpec, self.bottomPlateWSpec] == [[1,0],[0,1]] else [self.nets[1], self.nets[0]] netsDistribution = self.nets if [self.topPlateWSpec, self.bottomPlateWSpec] == [[1,0],[0,1]] else [self.nets[1], self.nets[0]]
else : netsDistribution = self.nets else : netsDistribution = self.nets
return netsDistribution return netsDistribution
## Draws the routing layers connecting top and bottom plates to the associated routing track. ## Draws the routing layers connecting top and bottom plates to the associated routing track.
# \param Plate The capacitor's plate to be routed (ie., top, bottom). # \param Plate The capacitor's plate to be routed (ie., top, bottom).
# \paramx PlateRLayer Routing layer. # \paramx PlateRLayer Routing layer.
# \param PlateWSpec Connection specifications of the plate. # \param PlateWSpec Connection specifications of the plate.
# \param xPlateRLayerXCenter Horizontal position of the routing layer. # \param xPlateRLayerXCenter Horizontal position of the routing layer.
# \param xPlateRLayer_width Width of the routing layer. # \param xPlateRLayer_width Width of the routing layer.
@ -441,54 +446,54 @@ class RoutCapacitor( CapacitorUnit ):
def drawPlatesVRLayers( self, Plate, xPlateRLayer, PlateWSpec, xPlateRLayerXCenter, xPlateRLayer_width ): def drawPlatesVRLayers( self, Plate, xPlateRLayer, PlateWSpec, xPlateRLayerXCenter, xPlateRLayer_width ):
if self.capacitorInstance.__isUnitCap__() : if self.capacitorInstance.__isUnitCap__() :
[firstElementInCapacitor , lastElementInCapacitor] = [self.capacitor , self.capacitor] [firstElementInCapacitor , lastElementInCapacitor] = [self.capacitor , self.capacitor]
elif not( self.capacitorInstance.__isUnitCap__() ): elif not( self.capacitorInstance.__isUnitCap__() ):
[firstElementInCapacitor , lastElementInCapacitor] = [self.capacitor[0][0] , self.capacitor[-1][0]] [firstElementInCapacitor , lastElementInCapacitor] = [self.capacitor[0][0] , self.capacitor[-1][0]]
[ doTop, doBottom ] = [1, 0] if Plate == 'topPlate' else [0, 1] [ doTop, doBottom ] = [1, 0] if Plate == 'topPlate' else [0, 1]
if ( Plate == 'topPlate' ) : if ( Plate == 'topPlate' ) :
YMinDict = { YMinDict = {
"toTopToUpper" : firstElementInCapacitor.getTopPlateRLayerYMin(), "toTopToUpper" : firstElementInCapacitor.getTopPlateRLayerYMin(),
"toTopToLower" : firstElementInCapacitor.getTopPlateRLayerYMin(), "toTopToLower" : firstElementInCapacitor.getTopPlateRLayerYMin(),
"toBottomToUpper" : lastElementInCapacitor.getTopPlateRLayerYMax(), "toBottomToUpper" : lastElementInCapacitor.getTopPlateRLayerYMax(),
"toBottomToLower" : lastElementInCapacitor.getTopPlateRLayerYMax() "toBottomToLower" : lastElementInCapacitor.getTopPlateRLayerYMax()
} }
net = self.nets[0] net = self.nets[0]
xMetalXCenter = self.xPlateRLayerXCenter["top"] xMetalXCenter = self.xPlateRLayerXCenter["top"]
elif ( Plate == 'bottomPlate' ) : elif ( Plate == 'bottomPlate' ) :
YMinDict = { YMinDict = {
"toTopToUpper" : firstElementInCapacitor.getBotPlateRLayerYMin(), "toTopToUpper" : firstElementInCapacitor.getBotPlateRLayerYMin(),
"toTopToLower" : firstElementInCapacitor.getBotPlateRLayerYMin(), "toTopToLower" : firstElementInCapacitor.getBotPlateRLayerYMin(),
"toBottomToUpper" : lastElementInCapacitor.getBotPlateRLayerYMax(), "toBottomToUpper" : lastElementInCapacitor.getBotPlateRLayerYMax(),
"toBottomToLower" : lastElementInCapacitor.getBotPlateRLayerYMax() "toBottomToLower" : lastElementInCapacitor.getBotPlateRLayerYMax()
} }
net = self.nets[1] net = self.nets[1]
xMetalXCenter = self.xPlateRLayerXCenter["bottom"] xMetalXCenter = self.xPlateRLayerXCenter["bottom"]
else : raise Error( 1, 'drawPlatesVRLayers() : Undefined plate, "%s".' % Plate ) else : raise Error( 1, 'drawPlatesVRLayers() : Undefined plate, "%s".' % Plate )
if ( self.connectToTopTracksOnly () and self.connectToUpper( PlateWSpec ) ) : if ( self.connectToTopTracksOnly () and self.connectToUpper( PlateWSpec ) ) :
[ dySource, dyTarget ] = [ YMinDict["toTopToUpper" ] , self.topUpperTrackDict["YMax"] ] [ dySource, dyTarget ] = [ YMinDict["toTopToUpper" ] , self.topUpperTrackDict["YMax"] ]
elif ( self.connectToTopTracksOnly () and self.connectToLower( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks () and self.connectToUpper( PlateWSpec ) ) : elif ( self.connectToTopTracksOnly () and self.connectToLower( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks () and self.connectToUpper( PlateWSpec ) ) :
dyTarget = self.topLowerTrackDict ["YMax"] dyTarget = self.topLowerTrackDict ["YMax"]
dySource = self.bottomUpperTrackDict["YMin"] if self.dummyMode == True and self.connectToTopAndBottomTracks () else YMinDict["toTopToLower" ] dySource = self.bottomUpperTrackDict["YMin"] if self.dummyMode == True and self.connectToTopAndBottomTracks () else YMinDict["toTopToLower" ]
elif ( self.connectToBottomTracksOnly() and self.connectToUpper( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks () and self.connectToLower( PlateWSpec ) ) : elif ( self.connectToBottomTracksOnly() and self.connectToUpper( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks () and self.connectToLower( PlateWSpec ) ) :
[ dySource, dyTarget ] = [ YMinDict["toBottomToUpper"] , self.bottomUpperTrackDict["YMin"] ] [ dySource, dyTarget ] = [ YMinDict["toBottomToUpper"] , self.bottomUpperTrackDict["YMin"] ]
elif ( self.connectToBottomTracksOnly() and self.connectToLower( PlateWSpec ) ) : elif ( self.connectToBottomTracksOnly() and self.connectToLower( PlateWSpec ) ) :
[ dySource, dyTarget ] = [ YMinDict["toBottomToLower"] , self.bottomLowerTrackDict["YMin"] ] [ dySource, dyTarget ] = [ YMinDict["toBottomToLower"] , self.bottomLowerTrackDict["YMin"] ]
else : raise Error( 1, 'drawPlatesVRLayers() : Invalid routing specifications "%s".' % PlateWSpec ) else : raise Error( 1, 'drawPlatesVRLayers() : Invalid routing specifications "%s".' % PlateWSpec )
for i in range( 0, self.matrixDim["columns"] - doBottom ): for i in range( 0, self.matrixDim["columns"] - doBottom ):
Vertical.create ( net, xPlateRLayer, xPlateRLayerXCenter[i], xPlateRLayer_width, dySource, dyTarget ) Vertical.create ( net, xPlateRLayer, xPlateRLayerXCenter[i], xPlateRLayer_width, dySource, dyTarget )
if doBottom : if doBottom :
for i in range( 0,2): for i in range( 0,2):
Vertical.create ( self.nets[1], xPlateRLayer , self.xPlateRLayerXCenter["bottomBorders"][i], self.xPlateRLayer_width["bottomBorders"], dySource, dyTarget ) Vertical.create ( self.nets[1], xPlateRLayer , self.xPlateRLayerXCenter["bottomBorders"][i], self.xPlateRLayer_width["bottomBorders"], dySource, dyTarget )
return return
@ -502,7 +507,7 @@ class RoutCapacitor( CapacitorUnit ):
# \throw <Invalid-specifictions > \c Not \c possible \c to \c compute cuts vertical position due to invalid routing specifications # \throw <Invalid-specifictions > \c Not \c possible \c to \c compute cuts vertical position due to invalid routing specifications
# \remak The number of cuts is maximized according to the track's width. # \remak The number of cuts is maximized according to the track's width.
# \param net Net of the Hurricane Device to which the cuts will be connected. # \param net Net of the Hurricane Device to which the cuts will be connected.
# \param Plate Capacitor's plate, top or bottom. # \param Plate Capacitor's plate, top or bottom.
# \param PlateWSpec Wiring specifications of the plate. It is useful to identify the track on which the cuts are to draw. # \param PlateWSpec Wiring specifications of the plate. It is useful to identify the track on which the cuts are to draw.
# \param layer Cut's layer. # \param layer Cut's layer.
# \param xPlateRLayer_width Width of the plate's routing layer. It is useful to compute the maximum number of cuts. # \param xPlateRLayer_width Width of the plate's routing layer. It is useful to compute the maximum number of cuts.
@ -511,35 +516,35 @@ class RoutCapacitor( CapacitorUnit ):
def drawCuts( self, net, Plate, PlateWSpec, layer, xPlateRLayer_width, xPlateRLayerXCenter ): def drawCuts( self, net, Plate, PlateWSpec, layer, xPlateRLayer_width, xPlateRLayerXCenter ):
[ doTop, doBottom ] = [1, 0] if Plate == 'topPlate' else [0, 1] [ doTop, doBottom ] = [1, 0] if Plate == 'topPlate' else [0, 1]
cutsYCenter = self. __setCutsYCenter__( PlateWSpec ) cutsYCenter = self. __setCutsYCenter__( PlateWSpec )
if not( self.capacitorInstance.__isUnitCap__() ) or ( self.capacitorInstance.__isUnitCap__() and doTop ) : if not( self.capacitorInstance.__isUnitCap__() ) or ( self.capacitorInstance.__isUnitCap__() and doTop ) :
print("xPlateRLayer_width",xPlateRLayer_width) print("xPlateRLayer_width",xPlateRLayer_width)
cutsNumber = CapacitorUnit.cutMaxNumber( self, xPlateRLayer_width, self.minWidth_routingTrackcut, self.minSpacing_routingTrackcut, self.minEnclo_routingTrackMetal_cut ) cutsNumber = CapacitorUnit.cutMaxNumber( self, xPlateRLayer_width, self.minWidth_routingTrackcut, self.minSpacing_routingTrackcut, self.minEnclo_routingTrackMetal_cut )
enclosure_RLayer_cut = ( xPlateRLayer_width - cutsNumber*self.minWidth_routingTrackcut - ( cutsNumber - 1 )*self.minSpacing_routingTrackcut ) / 2 enclosure_RLayer_cut = ( xPlateRLayer_width - cutsNumber*self.minWidth_routingTrackcut - ( cutsNumber - 1 )*self.minSpacing_routingTrackcut ) / 2
for i in range( 0, self.matrixDim["columns"] - doBottom ): for i in range( 0, self.matrixDim["columns"] - doBottom ):
cutXCenter = xPlateRLayerXCenter[i] - xPlateRLayer_width/2 + enclosure_RLayer_cut + self.minWidth_routingTrackcut/2 cutXCenter = xPlateRLayerXCenter[i] - xPlateRLayer_width/2 + enclosure_RLayer_cut + self.minWidth_routingTrackcut/2
CapacitorUnit.cutLine( self, net, layer, cutXCenter, cutsYCenter, self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, cutsNumber , 'horizontal' ) CapacitorUnit.cutLine( self, net, layer, cutXCenter, cutsYCenter, self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, cutsNumber , 'horizontal' )
if self.dummyMode == True and self.connectToTopAndBottomTracks() : if self.dummyMode == True and self.connectToTopAndBottomTracks() :
CapacitorUnit.cutLine( self, net, layer, cutXCenter, self.routingTrackYCenter["bottom"]["upper"], self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, cutsNumber , 'horizontal' ) CapacitorUnit.cutLine( self, net, layer, cutXCenter, self.routingTrackYCenter["bottom"]["upper"], self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, cutsNumber , 'horizontal' )
if doBottom : if doBottom :
borderscutsNumber = CapacitorUnit.cutMaxNumber( self, self.xPlateRLayer_width["bottomBorders"], self.minWidth_routingTrackcut, self.minSpacing_routingTrackcut, self.minEnclo_routingTrackMetal_cut ) borderscutsNumber = CapacitorUnit.cutMaxNumber( self, self.xPlateRLayer_width["bottomBorders"], self.minWidth_routingTrackcut, self.minSpacing_routingTrackcut, self.minEnclo_routingTrackMetal_cut )
enclosure_RLayer_cut = ( self.xPlateRLayer_width["bottomBorders"] - borderscutsNumber*self.minWidth_routingTrackcut - ( borderscutsNumber - 1 )*self.minSpacing_routingTrackcut ) / 2 enclosure_RLayer_cut = ( self.xPlateRLayer_width["bottomBorders"] - borderscutsNumber*self.minWidth_routingTrackcut - ( borderscutsNumber - 1 )*self.minSpacing_routingTrackcut ) / 2
for i in range( 0,2): for i in range( 0,2):
CapacitorUnit.cutLine( self, net, layer, self.xPlateRLayerXCenter["bottomBorders"][i], cutsYCenter, self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, borderscutsNumber , 'horizontal' ) CapacitorUnit.cutLine( self, net, layer, self.xPlateRLayerXCenter["bottomBorders"][i], cutsYCenter, self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, borderscutsNumber , 'horizontal' )
if self.dummyMode == True and self.connectToTopAndBottomTracks() : if self.dummyMode == True and self.connectToTopAndBottomTracks() :
CapacitorUnit.cutLine( self, net, layer, self.xPlateRLayerXCenter["bottomBorders"][i], self.routingTrackYCenter["bottom"]["upper"], self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, borderscutsNumber , 'horizontal' ) CapacitorUnit.cutLine( self, net, layer, self.xPlateRLayerXCenter["bottomBorders"][i], self.routingTrackYCenter["bottom"]["upper"], self.minWidth_routingTrackcut, self.minHeight_routingTrackcut, self.minSpacing_routingTrackcut, borderscutsNumber , 'horizontal' )
return return
def __setCutsYCenter__( self, PlateWSpec ): def __setCutsYCenter__( self, PlateWSpec ):
if ( self.connectToTopTracksOnly () and self.connectToLower( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks() and self.connectToUpper( PlateWSpec ) ) : if ( self.connectToTopTracksOnly () and self.connectToLower( PlateWSpec ) ) or ( self.connectToTopAndBottomTracks() and self.connectToUpper( PlateWSpec ) ) :
cutsYCenter = self.routingTrackYCenter["top"]["lower"] cutsYCenter = self.routingTrackYCenter["top"]["lower"]
elif ( self.connectToTopTracksOnly () and self.connectToUpper( PlateWSpec ) ) : elif ( self.connectToTopTracksOnly () and self.connectToUpper( PlateWSpec ) ) :
@ -549,12 +554,12 @@ class RoutCapacitor( CapacitorUnit ):
cutsYCenter = self.routingTrackYCenter["bottom"]["upper"] cutsYCenter = self.routingTrackYCenter["bottom"]["upper"]
elif ( self.connectToBottomTracksOnly() and self.connectToLower( PlateWSpec ) ) : elif ( self.connectToBottomTracksOnly() and self.connectToLower( PlateWSpec ) ) :
cutsYCenter = self.routingTrackYCenter["bottom"]["lower"] cutsYCenter = self.routingTrackYCenter["bottom"]["lower"]
else : raise Error( 1, '__setCutsYCenter__() : Not possible to compute cuts vertical position due to invalid routing specifications "%s".' % PlateWSpec ) else : raise Error( 1, '__setCutsYCenter__() : Not possible to compute cuts vertical position due to invalid routing specifications "%s".' % PlateWSpec )
return cutsYCenter return cutsYCenter
@ -610,18 +615,31 @@ def ScriptMain( **kw ):
UpdateSession.open() UpdateSession.open()
nets = [[t0,b0]] nets = [[t0,b0]]
capacitance = [400]
capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 400) ## A matrix of unit capacitors (all are active or all are dummy capacitors)
# capacitorInstance = CapacitorStack( Device, 400, 'MIMCap', [0,0], unitCap = 100 )
# capacitance = [1600]
# capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 400)
# capacitor = capacitorInstance.create()
#
# routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, dummyMode = True, tracksNumbers = [1,0] )
# routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, tracksNumbers = [2,0], topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] )
# routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, dummyMode = False , tracksNumbers = [1,1], topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0])
## Unit capacitor ( an active capacitor )
capacitance = [600]
capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 600)
capacitor = capacitorInstance.create() capacitor = capacitorInstance.create()
print(capacitor) routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] )
# routedCap = RoutCapacitor( capacitorInstance, capacitor , tracksNumbers = [2,0], topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] )
# routedCap = RoutCapacitor( capacitorInstance, capacitor, dummyMode = False , tracksNumbers = [1,1], topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] ) ## Unit capacitor ( a dummy capacitor )
routedCap = RoutCapacitor( capacitorInstance, capacitor, dummyMode = True, tracksNumbers = [1,0] ) #, topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] ) # capacitance = [600]
# routedCap = RoutCapacitor( capacitorInstance, capacitor, dummyMode = True , tracksNumbers = [1,0]) #, topPlateWSpec = [1,0] , bottomPlateWSpec = [1,0] ) # capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 600)
bondingBox = routedCap.rout() # capacitor = capacitorInstance.create()
print(bondingBox) # routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, dummyMode = True, tracksNumbers = [1,0] )
bondingBox = routedCap.route()
AllianceFramework.get().saveCell( Device, Catalog.State.Views ) AllianceFramework.get().saveCell( Device, Catalog.State.Views )

View File

@ -174,10 +174,19 @@ class CapacitorUnit():
def __isCapacitorUnitOK__( self, capDim ): def __isCapacitorUnitOK__( self, capDim ):
print 'capDim:', DbU.getValueString(capDim['width']), DbU.getValueString(capDim['height'])
print 'min / max:', DbU.getValueString(self.getMinimumCapWidth() ), DbU.getValueString(self.getMaximumCapWidth() )
state = False state = False
if ( self.capacitorType == 'MIMCap' and CapacitorUnit.getMinimumCapWidth( self ) < capDim["width"] < self.getMaximumCapWidth() and CapacitorUnit.getMinimumCapWidth( self ) < capDim["height"] < self.getMaximumCapWidth() ) or ( self.capacitorType == 'PIPCap' and self.getMinimumCapWidth() < capDim["width"] and self.getMinimumCapWidth() < capDim["height"] ) : if ( self.capacitorType == 'MIMCap' \
and CapacitorUnit.getMinimumCapWidth(self) < capDim["width" ] < self.getMaximumCapWidth() \
and CapacitorUnit.getMinimumCapWidth(self) < capDim["height"] < self.getMaximumCapWidth() ) \
or ( self.capacitorType == 'PIPCap' \
and self.getMinimumCapWidth() < capDim["width" ] \
and self.getMinimumCapWidth() < capDim["height"] ):
state = True state = True
print '__isCapacitorUnitOK__:', state
return state return state

View File

@ -77,6 +77,9 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
self.setRules () self.setRules ()
vRoutingTracksLayer = DataBase.getDB().getTechnology().getLayer("metal3" ) vRoutingTracksLayer = DataBase.getDB().getTechnology().getLayer("metal3" )
print 'self.capacitorInstance.doMatrix:', self.capacitorInstance.doMatrix
print 'self.capacitorsNumber:', self.capacitorsNumber
if self.capacitorInstance.doMatrix == True and self.capacitorsNumber > 1 : if self.capacitorInstance.doMatrix == True and self.capacitorsNumber > 1 :
self.minimizeVRTs() self.minimizeVRTs()
self.computeVRTDimensions() self.computeVRTDimensions()

View File

@ -13,10 +13,11 @@ helpers.setTraceLevel( 1000 )
import Analog import Analog
import ParamsMatrix import ParamsMatrix
import oroshi import oroshi
from CapacitorUnit import CapacitorUnit from CapacitorUnit import CapacitorUnit
from CapacitorMatrix import CapacitorStack from CapacitorMatrix import CapacitorStack
from CapacitorVRTracks import VerticalRoutingTracks from CapacitorVRTracks import VerticalRoutingTracks
from CapacitorRouted import RoutMatchedCapacitor from CapacitorRouted import RoutMatchedCapacitor
from CapacitorRoutedSingle import RouteCapacitorSingle
def toMatrixArgs ( matrix ): def toMatrixArgs ( matrix ):
@ -53,6 +54,7 @@ def checkCoherency ( device, bbMode ):
valid = True valid = True
if pmatrix: if pmatrix:
print 'MultiCapacitor.checkCoherency(): Matrix:'
rows = pmatrix.getRows () rows = pmatrix.getRows ()
columns = pmatrix.getColumns() columns = pmatrix.getColumns()
@ -96,22 +98,40 @@ def layout ( device, bbMode ):
if device.isMIM(): typeArg = 'MIMCap' if device.isMIM(): typeArg = 'MIMCap'
if device.isMOM(): typeArg = 'MOMCap' if device.isMOM(): typeArg = 'MOMCap'
print 'matrixSizeArg', matrixSizeArg
#capaGenerator = CapacitorStack( device
# , capValuesArg
# , typeArg
# , matrixSizeArg
# , vTrackNetsArg
# , matrixDim =matrixSizeArg
# , matchingMode =True
# , matchingScheme=matchingSchemeArg
# , dummyRing =False
# )
capaGenerator = CapacitorStack( device capaGenerator = CapacitorStack( device
, capValuesArg , capValuesArg
, typeArg , typeArg
, matrixSizeArg , [0,0] # AB position.
, vTrackNetsArg , vTrackNetsArg
, matrixDim =matrixSizeArg #, matrixDim =matrixSizeArg
, matchingMode =True #, matchingMode =True
, matchingScheme=matchingSchemeArg #, matchingScheme=matchingSchemeArg
, dummyRing =False , dummyRing =False
) )
capaMatrix = capaGenerator.create() capaMatrix = capaGenerator.create()
capaTracks = VerticalRoutingTracks( capaGenerator, capaMatrix, True ) if hasattr(capaMatrix,'doMatrix') and capaMatrix.doMatrix:
capaTracks.create() capaTracks = VerticalRoutingTracks( capaGenerator, capaMatrix, True )
capaTracks.create()
capaRouted = RoutMatchedCapacitor( capaTracks ) capaRouted = RoutMatchedCapacitor( capaTracks )
capaRouted.route() capaRouted.route()
else:
capaSingle = RouteCapacitorSingle( capaGenerator
, capaMatrix
, topPlateWSpec=[0,1]
, bottomPlateWSpec=[1,0] )
capaSingle.route()
paramsMatrix.setGlobalCapacitorParams( device.getAbutmentBox() ) paramsMatrix.setGlobalCapacitorParams( device.getAbutmentBox() )
trace( 100, '++' ) trace( 100, '++' )