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 (source.getY() > gcellsArea.getYMax())
or (target.getX() <= gcellsArea.getXMin()) or (target.getX() <= gcellsArea.getXMin())
or (target.getY() <= gcellsArea.getYMin()) ) { or (target.getY() <= gcellsArea.getYMin()) ) {
cerr << Error( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n" cerr << Warning( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n"
" * GCells area: %s\n" " * GCells area: %s\n"
" * Obstacle area: [%s %s %s %s]" " * Obstacle area: [%s %s %s %s]"
, getString(gcellsArea).c_str() , getString(gcellsArea).c_str()
, DbU::getValueString(source.getX()).c_str() , DbU::getValueString(source.getX()).c_str()
, DbU::getValueString(source.getY()).c_str() , DbU::getValueString(source.getY()).c_str()
, DbU::getValueString(target.getX()).c_str() , DbU::getValueString(target.getX()).c_str()
, DbU::getValueString(target.getY()).c_str() , DbU::getValueString(target.getY()).c_str()
) << endl; ) << endl;
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close(); DebugSession::close();
return; return;

View File

@ -3173,7 +3173,8 @@ namespace Anabatic {
void AutoSegment::getTopologicalInfos ( AutoSegment* seed void AutoSegment::getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& aligneds , vector<AutoSegment*>& aligneds
, vector<AutoSegment*>& perpandiculars , vector< tuple<AutoSegment*,Flags> >&
perpandiculars
, DbU::Unit& leftBound , DbU::Unit& leftBound
, DbU::Unit& rightBound , DbU::Unit& rightBound
) )
@ -3234,7 +3235,9 @@ namespace Anabatic {
} }
} else { } else {
cdebug_log(149,0) << "| perpandicular " << currentSegment << endl; 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 ) { for ( AutoSegment* horizontal : horizontals ) {
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
vector<AutoSegment*> northBounds; //vector<AutoSegment*> northBounds;
vector<AutoSegment*> southBounds; //vector<AutoSegment*> southBounds;
DbU::Unit leftBound; DbU::Unit leftBound;
DbU::Unit rightBound; DbU::Unit rightBound;
//bool hasNorth = false; //bool hasNorth = false;
@ -582,12 +582,13 @@ namespace Anabatic {
AutoSegment::getTopologicalInfos( horizontal AutoSegment::getTopologicalInfos( horizontal
, collapseds , collapseds
, perpandiculars , perpandicularsDatas
, leftBound , leftBound
, rightBound , rightBound
); );
for ( AutoSegment* perpandicular : perpandiculars ) { for ( auto perpandicularDatas : perpandicularsDatas ) {
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue; if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
bool hasGlobal = false; bool hasGlobal = false;

View File

@ -14,9 +14,8 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef ANABATIC_AUTOSEGMENT_H #pragma once
#define ANABATIC_AUTOSEGMENT_H #include <tuple>
#include <set> #include <set>
#include <iostream> #include <iostream>
#include <functional> #include <functional>
@ -39,6 +38,7 @@ namespace Hurricane {
namespace Anabatic { namespace Anabatic {
using std::tuple;
using std::array; using std::array;
using std::set; using std::set;
using std::cerr; using std::cerr;
@ -468,7 +468,8 @@ namespace Anabatic {
); );
static void getTopologicalInfos ( AutoSegment* seed static void getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& collapseds , vector<AutoSegment*>& collapseds
, vector<AutoSegment*>& perpandiculars , vector< tuple<AutoSegment*,Flags> >&
perpandiculars
, DbU::Unit& leftBound , DbU::Unit& leftBound
, DbU::Unit& rightBound , DbU::Unit& rightBound
); );
@ -667,7 +668,8 @@ namespace Anabatic {
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl; cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Flags> >
perpandiculars;
DbU::Unit leftBound; DbU::Unit leftBound;
DbU::Unit rightBound; DbU::Unit rightBound;
@ -703,6 +705,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment); INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
# endif // ANABATIC_AUTOSEGMENT_H

View File

@ -29,6 +29,7 @@ namespace Katana {
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::tuple;
using std::map; using std::map;
using std::multimap; using std::multimap;
using std::make_pair; using std::make_pair;
@ -91,7 +92,7 @@ namespace Katana {
DbU::Unit pitch = _trackSegment->getPitch(); DbU::Unit pitch = _trackSegment->getPitch();
#endif #endif
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Anabatic::Flags> > perpandiculars;
map<DbU::Unit,int> attractorSpins; map<DbU::Unit,int> attractorSpins;
_reduceRanges[0].makeEmpty(); _reduceRanges[0].makeEmpty();
@ -113,20 +114,21 @@ namespace Katana {
cdebug_log(159,0) << "Extracting attractors from perpandiculars." << endl; cdebug_log(159,0) << "Extracting attractors from perpandiculars." << endl;
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
Interval interval; Interval interval;
AutoSegment* basePerpand = std::get<0>( perpandiculars[i] );
TrackElement* perpandicular; TrackElement* perpandicular;
if (perpandiculars[i]->isCanonical()) { if (basePerpand->isCanonical()) {
perpandicular = Session::lookup( perpandiculars[i]->base() ); perpandicular = Session::lookup( basePerpand->base() );
if (perpandicular) perpandicular->getCanonical( interval ); if (perpandicular) perpandicular->getCanonical( interval );
} else { } else {
perpandicular = Session::lookup( perpandiculars[i]->getCanonical(interval)->base() ); perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() );
} }
if (not perpandicular) { if (not perpandicular) {
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)" cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
//, getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str() //, getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
, getString(perpandiculars[i]->getCanonical(interval)).c_str() , getString(basePerpand->getCanonical(interval)).c_str()
//, getString((void*)perpandiculars[i]->base()).c_str() //, getString((void*)basePerpand->base()).c_str()
, getString(perpandiculars[i]).c_str() , getString(basePerpand).c_str()
) << endl; ) << endl;
continue; continue;
} }
@ -138,7 +140,7 @@ namespace Katana {
//cerr << " " << interval << endl; //cerr << " " << interval << endl;
//interval.inflate( DbU::fromLambda(-0.5) ); //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,1) << "| canonical: " << perpandicular << endl;
cdebug_log(159,0) << "Canonical // interval: " << interval << endl; cdebug_log(159,0) << "Canonical // interval: " << interval << endl;
@ -181,9 +183,13 @@ namespace Katana {
Interval trackFree = perpandicular->getFreeInterval(); Interval trackFree = perpandicular->getFreeInterval();
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl; cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;
_perpandicularFree.intersection DbU::Unit sourceCap = perpandicular->getExtensionCap( Flags::Source );
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source) DbU::Unit targetCap = perpandicular->getExtensionCap( Flags::Target );
, -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:" cdebug_log(159,0) << "Source cap:"
<< DbU::getValueString(perpandicular->getExtensionCap(Flags::Source)) << endl; << DbU::getValueString(perpandicular->getExtensionCap(Flags::Source)) << endl;
} else if (perpandicular->isFixedAxis() /*or _trackSegment->isDogleg()*/) { } 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; cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, target): " << trackFree << endl;
} }
Flags isSource = std::get<1>( perpandiculars[i] );
_perpandicularFree.intersection _perpandicularFree.intersection
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source) ( trackFree.inflate ( -perpandicular->getExtensionCap( isSource )
, -perpandicular->getExtensionCap(Flags::Target)) ); , -perpandicular->getExtensionCap( isSource ) ));
} }
} else { } else {
cdebug_log(159,0) << "Not in any track " << perpandicular << endl; cdebug_log(159,0) << "Not in any track " << perpandicular << endl;
@ -217,7 +224,7 @@ namespace Katana {
} }
if ( (interval.getVMin() != _trackSegment->getAxis()) if ( (interval.getVMin() != _trackSegment->getAxis())
or AutoSegment::isTopologicalBound(perpandiculars[i] or AutoSegment::isTopologicalBound(basePerpand
,perpandicular->isHorizontal() ? Flags::Horizontal : 0 ,perpandicular->isHorizontal() ? Flags::Horizontal : 0
) ) { ) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMin() ); map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMin() );
@ -230,7 +237,7 @@ namespace Katana {
} }
if ( (interval.getVMax() != _trackSegment->getAxis()) if ( (interval.getVMax() != _trackSegment->getAxis())
or AutoSegment::isTopologicalBound(perpandiculars[i] or AutoSegment::isTopologicalBound(basePerpand
,Flags::Propagate | (perpandicular->isHorizontal() ? Flags::Horizontal : 0) ,Flags::Propagate | (perpandicular->isHorizontal() ? Flags::Horizontal : 0)
) ) { ) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMax() ); map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMax() );

