Various fixes for Katana::BloatProfile.

* Bug: In Katana::BloatProfile::FlatInstance for X & Y calculation of
    flattened instances reserse the order of transformation. We must apply
    the occurrence path transformation to the instance transformation,
    and not the other way around.
      Was causing the bug in SNX example.
* Bug: In Katana::BloatProfile::Slice::tagOverloadeds(), the underlying
    Gcell was not kept in synch with the instance. This was causing a right
    shift of the bloated area.
* New: In Katana::BloatProfile, add the selection of overloaded edges and
    failed nets.
      Add a flag to KatanaEngine::runGlobalrouter() to choose what failed/
    overloaded components to display (selectors).
This commit is contained in:
Jean-Paul Chaput 2019-12-11 11:17:32 +01:00
parent 8cc2d9f06e
commit 09eccacfee
7 changed files with 115 additions and 27 deletions

View File

@ -66,9 +66,9 @@ def ScriptMain ( **kw ):
stopLevel = Cfg.getParamInt('conductor.stopLevel').asInt()
Breakpoint.setStopLevel( stopLevel )
maxPlaceIteration = 2
maxPlaceIterations = 2
if Cfg.hasParameter('conductor.maxPlaceIterations'):
maxPlaceIteration = Cgf.getParamInt('conductor.maxPlaceIterations')
maxPlaceIterations = Cfg.getParamInt('conductor.maxPlaceIterations').asInt()
cell = None
if kw.has_key('cell') and kw['cell']:
@ -88,8 +88,8 @@ def ScriptMain ( **kw ):
katana = None
iteration = 0
while iteration < maxPlaceIteration:
print '\n o P&R Conductor iteration: %d' % iteration
while iteration < maxPlaceIterations:
print '\n o P&R Conductor iteration: %d (max:%s)' % (iteration,maxPlaceIterations)
if not (katana is None):
print ' o Global routing has failed, re-place design.'
@ -114,7 +114,11 @@ def ScriptMain ( **kw ):
katana.setPassNumber( iteration )
if editor: katana.setViewer( editor )
katana.digitalInit ()
katana.runGlobalRouter( Katana.Flags.ShowBloatedInstances )
katana.runGlobalRouter( Katana.Flags.ShowBloatedInstances
| Katana.Flags.ShowOverloadedEdges
| Katana.Flags.ShowOverloadedGCells
)
#| Katana.Flags.ShowFailedNets
Breakpoint.stop( 1, 'After routing iteration %d' % iteration )
if katana.isGlobalRoutingSuccess(): break

View File

@ -73,8 +73,8 @@ namespace {
DbU::Unit FlatInstance::getXFromOccurrence ( Occurrence o )
{
Instance* instance = dynamic_cast<Instance*>( o.getEntity() );
Transformation transf = o.getPath().getTransformation();
instance->getTransformation().applyOn( transf );
Transformation transf = instance->getTransformation();
o.getPath().getTransformation().applyOn( transf );
Box ab = instance->getMasterCell()->getAbutmentBox();
transf.applyOn( ab );
return ab.getXMin();
@ -145,10 +145,17 @@ namespace {
Edge* northEdge = _left->getNorthEdge();
bool bloated = false;
//cerr << "+ Slice @" << DbU::getValueString(getY()) << endl;
for ( FlatInstance& fi : _instances ) {
//cerr << "| @" << DbU::getValueString(fi.getX()) << " " << fi.getOccurrence() << endl;
if (fi.getX() >= gcell->getXMax()) {
for ( gcell = gcell->getEast() ; gcell and (fi.getX() < gcell->getXMin())
; gcell = gcell->getEast() );
for ( gcell = gcell->getEast() ; gcell and (fi.getX() > gcell->getXMax())
; gcell = gcell->getEast() ) {
//cerr << "| Skip " << gcell << endl;
}
//cerr << "| Advance to " << gcell << endl;
if (not gcell) break;
bloated = false;
@ -181,6 +188,8 @@ namespace {
BloatState* state = BloatExtension::get( fi.getOccurrence() );
if (not state) {
state = BloatExtension::create( fi.getOccurrence(), overload );
//cerr << "> Bloat: " << fi.getOccurrence() << endl;
//cerr << "> Under:" << gcell << endl;
++newCount;
} else {
state->setTracksCount( state->getTracksCount() + overload );

View File

@ -34,9 +34,11 @@ namespace Katana {
const Hurricane::BaseFlags Flags::SlowMotion = (1L << 30);
const Hurricane::BaseFlags Flags::PreRoutedStage = (1L << 31);
const Hurricane::BaseFlags Flags::PairSymmetrics = (1L << 32);
const Hurricane::BaseFlags Flags::ShowFailedGSegments = (1L << 33);
const Hurricane::BaseFlags Flags::ShowOverloadedGCells = (1L << 34);
const Hurricane::BaseFlags Flags::ShowBloatedInstances = (1L << 35);
const Hurricane::BaseFlags Flags::ShowFailedNets = (1L << 33);
const Hurricane::BaseFlags Flags::ShowFailedGSegments = (1L << 34);
const Hurricane::BaseFlags Flags::ShowOverloadedEdges = (1L << 35);
const Hurricane::BaseFlags Flags::ShowOverloadedGCells = (1L << 36);
const Hurricane::BaseFlags Flags::ShowBloatedInstances = (1L << 37);
} // Anabatic namespace.

View File

@ -182,6 +182,29 @@ namespace {
}
void selectNets ( KatanaEngine* katana, set<const Net*,Net::CompareByName>& nets )
{
if (katana->getViewer()) {
cmess2 << " o Selecting failed nets (slow)." << endl;
Dots dots ( cmess2, " ", 80, 100 );
if (not cmess2.enabled()) dots.disable();
katana->getViewer()->setShowSelection( false );
katana->getViewer()->setCumulativeSelection( true );
for ( const Net* net : nets ) {
Occurrence netOcc ( net );
katana->getViewer()->select( netOcc );
dots.dot();
}
dots.finish( Dots::Reset );
katana->getViewer()->setShowSelection( true );
}
}
void selectSegments ( KatanaEngine* katana, set<Segment*,DBo::CompareById>& segments )
{
if (katana->getViewer()) {
@ -260,6 +283,35 @@ namespace {
}
void selectOverloadedEdges ( KatanaEngine* katana )
{
CellViewer* viewer = katana->getViewer();
if (viewer) {
cmess2 << " o Selecting overloaded Edges (slow)." << endl;
Dots dots ( cmess2, " ", 80, 100 );
if (not cmess2.enabled()) dots.disable();
viewer->setShowSelection( false );
viewer->setCumulativeSelection( true );
for ( GCell* gcell : katana->getGCells() ) {
for ( Edge* edge : gcell->getEdges( Flags::NorthSide|Flags::EastSide ) ) {
if (edge->getRealOccupancy() > edge->getCapacity()) {
Occurrence edgeOcc ( edge );
viewer->select( edgeOcc );
dots.dot();
}
}
}
dots.finish( Dots::Reset );
viewer->setShowSelection( true );
}
}
void selectBloatedInstances ( KatanaEngine* katana )
{
CellViewer* viewer = katana->getViewer();
@ -464,9 +516,10 @@ namespace Katana {
else
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*getSearchHalo() );
bool globalEstimated = false;
size_t iteration = 0;
size_t netCount = 0;
bool globalEstimated = false;
size_t iteration = 0;
size_t netCount = 0;
uint64_t edgeOverflowWL = 0;
do {
cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:";
@ -524,12 +577,15 @@ namespace Katana {
//Breakpoint::stop( 1, "Before riping up overflowed edges." );
//openSession();
netCount = 0;
edgeOverflowWL = 0;
netCount = 0;
if (iteration < globalIterations - 1) {
size_t iEdge = 0;
while ( iEdge < ovEdges.size() ) {
Edge* edge = ovEdges[iEdge];
netCount += edge->ripup();
edgeOverflowWL += edge->getRealOccupancy() - edge->getCapacity();
netCount += edge->ripup();
if (iEdge >= ovEdges.size()) break;
if (ovEdges[iEdge] == edge) {
@ -545,12 +601,12 @@ namespace Katana {
dijkstra->setSearchAreaHalo( 3 * Session::getSliceHeight() );
}
cmess2 << " ovE:" << setw(4) << overflow;
cmess2 << " ovE:" << setw(4) << overflow << " " << setw(5) << edgeOverflowWL;
cmess2 << " ripup:" << setw(4) << netCount << right;
suspendMeasures();
cmess2 << " " << setw(5) << Timer::getStringTime (getTimer().getCombTime())
<< " " << setw(6) << Timer::getStringMemory(getTimer().getIncrease()) << endl;
cmess2 << " " << setw(6) << Timer::getStringMemory(getTimer().getIncrease())
<< " " << setw(5) << Timer::getStringTime (getTimer().getCombTime()) << endl;
resumeMeasures();
++iteration;
@ -577,9 +633,21 @@ namespace Katana {
if (ovEdges[iEdge]->isHorizontal()) hoverflow += edgeOverflow;
else voverflow += edgeOverflow;
for ( Segment* segment : ovEdges[iEdge]->getSegments() ) {
nets.insert( segment->getNet() );
if (edgeOverflow > 2) segments.insert( segment );
if (edgeOverflow > 0) {
const vector<Segment*> ovSegs = ovEdges[iEdge]->getSegments();
for ( size_t iSeg=ovEdges[iEdge]->getCapacity() ; iSeg<ovSegs.size() ; ++iSeg ) {
Net* net = ovSegs[iSeg]->getNet();
auto netData = getNetDatas().find( net->getId() );
if (netData == getNetDatas().end()) continue;
if ((*netData).second->getRpCount() > 20) {
cmess2 << " - Not showing " << net << " too much terminals ("
<< (*netData).second->getRpCount() << ")." << endl;
continue;
}
nets.insert( net );
}
}
}
@ -611,7 +679,9 @@ namespace Katana {
_buildBloatProfile();
if (flags & Flags::ShowFailedNets ) selectNets ( this, nets );
if (flags & Flags::ShowFailedGSegments ) selectSegments ( this, segments );
if (flags & Flags::ShowOverloadedEdges ) selectOverloadedEdges ( this );
if (flags & Flags::ShowOverloadedGCells) selectOverloadedGCells( this );
if (flags & Flags::ShowBloatedInstances) selectBloatedInstances( this );
}

View File

@ -155,20 +155,19 @@ namespace Katana {
#define EDGE_OVERLOAD_DISPLAY 1
#if NORMAL_DENSITY_DISPLAY
if ((unsigned int)edgeOccupancy < edge->getCapacity())
if ((unsigned int)edgeOccupancy <= edge->getCapacity())
occupancy = (uint32_t)( 255.0 * (edgeOccupancy / (float)edge->getCapacity()) );
#endif
#if HISTORIC_COST_DISPLAY
occupancy = (uint32_t)( 10.0 * edge->getHistoricCost() );
if (occupancy > 255) occupancy = 255;
#endif
#if EDGE_OVERLOAD_DISPLAY
if ((unsigned int)edgeOccupancy < edge->getCapacity())
if ((unsigned int)edgeOccupancy <= edge->getCapacity())
occupancy = 0;
else
occupancy = (uint32_t)( 20.0 * ((unsigned int)edgeOccupancy - edge->getCapacity()) );
if (occupancy > 255) occupancy = 255;
#endif
if (occupancy > 254) occupancy = 254;
QPainter& painter = widget->getPainter();
if ((unsigned int)edgeOccupancy > edge->getCapacity()) {

View File

@ -97,8 +97,10 @@ extern "C" {
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::SlowMotion ,"SlowMotion" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::PreRoutedStage ,"PreRoutedStage" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::PairSymmetrics ,"PairSymmetrics" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::ShowFailedNets ,"ShowFailedNets" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::ShowFailedGSegments ,"ShowFailedGSegments" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::ShowOverloadedGCells,"ShowOverloadedGCells");
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::ShowOverloadedEdges ,"ShowOverloadedEdges" );
LoadObjectConstant(PyTypeKatanaFlags.tp_dict,(uint64_t)Katana::Flags::ShowBloatedInstances,"ShowBloatedInstances");
}

View File

@ -39,7 +39,9 @@ namespace Katana {
static const Hurricane::BaseFlags SlowMotion;
static const Hurricane::BaseFlags PreRoutedStage;
static const Hurricane::BaseFlags PairSymmetrics;
static const Hurricane::BaseFlags ShowFailedNets;
static const Hurricane::BaseFlags ShowFailedGSegments;
static const Hurricane::BaseFlags ShowOverloadedEdges;
static const Hurricane::BaseFlags ShowOverloadedGCells;
static const Hurricane::BaseFlags ShowBloatedInstances;
public: