2010-03-09 09:24:55 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2018-01-06 10:55:44 -06:00
|
|
|
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
2013-12-03 18:59:29 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
// | C O R I O L I S |
|
|
|
|
// | K i t e - D e t a i l e d R o u t e r |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./RoutingPlane.cpp" |
|
2013-12-03 18:59:29 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
#include "hurricane/Error.h"
|
|
|
|
#include "hurricane/Box.h"
|
|
|
|
#include "hurricane/Cell.h"
|
|
|
|
#include "crlcore/RoutingLayerGauge.h"
|
|
|
|
#include "kite/HorizontalTrack.h"
|
|
|
|
#include "kite/VerticalTrack.h"
|
|
|
|
#include "kite/RoutingPlane.h"
|
|
|
|
#include "kite/KiteEngine.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
const char* badLayerGauge =
|
|
|
|
"RoutingPlane::create() :\n\n"
|
|
|
|
" No plane at depth %u in %s.";
|
|
|
|
|
|
|
|
|
|
|
|
} // End of local namespace.
|
|
|
|
|
|
|
|
|
|
|
|
namespace Kite {
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::Box;
|
|
|
|
using Hurricane::Cell;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "RoutingPlane".
|
|
|
|
|
|
|
|
|
|
|
|
RoutingPlane::RoutingPlane ( KiteEngine* kite, size_t depth )
|
|
|
|
: _kite (kite)
|
|
|
|
, _layerGauge(kite->getLayerGauge(depth))
|
|
|
|
, _depth (depth)
|
2013-12-03 18:59:29 -06:00
|
|
|
, _flags (0)
|
|
|
|
, _axisMin (0)
|
|
|
|
, _axisMax (0)
|
|
|
|
, _trackMin (0)
|
|
|
|
, _trackMax (0)
|
2010-03-09 09:24:55 -06:00
|
|
|
, _tracks ()
|
2013-12-03 18:59:29 -06:00
|
|
|
{
|
|
|
|
switch ( _layerGauge->getDirection() ) {
|
|
|
|
case Constant::Horizontal: _flags |= KbHorizontal; break;
|
|
|
|
case Constant::Vertical: _flags |= KbVertical; break;
|
|
|
|
default:
|
|
|
|
cerr << Error( "RoutingPlane::RoutingPlane() - Unknown plane direction from LayerGauge: %u"
|
|
|
|
, _layerGauge->getDirection() ) << endl;
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
RoutingPlane::~RoutingPlane ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
void RoutingPlane::destroy ()
|
|
|
|
{
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_log(155,1) << "RoutingPlane::destroy() - "
|
2016-05-17 16:00:06 -05:00
|
|
|
<< (void*)this << " " << this << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t index=0 ; index<_tracks.size() ; ++index )
|
|
|
|
_tracks[index]->destroy();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
delete this;
|
|
|
|
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_tabw(155,-1);
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RoutingPlane* RoutingPlane::create ( KiteEngine* kite, size_t depth )
|
|
|
|
{
|
|
|
|
RoutingPlane* plane = new RoutingPlane ( kite, depth );
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not plane->_layerGauge)
|
|
|
|
throw Error( badLayerGauge, depth, getString(kite->getRoutingGauge()).c_str() );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
DbU::Unit hExtension = 0;
|
|
|
|
DbU::Unit vExtension = 0;
|
|
|
|
unsigned int gaugeDepth = 0;
|
|
|
|
if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth;
|
|
|
|
|
|
|
|
bool HV = (Session::getLayerGauge(gaugeDepth)->getDirection() == Constant::Horizontal);
|
|
|
|
hExtension = Session::getLayerGauge( gaugeDepth + (HV?1:0) )->getPitch() / 2;
|
|
|
|
vExtension = Session::getLayerGauge( gaugeDepth + (HV?0:1) )->getPitch() / 2;
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
size_t trackNumber;
|
|
|
|
Box abutmentBox = kite->getCell()->getAbutmentBox();
|
2013-12-03 18:59:29 -06:00
|
|
|
// HARD CODED.
|
|
|
|
if (plane->getDirection() == KbHorizontal) {
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
plane->_trackMin = abutmentBox.getXMin() - hExtension;
|
|
|
|
plane->_trackMax = abutmentBox.getXMax() + hExtension;
|
2013-12-03 18:59:29 -06:00
|
|
|
plane->_axisMin = abutmentBox.getYMin();
|
|
|
|
plane->_axisMax = abutmentBox.getYMax();
|
|
|
|
trackNumber = plane->computeTracksSize();
|
2010-03-09 09:24:55 -06:00
|
|
|
} else {
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
plane->_trackMin = abutmentBox.getYMin() - vExtension;
|
|
|
|
plane->_trackMax = abutmentBox.getYMax() + vExtension;
|
2013-12-03 18:59:29 -06:00
|
|
|
plane->_axisMin = abutmentBox.getXMin();
|
|
|
|
plane->_axisMax = abutmentBox.getXMax();
|
|
|
|
trackNumber = plane->computeTracksSize();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
plane->_tracks.reserve( trackNumber );
|
|
|
|
for ( size_t index=0 ; index<trackNumber ; ++index ) {
|
|
|
|
if (plane->getDirection() == KbHorizontal) {
|
|
|
|
plane->_tracks.push_back( HorizontalTrack::create( plane, index ) );
|
* ./kite:
- New: In RoutingEvent, while routing a full chip, transient full blockages
may happens due to the initial position of some perpandiculars on theirs
optimal positions. Check for it and perform a "ripupPerpandicular" with
the perpandiculars re-routed first (on normal operation, this is the
reverse).
- Change: In NegociateWindow::NegociateOverlapCost(), do not account terminals
if the layer is *above* METAL3 as it is unlikely that it's truly directly
connected to a terminal (true at least for our designs).
- Change: In RoutingEvent::State, add a "fullBlocked" flag to perform the
full blockage direction while building the state object.
- Change: In RoutingEvent::cacheAxisHint(), when the TrackSegment has parent,
uses the parent current axis position and not it's axis hint.
- Change: In Manipulator::insertInTrack(), when the overlapped segment is a
Local and is completly enclosed (shrinkLeft & shrinkRight), no longer
rip it up but force a shrink left/right instead.
- Bug: In RoutingEvent, the event sorting function was sorting in the *wrong*
order! The less prioritary first! With the correct sort, we won an
additionnal 30% in speed (total: 69%). From the "reference" time we have
a 3.2 speed-up. And we can successfully process denser designs...
2011-01-09 12:08:57 -06:00
|
|
|
// Ugly: Direct uses of CellGauge (middle tracks 4 & 5 for local use).
|
2013-12-03 18:59:29 -06:00
|
|
|
if (depth == 1) {
|
|
|
|
switch ( index%10 ) {
|
* ./kite:
- New: In RoutingEvent, while routing a full chip, transient full blockages
may happens due to the initial position of some perpandiculars on theirs
optimal positions. Check for it and perform a "ripupPerpandicular" with
the perpandiculars re-routed first (on normal operation, this is the
reverse).
- Change: In NegociateWindow::NegociateOverlapCost(), do not account terminals
if the layer is *above* METAL3 as it is unlikely that it's truly directly
connected to a terminal (true at least for our designs).
- Change: In RoutingEvent::State, add a "fullBlocked" flag to perform the
full blockage direction while building the state object.
- Change: In RoutingEvent::cacheAxisHint(), when the TrackSegment has parent,
uses the parent current axis position and not it's axis hint.
- Change: In Manipulator::insertInTrack(), when the overlapped segment is a
Local and is completly enclosed (shrinkLeft & shrinkRight), no longer
rip it up but force a shrink left/right instead.
- Bug: In RoutingEvent, the event sorting function was sorting in the *wrong*
order! The less prioritary first! With the correct sort, we won an
additionnal 30% in speed (total: 69%). From the "reference" time we have
a 3.2 speed-up. And we can successfully process denser designs...
2011-01-09 12:08:57 -06:00
|
|
|
case 4:
|
|
|
|
case 5:
|
2013-12-03 18:59:29 -06:00
|
|
|
plane->_tracks.back()->setLocalAssigned( true );
|
* ./kite:
- New: In RoutingEvent, while routing a full chip, transient full blockages
may happens due to the initial position of some perpandiculars on theirs
optimal positions. Check for it and perform a "ripupPerpandicular" with
the perpandiculars re-routed first (on normal operation, this is the
reverse).
- Change: In NegociateWindow::NegociateOverlapCost(), do not account terminals
if the layer is *above* METAL3 as it is unlikely that it's truly directly
connected to a terminal (true at least for our designs).
- Change: In RoutingEvent::State, add a "fullBlocked" flag to perform the
full blockage direction while building the state object.
- Change: In RoutingEvent::cacheAxisHint(), when the TrackSegment has parent,
uses the parent current axis position and not it's axis hint.
- Change: In Manipulator::insertInTrack(), when the overlapped segment is a
Local and is completly enclosed (shrinkLeft & shrinkRight), no longer
rip it up but force a shrink left/right instead.
- Bug: In RoutingEvent, the event sorting function was sorting in the *wrong*
order! The less prioritary first! With the correct sort, we won an
additionnal 30% in speed (total: 69%). From the "reference" time we have
a 3.2 speed-up. And we can successfully process denser designs...
2011-01-09 12:08:57 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
} else {
|
2013-12-03 18:59:29 -06:00
|
|
|
plane->_tracks.push_back( VerticalTrack::create( plane, index ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return plane;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RoutingPlane* RoutingPlane::getTop () const
|
2013-12-03 18:59:29 -06:00
|
|
|
{ return getKiteEngine()->getRoutingPlaneByIndex( getDepth()+1 ); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
RoutingPlane* RoutingPlane::getBottom () const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not getDepth()) return NULL;
|
|
|
|
return getKiteEngine()->getRoutingPlaneByIndex( getDepth()-1 );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Track* RoutingPlane::getTrackByIndex ( size_t index ) const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (index >= getTracksSize()) return NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
return _tracks[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, unsigned int mode ) const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
return getTrackByIndex( getLayerGauge()->getTrackIndex( getAxisMin()
|
|
|
|
, getAxisMax()
|
|
|
|
, axis
|
|
|
|
, mode
|
|
|
|
) );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool RoutingPlane::_check ( unsigned int& overlaps ) const
|
|
|
|
{
|
|
|
|
bool coherency = true;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t i=0 ; i<_tracks.size() ; ++i ) {
|
|
|
|
coherency = _tracks[i]->check(overlaps) and coherency;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return coherency;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string RoutingPlane::_getString () const
|
|
|
|
{
|
|
|
|
return "<" + _getTypeName() + " @"
|
2013-12-03 18:59:29 -06:00
|
|
|
+ getString(_depth) + " "
|
|
|
|
+ getString(getLayer()) + " [ "
|
|
|
|
+ ((getDirection() == KbHorizontal) ? " horizontal [" : " vertical [")
|
2010-03-09 09:24:55 -06:00
|
|
|
+ getString(_tracks.size()) + "/"
|
|
|
|
+ getString(_tracks.capacity())
|
|
|
|
+ "]>";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* RoutingPlane::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = new Record ( getString(this) );
|
2013-12-03 18:59:29 -06:00
|
|
|
record->add( getSlot ( "_kite" , _kite ) );
|
|
|
|
record->add( getSlot ( "_layerGauge" , _layerGauge ) );
|
|
|
|
record->add( getSlot ( "_depth" , &_depth ) );
|
|
|
|
record->add( DbU::getValueSlot( "_axisMin" , &_axisMin ) );
|
|
|
|
record->add( DbU::getValueSlot( "_axisMax" , &_axisMax ) );
|
|
|
|
record->add( DbU::getValueSlot( "_trackMin" , &_trackMin ) );
|
|
|
|
record->add( DbU::getValueSlot( "_trackMax" , &_trackMax ) );
|
|
|
|
record->add( getSlot ( "_tracks" , &_tracks ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
} // Kite namespace.
|