Resistor integration.

* New: In Isobar::PyResistor, manage type RPOLYH and RPOLY2PH.
* Change: In Hurricane::Resistor, rename plate nets from "PIN1" and
    "PIN2" into "t1" and "t2" (try to respect uniform naming scheme).
* New: In Karakaze/AnalogDesign.py, support for reading Resistor
    parameters.
* New: In Orosshi, ResistorSnake.py imported from Mariam Tlili's work
    and associated Resistor.py to make parameter conversion.
      Currently we only uses vertical layout for resistors.
      Added METAL2 horizontal terminals for resistors.
This commit is contained in:
Jean-Paul Chaput 2020-03-30 12:40:29 +02:00
parent 2fa8016eaa
commit e9ce33a857
8 changed files with 1635 additions and 86 deletions

View File

@ -248,17 +248,17 @@ class ErrorMessage ( Exception ):
def catch ( errorObject ):
if isinstance(errorObject,ErrorMessage):
em = errorObject
em = errorObject
else:
em = ErrorMessage( 2, errorObject )
em.trace = traceback.extract_tb( sys.exc_info()[2] )
#em.scriptPath = __file__
em = ErrorMessage( 2, errorObject )
em.trace = traceback.extract_tb( sys.exc_info()[2] )
#em.scriptPath = __file__
print em
print helpers.textStackTrace( em.trace, True, em.scriptPath )
if Viewer.Graphics.get().isEnabled():
tryCont = ErrorWidget( em ).exec_()
tryCont = ErrorWidget( em ).exec_()
if UpdateSession.getStackSize() > 0: UpdateSession.close()
return

View File

@ -62,9 +62,11 @@ extern "C" {
}
switch ( pyType ) {
case Resistor::LOWRES:
case Resistor::HIRES: break;
case Resistor::HIRES:
case Resistor::RPOLYH:
case Resistor::RPOLY2PH: break;
default:
PyErr_SetString ( ConstructorError, "Resistor.create(): Type argument is neither LOWRES nor HIRES." );
PyErr_SetString ( ConstructorError, "Resistor.create(): Type argument is neither LOWRES, HIRES, RPOLYH nor RPOLY2PH." );
return NULL;
}

View File

