Improved handling of short nets (fully included in one GCell).
The short net mode degrade the routing in some cases. This will be fixed in a next batch of commits. * New: In Hurricane::NetRoutingProperty, added "ShortNet" flag for Nets that are completly inside *one* GCell. * Bug: In CRL::BlifParser::Model::staticInit(), when looking for the output of zero and one cell, also skip the blockage net (as well as automatic and supplies). * New: In Anabatic::AutoSegment, added "ShortNet" flag to know if the segment is part of a short net (fully included in *one* GCell). Also add accessor/mutators for the _analogMode flag (was it ever used before?). * New: In Anabatic::NetBuilder::singleGCell(), if a RoutingPad is vertically small, add a vertical segment to give it some slack. * New: In Anabatic::Dijkstra::_materialize(), detect "short net" as they have only one GCell in their source list... * Bug: In AnabaticEngine::_loadGrbyNet(), reset the AutoSegment "short net" and "analog mode" creation flags between two different nets. * New: In Katana::Configuration, added dedicated ripup for short net segmnts. * New: In Katana: partially implemented support for "short dogleg", that is dogleg that are always kept in same metal because they connect neighboring perpandicular tracks. Not finished neither activated yet. * New: In Katana::TreckElement and derived, export the the *short net* support from AutoSegment. * Bug: In Katana::RoutingEvent::_processRepair(), when a segment is successfully inserted, re-process any perpandicular that is in repair state, as it may have a new chance to be placed. * New: In Katana::SegmentFsm::slackenTopology(), always reject short nets. * Bug: In Katana::Track::check(), correctly handle wide segments instead of issuing false check messages.
This commit is contained in:
parent
b88c3336cd
commit
094cb8a132
|
@ -878,7 +878,7 @@ namespace Anabatic {
|
|||
and north->canDrag()
|
||||
and (south->getNet() != north->getNet())
|
||||
and (south->getX () == north->getX ()) ) {
|
||||
Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() );
|
||||
Interval constraints ( gcell->getYMin(), north->getCBYMin() /*- pitch3*/ );
|
||||
AutoSegment* terminal = south->getSegment();
|
||||
AutoContact* opposite = terminal->getOppositeAnchor( south );
|
||||
|
||||
|
@ -887,7 +887,7 @@ namespace Anabatic {
|
|||
constraineds.insert( segment );
|
||||
}
|
||||
|
||||
constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() );
|
||||
constraints = Interval( south->getCBYMax() /*+ pitch3*/, gcell->getYMax() );
|
||||
terminal = north->getSegment();
|
||||
opposite = terminal->getOppositeAnchor( north );
|
||||
|
||||
|
@ -919,7 +919,7 @@ namespace Anabatic {
|
|||
|
||||
sort( aligneds.begin(), aligneds.end(), AutoSegment::CompareBySourceU() );
|
||||
|
||||
AutoSegment* previous = NULL;
|
||||
//AutoSegment* previous = NULL;
|
||||
for ( AutoSegment* aligned : aligneds ) {
|
||||
Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() );
|
||||
|
||||
|
@ -959,7 +959,7 @@ namespace Anabatic {
|
|||
userConstraints = constraints;
|
||||
}
|
||||
|
||||
previous = aligned;
|
||||
//previous = aligned;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -971,6 +971,8 @@ namespace Anabatic {
|
|||
{
|
||||
cmess1 << " o Building detailed routing from global. " << endl;
|
||||
|
||||
size_t shortNets = 0;
|
||||
|
||||
startMeasures();
|
||||
openSession();
|
||||
|
||||
|
@ -981,6 +983,10 @@ namespace Anabatic {
|
|||
|
||||
if (gaugeKind < 3) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isShortNet(net)) {
|
||||
AutoSegment::setShortNetMode( true );
|
||||
++shortNets;
|
||||
}
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 145, 150 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
@ -994,8 +1000,9 @@ namespace Anabatic {
|
|||
Session::revalidate();
|
||||
DebugSession::close();
|
||||
}
|
||||
AutoSegment::setAnalogMode ( false );
|
||||
AutoSegment::setShortNetMode( false );
|
||||
}
|
||||
AutoSegment::setAnalogMode( false );
|
||||
}
|
||||
|
||||
#if defined(CHECK_DATABASE)
|
||||
|
@ -1005,6 +1012,8 @@ namespace Anabatic {
|
|||
Session::close();
|
||||
stopMeasures();
|
||||
|
||||
cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl;
|
||||
|
||||
if (gaugeKind > 2) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
|
||||
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
|
@ -33,7 +34,6 @@
|
|||
|
||||
namespace {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace CRL;
|
||||
using namespace Hurricane;
|
||||
|
@ -413,12 +413,14 @@ namespace Anabatic {
|
|||
size_t AutoSegment::_allocateds = 0;
|
||||
size_t AutoSegment::_globalsCount = 0;
|
||||
bool AutoSegment::_analogMode = false;
|
||||
bool AutoSegment::_shortNetMode = false;
|
||||
bool AutoSegment::_initialized = false;
|
||||
vector< array<DbU::Unit*,3> > AutoSegment::_extensionCaps;
|
||||
|
||||
|
||||
void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; }
|
||||
bool AutoSegment::getAnalogMode () { return _analogMode; }
|
||||
void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; }
|
||||
bool AutoSegment::getAnalogMode () { return _analogMode; }
|
||||
void AutoSegment::setShortNetMode ( bool state ) { _shortNetMode = state; }
|
||||
|
||||
|
||||
void AutoSegment::_initialize ()
|
||||
|
@ -491,6 +493,7 @@ namespace Anabatic {
|
|||
if (source->isTerminal()) setFlags( SegSourceTerminal );
|
||||
if (target->isTerminal()) setFlags( SegTargetTerminal );
|
||||
if (_analogMode) setFlags( SegAnalog );
|
||||
if (_shortNetMode) setFlags( SegShortNet );
|
||||
|
||||
source->invalidate( Flags::Topology );
|
||||
}
|
||||
|
@ -982,9 +985,11 @@ namespace Anabatic {
|
|||
|
||||
void AutoSegment::mergeUserConstraints ( const Interval& constraints )
|
||||
{
|
||||
DebugSession::open( getNet(), 149, 160 );
|
||||
cdebug_log(149,0) << "mergeUserConstraints() " << this << endl;
|
||||
cdebug_log(149,0) << "| " << constraints << " merged with " << _userConstraints << endl;
|
||||
_userConstraints.intersection(constraints);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2328,6 +2333,8 @@ namespace Anabatic {
|
|||
else if (_flags & SegTargetBottom) state += 'b';
|
||||
else state += '-';
|
||||
|
||||
state += isShortNet () ? "s": "-";
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -2028,6 +2028,10 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(112,1) << "Dijkstra::_materialize() " << _net << " _sources:" << _sources.size() << endl;
|
||||
|
||||
if (_sources.size() < 2)
|
||||
NetRoutingExtension::create( _net )->setFlags( NetRoutingState::ShortNet
|
||||
| NetRoutingState::AutomaticGlobalRoute );
|
||||
|
||||
if (_sources.size() < 2) { cdebug_tabw(112,-1); return; }
|
||||
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
|
|
|
@ -616,12 +616,13 @@ namespace Anabatic {
|
|||
globalNets.clear();
|
||||
Session::revalidate();
|
||||
|
||||
if (getConfiguration()->getAllowedDepth() > 2) {
|
||||
if ( (method != EngineLayerAssignNoGlobalM2V)
|
||||
and (getConfiguration()->getAllowedDepth() > 2) ) {
|
||||
for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) {
|
||||
_desaturate( depth, globalNets, total, global );
|
||||
if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate();
|
||||
}
|
||||
|
||||
|
||||
globalNets.clear ();
|
||||
Session::revalidate();
|
||||
}
|
||||
|
|
|
@ -1084,9 +1084,31 @@ namespace Anabatic {
|
|||
doRp_AutoContacts( gcell1, rpM1s[irp-1], source, turn1, DoSourceContact );
|
||||
doRp_AutoContacts( gcell1, rpM1s[irp ], target, turn1, DoSourceContact );
|
||||
|
||||
if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical)))
|
||||
if (source->getUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) {
|
||||
uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] );
|
||||
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
|
||||
if (Session::getConfiguration()->isHV()) {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1, Flags::Horizontal );
|
||||
source = turn1;
|
||||
}
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1 , Flags::Vertical );
|
||||
source = turn1;
|
||||
}
|
||||
flags = checkRoutingPadSize( rpM1s[irp] );
|
||||
if ((flags & VSmall) or Session::getConfiguration()->isVH()) {
|
||||
if (Session::getConfiguration()->isHV()) {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( target, turn1, Flags::Horizontal );
|
||||
target = turn1;
|
||||
}
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( target, turn1 , Flags::Vertical );
|
||||
target = turn1;
|
||||
}
|
||||
AutoSegment::create( source, target, Flags::Horizontal );
|
||||
else {
|
||||
} else {
|
||||
turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
turn2 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() );
|
||||
AutoSegment::create( source, turn1 , Flags::Horizontal );
|
||||
|
|
|
@ -152,7 +152,8 @@ namespace Anabatic {
|
|||
state->setFlags ( NetRoutingState::Unconnected );
|
||||
|
||||
if (isFixed) {
|
||||
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
|
||||
if (rpCount > 1)
|
||||
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
|
||||
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
|
||||
state->setFlags ( NetRoutingState::Fixed );
|
||||
} else {
|
||||
|
|
|
@ -105,6 +105,7 @@ namespace Anabatic {
|
|||
static const uint64_t SegUserDefined = (1L<<32);
|
||||
static const uint64_t SegAnalog = (1L<<33);
|
||||
static const uint64_t SegWide = (1L<<34);
|
||||
static const uint64_t SegShortNet = (1L<<35);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
|
@ -135,6 +136,7 @@ namespace Anabatic {
|
|||
public:
|
||||
static void setAnalogMode ( bool );
|
||||
static bool getAnalogMode ();
|
||||
static void setShortNetMode ( bool );
|
||||
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||
|
@ -216,6 +218,7 @@ namespace Anabatic {
|
|||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isWide () const;
|
||||
inline bool isShortNet () const;
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canReduce () const;
|
||||
bool mustRaise () const;
|
||||
|
@ -358,6 +361,7 @@ namespace Anabatic {
|
|||
static size_t _allocateds;
|
||||
static size_t _globalsCount;
|
||||
static bool _analogMode;
|
||||
static bool _shortNetMode;
|
||||
static bool _initialized;
|
||||
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||
// Internal: Attributes.
|
||||
|
@ -525,6 +529,7 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
|
||||
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
|
||||
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
|
||||
inline bool AutoSegment::isShortNet () const { return _flags & SegShortNet; }
|
||||
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
|
||||
|
||||
|
|
|
@ -372,14 +372,18 @@ namespace {
|
|||
|
||||
if (_zero) {
|
||||
for ( Net* net : _zero->getNets() )
|
||||
if (not net->isSupply() and not net->isAutomatic()) { _masterNetZero = net; break; }
|
||||
if ( not net->isSupply ()
|
||||
and not net->isAutomatic()
|
||||
and not net->isBlockage () ) { _masterNetZero = net; break; }
|
||||
} else
|
||||
cerr << Warning( "BlifParser::Model::connectSubckts(): The zero (tie high) cell \"%s\" has not been found."
|
||||
, zeroName.c_str() ) << endl;
|
||||
|
||||
if (_one) {
|
||||
for ( Net* net : _one->getNets() )
|
||||
if (not net->isSupply() and not net->isAutomatic()) { _masterNetOne = net; break; }
|
||||
if ( not net->isSupply ()
|
||||
and not net->isAutomatic()
|
||||
and not net->isBlockage () ) { _masterNetOne = net; break; }
|
||||
} else
|
||||
cerr << Warning( "BlifParser::Model::connectSubckts(): The one (tie low) cell \"%s\" has not been found."
|
||||
, oneName.c_str() ) << endl;
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace Hurricane {
|
|||
, Symmetric = (1<< 7)
|
||||
, SymmetricMaster = (1<< 8)
|
||||
, Analog = (1<< 9)
|
||||
, ShortNet = (1<<10)
|
||||
};
|
||||
public:
|
||||
inline bool isExcluded () const;
|
||||
|
@ -63,6 +64,7 @@ namespace Hurricane {
|
|||
inline bool isSymMaster () const;
|
||||
inline bool isSymSlave () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isShortNet () const;
|
||||
inline Net* getNet () const;
|
||||
inline Net* getSymNet () const;
|
||||
inline DbU::Unit getSymAxis () const;
|
||||
|
@ -103,6 +105,7 @@ namespace Hurricane {
|
|||
inline bool NetRoutingState::isSymVertical () const { return _flags & Vertical; }
|
||||
inline bool NetRoutingState::isSymMaster () const { return _flags & SymmetricMaster; }
|
||||
inline bool NetRoutingState::isAnalog () const { return _flags & Analog; }
|
||||
inline bool NetRoutingState::isShortNet () const { return _flags & ShortNet; }
|
||||
inline Net* NetRoutingState::getSymNet () const { return _symNet; }
|
||||
inline DbU::Unit NetRoutingState::getSymAxis () const { return _axis; }
|
||||
inline uint32_t NetRoutingState::getFlags () const { return _flags; };
|
||||
|
@ -177,6 +180,7 @@ namespace Hurricane {
|
|||
static inline bool isSymVertical ( const Net* );
|
||||
static inline bool isSymMaster ( const Net* );
|
||||
static inline bool isAnalog ( const Net* );
|
||||
static inline bool isShortNet ( const Net* );
|
||||
static inline uint32_t getFlags ( const Net* );
|
||||
static inline Net* getSymNet ( const Net* );
|
||||
static inline DbU::Unit getSymAxis ( const Net* );
|
||||
|
@ -266,6 +270,13 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
inline bool NetRoutingExtension::isShortNet ( const Net* net )
|
||||
{
|
||||
NetRoutingState* state = get( net );
|
||||
return (state == NULL) ? false : state->isShortNet();
|
||||
}
|
||||
|
||||
|
||||
inline uint32_t NetRoutingExtension::getFlags ( const Net* net )
|
||||
{
|
||||
NetRoutingState* state = get( net );
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace Katana {
|
|||
_ripupLimits[LocalRipupLimit] = Cfg::getParamInt("katana.localRipupLimit" , 7)->asInt();
|
||||
_ripupLimits[GlobalRipupLimit] = Cfg::getParamInt("katana.globalRipupLimit" , 5)->asInt();
|
||||
_ripupLimits[LongGlobalRipupLimit] = Cfg::getParamInt("katana.longGlobalRipupLimit" , 5)->asInt();
|
||||
_ripupLimits[ShortNetRipupLimit] = Cfg::getParamInt("katana.shortNetRipupLimit" ,16)->asInt();
|
||||
|
||||
// for ( size_t i=0 ; i<MaxMetalDepth ; ++i ) {
|
||||
// ostringstream paramName;
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
namespace Katana {
|
||||
|
||||
|
||||
const Hurricane::BaseFlags Flags::AllowDoglegReuse = (1 << 20);
|
||||
const Hurricane::BaseFlags Flags::DataSelf = (1 << 21);
|
||||
const Hurricane::BaseFlags Flags::Nearest = (1 << 22);
|
||||
const Hurricane::BaseFlags Flags::Force = (1 << 23);
|
||||
const Hurricane::BaseFlags Flags::ResetCount = (1 << 24);
|
||||
const Hurricane::BaseFlags Flags::WithConstraints = (1 << 25);
|
||||
const Hurricane::BaseFlags Flags::MoveToLeft = (1 << 26);
|
||||
const Hurricane::BaseFlags Flags::MoveToRight = (1 << 27);
|
||||
const Hurricane::BaseFlags Flags::LoadingStage = (1 << 28);
|
||||
const Hurricane::BaseFlags Flags::SlowMotion = (1 << 29);
|
||||
const Hurricane::BaseFlags Flags::PreRoutedStage = (1 << 30);
|
||||
const Hurricane::BaseFlags Flags::PairSymmetrics = (1 << 31);
|
||||
const Hurricane::BaseFlags Flags::AllowDoglegReuse = (1L << 20);
|
||||
const Hurricane::BaseFlags Flags::DataSelf = (1L << 21);
|
||||
const Hurricane::BaseFlags Flags::Nearest = (1L << 22);
|
||||
const Hurricane::BaseFlags Flags::Force = (1L << 23);
|
||||
const Hurricane::BaseFlags Flags::ResetCount = (1L << 24);
|
||||
const Hurricane::BaseFlags Flags::WithConstraints = (1L << 25);
|
||||
const Hurricane::BaseFlags Flags::MoveToLeft = (1L << 26);
|
||||
const Hurricane::BaseFlags Flags::MoveToRight = (1L << 27);
|
||||
const Hurricane::BaseFlags Flags::ShortDogleg = (1L << 28);
|
||||
const Hurricane::BaseFlags Flags::LoadingStage = (1L << 29);
|
||||
const Hurricane::BaseFlags Flags::SlowMotion = (1L << 30);
|
||||
const Hurricane::BaseFlags Flags::PreRoutedStage = (1L << 31);
|
||||
const Hurricane::BaseFlags Flags::PairSymmetrics = (1L << 32);
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -243,6 +243,10 @@ namespace Katana {
|
|||
cdebug_log(159,0) << s.str() << endl;
|
||||
cdebug_log(159,0) << "Perpandicular Free: " << _perpandicularFree << endl;
|
||||
|
||||
cdebug_log(159,0) << "Perpandiculars: " << endl;
|
||||
for ( TrackElement* perpand : _perpandiculars ) {
|
||||
cdebug_log(159,0) << "| " << perpand << endl;
|
||||
}
|
||||
|
||||
cdebug_tabw(159,-1);
|
||||
DebugSession::close();
|
||||
|
|
|
@ -186,6 +186,8 @@ namespace Katana {
|
|||
, _routingPlanes ()
|
||||
, _negociateWindow(NULL)
|
||||
, _minimumWL (0.0)
|
||||
, _shortDoglegs ()
|
||||
, _symmetrics ()
|
||||
, _mode (DigitalMode)
|
||||
, _toolSuccess (false)
|
||||
{
|
||||
|
@ -348,7 +350,8 @@ namespace Katana {
|
|||
{
|
||||
if (segment->isBlockage()) return 0;
|
||||
|
||||
if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isShortNet()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit );
|
||||
if (segment->isGlobal()) {
|
||||
vector<GCell*> gcells;
|
||||
segment->getGCells( gcells );
|
||||
|
|
|
@ -1226,7 +1226,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
bool Manipulator::makeDogleg ( Interval overlap )
|
||||
bool Manipulator::makeDogleg ( Interval overlap, Flags flags )
|
||||
{
|
||||
cdebug_log(159,0) << "Manipulator::makeDogleg(Interval) " << _segment << endl;
|
||||
cdebug_log(159,0) << overlap << endl;
|
||||
|
@ -1234,11 +1234,15 @@ namespace Katana {
|
|||
if ( _segment->isFixed () ) return false;
|
||||
if (not _segment->canDogleg(overlap)) return false;
|
||||
|
||||
Flags flags = Flags::NoFlags;
|
||||
TrackElement* dogleg = _segment->makeDogleg(overlap,flags);
|
||||
TrackElement* dogleg = NULL;
|
||||
TrackElement* parallel = NULL;
|
||||
_segment->makeDogleg( overlap, dogleg, parallel, flags );
|
||||
if (dogleg) {
|
||||
cdebug_log(159,0) << "Manipulator::makeDogleg(Interval) - Push dogleg to the "
|
||||
<< ((flags&Flags::DoglegOnLeft)?"left":"right") << endl;
|
||||
if (flags & Flags::ShortDogleg)
|
||||
Session::addShortDogleg( _segment, parallel );
|
||||
|
||||
if (_segment->isTerminal()) {
|
||||
Anabatic::AutoContact* contact =
|
||||
(flags&Flags::DoglegOnLeft) ? _segment->base()->getAutoSource()
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace {
|
|||
{
|
||||
AllianceFramework* af = AllianceFramework::get ();
|
||||
RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge();
|
||||
bool isVH = rg->isVH();
|
||||
//bool isVH = rg->isVH();
|
||||
|
||||
for( Net* net : nw->getCell()->getNets() ) {
|
||||
if (net->getType() == Net::Type::POWER ) continue;
|
||||
|
@ -529,7 +529,7 @@ namespace Katana {
|
|||
cmess2.flush ();
|
||||
} else {
|
||||
cmess2 << " <event:" << right << setw(8) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds()-1 << setfill(' ') << " "
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
|
||||
<< event->getEventLevel() << ":" << event->getPriority() << "> "
|
||||
<< event->getSegment()
|
||||
<< endl;
|
||||
|
|
|
@ -208,6 +208,7 @@ namespace {
|
|||
Interval constraints ( minConstraint, maxConstraint );
|
||||
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
|
||||
cdebug_log(159,0) << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl;
|
||||
cerr << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl;
|
||||
perpandiculars[iperpand]->base()->mergeUserConstraints( constraints );
|
||||
if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) {
|
||||
cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl;
|
||||
|
|
|
@ -415,6 +415,7 @@ namespace Katana {
|
|||
loop.erase( _segment );
|
||||
setState( DataNegociate::RepairFailed );
|
||||
setDisabled( true );
|
||||
setProcessed();
|
||||
}
|
||||
|
||||
//DebugSession::open( _segment->getNet(), 155, 160 );
|
||||
|
@ -594,18 +595,30 @@ namespace Katana {
|
|||
if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) {
|
||||
cdebug_log(159,0) << "Insert in free space." << endl;
|
||||
fsm.bindToTrack( 0 );
|
||||
|
||||
cdebug_log(159,0) << "Re-try perpandiculars:" << endl;
|
||||
for ( TrackElement* perpandicular : getPerpandiculars() ) {
|
||||
if (not perpandicular->getTrack() ) {
|
||||
cdebug_log(159,0) << "| " << perpandicular << endl;
|
||||
fsm.addAction( perpandicular, SegmentAction::SelfInsert );
|
||||
DataNegociate* data = perpandicular->getDataNegociate();
|
||||
if (data) data->setState( DataNegociate::Repair );
|
||||
}
|
||||
}
|
||||
fsm.doActions();
|
||||
queue.commit();
|
||||
} else {
|
||||
switch ( fsm.getData()->getStateCount() ) {
|
||||
case 1:
|
||||
// First try: minimize.
|
||||
Manipulator(_segment,fsm).minimize ();
|
||||
Manipulator(_segment,fsm).minimize();
|
||||
fsm.addAction( _segment, SegmentAction::SelfInsert );
|
||||
fsm.doActions();
|
||||
queue.commit();
|
||||
break;
|
||||
case 2:
|
||||
// Second try: failed re-inserted first.
|
||||
Manipulator(_segment,fsm).repackPerpandiculars ();
|
||||
Manipulator(_segment,fsm).repackPerpandiculars();
|
||||
fsm.addAction( _segment, SegmentAction::SelfInsert );
|
||||
fsm.doActions();
|
||||
queue.commit();
|
||||
|
@ -650,6 +663,18 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "Expanding (after):" << _constraints << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (_segment->isShortDogleg()) {
|
||||
TrackElement* parallel = Session::getDoglegPaired( _segment );
|
||||
if (parallel and parallel->getTrack()) {
|
||||
Interval delta ( parallel->getAxis() - _segment->getPitch()
|
||||
, parallel->getAxis() + _segment->getPitch() );
|
||||
_constraints.intersection( delta );
|
||||
cdebug_log(159,0) << "Short parallel to: " << parallel << endl;
|
||||
cdebug_log(159,0) << "Constraints restricted to: " << delta << endl;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(159,0) << "| Raw Track Constraint: " << _constraints
|
||||
<< " [" << _constraints.getVMin()
|
||||
<< "," << _constraints.getVMax() << "]" << endl;
|
||||
|
|
|
@ -776,6 +776,7 @@ namespace Katana {
|
|||
and (not _event2 or Manipulator(getSegment2(),*this).canRipup(flags));
|
||||
}
|
||||
|
||||
|
||||
bool SegmentFsm::conflictSolveByHistory ()
|
||||
{
|
||||
bool success = false;
|
||||
|
@ -976,24 +977,32 @@ namespace Katana {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (other->isGlobal()) {
|
||||
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
|
||||
if ((success = Manipulator(other,*this).moveUp())) break;
|
||||
}
|
||||
|
||||
cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl;
|
||||
|
||||
if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) {
|
||||
success = true;
|
||||
break;
|
||||
} else {
|
||||
if ( not canMoveUp
|
||||
and (relaxFlags != Manipulator::NoExpand)
|
||||
and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) {
|
||||
cdebug_log(159,0) << "Cannot move up but successful narrow breaking." << endl;
|
||||
if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) {
|
||||
if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) {
|
||||
cerr << "Break using ShortDogleg." << endl;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (other->isGlobal()) {
|
||||
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
|
||||
if ((success = Manipulator(other,*this).moveUp())) break;
|
||||
}
|
||||
|
||||
cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl;
|
||||
|
||||
if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) {
|
||||
success = true;
|
||||
break;
|
||||
} else {
|
||||
if ( not canMoveUp
|
||||
and (relaxFlags != Manipulator::NoExpand)
|
||||
and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) {
|
||||
cdebug_log(159,0) << "Cannot move up but successful narrow breaking." << endl;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1181,10 +1190,10 @@ namespace Katana {
|
|||
if (not success and (nextState != DataNegociate::Unimplemented))
|
||||
success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit);
|
||||
|
||||
if (not (flags&NoTransition)) {
|
||||
// if (not (flags&NoTransition)) {
|
||||
data->setState( nextState );
|
||||
cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl;
|
||||
}
|
||||
// }
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -1281,11 +1290,11 @@ namespace Katana {
|
|||
if (solveFullBlockages()) nextState = DataNegociate::MoveUp;
|
||||
}
|
||||
|
||||
if (not (flags&NoTransition)) {
|
||||
// if (not (flags&NoTransition)) {
|
||||
data->setState( nextState );
|
||||
cdebug_log(159,0) << "Incrementing state (after): "
|
||||
<< DataNegociate::getStateString(nextState,data->getStateCount()) << endl;
|
||||
}
|
||||
// }
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -1368,7 +1377,7 @@ namespace Katana {
|
|||
if (solveFullBlockages()) nextState = DataNegociate::MoveUp;
|
||||
}
|
||||
|
||||
if (not (flags&NoTransition)) {
|
||||
//if (not (flags&NoTransition)) {
|
||||
if (data->getChildSegment()) {
|
||||
TrackElement* child = segment;
|
||||
cdebug_log(159,0) << "Incrementing state of childs (after): " << endl;
|
||||
|
@ -1387,7 +1396,7 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "Incrementing state (after): " << segment << endl;
|
||||
cdebug_log(159,0) << "| " << nextState << " count:" << data->getStateCount() << endl;
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -1410,6 +1419,13 @@ namespace Katana {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (segment1->isShortNet()) {
|
||||
cdebug_log(159,0) << "Short net segments are not allowed to slacken" << endl;
|
||||
cdebug_tabw(159,-1);
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not segment1 or not _data1) { cdebug_tabw(159,-1); DebugSession::close(); return false; }
|
||||
|
||||
_event1->resetInsertState();
|
||||
|
|
|
@ -157,6 +157,14 @@ namespace Katana {
|
|||
{ return Session::get("lookup(AutoSegment*)")->_getKatanaEngine()->_lookup ( segment ); }
|
||||
|
||||
|
||||
void Session::addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB )
|
||||
{ Session::get("addShortDogleg(AutoSegment*)")->_getKatanaEngine()->_addShortDogleg( segmentA, segmentB ); }
|
||||
|
||||
|
||||
TrackElement* Session::getDoglegPaired ( TrackElement* segment )
|
||||
{ return Session::get("getDoglegPaired(AutoSegment*)")->_getKatanaEngine()->_getDoglegPaired( segment ); }
|
||||
|
||||
|
||||
void Session::setInterrupt ( bool state )
|
||||
{ Session::get("setInterrupt()")->_getKatanaEngine()->setInterrupt(state); }
|
||||
|
||||
|
|
|
@ -505,7 +505,12 @@ namespace Katana {
|
|||
if (message) cerr << " o Checking Track - " << message << endl;
|
||||
cdebug_log(155,0) << (void*)this << ":" << this << endl;
|
||||
|
||||
|
||||
for ( size_t i=0 ; i<_segments.size() ; i++ ) {
|
||||
Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2
|
||||
, _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 );
|
||||
bool inTrackRange = trackRange.contains( _axis );
|
||||
|
||||
if (_segments[i]) {
|
||||
if (i) {
|
||||
if (_segments[i-1] == _segments[i]) {
|
||||
|
@ -519,14 +524,15 @@ namespace Katana {
|
|||
<< _segments[i] << " is detached." << endl;
|
||||
coherency = false;
|
||||
} else {
|
||||
if (_segments[i]->getTrack() != this) {
|
||||
if ( (_segments[i]->getTrack() != this) and not inTrackRange ) {
|
||||
cerr << "[CHECK] incoherency at " << i << " "
|
||||
<< _segments[i] << " is in track "
|
||||
<< _segments[i]->getTrack() << endl;
|
||||
coherency = false;
|
||||
cerr << _segments[i]->getTrackSpan() << endl;
|
||||
}
|
||||
}
|
||||
if (_segments[i]->getAxis() != getAxis()) {
|
||||
if ( (_segments[i]->getAxis() != getAxis()) and not inTrackRange ) {
|
||||
cerr << "[CHECK] incoherency at " << i << " "
|
||||
<< _segments[i] << " is not on Track axis "
|
||||
<< DbU::getValueString(getAxis()) << "." << endl;
|
||||
|
|
|
@ -243,6 +243,8 @@ namespace Katana {
|
|||
s += string ( (isOverlap() )?"o":"-" );
|
||||
s += string ( (isOverlapGlobal() )?"g":"-" );
|
||||
s += string ( (isGlobalEnclosed())?"e":"-" );
|
||||
s += string ( (isAnalog ())?"a":"-" );
|
||||
s += string ( (isShortNet ())?"N":"-" );
|
||||
s += " " + getString(_terminals);
|
||||
s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta);
|
||||
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
|
||||
|
|
|
@ -143,11 +143,13 @@ namespace Katana {
|
|||
bool TrackElement::isStrap () const { return false; }
|
||||
bool TrackElement::isSlackened () const { return false; }
|
||||
bool TrackElement::isDogleg () const { return false; }
|
||||
bool TrackElement::isShortDogleg () const { return false; }
|
||||
bool TrackElement::isReduced () const { return false; }
|
||||
bool TrackElement::isUTurn () const { return false; }
|
||||
bool TrackElement::isUserDefined () const { return false; }
|
||||
bool TrackElement::isAnalog () const { return false; }
|
||||
bool TrackElement::isWide () const { return false; }
|
||||
bool TrackElement::isShortNet () const { return false; }
|
||||
// Predicates.
|
||||
bool TrackElement::hasSymmetric () const { return false; }
|
||||
bool TrackElement::canSlacken () const { return false; }
|
||||
|
@ -161,6 +163,7 @@ namespace Katana {
|
|||
unsigned long TrackElement::getId () const { return 0; }
|
||||
unsigned long TrackElement::getFreedomDegree () const { return 0; }
|
||||
uint32_t TrackElement::getTrackCount () const { return 0; }
|
||||
unsigned int TrackElement::getDepth () const { return 0; }
|
||||
DbU::Unit TrackElement::getPitch () const { return 0; }
|
||||
DbU::Unit TrackElement::getPPitch () const { return 0; }
|
||||
DbU::Unit TrackElement::getExtensionCap ( Flags ) const { return 0; }
|
||||
|
@ -190,7 +193,7 @@ namespace Katana {
|
|||
void TrackElement::updatePPitch () { }
|
||||
void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { }
|
||||
TrackElement* TrackElement::makeDogleg () { return NULL; }
|
||||
TrackElement* TrackElement::makeDogleg ( Interval, Flags& ) { return NULL; }
|
||||
Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; }
|
||||
TrackElement* TrackElement::makeDogleg ( Anabatic::GCell*, TrackElement*&, TrackElement*& ) { return NULL; }
|
||||
void TrackElement::_postDoglegs ( TrackElement*&, TrackElement*& ) { }
|
||||
bool TrackElement::moveAside ( Flags ) { return false; }
|
||||
|
|
|
@ -140,6 +140,7 @@ namespace Katana {
|
|||
Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); }
|
||||
DbU::Unit TrackFixedSegment::getWidth () const { return _segment->getWidth(); }
|
||||
const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); }
|
||||
unsigned int TrackFixedSegment::getDepth () const { return Session::getLayerDepth(getLayer()); }
|
||||
Interval TrackFixedSegment::getFreeInterval () const { return Interval(); }
|
||||
size_t TrackFixedSegment::getTrackSpan () const { return 1; }
|
||||
|
||||
|
|
|
@ -166,11 +166,13 @@ namespace Katana {
|
|||
bool TrackSegment::isStrap () const { return _base->isStrap(); }
|
||||
bool TrackSegment::isSlackened () const { return _base->isSlackened(); }
|
||||
bool TrackSegment::isDogleg () const { return _base->isDogleg(); }
|
||||
bool TrackSegment::isShortDogleg () const { return _flags & TElemShortDogleg; }
|
||||
bool TrackSegment::isReduced () const { return _base->isReduced(); }
|
||||
bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); }
|
||||
bool TrackSegment::isUTurn () const { return _base->isUTurn(); }
|
||||
bool TrackSegment::isAnalog () const { return _base->isAnalog(); }
|
||||
bool TrackSegment::isWide () const { return _base->isWide(); }
|
||||
bool TrackSegment::isShortNet () const { return _base->isShortNet(); }
|
||||
bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; }
|
||||
// Predicates.
|
||||
bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; }
|
||||
|
@ -180,6 +182,7 @@ namespace Katana {
|
|||
Net* TrackSegment::getNet () const { return _base->getNet(); }
|
||||
DbU::Unit TrackSegment::getWidth () const { return _base->getWidth(); }
|
||||
const Layer* TrackSegment::getLayer () const { return _base->getLayer(); }
|
||||
unsigned int TrackSegment::getDepth () const { return _base->getDepth(); }
|
||||
DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); }
|
||||
DbU::Unit TrackSegment::getPPitch () const { return _ppitch; }
|
||||
DbU::Unit TrackSegment::getExtensionCap ( Flags flags ) const { return _base->getExtensionCap(flags); }
|
||||
|
@ -894,16 +897,21 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
TrackElement* TrackSegment::makeDogleg ( Interval interval, Flags& flags )
|
||||
Flags TrackSegment::makeDogleg ( Interval interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags )
|
||||
{
|
||||
TrackElement* perpandicular = NULL;
|
||||
TrackElement* parallel = NULL;
|
||||
perpandicular = NULL;
|
||||
parallel = NULL;
|
||||
|
||||
cdebug_log(159,0) << "TrackSegment::makeDogleg(Interval)" << endl;
|
||||
flags = base()->makeDogleg( interval );
|
||||
flags |= base()->makeDogleg( interval );
|
||||
_postDoglegs( perpandicular, parallel );
|
||||
|
||||
return perpandicular;
|
||||
if (flags & Flags::ShortDogleg) {
|
||||
parallel->setFlags( TElemShortDogleg );
|
||||
Session::addShortDogleg( this, parallel );
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ namespace Katana {
|
|||
, LocalRipupLimit = 1
|
||||
, GlobalRipupLimit = 2
|
||||
, LongGlobalRipupLimit = 3
|
||||
, RipupLimitsTableSize = 4
|
||||
, ShortNetRipupLimit = 4
|
||||
, RipupLimitsTableSize = 5
|
||||
};
|
||||
enum Constants { MaxMetalDepth = 20 };
|
||||
enum Flag { UseClockTree = (1 << 0) };
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Katana {
|
|||
static const Hurricane::BaseFlags WithConstraints;
|
||||
static const Hurricane::BaseFlags MoveToLeft;
|
||||
static const Hurricane::BaseFlags MoveToRight;
|
||||
static const Hurricane::BaseFlags ShortDogleg;
|
||||
static const Hurricane::BaseFlags LoadingStage;
|
||||
static const Hurricane::BaseFlags SlowMotion;
|
||||
static const Hurricane::BaseFlags PreRoutedStage;
|
||||
|
|
|
@ -143,18 +143,16 @@ namespace Katana {
|
|||
|
||||
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
||||
{
|
||||
if ( (_state >= Repair) and (state < _state) ) {
|
||||
std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl;
|
||||
std::cerr << "On " << _getString() << std::endl;
|
||||
// if ( (_state >= Repair) and (state < _state) ) {
|
||||
// std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl;
|
||||
// std::cerr << "On " << _getString() << std::endl;
|
||||
|
||||
std::cerr << *((char*)NULL) << std::endl;
|
||||
|
||||
throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s."
|
||||
" On %s"
|
||||
, getStateString(state,_stateCount).c_str()
|
||||
, _getString().c_str()
|
||||
);
|
||||
}
|
||||
// throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s."
|
||||
// " On %s"
|
||||
// , getStateString(state,_stateCount).c_str()
|
||||
// , _getString().c_str()
|
||||
// );
|
||||
// }
|
||||
if ( (_state != state) or (flags & Flags::ResetCount) ) {
|
||||
//std::cerr << "Changing state to:" << state << std::endl;
|
||||
_state = state;
|
||||
|
|
|
@ -132,6 +132,8 @@ namespace Katana {
|
|||
void _computeCagedConstraints ();
|
||||
TrackElement* _lookup ( Segment* ) const;
|
||||
inline TrackElement* _lookup ( AutoSegment* ) const;
|
||||
inline void _addShortDogleg ( TrackElement*, TrackElement* );
|
||||
inline TrackElement* _getDoglegPaired ( TrackElement* ) const;
|
||||
bool _check ( uint32_t& overlap, const char* message=NULL ) const;
|
||||
void _check ( Net* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
@ -147,6 +149,7 @@ namespace Katana {
|
|||
vector<RoutingPlane*> _routingPlanes;
|
||||
NegociateWindow* _negociateWindow;
|
||||
double _minimumWL;
|
||||
TrackElementPairing _shortDoglegs;
|
||||
DataSymmetricMap _symmetrics;
|
||||
uint32_t _mode;
|
||||
mutable bool _toolSuccess;
|
||||
|
@ -195,6 +198,19 @@ namespace Katana {
|
|||
inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); }
|
||||
inline TrackElement* KatanaEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver<TrackElement>(AutoSegment::Observable::TrackSegment); }
|
||||
|
||||
inline void KatanaEngine::_addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB )
|
||||
{
|
||||
_shortDoglegs.insert( std::make_pair(segmentA,segmentB) );
|
||||
_shortDoglegs.insert( std::make_pair(segmentB,segmentA) );
|
||||
}
|
||||
|
||||
inline TrackElement* KatanaEngine::_getDoglegPaired ( TrackElement* segment ) const
|
||||
{
|
||||
auto ipaired = _shortDoglegs.find( segment );
|
||||
if (ipaired != _shortDoglegs.end()) return ipaired->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Variables.
|
||||
extern const char* missingRW;
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Katana {
|
|||
bool moveUp ( uint32_t flags=0 );
|
||||
bool makeDogleg ();
|
||||
bool makeDogleg ( DbU::Unit );
|
||||
bool makeDogleg ( Interval );
|
||||
bool makeDogleg ( Interval, Flags=Flags::NoFlags );
|
||||
bool relax ( Interval, uint32_t flags=AllowExpand );
|
||||
bool insertInTrack ( size_t icost );
|
||||
bool shrinkToTrack ( size_t icost
|
||||
|
|
|
@ -86,6 +86,8 @@ namespace Katana {
|
|||
static AutoContact* lookup ( Contact* );
|
||||
static TrackElement* lookup ( Segment* );
|
||||
static TrackElement* lookup ( AutoSegment* );
|
||||
static void addShortDogleg ( TrackElement*, TrackElement* );
|
||||
static TrackElement* getDoglegPaired ( TrackElement* );
|
||||
static Session* _open ( KatanaEngine* );
|
||||
private:
|
||||
KatanaEngine* _getKatanaEngine ();
|
||||
|
|
|
@ -48,17 +48,18 @@ namespace Katana {
|
|||
, LocalAndTopDepth = (1 << 3)
|
||||
, ZeroCost = (1 << 4)
|
||||
, Analog = (1 << 5)
|
||||
, Symmetric = (1 << 6)
|
||||
, ForGlobal = (1 << 7)
|
||||
, Blockage = (1 << 8)
|
||||
, Fixed = (1 << 9)
|
||||
, Infinite = (1 << 10)
|
||||
, HardOverlap = (1 << 11)
|
||||
, Overlap = (1 << 12)
|
||||
, LeftOverlap = (1 << 13)
|
||||
, RightOverlap = (1 << 14)
|
||||
, OverlapGlobal = (1 << 15)
|
||||
, GlobalEnclosed = (1 << 16)
|
||||
, ShortNet = (1 << 6)
|
||||
, Symmetric = (1 << 7)
|
||||
, ForGlobal = (1 << 8)
|
||||
, Blockage = (1 << 9)
|
||||
, Fixed = (1 << 10)
|
||||
, Infinite = (1 << 11)
|
||||
, HardOverlap = (1 << 12)
|
||||
, Overlap = (1 << 13)
|
||||
, LeftOverlap = (1 << 14)
|
||||
, RightOverlap = (1 << 15)
|
||||
, OverlapGlobal = (1 << 16)
|
||||
, GlobalEnclosed = (1 << 17)
|
||||
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|
||||
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|
||||
|GlobalEnclosed
|
||||
|
@ -87,6 +88,8 @@ namespace Katana {
|
|||
~TrackCost ();
|
||||
inline bool isForGlobal () const;
|
||||
inline bool isBlockage () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isShortNet () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isInfinite () const;
|
||||
inline bool isOverlap () const;
|
||||
|
@ -179,6 +182,8 @@ namespace Katana {
|
|||
// Inline Functions.
|
||||
inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; }
|
||||
inline bool TrackCost::isBlockage () const { return _flags & Blockage; }
|
||||
inline bool TrackCost::isAnalog () const { return _flags & Analog; }
|
||||
inline bool TrackCost::isShortNet () const { return _flags & ShortNet; }
|
||||
inline bool TrackCost::isFixed () const { return _flags & Fixed; }
|
||||
inline bool TrackCost::isInfinite () const { return _flags & Infinite; }
|
||||
inline bool TrackCost::isOverlap () const { return _flags & Overlap; }
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace Katana {
|
|||
class TrackSegment;
|
||||
|
||||
|
||||
typedef map<TrackElement*,TrackElement*> TrackElementPairing;
|
||||
typedef map<Segment*,TrackElement*,Entity::CompareById> TrackElementLut;
|
||||
typedef void (SegmentOverlapCostCB)( const TrackElement*, TrackCost& );
|
||||
|
||||
|
@ -69,13 +70,14 @@ namespace Katana {
|
|||
, TElemFixed = (1 << 2)
|
||||
, TElemLocked = (1 << 4)
|
||||
, TElemRouted = (1 << 5)
|
||||
, TElemSourceDogleg = (1 << 6)
|
||||
, TElemTargetDogleg = (1 << 7)
|
||||
, TElemAlignBottom = (1 << 8)
|
||||
, TElemAlignCenter = (1 << 9)
|
||||
, TElemAlignTop = (1 << 10)
|
||||
, TElemRipple = (1 << 11)
|
||||
, TElemInvalidated = (1 << 12)
|
||||
, TElemShortDogleg = (1 << 6)
|
||||
, TElemSourceDogleg = (1 << 7)
|
||||
, TElemTargetDogleg = (1 << 8)
|
||||
, TElemAlignBottom = (1 << 9)
|
||||
, TElemAlignCenter = (1 << 10)
|
||||
, TElemAlignTop = (1 << 11)
|
||||
, TElemRipple = (1 << 12)
|
||||
, TElemInvalidated = (1 << 13)
|
||||
};
|
||||
|
||||
|
||||
|
@ -113,10 +115,12 @@ namespace Katana {
|
|||
virtual bool isStrap () const;
|
||||
virtual bool isSlackened () const;
|
||||
virtual bool isDogleg () const;
|
||||
virtual bool isShortDogleg () const;
|
||||
virtual bool isReduced () const;
|
||||
virtual bool isUTurn () const;
|
||||
virtual bool isUserDefined () const;
|
||||
virtual bool isAnalog () const;
|
||||
virtual bool isShortNet () const;
|
||||
virtual bool isPriorityLocked () const = 0;
|
||||
// Predicates.
|
||||
inline bool isCreated () const;
|
||||
|
@ -143,6 +147,7 @@ namespace Katana {
|
|||
virtual Net* getNet () const = 0;
|
||||
virtual DbU::Unit getWidth () const = 0;
|
||||
virtual const Layer* getLayer () const = 0;
|
||||
virtual unsigned int getDepth () const;
|
||||
virtual DbU::Unit getPitch () const;
|
||||
virtual DbU::Unit getPPitch () const;
|
||||
virtual size_t getTrackSpan () const = 0;
|
||||
|
@ -200,7 +205,7 @@ namespace Katana {
|
|||
virtual TrackElement* makeDogleg ();
|
||||
inline bool makeDogleg ( Anabatic::GCell* );
|
||||
virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel );
|
||||
virtual TrackElement* makeDogleg ( Interval, Flags& flags );
|
||||
virtual Flags makeDogleg ( Interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags );
|
||||
virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel );
|
||||
virtual bool moveAside ( Flags flags );
|
||||
virtual bool slacken ( Flags flags=Flags::NoFlags );
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace Katana {
|
|||
virtual Flags getDirection () const;
|
||||
virtual Net* getNet () const;
|
||||
virtual DbU::Unit getWidth () const;
|
||||
virtual unsigned int getDepth () const;
|
||||
virtual const Layer* getLayer () const;
|
||||
virtual size_t getTrackSpan () const;
|
||||
virtual TrackElement* getNext () const;
|
||||
|
|
|
@ -75,11 +75,13 @@ namespace Katana {
|
|||
virtual bool isStrap () const;
|
||||
virtual bool isSlackened () const;
|
||||
virtual bool isDogleg () const;
|
||||
virtual bool isShortDogleg () const;
|
||||
virtual bool isReduced () const;
|
||||
virtual bool isUTurn () const;
|
||||
virtual bool isUserDefined () const;
|
||||
virtual bool isAnalog () const;
|
||||
virtual bool isWide () const;
|
||||
virtual bool isShortNet () const;
|
||||
virtual bool isPriorityLocked () const;
|
||||
// Predicates.
|
||||
virtual bool hasSymmetric () const;
|
||||
|
@ -96,6 +98,7 @@ namespace Katana {
|
|||
virtual Net* getNet () const;
|
||||
virtual DbU::Unit getWidth () const;
|
||||
virtual const Layer* getLayer () const;
|
||||
virtual unsigned int getDepth () const;
|
||||
virtual DbU::Unit getPitch () const;
|
||||
virtual DbU::Unit getPPitch () const;
|
||||
virtual DbU::Unit getExtensionCap ( Flags ) const;
|
||||
|
@ -138,7 +141,7 @@ namespace Katana {
|
|||
virtual void setAxis ( DbU::Unit, uint32_t flags );
|
||||
virtual TrackElement* makeDogleg ();
|
||||
virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel );
|
||||
virtual TrackElement* makeDogleg ( Interval, Flags& flags );
|
||||
virtual Flags makeDogleg ( Interval, TrackElement*& perpandicular, TrackElement*& parallel, Flags flags );
|
||||
virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel );
|
||||
virtual bool moveAside ( Flags );
|
||||
virtual bool slacken ( Flags flags=Flags::NoFlags );
|
||||
|
|
Loading…
Reference in New Issue