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:
parent
592c098ab2
commit
793dbb26b2
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 } ) );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
|
@ -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); };
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue