2020-04-08 04:24:42 -05:00
|
|
|
# -*- 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
|
|
|
|
from Analog import Device
|
|
|
|
import oroshi
|
|
|
|
import oroshi.paramsmatrix
|
|
|
|
from oroshi.capacitorunit import CapacitorUnit
|
|
|
|
from oroshi.capacitormatrix import CapacitorStack
|
|
|
|
from oroshi.capacitorvrtracks import VerticalRoutingTracks
|
|
|
|
from oroshi.capacitorrouted import RoutMatchedCapacitor
|
|
|
|
from oroshi.capacitorroutedsingle import RouteCapacitorSingle
|
|
|
|
|
|
|
|
|
|
|
|
def toMatrixArgs ( matrix ):
|
|
|
|
valid = True
|
|
|
|
rows = matrix.getRows ()
|
|
|
|
columns = matrix.getColumns()
|
|
|
|
lol = []
|
|
|
|
|
|
|
|
for row in range(rows):
|
|
|
|
lol.append( [] )
|
|
|
|
for column in range(columns):
|
|
|
|
lol[-1].append( matrix.getValue(row,column) )
|
|
|
|
|
|
|
|
return [rows,columns], lol
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def checkCoherency ( device, bbMode ):
|
|
|
|
message = 'CapacitorMatrix.checkCoherency(): device "%s".\n' % device.getName()
|
|
|
|
|
|
|
|
techno = DataBase.getDB().getTechnology()
|
|
|
|
rules = oroshi.getRules()
|
|
|
|
|
|
|
|
capacities = device.getParameter( 'capacities' )
|
|
|
|
if capacities is None:
|
|
|
|
message += ' Missing "capacities" parameter on %s' % str(device)
|
|
|
|
return (False, message)
|
|
|
|
|
|
|
|
pmatrix = device.getParameter( 'matrix' )
|
|
|
|
if pmatrix is None:
|
|
|
|
message += ' Missing "matrix" parameter on %s' % str(device)
|
|
|
|
return (False, message)
|
|
|
|
|
|
|
|
valid = True
|
|
|
|
if pmatrix:
|
|
|
|
rows = pmatrix.getRows ()
|
|
|
|
columns = pmatrix.getColumns()
|
|
|
|
|
|
|
|
for row in range(rows):
|
|
|
|
#print ' [',
|
|
|
|
for column in range(columns):
|
|
|
|
capaIndex = pmatrix.getValue(row,column)
|
|
|
|
#print '%2d' % capaIndex,
|
|
|
|
|
|
|
|
if capaIndex >= capacities.getCount():
|
|
|
|
valid = False
|
|
|
|
message += ' element [%d,%d] == %d is out of range, must be in [0..%d]\n' \
|
|
|
|
% (row,column,capaIndex,capacities.getCount()-1)
|
|
|
|
#print ']'
|
|
|
|
|
|
|
|
if not valid: return (False, message)
|
|
|
|
|
|
|
|
return (True, "")
|
|
|
|
|
|
|
|
|
|
|
|
def addDummyNets ( device ):
|
|
|
|
if not device.hasDummy(): return
|
|
|
|
|
|
|
|
i = device.getParameter( 'capacities' ).getCount()
|
|
|
|
topName = 't%d'%i
|
|
|
|
botName = 'b%d'%i
|
|
|
|
|
|
|
|
topNet = device.getNet( topName )
|
|
|
|
if not topNet:
|
|
|
|
topNet = Net.create( device, topName )
|
|
|
|
topNet.setExternal( True )
|
|
|
|
|
|
|
|
botNet = device.getNet( botName )
|
|
|
|
if not botNet:
|
|
|
|
botNet = Net.create( device, botName )
|
|
|
|
botNet.setExternal( True )
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
def layout ( device, bbMode ):
|
|
|
|
|
|
|
|
trace( 100, ',+', '\tMultiCapacitor.layout() called for "%s".\n' % device.getName())
|
|
|
|
|
|
|
|
paramsMatrix = oroshi.paramsmatrix.ParamsMatrix()
|
|
|
|
|
|
|
|
try:
|
|
|
|
capacities = device.getParameter( 'capacities' )
|
|
|
|
dummyArg = device.hasDummy()
|
|
|
|
capaValuesArg = []
|
|
|
|
vTrackNetsArg = []
|
|
|
|
|
|
|
|
addDummyNets( device )
|
|
|
|
|
|
|
|
for i in range(capacities.getCount()):
|
|
|
|
capaValuesArg.append( capacities.getValue(i)*1000.0 )
|
|
|
|
vTrackNetsArg.append( [ device.getNet('t%d'%i), device.getNet("b%d"%i) ] )
|
|
|
|
|
|
|
|
if dummyArg:
|
|
|
|
i = device.getParameter( 'capacities' ).getCount()
|
|
|
|
vTrackNetsArg.append( [ device.getNet('t%d'%i), device.getNet("b%d"%i) ] )
|
|
|
|
|
|
|
|
matrixSizeArg, matchingSchemeArg = toMatrixArgs( device.getParameter('matrix') )
|
|
|
|
|
|
|
|
typeArg = 'UnknownType'
|
|
|
|
if device.isPIP(): typeArg = 'PIPCap'
|
|
|
|
if device.isMIM(): typeArg = 'MIMCap'
|
|
|
|
if device.isMOM(): typeArg = 'MOMCap'
|
|
|
|
|
|
|
|
if len(capaValuesArg) == 1:
|
|
|
|
# One capa, multiple units.
|
|
|
|
capaGenerator = CapacitorStack( device
|
|
|
|
, capaValuesArg # (fF).
|
|
|
|
, typeArg
|
|
|
|
, [0,0] # AB position.
|
|
|
|
, vTrackNetsArg
|
|
|
|
, matrixDim =matrixSizeArg
|
|
|
|
, dummyRing =dummyArg
|
|
|
|
)
|
|
|
|
capaMatrix = capaGenerator.create()
|
|
|
|
capaSingle = RouteCapacitorSingle( capaGenerator
|
|
|
|
, capaMatrix
|
|
|
|
, topPlateWSpec=[1,0]
|
|
|
|
, bottomPlateWSpec=[0,1] )
|
|
|
|
capaSingle.route()
|
|
|
|
else:
|
|
|
|
# Two capa, multiple units.
|
|
|
|
capaGenerator = CapacitorStack( device
|
|
|
|
, capaValuesArg # [ 240, 720 ] # capaValuesArg (fF).
|
|
|
|
, typeArg
|
|
|
|
, [0,0] # AB position.
|
|
|
|
, vTrackNetsArg
|
|
|
|
, matrixDim =matrixSizeArg
|
|
|
|
, matchingMode =True
|
|
|
|
, matchingScheme=matchingSchemeArg
|
|
|
|
, dummyRing =dummyArg
|
|
|
|
)
|
|
|
|
capaMatrix = capaGenerator.create()
|
|
|
|
capaTracks = VerticalRoutingTracks( capaGenerator, capaMatrix, True )
|
|
|
|
capaTracks.create()
|
|
|
|
|
|
|
|
capaRouted = RoutMatchedCapacitor( capaTracks )
|
|
|
|
capaRouted.route()
|
|
|
|
|
|
|
|
for pair in vTrackNetsArg:
|
|
|
|
for net in pair:
|
|
|
|
device.setRestrictions( net, Device.NorthBlocked|Device.SouthBlocked )
|
|
|
|
|
|
|
|
paramsMatrix.setGlobalCapacitorParams( device.getAbutmentBox() )
|
|
|
|
trace( 100, '++' )
|
|
|
|
#paramsMatrix.trace()
|
|
|
|
|
2022-07-13 04:20:55 -05:00
|
|
|
except Exception as e:
|
2020-04-08 04:24:42 -05:00
|
|
|
helpers.io.catch( e )
|
|
|
|
|
|
|
|
trace( 100, '---' )
|
|
|
|
|
|
|
|
return paramsMatrix.getMatrix()
|