From 09eccacfeecbc3415ecc9ddc2a0fabdfd41836ce Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 11 Dec 2019 11:17:32 +0100 Subject: [PATCH] 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). --- cumulus/src/plugins/ConductorPlugin.py | 14 ++-- katana/src/BloatProfile.cpp | 17 +++-- katana/src/Constants.cpp | 8 ++- katana/src/GlobalRoute.cpp | 92 +++++++++++++++++++++++--- katana/src/GraphicKatanaEngine.cpp | 7 +- katana/src/PyKatanaFlags.cpp | 2 + katana/src/katana/Constants.h | 2 + 7 files changed, 115 insertions(+), 27 deletions(-) diff --git a/cumulus/src/plugins/ConductorPlugin.py b/cumulus/src/plugins/ConductorPlugin.py index f4325681..1ca2e576 100644 --- a/cumulus/src/plugins/ConductorPlugin.py +++ b/cumulus/src/plugins/ConductorPlugin.py @@ -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 diff --git a/katana/src/BloatProfile.cpp b/katana/src/BloatProfile.cpp index 56b62e0a..2434a2e8 100644 --- a/katana/src/BloatProfile.cpp +++ b/katana/src/BloatProfile.cpp @@ -73,8 +73,8 @@ namespace { DbU::Unit FlatInstance::getXFromOccurrence ( Occurrence o ) { Instance* instance = dynamic_cast( 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 ); diff --git a/katana/src/Constants.cpp b/katana/src/Constants.cpp index 461f9cc9..6a100773 100644 --- a/katana/src/Constants.cpp +++ b/katana/src/Constants.cpp @@ -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. diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index aa12c6a1..0ee138fd 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -182,6 +182,29 @@ namespace { } + void selectNets ( KatanaEngine* katana, set& 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& 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 ovSegs = ovEdges[iEdge]->getSegments(); + for ( size_t iSeg=ovEdges[iEdge]->getCapacity() ; iSeggetNet(); + 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 ); } diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index 60876a4a..85e9dd73 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -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()) { diff --git a/katana/src/PyKatanaFlags.cpp b/katana/src/PyKatanaFlags.cpp index 3fef92bf..13d85f89 100644 --- a/katana/src/PyKatanaFlags.cpp +++ b/katana/src/PyKatanaFlags.cpp @@ -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"); } diff --git a/katana/src/katana/Constants.h b/katana/src/katana/Constants.h index 83eee998..6ecb2fa3 100644 --- a/katana/src/katana/Constants.h +++ b/katana/src/katana/Constants.h @@ -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: