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()".
This commit is contained in:
Jean-Paul Chaput 2017-08-18 23:56:23 +02:00
parent 809a91c9c1
commit eae5d6bf83
35 changed files with 1854 additions and 813 deletions

View File

@ -407,9 +407,7 @@ namespace Anabatic {
void AnabaticEngine::updateMatrix()
{
_matrix.setCell( getCell(), Session::getSliceHeight() );
for ( GCell* gcell : _gcells ){
gcell->_revalidate();
}
for ( GCell* gcell : _gcells ) _updateLookup( gcell );
}
size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets )
@ -939,6 +937,18 @@ namespace Anabatic {
}
void AnabaticEngine::invalidateRoutingPads ()
{
// This a flaw in the Hurricane Session update mechanism
// and needs to be fixed in the future.
for ( Net* net : getCell()->getNets() ) {
for ( RoutingPad* rp : net->getRoutingPads() ) {
rp->invalidate( false );
}
}
}
void AnabaticEngine::updateDensity ()
{ for ( GCell* gcell : _gcells ) gcell->updateDensity(); }

View File

@ -157,6 +157,13 @@ namespace Anabatic {
<< DbU::getValueString(getAutoSource()->getCBYMax()) << "]"
<< endl;
constraintMin = std::max ( constraintMin, getAutoTarget()->getCBYMin() );
constraintMax = std::min ( constraintMax, getAutoTarget()->getCBYMax() );
cdebug_log(144,0) << "Merge with target constraints: ["
<< DbU::getValueString(getAutoTarget()->getCBYMin()) << ":"
<< DbU::getValueString(getAutoTarget()->getCBYMax()) << "]"
<< endl;
constraintMin = std::max ( constraintMin, getUserConstraints().getVMin() );
constraintMax = std::min ( constraintMax, getUserConstraints().getVMax() );
cdebug_log(144,0) << "Merge with user constraints: ["
@ -177,13 +184,14 @@ namespace Anabatic {
{ return Flags::Horizontal; }
size_t AutoHorizontal::getGCells ( vector<GCell*>& gcells ) const
bool AutoHorizontal::getGCells ( vector<GCell*>& gcells ) const
{
vector<GCell*>().swap( gcells );
DbU::Unit yprobe = getY();
GCell* gcell = getAutoSource()->getGCell();
GCell* end = getAutoTarget()->getGCell();
bool success = true;
DbU::Unit yprobe = getY();
GCell* gcell = getAutoSource()->getGCell();
GCell* end = getAutoTarget()->getGCell();
cdebug_log(144,0) << "yprobe: " << DbU::getValueString(yprobe) << endl;
@ -195,6 +203,7 @@ namespace Anabatic {
while ( gcell != end ) {
gcell = gcell->getEast( yprobe );
if (not gcell) {
success = false;
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
@ -208,7 +217,7 @@ namespace Anabatic {
gcells.push_back( gcell );
}
return gcells.size();
return success;
}

View File

@ -615,6 +615,7 @@ namespace Anabatic {
return getWidth() / 2;
}
DbU::Unit AutoSegment::getSlack () const
{
DbU::Unit constraintMin;
@ -1862,13 +1863,13 @@ namespace Anabatic {
if (getSpanU().contains(interval.getVMax())) rightDogleg++;
if (not isNotAligned()) {
forEach ( AutoSegment*, isegment, getAligneds() ) {
if (isegment->getSpanU().contains(interval.getVMin())) {
if (isegment->isFixed()) return false;
for ( AutoSegment* segment : getAligneds() ) {
if (segment->getSpanU().contains(interval.getVMin())) {
if (segment->isFixed()) return false;
leftDogleg++;
}
if (isegment->getSpanU().contains(interval.getVMax())) {
if (isegment->isFixed()) return 0;
if (segment->getSpanU().contains(interval.getVMax())) {
if (segment->isFixed()) return 0;
rightDogleg++;
}
}
@ -1879,7 +1880,7 @@ namespace Anabatic {
cdebug_log(149,0) << "leftCount:" << leftDogleg << " rightCount:" << rightDogleg << endl;
return 0;
return Flags::NoFlags;
}
@ -2151,15 +2152,15 @@ namespace Anabatic {
, Segment* hurricaneSegment
)
{
const Layer* horizontalLayer = Session::getRoutingLayer( 1 );
DbU::Unit horizontalWidth = Session::getWireWidth ( 1 );
const Layer* verticalLayer = Session::getRoutingLayer( 2 );
DbU::Unit verticalWidth = Session::getWireWidth ( 2 );
const Layer* horizontalLayer = Session::getDHorizontalLayer();
DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
const Layer* verticalLayer = Session::getDVerticalLayer();
DbU::Unit verticalWidth = Session::getDVerticalWidth();
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
if (wPitch > 1) {
horizontalWidth += (wPitch-1) * Session::getPitch(1);
verticalWidth += (wPitch-1) * Session::getPitch(2);
horizontalWidth += (wPitch-1) * Session::getDHorizontalPitch();
verticalWidth += (wPitch-1) * Session::getDVerticalPitch ();
}
cdebug_log(149,0) << "wPitch:" << wPitch << " hW:" << DbU::getValueString(horizontalWidth) << endl;
@ -2197,6 +2198,8 @@ namespace Anabatic {
reference = target;
}
if (target->isTerminal()) reference = target;
Contact* contact = dynamic_cast<Contact*>( hurricaneSegment->getSource() );
AutoContact* autoContact = Session::lookup( contact );
if (contact == NULL) {
@ -2287,10 +2290,10 @@ namespace Anabatic {
// depth=1 is horizontal | METAL2
// depth=2 is vertical | METAL3
// Should be based on gauge informations.
const Layer* hLayer = Session::getRoutingLayer( 1 );
DbU::Unit hWidth = Session::getWireWidth ( 1 );
const Layer* vLayer = Session::getRoutingLayer( 2 );
DbU::Unit vWidth = Session::getWireWidth ( 2 );
const Layer* hLayer = Session::getDHorizontalLayer();
DbU::Unit hWidth = Session::getDHorizontalWidth();
const Layer* vLayer = Session::getDVerticalLayer();
DbU::Unit vWidth = Session::getDVerticalWidth();
const Layer* horizontalLayer = hLayer;
DbU::Unit horizontalWidth = hWidth;
@ -2299,8 +2302,8 @@ namespace Anabatic {
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
if (wPitch > 1) {
horizontalWidth = (wPitch-1) * Session::getPitch(1) + hWidth;
verticalWidth = (wPitch-1) * Session::getPitch(2) + vWidth;
horizontalWidth = (wPitch-1) * Session::getDHorizontalPitch() + hWidth;
verticalWidth = (wPitch-1) * Session::getDVerticalPitch () + vWidth;
}
if (depth != RoutingGauge::nlayerdepth) {

View File

@ -152,6 +152,13 @@ namespace Anabatic {
<< DbU::getValueString(getAutoSource()->getCBXMax()) << "]"
<< endl;
constraintMin = std::max ( constraintMin, getAutoTarget()->getCBXMin() );
constraintMax = std::min ( constraintMax, getAutoTarget()->getCBXMax() );
cdebug_log(149,0) << "Merge with target constraints: ["
<< DbU::getValueString(getAutoTarget()->getCBXMin()) << ":"
<< DbU::getValueString(getAutoTarget()->getCBXMax()) << "]"
<< endl;
constraintMin = max ( constraintMin, getUserConstraints().getVMin() );
constraintMax = min ( constraintMax, getUserConstraints().getVMax() );
@ -173,13 +180,14 @@ namespace Anabatic {
{ return Flags::Vertical; }
size_t AutoVertical::getGCells ( vector<GCell*>& gcells ) const
bool AutoVertical::getGCells ( vector<GCell*>& gcells ) const
{
vector<GCell*>().swap( gcells );
DbU::Unit xprobe = getX();
GCell* gcell = getAutoSource()->getGCell();
GCell* end = getAutoTarget()->getGCell();
bool success = true;
DbU::Unit xprobe = getX();
GCell* gcell = getAutoSource()->getGCell();
GCell* end = getAutoTarget()->getGCell();
cdebug_log(144,0) << "xprobe: " << DbU::getValueString(xprobe) << endl;
@ -192,6 +200,7 @@ namespace Anabatic {
gcell = gcell->getNorth( xprobe );
if (not gcell) {
success = false;
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
@ -205,7 +214,7 @@ namespace Anabatic {
gcells.push_back( gcell );
}
return gcells.size();
return success;
}

View File

@ -59,7 +59,12 @@ namespace Anabatic {
Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg )
: _cg (NULL)
: _gdepthv (ndepth)
, _gdepthh (ndepth)
, _ddepthv (ndepth)
, _ddepthh (ndepth)
, _ddepthc (ndepth)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
@ -75,14 +80,18 @@ namespace Anabatic {
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
if (rg == NULL) {
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
if (rg == NULL)
throw Error( "Anabatic::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
}
_cg = cg->getClone();
_rg = rg->getClone();
if (Cfg::hasParameter("anabatic.topRoutingLayer")) {
_setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() );
} else
_allowedDepth = rg->getDepth()-1;
_allowedDepth = rg->getDepth()-1;
if (Cfg::hasParameter("katabatic.topRoutingLayer"))
_setTopRoutingLayer( Cfg::getParamString("katabatic.topRoutingLayer")->asString() );
_gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh");
_gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv");
@ -94,8 +103,24 @@ namespace Anabatic {
//DbU::Unit sliceHeight = _cg->getSliceHeight();
_ddepthc = (_allowedDepth > 1) ? 1 : 0;
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) {
if ( (_gdepthh == ndepth)
and layerGauges[depth]->isHorizontal()
and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) {
_gdepthh = depth;
_ddepthh = depth;
}
if ( (_gdepthv == ndepth)
and layerGauges[depth]->isVertical()
and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) {
_gdepthv = depth;
_ddepthv = depth;
}
const RegularLayer* regularLayer = dynamic_cast<const RegularLayer*>( layerGauges[depth]->getLayer() );
if (regularLayer)
_extensionCaps.push_back( regularLayer->getExtentionCap() );
@ -115,6 +140,11 @@ namespace Anabatic {
: _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv)
, _gcontact (other._gcontact)
, _gdepthv (other._gdepthv)
, _gdepthh (other._gdepthh)
, _ddepthv (other._ddepthv)
, _ddepthh (other._ddepthh)
, _ddepthc (other._ddepthc)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps (other._extensionCaps)
@ -288,7 +318,7 @@ namespace Anabatic {
}
}
cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n"
" The routing gauge <%s> has no layer named <%s>"
" The routing gauge <%s> has no layer named <%s>"
, getString(_rg->getName()).c_str()
, getString(name).c_str() ) << endl;
}
@ -360,6 +390,8 @@ namespace Anabatic {
Record* Configuration::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add ( getSlot( "_gdepthh" , _gdepthh ) );
record->add ( getSlot( "_gdepthv" , _gdepthv ) );
record->add ( getSlot( "_rg" , _rg ) );
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
record->add ( getSlot( "_gmetalv" , _gmetalv ) );

View File

@ -39,6 +39,9 @@ namespace Anabatic {
const BaseFlags Flags::MatrixGCell = (1L << 9);
const BaseFlags Flags::IoPadGCell = (1L << 10);
const BaseFlags Flags::Saturated = (1L << 11);
const BaseFlags Flags::StdCellRow = (1L << 12);
const BaseFlags Flags::ChannelRow = (1L << 13);
const BaseFlags Flags::IllimitedCapacity = (1L << 5);
// Flags for Anabatic objects states only.
const BaseFlags Flags::DemoMode = (1L << 5);
const BaseFlags Flags::WarnOnGCellOverload = (1L << 6);
@ -56,7 +59,19 @@ namespace Anabatic {
const BaseFlags Flags::EndsMask = Source|Target;
const BaseFlags Flags::DirectionMask = Horizontal|Vertical;
const BaseFlags Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
const BaseFlags Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
const BaseFlags Flags::GCellTypeMask = DeviceGCell
| HChannelGCell
| VChannelGCell
| StrutGCell
| MatrixGCell
| IoPadGCell
| StdCellRow
| ChannelRow;
const BaseFlags Flags::RowGCellMask = StdCellRow|ChannelRow;
const BaseFlags Flags::AnalogGCellMask = DeviceGCell
| HChannelGCell
| VChannelGCell
| StrutGCell;
// Flags for functions arguments only.
const BaseFlags Flags::Create = (1L << 5);
const BaseFlags Flags::WithPerpands = (1L << 6);
@ -146,20 +161,22 @@ namespace Anabatic {
string Flags::_getString () const
{
string s = "";
s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-';
s += (_flags & (uint64_t)Vertical ) ? 'v' : '-';
s += (_flags & (uint64_t)Source ) ? 'S' : '-';
s += (_flags & (uint64_t)Target ) ? 'T' : '-';
s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-';
s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-';
s += (_flags & (uint64_t)Vertical ) ? 'v' : '-';
s += (_flags & (uint64_t)Source ) ? 'S' : '-';
s += (_flags & (uint64_t)Target ) ? 'T' : '-';
s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-';
s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)StrutGCell ) ? 's' : '-';
s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-';
s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-';
s += (_flags & (uint64_t)StdCellRow ) ? 'S' : '-';
s += (_flags & (uint64_t)ChannelRow ) ? 'C' : '-';
s += ",";
s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-';
s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-';
s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-';
s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-';
s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-';
s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-';
s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-';
s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-';
return s;
}

View File

@ -276,7 +276,10 @@ namespace Anabatic {
) return true;
else {
if ((v2->getGCell()->isStrut())){
if (e->isMaxCapacity(net)) return true;
if (e->isMaxCapacity(net)) {
cdebug_log(112,0) << "Overcapacity:" << e << endl;
return true;
}
else return false;
} else return false;
}
@ -292,7 +295,7 @@ namespace Anabatic {
return Point(0,0);
}
if (vnext->getGCell()->isMatrix()) {
if (not vnext->getGCell()->isAnalog()) {
cdebug_tabw(112,-1);
return Point(vnext->getGCell()->getXCenter(), vnext->getGCell()->getYCenter());
}
@ -1283,7 +1286,7 @@ namespace Anabatic {
Vertex* seed = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
GCell* gseed = seed->getGCell();
if (!gseed->isMatrix()) _setSourcesGRAData( seed, rp ); // ANALOG
if (gseed->isAnalog()) _setSourcesGRAData( seed, rp ); // ANALOG
if (seed->getConnexId() < 0) {
VertexSet connecteds;
@ -1311,7 +1314,7 @@ namespace Anabatic {
}
_searchArea.inflate( _searchAreaHalo );
cdebug_log(112,0) << "Search halo: " << _searchAreaHalo << endl;
cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl;
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
setAxisTargets();
@ -1547,14 +1550,14 @@ namespace Anabatic {
continue;
}
if (_checkFrom2(edge, current)) { // ANALOG
if ((gcurrent->isAnalog()) and _checkFrom2(edge, current)) {
cdebug_log(111,0) << "| Reject: _checkFrom2()" << endl;
continue;
}
GCell* gneighbor = edge->getOpposite(current->getGCell());
Vertex* vneighbor = gneighbor->getObserver<Vertex>( GCell::Observable::Vertex );
if (not gneighbor->isMatrix()) vneighbor->createAData();
if (gneighbor->isAnalog()) vneighbor->createAData();
cdebug_log(111,0) << "+ Neighbor:" << vneighbor << endl;
@ -1573,7 +1576,7 @@ namespace Anabatic {
cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl;
//current->getIntervFrom().print();
}
if (current->getFrom2()) {
if (gcurrent->isAnalog() and current->getFrom2()) {
cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl;
current->getIntervFrom2().print();
}
@ -1584,14 +1587,17 @@ namespace Anabatic {
///////////////////////////////////////////////////////////////////////////////////
DbU::Unit distance = _distanceCb( current, vneighbor, edge );
cdebug_log(111,0) << "distance:" << Vertex::getValueString(distance) << endl;
bool isDistance2shorter = false;
if (gcurrent->isAnalog() and gneighbor->isAnalog())
_isDistance2Shorter ( distance, current, vneighbor, edge );
bool isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge ); // ANALOG
if ( (distance == vneighbor->getDistance())
and (not gcurrent->isMatrix() )
and (not gneighbor->isMatrix())
and (vneighbor->getFrom2() == NULL)
) {
and gcurrent->isAnalog()
and gneighbor->isAnalog()
and (vneighbor->getFrom2() == NULL) ) {
_pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG
} else
if ( (distance < vneighbor->getDistance()) and (distance != Vertex::unreachable) ) {
@ -1607,17 +1613,21 @@ namespace Anabatic {
}
}
cdebug_log(111,0) << "Vertex reached through a shorter path" << endl;
_updateGRAData( vneighbor, isDistance2shorter, current ); // ANALOG
if (gcurrent->isAnalog() and gneighbor->isAnalog())
_updateGRAData( vneighbor, isDistance2shorter, current );
vneighbor->setBranchId( current->getBranchId() );
vneighbor->setDistance( distance );
cdebug_log(111,0) << "setFrom1: " << vneighbor << endl;
vneighbor->setFrom ( edge );
vneighbor->setFrom2( NULL );
if (gneighbor->isAnalog()) vneighbor->setFrom2( NULL );
_queue.push( vneighbor );
cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl;
} else {
cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path" << endl;
cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path or unreachable:"
<< boolalpha << (distance == Vertex::unreachable)
<< endl;
}
cdebug_tabw(111,-1);
@ -1659,39 +1669,35 @@ namespace Anabatic {
bool isfirst = true;
bool useFrom2 = false;
if (!current->getGCell()->isMatrix()){
_initiateUpdateIntervals ( current ); // ANALOG
if (current->getGCell()->isAnalog()) {
_initiateUpdateIntervals( current );
} else {
current = current->getPredecessor();
isfirst = false;
}
cdebug_log(112,0) << "[Start WHILE]" << endl;
Edge* from = NULL;
while ( current ) {
cdebug_log(112,0) << endl;
cdebug_log(112,0) << "| " << current << " | " << endl;
if (current->getFrom()) cdebug_log(112,0) << " | From :" << current->getFrom()->getOpposite(current->getGCell()) << " | " << endl;
if (current->getFrom2()) cdebug_log(112,0) << " | From2:" << current->getFrom2()->getOpposite(current->getGCell()) << " | " << endl;
cdebug_log(112,0) << "+ " << current << endl;
if (current->getFrom()) cdebug_log(112,0) << "| From:" << current->getFrom()->getOpposite(current->getGCell()) << endl;
if (!current->getGCell()->isMatrix()){
//////////////////////////////////////////////////////////////////////////////////////////// ANALOG
if (_updateIntervals ( isfirst, current, useFrom2, branchId, from )) break;
if (current->getGCell()->isAnalog()) {
if (current->getFrom2()) cdebug_log(112,0) << "| From2:" << current->getFrom2()->getOpposite(current->getGCell()) << endl;
if (_updateIntervals( isfirst, current, useFrom2, branchId, from )) break;
Vertex* next = NULL;
next = current->getPredecessor();
if( current->isFromFrom2()) {
cdebug_log(112,0) << "ISFROMFROM2: " << current << endl;
if (current->isFromFrom2()) {
cdebug_log(112,0) << "| isFromFrom2:true (" << current << ")" << endl;
useFrom2 = true;
current->unsetFlags(Vertex::UseFromFrom2);
current->unsetFlags( Vertex::UseFromFrom2 );
} else {
cdebug_log(112,0) << "ISNOT FROMFROM2" << endl;
cdebug_log(112,0) << "| isFromFrom2:false" << endl;
useFrom2 = false;
}
cdebug_log(112,0) << "next: " << next << endl;
cdebug_log(112,0) << "| Next: " << next << endl;
current = next;
////////////////////////////////////////////////////////////////////////////////////////////
} else {
current->incDegree();
if (current->getConnexId() == _connectedsId) break;
@ -1720,8 +1726,8 @@ namespace Anabatic {
NetRoutingState* state = NetRoutingExtension::get( _net );
for ( Vertex* startVertex : _sources ) {
if (not startVertex->getFrom()) continue;
if ( not startVertex->hasGContact(_net)
and not startVertex->getRpCount()
and (startVertex->getDegree() < 3)
@ -1729,11 +1735,12 @@ namespace Anabatic {
Vertex* source = startVertex;
while ( source ) {
source->resetIntervals(); // ANALOG
cdebug_log(112,0) << "* " << source << endl;
Edge* from = source->getFrom();
bool isAnalog = source->getGCell()->isAnalog();
if (isAnalog) source->resetIntervals();
Edge* from = source->getFrom();
vector<Edge*> aligneds;
aligneds.push_back( from );
@ -1751,13 +1758,21 @@ namespace Anabatic {
while ( true ) {
from = target->getFrom();
if ( not from
or not (target->getGCell()->isMatrix())
or (target->getGCell()->isAnalog())
or (target->hasGContact(_net))
or (target->getRpCount())
or (target->getDegree() > 2)
or (aligneds.back()->isHorizontal() xor from->isHorizontal())
or not constraint.intersect(from->getSide())) break;
// U-turn detection. All edges must have the same *spin*.
if ( (aligneds[0]->getSource() == source->getGCell())
xor (from ->getSource() == target->getGCell()) ) break;
// Always break vertical in channel (2M routing).
if (target->getGCell()->isChannelRow() and aligneds.back()->isVertical())
break;
aligneds.push_back( from );
constraint.merge( from->getSide() );
@ -1772,17 +1787,20 @@ namespace Anabatic {
Contact* targetContact = target->hasGContact( _net );
Segment* segment = NULL;
if (not targetContact) {
if (target->getFrom()) targetContact = target->getGContact( _net );
else targetContact = target->breakGoThrough( _net );
}
cdebug_log(112,0) << "| aligneds.front():" << aligneds.front()
<< " isHorizontal():" << aligneds.front()->isHorizontal() << endl;
if (aligneds.front()->isHorizontal()) {
if (sourceContact->getX() > targetContact->getX())
std::swap( sourceContact, targetContact );
DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); //DbU::fromLambda(2.0);
//DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); //DbU::fromLambda(2.0);
DbU::Unit width = Session::getGHorizontalPitch(); //DbU::fromLambda(2.0);
if (state) width *= state->getWPitch();
segment = Horizontal::create( sourceContact
@ -1792,14 +1810,15 @@ namespace Anabatic {
, width
);
for ( Edge* through : aligneds ) through->add( segment );
if (state){
if (state) {
if (state->isSymmetric()) _createSelfSymSeg ( segment );
}
} else {
if (sourceContact->getY() > targetContact->getY())
std::swap( sourceContact, targetContact );
DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3")); //DbU::fromLambda(2.0);
//DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3")); //DbU::fromLambda(2.0);
DbU::Unit width = Session::getGVerticalPitch(); //DbU::fromLambda(2.0);
if (state) width *= state->getWPitch();
segment = Vertical::create( sourceContact
@ -1809,16 +1828,17 @@ namespace Anabatic {
, width
);
for ( Edge* through : aligneds ) through->add( segment );
if (state){
if (state) {
if (state->isSymmetric()) _createSelfSymSeg ( segment );
}
}
cdebug_log(112,0) << "|| " << segment << endl;
//cdebug_log(112,0) << "| " << "break (turn, branch or terminal)." << endl;
Vertex* stc = source;
cdebug_log(112,0) << "| break (U-turn, turn, branch or terminal)." << endl;
cdebug_log(112,0) << "| " << segment << endl;
Vertex* prevSource = source;
source = (target->getFrom()) ? target : NULL;
stc->clearFrom2();
if (isAnalog) prevSource->clearFrom2();
}
}

View File

@ -184,11 +184,13 @@ namespace Anabatic {
_realOccupancy = occupancy;
}
void Edge::incRealOccupancy2 ( int value )
{
_realOccupancy += value;
}
Segment* Edge::getSegment ( const Net* owner ) const
{
for ( Segment* segment : _segments ) {
@ -204,8 +206,8 @@ namespace Anabatic {
Horizontal* h = dynamic_cast<Horizontal*>(segment);
Vertical* v = dynamic_cast<Vertical*>(segment);
DbU::Unit pitch = 0;
if (h) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"));
if (v) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3"));
if (h) pitch = Session::getGHorizontalPitch();
if (v) pitch = Session::getGVerticalPitch();
incRealOccupancy( segment->getWidth()/pitch ); // Need to take the wire width into account.
}
@ -259,7 +261,7 @@ namespace Anabatic {
if (source == _target)
throw Error("Edge::_setSource(): Source & target are the same (%s).", getString(source).c_str() );
_invalidate();
invalidate( false );
_source=source;
}
@ -269,26 +271,40 @@ namespace Anabatic {
if (_source == target)
throw Error("Edge::_setTarget(): Source & target are the same (%s).", getString(target).c_str() );
_invalidate();
invalidate( false );
_target=target;
}
void Edge::_invalidate ()
void Edge::invalidate ( bool )
{
cdebug_log(110,1) << "Edge::invalidate() " << this << endl;
_flags |= Flags::Invalidated;
Super::invalidate( false );
cdebug_tabw(110,-1);
}
void Edge::_revalidate ()
void Edge::materialize ()
{
cdebug_log(110,1) << "Edge::materialize() " << this << endl;
Interval side = getSide();
_axis = side.getCenter();
_capacity = getAnabatic()->getCapacity( side, _flags );
_axis = side.getCenter();
if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) _capacity = 0;
else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) _capacity = 100;
else
_capacity = getAnabatic()->getCapacity( side, _flags );
_flags.reset( Flags::Invalidated );
cdebug_log(110,0) << "Edge::_revalidate() " << this << endl;
cdebug_log(110,0) << "Edge::materialize() " << this << endl;
Super::materialize();
cdebug_tabw(110,-1);
}
@ -301,28 +317,30 @@ namespace Anabatic {
static DbU::Unit halfThickness = getAnabatic()->getConfiguration()->getEdgeWidth () / 2;
static DbU::Unit halfLength = getAnabatic()->getConfiguration()->getEdgeLength() / 2;
if (_flags.isset(Flags::Horizontal))
return Box( _target->getXMin() - halfLength, _axis - halfThickness
, _target->getXMin() + halfLength, _axis + halfThickness
);
Box bb;
return Box( _axis - halfThickness, _target->getYMin() - halfLength
if (_flags.isset(Flags::Horizontal))
bb = Box( _target->getXMin() - halfLength, _axis - halfThickness
, _target->getXMin() + halfLength, _axis + halfThickness
);
else
bb = Box( _axis - halfThickness, _target->getYMin() - halfLength
, _axis + halfThickness, _target->getYMin() + halfLength
);
return bb;
}
bool Edge::isMaxCapacity ( Net* net ) const
{
if (net){
if (net) {
cdebug_log(112,0) << "_capacity:" << _capacity << endl;
Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net );
//cerr << "bool Edge::isMaxCapacity ( Net* net ) const: " << net << endl;
//cerr << "WPitch: " << state->getWPitch() << endl;
return ( (_realOccupancy +state->getWPitch()) > _capacity ) ? true : false;
} else {
return ( _realOccupancy >= _capacity ) ? true : false;
return ((_realOccupancy + state->getWPitch()) > _capacity) ? true : false;
}
return (_realOccupancy >= _capacity) ? true : false;
}

View File

@ -63,10 +63,10 @@ namespace Anabatic {
{
cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl;
cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size()
<< " North:" << _gcell->getNorthEdges().size()
<< " West:" << _gcell->getWestEdges().size()
<< " South:" << _gcell->getSouthEdges().size() << endl;
cdebug_log(110,0) << " East:" << _gcell->getEastEdges ().size()
<< " North:" << _gcell->getNorthEdges().size()
<< " West:" << _gcell->getWestEdges ().size()
<< " South:" << _gcell->getSouthEdges().size() << endl;
cdebug_log(110,0) << this << endl;
++_iedge;

View File

@ -331,13 +331,13 @@ namespace Anabatic {
if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." );
if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." );
anabatic->openSession();
bool reUseSession = Session::isOpen();
if (not reUseSession) anabatic->openSession();
GCell* gcell = new GCell ( anabatic
, anabatic->getCell()->getAbutmentBox().getXMin()
, anabatic->getCell()->getAbutmentBox().getYMin() );
gcell->_postCreate();
gcell->_revalidate();
Session::close();
if (not reUseSession) Session::close();
return gcell;
}
@ -661,9 +661,6 @@ namespace Anabatic {
_moveEdges( chunk, iedge+1, Flags::NorthSide );
}
_revalidate();
chunk->_revalidate();
cdebug_tabw(110,-1);
return chunk;
@ -713,9 +710,6 @@ namespace Anabatic {
_moveEdges( chunk, iedge+1, Flags::EastSide );
}
_revalidate();
chunk->_revalidate();
cdebug_tabw(110,-1);
return chunk;
@ -787,21 +781,33 @@ namespace Anabatic {
}
void GCell::_revalidate ()
void GCell::invalidate ( bool propagateFlag )
{
cdebug_log(110,1) << "GCell::revalidate() " << this << endl;
cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "GCell::invalidate() " << this << endl;
Super::invalidate( propagateFlag );
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 ()
{
cdebug_log(110,1) << "GCell::materialize() " << this << endl;
if (_xmin > getXMax()+1)
cerr << Error( "GCell::_revalidate(): %s, X Min is greater than Max.", getString(this).c_str() );
cerr << Error( "GCell::materialize(): %s, X Min is greater than Max.", getString(this).c_str() );
if (_ymin > getYMax()+1)
cerr << Error( "GCell::_revalidate(): %s, Y Min is greater than Max.", getString(this).c_str() );
cerr << Error( "GCell::materialize(): %s, Y Min is greater than Max.", getString(this).c_str() );
_anabatic->_updateLookup( this );
//_anabatic->getMatrix()->show();
Super::materialize();
cdebug_tabw(110,-1);
}
@ -898,36 +904,31 @@ namespace Anabatic {
}
void GCell::setXY ( DbU::Unit x, DbU::Unit y )
void GCell::setSouthWestCorner ( DbU::Unit x, DbU::Unit y )
{
UpdateSession::open();
_xmin = x;
_ymin = y;
UpdateSession::close();
}
DbU::Unit dx = x - _xmin;
DbU::Unit dy = y - _ymin;
void GCell::updateContactsPosition ()
{
UpdateSession::open();
DbU::Unit xc = (getXMax() + getXMin())/2;
DbU::Unit yc = (getYMax() + getYMin())/2;
for (vector<Contact*>::iterator it = _gcontacts.begin(); it != _gcontacts.end(); it++){
for ( Component* c : (*it)->getSlaveComponents() ){
Horizontal* h = dynamic_cast<Horizontal*>(c);
Vertical* v = dynamic_cast<Vertical*> (c);
if (h){
//if (h->getY() == (*it)->getY()) h->setY(yc);
h->setY(yc);
} else if (v) {
//if (v->getX() == (*it)->getX()) v->setX(xc);
v->setX(xc);
for ( Contact* contact : _gcontacts ) {
Point position = contact->getPosition().translate( dx, dy );
for ( Component* component : contact->getSlaveComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal) {
horizontal->setY( position.getY() );
} else {
Vertical* vertical = dynamic_cast<Vertical*>( component );
vertical->setX( position.getX() );
}
}
(*it)->setX(xc);
(*it)->setY(yc);
if (not contact->getAnchor()) contact->setPosition( position );
}
UpdateSession::close();
_xmin = x;
_ymin = y;
invalidate( false );
}
@ -1522,6 +1523,19 @@ namespace Anabatic {
}
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;
@ -1702,6 +1716,7 @@ namespace Anabatic {
record->add( getSlot("_northEdges" , &_northEdges) );
record->add( DbU::getValueSlot("_xmin", &_xmin) );
record->add( DbU::getValueSlot("_ymin", &_ymin) );
record->add( getSlot ( "_gcontacts", &_gcontacts ) );
record->add( getSlot ( "_vsegments", &_vsegments ) );
record->add( getSlot ( "_hsegments", &_hsegments ) );
record->add( getSlot ( "_contacts" , &_contacts ) );

File diff suppressed because it is too large Load Diff

View File

@ -117,7 +117,7 @@ namespace Anabatic {
DbU::Unit dy = updateArea.getYMin() - _area.getYMin();
cdebug_log(110,0) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0))
<< " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl;
<< " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl;
cdebug_log(110,0) << "indexMin:" << indexMin << endl;
cdebug_log(110,0) << "indexMax:" << indexMax << endl;
cdebug_log(110,0) << "xspan: " << xspan << endl;
@ -138,6 +138,13 @@ namespace Anabatic {
}
void Matrix::resize ( Cell* cell, const vector<GCell*>& gcells )
{
setCell( cell, _side );
for ( GCell* gcell : gcells ) updateLookup( gcell );
}
void Matrix::show () const
{
cdebug_log(111,0) << this << endl;

View File

@ -230,6 +230,7 @@ namespace Anabatic {
inline Net* getBlockageNet () const;
inline const ChipTools& getChipTools () const;
inline const vector<NetData*>& getNetOrdering () const;
void invalidateRoutingPads ();
void updateDensity ();
size_t checkGCellDensities ();
inline void setGlobalThreshold ( DbU::Unit );
@ -277,6 +278,7 @@ namespace Anabatic {
inline void _add ( GCell* );
inline void _remove ( GCell* );
inline void _updateLookup ( GCell* );
inline void _resizeMatrix ();
inline bool _inDestroy () const;
// Inspector support.
virtual Record* _getRecord () const;
@ -346,6 +348,7 @@ namespace Anabatic {
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::_add ( GCell* gcell )

View File

@ -97,7 +97,7 @@ namespace Anabatic {
inline void setSizes ( DbU::Unit width, DbU::Unit height );
inline void setX ( DbU::Unit );
inline void setY ( DbU::Unit );
inline void setPosition ( DbU::Unit width, DbU::Unit height );
inline void setPosition ( DbU::Unit x, DbU::Unit y );
inline void setPosition ( const Point& );
inline void setDx ( DbU::Unit );
inline void setDy ( DbU::Unit );

View File

@ -49,7 +49,7 @@ namespace Anabatic {
virtual Interval getSourceConstraints ( Flags flags=0 ) const;
virtual Interval getTargetConstraints ( Flags flags=0 ) const;
virtual Flags getDirection () const;
virtual size_t getGCells ( vector<GCell*>& ) const;
virtual bool getGCells ( vector<GCell*>& ) const;
// Modifiers.
virtual void setDuSource ( DbU::Unit );
virtual void setDuTarget ( DbU::Unit );

View File

@ -226,7 +226,7 @@ namespace Anabatic {
inline uint64_t getFlags () const;
virtual Flags getDirection () const = 0;
inline GCell* getGCell () const;
virtual size_t getGCells ( vector<GCell*>& ) const = 0;
virtual bool getGCells ( vector<GCell*>& ) const = 0;
inline AutoContact* getAutoSource () const;
inline AutoContact* getAutoTarget () const;
AutoContact* getOppositeAnchor ( AutoContact* ) const;

View File

@ -49,7 +49,7 @@ namespace Anabatic {
virtual Interval getSourceConstraints ( Flags flags=0 ) const;
virtual Interval getTargetConstraints ( Flags flags=0 ) const;
virtual Flags getDirection () const;
virtual size_t getGCells ( vector<GCell*>& ) const;
virtual bool getGCells ( vector<GCell*>& ) const;
// Modifiers.
virtual void setDuSource ( DbU::Unit );
virtual void setDuTarget ( DbU::Unit );

View File

@ -53,6 +53,8 @@ namespace Anabatic {
// Class : "Anabatic::Configuration".
class Configuration {
public:
static const size_t ndepth = (size_t)-1;
public:
// Constructor & Destructor.
Configuration ( const CellGauge* cg=NULL, const RoutingGauge* rg=NULL );
@ -65,6 +67,22 @@ namespace Anabatic {
const Layer* getGContactLayer () const;
const Layer* getGHorizontalLayer () const;
const Layer* getGVerticalLayer () const;
inline size_t getGVerticalDepth () const;
inline DbU::Unit getGVerticalPitch () const;
inline size_t getGHorizontalDepth () const;
inline DbU::Unit getGHorizontalPitch () const;
inline size_t getDVerticalDepth () const;
inline const Layer* getDVerticalLayer () const;
inline DbU::Unit getDVerticalWidth () const;
inline DbU::Unit getDVerticalPitch () const;
inline size_t getDHorizontalDepth () const;
inline const Layer* getDHorizontalLayer () const;
inline DbU::Unit getDHorizontalWidth () const;
inline DbU::Unit getDHorizontalPitch () const;
inline size_t getDContactDepth () const;
inline const Layer* getDContactLayer () const;
inline DbU::Unit getDContactWidth () const;
inline DbU::Unit getDContactPitch () const;
size_t getDepth () const;
size_t getAllowedDepth () const;
size_t getLayerDepth ( const Layer* ) const;
@ -106,6 +124,11 @@ namespace Anabatic {
const Layer* _gmetalh;
const Layer* _gmetalv;
const Layer* _gcontact;
size_t _gdepthv;
size_t _gdepthh;
size_t _ddepthv;
size_t _ddepthh;
size_t _ddepthc;
CellGauge* _cg;
RoutingGauge* _rg;
std::vector<DbU::Unit> _extensionCaps;
@ -124,6 +147,24 @@ namespace Anabatic {
};
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); }
inline DbU::Unit Configuration::getGVerticalPitch () const { return getPitch( getGVerticalDepth (), Flags::NoFlags ); }
inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; }
inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); }
inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); }
inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); }
inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; }
inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); }
inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); }
inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); }
inline size_t Configuration::getDContactDepth () const { return _ddepthc; }
inline const Layer* Configuration::getDContactLayer () const { return getContactLayer( getDContactDepth() ); }
inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); }
inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); }
} // Anabatic namespace.

View File

@ -39,6 +39,10 @@ namespace Anabatic {
static const BaseFlags MatrixGCell ; // = (1 << 9);
static const BaseFlags IoPadGCell ; // = (1 << 10);
static const BaseFlags Saturated ; // = (1 << 11);
static const BaseFlags StdCellRow ; // = (1 << 12);
static const BaseFlags ChannelRow ; // = (1 << 13);
// Flags for Edge objects states only.
static const BaseFlags IllimitedCapacity ; // = (1 << 5);
// Flags for Anabatic objects states only.
static const BaseFlags DemoMode ; // = (1 << 5);
static const BaseFlags WarnOnGCellOverload ; // = (1 << 6);
@ -57,6 +61,8 @@ namespace Anabatic {
static const BaseFlags DirectionMask ; // = Horizontal|Vertical;
static const BaseFlags DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow;
static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell;
// Flags for functions arguments only.
static const BaseFlags Create ; // = (1 << 5);
static const BaseFlags WithPerpands ;

View File

@ -164,10 +164,13 @@ namespace Anabatic {
inline void GRAData::printInterv () const { _interv.print() ; }
inline void GRAData::printIntervfrom () const { _intervfrom.print(); }
// -------------------------------------------------------------------
// Class : "Anabatic::Vertex".
class Vertex {
public:
static inline std::string getValueString ( DbU::Unit );
public:
class CompareById {
public:
@ -191,6 +194,7 @@ namespace Anabatic {
static DbU::Unit unreachable;
public:
static void notify ( Vertex*, unsigned flags );
static inline Vertex* lookup ( GCell* );
public:
inline Vertex ( GCell* );
//inline Vertex ( size_t id );
@ -328,6 +332,7 @@ namespace Anabatic {
}
inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver<Vertex>(GCell::Observable::Vertex); }
inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); }
inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); }
inline unsigned int Vertex::getId () const { return _id; }
@ -387,6 +392,14 @@ namespace Anabatic {
inline void Vertex::setFlags ( uint32_t mask ) { _flags |= mask ; }
inline void Vertex::unsetFlags ( uint32_t mask ) { _flags &= ~mask; }
inline std::string Vertex::getValueString ( DbU::Unit distance )
{
if (distance == Vertex::unreachable) return "unreachable";
if (distance == Vertex::unreached ) return "unreached";
return DbU::getValueString( distance );
}
// -------------------------------------------------------------------
// Class : "Anabatic::PriorityQueue".

View File

@ -86,19 +86,18 @@ namespace Anabatic {
inline const Flags& flags () const;
inline Flags& flags ();
inline void revalidate () const;
bool isMaxCapacity ( Net* net = NULL ) const;
inline Flags& setFlags ( Flags mask );
void _setSource ( GCell* );
void _setTarget ( GCell* );
private:
void _invalidate ();
void _revalidate ();
public:
// ExtensionGo support.
inline const Name& staticGetName ();
virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const;
virtual void invalidate ( bool propagateFlag=true );
virtual void materialize ();
public:
// Inspector support.
virtual string _getTypeName () const;
@ -144,7 +143,7 @@ namespace Anabatic {
inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; }
inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; }
inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); }
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
} // Anabatic namespace.

View File

@ -139,8 +139,12 @@ namespace Anabatic {
inline bool isHChannel () const;
inline bool isVChannel () const;
inline bool isStrut () const;
inline bool isAnalog () const;
inline bool isMatrix () const;
inline bool isRow () const;
inline bool isIoPad () const;
inline bool isStdCellRow () const;
inline bool isChannelRow () const;
bool isWest ( GCell* ) const;
bool isEast ( GCell* ) const;
bool isNorth ( GCell* ) const;
@ -191,14 +195,14 @@ namespace Anabatic {
inline const vector<Contact*>& getGContacts () const;
Contact* breakGoThrough ( Net* net );
bool unrefContact ( Contact* );
void setXY ( DbU::Unit x, DbU::Unit y );
void updateContactsPosition ();
void setSouthWestCorner ( DbU::Unit x, DbU::Unit y );
void cleanupGlobal ();
inline DbU::Unit getWidth () const;
inline DbU::Unit getHeight () const;
// Detailed routing functions.
bool hasFreeTrack ( size_t depth, float reserve ) const;
inline size_t getDepth () const;
size_t getNetCount () const;
float getHCapacity () const;
float getVCapacity () const;
float getDensity ( Flags flags=Flags::NoFlags ) const;
@ -251,7 +255,6 @@ namespace Anabatic {
void _add ( Edge* edge, Flags side );
void _remove ( Edge* edge, Flags side=Flags::AllSides );
void _destroyEdges ();
void _revalidate ();
private:
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
public:
@ -265,6 +268,8 @@ namespace Anabatic {
virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const;
virtual void invalidate ( bool propagateFlag=true );
virtual void materialize ();
public:
// Inspector support.
virtual string _getTypeName () const;
@ -314,8 +319,12 @@ namespace Anabatic {
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }

View File

@ -94,7 +94,7 @@ namespace Anabatic {
inline GCell* getUnder ( Point ) const;
void setCell ( Cell*, DbU::Unit side );
void updateLookup ( GCell* );
void resize ( Box area, DbU::Unit side );
void resize ( Cell*, const vector<GCell*>& );
void show () const;
// Inspector support.
virtual Record* _getRecord () const;

View File

@ -71,6 +71,7 @@ namespace Anabatic {
class Session {
public:
// Static Methods.
static inline bool isOpen ();
static inline bool doDestroyBaseContact ();
static inline bool doDestroyBaseSegment ();
static inline bool doDestroyTool ();
@ -87,6 +88,22 @@ namespace Anabatic {
static inline CellGauge* getCellGauge ();
static inline DbU::Unit getSliceHeight ();
static inline DbU::Unit getSliceStep ();
static inline size_t getGVerticalDepth ();
static inline size_t getGHorizontalDepth ();
static inline DbU::Unit getGHorizontalPitch ();
static inline DbU::Unit getGVerticalPitch ();
static inline size_t getDVerticalDepth ();
static inline const Layer* getDVerticalLayer ();
static inline DbU::Unit getDVerticalWidth ();
static inline DbU::Unit getDVerticalPitch ();
static inline size_t getDHorizontalDepth ();
static inline const Layer* getDHorizontalLayer ();
static inline DbU::Unit getDHorizontalWidth ();
static inline DbU::Unit getDHorizontalPitch ();
static inline size_t getDContactDepth ();
static inline const Layer* getDContactLayer ();
static inline DbU::Unit getDContactWidth ();
static inline DbU::Unit getDContactPitch ();
static inline RoutingGauge* getRoutingGauge ();
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
static inline size_t getDepth ();
@ -178,6 +195,7 @@ namespace Anabatic {
// Inline Functions.
inline bool Session::isOpen () { return get() != NULL; }
inline Technology* Session::getTechnology () { return get("getTechnology()")->_technology; }
inline CellGauge* Session::getCellGauge () { return get("getCellGauge()")->_cellGauge; }
inline RoutingGauge* Session::getRoutingGauge () { return get("getRoutingGauge()")->_routingGauge; }
@ -206,6 +224,22 @@ namespace Anabatic {
inline DbU::Unit Session::getSliceHeight () { return getCellGauge()->getSliceHeight(); }
inline DbU::Unit Session::getSliceStep () { return getCellGauge()->getSliceStep(); }
inline size_t Session::getGVerticalDepth () { return getConfiguration()->getGVerticalDepth(); }
inline size_t Session::getGHorizontalDepth () { return getConfiguration()->getGHorizontalDepth(); }
inline DbU::Unit Session::getGVerticalPitch () { return getConfiguration()->getGVerticalPitch(); }
inline DbU::Unit Session::getGHorizontalPitch () { return getConfiguration()->getGHorizontalPitch(); }
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }

365
katana/src/Block.cpp Normal file
View File

@ -0,0 +1,365 @@
// -*- mode: C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2017-2017, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | 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 );
channel->getWestEdge()->setFlags( Flags::IllimitedCapacity );
}
}
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->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.

View File

@ -10,6 +10,7 @@
${PYTHON_INCLUDE_PATH}
)
set( includes katana/Constants.h
katana/Block.h
katana/TrackCost.h
katana/DataNegociate.h
katana/DataSymmetric.h
@ -43,6 +44,7 @@
set( mocIncludes katana/GraphicKatanaEngine.h )
set( cpps Constants.cpp
Configuration.cpp
Block.cpp
DataNegociate.cpp
DataSymmetric.cpp
TrackCost.cpp

View File

@ -5,7 +5,7 @@
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | 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 |
@ -14,8 +14,11 @@
// +-----------------------------------------------------------------+
#include "hurricane/Warning.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/Cell.h"
#include "anabatic/Dijkstra.h"
#include "katana/Block.h"
#include "katana/RoutingPlane.h"
#include "katana/KatanaEngine.h"
@ -29,6 +32,7 @@ namespace {
using std::left;
using std::right;
using Hurricane::DbU;
using Hurricane::DbU;
using Hurricane::Net;
using Anabatic::Edge;
using Anabatic::Vertex;
@ -54,10 +58,16 @@ namespace {
DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const
{
if (edge->getCapacity() <= 0) return Vertex::unreached;
if (edge->getCapacity() <= 0) return Vertex::unreachable;
if (source->getGCell()->isStdCellRow() and target->getGCell()->isStdCellRow())
return Vertex::unreachable;
float congestionCost = 1.0;
float congestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity();
float congestionCost = 1.0 + _h / (1.0 + std::exp(_k * (congestion - 1.0)));
if (not source->getGCell()->isChannelRow() or not target->getGCell()->isChannelRow())
congestionCost += _h / (1.0 + std::exp(_k * (congestion - 1.0)));
float viaCost = 0.0;
if ( source->getFrom()
@ -101,12 +111,30 @@ namespace {
namespace Katana {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Breakpoint;
using Hurricane::Timer;
using Hurricane::Occurrence;
using Hurricane::Transformation;
using Hurricane::Instance;
using Anabatic::EngineState;
using Anabatic::Dijkstra;
using Anabatic::NetData;
void KatanaEngine::createChannels ()
{
Cell* core = getCell();
if (isChip())
core = getChipTools().getCore()->getMasterCell();
Block* block = new Block( this, core );
block->createChannels();
_resizeMatrix();
}
void KatanaEngine::setupGlobalGraph ( uint32_t mode )
{
Cell* cell = getCell();
@ -116,6 +144,8 @@ namespace Katana {
startMeasures();
if (isChannelMode()) createChannels();
if (getGCells().size() == 1) {
cmess1 << " o Building regular grid..." << endl;
getSouthWestGCell()->doGrid();
@ -160,6 +190,9 @@ namespace Katana {
dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH()
, getConfiguration()->getEdgeCostK() ));
if (isChannelMode())
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*2 );
size_t iteration = 0;
size_t netCount = 0;
do {
@ -211,8 +244,19 @@ namespace Katana {
stopMeasures();
printMeasures( "Dijkstra" );
if (getBlock(0)) {
getBlock(0)->resizeChannels();
_resizeMatrix();
}
delete dijkstra;
Session::close();
if (isChannelMode()) {
setupRoutingPlanes();
setupPowerRails();
protectRoutingPads();
}
setState( EngineState::EngineGlobalLoaded );
}

View File

@ -37,6 +37,7 @@
#include "hurricane/viewer/Script.h"
#include "crlcore/Measures.h"
#include "anabatic/AutoContact.h"
#include "katana/Block.h"
#include "katana/DataNegociate.h"
#include "katana/RoutingPlane.h"
#include "katana/Session.h"
@ -175,9 +176,11 @@ namespace Katana {
: Super (cell)
, _viewer (NULL)
, _configuration (new Configuration())
, _blocks ()
, _routingPlanes ()
, _negociateWindow(NULL)
, _minimumWL (0.0)
, _mode (DigitalMode)
, _toolSuccess (false)
{ }
@ -213,14 +216,21 @@ namespace Katana {
{
cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl;
_mode |= DigitalMode;
Super::chipPrep();
setupChannelMode();
setupGlobalGraph( 0 );
setupRoutingPlanes();
if (not isChannelMode()) {
setupRoutingPlanes();
}
setupSpecialNets();
setupPreRouteds();
setupPowerRails();
protectRoutingPads();
if (not isChannelMode()) {
setupPowerRails();
protectRoutingPads();
}
_runKatanaInit();
cdebug_tabw(155,-1);
@ -231,6 +241,9 @@ namespace Katana {
{
cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl;
_mode &= ~DigitalMode;
_mode |= AnalogMode;
Super::chipPrep();
setupRoutingPlanes();
@ -240,6 +253,25 @@ namespace Katana {
}
void KatanaEngine::setupChannelMode ()
{
cdebug_log(155,1) << "KatanaEngine::setupChannelMode()" << endl;
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
size_t maxDepth = rg->getDepth();
if (maxDepth < 3) {
_mode |= ChannelMode;
if (maxDepth < 2) {
throw Error( "KatanaEngine::setupChannelMode(): Layer gauge %s must contains at least two layers (%u)."
, getString(rg->getName()).c_str(), maxDepth );
}
}
cdebug_tabw(155,-1);
}
void KatanaEngine::setupRoutingPlanes ()
{
cdebug_log(155,1) << "KatanaEngine::setupRoutingPlanes()" << endl;
@ -254,6 +286,7 @@ namespace Katana {
}
if (not sessionReUse) Session::close();
cdebug_tabw(155,-1);
}
@ -674,6 +707,9 @@ namespace Katana {
if (getState() < EngineState::EngineGutted) {
openSession();
for ( Block* block : _blocks ) delete block;
_blocks.clear();
size_t maxDepth = std::min( getConfiguration()->getRoutingGauge()->getDepth(), _routingPlanes.size() );
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
_routingPlanes[depth]->destroy();
@ -740,6 +776,7 @@ namespace Katana {
if (record) {
record->add( getSlot( "_configuration", _configuration ) );
record->add( getSlot( "_blocks" , &_blocks ) );
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
record->add( getSlot( "_symmetrics" , &_symmetrics ) );
}

View File

@ -491,7 +491,11 @@ namespace Katana {
cdebug_tabw(159,-1);
return false;
}
_segment->makeDogleg( dogLegGCell, dogleg, segment1 );
if (not _segment->makeDogleg( dogLegGCell, dogleg, segment1 )) {
cdebug_log(159,0) << "FIRST makeDogleg() call failed (BUG)." << endl;
cdebug_tabw(159,-1);
return false;
}
}
if (firstDoglegIsMin) {
@ -548,7 +552,11 @@ namespace Katana {
cdebug_tabw(159,-1);
return false;
}
segment1->makeDogleg( dogLegGCell, dogleg, segment2 );
if (not segment1->makeDogleg( dogLegGCell, dogleg, segment2 )) {
cdebug_log(159,0) << "SECOND makeDogleg() call failed (BUG)." << endl;
cdebug_tabw(159,-1);
return false;
}
}
if (maxExpanded) {

View File

@ -316,9 +316,15 @@ namespace Katana {
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) );
cdebug_log(159,0) << "* Nearest " << track << endl;
if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack();
if (track->getAxis() < uside.getVMin()) track = track->getNextTrack();
if (not track)
throw Error( "NegociateWindow::createTracksegment(): No track near axis of %s."
, getString(autoSegment).c_str() );
cdebug_log(159,0) << "* GCell U-side " << uside << endl;
cdebug_log(159,0) << "* " << plane << endl;
cdebug_log(159,0) << "* " << track << endl;
@ -529,51 +535,53 @@ namespace Katana {
//_pack( count, true );
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
cdebug_log(9000,0) << "Deter| Repair Stage" << endl;
cmess1 << " o Repair Stage." << endl;
if (not _katana->isChannelMode() ) {
cdebug_log(9000,0) << "Deter| Repair Stage" << endl;
cmess1 << " o Repair Stage." << endl;
cdebug_log(159,0) << "Loadind Repair queue." << endl;
RoutingEvent::setStage( RoutingEvent::Repair );
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
RoutingEvent* event = _eventHistory.getNth(i);
cdebug_log(159,0) << "Loadind Repair queue." << endl;
RoutingEvent::setStage( RoutingEvent::Repair );
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
RoutingEvent* event = _eventHistory.getNth(i);
if (not event->isCloned() and event->isUnimplemented()) {
event->reschedule( _eventQueue, 0 );
if (not event->isCloned() and event->isUnimplemented()) {
event->reschedule( _eventQueue, 0 );
}
}
}
_eventQueue.commit();
cmess2 << " <repair.queue:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">" << endl;
_eventQueue.commit();
cmess2 << " <repair.queue:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">" << endl;
count = 0;
//_eventQueue.prepareRepair();
while ( not _eventQueue.empty() and not isInterrupted() ) {
RoutingEvent* event = _eventQueue.pop();
count = 0;
//_eventQueue.prepareRepair();
while ( not _eventQueue.empty() and not isInterrupted() ) {
RoutingEvent* event = _eventQueue.pop();
if (tty::enabled()) {
cmess2 << " <repair.event:" << tty::bold << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << tty::reset
<< " remains:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">"
<< setfill(' ') << tty::reset << tty::cr;
cmess2.flush();
} else {
cmess2 << " <repair.event:" << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()
<< endl;
cmess2.flush();
if (tty::enabled()) {
cmess2 << " <repair.event:" << tty::bold << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << tty::reset
<< " remains:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">"
<< setfill(' ') << tty::reset << tty::cr;
cmess2.flush();
} else {
cmess2 << " <repair.event:" << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()
<< endl;
cmess2.flush();
}
event->process( _eventQueue, _eventHistory, _eventLoop );
count++;
if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true );
}
event->process( _eventQueue, _eventHistory, _eventLoop );
count++;
if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true );
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
}
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
size_t eventsCount = _eventHistory.size();
_eventHistory.clear();

View File

@ -1284,7 +1284,6 @@ namespace Katana {
void KatanaEngine::setupPowerRails ()
{
//DebugSession::open( 150, 160 );
openSession();
if (not getBlockageNet()) {
@ -1321,7 +1320,6 @@ namespace Katana {
}
Session::close();
//DebugSession::close();
}

View File

@ -711,6 +711,12 @@ namespace Katana {
return false;
}
if (doglegGCell->isStdCellRow()) {
cdebug_log(159,0) << "false: Cannot dogleg in a Standard Cell row." << endl;
cdebug_tabw(159,-1);
return false;
}
if (isFixed()) {
cdebug_log(159,0) << "false: Cannot dogleg a fixed segment." << endl;
cdebug_tabw(159,-1);
@ -743,7 +749,11 @@ namespace Katana {
}
vector<Anabatic::GCell*> gcells;
getGCells( gcells );
if (not getGCells(gcells)) {
cdebug_log(159,0) << "getGCell() has gone wrong." << endl;
cdebug_tabw(159,-1);
return false;
}
cdebug_log(159,0) << "Source: " << *gcells.begin () << endl;
cdebug_log(159,0) << "Target: " << *gcells.rbegin() << endl;

117
katana/src/katana/Block.h Normal file
View File

@ -0,0 +1,117 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2017-2017, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | 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++ Header : "./katana/Block.h" |
// +-----------------------------------------------------------------+
#ifndef KATANA_BLOCK_H
#define KATANA_BLOCK_H
#include <string>
#include <vector>
#include <map>
#include "hurricane/DbU.h"
#include "hurricane/Occurrence.h"
namespace Anabatic {
class GCell;
}
namespace Katana {
using std::string;
using std::vector;
using std::map;
using Hurricane::Name;
using Hurricane::DbU;
using Hurricane::Record;
using Hurricane::Cell;
using Hurricane::Occurrence;
using Anabatic::GCell;
class KatanaEngine;
class Block;
// -------------------------------------------------------------------
// Class : "Katana::Row".
class Row {
public:
inline Row ( Block*, DbU::Unit );
inline Block* getBlock () const;
inline Cell* getCell () const;
inline DbU::Unit getY () const;
inline GCell* getSouthWest () const;
inline uint32_t getChannelHeight () const;
void setY ( DbU::Unit y );
void add ( DbU::Unit x, Occurrence );
GCell* createChannel ( GCell* southWest, DbU::Unit channelHeight );
uint32_t computeChannelHeight ();
void routingPadsSubBreak ();
string _getString () const;
Record* _getRecord () const;
private:
Block* _block;
DbU::Unit _y;
map<DbU::Unit,Occurrence> _occurrences;
GCell* _southWest;
uint32_t _channelHeight;
};
inline Row::Row ( Block* block, DbU::Unit y )
: _block(block), _y(y), _occurrences(), _southWest(NULL), _channelHeight(1) { }
inline DbU::Unit Row::getY () const { return _y; }
inline Block* Row::getBlock () const { return _block; }
inline GCell* Row::getSouthWest () const { return _southWest; }
inline uint32_t Row::getChannelHeight () const { return _channelHeight; }
// -------------------------------------------------------------------
// Class : "Katana::Block".
class Block {
public:
Block ( KatanaEngine*, Cell* );
~Block ();
inline Cell* getCell () const;
Row* getAt ( DbU::Unit y ) const;
void add ( Occurrence );
void createChannels ();
void resizeChannels ();
string _getString () const;
Record* _getRecord () const;
private:
KatanaEngine* _katana;
Cell* _cell;
vector<Row*> _rows;
};
inline Cell* Block::getCell () const { return _cell; }
// Deferred Row functions.
inline Cell* Row::getCell () const { return _block->getCell(); }
} // Katana namespace.
INSPECTOR_P_SUPPORT(Katana::Row);
INSPECTOR_P_SUPPORT(Katana::Block);
#endif // KATANA_BLOCK_H

View File

@ -29,11 +29,6 @@ namespace Hurricane {
#include "crlcore/RoutingGauge.h"
#include "anabatic/AnabaticEngine.h"
namespace Knik {
class KnikEngine;
}
#include "katana/Constants.h"
#include "katana/TrackElement.h"
#include "katana/Configuration.h"
@ -50,6 +45,7 @@ namespace Katana {
using CRL::RoutingGauge;
using Anabatic::AnabaticEngine;
class Block;
class Track;
class RoutingPlane;
class NegociateWindow;
@ -59,6 +55,11 @@ namespace Katana {
// Class : "Katana::KatanaEngine".
class KatanaEngine : public AnabaticEngine {
public:
static const uint32_t DigitalMode = (1 << 0);
static const uint32_t AnalogMode = (1 << 1);
static const uint32_t MixedMode = (1 << 2);
static const uint32_t ChannelMode = (1 << 3);
public:
typedef AnabaticEngine Super;
public:
@ -66,6 +67,10 @@ namespace Katana {
static KatanaEngine* create ( Cell* );
static KatanaEngine* get ( const Cell* );
public:
inline bool isDigitalMode () const;
inline bool isAnalogMode () const;
inline bool isMixedMode () const;
inline bool isChannelMode () const;
inline bool useClockTree () const;
inline CellViewer* getViewer () const;
inline AnabaticEngine* base ();
@ -90,6 +95,7 @@ namespace Katana {
DataSymmetric* getDataSymmetric ( Net* );
inline const std::map<Net*,DataSymmetric*>&
getSymmetrics () const;
inline Block* getBlock ( size_t i ) const;
inline void printConfiguration () const;
void printCompletion () const;
void dumpMeasures ( std::ostream& ) const;
@ -103,11 +109,14 @@ namespace Katana {
inline void setRipupCost ( uint32_t );
inline void setHTracksReservedLocal ( uint32_t );
inline void setVTracksReservedLocal ( uint32_t );
inline void addBlock ( Block* );
DataSymmetric* addDataSymmetric ( Net* );
void setupChannelMode ();
void setupPowerRails ();
void protectRoutingPads ();
void preProcess ();
void setInterrupt ( bool );
void createChannels ();
void setupRoutingPlanes ();
void setupGlobalGraph ( uint32_t mode );
void annotateGlobalGraph ();
@ -135,10 +144,12 @@ namespace Katana {
protected:
CellViewer* _viewer;
Configuration* _configuration;
vector<Block*> _blocks;
vector<RoutingPlane*> _routingPlanes;
NegociateWindow* _negociateWindow;
double _minimumWL;
std::map<Net*,DataSymmetric*> _symmetrics;
uint32_t _mode;
mutable bool _toolSuccess;
protected:
// Constructors & Destructors.
@ -153,6 +164,10 @@ namespace Katana {
// Inline Functions.
inline bool KatanaEngine::isDigitalMode () const { return (_mode & DigitalMode); };
inline bool KatanaEngine::isAnalogMode () const { return (_mode & AnalogMode); };
inline bool KatanaEngine::isMixedMode () const { return (_mode & MixedMode); };
inline bool KatanaEngine::isChannelMode () const { return (_mode & ChannelMode); };
inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); }
inline CellViewer* KatanaEngine::getViewer () const { return _viewer; }
inline AnabaticEngine* KatanaEngine::base () { return static_cast<AnabaticEngine*>(this); }
@ -167,6 +182,7 @@ namespace Katana {
inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); }
inline const std::map<Net*,DataSymmetric*>&
KatanaEngine::getSymmetrics () const { return _symmetrics; }
inline Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; }
inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; }
inline size_t KatanaEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); }
inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
@ -175,6 +191,7 @@ namespace Katana {
inline void KatanaEngine::setRipupCost ( uint32_t cost ) { _configuration->setRipupCost(cost); }
inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { _configuration->setHTracksReservedLocal(reserved); }
inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { _configuration->setVTracksReservedLocal(reserved); }
inline void KatanaEngine::addBlock ( Block* block ) { _blocks.push_back(block); }
inline void KatanaEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; }
inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); }
inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); }

View File

@ -66,7 +66,6 @@ namespace Katana {
public:
static Session* get ( const char* message=NULL );
inline static Super* base ();
inline static bool isOpen ();
inline static bool isEmpty ();
inline static KatanaEngine* getKatanaEngine ();
static Configuration* getConfiguration ();
@ -179,9 +178,6 @@ namespace Katana {
inline size_t Session::revalidate ()
{ return get("revalidate()")->_revalidate(); }
inline bool Session::isOpen ()
{ return get() != NULL; }
inline bool Session::isEmpty ()
{ return get("isEmpty()")->_isEmpty(); }