Merge branch 'devel_anabatic' of ssh://bop.soc.lip6.fr/users/largo2/git/coriolis into devel_anabatic
Conflicts: anabatic/src/Dijkstra.cpp
This commit is contained in:
commit
37d6a02b0e
|
@ -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: "
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: "
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
SharedPath.cpp
|
||||
Path.cpp
|
||||
Occurrence.cpp
|
||||
Occurrences.cpp
|
||||
QuadTree.cpp
|
||||
Slice.cpp
|
||||
ExtensionSlice.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<HyperNet> hyperNets;
|
||||
vector<HyperNet> topHyperNets;
|
||||
|
||||
for ( Occurrence occurrence : getHyperNetRootNetOccurrences() ) {
|
||||
for ( Occurrence occurrence : getHyperNetRootNetOccurrences().getSubSet(NotFilter<Occurrence>(Occurrence_Contains(instance))) ) {
|
||||
Net* net = static_cast<Net*>(occurrence.getEntity());
|
||||
|
||||
if (net->isClock() and (flags & Flags::NoClockFlatten)) continue;
|
||||
|
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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<Instance*>(occurrence.getEntity()) == _instance) return true;
|
||||
for ( Instance* instance : occurrence.getPath().getInstances() ) {
|
||||
if (instance == _instance) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
string Occurrence_Contains::_getString () const
|
||||
{ return "<Occurrence_Contains " + getString(_instance) + " >"; }
|
||||
|
||||
|
||||
|
||||
} // Hurricane namespace.
|
|
@ -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; }
|
||||
|
|
|
@ -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) ) );
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
// ****************************************************************************************************
|
||||
// You should have received a copy of the Lesser GNU General Public
|
||||
// License along with Hurricane. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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<Occurrence> Occurrences;
|
||||
typedef GenericLocator<Occurrence> OccurrenceLocator;
|
||||
typedef GenericFilter<Occurrence> OccurrenceFilter;
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// Occurrences declaration
|
||||
// ****************************************************************************************************
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Occurrence_Contains".
|
||||
|
||||
typedef GenericCollection<Occurrence> 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<Occurrence> OccurrenceLocator;
|
||||
Occurrence_Contains::Occurrence_Contains ( const Occurrence_Contains& other )
|
||||
: OccurrenceFilter()
|
||||
, _instance(other._instance)
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
// OccurrenceFilter declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
typedef GenericFilter<Occurrence> 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
|
||||
// ****************************************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<TrackCost,2> >& costs = _fsm.getCosts();
|
||||
vector<TrackCost*>& costs = _fsm.getCosts();
|
||||
size_t itrack = 0;
|
||||
for ( ; itrack<costs.size() ; ++itrack ) {
|
||||
cdebug_log(159,0) << "Trying itrack:" << itrack << endl;
|
||||
|
||||
if ( costs[itrack][0].isFixed()
|
||||
or costs[itrack][0].isBlockage()
|
||||
or costs[itrack][0].isInfinite()
|
||||
or costs[itrack][0].isOverlapGlobal() )
|
||||
if ( costs[itrack]->isFixed()
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -507,7 +507,7 @@ namespace Katana {
|
|||
cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << tty::reset
|
||||
<< " remains:" << right << setw(8) << setfill('0')
|
||||
<< _eventQueue.size()+1
|
||||
<< _eventQueue.size()
|
||||
<< setfill(' ') << tty::reset << ">" << tty::cr;
|
||||
cmess2.flush ();
|
||||
} else {
|
||||
|
|
|
@ -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 ; itrack<fsm.getCosts().size() ; itrack++ ) {
|
||||
cdebug_log(159,0) << "Trying Track: " << itrack << endl;
|
||||
if (fsm.getCost(itrack).isInfinite()) break;
|
||||
if (fsm.getCost(itrack)->isInfinite()) 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 {
|
||||
|
|
|
@ -36,26 +36,6 @@ namespace {
|
|||
using namespace Katana;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "CompareCostArray".
|
||||
|
||||
class CompareCostArray {
|
||||
public:
|
||||
inline CompareCostArray ( uint32_t flags=0 );
|
||||
inline bool operator() ( const array<TrackCost,2>& lhs, const array<TrackCost,2>& rhs );
|
||||
private:
|
||||
TrackCost::Compare _compare;
|
||||
};
|
||||
|
||||
|
||||
inline CompareCostArray::CompareCostArray ( uint32_t flags )
|
||||
: _compare(flags)
|
||||
{ }
|
||||
|
||||
inline bool CompareCostArray::operator() ( const array<TrackCost,2>& lhs, const array<TrackCost,2>& 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,2>( { 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 ( ; begin<end ; ++begin ) {
|
||||
TrackElement* other = getCost(icost).getTrack()->getSegment(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 ( ; begin<end ; ++begin ) {
|
||||
TrackElement* other = getCost(0).getTrack()->getSegment(begin);
|
||||
TrackElement* other = getTrack1(0)->getSegment(begin);
|
||||
Interval otherOverlap = other->getCanonicalInterval();
|
||||
|
||||
if ( other->getNet() == segment->getNet() ) continue;
|
||||
|
@ -1124,7 +1067,7 @@ namespace Katana {
|
|||
for ( ; itrack<getCosts().size() ; ++itrack ) {
|
||||
cdebug_log(159,0) << "Trying track:" << itrack << endl;
|
||||
|
||||
if ( getCost(itrack).isGlobalEnclosed() ) {
|
||||
if ( getCost(itrack)->isGlobalEnclosed() ) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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<Track*>(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<Track*>(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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <iostream>
|
||||
#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<Track*,size_t,size_t>(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 ) );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 <sstream>
|
||||
#include <limits>
|
||||
#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.
|
|
@ -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 <sstream>
|
||||
#include <limits>
|
||||
#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.
|
|
@ -17,12 +17,10 @@
|
|||
#ifndef KATANA_SEGMENT_FSM_H
|
||||
#define KATANA_SEGMENT_FSM_H
|
||||
|
||||
#include <array>
|
||||
#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<TrackCost,2> >& 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<SegmentAction>& 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<TrackCost,2> > _costs;
|
||||
vector<SegmentAction> _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<TrackCost*>& 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<SegmentAction>& 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<TrackCost*> _costs;
|
||||
vector<SegmentAction> _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<TrackCost,2> >& 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<SegmentAction>& 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<TrackCost*>& 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<SegmentAction>& 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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define KATANA_TRACK_COST_H
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#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<Track*,size_t,size_t> >
|
||||
_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
|
||||
|
|
|
@ -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<Segment*,TrackElement*> 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<TrackElement> _observer;
|
||||
uint32_t _flags;
|
||||
Track* _track;
|
||||
size_t _index;
|
||||
DbU::Unit _sourceU;
|
||||
DbU::Unit _targetU;
|
||||
Observer<TrackElement> _observer;
|
||||
|
||||
protected:
|
||||
// Constructors & Destructors.
|
||||
|
@ -221,8 +231,9 @@ namespace Katana {
|
|||
|
||||
// Inline functions.
|
||||
inline Observer<TrackElement>* 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; }
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 <set>
|
||||
#include <functional>
|
||||
#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
|
|
@ -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 <set>
|
||||
#include <functional>
|
||||
#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
|
Loading…
Reference in New Issue