diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index ea4bde74..2af7fb54 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -432,8 +432,8 @@ namespace Anabatic { void AutoHorizontal::updatePositions () { - _sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(getLayer()); - _targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(getLayer()); + _sourcePosition = _horizontal->getSourceX() - getExtensionCap(); + _targetPosition = _horizontal->getTargetX() + getExtensionCap(); } @@ -453,8 +453,8 @@ namespace Anabatic { bool AutoHorizontal::checkPositions () const { bool coherency = true; - DbU::Unit sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(getLayer()); - DbU::Unit targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(getLayer()); + DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(); + DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(); if ( _sourcePosition != sourcePosition ) { cerr << Error ( "%s\n Source position incoherency: " diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index eb1c7fb3..d448de08 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -608,6 +608,13 @@ namespace Anabatic { } + DbU::Unit AutoSegment::getExtensionCap () const + { + DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) ); + if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() ); + return getWidth() / 2; + } + DbU::Unit AutoSegment::getSlack () const { DbU::Unit constraintMin; diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index b0092f5b..98e8369b 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -371,8 +371,8 @@ namespace Anabatic { void AutoVertical::updatePositions () { - _sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(getLayer()); - _targetPosition = _vertical->getTargetY() + Session::getExtensionCap(getLayer()); + _sourcePosition = _vertical->getSourceY() - getExtensionCap(); + _targetPosition = _vertical->getTargetY() + getExtensionCap(); } @@ -392,8 +392,8 @@ namespace Anabatic { bool AutoVertical::checkPositions () const { bool coherency = true; - DbU::Unit sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(getLayer()); - DbU::Unit targetPosition = _vertical->getTargetY() + Session::getExtensionCap(getLayer()); + DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(); + DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(); if ( _sourcePosition != sourcePosition ) { cerr << Error ( "%s\n Source position incoherency: " diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 6e9f82f1..0a0da01f 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1961,11 +1961,12 @@ namespace Anabatic { DbU::Unit width = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2")); if (state) width *= state->getWPitch(); + segment = Horizontal::create( sourceContact , targetContact , _anabatic->getConfiguration()->getGHorizontalLayer() , constraint.getCenter() - , width//DbU::fromLambda(2.0) + , width ); for ( Edge* through : aligneds ) through->add( segment ); if (state){ @@ -1981,7 +1982,7 @@ namespace Anabatic { , targetContact , _anabatic->getConfiguration()->getGVerticalLayer() , constraint.getCenter() - , width//DbU::fromLambda(2.0) + , width ); for ( Edge* through : aligneds ) through->add( segment ); if (state){ diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index 8e88f3cf..84b226ce 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -231,6 +231,7 @@ namespace Anabatic { inline unsigned int getDepth () const; inline DbU::Unit getPitch () const; DbU::Unit getPPitch () const; + DbU::Unit getExtensionCap () const; inline DbU::Unit getAxis () const; virtual DbU::Unit getSourceU () const = 0; virtual DbU::Unit getTargetU () const = 0; diff --git a/cumulus/src/plugins/__init__.py b/cumulus/src/plugins/__init__.py index 8ef8ebc0..e8d4e5cf 100644 --- a/cumulus/src/plugins/__init__.py +++ b/cumulus/src/plugins/__init__.py @@ -41,8 +41,8 @@ def kwParseMain ( **kw ): editor = kw['editor'] if cell == None: cell = editor.getCell() - if cell == None: - raise ErrorMessage( 3, 'Chip: No cell loaded yet.' ) + #if cell == None: + # raise ErrorMessage( 3, 'Chip: No cell loaded yet.' ) return cell, editor diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index c9a827f0..a1e6ef32 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -171,6 +171,7 @@ SharedPath.cpp Path.cpp Occurrence.cpp + Occurrences.cpp QuadTree.cpp Slice.cpp ExtensionSlice.cpp diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 6a81e63d..3745b708 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -813,9 +813,14 @@ DeepNet* Cell::getDeepNet ( Path path, const Net* leafNet ) const return NULL; } +void Cell::flattenNets (uint64_t flags ) +// ************************************* +{ + flattenNets( NULL, flags ); +} -void Cell::flattenNets(uint64_t flags) -// *************************************** +void Cell::flattenNets ( const Instance* instance, uint64_t flags ) +// **************************************************************** { cdebug_log(18,0) << "Cell::flattenNets() flags:0x" << hex << flags << endl; @@ -828,7 +833,7 @@ void Cell::flattenNets(uint64_t flags) vector hyperNets; vector topHyperNets; - for ( Occurrence occurrence : getHyperNetRootNetOccurrences() ) { + for ( Occurrence occurrence : getHyperNetRootNetOccurrences().getSubSet(NotFilter(Occurrence_Contains(instance))) ) { Net* net = static_cast(occurrence.getEntity()); if (net->isClock() and (flags & Flags::NoClockFlatten)) continue; diff --git a/hurricane/src/hurricane/Occurrences.cpp b/hurricane/src/hurricane/Occurrences.cpp new file mode 100644 index 00000000..cce5d612 --- /dev/null +++ b/hurricane/src/hurricane/Occurrences.cpp @@ -0,0 +1,63 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2017-2017, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Occurrences.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Occurrences.h" +#include "hurricane/Instance.h" + + +namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "Occurrence_Contains". + + OccurrenceFilter* Occurrence_Contains::getClone () const + { return new Occurrence_Contains(_instance); } + + + bool Occurrence_Contains::accept ( Occurrence occurrence ) const + { + if (not _instance) return false; + + if (dynamic_cast(occurrence.getEntity()) == _instance) return true; + for ( Instance* instance : occurrence.getPath().getInstances() ) { + if (instance == _instance) return true; + } + return false; + } + + + string Occurrence_Contains::_getString () const + { return ""; } + + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 0086815e..00b3d796 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -507,6 +507,7 @@ class Cell : public Entity { public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);}; public: void setFeed(bool isFeed) {_flags.set(Flags::Feed,isFeed);}; public: void flattenNets(uint64_t flags=Flags::BuildRings); + public: void flattenNets(const Instance* instance, uint64_t flags=Flags::BuildRings); public: void createRoutingPadRings(uint64_t flags=Flags::BuildRings); public: void setFlags(uint64_t flags) { _flags |= flags; } public: void resetFlags(uint64_t flags) { _flags &= ~flags; } diff --git a/hurricane/src/hurricane/hurricane/DebugSession.h b/hurricane/src/hurricane/hurricane/DebugSession.h index a01d893b..c62b7131 100644 --- a/hurricane/src/hurricane/hurricane/DebugSession.h +++ b/hurricane/src/hurricane/hurricane/DebugSession.h @@ -96,6 +96,9 @@ namespace Hurricane { void DebugSession::open ( int minLevel, int maxLevel ) { + if (cdebug.getMinLevel() < minLevel) minLevel = cdebug.getMinLevel(); + if (cdebug.getMaxLevel() > maxLevel) maxLevel = cdebug.getMaxLevel(); + _singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel) , cdebug.setMaxLevel(maxLevel) ) ); } @@ -103,6 +106,9 @@ namespace Hurricane { void DebugSession::open ( const void* symbol, int minLevel, int maxLevel ) { + if (cdebug.getMinLevel() < minLevel) minLevel = cdebug.getMinLevel(); + if (cdebug.getMaxLevel() > maxLevel) maxLevel = cdebug.getMaxLevel(); + if ( _singleton->_isTraced(symbol) ) _singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel) , cdebug.setMaxLevel(maxLevel) ) ); diff --git a/hurricane/src/hurricane/hurricane/Occurrences.h b/hurricane/src/hurricane/hurricane/Occurrences.h index bd81d5d9..ff31f5c6 100644 --- a/hurricane/src/hurricane/hurricane/Occurrences.h +++ b/hurricane/src/hurricane/hurricane/Occurrences.h @@ -1,21 +1,33 @@ -// **************************************************************************************************** -// File: ./hurricane/Occurrences.h -// Authors: R. Escassut -// Copyright (c) BULL S.A. 2000-2016, All Rights Reserved +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2017, All Rights Reserved // // This file is part of Hurricane. // -// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU -// Lesser General Public License as published by the Free Software Foundation, either version 3 of the +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // -// Hurricane is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU // General Public License for more details. // -// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If -// not, see . -// **************************************************************************************************** +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Rémy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Occurrences.cpp" | +// +-----------------------------------------------------------------+ + #ifndef HURRICANE_OCCURENCES #define HURRICANE_OCCURENCES @@ -25,52 +37,47 @@ namespace Hurricane { + class Instance; + + typedef GenericCollection Occurrences; + typedef GenericLocator OccurrenceLocator; + typedef GenericFilter OccurrenceFilter; -// **************************************************************************************************** -// Occurrences declaration -// **************************************************************************************************** +// ------------------------------------------------------------------- +// Class : "Occurrence_Contains". -typedef GenericCollection Occurrences; + class Occurrence_Contains : public OccurrenceFilter { + public: + inline Occurrence_Contains ( const Instance* ); + inline Occurrence_Contains ( const Occurrence_Contains& ); + virtual OccurrenceFilter* getClone () const; + virtual bool accept ( Occurrence ) const; + virtual string _getString () const; + protected: + const Instance* _instance; + }; + Occurrence_Contains::Occurrence_Contains ( const Instance* instance ) + : OccurrenceFilter() + , _instance(instance) + { } -// **************************************************************************************************** -// OccurrenceLocator declaration -// **************************************************************************************************** - -typedef GenericLocator OccurrenceLocator; + Occurrence_Contains::Occurrence_Contains ( const Occurrence_Contains& other ) + : OccurrenceFilter() + , _instance(other._instance) + { } - -// **************************************************************************************************** -// OccurrenceFilter declaration -// **************************************************************************************************** - -typedef GenericFilter OccurrenceFilter; - - - -// **************************************************************************************************** -// for_each_occurrence declaration -// **************************************************************************************************** - -#define for_each_occurrence(occurrence, occurrences)\ -/************************************************/\ -{\ - OccurrenceLocator _locator = occurrences.getLocator();\ - while (_locator.isValid()) {\ - Occurrence occurrence = _locator.getElement();\ +#define for_each_occurrence(occurrence, occurrences) \ +{ \ + OccurrenceLocator _locator = occurrences.getLocator(); \ + while (_locator.isValid()) { \ + Occurrence occurrence = _locator.getElement(); \ _locator.progress(); - -} // End of Hurricane namespace. - +} // Hurricane namespace. #endif // HURRICANE_OCCURENCES - - -// **************************************************************************************************** -// Copyright (c) BULL S.A. 2000-2016, All Rights Reserved -// **************************************************************************************************** diff --git a/katana/src/CMakeLists.txt b/katana/src/CMakeLists.txt index b77aec7a..7fae19eb 100644 --- a/katana/src/CMakeLists.txt +++ b/katana/src/CMakeLists.txt @@ -15,6 +15,8 @@ katana/DataSymmetric.h katana/TrackElement.h katana/TrackElements.h katana/TrackSegment.h + katana/TrackSegmentRegular.h + katana/TrackSegmentWide.h katana/TrackFixedSegment.h katana/TrackMarker.h katana/Track.h @@ -47,6 +49,8 @@ TrackElement.cpp TrackElements.cpp TrackSegment.cpp + TrackSegmentRegular.cpp + TrackSegmentWide.cpp TrackFixedSegment.cpp TrackMarker.cpp Track.cpp diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 3db1b0a2..ad0a459c 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -781,7 +781,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 - , _fsm.getCost(itrack).getTrack()->getAxis() ); + , _fsm.getTrack1(itrack)->getAxis() ); uint32_t flags = 0; if ( rightIntrication ) flags |= RightAxisHint; @@ -850,7 +850,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getCost(itrack).getTrack()->getAxis() ); + , _fsm.getTrack(itrack)->getAxis() ); } cdebug_tabw(159,-1); @@ -932,15 +932,15 @@ namespace Katana { { cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl; - vector< array >& costs = _fsm.getCosts(); + vector& costs = _fsm.getCosts(); size_t itrack = 0; for ( ; itrackisFixed() + or costs[itrack]->isBlockage() + or costs[itrack]->isInfinite() + or costs[itrack]->isOverlapGlobal() ) continue; bool success = true; @@ -979,7 +979,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getCost(itrack).getTrack()->getAxis() + , _fsm.getTrack(itrack)->getAxis() ); break; } diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index d09ea9cb..88713fce 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -507,7 +507,7 @@ namespace Katana { cmess2 << " " << tty::cr; cmess2.flush (); } else { diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index ec7a3ef2..1bb6c676 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -475,7 +475,7 @@ namespace Katana { itrack = 0; if ( (not isOverConstrained()) and fsm.canRipup() ) { - if (fsm.getCosts().size() and fsm.getCost(itrack).isFree()) { + if (fsm.getCosts().size() and fsm.getCost(itrack)->isFree()) { cdebug_log(159,0) << "Insert in free space " << this << endl; fsm.bindToTrack( itrack ); } else { @@ -491,7 +491,7 @@ namespace Katana { } for ( itrack=0 ; itrackisInfinite()) break; if (fsm.insertInTrack(itrack)) break; resetInsertState(); } // Next ripup is possible. @@ -516,7 +516,7 @@ namespace Katana { fsm.doActions(); if (itrack < fsm.getCosts().size()) { - cdebug_log(159,0) << "Placed: @" << DbU::getValueString(fsm.getCost(itrack).getTrack()->getAxis()) + cdebug_log(159,0) << "Placed: @" << DbU::getValueString(fsm.getTrack1(itrack)->getAxis()) << " " << this << endl; } @@ -541,10 +541,10 @@ namespace Katana { if ( _segment->getTrack() and fsm.getCosts().size() - and fsm.getCost(0).isFree() - and (fsm.getCost(0).getTrack() != _segment->getTrack()) ) { + and fsm.getCost(0)->isFree() + and (fsm.getTrack1(0) != _segment->getTrack()) ) { - cerr << "_processPack(): move to " << fsm.getCost(0).getTrack() << endl; + cerr << "_processPack(): move to " << fsm.getTrack1(0) << endl; fsm.moveToTrack( 0 ); } } @@ -569,7 +569,7 @@ namespace Katana { cdebug_log(159,0) << "| " << fsm.getCost(i) << endl; cdebug_tabw(159,-1); - if (fsm.getCosts().size() and fsm.getCost(0).isFree()) { + if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) { cdebug_log(159,0) << "Insert in free space." << endl; fsm.bindToTrack( 0 ); } else { diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 26053225..b0a14db7 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -36,26 +36,6 @@ namespace { using namespace Katana; -// ------------------------------------------------------------------- -// Class : "CompareCostArray". - - class CompareCostArray { - public: - inline CompareCostArray ( uint32_t flags=0 ); - inline bool operator() ( const array& lhs, const array& rhs ); - private: - TrackCost::Compare _compare; - }; - - - inline CompareCostArray::CompareCostArray ( uint32_t flags ) - : _compare(flags) - { } - - inline bool CompareCostArray::operator() ( const array& lhs, const array& rhs ) - { return _compare( lhs[0], rhs[0] ); } - - // ------------------------------------------------------------------- // Class : "Cs1Candidate". @@ -479,7 +459,6 @@ namespace Katana { DataSymmetric* symData = NULL; TrackElement* segment1 = _event1->getSegment(); TrackElement* segment2 = segment1->getSymmetric(); - uint32_t depth = Session::getRoutingGauge()->getLayerDepth(segment1->getLayer()); _event1->setTracksFree( 0 ); _data1 = segment1->getDataNegociate(); @@ -562,58 +541,20 @@ namespace Katana { // if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) ) // _constraint.inflate ( 0, DbU::lambda(1.0) ); - bool inLocalDepth = (depth < 3); - bool isOneLocalTrack = (segment1->isLocal()) - and (segment1->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); - RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer()); for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) { - uint32_t costflags = 0; - costflags |= (segment1->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; - costflags |= (segment1->isAnalog()) ? TrackCost::Analog : 0; - Track* track2 = NULL; if (_event2) { track2 = (_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) ); } - _costs.push_back( array( { TrackCost(NULL), TrackCost(NULL) } ) ); - if (not segment1->isReduced()) { - _costs.back()[0] = track1->getOverlapCost(segment1,costflags); - if (_event2) _costs.back()[1] = track2->getOverlapCost(segment2,costflags); - } else { - _costs.back()[0] = TrackCost(track1); - if (_event2) _costs.back()[1] = TrackCost(track2); - } + _costs.push_back( new TrackCost(segment1,segment2,track1,track2) ); - _costs.back()[0].setAxisWeight ( _event1->getAxisWeight(track1->getAxis()) ); - _costs.back()[0].incDeltaPerpand( _data1->getWiringDelta(track1->getAxis()) ); - if (_event2) { - _costs.back()[1].setAxisWeight ( _event2->getAxisWeight(track2->getAxis()) ); - _costs.back()[1].incDeltaPerpand( _data2->getWiringDelta(track2->getAxis()) ); - _costs.back()[0].merge( _costs.back()[1] ); - - } - - if (segment1->isGlobal()) { - cdebug_log(9000,0) << "Deter| setForGlobal() on " << track1 << endl; - _costs.back()[0].setForGlobal(); - } - - if ( inLocalDepth and (_costs.back()[0].getDataState() == DataNegociate::MaximumSlack) ) - _costs.back()[0].setInfinite(); - - if ( isOneLocalTrack - and _costs.back()[0].isOverlapGlobal() - and (_costs.back()[0].getDataState() >= DataNegociate::ConflictSolveByHistory) ) - _costs.back()[0].setInfinite(); - - _costs.back()[0].consolidate(); - if ( _fullBlocked and (not _costs.back()[0].isBlockage() and not _costs.back()[0].isFixed()) ) + if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) _fullBlocked = false; - cdebug_log(155,0) << "| " << _costs.back()[0] << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; + cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; } cdebug_tabw(159,-1); @@ -648,16 +589,18 @@ namespace Katana { // FOR ANALOG ONLY. //flags |= TrackCost::IgnoreSharedLength; - sort( _costs.begin(), _costs.end(), CompareCostArray(flags) ); + sort( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); size_t i=0; - for ( ; (i<_costs.size()) and _costs[i][0].isFree() ; i++ ); - _event1->setTracksFree ( i ); + for ( ; (i<_costs.size()) and _costs[i]->isFree() ; i++ ); + _event1->setTracksFree( i ); + if (_event2) _event2->setTracksFree( i ); + } - if (_event2) { - for ( ; (i<_costs.size()) and _costs[i][1].isFree() ; i++ ); - _event2->setTracksFree ( i ); - } + + SegmentFsm::~SegmentFsm () + { + for ( TrackCost* cost : _costs ) delete cost; } @@ -720,7 +663,7 @@ namespace Katana { bool SegmentFsm::insertInTrack ( size_t i ) { cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event1->getInsertState() - << " track:" << i << endl; + << " track:" << i << endl; bool success = true; @@ -761,8 +704,8 @@ namespace Katana { _event1->updateAxisHistory(); _event1->setEventLevel( 0 ); - cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; - Session::addInsertEvent( getSegment1(), getCost1(i).getTrack() ); + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; + Session::addInsertEvent( getSegment1(), getTrack1(i) ); if (_event2) { _event2->resetInsertState(); @@ -770,8 +713,8 @@ namespace Katana { _event2->setEventLevel( 0 ); _event2->setProcessed( true ); - cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; - Session::addInsertEvent( getSegment2(), getCost2(i).getTrack() ); + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; + Session::addInsertEvent( getSegment2(), getTrack2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -782,11 +725,11 @@ namespace Katana { { cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; - Session::addMoveEvent( getSegment1(), getCost1(i).getTrack() ); + Session::addMoveEvent( getSegment1(), getTrack1(i) ); if (_event2) { - cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; - Session::addMoveEvent( getSegment2(), getCost2(i).getTrack() ); + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; + Session::addMoveEvent( getSegment2(), getTrack2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -1045,10 +988,10 @@ namespace Katana { Interval overlap = segment->getCanonicalInterval(); size_t begin; size_t end; - getCost(icost).getTrack()->getOverlapBounds( overlap, begin, end ); + getTrack1(icost)->getOverlapBounds( overlap, begin, end ); for ( ; begingetSegment(begin); + TrackElement* other = getTrack1(icost)->getSegment(begin); Interval otherOverlap = other->getCanonicalInterval(); if (other->getNet() == segment->getNet()) continue; @@ -1087,9 +1030,9 @@ namespace Katana { size_t begin; size_t end; - getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end ); + getTrack1(0)->getOverlapBounds ( overlap, begin, end ); for ( ; begingetSegment(begin); + TrackElement* other = getTrack1(0)->getSegment(begin); Interval otherOverlap = other->getCanonicalInterval(); if ( other->getNet() == segment->getNet() ) continue; @@ -1124,7 +1067,7 @@ namespace Katana { for ( ; itrackisGlobalEnclosed() ) { Track* track = getTrack(itrack); size_t begin = getBegin(itrack); size_t end = getEnd (itrack); @@ -1161,7 +1104,7 @@ namespace Katana { setState ( SegmentFsm::OtherRipup ); addAction( segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , getCost(itrack).getTrack()->getAxis() + , getTrack1(itrack)->getAxis() ); break; } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 56487d26..1e548f1d 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -277,15 +277,16 @@ namespace Katana { } - TrackCost Track::getOverlapCost ( Interval interval - , Net* net - , size_t begin - , size_t end - , uint32_t flags ) const + TrackCost& Track::addOverlapCost ( TrackCost& cost ) const { - TrackCost cost ( const_cast(this), interval, begin, end, net, flags ); + size_t begin = Track::npos; + size_t end = Track::npos; + const Interval& interval = cost.getInterval(); - cdebug_log(155,1) << "getOverlapCost() @" << DbU::getValueString(_axis) + getOverlapBounds( cost.getInterval(), begin, end ); + cost.setTrack( const_cast(this), begin, end ); + + cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis) << " [" << DbU::getValueString(interval.getVMin()) << ":" << DbU::getValueString(interval.getVMax()) << "] <-> [" << begin << ":" << end << "]" @@ -298,7 +299,7 @@ namespace Katana { for ( ; (mbegin < _markers.size()) and (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { cdebug_log(155,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; - if ( _markers[mbegin]->getNet() != net ) { + if (_markers[mbegin]->getNet() != cost.getNet()) { cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; cost.incTerminals( _markers[mbegin]->getWeight(this) ); } @@ -312,12 +313,12 @@ namespace Katana { for ( ; begin < end ; begin++ ) { Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() ); - if ( _segments[begin]->getNet() == net ) { + if (_segments[begin]->getNet() == cost.getNet()) { cdebug_log(155,0) << "overlap:" << overlap << " size:" << overlap.getSize() << endl; cost.incDeltaShared ( overlap.getSize() ); } - _segments[begin]->incOverlapCost( net, cost ); - cdebug_log(155,0) << "| overlap: " << _segments[begin] << " cost:" << cost << endl; + _segments[begin]->incOverlapCost( cost ); + cdebug_log(155,0) << "| overlap: " << _segments[begin] << " cost:" << &cost << endl; if (cost.isInfinite()) break; } @@ -328,21 +329,6 @@ namespace Katana { } - TrackCost Track::getOverlapCost ( Interval interval, Net* net, uint32_t flags ) const - { - size_t begin; - size_t end; - - getOverlapBounds( interval, begin, end ); - - return getOverlapCost( interval, net, begin, end, flags ); - } - - - TrackCost Track::getOverlapCost ( TrackElement* segment, uint32_t flags ) const - { return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet(), flags ); } - - void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, uint32_t& weight ) const { cdebug_log(155,1) << "getTerminalWeight() @" << DbU::getValueString(_axis) @@ -468,10 +454,10 @@ namespace Katana { ,getString(segment).c_str()) << endl; } - segment->setAxis ( getAxis() ); _segments.push_back ( segment ); _segmentsValid = false; + //segment->setAxis ( getAxis() ); segment->setTrack ( this ); } diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index e173ede2..991a00dc 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -19,6 +19,7 @@ #include #include "katana/Track.h" #include "katana/TrackCost.h" +#include "katana/TrackElement.h" #include "katana/Session.h" @@ -26,63 +27,27 @@ namespace Katana { using std::cerr; using std::endl; + using Hurricane::Error; // ------------------------------------------------------------------- // Class : "TrackCost". - TrackCost::TrackCost ( Track* track ) - : _flags (ZeroCost) - , _track (track) - , _begin (Track::npos) - , _end (Track::npos) - , _interval () - , _forGlobal (false) - , _blockage (false) - , _fixed (false) - , _infinite (false) - , _hardOverlap (false) - , _overlap (false) - , _leftOverlap (false) - , _rightOverlap (false) - , _overlapGlobal (false) - , _globalEnclosed (false) - , _terminals (0) - , _delta (0) - , _deltaShared (0) - , _deltaPerpand (0) - , _axisWeight (0) - , _distanceToFixed(2*Session::getSliceHeight()) - , _longuestOverlap(0) - , _dataState (0) - , _ripupCount (0) - { } - - - TrackCost::TrackCost ( Track* track - , const Interval& interval - , size_t begin - , size_t end - , Net* net - , uint32_t flags + TrackCost::TrackCost ( TrackElement* refSegment + , TrackElement* symSegment + , Track* refTrack + , Track* symTrack ) - : _flags (flags) - , _track (track) - , _begin (begin) - , _end (end) - , _interval (interval) - , _forGlobal (false) - , _blockage (false) - , _fixed (false) - , _infinite (false) - , _hardOverlap (false) - , _overlap (false) - , _leftOverlap (false) - , _rightOverlap (false) - , _overlapGlobal (false) - , _globalEnclosed (false) + : _flags ((symSegment) ? Symmetric : NoFlags) + , _span (1) + , _tracks ( _span * ((symSegment) ? 2 : 1) + , std::tuple(NULL,Track::npos,Track::npos) ) + , _segment1 (refSegment) + , _segment2 (symSegment) + , _interval1 (refSegment->getCanonicalInterval()) + , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) , _terminals (0) - , _delta (-interval.getSize()) + , _delta (-_interval1.getSize() -_interval2.getSize()) , _deltaShared (0) , _deltaPerpand (0) , _axisWeight (0) @@ -90,94 +55,76 @@ namespace Katana { , _longuestOverlap(0) , _dataState (0) , _ripupCount (0) + , _selectFlags (NoFlags) + , _selectIndex (0) { - if (not (_flags & Analog)) { - // This is the GCell side (it is *one* cell height from the gauge). - DbU::Unit cellHeight = Session::getSliceHeight(); + std::get<0>( _tracks[0] ) = refTrack; + _segment1->addOverlapCost( *this ); - TrackElement* neighbor; - if ( _begin != Track::npos ) { - neighbor = _track->getSegment(_begin); - if ( neighbor and (neighbor->getNet() != net) ) { - DbU::Unit distance = interval.getVMin() - neighbor->getTargetU(); - if ( distance < cellHeight ) - _distanceToFixed = distance; - } - // if ( neighbor and neighbor->isFixed() ) { - // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; - // _distanceToFixed += interval.getVMin() - neighbor->getTargetU(); - // } - } - if ( _end != Track::npos ) { - neighbor = _track->getSegment(_end); - if ( neighbor and (neighbor->getNet() != net) ) { - DbU::Unit distance = neighbor->getSourceU() - interval.getVMax(); - if ( _distanceToFixed == 2*cellHeight ) _distanceToFixed = 0; - if ( distance < cellHeight ) - _distanceToFixed += distance; - } - // if ( neighbor and neighbor->isFixed() ) { - // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; - // _distanceToFixed += neighbor->getSourceU() - interval.getVMax(); - // } - } + if (symTrack) { + std::get<0>( _tracks[_span] ) = symTrack; + select( 0, Symmetric ); + _segment2->addOverlapCost( *this ); } + + consolidate(); } + TrackCost::~TrackCost () { } bool TrackCost::isFree () const { - return /*(not _terminals) and*/ (not _overlap) and (not _infinite); + return /*(not _terminals) and*/ (not isOverlap()) and (not isInfinite()); } - bool TrackCost::Compare::operator() ( const TrackCost& lhs, const TrackCost& rhs ) + bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs ) { - if ( lhs._infinite xor rhs._infinite ) return rhs._infinite; + if ( lhs->isInfinite() xor rhs->isInfinite() ) return rhs->isInfinite(); if ( (_flags & TrackCost::DiscardGlobals) - and (lhs._overlapGlobal xor rhs._overlapGlobal) ) - return rhs._overlapGlobal; + and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) ) + return rhs->isOverlapGlobal(); - if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap; + if ( lhs->isHardOverlap() xor rhs->isHardOverlap() ) return rhs->isHardOverlap(); - if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true; - if ( lhs._ripupCount > (int)Session::getRipupCost() + rhs._ripupCount ) return false; + if ( lhs->_ripupCount + (int)Session::getRipupCost() < rhs->_ripupCount ) return true; + if ( lhs->_ripupCount > (int)Session::getRipupCost() + rhs->_ripupCount ) return false; - //int lhsRipupCost = (lhs._dataState<<2) + lhs._ripupCount; - //int rhsRipupCost = (rhs._dataState<<2) + rhs._ripupCount; + //int lhsRipupCost = (lhs->_dataState<<2) + lhs->_ripupCount; + //int rhsRipupCost = (rhs->_dataState<<2) + rhs->_ripupCount; //if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true; //if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false; //if ( _flags & TrackCost::DiscardGlobals ) { - // if ( lhs._longuestOverlap < rhs._longuestOverlap ) return true; - // if ( lhs._longuestOverlap > rhs._longuestOverlap ) return false; + // if ( lhs->_longuestOverlap < rhs->_longuestOverlap ) return true; + // if ( lhs->_longuestOverlap > rhs->_longuestOverlap ) return false; //} - if ( lhs._overlap xor rhs._overlap ) return rhs._overlap; + if ( lhs->isOverlap() xor rhs->isOverlap() ) return rhs->isOverlap(); - if ( lhs._terminals < rhs._terminals ) return true; - if ( lhs._terminals > rhs._terminals ) return false; + if ( lhs->_terminals < rhs->_terminals ) return true; + if ( lhs->_terminals > rhs->_terminals ) return false; - if (lhs._delta != rhs._delta) { - //cdebug_log(155,0) << "TrackCost::Compare() lhs._delta:" << lhs._delta << " rhs._delta:" << rhs._delta << endl; - //if ( not (_flags & TrackCost::IgnoreSharedLength) or (lhs._delta > 0) or (rhs._delta > 0) ) { - //if ( (lhs._delta > 0) or (rhs._delta > 0) ) { - if (lhs._delta < rhs._delta) return true; - if (lhs._delta > rhs._delta) return false; + if (lhs->_delta != rhs->_delta) { + //cdebug_log(155,0) << "TrackCost::Compare() lhs->_delta:" << lhs->_delta << " rhs->_delta:" << rhs->_delta << endl; + //if ( not (_flags & TrackCost::IgnoreSharedLength) or (lhs->_delta > 0) or (rhs->_delta > 0) ) { + //if ( (lhs->_delta > 0) or (rhs->_delta > 0) ) { + if (lhs->_delta < rhs->_delta) return true; + if (lhs->_delta > rhs->_delta) return false; //} // Both delta should be negative, chose the least one. - //return lhs._delta > rhs._delta; - return lhs._delta < rhs._delta; + //return lhs->_delta > rhs->_delta; + return lhs->_delta < rhs->_delta; } #if 0 - DbU::Unit lhsMixedWeight = 0.5*lhs._deltaPerpand; - DbU::Unit rhsMixedWeight = 0.5*rhs._deltaPerpand; + DbU::Unit lhsMixedWeight = 0.5*lhs->_deltaPerpand; + DbU::Unit rhsMixedWeight = 0.5*rhs->_deltaPerpand; if ( not (_flags & TrackCost::IgnoreAxisWeight) ) { lhsMixedWeight += lhsMixedWeight; @@ -189,29 +136,46 @@ namespace Katana { #endif if ( not (_flags & TrackCost::IgnoreAxisWeight) ) { - if ( lhs._axisWeight < rhs._axisWeight ) return true; - if ( lhs._axisWeight > rhs._axisWeight ) return false; + if ( lhs->_axisWeight < rhs->_axisWeight ) return true; + if ( lhs->_axisWeight > rhs->_axisWeight ) return false; } - if ( lhs._deltaPerpand < rhs._deltaPerpand ) return true; - if ( lhs._deltaPerpand > rhs._deltaPerpand ) return false; + if ( lhs->_deltaPerpand < rhs->_deltaPerpand ) return true; + if ( lhs->_deltaPerpand > rhs->_deltaPerpand ) return false; - if ( lhs._distanceToFixed > rhs._distanceToFixed ) return true; - if ( lhs._distanceToFixed < rhs._distanceToFixed ) return false; + if ( lhs->_distanceToFixed > rhs->_distanceToFixed ) return true; + if ( lhs->_distanceToFixed < rhs->_distanceToFixed ) return false; - return lhs.getTrack()->getAxis() < rhs.getTrack()->getAxis(); + return lhs->getTrack(0)->getAxis() < rhs->getTrack(0)->getAxis(); } - bool TrackCost::CompareByDelta::operator() ( const TrackCost& lhs, const TrackCost& rhs ) + bool TrackCost::CompareByDelta::operator() ( const TrackCost* lhs, const TrackCost* rhs ) { - return lhs.getDelta() < rhs.getDelta(); + return lhs->getDelta() < rhs->getDelta(); + } + + + Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } + Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } + + + size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const + { + if (i >= _span) return Track::npos; + return std::get<1>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); + } + + size_t TrackCost::getEnd ( size_t i, uint32_t flags ) const + { + if (i >= _span) return Track::npos; + return std::get<2>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); } void TrackCost::consolidate () { - if ( not _infinite and not _hardOverlap ) { + if ( not isInfinite() and not isHardOverlap() ) { cdebug_log(159,0) << "TrackCost::consolidate() " << _delta << " - " << _deltaShared << endl; //_deltaPerpand += - (_deltaShared << 1); _delta -= _deltaShared; @@ -221,16 +185,41 @@ namespace Katana { } - void TrackCost::merge ( const TrackCost& other ) + void TrackCost::setDistanceToFixed () { - _terminals += other._terminals; - _delta += other._delta; - _deltaShared += other._deltaShared; - _deltaPerpand += other._deltaPerpand; - _axisWeight += other._axisWeight; - _distanceToFixed = std::min( _distanceToFixed, other._distanceToFixed ); - _longuestOverlap = std::min( _longuestOverlap, other._longuestOverlap ); - _dataState = std::max( _dataState, other._dataState ); + if (_flags & Analog) return; + + // This is the GCell side (it is *one* cell height from the gauge). + DbU::Unit cellHeight = Session::getSliceHeight(); + + cdebug_log(159,0) << "TrackCost::setDistanceToFixed() begin:" << getBegin(0) << endl; + + TrackElement* neighbor; + if (getBegin(0) != Track::npos) { + neighbor = getTrack(0)->getSegment(getBegin(0)); + if ( neighbor and (neighbor->getNet() != getNet()) ) { + DbU::Unit distance = getInterval().getVMin() - neighbor->getTargetU(); + if ( distance < cellHeight ) + _distanceToFixed = distance; + } + // if ( neighbor and neighbor->isFixed() ) { + // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; + // _distanceToFixed += _interval.getVMin() - neighbor->getTargetU(); + // } + } + if (getEnd(0) != Track::npos) { + neighbor = getTrack(0)->getSegment(getEnd(0)); + if ( neighbor and (neighbor->getNet() != getNet()) ) { + DbU::Unit distance = neighbor->getSourceU() - getInterval().getVMax(); + if ( _distanceToFixed == 2*cellHeight ) _distanceToFixed = 0; + if ( distance < cellHeight ) + _distanceToFixed += distance; + } + // if ( neighbor and neighbor->isFixed() ) { + // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; + // _distanceToFixed += neighbor->getSourceU() - _interval.getVMax(); + // } + } } @@ -238,25 +227,25 @@ namespace Katana { { string s = "<" + _getTypeName(); - s += " " + getString(_track); - s += " " + getString(_dataState); - s += "+" + getString(_ripupCount); - s += ":" + getString((_dataState<<2)+_ripupCount); - s += " " + string ( (_infinite )?"I":"-" ); - s += string ( (_blockage )?"b":"-" ); - s += string ( (_fixed )?"f":"-" ); - s += string ( (_hardOverlap )?"h":"-" ); - s += string ( (_overlap )?"o":"-" ); - s += string ( (_overlapGlobal )?"g":"-" ); - s += string ( (_globalEnclosed)?"e":"-" ); - s += " " + getString(_terminals); - s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); - s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); - s += "/" + DbU::getValueString(_axisWeight); - s += "/" + DbU::getValueString(_deltaPerpand); + s += " " + getString(getTrack(0)); + s += " " + getString(_dataState); + s += "+" + getString(_ripupCount); + s += ":" + getString((_dataState<<2)+_ripupCount); + s += " " + string ( (isInfinite() )?"I":"-" ); + s += string ( (isBlockage() )?"b":"-" ); + s += string ( (isFixed() )?"f":"-" ); + s += string ( (isHardOverlap() )?"h":"-" ); + s += string ( (isOverlap() )?"o":"-" ); + s += string ( (isOverlapGlobal() )?"g":"-" ); + s += string ( (isGlobalEnclosed())?"e":"-" ); + s += " " + getString(_terminals); + s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); + s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); + s += "/" + DbU::getValueString(_axisWeight); + s += "/" + DbU::getValueString(_deltaPerpand); s += "/f:" + DbU::getValueString(_distanceToFixed); - s += "/" + DbU::getValueString(_longuestOverlap); - s += " " + getString(_dataState); + s += "/" + DbU::getValueString(_longuestOverlap); + s += " " + getString(_dataState); s += ">"; return s; @@ -266,12 +255,10 @@ namespace Katana { Record* TrackCost::_getRecord () const { Record* record = new Record ( _getString() ); - record->add( getSlot ( "_track" , _track ) ); - record->add( getSlot ( "_begin" , &_begin ) ); - record->add( getSlot ( "_end" , &_end ) ); - record->add( getSlot ( "_interval" , &_interval ) ); - record->add( getSlot ( "_infinite" , _infinite ) ); - record->add( getSlot ( "_overlap" , _overlap ) ); + record->add( getSlot ( "_flags" , _flags ) ); + record->add( getSlot ( "_tracks" , _tracks ) ); + record->add( getSlot ( "_interval1" , &_interval1 ) ); + record->add( getSlot ( "_interval2" , &_interval2 ) ); record->add( getSlot ( "_terminals" , _terminals ) ); record->add( DbU::getValueSlot( "_delta" , &_delta ) ); record->add( DbU::getValueSlot( "_deltaShared" , &_deltaShared ) ); diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index c36399d9..7d896f6d 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -256,9 +256,9 @@ namespace Katana { } - void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const + void TrackElement::incOverlapCost ( TrackCost& cost ) const { - if (not _track or (getNet() == net)) return; + if (not _track or (getNet() == cost.getNet())) return; _overlapCostCallback( this, cost ); } diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index dd763853..8201d250 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -140,6 +140,7 @@ namespace Katana { Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } Interval TrackFixedSegment::getFreeInterval () const { return Interval(); } + size_t TrackFixedSegment::getTrackSpan () const { return 1; } unsigned long TrackFixedSegment::getId () const @@ -172,6 +173,15 @@ namespace Katana { } + void TrackFixedSegment::addOverlapCost ( TrackCost& cost ) const + { + Track* track = cost.getTrack(); + + if (not track) return; + track->addOverlapCost( cost ); + } + + float TrackFixedSegment::getPriority () const { return 0.0; } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 2554e2d2..dc54a625 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -26,7 +26,8 @@ #include "anabatic/GCell.h" #include "crlcore/RoutingGauge.h" #include "katana/DataNegociate.h" -#include "katana/TrackSegment.h" +#include "katana/TrackSegmentRegular.h" +#include "katana/TrackSegmentWide.h" #include "katana/Track.h" #include "katana/Session.h" #include "katana/RoutingEvent.h" @@ -69,8 +70,8 @@ namespace Katana { , _dogLegLevel (0) , _flags (NoFlags) { - cdebug_log(155,0) << "CTOR TrackSegment " << (void*)this << ":" << this << endl; - cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl; + cdebug_log(155,0) << "CTOR TrackSegment " << /*(void*)this <<*/ ":" << this << endl; + cdebug_log(155,0) << " over " << /*(void*)segment <<*/ ":" << segment << endl; setFlags( TElemCreated|TElemLocked ); if (segment) { @@ -129,16 +130,23 @@ namespace Katana { { created = false; - TrackElement* trackElement = Session::lookup( segment->base() ); + DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() ); + TrackElement* trackElement = Session::lookup( segment->base() ); if (not trackElement) { - TrackSegment* trackSegment = new TrackSegment( segment, track ); - trackSegment->_postCreate(); - created = true; + if (segment->base()->getWidth() <= defaultWireWidth) { + trackElement = new TrackSegmentRegular( segment, track ); + trackElement->_postCreate(); + created = true; - trackSegment->invalidate(); + trackElement->invalidate(); - cdebug_log(159,0) << "TrackSegment::create(): " << trackSegment << endl; - trackElement = trackSegment; + cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; + } else { + throw Error( "TrackSegment::create() Non-regular TrackSegment are not supported yet.\n" + " (on: %s)" + , getString(segment).c_str() + ); + } } return trackElement; @@ -356,7 +364,10 @@ namespace Katana { void TrackSegment::setTrack ( Track* track ) - { TrackElement::setTrack( track ); } + { + if (track) setAxis( track->getAxis(), Anabatic::SegAxisSet ); + TrackElement::setTrack( track ); + } void TrackSegment::setSymmetric ( TrackElement* segment ) diff --git a/katana/src/TrackSegmentRegular.cpp b/katana/src/TrackSegmentRegular.cpp new file mode 100644 index 00000000..0a64bdcf --- /dev/null +++ b/katana/src/TrackSegmentRegular.cpp @@ -0,0 +1,111 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./TrackSegmentRegular.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RoutingPad.h" +#include "anabatic/AutoContact.h" +#include "anabatic/GCell.h" +#include "crlcore/RoutingGauge.h" +#include "katana/DataNegociate.h" +#include "katana/TrackSegmentRegular.h" +#include "katana/Track.h" +#include "katana/Session.h" +#include "katana/RoutingEvent.h" +#include "katana/NegociateWindow.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using namespace std; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::BasicLayer; + using Hurricane::Net; + using Hurricane::Name; + using Hurricane::RoutingPad; + using Anabatic::SegSlackened; + using Anabatic::perpandicularTo; + +// ------------------------------------------------------------------- +// Class : "TrackSegmentRegular". + + + TrackSegmentRegular::TrackSegmentRegular ( AutoSegment* segment, Track* track ) + : Super(segment,track) + { + // cdebug_log(155,0) << "CTOR TrackSegmentRegular " << (void*)this << ":" << this << endl; + // cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl; + } + + + void TrackSegmentRegular::_postCreate () + { + Super::_postCreate(); + } + + + TrackSegmentRegular::~TrackSegmentRegular () + { + } + + + void TrackSegmentRegular::_preDestroy () + { + Super::_preDestroy(); + } + + + size_t TrackSegmentRegular::getTrackSpan () const { return 1; } + + + void TrackSegmentRegular::addOverlapCost ( TrackCost& cost ) const + { + uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + bool inLocalDepth = (depth < 3); + bool isOneLocalTrack = (isLocal()) and (base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); + Track* track = cost.getTrack(); + + if (not track) return; + + cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); + cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + + track->addOverlapCost( cost ); + + cost.setDistanceToFixed(); + cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); + cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); + if (isGlobal()) cost.setForGlobal(); + + if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) + cost.setInfinite(); + + if ( isOneLocalTrack + and cost.isOverlapGlobal() + and (cost.getDataState() >= DataNegociate::ConflictSolveByHistory) ) + cost.setInfinite(); + } + + +} // Katana namespace. diff --git a/katana/src/TrackSegmentWide.cpp b/katana/src/TrackSegmentWide.cpp new file mode 100644 index 00000000..74304d16 --- /dev/null +++ b/katana/src/TrackSegmentWide.cpp @@ -0,0 +1,121 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./TrackSegmentWide.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RoutingPad.h" +#include "anabatic/AutoContact.h" +#include "anabatic/GCell.h" +#include "crlcore/RoutingGauge.h" +#include "katana/DataNegociate.h" +#include "katana/TrackSegmentWide.h" +#include "katana/Track.h" +#include "katana/Session.h" +#include "katana/RoutingEvent.h" +#include "katana/NegociateWindow.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using namespace std; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::BasicLayer; + using Hurricane::Net; + using Hurricane::Name; + using Hurricane::RoutingPad; + using Anabatic::SegSlackened; + using Anabatic::perpandicularTo; + + +// ------------------------------------------------------------------- +// Class : "TrackSegmentWide". + + + TrackSegmentWide::TrackSegmentWide ( AutoSegment* segment, Track* track, size_t trackSpan ) + : Super(segment,track) + , _trackSpan(trackSpan) + { + cdebug_log(155,0) << "CTOR TrackSegmentWide " << (void*)this << ":" << this << endl; + cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl; + + if (not _trackSpan) { + DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) ); + if (segment->getWidth() < mWidth) { + _trackSpan = 1; + } else { + _trackSpan = ((segment->getWidth() - mWidth) / Session::getPitch(segment->getLayer())) + 2; + } + } + } + + + void TrackSegmentWide::_postCreate () + { + Super::_postCreate(); + } + + + TrackSegmentWide::~TrackSegmentWide () + { + } + + + void TrackSegmentWide::_preDestroy () + { + Super::_preDestroy(); + } + + + size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; } + + + void TrackSegmentWide::addOverlapCost ( TrackCost& cost ) const + { + uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + bool inLocalDepth = (depth < 3); + Track* track = cost.getTrack(); + + if (not track) return; + + cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); + cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + + for ( size_t span=0 ; (span < _trackSpan) and (track != NULL) ; ++span ) { + track->addOverlapCost( cost ); + // Todo: have to choose here wether we go *next* or *previous* according + // to the symmetry kind. + track = track->getNextTrack(); + } + + cost.setDistanceToFixed(); + cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); + cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); + if (isGlobal()) cost.setForGlobal(); + + if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) + cost.setInfinite(); + } + + +} // Katana namespace. diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index 426379bc..bcbb69e9 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -17,12 +17,10 @@ #ifndef KATANA_SEGMENT_FSM_H #define KATANA_SEGMENT_FSM_H -#include #include "katana/TrackCost.h" namespace Katana { - using std::array; class TrackElement; class DataNegociate; class RoutingEvent; @@ -107,111 +105,120 @@ namespace Katana { }; public: - SegmentFsm ( RoutingEvent* - , RoutingEventQueue& - , RoutingEventHistory& - ); - inline bool isFullBlocked () const; - inline bool isSymmetric () const; - inline RoutingEvent* getEvent () const; - inline RoutingEvent* getEvent1 () const; - inline RoutingEvent* getEvent2 () const; - inline RoutingEventQueue& getQueue () const; - inline RoutingEventHistory& getHistory () const; - inline TrackElement* getSegment1 () const; - inline TrackElement* getSegment2 () const; - inline uint32_t getState () const; - inline DataNegociate* getData (); - inline DataNegociate* getData1 (); - inline DataNegociate* getData2 (); - inline Interval& getConstraint (); - inline Interval& getOptimal (); - inline vector< array >& getCosts (); - inline TrackCost& getCost ( size_t ); - inline TrackCost& getCost1 ( size_t ); - inline TrackCost& getCost2 ( size_t ); - inline Track* getTrack ( size_t ); - inline size_t getBegin ( size_t ); - inline size_t getEnd ( size_t ); - inline vector& getActions (); - inline void setState ( uint32_t ); - void setDataState ( uint32_t ); - void addAction ( TrackElement* - , uint32_t type - , DbU::Unit axisHint=0 - , uint32_t toState =0 - ); - void doActions (); - inline void clearActions (); - inline SegmentFsm& useEvent1 (); - inline SegmentFsm& useEvent2 (); - void incRipupCount (); - bool insertInTrack ( size_t ); - void bindToTrack ( size_t ); - void moveToTrack ( size_t ); - void ripupPerpandiculars (); - bool canRipup ( uint32_t flags=0 ); - bool conflictSolveByHistory (); - bool conflictSolveByPlaceds (); - bool solveTerminalVsGlobal (); - bool desaturate (); - bool slackenTopology ( uint32_t flags=0 ); - bool solveFullBlockages (); - private: - bool _slackenStrap ( TrackElement*& - , DataNegociate*& - , uint32_t flags ); - bool _slackenLocal ( TrackElement*& - , DataNegociate*& - , uint32_t flags ); - bool _slackenGlobal ( TrackElement*& - , DataNegociate*& - , uint32_t flags ); - private: - RoutingEvent* _event1; - RoutingEvent* _event2; - RoutingEventQueue& _queue; - RoutingEventHistory& _history; - uint32_t _state; - DataNegociate* _data1; - DataNegociate* _data2; - Interval _constraint; - Interval _optimal; - vector< array > _costs; - vector _actions; - bool _fullBlocked; - bool _sameAxis; - bool _useEvent2; + SegmentFsm ( RoutingEvent* + , RoutingEventQueue& + , RoutingEventHistory& + ); + ~SegmentFsm (); + inline bool isFullBlocked () const; + inline bool isSymmetric () const; + inline RoutingEvent* getEvent () const; + inline RoutingEvent* getEvent1 () const; + inline RoutingEvent* getEvent2 () const; + inline RoutingEventQueue& getQueue () const; + inline RoutingEventHistory& getHistory () const; + inline TrackElement* getSegment1 () const; + inline TrackElement* getSegment2 () const; + inline uint32_t getState () const; + inline DataNegociate* getData (); + inline DataNegociate* getData1 (); + inline DataNegociate* getData2 (); + inline Interval& getConstraint (); + inline Interval& getOptimal (); + inline vector& getCosts (); + inline TrackCost* getCost ( size_t ); + inline Track* getTrack ( size_t ); + inline Track* getTrack1 ( size_t ); + inline Track* getTrack2 ( size_t ); + inline size_t getBegin ( size_t ); + inline size_t getBegin1 ( size_t ); + inline size_t getBegin2 ( size_t ); + inline size_t getEnd ( size_t ); + inline size_t getEnd1 ( size_t ); + inline size_t getEnd2 ( size_t ); + inline vector& getActions (); + inline void setState ( uint32_t ); + void setDataState ( uint32_t ); + void addAction ( TrackElement* + , uint32_t type + , DbU::Unit axisHint=0 + , uint32_t toState =0 + ); + void doActions (); + inline void clearActions (); + inline SegmentFsm& useEvent1 (); + inline SegmentFsm& useEvent2 (); + void incRipupCount (); + bool insertInTrack ( size_t ); + void bindToTrack ( size_t ); + void moveToTrack ( size_t ); + void ripupPerpandiculars (); + bool canRipup ( uint32_t flags=0 ); + bool conflictSolveByHistory (); + bool conflictSolveByPlaceds (); + bool solveTerminalVsGlobal (); + bool desaturate (); + bool slackenTopology ( uint32_t flags=0 ); + bool solveFullBlockages (); + private: + bool _slackenStrap ( TrackElement*& + , DataNegociate*& + , uint32_t flags ); + bool _slackenLocal ( TrackElement*& + , DataNegociate*& + , uint32_t flags ); + bool _slackenGlobal ( TrackElement*& + , DataNegociate*& + , uint32_t flags ); + private: + RoutingEvent* _event1; + RoutingEvent* _event2; + RoutingEventQueue& _queue; + RoutingEventHistory& _history; + uint32_t _state; + DataNegociate* _data1; + DataNegociate* _data2; + Interval _constraint; + Interval _optimal; + vector _costs; + vector _actions; + bool _fullBlocked; + bool _sameAxis; + bool _useEvent2; }; - inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } - inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } - inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } - inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } - inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } - inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } - inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } - inline uint32_t SegmentFsm::getState () const { return _state; } - inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } - inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } - inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } - inline DataNegociate* SegmentFsm::getData1 () { return _data1; } - inline DataNegociate* SegmentFsm::getData2 () { return _data2; } - inline Interval& SegmentFsm::getConstraint () { return _constraint; } - inline Interval& SegmentFsm::getOptimal () { return _optimal; } - inline vector< array >& SegmentFsm::getCosts () { return _costs; } - inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i][0]; } - inline TrackCost& SegmentFsm::getCost1 ( size_t i ) { return _costs[i][0]; } - inline TrackCost& SegmentFsm::getCost2 ( size_t i ) { return _costs[i][1]; } - inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? _costs[i][1].getTrack() : _costs[i][0].getTrack(); } - inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? _costs[i][1].getBegin() : _costs[i][0].getBegin(); } - inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? _costs[i][1].getEnd () : _costs[i][0].getEnd (); } - inline vector& SegmentFsm::getActions () { return _actions; } - inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } - inline void SegmentFsm::clearActions () { _actions.clear(); } - inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } - inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } + inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } + inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } + inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } + inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } + inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } + inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } + inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } + inline uint32_t SegmentFsm::getState () const { return _state; } + inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } + inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } + inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } + inline DataNegociate* SegmentFsm::getData1 () { return _data1; } + inline DataNegociate* SegmentFsm::getData2 () { return _data2; } + inline Interval& SegmentFsm::getConstraint () { return _constraint; } + inline Interval& SegmentFsm::getOptimal () { return _optimal; } + inline vector& SegmentFsm::getCosts () { return _costs; } + inline TrackCost* SegmentFsm::getCost ( size_t i ) { return _costs[i]; } + inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? getTrack2(i) : getTrack1(i); } + inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? getBegin2(i) : getBegin1(i); } + inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? getEnd2 (i) : getEnd1 (i); } + inline Track* SegmentFsm::getTrack1 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::NoFlags ); } + inline Track* SegmentFsm::getTrack2 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::Symmetric); } + inline size_t SegmentFsm::getBegin1 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getBegin2 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::Symmetric); } + inline size_t SegmentFsm::getEnd1 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getEnd2 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::Symmetric); } + inline vector& SegmentFsm::getActions () { return _actions; } + inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } + inline void SegmentFsm::clearActions () { _actions.clear(); } + inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } + inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } } // Katana namespace. diff --git a/katana/src/katana/Track.h b/katana/src/katana/Track.h index 1b7e2a2a..95b4689b 100644 --- a/katana/src/katana/Track.h +++ b/katana/src/katana/Track.h @@ -95,9 +95,7 @@ namespace Katana { Interval expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* ) const; void getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const; void getOverlapBounds ( Interval, size_t& begin, size_t& end ) const; - TrackCost getOverlapCost ( Interval, Net*, size_t begin, size_t end, uint32_t flags ) const; - TrackCost getOverlapCost ( Interval, Net*, uint32_t flags ) const; - TrackCost getOverlapCost ( TrackElement*, uint32_t flags ) const; + TrackCost& addOverlapCost ( TrackCost& ) const; void getTerminalWeight ( Interval, Net*, size_t& count, uint32_t& weight ) const; DbU::Unit getSourcePosition ( size_t index ) const; bool check ( uint32_t& overlaps, const char* message=NULL ) const; diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index c0ba9ff3..9e70eeb9 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -18,6 +18,7 @@ #define KATANA_TRACK_COST_H #include +#include #include "hurricane/Interval.h" namespace Hurricane { class Net; @@ -32,6 +33,7 @@ namespace Katana { using Hurricane::Interval; using Hurricane::Net; class Track; + class TrackElement; // ------------------------------------------------------------------- @@ -39,36 +41,48 @@ namespace Katana { class TrackCost { public: - enum Flags { IgnoreAxisWeight = (1 << 0) - , DiscardGlobals = (1 << 1) - , IgnoreSharedLength = (1 << 2) - , LocalAndTopDepth = (1 << 3) - , ZeroCost = (1 << 4) - , Analog = (1 << 5) + enum Flags { NoFlags = 0 + , IgnoreAxisWeight = (1 << 0) + , DiscardGlobals = (1 << 1) + , IgnoreSharedLength = (1 << 2) + , LocalAndTopDepth = (1 << 3) + , ZeroCost = (1 << 4) + , Analog = (1 << 5) + , Symmetric = (1 << 6) + , ForGlobal = (1 << 7) + , Blockage = (1 << 8) + , Fixed = (1 << 9) + , Infinite = (1 << 10) + , HardOverlap = (1 << 11) + , Overlap = (1 << 12) + , LeftOverlap = (1 << 13) + , RightOverlap = (1 << 14) + , OverlapGlobal = (1 << 15) + , GlobalEnclosed = (1 << 16) + , MergeMask = ForGlobal |Blockage|Fixed |Infinite + |HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal + |GlobalEnclosed }; public: // Sub-Class: "CompareByDelta()". class CompareByDelta { public: - bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); + bool operator() ( const TrackCost* lhs, const TrackCost* rhs ); }; class Compare { public: inline Compare ( uint32_t flags=0 ); - bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); + bool operator() ( const TrackCost* lhs, const TrackCost* rhs ); private: uint32_t _flags; }; public: - TrackCost ( Track* track ); - TrackCost ( Track* track - , const Interval& interval - , size_t begin - , size_t end - , Net* net - , uint32_t flags + TrackCost ( TrackElement* refSegment + , TrackElement* symSegment + , Track* refTrack + , Track* symTrack ); ~TrackCost (); inline bool isForGlobal () const; @@ -82,11 +96,25 @@ namespace Katana { inline bool isOverlapGlobal () const; inline bool isGlobalEnclosed () const; bool isFree () const; + inline bool isSymmetric () const; + inline bool isWide () const; inline uint32_t getFlags () const; + inline size_t getSpan () const; + inline Net* getNet () const; + Net* getNet1 () const; + Net* getNet2 () const; inline Track* getTrack () const; inline size_t getBegin () const; inline size_t getEnd () const; + inline Track* getTrack ( size_t i ) const; + inline size_t getBegin ( size_t i ) const; + inline size_t getEnd ( size_t i ) const; + inline Track* getTrack ( size_t i, uint32_t flags ) const; + size_t getBegin ( size_t i, uint32_t flags ) const; + size_t getEnd ( size_t i, uint32_t flags ) const; inline const Interval& getInterval () const; + inline const Interval& getInterval1 () const; + inline const Interval& getInterval2 () const; inline uint32_t getTerminals () const; inline DbU::Unit getDelta () const; inline DbU::Unit getDeltaPerpand () const; @@ -94,6 +122,8 @@ namespace Katana { inline long getAxisWeight () const; inline int getRipupCount () const; inline uint32_t getDataState () const; + inline uint32_t setFlags ( uint32_t ); + inline void setTrack ( Track*, size_t begin, size_t end ); inline void setForGlobal (); inline void setBlockage (); inline void setFixed (); @@ -108,34 +138,29 @@ namespace Katana { inline void incDelta ( DbU::Unit ); inline void incDeltaPerpand ( DbU::Unit ); inline void incDeltaShared ( DbU::Unit ); - inline void setAxisWeight ( DbU::Unit ); + inline void incAxisWeight ( DbU::Unit ); inline void setLonguestOverlap ( DbU::Unit ); inline void mergeRipupCount ( int ); inline void mergeDataState ( uint32_t ); - void merge ( const TrackCost& ); + inline bool select ( size_t index, uint32_t flags ); void consolidate (); + void setDistanceToFixed (); Record* _getRecord () const; string _getString () const; inline string _getTypeName () const; - // Operators. - + private: + TrackCost ( const TrackCost& ) = delete; + TrackCost& operator= ( const TrackCost& ) = delete; // Attributes. - protected: + private: uint32_t _flags; - Track* _track; - size_t _begin; - size_t _end; - Interval _interval; - bool _forGlobal; - bool _blockage; - bool _fixed; - bool _infinite; - bool _hardOverlap; - bool _overlap; - bool _leftOverlap; - bool _rightOverlap; - bool _overlapGlobal; - bool _globalEnclosed; + size_t _span; + std::vector< std::tuple > + _tracks; + TrackElement* _segment1; + TrackElement* _segment2; + Interval _interval1; + Interval _interval2; uint32_t _terminals; DbU::Unit _delta; DbU::Unit _deltaShared; @@ -145,59 +170,101 @@ namespace Katana { DbU::Unit _longuestOverlap; uint32_t _dataState; int _ripupCount; - + uint32_t _selectFlags; + size_t _selectIndex; }; // Inline Functions. - inline bool TrackCost::isForGlobal () const { return _forGlobal; } - inline bool TrackCost::isBlockage () const { return _blockage; } - inline bool TrackCost::isFixed () const { return _fixed; } - inline bool TrackCost::isInfinite () const { return _infinite; } - inline bool TrackCost::isOverlap () const { return _overlap; } - inline bool TrackCost::isLeftOverlap () const { return _leftOverlap; } - inline bool TrackCost::isRightOverlap () const { return _rightOverlap; } - inline bool TrackCost::isHardOverlap () const { return _hardOverlap; } - inline bool TrackCost::isOverlapGlobal () const { return _overlapGlobal; } - inline bool TrackCost::isGlobalEnclosed () const { return _globalEnclosed; } + inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } + inline bool TrackCost::isBlockage () const { return _flags & Blockage; } + inline bool TrackCost::isFixed () const { return _flags & Fixed; } + inline bool TrackCost::isInfinite () const { return _flags & Infinite; } + inline bool TrackCost::isOverlap () const { return _flags & Overlap; } + inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } + inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } + inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } + inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } + inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } + inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } + inline bool TrackCost::isWide () const { return (_span > 1); } inline uint32_t TrackCost::getFlags () const { return _flags; } - inline Track* TrackCost::getTrack () const { return _track; } - inline size_t TrackCost::getBegin () const { return _begin; } - inline size_t TrackCost::getEnd () const { return _end; } - inline const Interval& TrackCost::getInterval () const { return _interval; } + inline size_t TrackCost::getSpan () const { return _span; } + inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } + inline Track* TrackCost::getTrack () const { return getTrack(_selectIndex,_selectFlags); } + inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } + inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } + inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } + inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } + inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } + inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } + inline const Interval& TrackCost::getInterval1 () const { return _interval1; } + inline const Interval& TrackCost::getInterval2 () const { return _interval2; } inline uint32_t TrackCost::getTerminals () const { return _terminals; } inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } inline DbU::Unit TrackCost::getDelta () const { return _delta; } inline long TrackCost::getAxisWeight () const { return _axisWeight; } inline int TrackCost::getRipupCount () const { return _ripupCount; } inline uint32_t TrackCost::getDataState () const { return _dataState; } - inline void TrackCost::setForGlobal () { _forGlobal = true; } - inline void TrackCost::setBlockage () { _blockage = true; } - inline void TrackCost::setFixed () { _fixed = true; } - inline void TrackCost::setInfinite () { _infinite = true; } - inline void TrackCost::setOverlap () { _overlap = true; } - inline void TrackCost::setLeftOverlap () { _leftOverlap = true; } - inline void TrackCost::setRightOverlap () { _rightOverlap = true; } - inline void TrackCost::setHardOverlap () { _hardOverlap = true; } - inline void TrackCost::setOverlapGlobal () { _overlapGlobal = true; } - inline void TrackCost::setGlobalEnclosed () { _globalEnclosed = true; } - inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } - inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } - inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } - inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } - inline void TrackCost::setAxisWeight ( DbU::Unit weight ) { _axisWeight = weight; } - inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = (overlap > _longuestOverlap) ? overlap : _longuestOverlap; } - inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = (count>_ripupCount)?count:_ripupCount; } - inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = (state>_dataState)?state:_dataState; } + inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } + inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } + inline void TrackCost::setBlockage () { _flags |= Blockage; } + inline void TrackCost::setFixed () { _flags |= Fixed; } + inline void TrackCost::setInfinite () { _flags |= Infinite; } + inline void TrackCost::setOverlap () { _flags |= Overlap; } + inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } + inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } + inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } + inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } + inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } + inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } + inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } + inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } + inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } + inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } + inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } + inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } + inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } inline string TrackCost::_getTypeName () const { return "TrackCost"; } + inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { } + inline bool TrackCost::select ( size_t index, uint32_t flags ) + { + if ( (index >= _span) or ((flags & Symmetric) and not (_flags & Symmetric)) ) { + _selectIndex = 0; + _selectFlags = NoFlags; + return false; + } + + _selectIndex = index; + _selectFlags = flags; + return true; + } + + + inline Track* TrackCost::getTrack ( size_t i, uint32_t flags ) const + { + if (i >= _span) return NULL; + return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); + } + + + inline void TrackCost::setTrack ( Track* track, size_t begin, size_t end ) + { + auto& entry = _tracks[_selectIndex + ((_selectFlags & Symmetric) ? _span : 0)]; + std::get<0>( entry ) = track; + std::get<1>( entry ) = begin; + std::get<2>( entry ) = end; + } + + } // Katana namespace. -INSPECTOR_V_SUPPORT(Katana::TrackCost); +INSPECTOR_P_SUPPORT(Katana::TrackCost); #endif // KATANA_TRACK_COST_H diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index b89691fe..45b62c3d 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -31,6 +31,7 @@ namespace Hurricane { #include "anabatic/AutoSegment.h" #include "katana/Constants.h" #include "katana/Session.h" +#include "katana/TrackCost.h" #include "katana/TrackElements.h" @@ -51,6 +52,7 @@ namespace Katana { class DataNegociate; class Track; class TrackCost; + class TrackSegment; typedef map TrackElementLut; @@ -60,15 +62,19 @@ namespace Katana { // ------------------------------------------------------------------- // Class : "TrackElement". - enum TrackElementFlags { TElemCreated =0x00000001 - , TElemBlockage =0x00000002 - , TElemFixed =0x00000004 - , TElemLocked =0x00000008 - , TElemRouted =0x00000010 - , TElemSourceDogleg=0x00000020 - , TElemTargetDogleg=0x00000040 - , TElemRipple =0x00000080 - , TElemInvalidated =0x00000100 + enum TrackElementFlags { TElemCreated = (1 << 0) + , TElemBlockage = (1 << 1) + , TElemFixed = (1 << 2) + , TElemWide = (1 << 3) + , TElemLocked = (1 << 4) + , TElemRouted = (1 << 5) + , TElemSourceDogleg = (1 << 6) + , TElemTargetDogleg = (1 << 7) + , TElemAlignBottom = (1 << 8) + , TElemAlignCenter = (1 << 9) + , TElemAlignTop = (1 << 10) + , TElemRipple = (1 << 11) + , TElemInvalidated = (1 << 12) }; @@ -82,6 +88,7 @@ namespace Katana { class TrackElement { + friend class TrackSegment; public: static SegmentOverlapCostCB* setOverlapCostCB ( SegmentOverlapCostCB* ); @@ -94,6 +101,7 @@ namespace Katana { virtual bool isFixed () const; virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; + inline bool isWide () const; virtual bool isLocal () const; virtual bool isGlobal () const; virtual bool isBipoint () const; @@ -132,6 +140,7 @@ namespace Katana { virtual const Layer* getLayer () const = 0; virtual DbU::Unit getPitch () const; virtual DbU::Unit getPPitch () const; + virtual size_t getTrackSpan () const = 0; inline Track* getTrack () const; inline size_t getIndex () const; virtual float getPriority () const = 0; @@ -157,6 +166,7 @@ namespace Katana { virtual TrackElement* getTargetDogleg (); virtual TrackElement* getSymmetric (); virtual TrackElements getPerpandiculars (); + virtual void addOverlapCost ( TrackCost& ) const = 0; // Mutators. inline void setFlags ( uint32_t ); inline void unsetFlags ( uint32_t ); @@ -176,7 +186,7 @@ namespace Katana { virtual void invalidate (); virtual void revalidate (); virtual void updatePPitch (); - virtual void incOverlapCost ( Net*, TrackCost& ) const; + virtual void incOverlapCost ( TrackCost& ) const; virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::SegAxisSet ); virtual TrackElement* makeDogleg (); inline bool makeDogleg ( Anabatic::GCell* ); @@ -199,12 +209,12 @@ namespace Katana { // Static Attributes. static SegmentOverlapCostCB* _overlapCostCallback; // Attributes. - uint32_t _flags; - Track* _track; - size_t _index; - DbU::Unit _sourceU; - DbU::Unit _targetU; - Observer _observer; + uint32_t _flags; + Track* _track; + size_t _index; + DbU::Unit _sourceU; + DbU::Unit _targetU; + Observer _observer; protected: // Constructors & Destructors. @@ -221,8 +231,9 @@ namespace Katana { // Inline functions. inline Observer* TrackElement::getObserver () { return &_observer; } - inline void TrackElement::setFlags ( uint32_t flags ) { _flags|= flags; } - inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags&=~flags; } + inline void TrackElement::setFlags ( uint32_t flags ) { _flags |= flags; } + inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } + inline bool TrackElement::isWide () const { return _flags & TElemWide; } inline bool TrackElement::isCreated () const { return _flags & TElemCreated; } inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; } inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; } diff --git a/katana/src/katana/TrackFixedSegment.h b/katana/src/katana/TrackFixedSegment.h index b5f623f3..259ae556 100644 --- a/katana/src/katana/TrackFixedSegment.h +++ b/katana/src/katana/TrackFixedSegment.h @@ -50,10 +50,12 @@ namespace Katana { virtual Flags getDirection () const; virtual Net* getNet () const; virtual const Layer* getLayer () const; + virtual size_t getTrackSpan () const; virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; virtual DbU::Unit getAxis () const; virtual Interval getFreeInterval () const; + virtual void addOverlapCost ( TrackCost& ) const; virtual float getPriority () const; virtual void setPriorityLock ( bool ); virtual void forcePriority ( float ); diff --git a/katana/src/katana/TrackSegmentRegular.h b/katana/src/katana/TrackSegmentRegular.h new file mode 100644 index 00000000..a561f089 --- /dev/null +++ b/katana/src/katana/TrackSegmentRegular.h @@ -0,0 +1,68 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./katana/TrackSegmentRegular.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KATANA_TRACK_SEGMENT_REGULAR_H +#define KATANA_TRACK_SEGMENT_REGULAR_H + +#include +#include +#include "katana/TrackSegment.h" + + +namespace Katana { + + using std::string; + using std::map; + using std::set; + using std::binary_function; + using Hurricane::Record; + using Hurricane::Interval; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Layer; + using Anabatic::AutoSegment; + + class DataNegociate; + class Track; + class TrackCost; + + +// ------------------------------------------------------------------- +// Class : "TrackSegmentRegular". + + class TrackSegmentRegular : public TrackSegment { + friend class TrackSegment; + public: + typedef TrackSegment Super; + protected: + TrackSegmentRegular ( AutoSegment*, Track* ) ; + virtual ~TrackSegmentRegular (); + virtual void _postCreate (); + virtual void _preDestroy (); + virtual size_t getTrackSpan () const; + virtual void addOverlapCost ( TrackCost& ) const; + private: + TrackSegmentRegular ( const TrackSegmentRegular& ) = delete; + TrackSegmentRegular& operator= ( const TrackSegmentRegular& ) = delete; + }; + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::TrackSegmentRegular); + +#endif // KATANA_TRACK_SEGMENT_REGULAR_H diff --git a/katana/src/katana/TrackSegmentWide.h b/katana/src/katana/TrackSegmentWide.h new file mode 100644 index 00000000..8a31fc67 --- /dev/null +++ b/katana/src/katana/TrackSegmentWide.h @@ -0,0 +1,70 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./katana/TrackSegmentWide.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KATANA_TRACK_SEGMENT_WIDE_H +#define KATANA_TRACK_SEGMENT_WIDE_H + +#include +#include +#include "katana/TrackSegment.h" + + +namespace Katana { + + using std::string; + using std::map; + using std::set; + using std::binary_function; + using Hurricane::Record; + using Hurricane::Interval; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Layer; + using Anabatic::AutoSegment; + + class DataNegociate; + class Track; + class TrackCost; + + +// ------------------------------------------------------------------- +// Class : "TrackSegmentWide". + + class TrackSegmentWide : public TrackSegment { + friend class TrackSegment; + public: + typedef TrackSegment Super; + protected: + TrackSegmentWide ( AutoSegment*, Track*, size_t trackSpan=0 ) ; + virtual ~TrackSegmentWide (); + virtual void _postCreate (); + virtual void _preDestroy (); + virtual size_t getTrackSpan () const; + virtual void addOverlapCost ( TrackCost& ) const; + private: + TrackSegmentWide ( const TrackSegmentWide& ) = delete; + TrackSegmentWide& operator= ( const TrackSegmentWide& ) = delete; + private: + size_t _trackSpan; + }; + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::TrackSegmentWide); + +#endif // KATANA_TRACK_SEGMENT_WIDE_H