diff --git a/crlcore/src/cyclop/CMakeLists.txt b/crlcore/src/cyclop/CMakeLists.txt index 259f20e3..4ee51be4 100644 --- a/crlcore/src/cyclop/CMakeLists.txt +++ b/crlcore/src/cyclop/CMakeLists.txt @@ -21,6 +21,7 @@ link_directories ( ${CRLCORE_BINARY_DIR}/src/ccore ) +# add_executable ( cyclop ${cpps} ) add_executable ( cyclop ${cpps} ${mocCpps} ) target_link_libraries ( cyclop crlcore ${HURRICANE_PYTHON_LIBRARIES} diff --git a/cumulus/src/plugins/ClockTree.py b/cumulus/src/plugins/ClockTree.py deleted file mode 100755 index 3c22537e..00000000 --- a/cumulus/src/plugins/ClockTree.py +++ /dev/null @@ -1,582 +0,0 @@ -#!/usr/bin/env python -# -# This file is part of the Coriolis Software. -# Copyright (c) UPMC 2014-2014, All Rights Reserved -# -# +-----------------------------------------------------------------+ -# | C O R I O L I S | -# | C u m u l u s - P y t h o n T o o l s | -# | | -# | Author : Jean-Paul CHAPUT | -# | E-mail : Jean-Paul.Chaput@asim.lip6.fr | -# | =============================================================== | -# | Python : "./plugins/ClockTree.cpp" | -# +-----------------------------------------------------------------+ - -try: - import sys - import traceback - import os.path - import optparse - import math - import Cfg - import Hurricane - from Hurricane import DbU - from Hurricane import Transformation - from Hurricane import Box - from Hurricane import Path - from Hurricane import Occurrence - from Hurricane import UpdateSession - from Hurricane import Breakpoint - from Hurricane import Net - from Hurricane import RoutingPad - from Hurricane import Contact - from Hurricane import Horizontal - from Hurricane import Vertical - from Hurricane import Instance - from Hurricane import HyperNet - import Viewer - import CRL - from CRL import RoutingLayerGauge - from helpers import ErrorMessage - import Nimbus - import Metis - import Mauka - import Katabatic - import Kite - import Unicorn - import plugins -except ImportError, e: - module = str(e).split()[-1] - - print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module - print ' Please check the integrity of the package.' - sys.exit(1) -except Exception, e: - print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' - print ' modules. Something may be wrong at Python/C API level.\n' - print ' %s' % e - sys.exit(2) - - -# Will be moved away from the students eyes in the future. -def breakpoint ( editor, level, message ): - if editor: - editor.fit() - editor.refresh() - Breakpoint.stop( level, message ) - return - - -def getPlugByName ( instance, netName ): - masterCell = instance.getMasterCell() - masterNet = masterCell.getNet( netName ) - if masterNet: - return instance.getPlug( masterNet ) - return None - - -def getPlugByNet ( instance, net ): - #print 'getPlugByNet:', net, 'connected to', instance - for plug in net.getPlugs(): - #print '|', plug - if plug.getInstance() == instance: - #print '| Found.' - return plug - #print '| NOT Found' - return None - - -def showNet ( cell, netName ): - net = cell.getNet(netName) - if not net: - print ErrorMessage( 3, 'Cell %s doesn\'t have net %s' % cell.getName(), netName ) - return - - print 'Components of', netName - for component in net.getComponents(): - print '| ', component, component.getBoundingBox() - return - - -class HTree ( object ): - - HAccess = 0x0001 - - @staticmethod - def create ( cell, clockBox ): - if clockBox.isEmpty(): raise ErrorMessage( 3, 'ClockTree: The clock area is empty.' ) - - aspectRatio = DbU.toLambda( clockBox.getWidth() ) / DbU.toLambda( clockBox.getHeight() ) - if aspectRatio > 1.5 or aspectRatio < 0.5: - raise ErrorMessage( 3, 'ClockTree: aspect ratio %f is disproportionate, must be between 0.5 and 1.5.' \ - % aspectRatio ) - - ht = HTree( cell, clockBox ) - print ' o Creating Clock H-Tree for <%s>.' % cell.getName() - ht.build() - ht.place() - ht.route() - print ' - H-Tree depth: %d' % ht.getTreeDepth() - return ht - - def __init__ ( self, cell, area ): - self.minSide = DbU.fromLambda( Cfg.getParamInt('clockTree.minimumSide').asInt() ) - if self.minSide < DbU.fromLambda(100.0): - raise ErrorMessage( 3, 'ClockTree: clockTree.minimumSide (%g) is less than 100 lambda.' \ - % DbU.toLambda(self.minSide) ) - - self.framework = CRL.AllianceFramework.get() - self.cell = cell - self.area = area - self.childs = [] - self.bufferCell = self.framework.getCell( 'buf_x2', CRL.Catalog.State.Logical ) - self.cellGauge = self.framework.getCellGauge() - self.routingGauge = self.framework.getRoutingGauge() - self.topBuffer = Instance.create( self.cell, 'ck_htree', self.bufferCell ) - self.cloneds = [ self.cell ] - self.plugToRp = {} - self._createChildNet( self.topBuffer, 'ck_htree' ) - - topLayer = Cfg.getParamString('katabatic.topRoutingLayer').asString() - self.topLayerDepth = 0 - for layerGauge in self.routingGauge.getLayerGauges(): - if layerGauge.getLayer().getName() == topLayer: - self.topLayerDepth = layerGauge.getDepth() - break - if not self.topLayerDepth: - print '[WARNING] Gauge top layer not defined, using top of gauge (%d).' \ - % self.routingGauge.getDepth() - self.topLayerDepth = self.routingGauge.getDepth() - - self.horizontalDepth = 0 - self.verticalDepth = 0 - for depth in range(0,self.topLayerDepth+1): - if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal: - self.horizontalDepth = depth - if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Vertical: - self.verticalDepth = depth - - self.masterClock = None - for net in cell.getNets(): - if net.isClock(): - self.masterClock = net - break - if not self.masterClock: - print '[WARNING] Cell %s has no clock net.' % cell.getName() - - return - - def _createChildNet ( self, ibuffer, tag ): - childNet = Net.create( self.cell, tag ) - childNet.setType( Net.Type.CLOCK ) - getPlugByName(ibuffer, 'q').setNet( childNet ) - return - - def _createContact ( self, net, x, y ): - return Contact.create( net - , self.routingGauge.getContactLayer(self.horizontalDepth) - , x, y - , self.routingGauge.getLayerGauge(self.horizontalDepth).getViaWidth() - , self.routingGauge.getLayerGauge(self.horizontalDepth).getViaWidth() - ) - - def _createHorizontal ( self, source, target, y ): - return Horizontal.create( source - , target - , self.routingGauge.getRoutingLayer(self.horizontalDepth) - , y - , self.routingGauge.getLayerGauge(self.horizontalDepth).getWireWidth() - ) - - def _createVertical ( self, source, target, x ): - return Vertical.create( source - , target - , self.routingGauge.getRoutingLayer(self.verticalDepth) - , x - , self.routingGauge.getLayerGauge(self.verticalDepth).getWireWidth() - ) - - def _rpAccess ( self, rp, net, flags=0 ): - contact1 = Contact.create( rp, self.routingGauge.getContactLayer(0), 0, 0 ) - - if flags & HTree.HAccess: stopDepth = self.horizontalDepth - else: stopDepth = self.verticalDepth - - for depth in range(1,stopDepth): - contact2 = Contact.create( net - , self.routingGauge.getContactLayer(depth) - , contact1.getX() - , contact1.getY() - , self.routingGauge.getLayerGauge(depth).getViaWidth() - , self.routingGauge.getLayerGauge(depth).getViaWidth() - ) - if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal: - Horizontal.create( contact1 - , contact2 - , self.routingGauge.getRoutingLayer(depth) - , contact1.getY() - , self.routingGauge.getLayerGauge(depth).getWireWidth() - ) - else: - Vertical.create( contact1 - , contact2 - , self.routingGauge.getRoutingLayer(depth) - , contact1.getX() - , self.routingGauge.getLayerGauge(depth).getWireWidth() - ) - contact1 = contact2 - - return contact1 - - def _rpAccessByOccurrence ( self, occurrence, net, flags=0 ): - plug = occurrence.getEntity() - if self.plugToRp.has_key(plug): - rp = self.plugToRp[plug] - else: - rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea ) - self.plugToRp[plug] = rp - - return self._rpAccess( rp, net, flags ) - - def _rpAccessByPlug ( self, plug, net, flags=0 ): - if self.plugToRp.has_key(plug): - rp = self.plugToRp[plug] - else: - occurrence = Occurrence( plug, Path(self.cell,'') ) - rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea ) - self.plugToRp[plug] = rp - - return self._rpAccess( rp, net, flags ) - - def _rpAccessByPlugName ( self, instance, plugName, net, flags=0 ): - return self._rpAccessByPlug( getPlugByName(instance,plugName), net, flags ) - - def toXCellGrid ( self, x ): return x - (x % self.cellGauge.getSliceStep ()) - def toYCellGrid ( self, y ): return y - (y % self.cellGauge.getSliceHeight()) - - def placeInstance ( self, instance, x, y ): - xslice = self.toXCellGrid(x) - yslice = self.toYCellGrid(y) - - transformation = Transformation.Orientation.ID - if (yslice / self.cellGauge.getSliceHeight()) % 2 != 0: - transformation = Transformation.Orientation.MY - yslice += self.cellGauge.getSliceHeight() - - instance.setTransformation ( Transformation(xslice, yslice, transformation) ) - instance.setPlacementStatus( Instance.PlacementStatus.FIXED ) - return - - def getTreeDepth ( self ): - return self.childs[0].getTreeDepth() - - def getLeafBufferUnder ( self, point ): - return self.childs[0].getLeafBufferUnder( point ) - - def build ( self ): - self.childs.append( HTreeNode( self, self.topBuffer, self.area, '', HTreeNode.RootBranch ) ) - return - - def place ( self ): - UpdateSession.open() - center = self.area.getCenter() - self.placeInstance( self.topBuffer, center.getX(), center.getY() ) - self.childs[0].place() - UpdateSession.close() - return - - def route ( self ): - UpdateSession.open() - self.childs[0].route() - UpdateSession.close() - return - - def addDeepPlug ( self, topNet, path ): - if path.isEmpty(): return None - - tailPath = path.getTailPath() - headInstance = path.getHeadInstance() - headPlug = getPlugByNet(headInstance,topNet) - if headPlug: - if tailPath.isEmpty(): return headPlug - return self.addDeepPlug( headPlug.getMasterNet(), tailPath ) - - masterCell = headInstance.getMasterCell() - masterNet = Net.create( masterCell, topNet.getName() ) - masterNet.setExternal ( True ) - masterNet.setType ( Net.Type.CLOCK ) - masterNet.setDirection( Net.Direction.IN ) - headPlug = headInstance.getPlug( masterNet ) - if not headPlug: - raise ErrorMessage( 3, 'Plug not created for %s on instance %s of %s' \ - % (topNet.getName(),headInstance.getName(),masterCell.getName()) ) - headPlug.setNet( topNet ) - if not masterCell in self.cloneds: self.cloneds.append( masterCell ) - - if tailPath.isEmpty(): return headPlug - return self.addDeepPlug( masterNet, tailPath ) - - def connectLeaf ( self ): - UpdateSession.open() - - leafConnects = [] - hyperMasterClock = HyperNet.create( Occurrence(self.masterClock) ) - for plugOccurrence in hyperMasterClock.getLeafPlugOccurrences(): - position = plugOccurrence.getBoundingBox().getCenter() - leafBuffer = self.getLeafBufferUnder( position ) - leafCk = getPlugByName(leafBuffer,'q').getNet() - deepPlug = self.addDeepPlug( leafCk, plugOccurrence.getPath() ) - leafConnects.append( (deepPlug,plugOccurrence,leafCk,leafBuffer) ) - - for deepPlug, plugOccurrence, leafCk, leafBuffer in leafConnects: - plugOccurrence.getEntity().setNet( deepPlug.getMasterNet() ) - - bufferContact = self._rpAccessByPlugName( leafBuffer, 'q', leafCk , HTree.HAccess ) - registerContact = self._rpAccessByOccurrence( plugOccurrence, leafCk, 0 ) - turn = self._createContact( leafCk, registerContact.getX(), bufferContact.getY() ) - self._createVertical ( registerContact, turn, registerContact.getX() ) - self._createHorizontal( turn, bufferContact, bufferContact.getY() ) - - getPlugByName( self.topBuffer, 'i' ).setNet( self.masterClock ) - UpdateSession.close() - - return - - def _rsave ( self, cell ): - flags = CRL.Catalog.State.Physical - if cell.getName().endswith('_clocked'): - flags = flags | CRL.Catalog.State.Logical - self.framework.saveCell( cell, flags ) - - for instance in cell.getInstances(): - masterCell = instance.getMasterCell() - if not masterCell.isTerminal(): - self._rsave( masterCell ) - - def save ( self ): - for cell in self.cloneds: - cell.setName( cell.getName()+'_clocked' ) - - self._rsave( self.cell ) - return - - -class HTreeNode ( object ): - - RootBranch = 0x0001 - LeftBranch = 0x0002 - RightBranch = 0x0004 - UpBranch = 0x0008 - DownBranch = 0x0010 - - def __init__ ( self, topTree, sourceBuffer, area, prefix, flags ): - self.topTree = topTree - self.childs = [] - self.flags = flags - self.sourceBuffer = sourceBuffer - self.area = area - self.prefix = prefix - - self.blBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_bl_ins', self.topTree.bufferCell ) - self.brBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_br_ins', self.topTree.bufferCell ) - self.tlBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_tl_ins', self.topTree.bufferCell ) - self.trBuffer = Instance.create( self.topTree.cell, 'ck_htree'+self.prefix+'_tr_ins', self.topTree.bufferCell ) - self.ckNet = getPlugByName(self.sourceBuffer, 'q').getNet() - getPlugByName(self.blBuffer, 'i').setNet( self.ckNet ) - getPlugByName(self.brBuffer, 'i').setNet( self.ckNet ) - getPlugByName(self.tlBuffer, 'i').setNet( self.ckNet ) - getPlugByName(self.trBuffer, 'i').setNet( self.ckNet ) - - self.topTree._createChildNet( self.blBuffer, 'ck_htree'+self.prefix+'_bl' ) - self.topTree._createChildNet( self.brBuffer, 'ck_htree'+self.prefix+'_br' ) - self.topTree._createChildNet( self.tlBuffer, 'ck_htree'+self.prefix+'_tl' ) - self.topTree._createChildNet( self.trBuffer, 'ck_htree'+self.prefix+'_tr' ) - - halfWidth = self.area.getHalfWidth () - halfHeight = self.area.getHalfHeight() - if halfWidth >= self.topTree.minSide and halfHeight >= self.topTree.minSide: - # Recursive call. - self.childs.append( HTreeNode( self.topTree, self.blBuffer, self.blArea(), self.prefix+'_bl', 0 ) ) - self.childs.append( HTreeNode( self.topTree, self.brBuffer, self.brArea(), self.prefix+'_br', 0 ) ) - self.childs.append( HTreeNode( self.topTree, self.tlBuffer, self.tlArea(), self.prefix+'_tl', 0 ) ) - self.childs.append( HTreeNode( self.topTree, self.trBuffer, self.trArea(), self.prefix+'_tr', 0 ) ) - - return - - def xmin ( self ): return self.area.getXMin() - def xmax ( self ): return self.area.getXMax() - def ymin ( self ): return self.area.getYMin() - def ymax ( self ): return self.area.getYMax() - def halfWidth ( self ): return self.area.getHalfWidth() - def halfHeight( self ): return self.area.getHalfHeight() - - def blArea ( self ): - return Box( self.xmin() , self.ymin() - , self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight() ) - - def brArea ( self ): - return Box( self.xmin()+self.halfWidth(), self.ymin() - , self.xmax() , self.ymin()+self.halfHeight() ) - - def tlArea ( self ): - return Box( self.xmin() , self.ymin()+self.halfHeight() - , self.xmin()+self.halfWidth(), self.ymax() ) - - def trArea ( self ): - return Box( self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight() - , self.xmax() , self.ymax() ) - - def getTreeDepth ( self ): - if self.childs: return self.childs[0].getTreeDepth()+1 - return 1 - - def getLeafBufferUnder ( self, point ): - if self.childs: - if self.blArea().contains(point): return self.childs[0].getLeafBufferUnder(point) - if self.brArea().contains(point): return self.childs[1].getLeafBufferUnder(point) - if self.tlArea().contains(point): return self.childs[2].getLeafBufferUnder(point) - if self.trArea().contains(point): return self.childs[3].getLeafBufferUnder(point) - - if self.blArea().contains(point): return self.blBuffer - if self.brArea().contains(point): return self.brBuffer - if self.tlArea().contains(point): return self.tlBuffer - return self.trBuffer - - def place ( self ): - x = self.area.getXMin() + self.area.getWidth ()/4 - y = self.area.getYMin() + self.area.getHeight()/4 - halfWidth = self.area.getHalfWidth () - halfHeight = self.area.getHalfHeight() - - self.topTree.placeInstance( self.blBuffer, x , y ) - self.topTree.placeInstance( self.brBuffer, x+halfWidth, y ) - self.topTree.placeInstance( self.tlBuffer, x , y+halfHeight ) - self.topTree.placeInstance( self.trBuffer, x+halfWidth, y+halfHeight ) - - for child in self.childs: child.place() - return - - def route ( self ): - leftSourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess ) - rightSourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess ) - blContact = self.topTree._rpAccessByPlugName( self.blBuffer , 'i', self.ckNet ) - brContact = self.topTree._rpAccessByPlugName( self.brBuffer , 'i', self.ckNet ) - tlContact = self.topTree._rpAccessByPlugName( self.tlBuffer , 'i', self.ckNet ) - trContact = self.topTree._rpAccessByPlugName( self.trBuffer , 'i', 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() ) - self.topTree._createHorizontal( rightSourceContact, rightContact , rightSourceContact.getY() ) - self.topTree._createVertical ( leftContact , blContact , leftContact.getX() ) - self.topTree._createVertical ( tlContact , leftContact , leftContact.getX() ) - self.topTree._createVertical ( rightContact , brContact , rightContact.getX() ) - self.topTree._createVertical ( trContact , rightContact , rightContact.getX() ) - - for child in self.childs: child.route() - return - -def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ): - sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) - - instancesNb = 0 - cellLength = 0 - for occurrence in cell.getLeafInstanceOccurrences(): - instance = occurrence.getEntity() - instancesNb += 1 - cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) - - # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 - # y = sqrt(S/AR) - gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight - rows = math.sqrt( gcellLength/aspectRatio ) - if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 - else: rows = math.trunc(rows) - columns = gcellLength / rows - if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 - else: columns = math.trunc(columns) - - print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ - % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) - print ' - GCell grid: [%dx%d]' % (columns,rows) - - UpdateSession.open() - abutmentBox = Box( DbU.fromLambda(0) - , DbU.fromLambda(0) - , DbU.fromLambda(columns*sliceHeight) - , DbU.fromLambda(rows *sliceHeight) - ) - cell.setAbutmentBox( abutmentBox ) - UpdateSession.close() - - return abutmentBox - - -def unicornHook ( **kw ): - plugins.kwUnicornHook( 'plugins.clockTree' - , 'ClockTree' - , 'Build a buffered H-Tree for the clock' - , sys.modules[__name__].__file__ - , **kw - ) - return - - -def ScriptMain ( **kw ): - try: - errorCode = 0 - - print ' o Cleaning up any previous run.' - for fileName in os.listdir('.'): - if fileName.endswith('.ap'): - print ' - <%s>' % fileName - os.unlink(fileName) - - cell = None - if kw.has_key('cell') and kw['cell']: - cell = kw['cell'] - - editor = None - if kw.has_key('editor') and kw['editor']: - editor = kw['editor'] - print ' o Editor detected, running in graphic mode.' - if cell == None: cell = editor.getCell() - - if cell == None: - raise ErrorMessage( 3, 'ClockTree: No cell loaded yet.' ) - - framework = CRL.AllianceFramework.get() - cellGauge = framework.getCellGauge() - - if cell.getAbutmentBox().isEmpty(): - spaceMargin = Cfg.getParamPercentage('nimbus.spaceMargin').asPercentage() / 100.0 + 0.02 - aspectRatio = Cfg.getParamPercentage('nimbus.aspectRatio').asPercentage() / 100.0 - computeAbutmentBox( cell, spaceMargin, aspectRatio, cellGauge ) - if editor: editor.fit() - - ht = HTree.create( cell, cell.getAbutmentBox() ) - if editor: editor.refresh() - mauka = Mauka.MaukaEngine.create( cell ) - mauka.run() - mauka.destroy() - ht.connectLeaf() - ht.save() - - #showNet( cell, 'ck_htree_bl_bl_bl' ) - #showNet( cell, 'ck_htree_bl_bl_br' ) - #showNet( cell, 'ck_htree_bl_bl_tl' ) - #showNet( cell, 'ck_htree_bl_bl_tr' ) - - except ErrorMessage, e: - print e; errorCode = e.code - except Exception, e: - print '\n\n', e; errorCode = 1 - traceback.print_tb(sys.exc_info()[2]) - - return 0 - - -if __name__ == '__main__': - ScriptMain() - - sys.exit(0) diff --git a/hurricane/src/hurricane/Plug.cpp b/hurricane/src/hurricane/Plug.cpp index 2a806f6b..4f139e24 100644 --- a/hurricane/src/hurricane/Plug.cpp +++ b/hurricane/src/hurricane/Plug.cpp @@ -137,10 +137,10 @@ void Plug::setNet(Net* net) if (net != getNet()) { if (net && (getCell() != net->getCell())) - throw Error("Can't change net of plug : net : " + getString(net) + "does not belong to the cell : " + getString(getCell())); + throw Error("Can't change net of plug: " + getString(net) + " does not belong to " + getString(getCell())); if (!getBodyHook()->getSlaveHooks().isEmpty()) - throw Error("Can't change net of plug : not empty slave hooks"); + throw Error("Can't change net of plug: not empty slave hooks"); _setNet(net); } diff --git a/hurricane/src/hurricane/Segment.cpp b/hurricane/src/hurricane/Segment.cpp index 5496542f..b97b49fc 100644 --- a/hurricane/src/hurricane/Segment.cpp +++ b/hurricane/src/hurricane/Segment.cpp @@ -20,6 +20,7 @@ #include "hurricane/Segment.h" #include "hurricane/BasicLayer.h" #include "hurricane/Error.h" +#include "hurricane/Net.h" namespace Hurricane { @@ -173,16 +174,20 @@ Segment::Segment(Net* net, Component* source, Component* target, const Layer* la { if (source) { if (!source->getNet()) - throw Error("Can't create " + _TName("Segment") + " : unconnected source"); + throw Error("Can't create " + _TName("Segment") + ": unconnected source"); if (source->getNet() != net) - throw Error("Can't create " + _TName("Segment") + " : incompatible source"); + throw Error( "Can't create " + _TName("Segment") + ": incompatible source \n" + + " - Source:" + getString(source->getNet()) + "\n" + + " - Owner: " + getString(net) ); } if (target) { if (!target->getNet()) - throw Error("Can't create " + _TName("Segment") + " : unconnected target"); + throw Error("Can't create " + _TName("Segment") + ": unconnected target"); if (target->getNet() != net) - throw Error("Can't create " + _TName("Segment") + " : incompatible target"); + throw Error( "Can't create " + _TName("Segment") + ": incompatible target\n" + + " - Target:" + getString(target->getNet()) + "\n" + + " - Owner: " + getString(net) ); } if (!_layer) diff --git a/hurricane/src/hurricane/hurricane/DeepNet.h b/hurricane/src/hurricane/hurricane/DeepNet.h index 872bd5ce..209ddda0 100644 --- a/hurricane/src/hurricane/hurricane/DeepNet.h +++ b/hurricane/src/hurricane/hurricane/DeepNet.h @@ -60,6 +60,7 @@ namespace Hurricane { // Accessors. public: + inline Occurrence getRootNetOccurrence () const; // Predicates. public: @@ -71,6 +72,8 @@ namespace Hurricane { }; +inline Occurrence DeepNet::getRootNetOccurrence() const { return _netOccurrence; } + Net* getDeepNet(HyperNet& hyperNet); diff --git a/hurricane/src/isobar/PyHurricane.cpp b/hurricane/src/isobar/PyHurricane.cpp index 195587f5..eeea8380 100644 --- a/hurricane/src/isobar/PyHurricane.cpp +++ b/hurricane/src/isobar/PyHurricane.cpp @@ -750,8 +750,6 @@ extern "C" { PyModule_AddObject ( module, "TransistorLayer" , (PyObject*)&PyTypeTransistorLayer ); Py_INCREF ( &PyTypeViaLayer ); PyModule_AddObject ( module, "ViaLayer" , (PyObject*)&PyTypeViaLayer ); - Py_INCREF ( &PyTypeContactLayer ); - PyModule_AddObject ( module, "ContactLayer" , (PyObject*)&PyTypeContactLayer ); Py_INCREF ( &PyTypeNetExternalComponents ); PyModule_AddObject ( module, "NetExternalComponents", (PyObject*)&PyTypeNetExternalComponents ); Py_INCREF ( &PyTypeDebugSession ); @@ -770,7 +768,7 @@ extern "C" { Py_INCREF ( &PyTypeHookCollection ); PyModule_AddObject ( module, "HookCollection" , (PyObject*)&PyTypeHookCollection ); Py_INCREF ( &PyTypePlug ); - PyModule_AddObject ( module, "PyPlug" , (PyObject*)&PyTypePlug ); + PyModule_AddObject ( module, "Plug" , (PyObject*)&PyTypePlug ); Py_INCREF ( &PyTypeRoutingPad ); PyModule_AddObject ( module, "RoutingPad" , (PyObject*)&PyTypeRoutingPad ); Py_INCREF ( &PyTypeVertical ); diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 9205445f..fa85c54a 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -1953,8 +1953,8 @@ namespace Katabatic { } else { if (vertical->getWidth() != verticalWidth) { cerr << Warning("Segment %s has non-default width %s." - ,getString(horizontal).c_str() - ,DbU::getValueString(horizontal->getWidth()).c_str()) << endl; + ,getString(vertical).c_str() + ,DbU::getValueString(vertical->getWidth()).c_str()) << endl; } } diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index bc2ec0bc..d576794d 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -270,6 +270,7 @@ namespace { if (netType == Net::Type::CLOCK) { if (_ckoName.isEmpty()) { + cmess1 << " - Using <" << inet->getName() << "> as internal (core) clock net." << endl; _ckoName = inet->getName(); _cko = *inet; } else { @@ -282,7 +283,7 @@ namespace { } } - if ((_vddi) == NULL) cerr << Error("Missing net at top block level." ) << endl; + if (_vddi == NULL) cerr << Error("Missing net at top block level." ) << endl; else destroyRing( _vddi ); if (_vssi == NULL) cerr << Error("Missing net at top block level." ) << endl; else destroyRing( _vssi ); @@ -362,7 +363,7 @@ namespace { while ( true ) { //cerr << path << "+" << upNet << endl; - if ( (upNet == NULL) or not upNet->isExternal() ) return NULL; + if ( (upNet == NULL) or not upNet->isExternal() ) return _blockage; if ( path.isEmpty() ) break; instance = path.getTailInstance(); @@ -467,19 +468,21 @@ namespace { public: typedef map PlanesMap; public: - PowerRailsPlanes ( KiteEngine* ); - ~PowerRailsPlanes (); - inline Net* getRootNet ( Net*, Path ); - bool hasPlane ( const BasicLayer* ); - bool setActivePlane ( const BasicLayer* ); - inline Plane* getActivePlane () const; - void merge ( const Box&, Net* ); - void doLayout (); + PowerRailsPlanes ( KiteEngine* ); + ~PowerRailsPlanes (); + inline Net* getRootNet ( Net*, Path ); + bool hasPlane ( const BasicLayer* ); + bool setActivePlane ( const BasicLayer* ); + inline Plane* getActivePlane () const; + inline Plane* getActiveBlockagePlane () const; + void merge ( const Box&, Net* ); + void doLayout (); private: KiteEngine* _kite; GlobalNetTable _globalNets; PlanesMap _planes; Plane* _activePlane; + Plane* _activeBlockagePlane; }; @@ -496,12 +499,12 @@ namespace { << " " << ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical")<< endl; } - inline DbU::Unit PowerRailsPlanes::Rail::getAxis () const { return _axis; } - inline DbU::Unit PowerRailsPlanes::Rail::getWidth () const { return _width; } - inline PowerRailsPlanes::Rails* PowerRailsPlanes::Rail::getRails () const { return _rails; } - inline RoutingPlane* PowerRailsPlanes::Rail::getRoutingPlane () const { return _rails->getRoutingPlane(); } - inline unsigned int PowerRailsPlanes::Rail::getDirection () const { return _rails->getDirection(); } - inline Net* PowerRailsPlanes::Rail::getNet () const { return _rails->getNet(); } + inline DbU::Unit PowerRailsPlanes::Rail::getAxis () const { return _axis; } + inline DbU::Unit PowerRailsPlanes::Rail::getWidth () const { return _width; } + inline PowerRailsPlanes::Rails* PowerRailsPlanes::Rail::getRails () const { return _rails; } + inline RoutingPlane* PowerRailsPlanes::Rail::getRoutingPlane () const { return _rails->getRoutingPlane(); } + inline unsigned int PowerRailsPlanes::Rail::getDirection () const { return _rails->getDirection(); } + inline Net* PowerRailsPlanes::Rail::getNet () const { return _rails->getNet(); } void PowerRailsPlanes::Rail::merge ( DbU::Unit source, DbU::Unit target ) @@ -845,10 +848,11 @@ namespace { PowerRailsPlanes::PowerRailsPlanes ( KiteEngine* kite ) - : _kite (kite) - , _globalNets (kite) - , _planes () - , _activePlane(NULL) + : _kite (kite) + , _globalNets (kite) + , _planes () + , _activePlane (NULL) + , _activeBlockagePlane(NULL) { _globalNets.setBlockage( kite->getBlockageNet() ); @@ -899,9 +903,16 @@ namespace { bool PowerRailsPlanes::setActivePlane ( const BasicLayer* layer ) { PlanesMap::iterator iplane = _planes.find(layer); - if ( iplane == _planes.end() ) return false; + if (iplane == _planes.end()) return false; - _activePlane = iplane->second; + _activePlane = iplane->second; + _activeBlockagePlane = NULL; + if (layer->getMaterial() != BasicLayer::Material::blockage) { + BasicLayer* blockageLayer = layer->getBlockageLayer(); + PlanesMap::iterator ibplane = _planes.find(blockageLayer); + if (ibplane != _planes.end()) + _activeBlockagePlane = ibplane->second; + } return true; } @@ -910,17 +921,24 @@ namespace { { return _activePlane; } + inline PowerRailsPlanes::Plane* PowerRailsPlanes::getActiveBlockagePlane () const + { return _activeBlockagePlane; } + + void PowerRailsPlanes::merge ( const Box& bb, Net* net ) { - if ( not _activePlane ) return; + if (not _activePlane) return; - Net* topGlobalNet = _globalNets.getRootNet ( net, Path() ); - if ( topGlobalNet == NULL ) { + Net* topGlobalNet = _globalNets.getRootNet( net, Path() ); + if (topGlobalNet == NULL) { ltrace(300) << "Not a global net: " << net << endl; return; } - _activePlane->merge ( bb, topGlobalNet ); + if ( (topGlobalNet == _globalNets.getBlockage()) and (_activeBlockagePlane != NULL) ) + _activeBlockagePlane->merge( bb, topGlobalNet ); + else + _activePlane->merge( bb, topGlobalNet ); } @@ -1017,7 +1035,6 @@ namespace { cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " ..." << endl; Query::doQuery(); - } diff --git a/kite/src/BuildPreRouteds.cpp b/kite/src/BuildPreRouteds.cpp index 263ad77e..fde5a603 100644 --- a/kite/src/BuildPreRouteds.cpp +++ b/kite/src/BuildPreRouteds.cpp @@ -26,6 +26,7 @@ #include "hurricane/Vertical.h" #include "hurricane/RoutingPad.h" #include "hurricane/NetExternalComponents.h" +#include "hurricane/DeepNet.h" #include "hurricane/Instance.h" #include "hurricane/Plug.h" #include "hurricane/Path.h" @@ -62,6 +63,7 @@ namespace Kite { using Hurricane::Vertical; using Hurricane::RoutingPad; using Hurricane::NetExternalComponents; + using Hurricane::DeepNet; using Hurricane::Instance; using Hurricane::Plug; using Hurricane::Path; @@ -85,63 +87,93 @@ namespace Kite { void KiteEngine::buildPreRouteds () { + cmess1 << " o Looking for fixed or manually global routed nets." << endl; + forEach ( Net*, inet, getCell()->getNets() ) { if (*inet == _blockageNet) continue; if (inet->getType() == Net::Type::POWER ) continue; if (inet->getType() == Net::Type::GROUND) continue; - // Don't consider the clock. + // Don't skip the clock. vector segments; vector contacts; bool isPreRouted = false; - size_t rpCount = 0; - forEach ( Component*, icomponent, inet->getComponents() ) { - Horizontal* horizontal = dynamic_cast(*icomponent); - if (horizontal) { - segments.push_back( horizontal ); - isPreRouted = true; - } else { - Vertical* vertical = dynamic_cast(*icomponent); - if (vertical) { + bool isFixed = false; + size_t rpCount = 0; + + if (inet->isDeepNet()) { + rpCount = 2; + + Net* rootNet = dynamic_cast( + dynamic_cast(*inet)->getRootNetOccurrence().getEntity() ); + forEach ( Component*, icomponent, rootNet->getComponents() ) { + if (dynamic_cast(*icomponent)) { isFixed = true; break; } + if (dynamic_cast (*icomponent)) { isFixed = true; break; } + if (dynamic_cast (*icomponent)) { isFixed = true; break; } + } + } else { + forEach ( Component*, icomponent, inet->getComponents() ) { + Horizontal* horizontal = dynamic_cast(*icomponent); + if (horizontal) { + segments.push_back( horizontal ); isPreRouted = true; - segments.push_back( vertical ); + if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer())) + isFixed = true; } else { - Contact* contact = dynamic_cast(*icomponent); - if (contact) { + Vertical* vertical = dynamic_cast(*icomponent); + if (vertical) { isPreRouted = true; - contacts.push_back( contact ); + segments.push_back( vertical ); + if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer())) + isFixed = true; } else { - RoutingPad* rp = dynamic_cast(*icomponent); - if (rp) { - ++rpCount; + Contact* contact = dynamic_cast(*icomponent); + if (contact) { + isPreRouted = true; + contacts.push_back( contact ); + if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer())) + or (contact->getHeight() != Session::getViaWidth(contact->getLayer())) ) + isFixed = true; } else { - // Plug* plug = dynamic_cast(*icomponent); - // if (plug) { - // cerr << "buildPreRouteds(): " << plug << endl; - // ++rpCount; - // } + RoutingPad* rp = dynamic_cast(*icomponent); + if (rp) { + ++rpCount; + } else { + // Plug* plug = dynamic_cast(*icomponent); + // if (plug) { + // cerr << "buildPreRouteds(): " << plug << endl; + // ++rpCount; + // } + } } } } } } - if (isPreRouted or (rpCount < 2)) { + if (isFixed or isPreRouted or (rpCount < 2)) { NetRoutingState* state = getRoutingState( *inet, Katabatic::KbCreate ); - state->setFlags ( NetRoutingState::ManualGlobalRoute ); state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); + state->setFlags ( NetRoutingState::ManualGlobalRoute ); - if (rpCount > 1) { - for ( auto icontact : contacts ) { - AutoContact::createFrom( icontact ); - } - - for ( auto isegment : segments ) { - AutoContact* source = Session::base()->lookup( dynamic_cast( isegment->getSource() )); - AutoContact* target = Session::base()->lookup( dynamic_cast( isegment->getTarget() )); - AutoSegment* autoSegment = AutoSegment::create( source, target, isegment ); - autoSegment->setFlags( Katabatic::SegUserDefined|Katabatic::SegAxisSet ); + if (isFixed) { + cmess2 << " - <" << (*inet)->getName() << "> is fixed." << endl; + state->unsetFlags( NetRoutingState::ManualGlobalRoute ); + state->setFlags ( NetRoutingState::Fixed ); + } else { + if (rpCount > 1) { + cmess2 << " - <" << (*inet)->getName() << "> is manually global routed." << endl; + for ( auto icontact : contacts ) { + AutoContact::createFrom( icontact ); + } + + for ( auto isegment : segments ) { + AutoContact* source = Session::base()->lookup( dynamic_cast( isegment->getSource() )); + AutoContact* target = Session::base()->lookup( dynamic_cast( isegment->getTarget() )); + AutoSegment* autoSegment = AutoSegment::create( source, target, isegment ); + autoSegment->setFlags( Katabatic::SegUserDefined|Katabatic::SegAxisSet ); + } } } }