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:
Jean-Paul Chaput 2018-01-06 16:55:53 +01:00
parent 3d0431b238
commit 9b2648241d
19 changed files with 1055 additions and 355 deletions

View File

@ -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() );
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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) );

View File

@ -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()

View File

@ -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';

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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() ); }

View File

@ -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;

View File

@ -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(); }

View File

@ -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

View File

@ -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