diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 909a4edc..672b739e 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -239,14 +239,18 @@ namespace Anabatic { std::swap( gsource, gtarget ); } + cdebug_log(112,0) << "flags:" << side << " axis:" << DbU::getValueString(axis) << endl; + Edge* edge = gsource->getEdgeAt( side, axis ); while ( edge ) { _elements.push_back( Element(edge->getSource(),edge) ); + cdebug_log(112,0) << "| push:" << edge->getSource() << " from " << edge << endl; if (edge->getTarget() == gtarget) break; edge = edge->getTarget()->getEdgeAt( side, axis ); } _elements.push_back( Element(gtarget,NULL) ); + cdebug_log(112,0) << "| push:" << gtarget << " last/target" << endl; cdebug_tabw(112,-1); } @@ -755,8 +759,13 @@ namespace Anabatic { GCellsUnder gcells = getGCellsUnder( segment ); if (not gcells->empty()) { - for ( size_t i=0 ; isize()-1 ; ++i ) + for ( size_t i=0 ; isize()-1 ; ++i ) { + cdebug_log(112,0) << "| " << gcells->gcellAt(i) << endl; + cdebug_log(112,0) << "| " << gcells->edgeAt(i) << endl; gcells->edgeAt(i)->remove( segment ); + } + } else { + cdebug_log(112,0) << "No GCells under segment." << endl; } Contact* source = dynamic_cast( segment->getSource() ); diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index ddf42500..57f2b48a 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -24,6 +24,30 @@ #include "anabatic/AnabaticEngine.h" +namespace { + + using namespace std; + using namespace Hurricane; + + + class SortSegmentByLength { + public: + inline bool operator() ( const Segment*, const Segment* ); + }; + + + inline bool SortSegmentByLength::operator() ( const Segment* lhs, const Segment* rhs ) + { + DbU::Unit delta = rhs->getLength() - lhs->getLength(); + if (delta > 0) return true; + if (delta < 0) return false; + return (lhs->getId() < rhs->getId()); + } + + +} // Anonymous namespace. + + namespace Anabatic { using std::cerr; @@ -210,8 +234,23 @@ namespace Anabatic { DbU::Unit pitch = 0; if (h) pitch = Session::getGHorizontalPitch(); if (v) pitch = Session::getGVerticalPitch(); + + int deltaOccupancy = 0; - incRealOccupancy( segment->getWidth()/pitch ); // Need to take the wire width into account. + if (not Session::getRoutingGauge()->isTwoMetals()) deltaOccupancy = segment->getWidth()/pitch; + else { + // In channel routing, do not increase edge occupancy on terminals, + // because the capacity has already been decreased in annotedGlobalGraph (Katana). + AutoContact* autoContact = Session::lookup( dynamic_cast(segment->getSource()) ); + if (not autoContact or (autoContact->getGCell() != _source)) { + autoContact = Session::lookup( dynamic_cast(segment->getTarget()) ); + if (not autoContact or (autoContact->getGCell() != _target)) { + deltaOccupancy = segment->getWidth()/pitch; + } + } + } + + incRealOccupancy( deltaOccupancy ); } @@ -219,6 +258,9 @@ namespace Anabatic { { for ( size_t i=0 ; i<_segments.size() ; ++i ) { if (_segments[i] == segment) { + cdebug_log(110,0) << "On " << this << endl; + cdebug_log(110,0) << "| remove:" << segment << endl; + std::swap( _segments[i], _segments[_segments.size()-1] ); _segments.pop_back(); incRealOccupancy( -1 ); // Need to take the wire width into account. @@ -245,13 +287,29 @@ namespace Anabatic { DbU::Unit globalThreshold = Session::getSliceHeight()*3; size_t netCount = 0; + sort( _segments.begin(), _segments.end(), SortSegmentByLength() ); + for ( size_t i=0 ; i<_segments.size() ; ) { - if (_segments[i]->getLength() >= globalThreshold) { - NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); - if (netData->isGlobalRouted()) ++netCount; - anabatic->ripup( _segments[i], Flags::Propagate ); - } else { + if (Session::getRoutingGauge()->isTwoMetals()) { + AutoContact* autoContact = Session::lookup( dynamic_cast(_segments[i]->getSource()) ); + if (not autoContact or (autoContact->getGCell() != _source)) { + autoContact = Session::lookup( dynamic_cast(_segments[i]->getTarget()) ); + if (not autoContact or (autoContact->getGCell() != _target)) { + NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); + if (netData->isGlobalRouted()) ++netCount; + anabatic->ripup( _segments[i], Flags::Propagate ); + continue; + } + } ++i; + } else { + if (_segments[i]->getLength() >= globalThreshold) { + NetData* netData = anabatic->getNetData( _segments[i]->getNet() ); + if (netData->isGlobalRouted()) ++netCount; + anabatic->ripup( _segments[i], Flags::Propagate ); + } else { + ++i; + } } } return netCount; diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 231863ea..bdb7b57e 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -506,8 +506,16 @@ namespace Anabatic { { for ( Edge* edge : getEdges(sideHint) ) { GCell* side = edge->getOpposite(this); - if ( (sideHint & (Flags::WestSide |Flags::EastSide )) and (u < side->getYMax()) ) return edge; - if ( (sideHint & (Flags::SouthSide|Flags::NorthSide)) and (u < side->getXMax()) ) return edge; + if ( (sideHint.contains(Flags::WestSide) or sideHint.contains(Flags::EastSide )) + and (u < side->getYMax()) ) { + cdebug_log(112,0) << "H Opposite @" << DbU::getValueString(u) << " is: " << side << endl; + return edge; + } + if ( (sideHint.contains(Flags::SouthSide) or sideHint.contains(Flags::NorthSide)) + and (u < side->getXMax()) ) { + cdebug_log(112,0) << "V Opposite @" << DbU::getValueString(u) << " is: " << side << endl; + return edge; + } } return NULL; } diff --git a/anabatic/src/Matrix.cpp b/anabatic/src/Matrix.cpp index 9f041401..43eda943 100644 --- a/anabatic/src/Matrix.cpp +++ b/anabatic/src/Matrix.cpp @@ -78,8 +78,10 @@ namespace Anabatic { int index = xy2maxIndex(x,y); cdebug_log(110,0) << "Matrix::getUnder() (" - << DbU::getValueString(x) << " " - << DbU::getValueString(y) << ") index:" << index << endl; + << DbU::getValueString(x) << " " + << DbU::getValueString(y) << ") index:" << index + << " " << ((index < 0) ? NULL : _gcells[index]->getUnder(x,y)) << endl; + return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); } diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index febb46a7..86ec4284 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -60,6 +60,7 @@ namespace Anabatic { inline bool isHorizontal () const; inline bool hasNet ( const Net* ) const; inline unsigned int getCapacity () const; + inline unsigned int getReservedCapacity () const; inline unsigned int getCapacity ( size_t depth ) const; inline unsigned int getRealOccupancy () const; inline unsigned int getEstimateOccupancy () const; @@ -135,6 +136,7 @@ namespace Anabatic { inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; } inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } + inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline float Edge::getHistoricCost () const { return _historicCost; } diff --git a/katana/src/Block.cpp b/katana/src/Block.cpp index a54820aa..5f89a91d 100644 --- a/katana/src/Block.cpp +++ b/katana/src/Block.cpp @@ -170,7 +170,6 @@ namespace Katana { if (inet == nets.end()) { nets.insert( irp.second->getNet() ); } else { - if (southWest->getId() == 2998) DebugSession::close(); southWest = southWest->vcut( irp.second->getX() ); southWest->setType( Anabatic::Flags::StdCellRow ); gcellSplitted = true; @@ -181,7 +180,6 @@ namespace Katana { rps .clear(); nets.clear(); if (not gcellSplitted) { - if (southWest->getId() == 2998) DebugSession::close(); southWest = southWest->getEast(); } } @@ -305,8 +303,7 @@ namespace Katana { Session::close(); _katana->openSession(); - for ( Row* row : _rows ) - row->routingPadsSubBreak(); + for ( Row* row : _rows ) row->routingPadsSubBreak(); if (not sessionReUse) Session::close(); } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index b89ca0d0..cfe6e961 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -34,6 +34,7 @@ #include "hurricane/Instance.h" #include "hurricane/Vertical.h" #include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" #include "hurricane/viewer/Script.h" #include "crlcore/Measures.h" #include "anabatic/AutoContact.h" @@ -141,6 +142,7 @@ namespace Katana { using Hurricane::Layer; using Hurricane::Horizontal; using Hurricane::Vertical; + using Hurricane::RoutingPad; using Hurricane::NetRoutingState; using Hurricane::NetRoutingExtension; using Hurricane::Cell; @@ -464,6 +466,32 @@ namespace Katana { } } } + + if (Session::getConfiguration()->isTwoMetals()) { + for ( GCell* gcell : getGCells() ) { + if (not gcell->isStdCellRow()) continue; + + set terminalsX; + for ( Component* component : getCell()->getComponentsUnder(gcell->getBoundingBox()) ) { + RoutingPad* rp = dynamic_cast( component ); + if (rp) terminalsX.insert( rp->getX() ); + } + + unsigned int capacity = 0; + if (gcell->getNorthEdge()) { + capacity = gcell->getNorthEdge()->getCapacity(); + if (terminalsX.size() < capacity) capacity = terminalsX.size(); + else --capacity; + gcell->getNorthEdge()->reserveCapacity( capacity ); + } + if (gcell->getSouthEdge()) { + capacity = gcell->getSouthEdge()->getCapacity(); + if (terminalsX.size() < capacity) capacity = terminalsX.size(); + else --capacity; + gcell->getSouthEdge()->reserveCapacity( capacity ); + } + } + } }