diff --git a/Seabreeze/src/CMakeLists.txt b/Seabreeze/src/CMakeLists.txt index e75357dc..e5f063bf 100644 --- a/Seabreeze/src/CMakeLists.txt +++ b/Seabreeze/src/CMakeLists.txt @@ -12,11 +12,17 @@ set( includes seabreeze/SeabreezeEngine.h #seabreeze/GraphicSeabreezeEngine.h ) - set( pyIncludes seabreeze/PySeabreezeEngine.h + set( pyIncludes seabreeze/Configuration.h + seabreeze/Delay.h + seabreeze/Node.h + seabreeze/Tree.h + seabreeze/Elmore.h + seabreeze/PySeabreezeEngine.h #seabreeze/PyGraphicSeabreezeEngine.h ) #set( mocIncludes seabreeze/GraphicSeabreezeEngine.h ) set( cpps Configuration.cpp + Delay.cpp Node.cpp Tree.cpp Elmore.cpp diff --git a/Seabreeze/src/Configuration.cpp b/Seabreeze/src/Configuration.cpp index 51165753..e8a63f78 100644 --- a/Seabreeze/src/Configuration.cpp +++ b/Seabreeze/src/Configuration.cpp @@ -15,6 +15,7 @@ #include +#include #include #include "hurricane/configuration/Configuration.h" #include "hurricane/Warning.h" @@ -33,6 +34,7 @@ namespace Seabreeze { using std::string; + using std::ostringstream; using Hurricane::Warning; using Hurricane::Error; using Hurricane::Technology; @@ -73,22 +75,28 @@ namespace Seabreeze { { return new Configuration( *this ); } -/* - Record* Configuration::_getRecord () const - { - - } + string Configuration::_getTypeName () const + { return "Seabreeze::Configuration"; } string Configuration::_getString () const { - + ostringstream os; + os << "<" << _getTypeName() << ">"; + return os.str(); } -*/ - string Configuration::_getTypeName () const - { return "Configuration"; } + Record* Configuration::_getRecord () const + { + Record* record = new Record ( _getString() ); + if (record != nullptr) { + record->add( getSlot("_Rct", _Rct) ); + record->add( getSlot("_Rsm", _Rsm) ); + record->add( getSlot("_Csm", _Csm) ); + } + return record; + } } // Seabreeze namespace. diff --git a/Seabreeze/src/Delay.cpp b/Seabreeze/src/Delay.cpp index 0394ad24..f3fab88f 100644 --- a/Seabreeze/src/Delay.cpp +++ b/Seabreeze/src/Delay.cpp @@ -14,38 +14,58 @@ // +-----------------------------------------------------------------+ -#pragma once #include #include #include "hurricane/RoutingPad.h" #include "seabreeze/Delay.h" +#include "seabreeze/Elmore.h" using namespace std; + namespace Seabreeze { using Hurricane::RoutingPad; + //--------------------------------------------------------- // Class : Seabreeze::Delay - Delay::Delay() - : _values() - {} + Delay::Delay ( Elmore* elmore, RoutingPad* sink ) + : _elmore(elmore) + , _sink (sink) + , _delay (0.0) + { } - Delay::~Delay() - {} - - void Delay::addPair ( RoutingPad* driver, RoutingPad* sink, double delay) - { - if ( _values.count(driver) > 0 ) { - cerr << "Driver already exist." << endl - << "If you want to add value, please use the function addValue( RoutingPad*, RoutingPad*, double)" << endl - << "Example : addValue(driver, sink, delay)" << endl; - } - else { - map val { {sink, delay}, }; - _values.insert(driver, val); - } + + Delay::~Delay () + { } + + + string Delay::_getTypeName () const + { return "Seabreeze::Delay"; } + + + string Delay::_getString () const + { + string s = "add( getSlot("_elmore" , _elmore) ); + record->add( getSlot("_sink" , _sink ) ); + record->add( getSlot("_delay" , _delay ) ); } -} + return record; + } + + +} // Seabreeze namespace. diff --git a/Seabreeze/src/Elmore.cpp b/Seabreeze/src/Elmore.cpp index 39a0495a..f5c32c9b 100644 --- a/Seabreeze/src/Elmore.cpp +++ b/Seabreeze/src/Elmore.cpp @@ -13,10 +13,11 @@ // | C++ Module : "./Elmore.cpp" | // +-----------------------------------------------------------------+ -#include "hurricane/Net.h" -#include "hurricane/Segment.h" #include "hurricane/DebugSession.h" #include "hurricane/Error.h" +#include "hurricane/Segment.h" +#include "hurricane/Plug.h" +#include "hurricane/Net.h" #include "seabreeze/Elmore.h" #include "seabreeze/Node.h" #include "seabreeze/SeabreezeEngine.h" @@ -27,6 +28,7 @@ namespace Seabreeze { using Hurricane::Error; using Hurricane::DBo; using Hurricane::DbU; + using Hurricane::Plug; using Hurricane::Net; using Hurricane::Cell; using Hurricane::Instance; @@ -42,9 +44,10 @@ namespace Seabreeze { Elmore::Elmore ( Net* net ) : _seabreeze(nullptr) - , _contacts () - , _checker () - , _tree (new Tree()) + , _net (net) + , _driver (nullptr) + , _tree (new Tree(this)) + , _delays () {} @@ -52,6 +55,44 @@ namespace Seabreeze { { cdebug_log(199,0) << "Elmore::~Elmore() " << endl; delete _tree; + for ( Delay* delay : _delays ) delete delay; + } + + + void Elmore::setup () + { + cdebug_log(199,1) << "Elmore::findDriver()" << endl; + + for ( RoutingPad* rp : _net->getRoutingPads() ) { + Plug* plug = static_cast( rp->getPlugOccurrence().getEntity() ); + if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) { + if (_driver) { + cerr << Error( "Elmore::setup(): %s has more than one driver:\n" + " * Using: %s\n" + " * Ignoring: %s" + , getString(_net).c_str() + , getString(_driver).c_str() + , getString(rp).c_str() + ) << endl; + continue; + } + _driver = rp; + } else { + _delays.push_back( new Delay(this,rp) ); + } + } + cdebug_log(199,0) << "Found " << _delays.size() << " sink points:" << endl; + for ( Delay* delay : _delays ) { + cdebug_log(199,0) << "| " << delay << endl; + } + if (not _driver) { + cerr << Error( "Elmore::_postCreate(): No driver found on %s, aborting." + , getString(_net).c_str() ) << endl; + cdebug_tabw(199,-1); + return; + } + + cdebug_tabw(199,-1); } @@ -59,27 +100,24 @@ namespace Seabreeze { { return _seabreeze->getConfiguration(); } - void Elmore::contFromNet ( Net* net ) + Delay* Elmore::getDelay ( RoutingPad* rp ) const { - for ( RoutingPad* rp : net->getRoutingPads() ) { - for ( Component* component : rp->getSlaveComponents() ) { - Contact* contact = dynamic_cast( component ); - if (not contact) continue; - _contacts.insert( contact ); - } + for ( Delay* delay : _delays ) { + if (delay->getSink() == rp) return delay; } + return nullptr; } - void Elmore::buildTree ( RoutingPad* rp ) + void Elmore::buildTree () { - if (not rp) { - cerr << Error( "Elmore::buildTree(): NULL RoutingPad, aborting." ) << endl; + if (not _driver) { + cerr << Error( "Elmore::buildTree(): Net has no driver, aborting." ) << endl; return; } Contact* rootContact = nullptr; - for ( Component* component : rp->getSlaveComponents() ) { + for ( Component* component : _driver->getSlaveComponents() ) { Contact* contact = dynamic_cast(component); if (contact) { rootContact = contact; @@ -88,14 +126,13 @@ namespace Seabreeze { } if (not rootContact) { cerr << Error( "Elmore::buildTree(): No Contact anchored on %s." - , getString(rp).c_str() ) << endl; + , getString(_driver).c_str() ) << endl; return; } cdebug_log(199,1) << "Elmore::buildTree()" << endl; cdebug_log(199,0) << "Root contact " << rootContact << endl; - _checker.insert( rootContact ); Node* rootNode = new Node( nullptr, rootContact ); double R = 0; double C = 0; @@ -183,7 +220,7 @@ namespace Seabreeze { } cdebug_log(199,0) << "target=" << target << endl; - if (not _checker.count(target)) { + if (not _tree->isReached(target)) { buildFromNode( node, segment); } } @@ -198,7 +235,7 @@ namespace Seabreeze { cdebug_log(199,0) << "current=" << current << endl; while ( true ) { - _checker.insert( current ); + _tree->setReached( current ); int count = 0; Segment* segment = nullptr; for ( Component* component : current->getSlaveComponents() ) { @@ -206,7 +243,7 @@ namespace Seabreeze { if (not segment) continue; Contact* opposite = dynamic_cast( segment->getOppositeAnchor(current) ); - if (opposite and (_checker.count(opposite)) != 0) { + if (opposite and _tree->isReached(opposite)) { setRC( R, C, current, segment ); cdebug_log(199,0) << "current=" << current << endl; cdebug_log(199,0) << "segment=" << segment << endl; @@ -235,7 +272,7 @@ namespace Seabreeze { Contact* opposite = dynamic_cast( segment->getOppositeAnchor(current) ); cdebug_log(199,0) << "opposite=" << opposite << endl; - if (opposite and (_checker.count(opposite) == 0)) + if (opposite and not _tree->isReached(opposite)) next = opposite; } @@ -280,24 +317,17 @@ namespace Seabreeze { *C += (Aseg) ? 1/(Cseg*Aseg) : 0.0; } } - - - void Elmore::clearTree () - { - _tree->clear(); - _checker.clear(); - } - double Elmore::delayElmore ( RoutingPad* rp ) + Delay* Elmore::delayElmore ( RoutingPad* rp ) { return _tree->computeElmoreDelay( rp ); } - void Elmore::toTree ( ostream& os ) const + void Elmore::toTree ( ostream& os ) const { _tree->print( os ); } - string Elmore::_getTypeName () const + string Elmore::_getTypeName () const { return "Seabreeze::Elmore"; } @@ -313,9 +343,10 @@ namespace Seabreeze { Record* record = new Record ( _getString() ); if (record != nullptr) { record->add( getSlot("_seabreeze", _seabreeze) ); - record->add( getSlot("_contacts" , &_contacts) ); - record->add( getSlot("_checker" , &_checker ) ); + record->add( getSlot("_net" , _net ) ); + record->add( getSlot("_driver" , _driver ) ); record->add( getSlot("_tree" , _tree ) ); + record->add( getSlot("_delays" , &_delays ) ); } return record; } @@ -339,6 +370,7 @@ namespace Seabreeze { , getString(net->getCell()).c_str()) << endl; } _elmore.setSeabreeze( seabreeze ); + _elmore.setup(); } cdebug_log(199,0) << "ElmoreProperty::ElmoreProperty() on " << net << endl; } diff --git a/Seabreeze/src/SeabreezeEngine.cpp b/Seabreeze/src/SeabreezeEngine.cpp index acd34470..c6bfaa94 100644 --- a/Seabreeze/src/SeabreezeEngine.cpp +++ b/Seabreeze/src/SeabreezeEngine.cpp @@ -36,6 +36,7 @@ #include "seabreeze/SeabreezeEngine.h" #include "seabreeze/Elmore.h" + namespace Seabreeze { using namespace std; @@ -117,41 +118,15 @@ namespace Seabreeze { cdebug_log(199,1) << "SeabreezeEngine::buildElmore()" << endl; cdebug_log(199,0) << "Run on " << net << endl; - RoutingPad* driver = nullptr; - for ( RoutingPad* rp : net->getRoutingPads() ) { - Plug* p = static_cast( rp->getPlugOccurrence().getEntity() ); - if (p->getMasterNet()->getDirection() & Net::Direction::DirOut) { - driver = rp; - break; - } - } - Elmore* elmore = ElmoreExtension::create( net ); - elmore->contFromNet( net ); - - cdebug_log(199,0) << "Found " << elmore->getContacts().size() << " RoutingPads:" << endl; - for ( Contact* contact : elmore->getContacts() ) { - cdebug_log(199,0) << "| " << contact << endl; - } - - elmore->buildTree( driver ); + elmore->buildTree(); + cerr << "Net has " << elmore->getDelays().size() << " sink(s)." << endl; for ( RoutingPad* rp : net->getRoutingPads() ) { Plug* plug = static_cast( rp->getPlugOccurrence().getEntity() ); if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) { continue; } - cdebug_log(199,0) << "| Elmore's delay: " << elmore->delayElmore(rp) << " " << rp << endl; - - Contact* ct = nullptr; - for ( Component* comp : rp->getSlaveComponents() ) { - Contact* cont = dynamic_cast(comp); - if (cont) { - ct = cont; - break; - } - } - cerr << "| Elmore's delay: " << elmore->delayElmore(rp) << " " << ct << endl; - + cerr << "| Elmore's delay: " << elmore->delayElmore(rp) << endl; } cdebug_tabw(199,-1); DebugSession::close(); diff --git a/Seabreeze/src/Tree.cpp b/Seabreeze/src/Tree.cpp index 6277e55d..26fd85f1 100644 --- a/Seabreeze/src/Tree.cpp +++ b/Seabreeze/src/Tree.cpp @@ -19,8 +19,11 @@ #include #include "hurricane/Error.h" #include "hurricane/RoutingPad.h" +#include "hurricane/Net.h" +#include "seabreeze/Elmore.h" #include "seabreeze/Tree.h" #include "seabreeze/Node.h" +#include "seabreeze/Delay.h" namespace Seabreeze { @@ -35,8 +38,10 @@ namespace Seabreeze { using Hurricane::Component; - Tree::Tree () - : _nodes() + Tree::Tree ( Elmore* elmore ) + : _elmore (elmore) + , _nodes () + , _reacheds() {} @@ -55,14 +60,12 @@ namespace Seabreeze { } - void Tree::newNode () - { _nodes.push_back( new Node() ); } - - void Tree::addNode ( Node* node ) { - if (find(_nodes.begin(), _nodes.end(), node) == _nodes.end()) + if (find(_nodes.begin(), _nodes.end(), node) == _nodes.end()) { + setReached( node->contact() ); _nodes.push_back( node ); + } } @@ -91,11 +94,17 @@ namespace Seabreeze { } - double Tree::computeElmoreDelay ( RoutingPad* rp ) + Delay* Tree::computeElmoreDelay ( RoutingPad* rp ) { if (not rp) { cerr << Error( "Tree::computeDelay(): Sink RoutingPad argument is NULL." ) << endl; - return -1.0; + return nullptr; + } + Delay* delay = _elmore->getDelay( rp ); + if (not delay) { + cerr << Error( "Tree::computeDelay(): No delay for %s, aborting." + , getString(rp).c_str() ) << endl; + return nullptr; } Contact* sink = nullptr; @@ -111,7 +120,7 @@ namespace Seabreeze { " (on %s)" , getString(rp).c_str() ) << endl; - return -1.0; + return nullptr; } cdebug_log(199,1) << "Tree::computeDelay()" << endl; @@ -139,9 +148,9 @@ namespace Seabreeze { } } // Compute Elmore delay time - double delay = 0.0; + delay->setDelay( 0.0 ); for ( size_t k = 0; k < _nodes.size(); k++ ) { - delay += (_nodes[k]->Rt()) * (_nodes[k]->C()); + delay->incDelay( (_nodes[k]->Rt()) * (_nodes[k]->C()) ); } return delay; @@ -166,12 +175,6 @@ namespace Seabreeze { } - void Tree::clear () - { - _nodes.clear(); - } - - string Tree::_getTypeName () const { return "Seabreeze::Tree"; } @@ -187,7 +190,8 @@ namespace Seabreeze { { Record* record = new Record ( _getString() ); if (record != nullptr) { - record->add( getSlot("_nodes", &_nodes) ); + record->add( getSlot("_nodes" , &_nodes ) ); + record->add( getSlot("_reacheds", &_reacheds) ); } return record; } diff --git a/Seabreeze/src/seabreeze/Configuration.h b/Seabreeze/src/seabreeze/Configuration.h index ab7788b5..b2439387 100644 --- a/Seabreeze/src/seabreeze/Configuration.h +++ b/Seabreeze/src/seabreeze/Configuration.h @@ -41,9 +41,9 @@ namespace Seabreeze { inline double getRct () const; inline double getRsm () const; inline double getCsm () const; - //virtual Record* _getRecord () const; - //virtual string _getString () const; - virtual string _getTypeName () const; + string _getTypeName () const; + string _getString () const; + Record* _getRecord () const; protected : // Attributes double _Rct; @@ -60,3 +60,5 @@ namespace Seabreeze { } // Seabreeze namespace. + +INSPECTOR_P_SUPPORT(Seabreeze::Configuration); diff --git a/Seabreeze/src/seabreeze/Delay.h b/Seabreeze/src/seabreeze/Delay.h index 6439a9e8..79e999ae 100644 --- a/Seabreeze/src/seabreeze/Delay.h +++ b/Seabreeze/src/seabreeze/Delay.h @@ -22,8 +22,10 @@ namespace Seabreeze { + using Hurricane::Record; using Hurricane::DBo; using Hurricane::RoutingPad; + class Elmore; //--------------------------------------------------------- @@ -31,28 +33,31 @@ namespace Seabreeze { class Delay { public: - typedef std::map< RoutingPad* - , std::map< RoutingPad*, double, DBo::CompareById > - , DBo::CompareById> DelayMap; - public: - Delay (); - ~Delay (); - inline const DelayMap& getValues () const ; - void addPair ( RoutingPad*, RoutingPad*, double ); - void addValue ( RoutingPad*, RoutingPad*, double ); - void printDelays (); - Record* _getRecord () const; - std::string _getString () const; - std::string _getTypeName () const; + Delay ( Elmore*, RoutingPad* ); + ~Delay (); + inline Elmore* getElmore () const; + inline RoutingPad* getSink () const; + inline double getDelay () const; + inline void setDelay ( double ); + inline void incDelay ( double ); + std::string _getTypeName () const; + std::string _getString () const; + Record* _getRecord () const; private: - DelayMap _values; + Elmore* _elmore; + RoutingPad* _sink; + double _delay; }; - - - inline const Delay::DelayMap& Delay::getValues () const { return _values; } + inline Elmore* Delay::getElmore () const { return _elmore; } + inline RoutingPad* Delay::getSink () const { return _sink; } + inline double Delay::getDelay () const { return _delay; } + inline void Delay::setDelay ( double delay ) { _delay = delay; } + inline void Delay::incDelay ( double delay ) { _delay += delay; } + + } // Seabreeze namespace. diff --git a/Seabreeze/src/seabreeze/Elmore.h b/Seabreeze/src/seabreeze/Elmore.h index 4168d015..1b8dcd50 100644 --- a/Seabreeze/src/seabreeze/Elmore.h +++ b/Seabreeze/src/seabreeze/Elmore.h @@ -22,6 +22,7 @@ #include "hurricane/Segment.h" #include "Configuration.h" #include "Tree.h" +#include "Delay.h" namespace Hurricane { class Net; @@ -40,45 +41,52 @@ namespace Seabreeze { using Hurricane::Segment; using Hurricane::PrivateProperty; class SeabreezeEngine; + class ElmoreProperty; //---------------------------------------------------------- // Class : Seabreeze::Elmore class Elmore { - public: - typedef std::set ContactSet; + friend class ElmoreProperty; public: Elmore ( Net* ); ~Elmore (); inline SeabreezeEngine* getSeabreeze () const; const Configuration* getConfiguration () const; - void contFromNet ( Net* ); - void buildTree ( RoutingPad* ); + inline Net* getNet () const; + inline RoutingPad* getDriver () const; + Delay* getDelay ( RoutingPad* ) const; + inline const std::vector& + getDelays () const; + void buildTree (); void buildFromNode ( Node* source, Segment* ); Contact* buildBranch ( double* R, double* C, Contact* contact ); void setRC ( double* R, double* C, Contact* , Segment* ); - void clearTree (); inline Tree* getTree (); - inline const ContactSet& getContacts () const; - double delayElmore ( RoutingPad* ); + void setup (); + Delay* delayElmore ( RoutingPad* ); void toTree ( std::ostream& ) const; inline void setSeabreeze ( SeabreezeEngine* ); - virtual Record* _getRecord () const; - virtual std::string _getString () const; - virtual std::string _getTypeName () const; + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; private: - SeabreezeEngine* _seabreeze; - ContactSet _contacts; - ContactSet _checker; - Tree* _tree; + private: + SeabreezeEngine* _seabreeze; + Net* _net; + RoutingPad* _driver; + Tree* _tree; + std::vector _delays; }; - inline SeabreezeEngine* Elmore::getSeabreeze () const { return _seabreeze; } - inline const Elmore::ContactSet& Elmore::getContacts () const { return _contacts; } - inline Tree* Elmore::getTree () { return _tree; } - inline void Elmore::setSeabreeze ( SeabreezeEngine* seabreeze ) { _seabreeze = seabreeze; } + inline SeabreezeEngine* Elmore::getSeabreeze () const { return _seabreeze; } + inline Net* Elmore::getNet () const { return _net; } + inline RoutingPad* Elmore::getDriver () const { return _driver; } + inline Tree* Elmore::getTree () { return _tree; } + inline void Elmore::setSeabreeze ( SeabreezeEngine* seabreeze ) { _seabreeze = seabreeze; } + inline const std::vector& Elmore::getDelays () const { return _delays; } //--------------------------------------------------------- diff --git a/Seabreeze/src/seabreeze/Tree.h b/Seabreeze/src/seabreeze/Tree.h index df62946d..9b79be57 100644 --- a/Seabreeze/src/seabreeze/Tree.h +++ b/Seabreeze/src/seabreeze/Tree.h @@ -18,18 +18,18 @@ #include #include #include -namespace Hurricane { - class Contact; - class RoutingPad; -} +#include "hurricane/RoutingPad.h" namespace Seabreeze { using Hurricane::Record; + using Hurricane::DBo; using Hurricane::Contact; using Hurricane::RoutingPad; class Node; + class Delay; + class Elmore; //--------------------------------------------------------- @@ -37,30 +37,39 @@ namespace Seabreeze { class Tree { public: - Tree (); + typedef std::set ContactSet; + public: + Tree ( Elmore* ); ~Tree (); + inline bool isReached ( Contact* ) const; + inline Elmore* getElmore () const; inline size_t getN (); Node* getNode ( Contact* ); inline const std::vector& getNodeList () const; - void newNode (); + inline void setReached ( Contact* ); void addNode ( Node* ); void markNodeAfter ( Node* ); void getBranch ( Contact* ); - double computeElmoreDelay ( RoutingPad* ); + Delay* computeElmoreDelay ( RoutingPad* ); void printNode ( std::ostream& , Node* , size_t depth ); void print ( std::ostream& ); - void clear (); Record* _getRecord () const; std::string _getString () const; std::string _getTypeName () const; - private: + private: + Elmore* _elmore; std::vector _nodes; + ContactSet _reacheds; }; + inline Elmore* Tree::getElmore () const { return _elmore; } inline size_t Tree::getN () { return _nodes.size(); } inline const std::vector& Tree::getNodeList () const { return _nodes; } + inline void Tree::setReached ( Contact* contact ) { _reacheds.insert( contact ); } + inline bool Tree::isReached ( Contact* contact ) const { return _reacheds.count( contact ); } + } // Seabreeze namespace.