From 5f25ba349f1e61205c264a4db07d28698332a160 Mon Sep 17 00:00:00 2001 From: EricLaoGitHub Date: Fri, 30 Sep 2016 18:09:05 +0200 Subject: [PATCH] * Change: Dijkstra, GCell Restriction on vertex are now correctly done. * Change: Constants There is only one type of Strut. * New: LoadGlobalRouting Detailed Routing can be performed for analog circuits. The router does not take into account analog constraints yet. Warnings on "metal2" should be corrected in the future. Types of GCell considered by the router are: Device, VChannel/HChannel and Strut. The analog circuit MUST be organized in a slicing structure. --- anabatic/src/Constants.cpp | 14 +- anabatic/src/Dijkstra.cpp | 58 +- anabatic/src/LoadGlobalRouting.cpp | 1358 +++++++++++++++++++++++----- anabatic/src/anabatic/Constants.h | 13 +- anabatic/src/anabatic/Dijkstra.h | 4 +- anabatic/src/anabatic/GCell.h | 6 +- 6 files changed, 1214 insertions(+), 239 deletions(-) diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index a659fb54..26bed1b1 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -33,11 +33,10 @@ namespace Anabatic { const unsigned int Flags::DeviceGCell = (1 << 5); const unsigned int Flags::HChannelGCell = (1 << 6); const unsigned int Flags::VChannelGCell = (1 << 7); - const unsigned int Flags::HStrutGCell = (1 << 8); - const unsigned int Flags::VStrutGCell = (1 << 9); - const unsigned int Flags::MatrixGCell = (1 << 10); - const unsigned int Flags::IoPadGCell = (1 << 11); - const unsigned int Flags::Saturated = (1 << 12); + const unsigned int Flags::StrutGCell = (1 << 8); + const unsigned int Flags::MatrixGCell = (1 << 9); + const unsigned int Flags::IoPadGCell = (1 << 10); + const unsigned int Flags::Saturated = (1 << 11); // Flags for Anabatic objects states only. const unsigned int Flags::DemoMode = (1 << 5); const unsigned int Flags::WarnOnGCellOverload = (1 << 6); @@ -55,7 +54,7 @@ namespace Anabatic { const unsigned int Flags::EndsMask = Source|Target; const unsigned int Flags::DirectionMask = Horizontal|Vertical; const unsigned int Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - const unsigned int Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|HStrutGCell|VStrutGCell|MatrixGCell|IoPadGCell; + const unsigned int Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; // Flags for functions arguments only. const unsigned int Flags::Create = (1 << 5); const unsigned int Flags::WithPerpands = (1 << 6); @@ -104,8 +103,7 @@ namespace Anabatic { s += (_flags & DeviceGCell ) ? 'd' : '-'; s += (_flags & HChannelGCell) ? 'c' : '-'; s += (_flags & VChannelGCell) ? 'c' : '-'; - s += (_flags & HStrutGCell ) ? 's' : '-'; - s += (_flags & VStrutGCell ) ? 's' : '-'; + s += (_flags & StrutGCell ) ? 's' : '-'; s += (_flags & MatrixGCell ) ? 'm' : '-'; s += ","; s += (_flags & Invalidated ) ? 'i' : '-'; diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 159e10d3..f56b8412 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -47,7 +47,7 @@ namespace Anabatic { // Class : "Anabatic::Vertex". - DbU::Unit Vertex::unreached = std::numeric_limits::max(); + DbU::Unit Vertex::unreached = std::numeric_limits::max(); DbU::Unit Vertex::unreachable = std::numeric_limits::max()-1; @@ -116,10 +116,15 @@ namespace Anabatic { DbU::Unit Dijkstra::_distance ( const Vertex* a, const Vertex* b, const Edge* e ) { + cdebug_log(112,0) << "Calcul _distance "<< endl; + cdebug_log(112,0) << "a: "<< b->hasRestrictions() << ", " << a << endl; + cdebug_log(112,0) << "b: "<< b->hasRestrictions() << ", " << b << endl; DbU::Unit distance = a->getDistance() + e->getDistance(); - if ( (a->isNotRestricted()) && (b->isNotRestricted()) ) { // A remplacer avec verification sur type IsDevice()?. - if (isRestricted(a, b)) distance = Vertex::unreachable; + if ( (a->hasRestrictions()) || (b->hasRestrictions()) ) { + if (isRestricted(a, b)) { + distance = Vertex::unreachable; + } } // Edge* aFrom = a->getFrom(); // if (aFrom) { @@ -213,14 +218,24 @@ namespace Anabatic { vector rps; for ( Component* component : _net->getComponents() ) { RoutingPad* rp = dynamic_cast( component ); - if (rp) { rps.push_back( rp ); continue; } + if (rp) { + rps.push_back( rp ); + cerr << "rp to route: " << rp << endl; + continue; + } } for ( auto rp : rps ) { Point center = rp->getBoundingBox().getCenter(); GCell* gcell = _anabatic->getGCellUnder( center ); + cerr << "rp : " << rp << endl; + cerr << "gcell: " << gcell << endl; + + if (gcell->isDevice()){ + _searchArea.merge( _net->getCell()->getAbutmentBox() ); + } - cdebug_log(112,0) << "| " << rp << " || " << gcell << endl; + cdebug_log(112,0) << "| " << rp << endl; if (not gcell) { cerr << Error( "Dijkstra::load(): %s\n" @@ -233,7 +248,9 @@ namespace Anabatic { continue; } + cdebug_log(112,0) << "Current Search area: " << _searchArea << ", gcell: " << gcell << endl; _searchArea.merge( gcell->getBoundingBox() ); + cdebug_log(112,0) << "New Search area: " << _searchArea << endl; Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); if (seed->getConnexId() < 0) { @@ -348,7 +365,7 @@ namespace Anabatic { _queue.dump(); Vertex* current = _queue.top(); - cdebug_log(111,0) << "Current Vertex: " << current << endl; + cdebug_log(111,0) << "[Current Vertex]: " << current << endl; _queue.pop(); if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) { @@ -364,7 +381,7 @@ namespace Anabatic { //if (not _searchArea.contains(vneighbor->getCenter())) { if (not _searchArea.intersect(gneighbor->getBoundingBox())) { - cdebug_log(111,0) << "not _searchArea.contains(vneighbor->getCenter()):" << _searchArea << endl; + cdebug_log(111,0) << "not in _searchArea: " << _searchArea << ", gneighbor area: " << gneighbor->getBoundingBox() << endl; continue; } @@ -372,15 +389,26 @@ namespace Anabatic { cdebug_log(111,0) << "+ Neighbor: " << vneighbor << endl; DbU::Unit distance = _distanceCb( current, vneighbor, edge ); + cdebug_log(111,0) << "Distance: " << distance << ", unreachable: " << Vertex::unreachable << endl; - if (vneighbor->getConnexId() == _connectedsId) continue; - if ( (distance < vneighbor->getDistance()) - or ( (distance == vneighbor->getDistance()) - and (current->getBranchId() > vneighbor->getBranchId())) ) { + if (vneighbor->getConnexId() == _connectedsId) { + cdebug_log(111,0) << "ConnectedsId" << endl; + continue; + } + + if ( ( (distance < vneighbor->getDistance()) + or ( (distance == vneighbor->getDistance()) + and (current->getBranchId() > vneighbor->getBranchId())) + ) + and (distance != Vertex::unreachable) + ){ + cdebug_log(111,0) << "1" << endl; if (vneighbor->getDistance() != Vertex::unreached) { + cdebug_log(111,0) << "2" << endl; _queue.erase( vneighbor ); } else { + cdebug_log(111,0) << "3" << endl; if (not vneighbor->hasValidStamp()) { vneighbor->setConnexId( -1 ); vneighbor->setStamp ( _stamp ); @@ -512,6 +540,10 @@ namespace Anabatic { if (aligneds.front()->isHorizontal()) { if (sourceContact->getX() > targetContact->getX()) std::swap( sourceContact, targetContact ); + if (sourceContact->getX() == targetContact->getX()){ + cerr << "source Vertex: " << source << endl; + cerr << "target Vertex: " << source << endl; + } segment = Horizontal::create( sourceContact , targetContact @@ -523,6 +555,10 @@ namespace Anabatic { } else { if (sourceContact->getY() > targetContact->getY()) std::swap( sourceContact, targetContact ); + if (sourceContact->getY() == targetContact->getY()){ + cerr << "source Vertex: " << source << endl; + cerr << "target Vertex: " << source << endl; + } segment = Vertical::create( sourceContact , targetContact diff --git a/anabatic/src/LoadGlobalRouting.cpp b/anabatic/src/LoadGlobalRouting.cpp index 049a957d..150032f4 100644 --- a/anabatic/src/LoadGlobalRouting.cpp +++ b/anabatic/src/LoadGlobalRouting.cpp @@ -17,6 +17,7 @@ #include #include #include "hurricane/Bug.h" +#include "hurricane/Breakpoint.h" #include "hurricane/Error.h" #include "hurricane/Warning.h" #include "hurricane/DebugSession.h" @@ -50,6 +51,8 @@ namespace { using Anabatic::AutoContactTerminal; + using Hurricane::Breakpoint; + /*! \defgroup LoadGlobalRouting Global Routing Loading @@ -709,12 +712,16 @@ namespace { void _do_xG_xM2 (); void _do_1G_1M3 (); void _do_xG_xM3 (); - void _doHChannel ( ForkStack& forks ); - void _doVChannel (); - void _doHStrut (); - void _doVStrut (); - void _doDevice (); + AutoContact* _doHChannel ( ForkStack& forks ); + AutoContact* _doVChannel ( ForkStack& forks ); + AutoContact* _doStrut ( ForkStack& forks ); + AutoContact* _doDevice ( ForkStack& forks ); void _doIoPad (); + + unsigned int getNumberGlobals (); + unsigned int getDeviceNeighbourBound(); + + private: enum ConnexityBits { GlobalBSize = 4 @@ -942,11 +949,11 @@ namespace { const Layer* layer = anchor->getLayer(); cdebug_log(145,0) << "rp: " << rp << endl; - 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 + if (layer == Session::getRoutingLayer(0)) _connexity.fields.M1++; // M1 V + else if (layer == Session::getRoutingLayer(1)) _connexity.fields.M2++; // M2 H + else if (layer == Session::getRoutingLayer(2)) _connexity.fields.M3++; // M3 V + else if (layer == Session::getRoutingLayer(3)) _connexity.fields.M2++; // M4 H + else if (layer == Session::getRoutingLayer(4)) _connexity.fields.M3++; // M5 V else { cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)." , getString(layer->getName()).c_str() @@ -1144,93 +1151,29 @@ namespace { toHook->attach( master ); } } else { - if (_gcell->isDevice ()){ - _doDevice(); - cdebug_log(145,0) << "doDevice done" << endl; - if (_sourceContact) { - cdebug_log(145,0) << "sourceContact is not NULL" << endl; - AutoContact* targetContact - = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ) - ? _northEastContact : _southWestContact ; - AutoSegment* globalSegment = AutoSegment::create( _sourceContact - , targetContact - , static_cast( _fromHook->getComponent() ) - ); - cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - } else { - cdebug_log(145,0) << "sourceContact is NULL" << endl; - _fromHook = NULL; - } + AutoContact* targetContact = NULL; + if (!_sourceContact) _fromHook = NULL; - Hook* toHook = NULL; - Hook* toHookOpposite = NULL; - if ( _east and (_fromHook != _east) ) { - toHook = _east; - toHookOpposite = getSegmentOppositeHook( _east ); - cdebug_log(145,0) << "Pushing East (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl; - cdebug_log(145,0) << "Pushing East (from) " << _northEastContact << endl; - forks.push( toHookOpposite, _northEastContact ); - } - if ( _west and (_fromHook != _west) ) { - toHook = _west; - toHookOpposite = getSegmentOppositeHook( _west ); - cdebug_log(145,0) << "Pushing West (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl; - cdebug_log(145,0) << "Pushing West (from) " << _southWestContact << endl; - forks.push( toHookOpposite, _southWestContact ); - } - if ( _north and (_fromHook != _north) ) { - toHook = _north; - toHookOpposite = getSegmentOppositeHook( _north ); - cdebug_log(145,0) << "Pushing North (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl; - cdebug_log(145,0) << "Pushing North (from) " << _northEastContact << endl; - forks.push( toHookOpposite, _northEastContact ); - } - if ( _south and (_fromHook != _south) ) { - toHook = _south; - toHookOpposite = getSegmentOppositeHook( _south ); - cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl; - cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl; - cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl; - forks.push( toHookOpposite, _southWestContact ); - } - - } else if ((_gcell->isHChannel()) || (_gcell->isHStrut ())){ - _doHChannel( forks ); - - cdebug_log(145,0) << "doHChannel done" << endl; - - } else if ((_gcell->isVChannel()) || (_gcell->isVStrut ())){ - _doVChannel(); - } else if (_gcell->isIoPad ()) _doIoPad(); + if (_gcell->isDevice ()) targetContact = _doDevice ( forks ); + else if (_gcell->isHChannel()) targetContact = _doHChannel( forks ); + else if (_gcell->isVChannel()) targetContact = _doVChannel( forks ); + else if (_gcell->isStrut ()) targetContact = _doStrut ( forks ); + else if (_gcell->isIoPad ()) _doIoPad(); else throw Bug( "Unmanaged GCell type: %s in %s\n" " The global routing seems to be defective." , getString(_gcell).c_str() , getString(_net).c_str() ); - - // for ( Hook* toHook : _fromHook->getHooks() ) { - // if (toHook == _fromHook) continue; - // Segment* segment = dynamic_cast( toHook->getComponent() ); - // if (not segment) continue; - - // Hook* toHookOpposite = getSegmentOppositeHook( toHook ); - - // // Temporary. A vector of HTee/VTee must be defined in replacement of - // // SW / NE contacts, so we connect to the right contact branch. - // cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl; - // cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl; - // forks.push( toHookOpposite, _southWestContact ); - // } - if (_sourceContact) { - } else _fromHook = NULL; - + if ( (_sourceContact) && (targetContact) ){ + AutoSegment* globalSegment = AutoSegment::create( _sourceContact + , targetContact + , static_cast( _fromHook->getComponent() ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + } } - cdebug_tabw(145,-1); } @@ -2235,8 +2178,8 @@ namespace { RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){ - DbU::Unit c1NE = (rp1->getTargetPosition().getX() - gcell->getXMin()) + (rp1->getTargetPosition().getY() - gcell->getYMin()); - DbU::Unit c2NE = (rp2->getTargetPosition().getX() - gcell->getXMin()) + (rp2->getTargetPosition().getY() - gcell->getYMin()); + DbU::Unit c1NE = (gcell->getXMax() - rp1->getTargetPosition().getX()) + (gcell->getYMax() - rp1->getTargetPosition().getY()); + DbU::Unit c2NE = (gcell->getXMax() - rp2->getTargetPosition().getX()) + (gcell->getYMax() - rp2->getTargetPosition().getY()); if ( c1NE < c2NE ){ return rp1; @@ -2271,10 +2214,139 @@ namespace { } - void GCellTopology::_doDevice () + AutoContact* GCellTopology::_doDevice ( ForkStack& forks ) + { + cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl; + // #0: Check if all RoutingPads are set to a component. + for ( unsigned int i=0; i<_routingPads.size() ; i++ ) { + if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() ) + &&( _routingPads[i]->getSourcePosition().getY() == _routingPads[i]->getTargetPosition().getY() ) + ){ + throw Error( "GCellTopology::_doDevice() Some RoutingPads are not set to a component.\n" + " On: %s." + , getString(_gcell).c_str() + ); + } + } + cdebug_log(145,0) << "FromHook: " << _fromHook << endl; + cdebug_log(145,0) << "North : " << _north << endl; + cdebug_log(145,0) << "East : " << _east << endl; + cdebug_log(145,0) << "South : " << _south << endl; + cdebug_log(145,0) << "West : " << _west << endl; + cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; + + RoutingPad* rpNE = NULL; + RoutingPad* rpSW = NULL; + AutoContact* targetContact = NULL; + + if ( _routingPads.size() > 1 ){ + cdebug_log(145,0) << "Case _routingPads.size() > 1 "<< endl; + for(vector::iterator it = _routingPads.begin(); it != _routingPads.end(); it++){ + cdebug_log(145,0) << (*it) << endl; + } + + // #1: Find RoutingPads to use for AutoContacts NE+SW + rpNE = _routingPads[0]; + rpSW = _routingPads[0]; + + for ( unsigned int i=1 ; i<_routingPads.size() ; i++ ) { + rpNE = returnNE( _gcell, rpNE, _routingPads[i] ); + rpSW = returnSW( _gcell, rpSW, _routingPads[i] ); + } + + cdebug_log(145,0) << "rpNE: " << rpNE << endl; + cdebug_log(145,0) << "rpSW: " << rpSW << endl; + } else if (_routingPads.size() == 0){ + cdebug_log(145,0) << "Case _routingPads.size() = 0 "<< endl; + throw Error( "GCellTopology::_doDevice() No RoutingPads found.\n" + " On: %s." + , getString(_gcell).c_str() + ); + } else { + cdebug_log(145,0) << "Case _routingPads.size() = 1 "<< endl; + rpNE = rpSW = _routingPads[0]; + } + cdebug_log(145,0) << "rp NE: " << rpNE << endl; + cdebug_log(145,0) << "rp SW: " << rpSW << endl; + + if ((rpNE != NULL) && (rpSW != NULL)){ + if (_east){ + cdebug_log(145,0) << "East" << endl; + const Layer* rpLayer = rpNE->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + Point position; + + position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2 + , abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2 + ); + AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position + , viaSide, viaSide + ); + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + if ( _fromHook != _east) forks.push( getSegmentOppositeHook( _east ), ac ); + else targetContact = ac; + } + if (_west){ + cdebug_log(145,0) << "West" << endl; + const Layer* rpLayer = rpSW->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + Point position; + + position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2 + , abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2 + ); + AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position + , viaSide, viaSide + ); + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + if ( _fromHook != _west) forks.push( getSegmentOppositeHook( _west ), ac ); + else targetContact = ac; + } + if (_south){ + cdebug_log(145,0) << "South" << endl; + const Layer* rpLayer = rpSW->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + Point position; + + position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2 + , abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2 + ); + AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position + , viaSide, viaSide + ); + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + if ( _fromHook != _south) forks.push( getSegmentOppositeHook( _south ), ac ); + else targetContact = ac; + } + if (_north){ + cdebug_log(145,0) << "North" << endl; + const Layer* rpLayer = rpNE->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); + Point position; + + position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2 + , abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2 + ); + AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position + , viaSide, viaSide + ); + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + if ( _fromHook != _north) forks.push( getSegmentOppositeHook( _north ), ac ); + else targetContact = ac; + } + } + cdebug_log(145,0) << "doDevice done" << endl; + cdebug_tabw(145,-1); + return targetContact; + } +/* + AutoContact* GCellTopology::_doDevice ( ForkStack& forks ) { cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl; - // #0: Check if all RoutingPads are set to a component. for ( unsigned int i=0; i<_routingPads.size() ; i++ ) { if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() ) @@ -2288,7 +2360,7 @@ namespace { } cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl; - if (_routingPads.size() > 1){ + if ( _routingPads.size() > 1 ){ // #1: Find RoutingPads to use for AutoContacts NE+SW RoutingPad* rpNE = _routingPads[0]; RoutingPad* rpSW = _routingPads[0]; @@ -2326,10 +2398,6 @@ namespace { bool ne = false; bool sw = false; - cdebug_log(145,0) << "North: " << _north << endl; - cdebug_log(145,0) << "East : " << _east << endl; - cdebug_log(145,0) << "South: " << _south << endl; - cdebug_log(145,0) << "West : " << _west << endl; if ( (_north) || (_east) ){ _northEastContact = doRp_AC ( _gcell , _routingPads[0], true ); ne = true; @@ -2343,151 +2411,1026 @@ namespace { cdebug_log(145,0) << "AutoContact NE: " << _northEastContact << endl; cdebug_log(145,0) << "AutoContact SW: " << _southWestContact << endl; } + + AutoContact* targetContact = NULL; + if (_sourceContact){ + targetContact = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ) + ? _northEastContact : _southWestContact ; + } + cdebug_log(145,0) << "fromHook: " << _fromHook << endl; + cdebug_log(145,0) << "North : " << _north << endl; + cdebug_log(145,0) << "East : " << _east << endl; + cdebug_log(145,0) << "South : " << _south << endl; + cdebug_log(145,0) << "West : " << _west << endl; + if ( _east and (_fromHook != _east) ) { + forks.push( getSegmentOppositeHook( _east ), _northEastContact ); + } + if ( _west and (_fromHook != _west) ) { + forks.push( getSegmentOppositeHook( _west ), _southWestContact ); + } + if ( _north and (_fromHook != _north) ) { + forks.push( getSegmentOppositeHook( _north ), _northEastContact ); + } + if ( _south and (_fromHook != _south) ) { + forks.push( getSegmentOppositeHook( _south ), _southWestContact ); + } + + cdebug_log(145,0) << "doDevice done" << endl; cdebug_tabw(145,-1); - } + + return targetContact; + }*/ - void GCellTopology::_doHChannel ( ForkStack& forks ) + AutoContact* GCellTopology::_doHChannel ( ForkStack& forks ) { cdebug_log(145,1) << "void GCellTopology::_doHChannel ( ForkStack& forks )" << _gcell << endl; - vector hooks; - vector autoContacts; - + vector hooks; + static const Layer* hLayer = Session::getRoutingLayer( 1 ); + static DbU::Unit hWidth = Session::getWireWidth ( 1 ); + static const Layer* vLayer = Session::getRoutingLayer( 2 ); + static DbU::Unit vWidth = Session::getWireWidth ( 2 ); + const Layer* horizontalLayer = hLayer; + DbU::Unit horizontalWidth = hWidth; + const Layer* verticalLayer = vLayer; + DbU::Unit verticalWidth = vWidth; + AutoContact* targetContact = NULL; + + // Save segments only cdebug_log(145,0) << "fromHook: " << _fromHook << endl; for ( Hook* toHook : _fromHook->getHooks() ) { cdebug_log(145,0) << "toHook: " << toHook << endl; Segment* s = dynamic_cast( toHook->getComponent() ); - if (s) hooks.push_back(toHook); - } - - sort( hooks.begin(), hooks.end(), SortHkByX(NoFlags) ); - size_t i = 0; - for (vector::iterator it = hooks.begin(); it != hooks.end(); it++){ - - Horizontal* h = dynamic_cast((*it)->getComponent()); - Vertical* v = dynamic_cast ((*it)->getComponent()); - AutoContact* ac = NULL; - if (i == 0){ - if (h){ - ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); - ac->setX(_gcell->getXMin()); - ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); - } else if (v){ - ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - ac->setX(v->getX()); - ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); - } - } else if (i == hooks.size()-1){ - if (h){ - ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); - ac->setX(_gcell->getXMin() + _gcell->getWidth()); - ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); - } else if (v){ - ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); - ac->setX(v->getX()); - ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); - } - } else { - ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); - ac->setX(v->getX()); - ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); - } - autoContacts.push_back(ac); - - cdebug_log(145,0) << "FromHook: " << _fromHook << endl << endl; - if (_fromHook->getComponent() == (*it)->getComponent()){ - cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl; - - if (_sourceContact) { - - if ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ){ - AutoSegment* globalSegment = AutoSegment::create( ac - , _sourceContact - , static_cast( _fromHook->getComponent() ) - ); - globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 ); - cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - } else if ( getSegmentHookType(_fromHook) & (EastBound|SouthBound) ){ - AutoSegment* globalSegment = AutoSegment::create( ac - , _sourceContact - , static_cast( _fromHook->getComponent() ) - ); - globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 ); - cdebug_log(145,0) << "Create global segment: " << globalSegment << endl; - } - } else _fromHook = NULL; - } else { - forks.push( getSegmentOppositeHook((*it)), ac ); + if (s) { + hooks.push_back(toHook); } - i++; } - - - cdebug_log(145,0) << "Segments:" << hooks.size() <::iterator it = hooks.begin(); it != hooks.end(); it++){ - cdebug_log(145,0) << (*it)->getComponent() << endl; + cdebug_log(145,0) << "toHook: " << (*it) << endl; } - cdebug_log(145,0) << "AutoContacts:" << autoContacts.size() << endl; - static const Layer* hLayer = Session::getRoutingLayer( 1 ); - static DbU::Unit hWidth = Session::getWireWidth ( 1 ); - const Layer* horizontalLayer = hLayer; - DbU::Unit horizontalWidth = hWidth; + size_t i = 0; - for (size_t j=1; j < autoContacts.size(); j++){ - AutoSegment::create( autoContacts[j-1] - , autoContacts[j] - , Horizontal::create( autoContacts[j-1]->base() - , autoContacts[j]->base() - , horizontalLayer - , autoContacts[j-1]->getY() - , horizontalWidth - ) - ); + // More than 2 AutoContacts to create + cdebug_log(145,0) << "Number of hooks: " << hooks.size() << endl; + if ( hooks.size() > 2 ){ + cdebug_log(145,0) << "Number of hooks > 2 : " << hooks.size() << endl; + vector autoContacts; + bool firstH = false; + + for (vector::iterator it = hooks.begin(); it != hooks.end(); it++){ + + Horizontal* h = dynamic_cast((*it)->getComponent()); + Vertical* v = dynamic_cast ((*it)->getComponent()); + AutoContact* ac = NULL; + cdebug_log(145,0) << "index: " << i << endl; + cdebug_log(145,0) << "h : " << h << endl; + cdebug_log(145,0) << "v : " << v << endl; + + if (i == 0){ + if (h){ + ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + ac->setX(_gcell->getXMin()); + ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); + firstH = true; + } else if (v){ + ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(v->getX()); + ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); + } + } else if (i == hooks.size()-1){ + if (h){ + ac = autoContacts[i-1]; + } else if (v){ + ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(v->getX()); + ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); + } + } else { + if ((i == 1)&&(firstH)){ + ac = autoContacts[i-1]; + if (v) ac->setX(v->getX()); + else { + cerr << Warning( "Something is wrong with the number of globals in this HChannel." + , getString(_gcell).c_str() ) + << endl; + } + } else { + ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + ac->setX(v->getX()); + ac->setY(_gcell->getYMin() + _gcell->getHeight()/2); + } + } + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + autoContacts.push_back(ac); + + cdebug_log(145,0) << "FromHook: " << _fromHook << endl; + if (_fromHook->getComponent() == (*it)->getComponent()){ + cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl; + targetContact = ac; + } else { + forks.push( getSegmentOppositeHook((*it)), ac ); + } + i++; + } + cdebug_log(145,0) << "Chain contacts: " << endl; + for (size_t j=1; j < autoContacts.size(); j++){ + if (autoContacts[j-1] != autoContacts[j]){ + AutoSegment* globalSegment = + AutoSegment::create( autoContacts[j-1] , autoContacts[j] + , Horizontal::create( autoContacts[j-1]->base() , autoContacts[j]->base() + , horizontalLayer + , autoContacts[j-1]->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + } + } + // There are only 2 AutoContacts to create + } else if (hooks.size() == 2){ + cdebug_log(145,0) << "Number of hooks == 2 : " << hooks.size() << endl; + Horizontal* h0 = dynamic_cast(hooks[0]->getComponent()); + Vertical* v0 = dynamic_cast (hooks[0]->getComponent()); + Horizontal* h1 = dynamic_cast(hooks[1]->getComponent()); + Vertical* v1 = dynamic_cast (hooks[1]->getComponent()); + AutoContact* source = NULL; + AutoContact* target = NULL; + cdebug_log(145,0) << "h0: " << h0 << endl; + cdebug_log(145,0) << "v0: " << v0 << endl; + cdebug_log(145,0) << "h1: " << h1 << endl; + cdebug_log(145,0) << "v1: " << v1 << endl; + + if ((v0 != NULL) && (v1 != NULL)){ + cdebug_log(145,0) << "case 2V" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(v0->getX()); + source->setY(_gcell->getYMin() + _gcell->getHeight()/2); + target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + target->setX(v1->getX()); + target->setY(_gcell->getYMin() + _gcell->getHeight()/2); + + cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Horizontal::create( source->base(), target->base() + , horizontalLayer + , source->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + targetContact = source; + forks.push( getSegmentOppositeHook(hooks[1]), target ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + targetContact = target; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + + } else if (((h0 != NULL) && (v1 != NULL)) || ((v0 != NULL) && (h1 != NULL))){ + cdebug_log(145,0) << "case 1V and 1H" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; + if (h0 && v1){ + source->setX(v1->getX()); + } else { + source->setX(v0->getX()); + } + source->setY(_gcell->getYMin() + _gcell->getHeight()/2); + targetContact = source; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + forks.push( getSegmentOppositeHook(hooks[1]), source ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + } else if ((h0 != NULL) && (h1 != NULL)){ + cdebug_log(145,0) << "case 2H" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(_gcell->getXMin() + _gcell->getWidth()/2); + source->setY(_gcell->getYMin() + _gcell->getHeight()/2); + target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + target->setX(_gcell->getXMin() + _gcell->getWidth()/2); + target->setY(_gcell->getYMin() + _gcell->getHeight()/2); + + cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; + + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Vertical::create( source->base(), target->base() + , verticalLayer + , source->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + targetContact = source; + forks.push( getSegmentOppositeHook(hooks[1]), target ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + targetContact = target; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + } } - - for (vector::iterator it = autoContacts.begin(); it != autoContacts.end(); it++){ - cdebug_log(145,0) << (*it) << endl; - } - cdebug_log(145,0) << _sourceContact << endl; - - /*throw Error( "GCellTopology::_doHChannel() Unimplemented, blame goes to E. Lao.\n" - " On: %s." - , getString(_gcell).c_str() - );*/ + cdebug_log(145,0) << "doHChannel done" << endl; cdebug_tabw(145,-1); + + return targetContact; } - void GCellTopology::_doVChannel () + AutoContact* GCellTopology::_doVChannel ( ForkStack& forks ) { cdebug_log(145,1) << "void GCellTopology::_doVChannel ()" << _gcell << endl; - /*throw Error( "GCellTopology::_doVChannel() Unimplemented, blame goes to E. Lao.\n" - " On: %s." - , getString(_gcell).c_str() - );*/ + + vector hooks; + static const Layer* hLayer = Session::getRoutingLayer( 1 ); + static DbU::Unit hWidth = Session::getWireWidth ( 1 ); + static const Layer* vLayer = Session::getRoutingLayer( 2 ); + static DbU::Unit vWidth = Session::getWireWidth ( 2 ); + + const Layer* horizontalLayer = hLayer; + DbU::Unit horizontalWidth = hWidth; + const Layer* verticalLayer = vLayer; + DbU::Unit verticalWidth = vWidth; + AutoContact* targetContact = NULL; + + // Save segments only + cdebug_log(145,0) << "fromHook: " << _fromHook << endl; + + + for ( Hook* toHook : _fromHook->getHooks() ) { + cdebug_log(145,0) << "toHook: " << toHook << endl; + + Segment* s = dynamic_cast( toHook->getComponent() ); + if (s) { + hooks.push_back(toHook); + } + } + + cdebug_log(145,0) << "Sorted hooks:" << endl; + sort( hooks.begin(), hooks.end(), SortHkByY(NoFlags) ); + for (vector::iterator it = hooks.begin(); it != hooks.end(); it++){ + cdebug_log(145,0) << "toHook: " << (*it) << endl; + } + size_t i = 0; + + // More than 2 AutoContacts to create + cdebug_log(145,0) << "Number of hooks: " << hooks.size() << endl; + if ( hooks.size() > 2 ){ + cdebug_log(145,0) << "Number of hooks > 2 : " << hooks.size() << endl; + vector autoContacts; + bool firstV = false; + + for (vector::iterator it = hooks.begin(); it != hooks.end(); it++){ + + Horizontal* h = dynamic_cast((*it)->getComponent()); + Vertical* v = dynamic_cast ((*it)->getComponent()); + AutoContact* ac = NULL; + cdebug_log(145,0) << "index: " << i << endl; + cdebug_log(145,0) << "h : " << h << endl; + cdebug_log(145,0) << "v : " << v << endl; + + if (i == 0){ + if (v){ + ac = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(_gcell->getXMin() + _gcell->getWidth()/2); + ac->setY(_gcell->getYMin()); + firstV = true; + } else if (h){ + ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(_gcell->getXMin() + _gcell->getWidth()/2); + ac->setY(h->getY()); + } + } else if (i == hooks.size()-1){ + if (v){ + ac = autoContacts[i-1]; + } else if (h){ + ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(_gcell->getXMin() + _gcell->getWidth()/2); + ac->setY(h->getY()); + } + } else { + if ((i == 1)&&(firstV)){ + ac = autoContacts[i-1]; + if (h) ac->setY(h->getY()); + else { + cerr << Warning( "Something is wrong with the number of globals in this VChannel." + , getString(_gcell).c_str() ) + << endl; + } + } else { + ac = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + ac->setX(_gcell->getXMin() + _gcell->getWidth()/2); + ac->setY(h->getY()); + } + } + cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl; + autoContacts.push_back(ac); + + cdebug_log(145,0) << "FromHook: " << _fromHook << endl << endl; + if (_fromHook->getComponent() == (*it)->getComponent()){ + cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl; + targetContact = ac; + } else { + forks.push( getSegmentOppositeHook((*it)), ac ); + } + i++; + } + cdebug_log(145,0) << "Chain contacts: " << endl; + for (size_t j=1; j < autoContacts.size(); j++){ + if (autoContacts[j-1] != autoContacts[j]){ + AutoSegment* globalSegment = + AutoSegment::create( autoContacts[j-1] , autoContacts[j] + , Vertical::create( autoContacts[j-1]->base() , autoContacts[j]->base() + , verticalLayer + , autoContacts[j-1]->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + } + } + // There are only 2 AutoContacts to create + } else if (hooks.size() == 2){ + cdebug_log(145,0) << "Number of hooks == 2 : " << hooks.size() << endl; + Horizontal* h0 = dynamic_cast(hooks[0]->getComponent()); + Vertical* v0 = dynamic_cast (hooks[0]->getComponent()); + Horizontal* h1 = dynamic_cast(hooks[1]->getComponent()); + Vertical* v1 = dynamic_cast (hooks[1]->getComponent()); + AutoContact* source = NULL; + AutoContact* target = NULL; + cdebug_log(145,0) << "h0: " << h0 << endl; + cdebug_log(145,0) << "v0: " << v0 << endl; + cdebug_log(145,0) << "h1: " << h1 << endl; + cdebug_log(145,0) << "v1: " << v1 << endl; + + if ((h0 != NULL) && (h1 != NULL)){ + cdebug_log(145,0) << "case 2H" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(_gcell->getXMin() + _gcell->getWidth()/2); + source->setY(h0->getY()); + + target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + target->setX(_gcell->getXMin() + _gcell->getWidth()/2); + target->setY(h1->getY()); + + cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; + + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Vertical::create( source->base(), target->base() + , verticalLayer + , source->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + targetContact = source; + forks.push( getSegmentOppositeHook(hooks[1]), target ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + targetContact = target; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + + } else if (((v0 != NULL) && (h1 != NULL)) || ((h0 != NULL) && (v1 != NULL))){ + cdebug_log(145,0) << "case 1V and 1H" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + if (v0 && h1){ + source->setY(h1->getY()); + } else { + source->setY(h0->getY()); + } + source->setX(_gcell->getXMin() + _gcell->getWidth()/2); + targetContact = source; + + cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + forks.push( getSegmentOppositeHook(hooks[1]), source ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + } else if ((v0 != NULL) && (v1 != NULL)){ + cdebug_log(145,0) << "case 2V" << endl; + source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(_gcell->getXMin() + _gcell->getWidth()/2); + source->setY(_gcell->getYMin() + _gcell->getHeight()/2); + target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + target->setX(_gcell->getXMin() + _gcell->getWidth()/2); + target->setY(_gcell->getYMin() + _gcell->getHeight()/2); + + cdebug_log(145,0) << "[Create AutoContact Source]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact Target]: " << target << endl; + + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Horizontal::create( source->base(), target->base() + , horizontalLayer + , source->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + if (_fromHook->getComponent() == hooks[0]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[0]->getComponent() << endl; + targetContact = source; + forks.push( getSegmentOppositeHook(hooks[1]), target ); + + } else if (_fromHook->getComponent() == hooks[1]->getComponent()){ + cdebug_log(145,0) << "Found from:" << hooks[1]->getComponent() << endl; + targetContact = target; + forks.push( getSegmentOppositeHook(hooks[0]), source ); + } + } + } + cdebug_log(145,0) << "doVChannel done" << endl; cdebug_tabw(145,-1); + + return targetContact; } - void GCellTopology::_doHStrut () + unsigned int GCellTopology::getNumberGlobals () { - cdebug_log(145,1) << "void GCellTopology::_doHStrut ()" << _gcell << endl; - //throw Error( "GCellTopology::_doHStrut() Unimplemented, blame goes to E. Lao." ); - cdebug_tabw(145,-1); + unsigned int i = 0; + if (_north) i++; + if (_south) i++; + if (_east ) i++; + if (_west ) i++; + return i; } - void GCellTopology::_doVStrut () + unsigned int GCellTopology::getDeviceNeighbourBound() { - cdebug_log(145,1) << "void GCellTopology::_doVStrut ()" << _gcell << endl; - //throw Error( "GCellTopology::_doVStrut() Unimplemented, blame goes to E. Lao." ); + unsigned int bound = 0; + if (_north){ + if (_gcell->getNorth()->isDevice()) bound = NorthBound; + } else if (_south){ + if (_gcell->getSouth()->isDevice()) bound = SouthBound; + } else if (_east){ + if (_gcell->getEast()->isDevice() ) bound = EastBound; + } else if (_west){ + if (_gcell->getWest()->isDevice() ) bound = WestBound; + } + return bound; + } + + + AutoContact* GCellTopology::_doStrut ( ForkStack& forks ) + { + cdebug_log(145,1) << "void GCellTopology::_doStrut ()" << _gcell << endl; + + static const Layer* hLayer = Session::getRoutingLayer( 1 ); + static DbU::Unit hWidth = Session::getWireWidth ( 1 ); + static const Layer* vLayer = Session::getRoutingLayer( 2 ); + static DbU::Unit vWidth = Session::getWireWidth ( 2 ); + + const Layer* horizontalLayer = hLayer; + DbU::Unit horizontalWidth = hWidth; + const Layer* verticalLayer = vLayer; + DbU::Unit verticalWidth = vWidth; + AutoContact* targetContact = NULL; // Contact for fromHook segment + cdebug_log(145,0) << "FromHook: " << _fromHook << endl; + cdebug_log(145,0) << "North : " << _north << endl; + cdebug_log(145,0) << "East : " << _east << endl; + cdebug_log(145,0) << "South : " << _south << endl; + cdebug_log(145,0) << "West : " << _west << endl; + + // Determine NE and SW contacts + if ( getNumberGlobals() == 2 ){ + cdebug_log(145,0) << "Case 2 globals: " << getNumberGlobals() << endl; + + AutoContact* source = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + targetContact = source; + if ( ((_north != NULL) && (_west != NULL)) + || ((_north != NULL) && (_east != NULL)) + || ((_south != NULL) && (_west != NULL)) + || ((_south != NULL) && (_east != NULL)) + ){ + if ((_north != NULL) && (_west != NULL)) { + cdebug_log(145,0) << "North: " << _north << endl; + cdebug_log(145,0) << "West : " << _west << endl; + source->setX(_north->getComponent()->getX()); + source->setY(_west->getComponent ()->getY()); + } else if ((_north != NULL) && (_east != NULL)) { + cdebug_log(145,0) << "North: " << _north << endl; + cdebug_log(145,0) << "East : " << _east << endl; + source->setX(_north->getComponent()->getX()); + source->setY(_east->getComponent ()->getY()); + } else if ((_south != NULL) && (_west != NULL)) { + cdebug_log(145,0) << "South: " << _south << endl; + cdebug_log(145,0) << "West : " << _west << endl; + source->setX(_south->getComponent()->getX()); + source->setY(_west->getComponent ()->getY()); + } else if ((_south != NULL) && (_east != NULL)) { + cdebug_log(145,0) << "South: " << _south << endl; + cdebug_log(145,0) << "East: " << _east << endl; + source->setX(_south->getComponent()->getX()); + source->setY(_east->getComponent ()->getY()); + } + + cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; + if ( _east and (_fromHook != _east) ) + forks.push( getSegmentOppositeHook( _east ), source ); + if ( _west and (_fromHook != _west) ) + forks.push( getSegmentOppositeHook( _west ), source ); + if ( _north and (_fromHook != _north) ) + forks.push( getSegmentOppositeHook( _north ), source ); + if ( _south and (_fromHook != _south) ) + forks.push( getSegmentOppositeHook( _south ), source ); + + } else if ((_north != NULL) && (_south != NULL)) { + cdebug_log(145,0) << "Case NS" << endl; + AutoContact* target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(_north->getComponent()->getX()); + source->setY(_gcell->getYMin() + _gcell->getHeight()/2); + target->setX(_south->getComponent()->getX()); + target->setY(_gcell->getYMin() + _gcell->getHeight()/2); + + if (_north->getComponent()->getX() > _south->getComponent()->getX()) { + swap( source, target ); + if ( _north and (_fromHook != _north) ){ + forks.push( getSegmentOppositeHook( _north ), target ); + } else if ( _south and (_fromHook != _south) ){ + forks.push( getSegmentOppositeHook( _south ), source ); + targetContact = target; + } else { + cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } else { + if ( _north and (_fromHook != _north) ){ + forks.push( getSegmentOppositeHook( _north ), source ); + targetContact = target; + } else if ( _south and (_fromHook != _south) ){ + forks.push( getSegmentOppositeHook( _south ), target ); + } else { + cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } + cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << target << endl; + + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Horizontal::create( source->base(), target->base() + , horizontalLayer + , source->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + } else if ((_east != NULL) && (_west != NULL) ) { + cdebug_log(145,0) << "Case EW" << endl; + AutoContact* target = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + source->setX(_gcell->getXMin() + _gcell->getWidth()/2); + source->setY(_east->getComponent()->getY()); + target->setX(_gcell->getXMin() + _gcell->getWidth()/2); + target->setY(_west->getComponent()->getY()); + cdebug_log(145,0) << "1" << endl; + + if (_east->getComponent()->getY() > _west->getComponent()->getY()){ + cdebug_log(145,0) << "2.1" << endl; + swap( source, target ); + + cdebug_log(145,0) << "3.1" << endl; + if ( _east and (_fromHook != _east) ){ + forks.push( getSegmentOppositeHook( _east ), target ); + } else if ( _west and (_fromHook != _west) ){ + forks.push( getSegmentOppositeHook( _west ), source ); + targetContact = target; + } else { + cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } else { + cdebug_log(145,0) << "2.2" << endl; + if ( _east and (_fromHook != _east) ){ + forks.push( getSegmentOppositeHook( _east ), source ); + targetContact = target; + } else if ( _west and (_fromHook != _west) ){ + forks.push( getSegmentOppositeHook( _west ), target ); + } else { + cerr << Warning( "Something is wrong with the globals and the fromHook in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } + cdebug_log(145,0) << "[Create AutoContact]: " << source << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << target << endl; + + AutoSegment* globalSegment = + AutoSegment::create( source, target + , Vertical::create( source->base(), target->base() + , verticalLayer + , source->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + } else { + cerr << Warning( "Something is wrong with the globals in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } else if ( getNumberGlobals() == 3 ){ + cdebug_log(145,0) << "Case 3 globals: " << getNumberGlobals() << endl; + + AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContact* xtee = NULL; + xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + + if ((_north != NULL) && (_south != NULL) && (_east != NULL)){ + cdebug_log(145,0) << "Case NSE " << endl; + xtee = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + + if (_north->getComponent()->getX() < _south->getComponent()->getX()){ + turn->setX(_north->getComponent()->getX()); + xtee->setX(_south->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), turn ); + else targetContact = turn; + if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); + else targetContact = xtee; + + } else { + turn->setX(_south->getComponent()->getX()); + xtee->setX(_north->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); + else targetContact = xtee; + if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), turn ); + else targetContact = turn; + } + turn->setY(_east->getComponent()->getY()); + xtee->setY(_east->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); + else targetContact = xtee; + + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; + AutoSegment* globalSegment = + AutoSegment::create( turn, xtee + , Horizontal::create( turn->base(), xtee->base() + , horizontalLayer + , turn->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + } else if ((_north != NULL) && (_south != NULL) && (_west != NULL)){ + cdebug_log(145,0) << "Case NSW " << endl; + xtee = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + + if (_north->getComponent()->getX() < _south->getComponent()->getX()){ + xtee->setX(_north->getComponent()->getX()); + turn->setX(_south->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); + else targetContact = xtee; + if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), turn ); + else targetContact = turn; + + } else { + xtee->setX(_south->getComponent()->getX()); + turn->setX(_north->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), turn ); + else targetContact = turn; + if ( _south and (_fromHook != _south) ) forks.push( getSegmentOppositeHook( _south ), xtee ); + else targetContact = xtee; + } + turn->setY(_east->getComponent()->getY()); + xtee->setY(_east->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); + else targetContact = xtee; + + cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment = + AutoSegment::create( xtee, turn + , Horizontal::create( xtee->base(), turn->base() + , horizontalLayer + , xtee->getY() + , horizontalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + + } else if ((_east != NULL) && (_north != NULL) && (_west != NULL)){ + cdebug_log(145,0) << "Case EWN " << endl; + xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + + if (_east->getComponent()->getY() < _west->getComponent()->getY()){ + turn->setY(_east->getComponent()->getY()); + xtee->setY(_west->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), turn ); + else targetContact = turn; + if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); + else targetContact = xtee; + + } else { + turn->setY(_west->getComponent()->getY()); + xtee->setY(_east->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); + else targetContact = xtee; + if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), turn ); + else targetContact = turn; + } + turn->setX(_north->getComponent()->getX()); + xtee->setX(_north->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); + else targetContact = xtee; + + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; + AutoSegment* globalSegment = + AutoSegment::create( turn, xtee + , Vertical::create( turn->base(), xtee->base() + , verticalLayer + , turn->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + } else if ((_east != NULL) && (_south != NULL) && (_west != NULL)){ + cdebug_log(145,0) << "Case EWS " << endl; + xtee = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + + if (_east->getComponent()->getY() < _west->getComponent()->getY()){ + xtee->setY(_east->getComponent()->getY()); + turn->setY(_west->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), xtee ); + else targetContact = xtee; + if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), turn ); + else targetContact = turn; + + } else { + xtee->setY(_west->getComponent()->getY()); + turn->setY(_east->getComponent()->getY()); + if ( _east and (_fromHook != _east) ) forks.push( getSegmentOppositeHook( _east ), turn ); + else targetContact = turn; + if ( _west and (_fromHook != _west) ) forks.push( getSegmentOppositeHook( _west ), xtee ); + else targetContact = xtee; + } + turn->setX(_south->getComponent()->getX()); + xtee->setX(_south->getComponent()->getX()); + if ( _north and (_fromHook != _north) ) forks.push( getSegmentOppositeHook( _north ), xtee ); + else targetContact = xtee; + + cdebug_log(145,0) << "[Create AutoContact]: " << xtee << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment = + AutoSegment::create( xtee, turn + , Vertical::create( xtee->base(), turn->base() + , verticalLayer + , turn->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment << endl; + + } else { + cerr << Warning( "Something is wrong with the globals in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + } else if ( getNumberGlobals() == 4 ){ + cdebug_log(145,0) << "Case 4 globals: " << getNumberGlobals() << endl; + AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); + AutoContact* hteeh = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) ); + AutoContact* vteev = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) ); + + if ( (_north->getComponent()->getX() < _south->getComponent()->getX() ) + && (_east->getComponent ()->getY() < _west->getComponent ()->getY() ) + ) { + cdebug_log(145,0) << "(N.X < S.X) & (E.Y < W.Y)" << endl; + turn->setX (_north->getComponent()->getX()); + turn->setY (_east->getComponent ()->getY()); + hteeh->setX(_south->getComponent()->getX()); + hteeh->setY(_east->getComponent ()->getY()); + vteev->setX(_north->getComponent()->getX()); + vteev->setY(_west->getComponent ()->getY()); + + if ( _east and (_fromHook != _east) ) + forks.push( getSegmentOppositeHook( _east ), hteeh ); + else targetContact = hteeh; + if ( _west and (_fromHook != _west) ) + forks.push( getSegmentOppositeHook( _west ), vteev ); + else targetContact = vteev; + if ( _north and (_fromHook != _north) ) + forks.push( getSegmentOppositeHook( _north ), vteev ); + else targetContact = vteev; + if ( _south and (_fromHook != _south) ) + forks.push( getSegmentOppositeHook( _south ), hteeh ); + else targetContact = hteeh; + + cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment1 = + AutoSegment::create( turn, hteeh + , Horizontal::create( turn->base(), hteeh->base() + , horizontalLayer + , turn->getY() + , horizontalWidth + ) + ); + AutoSegment* globalSegment2 = + AutoSegment::create( turn, hteeh + , Vertical::create( turn->base(), hteeh->base() + , verticalLayer + , turn->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment1 << endl; + cdebug_log(145,0) << "[Create global segment]: " << globalSegment2 << endl; + + } else if ( (_north->getComponent()->getX() > _south->getComponent()->getX() ) + && (_east->getComponent ()->getY() < _west->getComponent ()->getY() ) + ) { + cdebug_log(145,0) << "(N.X > S.X) & (E.Y < W.Y)" << endl; + turn->setX (_south->getComponent()->getX()); + turn->setY (_west->getComponent ()->getY()); + hteeh->setX(_north->getComponent()->getX()); + hteeh->setY(_east->getComponent ()->getY()); + vteev->setX(_south->getComponent()->getX()); + vteev->setY(_east->getComponent ()->getY()); + + if ( _east and (_fromHook != _east) ) + forks.push( getSegmentOppositeHook( _east ), hteeh ); + else targetContact = hteeh; + if ( _west and (_fromHook != _west) ) + forks.push( getSegmentOppositeHook( _west ), turn ); + else targetContact = turn; + if ( _north and (_fromHook != _north) ) + forks.push( getSegmentOppositeHook( _north ), hteeh ); + else targetContact = hteeh; + if ( _south and (_fromHook != _south) ) + forks.push( getSegmentOppositeHook( _south ), vteev ); + else targetContact = vteev; + + cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment1 = + AutoSegment::create( vteev, hteeh + , Horizontal::create( vteev->base(), hteeh->base() + , horizontalLayer + , vteev->getY() + , horizontalWidth + ) + ); + AutoSegment* globalSegment2 = + AutoSegment::create( vteev, turn + , Vertical::create( vteev->base(), turn->base() + , verticalLayer + , vteev->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment1 << endl; + cdebug_log(145,0) << "[Create global segment]: " << globalSegment2 << endl; + + } else if ( (_north->getComponent()->getX() < _south->getComponent()->getX() ) + && (_east->getComponent ()->getY() > _west->getComponent ()->getY() ) + ) { + cdebug_log(145,0) << "(N.X < S.X) & (E.Y > W.Y)" << endl; + turn->setX (_north->getComponent()->getX()); + turn->setY (_east->getComponent ()->getY()); + hteeh->setX(_south->getComponent()->getX()); + hteeh->setY(_east->getComponent ()->getY()); + vteev->setX(_south->getComponent()->getX()); + vteev->setY(_west->getComponent ()->getY()); + + if ( _east and (_fromHook != _east) ) + forks.push( getSegmentOppositeHook( _east ), hteeh ); + else targetContact = hteeh; + if ( _west and (_fromHook != _west) ) + forks.push( getSegmentOppositeHook( _west ), vteev ); + else targetContact = vteev; + if ( _north and (_fromHook != _north) ) + forks.push( getSegmentOppositeHook( _north ), turn ); + else targetContact = turn; + if ( _south and (_fromHook != _south) ) + forks.push( getSegmentOppositeHook( _south ), vteev ); + else targetContact = vteev; + + cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment1 = + AutoSegment::create( turn, hteeh + , Horizontal::create( turn->base(), hteeh->base() + , horizontalLayer + , turn->getY() + , horizontalWidth + ) + ); + AutoSegment* globalSegment2 = + AutoSegment::create( vteev, hteeh + , Vertical::create( vteev->base(), hteeh->base() + , verticalLayer + , vteev->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment1 << endl; + cdebug_log(145,0) << "[Create global segment]: " << globalSegment2 << endl; + + } else { + cdebug_log(145,0) << "(N.X > S.X) & (E.Y > W.Y)" << endl; + turn->setX (_south->getComponent()->getX()); + turn->setY (_east->getComponent ()->getY()); + hteeh->setX(_north->getComponent()->getX()); + hteeh->setY(_east->getComponent ()->getY()); + vteev->setX(_south->getComponent()->getX()); + vteev->setY(_west->getComponent ()->getY()); + + if ( _east and (_fromHook != _east) ) + forks.push( getSegmentOppositeHook( _east ), hteeh ); + else targetContact = hteeh; + if ( _west and (_fromHook != _west) ) + forks.push( getSegmentOppositeHook( _west ), vteev ); + else targetContact = vteev; + if ( _north and (_fromHook != _north) ) + forks.push( getSegmentOppositeHook( _north ), hteeh ); + else targetContact = hteeh; + if ( _south and (_fromHook != _south) ) + forks.push( getSegmentOppositeHook( _south ), vteev ); + else targetContact = vteev; + + cdebug_log(145,0) << "[Create AutoContact]: " << hteeh << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << vteev << endl; + cdebug_log(145,0) << "[Create AutoContact]: " << turn << endl; + AutoSegment* globalSegment1 = + AutoSegment::create( turn, hteeh + , Horizontal::create( turn->base(), hteeh->base() + , horizontalLayer + , turn->getY() + , horizontalWidth + ) + ); + AutoSegment* globalSegment2 = + AutoSegment::create( vteev, turn + , Vertical::create( vteev->base(), turn->base() + , verticalLayer + , vteev->getX() + , verticalWidth + ) + ); + cdebug_log(145,0) << "[Create global segment]: " << globalSegment1 << endl; + cdebug_log(145,0) << "[Create global segment]: " << globalSegment2 << endl; + } + } else { + cerr << Warning( "Something is wrong with the number of globals in this Strut." + , getString(_gcell).c_str() ) + << endl; + } + cdebug_log(145,0) << "doStrut done" << endl; cdebug_tabw(145,-1); + + return targetContact; } @@ -2559,8 +3502,8 @@ namespace Anabatic { size_t degree = routingPads.getSize(); if (degree == 0) { - cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)." - ,getString(net->getName()).c_str()) << endl; + cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)." + ,getString(net->getName()).c_str()) << endl; cdebug_tabw(145,-1); return; } @@ -2649,6 +3592,7 @@ namespace Anabatic { lookupClear(); Session::revalidate(); + //Breakpoint::stop( 0, "After construct" ); #if THIS_IS_DISABLED set::iterator iover = overconstraineds.begin(); diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 8bb732bd..dce2061d 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -34,12 +34,11 @@ namespace Anabatic { // Flags for GCell objects states only. static const unsigned int DeviceGCell ; // = (1 << 5); static const unsigned int HChannelGCell ; // = (1 << 6); - static const unsigned int VChannelGCell ; // = (1 << 6); - static const unsigned int HStrutGCell ; // = (1 << 7); - static const unsigned int VStrutGCell ; // = (1 << 7); - static const unsigned int MatrixGCell ; // = (1 << 8); - static const unsigned int IoPadGCell ; // = (1 << 9); - static const unsigned int Saturated ; // = (1 << 10); + static const unsigned int VChannelGCell ; // = (1 << 7); + static const unsigned int StrutGCell ; // = (1 << 8); + static const unsigned int MatrixGCell ; // = (1 << 9); + static const unsigned int IoPadGCell ; // = (1 << 10); + static const unsigned int Saturated ; // = (1 << 11); // Flags for Anabatic objects states only. static const unsigned int DemoMode ; // = (1 << 5); static const unsigned int WarnOnGCellOverload ; // = (1 << 6); @@ -57,7 +56,7 @@ namespace Anabatic { static const unsigned int EndsMask ; // = Source|Target; static const unsigned int DirectionMask ; // = Horizontal|Vertical; static const unsigned int DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; - static const unsigned int GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|HStrutGCell|VStrutGCell|MatrixGCell|IoPadGCell; + static const unsigned int GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell; // Flags for functions arguments only. static const unsigned int Create ; // = (1 << 5); static const unsigned int WithPerpands ; diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 68435d66..35982112 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -100,7 +100,7 @@ namespace Anabatic { inline bool isSRestricted () const; inline bool isERestricted () const; inline bool isWRestricted () const; - inline bool isNotRestricted() const; + inline bool hasRestrictions() const; inline void setRestricted (); inline void clearRestriction (); @@ -190,7 +190,7 @@ namespace Anabatic { inline bool Vertex::isSRestricted () const { return (_flags & SRestricted); } inline bool Vertex::isERestricted () const { return (_flags & ERestricted); } inline bool Vertex::isWRestricted () const { return (_flags & WRestricted); } - inline bool Vertex::isNotRestricted () const { return ((!_flags) & 0xF); } + inline bool Vertex::hasRestrictions () const { return ( isNRestricted()||isSRestricted()||isERestricted()||isWRestricted()) ; } inline void Vertex::setRestricted () { _flags |= 0xF; } inline void Vertex::clearRestriction () { _flags &= ~(0xF); } diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index a718c785..32158756 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -138,8 +138,7 @@ namespace Anabatic { inline bool isDevice () const; inline bool isHChannel () const; inline bool isVChannel () const; - inline bool isHStrut () const; - inline bool isVStrut () const; + inline bool isStrut () const; inline bool isMatrix () const; inline bool isIoPad () const; bool isWest ( GCell* ) const; @@ -305,8 +304,7 @@ namespace Anabatic { inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; } inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; } inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; } - inline bool GCell::isHStrut () const { return _flags & Flags::HStrutGCell; } - inline bool GCell::isVStrut () const { return _flags & Flags::VStrutGCell; } + inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; } inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; } inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }