Adjustements for analog routing.
* Change: In Anabatic::GCell::doGrid(), remove the "3 slice height" limit (for small digital analog blocs). * Bug: In Anabatic::NetBuilder::setStartHook(), perform a check for a RoutingPad still on a Plug. Diplay an error instead of crashing. * Bug: In CRL::RoutingLayerGauge::getTrackIndex(), the upper bound of the track interval must be included instead of excluded. * New: In Hurricane::Cell, add a StayOnPlugs flags for flattenNets(). To keep the RoutingPad occurrences on Plug instead of selecting physical components. * New: In Isobar::PyNet, add setAutomatic() and isAutomatic() to the interface. * Bug: In Katana::protectRoutingPads(), do not create protections on PinOnly layers (mostly metal1).
This commit is contained in:
parent
95aba574a5
commit
ba3ddafdf5
|
@ -397,7 +397,7 @@ namespace Anabatic {
|
|||
|
||||
bool Configuration::selectRpComponent ( RoutingPad* rp ) const
|
||||
{
|
||||
cdebug_log(145,1) << "selectRpComponent(): " << rp << endl;
|
||||
cdebug_log(112,1) << "selectRpComponent(): " << rp << endl;
|
||||
|
||||
Box ab = rp->getCell()->getBoundingBox();
|
||||
const Layer* metal1 = getLayerGauge( 0 )->getLayer();
|
||||
|
@ -410,16 +410,17 @@ namespace Anabatic {
|
|||
|
||||
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
|
||||
if (current and (current->getLayer()->getMask() != metal1->getMask())) {
|
||||
cdebug_log(145,0) << "> using default non-metal1 segment." << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
cdebug_log(112,0) << "> using default non-metal1 segment." << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
DbU::Unit bestSpan = 0;
|
||||
Component* bestComponent = NULL;
|
||||
|
||||
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
|
||||
for ( Component* component : masterNet->getComponents() ) {
|
||||
cdebug_log(145,0) << "@ " << component << endl;
|
||||
cdebug_log(112,0) << "@ " << component << endl;
|
||||
if (not NetExternalComponents::isExternal(component)) continue;
|
||||
|
||||
Segment* segment = dynamic_cast<Segment*>(component);
|
||||
|
@ -447,30 +448,27 @@ namespace Anabatic {
|
|||
maxPos = bb.getYMax();
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "| " << occurrence.getPath() << endl;
|
||||
cdebug_log(145,0) << "| " << transformation << endl;
|
||||
cdebug_log(145,0) << "| " << bb << " of:" << segment << endl;
|
||||
cdebug_log(145,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
|
||||
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
|
||||
cdebug_log(112,0) << "| " << transformation << endl;
|
||||
cdebug_log(112,0) << "| " << bb << " of:" << segment << endl;
|
||||
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
|
||||
|
||||
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
|
||||
if (not bestComponent) bestComponent = component;
|
||||
else {
|
||||
if (bestSpan < maxPos-minPos) {
|
||||
bestComponent = component;
|
||||
bestSpan = maxPos - minPos;
|
||||
}
|
||||
if (not bestComponent or (bestSpan > maxPos-minPos)) {
|
||||
bestComponent = component;
|
||||
bestSpan = maxPos - minPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestComponent) {
|
||||
rp->setExternalComponent( bestComponent );
|
||||
cdebug_log(145,0) << "Using best candidate:" << bestComponent << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
cdebug_log(112,0) << "Using best candidate:" << bestComponent << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
cdebug_tabw(112,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1450,7 +1450,6 @@ namespace Anabatic {
|
|||
|
||||
vector<RoutingPad*> rps;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
|
||||
|
||||
if (state){
|
||||
if (state->isSelfSym()){
|
||||
|
|
|
@ -751,24 +751,24 @@ namespace Anabatic {
|
|||
Interval hspan = getSide( Flags::Horizontal );
|
||||
Interval vspan = getSide( Flags::Vertical );
|
||||
|
||||
if (hspan.getSize() < 3*side) {
|
||||
cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
|
||||
" (%s)"
|
||||
, DbU::getValueString(hspan.getSize()).c_str()
|
||||
, getString(this).c_str()
|
||||
) << endl;
|
||||
Session::close();
|
||||
return false;
|
||||
}
|
||||
// if (hspan.getSize() < 2*side) {
|
||||
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
|
||||
// " (%s)"
|
||||
// , DbU::getValueString(hspan.getSize()).c_str()
|
||||
// , getString(this).c_str()
|
||||
// ) << endl;
|
||||
// Session::close();
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (vspan.getSize() < 3*side) {
|
||||
cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
|
||||
" (%s)"
|
||||
, DbU::getValueString(vspan.getSize()).c_str()
|
||||
, getString(this).c_str()
|
||||
) << endl;
|
||||
return false;
|
||||
}
|
||||
// if (vspan.getSize() < 2*side) {
|
||||
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
|
||||
// " (%s)"
|
||||
// , DbU::getValueString(vspan.getSize()).c_str()
|
||||
// , getString(this).c_str()
|
||||
// ) << endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
GCell* row = this;
|
||||
GCell* column = NULL;
|
||||
|
|
|
@ -451,6 +451,14 @@ namespace Anabatic {
|
|||
const Layer* layer = anchor->getLayer();
|
||||
cdebug_log(145,0) << "rp: " << rp << endl;
|
||||
|
||||
if (not layer) {
|
||||
cerr << Error( "RoutingPad is still on it's Plug, routing will be incomplete.\n"
|
||||
" %s"
|
||||
, getString(anchor).c_str() )
|
||||
<< endl;
|
||||
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
|
||||
|
|
|
@ -238,7 +238,7 @@ namespace CRL {
|
|||
}
|
||||
|
||||
unsigned int tracksNumber = getTrackNumber(start,stop);
|
||||
if ( (unsigned)index >= tracksNumber ) {
|
||||
if ( (unsigned)index > tracksNumber ) {
|
||||
cdebug_tabw(100,-1);
|
||||
return (tracksNumber > 0) ? tracksNumber-1 : 0;
|
||||
// throw Error ( overflowIndex
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2017-2018, All Rights Reserved
|
||||
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -381,6 +381,8 @@ namespace {
|
|||
blockageNet = Net::create( cell, "blockage" );
|
||||
blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
|
||||
//cerr << " @ _obstructionCbk: " << blockageNet->getName() << endl;
|
||||
|
||||
lefiGeometries* geoms = obstruction->geometries();
|
||||
for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) {
|
||||
|
@ -393,21 +395,23 @@ namespace {
|
|||
lefiGeomRect* r = geoms->getRect(igeom);
|
||||
double w = r->xh - r->xl;
|
||||
double h = r->yh - r->yl;
|
||||
Segment* segment = NULL;
|
||||
if (w >= h) {
|
||||
Horizontal::create( blockageNet, layer
|
||||
, parser->fromUnitsMicrons( (r->yl + r->yh)/2 )
|
||||
, parser->fromUnitsMicrons( h )
|
||||
, parser->fromUnitsMicrons( r->xl )
|
||||
, parser->fromUnitsMicrons( r->xh )
|
||||
);
|
||||
segment = Horizontal::create( blockageNet, layer
|
||||
, parser->fromUnitsMicrons( (r->yl + r->yh)/2 )
|
||||
, parser->fromUnitsMicrons( h )
|
||||
, parser->fromUnitsMicrons( r->xl )
|
||||
, parser->fromUnitsMicrons( r->xh )
|
||||
);
|
||||
} else {
|
||||
Vertical::create( blockageNet, layer
|
||||
, parser->fromUnitsMicrons( (r->xl + r->xh)/2 )
|
||||
, parser->fromUnitsMicrons( w )
|
||||
, parser->fromUnitsMicrons( r->yl )
|
||||
, parser->fromUnitsMicrons( r->yh )
|
||||
);
|
||||
segment = Vertical::create( blockageNet, layer
|
||||
, parser->fromUnitsMicrons( (r->xl + r->xh)/2 )
|
||||
, parser->fromUnitsMicrons( w )
|
||||
, parser->fromUnitsMicrons( r->yl )
|
||||
, parser->fromUnitsMicrons( r->yh )
|
||||
);
|
||||
}
|
||||
//cerr << " | " << segment << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,7 +444,8 @@ namespace {
|
|||
parser->_pinPostProcess();
|
||||
parser->clearPinSegments();
|
||||
|
||||
cerr << " - " << cellName << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << endl;
|
||||
cerr << " - " << cellName
|
||||
<< " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << "\n" << endl;
|
||||
parser->setCell( NULL );
|
||||
|
||||
return 0;
|
||||
|
@ -451,7 +456,7 @@ namespace {
|
|||
{
|
||||
LefParser* parser = (LefParser*)ud;
|
||||
|
||||
//cerr << " + _pinCbk: " << pin->name() << endl;
|
||||
//cerr << " @ _pinCbk: " << pin->name() << endl;
|
||||
|
||||
if (not parser->getCell()) parser->setCell( Cell::create( parser->getLibrary(true), "LefImportTmpCell" ) );
|
||||
|
||||
|
@ -511,6 +516,7 @@ namespace {
|
|||
);
|
||||
}
|
||||
if (segment) parser->addPinSegment( pin->name(), segment );
|
||||
//cerr << " | " << segment << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -550,6 +556,8 @@ namespace {
|
|||
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
|
||||
Box ab = _cell->getAbutmentBox();
|
||||
|
||||
//cerr << " @ _pinPostProcess" << endl;
|
||||
|
||||
for ( auto element : _pinSegments ) {
|
||||
string pinName = element.first;
|
||||
vector<Segment*>& segments = element.second;
|
||||
|
@ -558,6 +566,8 @@ namespace {
|
|||
for ( Segment* segment : segments ) {
|
||||
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
|
||||
|
||||
//cerr << " > " << segment << endl;
|
||||
|
||||
if (not segment->getNet()->isSupply()) {
|
||||
if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) {
|
||||
Vertical* v = dynamic_cast<Vertical*>( segment );
|
||||
|
@ -571,6 +581,12 @@ namespace {
|
|||
} else {
|
||||
DbU::Unit neighbor = nearestX
|
||||
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch();
|
||||
|
||||
//cerr << " | X:" << DbU::getValueString(v->getX())
|
||||
// << " nearestX:" << DbU::getValueString(nearestX)
|
||||
// << " neighbor:" << DbU::getValueString(neighbor)
|
||||
// << endl;
|
||||
|
||||
if ( (v->getX() - v->getHalfWidth() > neighbor)
|
||||
or (v->getX() + v->getHalfWidth() < neighbor) ) {
|
||||
ongrids.push_back( Vertical::create( v->getNet()
|
||||
|
@ -581,7 +597,7 @@ namespace {
|
|||
, v->getDyTarget()
|
||||
)
|
||||
);
|
||||
|
||||
//cerr << " | " << ongrids[ongrids.size()-1] << endl;
|
||||
} else {
|
||||
// Unpitched and not wide enough to be under a metal2 track, ignore.
|
||||
}
|
||||
|
|
|
@ -875,11 +875,13 @@ void Cell::flattenNets ( const Instance* instance, uint64_t flags )
|
|||
if (deepNet) deepNet->_createRoutingPads( flags );
|
||||
}
|
||||
|
||||
unsigned int rpFlags = (flags & Flags::StayOnPlugs) ? 0 : RoutingPad::BiggestArea;
|
||||
|
||||
for ( size_t i=0 ; i<topHyperNets.size() ; ++i ) {
|
||||
Net* net = static_cast<Net*>(topHyperNets[i].getNetOccurrence().getEntity());
|
||||
|
||||
for ( Occurrence plugOccurrence : topHyperNets[i].getLeafPlugOccurrences() ) {
|
||||
RoutingPad* rp = RoutingPad::create( net, plugOccurrence, RoutingPad::BiggestArea );
|
||||
RoutingPad* rp = RoutingPad::create( net, plugOccurrence, rpFlags );
|
||||
rp->materialize();
|
||||
|
||||
if (flags & Flags::WarnOnUnplacedInstances)
|
||||
|
|
|
@ -85,15 +85,16 @@ namespace Hurricane {
|
|||
|
||||
size_t DeepNet::_createRoutingPads ( unsigned int flags )
|
||||
{
|
||||
size_t nbRoutingPads = 0;
|
||||
HyperNet hyperNet ( _netOccurrence );
|
||||
RoutingPad* currentRp = NULL;
|
||||
bool createRp = true;
|
||||
size_t nbRoutingPads = 0;
|
||||
HyperNet hyperNet ( _netOccurrence );
|
||||
RoutingPad* currentRp = NULL;
|
||||
bool createRp = true;
|
||||
unsigned int rpFlags = (flags & Cell::Flags::StayOnPlugs) ? 0 : RoutingPad::BiggestArea;
|
||||
|
||||
for ( Occurrence occurrence : hyperNet.getComponentOccurrences() ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(occurrence.getEntity());
|
||||
if ( rp and (rp->getCell() == getCell()) ) { createRp = false; break; }
|
||||
if ( dynamic_cast<Segment* >(occurrence.getEntity()) ) { createRp = false; break; }
|
||||
if ( dynamic_cast<Segment*>(occurrence.getEntity()) ) { createRp = false; break; }
|
||||
}
|
||||
if (not createRp) return 0;
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ namespace Hurricane {
|
|||
throw Error( "Entity::Entity(): Identifier counter has reached it's limit (%d bits)."
|
||||
, std::numeric_limits<unsigned int>::digits );
|
||||
}
|
||||
|
||||
// if (_id == 75060)
|
||||
// cerr << "Entity::Entity() " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -74,28 +74,29 @@ class Cell : public Entity {
|
|||
|
||||
public: class Flags : public BaseFlags {
|
||||
public:
|
||||
enum Flag { NoFlags = 0x00000000
|
||||
, BuildRings = 0x00000001
|
||||
, BuildClockRings = 0x00000002
|
||||
, BuildSupplyRings = 0x00000004
|
||||
, NoClockFlatten = 0x00000008
|
||||
, WarnOnUnplacedInstances = 0x00000010
|
||||
enum Flag { NoFlags = (1 << 0)
|
||||
, BuildRings = (1 << 1)
|
||||
, BuildClockRings = (1 << 2)
|
||||
, BuildSupplyRings = (1 << 3)
|
||||
, NoClockFlatten = (1 << 4)
|
||||
, WarnOnUnplacedInstances = (1 << 5)
|
||||
, StayOnPlugs = (1 << 6)
|
||||
, MaskRings = BuildRings|BuildClockRings|BuildSupplyRings
|
||||
// Flags set for Observers.
|
||||
, CellAboutToChange = 0x00000100
|
||||
, CellChanged = 0x00000200
|
||||
, CellDestroyed = 0x00000400
|
||||
, CellAboutToChange = (1 << 10)
|
||||
, CellChanged = (1 << 11)
|
||||
, CellDestroyed = (1 << 12)
|
||||
// Cell states
|
||||
, Terminal = 0x00001000
|
||||
, FlattenLeaf = 0x00002000
|
||||
, Pad = 0x00004000
|
||||
, Feed = 0x00008000
|
||||
, FlattenedNets = 0x00010000
|
||||
, Placed = 0x00020000
|
||||
, Routed = 0x00040000
|
||||
, MergedQuadTree = 0x00080000
|
||||
, SlavedAb = 0x00100000
|
||||
, Materialized = 0x00200000
|
||||
, Terminal = (1 << 20)
|
||||
, FlattenLeaf = (1 << 21)
|
||||
, Pad = (1 << 22)
|
||||
, Feed = (1 << 23)
|
||||
, FlattenedNets = (1 << 24)
|
||||
, Placed = (1 << 25)
|
||||
, Routed = (1 << 26)
|
||||
, MergedQuadTree = (1 << 27)
|
||||
, SlavedAb = (1 << 28)
|
||||
, Materialized = (1 << 29)
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -48,11 +48,11 @@ namespace Hurricane {
|
|||
class RoutingPad : public Component {
|
||||
public:
|
||||
typedef Component Inherit;
|
||||
enum Flags { BiggestArea = 0x0001
|
||||
, HighestLayer = 0x0002
|
||||
, LowestLayer = 0x0004
|
||||
enum Flags { BiggestArea = (1 << 0)
|
||||
, HighestLayer = (1 << 1)
|
||||
, LowestLayer = (1 << 2)
|
||||
, ComponentSelection= BiggestArea|HighestLayer|LowestLayer
|
||||
, ShowWarning = 0x0008
|
||||
, ShowWarning = (1 << 4)
|
||||
};
|
||||
public:
|
||||
static RoutingPad* create ( Net*, Occurrence, unsigned int flags=0 );
|
||||
|
|
|
@ -91,15 +91,17 @@ extern "C" {
|
|||
DirectGetLongAttribute(PyNet_getY,getY,PyNet,Net)
|
||||
|
||||
// Standart Predicates (Attributes).
|
||||
DirectGetBoolAttribute(PyNet_isGlobal ,isGlobal ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isExternal,isExternal,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isLogical ,isLogical ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isClock ,isClock ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isGround ,isGround ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isPower ,isPower ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isSupply ,isSupply ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isGlobal ,isGlobal ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isExternal ,isExternal ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isLogical ,isLogical ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isClock ,isClock ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isGround ,isGround ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isPower ,isPower ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isSupply ,isSupply ,PyNet,Net)
|
||||
DirectGetBoolAttribute(PyNet_isAutomatic ,isAutomatic ,PyNet,Net)
|
||||
DirectSetBoolAttribute(PyNet_setAutomatic,setAutomatic,PyNet,Net)
|
||||
|
||||
GetBoundStateAttribute(PyNet_IsPyBound ,PyNet,Net)
|
||||
GetBoundStateAttribute(PyNet_IsPyBound,PyNet,Net)
|
||||
GetNameMethod(Net, net)
|
||||
|
||||
// Standart modificators.
|
||||
|
@ -456,9 +458,11 @@ extern "C" {
|
|||
, { "isGround" , (PyCFunction)PyNet_isGround , METH_NOARGS , "return true if the net is a ground" }
|
||||
, { "isSupply" , (PyCFunction)PyNet_isSupply , METH_NOARGS , "return true if the net is a supply" }
|
||||
, { "isBound" , (PyCFunction)PyNet_IsPyBound , METH_NOARGS , "return true if the net is bounded to the hurricane net" }
|
||||
, { "isAutomatic" , (PyCFunction)PyNet_isAutomatic , METH_NOARGS , "return true if the net is automatic (auto-generated)" }
|
||||
, { "setName" , (PyCFunction)PyNet_setName , METH_VARARGS, "Allows to change net name." }
|
||||
, { "setGlobal" , (PyCFunction)PyNet_setGlobal , METH_VARARGS, "set the net global." }
|
||||
, { "setExternal" , (PyCFunction)PyNet_setExternal , METH_VARARGS, "set the net external." }
|
||||
, { "setAutomatic" , (PyCFunction)PyNet_setAutomatic , METH_VARARGS, "declare the net as automatic (auto-generated)." }
|
||||
, { "setType" , (PyCFunction)PyNet_setType , METH_VARARGS, "set the type of the net." }
|
||||
, { "setDirection" , (PyCFunction)PyNet_setDirection , METH_VARARGS, "set the direction of the net." }
|
||||
, { "setPosition" , (PyCFunction)PyNet_setPosition , METH_VARARGS, "set the X,Y location of the net." }
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
|
@ -42,6 +43,7 @@
|
|||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::DbU;
|
||||
|
@ -68,30 +70,39 @@ namespace {
|
|||
|
||||
void protectRoutingPad ( RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << "::protectRoutingPad() " << rp << endl;
|
||||
|
||||
Name padNetName = "pad";
|
||||
Component* usedComponent = rp->_getEntityAsComponent();
|
||||
Path path = rp->getOccurrence().getPath();
|
||||
Net* masterNet = usedComponent->getNet();
|
||||
Transformation transformation = path.getTransformation();
|
||||
|
||||
if ( CatalogExtension::isPad(masterNet->getCell()) ) {
|
||||
if (Session::getRoutingGauge()->getLayerType(usedComponent->getLayer()) == Constant::PinOnly) {
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "masterCell: " << masterNet->getCell() << endl;
|
||||
cdebug_log(145,0) << "masterNet: " << masterNet << endl;
|
||||
|
||||
if (CatalogExtension::isPad(masterNet->getCell())) {
|
||||
if ( rp->getNet()->isPower()
|
||||
or (rp->getNet()->getName() == padNetName) )
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
vector<Segment*> segments;
|
||||
|
||||
for( Segment* segment : masterNet->getSegments() ) {
|
||||
for ( Segment* segment : masterNet->getSegments() ) {
|
||||
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer());
|
||||
if ( plane == NULL ) continue;
|
||||
if (not plane) continue;
|
||||
|
||||
if ( usedComponent == dynamic_cast<Component*>(segment) ) continue;
|
||||
if ( not NetExternalComponents::isExternal(segment) ) continue;
|
||||
if (usedComponent == dynamic_cast<Component*>(segment)) continue;
|
||||
if (not NetExternalComponents::isExternal(segment)) continue;
|
||||
|
||||
//cerr << "Looking " << (void*)*isegment << ":" << *isegment << endl;
|
||||
|
||||
segments.push_back ( segment );
|
||||
segments.push_back( segment );
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
||||
|
@ -105,7 +116,8 @@ namespace {
|
|||
Box bb ( segments[i]->getBoundingBox() );
|
||||
|
||||
transformation.applyOn ( bb );
|
||||
//cinfo << "bb: " << bb << endl;
|
||||
|
||||
cdebug_log(145,0) << "@ " << segments[i] << " bb:" << bb << endl;
|
||||
|
||||
if ( direction == Flags::Horizontal ) {
|
||||
DbU::Unit axisMin = bb.getYMin() - delta;
|
||||
|
@ -121,6 +133,7 @@ namespace {
|
|||
, bb.getXMax()-extension
|
||||
);
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
cdebug_log(145,0) << "| " << segment << endl;
|
||||
}
|
||||
} else {
|
||||
DbU::Unit axisMin = bb.getXMin() - delta;
|
||||
|
@ -136,9 +149,11 @@ namespace {
|
|||
, bb.getYMax()-extension
|
||||
);
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
cdebug_log(145,0) << "| " << segment << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,6 +178,8 @@ namespace Katana {
|
|||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (net->isSupply()) continue;
|
||||
|
||||
DebugSession::open( net, 140, 150 );
|
||||
|
||||
NetData* data = getNetData( net );
|
||||
if (data and data->isFixed()) continue;
|
||||
|
||||
|
@ -173,6 +190,8 @@ namespace Katana {
|
|||
|
||||
for ( size_t i=0 ; i<rps.size() ; ++i )
|
||||
protectRoutingPad( rps[i] );
|
||||
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
Session::close();
|
||||
|
|
Loading…
Reference in New Issue