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:
parent
eea67a9111
commit
057501a8df
|
@ -189,7 +189,10 @@ namespace Bora {
|
|||
{
|
||||
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 (getNbChild() == 1) {
|
||||
|
|
|
@ -70,7 +70,8 @@ namespace Bora {
|
|||
TransistorFamily* device = dynamic_cast<TransistorFamily *>( cell );
|
||||
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
|
||||
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) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
|
||||
, getString(device->getName()).c_str()
|
||||
|
@ -94,11 +95,14 @@ namespace Bora {
|
|||
MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( nodeset->getRange() );
|
||||
|
||||
if (mcapacitor) {
|
||||
cdebug_log(535,0) << "NodeSets::create(): for a Capacitor Analog Device" << endl;
|
||||
|
||||
if (not matrixRange) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s."
|
||||
, getString(mcapacitor->getName()).c_str()
|
||||
, getString(stepRange).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
matrixRange->reset();
|
||||
do {
|
||||
|
@ -109,15 +113,18 @@ namespace Bora {
|
|||
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 {
|
||||
ResistorFamily* device = dynamic_cast<ResistorFamily *>( cell );
|
||||
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( nodeset->getRange() );
|
||||
if (device) {
|
||||
cdebug_log(535,0) << "NodeSets::create(): for a Resistor Analog Device" << endl;
|
||||
|
||||
if (not stepRange) {
|
||||
throw Error( "NodeSets::create(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
|
||||
, getString(device->getName()).c_str()
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "crlcore/PyRoutingGauge.h"
|
||||
#include "bora/PyDSlicingNode.h"
|
||||
#include "bora/PyStepParameterRange.h"
|
||||
#include "bora/PyMatrixParameterRange.h"
|
||||
|
||||
|
||||
namespace Bora {
|
||||
|
@ -73,8 +74,9 @@ extern "C" {
|
|||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Second argument *must* be of type Cell." );
|
||||
return NULL;
|
||||
}
|
||||
if (not IsPyStepParameterRange(pyParameterRange)) {
|
||||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange." );
|
||||
if ( not IsPyStepParameterRange(pyParameterRange)
|
||||
and not IsPyMatrixParameterRange(pyParameterRange)) {
|
||||
PyErr_SetString( ConstructorError, "DSlicingNode.create(): Third argument *must* be of type StepParameterRange or MatrixParameterRange." );
|
||||
return NULL;
|
||||
}
|
||||
if (pyRoutingGauge and not IsPyRoutingGauge(pyRoutingGauge)) {
|
||||
|
@ -84,6 +86,14 @@ extern "C" {
|
|||
|
||||
Cell* cell = PYCELL_O( pyCell );
|
||||
Instance* instance = cell->getInstance( PyString_AsString(pyInstance) );
|
||||
if (not instance) {
|
||||
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;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "bora/PyParameterRange.h"
|
||||
#include "bora/PyStepParameterRange.h"
|
||||
#include "bora/PyMatrixParameterRange.h"
|
||||
|
||||
|
||||
namespace Bora {
|
||||
|
@ -113,6 +114,7 @@ extern "C" {
|
|||
|
||||
ParameterRange* ParameterRangeCast ( PyObject* derivedObject ) {
|
||||
if (IsPyStepParameterRange (derivedObject)) return PYSTEPPARAMETERRANGE_O (derivedObject);
|
||||
if (IsPyMatrixParameterRange(derivedObject)) return PYMATRIXPARAMETERRANGE_O(derivedObject);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -396,14 +396,18 @@ namespace Bora {
|
|||
for( Instance* iInstance : instances ) {
|
||||
Cell* model = iInstance->getMasterCell();
|
||||
Device* device = dynamic_cast<Device*>(model);
|
||||
cerr << "device:" << device << endl;
|
||||
|
||||
if (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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // Bora namespace.
|
||||
|
|
|
@ -54,6 +54,9 @@ import Katana
|
|||
import Bora
|
||||
|
||||
|
||||
helpers.setTraceLevel( 110 )
|
||||
|
||||
|
||||
NMOS = Transistor.NMOS
|
||||
PMOS = Transistor.PMOS
|
||||
PIP = CapacitorFamily.PIP
|
||||
|
@ -350,8 +353,18 @@ class AnalogDesign ( object ):
|
|||
|
||||
if not path: return
|
||||
self.parameters.read( path );
|
||||
|
||||
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]
|
||||
Tparameters = self.parameters.getTransistor( Tname )
|
||||
if not Tparameters:
|
||||
|
@ -410,6 +423,8 @@ class AnalogDesign ( object ):
|
|||
|
||||
device = dspec[0].create( self.library, dspec[1], dspec[3], len(capaValues) )
|
||||
device.getParameter( 'Layout Styles' ).setValue( dspec[2] )
|
||||
print device.getParameter( 'matrix' )
|
||||
device.getParameter( 'matrix' ).setMatrix( dspec[5] )
|
||||
for i in range(len(capaValues)):
|
||||
device.getParameter( 'capacities' ).setValue( i, capaValues[i] )
|
||||
|
||||
|
|
|
@ -7,15 +7,31 @@ class Parameters ( object ):
|
|||
class Transistor ( object ):
|
||||
|
||||
def __init__ ( self, aName ):
|
||||
name = aName
|
||||
L = 0.0
|
||||
W = 0.0
|
||||
M = 0
|
||||
self.name = aName
|
||||
self.L = 0.0
|
||||
self.W = 0.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
|
||||
|
||||
|
||||
def __init__ ( self ):
|
||||
self.transistors = { }
|
||||
self.capacitors = { }
|
||||
self.resistors = { }
|
||||
self.indexToName = { }
|
||||
return
|
||||
|
||||
|
@ -54,13 +70,59 @@ class Parameters ( object ):
|
|||
#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 ):
|
||||
reSpecCapa = re.compile( r'^(?P<name>C\w+)\s+(?P<value>.*)$' )
|
||||
reSpecResis = re.compile( r'^(?P<name>R\w+)\s+(?P<value>.*)$' )
|
||||
reSpecTran = re.compile( r'^\* SPECIFICATIONS DE M(?P<index>\d+)\s+:\s+(?P<name>\w+) \*$' )
|
||||
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' )
|
||||
for line in fd.readlines():
|
||||
if line.startswith('REGIME_'): continue
|
||||
|
||||
m = reSpecTran.match( line[:-1] )
|
||||
if m:
|
||||
|
@ -93,4 +155,12 @@ class Parameters ( object ):
|
|||
self.getTransistor(i).M = M
|
||||
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()
|
||||
|
|
|
@ -39,6 +39,8 @@ class CapacitorStack( CapacitorUnit ):
|
|||
# \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 ):
|
||||
print 'CapacitorStack.__init__()'
|
||||
print 'matrixDim:', matrixDim
|
||||
|
||||
self.device = device
|
||||
self.capacitorType = capacitorType
|
||||
|
@ -62,6 +64,7 @@ class CapacitorStack( CapacitorUnit ):
|
|||
self.vRoutingTrack_width = 0
|
||||
|
||||
if self.__areInputDataOK__(capacitance) == True :
|
||||
print 'Input data are OK'
|
||||
if self.matchingMode == False :
|
||||
self.compactCapDim = self.__computeCapDim__( capacitance[0] , capacitorType )
|
||||
|
||||
|
@ -134,24 +137,29 @@ class CapacitorStack( CapacitorUnit ):
|
|||
|
||||
|
||||
def __initGivenZeroUnitCap__( self, capacitance ):
|
||||
print '__initGivenZeroUnitCap__'
|
||||
print self.matrixDim.values()
|
||||
|
||||
if ( self.matrixDim.values() == [1,1] and CapacitorUnit.__isCapacitorUnitOK__(self, self.compactCapDim) ):
|
||||
|
||||
print 'Case 1'
|
||||
[ self.capacitance , self.unitCapDim ] = [ capacitance , 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
|
||||
|
||||
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 :
|
||||
print 'This is a mutlicapacitor'
|
||||
self.unitCapDim = unitCapDim
|
||||
[ 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
|
||||
|
||||
|
@ -181,6 +189,7 @@ class CapacitorStack( CapacitorUnit ):
|
|||
|
||||
|
||||
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)) :
|
||||
|
||||
|
@ -237,6 +246,10 @@ class CapacitorStack( CapacitorUnit ):
|
|||
for k in range(0, self.capacitorsNumber):
|
||||
unitCapList.append( capacitance[k]/self.capacitorIdOccurence(k) )
|
||||
|
||||
print self.capacitorsNumber
|
||||
print 'capacitance', capacitance
|
||||
print 'unitCapList', unitCapList
|
||||
print '============='
|
||||
return unitCapList
|
||||
|
||||
|
||||
|
@ -344,7 +357,8 @@ class CapacitorStack( CapacitorUnit ):
|
|||
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 )
|
||||
else:
|
||||
raise Error(1, 'create(): The bonding box mode parameter, "bbMode" must be either True or False : %s.' %bbMode )
|
||||
|
||||
UpdateSession.close ()
|
||||
|
||||
|
@ -372,7 +386,7 @@ class CapacitorStack( CapacitorUnit ):
|
|||
self.drawTopPlatesRLayers ( topPlateRLayer , drawnActiveCapacitor )
|
||||
|
||||
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] )
|
||||
|
||||
return drawnCapacitor
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
print "SOURCE RouteCapacitorSingle"
|
||||
|
||||
import sys
|
||||
import numpy
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
from math import sqrt, ceil
|
||||
import helpers
|
||||
from helpers import ErrorMessage as Error
|
||||
from helpers.io import ErrorMessage as Error
|
||||
from helpers import trace
|
||||
import oroshi
|
||||
from CapacitorFinal6 import CapacitorUnit
|
||||
from CapacitorMatrix20 import CapacitorStack
|
||||
from CapacitorUnit import CapacitorUnit
|
||||
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.
|
||||
# The dummy mode is also supported.
|
||||
# The dummyRing mode is not yet supported.
|
||||
|
||||
def toDbU ( l ): return DbU.fromPhysical( l, DbU.UnitPowerMicro )
|
||||
def toPhY ( l ): return DbU.toPhysical ( l, DbU.UnitPowerMicro )
|
||||
|
||||
def doBreak( level, message ):
|
||||
UpdateSession.close()
|
||||
|
@ -23,7 +28,7 @@ def doBreak( level, message ):
|
|||
|
||||
helpers.staticInitialization( True )
|
||||
|
||||
class RoutCapacitor( CapacitorUnit ):
|
||||
class RouteCapacitorSingle( CapacitorUnit ):
|
||||
|
||||
rules = oroshi.getRules()
|
||||
|
||||
|
@ -96,7 +101,7 @@ class RoutCapacitor( CapacitorUnit ):
|
|||
# - the capacitor type (ie., cuts2 if MIMCAP, cut1 if PIPCAP )
|
||||
# - routing tracks layers according to the designer specifications.
|
||||
|
||||
def rout( self, bbMode = False ):
|
||||
def route( self, bbMode = False ):
|
||||
|
||||
UpdateSession.open ()
|
||||
|
||||
|
@ -117,7 +122,7 @@ class RoutCapacitor( CapacitorUnit ):
|
|||
elif self.capacitorType == 'PIPCap' :
|
||||
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 )
|
||||
|
@ -145,19 +150,19 @@ class RoutCapacitor( CapacitorUnit ):
|
|||
def 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' :
|
||||
|
||||
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RoutCapacitor.rules.minWidth_cut2 )
|
||||
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RoutCapacitor.rules.minSpacing_cut2 )
|
||||
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RoutCapacitor.rules.minWidth_cut2 )
|
||||
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut2 )
|
||||
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RouteCapacitorSingle.rules.minSpacing_cut2 )
|
||||
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut2 )
|
||||
|
||||
elif self.capacitorType == 'PIPCap' :
|
||||
|
||||
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RoutCapacitor.rules.minWidth_cut1 )
|
||||
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RoutCapacitor.rules.minSpacing_cut1 )
|
||||
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RoutCapacitor.rules.minWidth_cut1 )
|
||||
CapacitorUnit.__setattr__( self, "minHeight_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut1 )
|
||||
CapacitorUnit.__setattr__( self, "minSpacing_routingTrackcut" , RouteCapacitorSingle.rules.minSpacing_cut1 )
|
||||
CapacitorUnit.__setattr__( self, "minWidth_routingTrackcut" , RouteCapacitorSingle.rules.minWidth_cut1 )
|
||||
|
||||
else : raise Error(1, 'setRules() : Unsupported capacitor type "%s".' % self.capacitorType )
|
||||
|
||||
|
@ -610,18 +615,31 @@ def ScriptMain( **kw ):
|
|||
UpdateSession.open()
|
||||
|
||||
nets = [[t0,b0]]
|
||||
capacitance = [400]
|
||||
|
||||
capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 400)
|
||||
# capacitorInstance = CapacitorStack( Device, 400, 'MIMCap', [0,0], unitCap = 100 )
|
||||
## A matrix of unit capacitors (all are active or all are dummy capacitors)
|
||||
|
||||
# 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()
|
||||
print(capacitor)
|
||||
# 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] )
|
||||
routedCap = RoutCapacitor( capacitorInstance, capacitor, dummyMode = True, tracksNumbers = [1,0] ) #, topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] )
|
||||
# routedCap = RoutCapacitor( capacitorInstance, capacitor, dummyMode = True , tracksNumbers = [1,0]) #, topPlateWSpec = [1,0] , bottomPlateWSpec = [1,0] )
|
||||
bondingBox = routedCap.rout()
|
||||
print(bondingBox)
|
||||
routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, topPlateWSpec = [0,1] , bottomPlateWSpec = [1,0] )
|
||||
|
||||
## Unit capacitor ( a dummy capacitor )
|
||||
# capacitance = [600]
|
||||
# capacitorInstance = CapacitorStack( Device, capacitance, 'MIMCap', [0,0], nets,unitCap = 600)
|
||||
# capacitor = capacitorInstance.create()
|
||||
# routedCap = RouteCapacitorSingle( capacitorInstance, capacitor, dummyMode = True, tracksNumbers = [1,0] )
|
||||
|
||||
|
||||
bondingBox = routedCap.route()
|
||||
|
||||
AllianceFramework.get().saveCell( Device, Catalog.State.Views )
|
||||
|
||||
|
|
|
@ -174,10 +174,19 @@ class CapacitorUnit():
|
|||
|
||||
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
|
||||
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
|
||||
|
||||
print '__isCapacitorUnitOK__:', state
|
||||
return state
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,9 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
|
|||
|
||||
self.setRules ()
|
||||
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 :
|
||||
self.minimizeVRTs()
|
||||
self.computeVRTDimensions()
|
||||
|
|
|
@ -17,6 +17,7 @@ from CapacitorUnit import CapacitorUnit
|
|||
from CapacitorMatrix import CapacitorStack
|
||||
from CapacitorVRTracks import VerticalRoutingTracks
|
||||
from CapacitorRouted import RoutMatchedCapacitor
|
||||
from CapacitorRoutedSingle import RouteCapacitorSingle
|
||||
|
||||
|
||||
def toMatrixArgs ( matrix ):
|
||||
|
@ -53,6 +54,7 @@ def checkCoherency ( device, bbMode ):
|
|||
|
||||
valid = True
|
||||
if pmatrix:
|
||||
print 'MultiCapacitor.checkCoherency(): Matrix:'
|
||||
rows = pmatrix.getRows ()
|
||||
columns = pmatrix.getColumns()
|
||||
|
||||
|
@ -96,22 +98,40 @@ def layout ( device, bbMode ):
|
|||
if device.isMIM(): typeArg = 'MIMCap'
|
||||
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
|
||||
, capValuesArg
|
||||
, typeArg
|
||||
, matrixSizeArg
|
||||
, [0,0] # AB position.
|
||||
, vTrackNetsArg
|
||||
, matrixDim =matrixSizeArg
|
||||
, matchingMode =True
|
||||
, matchingScheme=matchingSchemeArg
|
||||
#, matrixDim =matrixSizeArg
|
||||
#, matchingMode =True
|
||||
#, matchingScheme=matchingSchemeArg
|
||||
, dummyRing =False
|
||||
)
|
||||
capaMatrix = capaGenerator.create()
|
||||
if hasattr(capaMatrix,'doMatrix') and capaMatrix.doMatrix:
|
||||
capaTracks = VerticalRoutingTracks( capaGenerator, capaMatrix, True )
|
||||
capaTracks.create()
|
||||
|
||||
capaRouted = RoutMatchedCapacitor( capaTracks )
|
||||
capaRouted.route()
|
||||
else:
|
||||
capaSingle = RouteCapacitorSingle( capaGenerator
|
||||
, capaMatrix
|
||||
, topPlateWSpec=[0,1]
|
||||
, bottomPlateWSpec=[1,0] )
|
||||
capaSingle.route()
|
||||
|
||||
paramsMatrix.setGlobalCapacitorParams( device.getAbutmentBox() )
|
||||
trace( 100, '++' )
|
||||
|
|
Loading…
Reference in New Issue