Added direct management of macro blocks I/O pins in METAL2 & METAL3.

The decoupling of the cell gauge and the routing gauge implies that
the METAL2 & METAL3 terminals of macro blocks cannot be aligned on
the routing tracks anymore. That is, an horizontal METAL2 terminal
will not be on a track axis, but offgrid, so we no longer can use
a METAL2 horizontal segment to connect to it. Making an adjustement
between the offgrid terminal and the on-grid segment has proven
too complex and generating difficult configuration for the router.
Moreover, METLA2 terminal could be fully inside a METAL2 blockage.
So now, when the gauges are decoupled, we connect the METAL2 and
METAL3 the same way we do for METAL1: *from above* in the perpandicular
direction and using a *sliding* VIA. We assume that those kind of
terminals in upper metals are quite long.

* New: In Hurricane::Rectilinear, export the isNonRectangle() method
    to the Python interface.
* New: In CRL::RoutingGauge, add function isSuperPitched() with the
    associated boolean attribute. Set to true when each pitch of
    each layer is independant (not low fractional multiples).
* New: In AnabaticEngine, add the ability to temporarily disable the
    canonize() operation (mainly used in dogleg creation).
* New: In AutoSegment::canonize(), do nothing if the operation is
    disabled by AnabaticEngine.
* Bug: In Session::_revalidateTopology(), disable the canonization
    during the topology updating of a net. Too early canonization
    was occuring in makeDogleg() leading to incoherencies when
    performing the later canonization stage over the complete net.
    Mostly occured in the initial build stage of the net.
* New: In GCell, add function postGlobalAnnotate(), if a layer
    is fully blocked (above 0.9), typically, under a blockage,
    add a further capacity decrease of 2 on the edges. So we may
    handle a modicum of doglegs.
* Bug; In GCell::addBlockage(), removeContact(), removeHSegment()
    and removeVSegment(), forgot to set the Invalidated flag.
    This may have lead to innacurate densities.
* Change: In GCell::updateDensity(), more complex setting of the
    GoStraight flag. This flag is now set if we don't have two
    *contiguous* below 60% of density. We need free contiguous
    layers to make doglegs.
* New: In NetBuilder, now manage a current state flag along
    with the state flag of the *source* GCell. This flag is used
    to tell if the GCell needs it's *global* routing to be done
    using the upper layers (METAL4 & METAL5) instead of the
    lower ones.
* New: In NetBuilder::setStartHook(), set the state flag of the
    GCell to ToUpperRouting when processing a global routing
    articulation and one of the base layer is obstructed
    above 0.9.
      In GCell with terminals, also set ToUpperRouting when there
    are some in METAL2 / METAL3 and the gauge is not super-pitched.
* New: In NetBuilder, function isInsideBlockage(), to check if a
    terminal is completely or partially enclosed in a blockage.
* Change: In NetBuilderHV::doRp_AutoContact(), remove support for
    trying to put on grid misaligned METAL2/METAL3.
      Instead systematically access them from above.
      Do not cover with fixed protection terminals that are already
    enclosed in blockages.
* Bug: In NetBuilderHV::doRp_AutoContact(), always add the terminal
    contact in the requested GCell and not the target/source one,
    in case the terminal span several GCells.
* Change: In NetBuilderHV::doRp_Access(), create the local wiring
    according to the RoutingPad layer.
* Change: In NetBuilderHV::_do_xG(), _do_2G(),
    create the global wiring in upper layers, according to the
    ToUpperRouting flag.
* Change: In NetBuilderHV::_do_xG_xM3(), now delegate to
    _do_xG_xM3_baseRouting() and _do_xG_xM3_upperRouting() if the
    density at terminal level is above 0.5.
* New: NetBuilderHV::_do_xG_xM3_baseRouting() and
    _do_xG_xM3_upperRouting() separated function to manage the
    local routing.
* Change: In NetBuilder::_do_globalSegment(), if the currently
    processed GCell or it's source is in ToUpperRouting mode,
    move up the global segment. Do *not* use the moveUp() function
    which would create doglegs unwanted at this stage.
* New: In KatanaEngine::annotateGlobalGraph(), call postGlobalAnnotate()
    on the GCell after the blockages have been taken into accound to
    add the penalty.
* Bug: In Track::getPrevious(), correctly manage the 0 value for the
    index argument. Strange it didn't show earlier.
      Same goes for Track::expandFreeInterval().
This commit is contained in:
Jean-Paul Chaput 2022-04-27 21:56:41 +02:00
parent 908231c4c4
commit cd60032d9c
25 changed files with 541 additions and 230 deletions

View File

@ -183,19 +183,26 @@ namespace Anabatic {
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
{
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
minDepth = (size_t)-1;
maxDepth = 0;
Component* anchor = getAnchor ();
if (anchor) {
cdebug_log(145,0) << "* Anchor depth: "
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
}
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
cdebug_log(145,0) << "* segment depth: "
<< Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
}
cdebug_tabw(145,-1);
}

View File

@ -559,11 +559,11 @@ namespace Anabatic {
if (delta > 1) {
//_segment = _segment->makeDogleg( this );
_segment->makeDogleg( this );
cdebug_log(145,0) << "Update seg: " << _segment << endl;
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
}
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
}
_segment->invalidate( this );

View File

