In Anabatic/Katana, add support for VH gauges (real technos).
* Change: In Anabatic::AutoContactTerminal::getNativeConstraintBox(), when the anchor is a RoutingPad (which must be always the case), perform the true computation of it's position based on the segment occurrence. It is a important change, previously the area was in fact the "center line" of the connector while now it is really an area (mandatory for "half-offgrid" terminals of real technologies). The change is not complete yet, the area should be shrinked by the half size of a VIA, because the area applies to the center coordinate of the VIA (to be done quickly). * Bug: In Anabatic::AutoContactTurn::updateTopology(), when a dogleg is created (restore connexity after a layer change) the layer of the VIA, based on the segments it connects to must be re-computed *after* the dogleg has been made. * Change: In all files of Anabatic, when comparing two layers, no longer use the Layer pointer itself, but the layer mask. This allow a transparent management of both real and symbolic layers (which do share the same mask). Real metal layers (not VIAs) will be BasicLayer and symbolic metal layers will be RegularLayer. * New: Anabatic::Configuration::selectRpComponent(), select the best RoutingPad component for metal1 terminals. Look for the metal1 component with the biggest accessibility on-grid. RoutingPad using other metals are left untoucheds. * New: New function Anabatic::Vertex::getNeighbor(Edge*) to get the neighbor Vertex through an Edge*. This method allows to write clearer code as we no longer need to access the neighbor through the underlying GCell. Also add proxies for GCell methods in Vertex. * Bug: In Anabatic::Dijkstra::_toSources(), in the ripup stage, when a component with multiples vertexes is reached *and* two of it's vertexes are reached *at the same time* (one from which we backtrack and one still in the queue) extraneous edges may be created by _materialize(). Case occurs on snx/c35b4, "abc_5360_n903_1". To solve this, Dijkstra::_toSource() is modificated, the "from" edges of the newly reacheds vertexes are reset to NULL, *except* for the one we will be backtracking from. That is, the one given in the source argument. * Change: In Anabatic::NetBuilder class, put the various Hooks and RoutingPad sorting functions as class ones. * Bug: In AutoSegment::setLayer(), raise the SegInvalidatedFayer flag. This unset flag was causing AutoContactTurn::updateTopology() to not work as expected and making gaps, this was the cause of the last remaining warnings about layer connexity.
This commit is contained in:
parent
3d0431b238
commit
9b2648241d
|
@ -31,6 +31,7 @@
|
|||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/NetBuilderM2.h"
|
||||
#include "anabatic/NetBuilderHV.h"
|
||||
#include "anabatic/NetBuilderVH.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
||||
|
@ -725,7 +726,7 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::_loadGrByNet ()
|
||||
{
|
||||
cmess1 << " o Building detailed routing from global." << endl;
|
||||
cmess1 << " o Building detailed routing from global. " << endl;
|
||||
|
||||
startMeasures();
|
||||
openSession();
|
||||
|
@ -735,16 +736,16 @@ namespace Anabatic {
|
|||
if (getConfiguration()->isHV ()) gaugeKind = 1;
|
||||
if (getConfiguration()->isVH ()) gaugeKind = 2;
|
||||
|
||||
if (gaugeKind < 2) {
|
||||
if (gaugeKind < 3) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 144, 160 );
|
||||
DebugSession::open( net, 145, 150 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
switch ( gaugeKind ) {
|
||||
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
|
||||
//case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -761,7 +762,7 @@ namespace Anabatic {
|
|||
Session::close();
|
||||
stopMeasures();
|
||||
|
||||
if (gaugeKind > 1) {
|
||||
if (gaugeKind > 2) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
|
||||
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
|
||||
}
|
||||
|
|
|
@ -459,7 +459,8 @@ namespace Anabatic {
|
|||
setCBXMax ( box.getXMax() );
|
||||
setCBYMin ( box.getYMin() );
|
||||
setCBYMax ( box.getYMax() );
|
||||
cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox() << endl;
|
||||
cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox()
|
||||
<< " from:" << box << endl;
|
||||
cdebug_log(149,0) << "* " << _gcell << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace Anabatic {
|
|||
using Hurricane::DebugSession;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Occurrence;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -60,7 +61,7 @@ namespace Anabatic {
|
|||
, DbU::Unit height
|
||||
)
|
||||
{
|
||||
cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...)" << endl;
|
||||
cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...) " << endl;
|
||||
cdebug_log(145,0) << "@" << point << endl;
|
||||
|
||||
anchor->getBodyHook()->detach();
|
||||
|
@ -85,7 +86,7 @@ namespace Anabatic {
|
|||
, const DbU::Unit height
|
||||
)
|
||||
{
|
||||
cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...)" << endl;
|
||||
cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...) " << endl;
|
||||
cdebug_log(145,0) << "@ x:" << DbU::getValueString(x) << " y:" << DbU::getValueString(y) << endl;
|
||||
|
||||
_preCreate( gcell, anchor->getNet(), layer );
|
||||
|
@ -195,6 +196,26 @@ namespace Anabatic {
|
|||
xMin = xMax
|
||||
= vertical->getTargetPosition().getX();
|
||||
} else if ( (routingPad = dynamic_cast<RoutingPad*>(component)) ) {
|
||||
Occurrence occurrence = routingPad->getOccurrence();
|
||||
Transformation transformation = occurrence.getPath().getTransformation();
|
||||
Segment* segment = dynamic_cast<Segment*>( occurrence.getEntity() );
|
||||
|
||||
cdebug_log(145,0) << "Anchor: " << occurrence.getEntity() << endl;
|
||||
cdebug_log(145,0) << "transf: " << transformation << endl;
|
||||
|
||||
if (segment) {
|
||||
Box bb = segment->getBoundingBox();
|
||||
transformation.applyOn( bb );
|
||||
xMin = bb.getXMin();
|
||||
yMin = bb.getYMin();
|
||||
xMax = bb.getXMax();
|
||||
yMax = bb.getYMax();
|
||||
} else {
|
||||
xMin = xMax = component->getPosition().getX();
|
||||
yMin = yMax = component->getPosition().getY();
|
||||
}
|
||||
|
||||
#if FOR_SYMBOLIC_LAYERS
|
||||
Entity* entity = routingPad->getOccurrence().getEntity();
|
||||
Transformation transf = routingPad->getOccurrence().getPath().getTransformation();
|
||||
cdebug_log(145,0) << "Anchor: " << routingPad << endl;
|
||||
|
@ -238,6 +259,7 @@ namespace Anabatic {
|
|||
yMin = yMax = routingPad->getPosition().getY();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
xMin = xMax = component->getPosition().getX();
|
||||
yMin = yMax = component->getPosition().getY();
|
||||
|
@ -255,7 +277,7 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(145,0) << "| Using (y): "
|
||||
<< DbU::getValueString(bb.getYMin()) << " "
|
||||
<< DbU::getValueString(bb.getYMax()) << endl;
|
||||
<< DbU::getValueString(bb.getYMax()) << " " << bb << endl;
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return bb;
|
||||
|
@ -398,7 +420,7 @@ namespace Anabatic {
|
|||
|
||||
if (not getUConstraints(Flags::Horizontal).contains(axis)) {
|
||||
cdebug_log(145,0) << "Cached: " << _segment << endl;
|
||||
message << "Terminal vertical segment X" << DbU::getValueString(axis)
|
||||
message << "Terminal vertical segment X " << DbU::getValueString(axis)
|
||||
<< " axis is outside RoutingPad " << getUConstraints(Flags::Horizontal) << ".";
|
||||
|
||||
Flags flags = Flags::NoFlags;
|
||||
|
|
|
@ -251,15 +251,16 @@ namespace Anabatic {
|
|||
if (_horizontal1->isInvalidatedLayer()) {
|
||||
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
|
||||
_horizontal1->makeDogleg(this);
|
||||
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
|
||||
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
||||
} else /*if (_vertical1->isInvalidatedLayer())*/ {
|
||||
//_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) );
|
||||
_vertical1->makeDogleg(this);
|
||||
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
|
||||
cdebug_log(145,0) << "Update v1: " << _vertical1 << endl;
|
||||
}
|
||||
delta = abssub ( depthH1, depthV1 );
|
||||
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
|
||||
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
|
||||
depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
|
||||
delta = abssub ( depthH1, depthV1 );
|
||||
}
|
||||
|
||||
setLayer ( (delta == 0) ? rg->getRoutingLayer(depthContact) : rg->getContactLayer(depthContact) );
|
||||
|
|
|
@ -466,6 +466,9 @@ namespace Anabatic {
|
|||
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap();
|
||||
|
||||
if ( _sourcePosition != sourcePosition ) {
|
||||
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap()) << endl;
|
||||
cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl;
|
||||
cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl;
|
||||
cerr << Error ( "%s\n Source position incoherency: "
|
||||
"shadow: %s, real: %s."
|
||||
, _getString().c_str()
|
||||
|
|
|
@ -549,7 +549,7 @@ namespace Anabatic {
|
|||
|
||||
unsetFlags( SegSourceTop|SegSourceBottom );
|
||||
if (contactLayer->getMask() != segmentLayer->getMask())
|
||||
setFlags( (segmentLayer == contactLayer->getTop()) ? SegSourceBottom : SegSourceTop );
|
||||
setFlags( (segmentLayer->getMask() == contactLayer->getTop()->getMask()) ? SegSourceBottom : SegSourceTop );
|
||||
if (source->isTurn() and source->getPerpandicular(this)->isReduced())
|
||||
incReduceds();
|
||||
}
|
||||
|
@ -562,7 +562,7 @@ namespace Anabatic {
|
|||
|
||||
unsetFlags( SegTargetTop|SegTargetBottom );
|
||||
if (contactLayer->getMask() != segmentLayer->getMask())
|
||||
setFlags( (segmentLayer == contactLayer->getTop()) ? SegTargetBottom : SegTargetTop );
|
||||
setFlags( (segmentLayer->getMask() == contactLayer->getTop()->getMask()) ? SegTargetBottom : SegTargetTop );
|
||||
if (target->isTurn() and target->getPerpandicular(this)->isReduced())
|
||||
incReduceds();
|
||||
}
|
||||
|
@ -601,7 +601,7 @@ namespace Anabatic {
|
|||
DbU::Unit AutoSegment::getPPitch () const
|
||||
{
|
||||
unsigned int depth = getDepth();
|
||||
DbU::Unit topPPitch = Session::getPitch( depth + ( ((_flags & SegSpinTop) and (depth+1 < Session::getDepth())) ? 1 : 0) );
|
||||
DbU::Unit topPPitch = Session::getPitch( depth + ( ((_flags & SegSpinTop ) and (depth+1 < Session::getDepth())) ? 1 : 0) );
|
||||
DbU::Unit bottomPPitch = Session::getPitch( depth - ( ((_flags & SegSpinBottom) and (depth > 0))? 1 : 0) );
|
||||
|
||||
return std::max( topPPitch, bottomPPitch );
|
||||
|
@ -613,6 +613,10 @@ namespace Anabatic {
|
|||
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
|
||||
if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() );
|
||||
return getWidth() / 2;
|
||||
#if NEW_WAY
|
||||
if (getWidth() <= mWidth) return mWidth/2 + getPitch()/2;
|
||||
return getWidth()/2 + getPitch()/2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -730,15 +734,23 @@ namespace Anabatic {
|
|||
const Layer* sourceLayer = getAutoSource()->getLayer();
|
||||
const Layer* targetLayer = getAutoTarget()->getLayer();
|
||||
|
||||
if ( (_flags & SegSourceTop) and (sourceLayer->getBottom() != getLayer()) ) {
|
||||
cerr << Error("%s\n"
|
||||
" Source is not going above, connected to *top* of %s."
|
||||
if ( (_flags & SegSourceTop)
|
||||
and (sourceLayer->getBottom()->getMask() != getLayer()->getMask()) ) {
|
||||
cerr << Error( "%s\n"
|
||||
" Source is not going above, connected to *top* of %s.\n"
|
||||
" bottom:%s mask:%s\n"
|
||||
" layer:%s mask:%s\n"
|
||||
, getString(this).c_str()
|
||||
, getString(getAutoSource()).c_str()
|
||||
, getString(sourceLayer->getBottom()).c_str()
|
||||
, getString(sourceLayer->getBottom()->getMask()).c_str()
|
||||
, getString(getLayer()).c_str()
|
||||
, getString(getLayer()->getMask()).c_str()
|
||||
) << endl;
|
||||
valid = false;
|
||||
}
|
||||
if ( (_flags & SegSourceBottom) and (sourceLayer->getTop() != getLayer()) ) {
|
||||
if ( (_flags & SegSourceBottom)
|
||||
and (sourceLayer->getTop()->getMask() != getLayer()->getMask()) ) {
|
||||
cerr << Error("%s\n"
|
||||
" Source is not going below, connected to *bottom* of %s."
|
||||
, getString(this).c_str()
|
||||
|
@ -746,7 +758,8 @@ namespace Anabatic {
|
|||
) << endl;
|
||||
valid = false;
|
||||
}
|
||||
if ( (_flags & SegTargetTop) and (targetLayer->getBottom() != getLayer()) ) {
|
||||
if ( (_flags & SegTargetTop)
|
||||
and (targetLayer->getBottom()->getMask() != getLayer()->getMask()) ) {
|
||||
cerr << Error("%s\n"
|
||||
" Target is not going above connected to *top* of %s."
|
||||
, getString(this).c_str()
|
||||
|
@ -754,7 +767,8 @@ namespace Anabatic {
|
|||
) << endl;
|
||||
valid = false;
|
||||
}
|
||||
if ( (_flags & SegTargetBottom) and (targetLayer->getTop() != getLayer()) ) {
|
||||
if ( (_flags & SegTargetBottom)
|
||||
and (targetLayer->getTop()->getMask() != getLayer()->getMask()) ) {
|
||||
cerr << Error("%s\n"
|
||||
" Target is not going below, connected to *bottom* of %s."
|
||||
, getString(this).c_str()
|
||||
|
@ -1439,13 +1453,12 @@ namespace Anabatic {
|
|||
const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth);
|
||||
if (getLayer() != newLayer) {
|
||||
setLayer( newLayer );
|
||||
|
||||
getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer );
|
||||
getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer );
|
||||
}
|
||||
|
||||
if (not (flags & Flags::WithNeighbors)) {
|
||||
cdebug_tabw(149,-1);
|
||||
cdebug_tabw(159,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1771,9 +1784,14 @@ namespace Anabatic {
|
|||
return false;
|
||||
}
|
||||
|
||||
source->setLayer( Session::getRoutingLayer(perpandicularDepth) );
|
||||
target->setLayer( Session::getRoutingLayer(perpandicularDepth) );
|
||||
setLayer( Session::getRoutingLayer(perpandicularDepth) );
|
||||
const Layer* layer = Session::getRoutingLayer(perpandicularDepth);
|
||||
DbU::Unit side = Session::getWireWidth (perpandicularDepth);
|
||||
|
||||
source->setLayer( layer );
|
||||
target->setLayer( layer );
|
||||
setLayer( layer );
|
||||
source->setSizes( side, side );
|
||||
target->setSizes( side, side );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2097,20 +2115,21 @@ namespace Anabatic {
|
|||
string AutoSegment::_getStringFlags () const
|
||||
{
|
||||
string state;
|
||||
state += isFixed () ?" F":" -";
|
||||
state += isUnsetAxis () ? "u": "-";
|
||||
state += isStrap () ? "S": "-";
|
||||
state += isCanonical () ? "C": "-";
|
||||
state += isGlobal () ? "G": "-";
|
||||
state += isWeakGlobal () ? "g": "-";
|
||||
state += isLongLocal () ? "L": "-";
|
||||
state += isStrongTerminal() ? "T": "-";
|
||||
state += isWeakTerminal1 () ? "W": "-";
|
||||
state += isWeakTerminal2 () ? "w": "-";
|
||||
state += isNotAligned () ? "A": "-";
|
||||
state += isSlackened () ? "S": "-";
|
||||
state += isReduced () ? "r": "-";
|
||||
state += isInvalidated () ? "i": "-";
|
||||
state += isFixed () ?" F":" -";
|
||||
state += isUnsetAxis () ? "u": "-";
|
||||
state += isStrap () ? "S": "-";
|
||||
state += isCanonical () ? "C": "-";
|
||||
state += isGlobal () ? "G": "-";
|
||||
state += isWeakGlobal () ? "g": "-";
|
||||
state += isLongLocal () ? "L": "-";
|
||||
state += isStrongTerminal () ? "T": "-";
|
||||
state += isWeakTerminal1 () ? "W": "-";
|
||||
state += isWeakTerminal2 () ? "w": "-";
|
||||
state += isNotAligned () ? "A": "-";
|
||||
state += isSlackened () ? "S": "-";
|
||||
state += isReduced () ? "r": "-";
|
||||
state += isInvalidated () ? "i": "-";
|
||||
state += isInvalidatedLayer() ? "l": "-";
|
||||
|
||||
if (_flags & SegSourceTop) state += 't';
|
||||
else if (_flags & SegSourceBottom) state += 'b';
|
||||
|
|
|
@ -32,6 +32,7 @@ endif ( CHECK_DETERMINISM )
|
|||
anabatic/NetBuilder.h
|
||||
anabatic/NetBuilderM2.h
|
||||
anabatic/NetBuilderHV.h
|
||||
anabatic/NetBuilderVH.h
|
||||
anabatic/ChipTools.h
|
||||
)
|
||||
set( pyIncludes )
|
||||
|
@ -56,6 +57,7 @@ endif ( CHECK_DETERMINISM )
|
|||
NetBuilder.cpp
|
||||
NetBuilderM2.cpp
|
||||
NetBuilderHV.cpp
|
||||
NetBuilderVH.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
PreRouteds.cpp
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/CellGauge.h"
|
||||
|
@ -46,9 +49,16 @@ namespace Anabatic {
|
|||
using Hurricane::tab;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::Occurrence;
|
||||
using Hurricane::NetExternalComponents;
|
||||
using CRL::AllianceFramework;
|
||||
using CRL::RoutingGauge;
|
||||
using CRL::RoutingLayerGauge;
|
||||
|
@ -125,12 +135,17 @@ namespace Anabatic {
|
|||
if (regularLayer)
|
||||
_extensionCaps.push_back( regularLayer->getExtentionCap() );
|
||||
else {
|
||||
_extensionCaps.push_back( 0 );
|
||||
cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n"
|
||||
" (%s)"
|
||||
, depth
|
||||
, getString(layerGauges[depth]->getLayer()).c_str()
|
||||
) << endl;
|
||||
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( layerGauges[depth]->getLayer() );
|
||||
if (basicLayer) {
|
||||
_extensionCaps.push_back( layerGauges[depth]->getHalfWireWidth() );
|
||||
} else {
|
||||
_extensionCaps.push_back( 0 );
|
||||
cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n"
|
||||
" (%s)"
|
||||
, depth
|
||||
, getString(layerGauges[depth]->getLayer()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,6 +379,102 @@ namespace Anabatic {
|
|||
{ return _edgeHInc; }
|
||||
|
||||
|
||||
DbU::Unit Configuration::isOnRoutingGrid ( RoutingPad* rp ) const
|
||||
{
|
||||
Box ab = rp->getCell()->getBoundingBox();
|
||||
Box bb = rp->getBoundingBox();
|
||||
Point center = rp->getCenter();
|
||||
|
||||
RoutingLayerGauge* gauge = getLayerGauge( 1 );
|
||||
if (gauge->isHorizontal()) return 0;
|
||||
|
||||
DbU::Unit nearestX = gauge->getTrackPosition( ab.getXMin(), ab.getXMax(), center.getX(), Constant::Nearest );
|
||||
if ( (nearestX >= bb.getXMin()) and (nearestX <= bb.getXMax()) ) return 0;
|
||||
|
||||
return nearestX;
|
||||
}
|
||||
|
||||
|
||||
bool Configuration::selectRpComponent ( RoutingPad* rp ) const
|
||||
{
|
||||
cdebug_log(145,1) << "selectRpComponent(): " << rp << endl;
|
||||
|
||||
Box ab = rp->getCell()->getBoundingBox();
|
||||
const Layer* metal1 = getLayerGauge( 0 )->getLayer();
|
||||
RoutingLayerGauge* gauge = getLayerGauge( 1 );
|
||||
Occurrence occurrence = rp->getPlugOccurrence();
|
||||
Plug* plug = dynamic_cast<Plug*>( occurrence.getEntity() );
|
||||
Net* masterNet = plug->getMasterNet();
|
||||
Path path = Path( occurrence.getPath(), plug->getInstance() );
|
||||
Transformation transformation = path.getTransformation();
|
||||
|
||||
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
|
||||
if (current and (current->getLayer()->getMask() != metal1->getMask())) {
|
||||
cdebug_log(145,0) << "> using default non-metal1 segment." << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
DbU::Unit bestSpan = 0;
|
||||
Component* bestComponent = NULL;
|
||||
|
||||
for ( Component* component : masterNet->getComponents() ) {
|
||||
cdebug_log(145,0) << "@ " << component << endl;
|
||||
if (not NetExternalComponents::isExternal(component)) continue;
|
||||
|
||||
Segment* segment = dynamic_cast<Segment*>(component);
|
||||
if (not segment) continue;
|
||||
if (segment->getLayer()->getMask() != metal1->getMask()) continue;
|
||||
|
||||
Box bb = transformation.getBox( component->getBoundingBox() );
|
||||
DbU::Unit trackPos = 0;
|
||||
DbU::Unit minPos = DbU::Max;
|
||||
DbU::Unit maxPos = DbU::Min;
|
||||
|
||||
if (gauge->isVertical()) {
|
||||
trackPos = gauge->getTrackPosition( ab.getXMin()
|
||||
, ab.getXMax()
|
||||
, bb.getCenter().getX()
|
||||
, Constant::Nearest );
|
||||
minPos = bb.getXMin();
|
||||
maxPos = bb.getXMax();
|
||||
} else {
|
||||
trackPos = gauge->getTrackPosition( ab.getYMin()
|
||||
, ab.getYMax()
|
||||
, bb.getCenter().getY()
|
||||
, Constant::Nearest );
|
||||
minPos = bb.getYMin();
|
||||
maxPos = bb.getYMax();
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "| " << occurrence.getPath() << endl;
|
||||
cdebug_log(145,0) << "| " << transformation << endl;
|
||||
cdebug_log(145,0) << "| " << bb << " of:" << segment << endl;
|
||||
cdebug_log(145,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
|
||||
|
||||
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
|
||||
if (not bestComponent) bestComponent = component;
|
||||
else {
|
||||
if (bestSpan < maxPos-minPos) {
|
||||
bestComponent = component;
|
||||
bestSpan = maxPos - minPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestComponent) {
|
||||
rp->setExternalComponent( bestComponent );
|
||||
cdebug_log(145,0) << "Using best candidate:" << bestComponent << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Configuration::print ( Cell* cell ) const
|
||||
{
|
||||
if (not cmess1.enabled()) return;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
|
@ -39,6 +40,7 @@ namespace Anabatic {
|
|||
using std::numeric_limits;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Horizontal;
|
||||
|
@ -1293,9 +1295,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
string Vertex::_getString () const
|
||||
{
|
||||
|
@ -1303,11 +1302,11 @@ namespace Anabatic {
|
|||
string s = "<Vertex [key] " + getString(_id) + ">";
|
||||
return s;
|
||||
}
|
||||
string s = "<Vertex " + getString(_id)
|
||||
+ " @(" + DbU::getValueString(_gcell->getXMin())
|
||||
+ "-" + DbU::getValueString(_gcell->getYMin())
|
||||
+ "-" + DbU::getValueString(_gcell->getXMax())
|
||||
+ "-" + DbU::getValueString(_gcell->getYMax()) + ")"
|
||||
string s = "<Vertex id:" + getString(_id)
|
||||
+ " [" + DbU::getValueString(_gcell->getXMin())
|
||||
+ " " + DbU::getValueString(_gcell->getYMin())
|
||||
+ " " + DbU::getValueString(_gcell->getXMax())
|
||||
+ " " + DbU::getValueString(_gcell->getYMax()) + "]"
|
||||
//+ " rps:" + getString(_rpCount)
|
||||
//+ " deg:" + getString(_degree)
|
||||
+ " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
|
||||
|
@ -1466,17 +1465,24 @@ namespace Anabatic {
|
|||
if (rp) {
|
||||
if (_attachSymContactsHook(rp)) continue; // ANALOG
|
||||
|
||||
cdebug_log(112,0) << "| frp:" << rp << endl;
|
||||
cdebug_log(112,0) << "@ frp:" << rp << endl;
|
||||
rps.push_back( rp );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto rp : rps ) {
|
||||
cdebug_log(112,0) << "| rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl;
|
||||
if (not _anabatic->getConfiguration()->selectRpComponent(rp))
|
||||
cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
||||
cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl;
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = _anabatic->getGCellUnder( center );
|
||||
|
||||
Box bb = rp->getBoundingBox();
|
||||
|
||||
cdebug_log(112,0) << bb.getXMin() << " " << bb.getXMax() << endl;
|
||||
cdebug_log(112,0) << "center X:" << center.getX() << " gcell Xmax:" << gcell->getXMax() << endl;
|
||||
|
||||
_limitSymSearchArea(rp); // ANALOG
|
||||
|
||||
if (not gcell) {
|
||||
|
@ -1490,29 +1496,22 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cdebug_log(112,0) << "Merge search area: " << _searchArea << ", gcell: " << gcell << endl;
|
||||
_searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE
|
||||
//if (_net->getCell()->getName() == "gmchamla") _searchArea.merge( _net->getCell()->getAbutmentBox() ); // TO CHANGE
|
||||
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
|
||||
cdebug_log(112,0) << "| Merged search area: " << _searchArea << ", gcell: " << gcell << endl;
|
||||
|
||||
Vertex* seed = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
GCell* gseed = seed->getGCell();
|
||||
Vertex* seed = gcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
GCell* gseed = seed->getGCell();
|
||||
|
||||
if (gseed->isAnalog()) _setSourcesGRAData( seed, rp ); // ANALOG
|
||||
cdebug_log(112,0) << "seed isH(): " << seed->isH() << endl;
|
||||
cdebug_log(112,0) << "seed isV(): " << seed->isV() << endl;
|
||||
cdebug_log(112,0) << "| seed->isH(): " << seed->isH()
|
||||
<< " seed->isV(): " << seed->isV() << endl;
|
||||
|
||||
if (seed->getConnexId() < 0) {
|
||||
cdebug_log(112,0) << "(seed->getConnexId() < 0)"<< endl;
|
||||
VertexSet connecteds;
|
||||
_getConnecteds( seed, connecteds );
|
||||
|
||||
++_connectedsId;
|
||||
for ( Vertex* vertex : connecteds ) {
|
||||
cdebug_log(112,0) << "| Current: " << vertex << endl;
|
||||
vertex->setDistance ( Vertex::unreached );
|
||||
vertex->setStamp ( _stamp );
|
||||
vertex->setConnexId ( _connectedsId );
|
||||
|
@ -1530,9 +1529,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "seed->incRpCount();" << endl;
|
||||
seed->incRpCount();
|
||||
cdebug_log(112,0) << "Contact* vcontact = seed->getGContact( _net );" << endl;
|
||||
Contact* vcontact = seed->getGContact( _net );
|
||||
rp->getBodyHook()->detach();
|
||||
rp->getBodyHook()->attach( vcontact->getBodyHook() );
|
||||
|
@ -1766,8 +1763,8 @@ namespace Anabatic {
|
|||
Vertex* current = _queue.top();
|
||||
GCell* gcurrent = current->getGCell();
|
||||
|
||||
cdebug_log(111,0) << "Current:" << current << endl;
|
||||
cdebug_log(111,0) << "isAxisTarget():" << current->isAxisTarget() << endl;
|
||||
cdebug_log(111,1) << "Current:" << current << endl;
|
||||
//cdebug_log(111,0) << "isAxisTarget():" << current->isAxisTarget() << endl;
|
||||
|
||||
_queue.pop();
|
||||
|
||||
|
@ -1776,61 +1773,58 @@ namespace Anabatic {
|
|||
cdebug_log(111,0) << "Looking for neighbors:" << endl;
|
||||
|
||||
for ( Edge* edge : current->getGCell()->getEdges() ) {
|
||||
cdebug_log(111,0) << "[Current]: " << current << endl;
|
||||
cdebug_log(111,0) << "@ Edge " << edge << endl;
|
||||
|
||||
if (edge == current->getFrom()) {
|
||||
cdebug_log(111,0) << "| Reject: edge == current->getFrom()" << endl;
|
||||
cdebug_log(111,0) << "> Reject: edge == current->getFrom()" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((gcurrent->isAnalog()) and _checkFrom2(edge, current)) {
|
||||
cdebug_log(111,0) << "| Reject: _checkFrom2()" << endl;
|
||||
cdebug_log(111,0) << "> Reject: _checkFrom2()" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
GCell* gneighbor = edge->getOpposite(current->getGCell());
|
||||
Vertex* vneighbor = gneighbor->getObserver<Vertex>( GCell::Observable::Vertex );
|
||||
if (gneighbor->isAnalog()) vneighbor->createAData();
|
||||
Vertex* vneighbor = current->getNeighbor( edge );
|
||||
if (vneighbor->isAnalog()) vneighbor->createAData();
|
||||
|
||||
cdebug_log(111,0) << "+ Neighbor:" << vneighbor << endl;
|
||||
cdebug_log(111,0) << "| Neighbor:" << vneighbor << endl;
|
||||
|
||||
if (vneighbor->getConnexId() == _connectedsId) {
|
||||
cdebug_log(111,0) << "| Reject: Neighbor already reached (has connectedsId)" << endl;
|
||||
cdebug_log(111,0) << "> Reject: Neighbor already reached (has connectedsId)" << endl;
|
||||
continue;
|
||||
}
|
||||
if (not _searchArea.intersect(gneighbor->getBoundingBox())) {
|
||||
cdebug_log(111,0) << "| Reject: not in _searchArea: " << _searchArea << ", gneighbor area: " << gneighbor->getBoundingBox() << endl;
|
||||
if (not _searchArea.intersect(vneighbor->getBoundingBox())) {
|
||||
cdebug_log(111,0) << "> Reject: not in _searchArea: " << _searchArea << ", vneighbor area: " << vneighbor->getBoundingBox() << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
////////////////////////////////////// DEBUG //////////////////////////////////////
|
||||
if (current->getFrom()) {
|
||||
cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl;
|
||||
//current->getIntervFrom().print();
|
||||
}
|
||||
if (gcurrent->isAnalog() and current->getFrom2()) {
|
||||
cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl;
|
||||
current->getIntervFrom2().print();
|
||||
}
|
||||
if ( (vneighbor->getFrom() != NULL) and (vneighbor->hasValidStamp()) ) {
|
||||
cdebug_log(111,0) << "| Neighbor GETFROM:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl;
|
||||
cdebug_log(111,0) << "Distance prev : " << DbU::getValueString(vneighbor->getDistance()) << endl;
|
||||
}
|
||||
//if (current->getFrom()) {
|
||||
// cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl;
|
||||
////current->getIntervFrom().print();
|
||||
//}
|
||||
//if (gcurrent->isAnalog() and current->getFrom2()) {
|
||||
// cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl;
|
||||
// current->getIntervFrom2().print();
|
||||
//}
|
||||
//if ( (vneighbor->getFrom() != NULL) and (vneighbor->hasValidStamp()) ) {
|
||||
// cdebug_log(111,0) << "| Neighbor GETFROM:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl;
|
||||
// cdebug_log(111,0) << "Distance prev : " << DbU::getValueString(vneighbor->getDistance()) << endl;
|
||||
//}
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DbU::Unit distance = _distanceCb( current, vneighbor, edge );
|
||||
cdebug_log(111,0) << "distance:" << Vertex::getValueString(distance) << endl;
|
||||
cdebug_log(111,0) << "| Distance:" << Vertex::getValueString(distance) << endl;
|
||||
|
||||
bool isDistance2shorter = false;
|
||||
if (gcurrent->isAnalog() and gneighbor->isAnalog())
|
||||
if (gcurrent->isAnalog() and vneighbor->isAnalog())
|
||||
isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge );
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
bool push = false;
|
||||
if (distance != Vertex::unreachable){
|
||||
if (not vneighbor->hasValidStamp()) {
|
||||
cdebug_log(111,0) << "Vertex reached for the first time" << endl;
|
||||
cdebug_log(111,0) << "> Vertex reached for the first time" << endl;
|
||||
vneighbor->setConnexId( -1 );
|
||||
vneighbor->setStamp ( _stamp );
|
||||
vneighbor->setDegree ( 1 );
|
||||
|
@ -1840,42 +1834,41 @@ namespace Anabatic {
|
|||
push = true;
|
||||
} else {
|
||||
if ( (distance == vneighbor->getDistance())
|
||||
and (gneighbor->isAnalog())
|
||||
and (vneighbor->isAnalog())
|
||||
and (vneighbor->getFrom2() == NULL)
|
||||
) {
|
||||
_pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG
|
||||
|
||||
} else if (distance < vneighbor->getDistance()) {
|
||||
if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor );
|
||||
cdebug_log(111,0) << "Vertex reached through a shorter path" << endl;
|
||||
cdebug_log(111,0) << "> Vertex reached through a shorter path (prev: "
|
||||
<< DbU::getValueString(vneighbor->getDistance()) << ")" << endl;
|
||||
push = true;
|
||||
} else {
|
||||
cdebug_log(111,0) << "Reject: Vertex reached through a *longer* path or unreachable:"
|
||||
cdebug_log(111,0) << "> Reject: Vertex reached through a *longer* path or unreachable:"
|
||||
<< boolalpha << (distance == Vertex::unreachable)
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cdebug_log(111,0) << "Reject: Vertex unreachable" << endl;
|
||||
cdebug_log(111,0) << "> Reject: Vertex unreachable" << endl;
|
||||
}
|
||||
|
||||
if (push){
|
||||
if (gneighbor->isAnalog()) // Gneighbor only not current gcell
|
||||
if (vneighbor->isAnalog()) // Vneighbor only not current gcell
|
||||
_updateGRAData( vneighbor, isDistance2shorter, current );
|
||||
vneighbor->setBranchId( current->getBranchId() );
|
||||
vneighbor->setDistance( distance );
|
||||
cdebug_log(111,0) << "setFrom1: " << vneighbor << endl;
|
||||
cdebug_log(111,0) << "| setFrom1: " << vneighbor << endl;
|
||||
vneighbor->setFrom ( edge );
|
||||
_queue.push( vneighbor );
|
||||
cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << ", isFromFrom2: " << vneighbor->isFromFrom2() << endl;
|
||||
cdebug_log(111,0) << "| Push: (size:" << _queue.size() << ") " << vneighbor << ", isFromFrom2: " << vneighbor->isFromFrom2() << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
|
||||
/*if ( (distance == vneighbor->getDistance())
|
||||
and gcurrent->isAnalog()
|
||||
and gneighbor->isAnalog()
|
||||
|
@ -1938,9 +1931,12 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
cdebug_tabw(111,-1);
|
||||
continue;
|
||||
}
|
||||
|
||||
cdebug_tabw(111,-1);
|
||||
// We did reach another target (different <connexId>).
|
||||
// Tag back the path, with a higher <branchId>.
|
||||
_traceback( current );
|
||||
|
@ -1971,79 +1967,39 @@ namespace Anabatic {
|
|||
|
||||
bool isfirst = true;
|
||||
bool useFrom2 = false;
|
||||
//<<<<<<< HEAD
|
||||
//if (!current->getGCell()->isMatrix()){
|
||||
/*_initiateUpdateIntervals ( current ); // ANALOG
|
||||
|
||||
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;
|
||||
|
||||
//if (!current->getGCell()->isMatrix()){
|
||||
//////////////////////////////////////////////////////////////////////////////////////////// ANALOG
|
||||
if (_updateIntervals ( isfirst, current, useFrom2, branchId, from )) break;
|
||||
Vertex* next = NULL;
|
||||
next = current->getPredecessor();
|
||||
|
||||
if( current->isFromFrom2()) {
|
||||
cdebug_log(112,0) << "ISFROMFROM2: " << current << endl;
|
||||
useFrom2 = true;
|
||||
current->unsetFlags(Vertex::UseFromFrom2);*/
|
||||
/*=======*/
|
||||
if (current->getGCell()->isAnalog()) {
|
||||
if (current->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) << "+ " << current << endl;
|
||||
//if (current->getFrom()) cdebug_log(112,0) << "| From:" << current->getFrom()->getOpposite(current->getGCell()) << endl;
|
||||
|
||||
if (current->getGCell()->isAnalog()) {
|
||||
//if (current->getFrom2()) cdebug_log(112,0) << "| From2:" << current->getFrom2()->getOpposite(current->getGCell()) << endl;
|
||||
|
||||
if (current->isAnalog()) {
|
||||
if (_updateIntervals( isfirst, current, useFrom2, branchId, from )) break;
|
||||
Vertex* next = NULL;
|
||||
next = current->getPredecessor();
|
||||
if (current == next){
|
||||
cdebug_log(112,0) << "[ERROR]: Current's predecessor is current." << endl;
|
||||
cdebug_log(112,0) << "[ERROR] Current's predecessor is current." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (current->isFromFrom2()) {
|
||||
//cdebug_log(112,0) << "| isFromFrom2:true (" << current << ")" << endl;
|
||||
useFrom2 = true;
|
||||
current->unsetFlags( Vertex::UseFromFrom2 );
|
||||
} else {
|
||||
//cdebug_log(112,0) << "| isFromFrom2:false" << endl;
|
||||
useFrom2 = false;
|
||||
}
|
||||
//cdebug_log(112,0) << "| Next: " << next << endl;
|
||||
current = next;
|
||||
//>>>>>>> 987289653831df12933bd4490d9559415e61f220
|
||||
/*} else {
|
||||
cdebug_log(112,0) << "ISNOT FROMFROM2" << endl;
|
||||
useFrom2 = false;
|
||||
}
|
||||
cdebug_log(112,0) << "next: " << next << endl;
|
||||
current = next;*/
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
} else {
|
||||
current->incDegree();
|
||||
if (current->getConnexId() == _connectedsId) break;
|
||||
|
||||
from = current->getFrom();
|
||||
from = current->getFrom();
|
||||
if (not from) break;
|
||||
|
||||
current->setDistance( 0.0 );
|
||||
|
@ -2077,7 +2033,7 @@ namespace Anabatic {
|
|||
|
||||
Vertex* source = startVertex;
|
||||
while ( source ) {
|
||||
cdebug_log(112,0) << "* " << source << endl;
|
||||
cdebug_log(112,0) << "@ " << source << endl;
|
||||
|
||||
bool isAnalog = source->getGCell()->isAnalog();
|
||||
if (isAnalog) source->resetIntervals();
|
||||
|
@ -2090,10 +2046,10 @@ namespace Anabatic {
|
|||
Interval constraint = from->getSide();
|
||||
source->setFrom( NULL );
|
||||
|
||||
cdebug_log(112,0) << "+ " << target << endl;
|
||||
cdebug_log(112,0) << "| " << target << endl;
|
||||
|
||||
if (target->getConnexId() < 0) {
|
||||
cdebug_log(112,0) << "| " << "break (abort: false start)." << endl;
|
||||
cdebug_log(112,0) << "> " << "break (abort: false start)." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2134,15 +2090,14 @@ namespace Anabatic {
|
|||
else targetContact = target->breakGoThrough( _net );
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "| aligneds.front():" << aligneds.front()
|
||||
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::getGHorizontalPitch(); //DbU::fromLambda(2.0);
|
||||
DbU::Unit width = Session::getGHorizontalPitch();
|
||||
|
||||
if (state) width *= state->getWPitch();
|
||||
|
||||
|
@ -2152,6 +2107,7 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
if (state->isSymmetric()) _createSelfSymSeg ( segment );
|
||||
|
@ -2160,8 +2116,7 @@ namespace Anabatic {
|
|||
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::getGVerticalPitch(); //DbU::fromLambda(2.0);
|
||||
DbU::Unit width = Session::getGVerticalPitch();
|
||||
|
||||
if (state) width *= state->getWPitch();
|
||||
segment = Vertical::create( sourceContact
|
||||
|
@ -2170,6 +2125,7 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
if (state->isSymmetric()) _createSelfSymSeg ( segment );
|
||||
|
@ -2177,7 +2133,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
cdebug_log(112,0) << "| break (U-turn, turn, branch or terminal)." << endl;
|
||||
cdebug_log(112,0) << "| " << segment << endl;
|
||||
cdebug_log(112,0) << "+ " << segment << endl;
|
||||
|
||||
Vertex* prevSource = source;
|
||||
source = (target->getFrom()) ? target : NULL;
|
||||
|
@ -2246,32 +2202,30 @@ namespace Anabatic {
|
|||
|
||||
VertexSet stack;
|
||||
stack.insert( source );
|
||||
|
||||
|
||||
cdebug_log(112,0) << "in WHILE" << endl;
|
||||
while ( not stack.empty() ) {
|
||||
source = *stack.begin();
|
||||
stack.erase( source );
|
||||
Vertex* current = *stack.begin();
|
||||
stack.erase( current );
|
||||
|
||||
cdebug_log(112,0) << "| source:" << source << " stack.size():" << stack.size() << endl;
|
||||
cdebug_log(112,0) << "@ source:" << current << " stack.size():" << stack.size() << endl;
|
||||
|
||||
for ( Edge* edge : source->getGCell()->getEdges() ) {
|
||||
for ( Edge* edge : current->getEdges() ) {
|
||||
if (not edge->hasNet(_net)) {
|
||||
cdebug_log(112,0) << " Not connected:" << edge
|
||||
<< " to:" << edge->getOpposite(source->getGCell()) << endl;
|
||||
cdebug_log(110,0) << "| Not connected:" << edge
|
||||
<< " to:" << (current->getNeighbor(edge)) << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
GCell* gneighbor = edge->getOpposite(source->getGCell());
|
||||
cdebug_log(112,0) << "GCell: " << gneighbor<< endl;
|
||||
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
Vertex* vneighbor = current->getNeighbor( edge );
|
||||
cdebug_log(110,0) << "| connected to: " << vneighbor<< endl;
|
||||
|
||||
if (not vneighbor->hasValidStamp()) continue;
|
||||
if (vneighbor->getConnexId() == connexId) continue;
|
||||
|
||||
vneighbor->setConnexId( connexId );
|
||||
vneighbor->setDistance( 0.0 );
|
||||
//vneighbor->setFrom ( edge );
|
||||
if (vneighbor != source) vneighbor->setFrom( NULL );
|
||||
|
||||
_targets.erase ( vneighbor );
|
||||
_sources.insert( vneighbor );
|
||||
_queue.push( vneighbor );
|
||||
|
@ -2279,7 +2233,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "Dijkstra::_toSources() END" << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
@ -2302,13 +2255,11 @@ namespace Anabatic {
|
|||
|
||||
for ( Edge* edge : source->getGCell()->getEdges() ) {
|
||||
if (not edge->hasNet(_net)) {
|
||||
cdebug_log(112,0) << " Not connected:" << edge << endl;
|
||||
cdebug_log(110,0) << " Not connected:" << edge << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
GCell* gneighbor = edge->getOpposite(source->getGCell());
|
||||
Vertex* vneighbor = gneighbor->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
|
||||
Vertex* vneighbor = source->getNeighbor( edge );
|
||||
if (connecteds.find(vneighbor) != connecteds.end()) continue;
|
||||
|
||||
stack.insert( vneighbor );
|
||||
|
|
|
@ -243,14 +243,14 @@ namespace Anabatic {
|
|||
DbU::Unit globalThreshold = Session::getSliceHeight()*3;
|
||||
size_t netCount = 0;
|
||||
|
||||
for ( size_t i=0 ; i<_segments.size(); ) {
|
||||
for ( size_t i=0 ; i<_segments.size() ; ) {
|
||||
if (_segments[i]->getLength() >= globalThreshold) {
|
||||
NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
|
||||
anabatic->ripup( _segments[i], Flags::Propagate );
|
||||
} else
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return netCount;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,139 @@ namespace {
|
|||
" No Contact in GCell.\n";
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortRpByX".
|
||||
|
||||
class SortRpByX {
|
||||
public:
|
||||
inline SortRpByX ( uint64_t flags );
|
||||
inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 );
|
||||
private:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline SortRpByX::SortRpByX ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 )
|
||||
{
|
||||
DbU::Unit x1 = rp1->getCenter().getX();
|
||||
DbU::Unit x2 = rp2->getCenter().getX();
|
||||
|
||||
if (x1 == x2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortRpByY".
|
||||
|
||||
class SortRpByY {
|
||||
public:
|
||||
inline SortRpByY ( uint64_t flags );
|
||||
inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline SortRpByY::SortRpByY ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortRpByY::operator() ( RoutingPad* rp1, RoutingPad* rp2 )
|
||||
{
|
||||
DbU::Unit y1 = rp1->getCenter().getY();
|
||||
DbU::Unit y2 = rp2->getCenter().getY();
|
||||
|
||||
if (y1 == y2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortHookByX".
|
||||
|
||||
class SortHookByX {
|
||||
public:
|
||||
inline SortHookByX ( uint64_t flags );
|
||||
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline SortHookByX::SortHookByX ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortHookByX::operator() ( Hook* h1, Hook* h2 )
|
||||
{
|
||||
DbU::Unit x1 = 0;
|
||||
DbU::Unit x2 = 0;
|
||||
Horizontal* hh1 = dynamic_cast<Horizontal*>(h1->getComponent());
|
||||
Horizontal* hh2 = dynamic_cast<Horizontal*>(h2->getComponent());
|
||||
Vertical* vv1 = dynamic_cast<Vertical*> (h1->getComponent());
|
||||
Vertical* vv2 = dynamic_cast<Vertical*> (h2->getComponent());
|
||||
|
||||
if (hh1) x1 = std::min( hh1->getSource()->getX(), hh1->getTarget()->getX() );
|
||||
else if (vv1) x1 = vv1->getX();
|
||||
else x1 = h1->getComponent()->getCenter().getX();
|
||||
|
||||
if (hh2) x2 = std::min( hh2->getSource()->getX(), hh2->getTarget()->getX() );
|
||||
else if (vv2) x2 = vv2->getX();
|
||||
else x2 = h2->getComponent()->getCenter().getX();
|
||||
|
||||
if (x1 == x2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortHookByY".
|
||||
|
||||
class SortHookByY {
|
||||
public:
|
||||
inline SortHookByY ( uint64_t flags );
|
||||
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline SortHookByY::SortHookByY ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortHookByY::operator() ( Hook* h1, Hook* h2 )
|
||||
{
|
||||
DbU::Unit y1 = 0;
|
||||
DbU::Unit y2 = 0;
|
||||
Horizontal* hh1 = dynamic_cast<Horizontal*>(h1->getComponent());
|
||||
Horizontal* hh2 = dynamic_cast<Horizontal*>(h2->getComponent());
|
||||
Vertical* vv1 = dynamic_cast<Vertical*> (h1->getComponent());
|
||||
Vertical* vv2 = dynamic_cast<Vertical*> (h2->getComponent());
|
||||
|
||||
if (vv1) y1 = std::min( vv1->getSource()->getY(), vv1->getTarget()->getY() );
|
||||
else if (hh1) y1 = hh1->getY();
|
||||
else y1 = h1->getComponent()->getCenter().getX();
|
||||
|
||||
if (vv2) y2 = std::min( vv2->getSource()->getY(), vv2->getTarget()->getY() );
|
||||
else if (hh2) y2 = hh2->getY();
|
||||
else y2 = h2->getComponent()->getCenter().getY();
|
||||
|
||||
if (y1 == y2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2);
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
|
@ -175,8 +308,25 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void NetBuilder::sortRpByX ( vector<RoutingPad*>& rps, uint64_t flags )
|
||||
{ sort( rps.begin(), rps.end(), SortRpByX(flags) ); }
|
||||
|
||||
|
||||
void NetBuilder::sortRpByY ( vector<RoutingPad*>& rps, uint64_t flags )
|
||||
{ sort( rps.begin(), rps.end(), SortRpByY(flags) ); }
|
||||
|
||||
|
||||
void NetBuilder::sortHookByX ( vector<Hook*>& hooks, uint64_t flags )
|
||||
{ sort( hooks.begin(), hooks.end(), SortHookByX(flags) ); }
|
||||
|
||||
|
||||
void NetBuilder::sortHookByY ( vector<Hook*>& hooks, uint64_t flags )
|
||||
{ sort( hooks.begin(), hooks.end(), SortHookByY(flags) ); }
|
||||
|
||||
|
||||
NetBuilder::NetBuilder ()
|
||||
: _forks ()
|
||||
: _anabatic (NULL)
|
||||
, _forks ()
|
||||
, _connexity ()
|
||||
, _topology (0)
|
||||
, _gcell (NULL)
|
||||
|
@ -348,7 +498,7 @@ namespace Anabatic {
|
|||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool NetBuilder::push ( Hook* toHook, AutoContact* contact, uint64_t flags )
|
||||
{
|
||||
|
@ -767,98 +917,98 @@ namespace Anabatic {
|
|||
|
||||
bool NetBuilder::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_2G() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_1Pad ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG_1Pad() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_1G_1PinM2() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_1G_1M1() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_2G_1M1() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_xM1 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_1G_xM1() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_xM1_xM3 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG_xM1_xM3() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_1M1_1M2 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG_1M1_1M2() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_4G_1M2 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_4G_1M2() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_xM2 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG_xM2() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1M3 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_1G_1M3() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_xM3 ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_xG_xM3() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::do_xG() method *not* reimplemented from base class." << endl;
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_globalSegment() method *not* reimplemented from base class." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -867,8 +1017,8 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << "NetBuilder::singleGCell() " << net << endl;
|
||||
|
||||
vector<Component*> rpM1s;
|
||||
Component* rpM2 = NULL;
|
||||
vector<RoutingPad*> rpM1s;
|
||||
Component* rpM2 = NULL;
|
||||
|
||||
forEach ( RoutingPad*, irp, net->getRoutingPads() ) {
|
||||
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1)
|
||||
|
@ -891,18 +1041,18 @@ namespace Anabatic {
|
|||
return;
|
||||
}
|
||||
|
||||
sort( rpM1s.begin(), rpM1s.end(), SortRpByX(NetBuilder::NoFlags) ); // increasing X.
|
||||
sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X.
|
||||
|
||||
GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() );
|
||||
GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() );
|
||||
|
||||
if (not gcell1) {
|
||||
cerr << Error( "No GCell under %s.", getString(rpM1s[0]).c_str() ) << endl;
|
||||
cerr << Error( "No GCell under %s.", getString(*(rpM1s.begin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
if (gcell1 != gcell2) {
|
||||
cerr << Error( "Not under a single GCell %s.", getString(rpM1s[0]).c_str() ) << endl;
|
||||
cerr << Error( "Not under a single GCell %s.", getString(*(rpM1s.rbegin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
@ -1081,7 +1231,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
cdebug_log(145,0) << "Sorted hooks:" << endl;
|
||||
sort( hooks.begin(), hooks.end(), SortHookByX(NoFlags) );
|
||||
sortHookByX( hooks, NoFlags );
|
||||
|
||||
if (firsthhook) hooks.insert (hooks.begin(), firsthhook);
|
||||
if (lasthhook ) hooks.push_back(lasthhook );
|
||||
|
@ -1288,7 +1438,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
cdebug_log(145,0) << "Sorted hooks:" << endl;
|
||||
sort( hooks.begin(), hooks.end(), SortHookByY(NoFlags) );
|
||||
sortHookByY( hooks, NoFlags );
|
||||
|
||||
if (firstvhook) hooks.insert (hooks.begin(), firstvhook);
|
||||
if (lastvhook ) hooks.push_back(lastvhook );
|
||||
|
@ -2008,6 +2158,8 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "NetBuilder::load( " << net << " )" << endl;
|
||||
cdebug_tabw(145,1);
|
||||
|
||||
_anabatic = anabatic;
|
||||
|
||||
Hook* sourceHook = NULL;
|
||||
AutoContact* sourceContact = NULL;
|
||||
RoutingPads routingPads = net->getRoutingPads();
|
||||
|
|
|
@ -74,6 +74,13 @@ namespace Anabatic {
|
|||
cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
RoutingPad* rrp = dynamic_cast<RoutingPad*>( rp );
|
||||
if (not rrp) {
|
||||
cerr << Warning( "%s::doRp_AutoContacts(): %s is *not* a RoutingPad."
|
||||
, getTypeName().c_str()
|
||||
, getString(rp).c_str() ) << endl;
|
||||
}
|
||||
|
||||
source = target = NULL;
|
||||
|
||||
Point sourcePosition;
|
||||
|
@ -208,7 +215,7 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Managed Configuration]" << endl;
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X.
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
|
@ -507,7 +514,7 @@ namespace Anabatic {
|
|||
if (getRoutingPads()[0]->getLayer() == Session::getRoutingLayer(2))
|
||||
rpM3 = getRoutingPads()[0];
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByX(NoFlags) ); // increasing X.
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
|
@ -721,7 +728,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "south:" << south() << endl;
|
||||
cdebug_log(145,0) << "north:" << north() << endl;
|
||||
|
||||
sort( getRoutingPads().begin(), getRoutingPads().end(), SortRpByY(NoFlags) ); // increasing Y.
|
||||
sortRpByY( getRoutingPads(), NoFlags ); // increasing Y.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; i++ ) {
|
||||
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||
}
|
||||
|
@ -801,7 +808,10 @@ namespace Anabatic {
|
|||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) return false;
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
|
@ -810,6 +820,7 @@ namespace Anabatic {
|
|||
push( north(), getNorthEastContact() );
|
||||
push( south(), getSouthWestContact() );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace Anabatic {
|
|||
|
||||
vector<Hook*> hooksNS = getNorths();
|
||||
hooksNS.insert( hooksNS.end(), getSouths().begin(), getSouths().end() );
|
||||
sort( hooksNS.begin(), hooksNS.end(), SortHookByX(NoFlags) );
|
||||
sortHookByX( hooksNS, NoFlags );
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
AutoContact* contactW = NULL;
|
||||
|
@ -321,10 +321,14 @@ namespace Anabatic {
|
|||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) return false;
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,475 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2018-2016, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./NetBuilderVH.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/NetRoutingProperty.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/RoutingPads.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/Measures.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/AutoContactTurn.h"
|
||||
#include "anabatic/AutoContactHTee.h"
|
||||
#include "anabatic/AutoContactVTee.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
#include "anabatic/NetBuilderVH.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::swap;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Error;
|
||||
|
||||
|
||||
NetBuilderVH::NetBuilderVH ()
|
||||
: NetBuilder()
|
||||
{ }
|
||||
|
||||
|
||||
NetBuilderVH::~NetBuilderVH () { }
|
||||
|
||||
|
||||
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
, AutoContact*& target
|
||||
, uint64_t flags
|
||||
)
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
source = target = NULL;
|
||||
|
||||
Point sourcePosition;
|
||||
Point targetPosition;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
||||
DbU::Unit gridPosition = 0;
|
||||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
|
||||
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
|
||||
|
||||
GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition );
|
||||
GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition );
|
||||
|
||||
if (rpDepth == 0) {
|
||||
rpLayer = Session::getContactLayer(0);
|
||||
direction = Flags::Vertical;
|
||||
viaSide = Session::getViaWidth( rpDepth );
|
||||
|
||||
RoutingPad* rrp = dynamic_cast<RoutingPad*>( rp );
|
||||
if (rrp) {
|
||||
// if (not getAnabatic()->getConfiguration()->selectRpComponent(rrp)) {
|
||||
// cerr << Warning( "%s::doRp_AutoContacts(): %s has no components on grid."
|
||||
// , getTypeName().c_str()
|
||||
// , getString(rp).c_str() ) << endl;
|
||||
// }
|
||||
} else {
|
||||
cerr << Warning( "%s::doRp_AutoContacts(): %s is *not* a RoutingPad."
|
||||
, getTypeName().c_str()
|
||||
, getString(rp).c_str() ) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
sourceProtect->setFlags( CntFixed );
|
||||
targetProtect->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
|
||||
segment->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
getRpLookup().insert( make_pair(rp,segment) );
|
||||
}
|
||||
}
|
||||
|
||||
if (sourcePosition != targetPosition) {
|
||||
if (flags & DoSourceContact)
|
||||
source = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
if (flags & DoTargetContact)
|
||||
target = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
}
|
||||
|
||||
if (not source and not target) {
|
||||
source = target = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
, rpLayer
|
||||
, rp->getCenter()
|
||||
, viaSide, viaSide
|
||||
);
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
AutoContact* rpContactSource;
|
||||
AutoContact* rpContactTarget;
|
||||
|
||||
flags |= checkRoutingPadSize( rp );
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
||||
|
||||
if (not (flags & (HAccess|HAccessEW))) {
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
rpContactSource = subContact2;
|
||||
} else {
|
||||
if (flags & VSmall) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
rpContactSource = subContact1;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
return rpContactSource;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_1G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
uint64_t flags = NoFlags;
|
||||
if (east() ) { flags |= HAccess|VSmall; }
|
||||
else if (west() ) { flags |= HAccess|VSmall; }
|
||||
|
||||
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_1G_xM1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Defered Configuration]" << endl;
|
||||
|
||||
_do_xG_xM1_xM3();
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_2G_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1 [Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "north: " << north() << endl;
|
||||
cdebug_log(145,0) << "south: " << south() << endl;
|
||||
cdebug_log(145,0) << "east: " << east() << endl;
|
||||
cdebug_log(145,0) << "west: " << west() << endl;
|
||||
|
||||
AutoContact* tee = NULL;
|
||||
|
||||
if (east() and west()) {
|
||||
tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall );
|
||||
} else {
|
||||
AutoContact* turn = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall );
|
||||
|
||||
if (east() or west())
|
||||
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() );
|
||||
else
|
||||
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getDContactLayer() );
|
||||
|
||||
AutoSegment::create( turn, tee, Flags::Horizontal );
|
||||
}
|
||||
setBothCornerContacts( tee );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_xG_xM1_xM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M1
|
||||
<< "M1_" << (int)getConnexity().fields.M3
|
||||
<< "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
|
||||
cdebug_log(145,0) << "north: " << north() << endl;
|
||||
cdebug_log(145,0) << "south: " << south() << endl;
|
||||
cdebug_log(145,0) << "east: " << east() << endl;
|
||||
cdebug_log(145,0) << "west: " << west() << endl;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
size_t iLast = getRoutingPads().size()-1;
|
||||
AutoContact* leftContact = NULL;
|
||||
AutoContact* rightContact = NULL;
|
||||
|
||||
if (south() or west()) {
|
||||
leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall );
|
||||
if (south() and west()) {
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
||||
AutoSegment::create( getSouthWestContact(), leftContact, Flags::Horizontal );
|
||||
} else {
|
||||
if (west())
|
||||
setSouthWestContact( leftContact );
|
||||
else {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
||||
AutoSegment::create( leftContact, getSouthWestContact(), Flags::Horizontal );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<getRoutingPads().size()-1 ; ++i ) {
|
||||
rightContact = doRp_Access( getGCell(), getRoutingPads()[i], HAccessEW|VSmall );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
|
||||
leftContact = rightContact;
|
||||
}
|
||||
|
||||
if (north() or east()) {
|
||||
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
|
||||
if (north() and east()) {
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
||||
AutoSegment::create( rightContact, getNorthEastContact(), Flags::Horizontal );
|
||||
} else {
|
||||
if (east())
|
||||
setNorthEastContact( rightContact );
|
||||
else {
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
||||
AutoSegment::create( rightContact, getNorthEastContact(), Flags::Horizontal );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccess|VSmall );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
if (east() and west()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (south()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
} else {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (west()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
}
|
||||
} else { // fields.globals == 4.
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||
|
||||
if (getSourceContact()) {
|
||||
AutoContact* targetContact
|
||||
= ( getSegmentHookType(getFromHook()) & (NorthBound|EastBound) )
|
||||
? getNorthEastContact() : getSouthWestContact() ;
|
||||
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
|
||||
, targetContact
|
||||
, static_cast<Segment*>( getFromHook()->getComponent() )
|
||||
);
|
||||
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
|
||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
push( east (), getNorthEastContact() );
|
||||
push( west (), getSouthWestContact() );
|
||||
push( north(), getNorthEastContact() );
|
||||
push( south(), getSouthWestContact() );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NetBuilderVH::singleGCell ( AnabaticEngine* anbt, Net* net )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl;
|
||||
|
||||
vector<RoutingPad*> rps;
|
||||
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 0) {
|
||||
rps.push_back( rp );
|
||||
continue;
|
||||
}
|
||||
cerr << Error( "%s::singleGCell(): Non metal1 terminals are not managed yet.\n"
|
||||
" (%s)"
|
||||
, getTypeName().c_str()
|
||||
, getString(rp).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rps.size() < 2) {
|
||||
cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)."
|
||||
, getTypeName().c_str()
|
||||
, getString(net).c_str()
|
||||
, rps.size() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rps.empty()) {
|
||||
cerr << Error( "%s::singleGCell(): No terminals for Net \"%s\"."
|
||||
, getTypeName().c_str()
|
||||
, getString(net->getName()).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
sortRpByX( rps, NetBuilder::NoFlags ); // increasing X.
|
||||
|
||||
GCell* gcell1 = anbt->getGCellUnder( (*rps.begin ())->getCenter() );
|
||||
GCell* gcell2 = anbt->getGCellUnder( (*rps.rbegin())->getCenter() );
|
||||
|
||||
if (not gcell1) {
|
||||
cerr << Error( "%s::singleGCell(): No GCell under %s."
|
||||
, getTypeName().c_str()
|
||||
, getString(*(rps.begin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
if (gcell1 != gcell2) {
|
||||
cerr << Error( "%s::singleGCell(): Not under a single GCell %s."
|
||||
, getTypeName().c_str()
|
||||
, getString(*(rps.rbegin())).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "singleGCell " << gcell1 << endl;
|
||||
|
||||
AutoContact* source = NULL;
|
||||
AutoContact* target = NULL;
|
||||
|
||||
for ( size_t irp=1 ; irp<rps.size() ; ++irp ) {
|
||||
source = doRp_Access( gcell1, rps[irp-1], HAccess|VSmall );
|
||||
target = doRp_Access( gcell1, rps[irp ], HAccess|VSmall );
|
||||
AutoSegment::create( source, target, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
string NetBuilderVH::getTypeName () const
|
||||
{ return "NetBuilderVH"; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -507,7 +507,7 @@ namespace Anabatic {
|
|||
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
|
||||
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
|
||||
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
|
||||
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); }
|
||||
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
|
||||
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); }
|
||||
inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); }
|
||||
inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
namespace Hurricane {
|
||||
class Layer;
|
||||
class Cell;
|
||||
class RoutingPad;
|
||||
}
|
||||
|
||||
namespace CRL {
|
||||
|
@ -43,6 +44,7 @@ namespace Anabatic {
|
|||
using Hurricane::Name;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Cell;
|
||||
using CRL::CellGauge;
|
||||
using CRL::RoutingGauge;
|
||||
|
@ -118,6 +120,8 @@ namespace Anabatic {
|
|||
float getEdgeCostH () const;
|
||||
float getEdgeCostK () const;
|
||||
float getEdgeHInc () const;
|
||||
DbU::Unit isOnRoutingGrid ( RoutingPad* ) const;
|
||||
bool selectRpComponent ( RoutingPad* ) const;
|
||||
virtual void print ( Cell* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
|
|
@ -200,10 +200,13 @@ namespace Anabatic {
|
|||
inline Vertex ( GCell* );
|
||||
//inline Vertex ( size_t id );
|
||||
inline ~Vertex ();
|
||||
inline bool isAnalog () const;
|
||||
inline bool hasDoneAllRps () const;
|
||||
inline Contact* hasGContact ( Net* ) const;
|
||||
inline unsigned int getId () const;
|
||||
inline GCell* getGCell () const;
|
||||
inline Box getBoundingBox () const;
|
||||
inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline Contact* getGContact ( Net* );
|
||||
bool hasValidStamp () const;
|
||||
|
@ -216,6 +219,7 @@ namespace Anabatic {
|
|||
inline int getRpCount () const;
|
||||
Edge* getFrom () const;
|
||||
inline Vertex* getPredecessor () const;
|
||||
inline Vertex* getNeighbor ( Edge* ) const;
|
||||
inline void setDistance ( DbU::Unit );
|
||||
inline void setStamp ( int );
|
||||
inline void setConnexId ( int );
|
||||
|
@ -334,6 +338,9 @@ 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 bool Vertex::isAnalog () const { return _gcell->isAnalog(); }
|
||||
inline Box Vertex::getBoundingBox () const { return _gcell->getBoundingBox(); }
|
||||
inline Edges Vertex::getEdges ( Flags sides ) const { return _gcell->getEdges(sides); }
|
||||
inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); }
|
||||
inline unsigned int Vertex::getId () const { return _id; }
|
||||
inline GCell* Vertex::getGCell () const { return _gcell; }
|
||||
|
@ -361,6 +368,12 @@ namespace Anabatic {
|
|||
inline Vertex* Vertex::getPredecessor () const
|
||||
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; }
|
||||
|
||||
inline Vertex* Vertex::getNeighbor ( Edge* edge ) const
|
||||
{
|
||||
GCell* gcell = edge->getOpposite( getGCell() );
|
||||
return (gcell) ? gcell->getObserver<Vertex>(GCell::Observable::Vertex) : NULL;
|
||||
}
|
||||
|
||||
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
|
|
|
@ -84,19 +84,20 @@ namespace Anabatic {
|
|||
enum FunctionFlags { NoFlags = (1 << 0)
|
||||
, SortDecreasing = (1 << 1)
|
||||
, HAccess = (1 << 2)
|
||||
, VSmall = (1 << 3)
|
||||
, HSmall = (1 << 4)
|
||||
, Punctual = (1 << 5)
|
||||
, HCollapse = (1 << 6)
|
||||
, VCollapse = (1 << 7)
|
||||
, Terminal = (1 << 8)
|
||||
, DoSourceContact = (1 << 9)
|
||||
, DoTargetContact = (1 << 10)
|
||||
, SouthBound = (1 << 11)
|
||||
, NorthBound = (1 << 12)
|
||||
, WestBound = (1 << 13)
|
||||
, EastBound = (1 << 14)
|
||||
, Middle = (1 << 15)
|
||||
, HAccessEW = (1 << 3)
|
||||
, VSmall = (1 << 4)
|
||||
, HSmall = (1 << 5)
|
||||
, Punctual = (1 << 6)
|
||||
, HCollapse = (1 << 7)
|
||||
, VCollapse = (1 << 8)
|
||||
, Terminal = (1 << 9)
|
||||
, DoSourceContact = (1 << 10)
|
||||
, DoTargetContact = (1 << 11)
|
||||
, SouthBound = (1 << 12)
|
||||
, NorthBound = (1 << 13)
|
||||
, WestBound = (1 << 14)
|
||||
, EastBound = (1 << 15)
|
||||
, Middle = (1 << 16)
|
||||
, SouthWest = SouthBound|WestBound
|
||||
, NorthEast = NorthBound|EastBound
|
||||
};
|
||||
|
@ -137,11 +138,16 @@ namespace Anabatic {
|
|||
static uint64_t checkRoutingPadSize ( Component* anchor );
|
||||
static Hook* getSegmentOppositeHook ( Hook* hook );
|
||||
static uint64_t getSegmentHookType ( Hook* hook );
|
||||
static void sortHookByX ( vector<Hook*>& , uint64_t flags=NoFlags );
|
||||
static void sortHookByY ( vector<Hook*>& , uint64_t flags=NoFlags );
|
||||
static void sortRpByX ( vector<RoutingPad*>& , uint64_t flags=NoFlags );
|
||||
static void sortRpByY ( vector<RoutingPad*>& , uint64_t flags=NoFlags );
|
||||
public:
|
||||
NetBuilder ();
|
||||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline bool isTwoMetals () const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline unsigned int getDegree () const;
|
||||
inline void setDegree ( unsigned int degree );
|
||||
void fixSegments ();
|
||||
|
@ -191,7 +197,6 @@ namespace Anabatic {
|
|||
virtual AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags );
|
||||
void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 );
|
||||
void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
|
||||
void singleGCell ( AnabaticEngine*, Net* );
|
||||
void _load ( AnabaticEngine*, Net* );
|
||||
private:
|
||||
virtual bool _do_xG ();
|
||||
|
@ -208,6 +213,7 @@ namespace Anabatic {
|
|||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
AutoContact* _doHChannel ();
|
||||
AutoContact* _doVChannel ();
|
||||
AutoContact* _doStrut ();
|
||||
|
@ -292,6 +298,7 @@ namespace Anabatic {
|
|||
|
||||
// Attributes.
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
ForkStack _forks;
|
||||
UConnexity _connexity;
|
||||
unsigned int _topology;
|
||||
|
@ -313,41 +320,11 @@ namespace Anabatic {
|
|||
|
||||
// Sort classes.
|
||||
public:
|
||||
class SortHookByX {
|
||||
public:
|
||||
inline SortHookByX ( uint64_t flags );
|
||||
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
class SortHookByY {
|
||||
public:
|
||||
inline SortHookByY ( uint64_t flags );
|
||||
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
class SortRpByX {
|
||||
public:
|
||||
inline SortRpByX ( uint64_t flags );
|
||||
inline bool operator() ( Component* rp1, Component* rp2 );
|
||||
private:
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
class SortRpByY {
|
||||
public:
|
||||
inline SortRpByY ( uint64_t flags );
|
||||
inline bool operator() ( Component* rp1, Component* rp2 );
|
||||
protected:
|
||||
uint64_t _flags;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; }
|
||||
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
|
||||
inline unsigned int NetBuilder::getDegree () const { return _degree; }
|
||||
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
|
||||
inline NetBuilder::UConnexity& NetBuilder::getConnexity () { return _connexity; }
|
||||
|
@ -389,102 +366,6 @@ namespace Anabatic {
|
|||
template< typename BuilderT >
|
||||
void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortRpByX".
|
||||
|
||||
inline NetBuilder::SortRpByX::SortRpByX ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool NetBuilder::SortRpByX::operator() ( Component* rp1, Component* rp2 )
|
||||
{
|
||||
DbU::Unit x1 = rp1->getCenter().getX();
|
||||
DbU::Unit x2 = rp2->getCenter().getX();
|
||||
|
||||
if (x1 == x2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortRpByY".
|
||||
|
||||
inline NetBuilder::SortRpByY::SortRpByY ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool NetBuilder::SortRpByY::operator() ( Component* rp1, Component* rp2 )
|
||||
{
|
||||
DbU::Unit y1 = rp1->getCenter().getY();
|
||||
DbU::Unit y2 = rp2->getCenter().getY();
|
||||
|
||||
if (y1 == y2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortHookByX".
|
||||
|
||||
inline NetBuilder::SortHookByX::SortHookByX ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool NetBuilder::SortHookByX::operator() ( Hook* h1, Hook* h2 )
|
||||
{
|
||||
DbU::Unit x1 = 0;
|
||||
DbU::Unit x2 = 0;
|
||||
Horizontal* hh1 = dynamic_cast<Horizontal*>(h1->getComponent());
|
||||
Horizontal* hh2 = dynamic_cast<Horizontal*>(h2->getComponent());
|
||||
Vertical* vv1 = dynamic_cast<Vertical*> (h1->getComponent());
|
||||
Vertical* vv2 = dynamic_cast<Vertical*> (h2->getComponent());
|
||||
|
||||
if (hh1) x1 = std::min( hh1->getSource()->getX(), hh1->getTarget()->getX() );
|
||||
else if (vv1) x1 = vv1->getX();
|
||||
else x1 = h1->getComponent()->getCenter().getX();
|
||||
|
||||
if (hh2) x2 = std::min( hh2->getSource()->getX(), hh2->getTarget()->getX() );
|
||||
else if (vv2) x2 = vv2->getX();
|
||||
else x2 = h2->getComponent()->getCenter().getX();
|
||||
|
||||
if (x1 == x2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (x1 < x2);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder::SortHookByY".
|
||||
|
||||
inline NetBuilder::SortHookByY::SortHookByY ( uint64_t flags )
|
||||
: _flags(flags)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool NetBuilder::SortHookByY::operator() ( Hook* h1, Hook* h2 )
|
||||
{
|
||||
DbU::Unit y1 = 0;
|
||||
DbU::Unit y2 = 0;
|
||||
Horizontal* hh1 = dynamic_cast<Horizontal*>(h1->getComponent());
|
||||
Horizontal* hh2 = dynamic_cast<Horizontal*>(h2->getComponent());
|
||||
Vertical* vv1 = dynamic_cast<Vertical*> (h1->getComponent());
|
||||
Vertical* vv2 = dynamic_cast<Vertical*> (h2->getComponent());
|
||||
|
||||
if (vv1) y1 = std::min( vv1->getSource()->getY(), vv1->getTarget()->getY() );
|
||||
else if (hh1) y1 = hh1->getY();
|
||||
else y1 = h1->getComponent()->getCenter().getX();
|
||||
|
||||
if (vv2) y2 = std::min( vv2->getSource()->getY(), vv2->getTarget()->getY() );
|
||||
else if (hh2) y2 = hh2->getY();
|
||||
else y2 = h2->getComponent()->getCenter().getY();
|
||||
|
||||
if (y1 == y2) return false;
|
||||
return (_flags & NetBuilder::SortDecreasing) xor (y1 < y2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_H
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2017-2016, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_VH_H
|
||||
#define ANABATIC_NET_BUILDER_VH_H
|
||||
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "NetBuilderVH".
|
||||
|
||||
class NetBuilderVH : public NetBuilder {
|
||||
public:
|
||||
NetBuilderVH ();
|
||||
virtual ~NetBuilderVH ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_VH_H
|
Loading…
Reference in New Issue