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.
2018-01-06 09:55:53 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2018-01-06 10:55:44 -06:00
|
|
|
// Copyright (c) UPMC 2018-2018, All Rights Reserved
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
//
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
// | 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"
|
2019-03-10 07:25:43 -05:00
|
|
|
#include "hurricane/Pin.h"
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
#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;
|
2019-03-10 07:25:43 -05:00
|
|
|
using Hurricane::Pin;
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Improved management of AutoContactTerminal for VH gauges (real ones).
* New: In Anabatic & Katana, add the new "drag" feature.
With VH gauges used by real technologies (M1-H, M2-V, M3-H) a new
routing configuration that was not efficiently handled did appear.
While the preferred routing direction for metal1 is officially
horizontal, due to the way the standard cell must be designed,
their metal1 terminals are still verticals (or punctuals).
Thus, when connecting to them, we face the case where the metal1
terminal (RoutingPad) is vertical *and* the metal2 wire is also
vertical. With that setup, the position of the AutoContactTerminal
via12 cannot be deduced, it may range all the way over the
metal1 RoutingPad. What may define it's position is the metal3 the
metal2 finally connects to. That, is, when we have one horizontal
(the metal3) and one vertical (the metal1 RoutingPad).
The intermediate wire of metal2 can be kept to a minimum size
by "dragging" the via12 close to the via23 when the metal3 wire is
moved.
* New: In Anabatic & Katana, problem of closely vertically aligneds
RoutingPads in metal1 is managed first in PreProcess by restricting
the span of the connecteds metal3 and in _makeDogleg also by restricting
the span even more tightly (to the RoutingPad itself).
* New: In Anabatic::AutoContactTerminal, add the "drag" support.
Automatically check if the connecting segment is in the same
direction as the RoutingPad, if so, sets the "SegDrag" flag.
The dragging state can be known with the "::canDrag()" predicate.
* New: In Anabatic::AutoHorizontal, add the "drag" support.
The drag state can be known with the "::isDrag()" predicate.
In "::_makeDogleg()", when making a dogleg on a dragable segment
pass the drag state correctly and restrict the perpandicular span
of the perpandicular to the RoutingPad (though segment user constraints).
If we make a dogleg on the metal2 is it likely than we cannot go
straigth out vertically from the RoutingPad, so the new perpandicular
*is* restricted to the RoutingPad span.
Idem for AutoVertical.
* New: In Katana::Manipulator, add method "::dragMinimize()" which find a
hole where to minimize a draggable segment. We finally did not use it,
but keep it for potential further use.
* New: In Katana::PreProcess, adds a "protectAlignedaccesses()" local
function to check for vertically aligned metal1 RoutingPads, in that
case setup user constraints on the metal3 segments so they cannot
completly cover the other RoutingPad with metal2.
We also keep a "metal2protect()" function that create a fixed segment
to lock/protect a RoutingPad. Not used for now.
* New: In Katana::Session, add a RoutingPad locking event mechanism.
This allows us to request the creation of a locking (fixed segment)
over a draggable segment. Not used for now.
Lock events are processeds before all others as they create new
TrackElements.
* New: In Katana::Track, "::getNextFree()" and "::getPreviousFree()"
method to find the nearest free interval in a Track after/before a
position.
* Bug: In Anabatic::AutoHorizontal::getConstraints(), merge with user
constraints *only* if it's not an empty interval (as we use min/max
functions). Idem for AutoVertical.
* Bug: In AutoSegments_OnContacts::Locator::isValid(), the boolean test
must be inverted. Seems it never worked, but we never used it until
now...
2018-01-25 04:58:04 -06:00
|
|
|
#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
|
|
|
|
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-03-10 07:25:43 -05:00
|
|
|
bool NetBuilderVH::_do_1G_1PinM2 ()
|
|
|
|
{
|
|
|
|
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
|
|
|
|
|
|
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
|
|
|
if ( (pin->getAccessDirection() != Pin::AccessDirection::SOUTH)
|
|
|
|
and (pin->getAccessDirection() != Pin::AccessDirection::NORTH) ) {
|
|
|
|
cerr << Error( "%s::do_1G_1PinM2(): %s *must* be north or south."
|
|
|
|
, getTypeName().c_str()
|
|
|
|
, getString(pin).c_str() ) << 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_xG_1PinM2 ()
|
|
|
|
{
|
|
|
|
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2() [Managed Configuration] " << getTopology() << endl;
|
|
|
|
|
|
|
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
|
|
|
if ( (pin->getAccessDirection() != Pin::AccessDirection::SOUTH)
|
|
|
|
and (pin->getAccessDirection() != Pin::AccessDirection::NORTH) ) {
|
|
|
|
cerr << Error( "%s::do_xG_1PinM2(): %s *must* be north or south."
|
|
|
|
, getTypeName().c_str()
|
|
|
|
, getString(pin).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
RoutingPad* rp = getRoutingPads()[0];
|
|
|
|
AutoContact* pinContact = NULL;
|
|
|
|
doRp_AutoContacts( getGCell(), rp, pinContact, pinContact, HSmall|VSmall );
|
|
|
|
|
|
|
|
if (not north() and not south()) {
|
|
|
|
AutoContact* subContact1 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( pinContact, subContact1, Flags::Vertical );
|
|
|
|
setBothCornerContacts( subContact1 );
|
|
|
|
} else {
|
|
|
|
AutoContact* subContact1 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( pinContact, subContact1, Flags::Vertical );
|
|
|
|
|
|
|
|
if (east() and west()) {
|
|
|
|
AutoContact* subContact2 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
|
|
|
|
|
|
|
|
setSouthWestContact( (south()) ? subContact1 : subContact2 );
|
|
|
|
setNorthEastContact( (south()) ? subContact2 : subContact1 );
|
|
|
|
} else
|
|
|
|
setBothCornerContacts( subContact1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_tabw(145,-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool NetBuilderVH::_do_1G_1PinM3 ()
|
|
|
|
{
|
|
|
|
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
|
|
|
|
|
|
|
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
|
|
|
if ( (pin->getAccessDirection() != Pin::AccessDirection::EAST)
|
|
|
|
and (pin->getAccessDirection() != Pin::AccessDirection::WEST) ) {
|
|
|
|
cerr << Error( "%s::do_1G_1PinM2(): %s *must* be east or west."
|
|
|
|
, getTypeName().c_str()
|
|
|
|
, getString(pin).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
AutoContact* pinContact = NULL;
|
|
|
|
doRp_AutoContacts( getGCell(), getRoutingPads()[0], pinContact, pinContact, HSmall|VSmall );
|
|
|
|
|
|
|
|
if (east() or west()) {
|
|
|
|
AutoContact* subContact1 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoContact* subContact2 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
|
|
|
|
|
|
|
|
AutoSegment::create( pinContact , subContact1, Flags::Horizontal );
|
|
|
|
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
|
|
|
|
pinContact = subContact2;
|
|
|
|
} else {
|
|
|
|
AutoContact* subContact1 = NULL;
|
|
|
|
subContact1 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
|
|
|
|
|
|
|
|
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
|
|
|
|
pinContact = subContact1;
|
|
|
|
}
|
|
|
|
|
|
|
|
setBothCornerContacts( pinContact );
|
|
|
|
|
|
|
|
cdebug_tabw(145,-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool NetBuilderVH::_do_xG_1PinM3 ()
|
|
|
|
{
|
|
|
|
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM3() [Managed Configuration] " << getTopology() << endl;
|
|
|
|
|
|
|
|
RoutingPad* rp = getRoutingPads()[0];
|
|
|
|
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
|
|
|
if ( (pin->getAccessDirection() != Pin::AccessDirection::EAST)
|
|
|
|
and (pin->getAccessDirection() != Pin::AccessDirection::WEST) ) {
|
|
|
|
cerr << Error( "%s::do_xG_1PinM3(): %s *must* be east or west."
|
|
|
|
, getTypeName().c_str()
|
|
|
|
, getString(pin).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
AutoContact* pinContact = NULL;
|
|
|
|
doRp_AutoContacts( getGCell(), rp, pinContact, pinContact, HSmall|VSmall );
|
|
|
|
|
|
|
|
if (not east() and not west()) {
|
|
|
|
AutoContact* subContact1 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
|
|
|
|
setBothCornerContacts( subContact1 );
|
|
|
|
} else {
|
|
|
|
AutoContact* subContact1 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
|
|
|
|
|
|
|
|
if (north() and south()) {
|
|
|
|
AutoContact* subContact2 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
|
|
|
|
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
|
|
|
|
|
|
|
setSouthWestContact( (west()) ? subContact1 : subContact2 );
|
|
|
|
setNorthEastContact( (west()) ? subContact2 : subContact1 );
|
|
|
|
} else
|
|
|
|
setBothCornerContacts( subContact1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_tabw(145,-1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
bool NetBuilderVH::_do_1G_1M1 ()
|
|
|
|
{
|
|
|
|
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
|
|
|
|
|
|
|
uint64_t flags = NoFlags;
|
2019-03-10 07:25:43 -05:00
|
|
|
if (east()) { flags |= HAccess|VSmall; }
|
|
|
|
else if (west()) { flags |= HAccess|VSmall; }
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
|
|
|
|
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 ()
|
|
|
|
{
|
Basic support for FreePDK 45 completed.
* New: In Commons, inspector support for std::pair<T,U>.
* New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non
square VIAs. The hole (cut) remains square, but the various metal
extensions can now be different in X and Y. The ::getEnclosure()
method now takes a flag EnclosureH / EnclosureV.
* New: In Hurricane::DbU, inspector support for:
std::pair<DbU::Unit,DbU::Unit>
std::array<DbU::Unit,3>
Must be defined here as DbU do not exists yet in Commons.h
* Bug: In Hurricane::Interval::getSize(), when the interval is "full span",
do not return the difference between min and max, but directly DbU::Max.
(the previous result was -1 !)
* New: In CRL Core Python/Technology.py, support for non square VIAs in
the configuration files. Applied to FreePDK 45.
* New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge
is for symbolic layout or not. Exported to Python.
* New: In Anabatic::AutoHorizontal::updatePosition(), differentiated
computation for soure or target taking account of the VIA extension
in the right segment metal (due to non-square VIAs).
* Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is
UP for HV gauges and DOWN for VH.
* New: In Anabatic::AutoSegment::_initialize(), create a cache of the
various extension length for each layer (viaToTop, viaToBottom,
viaToSame).
New implementation of getExtensionCap() using the previous cached
extension table. See updatePositions().
New static functions to access the extension cache in the header:
getViaTotopCap() ...
* Change: In Anabatic::AutoSegment, in various update methods, updateOrient()
must always be called *before* updatePositions() as extensions are
dependant on source/target.
* New: In Anabatic::AutoSegment::getEndAxes() compute the position of the
first source and last target position (center/axes) on an *aligned*
set of segments.
* New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to
signal segments that can be put on only one track. Specific case
to VH gauge for a M1 vertical terminal with a M2 vertical segment.
The M2 is effectively bound to the M1 axis position.
* Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global
and only one RoutingPad the connexion to the RoutingPad was duplicated.
It was valid, but totally stupid.
* Bug: In Anabatic::Session::_canonize(), for an aligned segment set,
intersect the user constraints from all segments instead of only
considering the canonical one.
Issue a warning about too tight constraints only for symbolic
gauges. It may be correct for the real ones.
* New: In Katata::DataNegociate::update(), more accurate computation
of the perpandicular free interval. Use segment extension cap
calculation. Create a special case for fixed axis segments allowing
them to find alternative free interval, try under source and under
target as they are likely to be draggable segments.
* Change: In Katana::Manipulator::relax(), use the extension cap value
to compute the axis of the perpandicular segemnts.
* Change: In Katana::Manipulator::moveUp(), now move up the whole set
of aligned segments instead of just the canonical one.
* Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate
TrackMarkers insertions for fixed terminals.
* New: In Katana::RoutingEvent::Key::Compare::operator(), segments with
fixed axis are processed prior to any others.
* New: In Katana::RoutingEventLoop, store segment pointers instead of
ids to generate more accurate error messages.
* Change: In Katana::RoutingPlane::create(), perform local track
assignment only for HV gauges.
* Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize"
step in the automaton. Mutliple states transitions can occurs in
a row if an action fails.
* New: In Katana::Session::_toIntervalAxis(), normalize interval
bounds so they are on track positions (by shrinking the interval).
* Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
|
|
|
// Implicit hypothesis : we have at least two globals and at least one terminal.
|
|
|
|
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
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()) {
|
Basic support for FreePDK 45 completed.
* New: In Commons, inspector support for std::pair<T,U>.
* New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non
square VIAs. The hole (cut) remains square, but the various metal
extensions can now be different in X and Y. The ::getEnclosure()
method now takes a flag EnclosureH / EnclosureV.
* New: In Hurricane::DbU, inspector support for:
std::pair<DbU::Unit,DbU::Unit>
std::array<DbU::Unit,3>
Must be defined here as DbU do not exists yet in Commons.h
* Bug: In Hurricane::Interval::getSize(), when the interval is "full span",
do not return the difference between min and max, but directly DbU::Max.
(the previous result was -1 !)
* New: In CRL Core Python/Technology.py, support for non square VIAs in
the configuration files. Applied to FreePDK 45.
* New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge
is for symbolic layout or not. Exported to Python.
* New: In Anabatic::AutoHorizontal::updatePosition(), differentiated
computation for soure or target taking account of the VIA extension
in the right segment metal (due to non-square VIAs).
* Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is
UP for HV gauges and DOWN for VH.
* New: In Anabatic::AutoSegment::_initialize(), create a cache of the
various extension length for each layer (viaToTop, viaToBottom,
viaToSame).
New implementation of getExtensionCap() using the previous cached
extension table. See updatePositions().
New static functions to access the extension cache in the header:
getViaTotopCap() ...
* Change: In Anabatic::AutoSegment, in various update methods, updateOrient()
must always be called *before* updatePositions() as extensions are
dependant on source/target.
* New: In Anabatic::AutoSegment::getEndAxes() compute the position of the
first source and last target position (center/axes) on an *aligned*
set of segments.
* New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to
signal segments that can be put on only one track. Specific case
to VH gauge for a M1 vertical terminal with a M2 vertical segment.
The M2 is effectively bound to the M1 axis position.
* Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global
and only one RoutingPad the connexion to the RoutingPad was duplicated.
It was valid, but totally stupid.
* Bug: In Anabatic::Session::_canonize(), for an aligned segment set,
intersect the user constraints from all segments instead of only
considering the canonical one.
Issue a warning about too tight constraints only for symbolic
gauges. It may be correct for the real ones.
* New: In Katata::DataNegociate::update(), more accurate computation
of the perpandicular free interval. Use segment extension cap
calculation. Create a special case for fixed axis segments allowing
them to find alternative free interval, try under source and under
target as they are likely to be draggable segments.
* Change: In Katana::Manipulator::relax(), use the extension cap value
to compute the axis of the perpandicular segemnts.
* Change: In Katana::Manipulator::moveUp(), now move up the whole set
of aligned segments instead of just the canonical one.
* Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate
TrackMarkers insertions for fixed terminals.
* New: In Katana::RoutingEvent::Key::Compare::operator(), segments with
fixed axis are processed prior to any others.
* New: In Katana::RoutingEventLoop, store segment pointers instead of
ids to generate more accurate error messages.
* Change: In Katana::RoutingPlane::create(), perform local track
assignment only for HV gauges.
* Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize"
step in the automaton. Mutliple states transitions can occurs in
a row if an action fails.
* New: In Katana::Session::_toIntervalAxis(), normalize interval
bounds so they are on track positions (by shrinking the interval).
* Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
|
|
|
if (getRoutingPads().size() > 1) {
|
|
|
|
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall );
|
|
|
|
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
|
|
|
} else {
|
|
|
|
rightContact = leftContact;
|
|
|
|
}
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
Basic support for FreePDK 45 completed.
* New: In Commons, inspector support for std::pair<T,U>.
* New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non
square VIAs. The hole (cut) remains square, but the various metal
extensions can now be different in X and Y. The ::getEnclosure()
method now takes a flag EnclosureH / EnclosureV.
* New: In Hurricane::DbU, inspector support for:
std::pair<DbU::Unit,DbU::Unit>
std::array<DbU::Unit,3>
Must be defined here as DbU do not exists yet in Commons.h
* Bug: In Hurricane::Interval::getSize(), when the interval is "full span",
do not return the difference between min and max, but directly DbU::Max.
(the previous result was -1 !)
* New: In CRL Core Python/Technology.py, support for non square VIAs in
the configuration files. Applied to FreePDK 45.
* New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge
is for symbolic layout or not. Exported to Python.
* New: In Anabatic::AutoHorizontal::updatePosition(), differentiated
computation for soure or target taking account of the VIA extension
in the right segment metal (due to non-square VIAs).
* Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is
UP for HV gauges and DOWN for VH.
* New: In Anabatic::AutoSegment::_initialize(), create a cache of the
various extension length for each layer (viaToTop, viaToBottom,
viaToSame).
New implementation of getExtensionCap() using the previous cached
extension table. See updatePositions().
New static functions to access the extension cache in the header:
getViaTotopCap() ...
* Change: In Anabatic::AutoSegment, in various update methods, updateOrient()
must always be called *before* updatePositions() as extensions are
dependant on source/target.
* New: In Anabatic::AutoSegment::getEndAxes() compute the position of the
first source and last target position (center/axes) on an *aligned*
set of segments.
* New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to
signal segments that can be put on only one track. Specific case
to VH gauge for a M1 vertical terminal with a M2 vertical segment.
The M2 is effectively bound to the M1 axis position.
* Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global
and only one RoutingPad the connexion to the RoutingPad was duplicated.
It was valid, but totally stupid.
* Bug: In Anabatic::Session::_canonize(), for an aligned segment set,
intersect the user constraints from all segments instead of only
considering the canonical one.
Issue a warning about too tight constraints only for symbolic
gauges. It may be correct for the real ones.
* New: In Katata::DataNegociate::update(), more accurate computation
of the perpandicular free interval. Use segment extension cap
calculation. Create a special case for fixed axis segments allowing
them to find alternative free interval, try under source and under
target as they are likely to be draggable segments.
* Change: In Katana::Manipulator::relax(), use the extension cap value
to compute the axis of the perpandicular segemnts.
* Change: In Katana::Manipulator::moveUp(), now move up the whole set
of aligned segments instead of just the canonical one.
* Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate
TrackMarkers insertions for fixed terminals.
* New: In Katana::RoutingEvent::Key::Compare::operator(), segments with
fixed axis are processed prior to any others.
* New: In Katana::RoutingEventLoop, store segment pointers instead of
ids to generate more accurate error messages.
* Change: In Katana::RoutingPlane::create(), perform local track
assignment only for HV gauges.
* Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize"
step in the automaton. Mutliple states transitions can occurs in
a row if an action fails.
* New: In Katana::Session::_toIntervalAxis(), normalize interval
bounds so they are on track positions (by shrinking the interval).
* Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
2018-02-17 13:27:38 -06:00
|
|
|
|
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.
2018-01-06 09:55:53 -06:00
|
|
|
string NetBuilderVH::getTypeName () const
|
|
|
|
{ return "NetBuilderVH"; }
|
|
|
|
|
|
|
|
|
|
|
|
} // Anabatic namespace.
|