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:
Jean-Paul Chaput 2018-01-10 12:45:00 +01:00
parent 95aba574a5
commit ba3ddafdf5
13 changed files with 149 additions and 98 deletions

View File

@ -397,7 +397,7 @@ namespace Anabatic {
bool Configuration::selectRpComponent ( RoutingPad* rp ) const 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(); Box ab = rp->getCell()->getBoundingBox();
const Layer* metal1 = getLayerGauge( 0 )->getLayer(); const Layer* metal1 = getLayerGauge( 0 )->getLayer();
@ -410,16 +410,17 @@ namespace Anabatic {
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() ); Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
if (current and (current->getLayer()->getMask() != metal1->getMask())) { if (current and (current->getLayer()->getMask() != metal1->getMask())) {
cdebug_log(145,0) << "> using default non-metal1 segment." << endl; cdebug_log(112,0) << "> using default non-metal1 segment." << endl;
cdebug_tabw(145,-1); cdebug_tabw(112,-1);
return true; return true;
} }
DbU::Unit bestSpan = 0; DbU::Unit bestSpan = 0;
Component* bestComponent = NULL; Component* bestComponent = NULL;
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
for ( Component* component : masterNet->getComponents() ) { for ( Component* component : masterNet->getComponents() ) {
cdebug_log(145,0) << "@ " << component << endl; cdebug_log(112,0) << "@ " << component << endl;
if (not NetExternalComponents::isExternal(component)) continue; if (not NetExternalComponents::isExternal(component)) continue;
Segment* segment = dynamic_cast<Segment*>(component); Segment* segment = dynamic_cast<Segment*>(component);
@ -447,30 +448,27 @@ namespace Anabatic {
maxPos = bb.getYMax(); maxPos = bb.getYMax();
} }
cdebug_log(145,0) << "| " << occurrence.getPath() << endl; cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
cdebug_log(145,0) << "| " << transformation << endl; cdebug_log(112,0) << "| " << transformation << endl;
cdebug_log(145,0) << "| " << bb << " of:" << segment << endl; cdebug_log(112,0) << "| " << bb << " of:" << segment << endl;
cdebug_log(145,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
if (not bestComponent) bestComponent = component; if (not bestComponent or (bestSpan > maxPos-minPos)) {
else { bestComponent = component;
if (bestSpan < maxPos-minPos) { bestSpan = maxPos - minPos;
bestComponent = component;
bestSpan = maxPos - minPos;
}
} }
} }
} }
if (bestComponent) { if (bestComponent) {
rp->setExternalComponent( bestComponent ); rp->setExternalComponent( bestComponent );
cdebug_log(145,0) << "Using best candidate:" << bestComponent << endl; cdebug_log(112,0) << "Using best candidate:" << bestComponent << endl;
cdebug_tabw(145,-1); cdebug_tabw(112,-1);
return true; return true;
} }
cdebug_tabw(145,-1); cdebug_tabw(112,-1);
return false; return false;
} }

View File

@ -1450,7 +1450,6 @@ namespace Anabatic {
vector<RoutingPad*> rps; vector<RoutingPad*> rps;
NetRoutingState* state = NetRoutingExtension::get( _net ); NetRoutingState* state = NetRoutingExtension::get( _net );
if (state){ if (state){
if (state->isSelfSym()){ if (state->isSelfSym()){

View File

@ -751,24 +751,24 @@ namespace Anabatic {
Interval hspan = getSide( Flags::Horizontal ); Interval hspan = getSide( Flags::Horizontal );
Interval vspan = getSide( Flags::Vertical ); Interval vspan = getSide( Flags::Vertical );
if (hspan.getSize() < 3*side) { // if (hspan.getSize() < 2*side) {
cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n" // cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
" (%s)" // " (%s)"
, DbU::getValueString(hspan.getSize()).c_str() // , DbU::getValueString(hspan.getSize()).c_str()
, getString(this).c_str() // , getString(this).c_str()
) << endl; // ) << endl;
Session::close(); // Session::close();
return false; // return false;
} // }
if (vspan.getSize() < 3*side) { // if (vspan.getSize() < 2*side) {
cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n" // cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
" (%s)" // " (%s)"
, DbU::getValueString(vspan.getSize()).c_str() // , DbU::getValueString(vspan.getSize()).c_str()
, getString(this).c_str() // , getString(this).c_str()
) << endl; // ) << endl;
return false; // return false;
} // }
GCell* row = this; GCell* row = this;
GCell* column = NULL; GCell* column = NULL;

View File

@ -451,6 +451,14 @@ namespace Anabatic {
const Layer* layer = anchor->getLayer(); const Layer* layer = anchor->getLayer();
cdebug_log(145,0) << "rp: " << rp << endl; 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 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(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(2)->getMask()) _connexity.fields.M3++; // M3 V

View File

@ -238,7 +238,7 @@ namespace CRL {
} }
unsigned int tracksNumber = getTrackNumber(start,stop); unsigned int tracksNumber = getTrackNumber(start,stop);
if ( (unsigned)index >= tracksNumber ) { if ( (unsigned)index > tracksNumber ) {
cdebug_tabw(100,-1); cdebug_tabw(100,-1);
return (tracksNumber > 0) ? tracksNumber-1 : 0; return (tracksNumber > 0) ? tracksNumber-1 : 0;
// throw Error ( overflowIndex // throw Error ( overflowIndex

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // 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 | // | C O R I O L I S |
@ -381,6 +381,8 @@ namespace {
blockageNet = Net::create( cell, "blockage" ); blockageNet = Net::create( cell, "blockage" );
blockageNet->setType( Net::Type::BLOCKAGE ); blockageNet->setType( Net::Type::BLOCKAGE );
} }
//cerr << " @ _obstructionCbk: " << blockageNet->getName() << endl;
lefiGeometries* geoms = obstruction->geometries(); lefiGeometries* geoms = obstruction->geometries();
for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) { for ( int igeom=0 ; igeom < geoms->numItems() ; ++ igeom ) {
@ -393,21 +395,23 @@ namespace {
lefiGeomRect* r = geoms->getRect(igeom); lefiGeomRect* r = geoms->getRect(igeom);
double w = r->xh - r->xl; double w = r->xh - r->xl;
double h = r->yh - r->yl; double h = r->yh - r->yl;
Segment* segment = NULL;
if (w >= h) { if (w >= h) {
Horizontal::create( blockageNet, layer segment = Horizontal::create( blockageNet, layer
, parser->fromUnitsMicrons( (r->yl + r->yh)/2 ) , parser->fromUnitsMicrons( (r->yl + r->yh)/2 )
, parser->fromUnitsMicrons( h ) , parser->fromUnitsMicrons( h )
, parser->fromUnitsMicrons( r->xl ) , parser->fromUnitsMicrons( r->xl )
, parser->fromUnitsMicrons( r->xh ) , parser->fromUnitsMicrons( r->xh )
); );
} else { } else {
Vertical::create( blockageNet, layer segment = Vertical::create( blockageNet, layer
, parser->fromUnitsMicrons( (r->xl + r->xh)/2 ) , parser->fromUnitsMicrons( (r->xl + r->xh)/2 )
, parser->fromUnitsMicrons( w ) , parser->fromUnitsMicrons( w )
, parser->fromUnitsMicrons( r->yl ) , parser->fromUnitsMicrons( r->yl )
, parser->fromUnitsMicrons( r->yh ) , parser->fromUnitsMicrons( r->yh )
); );
} }
//cerr << " | " << segment << endl;
} }
} }
@ -440,7 +444,8 @@ namespace {
parser->_pinPostProcess(); parser->_pinPostProcess();
parser->clearPinSegments(); parser->clearPinSegments();
cerr << " - " << cellName << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << endl; cerr << " - " << cellName
<< " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << "\n" << endl;
parser->setCell( NULL ); parser->setCell( NULL );
return 0; return 0;
@ -451,7 +456,7 @@ namespace {
{ {
LefParser* parser = (LefParser*)ud; 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" ) ); if (not parser->getCell()) parser->setCell( Cell::create( parser->getLibrary(true), "LefImportTmpCell" ) );
@ -511,6 +516,7 @@ namespace {
); );
} }
if (segment) parser->addPinSegment( pin->name(), segment ); if (segment) parser->addPinSegment( pin->name(), segment );
//cerr << " | " << segment << endl;
continue; continue;
} }
@ -550,6 +556,8 @@ namespace {
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
Box ab = _cell->getAbutmentBox(); Box ab = _cell->getAbutmentBox();
//cerr << " @ _pinPostProcess" << endl;
for ( auto element : _pinSegments ) { for ( auto element : _pinSegments ) {
string pinName = element.first; string pinName = element.first;
vector<Segment*>& segments = element.second; vector<Segment*>& segments = element.second;
@ -558,6 +566,8 @@ namespace {
for ( Segment* segment : segments ) { for ( Segment* segment : segments ) {
bool isWide = (segment->getWidth() >= getMinTerminalWidth()); bool isWide = (segment->getWidth() >= getMinTerminalWidth());
//cerr << " > " << segment << endl;
if (not segment->getNet()->isSupply()) { if (not segment->getNet()->isSupply()) {
if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) { if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) {
Vertical* v = dynamic_cast<Vertical*>( segment ); Vertical* v = dynamic_cast<Vertical*>( segment );
@ -571,6 +581,12 @@ namespace {
} else { } else {
DbU::Unit neighbor = nearestX DbU::Unit neighbor = nearestX
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch(); + ((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) if ( (v->getX() - v->getHalfWidth() > neighbor)
or (v->getX() + v->getHalfWidth() < neighbor) ) { or (v->getX() + v->getHalfWidth() < neighbor) ) {
ongrids.push_back( Vertical::create( v->getNet() ongrids.push_back( Vertical::create( v->getNet()
@ -581,7 +597,7 @@ namespace {
, v->getDyTarget() , v->getDyTarget()
) )
); );
//cerr << " | " << ongrids[ongrids.size()-1] << endl;
} else { } else {
// Unpitched and not wide enough to be under a metal2 track, ignore. // Unpitched and not wide enough to be under a metal2 track, ignore.
} }

View File

@ -875,11 +875,13 @@ void Cell::flattenNets ( const Instance* instance, uint64_t flags )
if (deepNet) deepNet->_createRoutingPads( flags ); if (deepNet) deepNet->_createRoutingPads( flags );
} }
unsigned int rpFlags = (flags & Flags::StayOnPlugs) ? 0 : RoutingPad::BiggestArea;
for ( size_t i=0 ; i<topHyperNets.size() ; ++i ) { for ( size_t i=0 ; i<topHyperNets.size() ; ++i ) {
Net* net = static_cast<Net*>(topHyperNets[i].getNetOccurrence().getEntity()); Net* net = static_cast<Net*>(topHyperNets[i].getNetOccurrence().getEntity());
for ( Occurrence plugOccurrence : topHyperNets[i].getLeafPlugOccurrences() ) { for ( Occurrence plugOccurrence : topHyperNets[i].getLeafPlugOccurrences() ) {
RoutingPad* rp = RoutingPad::create( net, plugOccurrence, RoutingPad::BiggestArea ); RoutingPad* rp = RoutingPad::create( net, plugOccurrence, rpFlags );
rp->materialize(); rp->materialize();
if (flags & Flags::WarnOnUnplacedInstances) if (flags & Flags::WarnOnUnplacedInstances)

View File

@ -85,15 +85,16 @@ namespace Hurricane {
size_t DeepNet::_createRoutingPads ( unsigned int flags ) size_t DeepNet::_createRoutingPads ( unsigned int flags )
{ {
size_t nbRoutingPads = 0; size_t nbRoutingPads = 0;
HyperNet hyperNet ( _netOccurrence ); HyperNet hyperNet ( _netOccurrence );
RoutingPad* currentRp = NULL; RoutingPad* currentRp = NULL;
bool createRp = true; bool createRp = true;
unsigned int rpFlags = (flags & Cell::Flags::StayOnPlugs) ? 0 : RoutingPad::BiggestArea;
for ( Occurrence occurrence : hyperNet.getComponentOccurrences() ) { for ( Occurrence occurrence : hyperNet.getComponentOccurrences() ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>(occurrence.getEntity()); RoutingPad* rp = dynamic_cast<RoutingPad*>(occurrence.getEntity());
if ( rp and (rp->getCell() == getCell()) ) { createRp = false; break; } 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; if (not createRp) return 0;

View File

@ -100,6 +100,9 @@ namespace Hurricane {
throw Error( "Entity::Entity(): Identifier counter has reached it's limit (%d bits)." throw Error( "Entity::Entity(): Identifier counter has reached it's limit (%d bits)."
, std::numeric_limits<unsigned int>::digits ); , std::numeric_limits<unsigned int>::digits );
} }
// if (_id == 75060)
// cerr << "Entity::Entity() " << this << endl;
} }

View File

@ -74,28 +74,29 @@ class Cell : public Entity {
public: class Flags : public BaseFlags { public: class Flags : public BaseFlags {
public: public:
enum Flag { NoFlags = 0x00000000 enum Flag { NoFlags = (1 << 0)
, BuildRings = 0x00000001 , BuildRings = (1 << 1)
, BuildClockRings = 0x00000002 , BuildClockRings = (1 << 2)
, BuildSupplyRings = 0x00000004 , BuildSupplyRings = (1 << 3)
, NoClockFlatten = 0x00000008 , NoClockFlatten = (1 << 4)
, WarnOnUnplacedInstances = 0x00000010 , WarnOnUnplacedInstances = (1 << 5)
, StayOnPlugs = (1 << 6)
, MaskRings = BuildRings|BuildClockRings|BuildSupplyRings , MaskRings = BuildRings|BuildClockRings|BuildSupplyRings
// Flags set for Observers. // Flags set for Observers.
, CellAboutToChange = 0x00000100 , CellAboutToChange = (1 << 10)
, CellChanged = 0x00000200 , CellChanged = (1 << 11)
, CellDestroyed = 0x00000400 , CellDestroyed = (1 << 12)
// Cell states // Cell states
, Terminal = 0x00001000 , Terminal = (1 << 20)
, FlattenLeaf = 0x00002000 , FlattenLeaf = (1 << 21)
, Pad = 0x00004000 , Pad = (1 << 22)
, Feed = 0x00008000 , Feed = (1 << 23)
, FlattenedNets = 0x00010000 , FlattenedNets = (1 << 24)
, Placed = 0x00020000 , Placed = (1 << 25)
, Routed = 0x00040000 , Routed = (1 << 26)
, MergedQuadTree = 0x00080000 , MergedQuadTree = (1 << 27)
, SlavedAb = 0x00100000 , SlavedAb = (1 << 28)
, Materialized = 0x00200000 , Materialized = (1 << 29)
}; };
public: public:

View File

@ -48,11 +48,11 @@ namespace Hurricane {
class RoutingPad : public Component { class RoutingPad : public Component {
public: public:
typedef Component Inherit; typedef Component Inherit;
enum Flags { BiggestArea = 0x0001 enum Flags { BiggestArea = (1 << 0)
, HighestLayer = 0x0002 , HighestLayer = (1 << 1)
, LowestLayer = 0x0004 , LowestLayer = (1 << 2)
, ComponentSelection= BiggestArea|HighestLayer|LowestLayer , ComponentSelection= BiggestArea|HighestLayer|LowestLayer
, ShowWarning = 0x0008 , ShowWarning = (1 << 4)
}; };
public: public:
static RoutingPad* create ( Net*, Occurrence, unsigned int flags=0 ); static RoutingPad* create ( Net*, Occurrence, unsigned int flags=0 );

View File

@ -91,15 +91,17 @@ extern "C" {
DirectGetLongAttribute(PyNet_getY,getY,PyNet,Net) DirectGetLongAttribute(PyNet_getY,getY,PyNet,Net)
// Standart Predicates (Attributes). // Standart Predicates (Attributes).
DirectGetBoolAttribute(PyNet_isGlobal ,isGlobal ,PyNet,Net) DirectGetBoolAttribute(PyNet_isGlobal ,isGlobal ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isExternal,isExternal,PyNet,Net) DirectGetBoolAttribute(PyNet_isExternal ,isExternal ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isLogical ,isLogical ,PyNet,Net) DirectGetBoolAttribute(PyNet_isLogical ,isLogical ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isClock ,isClock ,PyNet,Net) DirectGetBoolAttribute(PyNet_isClock ,isClock ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isGround ,isGround ,PyNet,Net) DirectGetBoolAttribute(PyNet_isGround ,isGround ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isPower ,isPower ,PyNet,Net) DirectGetBoolAttribute(PyNet_isPower ,isPower ,PyNet,Net)
DirectGetBoolAttribute(PyNet_isSupply ,isSupply ,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) GetNameMethod(Net, net)
// Standart modificators. // Standart modificators.
@ -456,9 +458,11 @@ extern "C" {
, { "isGround" , (PyCFunction)PyNet_isGround , METH_NOARGS , "return true if the net is a ground" } , { "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" } , { "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" } , { "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." } , { "setName" , (PyCFunction)PyNet_setName , METH_VARARGS, "Allows to change net name." }
, { "setGlobal" , (PyCFunction)PyNet_setGlobal , METH_VARARGS, "set the net global." } , { "setGlobal" , (PyCFunction)PyNet_setGlobal , METH_VARARGS, "set the net global." }
, { "setExternal" , (PyCFunction)PyNet_setExternal , METH_VARARGS, "set the net external." } , { "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." } , { "setType" , (PyCFunction)PyNet_setType , METH_VARARGS, "set the type of the net." }
, { "setDirection" , (PyCFunction)PyNet_setDirection , METH_VARARGS, "set the direction 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." } , { "setPosition" , (PyCFunction)PyNet_setPosition , METH_VARARGS, "set the X,Y location of the net." }

View File

@ -16,6 +16,7 @@
#include <map> #include <map>
#include <list> #include <list>
#include "hurricane/DebugSession.h"
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
#include "hurricane/Technology.h" #include "hurricane/Technology.h"
#include "hurricane/BasicLayer.h" #include "hurricane/BasicLayer.h"
@ -42,6 +43,7 @@
namespace { namespace {
using namespace std; using namespace std;
using Hurricane::DebugSession;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::DbU; using Hurricane::DbU;
@ -68,30 +70,39 @@ namespace {
void protectRoutingPad ( RoutingPad* rp ) void protectRoutingPad ( RoutingPad* rp )
{ {
cdebug_log(145,1) << "::protectRoutingPad() " << rp << endl;
Name padNetName = "pad"; Name padNetName = "pad";
Component* usedComponent = rp->_getEntityAsComponent(); Component* usedComponent = rp->_getEntityAsComponent();
Path path = rp->getOccurrence().getPath(); Path path = rp->getOccurrence().getPath();
Net* masterNet = usedComponent->getNet(); Net* masterNet = usedComponent->getNet();
Transformation transformation = path.getTransformation(); 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() if ( rp->getNet()->isPower()
or (rp->getNet()->getName() == padNetName) ) or (rp->getNet()->getName() == padNetName) )
cdebug_tabw(145,-1);
return; return;
} }
vector<Segment*> segments; vector<Segment*> segments;
for( Segment* segment : masterNet->getSegments() ) { for ( Segment* segment : masterNet->getSegments() ) {
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer());
if ( plane == NULL ) continue; if (not plane) continue;
if ( usedComponent == dynamic_cast<Component*>(segment) ) continue; if (usedComponent == dynamic_cast<Component*>(segment)) continue;
if ( not NetExternalComponents::isExternal(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 ) { for ( size_t i=0 ; i<segments.size() ; ++i ) {
@ -105,7 +116,8 @@ namespace {
Box bb ( segments[i]->getBoundingBox() ); Box bb ( segments[i]->getBoundingBox() );
transformation.applyOn ( bb ); transformation.applyOn ( bb );
//cinfo << "bb: " << bb << endl;
cdebug_log(145,0) << "@ " << segments[i] << " bb:" << bb << endl;
if ( direction == Flags::Horizontal ) { if ( direction == Flags::Horizontal ) {
DbU::Unit axisMin = bb.getYMin() - delta; DbU::Unit axisMin = bb.getYMin() - delta;
@ -121,6 +133,7 @@ namespace {
, bb.getXMax()-extension , bb.getXMax()-extension
); );
TrackFixedSegment::create ( track, segment ); TrackFixedSegment::create ( track, segment );
cdebug_log(145,0) << "| " << segment << endl;
} }
} else { } else {
DbU::Unit axisMin = bb.getXMin() - delta; DbU::Unit axisMin = bb.getXMin() - delta;
@ -136,9 +149,11 @@ namespace {
, bb.getYMax()-extension , bb.getYMax()-extension
); );
TrackFixedSegment::create ( track, segment ); 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() ) { for ( Net* net : getCell()->getNets() ) {
if (net->isSupply()) continue; if (net->isSupply()) continue;
DebugSession::open( net, 140, 150 );
NetData* data = getNetData( net ); NetData* data = getNetData( net );
if (data and data->isFixed()) continue; if (data and data->isFixed()) continue;
@ -173,6 +190,8 @@ namespace Katana {
for ( size_t i=0 ; i<rps.size() ; ++i ) for ( size_t i=0 ; i<rps.size() ; ++i )
protectRoutingPad( rps[i] ); protectRoutingPad( rps[i] );
DebugSession::close();
} }
Session::close(); Session::close();