Improved clock-tree support for variable pitch routing gauges.
* New: In Hurricane::Isobar::PySegment, added wrapper for getOppositeAnchor(). * Bug: CRL::PyRoutingLayerGauge, Python wrapper of getTrackPosition() was in fact returning getTrackNumer(). * Bug: In Katana::PowerRailsPlanes::Rail::doLayout(), add the half minimum distance to the blockage segments extensions. Was causing too near VIAs is cmos45. * Change: In cumulus/plugins/ClockTree, correctly manage routing gauge when the lower pitches (M2/M3) is different from the upper one (M4/M5). But we still can only do sxlib compliant gauges because we do not handle a switch in preferred routing directions.
This commit is contained in:
parent
5dd235b3cd
commit
3a2916b5e6
|
@ -267,9 +267,7 @@ namespace CRL {
|
|||
|
||||
|
||||
DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, unsigned depth ) const
|
||||
{
|
||||
return depth * _pitch + _offset + start;
|
||||
}
|
||||
{ return depth * _pitch + _offset + start; }
|
||||
|
||||
|
||||
string RoutingLayerGauge::_getTypeName () const
|
||||
|
|
|
@ -245,7 +245,7 @@ extern "C" {
|
|||
unsigned int depth = 0;
|
||||
|
||||
if (PyArg_ParseTuple( args, "OI:RoutingLayerGauge.getTrackIndex", &pyStart, &depth)) {
|
||||
trackPosition = rlg->getTrackNumber( PyAny_AsLong(pyStart), depth);
|
||||
trackPosition = rlg->getTrackPosition( PyAny_AsLong(pyStart), depth);
|
||||
} else {
|
||||
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingLayerGauge.getTrackPosition()." );
|
||||
return NULL;
|
||||
|
|
|
@ -20,6 +20,7 @@ try:
|
|||
import math
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import Breakpoint
|
||||
import Viewer
|
||||
import CRL
|
||||
from CRL import RoutingLayerGauge
|
||||
|
@ -58,8 +59,8 @@ def unicornHook ( **kw ):
|
|||
kw['beforeAction'] = 'placeAndRoute.placeChip'
|
||||
|
||||
plugins.kwUnicornHook( 'placeAndRoute.clockTree'
|
||||
, 'Clock Tree'
|
||||
, 'Build a buffered H-Tree for the clock'
|
||||
, 'Place Block && Clock Tree'
|
||||
, 'Place a block with a buffered H-Tree for the clock'
|
||||
, sys.modules[__name__].__file__
|
||||
, **kw
|
||||
)
|
||||
|
|
|
@ -176,6 +176,20 @@ class GaugeConf ( object ):
|
|||
, self._routingGauge.getLayerGauge(depth).getViaWidth()
|
||||
)
|
||||
|
||||
def _getNearestHorizontalTrack ( self, bb, y, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self._horizontalDeepDepth
|
||||
else: depth = self._horizontalDepth
|
||||
|
||||
index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getYMin(), bb.getYMax(), y, RoutingLayerGauge.Nearest )
|
||||
return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getYMin(), index )
|
||||
|
||||
def _getNearestVerticalTrack ( self, bb, x, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self._verticalDeepDepth
|
||||
else: depth = self._verticalDepth
|
||||
|
||||
index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getXMin(), bb.getXMax(), x, RoutingLayerGauge.Nearest )
|
||||
return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getXMin(), index )
|
||||
|
||||
def _createHorizontal ( self, source, target, y, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self._horizontalDeepDepth
|
||||
else: depth = self._horizontalDepth
|
||||
|
@ -309,6 +323,25 @@ class GaugeConf ( object ):
|
|||
def _rpAccessByPlugName ( self, instance, plugName, net, flags=0 ):
|
||||
return self._rpAccess( self._rpByPlugName(instance,plugName,net), flags )
|
||||
|
||||
def _setStackPosition ( self, topContact, x, y ):
|
||||
topContact.setX( x )
|
||||
topContact.setY( y )
|
||||
|
||||
count = 0
|
||||
for component in topContact.getSlaveComponents():
|
||||
segment = component
|
||||
count += 1
|
||||
if count != 1:
|
||||
print ErrorMessage( 1, 'GaugeConf::_setStackPosition(): There must be exactly one segment connected, not %d.' % count)
|
||||
|
||||
if isinstance(segment,Horizontal):
|
||||
segment.setY( y )
|
||||
segment.getOppositeAnchor( topContact ).setY( y )
|
||||
elif isinstance(segment,Vertical):
|
||||
segment.setX( x )
|
||||
segment.getOppositeAnchor( topContact ).setX( x )
|
||||
return
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "Configuration.GaugeConfWrapper".
|
||||
|
@ -364,6 +397,15 @@ class GaugeConfWrapper ( object ):
|
|||
def createVertical ( self, source, target, x, flags=0 ):
|
||||
return self._gaugeConf._createVertical( source, target, x, flags )
|
||||
|
||||
def getNearestHorizontalTrack ( self, bb, y, flags ):
|
||||
return self._gaugeConf._getNearestHorizontalTrack ( bb, y, flags )
|
||||
|
||||
def getNearestVerticalTrack ( self, bb, x, flags ):
|
||||
return self._gaugeConf._getNearestVerticalTrack( bb, x, flags )
|
||||
|
||||
def setStackPosition ( self, topContact, x, y ):
|
||||
self._gaugeConf._setStackPosition( topContact, x, y )
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "Configuration.ChipConf".
|
||||
|
|
|
@ -87,7 +87,8 @@ class HTree ( GaugeConfWrapper ):
|
|||
% aspectRatio )
|
||||
|
||||
ht = HTree( conf, cell, clockNet, clockBox )
|
||||
print ' o Creating Clock H-Tree for <%s>.' % cell.getName()
|
||||
print ' o Creating clock H-Tree for "%s".' % cell.getName()
|
||||
print ' - Clock is "%s"' % ht.masterClock.getName()
|
||||
ht.build()
|
||||
trace( 550, '\tht.build() OK\n' )
|
||||
ht.place()
|
||||
|
@ -482,6 +483,8 @@ class HTreeNode ( object ):
|
|||
leafCk = deepPlug.getMasterNet()
|
||||
plugOccurrence.getEntity().setNet( leafCk )
|
||||
|
||||
trace( 550, '\tLeaf clock set to <%s>.\n' % plugOccurrence.getEntity() )
|
||||
|
||||
return
|
||||
|
||||
def getLeafBufferUnder ( self, point ):
|
||||
|
@ -526,12 +529,34 @@ class HTreeNode ( object ):
|
|||
trContact = self.topTree.rpAccessByPlugName( self.trBuffer , self.topTree.bufferIn , self.ckNet )
|
||||
leftContact = self.topTree.createContact( self.ckNet, blContact.getX(), leftSourceContact.getY() )
|
||||
rightContact = self.topTree.createContact( self.ckNet, brContact.getX(), rightSourceContact.getY() )
|
||||
self.topTree.createHorizontal( leftContact , leftSourceContact, leftSourceContact.getY() , 0 )
|
||||
self.topTree.createHorizontal( rightSourceContact, rightContact , rightSourceContact.getY(), 0 )
|
||||
self.topTree.createVertical ( leftContact , blContact , leftContact.getX() , 0 )
|
||||
self.topTree.createVertical ( tlContact , leftContact , leftContact.getX() , 0 )
|
||||
self.topTree.createVertical ( rightContact , brContact , rightContact.getX() , 0 )
|
||||
self.topTree.createVertical ( trContact , rightContact , rightContact.getX() , 0 )
|
||||
|
||||
leftSourceX = self.topTree.getNearestVerticalTrack ( self.topTree.area, leftSourceContact.getX(), 0 )
|
||||
leftSourceY = self.topTree.getNearestHorizontalTrack( self.topTree.area, leftSourceContact.getY(), 0 )
|
||||
rightSourceX = self.topTree.getNearestVerticalTrack ( self.topTree.area, rightSourceContact.getX(), 0 )
|
||||
rightSourceY = self.topTree.getNearestHorizontalTrack( self.topTree.area, rightSourceContact.getY(), 0 )
|
||||
leftX = self.topTree.getNearestVerticalTrack ( self.topTree.area, leftContact.getX(), 0 )
|
||||
rightX = self.topTree.getNearestVerticalTrack ( self.topTree.area, rightContact.getX(), 0 )
|
||||
tlY = self.topTree.getNearestHorizontalTrack( self.topTree.area, tlContact.getY(), 0 )
|
||||
blY = self.topTree.getNearestHorizontalTrack( self.topTree.area, blContact.getY(), 0 )
|
||||
|
||||
self.topTree.setStackPosition( leftSourceContact, leftSourceX, leftSourceY )
|
||||
self.topTree.setStackPosition( rightSourceContact, rightSourceX, rightSourceY )
|
||||
self.topTree.setStackPosition( tlContact, leftX, tlY )
|
||||
self.topTree.setStackPosition( blContact, leftX, blY )
|
||||
self.topTree.setStackPosition( trContact, rightX, tlY )
|
||||
self.topTree.setStackPosition( brContact, rightX, blY )
|
||||
|
||||
leftContact .setX( leftX )
|
||||
leftContact .setY( leftSourceY )
|
||||
rightContact.setX( rightX )
|
||||
rightContact.setY( rightSourceY )
|
||||
|
||||
self.topTree.createHorizontal( leftContact , leftSourceContact, leftSourceY , 0 )
|
||||
self.topTree.createHorizontal( rightSourceContact, rightContact , rightSourceY, 0 )
|
||||
self.topTree.createVertical ( leftContact , blContact , leftX , 0 )
|
||||
self.topTree.createVertical ( tlContact , leftContact , leftX , 0 )
|
||||
self.topTree.createVertical ( rightContact , brContact , rightX , 0 )
|
||||
self.topTree.createVertical ( trContact , rightContact , rightX , 0 )
|
||||
|
||||
for child in self.childs: child.route()
|
||||
return
|
||||
|
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
if (pyReturnHook == NULL) return NULL;
|
||||
|
||||
PyObject* pyHook = NULL;
|
||||
if (not PyArg_ParseTuple(args,"O:Hook.merge", &pyHook)) return NULL;
|
||||
if (not PyArg_ParseTuple(args,"O:Segment.getOppositetHook", &pyHook)) return NULL;
|
||||
|
||||
Hook* hook = PYHOOK_O(pyHook);
|
||||
|
||||
|
@ -85,6 +85,29 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PySegment_getOppositeAnchor ( PySegment *self, PyObject* args )
|
||||
{
|
||||
cdebug_log(20,0) << "PySegment_getOppositeAnchor()" << endl;
|
||||
METHOD_HEAD ( "Segment.getOppositeAnchor()" )
|
||||
|
||||
Component* opposite = NULL;
|
||||
PyObject* pyOpposite = NULL;
|
||||
PyComponent* pyComponent = NULL;
|
||||
if (not PyArg_ParseTuple(args,"O:Segment.getOppositeAnchor", &pyComponent)) return NULL;
|
||||
|
||||
Component* anchor = PYCOMPONENT_O(pyComponent);
|
||||
|
||||
HTRY
|
||||
opposite = segment->getOppositeAnchor( anchor );
|
||||
if (opposite) pyOpposite = PyEntity_NEW( opposite );
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
HCATCH
|
||||
|
||||
return pyOpposite;
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PySegment_getSource ( PySegment *self )
|
||||
{
|
||||
cdebug_log(20,0) << "PySegment_getSource()" << endl;
|
||||
|
@ -164,6 +187,7 @@ extern "C" {
|
|||
{ { "getSourceHook" , (PyCFunction)PySegment_getSourceHook , METH_NOARGS , "Return the nested source Hook." }
|
||||
, { "getTargetHook" , (PyCFunction)PySegment_getTargetHook , METH_NOARGS , "Return the nested target Hook." }
|
||||
, { "getOppositeHook" , (PyCFunction)PySegment_getOppositeHook , METH_VARARGS, "Return the nested Hook opposite of the argument hook." }
|
||||
, { "getOppositeAnchor" , (PyCFunction)PySegment_getOppositeAnchor, METH_VARARGS, "Return the opposite component anchor." }
|
||||
, { "getSource" , (PyCFunction)PySegment_getSource , METH_NOARGS , "Return the Segment source component (or None)." }
|
||||
, { "getTarget" , (PyCFunction)PySegment_getTarget , METH_NOARGS , "Return the Segment target component (or None)." }
|
||||
, { "getSourceX" , (PyCFunction)PySegment_getSourceX , METH_NOARGS , "Return the Segment source X value." }
|
||||
|
@ -212,7 +236,5 @@ extern "C" {
|
|||
} // End of extern "C".
|
||||
|
||||
|
||||
|
||||
|
||||
} // End of Isobar namespace.
|
||||
|
||||
|
|
|
@ -638,7 +638,9 @@ namespace {
|
|||
// - plane->getLayerGauge()->getHalfWireWidth()
|
||||
// - DbU::fromLambda(0.1);
|
||||
DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1);
|
||||
DbU::Unit extension = layer->getExtentionCap();
|
||||
DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2;
|
||||
//DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth();
|
||||
//DbU::Unit extension = layer->getExtentionCap();
|
||||
//DbU::Unit extension = Session::getExtentionCap();
|
||||
//unsigned int type = plane->getLayerGauge()->getType();
|
||||
const Box& coronaBb = plane->getKatanaEngine()->getChipTools().getCoronaBb();
|
||||
|
|
Loading…
Reference in New Issue