// -*- C++ -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x // | | // | C O R I O L I S | // | K i t e - D e t a i l e d R o u t e r | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./QueryBlockages.cpp" | // | *************************************************************** | // | U p d a t e s | // | | // x-----------------------------------------------------------------x #include #include #include "hurricane/DataBase.h" #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" #include "hurricane/RegularLayer.h" #include "hurricane/Query.h" #include "kite/RoutingPlane.h" #include "kite/TrackBlockage.h" #include "kite/Track.h" #include "kite/KiteEngine.h" namespace { using namespace std; using Hurricane::tab; using Hurricane::inltrace; using Hurricane::DbU; using Hurricane::Box; using Hurricane::Interval; using Hurricane::Query; using Hurricane::Go; using Hurricane::Rubber; using Hurricane::Layer; using Hurricane::BasicLayer; using Hurricane::RegularLayer; using Hurricane::Transformation; using namespace Kite; // ------------------------------------------------------------------- // Class : "::BlockagesPlanes". class BlockagesPlanes { private: class Track { public: Track ( Kite::Track* ); void add ( Interval ); inline DbU::Unit getAxis () const; void dump ( DbU::Unit width ); private: Kite::Track* _ktrack; list _blockages; }; private: class Plane { public: Plane ( RoutingPlane* ); ~Plane (); void merge ( Box boundingBox ); inline unsigned int getDirection () const; inline const Layer* getLayer () const; inline DbU::Unit getHalfWireWidth () const; inline DbU::Unit getPitch () const; void dump (); private: RoutingPlane* _routingPlane; Interval _axisSpan; vector _tracks; }; public: static Track* createTrack ( Kite::Track* ); public: BlockagesPlanes ( KiteEngine* ); ~BlockagesPlanes (); bool hasPlane ( const BasicLayer* ); bool setActivePlane ( const BasicLayer* ); inline Plane* getActivePlane () const; void add ( Box boundingBox ); void dump (); private: KiteEngine* _kite; map _planes; Plane* _activePlane; }; BlockagesPlanes::Track::Track ( Kite::Track* ktrack ) : _ktrack(ktrack) , _blockages() { } inline DbU::Unit BlockagesPlanes::Track::getAxis () const { return _ktrack->getAxis(); } void BlockagesPlanes::Track::add ( Interval obstacle ) { if ( (obstacle.getVMax() <= _ktrack->getMin()) or (obstacle.getVMin() >= _ktrack->getMax()) ) return; list::iterator imerge = _blockages.end(); list::iterator iblockage = _blockages.begin(); while ( iblockage != _blockages.end() ) { if ( obstacle.getVMax() < (*iblockage).getVMin() ) break; if ( obstacle.intersect(*iblockage) ) { if ( imerge == _blockages.end() ) { imerge = iblockage; (*imerge).merge ( obstacle ); } else { (*imerge).merge ( *iblockage ); iblockage = _blockages.erase ( iblockage ); continue; } } iblockage++; } if ( imerge == _blockages.end() ) { _blockages.insert ( iblockage, obstacle ); ltrace(190) << "| Add on " << DbU::getValueString(_ktrack->getAxis()) << " " << obstacle << endl; } } void BlockagesPlanes::Track::dump ( DbU::Unit width ) { list::iterator iinterval = _blockages.begin(); if ( _ktrack->getDirection() == Constant::Horizontal ) { DbU::Unit ymin = _ktrack->getAxis() - width/2; DbU::Unit ymax = _ktrack->getAxis() + width/2; for ( ; iinterval != _blockages.end() ; iinterval++ ) { Box bb ( (*iinterval).getVMin(), ymin, (*iinterval).getVMax(), ymax ); TrackBlockage::create ( _ktrack, bb ); } } else { DbU::Unit xmin = _ktrack->getAxis() - width/2; DbU::Unit xmax = _ktrack->getAxis() + width/2; for ( ; iinterval != _blockages.end() ; iinterval++ ) { Box bb ( xmin, (*iinterval).getVMin(), xmax, (*iinterval).getVMax() ); TrackBlockage::create ( _ktrack, bb ); } } } BlockagesPlanes::Plane::Plane ( RoutingPlane* plane ) : _routingPlane(plane) , _axisSpan (plane->getAxisMin(),plane->getAxisMax()) , _tracks () { Kite::Track* ktrack = plane->getTrackByIndex(0); for ( ; ktrack != NULL ; ktrack=ktrack->getNext() ) { _tracks.push_back ( BlockagesPlanes::createTrack(ktrack) ); } } BlockagesPlanes::Plane::~Plane () { for ( size_t i=0 ; i<_tracks.size() ; i++ ) delete _tracks[i]; } inline unsigned int BlockagesPlanes::Plane::getDirection () const { return _routingPlane->getDirection(); } inline const Layer* BlockagesPlanes::Plane::getLayer () const { return _routingPlane->getLayer(); } inline DbU::Unit BlockagesPlanes::Plane::getHalfWireWidth () const { return _routingPlane->getLayerGauge()->getHalfWireWidth(); } inline DbU::Unit BlockagesPlanes::Plane::getPitch () const { return _routingPlane->getLayerGauge()->getPitch(); } void BlockagesPlanes::Plane::merge ( Box boundingBox ) { ltrace(190) << "| Add on plane " << _routingPlane->getLayer() << " " << boundingBox << endl; DbU::Unit delta = getPitch() - getHalfWireWidth() - 1; if ( getDirection() == Constant::Horizontal ) { boundingBox.inflate ( 0, delta, 0, delta ); ltrace(190) << "Track range: " << DbU::getValueString(boundingBox.getYMin()) << ":" << DbU::getValueString(boundingBox.getYMax()) << endl; for ( size_t i=0 ; (i<_tracks.size()) and (_tracks[i]->getAxis() < boundingBox.getYMax()) ; i++ ) { if ( _tracks[i]->getAxis() < boundingBox.getYMin() ) continue; _tracks[i]->add ( Interval(boundingBox.getXMin(),boundingBox.getXMax()) ); } } else { boundingBox.inflate ( delta, 0, delta, 0 ); for ( size_t i=0 ; (i<_tracks.size()) and (_tracks[i]->getAxis() < boundingBox.getXMax()) ; i++ ) { if ( _tracks[i]->getAxis() < boundingBox.getXMin() ) continue; _tracks[i]->add ( Interval(boundingBox.getYMin(),boundingBox.getYMax()) ); } } } void BlockagesPlanes::Plane::dump () { for ( size_t i=0 ; i<_tracks.size() ; i++ ) _tracks[i]->dump(DbU::lambda(2.0)); } BlockagesPlanes::Track* BlockagesPlanes::createTrack ( Kite::Track* ktrack ) { return new Track ( ktrack ); } BlockagesPlanes::BlockagesPlanes ( KiteEngine* kite ) : _kite (kite) , _planes () , _activePlane(NULL) { RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge(); size_t gaugeDepth = rg->getDepth (); for ( size_t depth=0 ; depth(rg->getRoutingLayer(depth)); if ( not routingLayer ) continue; const BasicLayer* blockageLayer = routingLayer->getBasicLayer()->getBlockageLayer(); if ( not blockageLayer ) continue; _planes.insert ( make_pair(blockageLayer,new Plane(_kite->getRoutingPlaneByIndex(depth))) ); } } BlockagesPlanes::~BlockagesPlanes () { while ( not _planes.empty() ) { delete _planes.begin()->second; _planes.erase ( _planes.begin() ); } } bool BlockagesPlanes::hasPlane ( const BasicLayer* basicLayer ) { return (_planes.find(basicLayer) != _planes.end()); } bool BlockagesPlanes::setActivePlane ( const BasicLayer* basicLayer ) { map::iterator iplane = _planes.find(basicLayer); if ( iplane == _planes.end() ) return false; _activePlane = iplane->second; return true; } inline BlockagesPlanes::Plane* BlockagesPlanes::getActivePlane () const { return _activePlane; } void BlockagesPlanes::add ( Box boundingBox ) { if ( not _activePlane ) return; _activePlane->merge ( boundingBox ); } void BlockagesPlanes::dump () { map::iterator iplane = _planes.begin(); for ( ; iplane != _planes.end() ; iplane++ ) { iplane->second->dump(); } } // ------------------------------------------------------------------- // Class : "::QueryBlockages". class QueryBlockages : public Query { public: QueryBlockages ( KiteEngine* ); virtual bool hasGoCallback () const; virtual void setBasicLayer ( const BasicLayer* ); virtual void goCallback ( Go* ); virtual void rubberCallback ( Rubber* ); virtual void extensionGoCallback ( Go* ); virtual void masterCellCallback (); void addBlockage ( const Go* go , const BasicLayer* basicLayer , const Box& area , const Transformation& transformation ); virtual void doQuery (); inline void dump (); inline unsigned int getBlockagesCount () const; private: KiteEngine* _kite; BlockagesPlanes _blockagesPlanes; unsigned int _blockagesCount; }; QueryBlockages::QueryBlockages ( KiteEngine* kite ) : Query () , _kite (kite) , _blockagesPlanes(kite) , _blockagesCount (0) { setCell ( kite->getCell() ); setArea ( kite->getCell()->getBoundingBox() ); setBasicLayer ( NULL ); setFilter ( Query::DoTerminalCells|Query::DoComponents ); } inline unsigned int QueryBlockages::getBlockagesCount () const { return _blockagesCount; } inline void QueryBlockages::dump () { return _blockagesPlanes.dump(); } void QueryBlockages::setBasicLayer ( const BasicLayer* basicLayer ) { _blockagesPlanes.setActivePlane ( basicLayer ); Query::setBasicLayer ( basicLayer ); } void QueryBlockages::doQuery () { if ( not _blockagesPlanes.getActivePlane() ) return; Query::doQuery (); } void QueryBlockages::masterCellCallback () { } bool QueryBlockages::hasGoCallback () const { return true; } void QueryBlockages::goCallback ( Go* go ) { addBlockage ( go, getBasicLayer(), getArea(), getTransformation() ); } void QueryBlockages::addBlockage ( const Go* go , const BasicLayer* basicLayer , const Box& area , const Transformation& transformation ) { const Component* component = dynamic_cast(go); if ( component ) { _blockagesCount++; Box bb ( transformation.getBox(component->getBoundingBox(basicLayer)) ); ltrace(190) << "Blockage: " << bb << " in " << basicLayer->getName() << endl; _blockagesPlanes.add ( bb ); } } void QueryBlockages::rubberCallback ( Rubber* ) { } void QueryBlockages::extensionGoCallback ( Go* ) { } } // End of anonymous namespace. namespace Kite { using Hurricane::DataBase; using Hurricane::Technology; using Hurricane::BasicLayer; using Hurricane::ForEachIterator; void KiteEngine::buildBlockages () { cmess1 << " o Building blockages." << endl; if ( not _obstacleNet ) { _obstacleNet = getCell()->getNet("obstaclenet"); if ( not _obstacleNet ) _obstacleNet = Net::create ( getCell(), "obstaclenet" ); } QueryBlockages query ( this ); Technology* technology = DataBase::getDB()->getTechnology(); forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) { if ( iLayer->getMaterial() != BasicLayer::Material::blockage ) continue; cmess1 << " - Blockages in " << iLayer->getName() << " ..." << endl; query.setBasicLayer ( *iLayer ); query.doQuery (); } query.dump (); cmess1 << " - " << query.getBlockagesCount() << " blockages found." << endl; Session::revalidate (); } } // End of Kite namespace.