diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 15f80dc8..abba3634 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -293,21 +293,22 @@ namespace Anabatic { AnabaticEngine::AnabaticEngine ( Cell* cell ) : Super(cell) - , _configuration (new Configuration()) - , _chipTools (cell) - , _state (EngineCreation) - , _matrix () - , _gcells () - , _ovEdges () - , _netOrdering () - , _netDatas () - , _viewer (NULL) - , _flags (Flags::DestroyBaseContact) - , _stamp (-1) - , _densityMode (MaxDensity) - , _autoSegmentLut () - , _autoContactLut () - , _blockageNet (cell->getNet("blockagenet")) + , _configuration (new Configuration()) + , _chipTools (cell) + , _state (EngineCreation) + , _matrix () + , _gcells () + , _ovEdges () + , _netOrdering () + , _netDatas () + , _viewer (NULL) + , _flags (Flags::DestroyBaseContact) + , _stamp (-1) + , _densityMode (MaxDensity) + , _autoSegmentLut () + , _autoContactLut () + , _edgeCapacitiesLut() + , _blockageNet (cell->getNet("blockagenet")) { _matrix.setCell( cell, _configuration->getSliceHeight() ); Edge::unity = _configuration->getSliceHeight(); @@ -824,8 +825,6 @@ namespace Anabatic { AutoSegment::IdSet processeds; for ( GCell* gcell : _gcells ) { - //cerr << "@ " << gcell << endl; - multiset acTerminals; for ( AutoContact* contact : gcell->getContacts() ) { if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) ) @@ -834,13 +833,11 @@ namespace Anabatic { AutoContactTerminal* south = NULL; for ( AutoContactTerminal* north : acTerminals ) { - //cerr << "@ " << north << endl; if (south) { if ( south->canDrag() and north->canDrag() and (south->getNet() != north->getNet()) and (south->getX () == north->getX ()) ) { - //Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() ); Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() ); AutoSegment* terminal = south->getSegment(); AutoContact* opposite = terminal->getOppositeAnchor( south ); @@ -848,10 +845,8 @@ namespace Anabatic { for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { segment->mergeUserConstraints( constraints ); constraineds.insert( segment ); - //cerr << "Apply " << constraints << " to " << segment << endl; } - //constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() ); constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() ); terminal = north->getSegment(); opposite = terminal->getOppositeAnchor( north ); @@ -859,12 +854,8 @@ namespace Anabatic { for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { segment->mergeUserConstraints( constraints ); constraineds.insert( segment ); - //cerr << "Apply " << constraints << " to " << segment << endl; } } - - //if (south->getConstraintBox().getHeight() < pitch3*2) metal2protect( south ); - //if (north->getConstraintBox().getHeight() < pitch3*2) metal2protect( north ); } south = north; } @@ -891,32 +882,31 @@ namespace Anabatic { AutoSegment* previous = NULL; for ( AutoSegment* aligned : aligneds ) { Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() ); - cerr << "aligned: " << aligned << " " << aligned->getUserConstraints() << endl; if (constraints.getSize() < Session::getPitch(1)) { - if (not previous) { - cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n" - " %s\n" - " S:%s\n" - " T:%s\n" - " Combined user constraints are too tight [%s : %s]." - , getString(aligned ).c_str() - , getString(aligned->getAutoSource()->getConstraintBox()).c_str() - , getString(aligned->getAutoTarget()->getConstraintBox()).c_str() - , DbU::getValueString(constraints.getVMin()).c_str() - , DbU::getValueString(constraints.getVMax()).c_str() - ) << endl; - } else { - cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n" - " %s\n" - " %s\n" - " Combined user constraints are too tight [%s : %s]." - , getString(previous).c_str() - , getString(aligned ).c_str() - , DbU::getValueString(constraints.getVMin()).c_str() - , DbU::getValueString(constraints.getVMax()).c_str() - ) << endl; - } + //if (not previous) { + // cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n" + // " %s\n" + // " S:%s\n" + // " T:%s\n" + // " Combined user constraints are too tight [%s : %s]." + // , getString(aligned ).c_str() + // , getString(aligned->getAutoSource()->getConstraintBox()).c_str() + // , getString(aligned->getAutoTarget()->getConstraintBox()).c_str() + // , DbU::getValueString(constraints.getVMin()).c_str() + // , DbU::getValueString(constraints.getVMax()).c_str() + // ) << endl; + //} else { + // cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n" + // " %s\n" + // " %s\n" + // " Combined user constraints are too tight [%s : %s]." + // , getString(previous).c_str() + // , getString(aligned ).c_str() + // , DbU::getValueString(constraints.getVMin()).c_str() + // , DbU::getValueString(constraints.getVMax()).c_str() + // ) << endl; + //} //if (previous) { // if (previous->getAutoTarget() == aligned->getAutoSource()) { // cerr << "Found a shared contact: " << aligned->getAutoSource() << endl; @@ -931,8 +921,6 @@ namespace Anabatic { previous = aligned; } - - cerr << "Final user constraints:" << userConstraints << endl; } Session::close(); @@ -1310,6 +1298,34 @@ namespace Anabatic { } + EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span ) + { + size_t depth = getConfiguration()->getAllowedDepth(); + EdgeCapacity* edgeCapacity = NULL; + + flags &= Flags::EdgeCapacityMask; + EdgeCapacity key ( this, flags, span, depth ); + + auto icap = _edgeCapacitiesLut.find( &key ); + if (icap != _edgeCapacitiesLut.end()) { + edgeCapacity = *icap; + } else { + edgeCapacity = new EdgeCapacity ( this, flags, span, depth ); + _edgeCapacitiesLut.insert( edgeCapacity ); + } + + edgeCapacity->incref(); + return edgeCapacity; + } + + + size_t AnabaticEngine::_unrefCapacity ( EdgeCapacity* capacity ) + { + if (capacity->getref() < 2) _edgeCapacitiesLut.erase( capacity ); + return capacity->decref(); + } + + void AnabaticEngine::_check ( Net* net ) const { cdebug_log(149,1) << "Checking " << net << endl; @@ -1376,10 +1392,13 @@ namespace Anabatic { Record* AnabaticEngine::_getRecord () const { Record* record = Super::_getRecord(); - record->add( getSlot("_configuration", _configuration) ); - record->add( getSlot("_gcells" , &_gcells ) ); - record->add( getSlot("_matrix" , &_matrix ) ); - record->add( getSlot("_flags" , &_flags ) ); + record->add( getSlot("_configuration" , _configuration ) ); + record->add( getSlot("_gcells" , &_gcells ) ); + record->add( getSlot("_matrix" , &_matrix ) ); + record->add( getSlot("_flags" , &_flags ) ); + record->add( getSlot("_autoSegmentLut" , &_autoSegmentLut ) ); + record->add( getSlot("_autoContactLut" , &_autoContactLut ) ); + record->add( getSlot("_edgeCapacitiesLut", &_edgeCapacitiesLut ) ); return record; } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index fe1c8b0c..ec0c2d42 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -402,7 +402,7 @@ namespace Anabatic { void AutoSegment::_initialize () { - cerr << "AutoSegment::_initialize()" << endl; + //cerr << "AutoSegment::_initialize()" << endl; _initialized = true; for ( size_t depth=0 ; depthisVertical()); uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; - cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() - << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; + //cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() + // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; *viaToSameCap = Session::getWireWidth(depth)/2; @@ -429,12 +429,12 @@ namespace Anabatic { *viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags ); } - cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; - cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; - if (depth > 0) - cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; - cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; - cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; + //cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; + //cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; + //if (depth > 0) + // cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; + //cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; + //cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; _extensionCaps.push_back( std::array( { viaToTopCap, viaToBottomCap, viaToSameCap } ) ); } diff --git a/anabatic/src/CMakeLists.txt b/anabatic/src/CMakeLists.txt index 6c675be3..c4456355 100644 --- a/anabatic/src/CMakeLists.txt +++ b/anabatic/src/CMakeLists.txt @@ -15,6 +15,7 @@ endif ( CHECK_DETERMINISM ) set( includes anabatic/Constants.h anabatic/Configuration.h anabatic/Matrix.h + anabatic/EdgeCapacity.h anabatic/Edge.h anabatic/Edges.h anabatic/GCell.h #anabatic/GCells.h anabatic/AnabaticEngine.h @@ -39,6 +40,7 @@ endif ( CHECK_DETERMINISM ) set( cpps Constants.cpp Configuration.cpp Matrix.cpp + EdgeCapacity.cpp Edge.cpp Edges.cpp GCell.cpp diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 44ee9f5c..2df94361 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -43,7 +43,9 @@ namespace Anabatic { const BaseFlags Flags::ChannelRow = (1L << 13); const BaseFlags Flags::HRailGCell = (1L << 14); const BaseFlags Flags::VRailGCell = (1L << 15); - const BaseFlags Flags::IllimitedCapacity = (1L << 5); +// Flags for Edge objects states only. + const BaseFlags Flags::NullCapacity = (1L << 5); + const BaseFlags Flags::InfiniteCapacity = (1L << 6); // Flags for Anabatic objects states only. const BaseFlags Flags::DemoMode = (1L << 5); const BaseFlags Flags::WarnOnGCellOverload = (1L << 6); @@ -78,6 +80,10 @@ namespace Anabatic { | StrutGCell | HRailGCell | VRailGCell; + const BaseFlags Flags::EdgeCapacityMask = Horizontal + | Vertical + | NullCapacity + | InfiniteCapacity ; // Flags for functions arguments only. const BaseFlags Flags::Create = (1L << 5); const BaseFlags Flags::WithPerpands = (1L << 6); diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index 1bed7d97..ddf42500 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -38,7 +38,8 @@ namespace Anabatic { Edge::Edge ( GCell* source, GCell* target, Flags flags ) : Super(source->getCell()) , _flags (flags|Flags::Invalidated) - , _capacity (0) + , _capacities (NULL) + , _reservedCapacity (0) , _realOccupancy (0) , _estimateOccupancy(0.0) , _historicCost (0.0) @@ -104,6 +105,7 @@ namespace Anabatic { void Edge::_preDestroy () { + _source->getAnabatic()->_unrefCapacity( _capacities ); _source->_remove( this, _flags|Flags::Source ); _target->_remove( this, _flags|Flags::Target ); @@ -179,8 +181,8 @@ namespace Anabatic { { unsigned int occupancy = 0; if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta; - if ((_realOccupancy <= _capacity) and (occupancy > _capacity)) getAnabatic()->addOv ( this ); - if ((_realOccupancy > _capacity) and (occupancy <= _capacity)) getAnabatic()->removeOv( this ); + if ((_realOccupancy <= getCapacity()) and (occupancy > getCapacity())) getAnabatic()->addOv ( this ); + if ((_realOccupancy > getCapacity()) and (occupancy <= getCapacity())) getAnabatic()->removeOv( this ); _realOccupancy = occupancy; } @@ -291,13 +293,14 @@ namespace Anabatic { { cdebug_log(110,1) << "Edge::materialize() " << this << endl; - Interval side = getSide(); + Flags flags = _flags; + Interval side = getSide(); _axis = side.getCenter(); - if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) _capacity = 0; - else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) _capacity = 100; - else - _capacity = getAnabatic()->getCapacity( side, _flags ); + if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) flags |= Flags::NullCapacity; + else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) flags |= Flags::InfiniteCapacity; + + _capacities = getAnabatic()->_createCapacity( _flags, side ); _flags.reset( Flags::Invalidated ); cdebug_log(110,0) << "Edge::materialize() " << this << endl; @@ -335,12 +338,12 @@ namespace Anabatic { bool Edge::isMaxCapacity ( Net* net ) const { if (net) { - cdebug_log(112,0) << "_capacity:" << _capacity << endl; + cdebug_log(112,0) << "_capacity:" << getCapacity() << endl; Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net ); - return ((_realOccupancy + state->getWPitch()) > _capacity) ? true : false; + return ((_realOccupancy + state->getWPitch()) > getCapacity()) ? true : false; } - return (_realOccupancy >= _capacity) ? true : false; + return (_realOccupancy >= getCapacity()) ? true : false; } @@ -366,7 +369,7 @@ namespace Anabatic { s.insert( s.size()-1, " " +DbU::getValueString(center.getY()) ); s.insert( s.size()-1, "] " +DbU::getValueString(_axis) ); s.insert( s.size()-1, " " +getString(_realOccupancy) ); - s.insert( s.size()-1, "/" +getString(_capacity) ); + s.insert( s.size()-1, "/" +getString(getCapacity()) ); s.insert( s.size()-1, " h:" +getString(_historicCost) ); s.insert( s.size()-1, " " +getString(_flags) ); return s; @@ -377,7 +380,8 @@ namespace Anabatic { { Record* record = Super::_getRecord(); record->add( getSlot("_flags" , _flags ) ); - record->add( getSlot("_capacity" , _capacity ) ); + record->add( getSlot("_capacities" , _capacities ) ); + record->add( getSlot("_reservedCapacity" , _reservedCapacity ) ); record->add( getSlot("_realOccupancy" , _realOccupancy ) ); record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); record->add( getSlot("_source" , _source ) ); diff --git a/anabatic/src/EdgeCapacity.cpp b/anabatic/src/EdgeCapacity.cpp new file mode 100644 index 00000000..84e944dd --- /dev/null +++ b/anabatic/src/EdgeCapacity.cpp @@ -0,0 +1,123 @@ +// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.cpp" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2018-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./EdgeCapacity.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "anabatic/EdgeCapacity.h" +#include "anabatic/AnabaticEngine.h" + + +namespace Anabatic { + + using std::ostringstream; + + + EdgeCapacity::EdgeCapacity ( AnabaticEngine* anabatic, Flags direction, Interval span, size_t depth ) + : _anabatic (anabatic) + , _refCount (0) + , _flags (direction) + , _depth (depth+1) + , _span (span) + , _capacities() + { + int defcap = (_flags & Flags::InfiniteCapacity) ? 100 : 0; + + _capacities.reserve( _depth ); + for ( size_t i=0 ; i<_depth ; ++i ) _capacities.push_back( defcap ); + + if (_flags & (Flags::NullCapacity|Flags::InfiniteCapacity)) return; + + Box ab = _anabatic->getCell()->getAbutmentBox(); + RoutingGauge* rg = _anabatic->getConfiguration()->getRoutingGauge(); + + span = _span; + span.inflate( 0, -1 ); + if (span.isEmpty()) return; + + const vector& layerGauges = rg->getLayerGauges(); + for ( size_t depth=0 ; depth < _depth ; ++depth ) { + if (layerGauges[depth]->getType() != Constant::Default) continue; + + if (_flags & Flags::Horizontal) { + if (layerGauges[depth]->getDirection() != Constant::Horizontal) continue; + _capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getYMin() + , span.getVMax() - ab.getYMin() ); + //cdebug_log(110,0) << "Horizontal edge capacity:" << capacity << endl; + } + + if (_flags & Flags::Vertical) { + if (layerGauges[depth]->getDirection() != Constant::Vertical) continue; + _capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getXMin() + , span.getVMax() - ab.getXMin() ); + //cdebug_log(110,0) << "Vertical edge capacity:" << capacity << endl; + } + } + } + + + void EdgeCapacity::forceCapacity ( unsigned int capacity ) + { + bool forced = false; + RoutingGauge* rg = _anabatic->getConfiguration()->getRoutingGauge(); + const vector& layerGauges = rg->getLayerGauges(); + + for ( size_t i=0 ; i<_depth ; ++i ) { + if (layerGauges[i]->getType() != Constant::Default) continue; + if ( (_flags & Flags::Horizontal) xor layerGauges[i]->isHorizontal() ) continue; + if (forced) _capacities[i] = 0; + else { + _capacities[i] = capacity; + forced = true; + } + } + } + + + string EdgeCapacity::_getString () const + { + ostringstream os; + os << ""; + return os.str(); + } + + + Record* EdgeCapacity::_getRecord () const + { + Record* record = new Record( getString(this) ); + record->add( getSlot( "_anabatic", _anabatic ) ); + record->add( getSlot( "_refCount", _refCount ) ); + record->add( getSlot( "_flags" , &_flags ) ); + record->add( getSlot( "_span" , &_span ) ); + + RoutingGauge* rg = getAnabatic()->getConfiguration()->getRoutingGauge(); + for ( size_t depth=0 ; depth<_depth ; ++depth ) { + ostringstream s; + const Layer* layer = rg->getRoutingLayer(depth); + s << "_capacities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; + record->add( getSlot ( s.str(), _capacities[depth] ) ); + } + return record; + } + + +} // Anabatic namespace. diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index b3d8990c..1ea69d60 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -447,6 +447,14 @@ namespace Anabatic { } + bool GCell::isHorizontalPlane ( size_t depth ) const + { return _anabatic->getConfiguration()->getLayerGauge(depth)->isHorizontal(); } + + + bool GCell::isVerticalPlane ( size_t depth ) const + { return _anabatic->getConfiguration()->getLayerGauge(depth)->isVertical(); } + + Contact* GCell::hasGContact ( const Net* net ) const { for ( Contact* contact : _gcontacts ) { @@ -1128,7 +1136,7 @@ namespace Anabatic { } - float GCell::getHCapacity () const + int GCell::getHCapacity () const { int capacity = 0; if (not _eastEdges.empty()) { @@ -1136,11 +1144,11 @@ namespace Anabatic { } else { for ( Edge* edge : _westEdges ) capacity += edge->getCapacity(); } - return (float)capacity; + return capacity; } - float GCell::getVCapacity () const + int GCell::getVCapacity () const { int capacity = 0; if (not _northEdges.empty()) { @@ -1148,7 +1156,20 @@ namespace Anabatic { } else { for ( Edge* edge : _southEdges ) capacity += edge->getCapacity(); } - return (float)capacity; + return capacity; + } + + + int GCell::getCapacity ( size_t depth ) const + { + const vector* edges = NULL; + if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges; + else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges; + + int capacity = 0; + for ( Edge* edge : *edges ) capacity += edge->getCapacity(depth); + + return capacity; } @@ -1171,8 +1192,8 @@ namespace Anabatic { float vdensity = 0.0; for ( size_t i=_pinDepth ; i<_depth ; i++ ) { - if ( i%2 ) { hdensity += _densities[i]; ++hplanes; } - else { vdensity += _densities[i]; ++vplanes; } + if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; } + else { vdensity += _densities[i]; ++vplanes; } } if (hplanes) hdensity /= hplanes; @@ -1197,7 +1218,7 @@ namespace Anabatic { float hdensity = 0.0; for ( size_t i=_pinDepth ; i<_depth ; i++ ) { - if (i%2) { hdensity += _densities[i]; ++hplanes; } + if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; } } if (hplanes) hdensity /= hplanes; @@ -1207,7 +1228,7 @@ namespace Anabatic { float vdensity = 0.0; for ( size_t i=_pinDepth ; i<_depth ; i++ ) { - if (i%2 == 0) { vdensity += _densities[i]; ++vplanes; } + if (isVerticalPlane(i)) { vdensity += _densities[i]; ++vplanes; } } if (vplanes) vdensity /= vplanes; @@ -1219,11 +1240,11 @@ namespace Anabatic { } } else if (getAnabatic()->getDensityMode() == MaxHDensity) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) { - if ((i%2) and (_densities[i] > density)) density = _densities[i]; + if (isHorizontalPlane(i) and (_densities[i] > density)) density = _densities[i]; } } else if (getAnabatic()->getDensityMode() == MaxVDensity) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) { - if ((i%2 == 0) and (_densities[i] > density)) density = _densities[i]; + if (isVerticalPlane(i) and (_densities[i] > density)) density = _densities[i]; } } @@ -1332,49 +1353,42 @@ namespace Anabatic { sort( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() ); sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() ); - float hcapacity = getHCapacity (); - float vcapacity = getVCapacity (); - float ccapacity = hcapacity * vcapacity * 4; - DbU::Unit width = getXMax() - getXMin(); - DbU::Unit height = getYMax() - getYMin(); - DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; - DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; - DbU::Unit uLengths1 [ _depth ]; - DbU::Unit uLengths2 [ _depth ]; - float localCounts [ _depth ]; - vector ufragments ( _depth ); + float ccapacity = getHCapacity() * getVCapacity() * (_depth-_pinDepth); + DbU::Unit width = getXMax() - getXMin(); + DbU::Unit height = getYMax() - getYMin(); + DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; + DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; + DbU::Unit uLengths1 [ _depth ]; + DbU::Unit uLengths2 [ _depth ]; + float localCounts [ _depth ]; + vector ufragments ( _depth ); for ( size_t i=0 ; i<_depth ; i++ ) { ufragments[i].setPitch ( Session::getPitch(i) ); _feedthroughs[i] = 0.0; + uLengths1 [i] = 0; uLengths2 [i] = 0; localCounts [i] = 0.0; _globalsCount[i] = 0.0; - if (Session::getDirection(i) & Flags::Horizontal) { - ufragments[i].setSpan ( getXMin(), getXMax() ); - ufragments[i].setCapacity( (size_t)hcapacity ); - } else { - ufragments[i].setSpan ( getYMin(), getYMax() ); - ufragments[i].setCapacity( (size_t)vcapacity ); - } + ufragments[i].setCapacity( (size_t)getCapacity(i) ); + if (isHorizontalPlane(i)) ufragments[i].setSpan( getXMin(), getXMax() ); + else ufragments[i].setSpan( getYMin(), getYMax() ); } // Compute wirelength associated to contacts (in DbU::Unit converted to float). AutoSegment::DepthLengthSet processeds; for ( AutoContact* contact : _contacts ) { for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; - contact->getLengths ( uLengths1, processeds ); + contact->getLengths( uLengths1, processeds ); for ( size_t i=0 ; i<_depth ; i++ ) { - if (Session::getDirection(i) & Flags::Horizontal) - uLengths2[i] += uLengths1[i]+hpenalty; - else - uLengths2[i] += uLengths1[i]+vpenalty; break; + if (isHorizontalPlane(i)) uLengths2[i] += uLengths1[i]+hpenalty; + else uLengths2[i] += uLengths1[i]+vpenalty; } } // Add the "pass through" horizontal segments. - if ( _hsegments.size() ) { + if (not _hsegments.empty()) { const Layer* layer = _hsegments[0]->getLayer(); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t count = 0; @@ -1398,7 +1412,7 @@ namespace Anabatic { } // Add the "pass through" vertical segments. - if ( _vsegments.size() ) { + if (not _vsegments.empty()) { const Layer* layer = _vsegments[0]->getLayer(); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t count = 0; @@ -1406,7 +1420,7 @@ namespace Anabatic { _globalsCount[depth] += 1.0; ufragments[depth].incGlobals(); - if ( layer != _vsegments[i]->getLayer() ) { + if (layer != _vsegments[i]->getLayer()) { uLengths2[depth] += count * height; count = 0; @@ -1416,18 +1430,16 @@ namespace Anabatic { count++; _feedthroughs[depth] += 1.0; } - if ( count ) { + if (count) { uLengths2[depth] += count * height; } } // Add the blockages. - for ( size_t i=0 ; i<_depth ; i++ ) { - uLengths2[i] += _blockages[i]; - } + for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i]; // Compute the number of non pass-through tracks. - if (processeds.size()) { + if (not processeds.empty()) { AutoSegment::DepthLengthSet::iterator isegment = processeds.begin(); const Layer* layer = (*isegment)->getLayer(); DbU::Unit axis = (*isegment)->getAxis(); @@ -1451,9 +1463,11 @@ namespace Anabatic { // Normalize: 0 < d < 1.0 (divide by H/V capacity). for ( size_t i=0 ; i<_depth ; i++ ) { + int capacity = getCapacity(i); + if (Session::getDirection(i) & Flags::Horizontal) { - if (width) { - _densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)width ); + if (width and capacity) { + _densities [i] = ((float)uLengths2[i]) / (float)( capacity * width ); _feedthroughs [i] += (float)(_blockages[i] / width); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width; } else { @@ -1462,8 +1476,8 @@ namespace Anabatic { _fragmentations[i] = 0; } } else { - if (height) { - _densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)height ); + if (height and capacity) { + _densities [i] = ((float)uLengths2[i]) / (float)( capacity * height ); _feedthroughs [i] += (float)(_blockages[i] / height); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height; } else { @@ -1488,17 +1502,16 @@ namespace Anabatic { void GCell::truncDensities () { - int hcapacity = (int)getHCapacity(); - int vcapacity = (int)getVCapacity(); - Box bBox = getBoundingBox(); + Box bBox = getBoundingBox(); for ( size_t i=0 ; i<_depth ; i++ ) { - if (Session::getDirection(i) & Flags::Horizontal) { - if (_blockages[i] > hcapacity * bBox.getWidth()) - _blockages[i] = hcapacity * bBox.getWidth(); + int capacity = getCapacity(i); + if (isHorizontalPlane(i)) { + if (_blockages[i] > capacity * bBox.getWidth()) + _blockages[i] = capacity * bBox.getWidth(); } else { - if (_blockages[i] > vcapacity * bBox.getHeight()) - _blockages[i] = vcapacity * bBox.getHeight(); + if (_blockages[i] > capacity * bBox.getHeight()) + _blockages[i] = capacity * bBox.getHeight(); } } _flags &= ~Flags::Saturated; @@ -1534,9 +1547,7 @@ namespace Anabatic { { if (isInvalidated()) const_cast(this)->updateDensity(); - float capacity = 0.0; - if (Session::getDirection(depth) & Flags::Horizontal) capacity = getHCapacity(); - else capacity = getVCapacity(); + float capacity = getCapacity(depth); cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() @@ -1704,14 +1715,15 @@ namespace Anabatic { return false; } - void GCell::setEdgesOccupancy ( unsigned int width, unsigned int height ) + + void GCell::forceEdgesCapacities ( unsigned int hcapacity, unsigned int vcapacity ) { - if (getEastEdge() ) getEastEdge()->setCapacity(width); - if (getWestEdge() ) getWestEdge()->setCapacity(width); - if (getNorthEdge()) getNorthEdge()->setCapacity(height); - if (getSouthEdge()) getSouthEdge()->setCapacity(height); - if (getEastEdge() ) getEastEdge()->setRealOccupancy(0); - if (getWestEdge() ) getWestEdge()->setRealOccupancy(0); + if (getEastEdge() ) getEastEdge ()->forceCapacity( hcapacity ); + if (getWestEdge() ) getWestEdge ()->forceCapacity( hcapacity ); + if (getNorthEdge()) getNorthEdge()->forceCapacity( vcapacity ); + if (getSouthEdge()) getSouthEdge()->forceCapacity( vcapacity ); + if (getEastEdge() ) getEastEdge ()->setRealOccupancy(0); + if (getWestEdge() ) getWestEdge ()->setRealOccupancy(0); if (getNorthEdge()) getNorthEdge()->setRealOccupancy(0); if (getSouthEdge()) getSouthEdge()->setRealOccupancy(0); } diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index ca794c40..452d9fcb 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -256,6 +256,8 @@ namespace Anabatic { void _unlink ( AutoSegment* ); AutoContact* _lookup ( Contact* ) const; AutoSegment* _lookup ( Segment* ) const; + EdgeCapacity* _createCapacity ( Flags, Interval ); + size_t _unrefCapacity ( EdgeCapacity* ); void _loadGrByNet (); void _computeNetOptimals ( Net* ); void _computeNetTerminals ( Net* ); @@ -294,22 +296,23 @@ namespace Anabatic { AnabaticEngine ( const AnabaticEngine& ); AnabaticEngine& operator= ( const AnabaticEngine& ); private: - static Name _toolName; - Configuration* _configuration; - ChipTools _chipTools; - EngineState _state; - Matrix _matrix; - vector _gcells; - vector _ovEdges; - vector _netOrdering; - NetDatas _netDatas; - CellViewer* _viewer; - Flags _flags; - int _stamp; - uint64_t _densityMode; - AutoSegmentLut _autoSegmentLut; - AutoContactLut _autoContactLut; - Net* _blockageNet; + static Name _toolName; + Configuration* _configuration; + ChipTools _chipTools; + EngineState _state; + Matrix _matrix; + vector _gcells; + vector _ovEdges; + vector _netOrdering; + NetDatas _netDatas; + CellViewer* _viewer; + Flags _flags; + int _stamp; + uint64_t _densityMode; + AutoSegmentLut _autoSegmentLut; + AutoContactLut _autoContactLut; + EdgeCapacityLut _edgeCapacitiesLut; + Net* _blockageNet; }; diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 8cdd2c3a..285c155d 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -44,7 +44,8 @@ namespace Anabatic { static const BaseFlags HRailGCell ; // = (1 << 14); static const BaseFlags VRailGCell ; // = (1 << 15); // Flags for Edge objects states only. - static const BaseFlags IllimitedCapacity ; // = (1 << 5); + static const BaseFlags NullCapacity ; // = (1 << 5); + static const BaseFlags InfiniteCapacity ; // = (1 << 6); // Flags for Anabatic objects states only. static const BaseFlags DemoMode ; // = (1 << 5); static const BaseFlags WarnOnGCellOverload ; // = (1 << 6); @@ -65,6 +66,7 @@ namespace Anabatic { static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell|HRailGCell|VRailGCell; static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow; static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|HRailGCell|VRailGCell; + static const BaseFlags EdgeCapacityMask ; // = Horizontal|Vertical|NullCapacity|InfiniteCapacity ; // Flags for functions arguments only. static const BaseFlags Create ; // = (1 << 5); static const BaseFlags WithPerpands ; diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index 576de9ac..febb46a7 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -26,10 +26,10 @@ namespace Hurricane { class Segment; } #include "anabatic/Constants.h" +#include "anabatic/EdgeCapacity.h" #include "anabatic/Edges.h" - namespace Anabatic { using std::string; @@ -60,6 +60,7 @@ namespace Anabatic { inline bool isHorizontal () const; inline bool hasNet ( const Net* ) const; inline unsigned int getCapacity () const; + inline unsigned int getCapacity ( size_t depth ) const; inline unsigned int getRealOccupancy () const; inline unsigned int getEstimateOccupancy () const; inline float getHistoricCost () const; @@ -73,8 +74,10 @@ namespace Anabatic { Interval getSide () const; Segment* getSegment ( const Net* ) const; inline const vector& getSegments () const; - inline void setCapacity ( int ); - inline void incCapacity ( int ); + //inline void setCapacity ( int ); + //inline void incCapacity ( int ); + inline void forceCapacity ( int ); + inline void reserveCapacity ( int ); inline void setRealOccupancy ( int ); void incRealOccupancy ( int ); void incRealOccupancy2 ( int ); @@ -114,7 +117,8 @@ namespace Anabatic { private: static Name _extensionName; Flags _flags; - unsigned int _capacity; + EdgeCapacity* _capacities; + unsigned int _reservedCapacity; unsigned int _realOccupancy; float _estimateOccupancy; float _historicCost; @@ -129,7 +133,8 @@ namespace Anabatic { inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } - inline unsigned int Edge::getCapacity () const { return _capacity; } + inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; } + inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline float Edge::getHistoricCost () const { return _historicCost; } @@ -137,8 +142,10 @@ namespace Anabatic { inline GCell* Edge::getTarget () const { return _target; } inline DbU::Unit Edge::getAxis () const { return _axis; } inline const vector& Edge::getSegments () const { return _segments; } - inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } - inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; } + inline void Edge::forceCapacity ( int capacity ) { if (_capacities) _capacities->forceCapacity(capacity); } + inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; } +//inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } +//inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; } inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; } inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; } inline const Flags& Edge::flags () const { return _flags; } diff --git a/anabatic/src/anabatic/EdgeCapacity.h b/anabatic/src/anabatic/EdgeCapacity.h new file mode 100644 index 00000000..ceda5cb2 --- /dev/null +++ b/anabatic/src/anabatic/EdgeCapacity.h @@ -0,0 +1,99 @@ +// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2018-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./anabatic/EdgeCapacity.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ANABATIC_EDGE_CAPACITY_H +#define ANABATIC_EDGE_CAPACITY_H + +#include +#include +#include "hurricane/Interval.h" +#include "anabatic/Constants.h" + +namespace Anabatic { + + using Hurricane::Record; + using Hurricane::DbU; + using Hurricane::Interval; + class AnabaticEngine; + + +// ------------------------------------------------------------------- +// Class : "EdgeCapacity". + + class EdgeCapacity { + public: + class Compare { + public: + inline bool operator() ( const EdgeCapacity*, const EdgeCapacity* ) const; + }; + public: + EdgeCapacity ( AnabaticEngine*, Flags, Interval, size_t depth ); + inline size_t incref (); + inline size_t decref (); + inline size_t getref () const; + inline AnabaticEngine* getAnabatic () const; + inline const Interval& getSpan () const; + inline int getCapacity () const; + inline int getCapacity ( size_t depth ) const; + void forceCapacity ( unsigned int ); + std::string _getString () const; + Record* _getRecord () const; + private: + private: + AnabaticEngine* _anabatic; + size_t _refCount; + Flags _flags; + size_t _depth; + Interval _span; + std::vector _capacities; + }; + + + inline size_t EdgeCapacity::incref () { return ++_refCount; } + inline size_t EdgeCapacity::decref () { if (_refCount < 2) { delete this; return 0; } return --_refCount; } + inline size_t EdgeCapacity::getref () const { return _refCount; } + inline AnabaticEngine* EdgeCapacity::getAnabatic () const { return _anabatic; } + inline const Interval& EdgeCapacity::getSpan () const { return _span; } + inline int EdgeCapacity::getCapacity ( size_t depth ) const { return (depth<_depth) ? _capacities[depth] : 0; } + + inline int EdgeCapacity::getCapacity () const + { + int full = 0; + for ( size_t depth=0; depth<_depth ; ++depth ) full += _capacities[depth]; + return full; + } + + inline bool EdgeCapacity::Compare::operator() ( const EdgeCapacity* lhs, const EdgeCapacity* rhs ) const + { + if ( (lhs->_flags & Flags::Horizontal) and not (rhs->_flags & Flags::Horizontal)) return true; + if (not (lhs->_flags & Flags::Horizontal) and (rhs->_flags & Flags::Horizontal)) return false; + + DbU::Unit dmin = lhs->getSpan().getVMin() - rhs->getSpan().getVMin(); + if (dmin < 0) return true; + if (dmin > 0) return false; + return lhs->getSpan().getVMax() < rhs->getSpan().getVMax(); + } + + + typedef std::set EdgeCapacityLut; + + +} // Anabatic namespace. + + +INSPECTOR_P_SUPPORT(Anabatic::EdgeCapacity); + +#endif // ANABATIC_EDGE_CAPACITY_H diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index f9eafb1e..97d301df 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -64,6 +64,8 @@ namespace Anabatic { class AnabaticEngine; class GCell; + + // ------------------------------------------------------------------- @@ -123,172 +125,176 @@ namespace Anabatic { float _density; }; public: - static uint32_t getDisplayMode (); - static void setDisplayMode ( uint32_t ); - static Box getBorder ( const GCell*, const GCell* ); - public: - static GCell* create ( AnabaticEngine* ); - public: - inline bool isSaturated () const; - bool isSaturated ( size_t depth ) const; - inline bool isInvalidated () const; - inline bool isHFlat () const; - inline bool isVFlat () const; - inline bool isFlat () const; - inline bool isDevice () const; - inline bool isHChannel () const; - inline bool isVChannel () const; - inline bool isStrut () const; - inline bool isAnalog () const; - inline bool isMatrix () const; - inline bool isRow () const; - inline bool isIoPad () const; - inline bool isHRail () const; - inline bool isVRail () const; - inline bool isStdCellRow () const; - inline bool isChannelRow () const; - bool isWest ( GCell* ) const; - bool isEast ( GCell* ) const; - bool isNorth ( GCell* ) const; - bool isSouth ( GCell* ) const; - Contact* hasGContact ( const Contact* ) const; - Contact* hasGContact ( const Net* ) const; - inline AnabaticEngine* getAnabatic () const; - inline Flags getType () const; - inline DbU::Unit getXMin () const; - inline DbU::Unit getYMin () const; - inline DbU::Unit getXMax ( int shrink=0 ) const; - inline DbU::Unit getYMax ( int shrink=0 ) const; - inline DbU::Unit getXCenter () const; - inline DbU::Unit getYCenter () const; - inline DbU::Unit getConstraintXMax ( int shrink=0 ) const; - inline DbU::Unit getConstraintYMax ( int shrink=0 ) const; - inline Interval getSide ( Flags direction, int shrink=0 ) const; - inline Point getCenter () const; - inline Box getConstraintBox () const; - inline const vector& getWestEdges () const; - inline const vector& getEastEdges () const; - inline const vector& getNorthEdges () const; - inline const vector& getSouthEdges () const; - Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const; - Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const; - inline Edges getEdges ( Flags sides=Flags::AllSides ) const; - inline GCell* getWest () const; - inline GCell* getEast () const; - inline GCell* getSouth () const; - inline GCell* getNorth () const; + static uint32_t getDisplayMode (); + static void setDisplayMode ( uint32_t ); + static Box getBorder ( const GCell*, const GCell* ); + public: + static GCell* create ( AnabaticEngine* ); + public: + inline bool isSaturated () const; + bool isSaturated ( size_t depth ) const; + inline bool isInvalidated () const; + inline bool isHFlat () const; + inline bool isVFlat () const; + inline bool isFlat () const; + inline bool isDevice () const; + inline bool isHChannel () const; + inline bool isVChannel () const; + inline bool isStrut () const; + inline bool isAnalog () const; + inline bool isMatrix () const; + inline bool isRow () const; + inline bool isIoPad () const; + inline bool isHRail () const; + inline bool isVRail () const; + inline bool isStdCellRow () const; + inline bool isChannelRow () const; + bool isWest ( GCell* ) const; + bool isEast ( GCell* ) const; + bool isNorth ( GCell* ) const; + bool isSouth ( GCell* ) const; + Contact* hasGContact ( const Contact* ) const; + Contact* hasGContact ( const Net* ) const; + bool isHorizontalPlane ( size_t depth ) const; + bool isVerticalPlane ( size_t depth ) const; + inline AnabaticEngine* getAnabatic () const; + inline Flags getType () const; + inline DbU::Unit getXMin () const; + inline DbU::Unit getYMin () const; + inline DbU::Unit getXMax ( int shrink=0 ) const; + inline DbU::Unit getYMax ( int shrink=0 ) const; + inline DbU::Unit getXCenter () const; + inline DbU::Unit getYCenter () const; + inline DbU::Unit getConstraintXMax ( int shrink=0 ) const; + inline DbU::Unit getConstraintYMax ( int shrink=0 ) const; + inline Interval getSide ( Flags direction, int shrink=0 ) const; + inline Point getCenter () const; + inline Box getConstraintBox () const; + inline const vector& getWestEdges () const; + inline const vector& getEastEdges () const; + inline const vector& getNorthEdges () const; + inline const vector& getSouthEdges () const; + Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const; + Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const; + inline Edges getEdges ( Flags sides=Flags::AllSides ) const; + inline GCell* getWest () const; + inline GCell* getEast () const; + inline GCell* getSouth () const; + inline GCell* getNorth () const; + + GCell* getEastNMatrix () const; + GCell* getNorthNMatrix () const; + + inline Edge* getWestEdge () const; + inline Edge* getEastEdge () const; + inline Edge* getSouthEdge () const; + inline Edge* getNorthEdge () const; + + GCell* getWest ( DbU::Unit y ) const; + GCell* getEast ( DbU::Unit y ) const; + GCell* getSouth ( DbU::Unit x ) const; + GCell* getNorth ( DbU::Unit x ) const; + GCell* getNeighborAt ( Flags side, DbU::Unit axis ) const; + GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const; + inline GCell* getUnder ( Point p ) const; + GCell* hcut ( DbU::Unit y ); + GCell* vcut ( DbU::Unit x ); + bool doGrid (); + Contact* getGContact ( Net* ); + inline const vector& getGContacts () const; + Contact* breakGoThrough ( Net* net ); + bool unrefContact ( Contact* ); + void setSouthWestCorner ( DbU::Unit x, DbU::Unit y ); + void cleanupGlobal (); + inline DbU::Unit getWidth () const; + inline DbU::Unit getHeight () const; + // Detailed routing functions. + bool hasFreeTrack ( size_t depth, float reserve ) const; + inline size_t getDepth () const; + size_t getNetCount () const; + int getHCapacity () const; + int getVCapacity () const; + int getCapacity ( size_t depth ) const; + float getDensity ( Flags flags=Flags::NoFlags ) const; + float getDensity ( size_t depth ) const; + float getAverageHVDensity () const; + float getMaxHVDensity () const; + inline float getCDensity ( Flags flags=Flags::NoFlags ) const; + inline float getWDensity ( size_t depth, Flags flags=Flags::NoFlags ) const; + inline DbU::Unit getBlockage ( size_t depth ) const; + inline float getFragmentation ( size_t depth ) const; + inline float getFeedthroughs ( size_t depth ) const; + inline float getGlobalsCount ( size_t depth ) const; + inline const vector& getHSegments () const; + inline const vector& getVSegments () const; + inline const vector& getContacts () const; + AutoSegments getHStartSegments (); + AutoSegments getVStartSegments (); + AutoSegments getHStopSegments (); + AutoSegments getVStopSegments (); + inline AutoSegments getStartSegments ( Flags direction ); + inline AutoSegments getStopSegments ( Flags direction ); + size_t getRoutingPads ( set& ); + inline const Key& getKey () const; + size_t checkDensity () const; + bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const; + void setType ( Flags ); + void addBlockage ( size_t depth, DbU::Unit ); + inline void addHSegment ( AutoSegment* ); + inline void addVSegment ( AutoSegment* ); + inline void addContact ( AutoContact* ); + void removeVSegment ( AutoSegment* ); + void removeHSegment ( AutoSegment* ); + void removeContact ( AutoContact* ); + void updateContacts (); + size_t updateDensity (); + inline void updateKey ( size_t depth ); + void truncDensities (); + bool stepBalance ( size_t depth, Set& invalidateds ); + void rpDesaturate ( set& ); + bool stepDesaturate ( size_t depth + , set&, AutoSegment*& moved + , Flags flags=Flags::NoFlags ); + bool stepNetDesaturate ( size_t depth + , set& globalNets + , Set& invalidateds ); - GCell* getEastNMatrix () const; - GCell* getNorthNMatrix () const; - - inline Edge* getWestEdge () const; - inline Edge* getEastEdge () const; - inline Edge* getSouthEdge () const; - inline Edge* getNorthEdge () const; - - GCell* getWest ( DbU::Unit y ) const; - GCell* getEast ( DbU::Unit y ) const; - GCell* getSouth ( DbU::Unit x ) const; - GCell* getNorth ( DbU::Unit x ) const; - GCell* getNeighborAt ( Flags side, DbU::Unit axis ) const; - GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const; - inline GCell* getUnder ( Point p ) const; - GCell* hcut ( DbU::Unit y ); - GCell* vcut ( DbU::Unit x ); - bool doGrid (); - Contact* getGContact ( Net* ); - inline const vector& getGContacts () const; - Contact* breakGoThrough ( Net* net ); - bool unrefContact ( Contact* ); - void setSouthWestCorner ( DbU::Unit x, DbU::Unit y ); - void cleanupGlobal (); - inline DbU::Unit getWidth () const; - inline DbU::Unit getHeight () const; - // Detailed routing functions. - bool hasFreeTrack ( size_t depth, float reserve ) const; - inline size_t getDepth () const; - size_t getNetCount () const; - float getHCapacity () const; - float getVCapacity () const; - float getDensity ( Flags flags=Flags::NoFlags ) const; - float getAverageHVDensity () const; - float getMaxHVDensity () const; - inline float getCDensity ( Flags flags=Flags::NoFlags ) const; - inline float getWDensity ( size_t depth, Flags flags=Flags::NoFlags ) const; - inline DbU::Unit getBlockage ( size_t depth ) const; - inline float getFragmentation ( size_t depth ) const; - inline float getFeedthroughs ( size_t depth ) const; - inline float getGlobalsCount ( size_t depth ) const; - inline const vector& getHSegments () const; - inline const vector& getVSegments () const; - inline const vector& getContacts () const; - AutoSegments getHStartSegments (); - AutoSegments getVStartSegments (); - AutoSegments getHStopSegments (); - AutoSegments getVStopSegments (); - inline AutoSegments getStartSegments ( Flags direction ); - inline AutoSegments getStopSegments ( Flags direction ); - size_t getRoutingPads ( set& ); - inline const Key& getKey () const; - size_t checkDensity () const; - bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const; - void setType ( Flags ); - void addBlockage ( size_t depth, DbU::Unit ); - inline void addHSegment ( AutoSegment* ); - inline void addVSegment ( AutoSegment* ); - inline void addContact ( AutoContact* ); - void removeVSegment ( AutoSegment* ); - void removeHSegment ( AutoSegment* ); - void removeContact ( AutoContact* ); - void updateContacts (); - size_t updateDensity (); - inline void updateKey ( size_t depth ); - void truncDensities (); - bool stepBalance ( size_t depth, Set& invalidateds ); - void rpDesaturate ( set& ); - bool stepDesaturate ( size_t depth - , set&, AutoSegment*& moved - , Flags flags=Flags::NoFlags ); - bool stepNetDesaturate ( size_t depth - , set& globalNets - , Set& invalidateds ); - - void setEdgesOccupancy (unsigned int, unsigned int); + void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities ); // Misc. functions. - inline const Flags& flags () const; - inline Flags& flags (); - void _add ( Edge* edge, Flags side ); - void _remove ( Edge* edge, Flags side=Flags::AllSides ); - void _destroyEdges (); - private: - void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); - public: - // Observers. - template - inline OwnerT* getObserver ( size_t slot ); - inline void setObserver ( size_t slot, BaseObserver* ); - inline void notify ( unsigned int flags ); - // ExtensionGo support. - inline const Name& staticGetName (); - virtual const Name& getName () const; - virtual void translate ( const DbU::Unit&, const DbU::Unit& ); - virtual Box getBoundingBox () const; - virtual void invalidate ( bool propagateFlag=true ); - virtual void materialize (); - public: - // Inspector support. - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - protected: - GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); - virtual ~GCell (); - GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - GCell ( const GCell& ); - GCell& operator= ( const GCell& ); + inline const Flags& flags () const; + inline Flags& flags (); + void _add ( Edge* edge, Flags side ); + void _remove ( Edge* edge, Flags side=Flags::AllSides ); + void _destroyEdges (); + private: + void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); + public: + // Observers. + template + inline OwnerT* getObserver ( size_t slot ); + inline void setObserver ( size_t slot, BaseObserver* ); + inline void notify ( unsigned int flags ); + // ExtensionGo support. + inline const Name& staticGetName (); + virtual const Name& getName () const; + virtual void translate ( const DbU::Unit&, const DbU::Unit& ); + virtual Box getBoundingBox () const; + virtual void invalidate ( bool propagateFlag=true ); + virtual void materialize (); + public: + // Inspector support. + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + protected: + GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); + virtual ~GCell (); + GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + GCell ( const GCell& ); + GCell& operator= ( const GCell& ); private: static Name _extensionName; static uint32_t _displayMode; @@ -362,6 +368,7 @@ namespace Anabatic { inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); } inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); } + inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; } inline const GCell::Key& GCell::getKey () const { return _key; } inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); }; diff --git a/crlcore/etc/45/freepdk_45/kite.conf b/crlcore/etc/45/freepdk_45/kite.conf index ec519a13..0d19875a 100644 --- a/crlcore/etc/45/freepdk_45/kite.conf +++ b/crlcore/etc/45/freepdk_45/kite.conf @@ -11,8 +11,8 @@ helpers.micronsMode() parametersTable = \ ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.065 ) , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. - , ("katabatic.saturateRatio" ,TypePercentage,80 ) - , ("katabatic.saturateRp" ,TypeInt ,8 ) + , ("katabatic.saturateRatio" ,TypePercentage,90 ) + , ("katabatic.saturateRp" ,TypeInt ,10 ) , ('katabatic.topRoutingLayer' ,TypeString , 'metal5') , ('anabatic.routingGauge' ,TypeString , 'gscl45') # Kite parameters. diff --git a/katana/src/Block.cpp b/katana/src/Block.cpp index 65f3efc5..ba964d82 100644 --- a/katana/src/Block.cpp +++ b/katana/src/Block.cpp @@ -140,7 +140,7 @@ namespace Katana { if (channel) { channel = channel->vcut( xcut ); channel->setType( Anabatic::Flags::ChannelRow ); - channel->getWestEdge()->setFlags( Flags::IllimitedCapacity ); + channel->getWestEdge()->setFlags( Flags::InfiniteCapacity ); } } diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 9faeaf97..35fa30bf 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -165,8 +165,8 @@ namespace Katana { if (not gcell->isMatrix()) continue; for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) { - if (edge->isHorizontal()) edge->incCapacity( -getHTracksReservedLocal() ); - else edge->incCapacity( -getVTracksReservedLocal() ); + if (edge->isHorizontal()) edge->reserveCapacity( getHTracksReservedLocal() ); + else edge->reserveCapacity( getVTracksReservedLocal() ); } } } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 46dd9a17..b89ca0d0 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -453,13 +453,13 @@ namespace Katana { axis = segment->getX(); } - int elementCapacity = -1; + int elementCapacity = 1; cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl; GCellsUnder gcells = getGCellsUnder( segment ); if (not gcells->empty()) { for ( size_t i=0 ; isize()-1 ; ++i ) - gcells->gcellAt(i)->getEdgeAt( side, axis )->incCapacity( elementCapacity ); + gcells->gcellAt(i)->getEdgeAt( side, axis )->reserveCapacity( elementCapacity ); } } }