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

@ -307,6 +307,7 @@ namespace Anabatic {
, _densityMode (MaxDensity)
, _autoSegmentLut ()
, _autoContactLut ()
, _edgeCapacitiesLut()
, _blockageNet (cell->getNet("blockagenet"))
{
_matrix.setCell( cell, _configuration->getSliceHeight() );
@ -824,8 +825,6 @@ namespace Anabatic {
AutoSegment::IdSet processeds;
for ( GCell* gcell : _gcells ) {
//cerr << "@ " << gcell << endl;
multiset<AutoContactTerminal*,SortAcByXY> 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("_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;
}

View File

@ -402,7 +402,7 @@ namespace Anabatic {
void AutoSegment::_initialize ()
{
cerr << "AutoSegment::_initialize()" << endl;
//cerr << "AutoSegment::_initialize()" << endl;
_initialized = true;
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
@ -412,8 +412,8 @@ namespace Anabatic {
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
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<DbU::Unit*,3>( { viaToTopCap, viaToBottomCap, viaToSameCap } ) );
}

View File

@ -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

View File

@ -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);

View File

@ -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;
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 ) );

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
{
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<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,7 +1192,7 @@ namespace Anabatic {
float vdensity = 0.0;
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; }
}
@ -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,9 +1353,7 @@ 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;
float ccapacity = getHCapacity() * getVCapacity() * (_depth-_pinDepth);
DbU::Unit width = getXMax() - getXMin();
DbU::Unit height = getYMax() - getYMin();
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
@ -1347,34 +1366,29 @@ namespace Anabatic {
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();
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<GCell*>(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);
}

View File

@ -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* );
@ -309,6 +311,7 @@ namespace Anabatic {
uint64_t _densityMode;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
EdgeCapacityLut _edgeCapacitiesLut;
Net* _blockageNet;
};

View File

@ -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 ;

View File

@ -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<Segment*>& 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<Segment*>& 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; }

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

@ -66,6 +66,8 @@ namespace Anabatic {
class GCell;
// -------------------------------------------------------------------
// Class : "GCell".
@ -153,6 +155,8 @@ namespace Anabatic {
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;
@ -208,9 +212,11 @@ namespace Anabatic {
bool hasFreeTrack ( size_t depth, float reserve ) const;
inline size_t getDepth () const;
size_t getNetCount () const;
float getHCapacity () const;
float getVCapacity () 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;
@ -253,7 +259,7 @@ namespace Anabatic {
, set<Net*>& 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 ();
@ -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); };

View File

@ -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.

View File

@ -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 );
}
}

View File

@ -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() );
}
}
}

View File

@ -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 ; i<gcells->size()-1 ; ++i )
gcells->gcellAt(i)->getEdgeAt( side, axis )->incCapacity( elementCapacity );
gcells->gcellAt(i)->getEdgeAt( side, axis )->reserveCapacity( elementCapacity );
}
}
}