Fix bad computation of perpandicular free space in DataNegociate.
NOTE: This is likely to explain why we still got overlap in the track coherency check in very rare occasions. * Bug: In Katana::DataNegociate::update(), when computing the allowed free interval for the segment axis deduced from the perpandicularly connex segments, we account for the extension of the connecting VIA. Those extension varies according to the kind of VIA and are given by getExtensionCap(). We were accounting for the source & target extension VIA on the parallel segments, assuming that source/target would not swap when the perpandicular is moved. Which is *not* true. Now account for the extension of the *connecting* VIA on all ends. * Change: In AutoSegment::getTopologicalInfos(), enrich the list of perpandicularly connected segment with wether they are connex by their *source* or *target* contact. Mainly to be used by DataNegociate::update().
This commit is contained in:
parent
ae1f08f039
commit
3fa8d516bc
|
@ -251,15 +251,15 @@ namespace Anabatic {
|
|||
or (source.getY() > gcellsArea.getYMax())
|
||||
or (target.getX() <= gcellsArea.getXMin())
|
||||
or (target.getY() <= gcellsArea.getYMin()) ) {
|
||||
cerr << Error( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n"
|
||||
" * GCells area: %s\n"
|
||||
" * Obstacle area: [%s %s %s %s]"
|
||||
, getString(gcellsArea).c_str()
|
||||
, DbU::getValueString(source.getX()).c_str()
|
||||
, DbU::getValueString(source.getY()).c_str()
|
||||
, DbU::getValueString(target.getX()).c_str()
|
||||
, DbU::getValueString(target.getY()).c_str()
|
||||
) << endl;
|
||||
cerr << Warning( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n"
|
||||
" * GCells area: %s\n"
|
||||
" * Obstacle area: [%s %s %s %s]"
|
||||
, getString(gcellsArea).c_str()
|
||||
, DbU::getValueString(source.getX()).c_str()
|
||||
, DbU::getValueString(source.getY()).c_str()
|
||||
, DbU::getValueString(target.getX()).c_str()
|
||||
, DbU::getValueString(target.getY()).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
|
|
|
@ -3173,7 +3173,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoSegment::getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& aligneds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, vector< tuple<AutoSegment*,Flags> >&
|
||||
perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
)
|
||||
|
@ -3234,7 +3235,9 @@ namespace Anabatic {
|
|||
}
|
||||
} else {
|
||||
cdebug_log(149,0) << "| perpandicular " << currentSegment << endl;
|
||||
perpandiculars.push_back( currentSegment );
|
||||
Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact)
|
||||
? Flags::Source : Flags::Target;
|
||||
perpandiculars.push_back( make_tuple( currentSegment, perpandFlags ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -572,9 +572,9 @@ namespace Anabatic {
|
|||
|
||||
for ( AutoSegment* horizontal : horizontals ) {
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector<AutoSegment*> northBounds;
|
||||
vector<AutoSegment*> southBounds;
|
||||
vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
|
||||
//vector<AutoSegment*> northBounds;
|
||||
//vector<AutoSegment*> southBounds;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
//bool hasNorth = false;
|
||||
|
@ -582,12 +582,13 @@ namespace Anabatic {
|
|||
|
||||
AutoSegment::getTopologicalInfos( horizontal
|
||||
, collapseds
|
||||
, perpandiculars
|
||||
, perpandicularsDatas
|
||||
, leftBound
|
||||
, rightBound
|
||||
);
|
||||
|
||||
for ( AutoSegment* perpandicular : perpandiculars ) {
|
||||
for ( auto perpandicularDatas : perpandicularsDatas ) {
|
||||
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
|
||||
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
|
||||
|
||||
bool hasGlobal = false;
|
||||
|
|
|
@ -14,9 +14,8 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||
#define ANABATIC_AUTOSEGMENT_H
|
||||
|
||||
#pragma once
|
||||
#include <tuple>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
@ -39,6 +38,7 @@ namespace Hurricane {
|
|||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::tuple;
|
||||
using std::array;
|
||||
using std::set;
|
||||
using std::cerr;
|
||||
|
@ -468,7 +468,8 @@ namespace Anabatic {
|
|||
);
|
||||
static void getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, vector< tuple<AutoSegment*,Flags> >&
|
||||
perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
);
|
||||
|
@ -667,7 +668,8 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector< tuple<AutoSegment*,Flags> >
|
||||
perpandiculars;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
|
||||
|
@ -703,6 +705,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||
|
||||
|
||||
# endif // ANABATIC_AUTOSEGMENT_H
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Katana {
|
|||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::tuple;
|
||||
using std::map;
|
||||
using std::multimap;
|
||||
using std::make_pair;
|
||||
|
@ -91,7 +92,7 @@ namespace Katana {
|
|||
DbU::Unit pitch = _trackSegment->getPitch();
|
||||
#endif
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector< tuple<AutoSegment*,Anabatic::Flags> > perpandiculars;
|
||||
map<DbU::Unit,int> attractorSpins;
|
||||
|
||||
_reduceRanges[0].makeEmpty();
|
||||
|
@ -113,20 +114,21 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "Extracting attractors from perpandiculars." << endl;
|
||||
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
|
||||
Interval interval;
|
||||
AutoSegment* basePerpand = std::get<0>( perpandiculars[i] );
|
||||
TrackElement* perpandicular;
|
||||
|
||||
if (perpandiculars[i]->isCanonical()) {
|
||||
perpandicular = Session::lookup( perpandiculars[i]->base() );
|
||||
if (basePerpand->isCanonical()) {
|
||||
perpandicular = Session::lookup( basePerpand->base() );
|
||||
if (perpandicular) perpandicular->getCanonical( interval );
|
||||
} else {
|
||||
perpandicular = Session::lookup( perpandiculars[i]->getCanonical(interval)->base() );
|
||||
perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() );
|
||||
}
|
||||
if (not perpandicular) {
|
||||
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
|
||||
//, getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str()
|
||||
, getString(perpandiculars[i]->getCanonical(interval)).c_str()
|
||||
//, getString((void*)perpandiculars[i]->base()).c_str()
|
||||
, getString(perpandiculars[i]).c_str()
|
||||
//, getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
, getString(basePerpand->getCanonical(interval)).c_str()
|
||||
//, getString((void*)basePerpand->base()).c_str()
|
||||
, getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
|
@ -138,7 +140,7 @@ namespace Katana {
|
|||
//cerr << " " << interval << endl;
|
||||
//interval.inflate( DbU::fromLambda(-0.5) );
|
||||
|
||||
cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl;
|
||||
cdebug_log(159,0) << "| perpandicular: " << basePerpand << endl;
|
||||
cdebug_log(159,1) << "| canonical: " << perpandicular << endl;
|
||||
cdebug_log(159,0) << "Canonical // interval: " << interval << endl;
|
||||
|
||||
|
@ -181,9 +183,13 @@ namespace Katana {
|
|||
Interval trackFree = perpandicular->getFreeInterval();
|
||||
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;
|
||||
|
||||
_perpandicularFree.intersection
|
||||
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source)
|
||||
, -perpandicular->getExtensionCap(Flags::Target)) );
|
||||
DbU::Unit sourceCap = perpandicular->getExtensionCap( Flags::Source );
|
||||
DbU::Unit targetCap = perpandicular->getExtensionCap( Flags::Target );
|
||||
if (std::get<1>(perpandiculars[i]) & Flags::Source)
|
||||
targetCap = std::max( targetCap, sourceCap );
|
||||
else
|
||||
sourceCap = std::max( targetCap, sourceCap );
|
||||
_perpandicularFree.intersection( trackFree.inflate ( -sourceCap, -targetCap ) );
|
||||
cdebug_log(159,0) << "Source cap:"
|
||||
<< DbU::getValueString(perpandicular->getExtensionCap(Flags::Source)) << endl;
|
||||
} else if (perpandicular->isFixedAxis() /*or _trackSegment->isDogleg()*/) {
|
||||
|
@ -200,9 +206,10 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, target): " << trackFree << endl;
|
||||
}
|
||||
|
||||
Flags isSource = std::get<1>( perpandiculars[i] );
|
||||
_perpandicularFree.intersection
|
||||
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source)
|
||||
, -perpandicular->getExtensionCap(Flags::Target)) );
|
||||
( trackFree.inflate ( -perpandicular->getExtensionCap( isSource )
|
||||
, -perpandicular->getExtensionCap( isSource ) ));
|
||||
}
|
||||
} else {
|
||||
cdebug_log(159,0) << "Not in any track " << perpandicular << endl;
|
||||
|
@ -217,7 +224,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( (interval.getVMin() != _trackSegment->getAxis())
|
||||
or AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
or AutoSegment::isTopologicalBound(basePerpand
|
||||
,perpandicular->isHorizontal() ? Flags::Horizontal : 0
|
||||
) ) {
|
||||
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMin() );
|
||||
|
@ -230,7 +237,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( (interval.getVMax() != _trackSegment->getAxis())
|
||||
or AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
or AutoSegment::isTopologicalBound(basePerpand
|
||||
,Flags::Propagate | (perpandicular->isHorizontal() ? Flags::Horizontal : 0)
|
||||
) ) {
|
||||
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMax() );
|
||||
|
|
|
@ -446,6 +446,7 @@ namespace Katana {
|
|||
|
||||
double NegociateWindow::computeWirelength ()
|
||||
{
|
||||
bool isSymbolic = getKatanaEngine()->getConfiguration()->getRoutingGauge()->isSymbolic();
|
||||
set<TrackElement*> accounteds;
|
||||
double totalWL = 0.0;
|
||||
|
||||
|
@ -466,7 +467,10 @@ namespace Katana {
|
|||
if (accounteds.find(trackSegment) != accounteds.end()) continue;
|
||||
|
||||
accounteds.insert( trackSegment );
|
||||
gcellWL += DbU::getLambda( trackSegment->getLength() );
|
||||
if (isSymbolic)
|
||||
gcellWL += DbU::getLambda( trackSegment->getLength() );
|
||||
else
|
||||
gcellWL += DbU::toPhysical( trackSegment->getLength(), DbU::UnitPower::Nano );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,6 +479,7 @@ namespace Katana {
|
|||
totalWL += gcellWL;
|
||||
}
|
||||
|
||||
if (not isSymbolic) totalWL /= 1000.0;
|
||||
return totalWL;
|
||||
}
|
||||
|
||||
|
@ -634,6 +639,11 @@ namespace Katana {
|
|||
// _pack( count, false );
|
||||
//}
|
||||
|
||||
// if (RoutingEvent::getProcesseds() == 330332) {
|
||||
// UpdateSession::close();
|
||||
// Breakpoint::stop( 0, "Overlap has happened" );
|
||||
// UpdateSession::open();
|
||||
// }
|
||||
if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true );
|
||||
}
|
||||
//_pack( count, true );
|
||||
|
|
|
@ -772,6 +772,8 @@ namespace Katana {
|
|||
|
||||
bool Track::check ( uint32_t& overlaps, const char* message ) const
|
||||
{
|
||||
//if ((getIndex() != 5627) or not isHorizontal()) return true;
|
||||
|
||||
bool coherency = true;
|
||||
bool holes = false;
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace Katana {
|
|||
cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector< tuple<AutoSegment*,Flags> > perpandiculars;
|
||||
map<DbU::Unit,int> attractorSpins;
|
||||
|
||||
AutoSegment::getTopologicalInfos ( trackSegment->base()
|
||||
|
@ -93,28 +93,29 @@ namespace Katana {
|
|||
|
||||
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
|
||||
Interval interval;
|
||||
TrackElement* perpandicular;
|
||||
AutoSegment* basePerpand = tuple::get<0>( perpandiculars[i] );
|
||||
TrackElement* perpandicular = NULL;
|
||||
|
||||
if ( perpandiculars[i]->isCanonical() ) {
|
||||
perpandicular = Session::lookup ( perpandiculars[i]->base() );
|
||||
if ( basePerpand->isCanonical() ) {
|
||||
perpandicular = Session::lookup ( basePerpand->base() );
|
||||
if ( perpandicular )
|
||||
perpandicular->getCanonical ( interval );
|
||||
} else {
|
||||
perpandicular = Session::lookup ( perpandiculars[i]->getCanonical(interval)->base() );
|
||||
perpandicular = Session::lookup ( basePerpand->getCanonical(interval)->base() );
|
||||
}
|
||||
|
||||
if ( not perpandicular ) {
|
||||
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)"
|
||||
,getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str()
|
||||
,getString(perpandiculars[i]->getCanonical(interval)).c_str()
|
||||
,getString((void*)perpandiculars[i]->base()).c_str()
|
||||
,getString(perpandiculars[i]).c_str()
|
||||
,getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
,getString(basePerpand->getCanonical(interval)).c_str()
|
||||
,getString((void*)basePerpand->base()).c_str()
|
||||
,getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
interval.inflate ( DbU::lambda(-1.5) );
|
||||
|
||||
cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl;
|
||||
cdebug_log(159,0) << "| perpandicular: " << basePerpand << endl;
|
||||
cdebug_log(159,1) << "| canonical: " << perpandicular << endl;
|
||||
cdebug_log(159,0) << "interval: " << interval << endl;
|
||||
|
||||
|
@ -126,10 +127,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( ( interval.getVMin() != trackSegment->getAxis() )
|
||||
or AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
,false
|
||||
,perpandicular->isHorizontal()
|
||||
) ) {
|
||||
or AutoSegment::isTopologicalBound(basePerpand,false,perpandicular->isHorizontal()) ) {
|
||||
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMin() );
|
||||
if ( iattractor == attractorSpins.end() ) {
|
||||
attractorSpins.insert ( make_pair(interval.getVMin(),-1) );
|
||||
|
@ -140,10 +138,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( ( interval.getVMax() != trackSegment->getAxis() )
|
||||
or AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
,true
|
||||
,perpandicular->isHorizontal()
|
||||
) ) {
|
||||
or AutoSegment::isTopologicalBound(basePerpand,true,perpandicular->isHorizontal()) ) {
|
||||
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMax() );
|
||||
if ( iattractor == attractorSpins.end() ) {
|
||||
attractorSpins.insert ( make_pair(interval.getVMax(),1) );
|
||||
|
|
Loading…
Reference in New Issue