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 )
: Super(cell)
, _timer ()
, _configuration (new Configuration())
, _chipTools (cell)
, _state (EngineCreation)
@ -947,45 +946,6 @@ namespace Anabatic {
}
void AnabaticEngine::startMeasures ()
{
_timer.resetIncrease();
_timer.start();
}
void AnabaticEngine::stopMeasures ()
{ _timer.stop(); }
void AnabaticEngine::suspendMeasures ()
{ _timer.suspend(); }
void AnabaticEngine::resumeMeasures ()
{ _timer.resume(); }
void AnabaticEngine::printMeasures ( const string& tag ) const
{
ostringstream result;
result << Timer::getStringTime(_timer.getCombTime())
<< ", " << Timer::getStringMemory(_timer.getIncrease());
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
result.str("");
result << _timer.getCombTime()
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
<< Timer::getStringMemory(Timer::getMemorySize());
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
// result.str("");
// result << Timer::getStringMemory(Timer::getMemorySize());
// cmess1 << Dots::asString( " - Total memory", result.str() ) << endl;
}
void AnabaticEngine::updateDensity ()
{ for ( GCell* gcell : _gcells ) gcell->updateDensity(); }
@ -1116,6 +1076,17 @@ namespace Anabatic {
}
void AnabaticEngine::printMeasures ( const string& tag ) const
{
Super::printMeasures();
// if (not tag.empty()) {
// addMeasure<double>( getCell(), tag+"T", getTimer().getCombTime () );
// addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
// }
}
string AnabaticEngine::_getTypeName () const
{ 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
{ 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
{
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 ()
{ return AutoSegments_Perpandiculars( this ); }

View File

@ -15,7 +15,8 @@
#include "hurricane/Error.h"
#include "anabatic/AutoContact.h"
#include "hurricane/RoutingPad.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoSegment.h"
@ -27,7 +28,7 @@ namespace Anabatic {
using Hurricane::Error;
using Hurricane::ForEachIterator;
using Hurricane::Hook;
using Hurricane::Contact;
using Hurricane::RoutingPad;
// -------------------------------------------------------------------
@ -111,6 +112,183 @@ namespace Anabatic {
}
// -------------------------------------------------------------------
// Class : "Anabatic::AutoSegments_OnRoutingPad".
AutoSegments_OnRoutingPad::Locator::Locator ( RoutingPad* rp, const AutoContactTerminal* contact )
: AutoSegmentHL()
, _elements ({NULL,NULL,NULL,NULL})
, _index (0)
{
if (rp) {
for ( Component* component : rp->getSlaveComponents() ) {
AutoSegment* segment = Session::lookup( dynamic_cast<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".

View File

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

View File

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

View File

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

View File

@ -311,6 +311,7 @@ namespace Anabatic {
AutoSegments getCachedOnSourceContact ( unsigned int direction );
AutoSegments getCachedOnTargetContact ( unsigned int direction );
AutoSegments getAligneds ( unsigned int flags=Flags::NoFlags );
AutoSegments getConnecteds ( unsigned int flags=Flags::NoFlags );
AutoSegments getPerpandiculars ();
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
// Observers.
@ -387,6 +388,7 @@ namespace Anabatic {
// Static Utilities.
public:
static inline unsigned int swapSourceTargetFlags ( AutoSegment* );
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
static bool isTopologicalBound ( AutoSegment* seed, unsigned int flags );
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
@ -520,6 +522,30 @@ namespace Anabatic {
inline unsigned long AutoSegment::getMaxId ()
{ return _maxId; }
inline unsigned int AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
{
unsigned int segFlags = segment->getFlags();
unsigned int swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|SegSourceBottom |SegTargetBottom
|SegSourceTerminal |SegTargetTerminal
|SegNotSourceAligned |SegNotTargetAligned
|SegInvalidatedSource|SegInvalidatedTarget
);
swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags;
swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags;
swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags;
swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags;
swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags;
swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags;
swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags;
swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags;
swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags;
swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags;
return swapFlags;
}
inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
{ return s1 and s2
and (s1->isHorizontal() == s2->isHorizontal())

View File

@ -20,6 +20,7 @@
#include <string>
#include <list>
#include <vector>
#include <array>
#include <map>
#include "hurricane/Collection.h"
#include "hurricane/DbU.h"
@ -30,6 +31,7 @@ namespace Hurricane {
class Component;
class Contact;
class Segment;
class RoutingPad;
class Net;
}
@ -49,6 +51,7 @@ namespace Anabatic {
using Hurricane::Component;
using Hurricane::Contact;
using Hurricane::Segment;
using Hurricane::RoutingPad;
using Hurricane::Net;
using Hurricane::Filter;
using Hurricane::Locator;
@ -59,6 +62,7 @@ namespace Anabatic {
class LocatorHelper;
class AutoContact;
class AutoContactTerminal;
class AutoSegment;
class GCell;
@ -155,6 +159,56 @@ namespace Anabatic {
{ }
// -------------------------------------------------------------------
// Class : "Anabatic::AutoSegments_OnRoutingPad".
class AutoSegments_OnRoutingPad : public AutoSegmentHC {
public:
// Sub-Class: Locator.
class Locator : public AutoSegmentHL {
public:
Locator ( RoutingPad* rp, const AutoContactTerminal* contact );
inline Locator ( const Locator& );
virtual AutoSegment* getElement () const;
virtual AutoSegmentHL* getClone () const;
virtual bool isValid () const;
virtual void progress ();
virtual string _getString () const;
protected:
std::array<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".
@ -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".

View File

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

View File

@ -28,6 +28,7 @@ namespace {
using std::cerr;
using std::endl;
using std::string;
using std::ostringstream;
using std::set;
using std::vector;
using Hurricane::ForEachIterator;
@ -191,30 +192,37 @@ namespace CRL {
ToolEngine::ToolEngine ( Cell* cell )
: DBo()
: Super()
, _cell (cell)
, _placementModificationFlag(0)
, _routingModificationFlag (0)
, _inRelationDestroy (false)
{}
, _timer ()
{ }
void ToolEngine::_postCreate ()
{
DBo::_postCreate();
if ( !_cell )
throw Error ( "Can't create " + _TName("ToolEngine") + " : empty _cell" );
Super::_postCreate();
if (not _cell)
throw Error( "Can't create " + _TName("ToolEngine") + " : empty _cell" );
ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !enginesRelation )
enginesRelation = ToolEnginesRelation::create ( _cell );
if (not enginesRelation)
enginesRelation = ToolEnginesRelation::create( _cell );
else
forEach ( ToolEngine*, itool, enginesRelation->getSlaveOwners().getSubSet<ToolEngine*>() ) {
if (itool->getName() == getName())
throw Error ( "Can't create " + _TName("ToolEngine") + " : already exists !!" );
for ( ToolEngine* tool : enginesRelation->getSlaveOwners().getSubSet<ToolEngine*>() ) {
if (tool->getName() == getName())
throw Error( "Can't create " + _TName("ToolEngine") + " : already exists !!" );
}
put ( enginesRelation );
put( enginesRelation );
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
<< _cell->getName() << ">" << endl;
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
}
@ -226,7 +234,7 @@ namespace CRL {
throw Error( "Abnormal state: no ToolEnginesRelation on %s", getString(_cell).c_str() );
remove( relation );
}
DBo::_preDestroy();
Super::_preDestroy();
_cell->notify( Cell::Flags::CellChanged );
}
@ -249,7 +257,7 @@ namespace CRL {
string ToolEngine::_getString () const
{
string s = DBo::_getString();
string s = Super::_getString();
s.insert(s.length() - 1, " " + getString(_cell->getName()));
return s;
}
@ -257,7 +265,7 @@ namespace CRL {
Record* ToolEngine::_getRecord () const
{
Record* record = DBo::_getRecord();
Record* record = Super::_getRecord();
if ( record ) {
record->add ( getSlot ( "Cell" , _cell ) );
record->add ( getSlot ( "Name" , getName() ) );
@ -348,4 +356,43 @@ namespace CRL {
}
void ToolEngine::startMeasures ()
{
_timer.resetIncrease();
_timer.start();
}
void ToolEngine::stopMeasures ()
{ _timer.stop(); }
void ToolEngine::suspendMeasures ()
{ _timer.suspend(); }
void ToolEngine::resumeMeasures ()
{ _timer.resume(); }
void ToolEngine::printMeasures () const
{
ostringstream result;
result << Timer::getStringTime(_timer.getCombTime())
<< ", " << Timer::getStringMemory(_timer.getIncrease());
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
result.str("");
result << _timer.getCombTime()
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
<< Timer::getStringMemory(Timer::getMemorySize());
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
// result.str("");
// result << Timer::getStringMemory(Timer::getMemorySize());
// cmess1 << Dots::asString( " - Total memory", result.str() ) << endl;
}
} // End of CRL namespace.

View File

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

View File

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

View File

@ -52,6 +52,8 @@ namespace Etesian {
// Class : "Etesian::EtesianEngine".
class EtesianEngine : public CRL::ToolEngine {
public:
typedef ToolEngine Super;
public:
static const Name& staticGetName ();
static EtesianEngine* create ( Cell* );
@ -73,10 +75,6 @@ namespace Etesian {
inline Hurricane::CellViewer* getViewer () const;
inline void setViewer ( Hurricane::CellViewer* );
void startMeasures ();
void stopMeasures ();
void printMeasures ( std::string ) const;
void setDefaultAb ();
void resetPlacement ();
void toColoquinte ();
@ -104,7 +102,6 @@ namespace Etesian {
bool _placed;
bool _ySpinSet;
bool _flatDesign;
Timer _timer;
coloquinte::box<coloquinte::int_t> _surface;
coloquinte::netlist _circuit;
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;
@ -892,7 +892,7 @@ void Cell::flattenNets(unsigned int flags)
}
void Cell::createRoutingPadRings(unsigned int flags)
void Cell::createRoutingPadRings(uint64_t flags)
// *************************************************
{
flags &= Flags::MaskRings;
@ -1339,7 +1339,7 @@ void Cell::_toJsonCollections(JsonWriter* writer) const
// Cell::Flags implementation
// ****************************************************************************************************
Cell::Flags::Flags ( unsigned int flags)
Cell::Flags::Flags ( uint64_t flags)
: BaseFlags(flags)
{ }

View File

@ -47,7 +47,7 @@ namespace Hurricane {
string BaseFlags::_getString () const
{
static size_t width = sizeof(unsigned int) * CHAR_BIT;
static size_t width = sizeof(uint64_t) * CHAR_BIT;
std::ostringstream formatted;
formatted << "0x" << std::hex << std::setw(width) << std::setfill('0') << _flags;

View File

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

View File

@ -41,6 +41,7 @@
#include <set>
#include <map>
#include <stack>
#include <array>
#include <vector>
#include <iostream>
#include <iomanip>
@ -318,6 +319,104 @@ template<typename Data> inline Hurricane::Record* getRecord ( Data data )
{ 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>*".

View File

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

View File

@ -145,7 +145,6 @@ namespace Katabatic {
KatabaticEngine::KatabaticEngine ( Cell* cell )
: ToolEngine (cell)
, _timer ()
, _state (EngineCreation)
, _flags (EngineDestroyBaseContact)
, _configuration (new ConfigurationConcrete())
@ -361,34 +360,13 @@ namespace Katabatic {
}
void KatabaticEngine::startMeasures ()
{
_timer.resetIncrease();
_timer.start();
}
void KatabaticEngine::stopMeasures ()
{ _timer.stop(); }
void KatabaticEngine::printMeasures ( const string& tag ) const
{
ostringstream result;
Super::printMeasures();
result << Timer::getStringTime(_timer.getCombTime())
<< ", " << Timer::getStringMemory(_timer.getIncrease());
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
result.str("");
result << _timer.getCombTime()
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
<< Timer::getStringMemory(Timer::getMemorySize());
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
if (not tag.empty()) {
addMeasure<double>( getCell(), tag+"T", _timer.getCombTime () );
addMeasure<size_t>( getCell(), tag+"S", (_timer.getMemorySize() >> 20) );
if (not tag.empty()) {
addMeasure<double>( getCell(), tag+"T", getTimer().getCombTime () );
addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
}
}

View File

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

View File

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

View File

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

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

View File

@ -256,9 +256,6 @@ namespace Katana {
KatanaEngine* KatanaEngine::create ( Cell* cell )
{
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
KatanaEngine* katana = new KatanaEngine ( cell );
katana->_postCreate();
@ -340,6 +337,13 @@ namespace Katana {
}
DataSymmetric* KatanaEngine::getDataSymmetric ( Net* net )
{
auto idata = _symmetrics.find( net );
if (idata != _symmetrics.end()) return (*idata).second;
return NULL;
}
void KatanaEngine::openSession ()
{ Session::_open(this); }
@ -353,6 +357,26 @@ namespace Katana {
}
DataSymmetric* KatanaEngine::addDataSymmetric ( Net* net )
{
DataSymmetric* data = getDataSymmetric( net );
if (data) {
cerr << Error( "KatanaEngine::addDataSymmetric(): Try to add twice Net \"%s\" (ignored)."
, getString(net->getName()).c_str() ) << endl;
return data;
}
data = DataSymmetric::create( net );
if (data) {
_symmetrics.insert( make_pair(net,data) );
if (data->getSymNet())
_symmetrics.insert( make_pair(data->getSymNet(),data) );
}
return data;
}
void KatanaEngine::annotateGlobalGraph ()
{
cmess1 << " o Back annotate global routing graph." << endl;
@ -649,6 +673,10 @@ namespace Katana {
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
_routingPlanes[depth]->destroy();
}
_routingPlanes.clear();
for ( auto symmetric : _symmetrics ) delete symmetric.second;
_symmetrics.clear();
Session::close();
}
@ -702,8 +730,9 @@ namespace Katana {
Record* record = Super::_getRecord ();
if (record) {
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_configuration", _configuration ) );
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_symmetrics" , &_symmetrics ) );
}
return record;
}

View File

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

View File

@ -43,8 +43,8 @@ namespace {
void getPerpandiculars ( TrackElement* segment
, Anabatic::AutoContact* from
, unsigned int direction
, Anabatic::AutoContact* from
, Flags direction
, 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;

View File

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

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

View File

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

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

View File

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

View File

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