View File

@ -446,6 +446,7 @@ namespace Katana {
double NegociateWindow::computeWirelength () double NegociateWindow::computeWirelength ()
{ {
bool isSymbolic = getKatanaEngine()->getConfiguration()->getRoutingGauge()->isSymbolic();
set<TrackElement*> accounteds; set<TrackElement*> accounteds;
double totalWL = 0.0; double totalWL = 0.0;
@ -466,7 +467,10 @@ namespace Katana {
if (accounteds.find(trackSegment) != accounteds.end()) continue; if (accounteds.find(trackSegment) != accounteds.end()) continue;
accounteds.insert( trackSegment ); 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; totalWL += gcellWL;
} }
if (not isSymbolic) totalWL /= 1000.0;
return totalWL; return totalWL;
} }
@ -634,6 +639,11 @@ namespace Katana {
// _pack( count, false ); // _pack( count, false );
//} //}
// if (RoutingEvent::getProcesseds() == 330332) {
// UpdateSession::close();
// Breakpoint::stop( 0, "Overlap has happened" );
// UpdateSession::open();
// }
if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true );
} }
//_pack( count, true ); //_pack( count, true );

View File

@ -772,6 +772,8 @@ namespace Katana {
bool Track::check ( uint32_t& overlaps, const char* message ) const bool Track::check ( uint32_t& overlaps, const char* message ) const
{ {
//if ((getIndex() != 5627) or not isHorizontal()) return true;
bool coherency = true; bool coherency = true;
bool holes = false; bool holes = false;

View File

@ -78,7 +78,7 @@ namespace Katana {
cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl; cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl;
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Flags> > perpandiculars;
map<DbU::Unit,int> attractorSpins; map<DbU::Unit,int> attractorSpins;
AutoSegment::getTopologicalInfos ( trackSegment->base() AutoSegment::getTopologicalInfos ( trackSegment->base()
@ -93,28 +93,29 @@ namespace Katana {
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
Interval interval; Interval interval;
TrackElement* perpandicular; AutoSegment* basePerpand = tuple::get<0>( perpandiculars[i] );
TrackElement* perpandicular = NULL;
if ( perpandiculars[i]->isCanonical() ) { if ( basePerpand->isCanonical() ) {
perpandicular = Session::lookup ( perpandiculars[i]->base() ); perpandicular = Session::lookup ( basePerpand->base() );
if ( perpandicular ) if ( perpandicular )
perpandicular->getCanonical ( interval ); perpandicular->getCanonical ( interval );
} else { } else {
perpandicular = Session::lookup ( perpandiculars[i]->getCanonical(interval)->base() ); perpandicular = Session::lookup ( basePerpand->getCanonical(interval)->base() );
} }
if ( not perpandicular ) { if ( not perpandicular ) {
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)" cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)"
,getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str() ,getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
,getString(perpandiculars[i]->getCanonical(interval)).c_str() ,getString(basePerpand->getCanonical(interval)).c_str()
,getString((void*)perpandiculars[i]->base()).c_str() ,getString((void*)basePerpand->base()).c_str()
,getString(perpandiculars[i]).c_str() ,getString(basePerpand).c_str()
) << endl; ) << endl;
continue; continue;
} }
interval.inflate ( DbU::lambda(-1.5) ); 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,1) << "| canonical: " << perpandicular << endl;
cdebug_log(159,0) << "interval: " << interval << endl; cdebug_log(159,0) << "interval: " << interval << endl;
@ -126,10 +127,7 @@ namespace Katana {
} }
if ( ( interval.getVMin() != trackSegment->getAxis() ) if ( ( interval.getVMin() != trackSegment->getAxis() )
or AutoSegment::isTopologicalBound(perpandiculars[i] or AutoSegment::isTopologicalBound(basePerpand,false,perpandicular->isHorizontal()) ) {
,false
,perpandicular->isHorizontal()
) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMin() ); map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMin() );
if ( iattractor == attractorSpins.end() ) { if ( iattractor == attractorSpins.end() ) {
attractorSpins.insert ( make_pair(interval.getVMin(),-1) ); attractorSpins.insert ( make_pair(interval.getVMin(),-1) );
@ -140,10 +138,7 @@ namespace Katana {
} }
if ( ( interval.getVMax() != trackSegment->getAxis() ) if ( ( interval.getVMax() != trackSegment->getAxis() )
or AutoSegment::isTopologicalBound(perpandiculars[i] or AutoSegment::isTopologicalBound(basePerpand,true,perpandicular->isHorizontal()) ) {
,true
,perpandicular->isHorizontal()
) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMax() ); map<DbU::Unit,int>::iterator iattractor = attractorSpins.find ( interval.getVMax() );
if ( iattractor == attractorSpins.end() ) { if ( iattractor == attractorSpins.end() ) {
attractorSpins.insert ( make_pair(interval.getVMax(),1) ); attractorSpins.insert ( make_pair(interval.getVMax(),1) );