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 ): def catch ( errorObject ):
if isinstance(errorObject,ErrorMessage): if isinstance(errorObject,ErrorMessage):
em = errorObject em = errorObject
else: else:
em = ErrorMessage( 2, errorObject ) em = ErrorMessage( 2, errorObject )
em.trace = traceback.extract_tb( sys.exc_info()[2] ) em.trace = traceback.extract_tb( sys.exc_info()[2] )
#em.scriptPath = __file__ #em.scriptPath = __file__
print em print em
print helpers.textStackTrace( em.trace, True, em.scriptPath ) print helpers.textStackTrace( em.trace, True, em.scriptPath )
if Viewer.Graphics.get().isEnabled(): if Viewer.Graphics.get().isEnabled():
tryCont = ErrorWidget( em ).exec_() tryCont = ErrorWidget( em ).exec_()
if UpdateSession.getStackSize() > 0: UpdateSession.close() if UpdateSession.getStackSize() > 0: UpdateSession.close()
return return

View File

@ -62,9 +62,11 @@ extern "C" {
} }
switch ( pyType ) { switch ( pyType ) {
case Resistor::LOWRES: case Resistor::LOWRES:
case Resistor::HIRES: break; case Resistor::HIRES:
case Resistor::RPOLYH:
case Resistor::RPOLY2PH: break;
default: 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; return NULL;
} }

View File

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

View File

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

View File

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