Capacity managment by layer in Edges & GCells (plus fixes).

* New: In Anabatic::EdgeCapacity, dedicated object to manage the capacities
    of an edge by layer. This needed now because with real technologies
    layers capacities differs (unlike with symbolic technologies).
      This object is separated to be shared between Edges with identical
    characteristics (direction+interval). Deletion is automatic and
    done through refcounting. All the already allocateds EdgeCapacity
    are kept into a set in the AnabaticEngine (key is (direction,interval)).
* New: In Anabatic::Edge, capacities are stored in a shared EdgeCapacity
    object. The total capacity can be annotated (i.e. decreased).
      EdgeCapacity attribute is created during the materialize() call.
    The capacities are computed at this time.
      The incCapacity() function is renamed in reserveCapacity().
* New: In Anabatic::AnabaticEngine, added attribute _edgeCapacitiesLut
    to store the shared EdgeCapacity.
      Lookup/Creation of an EdgeCapacity is done through _createCapacity().
* Change: In Anabatic::Constants, rename Flags::IllimitedCapacity into
    Flags::InfiniteCapacity. Add Flags::NullCapacity (both for Edges).
* Change: In Anabatic::GCell, implement a by depth (for layer) getCapacity().
    This modification did expose a bug in the density calculation :
    per depth density where divided by the complete density instead of the
    density's depth. This was leading to greatly underestimated densities.
    Thoses underestimations where preventing Dijkstra and layer assignement
    to manage congestion correctly (in fact, it was acting as if there
    never was congestion).
      Also avoid a divide by zero (thus -NAN showing in densities).
* Change: In Anabatic::GCell, rename setEdgeOccupancy() into the more
    accurate forceEdgesCapacities().
      Note for Eric: only the first Edge on each side has it's capacity
    forced. What if there's more than one Edge ?
This commit is contained in:
Jean-Paul Chaput 2018-02-21 00:16:50 +01:00
parent 592c098ab2
commit 793dbb26b2
16 changed files with 620 additions and 336 deletions

View File

