coriolis/anabatic/src/GCell.cpp

1935 lines
59 KiB
C++
Raw Normal View History

// -*- mode: C++; explicit-buffer-name: "GCell.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-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 : "./GCell.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/Contact.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/UpdateSession.h"
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
namespace {
using namespace std;
using namespace Hurricane;
using namespace Anabatic;
// -------------------------------------------------------------------
// Class : "::UsedFragments".
class UsedFragments {
private:
class Axiss;
class Axis {
public:
Axis ( UsedFragments*, DbU::Unit axis );
inline DbU::Unit getAxis () const;
inline UsedFragments* getUsedFragments () const;
void merge ( const Interval& mergeChunk );
Interval getMaxFree () const;
private:
UsedFragments* _ufragments;
DbU::Unit _axis;
list<Interval> _chunks;
};
private:
class AxisCompare {
public:
bool operator() ( const Axis* lhs, const Axis* rhs );
};
class AxisMatch : public unary_function<Axis*,bool> {
public:
inline AxisMatch ( DbU::Unit axis );
inline bool operator() ( const Axis* );
private:
DbU::Unit _axis;
};
public:
UsedFragments ();
~UsedFragments ();
inline DbU::Unit getPitch () const;
inline DbU::Unit getMin () const;
inline DbU::Unit getMax () const;
Interval getMaxFree () const;
inline void setSpan ( DbU::Unit min, DbU::Unit max );
inline void setCapacity ( size_t );
inline void incGlobals ( size_t count=1 );
inline void setPitch ( DbU::Unit );
void merge ( DbU::Unit axis, const Interval& );
private:
DbU::Unit _pitch;
vector<Axis*> _axiss;
Interval _span;
size_t _capacity;
size_t _globals;
};
UsedFragments::Axis::Axis ( UsedFragments* ufragments, DbU::Unit axis )
: _ufragments(ufragments)
, _axis (axis)
, _chunks ()
{
merge( Interval( ufragments->getMin()-ufragments->getPitch(), ufragments->getMin() ) );
merge( Interval( ufragments->getMax(), ufragments->getMax()+ufragments->getPitch() ) );
}
inline DbU::Unit UsedFragments::Axis::getAxis () const { return _axis; }
inline UsedFragments* UsedFragments::Axis::getUsedFragments () const { return _ufragments; }
void UsedFragments::Axis::merge ( const Interval& chunkMerge )
{
// cerr << " Merge @" << DbU::getValueString(_axis)
// << " " << chunkMerge << endl;
list<Interval>::iterator imerge = _chunks.end();
list<Interval>::iterator ichunk = _chunks.begin();
while ( ichunk != _chunks.end() ) {
if (chunkMerge.getVMax() < (*ichunk).getVMin()) break;
if (chunkMerge.intersect(*ichunk)) {
if (imerge == _chunks.end()) {
imerge = ichunk;
(*imerge).merge( chunkMerge );
} else {
(*imerge).merge( *ichunk );
ichunk = _chunks.erase( ichunk );
continue;
}
}
ichunk++;
}
if (imerge == _chunks.end()) {
_chunks.insert( ichunk, chunkMerge );
}
}
Interval UsedFragments::Axis::getMaxFree () const
{
list<Interval>::const_iterator ichunk = _chunks.begin();
list<Interval>::const_iterator iend = --_chunks.end();
Interval maxFree;
for ( ; ichunk != iend ; ++ichunk ) {
list<Interval>::const_iterator inext = ichunk;
++inext;
if (inext == iend) break;
Interval currentFree ( (*ichunk).getVMax(), (*inext).getVMin() );
if (currentFree.getSize() > maxFree.getSize())
maxFree = currentFree;
// cerr << " @" << DbU::getValueString(_axis)
// << " before:" << *ichunk << " after:" << *inext
// << " size:" << DbU::getValueString(currentFree.getSize()) << endl;
}
return maxFree;
}
inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs )
{
if (lhs->getAxis () < rhs->getAxis ()) return true;
return false;
}
inline UsedFragments::AxisMatch::AxisMatch ( DbU::Unit axis )
: _axis(axis)
{ }
inline bool UsedFragments::AxisMatch::operator() ( const Axis* axis )
{ return (axis->getAxis() == _axis); }
UsedFragments::UsedFragments ()
: _pitch (0)
, _axiss ()
, _span (false)
, _capacity(0)
, _globals (0)
{ }
UsedFragments::~UsedFragments ()
{
while ( not _axiss.empty() ) {
delete (*_axiss.begin());
_axiss.erase( _axiss.begin() );
}
}
inline DbU::Unit UsedFragments::getPitch () const { return _pitch; }
inline DbU::Unit UsedFragments::getMin () const { return _span.getVMin(); }
inline DbU::Unit UsedFragments::getMax () const { return _span.getVMax(); }
inline void UsedFragments::setPitch ( DbU::Unit pitch ) { _pitch=pitch; }
inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _span=Interval(min,max); }
inline void UsedFragments::setCapacity ( size_t capacity ) { _capacity=capacity; }
inline void UsedFragments::incGlobals ( size_t count ) { _globals+=count; }
void UsedFragments::merge ( DbU::Unit axis, const Interval& chunkMerge )
{
Interval restrict = chunkMerge.getIntersection(_span);
if (restrict.isEmpty()) return;
vector<Axis*>::iterator iaxis = find_if( _axiss.begin(), _axiss.end(), AxisMatch(axis) );
Axis* paxis = NULL;
if (iaxis == _axiss.end()) {
paxis = new Axis(this,axis);
_axiss.push_back ( paxis );
stable_sort( _axiss.begin(), _axiss.end(), AxisCompare() );
} else {
paxis = *iaxis;
}
paxis->merge( restrict );
}
Interval UsedFragments::getMaxFree () const
{
//cerr << "capacity:" << _capacity << " _globals:" << _globals << " _axiss:" << _axiss.size() << endl;
if (_capacity > _globals + _axiss.size() + 1) return _span;
Interval maxFree;
vector<Axis*>::const_iterator iaxis = _axiss.begin();
for ( ; iaxis != _axiss.end() ; ++iaxis ) {
Interval axisMaxFree = (*iaxis)->getMaxFree();
if (axisMaxFree.getSize() > maxFree.getSize())
maxFree = axisMaxFree;
}
return maxFree;
}
} // End of anonymous namespace.
namespace Anabatic {
using std::cerr;
using std::endl;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::UpdateSession;
using Hurricane::Horizontal;
using Hurricane::Vertical;
// -------------------------------------------------------------------
// Class : "Katabatic::GCell::CompareByDensity".
GCell::CompareByDensity::CompareByDensity ( size_t depth )
: _depth(depth)
{ }
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs )
{
float difference = lhs->getDensity(_depth) - rhs->getDensity(_depth);
if (difference != 0.0) return (difference > 0.0);
return lhs->getId() < rhs->getId();
}
// -------------------------------------------------------------------
// Class : "Anabatic::GCell".
Name GCell::_extensionName = "Anabatic::GCell";
uint32_t GCell::_displayMode = GCell::Boundary;
uint32_t GCell::getDisplayMode () { return _displayMode; }
void GCell::setDisplayMode ( uint32_t mode ) { _displayMode = mode; }
GCell::GCell ( AnabaticEngine* anabatic, DbU::Unit xmin, DbU::Unit ymin )
: Super(anabatic->getCell())
, _observable ()
, _anabatic (anabatic)
, _flags (Flags::HChannelGCell|Flags::Invalidated)
, _westEdges ()
, _eastEdges ()
, _southEdges ()
, _northEdges ()
, _xmin (xmin)
, _ymin (ymin)
, _gcontacts ()
, _vsegments ()
, _hsegments ()
, _contacts ()
, _depth (Session::getRoutingGauge()->getDepth())
, _pinDepth (0)
, _blockages (new DbU::Unit [_depth])
, _cDensity (0.0)
, _densities (new float [_depth])
, _feedthroughs (new float [_depth])
, _fragmentations(new float [_depth])
, _globalsCount (new float [_depth])
, _key (this,1)
{
for ( size_t i=0 ; i<_depth ; i++ ) {
_blockages [i] = 0;
_densities [i] = 0.0;
_feedthroughs [i] = 0.0;
_fragmentations[i] = 0.0;
_globalsCount [i] = 0.0;
if (Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly)
++_pinDepth;
}
updateKey( 1 );
}
void GCell::_postCreate ()
{
Super::_postCreate();
_anabatic->_add( this );
}
GCell* GCell::create ( AnabaticEngine* anabatic )
{
if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." );
if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." );
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
bool reUseSession = Session::isOpen();
if (not reUseSession) anabatic->openSession();
GCell* gcell = new GCell ( anabatic
, anabatic->getCell()->getAbutmentBox().getXMin()
, anabatic->getCell()->getAbutmentBox().getYMin() );
gcell->_postCreate();
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
if (not reUseSession) Session::close();
return gcell;
}
GCell* GCell::_create ( DbU::Unit xmin, DbU::Unit ymin )
{
GCell* gcell = new GCell ( getAnabatic(), xmin, ymin );
gcell->_postCreate();
return gcell;
}
GCell::~GCell ()
{
//cdebug_log(145,0) << "GCell::~GCell()" << endl;
delete [] _blockages;
delete [] _densities;
delete [] _feedthroughs;
delete [] _fragmentations;
delete [] _globalsCount;
}
void GCell::_destroyEdges ()
{
while (not _westEdges.empty()) (* _westEdges.rbegin())->destroy();
while (not _eastEdges.empty()) (* _eastEdges.rbegin())->destroy();
while (not _southEdges.empty()) (*_southEdges.rbegin())->destroy();
while (not _northEdges.empty()) (*_northEdges.rbegin())->destroy();
}
void GCell::_preDestroy ()
{
_destroyEdges();
_anabatic->_remove( this );
Super::_preDestroy();
}
void GCell::_remove ( Edge* edge, Flags side )
{
if (side.contains(Flags::WestSide )) erase_element( _westEdges, edge );
if (side.contains(Flags::EastSide )) erase_element( _eastEdges, edge );
if (side.contains(Flags::SouthSide)) erase_element( _southEdges, edge );
if (side.contains(Flags::NorthSide)) erase_element( _northEdges, edge );
}
void GCell::_add ( Edge* edge, Flags side )
{
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,1) << "GCell::_add(side): side:" << side << " " << edge << endl;
if (side.contains(Flags::WestSide)) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Adding to West side of " << this << endl;
for ( auto iedge=_westEdges.begin() ; iedge != _westEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() > edge->getAxisMin()) {
_westEdges.insert( iedge, edge );
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
return;
}
_westEdges.push_back( edge );
}
if (side.contains(Flags::EastSide)) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Adding to East side of " << this << endl;
for ( auto iedge=_eastEdges.begin() ; iedge != _eastEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() > edge->getAxisMin()) {
_eastEdges.insert( iedge, edge );
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
return;
}
_eastEdges.push_back( edge );
}
if (side.contains(Flags::SouthSide)) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Adding to South side of " << this << endl;
for ( auto iedge=_southEdges.begin() ; iedge != _southEdges.end() ; ++iedge )
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "| @" << DbU::getValueString((*iedge)->getAxisMin()) << " " << *iedge << endl;
for ( auto iedge=_southEdges.begin() ; iedge != _southEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() > edge->getAxisMin()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Insert *before* " << *iedge << endl;
_southEdges.insert( iedge, edge );
for ( auto iedge2=_southEdges.begin() ; iedge2 != _southEdges.end() ; ++iedge2 )
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "| @" << DbU::getValueString((*iedge2)->getAxisMin()) << " " << *iedge2 << endl;
cdebug_tabw(110,-1);
return;
}
_southEdges.push_back( edge );
}
if (side.contains(Flags::NorthSide)) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Adding to North side of " << this << endl;
for ( auto iedge=_northEdges.begin() ; iedge != _northEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() > edge->getAxisMin()) {
_northEdges.insert( iedge, edge );
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
return;
}
_northEdges.push_back( edge );
}
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
}
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 ?
2018-02-20 17:16:50 -06:00
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
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
{
for ( Contact* contact : _gcontacts ) {
if (contact->getNet() == net) return contact;
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
}
return NULL;
}
Contact* GCell::hasGContact ( const Contact* owned ) const
{
for ( Contact* contact : _gcontacts ) {
if (contact == owned) return contact;
}
return NULL;
}
Contact* GCell::breakGoThrough ( Net* net )
{
Corrections in the Dijkstra global routing (ripup) mechanism. * Bug: In Anabatic::Dijkstra, the degree of a vertex (the number of neighbors belonging to the same net) was miscalculated. This was leading, in the materialize step to some feed-through vertexes not being broken. Leading in turn to incomplete transformation of the detailed routing. Also in _trackback(), the degree of the first vertex we were backtracking from was not incremented. * Bug: In Anabatic::Dijkstra::materialize(), systematically use GCell::breakGoThrough() on both source and target. This is needed when we are in the ripup phase as both source and target can be go-through. This was also leading to incomplete detailed routing transformation. * Change: In Anabatic::Edge::ripup(), ripup one third of the segments instead of thoses exeeding the global length threshold. This way we are sure to desaturate an edge. Needs to be further calibrated. * Change: In Aanabatic::GCell::breakGoThrough(), no longer return NULL. Return existing gcontact if any. Break if it is a go-through and create a new gcontact in last resort. Maybe rename this function. * New: In Anabatic::Configuration, new parameters: - anabatic.edgeHScaling, to adjust the length of the horizontal edges relative to the vertical ones (this is a ratio). - anabatic.globalIterations, set the maximum number of ripup passes of the global router. * New: In CRL/etc/*/kite.conf, added new parameters anabatic.edgeHScaling and anabatic.globalIterations. * New: In Katana::GlobalRoute::DigitalDistance, take into account the new edgeHScaling factor. Must be used when the capacity of V-edges differs greatly for H-edges (case of AMS 350nm c35b4 for instance). * Bug: In Katana::GlobalRoute::DigitalDistance, the historic cost is computed for an edge length of "1". Must be multiplicated by the current edge length to have any measurable effect. This bug is finally explaining why the ripup was producing the same solutions over and over, the historical cost was negligible!
2018-04-16 05:10:48 -05:00
Contact* gcontact = hasGContact( net );
if (gcontact) return gcontact;
for ( Edge* edge : _eastEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net)
return getAnabatic()->breakAt( segment, this );
}
}
for ( Edge* edge : _northEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net)
return getAnabatic()->breakAt( segment, this );
}
}
Corrections in the Dijkstra global routing (ripup) mechanism. * Bug: In Anabatic::Dijkstra, the degree of a vertex (the number of neighbors belonging to the same net) was miscalculated. This was leading, in the materialize step to some feed-through vertexes not being broken. Leading in turn to incomplete transformation of the detailed routing. Also in _trackback(), the degree of the first vertex we were backtracking from was not incremented. * Bug: In Anabatic::Dijkstra::materialize(), systematically use GCell::breakGoThrough() on both source and target. This is needed when we are in the ripup phase as both source and target can be go-through. This was also leading to incomplete detailed routing transformation. * Change: In Anabatic::Edge::ripup(), ripup one third of the segments instead of thoses exeeding the global length threshold. This way we are sure to desaturate an edge. Needs to be further calibrated. * Change: In Aanabatic::GCell::breakGoThrough(), no longer return NULL. Return existing gcontact if any. Break if it is a go-through and create a new gcontact in last resort. Maybe rename this function. * New: In Anabatic::Configuration, new parameters: - anabatic.edgeHScaling, to adjust the length of the horizontal edges relative to the vertical ones (this is a ratio). - anabatic.globalIterations, set the maximum number of ripup passes of the global router. * New: In CRL/etc/*/kite.conf, added new parameters anabatic.edgeHScaling and anabatic.globalIterations. * New: In Katana::GlobalRoute::DigitalDistance, take into account the new edgeHScaling factor. Must be used when the capacity of V-edges differs greatly for H-edges (case of AMS 350nm c35b4 for instance). * Bug: In Katana::GlobalRoute::DigitalDistance, the historic cost is computed for an edge length of "1". Must be multiplicated by the current edge length to have any measurable effect. This bug is finally explaining why the ripup was producing the same solutions over and over, the historical cost was negligible!
2018-04-16 05:10:48 -05:00
return getGContact( net );
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
}
Edge* GCell::getEdgeTo ( GCell* neighbor, Flags sideHint ) const
{
for ( Edge* edge : getEdges(sideHint) ) {
if (edge->getOpposite(this) == neighbor) return edge;
}
return NULL;
}
Edge* GCell::getEdgeAt ( Flags sideHint, DbU::Unit u ) const
{
for ( Edge* edge : getEdges(sideHint) ) {
GCell* side = edge->getOpposite(this);
if ( (sideHint.contains(Flags::WestSide) or sideHint.contains(Flags::EastSide ))
and (u < side->getYMax()) ) {
cdebug_log(112,0) << "H Opposite @" << DbU::getValueString(u) << " is: " << side << endl;
return edge;
}
if ( (sideHint.contains(Flags::SouthSide) or sideHint.contains(Flags::NorthSide))
and (u < side->getXMax()) ) {
cdebug_log(112,0) << "V Opposite @" << DbU::getValueString(u) << " is: " << side << endl;
return edge;
}
}
return NULL;
}
2017-06-21 11:02:37 -05:00
GCell* GCell::getEastNMatrix() const
{
if (!this->getEast()->isMatrix()) return this->getEast();
else {
GCell* gcell = this->getEast();
while(gcell->getEast()){
if (!gcell->getEast()->isMatrix()) break;
else gcell = gcell->getEast();
}
return gcell->getEast();
}
}
GCell* GCell::getNorthNMatrix() const
{
if (!this->getNorth()->isMatrix()) return this->getNorth();
else {
GCell* gcell = this->getNorth();
while(gcell->getNorth()){
if (!gcell->getNorth()->isMatrix()) break;
else gcell = gcell->getNorth();
}
return gcell->getNorth();
}
}
GCell* GCell::getWest ( DbU::Unit y ) const
{
for ( Edge* edge : _westEdges ) {
GCell* side = edge->getOpposite(this);
if (y < side->getYMax()) return side;
}
return NULL;
}
GCell* GCell::getEast ( DbU::Unit y ) const
{
for ( Edge* edge : _eastEdges ) {
GCell* side = edge->getOpposite(this);
if (y < side->getYMax()) return side;
}
return NULL;
}
GCell* GCell::getSouth ( DbU::Unit x ) const
{
for ( Edge* edge : _southEdges ) {
GCell* side = edge->getOpposite(this);
if (x < side->getXMax()) return side;
}
return NULL;
}
GCell* GCell::getNorth ( DbU::Unit x ) const
{
for ( Edge* edge : _northEdges ) {
GCell* side = edge->getOpposite(this);
if (x < side->getXMax()) return side;
}
return NULL;
}
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
GCell* GCell::getNeighborAt ( Flags side, DbU::Unit axis ) const
{
if (side & Flags::EastSide ) return getEast (axis);
if (side & Flags::WestSide ) return getWest (axis);
if (side & Flags::NorthSide) return getNorth(axis);
if (side & Flags::SouthSide) return getSouth(axis);
return NULL;
}
GCell* GCell::getUnder ( DbU::Unit x, DbU::Unit y ) const
{
const GCell* current = this;
while ( current ) {
if (not current->isFlat() and current->getBoundingBox().contains(x,y)) break;
if (x >= current->getXMax()) { current = current->getEast (); continue; }
if (y >= current->getYMax()) { current = current->getNorth(); continue; }
cerr << Error( "GCell::getUnder(): No GCell under (%s,%s), this must *never* happen."
, DbU::getValueString(x).c_str()
, DbU::getValueString(y).c_str()
) << endl;
current = NULL; break;
}
return const_cast<GCell*>( current );
}
Box GCell::getBorder ( const GCell* s, const GCell* t )
{
Flags flags = Flags::NoFlags;
flags |= (s->getXMax() == t->getXMin()) ? Flags::EastSide : Flags::NoFlags;
flags |= (t->getXMax() == s->getXMin()) ? Flags::WestSide : Flags::NoFlags;
flags |= (s->getYMax() == t->getYMin()) ? Flags::NorthSide : Flags::NoFlags;
flags |= (t->getYMax() == s->getYMin()) ? Flags::SouthSide : Flags::NoFlags;
if (flags & Flags::Vertical) {
if (flags & Flags::Horizontal) return Box();
if (flags & Flags::WestSide)
return Box( s->getXMin(), std::max( s->getYMin(), t->getYMin() )
, s->getXMin(), std::min( s->getYMax(), t->getYMax() ) );
else
return Box( t->getXMin(), std::max( s->getYMin(), t->getYMin() )
, t->getXMin(), std::min( s->getYMax(), t->getYMax() ) );
}
if (flags & Flags::Horizontal) {
if (flags & Flags::Vertical) return Box();
if (flags & Flags::NorthSide)
return Box( std::max( s->getXMin(), t->getXMin() ), t->getYMin()
, std::min( s->getXMax(), t->getXMax() ), t->getYMin() );
else
return Box( std::max( s->getXMin(), t->getXMin() ), s->getYMin()
, std::min( s->getXMax(), t->getXMax() ), s->getYMin() );
}
return Box();
}
GCell* GCell::vcut ( DbU::Unit x )
{
cdebug_log(110,1) << "GCell::vcut() @x:" << DbU::getValueString(x) << " " << this << endl;
if ( (x < getXMin()) or (x > getXMax()) )
throw Error( "GCell::vcut(): Vertical cut axis at %s is outside GCell box,\n"
" in %s."
, DbU::getValueString(x).c_str()
, getString(this).c_str()
);
GCell* chunk = _create( x, getYMin() );
cdebug_log(110,0) << "New chunk:" << chunk << endl;
_moveEdges( chunk, 0, Flags::EastSide );
Edge::create( this, chunk, Flags::Horizontal );
if (not _southEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Split/create south edges." << endl;
size_t iedge = 0;
for ( ; (iedge < _southEdges.size()) ; ++iedge ) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "[" << iedge << "] xmax of:"
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
<< _southEdges[iedge]->getOpposite(this)
<< " " << _southEdges[iedge] << endl;
if (x <= _southEdges[iedge]->getOpposite(this)->getXMax()) break;
}
if ( (x < _southEdges[iedge]->getOpposite(this)->getXMax())
or ( (x == _southEdges[iedge]->getOpposite(this)->getXMax())
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
and (chunk->getXMax() == getXMax())) ) {
Edge::create( _southEdges[iedge]->getOpposite(this), chunk, Flags::Vertical );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
_southEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::SouthSide );
}
if (not _northEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "Split/create north edges." << endl;
size_t iedge = 0;
for ( ; (iedge < _northEdges.size()) ; ++iedge )
if (x <= _northEdges[iedge]->getOpposite(this)->getXMax()) break;
if ( (x < _northEdges[iedge]->getOpposite(this)->getXMax())
or ( (x == _northEdges[iedge]->getOpposite(this)->getXMax())
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
and (chunk->getXMax() == getXMax())) ) {
Edge::create( chunk, _northEdges[iedge]->getOpposite(this), Flags::Vertical );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
_northEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::NorthSide );
}
cdebug_tabw(110,-1);
return chunk;
}
GCell* GCell::hcut ( DbU::Unit y )
{
cdebug_log(110,1) << "GCell::hcut() @y:" << DbU::getValueString(y) << " " << this << endl;
if ( (y < getYMin()) or (y > getYMax()) )
throw Error( "GCell::hcut(): Horizontal cut axis at %s is outside GCell box,\n"
" in %s."
, DbU::getValueString(y).c_str()
, getString(this).c_str()
);
GCell* chunk = _create( getXMin(), y );
cdebug_log(110,0) << "New chunk:" << chunk << endl;
_moveEdges( chunk, 0, Flags::NorthSide );
Edge::create( this, chunk, Flags::Vertical );
if (not _westEdges.empty()) {
size_t iedge = 0;
for ( ; (iedge < _westEdges.size()) ; ++iedge )
if (y <= _westEdges[iedge]->getOpposite(this)->getYMax()) break;
if ( (y < _westEdges[iedge]->getOpposite(this)->getYMax())
or ( (y == _westEdges[iedge]->getOpposite(this)->getYMax())
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
and (chunk->getYMax() == getYMax())) ) {
Edge::create( _westEdges[iedge]->getOpposite(this), chunk, Flags::Horizontal );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
_westEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::WestSide );
}
if (not _eastEdges.empty()) {
size_t iedge = 0;
for ( ; (iedge < _eastEdges.size()) ; ++iedge )
if (y <= _eastEdges[iedge]->getOpposite(this)->getYMax()) break;
if ( (y < _eastEdges[iedge]->getOpposite(this)->getYMax())
or ( (y == _eastEdges[iedge]->getOpposite(this)->getYMax())
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
and (chunk->getYMax() == getYMax())) ) {
Edge::create( chunk, _eastEdges[iedge]->getOpposite(this), Flags::Horizontal );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
_eastEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::EastSide );
}
cdebug_tabw(110,-1);
return chunk;
}
bool GCell::doGrid ()
{
bool openSession = Session::isOpen();
if (not openSession) getAnabatic()->openSession();
DbU::Unit vside = Session::getSliceHeight();
DbU::Unit hside = Session::getSliceHeight();
Interval hspan = getSide( Flags::Horizontal );
Interval vspan = getSide( Flags::Vertical );
if (hside % Session::getSliceStep()) {
hside += Session::getSliceStep() - hside % Session::getSliceStep();
}
// if (hspan.getSize() < 2*hside) {
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
// " (%s)"
// , DbU::getValueString(hspan.getSize()).c_str()
// , getString(this).c_str()
// ) << endl;
// Session::close();
// return false;
// }
// if (vspan.getSize() < 2*vside) {
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
// " (%s)"
// , DbU::getValueString(vspan.getSize()).c_str()
// , getString(this).c_str()
// ) << endl;
// return false;
// }
GCell* row = this;
GCell* column = NULL;
DbU::Unit ycut = vspan.getVMin()+vside;
for ( ; ycut < vspan.getVMax() ; ycut += vside ) {
column = row;
row = row->hcut( ycut );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
row->setType( Flags::MatrixGCell );
for ( DbU::Unit xcut = hspan.getVMin()+hside ; xcut < hspan.getVMax() ; xcut += hside ) {
column = column->vcut( xcut );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
column->setType( Flags::MatrixGCell );
}
}
column = row;
for ( DbU::Unit xcut = hspan.getVMin()+hside ; xcut < hspan.getVMax() ; xcut += hside ) {
column = column->vcut( xcut );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
column->setType( Flags::MatrixGCell );
}
setType( Flags::MatrixGCell );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
//size_t hLocal = - getAnabatic()->getConfiguration()->getHEdgeLocal();
//size_t vLocal = - getAnabatic()->getConfiguration()->getVEdgeLocal();
//for ( ; ibegin < gcells.size() ; ++ibegin ) {
// gcells[ibegin]->setType( Flags::MatrixGCell );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
// for ( Edge* edge : gcells[ibegin]->getEdges(Flags::NorthSide|Flags::EastSide) ) {
// if (edge->isHorizontal()) edge->incCapacity( hLocal );
// else edge->incCapacity( vLocal );
// }
//}
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
if (not openSession) Session::close();
return true;
}
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
void GCell::invalidate ( bool propagateFlag )
{
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
cdebug_log(110,1) << "GCell::invalidate() " << this << endl;
Super::invalidate( propagateFlag );
_flags |= Flags::Invalidated;
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_tabw(110,-1);
}
void GCell::materialize ()
{
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
cdebug_log(110,1) << "GCell::materialize() " << this << endl;
if (_xmin > getXMax()+1)
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
cerr << Error( "GCell::materialize(): %s, X Min is greater than Max.", getString(this).c_str() );
if (_ymin > getYMax()+1)
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
cerr << Error( "GCell::materialize(): %s, Y Min is greater than Max.", getString(this).c_str() );
_anabatic->_updateLookup( this );
//_anabatic->getMatrix()->show();
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
Super::materialize();
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
}
void GCell::_moveEdges ( GCell* dest, size_t ibegin, Flags flags )
{
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,1) << "GCell::_moveEdges() " << this << endl;
cdebug_log(110,0) << " toward " << dest << endl;
cdebug_log(110,0) << " ibegin: " << ibegin << " flags:" << flags << endl;
size_t iclear = ibegin;
if (flags.contains(Flags::SouthSide) and not _southEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "South side." << endl;
if (iclear < _southEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _southEdges.size()) ; ++iedge ) {
_southEdges[iedge]->_setTarget( dest );
dest->_southEdges.push_back( _southEdges[iedge] );
}
_southEdges.resize( iclear );
} else {
if (iclear > _southEdges.size())
cerr << Error("GCell::_moveEdges(): On south side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _southEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::NorthSide) and not _northEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "North side." << endl;
if (iclear < _northEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _northEdges.size()) ; ++iedge ) {
_northEdges[iedge]->_setSource( dest );
dest->_northEdges.push_back( _northEdges[iedge] );
}
_northEdges.resize( iclear );
} else {
if (iclear > _northEdges.size())
cerr << Error("GCell::_moveEdges(): On north side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _northEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::WestSide) and not _westEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "West side." << endl;
if (iclear < _westEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _westEdges.size()) ; ++iedge ) {
_westEdges[iedge]->_setTarget( dest );
dest->_westEdges.push_back( _westEdges[iedge] );
}
_westEdges.resize( iclear );
} else {
if (iclear > _westEdges.size())
cerr << Error("GCell::_moveEdges(): On west side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _westEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::EastSide) and not _eastEdges.empty()) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(110,0) << "East side." << endl;
if (iclear < _eastEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _eastEdges.size()) ; ++iedge ) {
_eastEdges[iedge]->_setSource( dest );
dest->_eastEdges.push_back( _eastEdges[iedge] );
}
_eastEdges.resize( iclear );
} else {
if (iclear > _eastEdges.size())
cerr << Error("GCell::_moveEdges(): On east side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _eastEdges.size()
, getString(this).c_str()
) << endl;
}
}
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_tabw(110,-1);
}
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
void GCell::setSouthWestCorner ( DbU::Unit x, DbU::Unit y )
{
//DbU::Unit dx = x - _xmin;
//DbU::Unit dy = y - _ymin;
/*for ( Contact* contact : _gcontacts ) {
Point position = contact->getPosition().translate( dx, dy );
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
for ( Component* component : contact->getSlaveComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal) {
horizontal->setY( position.getY() );
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
} else {
Vertical* vertical = dynamic_cast<Vertical*>( component );
vertical->setX( position.getX() );
}
}
if (not contact->getAnchor()) contact->setPosition( Point(x,y) );
}*/
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
_xmin = x;
_ymin = y;
invalidate( false );
}
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
void GCell::updateGContacts ( Flags flags )
{
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
Point center ( _xmin+getWidth()/2, _ymin+getHeight()/2 );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
for ( Contact* contact : _gcontacts ) {
for ( Component* component : contact->getSlaveComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
if (horizontal and (flags & Flags::Vertical)) {
horizontal->setY( center.getY() );
} else {
Vertical* vertical = dynamic_cast<Vertical*>( component );
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
if (vertical and (flags & Flags::Horizontal)) {
vertical->setX( center.getX() );
}
}
}
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
if (not contact->getAnchor()) contact->setPosition( center );
}
}
Contact* GCell::getGContact ( Net* net )
{
for ( Contact* contact : _gcontacts ) {
if (contact->getNet() == net) {
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl;
return contact;
}
}
Point center = getBoundingBox().getCenter();
Contact* contact = Contact::create( net
, _anabatic->getConfiguration()->getGContactLayer()
, center.getX()
, center.getY()
, DbU::fromLambda(2.0)
, DbU::fromLambda(2.0)
);
_gcontacts.push_back( contact );
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(111,0) << "GCell::getGContact(): " << contact << endl;
return contact;
}
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
bool GCell::unrefContact ( Contact* unref )
{
if (_gcontacts.empty()) return false;
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
cdebug_log(112,0) << "GCell::unrefContact(): " << unref << endl;
for ( size_t i=0 ; i< _gcontacts.size() ; ++i ) {
if (_gcontacts[i] == unref) {
if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false;
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
Validating channel routing mode (two metals) on SNX. * New: In Hurricane::Entity, add an id counter limit and a memory size limit. The two limits are checked only when a new Entity object is created. This should help avoiding massive memory links. * New: In CRL Core, add a "crlcore.groundName" and a "crlcore.powerName" parameter to specify the name of the ground/power signals to be created if they are missing in a Cell. For Alliance libraries it would be "vss" & "vdd" (default values), but for real technologies, it is often "gnd!" & "vdd!". The Blif parser is modificated to make use of it. * Bug: In AnabaticEngine::unify(), set the resulting unified segment in the center of the GCells common side. Gcells under a segment are found by using the edge that cover the segment axis. When we have a "bend" GCell stack and the axis is wrong, they could be ommited. This was causing deleted segments to be not removed from some Edges, then core dump. * Change: In Anabatic::AutoSegment::create(), smarter choosing of the reference contact, select the fixed or terminal one instead of always the source one. * New: In Anabatic::Edge::isEnding(), new function to check if a segment going through an Edge is starting/ending in either source or target GCell of the edge (active only when running in channel mode). * New: In Anabatic::Edge::add(), a segment takes part in the occupancy only if it is not ending in either source or target (channel mode only). The occupancy due to terminal is pre-computed in Katana. * New: In Anabatic::Edge::ripup(), in channel mode, never ripup a segment which is ending in either source or target (we *have* to access this edge to connect to the terminal). * Bug: In Anabatic::GCell::hcut() and vcut(), force the update of the Edge which is on the side that will get splitted by the cut. It's capacity will be reduced to it must be updated. * Change: In Anabatic::GCell::updateGContacts() add a flag to conditionnally update horizontals or verticals only. We may require only a partial update when resizing the GCell in only one direction. This, again, related to the fact that we compute the GCells under a segment thanks to it's axis position, so we need to be very careful when modificating axis. * Change: In Katana::Block::resizeChannels(), only update GContact vertical position. Do not disturb X positions of segments. * Bug: In Katana::GlobalRoute::DigitalDistance, in channel mode, some Edges can have a zero capacity, but still be reachable if the net has a terminal in either source or target. Look for this case and return a distance of zero instead of "unreachable". This was causing the global routing not to complete in channel mode. For computing the edge distance, makes the vertical edges much more long (10 times) than the horizontal ones as the vertical capacity is very limited. Hard coded for now, should make it a parameter in the future. * Change: In KatanaEngine::annotateGlobalGraph(), decrease the capacity of edges with reserveCapacity for each terminal inside a GCell. Both north and south edges are decreased as we a terminal will block both north and south edges. As a counterpart, the Edge capacity is not decreased when the global router connect to a terminal. * Change: In Katana::RoutingEvent::revalidate(), when in repair stage, do not expand the slack for horizontal segments in channel mode. So they may not overlap the standard cell row. * Bug: In Stratus documentation, do not use the french option in babel, the documentation is in english! * New: In Documentation, added Hurricane/Python tutorial, part for drawing layout.
2018-03-16 10:20:04 -05:00
cdebug_log(112,0) << " Effective destroy " << (void*)unref << endl;
std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] );
_gcontacts[ _gcontacts.size()-1 ]->destroy();
_gcontacts.pop_back();
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
return true;
}
}
return false;
}
void GCell::cleanupGlobal ()
{
for ( size_t i=0 ; i<_gcontacts.size() ; ) {
if (not _gcontacts[i]->getSlaveComponents().getLocator()->isValid()) {
std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] );
_gcontacts[ _gcontacts.size()-1 ]->destroy();
_gcontacts.pop_back();
} else
++i;
}
}
const Name& GCell::getName () const
{ return _extensionName; }
Box GCell::getBoundingBox () const
{
return Box( getXMin(), getYMin(), getXMax(1), getYMax(1) );
}
void GCell::translate ( const DbU::Unit&, const DbU::Unit& )
{
cerr << Error( "GCell::translate(): On %s,\n"
" Must never be called on a GCell object (ignored)."
, getString(this).c_str()
) << endl;
}
bool GCell::isNorth ( GCell* c ) const
{
bool found = false;
for (vector<Edge*>::const_iterator it = _northEdges.begin(); it != _northEdges.end(); it++){
if ( (*it)->getOpposite(this)->getId() == c->getId() ) {
found = true;
break;
}
}
return found;
}
bool GCell::isSouth ( GCell* c ) const
{
bool found = false;
for (vector<Edge*>::const_iterator it = _southEdges.begin(); it != _southEdges.end(); it++){
if ( (*it)->getOpposite(this)->getId() == c->getId() ) {
found = true;
break;
}
}
return found;
}
bool GCell::isEast ( GCell* c ) const
{
bool found = false;
for (vector<Edge*>::const_iterator it = _eastEdges.begin(); it != _eastEdges.end(); it++){
if ( (*it)->getOpposite(this)->getId() == c->getId() ) {
found = true;
break;
}
}
return found;
}
bool GCell::isWest ( GCell* c ) const
{
bool found = false;
for (vector<Edge*>::const_iterator it = _westEdges.begin(); it != _westEdges.end(); it++){
if ( (*it)->getOpposite(this)->getId() == c->getId() ) {
found = true;
break;
}
}
return found;
}
bool GCell::isSaturated ( size_t depth ) const
{ return getDensity(depth) > Session::getSaturateRatio(); }
// Interval GCell::getSide ( Flags direction ) const
// {
// if (direction & Flags::Vertical) return Interval( getYMin(), getYMax() );
// return Interval( getXMin(), getXMax() );
// }
AutoSegments GCell::getHStartSegments ()
{ return new AutoSegments_AnchorOnGCell (this,Flags::EastSide); }
AutoSegments GCell::getVStartSegments ()
{ return new AutoSegments_AnchorOnGCell (this,Flags::NorthSide); }
AutoSegments GCell::getHStopSegments ()
{ return new AutoSegments_AnchorOnGCell (this,Flags::WestSide); }
AutoSegments GCell::getVStopSegments ()
{ return new AutoSegments_AnchorOnGCell (this,Flags::SouthSide); }
size_t GCell::getRoutingPads ( set<RoutingPad*>& rps )
{
for ( size_t i=0 ; i<_contacts.size() ; ++i ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>(_contacts[i]->getAnchor());
if ( rp ) {
rps.insert ( rp );
}
}
return rps.size();
}
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 ?
2018-02-20 17:16:50 -06:00
int GCell::getHCapacity () const
{
int capacity = 0;
if (not _eastEdges.empty()) {
for ( Edge* edge : _eastEdges ) capacity += edge->getCapacity();
} else {
for ( Edge* edge : _westEdges ) capacity += edge->getCapacity();
}
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 ?
2018-02-20 17:16:50 -06:00
return capacity;
}
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 ?
2018-02-20 17:16:50 -06:00
int GCell::getVCapacity () const
{
int capacity = 0;
if (not _northEdges.empty()) {
for ( Edge* edge : _northEdges ) capacity += edge->getCapacity();
} else {
for ( Edge* edge : _southEdges ) capacity += edge->getCapacity();
}
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 ?
2018-02-20 17:16:50 -06:00
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;
}
float GCell::getAverageHVDensity () const
{
// Average density of all layers mixeds together.
float density = 0.0;
for ( size_t i=0 ; i<_depth ; i++ )
density += _densities[i];
return density / ((float)(_depth-_pinDepth));
}
float GCell::getMaxHVDensity () const
{
// Maximum density between all horizontal vs. all vertical layers.
size_t hplanes = 0;
size_t vplanes = 0;
float hdensity = 0.0;
float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; }
else { vdensity += _densities[i]; ++vplanes; }
}
if (hplanes) hdensity /= hplanes;
if (vplanes) vdensity /= vplanes;
return std::max(hdensity, vdensity);
}
float GCell::getDensity ( Flags flags ) const
{
if (isInvalidated() and not(flags & Flags::NoUpdate)) const_cast<GCell*>(this)->updateDensity();
float density = 0.0;
if (getAnabatic()->getDensityMode() == AverageHVDensity) {
density = getAverageHVDensity();
} else if (getAnabatic()->getDensityMode() == MaxHVDensity) {
density = getMaxHVDensity();
} else if (getAnabatic()->getDensityMode() == AverageHDensity) {
size_t hplanes = 0;
float hdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; }
}
if (hplanes) hdensity /= hplanes;
density = hdensity;
} else if (getAnabatic()->getDensityMode() == AverageVDensity) {
size_t vplanes = 0;
float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isVerticalPlane(i)) { vdensity += _densities[i]; ++vplanes; }
}
if (vplanes) vdensity /= vplanes;
density = vdensity;
} else if (getAnabatic()->getDensityMode() == MaxDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (_densities[i] > density) density = _densities[i];
}
} else if (getAnabatic()->getDensityMode() == MaxHDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isHorizontalPlane(i) and (_densities[i] > density)) density = _densities[i];
}
} else if (getAnabatic()->getDensityMode() == MaxVDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isVerticalPlane(i) and (_densities[i] > density)) density = _densities[i];
}
}
return density;
}
void GCell::addBlockage ( size_t depth, DbU::Unit length )
{
if (depth >= _depth) return;
_blockages[depth] += length;
_flags |= Flags::Invalidated;
cdebug_log(149,0) << "GCell:addBlockage() " << this << " "
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
}
void GCell::removeContact ( AutoContact* ac )
{
size_t begin = 0;
size_t end = _contacts.size();
bool found = false;
for ( ; not found and (begin < end) ; begin++ ) {
if ( _contacts[begin] == ac ) {
_contacts[begin] = _contacts[end-1];
found = true;
}
}
if (found) {
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
_contacts.pop_back();
} else {
cerr << Bug("%p:%s do not belong to %s."
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
}
}
void GCell::removeHSegment ( AutoSegment* segment )
{
size_t end = _hsegments.size();
size_t begin = 0;
for ( ; begin < end ; begin++ ) {
if (_hsegments[begin] == segment) std::swap( _hsegments[begin], _hsegments[--end] );
}
if (_hsegments.size() == end) {
cerr << Bug( "%s do not go through %s."
, getString(segment).c_str(), _getString().c_str() ) << endl;
return;
}
if (_hsegments.size() - end > 1)
cerr << Bug( "%s has multiple occurrences of %s."
, _getString().c_str(), getString(segment).c_str() ) << endl;
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
}
void GCell::removeVSegment ( AutoSegment* segment )
{
size_t end = _vsegments.size();
size_t begin = 0;
for ( ; begin < end ; begin++ ) {
if (_vsegments[begin] == segment) std::swap( _vsegments[begin], _vsegments[--end] );
}
if (_vsegments.size() == end) {
cerr << Bug( "%s do not go through %s."
, getString(segment).c_str()
, _getString().c_str() ) << endl;
return;
}
if (_vsegments.size() - end > 1)
cerr << Bug( "%s has multiple occurrences of %s."
, _getString().c_str()
, getString(segment).c_str() ) << endl;
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
}
void GCell::updateContacts ()
{ for ( AutoContact* contact : _contacts ) contact->updateGeometry(); }
size_t GCell::updateDensity ()
{
if (not isInvalidated()) return (isSaturated()) ? 1 : 0;
_flags.reset( Flags::Saturated );
for ( size_t i=0 ; i<_vsegments.size() ; i++ ) {
if ( _vsegments[i] == NULL )
cerr << "NULL Autosegment at index " << i << endl;
}
sort( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
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 ?
2018-02-20 17:16:50 -06:00
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;
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 ?
2018-02-20 17:16:50 -06:00
uLengths1 [i] = 0;
uLengths2 [i] = 0;
localCounts [i] = 0.0;
_globalsCount[i] = 0.0;
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 ?
2018-02-20 17:16:50 -06:00
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;
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 ?
2018-02-20 17:16:50 -06:00
contact->getLengths( uLengths1, processeds );
for ( size_t i=0 ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
if (isHorizontalPlane(i)) uLengths2[i] += uLengths1[i]+hpenalty;
else uLengths2[i] += uLengths1[i]+vpenalty;
}
}
// Add the "pass through" horizontal segments.
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 ?
2018-02-20 17:16:50 -06:00
if (not _hsegments.empty()) {
const Layer* layer = _hsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0;
for ( size_t i=0 ; i<_hsegments.size() ; i++ ) {
_globalsCount[depth] += 1.0;
ufragments[depth].incGlobals();
if ( layer != _hsegments[i]->getLayer() ) {
uLengths2[depth] += count * width;
count = 0;
layer = _hsegments[i]->getLayer();
depth = Session::getRoutingGauge()->getLayerDepth(layer);
}
count++;
_feedthroughs[depth] += 1.0;
}
if ( count ) {
uLengths2[depth] += count * width;
}
}
// Add the "pass through" vertical segments.
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 ?
2018-02-20 17:16:50 -06:00
if (not _vsegments.empty()) {
const Layer* layer = _vsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0;
for ( size_t i=0 ; i<_vsegments.size() ; i++ ) {
_globalsCount[depth] += 1.0;
ufragments[depth].incGlobals();
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 ?
2018-02-20 17:16:50 -06:00
if (layer != _vsegments[i]->getLayer()) {
uLengths2[depth] += count * height;
count = 0;
layer = _vsegments[i]->getLayer();
depth = Session::getRoutingGauge()->getLayerDepth(layer);
}
count++;
_feedthroughs[depth] += 1.0;
}
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 ?
2018-02-20 17:16:50 -06:00
if (count) {
uLengths2[depth] += count * height;
}
}
// Add the blockages.
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 ?
2018-02-20 17:16:50 -06:00
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
// Compute the number of non pass-through tracks.
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 ?
2018-02-20 17:16:50 -06:00
if (not processeds.empty()) {
AutoSegment::DepthLengthSet::iterator isegment = processeds.begin();
const Layer* layer = (*isegment)->getLayer();
DbU::Unit axis = (*isegment)->getAxis();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0;
for ( ; isegment != processeds.end(); ++isegment ) {
_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
localCounts [depth] += 1.0;
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;
ufragments[depth].merge( (*isegment)->getAxis(), (*isegment)->getSpanU() );
if ( (axis != (*isegment)->getAxis()) or (layer != (*isegment)->getLayer()) ) {
count = 0;
axis = (*isegment)->getAxis();
layer = (*isegment)->getLayer();
depth = Session::getRoutingGauge()->getLayerDepth(layer);
}
++count;
}
}
// Normalize: 0 < d < 1.0 (divide by H/V capacity).
for ( size_t i=0 ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
int capacity = getCapacity(i);
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
if (Session::getDirection(i) & Flags::Horizontal) {
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 ?
2018-02-20 17:16:50 -06:00
if (width and capacity) {
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * width );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
_feedthroughs [i] += (float)(_blockages[i] / width);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width;
} else {
_densities [i] = 0;
_feedthroughs [i] = 0;
_fragmentations[i] = 0;
}
} else {
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 ?
2018-02-20 17:16:50 -06:00
if (height and capacity) {
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * height );
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
_feedthroughs [i] += (float)(_blockages[i] / height);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height;
} else {
_densities [i] = 0;
_feedthroughs [i] = 0;
_fragmentations[i] = 0;
}
}
if (_densities[i] >= 1.0) _flags |= Flags::Saturated;
}
Basic support for FreePDK 45 completed. * New: In Commons, inspector support for std::pair<T,U>. * New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non square VIAs. The hole (cut) remains square, but the various metal extensions can now be different in X and Y. The ::getEnclosure() method now takes a flag EnclosureH / EnclosureV. * New: In Hurricane::DbU, inspector support for: std::pair<DbU::Unit,DbU::Unit> std::array<DbU::Unit,3> Must be defined here as DbU do not exists yet in Commons.h * Bug: In Hurricane::Interval::getSize(), when the interval is "full span", do not return the difference between min and max, but directly DbU::Max. (the previous result was -1 !) * New: In CRL Core Python/Technology.py, support for non square VIAs in the configuration files. Applied to FreePDK 45. * New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge is for symbolic layout or not. Exported to Python. * New: In Anabatic::AutoHorizontal::updatePosition(), differentiated computation for soure or target taking account of the VIA extension in the right segment metal (due to non-square VIAs). * Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is UP for HV gauges and DOWN for VH. * New: In Anabatic::AutoSegment::_initialize(), create a cache of the various extension length for each layer (viaToTop, viaToBottom, viaToSame). New implementation of getExtensionCap() using the previous cached extension table. See updatePositions(). New static functions to access the extension cache in the header: getViaTotopCap() ... * Change: In Anabatic::AutoSegment, in various update methods, updateOrient() must always be called *before* updatePositions() as extensions are dependant on source/target. * New: In Anabatic::AutoSegment::getEndAxes() compute the position of the first source and last target position (center/axes) on an *aligned* set of segments. * New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to signal segments that can be put on only one track. Specific case to VH gauge for a M1 vertical terminal with a M2 vertical segment. The M2 is effectively bound to the M1 axis position. * Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global and only one RoutingPad the connexion to the RoutingPad was duplicated. It was valid, but totally stupid. * Bug: In Anabatic::Session::_canonize(), for an aligned segment set, intersect the user constraints from all segments instead of only considering the canonical one. Issue a warning about too tight constraints only for symbolic gauges. It may be correct for the real ones. * New: In Katata::DataNegociate::update(), more accurate computation of the perpandicular free interval. Use segment extension cap calculation. Create a special case for fixed axis segments allowing them to find alternative free interval, try under source and under target as they are likely to be draggable segments. * Change: In Katana::Manipulator::relax(), use the extension cap value to compute the axis of the perpandicular segemnts. * Change: In Katana::Manipulator::moveUp(), now move up the whole set of aligned segments instead of just the canonical one. * Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate TrackMarkers insertions for fixed terminals. * New: In Katana::RoutingEvent::Key::Compare::operator(), segments with fixed axis are processed prior to any others. * New: In Katana::RoutingEventLoop, store segment pointers instead of ids to generate more accurate error messages. * Change: In Katana::RoutingPlane::create(), perform local track assignment only for HV gauges. * Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize" step in the automaton. Mutliple states transitions can occurs in a row if an action fails. * New: In Katana::Session::_toIntervalAxis(), normalize interval bounds so they are on track positions (by shrinking the interval). * Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
if (ccapacity) _cDensity = ( (float)_contacts.size() ) / ccapacity;
else _cDensity = 0;
_flags.reset( Flags::Invalidated );
checkDensity();
return isSaturated() ? 1 : 0 ;
}
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
void GCell::truncDensities ()
{
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 ?
2018-02-20 17:16:50 -06:00
Box bBox = getBoundingBox();
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
for ( size_t i=0 ; i<_depth ; i++ ) {
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 ?
2018-02-20 17:16:50 -06:00
int capacity = getCapacity(i);
if (isHorizontalPlane(i)) {
if (_blockages[i] > capacity * bBox.getWidth())
_blockages[i] = capacity * bBox.getWidth();
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
} else {
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 ?
2018-02-20 17:16:50 -06:00
if (_blockages[i] > capacity * bBox.getHeight())
_blockages[i] = capacity * bBox.getHeight();
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
}
}
_flags &= ~Flags::Saturated;
}
size_t GCell::checkDensity () const
{
if (isInvalidated()) const_cast<GCell*>(this)->updateDensity();
if ( not Session::isInDemoMode() and Session::doWarnGCellOverload() ) {
for ( size_t i=0 ; i<_depth ; i++ ) {
if (_densities[i] > 1.0) {
cparanoid << Warning( "%s overloaded in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
, _getString().c_str()
, getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
, _densities[1] // M2
, _densities[2] // M3
//, _blockages[2] // M4
, _densities[3] // M5
, _densities[4] // M6
)
<< endl;
}
}
}
return isSaturated() ? 1 : 0 ;
}
bool GCell::hasFreeTrack ( size_t depth, float reserve ) const
{
if (isInvalidated()) const_cast<GCell*>(this)->updateDensity();
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 ?
2018-02-20 17:16:50 -06:00
float capacity = getCapacity(depth);
cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName()
//<< " " << (_densities[depth]*capacity) << " vs. " << capacity
<< " " << _feedthroughs[depth] << " vs. " << capacity
<< " " << this << endl;
return (_feedthroughs[depth] + 0.99 + reserve <= capacity);
}
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
size_t GCell::getNetCount () const
{
set<Net*> nets;
for ( Edge* edge : _westEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _eastEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _northEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _southEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
return nets.size();
}
void GCell::rpDesaturate ( set<Net*>& globalNets )
{
set<RoutingPad*> rps;
getRoutingPads( rps );
set<Net*> rpNets;
for ( RoutingPad* rp : rps ) {
if (rp->getLayer() != Session::getRoutingLayer(0)) continue;
rpNets.insert( rp->getNet() );
}
if (rpNets.size() < Session::getSaturateRp()) return;
cerr << Warning("%s has %zd terminals (h:%zd, v:%zd)"
,getString(this).c_str()
,rps.size()
,_hsegments.size()
,_vsegments.size()
) << endl;
AutoSegment* segment;
while ( (_densities[1] > 0.5) and stepDesaturate(1,globalNets,segment,Flags::ForceMove) ) {
cdebug_log(149,0) << "Moved up: " << segment << endl;
}
}
bool GCell::stepDesaturate ( size_t depth
, set<Net*>& globalNets
, AutoSegment*& moved
, Flags flags
)
{
cdebug_log(9000,0) << "Deter| GCell::stepDesaturate() [" << getId() << "] depth:" << depth << endl;
updateDensity();
moved = NULL;
if (not (flags & Flags::ForceMove) and not isSaturated(depth)) return false;
vector<AutoSegment*>::iterator isegment;
vector<AutoSegment*>::iterator iend;
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
if (Session::getDirection(depth) & Flags::Horizontal) {
iend = _hsegments.end ();
isegment = _hsegments.begin();
} else {
iend = _vsegments.end ();
isegment = _vsegments.begin();
}
for ( ; (isegment != iend) ; isegment++ ) {
unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer());
if (segmentDepth < depth) continue;
if (segmentDepth > depth) break;
globalNets.insert( (*isegment)->getNet() );
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
moved = (*isegment);
if (moved) return true;
}
return false;
}
bool GCell::stepBalance ( size_t depth, GCell::Set& invalidateds )
{
cdebug_log(149,0) << "stepBalance() - " << this << endl;
updateDensity();
vector<AutoSegment*>::iterator isegment;
vector<AutoSegment*>::iterator iend;
set<Net*> globalNets;
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
if (Session::getDirection(depth) & Flags::Horizontal) {
iend = _hsegments.end ();
isegment = _hsegments.begin();
} else {
iend = _vsegments.end ();
isegment = _vsegments.begin();
}
for ( ; (isegment != iend) ; isegment++ ) {
unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer());
if (segmentDepth < depth) continue;
if (segmentDepth > depth) break;
#if THIS_IS_DISABLED
// Hard-coded: reserve 3 tracks (1/20 * 3).
if ((*isegment)->canMoveULeft(0.05)) {
getAnabatic()->moveULeft(*isegment,globalNets,invalidateds);
return true;
}
if ((*isegment)->canMoveURight(0.05)) {
getAnabatic()->moveURight(*isegment,globalNets,invalidateds);
return true;
}
#endif
}
return false;
}
bool GCell::stepNetDesaturate ( size_t depth, set<Net*>& globalNets, GCell::Set& invalidateds )
{
cdebug_log(9000,0) << "Deter| GCell::stepNetDesaturate() depth:" << depth << endl;
cdebug_log(9000,0) << "Deter| " << this << endl;
updateDensity();
vector<AutoSegment*>::iterator isegment;
vector<AutoSegment*>::iterator iend;
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
if (Session::getDirection(depth) & Flags::Horizontal) {
iend = _hsegments.end ();
isegment = _hsegments.begin ();
} else {
iend = _vsegments.end ();
isegment = _vsegments.begin ();
}
for ( ; (isegment != iend) ; isegment++ ) {
unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer());
if (segmentDepth < depth) continue;
if (segmentDepth > depth) break;
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
return true;
}
return false;
}
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 ?
2018-02-20 17:16:50 -06:00
void GCell::forceEdgesCapacities ( unsigned int hcapacity, unsigned int vcapacity )
{
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);
}
string GCell::_getTypeName () const
{ return getString(_extensionName); }
string GCell::_getString () const
{
string s = Super::_getString();
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
s.insert( s.size()-1, " "+getString(_flags) );
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
2017-06-21 11:02:37 -05:00
+ "-" + DbU::getValueString(getYMin())
+ "-" + DbU::getValueString(getXMax())
+ "-" + DbU::getValueString(getYMax())
+ "-" + DbU::getValueString(getHeight())
+ "-" + DbU::getValueString(getWidth()) + ")";*/
return s;
}
Record* GCell::_getRecord () const
{
Record* record = Super::_getRecord();
record->add( getSlot("_flags" , &_flags ) );
record->add( getSlot("_westEdges" , &_westEdges ) );
record->add( getSlot("_eastEdges" , &_eastEdges ) );
record->add( getSlot("_southEdges" , &_southEdges) );
record->add( getSlot("_northEdges" , &_northEdges) );
record->add( DbU::getValueSlot("_xmin", &_xmin) );
record->add( DbU::getValueSlot("_ymin", &_ymin) );
Added support for 2-Metal block routing in Anabatic & Katana. * New: In AnabaticEngine::invalidateRoutingPads() this method is a temporary workaround for a Hurricane problems. When an instance is moved, the RoutingPads that use it must be moved accordingly, but they are not invalidated so they stay in the wrong QuadTree. New method ::_resizeMatrix() to be called when the associated Cell is resized. * Bug: In AutoHorizontal::getConstraints() and AutoVertical::getConstraints(), the *target* constraints where never merged. * Change: In AutoHorizontal::getCells() and AutoVertical::getGCells(), now return a boolean to tell if it was ok (must not encounter a NULL GCell while progessing from source to target). * New: In Anabatic::Configuration and Anabatic:Session, create new methods: - getDHorizontalLayer() - getDhorizontalDepth() - getDHorizontalWidth() - getDHorizontalPitch() And so on for Vertical and Contact. They supply depth-independant informations about the H/V layers to build the initial detailed routing. The AutoSegment::create() methods have been modificated accordingly. * New: In Anabatic::GCell, add two new types "StdCellRow" and "ChannelRow" for implementing 2-Metal blocks. Rename the GCell::setXY() method in GCell::setSouthWestCorner(), move the contents of GCell::updateContactsPosition() into it and suppress it. WARNING: In case of a GCell shrink this may cause problems. But for now we only expand... New method GCell::getNetCount() to count the number of Net going though the GCell. * Change: In Anabatic::Edge, add specific support for capacity of 2-Metal routing channels. * Change: In Anabatic::Dijsktra various methods, replace the "gcell->isMatrix()" calls by "not gcell->isAnalog()". Add more check so that the methods pertaining to the analog routing (GRData) are not called in digital mode. * New: In Anabatic::Dijkstra::materialize(), add support for 2-Metal specific cases. That is, always break in case of vertical pass-through or U-turn. The global routing must always be broken in H-Channel. * New: In Anabatic::GCell & Anabatic::Edge, make use of the Session mechanism to ensure the revalidation. The "::revalidate()" method is then moved as "::materialize()" (overload of Go) and "::_invalidate()" becomes "::invalidate()" * Change: In LoadGlobalRouting, cosmetic rename of SortHkByX in SortHookByX. * New: In GCellTopology, added support for building 2-Metal topologies. * ForkStack is now an object attribute as many methods do need it. * To push segments/hook on the stack, a new method "push()" is available. Perform NULL and fromHook checking. Can also setup _southWestContact or _northEastContact if it is the "from" edge. * N/S/E/W edges are now vector as in digital channel mode there can be more than one. * Added build topological build methods: - doRp_2m_Access() RoutingPad stem access. - _do_2m_1G_1M1() North or south access. - _do_2m_2G_1M1() North AND south access. - _do_2m_xG() H-Channel routing. * New: In Anabatic::Matrix, new ::resize() function, as Cell can be resizeds. * New: In Anabatic::Vertex, new static method ::getValueString() for a friendly text rendering. * New: In Katana::DigitalDistance, support for channel routing. * Change: In KatanaEngine::digitalSetup() and KatanaEngine::runGlobalrouter(), for channel routing, calls to setupPowerRails() and protectRoutingPads() must be called after the core block has been fully dimensionned. ::runGlobalrouter() contains the code tasked with the grid creation and channel sizing. * New: In KatanaEngine: Added support for core block, for 2-Metal routing. May be expanded for over-the-cell routing in the future. Added methods : - isDigitalMode() - isAnalogMode() - isMixedMode() - isChannelMode() - getBlock() / addBlock() - setupChannelMode() - createChannel() * New: In Katana, new class Block to manage core blocks and perform channel routing. * New: In Katana::Session, new convenience method "isOpen()".
2017-08-18 16:56:23 -05:00
record->add( getSlot ( "_gcontacts", &_gcontacts ) );
record->add( getSlot ( "_vsegments", &_vsegments ) );
record->add( getSlot ( "_hsegments", &_hsegments ) );
record->add( getSlot ( "_contacts" , &_contacts ) );
record->add( getSlot ( "_depth" , &_depth ) );
RoutingGauge* rg = getAnabatic()->getConfiguration()->getRoutingGauge();
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_blockages[depth] ) );
}
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth);
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_densities[depth] ) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "Anabatic::GCellDensitySet".
GCellDensitySet::GCellDensitySet ( size_t depth )
: _depth (depth)
, _set ()
, _requests()
{ }
GCellDensitySet::GCellDensitySet ( size_t depth, const GCell::Vector& gcells )
: _depth (depth)
, _set ()
, _requests()
{
for ( size_t i=0 ; i<gcells.size() ; i++ )
_requests.insert( gcells[i] );
requeue();
}
GCellDensitySet::~GCellDensitySet ()
{
if (not _requests.empty()) {
cerr << Warning("~GCellDensitySet(): Still contains %d requests (and %d elements)."
,_requests.size(),_set.size()) << endl;
}
}
void GCellDensitySet::requeue ()
{
cdebug_log(149,0) << "GCellDensitySet::requeue()" << endl;
std::set<GCell*,GCell::CompareByKey>::iterator iinserted;
GCell::Set::iterator igcell = _requests.begin();
// Remove invalidateds GCell from the queue.
for ( ; igcell != _requests.end() ; ++igcell ) {
iinserted = _set.find(*igcell);
if (iinserted != _set.end()) {
_set.erase( iinserted );
}
}
// Re-insert invalidateds GCell in the queue *after* updating the key.
for ( igcell = _requests.begin() ; igcell != _requests.end() ; ++igcell ) {
(*igcell)->updateKey( _depth );
_set.insert( *igcell );
}
_requests.clear();
}
// -------------------------------------------------------------------
// Utilities.
string getVectorString ( float* v, size_t size )
{
ostringstream s;
s << setprecision(3);
for ( size_t i=0 ; i<size ; i++ ) {
if ( !i ) s << "[";
else s << " ";
s << v[i];
}
s << "]";
return s.str();
}
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah! * Bug: In Hurricane, in StaticObservable::getObserver(), if the slot pointer is NULL, do not try to access the owner. Returns NULL, so the caller can be aware of the situation... * Change: In Hurricane, in BreakpointWidget & ExceptionWidget some cosmetic changes (fonts and window sizes). * Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account the constraints from the source AutoContact, as it holds the constraints transmitted by the RoutingPads and sets up by propageConstraintsFromRp(). It is likely to be a bug affecting the original Katabatic as well. * Change: In Anabatic, in RawGCellsUnder(), check that the segment is not completly oustside the cell abutment box and truncate the coordinates to the part that is inside. Use the "shrink" if we reach the east/north border. * Change: In Anabatic, in Configuration, no more decorator because we will use a true derived relationship. Katana *derives* from *Anabatic* and do not *decorate* it, so the Configuration can do the same. It also implies that we directly create a Katana engine, not an Anabatic one. * Change: In Anabatic, in Session, do not allow the opening of the Session in a standalone fashion (with a static method). Instead it must be opened using the relevant method of the Anabatic/Katana engine. This ensure we are opening the right Session type. * Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment is not part of the collection by default, but will be included if the Flags::WithSelf is set. * Change: In Configuration, all the flags value are now defined in two steps. Declared in the header and initialized in the module. This is to prevent the fact that on some cases, in relation with the Python "extern C" part modules, we need a true allocated variable. It was causing weird linking problems. A side effect is that they can no longer be used as entry is switches, have to replace them by if/else. * New: In Anabatic, new GCell::getNeighborAt() utility function. * Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with the grid type... Back annote all the edges capacity (north & east) with the reserved local capacity. * New: Complete portage of Kite over Anabatic. The new engine is christened "Katana" for Kite-Analogic. When it's capabilities and performances will be on a part with Kite, it is to completly replace it (and take back the "Kite" name). Preliminary tests seems to show that, contrary to intuition (because built on a more complex/slower grid), it is even slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
bool isLess ( const GCell* lhs, const GCell* rhs, Flags direction )
{
if (direction & Flags::Horizontal) {
if (lhs->getXMin() != rhs->getXMin()) return lhs->getXMin() < rhs->getXMin();
} else {
if (direction & Flags::Vertical) {
if (lhs->getYMin() != rhs->getYMin()) return lhs->getYMin() < rhs->getYMin();
}
}
return lhs->getId() < rhs->getId();
}
bool isGreater ( const GCell* lhs, const GCell* rhs, Flags direction )
{
if (direction & Flags::Horizontal) {
if (lhs->getXMin() != rhs->getXMin()) return lhs->getXMin() > rhs->getXMin();
} else {
if (direction & Flags::Vertical) {
if (lhs->getYMin() != rhs->getYMin()) return lhs->getYMin() > rhs->getYMin();
}
}
return lhs->getId() > rhs->getId();
}
} // Anabatic namespace.