coriolis/katana/src/Block.cpp

363 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 {
southWest = southWest->vcut( irp.second->getX() );
southWest->setType( Anabatic::Flags::StdCellRow );
gcellSplitted = true;
break;
}
}
rps .clear();
nets.clear();
if (not gcellSplitted) {
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();
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 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;
}
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
_katana->_updateGContacts( Flags::Vertical );
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.