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:
Jean-Paul Chaput 2021-12-18 17:45:17 +01:00
parent ae1f08f039
commit 3fa8d516bc
8 changed files with 76 additions and 59 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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