Re-enable and check the building of I/O ring with pad spacers.
* New: In cumulus/block.bigvia, add a getBoundingBox() method. * New: In cumulus/block.configuration.GaugeConf.rpAccess(), add a vertical strap segment in case the RP is not high enough to accomodate the potential offset of the contact. In case of gauge with only two routing layers, if the RP is vertically accessed, do not put a VIA12 but just a METAL2 contact (there will be *no* turn). * Change: In cumulus/chip.CoreWire.drawWire(), the wire at *chip level* going to the pad was shrunk of 3 pitch when *not* in the preferred routing direction. Removing it as it creates gaps in some cases. This was likely needed for a specific kind of I/O pad so should be re-enabled on targeted cases in the future. * Change: In cumulus/chip.corona.VerticalRail, manage in a smarter way the conflicts when a rail is accessed from both sides overlapping on an Y position. That is, from the supply I/O pads *and* from the *core* supply lines. Formerly, we just didn't connect the core power line, which was a mistake potentially leaving power rails unconnected (it it did occur on both sides). Also checks if the conflict really arise, that is, the power lines are both on top or bottom. * Change: In cumulus/chip.pads.Side._placePad(), manage I/O pads with a bottom left corner of abutment box *not* at (0,0). Argh! * Bug: In cumulus/chip.pads, create the filler pad instances in the chip, not in the corona.
This commit is contained in:
parent
0e17b91692
commit
181b2e1080
|
@ -89,6 +89,12 @@ class BigVia ( object ):
|
||||||
|
|
||||||
def getNet ( self ): return self.net
|
def getNet ( self ): return self.net
|
||||||
|
|
||||||
|
def getBoundingBox ( self, depth ):
|
||||||
|
bb = Box( self.x, self.y )
|
||||||
|
bb.inflate( self.widths[depth] // 2, self.heights[depth] // 2 )
|
||||||
|
return bb
|
||||||
|
|
||||||
|
|
||||||
def getPlate ( self, metal ):
|
def getPlate ( self, metal ):
|
||||||
if not self.hasLayout: return None
|
if not self.hasLayout: return None
|
||||||
for plate in self.plates.values():
|
for plate in self.plates.values():
|
||||||
|
|
|
@ -319,21 +319,60 @@ class GaugeConf ( object ):
|
||||||
if flags & GaugeConf.OffsetTop2: yoffset = -2
|
if flags & GaugeConf.OffsetTop2: yoffset = -2
|
||||||
trace( 550, '\tyoffset:{}\n'.format(yoffset) )
|
trace( 550, '\tyoffset:{}\n'.format(yoffset) )
|
||||||
if startDepth == 0:
|
if startDepth == 0:
|
||||||
contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 )
|
rg = self.routingGauge.getLayerGauge( 0 )
|
||||||
ytrack = self.getTrack( contact1.getY(), self.horizontalDeepDepth, yoffset )
|
rpContact = Contact.create( rp, rg.getLayer(), 0, 0 )
|
||||||
dy = ytrack - contact1.getY()
|
ytrack = self.getTrack( rpContact.getY(), self.horizontalDeepDepth, yoffset )
|
||||||
trace( 550, '\tPut on Y-tracks:{}\n'.format(DbU.getValueString(ytrack)) )
|
contact1 = Contact.create( rp.getNet()
|
||||||
contact1.setDy( dy )
|
, self._routingGauge.getContactLayer( 0 )
|
||||||
|
, rpContact.getX()
|
||||||
|
, ytrack
|
||||||
|
, rg.getViaWidth()
|
||||||
|
, rg.getViaWidth()
|
||||||
|
)
|
||||||
|
segment = Vertical.create( rpContact
|
||||||
|
, contact1
|
||||||
|
, rpContact.getLayer()
|
||||||
|
, rpContact.getX()
|
||||||
|
, rg.getWireWidth()
|
||||||
|
)
|
||||||
|
#dy = ytrack - contact1.getY()
|
||||||
|
#trace( 550, '\tPut on Y-tracks:{}\n'.format(DbU.getValueString(ytrack)) )
|
||||||
|
#contact1.setDy( dy )
|
||||||
else:
|
else:
|
||||||
contact1 = Contact.create( rp, self._routingGauge.getContactLayer(startDepth), 0, 0 )
|
rg = self.routingGauge.getLayerGauge( startDepth )
|
||||||
ytrack = self.getTrack( contact1.getY(), startDepth, 0 )
|
rpContact = Contact.create( rp, rg.getLayer(), 0, 0 )
|
||||||
dy = ytrack - contact1.getY()
|
ytrack = self.getTrack( rpContact.getY(), startDepth, 0 )
|
||||||
|
#dy = ytrack - contact1.getY()
|
||||||
|
contact1 = Contact.create( rp.getNet()
|
||||||
|
, self._routingGauge.getContactLayer( startDepth )
|
||||||
|
, rpContact.getX()
|
||||||
|
, ytrack
|
||||||
|
, rg.getViaWidth()
|
||||||
|
, rg.getViaWidth()
|
||||||
|
)
|
||||||
|
segment = Vertical.create( rpContact
|
||||||
|
, contact1
|
||||||
|
, rpContact.getLayer()
|
||||||
|
, rpContact.getX()
|
||||||
|
, rg.getWireWidth()
|
||||||
|
)
|
||||||
|
trace( 550, '\trpContact:{}\n'.format( rpContact ))
|
||||||
|
trace( 550, '\tcontact1: {}\n'.format( contact1 ))
|
||||||
|
trace( 550, '\tsegment: {}\n'.format( segment ))
|
||||||
startDepth += 1
|
startDepth += 1
|
||||||
trace( 550, contact1 )
|
trace( 550, '\tcontact1={}\n'.format( contact1 ))
|
||||||
|
|
||||||
if flags & GaugeConf.HAccess: stopDepth = hdepth
|
if flags & GaugeConf.HAccess: stopDepth = hdepth
|
||||||
else: stopDepth = vdepth
|
else: stopDepth = vdepth
|
||||||
trace( 550, '\tstopDepth:%d\n' % stopDepth )
|
trace( 550, '\trange(startDepth={},stopDepth={})={}\n' \
|
||||||
|
.format( startDepth, stopDepth, list(range(startDepth,stopDepth)) ))
|
||||||
|
|
||||||
|
if startDepth >= stopDepth:
|
||||||
|
if not flags & GaugeConf.HAccess:
|
||||||
|
contact1.setLayer( rpContact.getLayer() )
|
||||||
|
self._rpToAccess[rp] = contact1
|
||||||
|
trace( 550, '-' )
|
||||||
|
return contact1
|
||||||
|
|
||||||
for depth in range(startDepth,stopDepth):
|
for depth in range(startDepth,stopDepth):
|
||||||
rg = self.routingGauge.getLayerGauge(depth)
|
rg = self.routingGauge.getLayerGauge(depth)
|
||||||
|
|
|
@ -154,12 +154,13 @@ class HTree ( object ):
|
||||||
ckParentNet = qt.bInputPlug(0).getNet()
|
ckParentNet = qt.bInputPlug(0).getNet()
|
||||||
driverContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.input, ckParentNet )
|
driverContact = gaugeConf.rpAccessByPlugName( qt.buffers[0], bufferConf.input, ckParentNet )
|
||||||
driverY = driverContact.getY()
|
driverY = driverContact.getY()
|
||||||
|
trace( 550, '\tdriverContact={}\n'.format( driverContact ))
|
||||||
if qt.bl:
|
if qt.bl:
|
||||||
trace( 550, '+,', '\tblContact\n' )
|
trace( 550, '+,', '\tblContact\n' )
|
||||||
blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffers[0], bufferConf.input, ckNet, GaugeConf.OffsetLeft1 )
|
blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffers[0], bufferConf.input, ckNet, GaugeConf.OffsetLeft1 )
|
||||||
trace( 550, ',-', '\tblContact={}\n'.format(blContact) )
|
trace( 550, ',-', '\tblContact={}\n'.format(blContact) )
|
||||||
if qt.br:
|
if qt.br:
|
||||||
trace( 550, '+,', '\trlContact\n' )
|
trace( 550, '+,', '\tbrContact\n' )
|
||||||
brContact = gaugeConf.rpAccessByPlugName( qt.br.buffers[0], bufferConf.input, ckNet, GaugeConf.OffsetLeft1 )
|
brContact = gaugeConf.rpAccessByPlugName( qt.br.buffers[0], bufferConf.input, ckNet, GaugeConf.OffsetLeft1 )
|
||||||
trace( 550, ',-', '\tbrContact={}\n'.format(brContact) )
|
trace( 550, ',-', '\tbrContact={}\n'.format(brContact) )
|
||||||
if qt.tl:
|
if qt.tl:
|
||||||
|
|
|
@ -203,9 +203,11 @@ class CoreWire ( object ):
|
||||||
coronaAb = self.conf.getInstanceAb( self.conf.icorona )
|
coronaAb = self.conf.getInstanceAb( self.conf.icorona )
|
||||||
coronaTransf = self.conf.icorona.getTransformation()
|
coronaTransf = self.conf.icorona.getTransformation()
|
||||||
self._computeCoreLayers()
|
self._computeCoreLayers()
|
||||||
|
trace( 550, '\tbbSegment: {}\n'.format(self.bbSegment) )
|
||||||
padLayer = self.padSegment.getLayer()
|
padLayer = self.padSegment.getLayer()
|
||||||
if not isinstance(padLayer,BasicLayer):
|
if not isinstance(padLayer,BasicLayer):
|
||||||
padLayer = padLayer.getBasicLayer()
|
padLayer = padLayer.getBasicLayer()
|
||||||
|
trace( 550, '\tpadLayer={}\n'.format( padLayer ))
|
||||||
if self.side == West or self.side == East:
|
if self.side == West or self.side == East:
|
||||||
flags = OnHorizontalPitch
|
flags = OnHorizontalPitch
|
||||||
hPitch = self.conf.getPitch( self.symSegmentLayer )
|
hPitch = self.conf.getPitch( self.symSegmentLayer )
|
||||||
|
@ -222,18 +224,20 @@ class CoreWire ( object ):
|
||||||
xContact = self.corona.coreSymBb.getXMin() - self.offset * 2*vPitch
|
xContact = self.corona.coreSymBb.getXMin() - self.offset * 2*vPitch
|
||||||
xPadMax = xContact
|
xPadMax = xContact
|
||||||
xCore = coronaAb.getXMin()
|
xCore = coronaAb.getXMin()
|
||||||
if not self.preferredDir:
|
trace( 550, '\txPadMin: {}\n'.format(DbU.getValueString( xPadMin )))
|
||||||
#xPadMax += self.bbSegment.getHeight()//2
|
#if not self.preferredDir:
|
||||||
xPadMin += 3*vPitch
|
# #xPadMax += self.bbSegment.getHeight()//2
|
||||||
|
# xPadMin += 3*vPitch
|
||||||
|
# trace( 550, '\txPadMin: {}\n'.format(DbU.getValueString( xPadMin )))
|
||||||
else:
|
else:
|
||||||
accessDirection = Pin.Direction.EAST
|
accessDirection = Pin.Direction.EAST
|
||||||
xPadMax = self.bbSegment.getXMax()
|
xPadMax = self.bbSegment.getXMax()
|
||||||
xContact = self.corona.coreSymBb.getXMax() + self.offset * 2*vPitch
|
xContact = self.corona.coreSymBb.getXMax() + self.offset * 2*vPitch
|
||||||
xPadMin = xContact
|
xPadMin = xContact
|
||||||
xCore = coronaAb.getXMax() - vPitch
|
xCore = coronaAb.getXMax() - vPitch
|
||||||
if not self.preferredDir:
|
#if not self.preferredDir:
|
||||||
#xPadMin -= self.bbSegment.getHeight()//2
|
# #xPadMin -= self.bbSegment.getHeight()//2
|
||||||
xPadMin -= 3*vPitch
|
# xPadMin -= 3*vPitch
|
||||||
if self.addJumper:
|
if self.addJumper:
|
||||||
rg = self.conf.routingGauge
|
rg = self.conf.routingGauge
|
||||||
gaugeM5 = rg.getLayerGauge( 4 )
|
gaugeM5 = rg.getLayerGauge( 4 )
|
||||||
|
@ -296,6 +300,7 @@ class CoreWire ( object ):
|
||||||
, xPadMin
|
, xPadMin
|
||||||
, xPadMax
|
, xPadMax
|
||||||
)
|
)
|
||||||
|
trace( 550, '\thChip={}\n'.format( hChip ))
|
||||||
trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) )
|
trace( 550, '\tself.arraySize: %s\n' % str(self.arraySize) )
|
||||||
if self.arraySize:
|
if self.arraySize:
|
||||||
contacts = self.conf.coronaContactArray( self.chipNet
|
contacts = self.conf.coronaContactArray( self.chipNet
|
||||||
|
@ -331,6 +336,7 @@ class CoreWire ( object ):
|
||||||
, xContact
|
, xContact
|
||||||
, xCore
|
, xCore
|
||||||
)
|
)
|
||||||
|
trace( 550, '\thCorona={}\n'.format( hCorona ))
|
||||||
trace( 550, '\tCORONA PIN: {} {}\n'.format(self.chipNet, self.count) )
|
trace( 550, '\tCORONA PIN: {} {}\n'.format(self.chipNet, self.count) )
|
||||||
pin = self.conf.coronaPin( self.chipNet
|
pin = self.conf.coronaPin( self.chipNet
|
||||||
, self.count
|
, self.count
|
||||||
|
@ -342,22 +348,26 @@ class CoreWire ( object ):
|
||||||
, self.bbSegment.getHeight()
|
, self.bbSegment.getHeight()
|
||||||
)
|
)
|
||||||
hChipBb = hChip.getBoundingBox( padLayer )
|
hChipBb = hChip.getBoundingBox( padLayer )
|
||||||
|
trace( 550, '\thChipBb={}\n'.format( hChipBb ))
|
||||||
vStrapBb.merge( vStrapBb.getXMin(), hChipBb.getYMin() )
|
vStrapBb.merge( vStrapBb.getXMin(), hChipBb.getYMin() )
|
||||||
vStrapBb.merge( vStrapBb.getXMin(), hChipBb.getYMax() )
|
vStrapBb.merge( vStrapBb.getXMin(), hChipBb.getYMax() )
|
||||||
hCoronaBb = hCorona.getBoundingBox( padLayer )
|
#hCoronaBb = hCorona.getBoundingBox( padLayer )
|
||||||
|
hCoronaBb = hCorona.getBoundingBox()
|
||||||
self.conf.icorona.getTransformation().applyOn( hCoronaBb )
|
self.conf.icorona.getTransformation().applyOn( hCoronaBb )
|
||||||
|
trace( 550, '\thCoronaBb={}\n'.format( hCoronaBb ))
|
||||||
vStrapBb.merge( vStrapBb.getXMin(), hCoronaBb.getYMin() )
|
vStrapBb.merge( vStrapBb.getXMin(), hCoronaBb.getYMin() )
|
||||||
vStrapBb.merge( vStrapBb.getXMin(), hCoronaBb.getYMax() )
|
vStrapBb.merge( vStrapBb.getXMin(), hCoronaBb.getYMax() )
|
||||||
if self.padSegment.getLayer().isSymbolic():
|
if self.padSegment.getLayer().isSymbolic():
|
||||||
vStrapBb.inflate( 0, -self.padSegment.getLayer().getExtentionCap()
|
vStrapBb.inflate( 0, -self.padSegment.getLayer().getExtentionCap()
|
||||||
, 0, -self.padSegment.getLayer().getExtentionCap() )
|
, 0, -self.padSegment.getLayer().getExtentionCap() )
|
||||||
Vertical.create( self.chipNet
|
v = Vertical.create( self.chipNet
|
||||||
, self.padSegment.getLayer()
|
, self.padSegment.getLayer()
|
||||||
, vStrapBb.getCenter().getX()
|
, vStrapBb.getCenter().getX()
|
||||||
, vStrapBb.getWidth()
|
, vStrapBb.getWidth()
|
||||||
, vStrapBb.getYMin()
|
, vStrapBb.getYMin()
|
||||||
, vStrapBb.getYMax()
|
, vStrapBb.getYMax()
|
||||||
)
|
)
|
||||||
|
trace( 550, '\tvChip={}\n'.format( v ))
|
||||||
else:
|
else:
|
||||||
flags = OnVerticalPitch
|
flags = OnVerticalPitch
|
||||||
hPitch = self.conf.getPitch( self.padSegment.getLayer() )
|
hPitch = self.conf.getPitch( self.padSegment.getLayer() )
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
import bisect
|
import bisect
|
||||||
from operator import methodcaller
|
from operator import methodcaller, xor
|
||||||
import Cfg
|
import Cfg
|
||||||
from Hurricane import DbU, Point, Interval, Box, Transformation, \
|
from Hurricane import DbU, Point, Interval, Box, Transformation, \
|
||||||
Path, Occurrence, Net, Contact, Horizontal, \
|
Path, Occurrence, Net, Contact, Horizontal, \
|
||||||
|
@ -100,8 +101,7 @@ class HorizontalRail ( Rail ):
|
||||||
return '<HorizontalRail "{}" ({}) @{}>'.format( self.side.getRailNet(self.order).getName()
|
return '<HorizontalRail "{}" ({}) @{}>'.format( self.side.getRailNet(self.order).getName()
|
||||||
, self.order
|
, self.order
|
||||||
, DbU.getValueString(self.axis) )
|
, DbU.getValueString(self.axis) )
|
||||||
|
def isReachable ( self, contact ):
|
||||||
def connect ( self, contact ):
|
|
||||||
trace( 550, ',+', '\tTry to connect to: {}\n'.format(self) )
|
trace( 550, ',+', '\tTry to connect to: {}\n'.format(self) )
|
||||||
trace( 550, '\tContact {}\n'.format(contact) )
|
trace( 550, '\tContact {}\n'.format(contact) )
|
||||||
contactBb = contact.getBoundingBox()
|
contactBb = contact.getBoundingBox()
|
||||||
|
@ -132,6 +132,10 @@ class HorizontalRail ( Rail ):
|
||||||
trace( 550, ',-', '\tFailed: overlap with existing contact @{}.\n' \
|
trace( 550, ',-', '\tFailed: overlap with existing contact @{}.\n' \
|
||||||
.format(self.vias[keys[insertIndex-1]][2]) )
|
.format(self.vias[keys[insertIndex-1]][2]) )
|
||||||
return False
|
return False
|
||||||
|
trace( 550, ',-' )
|
||||||
|
return True
|
||||||
|
|
||||||
|
def connect ( self, contact ):
|
||||||
viaWidth = contact.getWidth()
|
viaWidth = contact.getWidth()
|
||||||
viaHeight = self.side.hRailWidth
|
viaHeight = self.side.hRailWidth
|
||||||
if self.conf.routingGauge.isSymbolic():
|
if self.conf.routingGauge.isSymbolic():
|
||||||
|
@ -152,7 +156,6 @@ class HorizontalRail ( Rail ):
|
||||||
, DbU.getValueString(contact.getX())
|
, DbU.getValueString(contact.getX())
|
||||||
, DbU.getValueString(self.axis)) )
|
, DbU.getValueString(self.axis)) )
|
||||||
self.vias[ contact.getX() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
self.vias[ contact.getX() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
||||||
trace( 550, '-' )
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def doLayout ( self ):
|
def doLayout ( self ):
|
||||||
|
@ -218,8 +221,11 @@ class VerticalRail ( Rail ):
|
||||||
, self.side.vRailWidth
|
, self.side.vRailWidth
|
||||||
)
|
)
|
||||||
|
|
||||||
def connect ( self, contact ):
|
def isReachable ( self, contact ):
|
||||||
contactBb = contact.getBoundingBox()
|
railDepth = self.conf.routingGauge.getLayerDepth( self.side.getVLayer() )
|
||||||
|
contactDepth = self.conf.routingGauge.getLayerDepth( contact.getLayer() )
|
||||||
|
contactBb = contact.getBoundingBox()
|
||||||
|
contactAbove = True if contactDepth > railDepth else False
|
||||||
if contactBb.getYMin() < self.side.innerBb.getYMin() \
|
if contactBb.getYMin() < self.side.innerBb.getYMin() \
|
||||||
or contactBb.getYMax() > self.side.innerBb.getYMax():
|
or contactBb.getYMax() > self.side.innerBb.getYMax():
|
||||||
# XXX turn this into a non-fatal case. ERROR is still printed,
|
# XXX turn this into a non-fatal case. ERROR is still printed,
|
||||||
|
@ -228,7 +234,7 @@ class VerticalRail ( Rail ):
|
||||||
, 'power pad is likely to be to far off north or south.'
|
, 'power pad is likely to be to far off north or south.'
|
||||||
, '(core:{})'.format(self.side.innerBb) ] ) )
|
, '(core:{})'.format(self.side.innerBb) ] ) )
|
||||||
if contact.getY() in self.vias: return False
|
if contact.getY() in self.vias: return False
|
||||||
trace( 550, ',+', '\tVerticalRail.connect() [{}] @{}\n'.format(self.order,DbU.getValueString(self.axis)) )
|
trace( 550, ',+', '\tVerticalRail.isReachable() [{}] @{}\n'.format(self.order,DbU.getValueString(self.axis)) )
|
||||||
trace( 550, '\t{}\n'.format(contact) )
|
trace( 550, '\t{}\n'.format(contact) )
|
||||||
keys = list( self.vias.keys() )
|
keys = list( self.vias.keys() )
|
||||||
keys.sort()
|
keys.sort()
|
||||||
|
@ -241,20 +247,43 @@ class VerticalRail ( Rail ):
|
||||||
if len(keys) > 0:
|
if len(keys) > 0:
|
||||||
if insertIndex < len(keys):
|
if insertIndex < len(keys):
|
||||||
insertPosition = keys[ insertIndex ]
|
insertPosition = keys[ insertIndex ]
|
||||||
trace( 550, '\tinsertIndex:{}'.format(insertIndex) )
|
trace( 550, '\tinsertIndex:{}\n'.format(insertIndex) )
|
||||||
trace( 550, '\tCheck NEXT contactBb:{} via:{}\n' \
|
trace( 550, '\tCheck NEXT contactBb:{} via:{}\n' \
|
||||||
.format( contactBb
|
.format( contactBb
|
||||||
, self.vias[insertPosition][2].getBoundingBox()) )
|
, self.vias[insertPosition][1].getBoundingBox(railDepth)) )
|
||||||
if contactBb.getYMax() >= self.vias[insertPosition][2].getBoundingBox().getYMin():
|
if self.vias[insertPosition][1].bottomDepth < railDepth: bigviaAbove = False
|
||||||
|
elif self.vias[insertPosition][1].topDepth > railDepth: bigviaAbove = True
|
||||||
|
else:
|
||||||
|
print( ErrorMessage( 1, [ '{} neither above nor below' \
|
||||||
|
.format( self.vias[insertPosition][1] ) ] ))
|
||||||
|
trace( 550, '\tcontactAbove={} bigviaAbove={}\n'.format( contactAbove, bigviaAbove ))
|
||||||
|
if contactBb.getYMax() >= self.vias[insertPosition][1].getBoundingBox(railDepth).getYMin() \
|
||||||
|
and not xor(contactAbove,bigviaAbove):
|
||||||
trace( 550, ',--', '\tReject {} intersect NEXT\n'.format(contact) )
|
trace( 550, ',--', '\tReject {} intersect NEXT\n'.format(contact) )
|
||||||
return False
|
return False
|
||||||
if insertIndex > 0:
|
if insertIndex > 0:
|
||||||
|
insertPosition = keys[ insertIndex-1 ]
|
||||||
trace( 550, '\tcheck PREVIOUS contactBb:{} via:{}\n' \
|
trace( 550, '\tcheck PREVIOUS contactBb:{} via:{}\n' \
|
||||||
.format( contactBb
|
.format( contactBb
|
||||||
, self.vias[keys[insertIndex-1]][2].getBoundingBox()) )
|
, self.vias[insertPosition][1].getBoundingBox(railDepth)) )
|
||||||
if self.vias[keys[insertIndex-1]][2].getBoundingBox().getYMax() >= contactBb.getYMin():
|
if self.vias[insertPosition][1].bottomDepth < railDepth: bigviaAbove = False
|
||||||
|
elif self.vias[insertPosition][1].topDepth > railDepth: bigviaAbove = True
|
||||||
|
else:
|
||||||
|
print( ErrorMessage( 1, [ '{} neither above nor below' \
|
||||||
|
.format( self.vias[insertPosition][1] ) ] ))
|
||||||
|
trace( 550, '\tcontactAbove={} bigviaAbove={}\n'.format( contactAbove, bigviaAbove ))
|
||||||
|
if self.vias[insertPosition][1].getBoundingBox(railDepth).getYMax() >= contactBb.getYMin() \
|
||||||
|
and not xor(contactAbove,bigviaAbove):
|
||||||
trace( 550, ',--', '\tReject {} intersect PREVIOUS\n'.format(contact) )
|
trace( 550, ',--', '\tReject {} intersect PREVIOUS\n'.format(contact) )
|
||||||
return False
|
return False
|
||||||
|
trace( 550, ',--' )
|
||||||
|
return True
|
||||||
|
|
||||||
|
def connect ( self, contact ):
|
||||||
|
trace( 550, '\tVerticalRail.connect() {}\n'.format(contact) )
|
||||||
|
if self.net != contact.getNet():
|
||||||
|
trace( 550, '\tReject {} vs. {}\n'.format( self.net, contact.getNet() ))
|
||||||
|
return False
|
||||||
viaWidth = self.side.vRailWidth
|
viaWidth = self.side.vRailWidth
|
||||||
viaHeight = contact.getHeight()
|
viaHeight = contact.getHeight()
|
||||||
if self.conf.routingGauge.isSymbolic():
|
if self.conf.routingGauge.isSymbolic():
|
||||||
|
@ -269,8 +298,8 @@ class VerticalRail ( Rail ):
|
||||||
, contact.getHeight() - DbU.fromLambda(1.0)
|
, contact.getHeight() - DbU.fromLambda(1.0)
|
||||||
, flags=BigVia.AllowAllExpand )
|
, flags=BigVia.AllowAllExpand )
|
||||||
, contact ]
|
, contact ]
|
||||||
trace(550, ',--' '\tADD {}\n'.format(contact) )
|
|
||||||
self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
self.vias[ contact.getY() ][1].mergeDepth( self.side.getLayerDepth(contact.getLayer()) )
|
||||||
|
trace( 550, '\t-> BigVIA {}\n'.format(self.vias[ contact.getY() ][1]) )
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,15 +377,18 @@ class Side ( object ):
|
||||||
for terminal in blockSide.terminals:
|
for terminal in blockSide.terminals:
|
||||||
trace( 550, '\tterminal:{}\n'.format(terminal) )
|
trace( 550, '\tterminal:{}\n'.format(terminal) )
|
||||||
for rail in self.rails:
|
for rail in self.rails:
|
||||||
|
if not rail.isReachable( terminal[1] ):
|
||||||
|
break
|
||||||
rail.connect( terminal[1] )
|
rail.connect( terminal[1] )
|
||||||
|
|
||||||
def getRailRange ( self, net ):
|
def getRailRange ( self, net ):
|
||||||
if net.isClock(): return range(len(self.rails))
|
if net.isClock(): return range(len(self.rails))
|
||||||
if not net.isSupply(): return []
|
if not net.isSupply(): return []
|
||||||
if self.side & HORIZONTAL:
|
if self.side & HORIZONTAL:
|
||||||
trace( 550, '\tHORIZONTAL rail.\n' )
|
trace( 550, '\tHorizontal rail.\n' )
|
||||||
return range( len(self.coronaCks), len(self.rails) )
|
return range( len(self.coronaCks), len(self.rails) )
|
||||||
else:
|
else:
|
||||||
|
trace( 550, '\tVertical rail.\n' )
|
||||||
trace( 550, '\t{} > {}\n'.format(self.horizontalDepth,self.verticalDepth) )
|
trace( 550, '\t{} > {}\n'.format(self.horizontalDepth,self.verticalDepth) )
|
||||||
if self.horizontalDepth > self.verticalDepth:
|
if self.horizontalDepth > self.verticalDepth:
|
||||||
return range( len(self.coronaCks), len(self.rails) )
|
return range( len(self.coronaCks), len(self.rails) )
|
||||||
|
|
|
@ -150,7 +150,7 @@ class Corner ( object ):
|
||||||
|
|
||||||
def _instanciateCorner ( self ):
|
def _instanciateCorner ( self ):
|
||||||
name, transformation = self._getTransformation()
|
name, transformation = self._getTransformation()
|
||||||
corner = Instance.create( self.conf.cell
|
corner = Instance.create( self.conf.chip
|
||||||
, name, self.corona.padCorner
|
, name, self.corona.padCorner
|
||||||
, transformation
|
, transformation
|
||||||
, Instance.PlacementStatus.FIXED
|
, Instance.PlacementStatus.FIXED
|
||||||
|
@ -278,7 +278,7 @@ class Side ( object ):
|
||||||
iPadSpacer = _nextSpacer( iPadSpacer )
|
iPadSpacer = _nextSpacer( iPadSpacer )
|
||||||
while iPadSpacer < len(self.corona.padSpacers) and gapWidth > 0:
|
while iPadSpacer < len(self.corona.padSpacers) and gapWidth > 0:
|
||||||
gapWidth -= _getWidth( self.corona.padSpacers[iPadSpacer] )
|
gapWidth -= _getWidth( self.corona.padSpacers[iPadSpacer] )
|
||||||
spacer = Instance.create( self.conf.cell
|
spacer = Instance.create( self.conf.chip
|
||||||
, self.spacerNames % self.spacerCount
|
, self.spacerNames % self.spacerCount
|
||||||
, self.corona.padSpacers[iPadSpacer])
|
, self.corona.padSpacers[iPadSpacer])
|
||||||
self.spacerCount += 1
|
self.spacerCount += 1
|
||||||
|
@ -286,13 +286,14 @@ class Side ( object ):
|
||||||
if gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
if gapWidth < _getWidth(self.corona.padSpacers[iPadSpacer]):
|
||||||
iPadSpacer = _nextSpacer( iPadSpacer )
|
iPadSpacer = _nextSpacer( iPadSpacer )
|
||||||
if gapWidth != 0:
|
if gapWidth != 0:
|
||||||
raise ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on {} side, {} remains.' \
|
print( ErrorMessage( 1, 'PadsCorona.Side._placePads(): Pad fillers cannot close the gap between pads on {} side, {} remains.' \
|
||||||
.format(self.sideName,DbU.getValueString(gapWidth)) )
|
.format(self.sideName,DbU.getValueString(gapWidth)) ))
|
||||||
self.u += gapWidth
|
self.u += gapWidth
|
||||||
|
|
||||||
def _placePad ( self, padInstance ):
|
def _placePad ( self, padInstance ):
|
||||||
|
padAb = padInstance.getMasterCell().getAbutmentBox()
|
||||||
if self.type == North:
|
if self.type == North:
|
||||||
x = self.conf.chipAb.getXMin() + self.u
|
x = self.conf.chipAb.getXMin() + self.u - padAb.getXMin()
|
||||||
y = self.conf.chipAb.getYMax()
|
y = self.conf.chipAb.getYMax()
|
||||||
if self.corona.padOrient == Transformation.Orientation.ID:
|
if self.corona.padOrient == Transformation.Orientation.ID:
|
||||||
orientation = Transformation.Orientation.MY
|
orientation = Transformation.Orientation.MY
|
||||||
|
@ -301,7 +302,7 @@ class Side ( object ):
|
||||||
y -= self.conf.ioPadHeight
|
y -= self.conf.ioPadHeight
|
||||||
x = self.toGrid( x )
|
x = self.toGrid( x )
|
||||||
elif self.type == South:
|
elif self.type == South:
|
||||||
x = self.conf.chipAb.getXMin() + self.u
|
x = self.conf.chipAb.getXMin() + self.u - padAb.getXMin()
|
||||||
y = self.conf.chipAb.getYMin()
|
y = self.conf.chipAb.getYMin()
|
||||||
if self.corona.padOrient == Transformation.Orientation.ID:
|
if self.corona.padOrient == Transformation.Orientation.ID:
|
||||||
orientation = Transformation.Orientation.ID
|
orientation = Transformation.Orientation.ID
|
||||||
|
@ -311,27 +312,29 @@ class Side ( object ):
|
||||||
x = self.toGrid( x )
|
x = self.toGrid( x )
|
||||||
elif self.type == West:
|
elif self.type == West:
|
||||||
x = self.conf.chipAb.getXMin()
|
x = self.conf.chipAb.getXMin()
|
||||||
y = self.conf.chipAb.getYMin() + self.u
|
y = self.conf.chipAb.getYMin() + self.u + padAb.getXMin()
|
||||||
if self.corona.padOrient == Transformation.Orientation.ID:
|
if self.corona.padOrient == Transformation.Orientation.ID:
|
||||||
orientation = Transformation.Orientation.R3
|
orientation = Transformation.Orientation.R3
|
||||||
y += padInstance.getMasterCell().getAbutmentBox().getWidth()
|
y += padAb.getWidth()
|
||||||
else:
|
else:
|
||||||
orientation = Transformation.Orientation.R1
|
orientation = Transformation.Orientation.R1
|
||||||
x += padInstance.getMasterCell().getAbutmentBox().getHeight()
|
x += padAb.getHeight()
|
||||||
y = self.toGrid( y )
|
y = self.toGrid( y )
|
||||||
elif self.type == East:
|
elif self.type == East:
|
||||||
x = self.conf.chipAb.getXMax()
|
x = self.conf.chipAb.getXMax()
|
||||||
y = self.conf.chipAb.getYMin() + self.u
|
y = self.conf.chipAb.getYMin() + self.u
|
||||||
|
if padAb.getXMin():
|
||||||
|
y += padAb.getXMin() + padAb.getWidth()
|
||||||
if self.corona.padOrient == Transformation.Orientation.ID:
|
if self.corona.padOrient == Transformation.Orientation.ID:
|
||||||
orientation = Transformation.Orientation.R1
|
orientation = Transformation.Orientation.R1
|
||||||
else:
|
else:
|
||||||
orientation = Transformation.Orientation.R3
|
orientation = Transformation.Orientation.R3
|
||||||
x -= padInstance.getMasterCell().getAbutmentBox().getHeight()
|
x -= padAb.getHeight()
|
||||||
y += padInstance.getMasterCell().getAbutmentBox().getWidth()
|
y += padAb.getWidth()
|
||||||
y = self.toGrid( y )
|
y = self.toGrid( y )
|
||||||
padInstance.setTransformation ( Transformation( x, y, orientation ) )
|
padInstance.setTransformation ( Transformation( x, y, orientation ) )
|
||||||
padInstance.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
padInstance.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||||
self.u += padInstance.getMasterCell().getAbutmentBox().getWidth()
|
self.u += padAb.getWidth()
|
||||||
p = None
|
p = None
|
||||||
if self.conf.ioPadGauge.getName() == 'pxlib':
|
if self.conf.ioPadGauge.getName() == 'pxlib':
|
||||||
p = re.compile( r'p(?P<power>v[sd]{2}[ei])ck_px' )
|
p = re.compile( r'p(?P<power>v[sd]{2}[ei])ck_px' )
|
||||||
|
@ -510,12 +513,15 @@ class Corona ( object ):
|
||||||
|
|
||||||
def __init__ ( self, chip ):
|
def __init__ ( self, chip ):
|
||||||
|
|
||||||
def _cmpPad ( pad1, pad2):
|
def _cmpPad ( pad ):
|
||||||
width1 = pad1.getAbutmentBox().getWidth()
|
return pad.getAbutmentBox().getWidth()
|
||||||
width2 = pad2.getAbutmentBox().getWidth()
|
|
||||||
if width1 == width2: return 0
|
#def _cmpPad ( pad1, pad2):
|
||||||
if width1 > width2: return -1
|
# width1 = pad1.getAbutmentBox().getWidth()
|
||||||
return 1
|
# width2 = pad2.getAbutmentBox().getWidth()
|
||||||
|
# if width1 == width2: return 0
|
||||||
|
# if width1 > width2: return -1
|
||||||
|
# return 1
|
||||||
|
|
||||||
def _dupPads ( padsConf ):
|
def _dupPads ( padsConf ):
|
||||||
duplicateds = []
|
duplicateds = []
|
||||||
|
@ -560,7 +566,7 @@ class Corona ( object ):
|
||||||
if spacerCell: self.padSpacers.append( spacerCell )
|
if spacerCell: self.padSpacers.append( spacerCell )
|
||||||
else:
|
else:
|
||||||
raise ErrorMessage( 1, 'Corona.__init__(): Missing spacer cell "{}"'.format(spacerName) )
|
raise ErrorMessage( 1, 'Corona.__init__(): Missing spacer cell "{}"'.format(spacerName) )
|
||||||
self.padSpacers.sort( _cmpPad )
|
self.padSpacers = sorted( self.padSpacers, key=_cmpPad, reverse=True )
|
||||||
if self.conf.cfg.chip.padCorner is not None:
|
if self.conf.cfg.chip.padCorner is not None:
|
||||||
self.padCorner = self.padLib.getCell( self.conf.cfg.chip.padCorner )
|
self.padCorner = self.padLib.getCell( self.conf.cfg.chip.padCorner )
|
||||||
if self.conf.cfg.chip.minPadSpacing is None:
|
if self.conf.cfg.chip.minPadSpacing is None:
|
||||||
|
|
Loading…
Reference in New Issue