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
|
@ -293,21 +293,22 @@ namespace Anabatic {
|
|||
|
||||
AnabaticEngine::AnabaticEngine ( Cell* cell )
|
||||
: Super(cell)
|
||||
, _configuration (new Configuration())
|
||||
, _chipTools (cell)
|
||||
, _state (EngineCreation)
|
||||
, _matrix ()
|
||||
, _gcells ()
|
||||
, _ovEdges ()
|
||||
, _netOrdering ()
|
||||
, _netDatas ()
|
||||
, _viewer (NULL)
|
||||
, _flags (Flags::DestroyBaseContact)
|
||||
, _stamp (-1)
|
||||
, _densityMode (MaxDensity)
|
||||
, _autoSegmentLut ()
|
||||
, _autoContactLut ()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
, _configuration (new Configuration())
|
||||
, _chipTools (cell)
|
||||
, _state (EngineCreation)
|
||||
, _matrix ()
|
||||
, _gcells ()
|
||||
, _ovEdges ()
|
||||
, _netOrdering ()
|
||||
, _netDatas ()
|
||||
, _viewer (NULL)
|
||||
, _flags (Flags::DestroyBaseContact)
|
||||
, _stamp (-1)
|
||||
, _densityMode (MaxDensity)
|
||||
, _autoSegmentLut ()
|
||||
, _autoContactLut ()
|
||||
, _edgeCapacitiesLut()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
{
|
||||
_matrix.setCell( cell, _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
@ -824,8 +825,6 @@ namespace Anabatic {
|
|||
AutoSegment::IdSet processeds;
|
||||
|
||||
for ( GCell* gcell : _gcells ) {
|
||||
//cerr << "@ " << gcell << endl;
|
||||
|
||||
multiset<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("_gcells" , &_gcells ) );
|
||||
record->add( getSlot("_matrix" , &_matrix ) );
|
||||
record->add( getSlot("_flags" , &_flags ) );
|
||||
record->add( getSlot("_configuration" , _configuration ) );
|
||||
record->add( getSlot("_gcells" , &_gcells ) );
|
||||
record->add( getSlot("_matrix" , &_matrix ) );
|
||||
record->add( getSlot("_flags" , &_flags ) );
|
||||
record->add( getSlot("_autoSegmentLut" , &_autoSegmentLut ) );
|
||||
record->add( getSlot("_autoContactLut" , &_autoContactLut ) );
|
||||
record->add( getSlot("_edgeCapacitiesLut", &_edgeCapacitiesLut ) );
|
||||
return record;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
Interval side = getSide();
|
||||
Flags flags = _flags;
|
||||
Interval side = getSide();
|
||||
_axis = side.getCenter();
|
||||
|
||||
if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) _capacity = 0;
|
||||
else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) _capacity = 100;
|
||||
else
|
||||
_capacity = getAnabatic()->getCapacity( side, _flags );
|
||||
if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) flags |= Flags::NullCapacity;
|
||||
else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) flags |= Flags::InfiniteCapacity;
|
||||
|
||||
_capacities = getAnabatic()->_createCapacity( _flags, side );
|
||||
|
||||
_flags.reset( Flags::Invalidated );
|
||||
cdebug_log(110,0) << "Edge::materialize() " << this << endl;
|
||||
|
@ -335,12 +338,12 @@ namespace Anabatic {
|
|||
bool Edge::isMaxCapacity ( Net* net ) const
|
||||
{
|
||||
if (net) {
|
||||
cdebug_log(112,0) << "_capacity:" << _capacity << endl;
|
||||
cdebug_log(112,0) << "_capacity:" << getCapacity() << endl;
|
||||
|
||||
Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net );
|
||||
return ((_realOccupancy + state->getWPitch()) > _capacity) ? true : false;
|
||||
return ((_realOccupancy + state->getWPitch()) > getCapacity()) ? true : false;
|
||||
}
|
||||
return (_realOccupancy >= _capacity) ? true : false;
|
||||
return (_realOccupancy >= getCapacity()) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -366,7 +369,7 @@ namespace Anabatic {
|
|||
s.insert( s.size()-1, " " +DbU::getValueString(center.getY()) );
|
||||
s.insert( s.size()-1, "] " +DbU::getValueString(_axis) );
|
||||
s.insert( s.size()-1, " " +getString(_realOccupancy) );
|
||||
s.insert( s.size()-1, "/" +getString(_capacity) );
|
||||
s.insert( s.size()-1, "/" +getString(getCapacity()) );
|
||||
s.insert( s.size()-1, " h:" +getString(_historicCost) );
|
||||
s.insert( s.size()-1, " " +getString(_flags) );
|
||||
return s;
|
||||
|
@ -377,7 +380,8 @@ namespace Anabatic {
|
|||
{
|
||||
Record* record = Super::_getRecord();
|
||||
record->add( getSlot("_flags" , _flags ) );
|
||||
record->add( getSlot("_capacity" , _capacity ) );
|
||||
record->add( getSlot("_capacities" , _capacities ) );
|
||||
record->add( getSlot("_reservedCapacity" , _reservedCapacity ) );
|
||||
record->add( getSlot("_realOccupancy" , _realOccupancy ) );
|
||||
record->add( getSlot("_estimateOccupancy", _estimateOccupancy) );
|
||||
record->add( getSlot("_source" , _source ) );
|
||||
|
|
|
@ -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,8 +1192,8 @@ namespace Anabatic {
|
|||
float vdensity = 0.0;
|
||||
|
||||
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||
if ( i%2 ) { hdensity += _densities[i]; ++hplanes; }
|
||||
else { vdensity += _densities[i]; ++vplanes; }
|
||||
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; }
|
||||
else { vdensity += _densities[i]; ++vplanes; }
|
||||
}
|
||||
|
||||
if (hplanes) hdensity /= hplanes;
|
||||
|
@ -1197,7 +1218,7 @@ namespace Anabatic {
|
|||
float hdensity = 0.0;
|
||||
|
||||
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||
if (i%2) { hdensity += _densities[i]; ++hplanes; }
|
||||
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; }
|
||||
}
|
||||
if (hplanes) hdensity /= hplanes;
|
||||
|
||||
|
@ -1207,7 +1228,7 @@ namespace Anabatic {
|
|||
float vdensity = 0.0;
|
||||
|
||||
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||
if (i%2 == 0) { vdensity += _densities[i]; ++vplanes; }
|
||||
if (isVerticalPlane(i)) { vdensity += _densities[i]; ++vplanes; }
|
||||
}
|
||||
|
||||
if (vplanes) vdensity /= vplanes;
|
||||
|
@ -1219,11 +1240,11 @@ namespace Anabatic {
|
|||
}
|
||||
} else if (getAnabatic()->getDensityMode() == MaxHDensity) {
|
||||
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||
if ((i%2) and (_densities[i] > density)) density = _densities[i];
|
||||
if (isHorizontalPlane(i) and (_densities[i] > density)) density = _densities[i];
|
||||
}
|
||||
} else if (getAnabatic()->getDensityMode() == MaxVDensity) {
|
||||
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
|
||||
if ((i%2 == 0) and (_densities[i] > density)) density = _densities[i];
|
||||
if (isVerticalPlane(i) and (_densities[i] > density)) density = _densities[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1332,49 +1353,42 @@ namespace Anabatic {
|
|||
sort( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
|
||||
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
|
||||
|
||||
float hcapacity = getHCapacity ();
|
||||
float vcapacity = getVCapacity ();
|
||||
float ccapacity = hcapacity * vcapacity * 4;
|
||||
DbU::Unit width = getXMax() - getXMin();
|
||||
DbU::Unit height = getYMax() - getYMin();
|
||||
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
|
||||
DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/;
|
||||
DbU::Unit uLengths1 [ _depth ];
|
||||
DbU::Unit uLengths2 [ _depth ];
|
||||
float localCounts [ _depth ];
|
||||
vector<UsedFragments> ufragments ( _depth );
|
||||
float ccapacity = getHCapacity() * getVCapacity() * (_depth-_pinDepth);
|
||||
DbU::Unit width = getXMax() - getXMin();
|
||||
DbU::Unit height = getYMax() - getYMin();
|
||||
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
|
||||
DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/;
|
||||
DbU::Unit uLengths1 [ _depth ];
|
||||
DbU::Unit uLengths2 [ _depth ];
|
||||
float localCounts [ _depth ];
|
||||
vector<UsedFragments> ufragments ( _depth );
|
||||
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
ufragments[i].setPitch ( Session::getPitch(i) );
|
||||
_feedthroughs[i] = 0.0;
|
||||
uLengths1 [i] = 0;
|
||||
uLengths2 [i] = 0;
|
||||
localCounts [i] = 0.0;
|
||||
_globalsCount[i] = 0.0;
|
||||
|
||||
if (Session::getDirection(i) & Flags::Horizontal) {
|
||||
ufragments[i].setSpan ( getXMin(), getXMax() );
|
||||
ufragments[i].setCapacity( (size_t)hcapacity );
|
||||
} else {
|
||||
ufragments[i].setSpan ( getYMin(), getYMax() );
|
||||
ufragments[i].setCapacity( (size_t)vcapacity );
|
||||
}
|
||||
ufragments[i].setCapacity( (size_t)getCapacity(i) );
|
||||
if (isHorizontalPlane(i)) ufragments[i].setSpan( getXMin(), getXMax() );
|
||||
else ufragments[i].setSpan( getYMin(), getYMax() );
|
||||
}
|
||||
|
||||
// Compute wirelength associated to contacts (in DbU::Unit converted to float).
|
||||
AutoSegment::DepthLengthSet processeds;
|
||||
for ( AutoContact* contact : _contacts ) {
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0;
|
||||
contact->getLengths ( uLengths1, processeds );
|
||||
contact->getLengths( uLengths1, processeds );
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
if (Session::getDirection(i) & Flags::Horizontal)
|
||||
uLengths2[i] += uLengths1[i]+hpenalty;
|
||||
else
|
||||
uLengths2[i] += uLengths1[i]+vpenalty; break;
|
||||
if (isHorizontalPlane(i)) uLengths2[i] += uLengths1[i]+hpenalty;
|
||||
else uLengths2[i] += uLengths1[i]+vpenalty;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the "pass through" horizontal segments.
|
||||
if ( _hsegments.size() ) {
|
||||
if (not _hsegments.empty()) {
|
||||
const Layer* layer = _hsegments[0]->getLayer();
|
||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
|
||||
size_t count = 0;
|
||||
|
@ -1398,7 +1412,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
// Add the "pass through" vertical segments.
|
||||
if ( _vsegments.size() ) {
|
||||
if (not _vsegments.empty()) {
|
||||
const Layer* layer = _vsegments[0]->getLayer();
|
||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
|
||||
size_t count = 0;
|
||||
|
@ -1406,7 +1420,7 @@ namespace Anabatic {
|
|||
_globalsCount[depth] += 1.0;
|
||||
ufragments[depth].incGlobals();
|
||||
|
||||
if ( layer != _vsegments[i]->getLayer() ) {
|
||||
if (layer != _vsegments[i]->getLayer()) {
|
||||
uLengths2[depth] += count * height;
|
||||
|
||||
count = 0;
|
||||
|
@ -1416,18 +1430,16 @@ namespace Anabatic {
|
|||
count++;
|
||||
_feedthroughs[depth] += 1.0;
|
||||
}
|
||||
if ( count ) {
|
||||
if (count) {
|
||||
uLengths2[depth] += count * height;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the blockages.
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
}
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
|
||||
|
||||
// Compute the number of non pass-through tracks.
|
||||
if (processeds.size()) {
|
||||
if (not processeds.empty()) {
|
||||
AutoSegment::DepthLengthSet::iterator isegment = processeds.begin();
|
||||
const Layer* layer = (*isegment)->getLayer();
|
||||
DbU::Unit axis = (*isegment)->getAxis();
|
||||
|
@ -1451,9 +1463,11 @@ namespace Anabatic {
|
|||
|
||||
// Normalize: 0 < d < 1.0 (divide by H/V capacity).
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
int capacity = getCapacity(i);
|
||||
|
||||
if (Session::getDirection(i) & Flags::Horizontal) {
|
||||
if (width) {
|
||||
_densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)width );
|
||||
if (width and capacity) {
|
||||
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * width );
|
||||
_feedthroughs [i] += (float)(_blockages[i] / width);
|
||||
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width;
|
||||
} else {
|
||||
|
@ -1462,8 +1476,8 @@ namespace Anabatic {
|
|||
_fragmentations[i] = 0;
|
||||
}
|
||||
} else {
|
||||
if (height) {
|
||||
_densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)height );
|
||||
if (height and capacity) {
|
||||
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * height );
|
||||
_feedthroughs [i] += (float)(_blockages[i] / height);
|
||||
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height;
|
||||
} else {
|
||||
|
@ -1488,17 +1502,16 @@ namespace Anabatic {
|
|||
|
||||
void GCell::truncDensities ()
|
||||
{
|
||||
int hcapacity = (int)getHCapacity();
|
||||
int vcapacity = (int)getVCapacity();
|
||||
Box bBox = getBoundingBox();
|
||||
Box bBox = getBoundingBox();
|
||||
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
if (Session::getDirection(i) & Flags::Horizontal) {
|
||||
if (_blockages[i] > hcapacity * bBox.getWidth())
|
||||
_blockages[i] = hcapacity * bBox.getWidth();
|
||||
int capacity = getCapacity(i);
|
||||
if (isHorizontalPlane(i)) {
|
||||
if (_blockages[i] > capacity * bBox.getWidth())
|
||||
_blockages[i] = capacity * bBox.getWidth();
|
||||
} else {
|
||||
if (_blockages[i] > vcapacity * bBox.getHeight())
|
||||
_blockages[i] = vcapacity * bBox.getHeight();
|
||||
if (_blockages[i] > capacity * bBox.getHeight())
|
||||
_blockages[i] = capacity * bBox.getHeight();
|
||||
}
|
||||
}
|
||||
_flags &= ~Flags::Saturated;
|
||||
|
@ -1534,9 +1547,7 @@ namespace Anabatic {
|
|||
{
|
||||
if (isInvalidated()) const_cast<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* );
|
||||
|
@ -294,22 +296,23 @@ namespace Anabatic {
|
|||
AnabaticEngine ( const AnabaticEngine& );
|
||||
AnabaticEngine& operator= ( const AnabaticEngine& );
|
||||
private:
|
||||
static Name _toolName;
|
||||
Configuration* _configuration;
|
||||
ChipTools _chipTools;
|
||||
EngineState _state;
|
||||
Matrix _matrix;
|
||||
vector<GCell*> _gcells;
|
||||
vector<Edge*> _ovEdges;
|
||||
vector<NetData*> _netOrdering;
|
||||
NetDatas _netDatas;
|
||||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
uint64_t _densityMode;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
Net* _blockageNet;
|
||||
static Name _toolName;
|
||||
Configuration* _configuration;
|
||||
ChipTools _chipTools;
|
||||
EngineState _state;
|
||||
Matrix _matrix;
|
||||
vector<GCell*> _gcells;
|
||||
vector<Edge*> _ovEdges;
|
||||
vector<NetData*> _netOrdering;
|
||||
NetDatas _netDatas;
|
||||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
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
|
|
@ -64,6 +64,8 @@ namespace Anabatic {
|
|||
|
||||
class AnabaticEngine;
|
||||
class GCell;
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -123,172 +125,176 @@ namespace Anabatic {
|
|||
float _density;
|
||||
};
|
||||
public:
|
||||
static uint32_t getDisplayMode ();
|
||||
static void setDisplayMode ( uint32_t );
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
inline bool isSaturated () const;
|
||||
bool isSaturated ( size_t depth ) const;
|
||||
inline bool isInvalidated () const;
|
||||
inline bool isHFlat () const;
|
||||
inline bool isVFlat () const;
|
||||
inline bool isFlat () const;
|
||||
inline bool isDevice () const;
|
||||
inline bool isHChannel () const;
|
||||
inline bool isVChannel () const;
|
||||
inline bool isStrut () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isMatrix () const;
|
||||
inline bool isRow () const;
|
||||
inline bool isIoPad () const;
|
||||
inline bool isHRail () const;
|
||||
inline bool isVRail () const;
|
||||
inline bool isStdCellRow () const;
|
||||
inline bool isChannelRow () const;
|
||||
bool isWest ( GCell* ) const;
|
||||
bool isEast ( GCell* ) const;
|
||||
bool isNorth ( GCell* ) const;
|
||||
bool isSouth ( GCell* ) const;
|
||||
Contact* hasGContact ( const Contact* ) const;
|
||||
Contact* hasGContact ( const Net* ) const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline Flags getType () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getYMin () const;
|
||||
inline DbU::Unit getXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getYMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getXCenter () const;
|
||||
inline DbU::Unit getYCenter () const;
|
||||
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
|
||||
inline Interval getSide ( Flags direction, int shrink=0 ) const;
|
||||
inline Point getCenter () const;
|
||||
inline Box getConstraintBox () const;
|
||||
inline const vector<Edge*>& getWestEdges () const;
|
||||
inline const vector<Edge*>& getEastEdges () const;
|
||||
inline const vector<Edge*>& getNorthEdges () const;
|
||||
inline const vector<Edge*>& getSouthEdges () const;
|
||||
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
|
||||
Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const;
|
||||
inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
|
||||
inline GCell* getWest () const;
|
||||
inline GCell* getEast () const;
|
||||
inline GCell* getSouth () const;
|
||||
inline GCell* getNorth () const;
|
||||
static uint32_t getDisplayMode ();
|
||||
static void setDisplayMode ( uint32_t );
|
||||
static Box getBorder ( const GCell*, const GCell* );
|
||||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
inline bool isSaturated () const;
|
||||
bool isSaturated ( size_t depth ) const;
|
||||
inline bool isInvalidated () const;
|
||||
inline bool isHFlat () const;
|
||||
inline bool isVFlat () const;
|
||||
inline bool isFlat () const;
|
||||
inline bool isDevice () const;
|
||||
inline bool isHChannel () const;
|
||||
inline bool isVChannel () const;
|
||||
inline bool isStrut () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isMatrix () const;
|
||||
inline bool isRow () const;
|
||||
inline bool isIoPad () const;
|
||||
inline bool isHRail () const;
|
||||
inline bool isVRail () const;
|
||||
inline bool isStdCellRow () const;
|
||||
inline bool isChannelRow () const;
|
||||
bool isWest ( GCell* ) const;
|
||||
bool isEast ( GCell* ) const;
|
||||
bool isNorth ( GCell* ) const;
|
||||
bool isSouth ( GCell* ) const;
|
||||
Contact* hasGContact ( const Contact* ) const;
|
||||
Contact* hasGContact ( const Net* ) const;
|
||||
bool isHorizontalPlane ( size_t depth ) const;
|
||||
bool isVerticalPlane ( size_t depth ) const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline Flags getType () const;
|
||||
inline DbU::Unit getXMin () const;
|
||||
inline DbU::Unit getYMin () const;
|
||||
inline DbU::Unit getXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getYMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getXCenter () const;
|
||||
inline DbU::Unit getYCenter () const;
|
||||
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
|
||||
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
|
||||
inline Interval getSide ( Flags direction, int shrink=0 ) const;
|
||||
inline Point getCenter () const;
|
||||
inline Box getConstraintBox () const;
|
||||
inline const vector<Edge*>& getWestEdges () const;
|
||||
inline const vector<Edge*>& getEastEdges () const;
|
||||
inline const vector<Edge*>& getNorthEdges () const;
|
||||
inline const vector<Edge*>& getSouthEdges () const;
|
||||
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
|
||||
Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const;
|
||||
inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
|
||||
inline GCell* getWest () const;
|
||||
inline GCell* getEast () const;
|
||||
inline GCell* getSouth () const;
|
||||
inline GCell* getNorth () const;
|
||||
|
||||
GCell* getEastNMatrix () const;
|
||||
GCell* getNorthNMatrix () const;
|
||||
|
||||
inline Edge* getWestEdge () const;
|
||||
inline Edge* getEastEdge () const;
|
||||
inline Edge* getSouthEdge () const;
|
||||
inline Edge* getNorthEdge () const;
|
||||
|
||||
GCell* getWest ( DbU::Unit y ) const;
|
||||
GCell* getEast ( DbU::Unit y ) const;
|
||||
GCell* getSouth ( DbU::Unit x ) const;
|
||||
GCell* getNorth ( DbU::Unit x ) const;
|
||||
GCell* getNeighborAt ( Flags side, DbU::Unit axis ) const;
|
||||
GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getUnder ( Point p ) const;
|
||||
GCell* hcut ( DbU::Unit y );
|
||||
GCell* vcut ( DbU::Unit x );
|
||||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
inline const vector<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;
|
||||
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);
|
||||
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
|
||||
// Misc. functions.
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
void _add ( Edge* edge, Flags side );
|
||||
void _remove ( Edge* edge, Flags side=Flags::AllSides );
|
||||
void _destroyEdges ();
|
||||
private:
|
||||
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
|
||||
public:
|
||||
// Observers.
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
inline void notify ( unsigned int flags );
|
||||
// ExtensionGo support.
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
virtual void invalidate ( bool propagateFlag=true );
|
||||
virtual void materialize ();
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
GCell ( const GCell& );
|
||||
GCell& operator= ( const GCell& );
|
||||
inline const Flags& flags () const;
|
||||
inline Flags& flags ();
|
||||
void _add ( Edge* edge, Flags side );
|
||||
void _remove ( Edge* edge, Flags side=Flags::AllSides );
|
||||
void _destroyEdges ();
|
||||
private:
|
||||
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
|
||||
public:
|
||||
// Observers.
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
inline void notify ( unsigned int flags );
|
||||
// ExtensionGo support.
|
||||
inline const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
|
||||
virtual Box getBoundingBox () const;
|
||||
virtual void invalidate ( bool propagateFlag=true );
|
||||
virtual void materialize ();
|
||||
public:
|
||||
// Inspector support.
|
||||
virtual string _getTypeName () const;
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
protected:
|
||||
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual ~GCell ();
|
||||
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
private:
|
||||
GCell ( const GCell& );
|
||||
GCell& operator= ( const GCell& );
|
||||
private:
|
||||
static Name _extensionName;
|
||||
static uint32_t _displayMode;
|
||||
|
@ -362,6 +368,7 @@ namespace Anabatic {
|
|||
|
||||
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
|
||||
|
||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||
|
|
|
@ -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