diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 23b55d33..3e0dc106 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -198,7 +198,6 @@ namespace Anabatic { AnabaticEngine::AnabaticEngine ( Cell* cell ) : Super(cell) - , _timer () , _configuration (new Configuration()) , _chipTools (cell) , _state (EngineCreation) @@ -947,45 +946,6 @@ namespace Anabatic { } - void AnabaticEngine::startMeasures () - { - _timer.resetIncrease(); - _timer.start(); - } - - - void AnabaticEngine::stopMeasures () - { _timer.stop(); } - - - void AnabaticEngine::suspendMeasures () - { _timer.suspend(); } - - - void AnabaticEngine::resumeMeasures () - { _timer.resume(); } - - - void AnabaticEngine::printMeasures ( const string& tag ) const - { - ostringstream result; - - result << Timer::getStringTime(_timer.getCombTime()) - << ", " << Timer::getStringMemory(_timer.getIncrease()); - cmess1 << Dots::asString( " - Done in", result.str() ) << endl; - - result.str(""); - result << _timer.getCombTime() - << "s, +" << (_timer.getIncrease()>>10) << "Kb/" - << Timer::getStringMemory(Timer::getMemorySize()); - cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl; - - // result.str(""); - // result << Timer::getStringMemory(Timer::getMemorySize()); - // cmess1 << Dots::asString( " - Total memory", result.str() ) << endl; - } - - void AnabaticEngine::updateDensity () { for ( GCell* gcell : _gcells ) gcell->updateDensity(); } @@ -1116,6 +1076,17 @@ namespace Anabatic { } + void AnabaticEngine::printMeasures ( const string& tag ) const + { + Super::printMeasures(); + + // if (not tag.empty()) { + // addMeasure( getCell(), tag+"T", getTimer().getCombTime () ); + // addMeasure( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) ); + // } + } + + string AnabaticEngine::_getTypeName () const { return getString(_toolName); } diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 448a6d0e..376a194b 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -121,6 +121,13 @@ namespace Anabatic { { } + bool AutoContactTerminal::isEndPoint () const + { + RoutingPad* rp = dynamic_cast( getAnchor() ); + return (rp->getBodyHook()->getSlaveHooks().getSize() == 1); + } + + AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const { return NULL; } @@ -141,6 +148,14 @@ namespace Anabatic { } + RoutingPad* AutoContactTerminal::getRoutingPad () const + { return dynamic_cast(getAnchor()); } + + + AutoSegments AutoContactTerminal::getRpConnecteds () const + { return AutoSegments_OnRoutingPad(this); } + + Box AutoContactTerminal::getNativeConstraintBox () const { cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl; diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 4fa9114a..be78df56 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -635,6 +635,13 @@ namespace Anabatic { } + AutoSegments AutoSegment::getConnecteds ( unsigned int flags ) + { + cdebug_log(145,0) << "AutoSegment::getConnecteds() - flags:" << flags << endl; + return AutoSegments_Connecteds( this, flags ); + } + + AutoSegments AutoSegment::getPerpandiculars () { return AutoSegments_Perpandiculars( this ); } diff --git a/anabatic/src/AutoSegments.cpp b/anabatic/src/AutoSegments.cpp index 358b4e29..f2739655 100644 --- a/anabatic/src/AutoSegments.cpp +++ b/anabatic/src/AutoSegments.cpp @@ -15,7 +15,8 @@ #include "hurricane/Error.h" -#include "anabatic/AutoContact.h" +#include "hurricane/RoutingPad.h" +#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoSegment.h" @@ -27,7 +28,7 @@ namespace Anabatic { using Hurricane::Error; using Hurricane::ForEachIterator; using Hurricane::Hook; - using Hurricane::Contact; + using Hurricane::RoutingPad; // ------------------------------------------------------------------- @@ -111,6 +112,183 @@ namespace Anabatic { } +// ------------------------------------------------------------------- +// Class : "Anabatic::AutoSegments_OnRoutingPad". + + AutoSegments_OnRoutingPad::Locator::Locator ( RoutingPad* rp, const AutoContactTerminal* contact ) + : AutoSegmentHL() + , _elements ({NULL,NULL,NULL,NULL}) + , _index (0) + { + if (rp) { + for ( Component* component : rp->getSlaveComponents() ) { + AutoSegment* segment = Session::lookup( dynamic_cast(component) ); + if (not segment) continue; + + size_t offset = 2; + if (contact and (contact->getSegment() == segment)) offset = 0; + + if (segment->isHorizontal()) _elements[offset ] = segment; + else _elements[offset+1] = segment; + } + } + + while ( (_index < 4) and not _elements[_index] ) ++_index; + } + + + AutoSegmentHL* AutoSegments_OnRoutingPad::Locator::getClone () const + { return new Locator(*this); } + + + AutoSegment* AutoSegments_OnRoutingPad::Locator::getElement () const + { return (_index < 4) ? _elements[_index] : NULL; } + + + bool AutoSegments_OnRoutingPad::Locator::isValid () const + { return (_index < 4); } + + + void AutoSegments_OnRoutingPad::Locator::progress () + { + cdebug_log(145,0) << "AutoSegments_OnRoutingPad::Locator::progress()" << endl; + ++_index; + while ( (_index < 4) and not _elements[_index] ) ++_index; + } + + + string AutoSegments_OnRoutingPad::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_OnRoutingPad::Locator") + + getString(_index) + + ">"; + return s; + } + + + AutoSegments_OnRoutingPad::AutoSegments_OnRoutingPad ( const AutoContact* contact ) + : AutoSegmentHC() + , _routingPad(NULL) + , _contact (dynamic_cast(contact)) + { + if (_contact) + _routingPad = dynamic_cast(_contact->getAnchor()); + } + + + AutoSegmentHC* AutoSegments_OnRoutingPad::getClone () const + { return new AutoSegments_OnRoutingPad(*this); } + + + AutoSegmentHL* AutoSegments_OnRoutingPad::getLocator () const + { return new Locator(_routingPad,_contact); } + + + string AutoSegments_OnRoutingPad::_getString () const + { + string s = "<" + _TName("AutoSegments_OnRoutingPad") + " " + + getString(_routingPad) + + ">"; + return s; + } + + +// ------------------------------------------------------------------- +// Class : "AutoSegments_Connecteds". + + AutoSegments_Connecteds::Locator::Locator ( AutoSegment* segment, unsigned int flags ) + : AutoSegmentHL() + , _stack () + { + cdebug_log(145,0) << "AutoSegments_Connecteds::Locator::Locator()" << endl; + + if (flags & Flags::Source) { + AutoContact* contact = segment->getAutoSource(); + if (contact) _stack.push( contact, segment ); + } + + if (flags & Flags::Target) { + AutoContact* contact = segment->getAutoTarget(); + if (contact) _stack.push( contact, segment ); + } + } + + + AutoSegmentHL* AutoSegments_Connecteds::Locator::getClone () const + { return new Locator(*this); } + + + bool AutoSegments_Connecteds::Locator::isValid () const + { return not _stack.isEmpty(); } + + + void AutoSegments_Connecteds::Locator::progress () + { + cdebug_log(145,0) << "AutoSegments_Connecteds::Locator::progress()" << endl; + + while (not _stack.isEmpty()) { + AutoContact* sourceContact = _stack.getAutoContact (); + AutoSegment* sourceSegment = _stack.getAutoSegment (); + + _stack.pop (); + + AutoContactTerminal* sourceTerminal = dynamic_cast( sourceContact ); + if (sourceTerminal) { + for ( AutoSegment* currentSegment : sourceTerminal->getRpConnecteds() ) { + cdebug_log(145,0) << "Looking at: " << currentSegment << endl; + if (currentSegment == sourceSegment) continue; + + AutoContact* targetContact = currentSegment->getAutoSource(); + if (not targetContact->isTerminal()) _stack.push( targetContact, currentSegment ); + + targetContact = currentSegment->getAutoTarget(); + if (not targetContact->isTerminal()) _stack.push( targetContact, currentSegment ); + } + } else { + LocatorHelper helper (sourceContact,Flags::WithPerpands); + for ( ; helper.isValid() ; helper.progress() ) { + AutoSegment* currentSegment = helper.getSegment(); + cdebug_log(145,0) << "Looking at: " << currentSegment << endl; + + if (currentSegment == sourceSegment) continue; + + AutoContact* targetContact = currentSegment->getOppositeAnchor( sourceContact ); + if (targetContact) _stack.push( targetContact, currentSegment ); + } + } + break; + } + } + + + string AutoSegments_Connecteds::Locator::_getString () const + { + string s = "<" + _TName("AutoSegments_Connecteds::Locator") + ">"; + return s; + } + + + AutoSegmentHC* AutoSegments_Connecteds::getClone () const + { return new AutoSegments_Connecteds(*this); } + + + AutoSegmentHL* AutoSegments_Connecteds::getLocator () const + { return new Locator(_segment,_flags); } + + + AutoSegment* AutoSegments_Connecteds::Locator::getElement () const + { return _stack.getAutoSegment(); } + + + string AutoSegments_Connecteds::_getString () const + { + string s = "<" + _TName("AutoSegments_Connecteds") + " " + + getString(_segment) + + ">"; + return s; + } + + // ------------------------------------------------------------------- // Class : "AutoSegments_Aligneds". diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 26bed1b1..ab784cc3 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -22,67 +22,67 @@ namespace Anabatic { using std::string; - const unsigned int Flags::NoFlags = 0; + const uint64_t Flags::NoFlags = 0; // Flags used for both objects states & functions arguments. - const unsigned int Flags::Horizontal = (1 << 0); - const unsigned int Flags::Vertical = (1 << 1); - const unsigned int Flags::Source = (1 << 2); - const unsigned int Flags::Target = (1 << 3); - const unsigned int Flags::Invalidated = (1 << 4); + const uint64_t Flags::Horizontal = (1 << 0); + const uint64_t Flags::Vertical = (1 << 1); + const uint64_t Flags::Source = (1 << 2); + const uint64_t Flags::Target = (1 << 3); + const uint64_t Flags::Invalidated = (1 << 4); // Flags for GCell objects states only. - const unsigned int Flags::DeviceGCell = (1 << 5); - const unsigned int Flags::HChannelGCell = (1 << 6); - const unsigned int Flags::VChannelGCell = (1 << 7); - const unsigned int Flags::StrutGCell = (1 << 8); - const unsigned int Flags::MatrixGCell = (1 << 9); - const unsigned int Flags::IoPadGCell = (1 << 10); - const unsigned int Flags::Saturated = (1 << 11); + const uint64_t Flags::DeviceGCell = (1 << 5); + const uint64_t Flags::HChannelGCell = (1 << 6); + const uint64_t Flags::VChannelGCell = (1 << 7); + const uint64_t Flags::StrutGCell = (1 << 8); + const uint64_t Flags::MatrixGCell = (1 << 9); + const uint64_t Flags::IoPadGCell = (1 << 10); + const uint64_t Flags::Saturated = (1 << 11); // Flags for Anabatic objects states only. - const unsigned int Flags::DemoMode = (1 << 5); - const unsigned int Flags::WarnOnGCellOverload = (1 << 6); - const unsigned int Flags::DestroyGCell = (1 << 7); - const unsigned int Flags::DestroyBaseContact = (1 << 8); - const unsigned int Flags::DestroyBaseSegment = (1 << 9); + const uint64_t Flags::DemoMode = (1 << 5); + const uint64_t Flags::WarnOnGCellOverload = (1 << 6); + const uint64_t Flags::DestroyGCell = (1 << 7); + const uint64_t Flags::DestroyBaseContact = (1 << 8); + const uint64_t Flags::DestroyBaseSegment = (1 << 9); // Flags for NetDatas objects states only. - const unsigned int Flags::GlobalRouted = (1 << 5); + const uint64_t Flags::GlobalRouted = (1 << 5); // Masks. - const unsigned int Flags::WestSide = Horizontal|Target; - const unsigned int Flags::EastSide = Horizontal|Source; - const unsigned int Flags::SouthSide = Vertical |Target; - const unsigned int Flags::NorthSide = Vertical |Source; - const unsigned int Flags::AllSides = WestSide|EastSide|SouthSide|NorthSide ; - const unsigned int Flags::EndsMask = Source|Target; - const unsigned int Flags::DirectionMask = Horizontal|Vertical; - const unsigned int Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - const unsigned int Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; + const uint64_t Flags::WestSide = Horizontal|Target; + const uint64_t Flags::EastSide = Horizontal|Source; + const uint64_t Flags::SouthSide = Vertical |Target; + const uint64_t Flags::NorthSide = Vertical |Source; + const uint64_t Flags::AllSides = WestSide|EastSide|SouthSide|NorthSide ; + const uint64_t Flags::EndsMask = Source|Target; + const uint64_t Flags::DirectionMask = Horizontal|Vertical; + const uint64_t Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; + const uint64_t Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; // Flags for functions arguments only. - const unsigned int Flags::Create = (1 << 5); - const unsigned int Flags::WithPerpands = (1 << 6); - const unsigned int Flags::WithSelf = (1 << 7); - const unsigned int Flags::AboveLayer = (1 << 8); - const unsigned int Flags::BelowLayer = (1 << 9); - const unsigned int Flags::OpenSession = (1 << 10); - const unsigned int Flags::Realignate = (1 << 11); - const unsigned int Flags::NativeConstraints = (1 << 12); - const unsigned int Flags::ForceMove = (1 << 13); - const unsigned int Flags::WarnOnError = (1 << 14); - const unsigned int Flags::Topology = (1 << 15); - const unsigned int Flags::GlobalSegment = (1 << 16); - const unsigned int Flags::AllowTerminal = (1 << 17); - const unsigned int Flags::AllowLocal = (1 << 18); - const unsigned int Flags::IgnoreContacts = (1 << 19); - const unsigned int Flags::Propagate = (1 << 20); - const unsigned int Flags::Superior = (1 << 21); - const unsigned int Flags::DoglegOnLeft = (1 << 22); - const unsigned int Flags::DoglegOnRight = (1 << 23); - const unsigned int Flags::WithNeighbors = (1 << 24); - const unsigned int Flags::NoCheckLayer = (1 << 25); - const unsigned int Flags::HalfSlacken = (1 << 26); - const unsigned int Flags::NoGCellShrink = (1 << 27); - const unsigned int Flags::CParanoid = (1 << 28); - const unsigned int Flags::CheckLowDensity = (1 << 29); - const unsigned int Flags::CheckLowUpDensity = (1 << 30); - const unsigned int Flags::NoUpdate = (1 << 31); + const uint64_t Flags::Create = (1 << 5); + const uint64_t Flags::WithPerpands = (1 << 6); + const uint64_t Flags::WithSelf = (1 << 7); + const uint64_t Flags::AboveLayer = (1 << 8); + const uint64_t Flags::BelowLayer = (1 << 9); + const uint64_t Flags::OpenSession = (1 << 10); + const uint64_t Flags::Realignate = (1 << 11); + const uint64_t Flags::NativeConstraints = (1 << 12); + const uint64_t Flags::ForceMove = (1 << 13); + const uint64_t Flags::WarnOnError = (1 << 14); + const uint64_t Flags::Topology = (1 << 15); + const uint64_t Flags::GlobalSegment = (1 << 16); + const uint64_t Flags::AllowTerminal = (1 << 17); + const uint64_t Flags::AllowLocal = (1 << 18); + const uint64_t Flags::IgnoreContacts = (1 << 19); + const uint64_t Flags::Propagate = (1 << 20); + const uint64_t Flags::Superior = (1 << 21); + const uint64_t Flags::DoglegOnLeft = (1 << 22); + const uint64_t Flags::DoglegOnRight = (1 << 23); + const uint64_t Flags::WithNeighbors = (1 << 24); + const uint64_t Flags::NoCheckLayer = (1 << 25); + const uint64_t Flags::HalfSlacken = (1 << 26); + const uint64_t Flags::NoGCellShrink = (1 << 27); + const uint64_t Flags::CParanoid = (1 << 28); + const uint64_t Flags::CheckLowDensity = (1 << 29); + const uint64_t Flags::CheckLowUpDensity = (1 << 30); + const uint64_t Flags::NoUpdate = (1 << 31); Flags::~Flags () diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index 4389d0e6..7b93b3fd 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -22,7 +22,6 @@ #include #include -#include "hurricane/Timer.h" #include "hurricane/NetRoutingProperty.h" namespace Hurricane { class Instance; @@ -42,7 +41,6 @@ namespace Anabatic { using std::string; using std::vector; - using Hurricane::Timer; using Hurricane::Name; using Hurricane::Record; using Hurricane::Interval; @@ -271,16 +269,11 @@ namespace Anabatic { void _destroyAutoSegments (); void _check ( Net* net ) const; bool _check ( const char* message ) const; + void printMeasures ( const string& tag ) const; // Misc. functions. inline const Flags& flags () const; inline Flags& flags (); void reset (); - inline const Timer& getTimer () const; - void startMeasures (); - void stopMeasures (); - void suspendMeasures (); - void resumeMeasures (); - void printMeasures ( const string& ) const; inline void _add ( GCell* ); inline void _remove ( GCell* ); inline void _updateLookup ( GCell* ); @@ -300,7 +293,6 @@ namespace Anabatic { AnabaticEngine& operator= ( const AnabaticEngine& ); private: static Name _toolName; - Timer _timer; Configuration* _configuration; ChipTools _chipTools; EngineState _state; @@ -372,7 +364,6 @@ namespace Anabatic { } } - inline const Timer& AnabaticEngine::getTimer () const { return _timer; } inline int AnabaticEngine::getStamp () const { return _stamp; } inline int AnabaticEngine::incStamp () { return ++_stamp; } diff --git a/anabatic/src/anabatic/AutoContactTerminal.h b/anabatic/src/anabatic/AutoContactTerminal.h index 67be5711..0b134311 100644 --- a/anabatic/src/anabatic/AutoContactTerminal.h +++ b/anabatic/src/anabatic/AutoContactTerminal.h @@ -18,10 +18,17 @@ #define ANABATIC_AUTOCONTACT_TERMINAL_H #include "anabatic/AutoContact.h" +#include "anabatic/AutoSegments.h" + +namespace Hurricane { + class RoutingPad; +} namespace Anabatic { + using Hurricane::RoutingPad; + // ------------------------------------------------------------------- // Class : "Anabatic::AutoContactTerminal". @@ -52,11 +59,14 @@ namespace Anabatic { virtual ~AutoContactTerminal (); virtual void _invalidate ( unsigned int flags ); public: + bool isEndPoint () const; virtual Box getNativeConstraintBox () const; + RoutingPad* getRoutingPad () const; inline AutoSegment* getSegment () const; virtual AutoSegment* getSegment ( unsigned int ) const; virtual AutoSegment* getOpposite ( const AutoSegment* ) const; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; + AutoSegments getRpConnecteds () const; virtual void updateGeometry (); virtual void updateTopology (); virtual void forceOnGrid ( Point ); diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index 4b2d7521..810ecdf0 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -311,6 +311,7 @@ namespace Anabatic { AutoSegments getCachedOnSourceContact ( unsigned int direction ); AutoSegments getCachedOnTargetContact ( unsigned int direction ); AutoSegments getAligneds ( unsigned int flags=Flags::NoFlags ); + AutoSegments getConnecteds ( unsigned int flags=Flags::NoFlags ); AutoSegments getPerpandiculars (); size_t getAlignedContacts ( map& ) const ; // Observers. @@ -387,6 +388,7 @@ namespace Anabatic { // Static Utilities. public: + static inline unsigned int swapSourceTargetFlags ( AutoSegment* ); static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* ); static bool isTopologicalBound ( AutoSegment* seed, unsigned int flags ); static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b ); @@ -520,6 +522,30 @@ namespace Anabatic { inline unsigned long AutoSegment::getMaxId () { return _maxId; } + inline unsigned int AutoSegment::swapSourceTargetFlags ( AutoSegment* segment ) + { + unsigned int segFlags = segment->getFlags(); + unsigned int swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop + |SegSourceBottom |SegTargetBottom + |SegSourceTerminal |SegTargetTerminal + |SegNotSourceAligned |SegNotTargetAligned + |SegInvalidatedSource|SegInvalidatedTarget + ); + + swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags; + swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags; + swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags; + swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags; + swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags; + + swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags; + swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags; + swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags; + swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags; + swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags; + return swapFlags; + } + inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 ) { return s1 and s2 and (s1->isHorizontal() == s2->isHorizontal()) diff --git a/anabatic/src/anabatic/AutoSegments.h b/anabatic/src/anabatic/AutoSegments.h index d8f135c4..84151f20 100644 --- a/anabatic/src/anabatic/AutoSegments.h +++ b/anabatic/src/anabatic/AutoSegments.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "hurricane/Collection.h" #include "hurricane/DbU.h" @@ -30,6 +31,7 @@ namespace Hurricane { class Component; class Contact; class Segment; + class RoutingPad; class Net; } @@ -49,6 +51,7 @@ namespace Anabatic { using Hurricane::Component; using Hurricane::Contact; using Hurricane::Segment; + using Hurricane::RoutingPad; using Hurricane::Net; using Hurricane::Filter; using Hurricane::Locator; @@ -59,6 +62,7 @@ namespace Anabatic { class LocatorHelper; class AutoContact; + class AutoContactTerminal; class AutoSegment; class GCell; @@ -155,6 +159,56 @@ namespace Anabatic { { } +// ------------------------------------------------------------------- +// Class : "Anabatic::AutoSegments_OnRoutingPad". + + class AutoSegments_OnRoutingPad : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + Locator ( RoutingPad* rp, const AutoContactTerminal* contact ); + inline Locator ( const Locator& ); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + std::array _elements; + size_t _index; + }; + + public: + // AutoSegments_OnRoutingPad Methods. + AutoSegments_OnRoutingPad ( const AutoContact* contact ); + inline AutoSegments_OnRoutingPad ( const AutoSegments_OnRoutingPad& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_OnRoutingPad Attributes. + RoutingPad* _routingPad; + const AutoContactTerminal* _contact; + }; + + + inline AutoSegments_OnRoutingPad::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _elements(locator._elements) + , _index (locator._index) + { } + + + inline AutoSegments_OnRoutingPad::AutoSegments_OnRoutingPad ( const AutoSegments_OnRoutingPad& segments ) + : AutoSegmentHC() + , _routingPad(segments._routingPad) + , _contact (segments._contact) + { } + + // ------------------------------------------------------------------- // Class : "AutoSegments_Aligneds". @@ -214,6 +268,61 @@ namespace Anabatic { { } +// ------------------------------------------------------------------- +// Class : "AutoSegments_Connecteds". + + class AutoSegments_Connecteds : public AutoSegmentHC { + + public: + // Sub-Class: Locator. + class Locator : public AutoSegmentHL { + public: + inline Locator ( AutoSegment* segment, unsigned int flags ); + inline Locator ( const Locator &locator ); + virtual AutoSegment* getElement () const; + virtual AutoSegmentHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + AutoSegmentStack _stack; + }; + + public: + // AutoSegments_Connecteds Methods. + AutoSegments_Connecteds ( AutoSegment*, unsigned int flags ); + AutoSegments_Connecteds ( const AutoSegments_Connecteds& ); + virtual AutoSegmentHC* getClone () const; + virtual AutoSegmentHL* getLocator () const; + virtual string _getString () const; + + protected: + // AutoSegments_Connecteds Attributes. + unsigned int _flags; + AutoSegment* _segment; + }; + + + inline AutoSegments_Connecteds::Locator::Locator ( const Locator &locator ) + : AutoSegmentHL() + , _stack (locator._stack) + { } + + + inline AutoSegments_Connecteds::AutoSegments_Connecteds ( AutoSegment* segment, unsigned int flags ) + : AutoSegmentHC() + , _flags (flags) + , _segment(segment) + { } + + + inline AutoSegments_Connecteds::AutoSegments_Connecteds ( const AutoSegments_Connecteds& autosegments ) + : AutoSegmentHC() + , _flags (autosegments._flags) + , _segment(autosegments._segment) + { } + + // ------------------------------------------------------------------- // Class : "AutoSegments_Perpandiculars". diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index dce2061d..279f6883 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -24,69 +24,69 @@ namespace Anabatic { class Flags : public Hurricane::BaseFlags { public: - static const unsigned int NoFlags ; // = 0; + static const uint64_t NoFlags ; // = 0; // Flags used for both objects states & functions arguments. - static const unsigned int Horizontal ; // = (1 << 0); - static const unsigned int Vertical ; // = (1 << 1); - static const unsigned int Source ; // = (1 << 2); - static const unsigned int Target ; // = (1 << 3); - static const unsigned int Invalidated ; // = (1 << 4); + static const uint64_t Horizontal ; // = (1 << 0); + static const uint64_t Vertical ; // = (1 << 1); + static const uint64_t Source ; // = (1 << 2); + static const uint64_t Target ; // = (1 << 3); + static const uint64_t Invalidated ; // = (1 << 4); // Flags for GCell objects states only. - static const unsigned int DeviceGCell ; // = (1 << 5); - static const unsigned int HChannelGCell ; // = (1 << 6); - static const unsigned int VChannelGCell ; // = (1 << 7); - static const unsigned int StrutGCell ; // = (1 << 8); - static const unsigned int MatrixGCell ; // = (1 << 9); - static const unsigned int IoPadGCell ; // = (1 << 10); - static const unsigned int Saturated ; // = (1 << 11); + static const uint64_t DeviceGCell ; // = (1 << 5); + static const uint64_t HChannelGCell ; // = (1 << 6); + static const uint64_t VChannelGCell ; // = (1 << 7); + static const uint64_t StrutGCell ; // = (1 << 8); + static const uint64_t MatrixGCell ; // = (1 << 9); + static const uint64_t IoPadGCell ; // = (1 << 10); + static const uint64_t Saturated ; // = (1 << 11); // Flags for Anabatic objects states only. - static const unsigned int DemoMode ; // = (1 << 5); - static const unsigned int WarnOnGCellOverload ; // = (1 << 6); - static const unsigned int DestroyGCell ; // = (1 << 7); - static const unsigned int DestroyBaseContact ; // = (1 << 8); - static const unsigned int DestroyBaseSegment ; // = (1 << 9); + static const uint64_t DemoMode ; // = (1 << 5); + static const uint64_t WarnOnGCellOverload ; // = (1 << 6); + static const uint64_t DestroyGCell ; // = (1 << 7); + static const uint64_t DestroyBaseContact ; // = (1 << 8); + static const uint64_t DestroyBaseSegment ; // = (1 << 9); // Flags for NetDatas objects states only. - static const unsigned int GlobalRouted ; // = (1 << 5); + static const uint64_t GlobalRouted ; // = (1 << 5); // Masks. - static const unsigned int WestSide ; // = Horizontal|Target; - static const unsigned int EastSide ; // = Horizontal|Source; - static const unsigned int SouthSide ; // = Vertical |Target; - static const unsigned int NorthSide ; // = Vertical |Source; - static const unsigned int AllSides ; // = WestSide|EastSide|SouthSide|NorthSide ; - static const unsigned int EndsMask ; // = Source|Target; - static const unsigned int DirectionMask ; // = Horizontal|Vertical; - static const unsigned int DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - static const unsigned int GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; + static const uint64_t WestSide ; // = Horizontal|Target; + static const uint64_t EastSide ; // = Horizontal|Source; + static const uint64_t SouthSide ; // = Vertical |Target; + static const uint64_t NorthSide ; // = Vertical |Source; + static const uint64_t AllSides ; // = WestSide|EastSide|SouthSide|NorthSide ; + static const uint64_t EndsMask ; // = Source|Target; + static const uint64_t DirectionMask ; // = Horizontal|Vertical; + static const uint64_t DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; + static const uint64_t GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; // Flags for functions arguments only. - static const unsigned int Create ; // = (1 << 5); - static const unsigned int WithPerpands ; - static const unsigned int WithSelf ; - static const unsigned int AboveLayer ; - static const unsigned int BelowLayer ; - static const unsigned int OpenSession ; - static const unsigned int Realignate ; - static const unsigned int NativeConstraints ; - static const unsigned int ForceMove ; - static const unsigned int WarnOnError ; - static const unsigned int Topology ; - static const unsigned int GlobalSegment ; - static const unsigned int AllowTerminal ; - static const unsigned int AllowLocal ; - static const unsigned int IgnoreContacts ; - static const unsigned int Propagate ; - static const unsigned int Superior ; - static const unsigned int DoglegOnLeft ; - static const unsigned int DoglegOnRight ; - static const unsigned int WithNeighbors ; - static const unsigned int NoCheckLayer ; - static const unsigned int HalfSlacken ; - static const unsigned int NoGCellShrink ; - static const unsigned int CParanoid ; - static const unsigned int CheckLowDensity ; - static const unsigned int CheckLowUpDensity ; - static const unsigned int NoUpdate ; + static const uint64_t Create ; // = (1 << 5); + static const uint64_t WithPerpands ; + static const uint64_t WithSelf ; + static const uint64_t AboveLayer ; + static const uint64_t BelowLayer ; + static const uint64_t OpenSession ; + static const uint64_t Realignate ; + static const uint64_t NativeConstraints ; + static const uint64_t ForceMove ; + static const uint64_t WarnOnError ; + static const uint64_t Topology ; + static const uint64_t GlobalSegment ; + static const uint64_t AllowTerminal ; + static const uint64_t AllowLocal ; + static const uint64_t IgnoreContacts ; + static const uint64_t Propagate ; + static const uint64_t Superior ; + static const uint64_t DoglegOnLeft ; + static const uint64_t DoglegOnRight ; + static const uint64_t WithNeighbors ; + static const uint64_t NoCheckLayer ; + static const uint64_t HalfSlacken ; + static const uint64_t NoGCellShrink ; + static const uint64_t CParanoid ; + static const uint64_t CheckLowDensity ; + static const uint64_t CheckLowUpDensity ; + static const uint64_t NoUpdate ; public: - inline Flags ( unsigned int flags = NoFlags ); + inline Flags ( uint64_t flags = NoFlags ); inline Flags ( BaseFlags ); virtual ~Flags (); virtual std::string _getTypeName () const; @@ -94,8 +94,8 @@ namespace Anabatic { }; - Flags::Flags ( unsigned int flags ) : BaseFlags(flags) { } - Flags::Flags ( BaseFlags base ) : BaseFlags(base) { } + Flags::Flags ( uint64_t flags ) : BaseFlags(flags) { } + Flags::Flags ( BaseFlags base ) : BaseFlags(base) { } enum EngineState { EngineCreation = 1 diff --git a/crlcore/src/ccore/ToolEngine.cpp b/crlcore/src/ccore/ToolEngine.cpp index e5e69b70..6f789168 100644 --- a/crlcore/src/ccore/ToolEngine.cpp +++ b/crlcore/src/ccore/ToolEngine.cpp @@ -28,6 +28,7 @@ namespace { using std::cerr; using std::endl; using std::string; + using std::ostringstream; using std::set; using std::vector; using Hurricane::ForEachIterator; @@ -191,30 +192,37 @@ namespace CRL { ToolEngine::ToolEngine ( Cell* cell ) - : DBo() + : Super() , _cell (cell) , _placementModificationFlag(0) , _routingModificationFlag (0) , _inRelationDestroy (false) - {} + , _timer () + { } void ToolEngine::_postCreate () { - DBo::_postCreate(); - if ( !_cell ) - throw Error ( "Can't create " + _TName("ToolEngine") + " : empty _cell" ); + Super::_postCreate(); + if (not _cell) + throw Error( "Can't create " + _TName("ToolEngine") + " : empty _cell" ); + ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell); - if ( !enginesRelation ) - enginesRelation = ToolEnginesRelation::create ( _cell ); + if (not enginesRelation) + enginesRelation = ToolEnginesRelation::create( _cell ); else - forEach ( ToolEngine*, itool, enginesRelation->getSlaveOwners().getSubSet() ) { - if (itool->getName() == getName()) - throw Error ( "Can't create " + _TName("ToolEngine") + " : already exists !!" ); + for ( ToolEngine* tool : enginesRelation->getSlaveOwners().getSubSet() ) { + if (tool->getName() == getName()) + throw Error( "Can't create " + _TName("ToolEngine") + " : already exists !!" ); } - put ( enginesRelation ); + + put( enginesRelation ); + cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <" << _cell->getName() << ">" << endl; + + cmess1 << Dots::asString( " - Initial memory" + , Timer::getStringMemory(Timer::getMemorySize()) ) << endl; } @@ -226,7 +234,7 @@ namespace CRL { throw Error( "Abnormal state: no ToolEnginesRelation on %s", getString(_cell).c_str() ); remove( relation ); } - DBo::_preDestroy(); + Super::_preDestroy(); _cell->notify( Cell::Flags::CellChanged ); } @@ -249,7 +257,7 @@ namespace CRL { string ToolEngine::_getString () const { - string s = DBo::_getString(); + string s = Super::_getString(); s.insert(s.length() - 1, " " + getString(_cell->getName())); return s; } @@ -257,7 +265,7 @@ namespace CRL { Record* ToolEngine::_getRecord () const { - Record* record = DBo::_getRecord(); + Record* record = Super::_getRecord(); if ( record ) { record->add ( getSlot ( "Cell" , _cell ) ); record->add ( getSlot ( "Name" , getName() ) ); @@ -348,4 +356,43 @@ namespace CRL { } + void ToolEngine::startMeasures () + { + _timer.resetIncrease(); + _timer.start(); + } + + + void ToolEngine::stopMeasures () + { _timer.stop(); } + + + void ToolEngine::suspendMeasures () + { _timer.suspend(); } + + + void ToolEngine::resumeMeasures () + { _timer.resume(); } + + + void ToolEngine::printMeasures () const + { + ostringstream result; + + result << Timer::getStringTime(_timer.getCombTime()) + << ", " << Timer::getStringMemory(_timer.getIncrease()); + cmess1 << Dots::asString( " - Done in", result.str() ) << endl; + + result.str(""); + result << _timer.getCombTime() + << "s, +" << (_timer.getIncrease()>>10) << "Kb/" + << Timer::getStringMemory(Timer::getMemorySize()); + cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl; + + // result.str(""); + // result << Timer::getStringMemory(Timer::getMemorySize()); + // cmess1 << Dots::asString( " - Total memory", result.str() ) << endl; + } + + } // End of CRL namespace. diff --git a/crlcore/src/ccore/crlcore/ToolEngine.h b/crlcore/src/ccore/crlcore/ToolEngine.h index 84708c59..bbda64d6 100644 --- a/crlcore/src/ccore/crlcore/ToolEngine.h +++ b/crlcore/src/ccore/crlcore/ToolEngine.h @@ -21,6 +21,7 @@ #include #include #include "hurricane/Commons.h" +#include "hurricane/Timer.h" #include "hurricane/DBo.h" #include "hurricane/Slot.h" @@ -36,6 +37,7 @@ namespace CRL { using std::string; using std::vector; + using Hurricane::Timer; using Hurricane::Record; using Hurricane::Name; using Hurricane::DBo; @@ -47,36 +49,45 @@ namespace CRL { class ToolEngine : public DBo { public: - static ToolEngines get ( const Cell* cell ); - static ToolEngine* get ( const Cell* cell, const Name& name ); - static void destroyAll (); - static bool inDestroyAll (); + typedef DBo Super; public: - virtual const Name& getName () const = 0; - inline Cell* getCell () const; - bool placementModificationFlagHasChanged (); - bool routingModificationFlagHasChanged (); - inline void setInRelationDestroy ( bool ); - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; + static ToolEngines get ( const Cell* cell ); + static ToolEngine* get ( const Cell* cell, const Name& name ); + static void destroyAll (); + static bool inDestroyAll (); + public: + virtual const Name& getName () const = 0; + inline Cell* getCell () const; + bool placementModificationFlagHasChanged (); + bool routingModificationFlagHasChanged (); + inline void setInRelationDestroy ( bool ); + inline const Timer& getTimer () const; + void startMeasures (); + void stopMeasures (); + void suspendMeasures (); + void resumeMeasures (); + void printMeasures () const; + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; private: - static bool _inDestroyAll; + static bool _inDestroyAll; protected: - Cell* _cell; + Cell* _cell; private: - unsigned int _placementModificationFlag; - unsigned int _routingModificationFlag; - bool _inRelationDestroy; + unsigned int _placementModificationFlag; + unsigned int _routingModificationFlag; + bool _inRelationDestroy; + Timer _timer; protected: - ToolEngine ( Cell* cell ); - virtual void _postCreate (); - virtual void _preDestroy (); - protected: - void grabPlacementModificationFlag (); - void getPlacementModificationFlag (); - void grabRoutingModificationFlag (); - void getRoutingModificationFlag (); + ToolEngine ( Cell* cell ); + virtual void _postCreate (); + virtual void _preDestroy (); + protected: + void grabPlacementModificationFlag (); + void getPlacementModificationFlag (); + void grabRoutingModificationFlag (); + void getRoutingModificationFlag (); }; @@ -84,8 +95,9 @@ namespace CRL { // Inline Functions. - inline Cell* ToolEngine::getCell () const { return _cell; } - inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; } + inline Cell* ToolEngine::getCell () const { return _cell; } + inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; } + inline const Timer& ToolEngine::getTimer () const { return _timer; } } // CRL namespace. diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 9f95a24c..541186a2 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -244,11 +244,10 @@ namespace Etesian { EtesianEngine::EtesianEngine ( Cell* cell ) - : ToolEngine (cell) + : Super (cell) , _configuration(new Configuration()) , _placed (false) , _flatDesign (false) - , _timer () , _surface () , _circuit () , _placementLB () @@ -263,6 +262,8 @@ namespace Etesian { void EtesianEngine::_postCreate () { + Super::_postCreate(); + // Ugly: Name based detection of ISPD benchmarks. if (getString(getCell()->getName()).substr(0,7) == "bigblue") { cmess2 << " o ISPD benchmark <" << getCell()->getName() @@ -292,6 +293,8 @@ namespace Etesian { cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <" << getCell()->getName() << ">" << endl; + Super::_preDestroy(); + cdebug.log(129,-1); } @@ -314,33 +317,6 @@ namespace Etesian { { return _configuration; } - void EtesianEngine::startMeasures () - { - _timer.resetIncrease(); - _timer.start(); - } - - - void EtesianEngine::stopMeasures () - { _timer.stop(); } - - - void EtesianEngine::printMeasures ( string tag ) const - { - ostringstream result; - - result << Timer::getStringTime(_timer.getCombTime()) << ", " - << Timer::getStringMemory(_timer.getIncrease()); - cmess1 << ::Dots::asString( " - Done in", result.str() ) << endl; - - result.str(""); - result << _timer.getCombTime() - << "s, +" << (_timer.getIncrease()>>10) << "Kb/" - << (_timer.getMemorySize()>>10) << "Kb"; - cmess2 << ::Dots::asString( " - Raw measurements", result.str() ) << endl; - } - - void EtesianEngine::setDefaultAb () { double spaceMargin = getSpaceMargin(); @@ -925,7 +901,7 @@ namespace Etesian { cmess1 << " o Placement finished." << endl; stopMeasures(); - printMeasures( "total" ); + printMeasures(); cmess1 << ::Dots::asString ( " - HPWL", DbU::getValueString( (DbU::Unit)coloquinte::gp::get_HPWL_wirelength(_circuit,_placementUB )*getPitch() ) ) << endl; cmess1 << ::Dots::asString @@ -954,10 +930,7 @@ namespace Etesian { indent = label; } - ostringstream elapsed; - //elapsed << " dTime:" << setw(5) << _timer.getCombTime() << "s "; - - cmess2 << label << elapsed.str() + cmess2 << label << " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementUB ) << " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementUB ) << endl; @@ -977,10 +950,7 @@ namespace Etesian { indent = label; } - ostringstream elapsed; - //elapsed << " dTime:" << setw(5) << _timer.getCombTime() << "s "; - - cmess2 << label << elapsed.str() + cmess2 << label << " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementLB ) << " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementLB ) << endl; @@ -1042,7 +1012,7 @@ namespace Etesian { Record* EtesianEngine::_getRecord () const { - Record* record = ToolEngine::_getRecord (); + Record* record = Super::_getRecord (); if (record) { record->add( getSlot( "_configuration", _configuration ) ); diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index f4796b05..b57758e3 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -52,6 +52,8 @@ namespace Etesian { // Class : "Etesian::EtesianEngine". class EtesianEngine : public CRL::ToolEngine { + public: + typedef ToolEngine Super; public: static const Name& staticGetName (); static EtesianEngine* create ( Cell* ); @@ -73,10 +75,6 @@ namespace Etesian { inline Hurricane::CellViewer* getViewer () const; inline void setViewer ( Hurricane::CellViewer* ); - void startMeasures (); - void stopMeasures (); - void printMeasures ( std::string ) const; - void setDefaultAb (); void resetPlacement (); void toColoquinte (); @@ -104,7 +102,6 @@ namespace Etesian { bool _placed; bool _ySpinSet; bool _flatDesign; - Timer _timer; coloquinte::box _surface; coloquinte::netlist _circuit; coloquinte::placement_t _placementLB; diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index d907a236..6a81e63d 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -814,7 +814,7 @@ DeepNet* Cell::getDeepNet ( Path path, const Net* leafNet ) const } -void Cell::flattenNets(unsigned int flags) +void Cell::flattenNets(uint64_t flags) // *************************************** { cdebug_log(18,0) << "Cell::flattenNets() flags:0x" << hex << flags << endl; @@ -892,7 +892,7 @@ void Cell::flattenNets(unsigned int flags) } -void Cell::createRoutingPadRings(unsigned int flags) +void Cell::createRoutingPadRings(uint64_t flags) // ************************************************* { flags &= Flags::MaskRings; @@ -1339,7 +1339,7 @@ void Cell::_toJsonCollections(JsonWriter* writer) const // Cell::Flags implementation // **************************************************************************************************** - Cell::Flags::Flags ( unsigned int flags) + Cell::Flags::Flags ( uint64_t flags) : BaseFlags(flags) { } diff --git a/hurricane/src/hurricane/Flags.cpp b/hurricane/src/hurricane/Flags.cpp index ffecdbe5..b764800e 100644 --- a/hurricane/src/hurricane/Flags.cpp +++ b/hurricane/src/hurricane/Flags.cpp @@ -47,7 +47,7 @@ namespace Hurricane { string BaseFlags::_getString () const { - static size_t width = sizeof(unsigned int) * CHAR_BIT; + static size_t width = sizeof(uint64_t) * CHAR_BIT; std::ostringstream formatted; formatted << "0x" << std::hex << std::setw(width) << std::setfill('0') << _flags; diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index f6a4c580..0086815e 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -99,7 +99,7 @@ class Cell : public Entity { }; public: - Flags ( unsigned int flags = NoFlags ); + Flags ( uint64_t flags = NoFlags ); virtual ~Flags (); virtual std::string _getTypeName () const; virtual std::string _getString () const; @@ -357,9 +357,9 @@ class Cell : public Entity { public: virtual string _getTypeName() const {return _TName("Cell");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; - public: static string getFlagString( unsigned int ); - public: static Record* getFlagRecord( unsigned int ); - public: static Slot* getFlagSlot( unsigned int ); + public: static string getFlagString( uint64_t ); + public: static Record* getFlagRecord( uint64_t ); + public: static Slot* getFlagSlot( uint64_t ); public: InstanceMap& _getInstanceMap() {return _instanceMap;}; public: QuadTree* _getQuadTree() {return _quadTree;}; @@ -506,10 +506,10 @@ class Cell : public Entity { public: void setFlattenLeaf(bool isFlattenLeaf) {_flags.set(Flags::FlattenLeaf,isFlattenLeaf);}; public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);}; public: void setFeed(bool isFeed) {_flags.set(Flags::Feed,isFeed);}; - public: void flattenNets(unsigned int flags=Flags::BuildRings); - public: void createRoutingPadRings(unsigned int flags=Flags::BuildRings); - public: void setFlags(unsigned int flags) { _flags |= flags; } - public: void resetFlags(unsigned int flags) { _flags &= ~flags; } + public: void flattenNets(uint64_t flags=Flags::BuildRings); + public: void createRoutingPadRings(uint64_t flags=Flags::BuildRings); + public: void setFlags(uint64_t flags) { _flags |= flags; } + public: void resetFlags(uint64_t flags) { _flags &= ~flags; } public: bool updatePlacedFlag(); public: void materialize(); public: void unmaterialize(); diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index fca97d90..035517b1 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -318,6 +319,104 @@ template inline Hurricane::Record* getRecord ( Data data ) { return NULL; } +// ------------------------------------------------------------------- +// Inspector Support for : "[const] std::array*". + + +template +inline std::string getString ( std::array* v ) +{ + std::string name = "const std::array:"; + return name + getString(v->size()); +} + + +template +inline Hurricane::Record* getRecord ( std::array* v ) +{ + Hurricane::Record* record = NULL; + if ( !v->empty() ) { + record = new Hurricane::Record ( "std::array" ); + unsigned n = 0; + typename std::array::iterator iterator = v->begin(); + while ( iterator != v->end() ) { + record->add ( getSlot(getString(n++), *iterator) ); + ++iterator; + } + } + return record; +} + + +template +inline std::string getString ( const std::array* v ) +{ + std::string name = "const std::array:"; + return name + getString(v->size()); +} + + +template +inline Hurricane::Record* getRecord ( const std::array* v ) +{ + Hurricane::Record* record = NULL; + if ( !v->empty() ) { + record = new Hurricane::Record ( "const std::array" ); + unsigned n = 0; + typename std::array::const_iterator iterator = v->begin(); + while ( iterator != v->end() ) { + record->add ( getSlot(getString(n++), *iterator) ); + ++iterator; + } + } + return record; +} + + +template +inline std::string getString ( std::array& v ) +{ + std::string name = "std::array&:"; + return name + getString(v.size()); +} + + +template +inline Hurricane::Record* getRecord ( std::array& v ) +{ + Hurricane::Record* record = NULL; + if (not v.empty()) { + record = new Hurricane::Record ( "std::array&" ); + unsigned n = 0; + for ( auto element : v ) + record->add( getSlot(getString(n++), element) ); + } + return record; +} + + +template +inline std::string getString ( const std::array& v ) +{ + std::string name = "const std::array&:"; + return name + getString(v.size()); +} + + +template +inline Hurricane::Record* getRecord ( const std::array& v ) +{ + Hurricane::Record* record = NULL; + if (not v.empty()) { + record = new Hurricane::Record ( "const std::array&" ); + unsigned n = 0; + for ( auto element : v ) + record->add( getSlot(getString(n++), element) ); + } + return record; +} + + // ------------------------------------------------------------------- // Inspector Support for : "[const] std::vector*". diff --git a/hurricane/src/hurricane/hurricane/Flags.h b/hurricane/src/hurricane/hurricane/Flags.h index 54562406..be243968 100644 --- a/hurricane/src/hurricane/hurricane/Flags.h +++ b/hurricane/src/hurricane/hurricane/Flags.h @@ -32,6 +32,7 @@ #ifndef HURRICANE_BASE_FLAGS_H #define HURRICANE_BASE_FLAGS_H +#include #include #include "hurricane/Commons.h" @@ -42,7 +43,7 @@ namespace Hurricane { class BaseFlags { public: // Methods. - inline BaseFlags ( unsigned int flags=0 ); + inline BaseFlags ( uint64_t flags=0 ); virtual ~BaseFlags (); inline bool zero () const; inline BaseFlags& set ( BaseFlags, bool state=true ); @@ -50,7 +51,7 @@ namespace Hurricane { inline bool isset ( BaseFlags ) const; inline bool contains ( BaseFlags ) const; inline bool intersect ( BaseFlags ) const; - inline BaseFlags nthbit ( unsigned int ) const; + inline BaseFlags nthbit ( uint64_t ) const; inline BaseFlags operator compl () const; inline BaseFlags operator bitand ( BaseFlags ) const; inline BaseFlags operator bitor ( BaseFlags ) const; @@ -60,11 +61,11 @@ namespace Hurricane { inline BaseFlags operator xor ( int ) const; inline BaseFlags lshift ( int ) const; inline BaseFlags rshift ( int ) const; - inline BaseFlags operator bitand ( unsigned int ) const; - inline BaseFlags operator bitor ( unsigned int ) const; - inline BaseFlags operator xor ( unsigned int ) const; - inline BaseFlags lshift ( unsigned int ) const; - inline BaseFlags rshift ( unsigned int ) const; + inline BaseFlags operator bitand ( uint64_t ) const; + inline BaseFlags operator bitor ( uint64_t ) const; + inline BaseFlags operator xor ( uint64_t ) const; + inline BaseFlags lshift ( uint64_t ) const; + inline BaseFlags rshift ( uint64_t ) const; inline BaseFlags& operator |= ( BaseFlags ); inline BaseFlags& operator &= ( BaseFlags ); inline bool operator == ( BaseFlags ) const; @@ -77,12 +78,12 @@ namespace Hurricane { inline bool operator != ( int ) const; inline bool operator < ( int ) const; inline bool operator > ( int ) const; - inline BaseFlags& operator |= ( unsigned int ); - inline BaseFlags& operator &= ( unsigned int ); - inline bool operator == ( unsigned int ) const; - inline bool operator != ( unsigned int ) const; - inline bool operator < ( unsigned int ) const; - inline bool operator > ( unsigned int ) const; + inline BaseFlags& operator |= ( uint64_t ); + inline BaseFlags& operator &= ( uint64_t ); + inline bool operator == ( uint64_t ) const; + inline bool operator != ( uint64_t ) const; + inline bool operator < ( uint64_t ) const; + inline bool operator > ( uint64_t ) const; inline operator bool () const; //inline operator unsigned int () const; // Hurricane Managment. @@ -91,12 +92,12 @@ namespace Hurricane { inline Record* _getRecord () const; protected: // Internal: Attributes. - unsigned int _flags; + uint64_t _flags; }; // Inline Functions. - inline BaseFlags::BaseFlags ( unsigned int flags ) : _flags(flags) { } + inline BaseFlags::BaseFlags ( uint64_t flags ) : _flags(flags) { } inline bool BaseFlags::zero () const { return _flags == 0; } inline BaseFlags& BaseFlags::reset ( BaseFlags flags ) { _flags &= ~flags._flags; return *this; } inline bool BaseFlags::isset ( BaseFlags flags ) const { return _flags & flags._flags; } @@ -107,34 +108,34 @@ namespace Hurricane { inline BaseFlags BaseFlags::operator bitand ( BaseFlags flags ) const { return _flags & flags._flags; } inline BaseFlags BaseFlags::operator bitor ( BaseFlags flags ) const { return _flags | flags._flags; } inline BaseFlags BaseFlags::operator xor ( BaseFlags flags ) const { return _flags ^ flags._flags; } - inline BaseFlags BaseFlags::operator bitand ( int flags ) const { return _flags & (unsigned int)flags; } - inline BaseFlags BaseFlags::operator bitor ( int flags ) const { return _flags | (unsigned int)flags; } - inline BaseFlags BaseFlags::operator xor ( int flags ) const { return _flags ^ (unsigned int)flags; } - inline BaseFlags BaseFlags::lshift ( int s ) const { return _flags << (unsigned int)s; } - inline BaseFlags BaseFlags::rshift ( int s ) const { return _flags >> (unsigned int)s; } - inline BaseFlags BaseFlags::operator bitand ( unsigned int flags ) const { return _flags & flags; } - inline BaseFlags BaseFlags::operator bitor ( unsigned int flags ) const { return _flags | flags; } - inline BaseFlags BaseFlags::operator xor ( unsigned int flags ) const { return _flags ^ flags; } - inline BaseFlags BaseFlags::lshift ( unsigned int s ) const { return _flags << s; } - inline BaseFlags BaseFlags::rshift ( unsigned int s ) const { return _flags >> s; } + inline BaseFlags BaseFlags::operator bitand ( int flags ) const { return _flags & (uint64_t)flags; } + inline BaseFlags BaseFlags::operator bitor ( int flags ) const { return _flags | (uint64_t)flags; } + inline BaseFlags BaseFlags::operator xor ( int flags ) const { return _flags ^ (uint64_t)flags; } + inline BaseFlags BaseFlags::lshift ( int s ) const { return _flags << (uint64_t)s; } + inline BaseFlags BaseFlags::rshift ( int s ) const { return _flags >> (uint64_t)s; } + inline BaseFlags BaseFlags::operator bitand ( uint64_t flags ) const { return _flags & flags; } + inline BaseFlags BaseFlags::operator bitor ( uint64_t flags ) const { return _flags | flags; } + inline BaseFlags BaseFlags::operator xor ( uint64_t flags ) const { return _flags ^ flags; } + inline BaseFlags BaseFlags::lshift ( uint64_t s ) const { return _flags << s; } + inline BaseFlags BaseFlags::rshift ( uint64_t s ) const { return _flags >> s; } inline BaseFlags& BaseFlags::operator |= ( BaseFlags flags ) { _flags |= flags._flags; return *this; } inline BaseFlags& BaseFlags::operator &= ( BaseFlags flags ) { _flags &= flags._flags; return *this; } inline bool BaseFlags::operator == ( BaseFlags flags ) const { return _flags == flags._flags; } inline bool BaseFlags::operator != ( BaseFlags flags ) const { return _flags != flags._flags; } inline bool BaseFlags::operator < ( BaseFlags flags ) const { return _flags < flags._flags; } inline bool BaseFlags::operator > ( BaseFlags flags ) const { return _flags > flags._flags; } - inline BaseFlags& BaseFlags::operator |= ( int flags ) { _flags |= (unsigned int)flags; return *this; } - inline BaseFlags& BaseFlags::operator &= ( int flags ) { _flags &= (unsigned int)flags; return *this; } - inline bool BaseFlags::operator == ( int flags ) const { return _flags == (unsigned int)flags; } - inline bool BaseFlags::operator != ( int flags ) const { return _flags != (unsigned int)flags; } - inline bool BaseFlags::operator < ( int flags ) const { return _flags < (unsigned int)flags; } - inline bool BaseFlags::operator > ( int flags ) const { return _flags > (unsigned int)flags; } - inline BaseFlags& BaseFlags::operator |= ( unsigned int flags ) { _flags |= flags; return *this; } - inline BaseFlags& BaseFlags::operator &= ( unsigned int flags ) { _flags &= flags; return *this; } - inline bool BaseFlags::operator == ( unsigned int flags ) const { return _flags == flags; } - inline bool BaseFlags::operator != ( unsigned int flags ) const { return _flags != flags; } - inline bool BaseFlags::operator < ( unsigned int flags ) const { return _flags < flags; } - inline bool BaseFlags::operator > ( unsigned int flags ) const { return _flags > flags; } + inline BaseFlags& BaseFlags::operator |= ( int flags ) { _flags |= (uint64_t)flags; return *this; } + inline BaseFlags& BaseFlags::operator &= ( int flags ) { _flags &= (uint64_t)flags; return *this; } + inline bool BaseFlags::operator == ( int flags ) const { return _flags == (uint64_t)flags; } + inline bool BaseFlags::operator != ( int flags ) const { return _flags != (uint64_t)flags; } + inline bool BaseFlags::operator < ( int flags ) const { return _flags < (uint64_t)flags; } + inline bool BaseFlags::operator > ( int flags ) const { return _flags > (uint64_t)flags; } + inline BaseFlags& BaseFlags::operator |= ( uint64_t flags ) { _flags |= flags; return *this; } + inline BaseFlags& BaseFlags::operator &= ( uint64_t flags ) { _flags &= flags; return *this; } + inline bool BaseFlags::operator == ( uint64_t flags ) const { return _flags == flags; } + inline bool BaseFlags::operator != ( uint64_t flags ) const { return _flags != flags; } + inline bool BaseFlags::operator < ( uint64_t flags ) const { return _flags < flags; } + inline bool BaseFlags::operator > ( uint64_t flags ) const { return _flags > flags; } inline BaseFlags::operator bool () const { return _flags != 0; } //inline BaseFlags::operator unsigned int () const { return _flags; } //inline BaseFlags::operator unsigned int () const { return _flags; } @@ -146,9 +147,9 @@ namespace Hurricane { return *this; } - inline BaseFlags BaseFlags::nthbit ( unsigned int nth ) const + inline BaseFlags BaseFlags::nthbit ( uint64_t nth ) const { - unsigned int select = 1; + uint64_t select = 1; for ( ; select ; select=select<<1 ) { if ( _flags & select ) nth--; if ( !nth ) break; diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp index 1eedbcef..79374676 100644 --- a/katabatic/src/KatabaticEngine.cpp +++ b/katabatic/src/KatabaticEngine.cpp @@ -145,7 +145,6 @@ namespace Katabatic { KatabaticEngine::KatabaticEngine ( Cell* cell ) : ToolEngine (cell) - , _timer () , _state (EngineCreation) , _flags (EngineDestroyBaseContact) , _configuration (new ConfigurationConcrete()) @@ -361,34 +360,13 @@ namespace Katabatic { } - void KatabaticEngine::startMeasures () - { - _timer.resetIncrease(); - _timer.start(); - } - - - void KatabaticEngine::stopMeasures () - { _timer.stop(); } - - void KatabaticEngine::printMeasures ( const string& tag ) const { - ostringstream result; + Super::printMeasures(); - result << Timer::getStringTime(_timer.getCombTime()) - << ", " << Timer::getStringMemory(_timer.getIncrease()); - cmess1 << Dots::asString( " - Done in", result.str() ) << endl; - - result.str(""); - result << _timer.getCombTime() - << "s, +" << (_timer.getIncrease()>>10) << "Kb/" - << Timer::getStringMemory(Timer::getMemorySize()); - cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl; - - if (not tag.empty()) { - addMeasure( getCell(), tag+"T", _timer.getCombTime () ); - addMeasure( getCell(), tag+"S", (_timer.getMemorySize() >> 20) ); + if (not tag.empty()) { + addMeasure( getCell(), tag+"T", getTimer().getCombTime () ); + addMeasure( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) ); } } diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index 9d40a84c..da003cfe 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -22,7 +22,6 @@ #include #include #include -#include "hurricane/Timer.h" #include "hurricane/DbU.h" #include "hurricane/Torus.h" #include "hurricane/Layer.h" @@ -91,6 +90,7 @@ namespace Katabatic { class KatabaticEngine : public ToolEngine { public: + typedef ToolEngine Super; typedef set NetSet; public: @@ -134,8 +134,6 @@ namespace Katabatic { inline void setGlobalThreshold ( DbU::Unit ); inline void setSaturateRatio ( float ); inline void setSaturateRp ( size_t ); - void startMeasures (); - void stopMeasures (); void printMeasures ( const string& ) const; void refresh ( unsigned int flags=KbOpenSession ); virtual void createDetailedGrid (); @@ -192,7 +190,6 @@ namespace Katabatic { protected: // Attributes. static Name _toolName; - Timer _timer; EngineState _state; unsigned int _flags; Configuration* _configuration; diff --git a/katana/src/CMakeLists.txt b/katana/src/CMakeLists.txt index e4cf1b27..3eed1b87 100644 --- a/katana/src/CMakeLists.txt +++ b/katana/src/CMakeLists.txt @@ -12,6 +12,7 @@ set( includes katana/Constants.h katana/TrackCost.h katana/DataNegociate.h + katana/DataSymmetric.h katana/TrackElement.h katana/TrackElements.h katana/TrackSegment.h katana/TrackFixedSegment.h @@ -40,6 +41,7 @@ set( cpps Constants.cpp Configuration.cpp DataNegociate.cpp + DataSymmetric.cpp TrackCost.cpp TrackElement.cpp TrackElements.cpp @@ -64,6 +66,7 @@ ProtectRoutingPads.cpp PreProcess.cpp GlobalRoute.cpp + SymmetricRoute.cpp KatanaEngine.cpp GraphicKatanaEngine.cpp ) diff --git a/katana/src/Constants.cpp b/katana/src/Constants.cpp index a1ad8eb1..13e8e283 100644 --- a/katana/src/Constants.cpp +++ b/katana/src/Constants.cpp @@ -21,17 +21,18 @@ namespace Katana { - const unsigned int Flags::AllowDoglegReuse = (1 << 20); - const unsigned int Flags::DataSelf = (1 << 21); - const unsigned int Flags::Nearest = (1 << 22); - const unsigned int Flags::Force = (1 << 23); - const unsigned int Flags::ResetCount = (1 << 24); - const unsigned int Flags::WithConstraints = (1 << 25); - const unsigned int Flags::MoveToLeft = (1 << 26); - const unsigned int Flags::MoveToRight = (1 << 27); - const unsigned int Flags::LoadingStage = (1 << 28); - const unsigned int Flags::SlowMotion = (1 << 29); - const unsigned int Flags::PreRoutedStage = (1 << 30); + const uint64_t Flags::AllowDoglegReuse = (1 << 20); + const uint64_t Flags::DataSelf = (1 << 21); + const uint64_t Flags::Nearest = (1 << 22); + const uint64_t Flags::Force = (1 << 23); + const uint64_t Flags::ResetCount = (1 << 24); + const uint64_t Flags::WithConstraints = (1 << 25); + const uint64_t Flags::MoveToLeft = (1 << 26); + const uint64_t Flags::MoveToRight = (1 << 27); + const uint64_t Flags::LoadingStage = (1 << 28); + const uint64_t Flags::SlowMotion = (1 << 29); + const uint64_t Flags::PreRoutedStage = (1 << 30); + const uint64_t Flags::SymmetricStage = (1 << 31); } // Anabatic namespace. diff --git a/katana/src/DataSymmetric.cpp b/katana/src/DataSymmetric.cpp new file mode 100644 index 00000000..f0b44a6c --- /dev/null +++ b/katana/src/DataSymmetric.cpp @@ -0,0 +1,269 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | 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@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DataSymmetric.cpp" | +// +-----------------------------------------------------------------+ + +#include "anabatic/AutoSegment.h" +#include "katana/DataSymmetric.h" + + +namespace { + + using namespace std; + + + class Message { + public: + inline Message ( size_t, string header="" ); + inline size_t size () const; + inline ostringstream& newline (); + inline ostringstream& line (); + inline void setHeader ( string ); + void print ( ostream& ); + private: + size_t _indent; + string _header; + vector _lines; + ostringstream _current; + }; + + + inline Message::Message ( size_t indent, string header ) + : _indent (indent) + , _header (header) + , _lines () + , _current() + { } + + inline size_t Message::size () const { return _lines.size(); } + inline void Message::setHeader ( string header ) { _header = header; } + inline ostringstream& Message::line () { return _current; } + + inline ostringstream& Message::newline () + { + if (_current.str().size()) + _lines.push_back(_current.str()); + _current.str(""); + return _current; + } + + void Message::print ( ostream& o ) + { + if (not _header.empty()) _indent = _header.size()+1; + + string head ( _indent, ' ' ); + for ( size_t i=0 ; i<_lines.size() ; ++i ) { + if ((i == 0) and not _header.empty()) o << _header << " "; + else o << head; + o << _lines[i] << endl; + } + } + + +} // Anonymous namespace. + + +namespace Katana { + + using namespace std; + using Anabatic::AutoSegmentFlag; + + + DataSymmetric* DataSymmetric::create ( Net* net ) + { + NetRoutingState* state = NetRoutingExtension::get( net ); + + if (not state or not state->isSymmetric()) return NULL; + if (state->getSymNet() and not state->isSymMaster()) return NULL; + + return new DataSymmetric ( net ); + } + + + DataSymmetric::DataSymmetric ( Net* net ) + : _valid (true) + , _net (net) + , _symNet (NULL) + , _state (NetRoutingExtension::get(_net)) + , _paireds () + , _symIndex(0) + { + _symNet = _state->getSymNet(); + } + + + void DataSymmetric::addSymmetrical ( AutoSegment* symmetrical ) + { + if (_paireds.size() > _symIndex) _paireds[_symIndex++][1] = symmetrical; + else _paireds.push_back( { NULL, symmetrical } ); + } + + + AutoSegment* DataSymmetric::getSymmetrical ( AutoSegment* segment ) const + { + for ( const array& paired : _paireds ) { + if (segment == paired[0]) return paired[1]; + if (segment == paired[1]) return paired[0]; + } + return NULL; + } + + + bool DataSymmetric::checkPairing () + { + const unsigned int mask = ~(AutoSegmentFlag::SegIsReduced); + Message errors ( 0, "[ERROR]" ); + + size_t refs = 0; + size_t syms = 0; + for ( const array& paired : _paireds ) { + refs += (paired[0]) ? 1 : 0; + syms += (paired[1]) ? 1 : 0; + } + if (refs != syms) { + errors.newline() << "Segments symmetric sets size mismatch, reference:" << refs + << " symmetricals:" << syms << "."; + _valid = false; + } else { + size_t index = 0; + for ( const array& paired : _paireds ) { + if (paired[0]->isHorizontal() xor paired[1]->isHorizontal()) { + errors.newline() << "Direction mismatch @ [" << index << "]"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + + if (paired[0]->getLayer() != paired[1]->getLayer()) { + errors.newline() << "Layer mismatch @ [" << index << "]"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + + if (_state->isSymVertical()) { + if (paired[0]->isVertical()) { + if ( (paired[0]->getFlags() ^ paired[1]->getFlags()) & mask ) { + errors.newline() << "Flags mismatch at index " << index + << " " << paired[0]->getFlags() + << " vs. " << paired[1]->getFlags(); + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + + if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { + errors.newline() << "Mirror axis mismatch @ [" << index << "] " + << DbU::getValueString(paired[1]->getAxis()) << " (should be: " + << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + } else { + if ( (paired[0]->getFlags() ^ AutoSegment::swapSourceTargetFlags(paired[1])) & mask ) { + errors.newline() << "Flags mismatch at index " << index + << " " << paired[0]->getFlags() + << " vs. " << paired[1]->getFlags() + << " swp " << AutoSegment::swapSourceTargetFlags(paired[1]); + _valid = false; + } + + if (paired[0]->getAxis() != paired[1]->getAxis()) { + errors.newline() << "Axis mismatch index " << index << " " + << DbU::getValueString(paired[1]->getAxis()) << " (should be:" + << DbU::getValueString(paired[0]->getAxis()) << ")"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + } + } else { + if (paired[0]->isHorizontal()) { + if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { + errors.newline() << "Mirror axis mismatch index " << index << " " + << DbU::getValueString(paired[1]->getAxis()) << " (should be:" + << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + } else { + if (paired[0]->getAxis() != paired[1]->getAxis()) { + errors.newline() << "Axis mismatch index " << index << " " + << DbU::getValueString(paired[1]->getAxis()) << " (should be:" + << DbU::getValueString(paired[0]->getAxis()) << ")"; + errors.newline() << "| " << paired[0]; + errors.newline() << "| " << paired[1]; + _valid = false; + } + } + } + + ++index; + } + } + + + errors.newline(); + if (errors.size()) { + cmess2 << " pairing failed." << endl; + errors.print( cmess2 ); + } else { + cmess2 << " paired." << endl; + } + + return _valid; + } + + + void DataSymmetric::print ( ostream& o ) const + { + Message lines ( 0 ); + + lines.newline() << "Paired components of Net \"" << _net->getName() << "\""; + if (_symNet) lines.line() << " (symmetrical:\"" << _symNet->getName() << "\")"; + + size_t index = 0; + for ( const array& paired : _paireds ) { + lines.newline() << "| " << setw(2) << index << " " << paired[0]; + lines.newline() << "+ " << setw(2) << index << " " << paired[1]; + ++index; + } + + lines.newline(); + lines.print( o ); + } + + + string DataSymmetric::_getString () const + { + return "getName()) + ">"; + } + + + Record* DataSymmetric::_getRecord () const + { + Record* record = new Record ( getString(this) ); + record->add( getSlot( "_valid" , _valid ) ); + record->add( getSlot( "_net" , _net ) ); + record->add( getSlot( "_symNet" , _symNet ) ); + record->add( getSlot( "_state" , _state ) ); + record->add( getSlot( "_paireds" , &_paireds ) ); + record->add( getSlot( "_symIndex" , &_symIndex ) ); + + return record; + } + + +} // Katana namespace. diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index c94f4415..1a7ff74d 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -231,10 +231,10 @@ namespace Katana { void GraphicKatanaEngine::_loadGlobalRouting () { - KatanaEngine* anabatic = getForFramework( NoFlags ); + KatanaEngine* katana = getForFramework( NoFlags ); _viewer->clearToolInterrupt(); - anabatic->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); + katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); } @@ -273,7 +273,12 @@ namespace Katana { void GraphicKatanaEngine::_runTest () { KatanaEngine* katana = getForFramework( NoFlags ); - if (katana) katana->runTest(); + if (katana) { + katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); + katana->runTest(); + katana->runNegociate( Flags::SymmetricStage ); + katana->runNegociate(); + } } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 1898b15f..3aaf36cc 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -256,9 +256,6 @@ namespace Katana { KatanaEngine* KatanaEngine::create ( Cell* cell ) { - cmess1 << Dots::asString( " - Initial memory" - , Timer::getStringMemory(Timer::getMemorySize()) ) << endl; - KatanaEngine* katana = new KatanaEngine ( cell ); katana->_postCreate(); @@ -340,6 +337,13 @@ namespace Katana { } + DataSymmetric* KatanaEngine::getDataSymmetric ( Net* net ) + { + auto idata = _symmetrics.find( net ); + if (idata != _symmetrics.end()) return (*idata).second; + return NULL; + } + void KatanaEngine::openSession () { Session::_open(this); } @@ -353,6 +357,26 @@ namespace Katana { } + DataSymmetric* KatanaEngine::addDataSymmetric ( Net* net ) + { + DataSymmetric* data = getDataSymmetric( net ); + if (data) { + cerr << Error( "KatanaEngine::addDataSymmetric(): Try to add twice Net \"%s\" (ignored)." + , getString(net->getName()).c_str() ) << endl; + return data; + } + + data = DataSymmetric::create( net ); + if (data) { + _symmetrics.insert( make_pair(net,data) ); + if (data->getSymNet()) + _symmetrics.insert( make_pair(data->getSymNet(),data) ); + } + + return data; + } + + void KatanaEngine::annotateGlobalGraph () { cmess1 << " o Back annotate global routing graph." << endl; @@ -649,6 +673,10 @@ namespace Katana { for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { _routingPlanes[depth]->destroy(); } + _routingPlanes.clear(); + + for ( auto symmetric : _symmetrics ) delete symmetric.second; + _symmetrics.clear(); Session::close(); } @@ -702,8 +730,9 @@ namespace Katana { Record* record = Super::_getRecord (); if (record) { - record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); record->add( getSlot( "_configuration", _configuration ) ); + record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); + record->add( getSlot( "_symmetrics" , &_symmetrics ) ); } return record; } diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index f816be8e..3b8cc2a6 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -552,6 +552,11 @@ namespace Katana { Session::getKatanaEngine()->_check( overlaps, "after _createRouting(GCell*)" ); #endif + if (flags & Flags::SymmetricStage) { + _katana->runSymmetricRouter(); + Session::revalidate(); + } + _flags |= flags; _negociate(); printStatistics(); diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 8bb17e42..ef368468 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -43,8 +43,8 @@ namespace { void getPerpandiculars ( TrackElement* segment - , Anabatic::AutoContact* from - , unsigned int direction + , Anabatic::AutoContact* from + , Flags direction , vector& perpandiculars ) { @@ -69,7 +69,7 @@ namespace { } - void findFailedPerpandiculars ( RoutingPad* rp, unsigned int direction, set& faileds ) + void findFailedPerpandiculars ( RoutingPad* rp, Flags direction, set& faileds ) { cdebug_log(159,0) << "Find failed caging: " << rp << endl; diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 051d168c..a1f5b6a3 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -98,6 +98,10 @@ namespace Katana { { return Session::getKatanaEngine()->getConfiguration(); } + AutoContact* Session::lookup ( Contact* contact ) + { return Super::lookup(contact); } + + TrackElement* Session::lookup ( Segment* segment ) { return Session::get("Session::lookup(Segment*)")->_getKatanaEngine()->_lookup(segment); } diff --git a/katana/src/SymmetricRoute.cpp b/katana/src/SymmetricRoute.cpp new file mode 100644 index 00000000..933d9347 --- /dev/null +++ b/katana/src/SymmetricRoute.cpp @@ -0,0 +1,372 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2014-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | 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 : "./SymmetricRoute.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/NetRoutingProperty.h" +#include "hurricane/RoutingPad.h" +#include "anabatic/AutoContactTerminal.h" +#include "katana/RoutingPlane.h" +#include "katana/TrackFixedSegment.h" +#include "katana/Track.h" +#include "katana/KatanaEngine.h" + + +namespace { + + using namespace std; + using Hurricane::Error; + using Hurricane::DebugSession; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Net; + using Hurricane::NetRoutingState; + using Hurricane::NetRoutingExtension; + using Hurricane::Component; + using Hurricane::Contact; + using Hurricane::Segment; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Anabatic::Flags; + using Anabatic::GCell; + using Anabatic::AutoContact; + using Anabatic::AutoContactTerminal; + using Anabatic::AutoSegment; + using Anabatic::AutoSegmentFlag; + using Katana::KatanaEngine; + using Katana::DataSymmetric; + using Katana::Session; + + + class Message { + public: + inline Message ( size_t, string header="" ); + inline size_t size () const; + inline ostringstream& newline (); + inline ostringstream& line (); + inline void setHeader ( string ); + void print ( ostream& ); + private: + size_t _indent; + string _header; + vector _lines; + ostringstream _current; + }; + + + inline Message::Message ( size_t indent, string header ) + : _indent (indent) + , _header (header) + , _lines () + , _current() + { } + + inline size_t Message::size () const { return _lines.size(); } + inline void Message::setHeader ( string header ) { _header = header; } + inline ostringstream& Message::line () { return _current; } + + inline ostringstream& Message::newline () + { + if (_current.str().size()) + _lines.push_back(_current.str()); + _current.str(""); + return _current; + } + + void Message::print ( ostream& o ) + { + if (not _header.empty()) _indent = _header.size()+1; + + string head ( _indent, ' ' ); + for ( size_t i=0 ; i<_lines.size() ; ++i ) { + if ((i == 0) and not _header.empty()) o << _header << " "; + else o << head; + o << _lines[i] << endl; + } + } + + + class TopologicalPairing { + public: + TopologicalPairing ( KatanaEngine*, Net* ); + bool doPairing (); + void _doSelfPairing (); + void _doDualPairing (); + AutoContactTerminal* _getSymmetricTerminal ( AutoContactTerminal* masterContact ); + Component* _findMiddleComponent (); + private: + KatanaEngine* _katana; + AutoSegment* _seed; + DataSymmetric* _data; + }; + + + TopologicalPairing::TopologicalPairing ( KatanaEngine* katana, Net* net ) + : _katana (katana) + , _seed (NULL) + , _data (NULL) + { + _data = _katana->getDataSymmetric( net ); + if (not _data) + _data = _katana->addDataSymmetric( net ); + + if (_data and (_data->getNet() != net) ) _data = NULL; + } + + + bool TopologicalPairing::doPairing () + { + if (not _data) return false; + if (not _data->isValid()) return _data->isValid(); + + DebugSession::open( _data->getNet(), 144, 146 ); + + cmess2 << " - Net: \"" << _data->getNet()->getName() << "\" "; + cmess2 << "@" << DbU::getValueString(_data->getSymAxis()) << " "; + cmess2 << (_data->isSymVertical() ? "Vertical" : "Horizontal") << " "; + if (_data->getSymNet()) cmess2 << "(paired: \"" << _data->getSymNet()->getName() << "\")"; + else cmess2 << "(self symmetric)"; + + if (_data->getSymNet()) _doDualPairing(); + else _doSelfPairing(); + + if (_data->isValid()) _data->checkPairing(); + + DebugSession::close(); + + return _data->isValid(); + } + + + void TopologicalPairing::_doSelfPairing () + { + Component* middle = _findMiddleComponent(); + + AutoSegment* _seed = Session::base()->lookup( dynamic_cast( middle ) ); + if (_seed) { + for ( AutoSegment* segment : _seed->getConnecteds(Flags::Source) ) + _data->addReference( segment ); + + for ( AutoSegment* segment : _seed->getConnecteds(Flags::Target) ) + _data->addSymmetrical( segment ); + } + } + + + void TopologicalPairing::_doDualPairing () + { + for ( Contact* terminal : _data->getNet()->getContacts() ) { + AutoContactTerminal* autoTerminal = dynamic_cast(Session::lookup( terminal )); + if (autoTerminal) { + if (not autoTerminal->isEndPoint()) continue; + + _seed = autoTerminal->getSegment(); + unsigned int flags = (_seed->getAutoSource() == autoTerminal) ? Flags::Target : Flags::Source; + for ( AutoSegment* segment : _seed->getConnecteds(flags) ) + _data->addReference( segment ); + + AutoContactTerminal* symTerminal = _getSymmetricTerminal( autoTerminal ); + if (not symTerminal) { _data->setValid( false ); break; } + + AutoSegment* symSeed = symTerminal->getSegment(); + if (not symSeed) { _data->setValid( false ); break; } + + flags = (symSeed->getAutoSource() == symTerminal) ? Flags::Target : Flags::Source; + for ( AutoSegment* segment : symSeed->getConnecteds(flags) ) { + _data->addSymmetrical( segment ); + } + + break; + } + } + } + + + AutoContactTerminal* TopologicalPairing::_getSymmetricTerminal ( AutoContactTerminal* masterContact ) + { + Point mirror = masterContact->getCenter(); + _data->getSymmetrical( mirror ); + + GCell* mirrorGCell = _katana->getGCellUnder( mirror ); + if (not mirrorGCell) { + cerr << Error( "getSymmetricTerminal() No GCell under symmetric position (%s,%s)." + , DbU::getValueString(mirror.getX()).c_str() + , DbU::getValueString(mirror.getY()).c_str() + ) << endl; + _data->setValid( false ); + return NULL; + } + + for ( AutoContact* mirrorContact : mirrorGCell->getContacts() ) { + if (mirrorContact->getNet() == _data->getSymNet()) { + AutoContactTerminal* symContact = dynamic_cast( mirrorContact ); + if (symContact) return symContact; + } + } + + cerr << Error( "getSymmetricTerminal() Missing terminal contact in symmetric GCell." + ) << endl; + + _data->setValid( false ); + return NULL; + } + + + Component* TopologicalPairing::_findMiddleComponent () + { + DbU::Unit axis = _data->getSymAxis(); + Component* middle = NULL; + + if (_data->isSymVertical()) { + for ( Component* component : _data->getNet()->getComponents() ) { + Horizontal* horizontal = dynamic_cast(component); + if (horizontal) { + if ( (horizontal->getSourceX() < axis) and (axis < horizontal->getTargetX()) ) { + if (not middle) middle = horizontal; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Horizontal candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(horizontal).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + + Vertical* vertical = dynamic_cast(component); + if (vertical) { + if (vertical->getSourceX() == axis) { + if (not middle) middle = vertical; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Vertical candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(vertical).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + + RoutingPad* rp = dynamic_cast(component); + if (rp) { + if ( (rp->getSourcePosition().getX() < axis) and (axis < rp->getTargetPosition().getX()) ) { + if (not middle) middle = rp; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Horizontal candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(rp).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + } + } else { + for ( Component* component : _data->getNet()->getComponents() ) { + Vertical* vertical = dynamic_cast(component); + if (vertical) { + if ( (vertical->getSourceY() < axis) and (axis > vertical->getTargetY()) ) { + if (not middle) middle = vertical; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Vertical candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(vertical).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + + Horizontal* horizontal = dynamic_cast(component); + if (horizontal) { + if (horizontal->getSourceY() == axis) { + if (not middle) middle = horizontal; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Horizontal candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(horizontal).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + + RoutingPad* rp = dynamic_cast(component); + if (rp) { + if ( (rp->getSourcePosition().getY() < axis) and (axis > rp->getTargetPosition().getY()) ) { + if (not middle) middle = rp; + else { + cerr << Error( "::findMiddleComponent(): Multiple middle Horizontal candidates on \"%s\"\n" + " %s\n" + " %s" + , getString(_data->getNet()->getName()).c_str() + , getString(middle).c_str() + , getString(rp).c_str() + ) << endl; + _data->setValid( false ); + break; + } + } + } + } + } + + return middle; + } + + +} // Anonymous namespace. + + +namespace Katana { + + using namespace std; + + + void KatanaEngine::runSymmetricRouter () + { + for ( Net* net : getCell()->getNets() ) { + TopologicalPairing(this,net).doPairing(); + } + } + + + +} // Katana namespace. diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 6b2056b6..232af4bc 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -510,7 +510,7 @@ namespace Katana { { if (not hasSourceDogleg()) return NULL; - unsigned int direction = perpandicularTo( getDirection() ); + Flags direction = perpandicularTo( getDirection() ); TrackElement* dogleg = NULL; for( Segment* segment : base()->getAutoSource()->getSlaveComponents().getSubSet() ) { dogleg = Session::lookup( segment ); @@ -527,7 +527,7 @@ namespace Katana { { if (not hasSourceDogleg()) return NULL; - unsigned int direction = perpandicularTo( getDirection() ); + Flags direction = perpandicularTo( getDirection() ); TrackElement* dogleg = NULL; for( Segment* segment : base()->getAutoTarget()->getSlaveComponents().getSubSet() ) { dogleg = Session::lookup( segment ); diff --git a/katana/src/katana/Constants.h b/katana/src/katana/Constants.h index d78ef7ed..8ecf5093 100644 --- a/katana/src/katana/Constants.h +++ b/katana/src/katana/Constants.h @@ -26,24 +26,25 @@ namespace Katana { public: typedef Anabatic::Flags Super; public: - static const unsigned int AllowDoglegReuse; - static const unsigned int DataSelf; - static const unsigned int Nearest; - static const unsigned int Force; - static const unsigned int ResetCount; - static const unsigned int WithConstraints; - static const unsigned int MoveToLeft; - static const unsigned int MoveToRight; - static const unsigned int LoadingStage; - static const unsigned int SlowMotion; - static const unsigned int PreRoutedStage; + static const uint64_t AllowDoglegReuse; + static const uint64_t DataSelf; + static const uint64_t Nearest; + static const uint64_t Force; + static const uint64_t ResetCount; + static const uint64_t WithConstraints; + static const uint64_t MoveToLeft; + static const uint64_t MoveToRight; + static const uint64_t LoadingStage; + static const uint64_t SlowMotion; + static const uint64_t PreRoutedStage; + static const uint64_t SymmetricStage; public: - inline Flags ( unsigned int ); + inline Flags ( uint64_t ); inline Flags ( const Super& ); }; - inline Flags::Flags ( unsigned int flags ) : Super(flags) { } + inline Flags::Flags ( uint64_t flags ) : Super(flags) { } inline Flags::Flags ( const Flags::Super& base ) : Super(base) { } diff --git a/katana/src/katana/DataSymmetric.h b/katana/src/katana/DataSymmetric.h new file mode 100644 index 00000000..547269ff --- /dev/null +++ b/katana/src/katana/DataSymmetric.h @@ -0,0 +1,97 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | 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@lip6.fr | +// | =============================================================== | +// | C++ Header : "./katana/DataSymmetric.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KATANA_DATA_SYMMETRIC_H +#define KATANA_DATA_SYMMETRIC_H + +#include +#include +#include +#include "hurricane/Net.h" +#include "hurricane/NetRoutingProperty.h" + +namespace Hurricane { + class Record; +} + +namespace Anabatic { + class AutoSegment; +} + + +namespace Katana { + + using Hurricane::Record; + using Hurricane::DbU; + using Hurricane::Point; + using Hurricane::Net; + using Hurricane::NetRoutingState; + using Hurricane::NetRoutingExtension; + using Anabatic::AutoSegment; + + + class DataSymmetric { + public: + static DataSymmetric* create ( Net* ); + public: + inline bool isValid () const; + inline bool isSymVertical () const; + inline Net* getNet () const; + inline DbU::Unit getSymAxis () const; + inline Net* getSymNet () const; + inline Point& getSymmetrical ( Point& ) const; + AutoSegment* getSymmetrical ( AutoSegment* ) const; + void addSymmetrical ( AutoSegment* ); + inline void addReference ( AutoSegment* ); + inline void setValid ( bool ); + bool checkPairing (); + void print ( std::ostream& ) const; + Record* _getRecord () const; + std::string _getString () const; + private: + DataSymmetric ( Net* ); + private: + bool _valid; + Net* _net; + Net* _symNet; + NetRoutingState* _state; + std::vector< std::array > _paireds; + size_t _symIndex; + }; + + + inline bool DataSymmetric::isValid () const { return _valid; } + inline bool DataSymmetric::isSymVertical () const { return _state->isSymVertical(); } + inline Net* DataSymmetric::getNet () const { return _net; } + inline DbU::Unit DataSymmetric::getSymAxis () const { return _state->getSymAxis(); } + inline Net* DataSymmetric::getSymNet () const { return _symNet; } + inline void DataSymmetric::addReference ( AutoSegment* segment ) { _paireds.push_back( {segment,NULL} ); } + inline void DataSymmetric::setValid ( bool state ) { _valid = state; } + + inline Point& DataSymmetric::getSymmetrical ( Point& point ) const + { + if (_state->isSymVertical()) point.setX( 2*getSymAxis() - point.getX() ); + else point.setY( 2*getSymAxis() - point.getY() ); + return point; + } + + +} // Katana namespace. + +#endif // KATANA_DATA_SYMMETRIC_H + + +INSPECTOR_P_SUPPORT(Katana::DataSymmetric); diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index ca0cba61..86368737 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -37,6 +37,7 @@ namespace Knik { #include "katana/Constants.h" #include "katana/TrackElement.h" #include "katana/Configuration.h" +#include "katana/DataSymmetric.h" namespace Katana { @@ -85,6 +86,7 @@ namespace Katana { RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const; RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; + DataSymmetric* getDataSymmetric ( Net* ); inline void printConfiguration () const; void printCompletion () const; void dumpMeasures ( std::ostream& ) const; @@ -98,6 +100,7 @@ namespace Katana { inline void setRipupCost ( unsigned int ); inline void setHTracksReservedLocal ( size_t ); inline void setVTracksReservedLocal ( size_t ); + DataSymmetric* addDataSymmetric ( Net* ); void setupPowerRails (); void protectRoutingPads (); void preProcess (); @@ -110,6 +113,7 @@ namespace Katana { void analogInit (); void runNegociate ( unsigned int flags=Flags::NoFlags ); void runGlobalRouter (); + void runSymmetricRouter (); void runTest (); virtual void finalizeLayout (); void _runKatanaInit (); @@ -124,14 +128,15 @@ namespace Katana { virtual string _getTypeName () const; private: // Attributes. - static Name _toolName; - protected: - CellViewer* _viewer; - Configuration* _configuration; - vector _routingPlanes; - NegociateWindow* _negociateWindow; - double _minimumWL; - mutable bool _toolSuccess; + static Name _toolName; + protected: + CellViewer* _viewer; + Configuration* _configuration; + vector _routingPlanes; + NegociateWindow* _negociateWindow; + double _minimumWL; + std::map _symmetrics; + mutable bool _toolSuccess; protected: // Constructors & Destructors. KatanaEngine ( Cell* ); diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index 6f09de75..01dd6eeb 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/SegmentFsm.h" | +// | C++ Header : "./katana/SegmentFsm.h" | // +-----------------------------------------------------------------+ diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index a5bb9811..16edc456 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -24,12 +24,14 @@ namespace Hurricane { class Record; class Net; + class Contact; class Segment; } #include "anabatic/Session.h" namespace Anabatic { class GCell; + class AutoContact; class AutoSegment; } @@ -41,8 +43,10 @@ namespace Katana { using std::string; using Hurricane::Record; using Hurricane::Net; + using Hurricane::Contact; using Hurricane::Segment; using Hurricane::DbU; + using Anabatic::AutoContact; using Anabatic::AutoSegment; class Track; @@ -77,6 +81,7 @@ namespace Katana { inline static void addMoveEvent ( TrackElement* , Track* ); inline static void addSortEvent ( Track*, bool forced=false ); inline static size_t revalidate (); + static AutoContact* lookup ( Contact* ); static TrackElement* lookup ( Segment* ); static TrackElement* lookup ( AutoSegment* ); static Session* _open ( KatanaEngine* );