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:
parent
908231c4c4
commit
cd60032d9c
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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* );
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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." }
|
||||
|
|
|
@ -594,6 +594,7 @@ namespace Katana {
|
|||
if (edge->getReservedCapacity() < hReservedMin)
|
||||
edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() );
|
||||
}
|
||||
gcell->postGlobalAnnotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
// }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue