Apaired segments building for symmetric routing (step 1).

* Change: In Hurricane::BaseFlags, store flags in uint64_t instead of
    unsigned int because we start to need more than 32 different flags
    in some tools.
* New: In ::getString() & ::getRecord() templates, add support for
    std::array<>.
* Change: In CRL::ToolEngine, add support for timer (time & memory
    measurements) displaced from Katabatic. This way all ToolEngine
    can use this feature. The _postCreate() method display the
    memory just after ToolEngine allocation.
* Change: In Etesian::EtesianEngine, make use of the ToolEngine
    builtin timer (remove the local one). Forgot to call the base
    class _postCreate() and _preDestroy().
* Change: In Anabatic::AnabaticEngine, make use of the ToolEngine
    builtin timer (remove the local one).
* New: In Anabatic, new AutoSegments_Connecteds() collection. This
    Collection allows a deterministic walkthough *all* the AutoSegments
    connected either to source or target of one AutoSegment.
* New: In Anabatic::AutoContactTerminal::isEndPoint() to check if an
    AutoContactTerminal is the *only one* anchored on a RoutingPad,
    thus being a true "end point" and not a kind of feed-through.
* New: In Katana::KatanaEngine, added support for symmetric nets.
    Created new class DataSymmetric to store symmetric information
    of a net (mainly the paired AutoSegments).
      Added KatanaEngine::runSymmetricRouter(), for now only build
    the DataSymmetric informations. More to come...
* Change: In Katana::GraphicKatanaEngine::_runTest(), now perform
    symmetric information building the non-symmetric routing.
This commit is contained in:
Jean-Paul Chaput 2017-03-12 19:34:12 +01:00
parent b820d22daa
commit b99a362509
36 changed files with 1580 additions and 376 deletions

View File