@ -770,16 +770,16 @@ namespace Anabatic {
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
else cap = getViaToSameCap (depth);
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
<< " VIA cap:" << DbU::getValueString(cap)
<< " t:" << (getFlags() & SegSourceBottom)
<< " b:" << (getFlags() & SegSourceTop)
<< endl;
// cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
// << " VIA cap:" << DbU::getValueString(cap)
// << " t:" << (getFlags() & SegSourceBottom)
// << " b:" << (getFlags() & SegSourceTop)
// << endl;
if (not (flags & Flags::NoSegExt)) {
cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
// cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
if (-getDuSource() > cap) {
cap = -getDuSource();
cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
// cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
}
}
}
@ -788,16 +788,16 @@ namespace Anabatic {
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
else cap = getViaToSameCap (depth);
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
<< " VIA cap:" << DbU::getValueString(cap)
<< " t:" << (getFlags() & SegSourceBottom)
<< " b:" << (getFlags() & SegSourceTop)
<< endl;
// cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
// << " VIA cap:" << DbU::getValueString(cap)
// << " t:" << (getFlags() & SegSourceBottom)
// << " b:" << (getFlags() & SegSourceTop)
// << endl;
if (not (flags & Flags::NoSegExt)) {
cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
// cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
if (getDuTarget() > cap) {
cap = getDuTarget();
cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
// cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
}
}
}
@ -1455,6 +1455,7 @@ namespace Anabatic {
AutoSegment* AutoSegment::canonize ( Flags flags )
{
cdebug_log(149,0) << "canonize() - " << this << endl;
if (Session::getAnabatic()->isCanonizeDisabled()) return this;
// if (isCanonical() and isGlobal()) {
// cdebug_log(149,0) << "* " << this << " canonical" << endl;

View File

@ -53,6 +53,7 @@ namespace Anabatic {
const BaseFlags Flags::DestroyGCell = (1L << 7);
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
const BaseFlags Flags::DisableCanonize = (1L << 10);
// Flags for NetDatas objects states only.
const BaseFlags Flags::GlobalFixed = (1L << 5);
const BaseFlags Flags::GlobalEstimated = (1L << 6);

View File

@ -1343,6 +1343,26 @@ namespace Anabatic {
}
void GCell::postGlobalAnnotate ()
{
if (isInvalidated()) updateDensity();
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
RoutingLayerGauge* rlg = Session::getLayerGauge( depth );
if (rlg->getType() & Constant::PinOnly) continue;
if (_densities[depth] >= 0.9) {
if (depth+2 < _depth) {
Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge()
: getEastEdge();
if (edge) {
edge->reserveCapacity( 2 );
}
}
}
}
}
void GCell::addBlockage ( size_t depth, DbU::Unit length )
{
if (depth >= _depth) return;
@ -1371,6 +1391,7 @@ namespace Anabatic {
if (found) {
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
_contacts.pop_back();
_flags |= Flags::Invalidated;
} else {
cerr << Bug("%p:%s do not belong to %s."
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
@ -1404,6 +1425,7 @@ namespace Anabatic {
, _getString().c_str(), getString(segment).c_str() ) << endl;
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
_flags |= Flags::Invalidated;
}
@ -1429,6 +1451,7 @@ namespace Anabatic {
, getString(segment).c_str() ) << endl;
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
_flags |= Flags::Invalidated;
}
@ -1528,13 +1551,20 @@ namespace Anabatic {
}
// Add the blockages.
int contiguousNonSaturated = 0;
for ( size_t i=0 ; i<_depth ; i++ ) {
uLengths2[i] += _blockages[i];
if (not i) continue;
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) {
flags() |= Flags::GoStraight;
//cerr << "| Set GoStraight on " << this << endl;
}
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
continue;
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
contiguousNonSaturated = 0;
else
contiguousNonSaturated++;
}
if (contiguousNonSaturated < 2) {
flags() |= Flags::GoStraight;
//cerr << "| Set GoStraight on " << this << endl;
}
// Compute the number of non pass-through tracks.
@ -1880,6 +1910,13 @@ namespace Anabatic {
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_densities[depth] ) );
}
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth);
s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_feedthroughs[depth] ) );
}
return record;
}

View File

@ -37,6 +37,7 @@
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Rectilinear.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h"
@ -220,6 +221,7 @@ namespace Anabatic {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Bug;
using Hurricane::Rectilinear;
// -------------------------------------------------------------------
@ -367,6 +369,8 @@ namespace Anabatic {
, _toFixSegments ()
, _degree (0)
, _isTwoMetals (false)
, _sourceFlags (0)
, _flags (0)
{ }
@ -377,6 +381,8 @@ namespace Anabatic {
void NetBuilder::clear ()
{
_connexity.connexity = 0;
_sourceFlags = 0;
_flags = 0;
_topology = 0;
_net = NULL;
_netData = NULL;
@ -403,11 +409,15 @@ namespace Anabatic {
}
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact )
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt
, Hook* fromHook
, AutoContact* sourceContact
, uint64_t sourceFlags )
{
clear();
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
_sourceFlags = sourceFlags;
_sourceContact = sourceContact;
_fromHook = fromHook;
@ -470,6 +480,12 @@ namespace Anabatic {
throw Error( mismatchGCell );
}
if ( (_gcell->getDensity( Session::getDHorizontalDepth() ) > 0.9)
or (_gcell->getDensity( Session::getDVerticalDepth () ) > 0.9)) {
cdebug_log(145,0) << "Base layers blockeds, moving up" << endl;
_flags |= ToUpperRouting;
}
if (not _gcell->isMatrix()) {
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
cdebug_log(145,0) << "| " << gcell << endl;
@ -489,11 +505,23 @@ namespace Anabatic {
continue;
}
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V
size_t rpDepth = 0;
for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
rpDepth = depth;
break;
}
}
if ((rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched()) {
_flags |= ToUpperRouting;
cdebug_log(145,0) << "ToUpperRouting set, getFlags():" << getFlags() << endl;
}
if (rpDepth == 0) _connexity.fields.M1++; // M1 V
else if (rpDepth == 1) _connexity.fields.M2++; // M2 H
else if (rpDepth == 2) _connexity.fields.M3++; // M3 V
else if (rpDepth == 3) _connexity.fields.M2++; // M4 H
else if (rpDepth == 4) _connexity.fields.M3++; // M5 V
else {
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
, getString(layer->getName()).c_str()
@ -553,6 +581,7 @@ namespace Anabatic {
cdebug_log(145,0) << "NetBuilder::push()" << endl;
cdebug_log(145,0) << "* toHook: " << toHook << endl;
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
cdebug_log(145,0) << "* flags:" << flags << endl;
if (not toHook or (toHook == _fromHook)) {
if (contact) {
@ -571,12 +600,60 @@ namespace Anabatic {
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
_forks.push( toHookOpposite, contact );
_forks.push( toHookOpposite, contact, getFlags() );
return true;
}
bool NetBuilder::isInsideBlockage ( GCell* gcell, Component* rp ) const
{
cdebug_log(145,1) << getTypeName() << "::isInsideBlockage() " << endl;
cdebug_log(145,0) << rp << endl;
cdebug_log(145,0) << rp->getLayer()->getMask() << endl;
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
if (gcell->getDensity(rpDepth) < 0.5) {
cdebug_tabw(145,-1);
return false;
}
Box rpBb = rp->getBoundingBox();
Layer::Mask rpMask = rp->getLayer()->getBlockageLayer()->getMask();
cdebug_log(145,0) << "rpBb: " << rpBb << endl;
for ( Occurrence occurrence : getAnabatic()->getCell()->getOccurrencesUnder(rpBb) ) {
cdebug_log(145,0) << "| " << occurrence.getEntity() << endl;
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
if (not component) continue;
const Layer* blockageLayer = component->getLayer();
Box blockageBb = component->getBoundingBox();
cdebug_log(145,0) << " Mask: " << blockageLayer->getMask() << endl;
if ( blockageLayer->isBlockage()
and (blockageLayer->getMask() == rpMask)) {
occurrence.getPath().getTransformation().applyOn( blockageBb );
cdebug_log(145,0) << " Bb: " << blockageBb << endl;
if (blockageBb.contains(rpBb)) {
cdebug_log(145,-1) << "* Inside " << component << endl;
return true;
}
if (blockageBb.intersect(rpBb)) {
cerr << Warning( "NetBuilder::isInsideBlockage(): RoutingPad is only partially inside blocked area.\n"
" * %s\n"
" * %s"
, getString(rp).c_str()
, getString(component).c_str()
) << endl;
cdebug_log(145,-1) << "* Partially inside " << component << endl;
return true;
}
}
}
cdebug_tabw(145,-1);
return false;
}
void NetBuilder::construct ()
{
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
@ -589,6 +666,8 @@ namespace Anabatic {
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
<< " getFlags():" << getFlags() << endl;
if (not isTwoMetals()) {
_southWestContact = NULL;
@ -2374,6 +2453,7 @@ namespace Anabatic {
Hook* sourceHook = NULL;
AutoContact* sourceContact = NULL;
uint64_t sourceFlags = NoFlags;
RoutingPads routingPads = net->getRoutingPads();
size_t degree = routingPads.getSize();
@ -2412,7 +2492,7 @@ namespace Anabatic {
++connecteds;
segmentFound = true;
setStartHook( anabatic, hook, NULL );
setStartHook( anabatic, hook, NULL, NoFlags );
if (getStateG() == 1) {
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
@ -2440,9 +2520,9 @@ namespace Anabatic {
}
cdebug_tabw(145,-1);
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
setStartHook( anabatic, startHook, NULL );
setStartHook( anabatic, startHook, NULL, NoFlags );
cdebug_log(145,0) << endl;
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
cdebug_log(145,0) << endl;
@ -2451,18 +2531,21 @@ namespace Anabatic {
sourceHook = _forks.getFrom ();
sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop();
while ( sourceHook ) {
setStartHook( anabatic, sourceHook, sourceContact );
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
construct();
sourceHook = _forks.getFrom();
sourceHook = _forks.getFrom ();
sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop();
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
}
Session::revalidate();
@ -2473,10 +2556,11 @@ namespace Anabatic {
for ( ; iover != overconstraineds.end() ; ++iover ) {
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
}
Session::revalidate();
#endif
Session::revalidate();
fixSegments();
Session::revalidate();
cdebug_tabw(145,-1);
//DebugSession::close();

View File

@ -104,6 +104,7 @@ namespace Anabatic {
viaSide = Session::getViaWidth( rpDepth );
}
#if THIS_IS_DISABLED
// Non-M1 terminal or punctual M1 protections.
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
@ -177,17 +178,44 @@ namespace Anabatic {
getRpLookup().insert( make_pair(rp,segment) );
}
}
#endif
// Non-M1 terminal or punctual M1 protections.
if (isInsideBlockage(gcell,rp)) flags |= NoProtect;
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
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
source = AutoContactTerminal::create( gcell
, rp
, rpLayer
, sourcePosition
, viaSide, viaSide
);
if (flags & DoTargetContact)
target = AutoContactTerminal::create( targetGCell
target = AutoContactTerminal::create( gcell
, rp
, rpLayer
, targetPosition
@ -245,7 +273,7 @@ namespace Anabatic {
if (flags & (VSmall|UseNonPref)) {
cdebug_log(145,0) << "case: UseNonPref" << endl;
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
rpSourceContact = subContact1;
}
@ -254,19 +282,19 @@ namespace Anabatic {
cdebug_log(145,0) << "case: HSmall" << endl;
AutoContact* subContact1 = rpSourceContact;
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
rpSourceContact = subContact2;
if (flags & Punctual) {
cdebug_log(145,0) << "case: HSmall + Punctual" << endl;
subContact1 = subContact2;
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( subContact1, subContact2, Flags::Vertical, rpDepth+2 );
subContact1 = subContact2;
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
rpSourceContact = subContact2;
}
@ -277,12 +305,14 @@ namespace Anabatic {
AutoContact* subContact1 = NULL;
if (flags & HAccess) {
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
cdebug_log(145,0) << "HAccess" << endl;
if (flags & HAccessEW) {
cdebug_log(145,0) << "HAccessEW" << endl;
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
} else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical, rpDepth+1 );
} else {
#if OFFGRID_M2_DISABLED
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
@ -299,9 +329,14 @@ namespace Anabatic {
rpSourceContact = subContact1;
}
#endif
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
if (Session::getRoutingGauge()->isSuperPitched()) {
cdebug_log(145,0) << "Vertical access & super-pitched" << endl;
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
} else {
cdebug_log(145,0) << "Vertical access" << endl;
subContact1 = rpSourceContact;
}
}
rpSourceContact = subContact1;
}
@ -456,7 +491,15 @@ namespace Anabatic {
{
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
const Layer* viaLayer = Session::getDContactLayer();
size_t hDepth = Session::getDHorizontalDepth();
size_t vDepth = Session::getDVerticalDepth();
size_t cDepth = Session::getDContactDepth();
if (getFlags() & ToUpperRouting) {
hDepth += 2;
vDepth += 2;
cDepth += 2;
}
const Layer* viaLayer = Session::getContactLayer( cDepth );
if (getConnexity().fields.globals == 2) {
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
@ -466,20 +509,20 @@ namespace Anabatic {
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
if (south()) swapCornerContacts();
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth );
} else {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
if (west()) swapCornerContacts();
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth );
}
} 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 );
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal, hDepth );
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical , vDepth );
}
cdebug_tabw(145,-1);
return true;
@ -490,16 +533,24 @@ namespace Anabatic {
{
cdebug_log(145,1) << getTypeName() << "::_do_2G()" << endl;
const Layer* viaLayer = Session::getDContactLayer();
size_t hDepth = Session::getDHorizontalDepth();
size_t vDepth = Session::getDVerticalDepth();
size_t cDepth = Session::getDContactDepth();
if (getFlags() & ToUpperRouting) {
hDepth += 2;
vDepth += 2;
cDepth += 2;
}
const Layer* viaLayer = Session::getContactLayer( cDepth );
if (east() and west()) {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth );
} else if (south() and north()) {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth );
} else {
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
}
@ -1568,7 +1619,7 @@ namespace Anabatic {
biggestRp = getRoutingPads()[i];
}
const Layer* viaLayer1 = Session::getContactLayer(1);
const Layer* viaLayer1 = Session::getContactLayer(1);
if (east() and west() and not south() and not north()) {
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess );
@ -1580,6 +1631,7 @@ namespace Anabatic {
if (west() and not south()) {
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
} else if (not west() and south()) {
cdebug_log(145,1) << "case: not west and south" << endl;
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
} else if (west() and south()) {
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
@ -1590,6 +1642,7 @@ namespace Anabatic {
if (east() and not north()) {
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
} else if (not east() and north()) {
cdebug_log(145,1) << "case: not east and north" << endl;
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
} else if (east() and north()) {
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
@ -1605,6 +1658,7 @@ namespace Anabatic {
bool NetBuilderHV::_do_1G_1M3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M3() [Optimised Configuration]" << endl;
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
uint64_t flags = (east() or west()) ? HAccess : NoFlags;
flags |= (north()) ? DoTargetContact : NoFlags;
@ -1622,6 +1676,13 @@ namespace Anabatic {
cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl;
cdebug_log(145,0) << "_northEast: " << getNorthEastContact() << endl;
if (not (east() or west())) {
AutoContact* subContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer((rpDepth)) );
AutoSegment::create( getSouthWestContact(), subContact, Flags::Horizontal, rpDepth+1 );
setBothCornerContacts( subContact );
}
#if THIS_IS_DISABLED
const Layer* viaLayer1 = Session::getContactLayer(1);
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
@ -1658,6 +1719,7 @@ namespace Anabatic {
setBothCornerContacts( turn2 );
}
}
#endif
cdebug_tabw(145,-1);
return true;
}
@ -1665,9 +1727,28 @@ namespace Anabatic {
bool NetBuilderHV::_do_xG_xM3 ()
{
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
if (getGCell()->getDensity(rpDepth) > 0.5)
return _do_xG_xM3_upperRouting();
return _do_xG_xM3_baseRouting();
}
bool NetBuilderHV::_do_xG_xM3_baseRouting ()
{
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
size_t vDepth = rpDepth + 2;
size_t hDepth = rpDepth + 1;
const Layer* viaLayer = Session::getContactLayer( rpDepth );
if (Session::getRoutingGauge()->isSuperPitched()) {
viaLayer = Session::getContactLayer( 1 );
vDepth = 2;
hDepth = 1;
}
cdebug_log(145,1) << getTypeName()
<< "::_do_xG_" << (int)getConnexity().fields.M3
<< "M3() [Managed Configuration]" << endl;
<< "M3_baseRouting() [Managed Configuration]" << endl;
cdebug_log(145,0) << "west:" << west() << endl;
cdebug_log(145,0) << "east:" << east() << endl;
cdebug_log(145,0) << "south:" << south() << endl;
@ -1678,7 +1759,6 @@ namespace Anabatic {
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
}
const Layer* viaLayer1 = Session::getContactLayer(1);
AutoContact* unusedContact = NULL;
Component* rp = getRoutingPads()[0];
@ -1691,18 +1771,18 @@ namespace Anabatic {
cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX())
<< "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl;
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical , vDepth );
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
setSouthWestContact( turn2 );
}
}
} else if (west() and south()) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact );
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical, vDepth );
}
rp = getRoutingPads()[getRoutingPads().size()-1];
@ -1715,18 +1795,102 @@ namespace Anabatic {
cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX())
<< "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl;
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical );
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical , vDepth );
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
setNorthEastContact( turn2 );
}
}
} else if (east() and north()) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact );
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical, vDepth );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHV::_do_xG_xM3_upperRouting ()
{
cdebug_log(145,1) << getTypeName()
<< "::_do_xG_" << (int)getConnexity().fields.M3
<< "M3_upperRouting() [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;
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
sortRpByY( getRoutingPads(), NoFlags ); // increasing Y.
for ( size_t i=1 ; i<getRoutingPads().size() ; i++ ) {
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
}
if ((int)getConnexity().fields.M3 != 1) return false;
const Layer* viaLayer2 = Session::getContactLayer(rpDepth);
if (getConnexity().fields.globals == 2) {
if (north() and south()) {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
contact1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
setNorthEastContact( contact1 );
setSouthWestContact( contact2 );
} else if (east() and west()) {
AutoContact* contact1 = NULL;
AutoContact* contact2 = NULL;
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
setSouthWestContact( contact1 );
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
setNorthEastContact( contact1 );
} else {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
contact1 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Vertical, rpDepth+2 );
setBothCornerContacts( contact1 );
}
} else if (getConnexity().fields.globals == 3) {
if (not west() or not east()) {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
setSouthWestContact( (east()) ? contact2 : contact3 );
setNorthEastContact( (east()) ? contact3 : contact2 );
} else {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Vertical, rpDepth+2 );
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
setSouthWestContact( (north()) ? contact2 : contact3 );
setNorthEastContact( (north()) ? contact3 : contact2 );
}
} else {
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
AutoContact* contact4 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
AutoSegment::create( contact2, contact4, Flags::Vertical, rpDepth+2 );
setSouthWestContact( contact3 );
setNorthEastContact( contact4 );
}
cdebug_tabw(145,-1);
@ -1737,6 +1901,8 @@ namespace Anabatic {
bool NetBuilderHV::_do_globalSegment ()
{
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
<< " getFlags():" << getFlags() << endl;
if (getSourceContact()) {
AutoContact* targetContact
@ -1744,7 +1910,16 @@ namespace Anabatic {
? getNorthEastContact() : getSouthWestContact() ;
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
if ( (getSourceFlags() | getFlags()) & ToUpperRouting) {
cdebug_log(145,0) << "Moving up global" << endl;
size_t gdepth = Session::getGHorizontalDepth();
if (dynamic_cast<Vertical*>(baseSegment))
gdepth = Session::getGVerticalDepth();
baseSegment->setLayer( Session::getRoutingLayer( gdepth+2 ));
baseSegment->setWidth( Session::getWireWidth( gdepth+2 ));
}
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
, targetContact
, baseSegment

View File

@ -85,7 +85,6 @@ namespace Anabatic {
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 );
@ -114,56 +113,8 @@ namespace Anabatic {
}
}
#if 0
// Quasi-punctual M1 terminal.
if (flags & VSmall) {
Box ab = rp->getCell()->getBoundingBox();
RoutingLayerGauge* gaugeMetal3 = Session::getLayerGauge( 2 );
DbU::Unit metal3axis = gaugeMetal3->getTrackPosition( ab.getYMin()
, ab.getYMax()
, sourcePosition.getY()
, Constant::Nearest );
DbU::Unit viaSideProtect = Session::getViaWidth((size_t)0);
AutoContact* sourceVia12 = AutoContactTerminal::create( sourceGCell
, rp
, Session::getContactLayer(0)
, sourcePosition
, viaSideProtect, viaSideProtect
);
AutoContact* targetVia12 = AutoContactTerminal::create( targetGCell
, rp
, Session::getContactLayer(0)
, targetPosition
, viaSideProtect, viaSideProtect
);
AutoContact* sourceVia23 = AutoContactTurn::create( sourceGCell, net, Session::getContactLayer(1) );
AutoContact* targetVia23 = AutoContactTurn::create( targetGCell, net, Session::getContactLayer(1) );
sourceVia23->setY( metal3axis );
targetVia23->setY( metal3axis );
sourceVia23->setX( sourcePosition.getX() );
targetVia23->setX( targetPosition.getX() );
AutoSegment* segmentS = AutoSegment::create( sourceVia12, sourceVia23, Flags::Vertical );
AutoSegment* segmentT = AutoSegment::create( targetVia12, targetVia23, Flags::Vertical );
AutoSegment* segmentM = AutoSegment::create( sourceVia23, targetVia23, Flags::Horizontal );
sourceVia12->setFlags( CntFixed );
sourceVia23->setFlags( CntFixed );
targetVia12->setFlags( CntFixed );
targetVia23->setFlags( CntFixed );
segmentS->setFlags( AutoSegment::SegFixed );
segmentT->setFlags( AutoSegment::SegFixed );
segmentM->setFlags( AutoSegment::SegFixed );
cdebug_log(145,0) << "Hard protect: " << rp << endl;
cdebug_log(145,0) << "X:" << DbU::getValueString(sourcePosition.getX())
<< " Metal3 Track Y:" << DbU::getValueString(metal3axis) << endl;
}
#endif
// Non-M1 terminal or punctual M1 protections.
if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) {
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
if (irp == getRpLookup().end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
@ -205,6 +156,10 @@ namespace Anabatic {
);
}
if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) {
rpLayer = Session::getContactLayer( rpDepth );
}
if (not source and not target) {
source = target = AutoContactTerminal::create( gcell
, rp
@ -223,28 +178,43 @@ namespace Anabatic {
{
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
AutoContact* rpContactSource;
AutoContact* rpContactTarget;
AutoContact* rpContactSource = NULL;
AutoContact* rpContactTarget = NULL;
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
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) {
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
if (not (flags & (HAccess|HAccessEW))) {
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
rpContactSource = subContact2;
} else {
if (flags & VSmall) {
AutoContact* subContact1 = NULL;
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
rpContactSource = subContact1;
}
}
} else { // RP should be horizontal (M2).
if (flags & (HAccess|HAccessEW)) {
AutoContact* subContact1 = NULL;
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
rpContactSource = subContact1;
}
}

View File

@ -215,6 +215,7 @@ namespace Anabatic {
{
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
_anabatic->disableCanonize();
for ( Net* net : _netInvalidateds ) {
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
_anabatic->updateNetTopology ( net );
@ -222,6 +223,7 @@ namespace Anabatic {
_anabatic->_computeNetOptimals ( net );
//_anabatic->_computeNetTerminals ( net );
}
_anabatic->enableCanonize();
_canonize ();
AutoSegment* segment = NULL;

View File

@ -204,6 +204,7 @@ namespace Anabatic {
public:
static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* );
inline bool isCanonizeDisabled () const;
static const Name& staticGetName ();
virtual const Name& getName () const;
virtual Configuration* getConfiguration ();
@ -227,6 +228,8 @@ namespace Anabatic {
virtual void openSession ();
inline void setState ( EngineState state );
inline void setDensityMode ( uint64_t );
inline void disableCanonize ();
inline void enableCanonize ();
inline void addOv ( Edge* );
inline void removeOv ( Edge* );
inline const NetDatas& getNetDatas () const;
@ -380,6 +383,7 @@ namespace Anabatic {
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
@ -399,6 +403,8 @@ namespace Anabatic {
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
inline void AnabaticEngine::_add ( GCell* gcell )
{

View File

@ -51,6 +51,7 @@ namespace Anabatic {
static const BaseFlags DestroyGCell ; // = (1 << 7);
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
static const BaseFlags DisableCanonize ; // = (1 << 10);
// Flags for NetDatas objects states only.
static const BaseFlags GlobalFixed ; // = (1 << 5);
static const BaseFlags GlobalEstimated ; // = (1 << 6);

View File

@ -259,6 +259,7 @@ namespace Anabatic {
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
void setType ( Flags );
inline void setSatProcessed ( size_t depth );
void postGlobalAnnotate ();
void addBlockage ( size_t depth, DbU::Unit );
inline void addHSegment ( AutoSegment* );
inline void addVSegment ( AutoSegment* );

View File

@ -47,31 +47,39 @@ namespace Anabatic {
class ForkStack {
public:
inline void push ( Hook* from, AutoContact* contact );
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
inline void pop ();
inline Hook* getFrom () const;
inline AutoContact* getContact () const;
inline uint64_t getFlags () const;
inline void setFlags ( uint64_t );
private:
struct Element {
Hook* _from;
AutoContact* _contact;
inline Element ( Hook* from, AutoContact* contact );
uint64_t _flags;
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
};
private:
list<Element> _stack;
};
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {}
inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; }
inline uint64_t ForkStack::getFlags () const { return _stack.empty() ? 0 : _stack.back()._flags; }
inline void ForkStack::setFlags ( uint64_t flags ) { if (not _stack.empty()) _stack.back()._flags |= flags; }
inline void ForkStack::push ( Hook* from, AutoContact* contact )
inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags )
{
cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl;
_stack.push_back( Element(from,contact) );
cdebug_log(145,0) << " Stacking: " << endl;
cdebug_log(145,0) << " + " << from << endl;
cdebug_log(145,0) << " + " << contact << endl;
cdebug_log(145,0) << " + " << flags << endl;
_stack.push_back( Element(from,contact,flags) );
}
@ -99,6 +107,7 @@ namespace Anabatic {
, Middle = (1 << 16)
, UseNonPref = (1 << 17)
, NoProtect = (1 << 18)
, ToUpperRouting = (1 << 19)
, HBothAccess = HAccess|HAccessEW
, SouthWest = SouthBound|WestBound
, NorthEast = NorthBound|EastBound
@ -149,13 +158,15 @@ namespace Anabatic {
virtual ~NetBuilder ();
void clear ();
inline bool isTwoMetals () const;
inline bool isUpperMetalRp () const;
inline AnabaticEngine* getAnabatic () const;
inline unsigned int getDegree () const;
inline void setDegree ( unsigned int degree );
void fixSegments ();
NetBuilder& setStartHook ( AnabaticEngine*
, Hook* fromHook
, AutoContact* sourceContact=NULL );
, AutoContact* sourceContact=NULL
, uint64_t sourceFlags=0 );
void construct ();
inline unsigned int getStateG () const;
inline UConnexity getConnexity () const;
@ -169,6 +180,8 @@ namespace Anabatic {
inline AutoContact* getNorthEastContact () const;
inline AutoContact*& getNorthEastContact ();
inline Hook* getFromHook () const;
inline uint64_t getSourceFlags () const;
inline uint64_t getFlags () const;
inline ForkStack& getForks ();
inline vector<RoutingPad*>& getRoutingPads ();
inline map<Component*,AutoSegment*>& getRpLookup ();
@ -187,6 +200,7 @@ namespace Anabatic {
inline void clearSouths ();
inline void clearEasts ();
inline void clearWests ();
inline void setFlags ( uint64_t );
inline void setFromHook ( Hook* );
inline void setSouthWestContact ( AutoContact* );
inline void setNorthEastContact ( AutoContact* );
@ -194,6 +208,7 @@ namespace Anabatic {
inline void swapCornerContacts ();
inline void addToFixSegments ( AutoSegment* );
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
bool isInsideBlockage ( GCell*, Component* ) const;
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0;
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0;
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
@ -372,9 +387,8 @@ namespace Anabatic {
vector<AutoSegment*> _toFixSegments;
unsigned int _degree;
bool _isTwoMetals;
// Sort classes.
public:
uint64_t _sourceFlags;
uint64_t _flags;
};
@ -394,6 +408,8 @@ namespace Anabatic {
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
inline uint64_t NetBuilder::getSourceFlags () const { return _sourceFlags; }
inline uint64_t NetBuilder::getFlags () const { return _flags; }
inline unsigned int NetBuilder::getTopology () const { return _topology; }
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
@ -403,6 +419,7 @@ namespace Anabatic {
inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; }
inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; }
inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; }
inline void NetBuilder::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; }
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }

View File

@ -13,9 +13,7 @@
// | C++ Header : "./anabatic/NetBuilderHV.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_NET_BUILDER_HV_H
#define ANABATIC_NET_BUILDER_HV_H
#pragma once
#include "anabatic/NetBuilder.h"
@ -28,44 +26,44 @@ namespace Anabatic {
class NetBuilderHV : public NetBuilder {
public:
NetBuilderHV ();
virtual ~NetBuilderHV ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
private:
virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 ();
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
virtual bool _do_xG_1PinM3 ();
virtual bool _do_xG_1M1 ();
virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_4G_1M2 ();
virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 ();
virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_2G_xM1_1PinM3 ();
virtual bool _do_3G_xM1_1PinM3 ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public:
virtual string getTypeName () const;
NetBuilderHV ();
virtual ~NetBuilderHV ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
private:
virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 ();
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
virtual bool _do_xG_1PinM3 ();
virtual bool _do_xG_1M1 ();
virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_4G_1M2 ();
virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 ();
bool _do_xG_xM3_baseRouting ();
bool _do_xG_xM3_upperRouting ();
virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_2G_xM1_1PinM3 ();
virtual bool _do_3G_xM1_1PinM3 ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public:
virtual string getTypeName () const;
};
} // Anabatic namespace.
#endif // ANABATIC_NET_BUILDER_HV_H

View File

@ -13,9 +13,7 @@
// | C++ Header : "./anabatic/NetBuilderVH.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_NET_BUILDER_VH_H
#define ANABATIC_NET_BUILDER_VH_H
#pragma once
#include "anabatic/NetBuilder.h"
@ -50,5 +48,3 @@ namespace Anabatic {
} // Anabatic namespace.
#endif // ANABATIC_NET_BUILDER_VH_H

View File

@ -825,7 +825,7 @@ namespace CRL {
CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const
{
for ( const auto item : _cellGauges ) {
for ( const auto& item : _cellGauges ) {
CellGauge* cg = item.second;
DbU::Unit hcount = width / cg->getSliceStep ();
DbU::Unit hremains = width % cg->getSliceStep ();
@ -842,7 +842,7 @@ namespace CRL {
CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const
{
for ( const auto item : _cellGauges ) {
for ( const auto& item : _cellGauges ) {
CellGauge* cg = item.second;
DbU::Unit vcount = height / cg->getSliceHeight();
DbU::Unit vremains = height % cg->getSliceHeight();

View File

@ -56,20 +56,22 @@ namespace CRL {
RoutingGauge::RoutingGauge ( const char* name )
: _name (name)
, _layerGauges()
, _viaLayers ()
, _technology (DataBase::getDB()->getTechnology())
, _isSymbolic (true)
: _name (name)
, _layerGauges ()
, _viaLayers ()
, _technology (DataBase::getDB()->getTechnology())
, _isSymbolic (true)
, _isSuperPitched(true)
{ }
RoutingGauge::RoutingGauge ( const RoutingGauge& gauge )
: _name (gauge._name)
, _layerGauges()
, _viaLayers ()
, _technology (gauge._technology)
, _isSymbolic (gauge._isSymbolic)
: _name (gauge._name)
, _layerGauges ()
, _viaLayers ()
, _technology (gauge._technology)
, _isSymbolic (gauge._isSymbolic)
, _isSuperPitched(gauge._isSuperPitched)
{
// Make a deep copy of the map.
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
@ -304,6 +306,12 @@ namespace CRL {
}
_viaLayers.push_back( viaLayer );
}
if ((gaugeSize > 3) and _isSuperPitched) {
float r = ((float)layerGauge->getPitch() / (float)_layerGauges[gaugeSize-3]->getPitch());
if (fabsf(roundf(r) - r) > 0.00001f)
_isSuperPitched = false;
}
}

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef CRL_ROUTING_GAUGE_H
#define CRL_ROUTING_GAUGE_H
#pragma once
#include <string>
#include <vector>
#include "hurricane/Name.h"
@ -56,6 +54,7 @@ namespace CRL {
// Predicates.
inline bool isSymbolic () const;
inline bool isTwoMetals () const;
inline bool isSuperPitched () const;
inline bool isHV () const;
inline bool isVH () const;
inline bool hasPowerSupply () const;
@ -109,6 +108,7 @@ namespace CRL {
vector<Layer*> _viaLayers;
Technology* _technology;
bool _isSymbolic;
bool _isSuperPitched;
// Internal - Constructors & Destructors.
RoutingGauge ( const char* name );
@ -120,6 +120,7 @@ namespace CRL {
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; }
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
@ -155,5 +156,3 @@ namespace CRL {
} // CRL namespace.
INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
#endif

View File

@ -504,6 +504,7 @@ extern "C" {
GetNameMethod(RoutingGauge,rg)
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge)
DirectGetBoolAttribute(PyRoutingGauge_isSuperPitched,isSuperPitched,PyRoutingGauge,RoutingGauge)
DirectSetBoolAttribute(PyRoutingGauge_setSymbolic ,setSymbolic ,PyRoutingGauge,RoutingGauge)
DirectGetBoolAttribute(PyRoutingGauge_isHV ,isHV ,PyRoutingGauge,RoutingGauge)
DirectGetBoolAttribute(PyRoutingGauge_isVH ,isVH ,PyRoutingGauge,RoutingGauge)
@ -518,6 +519,8 @@ extern "C" {
, "Create a new RoutingGauge." }
, { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS
, "The RoutingGauge is for symbolic technology." }
, { "isSuperPitched" , (PyCFunction)PyRoutingGauge_isSuperPitched , METH_NOARGS
, "The RoutingGauge is super-pitched." }
, { "isHV" , (PyCFunction)PyRoutingGauge_isHV , METH_NOARGS
, "The first routing layer (metal2) is horizontal." }
, { "isVH" , (PyCFunction)PyRoutingGauge_isVH , METH_NOARGS

View File

@ -287,13 +287,13 @@ void Contact::translate(const DbU::Unit& dx, const DbU::Unit& dy)
void Contact::setLayer(const Layer* layer)
// ***************************************
{
if (!layer)
throw Error("Can't set layer : null layer");
if (not layer)
throw Error( "Contact::setLayer(): Invalid NULL layer on %s.", getString(this).c_str() );
if (layer != _layer) {
invalidate(false);
_layer = layer;
}
if (layer != _layer) {
invalidate( false );
_layer = layer;
}
}
void Contact::setWidth(DbU::Unit width)

View File

@ -62,8 +62,9 @@ extern "C" {
#if defined(__PYTHON_MODULE__)
// Standard Accessors (Attributes).
DirectGetLongAttribute(PyRectilinear_getX, getX, PyRectilinear, Rectilinear)
DirectGetLongAttribute(PyRectilinear_getY, getY, PyRectilinear, Rectilinear)
DirectGetLongAttribute(PyRectilinear_getX , getX , PyRectilinear, Rectilinear)
DirectGetLongAttribute(PyRectilinear_getY , getY , PyRectilinear, Rectilinear)
DirectGetBoolAttribute(PyRectilinear_isNonRectangle, isNonRectangle, PyRectilinear, Rectilinear)
// Standard Destroy (Attribute).
DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear)
@ -173,6 +174,7 @@ extern "C" {
PyMethodDef PyRectilinear_Methods[] =
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
, "Create a new Rectilinear polygon." }
, { "isNonRectangle", (PyCFunction)PyRectilinear_isNonRectangle, METH_NOARGS , "Tells if the shape is not a rectangle." }
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }

View File

@ -594,6 +594,7 @@ namespace Katana {
if (edge->getReservedCapacity() < hReservedMin)
edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() );
}
gcell->postGlobalAnnotate();
}
}
}

View File

@ -470,9 +470,9 @@ namespace Katana {
queue.repushInvalidateds();
// if (getProcesseds() == 286892 + 1) {
// if (getProcesseds() == 48172 + 1) {
// UpdateSession::close();
// Breakpoint::stop( 1, "Stopping before revalidating event 286892." );
// Breakpoint::stop( 0, "Stopping before revalidating event 3107." );
// UpdateSession::open();
// }

View File

@ -1399,10 +1399,12 @@ namespace Katana {
and ( manipulator.getEvent()->getConstraints().isPonctual()
or (isFullBlocked() and (_costs.size() > 7)))
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
cdebug_log(159,0) << "Next state: MoveUp." << endl;
moveUpFlags |= Manipulator::AllowTerminalMoveUp;
} else {
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
nextState = DataNegociate::RipupPerpandiculars;
cdebug_log(159,0) << "Next state: RipupPerpandiculars (half-slacken succeeded)." << endl;
break;
}
}

View File

@ -389,14 +389,14 @@ namespace Katana {
TrackElement* Track::getPrevious ( size_t& index, Net* net ) const
{
for ( index-- ; index != npos ; index-- ) {
cdebug_log(140,0) << index << ":" << _segments[index] << endl;
if (_segments[index]->getNet() == net) continue;
return _segments[index];
}
cdebug_log(155,0) << "Track::getPrevious() " << index << " for " << net << endl;
if ((index == npos) or (index == 0)) return NULL;
do {
--index;
cdebug_log(155,0) << "| " << index << ":" << _segments[index] << endl;
if (_segments[index]->getNet() != net) return _segments[index];
} while ( index != 0 );
index = npos;
return NULL;
}
@ -682,7 +682,7 @@ namespace Katana {
DbU::Unit minFree = _min;
cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl;
if (not (state & BeginIsTrackMin) ) {
if (not (state & BeginIsTrackMin) and (begin > 0)) {
if (_segments[begin]->getNet() == net)
getPrevious( begin, net );