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:
Jean-Paul Chaput 2019-03-23 11:05:51 +01:00
parent 5dd235b3cd
commit 3a2916b5e6
7 changed files with 107 additions and 17 deletions

View File

@ -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

View File

@ -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;

View File

@ -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
)

View File

@ -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".

View File

@ -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

View File

@ -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.

View File

@ -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();