@ -54,21 +54,21 @@ namespace Analog {
void Resistor::createConnections ()
{
Net* pin1 = Net::create( this, Name("PIN1") );
pin1->setExternal(true);
Net* t1 = Net::create( this, Name("t1") );
t1->setExternal(true);
Net* pin2 = Net::create( this, Name("PIN2") );
pin2->setExternal(true);
Net* t2 = Net::create( this, Name("t2") );
t2->setExternal(true);
_metaResistor = MetaResistor::create( getSubDevicesLibrary(), Name("R1") );
Instance* metaResistorIns = Instance::create( this, Name("R1Instance"), _metaResistor );
setReferenceResistor( _metaResistor );
Plug* mrPin1Plug = metaResistorIns->getPlug( _metaResistor->getPin1() );
mrPin1Plug->setNet( pin1 );
Plug* mrPin2Plug = metaResistorIns->getPlug( _metaResistor->getPin2() );
mrPin2Plug->setNet( pin2 );
Plug* mrT1Plug = metaResistorIns->getPlug( _metaResistor->getPin1() );
mrT1Plug->setNet( t1 );
Plug* mrT2Plug = metaResistorIns->getPlug( _metaResistor->getPin2() );
mrT2Plug->setNet( t2 );
}
@ -88,14 +88,14 @@ namespace Analog {
unsigned int west = 0;
unsigned int east = 2;
unsigned int south = 4;
unsigned int north = 6;
unsigned int north = 8;
unsigned int rule = 0;
if (net->getName() == namePin1) {
rule = (yes << south) | (yes << east) | (yes << west);
rule = (yes << east) | (yes << west);
} else {
if (net->getName() == namePin2) {
rule = (yes << north) | (yes << east) | (yes << west);
rule = (yes << east) | (yes << west);
} else {
cerr << Error( "Resistor::getRestriction(): Resistor device do not have Net named \"%s\"."
, getString(net->getName()).c_str()

View File

@ -54,25 +54,27 @@ import Katana
import Bora
#helpers.setTraceLevel( 110 )
helpers.setTraceLevel( 100 )
NMOS = Transistor.NMOS
PMOS = Transistor.PMOS
PIP = CapacitorFamily.PIP
MIM = CapacitorFamily.MIM
MOM = CapacitorFamily.MOM
LOWRES = ResistorFamily.LOWRES
HIRES = ResistorFamily.HIRES
Center = SlicingNode.AlignCenter
Left = SlicingNode.AlignLeft
Right = SlicingNode.AlignRight
Top = SlicingNode.AlignTop
Bottom = SlicingNode.AlignBottom
Unknown = SlicingNode.AlignBottom
VNode = 1
HNode = 2
DNode = 3
NMOS = Transistor.NMOS
PMOS = Transistor.PMOS
PIP = CapacitorFamily.PIP
MIM = CapacitorFamily.MIM
MOM = CapacitorFamily.MOM
LOWRES = ResistorFamily.LOWRES
HIRES = ResistorFamily.HIRES
RPOLYH = ResistorFamily.RPOLYH
RPOLY2PH = ResistorFamily.RPOLY2PH
Center = SlicingNode.AlignCenter
Left = SlicingNode.AlignLeft
Right = SlicingNode.AlignRight
Top = SlicingNode.AlignTop
Bottom = SlicingNode.AlignBottom
Unknown = SlicingNode.AlignBottom
VNode = 1
HNode = 2
DNode = 3
def toDbU ( value ): return DbU.fromPhysical( value, DbU.UnitPowerMicro )
@ -265,7 +267,7 @@ class AnalogDesign ( object ):
specSize = 0
if isderived(dspec[0],TransistorFamily): specSize = 12
elif isderived(dspec[0], CapacitorFamily): specSize = 7
elif isderived(dspec[0], ResistorFamily): specSize = 5
elif isderived(dspec[0], ResistorFamily): specSize = 8
else:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], has unsupported device type.' \
% (count)
@ -282,7 +284,7 @@ class AnalogDesign ( object ):
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [2] (layout style) is *not* a string.' % count
, '%s' % str(dspec) ])
if specSize == 12:
if isderived(dspec[0],TransistorFamily):
if dspec[3] not in [NMOS, PMOS]:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [3] (type) must be either NMOS or PMOS.' % count
, '%s' % str(dspec) ])
@ -315,7 +317,7 @@ class AnalogDesign ( object ):
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [11] (bulk connected) is *not* a boolean.' % count
, '%s' % str(dspec) ])
elif specSize == 7:
elif isderived(dspec[0], CapacitorFamily):
if dspec[3] not in [PIP, MIM, MOM]:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [3] (type) must be either PIP, MIM or MOM.' % count
, '%s' % str(dspec) ])
@ -325,11 +327,11 @@ class AnalogDesign ( object ):
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [4] (Cs) should either be *one* float or a *list* of floats.' % count
, '%s' % str(dspec) ])
elif specSize == 5:
if dspec[3] not in [LOWRES, HIRES]:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [3] (type) must be either LOWRES or HIRES.' % count
elif isderived(dspec[0],ResistorFamily):
if dspec[3] not in [RPOLYH, RPOLY2PH]:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [3] (type) must be either RPOLYH or RPOLY2PH.' % count
, '%s' % str(dspec) ])
if isinstance(dspec[4],float): pass
if isinstance(dspec[5],float): pass
else:
raise Error( 3, [ 'AnalogDesign.doDevices(): \"self.devicesSpecs\" entry [%d], field [4] (resistance) must be a float.' % count
, '%s' % str(dspec) ])
@ -435,9 +437,15 @@ class AnalogDesign ( object ):
device.getParameter( 'capacities' ).setValue( i, capaValues[i] )
elif isderived(dspec[0],ResistorFamily):
print dspec
device = dspec[0].create( self.library, dspec[1], dspec[3] )
device.getParameter( 'Layout Styles' ).setValue ( dspec[2] )
device.getParameter( 'Resistance' ).setMatrix( dspec[4] )
device.getParameter( 'R' ).setValue( dspec[4] )
device.getParameter( 'W' ).setValue( toDbU(dspec[5]) )
device.getParameter( 'L' ).setValue( toDbU(dspec[6]) )
device.getParameter( 'bends' ).setValue( dspec[7] )
trace( 100, '\tW:{0}\n'.format(dspec[5]) )
trace( 100, '\tpW:{0}\n'.format(device.getParameter('W')) )
trace( 100, '\tbends:{0}\n'.format(dspec[7]) )
else:
raise ErrorMessage( 1, 'AnalogDesign.doDevice(): Unknown/unsupported device "%s".' % str(dspec[0]) )
@ -450,6 +458,7 @@ class AnalogDesign ( object ):
, Instance.PlacementStatus.UNPLACED )
self.__dict__[ dspec[1] ] = instance
trace( 100, '\tAdd Instance:{0}\n'.format(dspec[1]) )
return