@ -293,21 +293,22 @@ namespace Anabatic {
AnabaticEngine::AnabaticEngine ( Cell* cell ) AnabaticEngine::AnabaticEngine ( Cell* cell )
: Super(cell) : Super(cell)
, _configuration (new Configuration()) , _configuration (new Configuration())
, _chipTools (cell) , _chipTools (cell)
, _state (EngineCreation) , _state (EngineCreation)
, _matrix () , _matrix ()
, _gcells () , _gcells ()
, _ovEdges () , _ovEdges ()
, _netOrdering () , _netOrdering ()
, _netDatas () , _netDatas ()
, _viewer (NULL) , _viewer (NULL)
, _flags (Flags::DestroyBaseContact) , _flags (Flags::DestroyBaseContact)
, _stamp (-1) , _stamp (-1)
, _densityMode (MaxDensity) , _densityMode (MaxDensity)
, _autoSegmentLut () , _autoSegmentLut ()
, _autoContactLut () , _autoContactLut ()
, _blockageNet (cell->getNet("blockagenet")) , _edgeCapacitiesLut()
, _blockageNet (cell->getNet("blockagenet"))
{ {
_matrix.setCell( cell, _configuration->getSliceHeight() ); _matrix.setCell( cell, _configuration->getSliceHeight() );
Edge::unity = _configuration->getSliceHeight(); Edge::unity = _configuration->getSliceHeight();
@ -824,8 +825,6 @@ namespace Anabatic {
AutoSegment::IdSet processeds; AutoSegment::IdSet processeds;
for ( GCell* gcell : _gcells ) { for ( GCell* gcell : _gcells ) {
//cerr << "@ " << gcell << endl;
multiset<AutoContactTerminal*,SortAcByXY> acTerminals; multiset<AutoContactTerminal*,SortAcByXY> acTerminals;
for ( AutoContact* contact : gcell->getContacts() ) { for ( AutoContact* contact : gcell->getContacts() ) {
if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) ) if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) )
@ -834,13 +833,11 @@ namespace Anabatic {
AutoContactTerminal* south = NULL; AutoContactTerminal* south = NULL;
for ( AutoContactTerminal* north : acTerminals ) { for ( AutoContactTerminal* north : acTerminals ) {
//cerr << "@ " << north << endl;
if (south) { if (south) {
if ( south->canDrag() if ( south->canDrag()
and north->canDrag() and north->canDrag()
and (south->getNet() != north->getNet()) and (south->getNet() != north->getNet())
and (south->getX () == north->getX ()) ) { and (south->getX () == north->getX ()) ) {
//Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() );
Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() ); Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() );
AutoSegment* terminal = south->getSegment(); AutoSegment* terminal = south->getSegment();
AutoContact* opposite = terminal->getOppositeAnchor( south ); AutoContact* opposite = terminal->getOppositeAnchor( south );
@ -848,10 +845,8 @@ namespace Anabatic {
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
segment->mergeUserConstraints( constraints ); segment->mergeUserConstraints( constraints );
constraineds.insert( segment ); constraineds.insert( segment );
//cerr << "Apply " << constraints << " to " << segment << endl;
} }
//constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() );
constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() ); constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() );
terminal = north->getSegment(); terminal = north->getSegment();
opposite = terminal->getOppositeAnchor( north ); opposite = terminal->getOppositeAnchor( north );
@ -859,12 +854,8 @@ namespace Anabatic {
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) { for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
segment->mergeUserConstraints( constraints ); segment->mergeUserConstraints( constraints );
constraineds.insert( segment ); 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; south = north;
} }
@ -891,32 +882,31 @@ namespace Anabatic {
AutoSegment* previous = NULL; AutoSegment* previous = NULL;
for ( AutoSegment* aligned : aligneds ) { for ( AutoSegment* aligned : aligneds ) {
Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() ); Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() );
cerr << "aligned: " << aligned << " " << aligned->getUserConstraints() << endl;
if (constraints.getSize() < Session::getPitch(1)) { if (constraints.getSize() < Session::getPitch(1)) {
if (not previous) { //if (not previous) {
cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n" // cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n"
" %s\n" // " %s\n"
" S:%s\n" // " S:%s\n"
" T:%s\n" // " T:%s\n"
" Combined user constraints are too tight [%s : %s]." // " Combined user constraints are too tight [%s : %s]."
, getString(aligned ).c_str() // , getString(aligned ).c_str()
, getString(aligned->getAutoSource()->getConstraintBox()).c_str() // , getString(aligned->getAutoSource()->getConstraintBox()).c_str()
, getString(aligned->getAutoTarget()->getConstraintBox()).c_str() // , getString(aligned->getAutoTarget()->getConstraintBox()).c_str()
, DbU::getValueString(constraints.getVMin()).c_str() // , DbU::getValueString(constraints.getVMin()).c_str()
, DbU::getValueString(constraints.getVMax()).c_str() // , DbU::getValueString(constraints.getVMax()).c_str()
) << endl; // ) << endl;
} else { //} else {
cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n" // cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n"
" %s\n" // " %s\n"
" %s\n" // " %s\n"
" Combined user constraints are too tight [%s : %s]." // " Combined user constraints are too tight [%s : %s]."
, getString(previous).c_str() // , getString(previous).c_str()
, getString(aligned ).c_str() // , getString(aligned ).c_str()
, DbU::getValueString(constraints.getVMin()).c_str() // , DbU::getValueString(constraints.getVMin()).c_str()
, DbU::getValueString(constraints.getVMax()).c_str() // , DbU::getValueString(constraints.getVMax()).c_str()
) << endl; // ) << endl;
} //}
//if (previous) { //if (previous) {
// if (previous->getAutoTarget() == aligned->getAutoSource()) { // if (previous->getAutoTarget() == aligned->getAutoSource()) {
// cerr << "Found a shared contact: " << aligned->getAutoSource() << endl; // cerr << "Found a shared contact: " << aligned->getAutoSource() << endl;
@ -931,8 +921,6 @@ namespace Anabatic {
previous = aligned; previous = aligned;
} }
cerr << "Final user constraints:" << userConstraints << endl;
} }
Session::close(); 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 void AnabaticEngine::_check ( Net* net ) const
{ {
cdebug_log(149,1) << "Checking " << net << endl; cdebug_log(149,1) << "Checking " << net << endl;
@ -1376,10 +1392,13 @@ namespace Anabatic {
Record* AnabaticEngine::_getRecord () const Record* AnabaticEngine::_getRecord () const
{ {
Record* record = Super::_getRecord(); Record* record = Super::_getRecord();
record->add( getSlot("_configuration", _configuration) ); record->add( getSlot("_configuration" , _configuration ) );
record->add( getSlot("_gcells" , &_gcells ) ); record->add( getSlot("_gcells" , &_gcells ) );
record->add( getSlot("_matrix" , &_matrix ) ); record->add( getSlot("_matrix" , &_matrix ) );
record->add( getSlot("_flags" , &_flags ) ); record->add( getSlot("_flags" , &_flags ) );
record->add( getSlot("_autoSegmentLut" , &_autoSegmentLut ) );
record->add( getSlot("_autoContactLut" , &_autoContactLut ) );
record->add( getSlot("_edgeCapacitiesLut", &_edgeCapacitiesLut ) );
return record; return record;
} }

View File

@ -402,7 +402,7 @@ namespace Anabatic {
void AutoSegment::_initialize () void AutoSegment::_initialize ()
{ {
cerr << "AutoSegment::_initialize()" << endl; //cerr << "AutoSegment::_initialize()" << endl;
_initialized = true; _initialized = true;
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) { for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
@ -412,8 +412,8 @@ namespace Anabatic {
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical()); bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ;
cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName() //cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
<< " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl; // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
*viaToSameCap = Session::getWireWidth(depth)/2; *viaToSameCap = Session::getWireWidth(depth)/2;
@ -429,12 +429,12 @@ namespace Anabatic {
*viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags ); *viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags );
} }
cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; //cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; //cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
if (depth > 0) //if (depth > 0)
cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; // cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl;
cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; //cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; //cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
_extensionCaps.push_back( std::array<DbU::Unit*,3>( { viaToTopCap, viaToBottomCap, viaToSameCap } ) ); _extensionCaps.push_back( std::array<DbU::Unit*,3>( { viaToTopCap, viaToBottomCap, viaToSameCap } ) );
} }

View File

@ -15,6 +15,7 @@ endif ( CHECK_DETERMINISM )
set( includes anabatic/Constants.h set( includes anabatic/Constants.h
anabatic/Configuration.h anabatic/Configuration.h
anabatic/Matrix.h anabatic/Matrix.h
anabatic/EdgeCapacity.h
anabatic/Edge.h anabatic/Edges.h anabatic/Edge.h anabatic/Edges.h
anabatic/GCell.h #anabatic/GCells.h anabatic/GCell.h #anabatic/GCells.h
anabatic/AnabaticEngine.h anabatic/AnabaticEngine.h
@ -39,6 +40,7 @@ endif ( CHECK_DETERMINISM )
set( cpps Constants.cpp set( cpps Constants.cpp
Configuration.cpp Configuration.cpp
Matrix.cpp Matrix.cpp
EdgeCapacity.cpp
Edge.cpp Edge.cpp
Edges.cpp Edges.cpp
GCell.cpp GCell.cpp

View File

@ -43,7 +43,9 @@ namespace Anabatic {
const BaseFlags Flags::ChannelRow = (1L << 13); const BaseFlags Flags::ChannelRow = (1L << 13);
const BaseFlags Flags::HRailGCell = (1L << 14); const BaseFlags Flags::HRailGCell = (1L << 14);
const BaseFlags Flags::VRailGCell = (1L << 15); 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. // Flags for Anabatic objects states only.
const BaseFlags Flags::DemoMode = (1L << 5); const BaseFlags Flags::DemoMode = (1L << 5);
const BaseFlags Flags::WarnOnGCellOverload = (1L << 6); const BaseFlags Flags::WarnOnGCellOverload = (1L << 6);
@ -78,6 +80,10 @@ namespace Anabatic {
| StrutGCell | StrutGCell
| HRailGCell | HRailGCell
| VRailGCell; | VRailGCell;
const BaseFlags Flags::EdgeCapacityMask = Horizontal
| Vertical
| NullCapacity
| InfiniteCapacity ;
// Flags for functions arguments only. // Flags for functions arguments only.
const BaseFlags Flags::Create = (1L << 5); const BaseFlags Flags::Create = (1L << 5);
const BaseFlags Flags::WithPerpands = (1L << 6); const BaseFlags Flags::WithPerpands = (1L << 6);

View File

@ -38,7 +38,8 @@ namespace Anabatic {
Edge::Edge ( GCell* source, GCell* target, Flags flags ) Edge::Edge ( GCell* source, GCell* target, Flags flags )
: Super(source->getCell()) : Super(source->getCell())
, _flags (flags|Flags::Invalidated) , _flags (flags|Flags::Invalidated)
, _capacity (0) , _capacities (NULL)
, _reservedCapacity (0)
, _realOccupancy (0) , _realOccupancy (0)
, _estimateOccupancy(0.0) , _estimateOccupancy(0.0)
, _historicCost (0.0) , _historicCost (0.0)
@ -104,6 +105,7 @@ namespace Anabatic {
void Edge::_preDestroy () void Edge::_preDestroy ()
{ {
_source->getAnabatic()->_unrefCapacity( _capacities );
_source->_remove( this, _flags|Flags::Source ); _source->_remove( this, _flags|Flags::Source );
_target->_remove( this, _flags|Flags::Target ); _target->_remove( this, _flags|Flags::Target );
@ -179,8 +181,8 @@ namespace Anabatic {
{ {
unsigned int occupancy = 0; unsigned int occupancy = 0;
if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta; if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta;
if ((_realOccupancy <= _capacity) and (occupancy > _capacity)) getAnabatic()->addOv ( this ); if ((_realOccupancy <= getCapacity()) and (occupancy > getCapacity())) getAnabatic()->addOv ( this );
if ((_realOccupancy > _capacity) and (occupancy <= _capacity)) getAnabatic()->removeOv( this ); if ((_realOccupancy > getCapacity()) and (occupancy <= getCapacity())) getAnabatic()->removeOv( this );
_realOccupancy = occupancy; _realOccupancy = occupancy;
} }
@ -291,13 +293,14 @@ namespace Anabatic {
{ {
cdebug_log(110,1) << "Edge::materialize() " << this << endl; cdebug_log(110,1) << "Edge::materialize() " << this << endl;
Interval side = getSide(); Flags flags = _flags;
Interval side = getSide();
_axis = side.getCenter(); _axis = side.getCenter();
if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) _capacity = 0; if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) flags |= Flags::NullCapacity;
else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) _capacity = 100; else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) flags |= Flags::InfiniteCapacity;
else
_capacity = getAnabatic()->getCapacity( side, _flags ); _capacities = getAnabatic()->_createCapacity( _flags, side );
_flags.reset( Flags::Invalidated ); _flags.reset( Flags::Invalidated );
cdebug_log(110,0) << "Edge::materialize() " << this << endl; cdebug_log(110,0) << "Edge::materialize() " << this << endl;
@ -335,12 +338,12 @@ namespace Anabatic {
bool Edge::isMaxCapacity ( Net* net ) const bool Edge::isMaxCapacity ( Net* net ) const
{ {
if (net) { if (net) {
cdebug_log(112,0) << "_capacity:" << _capacity << endl; cdebug_log(112,0) << "_capacity:" << getCapacity() << endl;
Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net ); 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(center.getY()) );
s.insert( s.size()-1, "] " +DbU::getValueString(_axis) ); s.insert( s.size()-1, "] " +DbU::getValueString(_axis) );
s.insert( s.size()-1, " " +getString(_realOccupancy) ); 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, " h:" +getString(_historicCost) );
s.insert( s.size()-1, " " +getString(_flags) ); s.insert( s.size()-1, " " +getString(_flags) );
return s; return s;
@ -377,7 +380,8 @@ namespace Anabatic {
{ {
Record* record = Super::_getRecord(); Record* record = Super::_getRecord();
record->add( getSlot("_flags" , _flags ) ); 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("_realOccupancy" , _realOccupancy ) );
record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); record->add( getSlot("_estimateOccupancy", _estimateOccupancy) );
record->add( getSlot("_source" , _source ) ); record->add( getSlot("_source" , _source ) );

View File

@ -0,0 +1,123 @@
// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.cpp<anabatic>" -*-
//
// 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 <sstream>
#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<RoutingLayerGauge*>& 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<RoutingLayerGauge*>& 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 << "<EdgeCapacity ";
if (_flags & Flags::Horizontal) os << "Horizontal ";
else if (_flags & Flags::Vertical ) os << "Vertical ";
else os << "Unknown ";
os << "[" << DbU::getValueString(_span.getVMin())
<< " : " << DbU::getValueString(_span.getVMax())
<< "] " << getCapacity()
<< " refs:" << _refCount
<< ">";
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.

View File

@ -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 Contact* GCell::hasGContact ( const Net* net ) const
{ {
for ( Contact* contact : _gcontacts ) { for ( Contact* contact : _gcontacts ) {
@ -1128,7 +1136,7 @@ namespace Anabatic {
} }
float GCell::getHCapacity () const int GCell::getHCapacity () const
{ {
int capacity = 0; int capacity = 0;
if (not _eastEdges.empty()) { if (not _eastEdges.empty()) {
@ -1136,11 +1144,11 @@ namespace Anabatic {
} else { } else {
for ( Edge* edge : _westEdges ) capacity += edge->getCapacity(); for ( Edge* edge : _westEdges ) capacity += edge->getCapacity();
} }
return (float)capacity; return capacity;
} }
float GCell::getVCapacity () const int GCell::getVCapacity () const
{ {
int capacity = 0; int capacity = 0;
if (not _northEdges.empty()) { if (not _northEdges.empty()) {
@ -1148,7 +1156,20 @@ namespace Anabatic {
} else { } else {
for ( Edge* edge : _southEdges ) capacity += edge->getCapacity(); for ( Edge* edge : _southEdges ) capacity += edge->getCapacity();
} }
return (float)capacity; return capacity;
}
int GCell::getCapacity ( size_t depth ) const
{
const vector<Edge*>* 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; float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if ( i%2 ) { hdensity += _densities[i]; ++hplanes; } if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; }
else { vdensity += _densities[i]; ++vplanes; } else { vdensity += _densities[i]; ++vplanes; }
} }
if (hplanes) hdensity /= hplanes; if (hplanes) hdensity /= hplanes;
@ -1197,7 +1218,7 @@ namespace Anabatic {
float hdensity = 0.0; float hdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { 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; if (hplanes) hdensity /= hplanes;
@ -1207,7 +1228,7 @@ namespace Anabatic {
float vdensity = 0.0; float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { 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; if (vplanes) vdensity /= vplanes;
@ -1219,11 +1240,11 @@ namespace Anabatic {
} }
} else if (getAnabatic()->getDensityMode() == MaxHDensity) { } else if (getAnabatic()->getDensityMode() == MaxHDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { 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) { } else if (getAnabatic()->getDensityMode() == MaxVDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { 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( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() ); sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
float hcapacity = getHCapacity (); float ccapacity = getHCapacity() * getVCapacity() * (_depth-_pinDepth);
float vcapacity = getVCapacity (); DbU::Unit width = getXMax() - getXMin();
float ccapacity = hcapacity * vcapacity * 4; DbU::Unit height = getYMax() - getYMin();
DbU::Unit width = getXMax() - getXMin(); DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
DbU::Unit height = getYMax() - getYMin(); DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/;
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; DbU::Unit uLengths1 [ _depth ];
DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; DbU::Unit uLengths2 [ _depth ];
DbU::Unit uLengths1 [ _depth ]; float localCounts [ _depth ];
DbU::Unit uLengths2 [ _depth ]; vector<UsedFragments> ufragments ( _depth );
float localCounts [ _depth ];
vector<UsedFragments> ufragments ( _depth );
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
ufragments[i].setPitch ( Session::getPitch(i) ); ufragments[i].setPitch ( Session::getPitch(i) );
_feedthroughs[i] = 0.0; _feedthroughs[i] = 0.0;
uLengths1 [i] = 0;
uLengths2 [i] = 0; uLengths2 [i] = 0;
localCounts [i] = 0.0; localCounts [i] = 0.0;
_globalsCount[i] = 0.0; _globalsCount[i] = 0.0;
if (Session::getDirection(i) & Flags::Horizontal) { ufragments[i].setCapacity( (size_t)getCapacity(i) );
ufragments[i].setSpan ( getXMin(), getXMax() ); if (isHorizontalPlane(i)) ufragments[i].setSpan( getXMin(), getXMax() );
ufragments[i].setCapacity( (size_t)hcapacity ); else ufragments[i].setSpan( getYMin(), getYMax() );
} else {
ufragments[i].setSpan ( getYMin(), getYMax() );
ufragments[i].setCapacity( (size_t)vcapacity );
}
} }
// Compute wirelength associated to contacts (in DbU::Unit converted to float). // Compute wirelength associated to contacts (in DbU::Unit converted to float).
AutoSegment::DepthLengthSet processeds; AutoSegment::DepthLengthSet processeds;
for ( AutoContact* contact : _contacts ) { for ( AutoContact* contact : _contacts ) {
for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; 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++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
if (Session::getDirection(i) & Flags::Horizontal) if (isHorizontalPlane(i)) uLengths2[i] += uLengths1[i]+hpenalty;
uLengths2[i] += uLengths1[i]+hpenalty; else uLengths2[i] += uLengths1[i]+vpenalty;
else
uLengths2[i] += uLengths1[i]+vpenalty; break;
} }
} }
// Add the "pass through" horizontal segments. // Add the "pass through" horizontal segments.
if ( _hsegments.size() ) { if (not _hsegments.empty()) {
const Layer* layer = _hsegments[0]->getLayer(); const Layer* layer = _hsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0; size_t count = 0;
@ -1398,7 +1412,7 @@ namespace Anabatic {
} }
// Add the "pass through" vertical segments. // Add the "pass through" vertical segments.
if ( _vsegments.size() ) { if (not _vsegments.empty()) {
const Layer* layer = _vsegments[0]->getLayer(); const Layer* layer = _vsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0; size_t count = 0;
@ -1406,7 +1420,7 @@ namespace Anabatic {
_globalsCount[depth] += 1.0; _globalsCount[depth] += 1.0;
ufragments[depth].incGlobals(); ufragments[depth].incGlobals();
if ( layer != _vsegments[i]->getLayer() ) { if (layer != _vsegments[i]->getLayer()) {
uLengths2[depth] += count * height; uLengths2[depth] += count * height;
count = 0; count = 0;
@ -1416,18 +1430,16 @@ namespace Anabatic {
count++; count++;
_feedthroughs[depth] += 1.0; _feedthroughs[depth] += 1.0;
} }
if ( count ) { if (count) {
uLengths2[depth] += count * height; uLengths2[depth] += count * height;
} }
} }
// Add the blockages. // Add the blockages.
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
uLengths2[i] += _blockages[i];
}
// Compute the number of non pass-through tracks. // Compute the number of non pass-through tracks.
if (processeds.size()) { if (not processeds.empty()) {
AutoSegment::DepthLengthSet::iterator isegment = processeds.begin(); AutoSegment::DepthLengthSet::iterator isegment = processeds.begin();
const Layer* layer = (*isegment)->getLayer(); const Layer* layer = (*isegment)->getLayer();
DbU::Unit axis = (*isegment)->getAxis(); DbU::Unit axis = (*isegment)->getAxis();
@ -1451,9 +1463,11 @@ namespace Anabatic {
// Normalize: 0 < d < 1.0 (divide by H/V capacity). // Normalize: 0 < d < 1.0 (divide by H/V capacity).
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
int capacity = getCapacity(i);
if (Session::getDirection(i) & Flags::Horizontal) { if (Session::getDirection(i) & Flags::Horizontal) {
if (width) { if (width and capacity) {
_densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)width ); _densities [i] = ((float)uLengths2[i]) / (float)( capacity * width );
_feedthroughs [i] += (float)(_blockages[i] / width); _feedthroughs [i] += (float)(_blockages[i] / width);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width; _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width;
} else { } else {
@ -1462,8 +1476,8 @@ namespace Anabatic {
_fragmentations[i] = 0; _fragmentations[i] = 0;
} }
} else { } else {
if (height) { if (height and capacity) {
_densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)height ); _densities [i] = ((float)uLengths2[i]) / (float)( capacity * height );
_feedthroughs [i] += (float)(_blockages[i] / height); _feedthroughs [i] += (float)(_blockages[i] / height);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height; _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height;
} else { } else {
@ -1488,17 +1502,16 @@ namespace Anabatic {
void GCell::truncDensities () void GCell::truncDensities ()
{ {
int hcapacity = (int)getHCapacity(); Box bBox = getBoundingBox();
int vcapacity = (int)getVCapacity();
Box bBox = getBoundingBox();
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
if (Session::getDirection(i) & Flags::Horizontal) { int capacity = getCapacity(i);
if (_blockages[i] > hcapacity * bBox.getWidth()) if (isHorizontalPlane(i)) {
_blockages[i] = hcapacity * bBox.getWidth(); if (_blockages[i] > capacity * bBox.getWidth())
_blockages[i] = capacity * bBox.getWidth();
} else { } else {
if (_blockages[i] > vcapacity * bBox.getHeight()) if (_blockages[i] > capacity * bBox.getHeight())
_blockages[i] = vcapacity * bBox.getHeight(); _blockages[i] = capacity * bBox.getHeight();
} }
} }
_flags &= ~Flags::Saturated; _flags &= ~Flags::Saturated;
@ -1534,9 +1547,7 @@ namespace Anabatic {
{ {
if (isInvalidated()) const_cast<GCell*>(this)->updateDensity(); if (isInvalidated()) const_cast<GCell*>(this)->updateDensity();
float capacity = 0.0; float capacity = getCapacity(depth);
if (Session::getDirection(depth) & Flags::Horizontal) capacity = getHCapacity();
else capacity = getVCapacity();
cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " " cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << Session::getRoutingGauge()->getRoutingLayer(depth)->getName()
@ -1704,14 +1715,15 @@ namespace Anabatic {
return false; 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 (getEastEdge() ) getEastEdge ()->forceCapacity( hcapacity );
if (getWestEdge() ) getWestEdge()->setCapacity(width); if (getWestEdge() ) getWestEdge ()->forceCapacity( hcapacity );
if (getNorthEdge()) getNorthEdge()->setCapacity(height); if (getNorthEdge()) getNorthEdge()->forceCapacity( vcapacity );
if (getSouthEdge()) getSouthEdge()->setCapacity(height); if (getSouthEdge()) getSouthEdge()->forceCapacity( vcapacity );
if (getEastEdge() ) getEastEdge()->setRealOccupancy(0); if (getEastEdge() ) getEastEdge ()->setRealOccupancy(0);
if (getWestEdge() ) getWestEdge()->setRealOccupancy(0); if (getWestEdge() ) getWestEdge ()->setRealOccupancy(0);
if (getNorthEdge()) getNorthEdge()->setRealOccupancy(0); if (getNorthEdge()) getNorthEdge()->setRealOccupancy(0);
if (getSouthEdge()) getSouthEdge()->setRealOccupancy(0); if (getSouthEdge()) getSouthEdge()->setRealOccupancy(0);
} }

View File

@ -256,6 +256,8 @@ namespace Anabatic {
void _unlink ( AutoSegment* ); void _unlink ( AutoSegment* );
AutoContact* _lookup ( Contact* ) const; AutoContact* _lookup ( Contact* ) const;
AutoSegment* _lookup ( Segment* ) const; AutoSegment* _lookup ( Segment* ) const;
EdgeCapacity* _createCapacity ( Flags, Interval );
size_t _unrefCapacity ( EdgeCapacity* );
void _loadGrByNet (); void _loadGrByNet ();
void _computeNetOptimals ( Net* ); void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* ); void _computeNetTerminals ( Net* );
@ -294,22 +296,23 @@ namespace Anabatic {
AnabaticEngine ( const AnabaticEngine& ); AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& ); AnabaticEngine& operator= ( const AnabaticEngine& );
private: private:
static Name _toolName; static Name _toolName;
Configuration* _configuration; Configuration* _configuration;
ChipTools _chipTools; ChipTools _chipTools;
EngineState _state; EngineState _state;
Matrix _matrix; Matrix _matrix;
vector<GCell*> _gcells; vector<GCell*> _gcells;
vector<Edge*> _ovEdges; vector<Edge*> _ovEdges;
vector<NetData*> _netOrdering; vector<NetData*> _netOrdering;
NetDatas _netDatas; NetDatas _netDatas;
CellViewer* _viewer; CellViewer* _viewer;
Flags _flags; Flags _flags;
int _stamp; int _stamp;
uint64_t _densityMode; uint64_t _densityMode;
AutoSegmentLut _autoSegmentLut; AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut; AutoContactLut _autoContactLut;
Net* _blockageNet; EdgeCapacityLut _edgeCapacitiesLut;
Net* _blockageNet;
}; };

View File

@ -44,7 +44,8 @@ namespace Anabatic {
static const BaseFlags HRailGCell ; // = (1 << 14); static const BaseFlags HRailGCell ; // = (1 << 14);
static const BaseFlags VRailGCell ; // = (1 << 15); static const BaseFlags VRailGCell ; // = (1 << 15);
// Flags for Edge objects states only. // 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. // Flags for Anabatic objects states only.
static const BaseFlags DemoMode ; // = (1 << 5); static const BaseFlags DemoMode ; // = (1 << 5);
static const BaseFlags WarnOnGCellOverload ; // = (1 << 6); 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 GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell|HRailGCell|VRailGCell;
static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow; static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow;
static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|HRailGCell|VRailGCell; static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|HRailGCell|VRailGCell;
static const BaseFlags EdgeCapacityMask ; // = Horizontal|Vertical|NullCapacity|InfiniteCapacity ;
// Flags for functions arguments only. // Flags for functions arguments only.
static const BaseFlags Create ; // = (1 << 5); static const BaseFlags Create ; // = (1 << 5);
static const BaseFlags WithPerpands ; static const BaseFlags WithPerpands ;

View File

@ -26,10 +26,10 @@ namespace Hurricane {
class Segment; class Segment;
} }
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
#include "anabatic/EdgeCapacity.h"
#include "anabatic/Edges.h" #include "anabatic/Edges.h"
namespace Anabatic { namespace Anabatic {
using std::string; using std::string;
@ -60,6 +60,7 @@ namespace Anabatic {
inline bool isHorizontal () const; inline bool isHorizontal () const;
inline bool hasNet ( const Net* ) const; inline bool hasNet ( const Net* ) const;
inline unsigned int getCapacity () const; inline unsigned int getCapacity () const;
inline unsigned int getCapacity ( size_t depth ) const;
inline unsigned int getRealOccupancy () const; inline unsigned int getRealOccupancy () const;
inline unsigned int getEstimateOccupancy () const; inline unsigned int getEstimateOccupancy () const;
inline float getHistoricCost () const; inline float getHistoricCost () const;
@ -73,8 +74,10 @@ namespace Anabatic {
Interval getSide () const; Interval getSide () const;
Segment* getSegment ( const Net* ) const; Segment* getSegment ( const Net* ) const;
inline const vector<Segment*>& getSegments () const; inline const vector<Segment*>& getSegments () const;
inline void setCapacity ( int ); //inline void setCapacity ( int );
inline void incCapacity ( int ); //inline void incCapacity ( int );
inline void forceCapacity ( int );
inline void reserveCapacity ( int );
inline void setRealOccupancy ( int ); inline void setRealOccupancy ( int );
void incRealOccupancy ( int ); void incRealOccupancy ( int );
void incRealOccupancy2 ( int ); void incRealOccupancy2 ( int );
@ -114,7 +117,8 @@ namespace Anabatic {
private: private:
static Name _extensionName; static Name _extensionName;
Flags _flags; Flags _flags;
unsigned int _capacity; EdgeCapacity* _capacities;
unsigned int _reservedCapacity;
unsigned int _realOccupancy; unsigned int _realOccupancy;
float _estimateOccupancy; float _estimateOccupancy;
float _historicCost; float _historicCost;
@ -129,7 +133,8 @@ namespace Anabatic {
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } 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::getRealOccupancy () const { return _realOccupancy; }
inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
inline float Edge::getHistoricCost () const { return _historicCost; } inline float Edge::getHistoricCost () const { return _historicCost; }
@ -137,8 +142,10 @@ namespace Anabatic {
inline GCell* Edge::getTarget () const { return _target; } inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; } inline DbU::Unit Edge::getAxis () const { return _axis; }
inline const vector<Segment*>& Edge::getSegments () const { return _segments; } inline const vector<Segment*>& Edge::getSegments () const { return _segments; }
inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } inline void Edge::forceCapacity ( int capacity ) { if (_capacities) _capacities->forceCapacity(capacity); }
inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; } 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::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; }
inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; } inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; }
inline const Flags& Edge::flags () const { return _flags; } inline const Flags& Edge::flags () const { return _flags; }

View File

@ -0,0 +1,99 @@
// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.h<anabatic>" -*-
//
// 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 <string>
#include <set>
#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<int> _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<EdgeCapacity*,EdgeCapacity::Compare> EdgeCapacityLut;
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::EdgeCapacity);
#endif // ANABATIC_EDGE_CAPACITY_H

View File

@ -64,6 +64,8 @@ namespace Anabatic {
class AnabaticEngine; class AnabaticEngine;
class GCell; class GCell;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -123,172 +125,176 @@ namespace Anabatic {
float _density; float _density;
}; };
public: public:
static uint32_t getDisplayMode (); static uint32_t getDisplayMode ();
static void setDisplayMode ( uint32_t ); static void setDisplayMode ( uint32_t );
static Box getBorder ( const GCell*, const GCell* ); static Box getBorder ( const GCell*, const GCell* );
public: public:
static GCell* create ( AnabaticEngine* ); static GCell* create ( AnabaticEngine* );
public: public:
inline bool isSaturated () const; inline bool isSaturated () const;
bool isSaturated ( size_t depth ) const; bool isSaturated ( size_t depth ) const;
inline bool isInvalidated () const; inline bool isInvalidated () const;
inline bool isHFlat () const; inline bool isHFlat () const;
inline bool isVFlat () const; inline bool isVFlat () const;
inline bool isFlat () const; inline bool isFlat () const;
inline bool isDevice () const; inline bool isDevice () const;
inline bool isHChannel () const; inline bool isHChannel () const;
inline bool isVChannel () const; inline bool isVChannel () const;
inline bool isStrut () const; inline bool isStrut () const;
inline bool isAnalog () const; inline bool isAnalog () const;
inline bool isMatrix () const; inline bool isMatrix () const;
inline bool isRow () const; inline bool isRow () const;
inline bool isIoPad () const; inline bool isIoPad () const;
inline bool isHRail () const; inline bool isHRail () const;
inline bool isVRail () const; inline bool isVRail () const;
inline bool isStdCellRow () const; inline bool isStdCellRow () const;
inline bool isChannelRow () const; inline bool isChannelRow () const;
bool isWest ( GCell* ) const; bool isWest ( GCell* ) const;
bool isEast ( GCell* ) const; bool isEast ( GCell* ) const;
bool isNorth ( GCell* ) const; bool isNorth ( GCell* ) const;
bool isSouth ( GCell* ) const; bool isSouth ( GCell* ) const;
Contact* hasGContact ( const Contact* ) const; Contact* hasGContact ( const Contact* ) const;
Contact* hasGContact ( const Net* ) const; Contact* hasGContact ( const Net* ) const;
inline AnabaticEngine* getAnabatic () const; bool isHorizontalPlane ( size_t depth ) const;
inline Flags getType () const; bool isVerticalPlane ( size_t depth ) const;
inline DbU::Unit getXMin () const; inline AnabaticEngine* getAnabatic () const;
inline DbU::Unit getYMin () const; inline Flags getType () const;
inline DbU::Unit getXMax ( int shrink=0 ) const; inline DbU::Unit getXMin () const;
inline DbU::Unit getYMax ( int shrink=0 ) const; inline DbU::Unit getYMin () const;
inline DbU::Unit getXCenter () const; inline DbU::Unit getXMax ( int shrink=0 ) const;
inline DbU::Unit getYCenter () const; inline DbU::Unit getYMax ( int shrink=0 ) const;
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const; inline DbU::Unit getXCenter () const;
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const; inline DbU::Unit getYCenter () const;
inline Interval getSide ( Flags direction, int shrink=0 ) const; inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
inline Point getCenter () const; inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
inline Box getConstraintBox () const; inline Interval getSide ( Flags direction, int shrink=0 ) const;
inline const vector<Edge*>& getWestEdges () const; inline Point getCenter () const;
inline const vector<Edge*>& getEastEdges () const; inline Box getConstraintBox () const;
inline const vector<Edge*>& getNorthEdges () const; inline const vector<Edge*>& getWestEdges () const;
inline const vector<Edge*>& getSouthEdges () const; inline const vector<Edge*>& getEastEdges () const;
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const; inline const vector<Edge*>& getNorthEdges () const;
Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const; inline const vector<Edge*>& getSouthEdges () const;
inline Edges getEdges ( Flags sides=Flags::AllSides ) const; Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
inline GCell* getWest () const; Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const;
inline GCell* getEast () const; inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
inline GCell* getSouth () const; inline GCell* getWest () const;
inline GCell* getNorth () 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<Contact*>& 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<AutoSegment*>& getHSegments () const;
inline const vector<AutoSegment*>& getVSegments () const;
inline const vector<AutoContact*>& getContacts () const;
AutoSegments getHStartSegments ();
AutoSegments getVStartSegments ();
AutoSegments getHStopSegments ();
AutoSegments getVStopSegments ();
inline AutoSegments getStartSegments ( Flags direction );
inline AutoSegments getStopSegments ( Flags direction );
size_t getRoutingPads ( set<RoutingPad*>& );
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<Net*>& );
bool stepDesaturate ( size_t depth
, set<Net*>&, AutoSegment*& moved
, Flags flags=Flags::NoFlags );
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
GCell* getEastNMatrix () const; void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
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<Contact*>& 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<AutoSegment*>& getHSegments () const;
inline const vector<AutoSegment*>& getVSegments () const;
inline const vector<AutoContact*>& getContacts () const;
AutoSegments getHStartSegments ();
AutoSegments getVStartSegments ();
AutoSegments getHStopSegments ();
AutoSegments getVStopSegments ();
inline AutoSegments getStartSegments ( Flags direction );
inline AutoSegments getStopSegments ( Flags direction );
size_t getRoutingPads ( set<RoutingPad*>& );
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<Net*>& );
bool stepDesaturate ( size_t depth
, set<Net*>&, AutoSegment*& moved
, Flags flags=Flags::NoFlags );
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
void setEdgesOccupancy (unsigned int, unsigned int);
// Misc. functions. // Misc. functions.
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
void _add ( Edge* edge, Flags side ); void _add ( Edge* edge, Flags side );
void _remove ( Edge* edge, Flags side=Flags::AllSides ); void _remove ( Edge* edge, Flags side=Flags::AllSides );
void _destroyEdges (); void _destroyEdges ();
private: private:
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
public: public:
// Observers. // Observers.
template<typename OwnerT> template<typename OwnerT>
inline OwnerT* getObserver ( size_t slot ); inline OwnerT* getObserver ( size_t slot );
inline void setObserver ( size_t slot, BaseObserver* ); inline void setObserver ( size_t slot, BaseObserver* );
inline void notify ( unsigned int flags ); inline void notify ( unsigned int flags );
// ExtensionGo support. // ExtensionGo support.
inline const Name& staticGetName (); inline const Name& staticGetName ();
virtual const Name& getName () const; virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const; virtual Box getBoundingBox () const;
virtual void invalidate ( bool propagateFlag=true ); virtual void invalidate ( bool propagateFlag=true );
virtual void materialize (); virtual void materialize ();
public: public:
// Inspector support. // Inspector support.
virtual string _getTypeName () const; virtual string _getTypeName () const;
virtual string _getString () const; virtual string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
protected: protected:
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
virtual ~GCell (); virtual ~GCell ();
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
private: private:
GCell ( const GCell& ); GCell ( const GCell& );
GCell& operator= ( const GCell& ); GCell& operator= ( const GCell& );
private: private:
static Name _extensionName; static Name _extensionName;
static uint32_t _displayMode; static uint32_t _displayMode;
@ -362,6 +368,7 @@ namespace Anabatic {
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); } inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); } 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 const GCell::Key& GCell::getKey () const { return _key; }
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); }; inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };

View File

@ -11,8 +11,8 @@ helpers.micronsMode()
parametersTable = \ parametersTable = \
( ('lefImport.minTerminalWidth' ,TypeDouble ,0.065 ) ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.065 )
, ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters.
, ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRatio" ,TypePercentage,90 )
, ("katabatic.saturateRp" ,TypeInt ,8 ) , ("katabatic.saturateRp" ,TypeInt ,10 )
, ('katabatic.topRoutingLayer' ,TypeString , 'metal5') , ('katabatic.topRoutingLayer' ,TypeString , 'metal5')
, ('anabatic.routingGauge' ,TypeString , 'gscl45') , ('anabatic.routingGauge' ,TypeString , 'gscl45')
# Kite parameters. # Kite parameters.

View File

@ -140,7 +140,7 @@ namespace Katana {
if (channel) { if (channel) {
channel = channel->vcut( xcut ); channel = channel->vcut( xcut );
channel->setType( Anabatic::Flags::ChannelRow ); channel->setType( Anabatic::Flags::ChannelRow );
channel->getWestEdge()->setFlags( Flags::IllimitedCapacity ); channel->getWestEdge()->setFlags( Flags::InfiniteCapacity );
} }
} }

View File

@ -165,8 +165,8 @@ namespace Katana {
if (not gcell->isMatrix()) continue; if (not gcell->isMatrix()) continue;
for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) { for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) {
if (edge->isHorizontal()) edge->incCapacity( -getHTracksReservedLocal() ); if (edge->isHorizontal()) edge->reserveCapacity( getHTracksReservedLocal() );
else edge->incCapacity( -getVTracksReservedLocal() ); else edge->reserveCapacity( getVTracksReservedLocal() );
} }
} }
} }

View File

@ -453,13 +453,13 @@ namespace Katana {
axis = segment->getX(); axis = segment->getX();
} }
int elementCapacity = -1; int elementCapacity = 1;
cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl; cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl;
GCellsUnder gcells = getGCellsUnder( segment ); GCellsUnder gcells = getGCellsUnder( segment );
if (not gcells->empty()) { if (not gcells->empty()) {
for ( size_t i=0 ; i<gcells->size()-1 ; ++i ) for ( size_t i=0 ; i<gcells->size()-1 ; ++i )
gcells->gcellAt(i)->getEdgeAt( side, axis )->incCapacity( elementCapacity ); gcells->gcellAt(i)->getEdgeAt( side, axis )->reserveCapacity( elementCapacity );
} }
} }
} }