Latest Capacitor corrections by Mariam.

This commit is contained in:
Mariam Tlili 2020-03-06 17:48:42 +01:00
parent f269c6b523
commit 7281129850
4 changed files with 136 additions and 120 deletions

View File

@ -13,6 +13,7 @@ import helpers
import oroshi
import numpy
def toPhY ( l ): return DbU.toPhysical ( l, DbU.UnitPowerMicro )
## Draws the layout of a compact capacitor or a matrix of adjacent identical capacitors. The matrix can be composed of one type of capacitors, either Poly-Poly or Metal-Metal in 350 nm AMS CMOS technology.
@ -42,7 +43,6 @@ class CapacitorStack( CapacitorUnit ):
self.device = device
self.capacitorType = capacitorType
print("self.capacitorType0",self.capacitorType)
self.matrixDim = { "columns" : matrixDim[1], "rows" : matrixDim[0] }
self.unitCapDim = self.__computeCapDim__( unitCap , capacitorType )
@ -169,7 +169,6 @@ class CapacitorStack( CapacitorUnit ):
if capacitance == unitCap : #compact
[ self.capacitance , self.unitCapDim ] = [ capacitance , self.compactCapDim ]
print("capa",capacitance)
elif capacitance <> unitCap : #matrice
self.__initMatrixMode__( capacitance, unitCap )
self.matrixDim = {"columns" : int(sqrt(capacitance/unitCap)), "rows" : int(sqrt(capacitance/unitCap)) } # ici mettre toutes les combi si matching mode = [] sinon utiliser la meme combi que matching scheme
@ -245,9 +244,8 @@ class CapacitorStack( CapacitorUnit ):
state = True
for k in range(0, self.capacitorsNumber):
print('self.capacitorIdOccurence( k )',self.capacitorIdOccurence( k ))
#print('self.capacitorIdOccurence( k )',self.capacitorIdOccurence( k ))
factor = capacitance[k]/unitCap
print('factor',factor)
if factor != self.capacitorIdOccurence( k ) : state = False
return state
@ -303,15 +301,13 @@ class CapacitorStack( CapacitorUnit ):
[ matchingSchemeCapIds , capacitanceIds ] = [ list( numpy.unique(self.matchingScheme) ) , range(0,self.capacitorsNumber) ]
if (self.matchingScheme != [] and set(matchingSchemeCapIds) == set(capacitanceIds) ) or (self.matchingScheme == [] and len(capacitance) == 1) :
print("len(self.nets)",len(self.nets))
print("self.capacitorsNumber + 1",self.capacitorsNumber + 1)
if (len(self.nets) == self.capacitorsNumber + 1 and self.dummyElement == False and self.dummyRing == True ) or (len(self.nets) == self.capacitorsNumber and self.dummyElement == False and self.dummyRing == False) or (len(self.nets) == self.capacitorsNumber and self.dummyElement == True and self.dummyRing == True) or (len(self.nets) == self.capacitorsNumber and self.dummyElement == True and self.dummyRing == False ):
if ( self.matchingMode == True and self.__isMatchingSchemeOK__() ) or ( self.matchingMode == False and self.matchingScheme == [] ):
state = True
else: raise Error(1, '__areInputDataOK__(): Please check compatibility of the entered parameters (Matching mode, matching scheme, capacitance). It must be either equal to (False, [], one capacitance value) or ( True, matching scheme, capacitance values as much as there are capacitor ids in matching scheme ). The entered parameters are (%s, %s, %s).' %(self.matchingMode, self.matchingScheme, capacitance) ) #com2 : tester
else : raise Error(1,'__areInputDataOK__() : Nets number, %s, is incompatible with number of capacitors to be drawn, %s.' %(self.netsNumber, self.capacitorsNumber))
else : raise Error(1,'__areInputDataOK__() : Nets number, %s, is incompatible with number of capacitors to be drawn, %s.' %(len(self.nets), self.capacitorsNumber))
else : raise Error(1, '__areInputDataOK__() : Please check compatibility between matching scheme elements, %s, and capacitance indexes, %s. They must be identical. Otherwise, when matching scheme is "False", capacitance indexes must be [0].' %(matchingSchemeCapIds, capacitanceIds) )
@ -340,7 +336,6 @@ class CapacitorStack( CapacitorUnit ):
if bbMode == True:
output = self.computeBondingBoxDimensions()
print('output',output)
elif bbMode == False :
drawnCapacitor = self.drawCapacitorStack( )
output = drawnCapacitor
@ -372,7 +367,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
@ -388,7 +383,6 @@ class CapacitorStack( CapacitorUnit ):
def capacitorLine( self, dy, abutmentBox_spacing , matchingSchemeRowIndex = 0 ):
print("self.capacitorType",self.capacitorType)
line = [ CapacitorUnit( self.device, self.capacitorType, [self.abutmentBoxPosition["XMin"], dy], capacitance = self.unitCapacitance ) ]
self.createElementInCapacitorLine( line, matchingSchemeRowIndex,0 )
limit = self.matrixDim["columns"] + 2 if self.dummyRing == True else self.matrixDim["columns"]
@ -424,7 +418,6 @@ class CapacitorStack( CapacitorUnit ):
def capacitorMatrix( self, abutmentBox_spacing = 0 ):
#print("capMatrix", nets)
matrix = [ self.capacitorLine( self.abutmentBoxPosition["YMin"], abutmentBox_spacing,0 ) ]
limit = self.matrixDim["rows"] + 2 if self.dummyRing == True else self.matrixDim["rows"]
for i in range( 1, limit ):
@ -445,7 +438,6 @@ class CapacitorStack( CapacitorUnit ):
elif direction == 'horizontal':
for j in range(1, self.matrixDim["columns"] + 2):
print('j',j)
dummyList.append( CapacitorUnit( self.device, self.capacitorType, [dummyList[j-1].abutmentBox.getXMax() + self.abutmentBox_spacing, dy], capacitance = self.unitCapacitance ) )
dummyList[j].create(self.nets[-1][0], self.nets[-1][1])
@ -600,7 +592,8 @@ def ScriptMain( **kw ):
#capacitorInstance = CapacitorStack( device, {"C1" : 558, "C2" : 558, "C3" : 186, "C4" : 186}, 'MIMCap', [0,0], nets, unitCap = 93, matrixDim = [4,4], matchingMode = True, matchingScheme = [ ['C2','C1','C2','C1'] , ['C1','C2','C1','C2'] , ['C2','C1','C2','C1'] , ['C3','C3','C4','C4'] ])
capacitor = capacitorInstance.create()
print(capacitor)
#print(toPhY(capacitor["width"]))
#print(toPhY(capacitor["height"]))
AllianceFramework.get().saveCell( device, Catalog.State.Views )

View File

@ -12,7 +12,19 @@ from CapacitorMatrix import CapacitorStack
from CapacitorVRTracks import VerticalRoutingTracks
## Routs two matched capacitors, C1 and C2, drawn in a capacitor matrix. Connections are put in place with reference to a given matching scheme. Elementary capacitor units are connected to horizontal and vertical routeing tracks that represent top plates and bottom plates nets of C1 and C2 . Supported types of capacitors are Poly-Poly and Metal-Metal. Technologycal rules are provided by 350 nm AMS CMOS technology with three-four metal layers. Metal layers that are used for routeing are placed similarly to horziontal-vertical (HV) symbolic Alliance CAD tool routeer, where horizontal metal channels are drawn in metal 2 and the vertical ones are in metal 3. Given a matrix of dimensions \f$ R*C \f$, the total number of vertical tracks is \f$ 2C+2 \f$ equivalent to \f$ C+1 \f$ couples, ensuring that every elementary capacitor is positioned between four vertical tracks, two from each side. In fact, every adjacent couple of these tracks represent top plates and bottom plates of C1 or C2 as shown in Figure 1.
def toPhY ( l ): return DbU.toPhysical ( l, DbU.UnitPowerMicro )
def doBreak( level, message ):
UpdateSession.close()
Breakpoint.stop( level, message )
UpdateSession.open()
helpers.staticInitialization( True )
## Routs two matched capacitors, C1 and C2, drawn in a capacitor matrix. Connections are put in place with reference to a given matching scheme. Elementary capacitor units are connected to horizontal and vertical routing tracks that represent top plates and bottom plates nets of C1 and C2 . Supported types of capacitors are Poly-Poly and Metal-Metal. Technologycal rules are provided by 350 nm AMS CMOS technology with three-four metal layers. Metal layers that are used for routing are placed similarly to horziontal-vertical (HV) symbolic Alliance CAD tool router, where horizontal metal channels are drawn in metal 2 and the vertical ones are in metal 3. Given a matrix of dimensions \f$ R*C \f$, the total number of vertical tracks is \f$ 2C+2 \f$ equivalent to \f$ C+1 \f$ couples, ensuring that every elementary capacitor is positioned between four vertical tracks, two from each side. In fact, every adjacent couple of these tracks represent top plates and bottom plates of C1 or C2 as shown in Figure 1.
# \image html Layout.png "Layout" width=.1\linewidth
# An elementary capacitor unit can be a part of C1 or C2 according to the matching scheme. However, to respect common-centroid layout specifications, for C1 and C2 to be equal, the matrix number of colums and number of rows must be both even. Addionnally, the number of elementary capacitors dedicated to C1 must be equal to those dedicated to C2. These two conditions are tested in one of the class methods. An exception is raised if at least one of the two is not respected.
@ -35,22 +47,22 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
# \param capacitorType Supported types of capacitors are MIM and PIP only. An exception is raised otherwise.
# \param abutmentBox The matrix's abutment box.
# \param matrxiDim The matrix dimensions, also equal to \c self.matchingScheme nested list dimensions.
# \param abutmentBox_spacing The spacing between elementary units in the matrix. It is computed in \c CapacitorStack and is reloaded in \c RoutMatchedCapacitor. \c self.abutmentBox_spacing includes, vertical routeing tracks width and minimum allowed spacing between two adjacent ones.
# \param hRoutingLayer_width The width of horizontal routeing layers in metal 2, which connect capacitors plates to vertical routeing tracks.
# \param vRoutingTrack_width The width of vertical routeing tracks in metal 3, which connects identical nets together ( ie : bottom plates of C1, top plates of C2, bottom plates of C2 and top plates of C2 ).
# \param hRoutingTrack_width The width of horizontal routeing tracks in metal 2, which connect identical vertical routeing tracks together.
# \param minSpacing_hRoutingTrack Minimum spacing between horizontal routeing tracks. Wide metal 2 specifications are considered since metal 2 dimensions may exceed 10 \f$ m\f$.
# \param abutmentBox_spacing The spacing between elementary units in the matrix. It is computed in \c CapacitorStack and is reloaded in \c RoutMatchedCapacitor. \c self.abutmentBox_spacing includes, vertical routing tracks width and minimum allowed spacing between two adjacent ones.
# \param hRoutingLayer_width The width of horizontal routing layers in metal 2, which connect capacitors plates to vertical routing tracks.
# \param vRoutingTrack_width The width of vertical routing tracks in metal 3, which connects identical nets together ( ie : bottom plates of C1, top plates of C2, bottom plates of C2 and top plates of C2 ).
# \param hRoutingTrack_width The width of horizontal routing tracks in metal 2, which connect identical vertical routing tracks together.
# \param minSpacing_hRoutingTrack Minimum spacing between horizontal routing tracks. Wide metal 2 specifications are considered since metal 2 dimensions may exceed 10 \f$ m\f$.
#
#\remark For more information about wide metal specifications, refer to ENG-183_rev8.pdf technology manual.
#
# \param minimumPosition The ordinate of the top plate's routeing layer's bottom extremity after stretching.
# \param maximumPosition The ordinate of the top plate's routeing layer's top extremity, also equivalent to the top plate's top extremity.
# \param vRoutingTrackXCenter A nested list of ordered dictionaries, with dimensions equal to \c self.matrixDim, containing abcissas of vertical routeing tracks. All sub-lists' lengths are identical and are equal to 2. The first and second elements describe position of top plate track and bottom plate track, respectively. For example, given a matrix of dimensions 2x2, \c self.vRoutingTrackXCenter can be [[0, 2], [4,6], [8,10]] \f$ \mu m\f$. Elements of this nested list have particular indexing as described in Figure 2.
# \param minimumPosition The ordinate of the top plate's routing layer's bottom extremity after stretching.
# \param maximumPosition The ordinate of the top plate's routing layer's top extremity, also equivalent to the top plate's top extremity.
# \param vRoutingTrackXCenter A nested list of ordered dictionaries, with dimensions equal to \c self.matrixDim, containing abcissas of vertical routing tracks. All sub-lists' lengths are identical and are equal to 2. The first and second elements describe position of top plate track and bottom plate track, respectively. For example, given a matrix of dimensions 2x2, \c self.vRoutingTrackXCenter can be [[0, 2], [4,6], [8,10]] \f$ \mu m\f$. Elements of this nested list have particular indexing as described in Figure 2.
#
# \param hRoutingtrackYCenter A nested dicitonary containing two keys, \c topTracks and \c bottomTracks. Each key contains as value a dictionary describing centers' ordinates of four parallel horizontal tracks. The reason why four tracks are needed on top and bottom positions of the matrix is that four nets are used, two for every capacitor \c Ci, were \c i is in [1,2].
# \param hRoutingLayerYCenter A nested dicitonary containing two keys, \c top and \c bottom. Each key contains as value a dictionary describing centers' ordinates of horizontal routeing layers.
# \param vRoutingTrackDict A dictionary of routeing tracks top and bottom extremities ordinates.
# \param topPlateStretching Since not only the same metal 2 layer is used to draw top/bottom plates connections to vertical tracks but also the two plates are superimposed, the top plate's routeing tracks is stretched. \c self.topPlateStretching is therefore the length added to top plate's routeing layer in order to avoid short circuits between top and bottom plates routeing to vertical tracks since the same metal is used for both.
# \param hRoutingLayerYCenter A nested dicitonary containing two keys, \c top and \c bottom. Each key contains as value a dictionary describing centers' ordinates of horizontal routing layers.
# \param vRoutingTrackDict A dictionary of routing tracks top and bottom extremities ordinates.
# \param topPlateStretching Since not only the same metal 2 layer is used to draw top/bottom plates connections to vertical tracks but also the two plates are superimposed, the top plate's routing tracks is stretched. \c self.topPlateStretching is therefore the length added to top plate's routing layer in order to avoid short circuits between top and bottom plates routing to vertical tracks since the same metal is used for both.
def __init__( self, vRTInstance ) :
@ -85,7 +97,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
# -# all required physical layers are loaded,
# -# technology rules are defined according to capacitor type,
# -# layout dimension parameters are computed,
# -# routeing tracks and layers are drawn,
# -# routing tracks and layers are drawn,
# -# top plates are stretched,
# -# all required cuts are drawn,
# -# The \c UpdateSession is closed.
@ -111,8 +123,8 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
self.drawHRoutingTracks ( layersDict["hRoutingTracks" ] )
self.__stretchTopPlates__( self.capacitor , layersDict["xPlateRLayer" ] )
self.drawCuts ( layersDict["cut_hRoutingLayer_vRoutingTracks"] , layersDict["cut_hRoutingTracks_vRoutingTracks"], layersDict["cut_hRoutingLayer_topPlate"] )
if self.dummyRing == True:
self.routeDummyRing (layersDict ["xPlateVRLayer_dummyRing" ] , layersDict["cut_hRoutingTracks_vRoutingTracks"] )
if self.dummyRing == True:
self.routeDummyRing (layersDict ["xPlateVRLayer_dummyRing" ] , layersDict["cut_hRoutingTracks_vRoutingTracks"] )
else : raise Error( 1, 'drawHRLayers() : Invalid matching scheme : "%s".' % self.matchingScheme )
@ -124,15 +136,15 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
def routeDummyRing( self, routeingLayer, cutLayer ):
def routeDummyRing( self, routingLayer, cutLayer ):
net = self.nets[-1][1]
bottomPlateRLayer_width = self.dummyRingCapacitor[0][0].getBotPlateRLayerWidth()
topPlateRLayer_width = self.dummyRingCapacitor[0][0].getTopPlateRLayerWidth()
self.computeDummyRingDimensions ()
self.routeLeftAndRightSides (net, routeingLayer, bottomPlateRLayer_width, topPlateRLayer_width )
self.routeTopOrBottomSide (net, "topSide" , routeingLayer , bottomPlateRLayer_width, topPlateRLayer_width)
self.routeTopOrBottomSide (net, "bottomSide" , routeingLayer , bottomPlateRLayer_width, topPlateRLayer_width)
self.routeLeftAndRightSides (net, routingLayer, bottomPlateRLayer_width, topPlateRLayer_width )
self.routeTopOrBottomSide (net, "topSide" , routingLayer , bottomPlateRLayer_width, topPlateRLayer_width)
self.routeTopOrBottomSide (net, "bottomSide" , routingLayer , bottomPlateRLayer_width, topPlateRLayer_width)
self.drawDummyRing_hRTracks_Cuts (net, "topSide" , cutLayer )
self.drawDummyRing_hRTracks_Cuts (net, "bottomSide" , cutLayer )
@ -140,24 +152,24 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
def routeLeftAndRightSides( self, dummyNet, routeingLayer, bottomPlateRLayer_width, topPlateRLayer_width ) :
def routeLeftAndRightSides( self, dummyNet, routingLayer, bottomPlateRLayer_width, topPlateRLayer_width ) :
for i in range(0,2):
bottomPlateLeftRLayerXCenter = self.dummyRingCapacitor[0][0 + i*(-1)].getBotPlateLeftRLayerXCenter()
bottomPlateRightRLayerXCenter = self.dummyRingCapacitor[0][0 + i*(-1)].getBotPlateRightRLayerXCenter()
Vertical.create ( dummyNet, routeingLayer , bottomPlateLeftRLayerXCenter , bottomPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
Vertical.create ( dummyNet, routeingLayer , bottomPlateRightRLayerXCenter , bottomPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
Vertical.create ( dummyNet, routingLayer , bottomPlateLeftRLayerXCenter , bottomPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
Vertical.create ( dummyNet, routingLayer , bottomPlateRightRLayerXCenter , bottomPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
for i in range(0,2):
topPlateRLayerXCenter = self.dummyRingCapacitor[0][0 + i*(-1)].topPlateRLayerDict["XCenter"]
Vertical.create ( dummyNet, routeingLayer , topPlateRLayerXCenter , topPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
Vertical.create ( dummyNet, routingLayer , topPlateRLayerXCenter , topPlateRLayer_width , self.dummyRingVRLayersDict["YMin"] , self.dummyRingVRLayersDict["YMax"] )
return
def routeTopOrBottomSide( self, dummyNet, side, routeingLayer, bottomPlateRLayer_width, topPlateRLayer_width):
def routeTopOrBottomSide( self, dummyNet, side, routingLayer, bottomPlateRLayer_width, topPlateRLayer_width):
if side == "topSide" :
dummyRingElement = self.dummyRingCapacitor[-1]
@ -170,18 +182,18 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
for j in range(1,len(self.dummyRingCapacitor[0])-1):
bottomPlateLeftRLayerXCenter = dummyRingElement[j].getBotPlateLeftRLayerXCenter()
bottomPlateRightRLayerXCenter = dummyRingElement[j].getBotPlateRightRLayerXCenter()
Vertical.create ( dummyNet, routeingLayer , bottomPlateLeftRLayerXCenter , bottomPlateRLayer_width , dummyRingElement[j].getBotPlateRLayerYMin() , dyTarget )
Vertical.create ( dummyNet, routeingLayer , bottomPlateRightRLayerXCenter , bottomPlateRLayer_width , dummyRingElement[j].getBotPlateRLayerYMin() , dyTarget )
Vertical.create ( dummyNet, routingLayer , bottomPlateLeftRLayerXCenter , bottomPlateRLayer_width , dummyRingElement[j].getBotPlateRLayerYMin() , dyTarget )
Vertical.create ( dummyNet, routingLayer , bottomPlateRightRLayerXCenter , bottomPlateRLayer_width , dummyRingElement[j].getBotPlateRLayerYMin() , dyTarget )
topPlateRLayerXCenter = dummyRingElement[j].topPlateRLayerDict["XCenter"]
Vertical.create ( dummyNet, routeingLayer , topPlateRLayerXCenter , topPlateRLayer_width , dummyRingElement[j].getTopPlateRLayerYMin() , dyTarget )
Vertical.create ( dummyNet, routingLayer , topPlateRLayerXCenter , topPlateRLayer_width , dummyRingElement[j].getTopPlateRLayerYMin() , dyTarget )
return
## Defines technology rules used to draw the layout. Some of the rules, namely those describing routeing layers and tracks are applicable for both MIM and PIP capacitors. However, cuts rules are different. \remark All \c CapacitorStack class rules are also reloaded in this class. An exception is raised if the entered capacitor type is unsupported.
## Defines technology rules used to draw the layout. Some of the rules, namely those describing routing layers and tracks are applicable for both MIM and PIP capacitors. However, cuts rules are different. \remark All \c CapacitorStack class rules are also reloaded in this class. An exception is raised if the entered capacitor type is unsupported.
# \return a dictionary with rules labels as keys and rules content as values.
def setRules ( self ):
@ -211,7 +223,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Defines all physical layers used to draw the layout. Layers are loaded using \c DataBase API. The same routeing layers are used for both capacitor types except cuts layers that connect top plates to vertical routeing tracks. Basicaly, metal 2, meta 3, cut 1 and cut 2 are the ones defined.
## Defines all physical layers used to draw the layout. Layers are loaded using \c DataBase API. The same routing layers are used for both capacitor types except cuts layers that connect top plates to vertical routing tracks. Basicaly, metal 2, meta 3, cut 1 and cut 2 are the ones defined.
# \return a dictionary composed of layers labels as keys and layers as values.
def setLayers( self ):
@ -234,7 +246,6 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Computes, through simple instructions and functions calls, layout variables detailed in Figure 2.
def computeDimensions ( self, bbMode ) :
print 'routMatchedCapacitor.computeDimensions()'
bondingBoxDimensions = {}
self.hRoutingLayer_width = max( self.minWidth_hRoutingLayer, self.minWidth_hRoutingLayer_vRoutingTrack_cut + 2*self.minEnclosure_hRoutingLayer_vRoutingTrack_cut, self.minWidth_hRoutingLayer_topPlate_cut + 2*self.minEnclosure_hRoutingLayer_topPlate_cut )
@ -253,8 +264,8 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
translation1 = self.vRoutingTrack_width/2 + self.vRoutingTrack_spacing
translation2 = translation1 + self.vRoutingTrack_width/2
self.vRoutingTrackXCenter = self.vRTInstance.vRoutingTrackXCenter #getvRoutingTrackXCenter()
self.vRoutingTrackXCenter = self.vRTInstance.vRoutingTrackXCenter #getvRoutingTrackXCenter()
print("vRoutingTrackXCenter",self.vRoutingTrackXCenter)
if bbMode == True :
bondingBoxDimensions = self.computeBondingBoxDimInbbMode()
@ -276,11 +287,11 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
abutmentBoxXMin = self.capacitorInstance.computeAbutmentBoxDimensions( self.abutmentBox_spacing )["XMin"]
abutmentBoxXMax = abutmentBoxXMin + self.capacitorInstance.computeAbutmentBoxDimensions( self.abutmentBox_spacing )["width" ]
bondingBoxDimensions["XMin" ] = self.vRoutingTrackXCenter[0]["t1"] - self.vRoutingTrack_width/2
bondingBoxDimensions["XMin" ] = self.vRoutingTrackXCenter[0]["t0"] - self.vRoutingTrack_width/2
if self.capacitorsNumber % 2 == 0 :
factor = self.capacitorsNumber
else :
if self.capacitorsNumber % 2 != 0 :
factor = self.capacitorsNumber + 1 if self.matrixDim["columns"] % 2 == 0 else self.capacitorsNumber - 1
bondingBoxXMax = abutmentBoxXMax + factor*(self.vRoutingTrack_width + self.vRoutingTrack_spacing)
@ -290,13 +301,13 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
bondingBoxDimensions["height" ] = bondingBoxYMax - bondingBoxDimensions["YMin"]
bondingBoxDimensions["surface"] = bondingBoxDimensions["width"]*bondingBoxDimensions["height"]
bondingBox = Box( bondingBoxDimensions["XMin"], bondingBoxDimensions["YMin"], bondingBoxXMax, bondingBoxYMax )
self.device.setAbutmentBox( bondingBox )
#bondingBox = Box( bondingBoxDimensions["XMin"], bondingBoxDimensions["YMin"], bondingBoxXMax, bondingBoxYMax )
#self.device.setAbutmentBox( bondingBox )
return bondingBoxDimensions
## Computes centers' ordinates of the eight horizontal routeing tracks. The tracks include four on top and four on bottom of the matrix. To do the computations, fist, center of the first bottom or top track, given in Figure 2, is computed. Then, all adjacent three centers are deduced by simples translation of the first one. Translation quantity is equal to the sum of distance between adjacent routeing tracks, self.hRoutingTracks_spacing, and half width of the routeing track itself, \c self.hRoutingTrack_width.
## Computes centers' ordinates of the eight horizontal routing tracks. The tracks include four on top and four on bottom of the matrix. To do the computations, fist, center of the first bottom or top track, given in Figure 2, is computed. Then, all adjacent three centers are deduced by simples translation of the first one. Translation quantity is equal to the sum of distance between adjacent routing tracks, self.hRoutingTracks_spacing, and half width of the routing track itself, \c self.hRoutingTrack_width.
def computeHRoutingTrackYCenter( self ):
@ -324,7 +335,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
return
## Sets the stretching value of top plates. Then iteratively computes the centers of horizontal routeing layer regarding top and bottom plates.
## Sets the stretching value of top plates. Then iteratively computes the centers of horizontal routing layer regarding top and bottom plates.
def computeHRLayerYCenter ( self ):
@ -380,9 +391,9 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Iteratively draws horizontal routeing tracks on top and bottom positions of the matrix using physical layer \c routeingTracksLayer.
## Iteratively draws horizontal routing tracks on top and bottom positions of the matrix using physical layer \c routingTracksLayer.
def drawHRoutingTracks( self , routeingTracksLayer ):
def drawHRoutingTracks( self , routingTracksLayer ):
lastVRTId = self.vRoutingTrackXCenter[-1].keys()[-1]
firstVRTId = "t0"
@ -401,11 +412,11 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
net = self.nets[-1][1]
# net = self.nets[ int(j[1]) ][0] if j[0] == 't' else self.nets[ int(j[1]) ][1]
print('net',net)
Horizontal.create ( net , routeingTracksLayer, self.hRoutingtrackYCenter[i][j] , self.hRoutingTrack_width , dxSource , dxTarget )
Horizontal.create ( net , routingTracksLayer, self.hRoutingtrackYCenter[i][j] , self.hRoutingTrack_width , dxSource , dxTarget )
return
## Iteratively draws the horizontal routeing layers starting with bottom left elementary capacitor \f$ C_{00} \f$.
## Iteratively draws the horizontal routing layers starting with bottom left elementary capacitor \f$ C_{00} \f$.
def drawHRLayers( self, xPlateRLayer ) :
@ -422,9 +433,9 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Draws all required cuts using physical layers :
# - \c layer_hRTrack_hRLayer to connect bottom plates to vertical routeing tracks,
# - \c layer_tracksCut to connect vertical routeing tracks to horizontal ones,
# - \c layer_topPlateCut to connect top plates to vertical routeing tracks.
# - \c layer_hRTrack_hRLayer to connect bottom plates to vertical routing tracks,
# - \c layer_tracksCut to connect vertical routing tracks to horizontal ones,
# - \c layer_topPlateCut to connect top plates to vertical routing tracks.
# ALso in \c drawCuts, nUmber of maximum cuts number on every layer is computed and cuts enclosure is adjusted according to layer's width.
def drawCuts( self, layer_hRTrack_hRLayer, layer_tracksCut, layer_topPlateCut ):
@ -472,7 +483,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Draws one cut, in layer \c cutLayer, in order to connect a vertical routeing track, at position \c cutXMin in metal 2, and a horizontal routeing track, at position \c cutYMin in metal 3.
## Draws one cut, in layer \c cutLayer, in order to connect a vertical routing track, at position \c cutXMin in metal 2, and a horizontal routing track, at position \c cutYMin in metal 3.
def drawOneCut_vRoutingTrack_HRLayer( self, net, cutLayer, cutXMin, cutYMin, cutNumber ):
CapacitorUnit.cutLine(self,net,cutLayer,cutXMin,cutYMin,self.minWidth_hRoutingLayer_vRoutingTrack_cut,self.minWidth_hRoutingLayer_vRoutingTrack_cut,self.minSpacing_hRoutingLayer_vRoutingTrack_cut,cutNumber,'horizontal')
@ -480,7 +491,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Draws cuts to connect vertical routeing tracks in metal 2 and horizontal routeing tracks in metal 3.
## Draws cuts to connect vertical routing tracks in metal 2 and horizontal routing tracks in metal 3.
def drawCuts_vRoutingTrack_hRoutingTrack( self,cutLayer, cutNumber, enclosure_cut ):
keysList = self.hRoutingtrackYCenter.keys()
@ -550,7 +561,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Iteratively performs top plates stretching for the capacitor matrix. Vertical segments are connected to top plate routeing layer.
## Iteratively performs top plates stretching for the capacitor matrix. Vertical segments are connected to top plate routing layer.
# \param capacitor Capacitor matrix.
# \param rlayer Layer of the drawn vertical rectangle.
def __stretchTopPlates__( self, capacitor, rlayer ):
@ -567,13 +578,13 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
## Draws vertical stretched layers for a given elementary capacitor.
def __stretchTopPlateCompactCap__( self, net, capacitor, routeingLayer, j = 0 ):
def __stretchTopPlateCompactCap__( self, net, capacitor, routingLayer, j = 0 ):
topPlateRLayer_width = capacitor.getTopPlateRLayerWidth()
topPlateRLayerXCenter = capacitor.getTopPlateRLayerXCenter()
[ dySource , dyTarget ] = self.__setStretchingDySourceDyTarget__( capacitor, self.topPlateStretching )
Vertical.create ( net, routeingLayer , topPlateRLayerXCenter , topPlateRLayer_width , dySource , dyTarget )
Vertical.create ( net, routingLayer , topPlateRLayerXCenter , topPlateRLayer_width , dySource , dyTarget )
return
@ -591,7 +602,7 @@ class RoutMatchedCapacitor( CapacitorUnit, CapacitorStack, VerticalRoutingTracks
return [ dySource , dyTarget ]
## Computes horizontal routeing layers source and target abcissas for top and bottom plates connections to its associated routeing track.
## Computes horizontal routing layers source and target abcissas for top and bottom plates connections to its associated routing track.
# \param (i,j) row and column indexes, respectively, in the matrix which describe the elementary capacitor position in the matrix.
# \param capacitorIdentifier equal to '1' if C1 and '2' if C2.
# \return A nested dicitionary. The overal dictionary is composed of keys equal to \c topPlate and \d bottomPlate and values equal to sub-dictionaries. The sub-dictionaries, are in their turn composed of two keys standing for the abcissa of the source and the abcissa of the target.
@ -758,8 +769,10 @@ def ScriptMain( **kw ):
capWithVRT.create()
routedCap = RoutMatchedCapacitor( capWithVRT )
surface = routedCap.route(True)
surface = routedCap.route()
print('routeMatchedCap bbMode', surface)
print('width', toPhY(surface["width"]))
print('height', toPhY(surface["height"]))
AllianceFramework.get().saveCell( Device, Catalog.State.Views )

View File

@ -1,20 +1,25 @@
#!/usr/bin/python
import sys
from Hurricane import *
from CRL import *
from math import sqrt, ceil
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 import trace
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 )

View File

@ -1,5 +1,4 @@
#!/usr/bin/python
import sys
from Hurricane import *
from CRL import *
@ -32,10 +31,9 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
self.abutmentBox = capacitorInstance.abutmentBox
self.matrixDim = self.capacitorInstance.matrixDim
self.nets = capacitorInstance.nets
self.capacitorsNumber = capacitorInstance.capacitorsNumber
self.dummyRing = capacitorInstance.dummyRing
self.dummyElement = capacitorInstance.dummyElement
print('capacitorInstance.capacitance',capacitorInstance.capacitance)
self.capacitorsNumber = capacitorInstance.capacitorsNumber
self.dummyRing = capacitorInstance.dummyRing
self.dummyElement = capacitorInstance.dummyElement
self.capacitorIds = range(0,self.capacitorsNumber)
self.abutmentBox_spacing = capacitorInstance.abutmentBox_spacing
self.vRoutingTrack_width = self.capacitorInstance.vRoutingTrack_width
@ -93,7 +91,6 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
netsDistribution = self.__setNetsDistribution__()
k = 0
print('netsDistribution',netsDistribution)
for j in range( 0, self.matrixDim["columns"] + 1 ):
for key in self.vRoutingTrackXCenter[j]:
if self.vRoutingTrackXCenter[j][key] != None:
@ -115,7 +112,6 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
self.maximumPosition = abutmentBoxYMax + self.__setStretching__()
vRTsNumber = self.__computeVRTsNumber__()
print("vRTsNumber",vRTsNumber)
self.vRoutingTrackDict["YMin"] = self.minimumPosition - vRTsNumber*(self.hRoutingTrack_width + self.minSpacing_hRoutingTrack)
self.vRoutingTrackDict["YMax"] = self.maximumPosition + vRTsNumber*(self.hRoutingTrack_width + self.minSpacing_hRoutingTrack)
@ -158,7 +154,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
for k in range( 1, leftVRTNumber ):
self.vRoutingTrackXCenter[0][self.platesDistribution[0][k]] = unitCapXMin - (factor1-k)*vRoutingTrack_spacing -(factor2-k)*self.vRoutingTrack_width - self.vRoutingTrack_width/2 if self.vRTsToEliminate[0][k] == 1 else None
print('self.vRoutingTrackXCenter',self.vRoutingTrackXCenter)
#print('self.vRoutingTrackXCenter',self.vRoutingTrackXCenter)
for j in range( 1, self.matrixDim["columns"] + 1 ):
factor3 = j - 1 if self.dummyRing == False else j
unitCapXMin = self.abutmentBox.getXMin() + factor3*( abutmentBoxUnitCap_width + self.capacitorInstance.abutmentBox_spacing )
@ -182,7 +178,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
self.vRoutingTrackXCenter[j][ self.platesDistribution[j][k] ] = unitCapXMax + (k+1)*vRoutingTrack_spacing + (k)*self.vRoutingTrack_width + self.vRoutingTrack_width/2 if self.vRTsToEliminate[j][k] == 1 else None
print('self.vRoutingTrackXCenter',self.vRoutingTrackXCenter)
#print('self.vRoutingTrackXCenter',self.vRoutingTrackXCenter)
return
@ -219,9 +215,9 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
capIdsToEliminate = []
capIdsj = capIdsToEliminatePerColumn[0]
print('capIdsj',capIdsj)
#print('capIdsj',capIdsj)
sharedVRTIds = self.capacitorIds[0:self.capacitorsNumber/2] if self.capacitorsNumber % 2 == 0 else self.capacitorIds[0: int(self.capacitorsNumber/2+1)]
print('sharedVRTIds',sharedVRTIds)
#print('sharedVRTIds',sharedVRTIds)
intersection2 = list( set(capIdsj).intersection(set(sharedVRTIds)) )
capIdsToEliminate.append( [None] ) if intersection2 == [] else capIdsToEliminate.append( intersection2 )
@ -233,7 +229,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
else:
sharedVRTIds = self.capacitorIds[0:self.capacitorsNumber/2] if (self.capacitorsNumber % 2 == 0) else self.capacitorIds[0: int(self.capacitorsNumber/2+1)]
print('sharedVRTIds',sharedVRTIds)
#print('sharedVRTIds',sharedVRTIds)
if j == len(capIdsToEliminatePerColumn)-1:
intersection1 = list( set(capIdsj) )
@ -250,7 +246,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
def __findVRTsToEliminate__( self, capIdsToEliminate ):
print('capIdsToEliminate',capIdsToEliminate)
#print('capIdsToEliminate',capIdsToEliminate)
for j in range( 0,len(self.vRTsDistribution) ) :
for k in range( 0,len(self.vRTsDistribution[j]) ) :
if k == 0 :
@ -260,7 +256,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
else :
self.vRTsToEliminate.append( [1] )
self.vRTsToEliminate[j].append( 1 )
print('vRTsToEliminate',self.vRTsToEliminate)
#print('vRTsToEliminate',self.vRTsToEliminate)
else :
if self.vRTsDistribution[j][k] in capIdsToEliminate[j]:
[self.vRTsToEliminate[j].append( 0 ) for u in range(0,2)]
@ -289,11 +285,11 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
capIdsToEliminate = self.__findCapIdsToEliminate__ (capIdsToEliminatePerColumn)
self.__findVRTsToEliminate__ (capIdsToEliminate )
print("self.matchingScheme" ,self.matchingScheme)
print("usedCapIdsPerColumn" ,usedCapIdsPerColumn)
print("capIdsToEliminatePerColumn",capIdsToEliminatePerColumn)
print("capIdsToEliminate" ,capIdsToEliminate)
print('self.vRTsToEliminate' ,self.vRTsToEliminate)
#print("self.matchingScheme" ,self.matchingScheme)
#print("usedCapIdsPerColumn" ,usedCapIdsPerColumn)
#print("capIdsToEliminatePerColumn",capIdsToEliminatePerColumn)
#print("capIdsToEliminate" ,capIdsToEliminate)
#print('self.vRTsToEliminate' ,self.vRTsToEliminate)
else : raise Error(1,'minimizeVRTs() : ')
@ -309,7 +305,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
self.vRTsDistribution.append( element[u] )
u = u+1 if u < 1 else 0
print('self.vRTsDistribution',self.vRTsDistribution)
#print('self.vRTsDistribution',self.vRTsDistribution)
return
@ -329,7 +325,7 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
netsDistribution[j].append( element[u][k][1] )
u = u+1 if u < 1 else 0
print('netsDistribution',netsDistribution)
#print('netsDistribution',netsDistribution)
return netsDistribution
@ -341,26 +337,22 @@ class VerticalRoutingTracks( CapacitorUnit, CapacitorStack ):
u = 0
for j in range(0,self.matrixDim["columns"]+1) :
print("j",j)
self.platesDistribution.append( ['t' + str(element[u][0])] )
print('self.platesDistribution',self.platesDistribution)
#print('self.platesDistribution',self.platesDistribution)
if self.dummyElement == False or self.dummyElement == True and j % 2 == 0 and len(element[u]) > 1 :
print("jif",j)
self.platesDistribution[j].append( 'b' + str(element[u][0]) )
for k in element[u][1:len(element[u])]:
print('k',k)
self.platesDistribution[j].append( 't' + str(k) )
print("jj",j)
if self.dummyElement == False or self.dummyElement == True and j % 2 == 0 or self.dummyElement == True and j % 2 != 0 and k != element[u][len(element[u])-1] :
self.platesDistribution[j].append( 'b' + str(k) )
u = u+1 if u < 1 else 0
print('self.platesDistribution',self.platesDistribution)
#print('self.platesDistribution',self.platesDistribution)
return