Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
// -*- 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@lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./SegmentFsm.cpp" |
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/DebugSession.h"
|
|
|
|
#include "katana/TrackElement.h"
|
|
|
|
#include "katana/Tracks.h"
|
|
|
|
#include "katana/RoutingPlane.h"
|
|
|
|
#include "katana/DataNegociate.h"
|
|
|
|
#include "katana/RoutingEvent.h"
|
|
|
|
#include "katana/RoutingEventQueue.h"
|
|
|
|
#include "katana/RoutingEventHistory.h"
|
|
|
|
#include "katana/Manipulator.h"
|
|
|
|
#include "katana/SegmentFsm.h"
|
|
|
|
#include "katana/KatanaEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace Hurricane;
|
|
|
|
using namespace Katana;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Cs1Candidate".
|
|
|
|
|
|
|
|
class Cs1Candidate {
|
|
|
|
public:
|
|
|
|
inline Cs1Candidate ( Track* track=NULL, DbU::Unit ppitch=0 );
|
|
|
|
inline Track* getTrack () const;
|
|
|
|
inline size_t getBegin () const;
|
|
|
|
inline size_t getEnd () const;
|
|
|
|
inline size_t getLength () const;
|
|
|
|
inline Interval getConflict ( size_t );
|
|
|
|
inline Interval getLongestConflict () const;
|
|
|
|
inline DbU::Unit getBreakPos () const;
|
|
|
|
inline DbU::Unit getConflictLength () const;
|
|
|
|
inline void setBegin ( size_t );
|
|
|
|
inline void setEnd ( size_t );
|
|
|
|
inline void addConflict ( const Interval& );
|
|
|
|
void consolidate ();
|
|
|
|
public:
|
|
|
|
friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& );
|
|
|
|
private:
|
|
|
|
Track* _track;
|
|
|
|
DbU::Unit _ppitch;
|
|
|
|
size_t _begin;
|
|
|
|
size_t _end;
|
|
|
|
vector<Interval> _conflicts;
|
|
|
|
Interval _longestConflict;
|
|
|
|
DbU::Unit _breakPos;
|
|
|
|
DbU::Unit _conflictLength;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
inline Cs1Candidate::Cs1Candidate ( Track* track, DbU::Unit ppitch )
|
|
|
|
: _track (track)
|
|
|
|
, _ppitch (ppitch)
|
|
|
|
, _begin (0)
|
|
|
|
, _end (0)
|
|
|
|
, _conflicts ()
|
|
|
|
, _longestConflict()
|
|
|
|
, _breakPos (0)
|
|
|
|
, _conflictLength (0)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
inline Track* Cs1Candidate::getTrack () const { return _track; }
|
|
|
|
inline size_t Cs1Candidate::getBegin () const { return _begin; }
|
|
|
|
inline size_t Cs1Candidate::getEnd () const { return _end; }
|
|
|
|
inline size_t Cs1Candidate::getLength () const { return _conflicts.size(); }
|
|
|
|
inline Interval Cs1Candidate::getLongestConflict () const { return _longestConflict; }
|
|
|
|
inline DbU::Unit Cs1Candidate::getBreakPos () const { return _breakPos; }
|
|
|
|
inline void Cs1Candidate::setBegin ( size_t i ) { _begin=i; }
|
|
|
|
inline void Cs1Candidate::setEnd ( size_t i ) { _end=i; }
|
|
|
|
|
|
|
|
inline void Cs1Candidate::addConflict ( const Interval& conflict )
|
|
|
|
{
|
|
|
|
_conflicts.push_back(conflict);
|
|
|
|
_conflictLength += conflict.getSize();
|
|
|
|
|
|
|
|
if (conflict.getSize() > _longestConflict.getSize())
|
|
|
|
_longestConflict = conflict;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline Interval Cs1Candidate::getConflict ( size_t i )
|
|
|
|
{
|
|
|
|
if (i >= _conflicts.size()) return Interval();
|
|
|
|
return _conflicts[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator< ( const Cs1Candidate& lhs, const Cs1Candidate& rhs )
|
|
|
|
{
|
|
|
|
DbU::Unit delta = lhs._longestConflict.getSize() - rhs._longestConflict.getSize();
|
|
|
|
if (delta < 0) return true;
|
|
|
|
if (delta > 0) return false;
|
|
|
|
|
|
|
|
return lhs._conflictLength < rhs._conflictLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Cs1Candidate::consolidate ()
|
|
|
|
{
|
|
|
|
if (_conflicts.size() > 0) {
|
|
|
|
DbU::Unit halfConflict = 0;
|
|
|
|
size_t i = 0;
|
|
|
|
for ( ; i<_conflicts.size()-1 ; ++i ) {
|
|
|
|
halfConflict += _conflicts[i].getSize();
|
|
|
|
if (halfConflict > _conflictLength/2)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ugly: hard-coded pitch.
|
|
|
|
_breakPos = _conflicts[i].getVMin() - _ppitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "UnionItervals".
|
|
|
|
|
|
|
|
class UnionIntervals {
|
|
|
|
public:
|
|
|
|
inline UnionIntervals ();
|
|
|
|
void addInterval ( Interval& );
|
|
|
|
inline size_t size () const;
|
|
|
|
inline bool empty () const;
|
|
|
|
inline list<Interval>::const_iterator begin () const;
|
|
|
|
inline list<Interval>::const_iterator end () const;
|
|
|
|
inline DbU::Unit getVMin () const;
|
|
|
|
inline DbU::Unit getVMax () const;
|
|
|
|
string _getString ();
|
|
|
|
private:
|
|
|
|
list<Interval> _intervals;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
inline UnionIntervals::UnionIntervals () : _intervals() { }
|
|
|
|
inline list<Interval>::const_iterator UnionIntervals::begin () const { return _intervals.begin(); }
|
|
|
|
inline list<Interval>::const_iterator UnionIntervals::end () const { return _intervals.end(); }
|
|
|
|
inline size_t UnionIntervals::size () const { return _intervals.size(); }
|
|
|
|
inline bool UnionIntervals::empty () const { return _intervals.empty(); }
|
|
|
|
inline DbU::Unit UnionIntervals::getVMin () const { return (empty()) ? DbU::Max : (*begin()).getVMin(); }
|
|
|
|
inline DbU::Unit UnionIntervals::getVMax () const { return (empty()) ? DbU::Min : (*begin()).getVMax(); }
|
|
|
|
|
|
|
|
|
|
|
|
void UnionIntervals::addInterval ( Interval& interval )
|
|
|
|
{
|
|
|
|
cdebug_log(159,0) << "UnionInterval::addInterval() - " << interval << endl;
|
|
|
|
|
|
|
|
list<Interval>::iterator iintv = _intervals.begin ();
|
|
|
|
|
|
|
|
bool merged = false;
|
|
|
|
while ( iintv != _intervals.end() ) {
|
|
|
|
if (not merged) {
|
|
|
|
if (interval.getVMax() < (*iintv).getVMin()) { _intervals.insert( iintv, interval ); return; }
|
|
|
|
if (interval.getVMin() > (*iintv).getVMax()) { ++iintv; continue; }
|
|
|
|
|
|
|
|
merged = true;
|
|
|
|
interval = (*iintv).merge( interval );
|
|
|
|
++iintv;
|
|
|
|
} else {
|
|
|
|
if ((*iintv).intersect( interval )) {
|
|
|
|
interval = (*iintv).merge( interval );
|
|
|
|
iintv = _intervals.erase( iintv );
|
|
|
|
continue;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not merged) _intervals.push_back( interval );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string UnionIntervals::_getString ()
|
|
|
|
{
|
|
|
|
ostringstream s;
|
|
|
|
|
|
|
|
list<Interval>::iterator iintv = _intervals.begin();
|
|
|
|
for ( ; iintv != _intervals.end() ; ++iintv ) {
|
|
|
|
s << " [" << DbU::getValueString((*iintv).getVMin())
|
|
|
|
<< ":" << DbU::getValueString((*iintv).getVMax()) << "]";
|
|
|
|
}
|
|
|
|
return s.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "RipupHistory".
|
|
|
|
|
|
|
|
class RipupHistory {
|
|
|
|
public:
|
|
|
|
RipupHistory ( RoutingEvent* );
|
|
|
|
inline bool isDislodger ( RoutingEvent* ) const;
|
|
|
|
inline size_t size () const;
|
|
|
|
inline size_t getDislodgersCount () const;
|
|
|
|
void addAxis ( DbU::Unit );
|
|
|
|
void addAxis ( RoutingEvent* );
|
|
|
|
bool hasAxis ( DbU::Unit ) const;
|
|
|
|
UnionIntervals* getUnionIntervals ( DbU::Unit );
|
|
|
|
void addDislodger ( RoutingEvent* );
|
|
|
|
void addDislodger ( TrackElement* );
|
|
|
|
void print ( ostream& );
|
|
|
|
private:
|
|
|
|
RoutingEvent* _masterEvent;
|
|
|
|
map<DbU::Unit,UnionIntervals> _dislodgers;
|
|
|
|
size_t _dislodgersCount;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
RipupHistory::RipupHistory ( RoutingEvent* event )
|
|
|
|
: _masterEvent (event)
|
|
|
|
, _dislodgers ()
|
|
|
|
, _dislodgersCount(0)
|
|
|
|
{
|
|
|
|
const Interval& perpandicular = _masterEvent->getPerpandicularFree();
|
|
|
|
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_masterEvent->getSegment()->getLayer());
|
|
|
|
Track* track;
|
|
|
|
|
|
|
|
if (not perpandicular.isEmpty()) {
|
|
|
|
track = plane->getTrackByPosition(perpandicular.getVMin());
|
|
|
|
|
|
|
|
if (track and (track->getAxis() < perpandicular.getVMin())) track = track->getNextTrack();
|
|
|
|
for ( ; track && (track->getAxis() <= perpandicular.getVMax())
|
|
|
|
; track = track->getNextTrack() )
|
|
|
|
addAxis( track->getAxis() );
|
|
|
|
}
|
|
|
|
|
|
|
|
track = plane->getTrackByPosition(_masterEvent->getSegment()->getAxis());
|
|
|
|
if (track) {
|
|
|
|
size_t begin = Track::npos;
|
|
|
|
size_t end = Track::npos;
|
|
|
|
Interval interval = _masterEvent->getSegment()->getCanonicalInterval();
|
|
|
|
track->getOverlapBounds( interval, begin, end );
|
|
|
|
|
|
|
|
if (begin != Track::npos) {
|
|
|
|
for ( ; begin < end ; ++begin ) {
|
|
|
|
TrackElement* other = track->getSegment(begin);
|
|
|
|
if (other->getNet() == _masterEvent->getSegment()->getNet() ) continue;
|
|
|
|
if (not interval.intersect(other->getCanonicalInterval())) continue;
|
|
|
|
|
|
|
|
addDislodger( other );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline bool RipupHistory::isDislodger ( RoutingEvent* event ) const { return hasAxis(event->getSegment()->getAxis()); }
|
|
|
|
inline size_t RipupHistory::size () const { return _dislodgers.size(); }
|
|
|
|
inline size_t RipupHistory::getDislodgersCount () const { return _dislodgersCount; }
|
|
|
|
|
|
|
|
|
|
|
|
void RipupHistory::addAxis ( DbU::Unit axis )
|
|
|
|
{
|
|
|
|
if (hasAxis(axis)) return;
|
|
|
|
_dislodgers.insert( make_pair(axis,UnionIntervals()) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RipupHistory::addAxis ( RoutingEvent* event )
|
|
|
|
{ addAxis( event->getAxisHistory() ); }
|
|
|
|
|
|
|
|
|
|
|
|
bool RipupHistory::hasAxis ( DbU::Unit axis ) const
|
|
|
|
{ return _dislodgers.find(axis) != _dislodgers.end(); }
|
|
|
|
|
|
|
|
|
|
|
|
UnionIntervals* RipupHistory::getUnionIntervals ( DbU::Unit axis )
|
|
|
|
{
|
|
|
|
map<DbU::Unit,UnionIntervals>::iterator iunion = _dislodgers.find ( axis );
|
|
|
|
if (iunion == _dislodgers.end()) return NULL;
|
|
|
|
|
|
|
|
return &(iunion->second);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RipupHistory::addDislodger ( RoutingEvent* event )
|
|
|
|
{
|
|
|
|
if (event->getSegment() == _masterEvent->getSegment()) return;
|
|
|
|
if (event->getSegment()->getLayer() != _masterEvent->getSegment()->getLayer()) return;
|
|
|
|
|
|
|
|
UnionIntervals* intervals = getUnionIntervals( event->getAxisHistory() );
|
|
|
|
if (not intervals) return;
|
|
|
|
|
|
|
|
Interval canonical = event->getSegment()->getCanonicalInterval();
|
|
|
|
intervals->addInterval( canonical );
|
|
|
|
|
|
|
|
++_dislodgersCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RipupHistory::addDislodger ( TrackElement* segment )
|
|
|
|
{
|
|
|
|
if (_masterEvent->getSegment()->getNet() == segment->getNet()) return;
|
|
|
|
|
|
|
|
UnionIntervals* intervals = getUnionIntervals( segment->getAxis() );
|
|
|
|
if (not intervals) return;
|
|
|
|
|
|
|
|
Interval canonical = segment->getCanonicalInterval();
|
|
|
|
intervals->addInterval( canonical );
|
|
|
|
|
|
|
|
++_dislodgersCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RipupHistory::print ( ostream& o )
|
|
|
|
{
|
|
|
|
o << "[HISTORY] " << _masterEvent << endl;
|
|
|
|
|
|
|
|
map<DbU::Unit,UnionIntervals>::iterator iunion = _dislodgers.begin();
|
|
|
|
for ( ; iunion != _dislodgers.end() ; ++iunion )
|
|
|
|
o << " @" << DbU::getValueString(iunion->first)
|
|
|
|
<< " " << (iunion->second)._getString() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // Anonymous namespace.
|
|
|
|
|
|
|
|
|
|
|
|
namespace Katana {
|
|
|
|
|
|
|
|
using std::sort;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::DebugSession;
|
|
|
|
using Hurricane::Bug;
|
|
|
|
using Hurricane::ForEachIterator;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "SegmentAction".
|
|
|
|
|
|
|
|
SegmentAction::SegmentAction ( TrackElement* segment
|
|
|
|
, unsigned int type
|
|
|
|
, DbU::Unit axisHint
|
|
|
|
, unsigned int toState
|
|
|
|
)
|
|
|
|
: _segment (segment)
|
|
|
|
, _type (type)
|
|
|
|
, _axisHint(axisHint)
|
|
|
|
, _toState (toState)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentAction::doAction ( RoutingEventQueue& queue )
|
|
|
|
{
|
|
|
|
// Note:
|
|
|
|
// "_immediate" ripup flags was associated with "perpandicular", as they
|
|
|
|
// must be re-inserted *before* any parallel. Must look to solve the redundancy.
|
|
|
|
|
|
|
|
DebugSession::open( _segment->getNet(), 150, 160 );
|
|
|
|
|
|
|
|
if (_type & Perpandicular) {
|
|
|
|
cdebug_log(159,0) << "* Riping Pp " << _segment << endl;
|
|
|
|
} else {
|
|
|
|
cdebug_log(159,0) << "* Riping // " << _segment << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_segment->isFixed()) { DebugSession::close(); return true; }
|
|
|
|
|
|
|
|
DataNegociate* data = _segment->getDataNegociate();
|
|
|
|
if (data == NULL) { DebugSession::close(); return true; }
|
|
|
|
|
|
|
|
if (_type & ResetRipup) data->resetRipupCount();
|
|
|
|
|
|
|
|
if (_type & ToState) {
|
|
|
|
data->setState ( _toState );
|
|
|
|
data->setRipupCount( Session::getKatanaEngine()->getRipupLimit(_segment) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_segment->getTrack()) Session::addRemoveEvent( _segment );
|
|
|
|
|
|
|
|
RoutingEvent* event = data->getRoutingEvent();
|
|
|
|
if (event == NULL) {
|
|
|
|
cerr << Bug( "Missing Event on %p:%s"
|
|
|
|
, _segment->base()->base(),getString(_segment).c_str() ) << endl;
|
|
|
|
DebugSession::close();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (_type & AxisHint) /*and not _segment->isSlackenDogleg()*/ ) {
|
|
|
|
cdebug_log(159,0) << "Setting Axis Hint: @" << DbU::getValueString(_axisHint) << endl;
|
|
|
|
event->setAxisHint( _axisHint );
|
|
|
|
}
|
|
|
|
|
|
|
|
// It is possible that this code could be disabled.
|
|
|
|
// There should be no need to move the axis of the segment to be inserted,
|
|
|
|
// it will automatically slot into the empty track, if any.
|
|
|
|
if (_type & MoveToAxis) {
|
|
|
|
cdebug_log(159,0) << "Moving Axis To: @" << DbU::getValueString(_axisHint) << endl;
|
|
|
|
_segment->setAxis( _axisHint );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_type & ToRipupLimit) {
|
|
|
|
unsigned int limit = Session::getKatanaEngine()->getRipupLimit(_segment);
|
|
|
|
if (limit > data->getRipupCount())
|
|
|
|
data->setRipupCount( limit );
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int eventLevel = 0;
|
|
|
|
if (_type & EventLevel1) eventLevel = 1;
|
|
|
|
if (_type & EventLevel2) eventLevel = 2;
|
|
|
|
if (_type & EventLevel3) eventLevel = 3;
|
|
|
|
if (_type & EventLevel4) eventLevel = 4;
|
|
|
|
if (_type & EventLevel5) eventLevel = 5;
|
|
|
|
event->setRipedByLocal( _type&RipedByLocal );
|
|
|
|
|
|
|
|
RoutingEvent* fork = event->reschedule( queue, eventLevel );
|
|
|
|
|
|
|
|
if (fork) {
|
|
|
|
unsigned int mode = RoutingEvent::Repair;
|
|
|
|
if (RoutingEvent::getStage() < RoutingEvent::Repair)
|
|
|
|
mode = (_type&PackingMode) ? RoutingEvent::Pack : RoutingEvent::Negociate;
|
|
|
|
fork->setMode( mode );
|
|
|
|
}
|
|
|
|
|
|
|
|
DebugSession::close();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "SegmentFsm".
|
|
|
|
|
|
|
|
|
|
|
|
SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history )
|
|
|
|
: _event (event)
|
|
|
|
, _queue (queue)
|
|
|
|
, _history (history)
|
|
|
|
, _state (0)
|
|
|
|
, _data (NULL)
|
|
|
|
, _constraint ()
|
|
|
|
, _optimal ()
|
|
|
|
, _costs ()
|
|
|
|
, _actions ()
|
|
|
|
, _fullBlocked(true)
|
|
|
|
{
|
|
|
|
TrackElement* segment = _event->getSegment();
|
|
|
|
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
|
|
|
_event->setTracksFree( 0 );
|
|
|
|
|
|
|
|
_data = segment->getDataNegociate();
|
|
|
|
if (not _data) {
|
|
|
|
_state = MissingData;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_data->update();
|
|
|
|
_event->revalidate();
|
|
|
|
|
|
|
|
_constraint = _event->getConstraints();
|
|
|
|
_optimal = _event->getOptimal();
|
|
|
|
|
|
|
|
const Interval& perpandicular = _event->getPerpandicularFree();
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "Anabatic intervals:" << endl;
|
|
|
|
cdebug_log(159,0) << "* Optimal: " << _optimal << endl;
|
|
|
|
cdebug_log(159,0) << "* Constraints: " << _constraint << endl;
|
|
|
|
cdebug_log(159,0) << "* Perpandicular: " << perpandicular << endl;
|
|
|
|
cdebug_log(159,0) << "* AxisHint: " << DbU::getValueString(_event->getAxisHint()) << endl;
|
|
|
|
|
|
|
|
if (_event->getTracksNb()) {
|
|
|
|
if (_constraint.getIntersection(perpandicular).isEmpty()) {
|
|
|
|
cdebug_log(159,0) << "Perpandicular free is too tight." << endl;
|
|
|
|
_state = EmptyTrackList;
|
|
|
|
} else
|
|
|
|
_constraint.intersection( perpandicular );
|
|
|
|
} else {
|
|
|
|
cdebug_log(159,0) << "No Track in perpandicular free." << endl;
|
|
|
|
_state = EmptyTrackList;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_state == EmptyTrackList) return;
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "Negociate intervals:" << endl;
|
|
|
|
cdebug_log(159,0) << "* Optimal: " << _optimal << endl;
|
|
|
|
cdebug_log(159,1) << "* Constraints: " << _constraint << endl;
|
|
|
|
|
|
|
|
// if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) )
|
|
|
|
// _constraint.inflate ( 0, DbU::lambda(1.0) );
|
|
|
|
|
|
|
|
bool inLocalDepth = (depth < 3);
|
|
|
|
bool isOneLocalTrack = (segment->isLocal())
|
|
|
|
and (segment->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0);
|
|
|
|
|
|
|
|
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer());
|
|
|
|
for ( Track* track : Tracks_Range::get(plane,_constraint) ) {
|
|
|
|
unsigned int costflags = 0;
|
|
|
|
costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0;
|
|
|
|
|
|
|
|
if (not segment->isReduced())
|
|
|
|
_costs.push_back( track->getOverlapCost(segment,costflags) );
|
|
|
|
else
|
|
|
|
_costs.push_back( TrackCost(track,segment->getNet()) );
|
|
|
|
_costs.back().setAxisWeight ( _event->getAxisWeight(track->getAxis()) );
|
|
|
|
_costs.back().incDeltaPerpand( _data->getWiringDelta(track->getAxis()) );
|
|
|
|
if (segment->isGlobal()) {
|
|
|
|
cdebug_log(9000,0) << "Deter| setForGlobal() on " << track << endl;
|
|
|
|
_costs.back().setForGlobal();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( inLocalDepth and (_costs.back().getDataState() == DataNegociate::MaximumSlack) )
|
|
|
|
_costs.back().setInfinite();
|
|
|
|
|
|
|
|
if ( isOneLocalTrack
|
|
|
|
and _costs.back().isOverlapGlobal()
|
|
|
|
and (_costs.back().getDataState() >= DataNegociate::ConflictSolveByHistory) )
|
|
|
|
_costs.back().setInfinite();
|
|
|
|
|
|
|
|
_costs.back().consolidate();
|
|
|
|
if ( _fullBlocked and (not _costs.back().isBlockage() and not _costs.back().isFixed()) )
|
|
|
|
_fullBlocked = false;
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track << endl;
|
|
|
|
}
|
|
|
|
cdebug_tabw(159,-1);
|
|
|
|
|
|
|
|
if (_costs.empty()) {
|
|
|
|
Track* nearest = plane->getTrackByPosition(_constraint.getCenter());
|
|
|
|
|
|
|
|
if ( (nearest->getAxis() < _constraint.getVMin())
|
|
|
|
or (nearest->getAxis() > _constraint.getVMax()) ) {
|
|
|
|
//setUnimplemented ();
|
|
|
|
//cerr << "[UNIMPLEMENTED] " << segment << " no Track in constraint interval "
|
|
|
|
// << _constraint << " " << "." << endl;
|
|
|
|
} else {
|
|
|
|
cerr << Bug( " %s Track_Range() failed to find Tracks in %s (they exists)."
|
|
|
|
, getString(segment).c_str()
|
|
|
|
, getString(_constraint).c_str()
|
|
|
|
) << endl;
|
|
|
|
}
|
|
|
|
_state = EmptyTrackList;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int flags = 0;
|
|
|
|
flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0;
|
|
|
|
flags |= (segment->isLocal()
|
|
|
|
and (_data->getState() < DataNegociate::Minimize)
|
|
|
|
and (_data->getRipupCount() < 5))
|
|
|
|
? TrackCost::DiscardGlobals : 0;
|
|
|
|
flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0;
|
|
|
|
|
|
|
|
if (flags & TrackCost::DiscardGlobals) {
|
|
|
|
cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
sort( _costs.begin(), _costs.end(), TrackCost::Compare(flags) );
|
|
|
|
|
|
|
|
size_t i=0;
|
|
|
|
for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ );
|
|
|
|
_event->setTracksFree ( i );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SegmentFsm::addAction ( TrackElement* segment
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
, unsigned int type
|
|
|
|
, DbU::Unit axisHint
|
|
|
|
, unsigned int toSegmentFsm )
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
{
|
|
|
|
if ( not segment->isFixed() ) {
|
|
|
|
_actions.push_back ( SegmentAction(segment,type,axisHint,toSegmentFsm) );
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::addAction(): " << segment << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SegmentFsm::doActions ()
|
|
|
|
{
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::doActions() - " << _actions.size() << endl;
|
|
|
|
|
|
|
|
bool ripupOthersParallel = false;
|
|
|
|
bool ripedByLocal = getEvent()->getSegment()->isLocal();
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<_actions.size() ; i++ ) {
|
|
|
|
if ( ripedByLocal ) _actions[i].setFlag ( SegmentAction::RipedByLocal );
|
|
|
|
if ( _actions[i].getType() & SegmentAction::OtherRipup ) {
|
|
|
|
ripupOthersParallel = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<_actions.size() ; i++ ) {
|
|
|
|
if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel )
|
|
|
|
_actions[i].setFlag ( SegmentAction::EventLevel3 );
|
|
|
|
|
|
|
|
DebugSession::open ( _actions[i].getSegment()->getNet(), 150, 160 );
|
|
|
|
if ( not _actions[i].doAction(_queue) ) {
|
|
|
|
cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl;
|
|
|
|
}
|
|
|
|
DebugSession::close ();
|
|
|
|
}
|
|
|
|
|
|
|
|
_actions.clear ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::insertInTrack ( size_t i )
|
|
|
|
{
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event->getInsertState()
|
|
|
|
<< " track:" << i << endl;
|
|
|
|
|
|
|
|
_event->incInsertState();
|
|
|
|
switch ( _event->getInsertState() ) {
|
|
|
|
case 1:
|
|
|
|
if ( Manipulator(_event->getSegment(),*this).insertInTrack(i) ) return true;
|
|
|
|
_event->incInsertState();
|
|
|
|
case 2:
|
|
|
|
if ( Manipulator(_event->getSegment(),*this).shrinkToTrack(i) ) return true;
|
|
|
|
_event->incInsertState();
|
|
|
|
case 3:
|
|
|
|
if ( Manipulator(_event->getSegment(),*this).forceToTrack(i) ) return true;
|
|
|
|
_event->incInsertState();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::conflictSolveByHistory ()
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
RipupHistory ripupHistory ( _event );
|
|
|
|
RoutingEvent* event;
|
|
|
|
TrackElement* segment = _event->getSegment();
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::conflictSolveByHistory()" << endl;
|
|
|
|
|
|
|
|
size_t maxDepth = min( getHistory().size(), (size_t)300 );
|
|
|
|
size_t depth = 0;
|
|
|
|
while ( (ripupHistory.getDislodgersCount() < 3) and (depth < maxDepth) ) {
|
|
|
|
event = getHistory().getRNth(depth++);
|
|
|
|
if (not event) continue;
|
|
|
|
if ( (event->getSegment() != segment) and ripupHistory.isDislodger(event) )
|
|
|
|
ripupHistory.addDislodger( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
//ripupHistory.print ( cout );
|
|
|
|
|
|
|
|
UnionIntervals* intervals = ripupHistory.getUnionIntervals( segment->getAxis() );
|
|
|
|
if (intervals and not intervals->empty()) {
|
|
|
|
|
|
|
|
DbU::Unit minConflict = intervals->getVMin();
|
|
|
|
DbU::Unit maxConflict = intervals->getVMax();
|
|
|
|
Interval canonical = segment->getCanonicalInterval();
|
|
|
|
bool sourceDogleg = canonical.contains(minConflict);
|
|
|
|
bool targetDogleg = canonical.contains(maxConflict);
|
|
|
|
Point breakPoint;
|
|
|
|
|
|
|
|
if (sourceDogleg) {
|
|
|
|
if (segment->isHorizontal()) {
|
|
|
|
breakPoint = Point( minConflict, segment->getAxis() );
|
|
|
|
cdebug_log(159,0) << breakPoint << endl;
|
|
|
|
} else {
|
|
|
|
breakPoint = Point( segment->getAxis(), minConflict );
|
|
|
|
cdebug_log(159,0) << breakPoint << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
Anabatic::GCell* dogLegGCell = Session::getGCellUnder( breakPoint.getX(), breakPoint.getY() );
|
|
|
|
if (dogLegGCell) {
|
|
|
|
if (segment->canDogleg(dogLegGCell))
|
|
|
|
success = segment->makeDogleg(dogLegGCell);
|
|
|
|
} else {
|
|
|
|
cerr << Bug( "No GCell under source %s for:\n %s."
|
|
|
|
, getString(breakPoint).c_str(), getString(segment).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not success and targetDogleg) {
|
|
|
|
if (segment->isHorizontal()) {
|
|
|
|
breakPoint = Point( maxConflict, segment->getAxis() );
|
|
|
|
cdebug_log(159,0) << breakPoint << endl;
|
|
|
|
} else {
|
|
|
|
breakPoint = Point( segment->getAxis(), maxConflict );
|
|
|
|
cdebug_log(159,0) << breakPoint << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
Anabatic::GCell* dogLegGCell = Session::getGCellUnder( breakPoint.getX(), breakPoint.getY() );
|
|
|
|
if (dogLegGCell) {
|
|
|
|
if (segment->canDogleg(dogLegGCell)) {
|
|
|
|
success = segment->makeDogleg(dogLegGCell);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cerr << Bug( "No GCell under target %s for:\n %s."
|
|
|
|
, getString(breakPoint).c_str(), getString(segment).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cdebug_log(159,0) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl;
|
|
|
|
|
|
|
|
Interval freeSpan = Session::getKatanaEngine()->
|
|
|
|
getTrackByPosition(segment->getLayer(),segment->getAxis())->
|
|
|
|
getFreeInterval(segment->getSourceU(),segment->getNet());
|
|
|
|
|
|
|
|
if (freeSpan.contains(segment->getCanonicalInterval())) {
|
|
|
|
cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl;
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::conflictSolveByPlaceds ()
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
Interval constraints;
|
|
|
|
vector<Cs1Candidate> candidates;
|
|
|
|
TrackElement* segment = _event->getSegment();
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5,Flags::NoFlags) : segment->canMoveUp(1.0,Flags::CheckLowDensity); // MARK 1
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
unsigned int relaxFlags = Manipulator::NoDoglegReuse
|
|
|
|
| ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand
|
|
|
|
: Manipulator::NoExpand);
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::conflictSolveByPlaceds()" << endl;
|
|
|
|
cdebug_log(159,0) << "| Candidates Tracks: " << endl;
|
|
|
|
|
|
|
|
segment->base()->getConstraints( constraints );
|
|
|
|
Interval overlap = segment->getCanonicalInterval();
|
|
|
|
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer());
|
|
|
|
Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior);
|
|
|
|
|
|
|
|
if (not track) {
|
|
|
|
cerr << Bug( "SegmentFsm::conflictSolveByPlaceds():\n"
|
|
|
|
" For: %s\n"
|
|
|
|
" In %s, no Track near %s"
|
|
|
|
, getString(segment).c_str()
|
|
|
|
, getString(plane).c_str()
|
|
|
|
, DbU::getValueString(constraints.getVMin()).c_str()
|
|
|
|
) << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( ; track and track->getAxis() <= constraints.getVMax() ; track = track->getNextTrack() ) {
|
|
|
|
candidates.push_back( Cs1Candidate(track,segment->getPPitch()) );
|
|
|
|
|
|
|
|
size_t begin;
|
|
|
|
size_t end;
|
|
|
|
TrackElement* other;
|
|
|
|
Net* otherNet = NULL;
|
|
|
|
Interval otherOverlap;
|
|
|
|
bool otherIsGlobal = false;
|
|
|
|
|
|
|
|
track->getOverlapBounds( overlap, begin, end );
|
|
|
|
candidates.back().setBegin( begin );
|
|
|
|
candidates.back().setEnd ( end );
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "* " << track << " [" << begin << ":" << end << "]" << endl;
|
|
|
|
|
|
|
|
for ( ; (begin < end) ; ++begin ) {
|
|
|
|
other = track->getSegment( begin );
|
|
|
|
|
|
|
|
if (other->getNet() == segment->getNet()) {
|
|
|
|
cdebug_log(159,0) << " | " << begin << " Same net: " << " " << other << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (not other->getCanonicalInterval().intersect(overlap)) {
|
|
|
|
cdebug_log(159,0) << " | " << begin << " No Conflict: " << " " << other << endl;
|
|
|
|
if (otherNet == NULL) candidates.back().setBegin( begin+1 );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
cdebug_log(159,0) << " | " << begin << " Conflict: " << " " << other << endl;
|
|
|
|
|
|
|
|
if (otherNet != other->getNet()) {
|
|
|
|
if (otherNet) {
|
|
|
|
if (otherIsGlobal) {
|
|
|
|
candidates.back().addConflict( otherOverlap );
|
|
|
|
cdebug_log(159,0) << " | Other overlap G: " << otherOverlap << endl;
|
|
|
|
} else {
|
|
|
|
cdebug_log(159,0) << " | Other overlap L: " << otherOverlap << " ignored." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
otherNet = other->getNet();
|
|
|
|
otherOverlap = other->getCanonicalInterval();
|
|
|
|
otherIsGlobal = other->isGlobal() or other->isBlockage() or other->isFixed();
|
|
|
|
} else {
|
|
|
|
otherOverlap.merge(other->getCanonicalInterval());
|
|
|
|
otherIsGlobal = otherIsGlobal or other->isGlobal() or other->isBlockage() or other->isFixed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (not otherOverlap.isEmpty()) {
|
|
|
|
if (otherIsGlobal) {
|
|
|
|
candidates.back().addConflict( otherOverlap );
|
|
|
|
cdebug_log(159,0) << " | Other overlap G: " << otherOverlap << endl;
|
|
|
|
} else {
|
|
|
|
cdebug_log(159,0) << " | Other overlap L: " << otherOverlap << " ignored." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
candidates.back().consolidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
sort( candidates.begin(), candidates.end() );
|
|
|
|
|
|
|
|
for ( size_t icandidate=0 ; icandidate<candidates.size() ; ++icandidate ) {
|
|
|
|
cdebug_log(159,0) << "Trying l:" << candidates[icandidate].getLength()
|
|
|
|
<< " " << candidates[icandidate].getTrack() << endl;
|
|
|
|
|
|
|
|
Interval overlap0 = candidates[icandidate].getLongestConflict();
|
|
|
|
cdebug_log(159,0) << "overlap0: " << overlap0 << endl;
|
|
|
|
|
|
|
|
if (overlap0.isEmpty()) {
|
|
|
|
cdebug_log(159,0) << "overlap0 is empty, no conflict, ignoring Track candidate." << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Track* track = candidates[icandidate].getTrack();
|
|
|
|
TrackElement* other = track->getSegment( overlap.getCenter() );
|
|
|
|
if (not other) {
|
|
|
|
cbug << Error("conflictSolveByPlaceds(): No segment under overlap center.") << endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (other->isGlobal()) {
|
|
|
|
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
|
|
|
|
if ((success = Manipulator(other,*this).moveUp())) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl;
|
|
|
|
|
|
|
|
if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) {
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if ( not canMoveUp
|
|
|
|
and (relaxFlags != Manipulator::NoExpand)
|
|
|
|
and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) {
|
|
|
|
cdebug_log(159,0) << "Cannot move up but successful narrow breaking." << endl;
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( not success and segment->isGlobal() and (_costs.size() <= 1) ) {
|
|
|
|
cdebug_log(159,0) << "Overconstrained perpandiculars, rip them up. On track:" << endl;
|
|
|
|
cdebug_log(159,0) << " " << track << endl;
|
|
|
|
Manipulator(segment,*this).ripupPerpandiculars ();
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::solveTerminalVsGlobal ()
|
|
|
|
{
|
|
|
|
TrackElement* segment = getEvent()->getSegment();
|
|
|
|
cdebug_log(159,0) << "SegmentFsm::solveTerminalVsGlobal: " << " " << segment << endl;
|
|
|
|
|
|
|
|
if (not (segment->isTerminal() and segment->isLocal())) return false;
|
|
|
|
|
|
|
|
for ( size_t icost=0 ; icost<_costs.size() ; ++icost ) {
|
|
|
|
Interval overlap = segment->getCanonicalInterval();
|
|
|
|
size_t begin;
|
|
|
|
size_t end;
|
|
|
|
getCost(icost).getTrack()->getOverlapBounds( overlap, begin, end );
|
|
|
|
|
|
|
|
for ( ; begin<end ; ++begin ) {
|
|
|
|
TrackElement* other = getCost(icost).getTrack()->getSegment(begin);
|
|
|
|
Interval otherOverlap = other->getCanonicalInterval();
|
|
|
|
|
|
|
|
if (other->getNet() == segment->getNet()) continue;
|
|
|
|
if (not other->isGlobal()) continue;
|
|
|
|
if (not otherOverlap.contains(overlap)) continue;
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "| Global candidate:" << other << endl;
|
|
|
|
if (Manipulator(other,*this).moveUp(Manipulator::AllowTerminalMoveUp)) {
|
|
|
|
cdebug_log(159,0) << "| Global candidate selected." << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::solveFullBlockages ()
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
TrackElement* segment = getEvent()->getSegment();
|
|
|
|
|
|
|
|
cdebug_log(159,1) << "SegmentFsm::solveFullBlockages: " << " " << segment << endl;
|
|
|
|
|
|
|
|
if ( segment->isLocal() ) {
|
|
|
|
success = Manipulator(segment,*this).pivotUp();
|
|
|
|
if ( not success ) {
|
|
|
|
cdebug_log(159,0) << "Tightly constrained local segment overlapping a blockage, move up." << endl;
|
|
|
|
cdebug_log(159,0) << segment << endl;
|
|
|
|
success = Manipulator(segment,*this).moveUp
|
|
|
|
(Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Interval overlap = segment->getCanonicalInterval();
|
|
|
|
size_t begin;
|
|
|
|
size_t end;
|
|
|
|
|
|
|
|
getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end );
|
|
|
|
for ( ; begin<end ; ++begin ) {
|
|
|
|
TrackElement* other = getCost(0).getTrack()->getSegment(begin);
|
|
|
|
Interval otherOverlap = other->getCanonicalInterval();
|
|
|
|
|
|
|
|
if ( other->getNet() == segment->getNet() ) continue;
|
|
|
|
if ( not otherOverlap.intersect(overlap) ) continue;
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "| " << begin << " Blockage conflict: " << " " << other << endl;
|
|
|
|
if ( (success = Manipulator(segment,*this).relax
|
|
|
|
(otherOverlap,Manipulator::NoDoglegReuse|Manipulator::NoExpand)) ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( not success ) {
|
|
|
|
cparanoid << Error( "Tighly constrained segment overlapping a blockage:\n %s"
|
|
|
|
, getString(segment).c_str() ) << endl;
|
|
|
|
cdebug_log(159,0) << "Segment is hard blocked, bypass to Unimplemented." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_tabw(159,-1);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::desaturate ()
|
|
|
|
{
|
|
|
|
cdebug_log(159,1) << "SegmentFsm::desaturate()" << endl;
|
|
|
|
|
|
|
|
size_t itrack = 0;
|
|
|
|
|
|
|
|
#if THIS_IS_DISABLED
|
|
|
|
TrackElement* segment = _event->getSegment();
|
|
|
|
for ( ; itrack<getCosts().size() ; ++itrack ) {
|
|
|
|
cdebug_log(159,0) << "Trying track:" << itrack << endl;
|
|
|
|
|
|
|
|
if ( getCost(itrack).isGlobalEnclosed() ) {
|
|
|
|
Track* track = getTrack(itrack);
|
|
|
|
size_t begin = getBegin(itrack);
|
|
|
|
size_t end = getEnd (itrack);
|
|
|
|
Net* ownerNet = segment->getNet();
|
|
|
|
Interval toFree (segment->getCanonicalInterval());
|
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
for ( size_t i = begin ; success and (i < end) ; i++ ) {
|
|
|
|
TrackElement* segment2 = track->getSegment(i);
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "* Looking // " << segment2 << endl;
|
|
|
|
|
|
|
|
if ( segment2->getNet() == ownerNet ) continue;
|
|
|
|
if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue;
|
|
|
|
if ( segment2->isFixed() or not segment2->isBipoint() ) {
|
|
|
|
success = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
DataNegociate* data2 = segment2->getDataNegociate();
|
|
|
|
if ( not data2 ) {
|
|
|
|
cdebug_log(159,0) << "No DataNegociate, ignoring." << endl;
|
|
|
|
success = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_log(159,0) << "- Forced moveUp " << segment2 << endl;
|
|
|
|
if ( not (success=Manipulator(segment2,*this).moveUp(Manipulator::AllowTerminalMoveUp)) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( success ) {
|
|
|
|
setState ( SegmentFsm::OtherRipup );
|
|
|
|
addAction( segment
|
|
|
|
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis
|
|
|
|
, getCost(itrack).getTrack()->getAxis()
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
cdebug_tabw(159,-1);
|
|
|
|
return (itrack < _costs.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::_slackenStrap ( TrackElement*& segment, DataNegociate*& data, unsigned int flags )
|
|
|
|
{
|
|
|
|
cdebug_log(159,0) << "Strap segment Fsm." << endl;
|
|
|
|
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
bool success = false;
|
|
|
|
unsigned int nextState = data->getState();
|
|
|
|
Manipulator manipulator ( segment, *this );
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
|
|
|
|
switch ( data->getState() ) {
|
|
|
|
case DataNegociate::RipupPerpandiculars:
|
|
|
|
nextState = DataNegociate::Minimize;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.ripupPerpandiculars();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::Minimize:
|
|
|
|
if (data->getStateCount() >= 2) {
|
|
|
|
nextState = DataNegociate::MaximumSlack;
|
|
|
|
}
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.minimize();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::Dogleg:
|
|
|
|
case DataNegociate::Slacken:
|
|
|
|
case DataNegociate::ConflictSolveByHistory:
|
|
|
|
case DataNegociate::ConflictSolveByPlaceds:
|
|
|
|
case DataNegociate::MoveUp:
|
|
|
|
case DataNegociate::MaximumSlack:
|
|
|
|
case DataNegociate::Unimplemented:
|
|
|
|
nextState = DataNegociate::Unimplemented;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not success and (nextState != DataNegociate::Unimplemented))
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit);
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
|
|
|
|
if (not (flags&NoTransition)) {
|
|
|
|
data->setState( nextState );
|
|
|
|
cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::_slackenLocal ( TrackElement*& segment, DataNegociate*& data, unsigned int flags )
|
|
|
|
{
|
|
|
|
cdebug_log(159,0) << "Local segment Fsm." << endl;
|
|
|
|
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
bool success = false;
|
|
|
|
unsigned int nextState = data->getState();
|
|
|
|
Manipulator manipulator ( segment, *this );
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
|
|
|
|
switch (data->getState()) {
|
|
|
|
case DataNegociate::RipupPerpandiculars:
|
|
|
|
nextState = DataNegociate::Minimize;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.ripupPerpandiculars();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::Minimize:
|
|
|
|
if (isFullBlocked() and not segment->isTerminal()) {
|
|
|
|
cdebug_log(159,0) << "Is Fully blocked." << endl;
|
|
|
|
nextState = DataNegociate::Unimplemented;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nextState = DataNegociate::Dogleg;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.minimize();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::Dogleg:
|
|
|
|
nextState = DataNegociate::Slacken;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.makeDogleg();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::Slacken:
|
|
|
|
nextState = DataNegociate::ConflictSolveByPlaceds;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.slacken();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::ConflictSolveByHistory:
|
|
|
|
case DataNegociate::ConflictSolveByPlaceds:
|
|
|
|
nextState = DataNegociate::LocalVsGlobal;
|
|
|
|
success = conflictSolveByHistory();
|
|
|
|
break;
|
|
|
|
case DataNegociate::LocalVsGlobal:
|
|
|
|
nextState = DataNegociate::MoveUp;
|
|
|
|
success = solveTerminalVsGlobal();
|
|
|
|
if (success) break;
|
|
|
|
break;
|
|
|
|
case DataNegociate::MoveUp:
|
|
|
|
nextState = DataNegociate::MaximumSlack;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.moveUp();
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
if (success) break;
|
|
|
|
case DataNegociate::MaximumSlack:
|
|
|
|
if (segment->isStrap()) {
|
|
|
|
if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) {
|
|
|
|
nextState = DataNegociate::MaximumSlack;
|
|
|
|
success = conflictSolveByPlaceds();
|
|
|
|
if (success) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case DataNegociate::Unimplemented:
|
|
|
|
nextState = DataNegociate::Unimplemented;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not success and (nextState != DataNegociate::Unimplemented)) {
|
|
|
|
if (data->getStateCount() < 6)
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit);
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (not success
|
|
|
|
and (nextState == DataNegociate::Unimplemented)
|
|
|
|
and segment->isSlackened()
|
|
|
|
and isFullBlocked()) {
|
|
|
|
if (solveFullBlockages()) nextState = DataNegociate::MoveUp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not (flags&NoTransition)) {
|
|
|
|
data->setState( nextState );
|
|
|
|
cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::_slackenGlobal ( TrackElement*& segment, DataNegociate*& data, unsigned int flags )
|
|
|
|
{
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
bool success = false;
|
|
|
|
unsigned int nextState = data->getState();
|
|
|
|
Manipulator manipulator ( segment, *this );
|
|
|
|
unsigned int moveUpFlags = Manipulator::AllowShortPivotUp|Manipulator::IgnoreContacts;
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
|
|
|
|
switch ( data->getState() ) {
|
|
|
|
case DataNegociate::RipupPerpandiculars:
|
|
|
|
case DataNegociate::Minimize:
|
|
|
|
case DataNegociate::Dogleg:
|
|
|
|
cdebug_log(159,0) << "Global, SegmentFsm: RipupPerpandiculars." << endl;
|
|
|
|
nextState = DataNegociate::Slacken;
|
|
|
|
break;
|
|
|
|
case DataNegociate::Slacken:
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
cdebug_log(159,0) << "Global, SegmentFsm: Slacken "
|
|
|
|
<< ((manipulator.getEvent())
|
|
|
|
? manipulator.getEvent()->getConstraints() : "(not event yet)") << endl;
|
|
|
|
if ( manipulator.getEvent()
|
|
|
|
and manipulator.getEvent()->getConstraints().isPonctual()
|
|
|
|
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
|
|
|
|
moveUpFlags |= Manipulator::AllowTerminalMoveUp;
|
|
|
|
} else {
|
|
|
|
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
|
|
|
|
nextState = DataNegociate::RipupPerpandiculars;
|
|
|
|
break;
|
|
|
|
}
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
}
|
|
|
|
case DataNegociate::MoveUp:
|
|
|
|
cdebug_log(159,0) << "Global, SegmentFsm: MoveUp." << endl;
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
if ((success = manipulator.moveUp(moveUpFlags))) {
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
nextState = DataNegociate::ConflictSolveByHistory;
|
|
|
|
break;
|
|
|
|
case DataNegociate::ConflictSolveByHistory:
|
|
|
|
case DataNegociate::ConflictSolveByPlaceds:
|
|
|
|
cdebug_log(159,0) << "Global, SegmentFsm: ConflictSolveByHistory or ConflictSolveByPlaceds." << endl;
|
|
|
|
if ((success = conflictSolveByPlaceds())) {
|
|
|
|
if (segment->canMoveUp(1.0,Flags::CheckLowDensity))
|
|
|
|
nextState = DataNegociate::MoveUp;
|
|
|
|
else {
|
|
|
|
if (data->getStateCount() > 3)
|
|
|
|
nextState = DataNegociate::MaximumSlack;
|
|
|
|
}
|
|
|
|
if (segment->getDataNegociate()->getState() < DataNegociate::ConflictSolveByHistory)
|
|
|
|
nextState = segment->getDataNegociate()->getState();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DataNegociate::MaximumSlack:
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
if ((success=manipulator.forceOverLocals())) {
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DataNegociate::Unimplemented:
|
|
|
|
cdebug_log(159,0) << "Global, SegmentFsm: MaximumSlack or Unimplemented." << endl;
|
|
|
|
nextState = DataNegociate::Unimplemented;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not success and (nextState != DataNegociate::Unimplemented)) {
|
|
|
|
if (data->getStateCount() < 6)
|
Forgot to perform Track re-order after removing zero-length segments.
* Change: In Anabatic::Autocontact, replace getMinDepth() and
getMaxDepth() by getDepthSpan().
* New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of
low up density (Flags::CheckLowUpDensity). Allows to move up a
segment if the up density is (very) low, and in this case it's more
efficient than breaking it to fit in the lower layer.
canMoveUp() is now able to perform the same work as canPivotUp()
if *not* supplied the flag Flags::IgnoreContacts.
* New: In Katana, in GlobalRouting::DigitalDistance() now take into
account the cost of a VIA (currently set to 2.5). Need to known the
Net currently routed in the DigitalDistance object itself.
* Change: In Katana::Track::Element::canPivotUp(), now also takes a flag
parameter.
* Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the
one of Anabatic.
* Change: In Katana::SegmentFsm, allocate once a Manipulator object instead
of many times on the fly.
In SegmentFsm::_slackenGlobal(), in the slacken state, if the up
density is (very) low, bypass to move up instead of slackening.
This solve better the routing of the control part of the register file.
The register file having a pathological case of terminal placement:
many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and
METAL3 blockages near below...
* Bug: In Katana::Session::_revalidate(), after removing the zero-length
segments, forgot to re-order the track, leading to many stranges effects
as the indexes where no longer coherent in the Track.
2016-09-20 04:30:45 -05:00
|
|
|
success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit);
|
Anabatic transient commit 18. Port of Kite (Katana), Yeah, Baby! Yeah!
* Bug: In Hurricane, in StaticObservable::getObserver(), if the slot
pointer is NULL, do not try to access the owner. Returns NULL, so
the caller can be aware of the situation...
* Change: In Hurricane, in BreakpointWidget & ExceptionWidget some
cosmetic changes (fonts and window sizes).
* Bug: In Anabatic, In AutoHorizontal::getConstraints(), take into account
the constraints from the source AutoContact, as it holds the constraints
transmitted by the RoutingPads and sets up by propageConstraintsFromRp().
It is likely to be a bug affecting the original Katabatic as well.
* Change: In Anabatic, in RawGCellsUnder(), check that the segment is not
completly oustside the cell abutment box and truncate the coordinates
to the part that is inside. Use the "shrink" if we reach the east/north
border.
* Change: In Anabatic, in Configuration, no more decorator because we will
use a true derived relationship. Katana *derives* from *Anabatic* and do
not *decorate* it, so the Configuration can do the same. It also implies
that we directly create a Katana engine, not an Anabatic one.
* Change: In Anabatic, in Session, do not allow the opening of the Session
in a standalone fashion (with a static method). Instead it must be opened
using the relevant method of the Anabatic/Katana engine. This ensure we
are opening the right Session type.
* Change: In Anabatic, in AutoSegment_Aligneds() collection the seed segment
is not part of the collection by default, but will be included if the
Flags::WithSelf is set.
* Change: In Configuration, all the flags value are now defined in two steps.
Declared in the header and initialized in the module. This is to prevent
the fact that on some cases, in relation with the Python "extern C" part
modules, we need a true allocated variable. It was causing weird linking
problems.
A side effect is that they can no longer be used as entry is switches,
have to replace them by if/else.
* New: In Anabatic, new GCell::getNeighborAt() utility function.
* Bug: In Anabatic, in GCell::doGrid(), tag all the GCells of the grid with
the grid type... Back annote all the edges capacity (north & east) with
the reserved local capacity.
* New: Complete portage of Kite over Anabatic. The new engine is christened
"Katana" for Kite-Analogic. When it's capabilities and performances
will be on a part with Kite, it is to completly replace it (and take
back the "Kite" name). Preliminary tests seems to show that, contrary
to intuition (because built on a more complex/slower grid), it is even
slightly faster than Kite 8-).
2016-08-15 09:30:13 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Special case: all tracks are overlaping a blockage.
|
|
|
|
if (not success
|
|
|
|
and (nextState == DataNegociate::Unimplemented)
|
|
|
|
and segment->isSlackened() ) {
|
|
|
|
if (solveFullBlockages()) nextState = DataNegociate::MoveUp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not (flags&NoTransition)) {
|
|
|
|
if (data->getChildSegment()) {
|
|
|
|
TrackElement* child = segment;
|
|
|
|
cdebug_log(159,0) << "Incrementing state of childs (after): " << endl;
|
|
|
|
while ( child ) {
|
|
|
|
cdebug_log(159,0) << "| " << child << endl;
|
|
|
|
if (child->base()->isGlobal()) {
|
|
|
|
child->getDataNegociate()->setState( nextState );
|
|
|
|
cdebug_log(159,0) << "| Update:" << nextState << " count:" << child->getDataNegociate()->getStateCount() << endl;
|
|
|
|
}
|
|
|
|
TrackElement* parent = child;
|
|
|
|
child = parent->getDataNegociate()->getChildSegment();
|
|
|
|
parent->getDataNegociate()->setChildSegment( NULL );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
data->setState( nextState );
|
|
|
|
cdebug_log(159,0) << "Incrementing state (after): " << segment << endl;
|
|
|
|
cdebug_log(159,0) << "| " << nextState << " count:" << data->getStateCount() << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SegmentFsm::slackenTopology ( unsigned int flags )
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
TrackElement* segment = getEvent()->getSegment();
|
|
|
|
DataNegociate* data = segment->getDataNegociate ();
|
|
|
|
unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5;
|
|
|
|
|
|
|
|
DebugSession::open( segment->getNet(), 150, 160 );
|
|
|
|
cdebug_log(159,1) << "Slacken Topology for " << segment->getNet()
|
|
|
|
<< " " << segment << endl;
|
|
|
|
|
|
|
|
if (not segment or not data) { cdebug_tabw(159,-1); DebugSession::close(); return false; }
|
|
|
|
|
|
|
|
_event->resetInsertState();
|
|
|
|
data->resetRipupCount();
|
|
|
|
|
|
|
|
if (segment->isStrap()) { success = _slackenStrap ( segment, data, flags ); }
|
|
|
|
else if (segment->isLocal()) { success = _slackenLocal ( segment, data, flags ); }
|
|
|
|
else { success = _slackenGlobal( segment, data, flags ); }
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
actionFlags |= SegmentAction::ResetRipup;
|
|
|
|
addAction( segment, actionFlags );
|
|
|
|
} else {
|
|
|
|
clearActions();
|
|
|
|
if (data->getState() == DataNegociate::Unimplemented) {
|
|
|
|
cinfo << "[UNSOLVED] " << segment << " unable to slacken topology." << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_tabw(159,-1);
|
|
|
|
DebugSession::close();
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // Katana namespace.
|