coriolis/katana/src/Block.cpp

366 lines
11 KiB
C++
Raw Normal View History

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
// -*- mode: C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2017-2018, All Rights Reserved
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
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Block.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/DebugSession.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Cell.h"
#include "anabatic/Edge.h"
#include "katana/Block.h"
#include "katana/KatanaEngine.h"
namespace Katana {
using std::cerr;
using std::endl;
using std::make_pair;
using std::ostringstream;
using std::setw;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Breakpoint;
using Hurricane::DebugSession;
using Hurricane::SubTypeCollection;
using Hurricane::Transformation;
using Hurricane::RoutingPad;
using Hurricane::Instance;
using Hurricane::Path;
using Anabatic::Edge;
// -------------------------------------------------------------------
// Class : "Katana::Row".
void Row::add ( DbU::Unit x, Occurrence occurrence )
{
auto iocc = _occurrences.find( x );
if (iocc != _occurrences.end()) {
cerr << Error( "Row::add() In row @%s, two elements at the same X position %s:\n"
" %s\n"
" %s"
, DbU::getValueString(_y).c_str()
, DbU::getValueString(x).c_str()
, getString((*iocc).second).c_str()
, getString(occurrence).c_str()
) << endl;
return;
}
_occurrences.insert( make_pair(x,occurrence) );
}
void Row::setY ( DbU::Unit y )
{
for ( auto iocc : _occurrences ) {
Instance* instance = dynamic_cast<Instance*>( iocc.second.getEntity() );
if (not instance) continue;
Transformation itransf = instance->getTransformation();
Transformation dtransf ( itransf.getTx(), itransf.getTy() - _y + y, itransf.getOrientation() );
instance->setTransformation( dtransf );
}
_y = y;
DbU::Unit sliceHeight = Session::getSliceHeight() + Session::getPitch( (size_t)0 );
if (getSouthWest()) {
GCell* gcellRow = getSouthWest();
GCell* gcellChannel = gcellRow->getNorth();
while ( gcellRow ) {
gcellRow->setSouthWestCorner( gcellRow->getXMin(), _y );
gcellRow = gcellRow->getEast();
if (gcellChannel) {
gcellChannel->setSouthWestCorner( gcellChannel->getXMin(), _y+sliceHeight );
gcellChannel = gcellChannel->getEast();
}
}
}
}
GCell* Row::createChannel ( GCell* southWest, DbU::Unit channelHeight )
{
if (not southWest)
throw Error( "Row::createChannel(): NULL southWest GCell." );
if (_occurrences.empty())
throw Error( "Row::createChannel(): No instances in row." );
if (southWest->getXMin() != (*_occurrences.begin()).first)
throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs." );
if (southWest->getYMin() != _y)
throw Error( "Row::createChannel(): South-west GCell YMIn and Row Y min differs (%s vs. %s)."
, DbU::getValueString(southWest->getYMin()).c_str()
, DbU::getValueString(_y).c_str()
);
DbU::Unit ypitch = Session::getPitch( (size_t)0 );
DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch;
bool northRow = (_y + sliceHeight >= getCell()->getAbutmentBox().getYMax());
_southWest = southWest;
GCell* channel = _southWest->hcut( _southWest->getYMin() + sliceHeight );
GCell* nextSW = NULL;
if (not northRow) {
nextSW = channel->hcut( _southWest->getYMin() + sliceHeight + channelHeight );
if (not nextSW) {
throw Error( "Row::createChannel(): Cannot h-cut %s @%s."
, getString(channel).c_str()
, DbU::getValueString(_southWest->getYMin() + sliceHeight + channelHeight).c_str()
);
}
}
southWest->setType( Anabatic::Flags::StdCellRow );
if (channel) channel->setType( Anabatic::Flags::ChannelRow );
DbU::Unit xmax = getCell()->getAbutmentBox().getXMax() - sliceHeight;
DbU::Unit xcut = _southWest->getXMin() + sliceHeight;
for ( ; xcut < xmax ; xcut += sliceHeight ) {
southWest = southWest->vcut( xcut );
southWest->setType( Anabatic::Flags::StdCellRow );
if (channel) {
channel = channel->vcut( xcut );
channel->setType( Anabatic::Flags::ChannelRow );
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
channel->getWestEdge()->setFlags( Flags::InfiniteCapacity );
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
}
}
return nextSW;
}
void Row::routingPadsSubBreak ()
{
if (not _southWest)
throw Error( "Row::routingPadsSubBreak(): NULL southWest GCell." );
set<Net*> nets;
map<DbU::Unit, RoutingPad*> rps;
GCell* southWest = _southWest;
while ( southWest ) {
bool gcellSplitted = false;
for ( RoutingPad* rp : SubTypeCollection<Component*,RoutingPad*>( getCell()->getComponentsUnder(southWest->getBoundingBox() ) ) ) {
if ( (rp->getX() >= southWest->getXMax())
or (rp->getX() < southWest->getXMin()) ) continue;
rps.insert( make_pair(rp->getX(),rp) );
}
for ( auto irp : rps ) {
auto inet = nets.find( irp.second->getNet() );
if (inet == nets.end()) {
nets.insert( irp.second->getNet() );
} else {
if (southWest->getId() == 2998) DebugSession::close();
southWest = southWest->vcut( irp.second->getX() );
southWest->setType( Anabatic::Flags::StdCellRow );
gcellSplitted = true;
break;
}
}
rps .clear();
nets.clear();
if (not gcellSplitted) {
if (southWest->getId() == 2998) DebugSession::close();
southWest = southWest->getEast();
}
}
}
uint32_t Row::computeChannelHeight ()
{
_channelHeight = 2;
GCell* gcell = getSouthWest()->getNorth();
while ( gcell ) {
_channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() );
// Edge* east = gcell->getEastEdge();
// if (east)
// _channelHeight = std::max( _channelHeight, east->getRealOccupancy() );
gcell = gcell->getEast();
}
return _channelHeight;
}
string Row::_getString () const
{ return "<Row @" + DbU::getValueString(_y) + " instances:" + getString(_occurrences.size()) + ">"; }
Record* Row::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add( DbU::getValueSlot( "_y", &_y ) );
record->add( getSlot( "_occurrences", &_occurrences ) );
return record;
}
// -------------------------------------------------------------------
// Class : "Katana::Block".
Block::Block ( KatanaEngine* katana, Cell* cell )
: _katana(katana)
, _cell (cell)
, _rows ()
{
for ( Occurrence occurrence : _cell->getLeafInstanceOccurrences() ) {
add( occurrence );
}
_katana->addBlock( this );
}
Block::~Block ()
{
for ( Row* row : _rows ) delete row;
}
Row* Block::getAt ( DbU::Unit y ) const
{
for ( size_t i=0 ; i<_rows.size() ; ++i ) {
if (_rows[i]->getY() == y) return _rows[i];
}
return NULL;
}
void Block::add ( Occurrence occurrence )
{
Instance* instance = dynamic_cast<Instance*>(occurrence.getEntity());
if (not instance) {
cerr << Warning( "Block::add(): Not an Instance occurrence, %s."
,getString(occurrence).c_str() ) << endl;
return;
}
Transformation transf = occurrence.getPath().getTransformation( instance->getTransformation() );
Box bbInstance = transf.getBox( instance->getMasterCell()->getAbutmentBox() );
Row* row = getAt( bbInstance.getYMin() );
if (not row) {
row = new Row ( this, bbInstance.getYMin() );
auto irow = _rows.begin();
for ( ; irow != _rows.end() ; ++irow ) {
if ((*irow)->getY() >= row->getY()) break;
}
_rows.insert( irow, row );
}
row->add( bbInstance.getXMin(), occurrence );
}
void Block::createChannels ()
{
bool sessionReUse = Session::isOpen();
if (not sessionReUse) _katana->openSession();
DbU::Unit ypitch = Session::getPitch( (size_t)0 );
DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch;
for ( size_t i=0 ; i<_rows.size() ; ++i )
_rows[i]->setY( i*ypitch + i*sliceHeight );
Box ab ( _cell->getAbutmentBox() );
if (not _rows.empty()) {
_cell->setAbutmentBox( ab.inflate( 0, 0, 0, ypitch*(2*_rows.size()-1) ) );
_katana->_resizeMatrix();
}
//GCell* southWest = _katana->getGCellUnder( ab.getXMin(), ab.getYMin() );
GCell* southWest = _katana->getSouthWestGCell();
if (southWest != _katana->getSouthWestGCell())
throw Error( "Block::createChannels(): Only block are supported for now..." );
for ( Row* row : _rows )
southWest = row->createChannel( southWest, ypitch );
_katana->invalidateRoutingPads();
Session::close();
_katana->openSession();
for ( Row* row : _rows )
row->routingPadsSubBreak();
if (not sessionReUse) Session::close();
}
void Block::resizeChannels ()
{
cmess1 << " o Sizing routing channels." << endl;
bool sessionReUse = Session::isOpen();
if (not sessionReUse) _katana->openSession();
DbU::Unit ypitch = Session::getPitch( (size_t)0 );
DbU::Unit sliceHeight = Session::getSliceHeight() + ypitch;
uint32_t channelSum = 0;
for ( Row* row : _rows ) channelSum += row->computeChannelHeight();
Box ab = _cell->getAbutmentBox();
_cell->setAbutmentBox( ab.inflate( 0, 0, 0, ypitch*(channelSum - _rows.size() + 1) ) );
_katana->_resizeMatrix();
channelSum = 0;
for ( size_t irow=0 ; irow < _rows.size() ; ++irow ) {
_rows[irow]->setY( ab.getYMin() + sliceHeight*irow + ypitch*channelSum );
channelSum += _rows[irow]->getChannelHeight();
ostringstream rowName;
rowName << " - [" << setw(2) << irow << "]";
rowName << " @" << DbU::getValueString(_rows[irow]->getY() + sliceHeight);
ostringstream rowTracks;
rowTracks << _rows[irow]->getChannelHeight() << " tracks.";
cmess2 << Dots::asString( rowName.str(), rowTracks.str() ) << endl;
}
_katana->_updateGContacts();
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
_katana->invalidateRoutingPads();
if (not sessionReUse) Session::close();
}
string Block::_getString () const
{ return "<Block rows:" + getString(_rows.size()) + ">"; }
Record* Block::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add( getSlot( "_katana", _katana ) );
record->add( getSlot( "_rows" , &_rows ) );
return record;
}
} // Katana namespace.