@ -198,7 +198,6 @@ namespace Anabatic {
AnabaticEngine::AnabaticEngine ( Cell* cell ) AnabaticEngine::AnabaticEngine ( Cell* cell )
: Super(cell) : Super(cell)
, _timer ()
, _configuration (new Configuration()) , _configuration (new Configuration())
, _chipTools (cell) , _chipTools (cell)
, _state (EngineCreation) , _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 () void AnabaticEngine::updateDensity ()
{ for ( GCell* gcell : _gcells ) gcell->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<double>( getCell(), tag+"T", getTimer().getCombTime () );
// addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
// }
}
string AnabaticEngine::_getTypeName () const string AnabaticEngine::_getTypeName () const
{ return getString(_toolName); } { return getString(_toolName); }

View File

@ -121,6 +121,13 @@ namespace Anabatic {
{ } { }
bool AutoContactTerminal::isEndPoint () const
{
RoutingPad* rp = dynamic_cast<RoutingPad*>( getAnchor() );
return (rp->getBodyHook()->getSlaveHooks().getSize() == 1);
}
AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const
{ return NULL; } { return NULL; }
@ -141,6 +148,14 @@ namespace Anabatic {
} }
RoutingPad* AutoContactTerminal::getRoutingPad () const
{ return dynamic_cast<RoutingPad*>(getAnchor()); }
AutoSegments AutoContactTerminal::getRpConnecteds () const
{ return AutoSegments_OnRoutingPad(this); }
Box AutoContactTerminal::getNativeConstraintBox () const Box AutoContactTerminal::getNativeConstraintBox () const
{ {
cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl; cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl;

View File

@ -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 () AutoSegments AutoSegment::getPerpandiculars ()
{ return AutoSegments_Perpandiculars( this ); } { return AutoSegments_Perpandiculars( this ); }

View File

@ -15,7 +15,8 @@
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "anabatic/AutoContact.h" #include "hurricane/RoutingPad.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoSegment.h" #include "anabatic/AutoSegment.h"
@ -27,7 +28,7 @@ namespace Anabatic {
using Hurricane::Error; using Hurricane::Error;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::Hook; 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<Segment*>(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<const AutoContactTerminal*>(contact))
{
if (_contact)
_routingPad = dynamic_cast<RoutingPad*>(_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<AutoContactTerminal*>( 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". // Class : "AutoSegments_Aligneds".

View File

@ -22,67 +22,67 @@ namespace Anabatic {
using std::string; using std::string;
const unsigned int Flags::NoFlags = 0; const uint64_t Flags::NoFlags = 0;
// Flags used for both objects states & functions arguments. // Flags used for both objects states & functions arguments.
const unsigned int Flags::Horizontal = (1 << 0); const uint64_t Flags::Horizontal = (1 << 0);
const unsigned int Flags::Vertical = (1 << 1); const uint64_t Flags::Vertical = (1 << 1);
const unsigned int Flags::Source = (1 << 2); const uint64_t Flags::Source = (1 << 2);
const unsigned int Flags::Target = (1 << 3); const uint64_t Flags::Target = (1 << 3);
const unsigned int Flags::Invalidated = (1 << 4); const uint64_t Flags::Invalidated = (1 << 4);
// Flags for GCell objects states only. // Flags for GCell objects states only.
const unsigned int Flags::DeviceGCell = (1 << 5); const uint64_t Flags::DeviceGCell = (1 << 5);
const unsigned int Flags::HChannelGCell = (1 << 6); const uint64_t Flags::HChannelGCell = (1 << 6);
const unsigned int Flags::VChannelGCell = (1 << 7); const uint64_t Flags::VChannelGCell = (1 << 7);
const unsigned int Flags::StrutGCell = (1 << 8); const uint64_t Flags::StrutGCell = (1 << 8);
const unsigned int Flags::MatrixGCell = (1 << 9); const uint64_t Flags::MatrixGCell = (1 << 9);
const unsigned int Flags::IoPadGCell = (1 << 10); const uint64_t Flags::IoPadGCell = (1 << 10);
const unsigned int Flags::Saturated = (1 << 11); const uint64_t Flags::Saturated = (1 << 11);
// Flags for Anabatic objects states only. // Flags for Anabatic objects states only.
const unsigned int Flags::DemoMode = (1 << 5); const uint64_t Flags::DemoMode = (1 << 5);
const unsigned int Flags::WarnOnGCellOverload = (1 << 6); const uint64_t Flags::WarnOnGCellOverload = (1 << 6);
const unsigned int Flags::DestroyGCell = (1 << 7); const uint64_t Flags::DestroyGCell = (1 << 7);
const unsigned int Flags::DestroyBaseContact = (1 << 8); const uint64_t Flags::DestroyBaseContact = (1 << 8);
const unsigned int Flags::DestroyBaseSegment = (1 << 9); const uint64_t Flags::DestroyBaseSegment = (1 << 9);
// Flags for NetDatas objects states only. // Flags for NetDatas objects states only.
const unsigned int Flags::GlobalRouted = (1 << 5); const uint64_t Flags::GlobalRouted = (1 << 5);
// Masks. // Masks.
const unsigned int Flags::WestSide = Horizontal|Target; const uint64_t Flags::WestSide = Horizontal|Target;
const unsigned int Flags::EastSide = Horizontal|Source; const uint64_t Flags::EastSide = Horizontal|Source;
const unsigned int Flags::SouthSide = Vertical |Target; const uint64_t Flags::SouthSide = Vertical |Target;
const unsigned int Flags::NorthSide = Vertical |Source; const uint64_t Flags::NorthSide = Vertical |Source;
const unsigned int Flags::AllSides = WestSide|EastSide|SouthSide|NorthSide ; const uint64_t Flags::AllSides = WestSide|EastSide|SouthSide|NorthSide ;
const unsigned int Flags::EndsMask = Source|Target; const uint64_t Flags::EndsMask = Source|Target;
const unsigned int Flags::DirectionMask = Horizontal|Vertical; const uint64_t Flags::DirectionMask = Horizontal|Vertical;
const unsigned int Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; const uint64_t Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
const unsigned int Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; const uint64_t Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
// Flags for functions arguments only. // Flags for functions arguments only.
const unsigned int Flags::Create = (1 << 5); const uint64_t Flags::Create = (1 << 5);
const unsigned int Flags::WithPerpands = (1 << 6); const uint64_t Flags::WithPerpands = (1 << 6);
const unsigned int Flags::WithSelf = (1 << 7); const uint64_t Flags::WithSelf = (1 << 7);
const unsigned int Flags::AboveLayer = (1 << 8); const uint64_t Flags::AboveLayer = (1 << 8);
const unsigned int Flags::BelowLayer = (1 << 9); const uint64_t Flags::BelowLayer = (1 << 9);
const unsigned int Flags::OpenSession = (1 << 10); const uint64_t Flags::OpenSession = (1 << 10);
const unsigned int Flags::Realignate = (1 << 11); const uint64_t Flags::Realignate = (1 << 11);
const unsigned int Flags::NativeConstraints = (1 << 12); const uint64_t Flags::NativeConstraints = (1 << 12);
const unsigned int Flags::ForceMove = (1 << 13); const uint64_t Flags::ForceMove = (1 << 13);
const unsigned int Flags::WarnOnError = (1 << 14); const uint64_t Flags::WarnOnError = (1 << 14);
const unsigned int Flags::Topology = (1 << 15); const uint64_t Flags::Topology = (1 << 15);
const unsigned int Flags::GlobalSegment = (1 << 16); const uint64_t Flags::GlobalSegment = (1 << 16);
const unsigned int Flags::AllowTerminal = (1 << 17); const uint64_t Flags::AllowTerminal = (1 << 17);
const unsigned int Flags::AllowLocal = (1 << 18); const uint64_t Flags::AllowLocal = (1 << 18);
const unsigned int Flags::IgnoreContacts = (1 << 19); const uint64_t Flags::IgnoreContacts = (1 << 19);
const unsigned int Flags::Propagate = (1 << 20); const uint64_t Flags::Propagate = (1 << 20);
const unsigned int Flags::Superior = (1 << 21); const uint64_t Flags::Superior = (1 << 21);
const unsigned int Flags::DoglegOnLeft = (1 << 22); const uint64_t Flags::DoglegOnLeft = (1 << 22);
const unsigned int Flags::DoglegOnRight = (1 << 23); const uint64_t Flags::DoglegOnRight = (1 << 23);
const unsigned int Flags::WithNeighbors = (1 << 24); const uint64_t Flags::WithNeighbors = (1 << 24);
const unsigned int Flags::NoCheckLayer = (1 << 25); const uint64_t Flags::NoCheckLayer = (1 << 25);
const unsigned int Flags::HalfSlacken = (1 << 26); const uint64_t Flags::HalfSlacken = (1 << 26);
const unsigned int Flags::NoGCellShrink = (1 << 27); const uint64_t Flags::NoGCellShrink = (1 << 27);
const unsigned int Flags::CParanoid = (1 << 28); const uint64_t Flags::CParanoid = (1 << 28);
const unsigned int Flags::CheckLowDensity = (1 << 29); const uint64_t Flags::CheckLowDensity = (1 << 29);
const unsigned int Flags::CheckLowUpDensity = (1 << 30); const uint64_t Flags::CheckLowUpDensity = (1 << 30);
const unsigned int Flags::NoUpdate = (1 << 31); const uint64_t Flags::NoUpdate = (1 << 31);
Flags::~Flags () Flags::~Flags ()

View File

@ -22,7 +22,6 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include "hurricane/Timer.h"
#include "hurricane/NetRoutingProperty.h" #include "hurricane/NetRoutingProperty.h"
namespace Hurricane { namespace Hurricane {
class Instance; class Instance;
@ -42,7 +41,6 @@ namespace Anabatic {
using std::string; using std::string;
using std::vector; using std::vector;
using Hurricane::Timer;
using Hurricane::Name; using Hurricane::Name;
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Interval; using Hurricane::Interval;
@ -271,16 +269,11 @@ namespace Anabatic {
void _destroyAutoSegments (); void _destroyAutoSegments ();
void _check ( Net* net ) const; void _check ( Net* net ) const;
bool _check ( const char* message ) const; bool _check ( const char* message ) const;
void printMeasures ( const string& tag ) const;
// Misc. functions. // Misc. functions.
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
void reset (); 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 _add ( GCell* );
inline void _remove ( GCell* ); inline void _remove ( GCell* );
inline void _updateLookup ( GCell* ); inline void _updateLookup ( GCell* );
@ -300,7 +293,6 @@ namespace Anabatic {
AnabaticEngine& operator= ( const AnabaticEngine& ); AnabaticEngine& operator= ( const AnabaticEngine& );
private: private:
static Name _toolName; static Name _toolName;
Timer _timer;
Configuration* _configuration; Configuration* _configuration;
ChipTools _chipTools; ChipTools _chipTools;
EngineState _state; 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::getStamp () const { return _stamp; }
inline int AnabaticEngine::incStamp () { return ++_stamp; } inline int AnabaticEngine::incStamp () { return ++_stamp; }

View File

@ -18,10 +18,17 @@
#define ANABATIC_AUTOCONTACT_TERMINAL_H #define ANABATIC_AUTOCONTACT_TERMINAL_H
#include "anabatic/AutoContact.h" #include "anabatic/AutoContact.h"
#include "anabatic/AutoSegments.h"
namespace Hurricane {
class RoutingPad;
}
namespace Anabatic { namespace Anabatic {
using Hurricane::RoutingPad;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::AutoContactTerminal". // Class : "Anabatic::AutoContactTerminal".
@ -52,11 +59,14 @@ namespace Anabatic {
virtual ~AutoContactTerminal (); virtual ~AutoContactTerminal ();
virtual void _invalidate ( unsigned int flags ); virtual void _invalidate ( unsigned int flags );
public: public:
bool isEndPoint () const;
virtual Box getNativeConstraintBox () const; virtual Box getNativeConstraintBox () const;
RoutingPad* getRoutingPad () const;
inline AutoSegment* getSegment () const; inline AutoSegment* getSegment () const;
virtual AutoSegment* getSegment ( unsigned int ) const; virtual AutoSegment* getSegment ( unsigned int ) const;
virtual AutoSegment* getOpposite ( const AutoSegment* ) const; virtual AutoSegment* getOpposite ( const AutoSegment* ) const;
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
AutoSegments getRpConnecteds () const;
virtual void updateGeometry (); virtual void updateGeometry ();
virtual void updateTopology (); virtual void updateTopology ();
virtual void forceOnGrid ( Point ); virtual void forceOnGrid ( Point );

View File

@ -311,6 +311,7 @@ namespace Anabatic {
AutoSegments getCachedOnSourceContact ( unsigned int direction ); AutoSegments getCachedOnSourceContact ( unsigned int direction );
AutoSegments getCachedOnTargetContact ( unsigned int direction ); AutoSegments getCachedOnTargetContact ( unsigned int direction );
AutoSegments getAligneds ( unsigned int flags=Flags::NoFlags ); AutoSegments getAligneds ( unsigned int flags=Flags::NoFlags );
AutoSegments getConnecteds ( unsigned int flags=Flags::NoFlags );
AutoSegments getPerpandiculars (); AutoSegments getPerpandiculars ();
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ; size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
// Observers. // Observers.
@ -387,6 +388,7 @@ namespace Anabatic {
// Static Utilities. // Static Utilities.
public: public:
static inline unsigned int swapSourceTargetFlags ( AutoSegment* );
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* ); static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
static bool isTopologicalBound ( AutoSegment* seed, unsigned int flags ); static bool isTopologicalBound ( AutoSegment* seed, unsigned int flags );
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b ); static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
@ -520,6 +522,30 @@ namespace Anabatic {
inline unsigned long AutoSegment::getMaxId () inline unsigned long AutoSegment::getMaxId ()
{ return _maxId; } { 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 ) inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
{ return s1 and s2 { return s1 and s2
and (s1->isHorizontal() == s2->isHorizontal()) and (s1->isHorizontal() == s2->isHorizontal())

View File

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <array>
#include <map> #include <map>
#include "hurricane/Collection.h" #include "hurricane/Collection.h"
#include "hurricane/DbU.h" #include "hurricane/DbU.h"
@ -30,6 +31,7 @@ namespace Hurricane {
class Component; class Component;
class Contact; class Contact;
class Segment; class Segment;
class RoutingPad;
class Net; class Net;
} }
@ -49,6 +51,7 @@ namespace Anabatic {
using Hurricane::Component; using Hurricane::Component;
using Hurricane::Contact; using Hurricane::Contact;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::RoutingPad;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Filter; using Hurricane::Filter;
using Hurricane::Locator; using Hurricane::Locator;
@ -59,6 +62,7 @@ namespace Anabatic {
class LocatorHelper; class LocatorHelper;
class AutoContact; class AutoContact;
class AutoContactTerminal;
class AutoSegment; class AutoSegment;
class GCell; 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<AutoSegment*,4> _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". // 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". // Class : "AutoSegments_Perpandiculars".

View File

@ -24,69 +24,69 @@ namespace Anabatic {
class Flags : public Hurricane::BaseFlags { class Flags : public Hurricane::BaseFlags {
public: public:
static const unsigned int NoFlags ; // = 0; static const uint64_t NoFlags ; // = 0;
// Flags used for both objects states & functions arguments. // Flags used for both objects states & functions arguments.
static const unsigned int Horizontal ; // = (1 << 0); static const uint64_t Horizontal ; // = (1 << 0);
static const unsigned int Vertical ; // = (1 << 1); static const uint64_t Vertical ; // = (1 << 1);
static const unsigned int Source ; // = (1 << 2); static const uint64_t Source ; // = (1 << 2);
static const unsigned int Target ; // = (1 << 3); static const uint64_t Target ; // = (1 << 3);
static const unsigned int Invalidated ; // = (1 << 4); static const uint64_t Invalidated ; // = (1 << 4);
// Flags for GCell objects states only. // Flags for GCell objects states only.
static const unsigned int DeviceGCell ; // = (1 << 5); static const uint64_t DeviceGCell ; // = (1 << 5);
static const unsigned int HChannelGCell ; // = (1 << 6); static const uint64_t HChannelGCell ; // = (1 << 6);
static const unsigned int VChannelGCell ; // = (1 << 7); static const uint64_t VChannelGCell ; // = (1 << 7);
static const unsigned int StrutGCell ; // = (1 << 8); static const uint64_t StrutGCell ; // = (1 << 8);
static const unsigned int MatrixGCell ; // = (1 << 9); static const uint64_t MatrixGCell ; // = (1 << 9);
static const unsigned int IoPadGCell ; // = (1 << 10); static const uint64_t IoPadGCell ; // = (1 << 10);
static const unsigned int Saturated ; // = (1 << 11); static const uint64_t Saturated ; // = (1 << 11);
// Flags for Anabatic objects states only. // Flags for Anabatic objects states only.
static const unsigned int DemoMode ; // = (1 << 5); static const uint64_t DemoMode ; // = (1 << 5);
static const unsigned int WarnOnGCellOverload ; // = (1 << 6); static const uint64_t WarnOnGCellOverload ; // = (1 << 6);
static const unsigned int DestroyGCell ; // = (1 << 7); static const uint64_t DestroyGCell ; // = (1 << 7);
static const unsigned int DestroyBaseContact ; // = (1 << 8); static const uint64_t DestroyBaseContact ; // = (1 << 8);
static const unsigned int DestroyBaseSegment ; // = (1 << 9); static const uint64_t DestroyBaseSegment ; // = (1 << 9);
// Flags for NetDatas objects states only. // Flags for NetDatas objects states only.
static const unsigned int GlobalRouted ; // = (1 << 5); static const uint64_t GlobalRouted ; // = (1 << 5);
// Masks. // Masks.
static const unsigned int WestSide ; // = Horizontal|Target; static const uint64_t WestSide ; // = Horizontal|Target;
static const unsigned int EastSide ; // = Horizontal|Source; static const uint64_t EastSide ; // = Horizontal|Source;
static const unsigned int SouthSide ; // = Vertical |Target; static const uint64_t SouthSide ; // = Vertical |Target;
static const unsigned int NorthSide ; // = Vertical |Source; static const uint64_t NorthSide ; // = Vertical |Source;
static const unsigned int AllSides ; // = WestSide|EastSide|SouthSide|NorthSide ; static const uint64_t AllSides ; // = WestSide|EastSide|SouthSide|NorthSide ;
static const unsigned int EndsMask ; // = Source|Target; static const uint64_t EndsMask ; // = Source|Target;
static const unsigned int DirectionMask ; // = Horizontal|Vertical; static const uint64_t DirectionMask ; // = Horizontal|Vertical;
static const unsigned int DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; static const uint64_t DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
static const unsigned int GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; static const uint64_t GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
// Flags for functions arguments only. // Flags for functions arguments only.
static const unsigned int Create ; // = (1 << 5); static const uint64_t Create ; // = (1 << 5);
static const unsigned int WithPerpands ; static const uint64_t WithPerpands ;
static const unsigned int WithSelf ; static const uint64_t WithSelf ;
static const unsigned int AboveLayer ; static const uint64_t AboveLayer ;
static const unsigned int BelowLayer ; static const uint64_t BelowLayer ;
static const unsigned int OpenSession ; static const uint64_t OpenSession ;
static const unsigned int Realignate ; static const uint64_t Realignate ;
static const unsigned int NativeConstraints ; static const uint64_t NativeConstraints ;
static const unsigned int ForceMove ; static const uint64_t ForceMove ;
static const unsigned int WarnOnError ; static const uint64_t WarnOnError ;
static const unsigned int Topology ; static const uint64_t Topology ;
static const unsigned int GlobalSegment ; static const uint64_t GlobalSegment ;
static const unsigned int AllowTerminal ; static const uint64_t AllowTerminal ;
static const unsigned int AllowLocal ; static const uint64_t AllowLocal ;
static const unsigned int IgnoreContacts ; static const uint64_t IgnoreContacts ;
static const unsigned int Propagate ; static const uint64_t Propagate ;
static const unsigned int Superior ; static const uint64_t Superior ;
static const unsigned int DoglegOnLeft ; static const uint64_t DoglegOnLeft ;
static const unsigned int DoglegOnRight ; static const uint64_t DoglegOnRight ;
static const unsigned int WithNeighbors ; static const uint64_t WithNeighbors ;
static const unsigned int NoCheckLayer ; static const uint64_t NoCheckLayer ;
static const unsigned int HalfSlacken ; static const uint64_t HalfSlacken ;
static const unsigned int NoGCellShrink ; static const uint64_t NoGCellShrink ;
static const unsigned int CParanoid ; static const uint64_t CParanoid ;
static const unsigned int CheckLowDensity ; static const uint64_t CheckLowDensity ;
static const unsigned int CheckLowUpDensity ; static const uint64_t CheckLowUpDensity ;
static const unsigned int NoUpdate ; static const uint64_t NoUpdate ;
public: public:
inline Flags ( unsigned int flags = NoFlags ); inline Flags ( uint64_t flags = NoFlags );
inline Flags ( BaseFlags ); inline Flags ( BaseFlags );
virtual ~Flags (); virtual ~Flags ();
virtual std::string _getTypeName () const; virtual std::string _getTypeName () const;
@ -94,8 +94,8 @@ namespace Anabatic {
}; };
Flags::Flags ( unsigned int flags ) : BaseFlags(flags) { } Flags::Flags ( uint64_t flags ) : BaseFlags(flags) { }
Flags::Flags ( BaseFlags base ) : BaseFlags(base) { } Flags::Flags ( BaseFlags base ) : BaseFlags(base) { }
enum EngineState { EngineCreation = 1 enum EngineState { EngineCreation = 1

View File

@ -28,6 +28,7 @@ namespace {
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::string; using std::string;
using std::ostringstream;
using std::set; using std::set;
using std::vector; using std::vector;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
@ -191,30 +192,37 @@ namespace CRL {
ToolEngine::ToolEngine ( Cell* cell ) ToolEngine::ToolEngine ( Cell* cell )
: DBo() : Super()
, _cell (cell) , _cell (cell)
, _placementModificationFlag(0) , _placementModificationFlag(0)
, _routingModificationFlag (0) , _routingModificationFlag (0)
, _inRelationDestroy (false) , _inRelationDestroy (false)
{} , _timer ()
{ }
void ToolEngine::_postCreate () void ToolEngine::_postCreate ()
{ {
DBo::_postCreate(); Super::_postCreate();
if ( !_cell ) if (not _cell)
throw Error ( "Can't create " + _TName("ToolEngine") + " : empty _cell" ); throw Error( "Can't create " + _TName("ToolEngine") + " : empty _cell" );
ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell); ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !enginesRelation ) if (not enginesRelation)
enginesRelation = ToolEnginesRelation::create ( _cell ); enginesRelation = ToolEnginesRelation::create( _cell );
else else
forEach ( ToolEngine*, itool, enginesRelation->getSlaveOwners().getSubSet<ToolEngine*>() ) { for ( ToolEngine* tool : enginesRelation->getSlaveOwners().getSubSet<ToolEngine*>() ) {
if (itool->getName() == getName()) if (tool->getName() == getName())
throw Error ( "Can't create " + _TName("ToolEngine") + " : already exists !!" ); throw Error( "Can't create " + _TName("ToolEngine") + " : already exists !!" );
} }
put ( enginesRelation );
put( enginesRelation );
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <" cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
<< _cell->getName() << ">" << endl; << _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() ); throw Error( "Abnormal state: no ToolEnginesRelation on %s", getString(_cell).c_str() );
remove( relation ); remove( relation );
} }
DBo::_preDestroy(); Super::_preDestroy();
_cell->notify( Cell::Flags::CellChanged ); _cell->notify( Cell::Flags::CellChanged );
} }
@ -249,7 +257,7 @@ namespace CRL {
string ToolEngine::_getString () const string ToolEngine::_getString () const
{ {
string s = DBo::_getString(); string s = Super::_getString();
s.insert(s.length() - 1, " " + getString(_cell->getName())); s.insert(s.length() - 1, " " + getString(_cell->getName()));
return s; return s;
} }
@ -257,7 +265,7 @@ namespace CRL {
Record* ToolEngine::_getRecord () const Record* ToolEngine::_getRecord () const
{ {
Record* record = DBo::_getRecord(); Record* record = Super::_getRecord();
if ( record ) { if ( record ) {
record->add ( getSlot ( "Cell" , _cell ) ); record->add ( getSlot ( "Cell" , _cell ) );
record->add ( getSlot ( "Name" , getName() ) ); 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. } // End of CRL namespace.

View File

@ -21,6 +21,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "hurricane/Commons.h" #include "hurricane/Commons.h"
#include "hurricane/Timer.h"
#include "hurricane/DBo.h" #include "hurricane/DBo.h"
#include "hurricane/Slot.h" #include "hurricane/Slot.h"
@ -36,6 +37,7 @@ namespace CRL {
using std::string; using std::string;
using std::vector; using std::vector;
using Hurricane::Timer;
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Name; using Hurricane::Name;
using Hurricane::DBo; using Hurricane::DBo;
@ -47,36 +49,45 @@ namespace CRL {
class ToolEngine : public DBo { class ToolEngine : public DBo {
public: public:
static ToolEngines get ( const Cell* cell ); typedef DBo Super;
static ToolEngine* get ( const Cell* cell, const Name& name );
static void destroyAll ();
static bool inDestroyAll ();
public: public:
virtual const Name& getName () const = 0; static ToolEngines get ( const Cell* cell );
inline Cell* getCell () const; static ToolEngine* get ( const Cell* cell, const Name& name );
bool placementModificationFlagHasChanged (); static void destroyAll ();
bool routingModificationFlagHasChanged (); static bool inDestroyAll ();
inline void setInRelationDestroy ( bool ); public:
virtual string _getTypeName () const; virtual const Name& getName () const = 0;
virtual string _getString () const; inline Cell* getCell () const;
virtual Record* _getRecord () 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: private:
static bool _inDestroyAll; static bool _inDestroyAll;
protected: protected:
Cell* _cell; Cell* _cell;
private: private:
unsigned int _placementModificationFlag; unsigned int _placementModificationFlag;
unsigned int _routingModificationFlag; unsigned int _routingModificationFlag;
bool _inRelationDestroy; bool _inRelationDestroy;
Timer _timer;
protected: protected:
ToolEngine ( Cell* cell ); ToolEngine ( Cell* cell );
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
protected: protected:
void grabPlacementModificationFlag (); void grabPlacementModificationFlag ();
void getPlacementModificationFlag (); void getPlacementModificationFlag ();
void grabRoutingModificationFlag (); void grabRoutingModificationFlag ();
void getRoutingModificationFlag (); void getRoutingModificationFlag ();
}; };
@ -84,8 +95,9 @@ namespace CRL {
// Inline Functions. // Inline Functions.
inline Cell* ToolEngine::getCell () const { return _cell; } inline Cell* ToolEngine::getCell () const { return _cell; }
inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; } inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; }
inline const Timer& ToolEngine::getTimer () const { return _timer; }
} // CRL namespace. } // CRL namespace.

View File

@ -244,11 +244,10 @@ namespace Etesian {
EtesianEngine::EtesianEngine ( Cell* cell ) EtesianEngine::EtesianEngine ( Cell* cell )
: ToolEngine (cell) : Super (cell)
, _configuration(new Configuration()) , _configuration(new Configuration())
, _placed (false) , _placed (false)
, _flatDesign (false) , _flatDesign (false)
, _timer ()
, _surface () , _surface ()
, _circuit () , _circuit ()
, _placementLB () , _placementLB ()
@ -263,6 +262,8 @@ namespace Etesian {
void EtesianEngine::_postCreate () void EtesianEngine::_postCreate ()
{ {
Super::_postCreate();
// Ugly: Name based detection of ISPD benchmarks. // Ugly: Name based detection of ISPD benchmarks.
if (getString(getCell()->getName()).substr(0,7) == "bigblue") { if (getString(getCell()->getName()).substr(0,7) == "bigblue") {
cmess2 << " o ISPD benchmark <" << getCell()->getName() cmess2 << " o ISPD benchmark <" << getCell()->getName()
@ -292,6 +293,8 @@ namespace Etesian {
cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <" cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <"
<< getCell()->getName() << ">" << endl; << getCell()->getName() << ">" << endl;
Super::_preDestroy();
cdebug.log(129,-1); cdebug.log(129,-1);
} }
@ -314,33 +317,6 @@ namespace Etesian {
{ return _configuration; } { 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 () void EtesianEngine::setDefaultAb ()
{ {
double spaceMargin = getSpaceMargin(); double spaceMargin = getSpaceMargin();
@ -925,7 +901,7 @@ namespace Etesian {
cmess1 << " o Placement finished." << endl; cmess1 << " o Placement finished." << endl;
stopMeasures(); stopMeasures();
printMeasures( "total" ); printMeasures();
cmess1 << ::Dots::asString cmess1 << ::Dots::asString
( " - HPWL", DbU::getValueString( (DbU::Unit)coloquinte::gp::get_HPWL_wirelength(_circuit,_placementUB )*getPitch() ) ) << endl; ( " - HPWL", DbU::getValueString( (DbU::Unit)coloquinte::gp::get_HPWL_wirelength(_circuit,_placementUB )*getPitch() ) ) << endl;
cmess1 << ::Dots::asString cmess1 << ::Dots::asString
@ -954,10 +930,7 @@ namespace Etesian {
indent = label; indent = label;
} }
ostringstream elapsed; cmess2 << label
//elapsed << " dTime:" << setw(5) << _timer.getCombTime() << "s ";
cmess2 << label << elapsed.str()
<< " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementUB ) << " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementUB )
<< " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementUB ) << " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementUB )
<< endl; << endl;
@ -977,10 +950,7 @@ namespace Etesian {
indent = label; indent = label;
} }
ostringstream elapsed; cmess2 << label
//elapsed << " dTime:" << setw(5) << _timer.getCombTime() << "s ";
cmess2 << label << elapsed.str()
<< " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementLB ) << " HPWL:" << setw(11) << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementLB )
<< " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementLB ) << " RMST:" << setw(11) << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementLB )
<< endl; << endl;
@ -1042,7 +1012,7 @@ namespace Etesian {
Record* EtesianEngine::_getRecord () const Record* EtesianEngine::_getRecord () const
{ {
Record* record = ToolEngine::_getRecord (); Record* record = Super::_getRecord ();
if (record) { if (record) {
record->add( getSlot( "_configuration", _configuration ) ); record->add( getSlot( "_configuration", _configuration ) );

View File

@ -52,6 +52,8 @@ namespace Etesian {
// Class : "Etesian::EtesianEngine". // Class : "Etesian::EtesianEngine".
class EtesianEngine : public CRL::ToolEngine { class EtesianEngine : public CRL::ToolEngine {
public:
typedef ToolEngine Super;
public: public:
static const Name& staticGetName (); static const Name& staticGetName ();
static EtesianEngine* create ( Cell* ); static EtesianEngine* create ( Cell* );
@ -73,10 +75,6 @@ namespace Etesian {
inline Hurricane::CellViewer* getViewer () const; inline Hurricane::CellViewer* getViewer () const;
inline void setViewer ( Hurricane::CellViewer* ); inline void setViewer ( Hurricane::CellViewer* );
void startMeasures ();
void stopMeasures ();
void printMeasures ( std::string ) const;
void setDefaultAb (); void setDefaultAb ();
void resetPlacement (); void resetPlacement ();
void toColoquinte (); void toColoquinte ();
@ -104,7 +102,6 @@ namespace Etesian {
bool _placed; bool _placed;
bool _ySpinSet; bool _ySpinSet;
bool _flatDesign; bool _flatDesign;
Timer _timer;
coloquinte::box<coloquinte::int_t> _surface; coloquinte::box<coloquinte::int_t> _surface;
coloquinte::netlist _circuit; coloquinte::netlist _circuit;
coloquinte::placement_t _placementLB; coloquinte::placement_t _placementLB;

View File

@ -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; 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; flags &= Flags::MaskRings;
@ -1339,7 +1339,7 @@ void Cell::_toJsonCollections(JsonWriter* writer) const
// Cell::Flags implementation // Cell::Flags implementation
// **************************************************************************************************** // ****************************************************************************************************
Cell::Flags::Flags ( unsigned int flags) Cell::Flags::Flags ( uint64_t flags)
: BaseFlags(flags) : BaseFlags(flags)
{ } { }

View File

@ -47,7 +47,7 @@ namespace Hurricane {
string BaseFlags::_getString () const 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; std::ostringstream formatted;
formatted << "0x" << std::hex << std::setw(width) << std::setfill('0') << _flags; formatted << "0x" << std::hex << std::setw(width) << std::setfill('0') << _flags;

View File

@ -99,7 +99,7 @@ class Cell : public Entity {
}; };
public: public:
Flags ( unsigned int flags = NoFlags ); Flags ( uint64_t flags = NoFlags );
virtual ~Flags (); virtual ~Flags ();
virtual std::string _getTypeName () const; virtual std::string _getTypeName () const;
virtual std::string _getString () 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 _getTypeName() const {return _TName("Cell");};
public: virtual string _getString() const; public: virtual string _getString() const;
public: virtual Record* _getRecord() const; public: virtual Record* _getRecord() const;
public: static string getFlagString( unsigned int ); public: static string getFlagString( uint64_t );
public: static Record* getFlagRecord( unsigned int ); public: static Record* getFlagRecord( uint64_t );
public: static Slot* getFlagSlot( unsigned int ); public: static Slot* getFlagSlot( uint64_t );
public: InstanceMap& _getInstanceMap() {return _instanceMap;}; public: InstanceMap& _getInstanceMap() {return _instanceMap;};
public: QuadTree* _getQuadTree() {return _quadTree;}; 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 setFlattenLeaf(bool isFlattenLeaf) {_flags.set(Flags::FlattenLeaf,isFlattenLeaf);};
public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);}; public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);};
public: void setFeed(bool isFeed) {_flags.set(Flags::Feed,isFeed);}; public: void setFeed(bool isFeed) {_flags.set(Flags::Feed,isFeed);};
public: void flattenNets(unsigned int flags=Flags::BuildRings); public: void flattenNets(uint64_t flags=Flags::BuildRings);
public: void createRoutingPadRings(unsigned int flags=Flags::BuildRings); public: void createRoutingPadRings(uint64_t flags=Flags::BuildRings);
public: void setFlags(unsigned int flags) { _flags |= flags; } public: void setFlags(uint64_t flags) { _flags |= flags; }
public: void resetFlags(unsigned int flags) { _flags &= ~flags; } public: void resetFlags(uint64_t flags) { _flags &= ~flags; }
public: bool updatePlacedFlag(); public: bool updatePlacedFlag();
public: void materialize(); public: void materialize();
public: void unmaterialize(); public: void unmaterialize();

View File

@ -41,6 +41,7 @@
#include <set> #include <set>
#include <map> #include <map>
#include <stack> #include <stack>
#include <array>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
@ -318,6 +319,104 @@ template<typename Data> inline Hurricane::Record* getRecord ( Data data )
{ return NULL; } { return NULL; }
// -------------------------------------------------------------------
// Inspector Support for : "[const] std::array<Element>*".
template<typename Element,size_t N>
inline std::string getString ( std::array<Element,N>* v )
{
std::string name = "const std::array<Element,N>:";
return name + getString<size_t>(v->size());
}
template<typename Element,size_t N>
inline Hurricane::Record* getRecord ( std::array<Element,N>* v )
{
Hurricane::Record* record = NULL;
if ( !v->empty() ) {
record = new Hurricane::Record ( "std::array<Element,N>" );
unsigned n = 0;
typename std::array<Element,N>::iterator iterator = v->begin();
while ( iterator != v->end() ) {
record->add ( getSlot<Element>(getString(n++), *iterator) );
++iterator;
}
}
return record;
}
template<typename Element,size_t N>
inline std::string getString ( const std::array<Element,N>* v )
{
std::string name = "const std::array<Element,N>:";
return name + getString<size_t>(v->size());
}
template<typename Element,size_t N>
inline Hurricane::Record* getRecord ( const std::array<Element,N>* v )
{
Hurricane::Record* record = NULL;
if ( !v->empty() ) {
record = new Hurricane::Record ( "const std::array<Element,N>" );
unsigned n = 0;
typename std::array<Element,N>::const_iterator iterator = v->begin();
while ( iterator != v->end() ) {
record->add ( getSlot<const Element>(getString(n++), *iterator) );
++iterator;
}
}
return record;
}
template<typename Element,size_t N>
inline std::string getString ( std::array<Element,N>& v )
{
std::string name = "std::array<Element,N>&:";
return name + getString<size_t>(v.size());
}
template<typename Element,size_t N>
inline Hurricane::Record* getRecord ( std::array<Element,N>& v )
{
Hurricane::Record* record = NULL;
if (not v.empty()) {
record = new Hurricane::Record ( "std::array<Element,N>&" );
unsigned n = 0;
for ( auto element : v )
record->add( getSlot<Element>(getString(n++), element) );
}
return record;
}
template<typename Element,size_t N>
inline std::string getString ( const std::array<Element,N>& v )
{
std::string name = "const std::array<Element,N>&:";
return name + getString<size_t>(v.size());
}
template<typename Element,size_t N>
inline Hurricane::Record* getRecord ( const std::array<Element,N>& v )
{
Hurricane::Record* record = NULL;
if (not v.empty()) {
record = new Hurricane::Record ( "const std::array<Element,N>&" );
unsigned n = 0;
for ( auto element : v )
record->add( getSlot<Element>(getString(n++), element) );
}
return record;
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Inspector Support for : "[const] std::vector<Element>*". // Inspector Support for : "[const] std::vector<Element>*".

View File

@ -32,6 +32,7 @@
#ifndef HURRICANE_BASE_FLAGS_H #ifndef HURRICANE_BASE_FLAGS_H
#define HURRICANE_BASE_FLAGS_H #define HURRICANE_BASE_FLAGS_H
#include <cstdint>
#include <string> #include <string>
#include "hurricane/Commons.h" #include "hurricane/Commons.h"
@ -42,7 +43,7 @@ namespace Hurricane {
class BaseFlags { class BaseFlags {
public: public:
// Methods. // Methods.
inline BaseFlags ( unsigned int flags=0 ); inline BaseFlags ( uint64_t flags=0 );
virtual ~BaseFlags (); virtual ~BaseFlags ();
inline bool zero () const; inline bool zero () const;
inline BaseFlags& set ( BaseFlags, bool state=true ); inline BaseFlags& set ( BaseFlags, bool state=true );
@ -50,7 +51,7 @@ namespace Hurricane {
inline bool isset ( BaseFlags ) const; inline bool isset ( BaseFlags ) const;
inline bool contains ( BaseFlags ) const; inline bool contains ( BaseFlags ) const;
inline bool intersect ( 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 compl () const;
inline BaseFlags operator bitand ( BaseFlags ) const; inline BaseFlags operator bitand ( BaseFlags ) const;
inline BaseFlags operator bitor ( BaseFlags ) const; inline BaseFlags operator bitor ( BaseFlags ) const;
@ -60,11 +61,11 @@ namespace Hurricane {
inline BaseFlags operator xor ( int ) const; inline BaseFlags operator xor ( int ) const;
inline BaseFlags lshift ( int ) const; inline BaseFlags lshift ( int ) const;
inline BaseFlags rshift ( int ) const; inline BaseFlags rshift ( int ) const;
inline BaseFlags operator bitand ( unsigned int ) const; inline BaseFlags operator bitand ( uint64_t ) const;
inline BaseFlags operator bitor ( unsigned int ) const; inline BaseFlags operator bitor ( uint64_t ) const;
inline BaseFlags operator xor ( unsigned int ) const; inline BaseFlags operator xor ( uint64_t ) const;
inline BaseFlags lshift ( unsigned int ) const; inline BaseFlags lshift ( uint64_t ) const;
inline BaseFlags rshift ( unsigned int ) const; inline BaseFlags rshift ( uint64_t ) const;
inline BaseFlags& operator |= ( BaseFlags ); inline BaseFlags& operator |= ( BaseFlags );
inline BaseFlags& operator &= ( BaseFlags ); inline BaseFlags& operator &= ( BaseFlags );
inline bool operator == ( BaseFlags ) const; 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 bool operator < ( int ) const;
inline bool operator > ( int ) const; inline bool operator > ( int ) const;
inline BaseFlags& operator |= ( unsigned int ); inline BaseFlags& operator |= ( uint64_t );
inline BaseFlags& operator &= ( unsigned int ); inline BaseFlags& operator &= ( uint64_t );
inline bool operator == ( unsigned int ) const; inline bool operator == ( uint64_t ) const;
inline bool operator != ( unsigned int ) const; inline bool operator != ( uint64_t ) const;
inline bool operator < ( unsigned int ) const; inline bool operator < ( uint64_t ) const;
inline bool operator > ( unsigned int ) const; inline bool operator > ( uint64_t ) const;
inline operator bool () const; inline operator bool () const;
//inline operator unsigned int () const; //inline operator unsigned int () const;
// Hurricane Managment. // Hurricane Managment.
@ -91,12 +92,12 @@ namespace Hurricane {
inline Record* _getRecord () const; inline Record* _getRecord () const;
protected: protected:
// Internal: Attributes. // Internal: Attributes.
unsigned int _flags; uint64_t _flags;
}; };
// Inline Functions. // 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 bool BaseFlags::zero () const { return _flags == 0; }
inline BaseFlags& BaseFlags::reset ( BaseFlags flags ) { _flags &= ~flags._flags; return *this; } inline BaseFlags& BaseFlags::reset ( BaseFlags flags ) { _flags &= ~flags._flags; return *this; }
inline bool BaseFlags::isset ( BaseFlags flags ) const { return _flags & flags._flags; } 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 bitand ( BaseFlags flags ) const { return _flags & flags._flags; }
inline BaseFlags BaseFlags::operator bitor ( 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 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 bitand ( int flags ) const { return _flags & (uint64_t)flags; }
inline BaseFlags BaseFlags::operator bitor ( int flags ) const { return _flags | (unsigned int)flags; } inline BaseFlags BaseFlags::operator bitor ( int flags ) const { return _flags | (uint64_t)flags; }
inline BaseFlags BaseFlags::operator xor ( int flags ) const { return _flags ^ (unsigned int)flags; } inline BaseFlags BaseFlags::operator xor ( int flags ) const { return _flags ^ (uint64_t)flags; }
inline BaseFlags BaseFlags::lshift ( int s ) const { return _flags << (unsigned int)s; } inline BaseFlags BaseFlags::lshift ( int s ) const { return _flags << (uint64_t)s; }
inline BaseFlags BaseFlags::rshift ( int s ) const { return _flags >> (unsigned int)s; } inline BaseFlags BaseFlags::rshift ( int s ) const { return _flags >> (uint64_t)s; }
inline BaseFlags BaseFlags::operator bitand ( unsigned int flags ) const { return _flags & flags; } inline BaseFlags BaseFlags::operator bitand ( uint64_t flags ) const { return _flags & flags; }
inline BaseFlags BaseFlags::operator bitor ( unsigned int flags ) const { return _flags | flags; } inline BaseFlags BaseFlags::operator bitor ( uint64_t flags ) const { return _flags | flags; }
inline BaseFlags BaseFlags::operator xor ( unsigned int flags ) const { return _flags ^ flags; } inline BaseFlags BaseFlags::operator xor ( uint64_t flags ) const { return _flags ^ flags; }
inline BaseFlags BaseFlags::lshift ( unsigned int s ) const { return _flags << s; } inline BaseFlags BaseFlags::lshift ( uint64_t s ) const { return _flags << s; }
inline BaseFlags BaseFlags::rshift ( unsigned int 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 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 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 |= (uint64_t)flags; return *this; }
inline BaseFlags& BaseFlags::operator &= ( int flags ) { _flags &= (unsigned int)flags; return *this; } inline BaseFlags& BaseFlags::operator &= ( int flags ) { _flags &= (uint64_t)flags; return *this; }
inline bool BaseFlags::operator == ( int flags ) const { return _flags == (unsigned int)flags; } inline bool BaseFlags::operator == ( int flags ) const { return _flags == (uint64_t)flags; }
inline bool BaseFlags::operator != ( int flags ) const { return _flags != (unsigned int)flags; } inline bool BaseFlags::operator != ( int flags ) const { return _flags != (uint64_t)flags; }
inline bool BaseFlags::operator < ( int flags ) const { return _flags < (unsigned int)flags; } inline bool BaseFlags::operator < ( int flags ) const { return _flags < (uint64_t)flags; }
inline bool BaseFlags::operator > ( int flags ) const { return _flags > (unsigned int)flags; } inline bool BaseFlags::operator > ( int flags ) const { return _flags > (uint64_t)flags; }
inline BaseFlags& BaseFlags::operator |= ( unsigned int flags ) { _flags |= flags; return *this; } inline BaseFlags& BaseFlags::operator |= ( uint64_t flags ) { _flags |= flags; return *this; }
inline BaseFlags& BaseFlags::operator &= ( unsigned int flags ) { _flags &= flags; return *this; } inline BaseFlags& BaseFlags::operator &= ( uint64_t flags ) { _flags &= flags; return *this; }
inline bool BaseFlags::operator == ( unsigned int flags ) const { return _flags == flags; } inline bool BaseFlags::operator == ( uint64_t flags ) const { return _flags == flags; }
inline bool BaseFlags::operator != ( unsigned int flags ) const { return _flags != flags; } inline bool BaseFlags::operator != ( uint64_t flags ) const { return _flags != flags; }
inline bool BaseFlags::operator < ( unsigned int flags ) const { return _flags < flags; } inline bool BaseFlags::operator < ( uint64_t flags ) const { return _flags < flags; }
inline bool BaseFlags::operator > ( unsigned int 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 bool () const { return _flags != 0; }
//inline BaseFlags::operator unsigned int () const { return _flags; } //inline BaseFlags::operator unsigned int () const { return _flags; }
//inline BaseFlags::operator unsigned int () const { return _flags; } //inline BaseFlags::operator unsigned int () const { return _flags; }
@ -146,9 +147,9 @@ namespace Hurricane {
return *this; 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 ) { for ( ; select ; select=select<<1 ) {
if ( _flags & select ) nth--; if ( _flags & select ) nth--;
if ( !nth ) break; if ( !nth ) break;

View File

@ -145,7 +145,6 @@ namespace Katabatic {
KatabaticEngine::KatabaticEngine ( Cell* cell ) KatabaticEngine::KatabaticEngine ( Cell* cell )
: ToolEngine (cell) : ToolEngine (cell)
, _timer ()
, _state (EngineCreation) , _state (EngineCreation)
, _flags (EngineDestroyBaseContact) , _flags (EngineDestroyBaseContact)
, _configuration (new ConfigurationConcrete()) , _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 void KatabaticEngine::printMeasures ( const string& tag ) const
{ {
ostringstream result; Super::printMeasures();
result << Timer::getStringTime(_timer.getCombTime()) if (not tag.empty()) {
<< ", " << Timer::getStringMemory(_timer.getIncrease()); addMeasure<double>( getCell(), tag+"T", getTimer().getCombTime () );
cmess1 << Dots::asString( " - Done in", result.str() ) << endl; addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
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<double>( getCell(), tag+"T", _timer.getCombTime () );
addMeasure<size_t>( getCell(), tag+"S", (_timer.getMemorySize() >> 20) );
} }
} }

View File

@ -22,7 +22,6 @@
#include <vector> #include <vector>
#include <set> #include <set>
#include <map> #include <map>
#include "hurricane/Timer.h"
#include "hurricane/DbU.h" #include "hurricane/DbU.h"
#include "hurricane/Torus.h" #include "hurricane/Torus.h"
#include "hurricane/Layer.h" #include "hurricane/Layer.h"
@ -91,6 +90,7 @@ namespace Katabatic {
class KatabaticEngine : public ToolEngine { class KatabaticEngine : public ToolEngine {
public: public:
typedef ToolEngine Super;
typedef set<Net*,NetCompareByName> NetSet; typedef set<Net*,NetCompareByName> NetSet;
public: public:
@ -134,8 +134,6 @@ namespace Katabatic {
inline void setGlobalThreshold ( DbU::Unit ); inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float ); inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t ); inline void setSaturateRp ( size_t );
void startMeasures ();
void stopMeasures ();
void printMeasures ( const string& ) const; void printMeasures ( const string& ) const;
void refresh ( unsigned int flags=KbOpenSession ); void refresh ( unsigned int flags=KbOpenSession );
virtual void createDetailedGrid (); virtual void createDetailedGrid ();
@ -192,7 +190,6 @@ namespace Katabatic {
protected: protected:
// Attributes. // Attributes.
static Name _toolName; static Name _toolName;
Timer _timer;
EngineState _state; EngineState _state;
unsigned int _flags; unsigned int _flags;
Configuration* _configuration; Configuration* _configuration;

View File

@ -12,6 +12,7 @@
set( includes katana/Constants.h set( includes katana/Constants.h
katana/TrackCost.h katana/TrackCost.h
katana/DataNegociate.h katana/DataNegociate.h
katana/DataSymmetric.h
katana/TrackElement.h katana/TrackElements.h katana/TrackElement.h katana/TrackElements.h
katana/TrackSegment.h katana/TrackSegment.h
katana/TrackFixedSegment.h katana/TrackFixedSegment.h
@ -40,6 +41,7 @@
set( cpps Constants.cpp set( cpps Constants.cpp
Configuration.cpp Configuration.cpp
DataNegociate.cpp DataNegociate.cpp
DataSymmetric.cpp
TrackCost.cpp TrackCost.cpp
TrackElement.cpp TrackElement.cpp
TrackElements.cpp TrackElements.cpp
@ -64,6 +66,7 @@
ProtectRoutingPads.cpp ProtectRoutingPads.cpp
PreProcess.cpp PreProcess.cpp
GlobalRoute.cpp GlobalRoute.cpp
SymmetricRoute.cpp
KatanaEngine.cpp KatanaEngine.cpp
GraphicKatanaEngine.cpp GraphicKatanaEngine.cpp
) )

View File

@ -21,17 +21,18 @@
namespace Katana { namespace Katana {
const unsigned int Flags::AllowDoglegReuse = (1 << 20); const uint64_t Flags::AllowDoglegReuse = (1 << 20);
const unsigned int Flags::DataSelf = (1 << 21); const uint64_t Flags::DataSelf = (1 << 21);
const unsigned int Flags::Nearest = (1 << 22); const uint64_t Flags::Nearest = (1 << 22);
const unsigned int Flags::Force = (1 << 23); const uint64_t Flags::Force = (1 << 23);
const unsigned int Flags::ResetCount = (1 << 24); const uint64_t Flags::ResetCount = (1 << 24);
const unsigned int Flags::WithConstraints = (1 << 25); const uint64_t Flags::WithConstraints = (1 << 25);
const unsigned int Flags::MoveToLeft = (1 << 26); const uint64_t Flags::MoveToLeft = (1 << 26);
const unsigned int Flags::MoveToRight = (1 << 27); const uint64_t Flags::MoveToRight = (1 << 27);
const unsigned int Flags::LoadingStage = (1 << 28); const uint64_t Flags::LoadingStage = (1 << 28);
const unsigned int Flags::SlowMotion = (1 << 29); const uint64_t Flags::SlowMotion = (1 << 29);
const unsigned int Flags::PreRoutedStage = (1 << 30); const uint64_t Flags::PreRoutedStage = (1 << 30);
const uint64_t Flags::SymmetricStage = (1 << 31);
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -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<string> _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<AutoSegment*,2>& 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<AutoSegment*,2>& 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<AutoSegment*,2>& 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<AutoSegment*,2>& 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 "<DataSymmetric " + getString(_net->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.

View File

@ -231,10 +231,10 @@ namespace Katana {
void GraphicKatanaEngine::_loadGlobalRouting () void GraphicKatanaEngine::_loadGlobalRouting ()
{ {
KatanaEngine* anabatic = getForFramework( NoFlags ); KatanaEngine* katana = getForFramework( NoFlags );
_viewer->clearToolInterrupt(); _viewer->clearToolInterrupt();
anabatic->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet );
} }
@ -273,7 +273,12 @@ namespace Katana {
void GraphicKatanaEngine::_runTest () void GraphicKatanaEngine::_runTest ()
{ {
KatanaEngine* katana = getForFramework( NoFlags ); KatanaEngine* katana = getForFramework( NoFlags );
if (katana) katana->runTest(); if (katana) {
katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet );
katana->runTest();
katana->runNegociate( Flags::SymmetricStage );
katana->runNegociate();
}
} }

View File

@ -256,9 +256,6 @@ namespace Katana {
KatanaEngine* KatanaEngine::create ( Cell* cell ) KatanaEngine* KatanaEngine::create ( Cell* cell )
{ {
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
KatanaEngine* katana = new KatanaEngine ( cell ); KatanaEngine* katana = new KatanaEngine ( cell );
katana->_postCreate(); 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 () void KatanaEngine::openSession ()
{ Session::_open(this); } { 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 () void KatanaEngine::annotateGlobalGraph ()
{ {
cmess1 << " o Back annotate global routing graph." << endl; cmess1 << " o Back annotate global routing graph." << endl;
@ -649,6 +673,10 @@ namespace Katana {
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
_routingPlanes[depth]->destroy(); _routingPlanes[depth]->destroy();
} }
_routingPlanes.clear();
for ( auto symmetric : _symmetrics ) delete symmetric.second;
_symmetrics.clear();
Session::close(); Session::close();
} }
@ -702,8 +730,9 @@ namespace Katana {
Record* record = Super::_getRecord (); Record* record = Super::_getRecord ();
if (record) { if (record) {
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_configuration", _configuration ) ); record->add( getSlot( "_configuration", _configuration ) );
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_symmetrics" , &_symmetrics ) );
} }
return record; return record;
} }

View File

@ -552,6 +552,11 @@ namespace Katana {
Session::getKatanaEngine()->_check( overlaps, "after _createRouting(GCell*)" ); Session::getKatanaEngine()->_check( overlaps, "after _createRouting(GCell*)" );
#endif #endif
if (flags & Flags::SymmetricStage) {
_katana->runSymmetricRouter();
Session::revalidate();
}
_flags |= flags; _flags |= flags;
_negociate(); _negociate();
printStatistics(); printStatistics();

View File

@ -43,8 +43,8 @@ namespace {
void getPerpandiculars ( TrackElement* segment void getPerpandiculars ( TrackElement* segment
, Anabatic::AutoContact* from , Anabatic::AutoContact* from
, unsigned int direction , Flags direction
, vector<TrackElement*>& perpandiculars , vector<TrackElement*>& perpandiculars
) )
{ {
@ -69,7 +69,7 @@ namespace {
} }
void findFailedPerpandiculars ( RoutingPad* rp, unsigned int direction, set<TrackElement*>& faileds ) void findFailedPerpandiculars ( RoutingPad* rp, Flags direction, set<TrackElement*>& faileds )
{ {
cdebug_log(159,0) << "Find failed caging: " << rp << endl; cdebug_log(159,0) << "Find failed caging: " << rp << endl;

View File

@ -98,6 +98,10 @@ namespace Katana {
{ return Session::getKatanaEngine()->getConfiguration(); } { return Session::getKatanaEngine()->getConfiguration(); }
AutoContact* Session::lookup ( Contact* contact )
{ return Super::lookup(contact); }
TrackElement* Session::lookup ( Segment* segment ) TrackElement* Session::lookup ( Segment* segment )
{ return Session::get("Session::lookup(Segment*)")->_getKatanaEngine()->_lookup(segment); } { return Session::get("Session::lookup(Segment*)")->_getKatanaEngine()->_lookup(segment); }

View File

@ -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 <map>
#include <list>
#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<string> _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<Segment*>( 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<AutoContactTerminal*>(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<AutoContactTerminal*>( 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<Horizontal*>(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<Vertical*>(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<RoutingPad*>(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<Vertical*>(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<Horizontal*>(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<RoutingPad*>(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.

View File

@ -510,7 +510,7 @@ namespace Katana {
{ {
if (not hasSourceDogleg()) return NULL; if (not hasSourceDogleg()) return NULL;
unsigned int direction = perpandicularTo( getDirection() ); Flags direction = perpandicularTo( getDirection() );
TrackElement* dogleg = NULL; TrackElement* dogleg = NULL;
for( Segment* segment : base()->getAutoSource()->getSlaveComponents().getSubSet<Segment*>() ) { for( Segment* segment : base()->getAutoSource()->getSlaveComponents().getSubSet<Segment*>() ) {
dogleg = Session::lookup( segment ); dogleg = Session::lookup( segment );
@ -527,7 +527,7 @@ namespace Katana {
{ {
if (not hasSourceDogleg()) return NULL; if (not hasSourceDogleg()) return NULL;
unsigned int direction = perpandicularTo( getDirection() ); Flags direction = perpandicularTo( getDirection() );
TrackElement* dogleg = NULL; TrackElement* dogleg = NULL;
for( Segment* segment : base()->getAutoTarget()->getSlaveComponents().getSubSet<Segment*>() ) { for( Segment* segment : base()->getAutoTarget()->getSlaveComponents().getSubSet<Segment*>() ) {
dogleg = Session::lookup( segment ); dogleg = Session::lookup( segment );

View File

@ -26,24 +26,25 @@ namespace Katana {
public: public:
typedef Anabatic::Flags Super; typedef Anabatic::Flags Super;
public: public:
static const unsigned int AllowDoglegReuse; static const uint64_t AllowDoglegReuse;
static const unsigned int DataSelf; static const uint64_t DataSelf;
static const unsigned int Nearest; static const uint64_t Nearest;
static const unsigned int Force; static const uint64_t Force;
static const unsigned int ResetCount; static const uint64_t ResetCount;
static const unsigned int WithConstraints; static const uint64_t WithConstraints;
static const unsigned int MoveToLeft; static const uint64_t MoveToLeft;
static const unsigned int MoveToRight; static const uint64_t MoveToRight;
static const unsigned int LoadingStage; static const uint64_t LoadingStage;
static const unsigned int SlowMotion; static const uint64_t SlowMotion;
static const unsigned int PreRoutedStage; static const uint64_t PreRoutedStage;
static const uint64_t SymmetricStage;
public: public:
inline Flags ( unsigned int ); inline Flags ( uint64_t );
inline Flags ( const Super& ); 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) { } inline Flags::Flags ( const Flags::Super& base ) : Super(base) { }

View File

@ -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 <string>
#include <vector>
#include <array>
#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<AutoSegment*,2> > _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);

View File

@ -37,6 +37,7 @@ namespace Knik {
#include "katana/Constants.h" #include "katana/Constants.h"
#include "katana/TrackElement.h" #include "katana/TrackElement.h"
#include "katana/Configuration.h" #include "katana/Configuration.h"
#include "katana/DataSymmetric.h"
namespace Katana { namespace Katana {
@ -85,6 +86,7 @@ namespace Katana {
RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const; RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const;
RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const;
Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const;
DataSymmetric* getDataSymmetric ( Net* );
inline void printConfiguration () const; inline void printConfiguration () const;
void printCompletion () const; void printCompletion () const;
void dumpMeasures ( std::ostream& ) const; void dumpMeasures ( std::ostream& ) const;
@ -98,6 +100,7 @@ namespace Katana {
inline void setRipupCost ( unsigned int ); inline void setRipupCost ( unsigned int );
inline void setHTracksReservedLocal ( size_t ); inline void setHTracksReservedLocal ( size_t );
inline void setVTracksReservedLocal ( size_t ); inline void setVTracksReservedLocal ( size_t );
DataSymmetric* addDataSymmetric ( Net* );
void setupPowerRails (); void setupPowerRails ();
void protectRoutingPads (); void protectRoutingPads ();
void preProcess (); void preProcess ();
@ -110,6 +113,7 @@ namespace Katana {
void analogInit (); void analogInit ();
void runNegociate ( unsigned int flags=Flags::NoFlags ); void runNegociate ( unsigned int flags=Flags::NoFlags );
void runGlobalRouter (); void runGlobalRouter ();
void runSymmetricRouter ();
void runTest (); void runTest ();
virtual void finalizeLayout (); virtual void finalizeLayout ();
void _runKatanaInit (); void _runKatanaInit ();
@ -124,14 +128,15 @@ namespace Katana {
virtual string _getTypeName () const; virtual string _getTypeName () const;
private: private:
// Attributes. // Attributes.
static Name _toolName; static Name _toolName;
protected: protected:
CellViewer* _viewer; CellViewer* _viewer;
Configuration* _configuration; Configuration* _configuration;
vector<RoutingPlane*> _routingPlanes; vector<RoutingPlane*> _routingPlanes;
NegociateWindow* _negociateWindow; NegociateWindow* _negociateWindow;
double _minimumWL; double _minimumWL;
mutable bool _toolSuccess; std::map<Net*,DataSymmetric*> _symmetrics;
mutable bool _toolSuccess;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
KatanaEngine ( Cell* ); KatanaEngine ( Cell* );

View File

@ -10,7 +10,7 @@
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./katana/SegmentFsm.h" | // | C++ Header : "./katana/SegmentFsm.h" |
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+

View File

@ -24,12 +24,14 @@
namespace Hurricane { namespace Hurricane {
class Record; class Record;
class Net; class Net;
class Contact;
class Segment; class Segment;
} }
#include "anabatic/Session.h" #include "anabatic/Session.h"
namespace Anabatic { namespace Anabatic {
class GCell; class GCell;
class AutoContact;
class AutoSegment; class AutoSegment;
} }
@ -41,8 +43,10 @@ namespace Katana {
using std::string; using std::string;
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Contact;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::DbU; using Hurricane::DbU;
using Anabatic::AutoContact;
using Anabatic::AutoSegment; using Anabatic::AutoSegment;
class Track; class Track;
@ -77,6 +81,7 @@ namespace Katana {
inline static void addMoveEvent ( TrackElement* , Track* ); inline static void addMoveEvent ( TrackElement* , Track* );
inline static void addSortEvent ( Track*, bool forced=false ); inline static void addSortEvent ( Track*, bool forced=false );
inline static size_t revalidate (); inline static size_t revalidate ();
static AutoContact* lookup ( Contact* );
static TrackElement* lookup ( Segment* ); static TrackElement* lookup ( Segment* );
static TrackElement* lookup ( AutoSegment* ); static TrackElement* lookup ( AutoSegment* );
static Session* _open ( KatanaEngine* ); static Session* _open ( KatanaEngine* );