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:
Jean-Paul Chaput 2018-07-16 11:16:51 +02:00
parent b88c3336cd
commit 094cb8a132
34 changed files with 276 additions and 97 deletions

View File

@ -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() );

View File

@ -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;
}

View File

@ -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 );

View File

@ -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();
}

View File

@ -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 );

View File

@ -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 {

View File

@ -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; }

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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.

View File

@ -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();

View File

@ -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 );

View File

@ -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()

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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); }

View File

@ -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;

View File

@ -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);

View File

@ -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; }

View File

@ -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; }

View File

@ -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;
}

View File

@ -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) };

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 ();

View File

@ -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; }

View File

@ -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 );

View File

@ -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;

View File

@ -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 );