View File

@ -15,6 +15,7 @@
CapacitorRoutedSingle.py
MultiCapacitor.py
ResistorSnake.py
Resistor.py
)
install( FILES ${pythonFiles} DESTINATION ${PYTHON_SITE_PACKAGES}/oroshi )

80
oroshi/python/Resistor.py Normal file
View File

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
from Hurricane import DataBase
from Hurricane import UpdateSession
from Hurricane import DbU
from Hurricane import Box
from Hurricane import Net
import helpers
import helpers.io
from helpers import trace
helpers.setTraceLevel( 100 )
import Analog
import ParamsMatrix
import oroshi
from Analog import Device
from ResistorSnake import Resistor
def checkCoherency ( device, bbMode ):
message = 'Resistor.checkCoherency(): device "%s".\n' % device.getName()
techno = DataBase.getDB().getTechnology()
rules = oroshi.getRules()
resistance = device.getParameter( 'R' )
if resistance is None:
message += ' Missing "resistance" parameter on %s' % str(device)
return (False, message)
return (True, "")
def layout ( device, bbMode ):
trace( 100, ',+', '\tResistor.layout() called for "%s".\n' % device.getName())
paramsMatrix = ParamsMatrix.ParamsMatrix()
try:
resistance = device.getParameter( 'R' ).getValue()
width = device.getParameter( 'W' ).getValue()
length = device.getParameter( 'L' ).getValue()
bends = device.getParameter( 'bends' ).getValue()
trace( 100, '\tpW:{0}\n'.format(device.getParameter('W')) )
trace( 100, '\tresistance:{0}, width:{1}, length:{2}\n'.format(resistance,width,length) )
typeArg = 'UnknownType'
if device.isRPOLYH(): typeArg = 'RPOLYH'
if device.isRPOLY2PH(): typeArg = 'RPOLY2PH'
netsArg = [ device.getNet('t1'), device.getNet('t2') ]
resistor = Resistor( device
, netsArg
, typeArg
, resistance
, resDim={ 'width':width, 'length':length }
, direction='vertical'
, bends=bends
, shape=135
)
resistor.create()
for net in netsArg:
device.setRestrictions( net, Device.SouthBlocked|Device.NorthBlocked )
paramsMatrix.setGlobalCapacitorParams( device.getAbutmentBox() )
trace( 100, '++' )
#paramsMatrix.trace()
except Exception, e:
helpers.io.catch( e )
trace( 100, '---' )
return paramsMatrix.getMatrix()

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
V ALLIANCE : 6
H capacitor,P,12/12/2019,100
A 0,0,27184,27184
EOF