From 1f4d6b7e830cde96f4052752753291a1a3785ada Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 30 May 2016 11:30:29 +0200 Subject: [PATCH] Anabatic transient commit 4. * New: In Anabatic: - A Dijkstra skeleton, not debugged yet. --- anabatic/src/AnabaticEngine.cpp | 4 +- anabatic/src/CMakeLists.txt | 5 +- anabatic/src/Configuration.cpp | 22 +- anabatic/src/Dijkstra.cpp | 238 +++++++++++++++++++ anabatic/src/Edge.cpp | 13 +- anabatic/src/Edges.cpp | 117 +++++++++ anabatic/src/GCell.cpp | 20 ++ anabatic/src/GraphicAnabaticEngine.cpp | 22 +- anabatic/src/anabatic/AnabaticEngine.h | 28 ++- anabatic/src/anabatic/Configuration.h | 80 ++++--- anabatic/src/anabatic/Dijkstra.h | 191 +++++++++++++++ anabatic/src/anabatic/Edge.h | 4 + anabatic/src/anabatic/Edges.h | 108 +++++++++ anabatic/src/anabatic/GCell.h | 73 ++++-- hurricane/src/hurricane/hurricane/Observer.h | 4 +- 15 files changed, 849 insertions(+), 80 deletions(-) create mode 100644 anabatic/src/Dijkstra.cpp create mode 100644 anabatic/src/Edges.cpp create mode 100644 anabatic/src/anabatic/Dijkstra.h create mode 100644 anabatic/src/anabatic/Edges.h diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index fa25e8cf..86f9cd22 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -64,8 +64,10 @@ namespace Anabatic { , _gcells () , _viewer (NULL) , _flags (Flags::NoFlags) + , _stamp (-1) { - _matrix.setCell( cell, _configuration->getSliceHeight()*2 ); + _matrix.setCell( cell, _configuration->getSliceHeight() ); + Edge::unity = _configuration->getSliceHeight(); } diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index 20163a25..e666a39a 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -15,10 +15,11 @@ endif ( CHECK_DETERMINISM ) set( includes anabatic/Constants.h anabatic/Configuration.h anabatic/Matrix.h - anabatic/Edge.h + anabatic/Edge.h anabatic/Edges.h anabatic/GCell.h #anabatic/GCells.h anabatic/AnabaticEngine.h anabatic/GraphicAnabaticEngine.h + anabatic/Dijkstra.h ) set( mocIncludes anabatic/GraphicAnabaticEngine.h ) set( pyIncludes anabatic/PyAnabaticEngine.h @@ -28,9 +29,11 @@ endif ( CHECK_DETERMINISM ) Configuration.cpp Matrix.cpp Edge.cpp + Edges.cpp GCell.cpp AnabaticEngine.cpp GraphicAnabaticEngine.cpp + Dijkstra.cpp ) set( pyCpps PyAnabaticEngine.cpp PyGraphicAnabaticEngine.cpp diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 79997b7b..705ac959 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -113,13 +113,13 @@ namespace Anabatic { ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other ) : Configuration() - , _gmetalh (other._gmetalh) - , _gmetalv (other._gmetalv) - , _gcontact (other._gcontact) - , _cg (NULL) - , _rg (NULL) - , _extensionCaps (other._extensionCaps) - , _allowedDepth (other._allowedDepth) + , _gmetalh (other._gmetalh) + , _gmetalv (other._gmetalv) + , _gcontact (other._gcontact) + , _cg (NULL) + , _rg (NULL) + , _extensionCaps(other._extensionCaps) + , _allowedDepth (other._allowedDepth) { if (other._cg) _cg = other._cg->getClone(); if (other._rg) _rg = other._rg->getClone(); @@ -145,6 +145,14 @@ namespace Anabatic { bool ConfigurationConcrete::isGContact ( const Layer* layer ) const { return (layer and (layer == _gcontact)); } + const Layer* ConfigurationConcrete::getGContactLayer () const + { return _gcontact; } + + const Layer* ConfigurationConcrete::getGHorizontalLayer () const + { return _gmetalh; } + + const Layer* ConfigurationConcrete::getGVerticalLayer () const + { return _gmetalv; } size_t ConfigurationConcrete::getDepth () const { return _rg->getDepth(); } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp new file mode 100644 index 00000000..0aa4056c --- /dev/null +++ b/anabatic/src/Dijkstra.cpp @@ -0,0 +1,238 @@ +// -*- mode: C++; explicit-buffer-name: "Dijkstra.cpp" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./anabatic/Dijkstra.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/Error.h" +#include "hurricane/Net.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/UpdateSession.h" +#include "anabatic/AnabaticEngine.h" +#include "anabatic/Dijkstra.h" + + +namespace Anabatic { + + using std::cerr; + using std::endl; + using std::numeric_limits; + using Hurricane::Error; + using Hurricane::Component; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Hurricane::UpdateSession; + + +// ------------------------------------------------------------------- +// Class : "Anabatic::Vertex". + + + float Vertex::unreached = numeric_limits::max(); + + + bool Vertex::hasValidStamp () const + { return _stamp == getAnabatic()->getStamp(); } + + +// ------------------------------------------------------------------- +// Class : "Anabatic::Dijkstra". + + + Dijkstra::Dijkstra ( AnabaticEngine* anabatic ) + : _anabatic (anabatic) + , _vertexes () + , _net (NULL) + , _stamp (-1) + , _sources () + , _targets () + , _searchArea () + , _connectedsId(-1) + , _queue () + { + const vector& gcells = _anabatic->getGCells(); + for ( GCell* gcell : gcells ) { + _vertexes.push_back( new Vertex (gcell) ); + } + } + + + Dijkstra::~Dijkstra () + { + for ( Vertex* vertex : _vertexes ) delete vertex; + } + + + void Dijkstra::load ( Net* net ) + { + UpdateSession::open(); + + _searchArea.makeEmpty(); + _stamp = _anabatic->incStamp(); + + for ( Component* component : net->getRoutingPads() ) { + RoutingPad* rp = dynamic_cast( component ); + if (rp) { + Box rpBb = rp->getBoundingBox(); + Point center = rpBb.getCenter(); + GCell* gcell = _anabatic->getGCellUnder( center ); + + if (not gcell) { + cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n" + " It will be ignored ans the routing will be incomplete." + , getString(rp ).c_str() + , getString(net).c_str() + ) << endl; + continue; + } + + _searchArea.merge( rpBb ); + + Vertex* vertex = gcell->lookup(); + if (vertex->getConnexId() < 0) { + vertex->setStamp ( _stamp ); + vertex->setConnexId( _targets.size() ); + vertex->getGContact( _net ); + _targets.insert( vertex ); + } + } + } + + UpdateSession::close(); + } + + + void Dijkstra::selectFirstSource () + { + if (_targets.empty()) { + cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored.\n" + , getString(_net).c_str() + ) << endl; + return; + } + Point areaCenter = _searchArea.getCenter(); + auto ivertex = _targets.begin(); + Vertex* firstSource = *ivertex++; + DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() ); + + for ( ; ivertex != _targets.end() ; ++ivertex ) { + DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() ); + if (distance < minDistance) { + minDistance = distance; + firstSource = *ivertex; + } + } + + _targets.erase( firstSource ); + } + + + void Dijkstra::propagate () + { + while ( not _queue.empty() ) { + Vertex* current = _queue.top(); + _queue.pop(); + + if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) { + for ( Edge* edge : current->getGCell()->getEdges() ) { + if (edge == current->getFrom()) continue; + + GCell* gneighbor = edge->getOpposite(current->getGCell()); + Vertex* vneighbor = gneighbor->lookup(); + + if (vneighbor->getConnexId() == _connectedsId) continue; + + float distance = current->getDistance() + edge->getDistance(); + if (distance < current->getDistance()) { + if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor ); + else vneighbor->setStamp( _stamp ); + + vneighbor->setDistance( distance ); + _queue.push( vneighbor ); + } + } + } + + // We did reach another target (different ). + // Tag back the path. + _targets.erase( current ); + while ( current ) { + _sources.insert( current ); + current->setDistance( 0.0 ); + current->setConnexId( _connectedsId ); + current = current->getPredecessor(); + } + + break; + } + } + + + void Dijkstra::run () + { + if (_sources.empty()) return; + + UpdateSession::open(); + + _queue.clear(); + _queue.push( *_sources.begin() ); + _connectedsId = (*_sources.begin())->getConnexId(); + + while ( not _targets.empty() ) propagate(); + + toWires(); + + UpdateSession::close(); + } + + + void Dijkstra::toWires () + { + for ( Vertex* vertex : _sources ) { + Edge* from = vertex->getFrom(); + if (not from) continue; + + Vertex* source = vertex; + Vertex* target = source->getPredecessor(); + + if ( (source->getGCell()->getXMin() > target->getGCell()->getXMin()) + or (source->getGCell()->getYMin() > target->getGCell()->getYMin()) ) + std::swap( source, target ); + + Contact* sourceContact = source->getGContact( _net ); + Contact* targetContact = source->getGContact( _net ); + + if (from->isHorizontal()) { + Horizontal::create( sourceContact + , targetContact + , _anabatic->getConfiguration()->getGHorizontalLayer() + , from->getAxis() + , DbU::fromLambda(2.0) + ); + } else { + Vertical::create( sourceContact + , targetContact + , _anabatic->getConfiguration()->getGVerticalLayer() + , from->getAxis() + , DbU::fromLambda(2.0) + ); + } + } + } + + +} // Anabatic namespace. diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index 421d25e4..d162fe36 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -28,7 +28,8 @@ namespace Anabatic { using Hurricane::Error; - Name Edge::_extensionName = "Anabatic::Edge"; + Name Edge::_extensionName = "Anabatic::Edge"; + DbU::Unit Edge::unity = 1; Edge::Edge ( GCell* source, GCell* target, Flags flags ) @@ -155,6 +156,16 @@ namespace Anabatic { } + float Edge::getDistance () const + { + Point sourceCenter = getSource()->getBoundingBox().getCenter(); + Point targetCenter = getTarget()->getBoundingBox().getCenter(); + + return ( (targetCenter.getX() - sourceCenter.getX()) + + (targetCenter.getY() - sourceCenter.getY()) ) / unity; + } + + void Edge::_setSource ( GCell* source ) { if (source == _target) diff --git a/anabatic/src/Edges.cpp b/anabatic/src/Edges.cpp new file mode 100644 index 00000000..1c2c7bef --- /dev/null +++ b/anabatic/src/Edges.cpp @@ -0,0 +1,117 @@ +// -*- mode: C++; explicit-buffer-name: "Edges.cpp" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./anabatic/Edges.cpp" | +// +-----------------------------------------------------------------+ + + +#include "anabatic/Edges.h" +#include "anabatic/GCell.h" + + +namespace Anabatic { + + using std::endl; + + +// ------------------------------------------------------------------- +// Class : "Anabatic::GCell_Edges". + + GCell_Edges::Locator::Locator ( const GCell* gcell ) + : EdgesHL() + , _gcell(gcell) + , _flags(Flags::EastSide) + , _iedge(0) + { + if (_gcell->getEastEdges().empty()) progress(); + } + + + EdgesHL* GCell_Edges::Locator::getClone () const + { return new Locator (*this); } + + + Edge* GCell_Edges::Locator::getElement () const + { + if (_flags & Flags::EastSide ) return _gcell->getEastEdges ()[_iedge]; + if (_flags & Flags::NorthSide) return _gcell->getNorthEdges()[_iedge]; + if (_flags & Flags::WestSide ) return _gcell->getWestEdges ()[_iedge]; + if (_flags & Flags::SouthSide) return _gcell->getSouthEdges()[_iedge]; + return NULL; + } + + + bool GCell_Edges::Locator::isValid () const + { return not _flags; } + + + void GCell_Edges::Locator::progress () + { + cdebug.log(110) << "GCell_Edges::Locator::progress()" << endl; + + ++_iedge; + while (_flags) { + if (_flags & Flags::EastSide) { + if (_iedge < _gcell->getEastEdges().size()) break; + _flags = Flags::NorthSide; + _iedge = 0; + } + if (_flags & Flags::NorthSide) { + if (_iedge < _gcell->getNorthEdges().size()) break; + _flags = Flags::WestSide; + _iedge = 0; + } + if (_flags & Flags::WestSide) { + if (_iedge < _gcell->getWestEdges().size()) break; + _flags = Flags::SouthSide; + _iedge = 0; + } + if (_flags & Flags::SouthSide) { + if (_iedge < _gcell->getSouthEdges().size()) break; + _flags = 0; + _iedge = 0; + } + } + } + + + string GCell_Edges::Locator::_getString () const + { + string s = ""; + return s; + } + + +} // Anabatic namespace. diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index ebe70e36..57e3a365 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -15,6 +15,7 @@ #include +#include "hurricane/Contact.h" #include "anabatic/GCell.h" #include "anabatic/AnabaticEngine.h" @@ -39,6 +40,8 @@ namespace Anabatic { , _northEdges() , _xmin (xmin) , _ymin (ymin) + , _contacts () + , _lookup (NULL) { } @@ -506,6 +509,23 @@ namespace Anabatic { } + Contact* GCell::getGContact ( Net* net ) + { + for ( Contact* contact : _contacts ) { + if (contact->getNet() == net) return contact; + } + + Point center = getBoundingBox().getCenter(); + return Contact::create( net + , _anabatic->getConfiguration()->getGContactLayer() + , center.getX() + , center.getY() + , DbU::fromLambda(2.0) + , DbU::fromLambda(2.0) + ); + } + + const Name& GCell::getName () const { return _extensionName; } diff --git a/anabatic/src/GraphicAnabaticEngine.cpp b/anabatic/src/GraphicAnabaticEngine.cpp index 34e8bb8e..404c34e5 100644 --- a/anabatic/src/GraphicAnabaticEngine.cpp +++ b/anabatic/src/GraphicAnabaticEngine.cpp @@ -35,6 +35,7 @@ #include #include "anabatic/GCell.h" #include "anabatic/GraphicAnabaticEngine.h" +#include "anabatic/Dijkstra.h" namespace Anabatic { @@ -123,6 +124,24 @@ namespace Anabatic { } + void anabaticTest_4 ( AnabaticEngine* engine ) + { + Cell* cell = engine->getCell(); + cell->flattenNets( Cell::Flags::BuildRings ); + cell->createRoutingPadRings( Cell::Flags::BuildRings ); + + engine->getSouthWestGCell()->doGrid(); + + Net* net = cell->getNet( "ialu.inv_x2_3_sig" ); + if (net) { + Dijkstra* dijkstra = new Dijkstra ( engine ); + dijkstra->load( net ); + dijkstra->run(); + delete dijkstra; + } + } + + // ------------------------------------------------------------------- // Class : "Anabatic::GraphicAnabaticEngine". @@ -254,7 +273,8 @@ namespace Anabatic { //anabaticTest_1( engine ); //anabaticTest_2( engine ); - anabaticTest_3( engine ); + //anabaticTest_3( engine ); + anabaticTest_4( engine ); if (_viewer) _viewer->emitCellChanged(); } diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index b492169f..af3f2f42 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -56,10 +56,15 @@ namespace Anabatic { virtual Configuration* getConfiguration (); inline CellViewer* getViewer () const; inline void setViewer ( CellViewer* ); + inline const vector& getGCells () const; inline GCell* getSouthWestGCell () const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; inline GCell* getGCellUnder ( Point ) const; int getCapacity ( Interval, Flags ) const; + // Dijkstra related functions. + inline int getStamp () const; + inline int incStamp (); + // Misc. functions. inline const Flags& flags () const; inline Flags& flags (); void reset (); @@ -87,18 +92,20 @@ namespace Anabatic { vector _gcells; CellViewer* _viewer; Flags _flags; + int _stamp; }; - inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } - inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } - inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } - inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } - inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } - inline const Flags& AnabaticEngine::flags () const { return _flags; } - inline Flags& AnabaticEngine::flags () { return _flags; } - inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } - inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::Destroy; } + inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } + inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline const vector& AnabaticEngine::getGCells () const { return _gcells; } + inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } + inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } + inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } + inline const Flags& AnabaticEngine::flags () const { return _flags; } + inline Flags& AnabaticEngine::flags () { return _flags; } + inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } + inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::Destroy; } inline void AnabaticEngine::_add ( GCell* gcell ) { @@ -116,6 +123,9 @@ namespace Anabatic { } } + inline int AnabaticEngine::getStamp () const { return _stamp; } + inline int AnabaticEngine::incStamp () { return ++_stamp; } + } // Anabatic namespace. diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 62fb0e47..fcd88581 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -55,43 +55,46 @@ namespace Anabatic { class Configuration { public: // Constructor & Destructor. - virtual ~Configuration (); - virtual Configuration* clone () const = 0; - // Methods. - virtual bool isGMetal ( const Layer* ) const = 0; - virtual bool isGContact ( const Layer* ) const = 0; - virtual size_t getDepth () const = 0; - virtual size_t getAllowedDepth () const = 0; - virtual size_t getLayerDepth ( const Layer* ) const = 0; - virtual CellGauge* getCellGauge () const = 0; - virtual RoutingGauge* getRoutingGauge () const = 0; - virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const = 0; - virtual const Layer* getRoutingLayer ( size_t depth ) const = 0; - virtual Layer* getContactLayer ( size_t depth ) const = 0; - virtual DbU::Unit getSliceHeight () const = 0; - virtual DbU::Unit getSliceStep () const = 0; - virtual DbU::Unit getPitch ( size_t depth, Flags flags ) const = 0; - virtual DbU::Unit getOffset ( size_t depth ) const = 0; - virtual DbU::Unit getWireWidth ( size_t depth ) const = 0; - virtual DbU::Unit getExtensionCap ( size_t depth ) const = 0; - virtual Flags getDirection ( size_t depth ) const = 0; - virtual DbU::Unit getPitch ( const Layer*, Flags flags ) const = 0; - virtual DbU::Unit getOffset ( const Layer* ) const = 0; - virtual DbU::Unit getWireWidth ( const Layer* ) const = 0; - virtual DbU::Unit getExtensionCap ( const Layer* ) const = 0; - virtual Flags getDirection ( const Layer* ) const = 0; - virtual void setAllowedDepth ( size_t ) = 0; - virtual DbU::Unit getEdgeLength () const = 0; - virtual DbU::Unit getEdgeWidth () const = 0; - virtual void print ( Cell* ) const = 0; - virtual Record* _getRecord () const = 0; - virtual string _getString () const = 0; - virtual string _getTypeName () const = 0; - protected: - Configuration (); - private: - Configuration ( const Configuration& ); - Configuration& operator= ( const Configuration& ); + virtual ~Configuration (); + virtual Configuration* clone () const = 0; + // Methods. + virtual bool isGMetal ( const Layer* ) const = 0; + virtual bool isGContact ( const Layer* ) const = 0; + virtual const Layer* getGContactLayer () const = 0; + virtual const Layer* getGHorizontalLayer () const = 0; + virtual const Layer* getGVerticalLayer () const = 0; + virtual size_t getDepth () const = 0; + virtual size_t getAllowedDepth () const = 0; + virtual size_t getLayerDepth ( const Layer* ) const = 0; + virtual CellGauge* getCellGauge () const = 0; + virtual RoutingGauge* getRoutingGauge () const = 0; + virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const = 0; + virtual const Layer* getRoutingLayer ( size_t depth ) const = 0; + virtual Layer* getContactLayer ( size_t depth ) const = 0; + virtual DbU::Unit getSliceHeight () const = 0; + virtual DbU::Unit getSliceStep () const = 0; + virtual DbU::Unit getPitch ( size_t depth, Flags flags ) const = 0; + virtual DbU::Unit getOffset ( size_t depth ) const = 0; + virtual DbU::Unit getWireWidth ( size_t depth ) const = 0; + virtual DbU::Unit getExtensionCap ( size_t depth ) const = 0; + virtual Flags getDirection ( size_t depth ) const = 0; + virtual DbU::Unit getPitch ( const Layer*, Flags flags ) const = 0; + virtual DbU::Unit getOffset ( const Layer* ) const = 0; + virtual DbU::Unit getWireWidth ( const Layer* ) const = 0; + virtual DbU::Unit getExtensionCap ( const Layer* ) const = 0; + virtual Flags getDirection ( const Layer* ) const = 0; + virtual void setAllowedDepth ( size_t ) = 0; + virtual DbU::Unit getEdgeLength () const = 0; + virtual DbU::Unit getEdgeWidth () const = 0; + virtual void print ( Cell* ) const = 0; + virtual Record* _getRecord () const = 0; + virtual string _getString () const = 0; + virtual string _getTypeName () const = 0; + protected: + Configuration (); + private: + Configuration ( const Configuration& ); + Configuration& operator= ( const Configuration& ); private: static Configuration* _default; }; @@ -110,6 +113,9 @@ namespace Anabatic { // Methods. virtual bool isGMetal ( const Layer* ) const; virtual bool isGContact ( const Layer* ) const; + virtual const Layer* getGContactLayer () const; + virtual const Layer* getGHorizontalLayer () const; + virtual const Layer* getGVerticalLayer () const; virtual size_t getDepth () const; virtual size_t getAllowedDepth () const; virtual size_t getLayerDepth ( const Layer* ) const; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h new file mode 100644 index 00000000..8c435e11 --- /dev/null +++ b/anabatic/src/anabatic/Dijkstra.h @@ -0,0 +1,191 @@ +// -*- mode: C++; explicit-buffer-name: "Dijkstra.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/Dijkstra.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ANABATIC_DIJKSTRA_H +#define ANABATIC_DIJKSTRA_H + +#include +namespace Hurricane { + class Net; +} +#include "anabatic/GCell.h" + + +namespace Anabatic { + + using std::set; + using Hurricane::Net; + class AnabaticEngine; + + +// ------------------------------------------------------------------- +// Class : "Anabatic::Vertex". + + class Vertex { + public: + class CompareById { + public: + inline bool operator() ( const Vertex* lhs, const Vertex* rhs ); + }; + public: + static float unreached; + public: + inline Vertex ( GCell* ); + inline Vertex ( size_t id ); + inline ~Vertex (); + inline unsigned int getId () const; + inline GCell* getGCell () const; + inline AnabaticEngine* getAnabatic () const; + inline Contact* getGContact ( Net* ); + bool hasValidStamp () const; + inline Point getCenter () const; + inline float getDistance () const; + inline int getStamp () const; + inline int getConnexId () const; + inline Edge* getFrom () const; + inline Vertex* getPredecessor () const; + inline void setDistance ( float ); + inline void setStamp ( int ); + inline void setConnexId ( int ); + inline void setFrom ( Edge* ); + private: + Vertex ( const Vertex& ); + Vertex& operator= ( const Vertex& ); + private: + size_t _id; + GCell* _gcell; + int _connexId; + int _stamp; + float _distance; + Edge* _from; + }; + + + inline Vertex::Vertex ( GCell* gcell ) + : _id (gcell->getId()) + , _gcell (gcell) + , _connexId(-1) + , _stamp (-1) + , _distance(unreached) + , _from (NULL) + { + gcell->setLookup( this ); + } + + inline Vertex::Vertex ( size_t id ) + : _id (id) + , _gcell (NULL) + , _connexId(-1) + , _stamp (-1) + , _distance(unreached) + , _from (NULL) + { } + + inline Vertex::~Vertex () { } + inline unsigned int Vertex::getId () const { return _id; } + inline GCell* Vertex::getGCell () const { return _gcell; } + inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } + inline Contact* Vertex::getGContact ( Net* net ) { return _gcell->getGContact(net); } + inline Point Vertex::getCenter () const { return _gcell->getBoundingBox().getCenter(); } + inline float Vertex::getDistance () const { return hasValidStamp() ? _distance : unreached; } + inline int Vertex::getStamp () const { return _stamp; } + inline int Vertex::getConnexId () const { return hasValidStamp() ? _connexId : -1; } + inline Edge* Vertex::getFrom () const { return _from; } + inline void Vertex::setDistance ( float distance ) { _distance=distance; } + inline void Vertex::setFrom ( Edge* from ) { _from=from; } + inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } + inline void Vertex::setConnexId ( int id ) { _connexId=id; } + + inline Vertex* Vertex::getPredecessor () const + { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->lookup() : NULL; } + + inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) + { return lhs->getId() < rhs->getId(); } + + typedef set VertexSet; + + +// ------------------------------------------------------------------- +// Class : "Anabatic::PriorityQueue". + + class PriorityQueue { + public: + inline PriorityQueue (); + inline ~PriorityQueue (); + inline bool empty () const; + inline size_t size () const; + inline void push ( Vertex* ); + inline void erase ( Vertex* ); + inline Vertex* top (); + inline void pop (); + inline void clear (); + private: + class CompareByDistance { + public: + inline bool operator() ( const Vertex* lhs, const Vertex* rhs ); + }; + private: + set _queue; + }; + + + inline bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs ) + { return lhs->getDistance() < rhs->getDistance(); } + + + inline PriorityQueue::PriorityQueue () : _queue() { } + inline PriorityQueue::~PriorityQueue () { } + inline bool PriorityQueue::empty () const { return _queue.empty(); } + inline size_t PriorityQueue::size () const { return _queue.size(); } + inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); } + inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); } + inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); } + inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); } + inline void PriorityQueue::clear () { _queue.clear(); } + + +// ------------------------------------------------------------------- +// Class : "Anabatic::Dijkstra". + + class Dijkstra { + public: + Dijkstra ( AnabaticEngine* ); + ~Dijkstra (); + public: + void load ( Net* ); + void run (); + void propagate (); + void selectFirstSource (); + void toWires (); + private: + Dijkstra ( const Dijkstra& ); + Dijkstra& operator= ( const Dijkstra& ); + private: + AnabaticEngine* _anabatic; + vector _vertexes; + Net* _net; + int _stamp; + VertexSet _sources; + VertexSet _targets; + Box _searchArea; + int _connectedsId; + PriorityQueue _queue; + }; + + +} // Anabatic namespace. + +#endif // ANABATIC_DIJKSTRA_H diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index e16a3958..ba3c55f8 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -23,6 +23,7 @@ #include "hurricane/Box.h" #include "hurricane/ExtensionGo.h" #include "anabatic/Constants.h" +#include "anabatic/Edges.h" namespace Anabatic { @@ -43,6 +44,8 @@ namespace Anabatic { class Edge : public ExtensionGo { public: typedef ExtensionGo Super; + public: + static DbU::Unit unity; public: static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags ); virtual void destroy (); @@ -52,6 +55,7 @@ namespace Anabatic { inline unsigned int getCapacity () const; inline unsigned int getRealOccupancy () const; inline unsigned int getEstimateOccupancy () const; + float getDistance () const; inline GCell* getSource () const; inline GCell* getTarget () const; GCell* getOpposite ( const GCell* ) const; diff --git a/anabatic/src/anabatic/Edges.h b/anabatic/src/anabatic/Edges.h new file mode 100644 index 00000000..9f7e48ac --- /dev/null +++ b/anabatic/src/anabatic/Edges.h @@ -0,0 +1,108 @@ +// -*- mode: C++; explicit-buffer-name: "Edges.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/Edges.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ANABATIC_EDGES_H +#define ANABATIC_EDGES_H + +#include +#include +#include "hurricane/Collection.h" +#include "anabatic/Constants.h" + + +namespace Anabatic { + + using std::string; + using std::vector; + using Hurricane::Record; + using Hurricane::Filter; + using Hurricane::Locator; + using Hurricane::Collection; + using Hurricane::GenericFilter; + using Hurricane::GenericLocator; + using Hurricane::GenericCollection; + class Edge; + class GCell; + + +// ------------------------------------------------------------------- +// Collections. + + typedef Hurricane::Filter EdgesHF; + typedef Hurricane::Locator EdgesHL; + typedef Hurricane::Collection EdgesHC; + typedef GenericCollection Edges; + typedef GenericLocator EdgesLocator; + typedef GenericFilter EdgesFilter; + class GCell; + + +// ------------------------------------------------------------------- +// Class : "GCell_Edges". + + class GCell_Edges : public EdgesHC { + public: + // Sub-Class: Locator. + class Locator : public EdgesHL { + public: + Locator ( const GCell* gcell ); + inline Locator ( const Locator& ); + virtual Edge* getElement () const; + virtual EdgesHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + const GCell* _gcell; + Flags _flags; + size_t _iedge; + }; + + // GCell_Edges. + public: + inline GCell_Edges ( const GCell* gcell ); + inline GCell_Edges ( const GCell_Edges& ); + virtual EdgesHC* getClone () const; + virtual EdgesHL* getLocator () const; + virtual string _getString () const; + protected: + const GCell* _gcell; + }; + + + inline GCell_Edges::Locator::Locator ( const Locator &locator ) + : EdgesHL() + , _gcell(locator._gcell) + , _flags(locator._flags) + , _iedge(locator._iedge) + { } + + + inline GCell_Edges::GCell_Edges ( const GCell* gcell ) + : EdgesHC() + , _gcell(gcell) + { } + + + inline GCell_Edges::GCell_Edges ( const GCell_Edges& edges ) + : EdgesHC() + , _gcell(edges._gcell) + { } + + +} // Anabatic namespace. + +#endif // ANABATIC_EDGES_H diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index 5b2955cd..e977723d 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -24,6 +24,9 @@ #include "hurricane/Box.h" #include "hurricane/Cell.h" #include "hurricane/ExtensionGo.h" +namespace Hurricane { + class Contact; +} #include "anabatic/Edge.h" @@ -37,7 +40,9 @@ namespace Anabatic { using Hurricane::Point; using Hurricane::Interval; using Hurricane::Box; + using Hurricane::Net; using Hurricane::Entity; + using Hurricane::Contact; using Hurricane::Cell; class AnabaticEngine; @@ -64,6 +69,11 @@ namespace Anabatic { inline DbU::Unit getYMax ( int shrink=0 ) const; inline Interval getSide ( Flags direction ) const; inline Point getCenter () const; + inline const vector& getWestEdges () const; + inline const vector& getEastEdges () const; + inline const vector& getNorthEdges () const; + inline const vector& getSouthEdges () const; + inline Edges getEdges () const; inline GCell* getWest () const; inline GCell* getEast () const; inline GCell* getSouth () const; @@ -73,9 +83,16 @@ namespace Anabatic { GCell* getSouth ( DbU::Unit x ) const; GCell* getNorth ( DbU::Unit x ) const; GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const; + inline GCell* getUnder ( Point p ) const; GCell* hcut ( DbU::Unit y ); GCell* vcut ( DbU::Unit x ); bool doGrid (); + Contact* getGContact ( Net* ); + template + inline void setLookup ( Type* decorator ); + template + inline Type* lookup () const; + // Misc. functions. inline const Flags& flags () const; inline Flags& flags (); void _add ( Edge* edge, Flags side ); @@ -105,30 +122,38 @@ namespace Anabatic { GCell ( const GCell& ); GCell& operator= ( const GCell& ); private: - static Name _extensionName; - AnabaticEngine* _anabatic; - Flags _flags; - vector _westEdges; - vector _eastEdges; - vector _southEdges; - vector _northEdges; - DbU::Unit _xmin; - DbU::Unit _ymin; + static Name _extensionName; + AnabaticEngine* _anabatic; + Flags _flags; + vector _westEdges; + vector _eastEdges; + vector _southEdges; + vector _northEdges; + DbU::Unit _xmin; + DbU::Unit _ymin; + vector _contacts; + void* _lookup; }; - inline bool GCell::isHFlat () const { return getYMin() == getYMax(); } - inline bool GCell::isVFlat () const { return getXMin() == getXMax(); } - inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); } - inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; } - inline DbU::Unit GCell::getXMin () const { return _xmin; } - inline DbU::Unit GCell::getYMin () const { return _ymin; } - inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); } - inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); } - inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); } - inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); } - inline const Flags& GCell::flags () const { return _flags; } - inline Flags& GCell::flags () { return _flags; } + inline bool GCell::isHFlat () const { return getYMin() == getYMax(); } + inline bool GCell::isVFlat () const { return getXMin() == getXMax(); } + inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); } + inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; } + inline DbU::Unit GCell::getXMin () const { return _xmin; } + inline DbU::Unit GCell::getYMin () const { return _ymin; } + inline Edges GCell::getEdges () const { return new GCell_Edges(this); } + inline const vector& GCell::getWestEdges () const { return _westEdges; } + inline const vector& GCell::getEastEdges () const { return _eastEdges; } + inline const vector& GCell::getNorthEdges () const { return _northEdges; } + inline const vector& GCell::getSouthEdges () const { return _southEdges; } + inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); } + inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); } + inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); } + inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); } + inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); } + inline const Flags& GCell::flags () const { return _flags; } + inline Flags& GCell::flags () { return _flags; } inline DbU::Unit GCell::getXMax ( int shrink ) const { return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink @@ -147,6 +172,12 @@ namespace Anabatic { return Interval( getXMin(), getXMax() ); } + template + inline void GCell::setLookup ( Type* decorator ) { _lookup=reinterpret_cast(decorator); } + + template + inline Type* GCell::lookup () const { return reinterpret_cast( _lookup ); } + // ------------------------------------------------------------------- // Class : "GCellSet". diff --git a/hurricane/src/hurricane/hurricane/Observer.h b/hurricane/src/hurricane/hurricane/Observer.h index 86190807..ae0693a8 100644 --- a/hurricane/src/hurricane/hurricane/Observer.h +++ b/hurricane/src/hurricane/hurricane/Observer.h @@ -98,8 +98,8 @@ namespace Hurricane { inline void Observable::notify ( unsigned int flags ) { - for ( auto iobserver : _observers ) { - iobserver->notify( flags ); + for ( BaseObserver* iobserver : _observers ) { + if (iobserver) iobserver->notify( flags ); } }