Basic support for FreePDK 45 completed.
* New: In Commons, inspector support for std::pair<T,U>. * New: In Hurricane::Layer, ContactLayer & ViaLayer, support for non square VIAs. The hole (cut) remains square, but the various metal extensions can now be different in X and Y. The ::getEnclosure() method now takes a flag EnclosureH / EnclosureV. * New: In Hurricane::DbU, inspector support for: std::pair<DbU::Unit,DbU::Unit> std::array<DbU::Unit,3> Must be defined here as DbU do not exists yet in Commons.h * Bug: In Hurricane::Interval::getSize(), when the interval is "full span", do not return the difference between min and max, but directly DbU::Max. (the previous result was -1 !) * New: In CRL Core Python/Technology.py, support for non square VIAs in the configuration files. Applied to FreePDK 45. * New: In CRL::RoutingGauge, added a "symbolic" flag to tell if a gauge is for symbolic layout or not. Exported to Python. * New: In Anabatic::AutoHorizontal::updatePosition(), differentiated computation for soure or target taking account of the VIA extension in the right segment metal (due to non-square VIAs). * Change: In Anabatic::AutoHorizontal::_makeDogleg(), the dogleg is UP for HV gauges and DOWN for VH. * New: In Anabatic::AutoSegment::_initialize(), create a cache of the various extension length for each layer (viaToTop, viaToBottom, viaToSame). New implementation of getExtensionCap() using the previous cached extension table. See updatePositions(). New static functions to access the extension cache in the header: getViaTotopCap() ... * Change: In Anabatic::AutoSegment, in various update methods, updateOrient() must always be called *before* updatePositions() as extensions are dependant on source/target. * New: In Anabatic::AutoSegment::getEndAxes() compute the position of the first source and last target position (center/axes) on an *aligned* set of segments. * New: In Anabatic::AutoSegment, add a new state flag SegAxisFixed to signal segments that can be put on only one track. Specific case to VH gauge for a M1 vertical terminal with a M2 vertical segment. The M2 is effectively bound to the M1 axis position. * Bug: In Anabatic::NetBuilderVH::_do_xG_xM1_xM3(), in case of E/W global and only one RoutingPad the connexion to the RoutingPad was duplicated. It was valid, but totally stupid. * Bug: In Anabatic::Session::_canonize(), for an aligned segment set, intersect the user constraints from all segments instead of only considering the canonical one. Issue a warning about too tight constraints only for symbolic gauges. It may be correct for the real ones. * New: In Katata::DataNegociate::update(), more accurate computation of the perpandicular free interval. Use segment extension cap calculation. Create a special case for fixed axis segments allowing them to find alternative free interval, try under source and under target as they are likely to be draggable segments. * Change: In Katana::Manipulator::relax(), use the extension cap value to compute the axis of the perpandicular segemnts. * Change: In Katana::Manipulator::moveUp(), now move up the whole set of aligned segments instead of just the canonical one. * Change: In Katana::NegociateWindow::loadRoutingPads(), more accurate TrackMarkers insertions for fixed terminals. * New: In Katana::RoutingEvent::Key::Compare::operator(), segments with fixed axis are processed prior to any others. * New: In Katana::RoutingEventLoop, store segment pointers instead of ids to generate more accurate error messages. * Change: In Katana::RoutingPlane::create(), perform local track assignment only for HV gauges. * Change: In Katana::SegmentFsm::_slackenLocal(), add a "dragMinimize" step in the automaton. Mutliple states transitions can occurs in a row if an action fails. * New: In Katana::Session::_toIntervalAxis(), normalize interval bounds so they are on track positions (by shrinking the interval). * Bug: In Katana::TrackMarker CTOR, the weigh computation was wrong.
This commit is contained in:
parent
7bcf47212b
commit
592c098ab2
|
@ -18,6 +18,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/Breakpoint.h"
|
#include "hurricane/Breakpoint.h"
|
||||||
#include "hurricane/RegularLayer.h"
|
#include "hurricane/RegularLayer.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
|
@ -29,20 +30,108 @@
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "crlcore/Measures.h"
|
#include "crlcore/Measures.h"
|
||||||
#include "anabatic/GCell.h"
|
#include "anabatic/GCell.h"
|
||||||
|
#include "anabatic/AutoContactTerminal.h"
|
||||||
#include "anabatic/NetBuilderM2.h"
|
#include "anabatic/NetBuilderM2.h"
|
||||||
#include "anabatic/NetBuilderHV.h"
|
#include "anabatic/NetBuilderHV.h"
|
||||||
#include "anabatic/NetBuilderVH.h"
|
#include "anabatic/NetBuilderVH.h"
|
||||||
#include "anabatic/AnabaticEngine.h"
|
#include "anabatic/AnabaticEngine.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace Hurricane;
|
||||||
|
using namespace Anabatic;
|
||||||
|
|
||||||
|
|
||||||
|
class SortAcByXY {
|
||||||
|
public:
|
||||||
|
inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 )
|
||||||
|
{
|
||||||
|
DbU::Unit x1 = contact1->getX();
|
||||||
|
DbU::Unit x2 = contact2->getX();
|
||||||
|
|
||||||
|
if (x1 == x2) {
|
||||||
|
DbU::Unit y1 = contact1->getY();
|
||||||
|
DbU::Unit y2 = contact2->getY();
|
||||||
|
|
||||||
|
if (y1 == y2) return false;
|
||||||
|
return (y1 < y2);
|
||||||
|
}
|
||||||
|
return (x1 < x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shear ( AutoSegment* segment )
|
||||||
|
{
|
||||||
|
AutoContact* source = segment->getAutoSource();
|
||||||
|
AutoContact* target = segment->getAutoTarget();
|
||||||
|
bool useSource = true;
|
||||||
|
|
||||||
|
if (segment->isHorizontal()) {
|
||||||
|
if (not source->isTurn() and target->isTurn()) useSource = false;
|
||||||
|
} else {
|
||||||
|
if (not source->isTurn() and target->isTurn()) useSource = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
segment->makeDogleg( (useSource ? source->getGCell() : target->getGCell()) );
|
||||||
|
Session::getDoglegs()[ Session::getDoglegs().size()-2 ]->unsetFlags( AutoSegment::SegAxisSet );
|
||||||
|
|
||||||
|
#if BAD_RESULTS
|
||||||
|
AutoContact* source = segment->getAutoSource();
|
||||||
|
AutoContact* target = segment->getAutoTarget();
|
||||||
|
AutoSegment* perpandicular = NULL;
|
||||||
|
bool useSource = true;
|
||||||
|
|
||||||
|
if (segment->isHorizontal()) {
|
||||||
|
if (source->isTurn()) perpandicular = source->getPerpandicular( segment );
|
||||||
|
else {
|
||||||
|
if (target->isTurn()) { perpandicular = target->getPerpandicular( segment ); useSource = false; }
|
||||||
|
else {
|
||||||
|
if (source->isHTee()) perpandicular = source->getPerpandicular( segment );
|
||||||
|
else {
|
||||||
|
if (target->isHTee()) { perpandicular = target->getPerpandicular( segment ); useSource = false; }
|
||||||
|
else
|
||||||
|
perpandicular = segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (source->isTurn()) perpandicular = source->getPerpandicular( segment );
|
||||||
|
else {
|
||||||
|
if (target->isTurn()) { perpandicular = target->getPerpandicular( segment ); useSource = false; }
|
||||||
|
else {
|
||||||
|
if (source->isVTee()) perpandicular = source->getPerpandicular( segment );
|
||||||
|
else {
|
||||||
|
if (target->isVTee()) { perpandicular = target->getPerpandicular( segment ); useSource = false; }
|
||||||
|
else
|
||||||
|
perpandicular = segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perpandicular->makeDogleg( (useSource ? source->getGCell() : target->getGCell()) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // Anonymous namespace.
|
||||||
|
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
using std::multiset;
|
||||||
using std::ostringstream;
|
using std::ostringstream;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Warning;
|
||||||
using Hurricane::Breakpoint;
|
using Hurricane::Breakpoint;
|
||||||
using Hurricane::RegularLayer;
|
using Hurricane::RegularLayer;
|
||||||
using Hurricane::Component;
|
using Hurricane::Component;
|
||||||
|
@ -416,6 +505,7 @@ namespace Anabatic {
|
||||||
for ( GCell* gcell : _gcells ) _updateLookup( gcell );
|
for ( GCell* gcell : _gcells ) _updateLookup( gcell );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets )
|
size_t AnabaticEngine::getNetsFromEdge ( const Edge* edge, NetSet& nets )
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
@ -719,11 +809,136 @@ namespace Anabatic {
|
||||||
throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() );
|
throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() );
|
||||||
}
|
}
|
||||||
cleanupGlobal();
|
cleanupGlobal();
|
||||||
|
relaxOverConstraineds();
|
||||||
|
|
||||||
_state = EngineActive;
|
_state = EngineActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnabaticEngine::relaxOverConstraineds ()
|
||||||
|
{
|
||||||
|
openSession();
|
||||||
|
|
||||||
|
DbU::Unit pitch3 = Session::getPitch( 2 );
|
||||||
|
AutoSegment::IdSet constraineds;
|
||||||
|
AutoSegment::IdSet processeds;
|
||||||
|
|
||||||
|
for ( GCell* gcell : _gcells ) {
|
||||||
|
//cerr << "@ " << gcell << endl;
|
||||||
|
|
||||||
|
multiset<AutoContactTerminal*,SortAcByXY> acTerminals;
|
||||||
|
for ( AutoContact* contact : gcell->getContacts() ) {
|
||||||
|
if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) )
|
||||||
|
acTerminals.insert( dynamic_cast<AutoContactTerminal*>(contact) );
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoContactTerminal* south = NULL;
|
||||||
|
for ( AutoContactTerminal* north : acTerminals ) {
|
||||||
|
//cerr << "@ " << north << endl;
|
||||||
|
if (south) {
|
||||||
|
if ( south->canDrag()
|
||||||
|
and north->canDrag()
|
||||||
|
and (south->getNet() != north->getNet())
|
||||||
|
and (south->getX () == north->getX ()) ) {
|
||||||
|
//Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() );
|
||||||
|
Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() );
|
||||||
|
AutoSegment* terminal = south->getSegment();
|
||||||
|
AutoContact* opposite = terminal->getOppositeAnchor( south );
|
||||||
|
|
||||||
|
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
|
||||||
|
segment->mergeUserConstraints( constraints );
|
||||||
|
constraineds.insert( segment );
|
||||||
|
//cerr << "Apply " << constraints << " to " << segment << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() );
|
||||||
|
constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() );
|
||||||
|
terminal = north->getSegment();
|
||||||
|
opposite = terminal->getOppositeAnchor( north );
|
||||||
|
|
||||||
|
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
|
||||||
|
segment->mergeUserConstraints( constraints );
|
||||||
|
constraineds.insert( segment );
|
||||||
|
//cerr << "Apply " << constraints << " to " << segment << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (south->getConstraintBox().getHeight() < pitch3*2) metal2protect( south );
|
||||||
|
//if (north->getConstraintBox().getHeight() < pitch3*2) metal2protect( north );
|
||||||
|
}
|
||||||
|
south = north;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::revalidate();
|
||||||
|
|
||||||
|
for ( AutoSegment* constrained : constraineds ) {
|
||||||
|
if (processeds.find(constrained) != processeds.end()) continue;
|
||||||
|
processeds.insert( constrained );
|
||||||
|
|
||||||
|
Interval userConstraints ( false );
|
||||||
|
vector<AutoSegment*> aligneds;
|
||||||
|
|
||||||
|
aligneds.push_back( constrained );
|
||||||
|
|
||||||
|
for ( AutoSegment* aligned : constrained->getAligneds() ) {
|
||||||
|
aligneds.push_back( aligned );
|
||||||
|
processeds.insert( aligned );
|
||||||
|
}
|
||||||
|
|
||||||
|
sort( aligneds.begin(), aligneds.end(), AutoSegment::CompareBySourceU() );
|
||||||
|
|
||||||
|
AutoSegment* previous = NULL;
|
||||||
|
for ( AutoSegment* aligned : aligneds ) {
|
||||||
|
Interval constraints = userConstraints.getIntersection( aligned->getUserConstraints() );
|
||||||
|
cerr << "aligned: " << aligned << " " << aligned->getUserConstraints() << endl;
|
||||||
|
|
||||||
|
if (constraints.getSize() < Session::getPitch(1)) {
|
||||||
|
if (not previous) {
|
||||||
|
cerr << Warning( "protectAlignedAccesses(): Shearing constraints between S/T on\n"
|
||||||
|
" %s\n"
|
||||||
|
" S:%s\n"
|
||||||
|
" T:%s\n"
|
||||||
|
" Combined user constraints are too tight [%s : %s]."
|
||||||
|
, getString(aligned ).c_str()
|
||||||
|
, getString(aligned->getAutoSource()->getConstraintBox()).c_str()
|
||||||
|
, getString(aligned->getAutoTarget()->getConstraintBox()).c_str()
|
||||||
|
, DbU::getValueString(constraints.getVMin()).c_str()
|
||||||
|
, DbU::getValueString(constraints.getVMax()).c_str()
|
||||||
|
) << endl;
|
||||||
|
} else {
|
||||||
|
cerr << Warning( "protectAlignedAccesses(): Shearing constraints between\n"
|
||||||
|
" %s\n"
|
||||||
|
" %s\n"
|
||||||
|
" Combined user constraints are too tight [%s : %s]."
|
||||||
|
, getString(previous).c_str()
|
||||||
|
, getString(aligned ).c_str()
|
||||||
|
, DbU::getValueString(constraints.getVMin()).c_str()
|
||||||
|
, DbU::getValueString(constraints.getVMax()).c_str()
|
||||||
|
) << endl;
|
||||||
|
}
|
||||||
|
//if (previous) {
|
||||||
|
// if (previous->getAutoTarget() == aligned->getAutoSource()) {
|
||||||
|
// cerr << "Found a shared contact: " << aligned->getAutoSource() << endl;
|
||||||
|
shear( aligned );
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
userConstraints = aligned->getUserConstraints();
|
||||||
|
} else {
|
||||||
|
userConstraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous = aligned;
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "Final user constraints:" << userConstraints << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnabaticEngine::_loadGrByNet ()
|
void AnabaticEngine::_loadGrByNet ()
|
||||||
{
|
{
|
||||||
cmess1 << " o Building detailed routing from global. " << endl;
|
cmess1 << " o Building detailed routing from global. " << endl;
|
||||||
|
|
|
@ -91,8 +91,11 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* ) const
|
AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* from ) const
|
||||||
{ return NULL; }
|
{
|
||||||
|
if ( (from == _horizontal1) or (from == _horizontal2) ) return _vertical1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegment* AutoContactHTee::getSegment ( unsigned int index ) const
|
AutoSegment* AutoContactHTee::getSegment ( unsigned int index ) const
|
||||||
|
|
|
@ -172,9 +172,36 @@ namespace Anabatic {
|
||||||
if (component == NULL) {
|
if (component == NULL) {
|
||||||
cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl;
|
cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl;
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
return _gcell->getBoundingBox ();
|
return _gcell->getBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RoutingLayerGauge* lg = Session::getLayerGauge( Session::getLayerDepth(component->getLayer()) );
|
||||||
|
DbU::Unit xborder = 0;
|
||||||
|
DbU::Unit yborder = 0;
|
||||||
|
const Layer* viaLayer = Session::getContactLayer( lg->getDepth() );
|
||||||
|
|
||||||
|
if (viaLayer) {
|
||||||
|
if (lg->isHorizontal() and (lg->getDepth() != 0)) {
|
||||||
|
xborder = Session::getViaWidth( lg->getDepth() )/2
|
||||||
|
+ viaLayer->getBottomEnclosure( Layer::EnclosureH );
|
||||||
|
} else {
|
||||||
|
yborder = Session::getViaWidth( lg->getDepth() )/2
|
||||||
|
+ viaLayer->getBottomEnclosure( Layer::EnclosureV );
|
||||||
|
xborder = Session::getViaWidth( lg->getDepth() )/2
|
||||||
|
+ viaLayer->getBottomEnclosure( Layer::EnclosureH );
|
||||||
|
|
||||||
|
if (Session::getRoutingGauge()->isSymbolic()) {
|
||||||
|
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
|
||||||
|
// their extremities. Should modificate all the standard cells layout...
|
||||||
|
// HARDCODED.
|
||||||
|
if (Session::getRoutingGauge()->getName() == "msxlib")
|
||||||
|
yborder -= DbU::fromLambda( 1.0 );
|
||||||
|
else
|
||||||
|
yborder -= DbU::fromLambda( 0.5 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DbU::Unit xMin;
|
DbU::Unit xMin;
|
||||||
DbU::Unit xMax;
|
DbU::Unit xMax;
|
||||||
DbU::Unit yMin;
|
DbU::Unit yMin;
|
||||||
|
@ -211,6 +238,17 @@ namespace Anabatic {
|
||||||
if (vertical) { bb = vertical ->getBoundingBox(); const_cast<AutoContactTerminal*>(this)->setFlags( CntOnVertical ); }
|
if (vertical) { bb = vertical ->getBoundingBox(); const_cast<AutoContactTerminal*>(this)->setFlags( CntOnVertical ); }
|
||||||
|
|
||||||
transformation.applyOn( bb );
|
transformation.applyOn( bb );
|
||||||
|
cdebug_log(145,0) << "Shrink border x:" << DbU::getValueString(xborder)
|
||||||
|
<< " y:" << DbU::getValueString(yborder)
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
// HARDCODED.
|
||||||
|
if ( (Session::getRoutingGauge()->getName() == "sxlib")
|
||||||
|
and (bb.getWidth() == DbU::fromLambda(1.0)) ) {
|
||||||
|
bb.inflate( DbU::fromLambda(0.5), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bb.inflate( -xborder, -yborder );
|
||||||
xMin = bb.getXMin();
|
xMin = bb.getXMin();
|
||||||
yMin = bb.getYMin();
|
yMin = bb.getYMin();
|
||||||
xMax = bb.getXMax();
|
xMax = bb.getXMax();
|
||||||
|
@ -298,6 +336,7 @@ namespace Anabatic {
|
||||||
void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
|
void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
|
||||||
{
|
{
|
||||||
if (_segment == segment) {
|
if (_segment == segment) {
|
||||||
|
_segment->unsetFlags( AutoSegment::SegAxisSet );
|
||||||
_segment = NULL;
|
_segment = NULL;
|
||||||
setFlags( CntInvalidatedCache );
|
setFlags( CntInvalidatedCache );
|
||||||
unsetFlags( CntDrag );
|
unsetFlags( CntDrag );
|
||||||
|
@ -325,7 +364,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
if ( (dynamic_cast<AutoHorizontal*>(_segment) and (getFlags() & CntOnHorizontal))
|
if ( (dynamic_cast<AutoHorizontal*>(_segment) and (getFlags() & CntOnHorizontal))
|
||||||
or (dynamic_cast<AutoVertical*> (_segment) and (getFlags() & CntOnVertical )) ) {
|
or (dynamic_cast<AutoVertical*> (_segment) and (getFlags() & CntOnVertical )) ) {
|
||||||
_segment->setFlags( AutoSegment::SegDrag );
|
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegAxisSet );
|
||||||
setFlags( CntDrag );
|
setFlags( CntDrag );
|
||||||
|
|
||||||
cdebug_log(145,0) << "Drag Contact/Segment set" << endl;
|
cdebug_log(145,0) << "Drag Contact/Segment set" << endl;
|
||||||
|
@ -364,13 +403,13 @@ namespace Anabatic {
|
||||||
_segment = Session::lookup( horizontals[0] );
|
_segment = Session::lookup( horizontals[0] );
|
||||||
if (getFlags() & CntOnHorizontal) {
|
if (getFlags() & CntOnHorizontal) {
|
||||||
setFlags( CntDrag );
|
setFlags( CntDrag );
|
||||||
_segment->setFlags( AutoSegment::SegDrag );
|
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_segment = Session::lookup( verticals[0] );
|
_segment = Session::lookup( verticals[0] );
|
||||||
if (getFlags() & CntOnVertical) {
|
if (getFlags() & CntOnVertical) {
|
||||||
setFlags( CntDrag );
|
setFlags( CntDrag );
|
||||||
_segment->setFlags( AutoSegment::SegDrag );
|
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_segment == NULL) {
|
if (_segment == NULL) {
|
||||||
|
|
|
@ -91,8 +91,11 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* ) const
|
AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* from ) const
|
||||||
{ return NULL; }
|
{
|
||||||
|
if ( (from == _vertical1) or (from == _vertical2) ) return _horizontal1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegment* AutoContactVTee::getSegment ( unsigned int index ) const
|
AutoSegment* AutoContactVTee::getSegment ( unsigned int index ) const
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/DebugSession.h"
|
||||||
|
#include "hurricane/ViaLayer.h"
|
||||||
#include "hurricane/RoutingPad.h"
|
#include "hurricane/RoutingPad.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "anabatic/Configuration.h"
|
#include "anabatic/Configuration.h"
|
||||||
|
@ -35,6 +36,7 @@ namespace Anabatic {
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
using Hurricane::DebugSession;
|
using Hurricane::DebugSession;
|
||||||
|
using Hurricane::ViaLayer;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
|
|
||||||
|
|
||||||
|
@ -330,7 +332,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
|
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
|
||||||
if (sourceSlackened and (doglegs.size() >= 2)) {
|
if (sourceSlackened and (doglegs.size() >= 2)) {
|
||||||
cdebug_log(149,0) << "AutoHorizontal::_slacken(): Source @" << DbU::getValueString(getSourcePosition()) << endl;
|
cdebug_log(149,0) << "Slackened from source @" << DbU::getValueString(getSourcePosition()) << endl;
|
||||||
doglegs[doglegs.size()-2]->setAxis( getSourcePosition() );
|
doglegs[doglegs.size()-2]->setAxis( getSourcePosition() );
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
|
@ -459,8 +461,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoHorizontal::updatePositions ()
|
void AutoHorizontal::updatePositions ()
|
||||||
{
|
{
|
||||||
_sourcePosition = _horizontal->getSourceX() - getExtensionCap();
|
_sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||||
_targetPosition = _horizontal->getTargetX() + getExtensionCap();
|
_targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -480,11 +482,11 @@ namespace Anabatic {
|
||||||
bool AutoHorizontal::checkPositions () const
|
bool AutoHorizontal::checkPositions () const
|
||||||
{
|
{
|
||||||
bool coherency = true;
|
bool coherency = true;
|
||||||
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap();
|
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||||
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap();
|
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||||
|
|
||||||
if ( _sourcePosition != sourcePosition ) {
|
if ( _sourcePosition != sourcePosition ) {
|
||||||
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap()) << endl;
|
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
|
||||||
cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl;
|
cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl;
|
||||||
cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl;
|
cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl;
|
||||||
cerr << Error ( "%s\n Source position incoherency: "
|
cerr << Error ( "%s\n Source position incoherency: "
|
||||||
|
@ -791,8 +793,17 @@ namespace Anabatic {
|
||||||
} while ( gcell and (gcell != end) );
|
} while ( gcell and (gcell != end) );
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() );
|
size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() );
|
||||||
bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
|
bool upLayer = true;
|
||||||
|
|
||||||
|
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||||
|
upLayer = (depth == 0);
|
||||||
|
} else if (Session::getRoutingGauge()->isVH()) {
|
||||||
|
upLayer = (depth < 2);
|
||||||
|
} else {
|
||||||
|
upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
|
||||||
|
}
|
||||||
|
|
||||||
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
|
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
|
||||||
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( depth + ((upLayer)?1:-1) );
|
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( depth + ((upLayer)?1:-1) );
|
||||||
|
|
||||||
|
@ -859,7 +870,7 @@ namespace Anabatic {
|
||||||
updateNativeConstraints();
|
updateNativeConstraints();
|
||||||
segment2->updateNativeConstraints();
|
segment2->updateNativeConstraints();
|
||||||
|
|
||||||
if (autoTarget->canDrag()) {
|
if (autoTarget->canDrag() and not autoSource->canDrag()) {
|
||||||
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
|
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
|
||||||
segment1->mergeUserConstraints( dragConstraints );
|
segment1->mergeUserConstraints( dragConstraints );
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
#include "hurricane/DataBase.h"
|
#include "hurricane/DataBase.h"
|
||||||
#include "hurricane/Technology.h"
|
#include "hurricane/Technology.h"
|
||||||
|
#include "hurricane/ViaLayer.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
|
@ -370,19 +371,76 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "Anabatic::AutoSegment::CompareBySourceU".
|
||||||
|
|
||||||
|
|
||||||
|
bool AutoSegment::CompareBySourceU::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const
|
||||||
|
{
|
||||||
|
DbU::Unit deltaUnit = lhs->getSourceU() - rhs->getSourceU();
|
||||||
|
if (deltaUnit < 0) return true; // Smallest source first.
|
||||||
|
if (deltaUnit > 0) return false;
|
||||||
|
|
||||||
|
return lhs->getId() < rhs->getId(); // Smallest Id first.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "Anabatic::AutoSegment".
|
// Class : "Anabatic::AutoSegment".
|
||||||
|
|
||||||
|
|
||||||
size_t AutoSegment::_allocateds = 0;
|
size_t AutoSegment::_allocateds = 0;
|
||||||
size_t AutoSegment::_globalsCount = 0;
|
size_t AutoSegment::_globalsCount = 0;
|
||||||
bool AutoSegment::_analogMode = false;
|
bool AutoSegment::_analogMode = false;
|
||||||
|
bool AutoSegment::_initialized = false;
|
||||||
|
vector< array<DbU::Unit*,3> > AutoSegment::_extensionCaps;
|
||||||
|
|
||||||
|
|
||||||
void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; }
|
void AutoSegment::setAnalogMode ( bool state ) { _analogMode = state; }
|
||||||
bool AutoSegment::getAnalogMode () { return _analogMode; }
|
bool AutoSegment::getAnalogMode () { return _analogMode; }
|
||||||
|
|
||||||
|
|
||||||
|
void AutoSegment::_initialize ()
|
||||||
|
{
|
||||||
|
cerr << "AutoSegment::_initialize()" << endl;
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
|
||||||
|
DbU::Unit* viaToTopCap = new DbU::Unit ( 0 );
|
||||||
|
DbU::Unit* viaToBottomCap = new DbU::Unit ( 0 );
|
||||||
|
DbU::Unit* viaToSameCap = new DbU::Unit ( 0 );
|
||||||
|
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
|
||||||
|
uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ;
|
||||||
|
|
||||||
|
cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||||
|
<< " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
|
||||||
|
|
||||||
|
*viaToSameCap = Session::getWireWidth(depth)/2;
|
||||||
|
|
||||||
|
// Bottom metal of the VIA going *up*.
|
||||||
|
const Layer* viaLayer = dynamic_cast<const ViaLayer*>( Session::getContactLayer(depth) );
|
||||||
|
if (viaLayer)
|
||||||
|
*viaToTopCap = Session::getViaWidth(depth)/2 + viaLayer->getBottomEnclosure( flags );
|
||||||
|
|
||||||
|
// Top metal of the VIA going *down*.
|
||||||
|
if (depth > 0) {
|
||||||
|
viaLayer = dynamic_cast<const ViaLayer*>( Session::getContactLayer(depth-1) );
|
||||||
|
if (viaLayer)
|
||||||
|
*viaToBottomCap = Session::getViaWidth(depth-1)/2 + viaLayer->getTopEnclosure( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
||||||
|
cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
|
||||||
|
if (depth > 0)
|
||||||
|
cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl;
|
||||||
|
cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
|
||||||
|
cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
|
||||||
|
|
||||||
|
_extensionCaps.push_back( std::array<DbU::Unit*,3>( { viaToTopCap, viaToBottomCap, viaToSameCap } ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegment::AutoSegment ( Segment* segment )
|
AutoSegment::AutoSegment ( Segment* segment )
|
||||||
: _id (segment->getId())
|
: _id (segment->getId())
|
||||||
, _gcell (NULL)
|
, _gcell (NULL)
|
||||||
|
@ -398,14 +456,16 @@ namespace Anabatic {
|
||||||
, _parent (NULL)
|
, _parent (NULL)
|
||||||
, _observers ()
|
, _observers ()
|
||||||
{
|
{
|
||||||
|
if (not _initialized) _initialize();
|
||||||
|
|
||||||
_allocateds++;
|
_allocateds++;
|
||||||
|
|
||||||
if (dynamic_cast<Horizontal*>(segment)) setFlags( SegHorizontal );
|
if (dynamic_cast<Horizontal*>(segment)) setFlags( SegHorizontal );
|
||||||
|
|
||||||
_globalsCount += isGlobal() ? 1 : 0;
|
_globalsCount += isGlobal() ? 1 : 0;
|
||||||
|
|
||||||
AutoContact* source = Session::lookup(dynamic_cast<Contact*>(segment->getSource()));
|
AutoContact* source = Session::lookup(dynamic_cast<Contact*>(segment->getSource()));
|
||||||
AutoContact* target = Session::lookup(dynamic_cast<Contact*>(segment->getTarget()));
|
AutoContact* target = Session::lookup(dynamic_cast<Contact*>(segment->getTarget()));
|
||||||
|
|
||||||
if (source->isTerminal()) setFlags( SegSourceTerminal );
|
if (source->isTerminal()) setFlags( SegSourceTerminal );
|
||||||
if (target->isTerminal()) setFlags( SegTargetTerminal );
|
if (target->isTerminal()) setFlags( SegTargetTerminal );
|
||||||
|
@ -544,8 +604,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
cdebug_tabw(149,1);
|
cdebug_tabw(149,1);
|
||||||
|
|
||||||
updateOrient ();
|
updateOrient();
|
||||||
updatePositions();
|
|
||||||
|
|
||||||
uint64_t oldSpinFlags = _flags & SegDepthSpin;
|
uint64_t oldSpinFlags = _flags & SegDepthSpin;
|
||||||
|
|
||||||
|
@ -575,6 +634,8 @@ namespace Anabatic {
|
||||||
incReduceds();
|
incReduceds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePositions();
|
||||||
|
|
||||||
unsigned int observerFlags = Revalidate;
|
unsigned int observerFlags = Revalidate;
|
||||||
if ( (_flags & SegCreated) or (oldSpinFlags != (_flags & SegDepthSpin)) )
|
if ( (_flags & SegCreated) or (oldSpinFlags != (_flags & SegDepthSpin)) )
|
||||||
observerFlags |= RevalidatePPitch;
|
observerFlags |= RevalidatePPitch;
|
||||||
|
@ -616,15 +677,29 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit AutoSegment::getExtensionCap () const
|
DbU::Unit AutoSegment::getExtensionCap ( Flags flags ) const
|
||||||
{
|
{
|
||||||
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
|
size_t depth = Session::getLayerDepth( getLayer() );
|
||||||
if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() );
|
DbU::Unit cap = 0;
|
||||||
return getWidth() / 2;
|
|
||||||
#if NEW_WAY
|
if (flags & Flags::Source) {
|
||||||
if (getWidth() <= mWidth) return mWidth/2 + getPitch()/2;
|
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||||
return getWidth()/2 + getPitch()/2;
|
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||||
#endif
|
else cap = getViaToSameCap (depth);
|
||||||
|
cdebug_log(159,0) << "getExtensionCap(): flags:" << getFlags()
|
||||||
|
<< " VIA cap:" << DbU::getValueString(cap)
|
||||||
|
<< " " << (getFlags() & SegSourceBottom)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & Flags::Target) {
|
||||||
|
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||||
|
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||||
|
else cap = getViaToSameCap (depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap < getWidth()/2) cap = getWidth()/2;
|
||||||
|
return cap + getLayer()->getMinimalSpacing()/2;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -702,6 +777,22 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AutoSegment::getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const
|
||||||
|
{
|
||||||
|
cdebug_log(145,0) << "AutoSegment::getEndAxes() - " << this << endl;
|
||||||
|
|
||||||
|
sourceAxis = getSourceU();
|
||||||
|
targetAxis = getTargetU();
|
||||||
|
|
||||||
|
if (not isNotAligned()) {
|
||||||
|
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||||
|
sourceAxis = std::min( sourceAxis, aligned->getSourceU() );
|
||||||
|
targetAxis = std::min( targetAxis, aligned->getTargetU() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AutoSegments AutoSegment::getOnSourceContact ( Flags direction )
|
AutoSegments AutoSegment::getOnSourceContact ( Flags direction )
|
||||||
{
|
{
|
||||||
return AutoSegments_OnContact
|
return AutoSegments_OnContact
|
||||||
|
@ -1029,6 +1120,43 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "Constraints: [" << DbU::getValueString(constraintMin)
|
cdebug_log(145,0) << "Constraints: [" << DbU::getValueString(constraintMin)
|
||||||
<< " " << DbU::getValueString(constraintMax) << "]" << endl;
|
<< " " << DbU::getValueString(constraintMax) << "]" << endl;
|
||||||
|
|
||||||
|
AutoContact* source = getAutoSource();
|
||||||
|
AutoContact* target = getAutoTarget();
|
||||||
|
|
||||||
|
if (isLocal() and source->isTurn() and target->isTurn() and not isUserDefined()) {
|
||||||
|
AutoSegment* sourcePerpand = source->getPerpandicular(this);
|
||||||
|
AutoSegment* targetPerpand = target->getPerpandicular(this);
|
||||||
|
|
||||||
|
sourcePerpand->updateOrient();
|
||||||
|
targetPerpand->updateOrient();
|
||||||
|
|
||||||
|
if (not ( (sourcePerpand->getAutoSource() == source)
|
||||||
|
xor (targetPerpand->getAutoSource() == target) ) ) {
|
||||||
|
// This is a U-Turn.
|
||||||
|
DbU::Unit optimal = 0;
|
||||||
|
|
||||||
|
if (sourcePerpand->getAutoSource() == source) {
|
||||||
|
optimal = std::min( sourcePerpand->getTargetU(), targetPerpand->getTargetU() );
|
||||||
|
optimal = std::min( optimal, constraintMax );
|
||||||
|
} else {
|
||||||
|
optimal = std::max( sourcePerpand->getSourceU(), targetPerpand->getSourceU() );
|
||||||
|
optimal = std::max( optimal, constraintMin );
|
||||||
|
}
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "| Source perpandicular: " << sourcePerpand << endl;
|
||||||
|
cdebug_log(145,0) << "| Target perpandicular: " << targetPerpand << endl;
|
||||||
|
cdebug_log(145,0) << "Applying constraint (U-Turn) on: " << this << endl;
|
||||||
|
cdebug_log(145,0) << "optimal: " << DbU::getValueString(optimal) << endl;
|
||||||
|
|
||||||
|
setOptimalMin( optimal );
|
||||||
|
setOptimalMax( optimal );
|
||||||
|
processeds.insert( this );
|
||||||
|
|
||||||
|
cdebug_tabw(145,-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isUserDefined()) {
|
if (isUserDefined()) {
|
||||||
optimalMin = optimalMax = getAxis();
|
optimalMin = optimalMax = getAxis();
|
||||||
aligneds.push_back( this );
|
aligneds.push_back( this );
|
||||||
|
@ -1368,7 +1496,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
bool AutoSegment::canReduce () const
|
bool AutoSegment::canReduce () const
|
||||||
{
|
{
|
||||||
if (isGlobal()) return false;
|
if (isGlobal() or isDrag()) return false;
|
||||||
if (not isSpinTopOrBottom()) return false;
|
if (not isSpinTopOrBottom()) return false;
|
||||||
if (_reduceds) return false;
|
if (_reduceds) return false;
|
||||||
|
|
||||||
|
@ -1442,8 +1570,9 @@ namespace Anabatic {
|
||||||
_changeDepth( depth, flags & ~Flags::Propagate );
|
_changeDepth( depth, flags & ~Flags::Propagate );
|
||||||
|
|
||||||
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
||||||
forEach ( AutoSegment*, isegment, getAligneds(Flags::NoCheckLayer) ) {
|
cdebug_log(149,0) << "Propagate to aligneds." << endl;
|
||||||
(*isegment)->_changeDepth( depth, flags & ~Flags::Propagate );
|
for ( AutoSegment* segment : getAligneds(Flags::NoCheckLayer) ) {
|
||||||
|
segment->_changeDepth( depth, flags & ~Flags::Propagate );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1525,8 +1654,8 @@ namespace Anabatic {
|
||||||
success = success or _slacken( flags );
|
success = success or _slacken( flags );
|
||||||
|
|
||||||
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
if ((flags & Flags::Propagate) and not isNotAligned()) {
|
||||||
forEach ( AutoSegment*, isegment, getAligneds() ) {
|
for ( AutoSegment* segment : getAligneds() ) {
|
||||||
success = success or (*isegment)->_slacken( flags );
|
success = success or segment->_slacken( flags );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2135,6 +2264,7 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
string state;
|
string state;
|
||||||
state += isFixed () ?" F":" -";
|
state += isFixed () ?" F":" -";
|
||||||
|
state += isFixedAxis () ? "X": "-";
|
||||||
state += isUnsetAxis () ? "u": "-";
|
state += isUnsetAxis () ? "u": "-";
|
||||||
state += isStrap () ? "S": "-";
|
state += isStrap () ? "S": "-";
|
||||||
state += isCanonical () ? "C": "-";
|
state += isCanonical () ? "C": "-";
|
||||||
|
@ -2175,6 +2305,7 @@ namespace Anabatic {
|
||||||
Record* AutoSegment::_getRecord () const
|
Record* AutoSegment::_getRecord () const
|
||||||
{
|
{
|
||||||
Record* record = base()->_getRecord ();
|
Record* record = base()->_getRecord ();
|
||||||
|
record->add ( getSlot ( "_extensionCaps" , &_extensionCaps ) );
|
||||||
record->add ( getSlot ( "_gcell" , _gcell ) );
|
record->add ( getSlot ( "_gcell" , _gcell ) );
|
||||||
record->add ( getSlot ( "_id" , &_id ) );
|
record->add ( getSlot ( "_id" , &_id ) );
|
||||||
record->add ( getSlot ( "_flags" , &_flags ) );
|
record->add ( getSlot ( "_flags" , &_flags ) );
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
|
#include "hurricane/ViaLayer.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "anabatic/Configuration.h"
|
#include "anabatic/Configuration.h"
|
||||||
|
@ -30,6 +31,7 @@ namespace Anabatic {
|
||||||
using std::max;
|
using std::max;
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
|
using Hurricane::ViaLayer;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -258,9 +260,11 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(149,1) << "AutoVertical::_slacken() " << this << endl;
|
cdebug_log(149,1) << "AutoVertical::_slacken() " << this << endl;
|
||||||
|
|
||||||
if ( not isStrongTerminal()
|
if (not isDrag()) {
|
||||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
|
if ( not isStrongTerminal()
|
||||||
{ cdebug_tabw(149,-1); return false; }
|
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
|
||||||
|
{ cdebug_tabw(149,-1); return false; }
|
||||||
|
}
|
||||||
|
|
||||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||||
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
|
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
|
||||||
|
@ -395,8 +399,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoVertical::updatePositions ()
|
void AutoVertical::updatePositions ()
|
||||||
{
|
{
|
||||||
_sourcePosition = _vertical->getSourceY() - getExtensionCap();
|
_sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||||
_targetPosition = _vertical->getTargetY() + getExtensionCap();
|
_targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -416,8 +420,8 @@ namespace Anabatic {
|
||||||
bool AutoVertical::checkPositions () const
|
bool AutoVertical::checkPositions () const
|
||||||
{
|
{
|
||||||
bool coherency = true;
|
bool coherency = true;
|
||||||
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap();
|
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||||
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap();
|
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||||
|
|
||||||
if ( _sourcePosition != sourcePosition ) {
|
if ( _sourcePosition != sourcePosition ) {
|
||||||
cerr << Error ( "%s\n Source position incoherency: "
|
cerr << Error ( "%s\n Source position incoherency: "
|
||||||
|
@ -697,8 +701,17 @@ namespace Anabatic {
|
||||||
} while ( gcell and (gcell != end) );
|
} while ( gcell and (gcell != end) );
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() );
|
size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() );
|
||||||
bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
|
bool upLayer = true;
|
||||||
|
|
||||||
|
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||||
|
upLayer = (depth == 0);
|
||||||
|
} else if (Session::getRoutingGauge()->isVH()) {
|
||||||
|
upLayer = (depth < 2);
|
||||||
|
} else {
|
||||||
|
upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
|
||||||
|
}
|
||||||
|
|
||||||
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
|
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
|
||||||
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) );
|
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) );
|
||||||
|
|
||||||
|
@ -767,7 +780,7 @@ namespace Anabatic {
|
||||||
updateNativeConstraints();
|
updateNativeConstraints();
|
||||||
segment2->updateNativeConstraints();
|
segment2->updateNativeConstraints();
|
||||||
|
|
||||||
if (autoTarget->canDrag()) {
|
if (autoTarget->canDrag() and not autoSource->canDrag()) {
|
||||||
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
|
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
|
||||||
segment1->mergeUserConstraints( dragConstraints );
|
segment1->mergeUserConstraints( dragConstraints );
|
||||||
|
|
||||||
|
|
|
@ -398,8 +398,14 @@ namespace Anabatic {
|
||||||
bool Configuration::selectRpComponent ( RoutingPad* rp ) const
|
bool Configuration::selectRpComponent ( RoutingPad* rp ) const
|
||||||
{
|
{
|
||||||
cdebug_log(112,1) << "selectRpComponent(): " << rp << endl;
|
cdebug_log(112,1) << "selectRpComponent(): " << rp << endl;
|
||||||
|
|
||||||
|
if (rp->isAtTopLevel()) {
|
||||||
|
cdebug_log(112,0) << "> RP is at top level, must not change it." << endl;
|
||||||
|
cdebug_tabw(112,-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Box ab = rp->getCell()->getBoundingBox();
|
Box ab = rp->getCell()->getAbutmentBox();
|
||||||
const Layer* metal1 = getLayerGauge( 0 )->getLayer();
|
const Layer* metal1 = getLayerGauge( 0 )->getLayer();
|
||||||
RoutingLayerGauge* gauge = getLayerGauge( 1 );
|
RoutingLayerGauge* gauge = getLayerGauge( 1 );
|
||||||
Occurrence occurrence = rp->getPlugOccurrence();
|
Occurrence occurrence = rp->getPlugOccurrence();
|
||||||
|
@ -407,8 +413,8 @@ namespace Anabatic {
|
||||||
Net* masterNet = plug->getMasterNet();
|
Net* masterNet = plug->getMasterNet();
|
||||||
Path path = Path( occurrence.getPath(), plug->getInstance() );
|
Path path = Path( occurrence.getPath(), plug->getInstance() );
|
||||||
Transformation transformation = path.getTransformation();
|
Transformation transformation = path.getTransformation();
|
||||||
|
|
||||||
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
|
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
|
||||||
|
|
||||||
if (current and (current->getLayer()->getMask() != metal1->getMask())) {
|
if (current and (current->getLayer()->getMask() != metal1->getMask())) {
|
||||||
cdebug_log(112,0) << "> using default non-metal1 segment." << endl;
|
cdebug_log(112,0) << "> using default non-metal1 segment." << endl;
|
||||||
cdebug_tabw(112,-1);
|
cdebug_tabw(112,-1);
|
||||||
|
@ -439,6 +445,11 @@ namespace Anabatic {
|
||||||
, Constant::Nearest );
|
, Constant::Nearest );
|
||||||
minPos = bb.getXMin();
|
minPos = bb.getXMin();
|
||||||
maxPos = bb.getXMax();
|
maxPos = bb.getXMax();
|
||||||
|
|
||||||
|
cdebug_log(112,0) << "Vertical gauge: " << gauge << endl;
|
||||||
|
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl;
|
||||||
|
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl;
|
||||||
|
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl;
|
||||||
} else {
|
} else {
|
||||||
trackPos = gauge->getTrackPosition( ab.getYMin()
|
trackPos = gauge->getTrackPosition( ab.getYMin()
|
||||||
, ab.getYMax()
|
, ab.getYMax()
|
||||||
|
@ -446,6 +457,11 @@ namespace Anabatic {
|
||||||
, Constant::Nearest );
|
, Constant::Nearest );
|
||||||
minPos = bb.getYMin();
|
minPos = bb.getYMin();
|
||||||
maxPos = bb.getYMax();
|
maxPos = bb.getYMax();
|
||||||
|
|
||||||
|
cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl;
|
||||||
|
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl;
|
||||||
|
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl;
|
||||||
|
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
|
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
|
||||||
|
|
|
@ -1476,10 +1476,8 @@ namespace Anabatic {
|
||||||
if (_densities[i] >= 1.0) _flags |= Flags::Saturated;
|
if (_densities[i] >= 1.0) _flags |= Flags::Saturated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccapacity)
|
if (ccapacity) _cDensity = ( (float)_contacts.size() ) / ccapacity;
|
||||||
_cDensity = ( (float)_contacts.size() ) / ccapacity;
|
else _cDensity = 0;
|
||||||
else
|
|
||||||
_cDensity = 0;
|
|
||||||
_flags.reset( Flags::Invalidated );
|
_flags.reset( Flags::Invalidated );
|
||||||
|
|
||||||
checkDensity();
|
checkDensity();
|
||||||
|
|
|
@ -311,6 +311,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
bool NetBuilderVH::_do_xG_xM1_xM3 ()
|
bool NetBuilderVH::_do_xG_xM1_xM3 ()
|
||||||
{
|
{
|
||||||
|
// Implicit hypothesis : we have at least two globals and at least one terminal.
|
||||||
|
|
||||||
cdebug_log(145,1) << getTypeName()
|
cdebug_log(145,1) << getTypeName()
|
||||||
<< "::_do_xG_" << (int)getConnexity().fields.M1
|
<< "::_do_xG_" << (int)getConnexity().fields.M1
|
||||||
<< "M1_" << (int)getConnexity().fields.M3
|
<< "M1_" << (int)getConnexity().fields.M3
|
||||||
|
@ -352,8 +354,12 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (north() or east()) {
|
if (north() or east()) {
|
||||||
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall );
|
if (getRoutingPads().size() > 1) {
|
||||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall );
|
||||||
|
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||||
|
} else {
|
||||||
|
rightContact = leftContact;
|
||||||
|
}
|
||||||
|
|
||||||
if (north() and east()) {
|
if (north() and east()) {
|
||||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
|
||||||
|
@ -517,6 +523,7 @@ namespace Anabatic {
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string NetBuilderVH::getTypeName () const
|
string NetBuilderVH::getTypeName () const
|
||||||
{ return "NetBuilderVH"; }
|
{ return "NetBuilderVH"; }
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,10 @@ namespace {
|
||||||
cdebug_log(145,0) << "slave component: " << component << endl;
|
cdebug_log(145,0) << "slave component: " << component << endl;
|
||||||
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
||||||
if (sourceContact) {
|
if (sourceContact) {
|
||||||
|
Box constraintBox = sourceContact->getConstraintBox();
|
||||||
|
|
||||||
cdebug_log(145,0) << "Start slave: " << sourceContact << endl;
|
cdebug_log(145,0) << "Start slave: " << sourceContact << endl;
|
||||||
|
cdebug_log(145,0) << "Constraint: " << constraintBox << endl;
|
||||||
|
|
||||||
set<AutoSegment*> verticalSegments;
|
set<AutoSegment*> verticalSegments;
|
||||||
set<AutoSegment*> horizontalSegments;
|
set<AutoSegment*> horizontalSegments;
|
||||||
|
@ -87,9 +90,6 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box constraintBox = sourceContact->getConstraintBox();
|
|
||||||
cdebug_log(145,0) << "Contraint: " << constraintBox << endl;
|
|
||||||
|
|
||||||
// Propagate constraint through horizontally aligned segments.
|
// Propagate constraint through horizontally aligned segments.
|
||||||
cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl;
|
cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
|
@ -47,6 +48,7 @@ namespace Anabatic {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using Hurricane::tab;
|
using Hurricane::tab;
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Warning;
|
||||||
using Hurricane::ForEachIterator;
|
using Hurricane::ForEachIterator;
|
||||||
using Hurricane::UpdateSession;
|
using Hurricane::UpdateSession;
|
||||||
using Hurricane::Horizontal;
|
using Hurricane::Horizontal;
|
||||||
|
@ -158,6 +160,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
canonical->setFlags( AutoSegment::SegCanonical );
|
canonical->setFlags( AutoSegment::SegCanonical );
|
||||||
cdebug_log(145,0) << "Canonical: " << canonical << endl;
|
cdebug_log(145,0) << "Canonical: " << canonical << endl;
|
||||||
|
Interval userConstraints = canonical->getUserConstraints();
|
||||||
|
|
||||||
for ( size_t j=0 ; j<aligneds.size() ; j++ ) {
|
for ( size_t j=0 ; j<aligneds.size() ; j++ ) {
|
||||||
if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal );
|
if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal );
|
||||||
|
@ -171,10 +174,23 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
aligneds[j]->unsetFlags( AutoSegment::SegCanonical );
|
aligneds[j]->unsetFlags( AutoSegment::SegCanonical );
|
||||||
cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl;
|
cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl;
|
||||||
|
|
||||||
|
userConstraints.intersection( aligneds[j]->getUserConstraints() );
|
||||||
}
|
}
|
||||||
if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned );
|
if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned );
|
||||||
|
|
||||||
|
if (not getRoutingGauge()->isSymbolic()
|
||||||
|
and (userConstraints.getSize() < Session::getPitch(1)*2) ) {
|
||||||
|
cerr << Warning( "Session::_canonize(): On %s\n"
|
||||||
|
" Combined user constraints are too tight [%s : %s]."
|
||||||
|
, getString(canonical).c_str()
|
||||||
|
, DbU::getValueString(userConstraints.getVMin()).c_str()
|
||||||
|
, DbU::getValueString(userConstraints.getVMax()).c_str()
|
||||||
|
) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
cdebug_log(149,0) << "Align on canonical:" << canonical << endl;
|
cdebug_log(149,0) << "Align on canonical:" << canonical << endl;
|
||||||
|
cdebug_log(145,0) << "Combined user constraints: " << userConstraints << endl;
|
||||||
|
|
||||||
//canonical->setAxis( canonical->getAxis(), Flags::Realignate );
|
//canonical->setAxis( canonical->getAxis(), Flags::Realignate );
|
||||||
if (canonical->isUnsetAxis() and not canonical->isFixed())
|
if (canonical->isUnsetAxis() and not canonical->isFixed())
|
||||||
|
@ -194,21 +210,19 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
||||||
|
|
||||||
set<Net*>::iterator inet = _netInvalidateds.begin();
|
for ( Net* net : _netInvalidateds ) {
|
||||||
|
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
|
||||||
for ( ; inet != _netInvalidateds.end() ; inet++ ) {
|
_anabatic->updateNetTopology ( net );
|
||||||
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << *inet << endl;
|
_anabatic->computeNetConstraints( net );
|
||||||
_anabatic->updateNetTopology ( *inet );
|
_anabatic->_computeNetOptimals ( net );
|
||||||
_anabatic->computeNetConstraints( *inet );
|
_anabatic->_computeNetTerminals ( net );
|
||||||
_anabatic->_computeNetOptimals ( *inet );
|
|
||||||
_anabatic->_computeNetTerminals ( *inet );
|
|
||||||
}
|
}
|
||||||
_canonize ();
|
_canonize ();
|
||||||
|
|
||||||
for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) {
|
for ( AutoSegment* segment : _segmentInvalidateds ) {
|
||||||
if (_segmentInvalidateds[i]->isCanonical()) {
|
if (segment->isCanonical()) {
|
||||||
if (_segmentInvalidateds[i]->isUnsetAxis()) _segmentInvalidateds[i]->toOptimalAxis();
|
if (segment->isUnsetAxis()) segment->toOptimalAxis();
|
||||||
else _segmentInvalidateds[i]->toConstraintAxis();
|
else segment->toConstraintAxis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,646 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
//
|
||||||
|
// This file is part of the Coriolis Software.
|
||||||
|
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||||
|
//
|
||||||
|
// +-----------------------------------------------------------------+
|
||||||
|
// | C O R I O L I S |
|
||||||
|
// | A n a b a t i c - Routing Toolbox |
|
||||||
|
// | |
|
||||||
|
// | Author : Jean-Paul CHAPUT |
|
||||||
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||||
|
// | =============================================================== |
|
||||||
|
// | C++ Header : "./anabatic/AutoSegment.h" |
|
||||||
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||||
|
#define ANABATIC_AUTOSEGMENT_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <iostream>
|
||||||
|
#include <functional>
|
||||||
|
#include "hurricane/Interval.h"
|
||||||
|
#include "hurricane/Segment.h"
|
||||||
|
#include "hurricane/Components.h"
|
||||||
|
#include "hurricane/Contact.h"
|
||||||
|
namespace Hurricane {
|
||||||
|
class Layer;
|
||||||
|
class Horizontal;
|
||||||
|
class Vertical;
|
||||||
|
class Cell;
|
||||||
|
}
|
||||||
|
#include "crlcore/RoutingGauge.h"
|
||||||
|
#include "anabatic/Constants.h"
|
||||||
|
#include "anabatic/GCell.h"
|
||||||
|
#include "anabatic/AutoSegments.h"
|
||||||
|
#include "anabatic/Session.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Anabatic {
|
||||||
|
|
||||||
|
using std::array;
|
||||||
|
using std::set;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::binary_function;
|
||||||
|
using Hurricane::StaticObservable;
|
||||||
|
using Hurricane::BaseObserver;
|
||||||
|
using Hurricane::tab;
|
||||||
|
using Hurricane::Interval;
|
||||||
|
using Hurricane::Layer;
|
||||||
|
using Hurricane::Components;
|
||||||
|
using Hurricane::Horizontal;
|
||||||
|
using Hurricane::Vertical;
|
||||||
|
using Hurricane::Cell;
|
||||||
|
using CRL::RoutingGauge;
|
||||||
|
|
||||||
|
class AutoHorizontal;
|
||||||
|
class AutoVertical;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "AutoSegment".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AutoSegment {
|
||||||
|
friend class AutoHorizontal;
|
||||||
|
friend class AutoVertical;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const uint64_t SegNoFlags = 0L;
|
||||||
|
static const uint64_t SegHorizontal = (1L<< 0);
|
||||||
|
static const uint64_t SegFixed = (1L<< 1);
|
||||||
|
static const uint64_t SegFixedAxis = (1L<< 2);
|
||||||
|
static const uint64_t SegGlobal = (1L<< 3);
|
||||||
|
static const uint64_t SegWeakGlobal = (1L<< 4);
|
||||||
|
static const uint64_t SegLongLocal = (1L<< 5);
|
||||||
|
static const uint64_t SegCanonical = (1L<< 6);
|
||||||
|
static const uint64_t SegBipoint = (1L<< 7);
|
||||||
|
static const uint64_t SegDogleg = (1L<< 8);
|
||||||
|
static const uint64_t SegStrap = (1L<< 9);
|
||||||
|
static const uint64_t SegSourceTop = (1L<<10);
|
||||||
|
static const uint64_t SegSourceBottom = (1L<<11);
|
||||||
|
static const uint64_t SegTargetTop = (1L<<12);
|
||||||
|
static const uint64_t SegTargetBottom = (1L<<13);
|
||||||
|
static const uint64_t SegIsReduced = (1L<<14);
|
||||||
|
static const uint64_t SegDrag = (1L<<15);
|
||||||
|
static const uint64_t SegLayerChange = (1L<<16);
|
||||||
|
static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal.
|
||||||
|
static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal.
|
||||||
|
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
|
||||||
|
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd.
|
||||||
|
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd.
|
||||||
|
static const uint64_t SegNotSourceAligned = (1L<<21);
|
||||||
|
static const uint64_t SegNotTargetAligned = (1L<<22);
|
||||||
|
static const uint64_t SegUnbound = (1L<<23);
|
||||||
|
static const uint64_t SegHalfSlackened = (1L<<24);
|
||||||
|
static const uint64_t SegSlackened = (1L<<25);
|
||||||
|
static const uint64_t SegAxisSet = (1L<<26);
|
||||||
|
static const uint64_t SegInvalidated = (1L<<27);
|
||||||
|
static const uint64_t SegInvalidatedSource = (1L<<28);
|
||||||
|
static const uint64_t SegInvalidatedTarget = (1L<<29);
|
||||||
|
static const uint64_t SegInvalidatedLayer = (1L<<30);
|
||||||
|
static const uint64_t SegCreated = (1L<<31);
|
||||||
|
static const uint64_t SegUserDefined = (1L<<32);
|
||||||
|
static const uint64_t SegAnalog = (1L<<33);
|
||||||
|
static const uint64_t SegWide = (1L<<34);
|
||||||
|
// Masks.
|
||||||
|
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||||
|
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||||
|
static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop;
|
||||||
|
static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom;
|
||||||
|
static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom;
|
||||||
|
|
||||||
|
public:
|
||||||
|
class Observable : public StaticObservable<1> {
|
||||||
|
public:
|
||||||
|
enum Indexes { TrackSegment = 0
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
inline Observable ();
|
||||||
|
private:
|
||||||
|
Observable ( const StaticObservable& );
|
||||||
|
Observable& operator= ( const StaticObservable& );
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
enum ObserverFlag { Create = (1 << 0)
|
||||||
|
, Destroy = (1 << 1)
|
||||||
|
, Invalidate = (1 << 2)
|
||||||
|
, Revalidate = (1 << 3)
|
||||||
|
, RevalidatePPitch = (1 << 4)
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
|
||||||
|
public:
|
||||||
|
static void setAnalogMode ( bool );
|
||||||
|
static bool getAnalogMode ();
|
||||||
|
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||||
|
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||||
|
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||||
|
static AutoSegment* create ( AutoContact* source
|
||||||
|
, AutoContact* target
|
||||||
|
, Segment* hurricaneSegment
|
||||||
|
);
|
||||||
|
static AutoSegment* create ( AutoContact* source
|
||||||
|
, AutoContact* target
|
||||||
|
, Flags dir
|
||||||
|
, size_t depth=RoutingGauge::nlayerdepth
|
||||||
|
);
|
||||||
|
void destroy ();
|
||||||
|
// Wrapped Segment Functions.
|
||||||
|
virtual Segment* base () const = 0;
|
||||||
|
virtual Segment* base () = 0;
|
||||||
|
virtual Horizontal* getHorizontal () { return NULL; };
|
||||||
|
virtual Vertical* getVertical () { return NULL; };
|
||||||
|
inline Cell* getCell () const;
|
||||||
|
inline Net* getNet () const;
|
||||||
|
inline const Layer* getLayer () const;
|
||||||
|
inline Box getBoundingBox () const;
|
||||||
|
inline Hook* getSourceHook ();
|
||||||
|
inline Hook* getTargetHook ();
|
||||||
|
inline Contact* getSource () const;
|
||||||
|
inline Contact* getTarget () const;
|
||||||
|
inline Component* getOppositeAnchor ( Component* ) const;
|
||||||
|
inline Components getAnchors () const;
|
||||||
|
virtual DbU::Unit getX () const;
|
||||||
|
virtual DbU::Unit getY () const;
|
||||||
|
inline DbU::Unit getWidth () const;
|
||||||
|
inline DbU::Unit getContactWidth () const;
|
||||||
|
inline DbU::Unit getLength () const;
|
||||||
|
inline DbU::Unit getSourcePosition () const;
|
||||||
|
inline DbU::Unit getTargetPosition () const;
|
||||||
|
inline DbU::Unit getSourceX () const;
|
||||||
|
inline DbU::Unit getSourceY () const;
|
||||||
|
inline DbU::Unit getTargetX () const;
|
||||||
|
inline DbU::Unit getTargetY () const;
|
||||||
|
inline void invert ();
|
||||||
|
inline void setLayer ( const Layer* );
|
||||||
|
// Predicates.
|
||||||
|
inline bool isHorizontal () const;
|
||||||
|
inline bool isVertical () const;
|
||||||
|
inline bool isGlobal () const;
|
||||||
|
inline bool isWeakGlobal () const;
|
||||||
|
inline bool isLongLocal () const;
|
||||||
|
inline bool isLocal () const;
|
||||||
|
inline bool isFixed () const;
|
||||||
|
inline bool isFixedAxis () const;
|
||||||
|
inline bool isBipoint () const;
|
||||||
|
inline bool isWeakTerminal () const;
|
||||||
|
inline bool isWeakTerminal1 () const;
|
||||||
|
inline bool isWeakTerminal2 () const;
|
||||||
|
inline bool isTerminal () const;
|
||||||
|
inline bool isDrag () const;
|
||||||
|
inline bool isNotSourceAligned () const;
|
||||||
|
inline bool isNotTargetAligned () const;
|
||||||
|
inline bool isNotAligned () const;
|
||||||
|
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
|
||||||
|
inline bool isSourceTerminal () const;
|
||||||
|
inline bool isTargetTerminal () const;
|
||||||
|
inline bool isLayerChange () const;
|
||||||
|
inline bool isSpinTop () const;
|
||||||
|
inline bool isSpinBottom () const;
|
||||||
|
inline bool isSpinTopOrBottom () const;
|
||||||
|
inline bool isReduced () const;
|
||||||
|
inline bool isStrap () const;
|
||||||
|
inline bool isDogleg () const;
|
||||||
|
inline bool isUnbound () const;
|
||||||
|
inline bool isInvalidated () const;
|
||||||
|
inline bool isInvalidatedLayer () const;
|
||||||
|
inline bool isCreated () const;
|
||||||
|
inline bool isCanonical () const;
|
||||||
|
inline bool isUnsetAxis () const;
|
||||||
|
inline bool isSlackened () const;
|
||||||
|
inline bool isUserDefined () const;
|
||||||
|
bool isReduceCandidate () const;
|
||||||
|
bool isUTurn () const;
|
||||||
|
inline bool isAnalog () const;
|
||||||
|
inline bool isWide () const;
|
||||||
|
virtual bool _canSlacken () const = 0;
|
||||||
|
bool canReduce () const;
|
||||||
|
bool mustRaise () const;
|
||||||
|
Flags canDogleg ( Interval );
|
||||||
|
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||||
|
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
|
||||||
|
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
|
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
|
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
|
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
|
||||||
|
virtual bool checkPositions () const = 0;
|
||||||
|
virtual bool checkConstraints () const = 0;
|
||||||
|
bool checkDepthSpin () const;
|
||||||
|
// Accessors.
|
||||||
|
inline unsigned long getId () const;
|
||||||
|
inline uint64_t getFlags () const;
|
||||||
|
virtual Flags getDirection () const = 0;
|
||||||
|
inline GCell* getGCell () const;
|
||||||
|
virtual bool getGCells ( vector<GCell*>& ) const = 0;
|
||||||
|
inline AutoContact* getAutoSource () const;
|
||||||
|
inline AutoContact* getAutoTarget () const;
|
||||||
|
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||||
|
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||||
|
inline AutoSegment* getParent () const;
|
||||||
|
inline unsigned int getDepth () const;
|
||||||
|
inline DbU::Unit getPitch () const;
|
||||||
|
DbU::Unit getPPitch () const;
|
||||||
|
#if DISABLED
|
||||||
|
DbU::Unit getExtensionCap () const;
|
||||||
|
#endif
|
||||||
|
DbU::Unit getExtensionCap ( Flags ) const;
|
||||||
|
inline DbU::Unit getAxis () const;
|
||||||
|
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const;
|
||||||
|
virtual DbU::Unit getSourceU () const = 0;
|
||||||
|
virtual DbU::Unit getTargetU () const = 0;
|
||||||
|
virtual DbU::Unit getDuSource () const = 0;
|
||||||
|
virtual DbU::Unit getDuTarget () const = 0;
|
||||||
|
inline DbU::Unit getOrigin () const;
|
||||||
|
inline DbU::Unit getExtremity () const;
|
||||||
|
virtual Interval getSpanU () const = 0;
|
||||||
|
Interval getMinSpanU () const;
|
||||||
|
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||||
|
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||||
|
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
|
||||||
|
inline bool getConstraints ( Interval& i ) const;
|
||||||
|
inline const Interval& getUserConstraints () const;
|
||||||
|
inline const Interval& getNativeConstraints () const;
|
||||||
|
virtual DbU::Unit getSlack () const;
|
||||||
|
inline DbU::Unit getOptimalMin () const;
|
||||||
|
inline DbU::Unit getOptimalMax () const;
|
||||||
|
inline DbU::Unit getNativeMin () const;
|
||||||
|
inline DbU::Unit getNativeMax () const;
|
||||||
|
Interval& getOptimal ( Interval& i ) const;
|
||||||
|
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
|
||||||
|
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||||
|
inline AutoSegment* getCanonical ( Interval& i );
|
||||||
|
float getMaxUnderDensity ( Flags flags );
|
||||||
|
// Modifiers.
|
||||||
|
inline void unsetFlags ( uint64_t );
|
||||||
|
inline void setFlags ( uint64_t );
|
||||||
|
void setFlagsOnAligneds ( uint64_t );
|
||||||
|
inline void incReduceds ();
|
||||||
|
inline void decReduceds ();
|
||||||
|
virtual void setDuSource ( DbU::Unit du ) = 0;
|
||||||
|
virtual void setDuTarget ( DbU::Unit du ) = 0;
|
||||||
|
void computeTerminal ();
|
||||||
|
virtual void updateOrient () = 0;
|
||||||
|
virtual void updatePositions () = 0;
|
||||||
|
virtual void updateNativeConstraints () = 0;
|
||||||
|
void updateSourceSpin ();
|
||||||
|
void updateTargetSpin ();
|
||||||
|
void sourceDetach ();
|
||||||
|
void targetDetach ();
|
||||||
|
void sourceAttach ( AutoContact* );
|
||||||
|
void targetAttach ( AutoContact* );
|
||||||
|
//inline void mergeUserConstraints ( const Interval& );
|
||||||
|
void mergeUserConstraints ( const Interval& );
|
||||||
|
inline void resetUserConstraints ();
|
||||||
|
inline void setOptimalMin ( DbU::Unit min );
|
||||||
|
inline void setOptimalMax ( DbU::Unit max );
|
||||||
|
inline void mergeNativeMin ( DbU::Unit min );
|
||||||
|
inline void mergeNativeMax ( DbU::Unit max );
|
||||||
|
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
|
||||||
|
bool checkNotInvalidated () const;
|
||||||
|
inline void setParent ( AutoSegment* );
|
||||||
|
void revalidate ();
|
||||||
|
AutoSegment* makeDogleg ( AutoContact* );
|
||||||
|
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
|
||||||
|
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
|
||||||
|
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
|
||||||
|
virtual bool moveULeft () = 0;
|
||||||
|
virtual bool moveURight () = 0;
|
||||||
|
bool slacken ( Flags flags );
|
||||||
|
virtual bool _slacken ( Flags flags ) = 0;
|
||||||
|
void _changeDepth ( unsigned int depth, Flags flags );
|
||||||
|
void changeDepth ( unsigned int depth, Flags flags );
|
||||||
|
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||||
|
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||||
|
bool reduceDoglegLayer ();
|
||||||
|
bool reduce ();
|
||||||
|
bool raise ();
|
||||||
|
// Canonical Modifiers.
|
||||||
|
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||||
|
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||||
|
void invalidate ( AutoContact* );
|
||||||
|
void computeOptimal ( set<AutoSegment*>& processeds );
|
||||||
|
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
|
||||||
|
bool toConstraintAxis ( Flags flags=Flags::Realignate );
|
||||||
|
bool toOptimalAxis ( Flags flags=Flags::Realignate );
|
||||||
|
// Collections & Filters.
|
||||||
|
AutoSegments getOnSourceContact ( Flags direction );
|
||||||
|
AutoSegments getOnTargetContact ( Flags direction );
|
||||||
|
AutoSegments getCachedOnSourceContact ( Flags direction );
|
||||||
|
AutoSegments getCachedOnTargetContact ( Flags direction );
|
||||||
|
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
|
||||||
|
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
|
||||||
|
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
|
||||||
|
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
|
||||||
|
// Observers.
|
||||||
|
template< typename OwnerT >
|
||||||
|
inline OwnerT* getObserver ( size_t slot );
|
||||||
|
inline void setObserver ( size_t slot, BaseObserver* );
|
||||||
|
inline void notify ( unsigned int flags );
|
||||||
|
// Inspector Management.
|
||||||
|
virtual Record* _getRecord () const = 0;
|
||||||
|
virtual string _getString () const = 0;
|
||||||
|
virtual string _getTypeName () const = 0;
|
||||||
|
// Non-reviewed atomic modifiers.
|
||||||
|
bool _check () const;
|
||||||
|
#if THIS_IS_DISABLED
|
||||||
|
virtual void desalignate ( AutoContact* ) = 0;
|
||||||
|
bool shearUp ( GCell*
|
||||||
|
, AutoSegment*& movedUp
|
||||||
|
, float reserve
|
||||||
|
, Flags flags );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Internal: Static Attributes.
|
||||||
|
static size_t _allocateds;
|
||||||
|
static size_t _globalsCount;
|
||||||
|
static bool _analogMode;
|
||||||
|
static bool _initialized;
|
||||||
|
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||||
|
// Internal: Attributes.
|
||||||
|
const unsigned long _id;
|
||||||
|
GCell* _gcell;
|
||||||
|
uint64_t _flags;
|
||||||
|
unsigned int _depth : 8;
|
||||||
|
unsigned int _optimalMin :16;
|
||||||
|
unsigned int _optimalMax :16;
|
||||||
|
unsigned int _reduceds : 2;
|
||||||
|
DbU::Unit _sourcePosition;
|
||||||
|
DbU::Unit _targetPosition;
|
||||||
|
Interval _userConstraints;
|
||||||
|
Interval _nativeConstraints;
|
||||||
|
AutoSegment* _parent;
|
||||||
|
Observable _observers;
|
||||||
|
|
||||||
|
// Internal: Constructors & Destructors.
|
||||||
|
protected:
|
||||||
|
AutoSegment ( Segment* segment );
|
||||||
|
virtual ~AutoSegment ();
|
||||||
|
static void _preCreate ( AutoContact* source, AutoContact* target );
|
||||||
|
virtual void _postCreate ();
|
||||||
|
virtual void _preDestroy ();
|
||||||
|
static void _initialize ();
|
||||||
|
private:
|
||||||
|
AutoSegment ( const AutoSegment& );
|
||||||
|
AutoSegment& operator= ( const AutoSegment& );
|
||||||
|
protected:
|
||||||
|
void _invalidate ();
|
||||||
|
inline uint64_t _getFlags () const;
|
||||||
|
std::string _getStringFlags () const;
|
||||||
|
virtual void _setAxis ( DbU::Unit ) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
struct CompareByDepthLength : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||||
|
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||||
|
|
||||||
|
// Static Utilities.
|
||||||
|
public:
|
||||||
|
static inline uint64_t swapSourceTargetFlags ( AutoSegment* );
|
||||||
|
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
|
||||||
|
static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from );
|
||||||
|
static bool isTopologicalBound ( AutoSegment* seed, Flags flags );
|
||||||
|
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
|
||||||
|
static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b );
|
||||||
|
static inline bool areAligneds ( AutoSegment* a, AutoSegment* b );
|
||||||
|
static Flags getPerpandicularState ( AutoContact* contact
|
||||||
|
, AutoSegment* source
|
||||||
|
, AutoSegment* current
|
||||||
|
, bool isHorizontalMaster
|
||||||
|
, const Layer* masterLayer=NULL
|
||||||
|
);
|
||||||
|
static inline Flags getPerpandicularState ( AutoContact* contact
|
||||||
|
, AutoSegment* source
|
||||||
|
, AutoSegment* current
|
||||||
|
, AutoSegment* master
|
||||||
|
);
|
||||||
|
static void getTopologicalInfos ( AutoSegment* seed
|
||||||
|
, vector<AutoSegment*>& collapseds
|
||||||
|
, vector<AutoSegment*>& perpandiculars
|
||||||
|
, DbU::Unit& leftBound
|
||||||
|
, DbU::Unit& rightBound
|
||||||
|
);
|
||||||
|
static int getTerminalCount ( AutoSegment* seed
|
||||||
|
, vector<AutoSegment*>& collapseds
|
||||||
|
);
|
||||||
|
static inline int getTerminalCount ( AutoSegment* seed );
|
||||||
|
static inline size_t getGlobalsCount ();
|
||||||
|
static inline size_t getAllocateds ();
|
||||||
|
static inline unsigned long getMaxId ();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Inline Functions.
|
||||||
|
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||||
|
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||||
|
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||||
|
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||||
|
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||||
|
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||||
|
inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); }
|
||||||
|
inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); }
|
||||||
|
inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); }
|
||||||
|
inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); }
|
||||||
|
inline Contact* AutoSegment::getSource () const { return static_cast<Contact*>(base()->getSource()); }
|
||||||
|
inline Contact* AutoSegment::getTarget () const { return static_cast<Contact*>(base()->getTarget()); }
|
||||||
|
inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); };
|
||||||
|
inline AutoSegment* AutoSegment::getParent () const { return _parent; }
|
||||||
|
inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; }
|
||||||
|
inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; }
|
||||||
|
inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); }
|
||||||
|
inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); }
|
||||||
|
inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); }
|
||||||
|
inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); }
|
||||||
|
inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); }
|
||||||
|
inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); }
|
||||||
|
inline void AutoSegment::invert () { base()->invert(); }
|
||||||
|
inline GCell* AutoSegment::getGCell () const { return _gcell; }
|
||||||
|
inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); }
|
||||||
|
inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); }
|
||||||
|
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
|
||||||
|
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
|
||||||
|
inline unsigned int AutoSegment::getDepth () const { return _depth; }
|
||||||
|
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
|
||||||
|
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
|
||||||
|
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
|
||||||
|
inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); }
|
||||||
|
inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); }
|
||||||
|
inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); }
|
||||||
|
inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); }
|
||||||
|
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
|
||||||
|
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
|
||||||
|
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
|
||||||
|
|
||||||
|
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||||
|
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||||
|
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
|
||||||
|
inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; }
|
||||||
|
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
|
||||||
|
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
||||||
|
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
||||||
|
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
|
||||||
|
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
|
||||||
|
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
|
||||||
|
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
|
||||||
|
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
|
||||||
|
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
|
||||||
|
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||||
|
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
|
||||||
|
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||||
|
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||||
|
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||||
|
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||||
|
inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; }
|
||||||
|
inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; }
|
||||||
|
inline bool AutoSegment::isStrap () const { return _flags & SegStrap; }
|
||||||
|
inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; }
|
||||||
|
inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); }
|
||||||
|
inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); }
|
||||||
|
inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); }
|
||||||
|
inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; }
|
||||||
|
inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; }
|
||||||
|
inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; }
|
||||||
|
inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); }
|
||||||
|
inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; }
|
||||||
|
inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; }
|
||||||
|
inline bool AutoSegment::isCreated () const { return _flags & SegCreated; }
|
||||||
|
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
|
||||||
|
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
|
||||||
|
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
|
||||||
|
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||||
|
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
|
||||||
|
|
||||||
|
inline uint64_t AutoSegment::getFlags () const { return _flags; }
|
||||||
|
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
|
||||||
|
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
|
||||||
|
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
|
||||||
|
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
|
||||||
|
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); }
|
||||||
|
inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); }
|
||||||
|
inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
|
||||||
|
inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); }
|
||||||
|
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||||
|
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||||
|
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||||
|
|
||||||
|
|
||||||
|
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||||
|
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||||
|
|
||||||
|
|
||||||
|
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||||
|
{
|
||||||
|
if ( parent == this ) {
|
||||||
|
cerr << "Parentage Looping: " << parent->_getString() << endl;
|
||||||
|
}
|
||||||
|
_parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||||
|
{ return lhs->getId() < rhs->getId(); }
|
||||||
|
|
||||||
|
inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
|
||||||
|
{
|
||||||
|
uint64_t segFlags = segment->getFlags();
|
||||||
|
uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|
||||||
|
|SegSourceBottom |SegTargetBottom
|
||||||
|
|SegSourceTerminal |SegTargetTerminal
|
||||||
|
|SegNotSourceAligned |SegNotTargetAligned
|
||||||
|
|SegInvalidatedSource|SegInvalidatedTarget
|
||||||
|
);
|
||||||
|
|
||||||
|
swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags;
|
||||||
|
|
||||||
|
swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags;
|
||||||
|
swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags;
|
||||||
|
return swapFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
|
||||||
|
{ return s1 and s2
|
||||||
|
and (s1->isHorizontal() == s2->isHorizontal())
|
||||||
|
and (s1->getLayer() != s2->getLayer()); }
|
||||||
|
|
||||||
|
inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b )
|
||||||
|
{ return a and b and (a->isHorizontal() != b->isHorizontal()); }
|
||||||
|
|
||||||
|
inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b )
|
||||||
|
{ return b and (isHorizontalA != b->isHorizontal()); }
|
||||||
|
|
||||||
|
inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b )
|
||||||
|
{ return a and b and (a->isHorizontal() == b->isHorizontal()); }
|
||||||
|
|
||||||
|
inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact
|
||||||
|
, AutoSegment* source
|
||||||
|
, AutoSegment* current
|
||||||
|
, AutoSegment* master )
|
||||||
|
{
|
||||||
|
return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int AutoSegment::getTerminalCount ( AutoSegment* seed )
|
||||||
|
{
|
||||||
|
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||||
|
|
||||||
|
vector<AutoSegment*> collapseds;
|
||||||
|
vector<AutoSegment*> perpandiculars;
|
||||||
|
DbU::Unit leftBound;
|
||||||
|
DbU::Unit rightBound;
|
||||||
|
|
||||||
|
getTopologicalInfos ( seed
|
||||||
|
, collapseds
|
||||||
|
, perpandiculars
|
||||||
|
, leftBound
|
||||||
|
, rightBound
|
||||||
|
);
|
||||||
|
|
||||||
|
return getTerminalCount ( seed, collapseds );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; }
|
||||||
|
inline size_t AutoSegment::getAllocateds () { return _allocateds; }
|
||||||
|
|
||||||
|
|
||||||
|
inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer )
|
||||||
|
{ _observers.setObserver( slot, observer ); }
|
||||||
|
|
||||||
|
template<typename OwnerT>
|
||||||
|
inline OwnerT* AutoSegment::getObserver ( size_t slot )
|
||||||
|
{ return _observers.getObserver<OwnerT>(slot); }
|
||||||
|
|
||||||
|
inline void AutoSegment::notify ( unsigned int flags )
|
||||||
|
{ _observers.notify( flags ); }
|
||||||
|
|
||||||
|
inline AutoSegment::Observable::Observable () : StaticObservable<1>() { }
|
||||||
|
|
||||||
|
|
||||||
|
} // End of Anabatic namespace.
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||||
|
|
||||||
|
|
||||||
|
# endif // ANABATIC_AUTOSEGMENT_H
|
|
@ -216,6 +216,7 @@ namespace Anabatic {
|
||||||
// Global routing related functions.
|
// Global routing related functions.
|
||||||
void globalRoute ();
|
void globalRoute ();
|
||||||
void cleanupGlobal ();
|
void cleanupGlobal ();
|
||||||
|
void relaxOverConstraineds ();
|
||||||
// Detailed routing related functions.
|
// Detailed routing related functions.
|
||||||
inline bool isInDemoMode () const;
|
inline bool isInDemoMode () const;
|
||||||
inline bool isChip () const;
|
inline bool isChip () const;
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace Hurricane {
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
|
||||||
|
using std::array;
|
||||||
using std::set;
|
using std::set;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
@ -70,39 +71,40 @@ namespace Anabatic {
|
||||||
static const uint64_t SegNoFlags = 0L;
|
static const uint64_t SegNoFlags = 0L;
|
||||||
static const uint64_t SegHorizontal = (1L<< 0);
|
static const uint64_t SegHorizontal = (1L<< 0);
|
||||||
static const uint64_t SegFixed = (1L<< 1);
|
static const uint64_t SegFixed = (1L<< 1);
|
||||||
static const uint64_t SegGlobal = (1L<< 2);
|
static const uint64_t SegFixedAxis = (1L<< 2);
|
||||||
static const uint64_t SegWeakGlobal = (1L<< 3);
|
static const uint64_t SegGlobal = (1L<< 3);
|
||||||
static const uint64_t SegLongLocal = (1L<< 4);
|
static const uint64_t SegWeakGlobal = (1L<< 4);
|
||||||
static const uint64_t SegCanonical = (1L<< 5);
|
static const uint64_t SegLongLocal = (1L<< 5);
|
||||||
static const uint64_t SegBipoint = (1L<< 6);
|
static const uint64_t SegCanonical = (1L<< 6);
|
||||||
static const uint64_t SegDogleg = (1L<< 7);
|
static const uint64_t SegBipoint = (1L<< 7);
|
||||||
static const uint64_t SegStrap = (1L<< 8);
|
static const uint64_t SegDogleg = (1L<< 8);
|
||||||
static const uint64_t SegSourceTop = (1L<< 9);
|
static const uint64_t SegStrap = (1L<< 9);
|
||||||
static const uint64_t SegSourceBottom = (1L<<10);
|
static const uint64_t SegSourceTop = (1L<<10);
|
||||||
static const uint64_t SegTargetTop = (1L<<11);
|
static const uint64_t SegSourceBottom = (1L<<11);
|
||||||
static const uint64_t SegTargetBottom = (1L<<12);
|
static const uint64_t SegTargetTop = (1L<<12);
|
||||||
static const uint64_t SegIsReduced = (1L<<13);
|
static const uint64_t SegTargetBottom = (1L<<13);
|
||||||
static const uint64_t SegDrag = (1L<<14);
|
static const uint64_t SegIsReduced = (1L<<14);
|
||||||
static const uint64_t SegLayerChange = (1L<<15);
|
static const uint64_t SegDrag = (1L<<15);
|
||||||
static const uint64_t SegSourceTerminal = (1L<<16); // Replace Terminal.
|
static const uint64_t SegLayerChange = (1L<<16);
|
||||||
static const uint64_t SegTargetTerminal = (1L<<17); // Replace Terminal.
|
static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal.
|
||||||
|
static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal.
|
||||||
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
|
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
|
||||||
static const uint64_t SegWeakTerminal1 = (1L<<18); // Replace TopologicalEnd.
|
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd.
|
||||||
static const uint64_t SegWeakTerminal2 = (1L<<19); // Replace TopologicalEnd.
|
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd.
|
||||||
static const uint64_t SegNotSourceAligned = (1L<<20);
|
static const uint64_t SegNotSourceAligned = (1L<<21);
|
||||||
static const uint64_t SegNotTargetAligned = (1L<<21);
|
static const uint64_t SegNotTargetAligned = (1L<<22);
|
||||||
static const uint64_t SegUnbound = (1L<<22);
|
static const uint64_t SegUnbound = (1L<<23);
|
||||||
static const uint64_t SegHalfSlackened = (1L<<23);
|
static const uint64_t SegHalfSlackened = (1L<<24);
|
||||||
static const uint64_t SegSlackened = (1L<<24);
|
static const uint64_t SegSlackened = (1L<<25);
|
||||||
static const uint64_t SegAxisSet = (1L<<25);
|
static const uint64_t SegAxisSet = (1L<<26);
|
||||||
static const uint64_t SegInvalidated = (1L<<26);
|
static const uint64_t SegInvalidated = (1L<<27);
|
||||||
static const uint64_t SegInvalidatedSource = (1L<<27);
|
static const uint64_t SegInvalidatedSource = (1L<<28);
|
||||||
static const uint64_t SegInvalidatedTarget = (1L<<28);
|
static const uint64_t SegInvalidatedTarget = (1L<<29);
|
||||||
static const uint64_t SegInvalidatedLayer = (1L<<29);
|
static const uint64_t SegInvalidatedLayer = (1L<<30);
|
||||||
static const uint64_t SegCreated = (1L<<30);
|
static const uint64_t SegCreated = (1L<<31);
|
||||||
static const uint64_t SegUserDefined = (1L<<31);
|
static const uint64_t SegUserDefined = (1L<<32);
|
||||||
static const uint64_t SegAnalog = (1L<<32);
|
static const uint64_t SegAnalog = (1L<<33);
|
||||||
static const uint64_t SegWide = (1L<<33);
|
static const uint64_t SegWide = (1L<<34);
|
||||||
// Masks.
|
// Masks.
|
||||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||||
|
@ -131,253 +133,264 @@ namespace Anabatic {
|
||||||
public:
|
public:
|
||||||
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
|
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
|
||||||
public:
|
public:
|
||||||
static void setAnalogMode ( bool );
|
static void setAnalogMode ( bool );
|
||||||
static bool getAnalogMode ();
|
static bool getAnalogMode ();
|
||||||
static AutoSegment* create ( AutoContact* source
|
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||||
, AutoContact* target
|
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||||
, Segment* hurricaneSegment
|
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||||
);
|
static AutoSegment* create ( AutoContact* source
|
||||||
static AutoSegment* create ( AutoContact* source
|
, AutoContact* target
|
||||||
, AutoContact* target
|
, Segment* hurricaneSegment
|
||||||
, Flags dir
|
);
|
||||||
, size_t depth=RoutingGauge::nlayerdepth
|
static AutoSegment* create ( AutoContact* source
|
||||||
);
|
, AutoContact* target
|
||||||
void destroy ();
|
, Flags dir
|
||||||
|
, size_t depth=RoutingGauge::nlayerdepth
|
||||||
|
);
|
||||||
|
void destroy ();
|
||||||
// Wrapped Segment Functions.
|
// Wrapped Segment Functions.
|
||||||
virtual Segment* base () const = 0;
|
virtual Segment* base () const = 0;
|
||||||
virtual Segment* base () = 0;
|
virtual Segment* base () = 0;
|
||||||
virtual Horizontal* getHorizontal () { return NULL; };
|
virtual Horizontal* getHorizontal () { return NULL; };
|
||||||
virtual Vertical* getVertical () { return NULL; };
|
virtual Vertical* getVertical () { return NULL; };
|
||||||
inline Cell* getCell () const;
|
inline Cell* getCell () const;
|
||||||
inline Net* getNet () const;
|
inline Net* getNet () const;
|
||||||
inline const Layer* getLayer () const;
|
inline const Layer* getLayer () const;
|
||||||
inline Box getBoundingBox () const;
|
inline Box getBoundingBox () const;
|
||||||
inline Hook* getSourceHook ();
|
inline Hook* getSourceHook ();
|
||||||
inline Hook* getTargetHook ();
|
inline Hook* getTargetHook ();
|
||||||
inline Contact* getSource () const;
|
inline Contact* getSource () const;
|
||||||
inline Contact* getTarget () const;
|
inline Contact* getTarget () const;
|
||||||
inline Component* getOppositeAnchor ( Component* ) const;
|
inline Component* getOppositeAnchor ( Component* ) const;
|
||||||
inline Components getAnchors () const;
|
inline Components getAnchors () const;
|
||||||
virtual DbU::Unit getX () const;
|
virtual DbU::Unit getX () const;
|
||||||
virtual DbU::Unit getY () const;
|
virtual DbU::Unit getY () const;
|
||||||
inline DbU::Unit getWidth () const;
|
inline DbU::Unit getWidth () const;
|
||||||
inline DbU::Unit getContactWidth () const;
|
inline DbU::Unit getContactWidth () const;
|
||||||
inline DbU::Unit getLength () const;
|
inline DbU::Unit getLength () const;
|
||||||
inline DbU::Unit getSourcePosition () const;
|
inline DbU::Unit getSourcePosition () const;
|
||||||
inline DbU::Unit getTargetPosition () const;
|
inline DbU::Unit getTargetPosition () const;
|
||||||
inline DbU::Unit getSourceX () const;
|
inline DbU::Unit getSourceX () const;
|
||||||
inline DbU::Unit getSourceY () const;
|
inline DbU::Unit getSourceY () const;
|
||||||
inline DbU::Unit getTargetX () const;
|
inline DbU::Unit getTargetX () const;
|
||||||
inline DbU::Unit getTargetY () const;
|
inline DbU::Unit getTargetY () const;
|
||||||
inline void invert ();
|
inline void invert ();
|
||||||
inline void setLayer ( const Layer* );
|
inline void setLayer ( const Layer* );
|
||||||
// Predicates.
|
// Predicates.
|
||||||
inline bool isHorizontal () const;
|
inline bool isHorizontal () const;
|
||||||
inline bool isVertical () const;
|
inline bool isVertical () const;
|
||||||
inline bool isGlobal () const;
|
inline bool isGlobal () const;
|
||||||
inline bool isWeakGlobal () const;
|
inline bool isWeakGlobal () const;
|
||||||
inline bool isLongLocal () const;
|
inline bool isLongLocal () const;
|
||||||
inline bool isLocal () const;
|
inline bool isLocal () const;
|
||||||
inline bool isFixed () const;
|
inline bool isFixed () const;
|
||||||
inline bool isBipoint () const;
|
inline bool isFixedAxis () const;
|
||||||
inline bool isWeakTerminal () const;
|
inline bool isBipoint () const;
|
||||||
inline bool isWeakTerminal1 () const;
|
inline bool isWeakTerminal () const;
|
||||||
inline bool isWeakTerminal2 () const;
|
inline bool isWeakTerminal1 () const;
|
||||||
inline bool isTerminal () const;
|
inline bool isWeakTerminal2 () const;
|
||||||
inline bool isDrag () const;
|
inline bool isTerminal () const;
|
||||||
inline bool isNotSourceAligned () const;
|
inline bool isDrag () const;
|
||||||
inline bool isNotTargetAligned () const;
|
inline bool isNotSourceAligned () const;
|
||||||
inline bool isNotAligned () const;
|
inline bool isNotTargetAligned () const;
|
||||||
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
|
inline bool isNotAligned () const;
|
||||||
inline bool isSourceTerminal () const;
|
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
|
||||||
inline bool isTargetTerminal () const;
|
inline bool isSourceTerminal () const;
|
||||||
inline bool isLayerChange () const;
|
inline bool isTargetTerminal () const;
|
||||||
inline bool isSpinTop () const;
|
inline bool isLayerChange () const;
|
||||||
inline bool isSpinBottom () const;
|
inline bool isSpinTop () const;
|
||||||
inline bool isSpinTopOrBottom () const;
|
inline bool isSpinBottom () const;
|
||||||
inline bool isReduced () const;
|
inline bool isSpinTopOrBottom () const;
|
||||||
inline bool isStrap () const;
|
inline bool isReduced () const;
|
||||||
inline bool isDogleg () const;
|
inline bool isStrap () const;
|
||||||
inline bool isUnbound () const;
|
inline bool isDogleg () const;
|
||||||
inline bool isInvalidated () const;
|
inline bool isUnbound () const;
|
||||||
inline bool isInvalidatedLayer () const;
|
inline bool isInvalidated () const;
|
||||||
inline bool isCreated () const;
|
inline bool isInvalidatedLayer () const;
|
||||||
inline bool isCanonical () const;
|
inline bool isCreated () const;
|
||||||
inline bool isUnsetAxis () const;
|
inline bool isCanonical () const;
|
||||||
inline bool isSlackened () const;
|
inline bool isUnsetAxis () const;
|
||||||
inline bool isUserDefined () const;
|
inline bool isSlackened () const;
|
||||||
bool isReduceCandidate () const;
|
inline bool isUserDefined () const;
|
||||||
bool isUTurn () const;
|
bool isReduceCandidate () const;
|
||||||
inline bool isAnalog () const;
|
bool isUTurn () const;
|
||||||
inline bool isWide () const;
|
inline bool isAnalog () const;
|
||||||
virtual bool _canSlacken () const = 0;
|
inline bool isWide () const;
|
||||||
bool canReduce () const;
|
virtual bool _canSlacken () const = 0;
|
||||||
bool mustRaise () const;
|
bool canReduce () const;
|
||||||
Flags canDogleg ( Interval );
|
bool mustRaise () const;
|
||||||
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
Flags canDogleg ( Interval );
|
||||||
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
|
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||||
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
|
||||||
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
|
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||||
virtual bool checkPositions () const = 0;
|
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
|
||||||
virtual bool checkConstraints () const = 0;
|
virtual bool checkPositions () const = 0;
|
||||||
bool checkDepthSpin () const;
|
virtual bool checkConstraints () const = 0;
|
||||||
|
bool checkDepthSpin () const;
|
||||||
// Accessors.
|
// Accessors.
|
||||||
inline unsigned long getId () const;
|
inline unsigned long getId () const;
|
||||||
inline uint64_t getFlags () const;
|
inline uint64_t getFlags () const;
|
||||||
virtual Flags getDirection () const = 0;
|
virtual Flags getDirection () const = 0;
|
||||||
inline GCell* getGCell () const;
|
inline GCell* getGCell () const;
|
||||||
virtual bool getGCells ( vector<GCell*>& ) const = 0;
|
virtual bool getGCells ( vector<GCell*>& ) const = 0;
|
||||||
inline AutoContact* getAutoSource () const;
|
inline AutoContact* getAutoSource () const;
|
||||||
inline AutoContact* getAutoTarget () const;
|
inline AutoContact* getAutoTarget () const;
|
||||||
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||||
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||||
inline AutoSegment* getParent () const;
|
inline AutoSegment* getParent () const;
|
||||||
inline unsigned int getDepth () const;
|
inline unsigned int getDepth () const;
|
||||||
inline DbU::Unit getPitch () const;
|
inline DbU::Unit getPitch () const;
|
||||||
DbU::Unit getPPitch () const;
|
DbU::Unit getPPitch () const;
|
||||||
DbU::Unit getExtensionCap () const;
|
#if DISABLED
|
||||||
inline DbU::Unit getAxis () const;
|
DbU::Unit getExtensionCap () const;
|
||||||
virtual DbU::Unit getSourceU () const = 0;
|
#endif
|
||||||
virtual DbU::Unit getTargetU () const = 0;
|
DbU::Unit getExtensionCap ( Flags ) const;
|
||||||
virtual DbU::Unit getDuSource () const = 0;
|
inline DbU::Unit getAxis () const;
|
||||||
virtual DbU::Unit getDuTarget () const = 0;
|
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const;
|
||||||
inline DbU::Unit getOrigin () const;
|
virtual DbU::Unit getSourceU () const = 0;
|
||||||
inline DbU::Unit getExtremity () const;
|
virtual DbU::Unit getTargetU () const = 0;
|
||||||
virtual Interval getSpanU () const = 0;
|
virtual DbU::Unit getDuSource () const = 0;
|
||||||
Interval getMinSpanU () const;
|
virtual DbU::Unit getDuTarget () const = 0;
|
||||||
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
inline DbU::Unit getOrigin () const;
|
||||||
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
inline DbU::Unit getExtremity () const;
|
||||||
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
|
virtual Interval getSpanU () const = 0;
|
||||||
inline bool getConstraints ( Interval& i ) const;
|
Interval getMinSpanU () const;
|
||||||
inline const Interval& getUserConstraints () const;
|
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||||
inline const Interval& getNativeConstraints () const;
|
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||||
virtual DbU::Unit getSlack () const;
|
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
|
||||||
inline DbU::Unit getOptimalMin () const;
|
inline bool getConstraints ( Interval& i ) const;
|
||||||
inline DbU::Unit getOptimalMax () const;
|
inline const Interval& getUserConstraints () const;
|
||||||
inline DbU::Unit getNativeMin () const;
|
inline const Interval& getNativeConstraints () const;
|
||||||
inline DbU::Unit getNativeMax () const;
|
virtual DbU::Unit getSlack () const;
|
||||||
Interval& getOptimal ( Interval& i ) const;
|
inline DbU::Unit getOptimalMin () const;
|
||||||
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
|
inline DbU::Unit getOptimalMax () const;
|
||||||
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
inline DbU::Unit getNativeMin () const;
|
||||||
inline AutoSegment* getCanonical ( Interval& i );
|
inline DbU::Unit getNativeMax () const;
|
||||||
float getMaxUnderDensity ( Flags flags );
|
Interval& getOptimal ( Interval& i ) const;
|
||||||
|
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
|
||||||
|
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||||
|
inline AutoSegment* getCanonical ( Interval& i );
|
||||||
|
float getMaxUnderDensity ( Flags flags );
|
||||||
// Modifiers.
|
// Modifiers.
|
||||||
inline void unsetFlags ( uint64_t );
|
inline void unsetFlags ( uint64_t );
|
||||||
inline void setFlags ( uint64_t );
|
inline void setFlags ( uint64_t );
|
||||||
void setFlagsOnAligneds ( uint64_t );
|
void setFlagsOnAligneds ( uint64_t );
|
||||||
inline void incReduceds ();
|
inline void incReduceds ();
|
||||||
inline void decReduceds ();
|
inline void decReduceds ();
|
||||||
virtual void setDuSource ( DbU::Unit du ) = 0;
|
virtual void setDuSource ( DbU::Unit du ) = 0;
|
||||||
virtual void setDuTarget ( DbU::Unit du ) = 0;
|
virtual void setDuTarget ( DbU::Unit du ) = 0;
|
||||||
void computeTerminal ();
|
void computeTerminal ();
|
||||||
virtual void updateOrient () = 0;
|
virtual void updateOrient () = 0;
|
||||||
virtual void updatePositions () = 0;
|
virtual void updatePositions () = 0;
|
||||||
virtual void updateNativeConstraints () = 0;
|
virtual void updateNativeConstraints () = 0;
|
||||||
void updateSourceSpin ();
|
void updateSourceSpin ();
|
||||||
void updateTargetSpin ();
|
void updateTargetSpin ();
|
||||||
void sourceDetach ();
|
void sourceDetach ();
|
||||||
void targetDetach ();
|
void targetDetach ();
|
||||||
void sourceAttach ( AutoContact* );
|
void sourceAttach ( AutoContact* );
|
||||||
void targetAttach ( AutoContact* );
|
void targetAttach ( AutoContact* );
|
||||||
//inline void mergeUserConstraints ( const Interval& );
|
//inline void mergeUserConstraints ( const Interval& );
|
||||||
void mergeUserConstraints ( const Interval& );
|
void mergeUserConstraints ( const Interval& );
|
||||||
inline void resetUserConstraints ();
|
inline void resetUserConstraints ();
|
||||||
inline void setOptimalMin ( DbU::Unit min );
|
inline void setOptimalMin ( DbU::Unit min );
|
||||||
inline void setOptimalMax ( DbU::Unit max );
|
inline void setOptimalMax ( DbU::Unit max );
|
||||||
inline void mergeNativeMin ( DbU::Unit min );
|
inline void mergeNativeMin ( DbU::Unit min );
|
||||||
inline void mergeNativeMax ( DbU::Unit max );
|
inline void mergeNativeMax ( DbU::Unit max );
|
||||||
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
|
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
|
||||||
bool checkNotInvalidated () const;
|
bool checkNotInvalidated () const;
|
||||||
inline void setParent ( AutoSegment* );
|
inline void setParent ( AutoSegment* );
|
||||||
void revalidate ();
|
void revalidate ();
|
||||||
AutoSegment* makeDogleg ( AutoContact* );
|
AutoSegment* makeDogleg ( AutoContact* );
|
||||||
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
|
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
|
||||||
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
|
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
|
||||||
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
|
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
|
||||||
virtual bool moveULeft () = 0;
|
virtual bool moveULeft () = 0;
|
||||||
virtual bool moveURight () = 0;
|
virtual bool moveURight () = 0;
|
||||||
bool slacken ( Flags flags );
|
bool slacken ( Flags flags );
|
||||||
virtual bool _slacken ( Flags flags ) = 0;
|
virtual bool _slacken ( Flags flags ) = 0;
|
||||||
void _changeDepth ( unsigned int depth, Flags flags );
|
void _changeDepth ( unsigned int depth, Flags flags );
|
||||||
void changeDepth ( unsigned int depth, Flags flags );
|
void changeDepth ( unsigned int depth, Flags flags );
|
||||||
bool moveUp ( Flags flags=Flags::NoFlags );
|
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||||
bool moveDown ( Flags flags=Flags::NoFlags );
|
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||||
bool reduceDoglegLayer ();
|
bool reduceDoglegLayer ();
|
||||||
bool reduce ();
|
bool reduce ();
|
||||||
bool raise ();
|
bool raise ();
|
||||||
// Canonical Modifiers.
|
// Canonical Modifiers.
|
||||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||||
void invalidate ( AutoContact* );
|
void invalidate ( AutoContact* );
|
||||||
void computeOptimal ( set<AutoSegment*>& processeds );
|
void computeOptimal ( set<AutoSegment*>& processeds );
|
||||||
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
|
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
|
||||||
bool toConstraintAxis ( Flags flags=Flags::Realignate );
|
bool toConstraintAxis ( Flags flags=Flags::Realignate );
|
||||||
bool toOptimalAxis ( Flags flags=Flags::Realignate );
|
bool toOptimalAxis ( Flags flags=Flags::Realignate );
|
||||||
// Collections & Filters.
|
// Collections & Filters.
|
||||||
AutoSegments getOnSourceContact ( Flags direction );
|
AutoSegments getOnSourceContact ( Flags direction );
|
||||||
AutoSegments getOnTargetContact ( Flags direction );
|
AutoSegments getOnTargetContact ( Flags direction );
|
||||||
AutoSegments getCachedOnSourceContact ( Flags direction );
|
AutoSegments getCachedOnSourceContact ( Flags direction );
|
||||||
AutoSegments getCachedOnTargetContact ( Flags direction );
|
AutoSegments getCachedOnTargetContact ( Flags direction );
|
||||||
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
|
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
|
||||||
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
|
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
|
||||||
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
|
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
|
||||||
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
|
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
|
||||||
// Observers.
|
// Observers.
|
||||||
template< typename OwnerT >
|
template< typename OwnerT >
|
||||||
inline OwnerT* getObserver ( size_t slot );
|
inline OwnerT* getObserver ( size_t slot );
|
||||||
inline void setObserver ( size_t slot, BaseObserver* );
|
inline void setObserver ( size_t slot, BaseObserver* );
|
||||||
inline void notify ( unsigned int flags );
|
inline void notify ( unsigned int flags );
|
||||||
// Inspector Management.
|
// Inspector Management.
|
||||||
virtual Record* _getRecord () const = 0;
|
virtual Record* _getRecord () const = 0;
|
||||||
virtual string _getString () const = 0;
|
virtual string _getString () const = 0;
|
||||||
virtual string _getTypeName () const = 0;
|
virtual string _getTypeName () const = 0;
|
||||||
// Non-reviewed atomic modifiers.
|
// Non-reviewed atomic modifiers.
|
||||||
bool _check () const;
|
bool _check () const;
|
||||||
#if THIS_IS_DISABLED
|
#if THIS_IS_DISABLED
|
||||||
virtual void desalignate ( AutoContact* ) = 0;
|
virtual void desalignate ( AutoContact* ) = 0;
|
||||||
bool shearUp ( GCell*
|
bool shearUp ( GCell*
|
||||||
, AutoSegment*& movedUp
|
, AutoSegment*& movedUp
|
||||||
, float reserve
|
, float reserve
|
||||||
, Flags flags );
|
, Flags flags );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal: Static Attributes.
|
// Internal: Static Attributes.
|
||||||
static size_t _allocateds;
|
static size_t _allocateds;
|
||||||
static size_t _globalsCount;
|
static size_t _globalsCount;
|
||||||
static bool _analogMode;
|
static bool _analogMode;
|
||||||
|
static bool _initialized;
|
||||||
|
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||||
// Internal: Attributes.
|
// Internal: Attributes.
|
||||||
const unsigned long _id;
|
const unsigned long _id;
|
||||||
GCell* _gcell;
|
GCell* _gcell;
|
||||||
uint64_t _flags;
|
uint64_t _flags;
|
||||||
unsigned int _depth : 8;
|
unsigned int _depth : 8;
|
||||||
unsigned int _optimalMin :16;
|
unsigned int _optimalMin :16;
|
||||||
unsigned int _optimalMax :16;
|
unsigned int _optimalMax :16;
|
||||||
unsigned int _reduceds : 2;
|
unsigned int _reduceds : 2;
|
||||||
DbU::Unit _sourcePosition;
|
DbU::Unit _sourcePosition;
|
||||||
DbU::Unit _targetPosition;
|
DbU::Unit _targetPosition;
|
||||||
Interval _userConstraints;
|
Interval _userConstraints;
|
||||||
Interval _nativeConstraints;
|
Interval _nativeConstraints;
|
||||||
AutoSegment* _parent;
|
AutoSegment* _parent;
|
||||||
Observable _observers;
|
Observable _observers;
|
||||||
|
|
||||||
// Internal: Constructors & Destructors.
|
// Internal: Constructors & Destructors.
|
||||||
protected:
|
protected:
|
||||||
AutoSegment ( Segment* segment );
|
AutoSegment ( Segment* segment );
|
||||||
virtual ~AutoSegment ();
|
virtual ~AutoSegment ();
|
||||||
static void _preCreate ( AutoContact* source, AutoContact* target );
|
static void _preCreate ( AutoContact* source, AutoContact* target );
|
||||||
virtual void _postCreate ();
|
virtual void _postCreate ();
|
||||||
virtual void _preDestroy ();
|
virtual void _preDestroy ();
|
||||||
|
static void _initialize ();
|
||||||
private:
|
private:
|
||||||
AutoSegment ( const AutoSegment& );
|
AutoSegment ( const AutoSegment& );
|
||||||
AutoSegment& operator= ( const AutoSegment& );
|
AutoSegment& operator= ( const AutoSegment& );
|
||||||
protected:
|
protected:
|
||||||
void _invalidate ();
|
void _invalidate ();
|
||||||
inline uint64_t _getFlags () const;
|
inline uint64_t _getFlags () const;
|
||||||
std::string _getStringFlags () const;
|
std::string _getStringFlags () const;
|
||||||
virtual void _setAxis ( DbU::Unit ) = 0;
|
virtual void _setAxis ( DbU::Unit ) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
@ -391,8 +404,13 @@ namespace Anabatic {
|
||||||
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
};
|
};
|
||||||
|
public:
|
||||||
|
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||||
|
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||||
|
|
||||||
// Static Utilities.
|
// Static Utilities.
|
||||||
public:
|
public:
|
||||||
|
@ -431,6 +449,9 @@ namespace Anabatic {
|
||||||
|
|
||||||
|
|
||||||
// Inline Functions.
|
// Inline Functions.
|
||||||
|
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||||
|
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||||
|
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||||
inline unsigned long AutoSegment::getId () const { return _id; }
|
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||||
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||||
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||||
|
@ -471,6 +492,7 @@ namespace Anabatic {
|
||||||
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||||
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||||
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
|
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
|
||||||
|
inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; }
|
||||||
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
|
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
|
||||||
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
||||||
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
||||||
|
@ -532,7 +554,6 @@ namespace Anabatic {
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||||
{ return lhs->getId() < rhs->getId(); }
|
{ return lhs->getId() < rhs->getId(); }
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ parametersTable = \
|
||||||
routingGaugesTable = {}
|
routingGaugesTable = {}
|
||||||
|
|
||||||
routingGaugesTable['gscl45'] = \
|
routingGaugesTable['gscl45'] = \
|
||||||
( ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.065, 7 ) )
|
( ( 'symbolic', False )
|
||||||
|
, ( 'metal1' , ( Gauge.Horizontal, Gauge.PinOnly, 0, 0.0, 0, 0.190, 0.065, 0.065, 7 ) )
|
||||||
, ( 'metal2' , ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 0.190, 0.070, 0.070, 8 ) )
|
, ( 'metal2' , ( Gauge.Vertical , Gauge.Default, 1, 0.0, 0, 0.190, 0.070, 0.070, 8 ) )
|
||||||
, ( 'metal3' , ( Gauge.Horizontal, Gauge.Default, 2, 0.0, 0, 0.190, 0.070, 0.070, 8 ) )
|
, ( 'metal3' , ( Gauge.Horizontal, Gauge.Default, 2, 0.0, 0, 0.190, 0.070, 0.070, 8 ) )
|
||||||
, ( 'metal4' , ( Gauge.Vertical , Gauge.Default, 3, 0.0, 0, 0.285, 0.140, 0.140, 8 ) )
|
, ( 'metal4' , ( Gauge.Vertical , Gauge.Default, 3, 0.0, 0, 0.285, 0.140, 0.140, 8 ) )
|
||||||
|
|
|
@ -33,7 +33,18 @@ technoConfig = { 'name' : 'freepdk_45'
|
||||||
# must be expressed in microns.
|
# must be expressed in microns.
|
||||||
|
|
||||||
layersExtensionsTable = \
|
layersExtensionsTable = \
|
||||||
( ('NWELL.nWell.extention.cap' , 0.0)
|
( ('metal1.minimalSpacing' , 0.065)
|
||||||
|
, ('metal2.minimalSpacing' , 0.075)
|
||||||
|
, ('metal3.minimalSpacing' , 0.07 )
|
||||||
|
, ('metal4.minimalSpacing' , 0.14 )
|
||||||
|
, ('metal5.minimalSpacing' , 0.14 )
|
||||||
|
, ('metal6.minimalSpacing' , 0.14 )
|
||||||
|
, ('metal7.minimalSpacing' , 0.4 )
|
||||||
|
, ('metal8.minimalSpacing' , 0.4 )
|
||||||
|
, ('metal9.minimalSpacing' , 0.8 )
|
||||||
|
, ('metal10.minimalSpacing' , 0.8 )
|
||||||
|
|
||||||
|
, ('NWELL.nWell.extention.cap' , 0.0)
|
||||||
, ('PWELL.pWell.extention.cap' , 0.0)
|
, ('PWELL.pWell.extention.cap' , 0.0)
|
||||||
|
|
||||||
, ('NTIE.minimum.width' , 3.0)
|
, ('NTIE.minimum.width' , 3.0)
|
||||||
|
@ -166,13 +177,15 @@ layersExtensionsTable = \
|
||||||
|
|
||||||
# VIAs (i.e. Metal <--> Metal) (real).
|
# VIAs (i.e. Metal <--> Metal) (real).
|
||||||
, ('via12.minimum.side' , 0.065)
|
, ('via12.minimum.side' , 0.065)
|
||||||
, ('via12.metal1.enclosure' , 0.0 )
|
# This is the rule as defined in LEF, but seems wrong to me.
|
||||||
, ('via12.metal2.enclosure' , 0.025)
|
#, ('via12.metal1.enclosure' , (0.035 , 0.0 ) )
|
||||||
|
, ('via12.metal1.enclosure' , (0.0 , 0.035) )
|
||||||
|
, ('via12.metal2.enclosure' , (0.0025, 0.035) )
|
||||||
, ('via23.minimum.side' , 0.070)
|
, ('via23.minimum.side' , 0.070)
|
||||||
, ('via23.metal2.enclosure' , 0.0 )
|
, ('via23.metal2.enclosure' , (0.0 , 0.035) )
|
||||||
, ('via23.metal3.enclosure' , 0.035)
|
, ('via23.metal3.enclosure' , (0.035 , 0.0 ) )
|
||||||
, ('via34.minimum.side' , 0.070)
|
, ('via34.minimum.side' , 0.070)
|
||||||
, ('via34.metal3.enclosure' , 0.0 )
|
, ('via34.metal3.enclosure' , (0.035, 0.0 ) )
|
||||||
, ('via34.metal4.enclosure' , 0.035)
|
, ('via34.metal4.enclosure' , 0.035)
|
||||||
, ('via45.minimum.side' , 0.140)
|
, ('via45.minimum.side' , 0.140)
|
||||||
, ('via45.metal4.enclosure' , 0.0 )
|
, ('via45.metal4.enclosure' , 0.0 )
|
||||||
|
|
|
@ -88,11 +88,11 @@ layersExtensionsTable = \
|
||||||
# Routing Layers.
|
# Routing Layers.
|
||||||
, ('METAL1.minimum.width' , 1.0)
|
, ('METAL1.minimum.width' , 1.0)
|
||||||
, ('METAL1.metal1.extention.cap' , 0.5)
|
, ('METAL1.metal1.extention.cap' , 0.5)
|
||||||
, ('METAL2.minimum.width' , 1.0)
|
, ('METAL2.minimum.width' , 2.0)
|
||||||
, ('METAL2.metal2.extention.cap' , 1.0)
|
, ('METAL2.metal2.extention.cap' , 1.0)
|
||||||
, ('METAL3.minimum.width' , 1.0)
|
, ('METAL3.minimum.width' , 2.0)
|
||||||
, ('METAL3.metal3.extention.cap' , 1.0)
|
, ('METAL3.metal3.extention.cap' , 1.0)
|
||||||
, ('METAL4.minimum.width' , 1.0)
|
, ('METAL4.minimum.width' , 2.0)
|
||||||
, ('METAL4.metal4.extention.cap' , 1.0)
|
, ('METAL4.metal4.extention.cap' , 1.0)
|
||||||
, ('METAL5.minimum.width' , 2.0)
|
, ('METAL5.minimum.width' , 2.0)
|
||||||
, ('METAL5.metal5.extention.cap' , 1.0)
|
, ('METAL5.metal5.extention.cap' , 1.0)
|
||||||
|
|
|
@ -147,16 +147,21 @@ def loadRoutingGaugesTable ( routingGaugesTable, fromFile ):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if len(entry) != 2:
|
if len(entry) != 2:
|
||||||
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
|
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
|
||||||
,'Must have exactly two fields ("METAL_LAYER", (parameters_list)).'
|
,'Must have exactly two fields ("METAL_LAYER", (parameters_list)).'
|
||||||
,str(entry)
|
,str(entry)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
if entry[0] == 'symbolic':
|
||||||
|
gauge.setSymbolic( entry[1] )
|
||||||
|
continue
|
||||||
|
|
||||||
if len(entry[1]) != 9:
|
if len(entry[1]) != 9:
|
||||||
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
|
raise ErrorMessage(1,['Malformed entry in <routingGaugesTable[%s]>.' % gaugeName
|
||||||
,'Parameters list must have exactly nine fields:'
|
,'Parameters list must have exactly nine fields:'
|
||||||
,' (direction, type, depth, density, offset, pitch, wire_width, via_width, obs_dw)'
|
,' (direction, type, depth, density, offset, pitch, wire_width, via_width, obs_dw)'
|
||||||
,str(entry)
|
,str(entry)
|
||||||
])
|
])
|
||||||
|
|
||||||
gauge.addLayerGauge( RoutingLayerGauge.create( technology.getLayer(entry[0])
|
gauge.addLayerGauge( RoutingLayerGauge.create( technology.getLayer(entry[0])
|
||||||
, Gauge.toRlGauge(entry[1][0]) # Direction.
|
, Gauge.toRlGauge(entry[1][0]) # Direction.
|
||||||
|
|
|
@ -216,36 +216,59 @@ def loadLayersExtensions ( layersExtensionsTable, confFile ):
|
||||||
,'Must contains exactly two fields: ( rule_path, value ).'
|
,'Must contains exactly two fields: ( rule_path, value ).'
|
||||||
,str(rule)
|
,str(rule)
|
||||||
])
|
])
|
||||||
if not isinstance(rule[1],int) and not isinstance(rule[1],float):
|
if not isinstance(rule[1],int) \
|
||||||
|
and not isinstance(rule[1],float) \
|
||||||
|
and not isinstance(rule[1],tuple):
|
||||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||||
,'Rule value must be of integer or float type.'
|
,'Rule value must be of integer, float, or pair a of those type.'
|
||||||
,str(rule)
|
,str(rule)
|
||||||
])
|
])
|
||||||
|
|
||||||
elements = rule[0].split('.')
|
elements = rule[0].split('.')
|
||||||
if len(elements) < 3:
|
if len(elements) == 2:
|
||||||
|
ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Real|LayersLUT.MissingError )
|
||||||
|
subLayer = None
|
||||||
|
elif len(elements) == 3 or len(elements) == 4:
|
||||||
|
ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Composite|LayersLUT.MissingError )
|
||||||
|
subLayer = layersLUT.lookup( elements[1], LayersLUT.Real )
|
||||||
|
else:
|
||||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||||
,'Rule name must contains at least three components: \"LAYER.category.dimension\".'
|
,'Rule name must contains two or three components:'
|
||||||
|
,' * \"COMP_LAYER.category.dimension\".'
|
||||||
|
,' * \"REAL_LAYER.dimension\".'
|
||||||
,str(rule)
|
,str(rule)
|
||||||
])
|
])
|
||||||
|
|
||||||
ruleLayer = layersLUT.lookup( elements[0], LayersLUT.Composite|LayersLUT.MissingError )
|
|
||||||
subLayer = layersLUT.lookup( elements[1], LayersLUT.Real )
|
|
||||||
|
|
||||||
if elements[0].startswith('via'): value = toDbU(rule[1])
|
if elements[0].startswith('via') or elements[0].startswith('metal'):
|
||||||
else: value = DbU.fromLambda(rule[1])
|
if isinstance(rule[1],tuple):
|
||||||
|
value = ( toDbU(rule[1][0]), toDbU(rule[1][1]) )
|
||||||
|
else:
|
||||||
|
value = toDbU(rule[1])
|
||||||
|
else:
|
||||||
|
if isinstance(rule[1],tuple):
|
||||||
|
value = ( DbU.fromLambda(rule[1][0]), DbU.fromLambda(rule[1][1]) )
|
||||||
|
else:
|
||||||
|
value = DbU.fromLambda(rule[1])
|
||||||
|
|
||||||
if subLayer: ruleTag = string.join(elements[2:],'.')
|
if subLayer: ruleTag = string.join(elements[2:],'.')
|
||||||
else: ruleTag = string.join(elements[1:],'.')
|
else: ruleTag = string.join(elements[1:],'.')
|
||||||
|
|
||||||
if ruleTag == 'extention.cap': ruleLayer.setExtentionCap ( subLayer, value )
|
if ruleTag == 'minimalSpacing': ruleLayer.setMinimalSpacing( value )
|
||||||
|
elif ruleTag == 'extention.cap': ruleLayer.setExtentionCap ( subLayer, value )
|
||||||
elif ruleTag == 'extention.width': ruleLayer.setExtentionWidth( subLayer, value )
|
elif ruleTag == 'extention.width': ruleLayer.setExtentionWidth( subLayer, value )
|
||||||
elif ruleTag == 'enclosure': ruleLayer.setEnclosure ( subLayer, value )
|
|
||||||
elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value )
|
elif ruleTag == 'minimum.width': ruleLayer.setMinimalSize ( value )
|
||||||
elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value )
|
elif ruleTag == 'minimum.side': ruleLayer.setMinimalSize ( value )
|
||||||
|
elif ruleTag == 'enclosure':
|
||||||
|
if isinstance(value,tuple):
|
||||||
|
ruleLayer.setEnclosure( subLayer, value[0], Layer.EnclosureH )
|
||||||
|
ruleLayer.setEnclosure( subLayer, value[1], Layer.EnclosureV )
|
||||||
|
else:
|
||||||
|
ruleLayer.setEnclosure( subLayer, value, Layer.EnclosureH|Layer.EnclosureV )
|
||||||
else:
|
else:
|
||||||
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
raise ErrorMessage(1,['Invalid entry in <layersExtensionsTable>.'
|
||||||
,'Unknown rule kind: \".%s\", should be any of:' % ruleTag
|
,'Unknown rule kind: \".%s\", should be any of:' % ruleTag
|
||||||
|
,' * "RULE_HEAD.minimalSpacing"'
|
||||||
,' * "RULE_HEAD.extention.cap"'
|
,' * "RULE_HEAD.extention.cap"'
|
||||||
,' * "RULE_HEAD.extention.width"'
|
,' * "RULE_HEAD.extention.width"'
|
||||||
,' * "RULE_HEAD.enclosure"'
|
,' * "RULE_HEAD.enclosure"'
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace CRL {
|
||||||
, _layerGauges()
|
, _layerGauges()
|
||||||
, _viaLayers ()
|
, _viaLayers ()
|
||||||
, _technology (DataBase::getDB()->getTechnology())
|
, _technology (DataBase::getDB()->getTechnology())
|
||||||
|
, _isSymbolic (true)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ namespace CRL {
|
||||||
, _layerGauges()
|
, _layerGauges()
|
||||||
, _viaLayers ()
|
, _viaLayers ()
|
||||||
, _technology (gauge._technology)
|
, _technology (gauge._technology)
|
||||||
|
, _isSymbolic (gauge._isSymbolic)
|
||||||
{
|
{
|
||||||
// Make a deep copy of the map.
|
// Make a deep copy of the map.
|
||||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ )
|
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ )
|
||||||
|
@ -283,8 +285,9 @@ namespace CRL {
|
||||||
if ( record == NULL )
|
if ( record == NULL )
|
||||||
record = new Record ( getString(this) );
|
record = new Record ( getString(this) );
|
||||||
|
|
||||||
record->add ( getSlot("_name" , _name ) );
|
record->add ( getSlot("_name" , _name ) );
|
||||||
record->add ( getSlot("_gauges" ,&_layerGauges) );
|
record->add ( getSlot("_gauges" ,&_layerGauges) );
|
||||||
|
record->add ( getSlot("_isSymbolic", _isSymbolic ) );
|
||||||
return ( record );
|
return ( record );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ namespace CRL {
|
||||||
switch ( ruleType ) {
|
switch ( ruleType ) {
|
||||||
case ExtentionCap: ruleLayer->setExtentionCap (basicLayer,DbU::lambda(doubleValue)); break;
|
case ExtentionCap: ruleLayer->setExtentionCap (basicLayer,DbU::lambda(doubleValue)); break;
|
||||||
case ExtentionWidth: ruleLayer->setExtentionWidth(basicLayer,DbU::lambda(doubleValue)); break;
|
case ExtentionWidth: ruleLayer->setExtentionWidth(basicLayer,DbU::lambda(doubleValue)); break;
|
||||||
case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue)); break;
|
case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue),Layer::EnclosureH|Layer::EnclosureV); break;
|
||||||
case MinimumWidth: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
|
case MinimumWidth: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
|
||||||
case MinimumSide: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
|
case MinimumSide: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace CRL {
|
||||||
static RoutingGauge* create ( const char* name );
|
static RoutingGauge* create ( const char* name );
|
||||||
virtual void destroy ();
|
virtual void destroy ();
|
||||||
// Predicates.
|
// Predicates.
|
||||||
|
inline bool isSymbolic () const;
|
||||||
inline bool isTwoMetals () const;
|
inline bool isTwoMetals () const;
|
||||||
inline bool isHV () const;
|
inline bool isHV () const;
|
||||||
inline bool isVH () const;
|
inline bool isVH () const;
|
||||||
|
@ -85,6 +86,7 @@ namespace CRL {
|
||||||
// Methods.
|
// Methods.
|
||||||
void addLayerGauge ( RoutingLayerGauge* layerGauge );
|
void addLayerGauge ( RoutingLayerGauge* layerGauge );
|
||||||
void checkConnexity () const;
|
void checkConnexity () const;
|
||||||
|
inline void setSymbolic ( bool );
|
||||||
// Hurricane Managment.
|
// Hurricane Managment.
|
||||||
void toJson ( JsonWriter* ) const;
|
void toJson ( JsonWriter* ) const;
|
||||||
virtual Record* _getRecord ( Record* record=NULL ) const;
|
virtual Record* _getRecord ( Record* record=NULL ) const;
|
||||||
|
@ -97,6 +99,7 @@ namespace CRL {
|
||||||
vector<RoutingLayerGauge*> _layerGauges;
|
vector<RoutingLayerGauge*> _layerGauges;
|
||||||
vector<Layer*> _viaLayers;
|
vector<Layer*> _viaLayers;
|
||||||
Technology* _technology;
|
Technology* _technology;
|
||||||
|
bool _isSymbolic;
|
||||||
|
|
||||||
// Internal - Constructors & Destructors.
|
// Internal - Constructors & Destructors.
|
||||||
RoutingGauge ( const char* name );
|
RoutingGauge ( const char* name );
|
||||||
|
@ -107,6 +110,7 @@ namespace CRL {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
|
||||||
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
|
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
|
||||||
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
||||||
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
||||||
|
@ -121,6 +125,7 @@ namespace CRL {
|
||||||
inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); }
|
inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); }
|
||||||
inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); }
|
inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); }
|
||||||
inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); }
|
inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); }
|
||||||
|
inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; }
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -358,6 +358,8 @@ extern "C" {
|
||||||
// Standard Attributes.
|
// Standard Attributes.
|
||||||
GetNameMethod(RoutingGauge,rg)
|
GetNameMethod(RoutingGauge,rg)
|
||||||
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
|
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
|
||||||
|
DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge)
|
||||||
|
DirectSetBoolAttribute(PyRoutingGauge_setSymbolic,setSymbolic,PyRoutingGauge,RoutingGauge)
|
||||||
|
|
||||||
|
|
||||||
// Standart Destroy (Attribute).
|
// Standart Destroy (Attribute).
|
||||||
|
@ -366,6 +368,8 @@ extern "C" {
|
||||||
PyMethodDef PyRoutingGauge_Methods[] =
|
PyMethodDef PyRoutingGauge_Methods[] =
|
||||||
{ { "create" , (PyCFunction)PyRoutingGauge_create , METH_VARARGS|METH_STATIC
|
{ { "create" , (PyCFunction)PyRoutingGauge_create , METH_VARARGS|METH_STATIC
|
||||||
, "Create a new RoutingGauge." }
|
, "Create a new RoutingGauge." }
|
||||||
|
, { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS
|
||||||
|
, "The RoutingGauge is for symbolic technology." }
|
||||||
, { "getName" , (PyCFunction)PyRoutingGauge_getName , METH_NOARGS
|
, { "getName" , (PyCFunction)PyRoutingGauge_getName , METH_NOARGS
|
||||||
, "Return the maximum depth of the RoutingGauge." }
|
, "Return the maximum depth of the RoutingGauge." }
|
||||||
, { "getTechnology" , (PyCFunction)PyRoutingGauge_getTechnology , METH_NOARGS
|
, { "getTechnology" , (PyCFunction)PyRoutingGauge_getTechnology , METH_NOARGS
|
||||||
|
@ -392,6 +396,8 @@ extern "C" {
|
||||||
, "Return the list of RoutingLayerGauge." }
|
, "Return the list of RoutingLayerGauge." }
|
||||||
, { "addLayerGauge" , (PyCFunction)PyRoutingGauge_addLayerGauge , METH_VARARGS
|
, { "addLayerGauge" , (PyCFunction)PyRoutingGauge_addLayerGauge , METH_VARARGS
|
||||||
, "Adds a new RoutingLayerGauge to the RoutingGauge." }
|
, "Adds a new RoutingLayerGauge to the RoutingGauge." }
|
||||||
|
, { "setSymbolic" , (PyCFunction)PyRoutingGauge_setSymbolic , METH_VARARGS
|
||||||
|
, "Set the symbolic technology state." }
|
||||||
//, { "destroy" , (PyCFunction)PyRoutingGauge_destroy , METH_VARARGS
|
//, { "destroy" , (PyCFunction)PyRoutingGauge_destroy , METH_VARARGS
|
||||||
// , "Destroy the associated hurricane object. The python object remains." }
|
// , "Destroy the associated hurricane object. The python object remains." }
|
||||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||||
|
|
|
@ -200,19 +200,21 @@ Point Contact::getPosition() const
|
||||||
Box Contact::getBoundingBox() const
|
Box Contact::getBoundingBox() const
|
||||||
// ********************************
|
// ********************************
|
||||||
{
|
{
|
||||||
DbU::Unit size = getLayer()->getEnclosure();
|
DbU::Unit enclosureH = getLayer()->getEnclosure( Layer::EnclosureH );
|
||||||
|
DbU::Unit enclosureV = getLayer()->getEnclosure( Layer::EnclosureV );
|
||||||
|
|
||||||
return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size);
|
return Box(getPosition()).inflate(getHalfWidth() + enclosureH, getHalfHeight() + enclosureV);
|
||||||
}
|
}
|
||||||
|
|
||||||
Box Contact::getBoundingBox(const BasicLayer* basicLayer) const
|
Box Contact::getBoundingBox(const BasicLayer* basicLayer) const
|
||||||
// ******************************************************
|
// ******************************************************
|
||||||
{
|
{
|
||||||
if (!_layer->contains(basicLayer)) return Box();
|
if (not _layer->contains(basicLayer)) return Box();
|
||||||
|
|
||||||
DbU::Unit size = getLayer()->getEnclosure(basicLayer);
|
DbU::Unit enclosureH = getLayer()->getEnclosure( basicLayer, Layer::EnclosureH );
|
||||||
|
DbU::Unit enclosureV = getLayer()->getEnclosure( basicLayer, Layer::EnclosureV );
|
||||||
|
|
||||||
return Box(getPosition()).inflate(getHalfWidth() + size, getHalfHeight() + size);
|
return Box(getPosition()).inflate(getHalfWidth() + enclosureH, getHalfHeight() + enclosureV );
|
||||||
}
|
}
|
||||||
|
|
||||||
Component* Contact::getAnchor() const
|
Component* Contact::getAnchor() const
|
||||||
|
|
|
@ -69,39 +69,37 @@ namespace Hurricane {
|
||||||
,_enclosures()
|
,_enclosures()
|
||||||
,_maximalEnclosure(0)
|
,_maximalEnclosure(0)
|
||||||
{
|
{
|
||||||
if ( !metalLayer ) throw Error ( nullLayer, getString(name).c_str(), "Metal" );
|
if (not metalLayer ) throw Error ( nullLayer, getString(name).c_str(), "Metal" );
|
||||||
if ( !cutLayer ) throw Error ( nullLayer, getString(name).c_str(), "Cut" );
|
if (not cutLayer ) throw Error ( nullLayer, getString(name).c_str(), "Cut" );
|
||||||
if ( !activeLayer ) throw Error ( nullLayer, getString(name).c_str(), "Active" );
|
if (not activeLayer ) throw Error ( nullLayer, getString(name).c_str(), "Active" );
|
||||||
if ( !diffusionLayer ) throw Error ( nullLayer, getString(name).c_str(), "Diffusion" );
|
if (not diffusionLayer) throw Error ( nullLayer, getString(name).c_str(), "Diffusion" );
|
||||||
|
|
||||||
_basicLayers.reserve ( 5 );
|
_basicLayers.reserve( 5 );
|
||||||
_enclosures .reserve ( 5 );
|
_enclosures .reserve( 5 );
|
||||||
|
|
||||||
// Have to check wich one is top layer & cutLayer of type cut.
|
// Have to check wich one is top layer & cutLayer of type cut.
|
||||||
_basicLayers.push_back ( metalLayer );
|
_basicLayers.push_back( metalLayer );
|
||||||
_basicLayers.push_back ( cutLayer );
|
_basicLayers.push_back( cutLayer );
|
||||||
_basicLayers.push_back ( activeLayer );
|
_basicLayers.push_back( activeLayer );
|
||||||
_basicLayers.push_back ( diffusionLayer );
|
_basicLayers.push_back( diffusionLayer );
|
||||||
|
|
||||||
for ( size_t i=0 ; i<4 ; i++ ) {
|
for ( size_t i=0 ; i<4 ; i++ ) _enclosures.push_back( make_pair(0,0) );
|
||||||
_enclosures.push_back ( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
_setMask ( metalLayer ->getMask()
|
_setMask ( metalLayer ->getMask()
|
||||||
| cutLayer ->getMask()
|
| cutLayer ->getMask()
|
||||||
| activeLayer ->getMask()
|
| activeLayer ->getMask()
|
||||||
| diffusionLayer->getMask() );
|
| diffusionLayer->getMask() );
|
||||||
_setExtractMask ( metalLayer ->getExtractMask()
|
_setExtractMask( metalLayer ->getExtractMask()
|
||||||
| cutLayer ->getExtractMask()
|
| cutLayer ->getExtractMask()
|
||||||
| activeLayer ->getExtractMask()
|
| activeLayer ->getExtractMask()
|
||||||
| diffusionLayer->getExtractMask() );
|
| diffusionLayer->getExtractMask() );
|
||||||
|
|
||||||
if ( wellLayer ) {
|
if (wellLayer) {
|
||||||
_basicLayers.push_back ( wellLayer );
|
_basicLayers.push_back( wellLayer );
|
||||||
_enclosures .push_back ( 0 );
|
_enclosures .push_back( make_pair(0,0) );
|
||||||
|
|
||||||
_setMask ( getMask() | wellLayer->getMask() );
|
_setMask ( getMask() | wellLayer->getMask() );
|
||||||
_setExtractMask ( getMask() | wellLayer->getExtractMask() );
|
_setExtractMask( getMask() | wellLayer->getExtractMask() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,38 +132,61 @@ namespace Hurricane {
|
||||||
{ return getCollection(_basicLayers); }
|
{ return getCollection(_basicLayers); }
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit ContactLayer::getEnclosure () const
|
DbU::Unit ContactLayer::getEnclosure ( uint32_t flags ) const
|
||||||
{ return _maximalEnclosure; }
|
{
|
||||||
|
if (flags & (Layer::EnclosureH|Layer::EnclosureV)) return _maximalEnclosure;
|
||||||
|
|
||||||
|
DbU::Unit enclosure = 0;
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.first );
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) {
|
||||||
|
for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.second );
|
||||||
|
}
|
||||||
|
|
||||||
|
return enclosure;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit ContactLayer::getEnclosure ( const BasicLayer* layer ) const
|
DbU::Unit ContactLayer::getEnclosure ( const BasicLayer* layer, uint32_t flags ) const
|
||||||
{
|
{
|
||||||
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
||||||
if ( _basicLayers[i] == layer )
|
if ( _basicLayers[i] == layer ) {
|
||||||
return _enclosures[i];
|
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
if (flags & Layer::EnclosureV) return std::max( _enclosures[i].first, _enclosures[i].second );
|
||||||
|
return _enclosures[i].first;
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) return _enclosures[i].second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ContactLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure )
|
void ContactLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags )
|
||||||
{
|
{
|
||||||
|
_maximalEnclosure = 0;
|
||||||
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
||||||
if ( _basicLayers[i] == layer ) {
|
if ( _basicLayers[i] == layer ) {
|
||||||
_enclosures[i] = enclosure;
|
if (flags & Layer::EnclosureH) _enclosures[i].first = enclosure;
|
||||||
_maximalEnclosure = max ( _maximalEnclosure, enclosure );
|
if (flags & Layer::EnclosureV) _enclosures[i].second = enclosure;
|
||||||
}
|
}
|
||||||
|
_maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].first );
|
||||||
|
_maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].second );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ContactLayer::_onDbuChange ( float scale )
|
void ContactLayer::_onDbuChange ( float scale )
|
||||||
{
|
{
|
||||||
Layer::_onDbuChange ( scale );
|
Layer::_onDbuChange( scale );
|
||||||
for ( size_t i=0 ; i<_enclosures.size() ; i++ )
|
for ( size_t i=0 ; i<_enclosures.size() ; i++ ) {
|
||||||
_enclosures[i] = (DbU::Unit)( (float)_enclosures[i] * scale );
|
_enclosures[i].first = (DbU::Unit)( (float)_enclosures[i].first * scale );
|
||||||
_maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale );
|
_enclosures[i].second = (DbU::Unit)( (float)_enclosures[i].second * scale );
|
||||||
|
}
|
||||||
|
_maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,11 +223,16 @@ namespace Hurricane {
|
||||||
if (_basicLayers.size() == 5) jsonWrite( w, "_well", _basicLayers[4]->getName() );
|
if (_basicLayers.size() == 5) jsonWrite( w, "_well", _basicLayers[4]->getName() );
|
||||||
else jsonWrite( w, "_well", "no_well_layer" );
|
else jsonWrite( w, "_well", "no_well_layer" );
|
||||||
|
|
||||||
jsonWrite( w, "_enclosure.metal" , _enclosures[0] );
|
jsonWrite( w, "_enclosureH.metal" , _enclosures[0].first );
|
||||||
jsonWrite( w, "_enclosure.cut" , _enclosures[1] );
|
jsonWrite( w, "_enclosureV.metal" , _enclosures[0].second );
|
||||||
jsonWrite( w, "_enclosure.active" , _enclosures[2] );
|
jsonWrite( w, "_enclosureH.cut" , _enclosures[1].first );
|
||||||
jsonWrite( w, "_enclosure.diffusion", _enclosures[3] );
|
jsonWrite( w, "_enclosureV.cut" , _enclosures[1].second );
|
||||||
jsonWrite( w, "_enclosure.well" , (_basicLayers.size() == 5) ? _enclosures[4] : 0 );
|
jsonWrite( w, "_enclosureH.active" , _enclosures[2].first );
|
||||||
|
jsonWrite( w, "_enclosureV.active" , _enclosures[2].second );
|
||||||
|
jsonWrite( w, "_enclosureH.diffusion", _enclosures[3].first );
|
||||||
|
jsonWrite( w, "_enclosureV.diffusion", _enclosures[3].second );
|
||||||
|
jsonWrite( w, "_enclosureH.well" , (_basicLayers.size() == 5) ? _enclosures[4].first : 0 );
|
||||||
|
jsonWrite( w, "_enclosureV.well" , (_basicLayers.size() == 5) ? _enclosures[4].second : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,16 +253,21 @@ namespace Hurricane {
|
||||||
|
|
||||||
cdebug_log(19,0) << "JsonContactLayer::JsonContactLayer()" << endl;
|
cdebug_log(19,0) << "JsonContactLayer::JsonContactLayer()" << endl;
|
||||||
|
|
||||||
add( "_metal" , typeid(string) );
|
add( "_metal" , typeid(string) );
|
||||||
add( "_cut" , typeid(string) );
|
add( "_cut" , typeid(string) );
|
||||||
add( "_active" , typeid(string) );
|
add( "_active" , typeid(string) );
|
||||||
add( "_diffusion" , typeid(string) );
|
add( "_diffusion" , typeid(string) );
|
||||||
add( "_well" , typeid(string) );
|
add( "_well" , typeid(string) );
|
||||||
add( "_enclosure.metal" , typeid(int64_t) );
|
add( "_enclosureH.metal" , typeid(int64_t) );
|
||||||
add( "_enclosure.cut" , typeid(int64_t) );
|
add( "_enclosureV.metal" , typeid(int64_t) );
|
||||||
add( "_enclosure.active" , typeid(int64_t) );
|
add( "_enclosureH.cut" , typeid(int64_t) );
|
||||||
add( "_enclosure.diffusion", typeid(int64_t) );
|
add( "_enclosureV.cut" , typeid(int64_t) );
|
||||||
add( "_enclosure.well" , typeid(int64_t) );
|
add( "_enclosureH.active" , typeid(int64_t) );
|
||||||
|
add( "_enclosureV.active" , typeid(int64_t) );
|
||||||
|
add( "_enclosureH.diffusion", typeid(int64_t) );
|
||||||
|
add( "_enclosureV.diffusion", typeid(int64_t) );
|
||||||
|
add( "_enclosureH.well" , typeid(int64_t) );
|
||||||
|
add( "_enclosureV.well" , typeid(int64_t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,11 +304,16 @@ namespace Hurricane {
|
||||||
BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
|
BasicLayer* active = techno->getBasicLayer( get<string>(stack,"_active" ) );
|
||||||
BasicLayer* diffusion = techno->getBasicLayer( get<string>(stack,"_diffusion") );
|
BasicLayer* diffusion = techno->getBasicLayer( get<string>(stack,"_diffusion") );
|
||||||
BasicLayer* well = techno->getBasicLayer( get<string>(stack,"_well" ) );
|
BasicLayer* well = techno->getBasicLayer( get<string>(stack,"_well" ) );
|
||||||
DbU::Unit metalEncl = get<int64_t>( stack, "_enclosure.metal" );
|
DbU::Unit metalEnclH = get<int64_t>( stack, "_enclosureH.metal" );
|
||||||
DbU::Unit cutEncl = get<int64_t>( stack, "_enclosure.cut" );
|
DbU::Unit metalEnclV = get<int64_t>( stack, "_enclosureV.metal" );
|
||||||
DbU::Unit activeEncl = get<int64_t>( stack, "_enclosure.active" );
|
DbU::Unit cutEnclH = get<int64_t>( stack, "_enclosureH.cut" );
|
||||||
DbU::Unit diffusionEncl = get<int64_t>( stack, "_enclosure.diffusion" );
|
DbU::Unit cutEnclV = get<int64_t>( stack, "_enclosureV.cut" );
|
||||||
DbU::Unit wellEncl = get<int64_t>( stack, "_enclosure.well" );
|
DbU::Unit activeEnclH = get<int64_t>( stack, "_enclosureH.active" );
|
||||||
|
DbU::Unit activeEnclV = get<int64_t>( stack, "_enclosureV.active" );
|
||||||
|
DbU::Unit diffusionEnclH = get<int64_t>( stack, "_enclosureH.diffusion" );
|
||||||
|
DbU::Unit diffusionEnclV = get<int64_t>( stack, "_enclosureV.diffusion" );
|
||||||
|
DbU::Unit wellEnclH = get<int64_t>( stack, "_enclosureH.well" );
|
||||||
|
DbU::Unit wellEnclV = get<int64_t>( stack, "_enclosureV.well" );
|
||||||
|
|
||||||
Layer::Mask mask = Layer::Mask::fromString( smask );
|
Layer::Mask mask = Layer::Mask::fromString( smask );
|
||||||
|
|
||||||
|
@ -292,11 +328,18 @@ namespace Hurricane {
|
||||||
, well
|
, well
|
||||||
);
|
);
|
||||||
layer->setSymbolic ( isSymbolic );
|
layer->setSymbolic ( isSymbolic );
|
||||||
layer->setEnclosure( metal , metalEncl );
|
layer->setEnclosure( metal , metalEnclH , Layer::EnclosureH );
|
||||||
layer->setEnclosure( cut , cutEncl );
|
layer->setEnclosure( metal , metalEnclV , Layer::EnclosureV );
|
||||||
layer->setEnclosure( active , activeEncl );
|
layer->setEnclosure( cut , cutEnclH , Layer::EnclosureH );
|
||||||
layer->setEnclosure( diffusion, diffusionEncl );
|
layer->setEnclosure( cut , cutEnclV , Layer::EnclosureV );
|
||||||
if (well) layer->setEnclosure( well, wellEncl );
|
layer->setEnclosure( active , activeEnclH , Layer::EnclosureH );
|
||||||
|
layer->setEnclosure( active , activeEnclV , Layer::EnclosureV );
|
||||||
|
layer->setEnclosure( diffusion, diffusionEnclH, Layer::EnclosureH );
|
||||||
|
layer->setEnclosure( diffusion, diffusionEnclV, Layer::EnclosureV );
|
||||||
|
if (well) {
|
||||||
|
layer->setEnclosure( well, wellEnclH, Layer::EnclosureH );
|
||||||
|
layer->setEnclosure( well, wellEnclV, Layer::EnclosureV );
|
||||||
|
}
|
||||||
|
|
||||||
if (layer->getMask() != mask) {
|
if (layer->getMask() != mask) {
|
||||||
cerr << Error( "JsonContactLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n"
|
cerr << Error( "JsonContactLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n"
|
||||||
|
|
|
@ -66,21 +66,21 @@ namespace Hurricane {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
DbUSlot ( const string& name, const DbU::Unit* data );
|
DbUSlot ( const string& name, const DbU::Unit* data );
|
||||||
DbUSlot ( string& name, const DbU::Unit* data );
|
DbUSlot ( string& name, const DbU::Unit* data );
|
||||||
// Accessors.
|
// Accessors.
|
||||||
virtual string getDataString () const;
|
virtual string getDataString () const;
|
||||||
virtual Record* getDataRecord () const;
|
virtual Record* getDataRecord () const;
|
||||||
virtual DbUSlot* getClone () const;
|
virtual DbUSlot* getClone () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal: Attributes.
|
// Internal: Attributes.
|
||||||
const DbU::Unit* _unit;
|
const DbU::Unit* _unit;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal: Constructors.
|
// Internal: Constructors.
|
||||||
DbUSlot ( const DbUSlot& );
|
DbUSlot ( const DbUSlot& );
|
||||||
DbUSlot& operator= ( const DbUSlot& );
|
DbUSlot& operator= ( const DbUSlot& );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ namespace Hurricane {
|
||||||
case Min: os << "MIN:"; break;
|
case Min: os << "MIN:"; break;
|
||||||
case Max: os << "MAX:"; break;
|
case Max: os << "MAX:"; break;
|
||||||
default:
|
default:
|
||||||
os << setprecision(3) << toPhysical(u,_stringModeUnitPower);
|
os << setprecision(4) << toPhysical(u,_stringModeUnitPower);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_stringMode != Db)
|
if (_stringMode != Db)
|
||||||
|
|
|
@ -100,7 +100,15 @@ namespace Hurricane {
|
||||||
{ return _technology->getCutBelow(this,useSymbolic); }
|
{ return _technology->getCutBelow(this,useSymbolic); }
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit Layer::getEnclosure () const
|
DbU::Unit Layer::getEnclosure ( uint32_t ) const
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit Layer::getTopEnclosure ( uint32_t ) const
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit Layer::getBottomEnclosure ( uint32_t ) const
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,15 +120,15 @@ namespace Hurricane {
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit Layer::getEnclosure ( const BasicLayer* layer ) const
|
DbU::Unit Layer::getEnclosure ( const BasicLayer*, uint32_t ) const
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit Layer::getExtentionCap ( const BasicLayer* layer ) const
|
DbU::Unit Layer::getExtentionCap ( const BasicLayer* ) const
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit Layer::getExtentionWidth ( const BasicLayer* layer ) const
|
DbU::Unit Layer::getExtentionWidth ( const BasicLayer* ) const
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,7 +172,7 @@ namespace Hurricane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Layer::setEnclosure ( const BasicLayer* layer, DbU::Unit )
|
void Layer::setEnclosure ( const BasicLayer*, DbU::Unit, uint32_t )
|
||||||
{
|
{
|
||||||
cerr << "[WARNING] Layer::setEnclosure() musn't be called on "
|
cerr << "[WARNING] Layer::setEnclosure() musn't be called on "
|
||||||
<< _getTypeName() << ": dummy implementation." << endl;
|
<< _getTypeName() << ": dummy implementation." << endl;
|
||||||
|
|
|
@ -312,15 +312,17 @@ namespace Hurricane {
|
||||||
|
|
||||||
Occurrence RoutingPad::getPlugOccurrence ()
|
Occurrence RoutingPad::getPlugOccurrence ()
|
||||||
{
|
{
|
||||||
if (dynamic_cast<Plug*>(_occurrence.getEntity()))
|
if (dynamic_cast<Plug*>(_occurrence.getEntity())) return _occurrence;
|
||||||
return _occurrence;
|
|
||||||
|
|
||||||
Component* component = static_cast<Component*>(_occurrence.getEntity());
|
Component* component = static_cast<Component*>(_occurrence.getEntity());
|
||||||
Net* net = component->getNet();
|
Net* net = component->getNet();
|
||||||
Path path = _occurrence.getPath();
|
Path path = _occurrence.getPath();
|
||||||
|
|
||||||
if ( path.isEmpty() )
|
if (path.isEmpty())
|
||||||
throw Error("Empty Path => not in an instance");
|
throw Error( "RoutingPad::getPlugOccurrence(): Empty Path, *not* in an instance for\n"
|
||||||
|
" %s"
|
||||||
|
, getString(this).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
Instance* instance = path.getTailInstance();
|
Instance* instance = path.getTailInstance();
|
||||||
Plug* plug = instance->getPlug(net);
|
Plug* plug = instance->getPlug(net);
|
||||||
|
|
|
@ -95,9 +95,9 @@ namespace Hurricane {
|
||||||
| cutLayer ->getExtractMask()
|
| cutLayer ->getExtractMask()
|
||||||
| topLayer ->getExtractMask() );
|
| topLayer ->getExtractMask() );
|
||||||
|
|
||||||
_enclosures.push_back ( 0 );
|
_enclosures.push_back ( make_pair(0,0) );
|
||||||
_enclosures.push_back ( 0 );
|
_enclosures.push_back ( make_pair(0,0) );
|
||||||
_enclosures.push_back ( 0 );
|
_enclosures.push_back ( make_pair(0,0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,40 +141,82 @@ namespace Hurricane {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit ViaLayer::getEnclosure () const
|
DbU::Unit ViaLayer::getEnclosure ( uint32_t flags ) const
|
||||||
{
|
{
|
||||||
return _maximalEnclosure;
|
if (flags & (Layer::EnclosureH|Layer::EnclosureV)) return _maximalEnclosure;
|
||||||
|
|
||||||
|
DbU::Unit enclosure = 0;
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.first );
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) {
|
||||||
|
for ( auto element : _enclosures ) enclosure = std::max( enclosure, element.second );
|
||||||
|
}
|
||||||
|
|
||||||
|
return enclosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DbU::Unit ViaLayer::getEnclosure ( const BasicLayer* layer ) const
|
DbU::Unit ViaLayer::getEnclosure ( const BasicLayer* layer, uint32_t flags ) const
|
||||||
{
|
{
|
||||||
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
||||||
if ( layer == _basicLayers[i] ) return _enclosures[i];
|
if ( _basicLayers[i] == layer ) {
|
||||||
|
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
if (flags & Layer::EnclosureV) return std::max( _enclosures[i].first, _enclosures[i].second );
|
||||||
|
return _enclosures[i].first;
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) return _enclosures[i].second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViaLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure )
|
DbU::Unit ViaLayer::getTopEnclosure ( uint32_t flags ) const
|
||||||
{
|
{
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
if (flags & Layer::EnclosureV) return std::max( _enclosures[2].first, _enclosures[2].second );
|
||||||
|
return _enclosures[2].first;
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) return _enclosures[2].second;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit ViaLayer::getBottomEnclosure ( uint32_t flags ) const
|
||||||
|
{
|
||||||
|
if (flags & Layer::EnclosureH) {
|
||||||
|
if (flags & Layer::EnclosureV) return std::max( _enclosures[0].first, _enclosures[0].second );
|
||||||
|
return _enclosures[0].first;
|
||||||
|
}
|
||||||
|
if (flags & Layer::EnclosureV) return _enclosures[0].second;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ViaLayer::setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags )
|
||||||
|
{
|
||||||
|
_maximalEnclosure = 0;
|
||||||
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
for ( size_t i=0 ; i<_basicLayers.size() ; i++ ) {
|
||||||
if ( layer == _basicLayers[i] ) {
|
if ( _basicLayers[i] == layer ) {
|
||||||
_enclosures[i] = enclosure;
|
if (flags & Layer::EnclosureH) _enclosures[i].first = enclosure;
|
||||||
_maximalEnclosure = max ( _maximalEnclosure, enclosure );
|
if (flags & Layer::EnclosureV) _enclosures[i].second = enclosure;
|
||||||
}
|
}
|
||||||
|
_maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].first );
|
||||||
|
_maximalEnclosure = std::max( _maximalEnclosure, _enclosures[i].second );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViaLayer::_onDbuChange ( float scale )
|
void ViaLayer::_onDbuChange ( float scale )
|
||||||
{
|
{
|
||||||
Layer::_onDbuChange ( scale );
|
Layer::_onDbuChange( scale );
|
||||||
|
for ( size_t i=0 ; i<_enclosures.size() ; i++ ) {
|
||||||
for ( size_t i=0 ; i<_enclosures.size() ; i++ )
|
_enclosures[i].first = (DbU::Unit)( (float)_enclosures[i].first * scale );
|
||||||
_enclosures[i] = (DbU::Unit)( (float)_enclosures[i] * scale );
|
_enclosures[i].second = (DbU::Unit)( (float)_enclosures[i].second * scale );
|
||||||
|
}
|
||||||
_maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale );
|
_maximalEnclosure = (DbU::Unit)( (float)_maximalEnclosure * scale );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,9 +251,12 @@ namespace Hurricane {
|
||||||
jsonWrite( w, "_cut" , _basicLayers[1]->getName() );
|
jsonWrite( w, "_cut" , _basicLayers[1]->getName() );
|
||||||
jsonWrite( w, "_top" , _basicLayers[2]->getName() );
|
jsonWrite( w, "_top" , _basicLayers[2]->getName() );
|
||||||
|
|
||||||
jsonWrite( w, "_enclosure.bottom", _enclosures[0] );
|
jsonWrite( w, "_enclosureH.bottom", _enclosures[0].first );
|
||||||
jsonWrite( w, "_enclosure.cut" , _enclosures[1] );
|
jsonWrite( w, "_enclosureV.bottom", _enclosures[0].second );
|
||||||
jsonWrite( w, "_enclosure.top" , _enclosures[2] );
|
jsonWrite( w, "_enclosureH.cut" , _enclosures[1].first );
|
||||||
|
jsonWrite( w, "_enclosureV.cut" , _enclosures[1].second );
|
||||||
|
jsonWrite( w, "_enclosureH.top" , _enclosures[2].first );
|
||||||
|
jsonWrite( w, "_enclosureV.top" , _enclosures[2].second );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -232,12 +277,15 @@ namespace Hurricane {
|
||||||
|
|
||||||
cdebug_log(19,0) << "JsonViaLayer::JsonViaLayer()" << endl;
|
cdebug_log(19,0) << "JsonViaLayer::JsonViaLayer()" << endl;
|
||||||
|
|
||||||
add( "_bottom" , typeid(string) );
|
add( "_bottom" , typeid(string) );
|
||||||
add( "_cut" , typeid(string) );
|
add( "_cut" , typeid(string) );
|
||||||
add( "_top" , typeid(string) );
|
add( "_top" , typeid(string) );
|
||||||
add( "_enclosure.bottom", typeid(int64_t) );
|
add( "_enclosureH.bottom", typeid(int64_t) );
|
||||||
add( "_enclosure.cut" , typeid(int64_t) );
|
add( "_enclosureV.bottom", typeid(int64_t) );
|
||||||
add( "_enclosure.top" , typeid(int64_t) );
|
add( "_enclosureH.cut" , typeid(int64_t) );
|
||||||
|
add( "_enclosureV.cut" , typeid(int64_t) );
|
||||||
|
add( "_enclosureH.top" , typeid(int64_t) );
|
||||||
|
add( "_enclosureV.top" , typeid(int64_t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,9 +320,12 @@ namespace Hurricane {
|
||||||
BasicLayer* bottom = techno->getBasicLayer( get<string>(stack,"_bottom" ) );
|
BasicLayer* bottom = techno->getBasicLayer( get<string>(stack,"_bottom" ) );
|
||||||
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
|
BasicLayer* cut = techno->getBasicLayer( get<string>(stack,"_cut" ) );
|
||||||
BasicLayer* top = techno->getBasicLayer( get<string>(stack,"_top" ) );
|
BasicLayer* top = techno->getBasicLayer( get<string>(stack,"_top" ) );
|
||||||
DbU::Unit bottomEncl = get<int64_t>( stack, "_enclosure.bottom" );
|
DbU::Unit bottomEnclH = get<int64_t>( stack, "_enclosureH.bottom" );
|
||||||
DbU::Unit cutEncl = get<int64_t>( stack, "_enclosure.cut" );
|
DbU::Unit bottomEnclV = get<int64_t>( stack, "_enclosureV.bottom" );
|
||||||
DbU::Unit topEncl = get<int64_t>( stack, "_enclosure.top" );
|
DbU::Unit cutEnclH = get<int64_t>( stack, "_enclosureH.cut" );
|
||||||
|
DbU::Unit cutEnclV = get<int64_t>( stack, "_enclosureV.cut" );
|
||||||
|
DbU::Unit topEnclH = get<int64_t>( stack, "_enclosureH.top" );
|
||||||
|
DbU::Unit topEnclV = get<int64_t>( stack, "_enclosureV.top" );
|
||||||
|
|
||||||
Layer::Mask mask = Layer::Mask::fromString( smask );
|
Layer::Mask mask = Layer::Mask::fromString( smask );
|
||||||
|
|
||||||
|
@ -287,9 +338,12 @@ namespace Hurricane {
|
||||||
, top
|
, top
|
||||||
);
|
);
|
||||||
layer->setSymbolic ( isSymbolic );
|
layer->setSymbolic ( isSymbolic );
|
||||||
layer->setEnclosure( bottom, bottomEncl );
|
layer->setEnclosure( bottom, bottomEnclH , Layer::EnclosureH );
|
||||||
layer->setEnclosure( cut , cutEncl );
|
layer->setEnclosure( bottom, bottomEnclV , Layer::EnclosureV );
|
||||||
layer->setEnclosure( top , topEncl );
|
layer->setEnclosure( cut , cutEnclH , Layer::EnclosureH );
|
||||||
|
layer->setEnclosure( cut , cutEnclV , Layer::EnclosureV );
|
||||||
|
layer->setEnclosure( top , topEnclH , Layer::EnclosureH );
|
||||||
|
layer->setEnclosure( top , topEnclV , Layer::EnclosureV );
|
||||||
|
|
||||||
if (layer->getMask() != mask) {
|
if (layer->getMask() != mask) {
|
||||||
cerr << Error( "JsonViaLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n"
|
cerr << Error( "JsonViaLayer::toData(): Layer mask re-creation discrepency on \"%s\":\n"
|
||||||
|
|
|
@ -329,6 +329,45 @@ template<typename Data> inline Hurricane::Record* getRecord ( Data data )
|
||||||
{ return NULL; }
|
{ return NULL; }
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Inspector Support for : "[const] std::pair<T,U>&".
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
inline std::string getString ( const std::pair<T,U>& p )
|
||||||
|
{
|
||||||
|
return "const std::pair<T,U>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
inline Hurricane::Record* getRecord ( const std::pair<T,U>& p )
|
||||||
|
{
|
||||||
|
Hurricane::Record* record = NULL;
|
||||||
|
record = new Hurricane::Record ( "const std::pair<T,U>" );
|
||||||
|
record->add( getSlot<T>("first" , &p.first ) );
|
||||||
|
record->add( getSlot<U>("second", &p.second) );
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
inline std::string getString ( std::pair<T,U>& p )
|
||||||
|
{
|
||||||
|
return "std::pair<T,U>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
inline Hurricane::Record* getRecord ( std::pair<T,U>& p )
|
||||||
|
{
|
||||||
|
Hurricane::Record* record = NULL;
|
||||||
|
record = new Hurricane::Record ( "std::pair<T,U>" );
|
||||||
|
record->add( getSlot<T>("first" , &p.first ) );
|
||||||
|
record->add( getSlot<U>("second", &p.second) );
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Inspector Support for : "[const] std::array<Element>*".
|
// Inspector Support for : "[const] std::array<Element>*".
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,10 @@ namespace Hurricane {
|
||||||
);
|
);
|
||||||
// Accessors.
|
// Accessors.
|
||||||
virtual BasicLayers getBasicLayers () const;
|
virtual BasicLayers getBasicLayers () const;
|
||||||
virtual DbU::Unit getEnclosure () const;
|
virtual DbU::Unit getEnclosure ( uint32_t flags ) const;
|
||||||
virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const;
|
virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const;
|
||||||
// Updators.
|
// Updators.
|
||||||
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure );
|
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags );
|
||||||
// Hurricane Managment.
|
// Hurricane Managment.
|
||||||
virtual void _toJson ( JsonWriter* ) const;
|
virtual void _toJson ( JsonWriter* ) const;
|
||||||
virtual void _onDbuChange ( float scale );
|
virtual void _onDbuChange ( float scale );
|
||||||
|
@ -72,9 +72,9 @@ namespace Hurricane {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal: Attributes
|
// Internal: Attributes
|
||||||
vector<BasicLayer*> _basicLayers;
|
vector<BasicLayer*> _basicLayers;
|
||||||
vector<DbU::Unit> _enclosures;
|
vector< pair<DbU::Unit,DbU::Unit> > _enclosures;
|
||||||
DbU::Unit _maximalEnclosure;
|
DbU::Unit _maximalEnclosure;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ContactLayer ( Technology* technology
|
ContactLayer ( Technology* technology
|
||||||
|
|
|
@ -187,4 +187,43 @@ namespace Hurricane {
|
||||||
// { w->key( key ); w->write( value ); }
|
// { w->key( key ); w->write( value ); }
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline std::string getString ( const std::pair<Hurricane::DbU::Unit,Hurricane::DbU::Unit>& p )
|
||||||
|
{
|
||||||
|
return "const std::pair<DbU::Unit,DbU::Unit>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Hurricane::Record* getRecord ( const std::pair<Hurricane::DbU::Unit,Hurricane::DbU::Unit>& p )
|
||||||
|
{
|
||||||
|
Hurricane::Record* record = NULL;
|
||||||
|
record = new Hurricane::Record ( "const std::pair<DbU::Unit,DbU::Unit>" );
|
||||||
|
record->add( Hurricane::DbU::getValueSlot("first" , &p.first ) );
|
||||||
|
record->add( Hurricane::DbU::getValueSlot("second", &p.second) );
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline std::string getString ( const std::array<Hurricane::DbU::Unit*,3>& a )
|
||||||
|
{
|
||||||
|
return "const array<DbU::Unit*,3>";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline Hurricane::Record* getRecord ( const std::array<Hurricane::DbU::Unit*,3>& a )
|
||||||
|
{
|
||||||
|
Hurricane::Record* record = NULL;
|
||||||
|
record = new Hurricane::Record ( "const array<DbU::Unit*,3>" );
|
||||||
|
|
||||||
|
for ( size_t i=0 ; i<a.size() ; ++i ) {
|
||||||
|
std::string label = "[" + getString(i) + "] ";
|
||||||
|
record->add( Hurricane::DbU::getValueSlot(label, a[i]) );
|
||||||
|
}
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // HURRICANE_DBU_H
|
#endif // HURRICANE_DBU_H
|
||||||
|
|
|
@ -63,7 +63,7 @@ class Interval {
|
||||||
public: DbU::Unit& getVMin() {return _vMin;};
|
public: DbU::Unit& getVMin() {return _vMin;};
|
||||||
public: DbU::Unit& getVMax() {return _vMax;};
|
public: DbU::Unit& getVMax() {return _vMax;};
|
||||||
public: DbU::Unit getCenter() const {return ((_vMin + _vMax) / 2);};
|
public: DbU::Unit getCenter() const {return ((_vMin + _vMax) / 2);};
|
||||||
public: DbU::Unit getSize() const {return (isEmpty() ? 0 : (_vMax - _vMin));};
|
public: DbU::Unit getSize() const;
|
||||||
public: DbU::Unit getHalfSize() const {return (getSize() / 2);};
|
public: DbU::Unit getHalfSize() const {return (getSize() / 2);};
|
||||||
public: Interval getUnion(const Interval& interval) const;
|
public: Interval getUnion(const Interval& interval) const;
|
||||||
public: Interval getIntersection(const Interval& interval) const;
|
public: Interval getIntersection(const Interval& interval) const;
|
||||||
|
@ -72,6 +72,7 @@ class Interval {
|
||||||
// **********
|
// **********
|
||||||
|
|
||||||
public: bool isEmpty() const { return (_vMax < _vMin);};
|
public: bool isEmpty() const { return (_vMax < _vMin);};
|
||||||
|
public: bool isFull() const { return (_vMin == DbU::Min) and (_vMax == DbU::Max); };
|
||||||
public: bool isPonctual() const { return (_vMax == _vMin);};
|
public: bool isPonctual() const { return (_vMax == _vMin);};
|
||||||
public: bool contains(const DbU::Unit& v) const;
|
public: bool contains(const DbU::Unit& v) const;
|
||||||
public: bool contains(const Interval& interval) const;
|
public: bool contains(const Interval& interval) const;
|
||||||
|
@ -104,6 +105,14 @@ class Interval {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline DbU::Unit Interval::getSize () const
|
||||||
|
{
|
||||||
|
if (isEmpty()) return 0;
|
||||||
|
if (isFull ()) return DbU::Max;
|
||||||
|
return _vMax - _vMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // End of Hurricane namespace.
|
} // End of Hurricane namespace.
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,13 @@ namespace Hurricane {
|
||||||
class Layer : public DBo {
|
class Layer : public DBo {
|
||||||
public:
|
public:
|
||||||
typedef DBo Super;
|
typedef DBo Super;
|
||||||
|
public:
|
||||||
|
static const uint32_t NoFlags = 0;
|
||||||
|
static const uint32_t EnclosureH = (1 << 0);
|
||||||
|
static const uint32_t EnclosureV = (1 << 1);
|
||||||
|
static const uint32_t EnclosureMax = (1 << 2);
|
||||||
|
static const uint32_t ExtensionCap = (1 << 3);
|
||||||
|
static const uint32_t ExtensionWidth = (1 << 4);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Types.
|
// Types.
|
||||||
|
@ -72,12 +79,14 @@ namespace Hurricane {
|
||||||
Layer* getMetalBelow ( bool useSymbolic=true ) const;
|
Layer* getMetalBelow ( bool useSymbolic=true ) const;
|
||||||
Layer* getCutAbove ( bool useSymbolic=true ) const;
|
Layer* getCutAbove ( bool useSymbolic=true ) const;
|
||||||
Layer* getCutBelow ( bool useSymbolic=true ) const;
|
Layer* getCutBelow ( bool useSymbolic=true ) const;
|
||||||
virtual DbU::Unit getEnclosure () const;
|
virtual DbU::Unit getEnclosure ( uint32_t flags ) const;
|
||||||
virtual DbU::Unit getExtentionCap () const;
|
virtual DbU::Unit getExtentionCap () const;
|
||||||
virtual DbU::Unit getExtentionWidth () const;
|
virtual DbU::Unit getExtentionWidth () const;
|
||||||
virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const;
|
virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const;
|
||||||
virtual DbU::Unit getExtentionCap ( const BasicLayer* layer ) const;
|
virtual DbU::Unit getExtentionCap ( const BasicLayer* layer ) const;
|
||||||
virtual DbU::Unit getExtentionWidth ( const BasicLayer* layer ) const;
|
virtual DbU::Unit getExtentionWidth ( const BasicLayer* layer ) const;
|
||||||
|
virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const;
|
||||||
|
virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const;
|
||||||
// Predicates
|
// Predicates
|
||||||
inline bool above ( const Layer* layer ) const;
|
inline bool above ( const Layer* layer ) const;
|
||||||
inline bool below ( const Layer* layer ) const;
|
inline bool below ( const Layer* layer ) const;
|
||||||
|
@ -89,7 +98,7 @@ namespace Hurricane {
|
||||||
inline void setSymbolic ( bool );
|
inline void setSymbolic ( bool );
|
||||||
void setMinimalSize ( const DbU::Unit& minimalSize );
|
void setMinimalSize ( const DbU::Unit& minimalSize );
|
||||||
void setMinimalSpacing ( const DbU::Unit& minimalSpacing );
|
void setMinimalSpacing ( const DbU::Unit& minimalSpacing );
|
||||||
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit );
|
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags );
|
||||||
virtual void setExtentionCap ( const BasicLayer* layer, DbU::Unit );
|
virtual void setExtentionCap ( const BasicLayer* layer, DbU::Unit );
|
||||||
virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit );
|
virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit );
|
||||||
// Hurricane Managment.
|
// Hurricane Managment.
|
||||||
|
|
|
@ -60,7 +60,8 @@ namespace Hurricane {
|
||||||
public:
|
public:
|
||||||
// Accessors.
|
// Accessors.
|
||||||
bool isPlacedOccurrence ( unsigned int flags ) const;
|
bool isPlacedOccurrence ( unsigned int flags ) const;
|
||||||
inline Occurrence getOccurrence () const { return _occurrence; };
|
inline bool isAtTopLevel () const;
|
||||||
|
inline Occurrence getOccurrence () const;
|
||||||
Occurrence getPlugOccurrence ();
|
Occurrence getPlugOccurrence ();
|
||||||
virtual const Layer* getLayer () const;
|
virtual const Layer* getLayer () const;
|
||||||
virtual DbU::Unit getX () const;
|
virtual DbU::Unit getX () const;
|
||||||
|
@ -97,6 +98,10 @@ namespace Hurricane {
|
||||||
Occurrence _occurrence;
|
Occurrence _occurrence;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool RoutingPad::isAtTopLevel () const { return _occurrence.getPath().isEmpty(); }
|
||||||
|
inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; };
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "JsonRoutingPad".
|
// Class : "JsonRoutingPad".
|
||||||
|
|
|
@ -49,33 +49,35 @@ namespace Hurricane {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
static ViaLayer* create ( Technology* technology
|
static ViaLayer* create ( Technology* technology
|
||||||
, const Name& name
|
, const Name& name
|
||||||
, BasicLayer* bottomLayer
|
, BasicLayer* bottomLayer
|
||||||
, BasicLayer* cutLayer
|
, BasicLayer* cutLayer
|
||||||
, BasicLayer* topLayer
|
, BasicLayer* topLayer
|
||||||
);
|
);
|
||||||
// Accessors.
|
// Accessors.
|
||||||
virtual BasicLayers getBasicLayers () const;
|
virtual BasicLayers getBasicLayers () const;
|
||||||
virtual const Layer* getTop () const;
|
virtual const Layer* getTop () const;
|
||||||
virtual const Layer* getBottom () const;
|
virtual const Layer* getBottom () const;
|
||||||
virtual const Layer* getOpposite ( const Layer* ) const;
|
virtual const Layer* getOpposite ( const Layer* ) const;
|
||||||
virtual DbU::Unit getEnclosure () const;
|
virtual DbU::Unit getEnclosure ( uint32_t flags ) const;
|
||||||
virtual DbU::Unit getEnclosure ( const BasicLayer* layer ) const;
|
virtual DbU::Unit getEnclosure ( const BasicLayer* layer, uint32_t flags ) const;
|
||||||
|
virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const;
|
||||||
|
virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const;
|
||||||
// Updators.
|
// Updators.
|
||||||
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure );
|
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit enclosure, uint32_t flags );
|
||||||
// Hurricane Managment.
|
// Hurricane Managment.
|
||||||
virtual void _toJson ( JsonWriter* ) const;
|
virtual void _toJson ( JsonWriter* ) const;
|
||||||
virtual void _onDbuChange ( float scale );
|
virtual void _onDbuChange ( float scale );
|
||||||
virtual string _getTypeName () const;
|
virtual string _getTypeName () const;
|
||||||
virtual string _getString () const;
|
virtual string _getString () const;
|
||||||
virtual Record* _getRecord () const;
|
virtual Record* _getRecord () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Internal: Attributes
|
// Internal: Attributes
|
||||||
vector<BasicLayer*> _basicLayers;
|
vector<BasicLayer*> _basicLayers;
|
||||||
vector<DbU::Unit> _enclosures;
|
vector< pair<DbU::Unit,DbU::Unit> > _enclosures;
|
||||||
DbU::Unit _maximalEnclosure;
|
DbU::Unit _maximalEnclosure;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Internal: Constructors & Destructors.
|
// Internal: Constructors & Destructors.
|
||||||
|
|
|
@ -51,7 +51,7 @@ extern "C" {
|
||||||
# define accessorDbuFromOptBasicLayer(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
# define accessorDbuFromOptBasicLayer(FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
|
||||||
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
static PyObject* PY_SELF_TYPE##_##FUNC_NAME ( PY_SELF_TYPE* self, PyObject* args ) \
|
||||||
{ \
|
{ \
|
||||||
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
cdebug_log(20,0) << #PY_SELF_TYPE "_" #FUNC_NAME "()" << endl; \
|
||||||
\
|
\
|
||||||
DbU::Unit rvalue = 0; \
|
DbU::Unit rvalue = 0; \
|
||||||
\
|
\
|
||||||
|
@ -240,13 +240,79 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject* PyLayer_getEnclosure ( PyLayer* self, PyObject* args )
|
||||||
|
{
|
||||||
|
cdebug_log(20,0) << "PyLayer_getEnclosure()" << endl;
|
||||||
|
|
||||||
|
DbU::Unit rvalue = 0;
|
||||||
|
|
||||||
|
HTRY
|
||||||
|
METHOD_HEAD("Layer.getEnclosure()")
|
||||||
|
|
||||||
|
PyObject* arg0 = NULL;
|
||||||
|
PyObject* arg1 = NULL;
|
||||||
|
|
||||||
|
__cs.init( "Layer.getEnclosure()" );
|
||||||
|
if (PyArg_ParseTuple( args, "O&|O&:Layer.getEnclosure()"
|
||||||
|
, Converter, &arg0
|
||||||
|
, Converter, &arg1 )) {
|
||||||
|
if (__cs.getObjectIds() == ":basiclayer:int")
|
||||||
|
rvalue = layer->getEnclosure( PYBASICLAYER_O(arg0), PyAny_AsLong(arg1) );
|
||||||
|
else if ( __cs.getObjectIds() == ":int" )
|
||||||
|
rvalue = layer->getEnclosure( PyAny_AsLong(arg1) );
|
||||||
|
else {
|
||||||
|
PyErr_SetString ( ConstructorError
|
||||||
|
, "invalid parameter type for Layer.getEnclosure()." );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyErr_SetString ( ConstructorError
|
||||||
|
, "Invalid number of parameters passed to Layer.getEnclosure()." );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
HCATCH
|
||||||
|
|
||||||
|
return PyLong_FromLong(rvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject* PyLayer_setEnclosure ( PyLayer* self, PyObject* args )
|
||||||
|
{
|
||||||
|
cdebug_log(20,0) << "PyLayer_setEnclosure()" << endl;
|
||||||
|
|
||||||
|
HTRY
|
||||||
|
METHOD_HEAD("PyLayer.setEnclosure()")
|
||||||
|
|
||||||
|
PyObject* pyBasicLayer = NULL;
|
||||||
|
PyObject* pyDimension = NULL;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
if (PyArg_ParseTuple( args, "OOi:Layer.setEnclosure()"
|
||||||
|
, &pyBasicLayer, &pyDimension, &flags )) {
|
||||||
|
BasicLayer* basicLayer = PYBASICLAYER_O(pyBasicLayer);
|
||||||
|
if (basicLayer == NULL) {
|
||||||
|
PyErr_SetString( ConstructorError
|
||||||
|
, "Layer.setEnclosure(): First parameter is not of BasicLayer type" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
layer->setEnclosure( basicLayer, PyAny_AsLong(pyDimension), flags );
|
||||||
|
} else {
|
||||||
|
PyErr_SetString( ConstructorError
|
||||||
|
, "Layer.setEnclosure(): Bad parameters types or numbers." );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
HCATCH
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GetNameMethod (Layer, layer)
|
GetNameMethod (Layer, layer)
|
||||||
predicateFromLayer ( above ,PyLayer,Layer)
|
predicateFromLayer ( above ,PyLayer,Layer)
|
||||||
predicateFromLayer ( below ,PyLayer,Layer)
|
predicateFromLayer ( below ,PyLayer,Layer)
|
||||||
predicateFromLayer ( contains ,PyLayer,Layer)
|
predicateFromLayer ( contains ,PyLayer,Layer)
|
||||||
predicateFromLayer ( intersect ,PyLayer,Layer)
|
predicateFromLayer ( intersect ,PyLayer,Layer)
|
||||||
predicateFromVoid ( isSymbolic ,PyLayer,Layer)
|
predicateFromVoid ( isSymbolic ,PyLayer,Layer)
|
||||||
accessorDbuFromOptBasicLayer( getEnclosure ,PyLayer,Layer)
|
|
||||||
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
|
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
|
||||||
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
|
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
|
||||||
accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer)
|
accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer)
|
||||||
|
@ -266,7 +332,6 @@ extern "C" {
|
||||||
SetNameMethod(Layer, layer)
|
SetNameMethod(Layer, layer)
|
||||||
updatorFromDbu (setMinimalSize ,PyLayer,Layer)
|
updatorFromDbu (setMinimalSize ,PyLayer,Layer)
|
||||||
updatorFromDbu (setMinimalSpacing,PyLayer,Layer)
|
updatorFromDbu (setMinimalSpacing,PyLayer,Layer)
|
||||||
updatorFromBasicLayerDbu(setEnclosure ,PyLayer,Layer)
|
|
||||||
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
|
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
|
||||||
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
|
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
|
||||||
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer)
|
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer)
|
||||||
|
@ -366,6 +431,15 @@ extern "C" {
|
||||||
extern void PyLayer_postModuleInit ()
|
extern void PyLayer_postModuleInit ()
|
||||||
{
|
{
|
||||||
PyDict_SetItemString ( PyTypeLayer.tp_dict, "Mask", (PyObject*)&PyTypeLayerMask );
|
PyDict_SetItemString ( PyTypeLayer.tp_dict, "Mask", (PyObject*)&PyTypeLayerMask );
|
||||||
|
|
||||||
|
PyObject* constant;
|
||||||
|
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::NoFlags ,"NoFlags" );
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureH ,"EnclosureH" );
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureV ,"EnclosureV" );
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::EnclosureMax ,"EnclosureMax" );
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::ExtensionCap ,"ExtensionCap" );
|
||||||
|
LoadObjectConstant(PyTypeLayer.tp_dict,Layer::ExtensionWidth,"ExtensionWidth");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/DebugSession.h"
|
||||||
#include "anabatic/AutoSegment.h"
|
#include "anabatic/AutoSegment.h"
|
||||||
#include "katana/DataNegociate.h"
|
#include "katana/DataNegociate.h"
|
||||||
|
#include "katana/RoutingPlane.h"
|
||||||
#include "katana/RoutingEvent.h"
|
#include "katana/RoutingEvent.h"
|
||||||
|
#include "katana/KatanaEngine.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Katana {
|
namespace Katana {
|
||||||
|
@ -136,16 +138,38 @@ namespace Katana {
|
||||||
//cerr << " " << interval << endl;
|
//cerr << " " << interval << endl;
|
||||||
//interval.inflate( DbU::fromLambda(-0.5) );
|
//interval.inflate( DbU::fromLambda(-0.5) );
|
||||||
|
|
||||||
cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl;
|
cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl;
|
||||||
cdebug_log(159,0) << "| canonical: " << perpandicular << endl;
|
cdebug_log(159,1) << "| canonical: " << perpandicular << endl;
|
||||||
cdebug_log(159,1) << "Canonical // interval: " << interval << endl;
|
cdebug_log(159,0) << "Canonical // interval: " << interval << endl;
|
||||||
|
|
||||||
_perpandiculars.push_back( perpandicular );
|
_perpandiculars.push_back( perpandicular );
|
||||||
if (perpandicular->getTrack()) {
|
if (perpandicular->getTrack()) {
|
||||||
Interval trackFree = perpandicular->getFreeInterval();
|
Interval trackFree = perpandicular->getFreeInterval();
|
||||||
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;
|
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;
|
||||||
|
|
||||||
_perpandicularFree.intersection( trackFree.inflate(-perpandicular->getExtensionCap()) );
|
_perpandicularFree.intersection
|
||||||
|
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source)
|
||||||
|
, -perpandicular->getExtensionCap(Flags::Target)) );
|
||||||
|
cdebug_log(159,0) << "Source cap:"
|
||||||
|
<< DbU::getValueString(perpandicular->getExtensionCap(Flags::Source)) << endl;
|
||||||
|
} else if (perpandicular->isFixedAxis()) {
|
||||||
|
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(perpandicular->getLayer());
|
||||||
|
Track* track = plane->getTrackByPosition( perpandicular->getAxis() );
|
||||||
|
if (track and (perpandicular->getAxis() == track->getAxis())) {
|
||||||
|
Interval trackFree = track->getFreeInterval( perpandicular->getSourceU(), _trackSegment->getNet() );
|
||||||
|
cdebug_log(159,0) << "SourceU: " << DbU::getValueString(perpandicular->getSourceU()) << endl;
|
||||||
|
cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, source): " << trackFree << endl;
|
||||||
|
|
||||||
|
if (trackFree.isEmpty()) {
|
||||||
|
trackFree = track->getFreeInterval( perpandicular->getTargetU(), _trackSegment->getNet() );
|
||||||
|
cdebug_log(159,0) << "TargetU: " << DbU::getValueString(perpandicular->getTargetU()) << endl;
|
||||||
|
cdebug_log(159,0) << "Track Perpandicular Free (fixed axis, target): " << trackFree << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
_perpandicularFree.intersection
|
||||||
|
( trackFree.inflate ( -perpandicular->getExtensionCap(Flags::Source)
|
||||||
|
, -perpandicular->getExtensionCap(Flags::Target)) );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cdebug_log(159,0) << "Not in any track " << perpandicular << endl;
|
cdebug_log(159,0) << "Not in any track " << perpandicular << endl;
|
||||||
}
|
}
|
||||||
|
@ -252,10 +276,10 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string DataNegociate::getStateString ( DataNegociate* data )
|
string DataNegociate::getStateString ( uint32_t state, unsigned int stateCount )
|
||||||
{
|
{
|
||||||
ostringstream s;
|
ostringstream s;
|
||||||
switch ( data->_state ) {
|
switch ( state ) {
|
||||||
case RipupPerpandiculars: s << "RipupPerpandiculars"; break;
|
case RipupPerpandiculars: s << "RipupPerpandiculars"; break;
|
||||||
case Minimize: s << "Minimize"; break;
|
case Minimize: s << "Minimize"; break;
|
||||||
case Dogleg: s << "Dogleg"; break;
|
case Dogleg: s << "Dogleg"; break;
|
||||||
|
@ -266,13 +290,20 @@ namespace Katana {
|
||||||
case MoveUp: s << "MoveUp"; break;
|
case MoveUp: s << "MoveUp"; break;
|
||||||
case MaximumSlack: s << "MaximumSlack"; break;
|
case MaximumSlack: s << "MaximumSlack"; break;
|
||||||
case Unimplemented: s << "Unimplemented"; break;
|
case Unimplemented: s << "Unimplemented"; break;
|
||||||
case Repair: s << "REPAIR"; break;
|
case Repair: s << "Repair"; break;
|
||||||
|
case RepairFailed: s << "RepairFailed"; break;
|
||||||
default:
|
default:
|
||||||
s << "Unknown(" << data->_state << ")"; break;
|
s << "Unknown(" << state << ")"; break;
|
||||||
}
|
}
|
||||||
s << ":" << data->_stateCount;
|
s << ":" << stateCount;
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string DataNegociate::getStateString ( DataNegociate* data )
|
||||||
|
{
|
||||||
|
return getStateString( data->_state, data->_stateCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // Katana namespace.
|
} // Katana namespace.
|
||||||
|
|
|
@ -143,21 +143,21 @@ namespace Katana {
|
||||||
|
|
||||||
bool Manipulator::ripup ( uint32_t type, DbU::Unit axisHint )
|
bool Manipulator::ripup ( uint32_t type, DbU::Unit axisHint )
|
||||||
{
|
{
|
||||||
cdebug_log(159,0) << "Manipulator::ripup() " << endl;
|
cdebug_log(159,1) << "Manipulator::ripup()" << endl;
|
||||||
|
|
||||||
if (not canRipup()) return false;
|
if (not canRipup()) { cdebug_tabw(159,-1); return false; }
|
||||||
|
if (_segment->isFixed()) { cdebug_tabw(159,-1); return false; }
|
||||||
if (_segment->isFixed()) return false;
|
if (_data == NULL) { cdebug_tabw(159,-1); return true; }
|
||||||
if (_data == NULL) return true;
|
|
||||||
|
|
||||||
_fsm.addAction( _segment, type, axisHint );
|
_fsm.addAction( _segment, type, axisHint );
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Manipulator::ripupPerpandiculars ( uint32_t flags )
|
bool Manipulator::ripupPerpandiculars ( uint32_t flags )
|
||||||
{
|
{
|
||||||
cdebug_log(159,0) << "Manipulator::ripupPerpandiculars() - " << flags << endl;
|
cdebug_log(159,1) << "Manipulator::ripupPerpandiculars() - " << flags << endl;
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
bool cagedPerpandiculars = false;
|
bool cagedPerpandiculars = false;
|
||||||
|
@ -183,6 +183,8 @@ namespace Katana {
|
||||||
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
|
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
|
||||||
|
|
||||||
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
|
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
|
||||||
|
cdebug_log(159,0) << "| " << perpandiculars[i] << endl;
|
||||||
|
|
||||||
track = perpandiculars[i]->getTrack();
|
track = perpandiculars[i]->getTrack();
|
||||||
if (not track) {
|
if (not track) {
|
||||||
// The perpandicular is not placed yet.
|
// The perpandicular is not placed yet.
|
||||||
|
@ -202,10 +204,11 @@ namespace Katana {
|
||||||
|
|
||||||
// Try to ripup the perpandicular.
|
// Try to ripup the perpandicular.
|
||||||
DataNegociate* data2 = perpandiculars[i]->getDataNegociate();
|
DataNegociate* data2 = perpandiculars[i]->getDataNegociate();
|
||||||
cdebug_log(159,0) << "| " << perpandiculars[i] << endl;
|
|
||||||
|
|
||||||
if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) )
|
if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) ) {
|
||||||
|
cdebug_log(159,0) << "Force move up of perpandicular." << endl;
|
||||||
data2->setState( DataNegociate::MoveUp );
|
data2->setState( DataNegociate::MoveUp );
|
||||||
|
}
|
||||||
|
|
||||||
if (Manipulator(perpandiculars[i],_fsm).ripup(perpandicularActionFlags)) {
|
if (Manipulator(perpandiculars[i],_fsm).ripup(perpandicularActionFlags)) {
|
||||||
if (dislodgeCaged) {
|
if (dislodgeCaged) {
|
||||||
|
@ -215,6 +218,7 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cannot ripup the perpandicular, try to ripup it's neigbors.
|
// Cannot ripup the perpandicular, try to ripup it's neigbors.
|
||||||
|
cdebug_log(159,0) << "Try to ripup neighbors." << endl;
|
||||||
size_t begin;
|
size_t begin;
|
||||||
size_t end;
|
size_t end;
|
||||||
track->getOverlapBounds( constraints, begin, end );
|
track->getOverlapBounds( constraints, begin, end );
|
||||||
|
@ -233,6 +237,7 @@ namespace Katana {
|
||||||
_fsm.addAction( other, SegmentAction::OtherRipup );
|
_fsm.addAction( other, SegmentAction::OtherRipup );
|
||||||
} else {
|
} else {
|
||||||
cdebug_log(159,0) << "Aborted ripup of perpandiculars, fixed or blocked." << endl;
|
cdebug_log(159,0) << "Aborted ripup of perpandiculars, fixed or blocked." << endl;
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,6 +246,7 @@ namespace Katana {
|
||||||
if (cagedPerpandiculars and not placedPerpandiculars) {
|
if (cagedPerpandiculars and not placedPerpandiculars) {
|
||||||
cdebug_log(159,0) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl;
|
cdebug_log(159,0) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl;
|
||||||
_fsm.addAction( _segment, SegmentAction::SelfRipup );
|
_fsm.addAction( _segment, SegmentAction::SelfRipup );
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +256,7 @@ namespace Katana {
|
||||||
_fsm.addAction( perpandiculars[i], perpandicularActionFlags|SegmentAction::EventLevel4 );
|
_fsm.addAction( perpandiculars[i], perpandicularActionFlags|SegmentAction::EventLevel4 );
|
||||||
}
|
}
|
||||||
_fsm.addAction( _segment, parallelActionFlags );
|
_fsm.addAction( _segment, parallelActionFlags );
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,13 +272,15 @@ namespace Katana {
|
||||||
if (_segment->isLocal() and (tracksNb < 2)) success = ripple();
|
if (_segment->isLocal() and (tracksNb < 2)) success = ripple();
|
||||||
|
|
||||||
_fsm.addAction( _segment, parallelActionFlags );
|
_fsm.addAction( _segment, parallelActionFlags );
|
||||||
|
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Manipulator::relax ( Interval interval, uint32_t flags )
|
bool Manipulator::relax ( Interval interval, uint32_t flags )
|
||||||
{
|
{
|
||||||
interval.inflate( - Session::getExtensionCap(getLayer()) );
|
Session::toAxisInterval( interval, Session::getLayerDepth(_segment->getLayer())+1 );
|
||||||
cdebug_log(159,0) << "Manipulator::relax() of: " << _segment << " " << interval << endl;
|
cdebug_log(159,0) << "Manipulator::relax() of: " << _segment << " " << interval << endl;
|
||||||
|
|
||||||
if (_segment->isFixed()) return false;
|
if (_segment->isFixed()) return false;
|
||||||
|
@ -784,7 +793,7 @@ namespace Katana {
|
||||||
|
|
||||||
if ( event3->getTracksFree() == 1 ) {
|
if ( event3->getTracksFree() == 1 ) {
|
||||||
cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl;
|
cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl;
|
||||||
if ( segment3->getAxis() == segment2->getTargetU() - Session::getExtensionCap(getLayer()) ) {
|
if ( segment3->getAxis() == segment2->getTargetAxis() ) {
|
||||||
//leftIntrication = true;
|
//leftIntrication = true;
|
||||||
//leftAxisHint = segment3->getAxis();
|
//leftAxisHint = segment3->getAxis();
|
||||||
}
|
}
|
||||||
|
@ -802,7 +811,7 @@ namespace Katana {
|
||||||
break;
|
break;
|
||||||
if ( event3->getTracksFree() == 1 ) {
|
if ( event3->getTracksFree() == 1 ) {
|
||||||
cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl;
|
cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl;
|
||||||
if ( segment3->getAxis() == segment2->getSourceU() + Session::getExtensionCap(getLayer()) ) {
|
if ( segment3->getAxis() == segment2->getSourceAxis() ) {
|
||||||
//rightIntrication = true;
|
//rightIntrication = true;
|
||||||
//rightAxisHint = segment3->getAxis();
|
//rightAxisHint = segment3->getAxis();
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1171,7 @@ namespace Katana {
|
||||||
} else {
|
} else {
|
||||||
if (not _segment->canMoveUp(0.5,kflags)) return false;
|
if (not _segment->canMoveUp(0.5,kflags)) return false;
|
||||||
}
|
}
|
||||||
return _segment->moveUp( kflags );
|
return _segment->moveUp( kflags|Flags::Propagate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1463,6 +1472,7 @@ namespace Katana {
|
||||||
Track* track = _fsm.getTrack( 0 );
|
Track* track = _fsm.getTrack( 0 );
|
||||||
DbU::Unit axisHint = 0;
|
DbU::Unit axisHint = 0;
|
||||||
|
|
||||||
|
#if DISABLED
|
||||||
if (termConstraints.getSize() < _segment->getPPitch()*2) {
|
if (termConstraints.getSize() < _segment->getPPitch()*2) {
|
||||||
cdebug_log(159,0) << "Constraints less than two perpandicular pitches, lock." << endl;
|
cdebug_log(159,0) << "Constraints less than two perpandicular pitches, lock." << endl;
|
||||||
|
|
||||||
|
@ -1475,25 +1485,32 @@ namespace Katana {
|
||||||
cdebug_tabw(159,-1);
|
cdebug_tabw(159,-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for ( ; begin < end ; ++begin ) {
|
for ( ; begin < end ; ++begin ) {
|
||||||
TrackElement* conflict = track->getSegment(begin);
|
TrackElement* conflict = track->getSegment(begin);
|
||||||
if (conflict->getCanonicalInterval().intersect( _segment->getCanonicalInterval() )) break;
|
if (conflict->getCanonicalInterval().intersect( _segment->getCanonicalInterval() )) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interval previousFree = track->getPreviousFree( begin, _segment->getNet() );
|
if (begin == end) {
|
||||||
if (previousFree.intersect(termConstraints))
|
axisHint = termConstraints.getCenter();
|
||||||
axisHint = previousFree.getCenter();
|
cdebug_log(159,0) << "No conflict under canonical interval (?) use terminal center." << endl;
|
||||||
else {
|
cdebug_log(159,0) << "term: " << termConstraints << " center:" << DbU::getValueString(axisHint) << endl;
|
||||||
Interval nextFree = track->getNextFree( end, _segment->getNet() );
|
} else {
|
||||||
if (nextFree.intersect(termConstraints)) {
|
Interval previousFree = track->getPreviousFree( begin, _segment->getNet() );
|
||||||
axisHint = nextFree.getCenter();
|
if (previousFree.intersect(termConstraints))
|
||||||
} else {
|
axisHint = previousFree.getCenter();
|
||||||
cdebug_log(159,0) << "Neither previous free nor next free can be used." << endl;
|
else {
|
||||||
cdebug_log(159,0) << "| previous:" << previousFree << endl;
|
Interval nextFree = track->getNextFree( end, _segment->getNet() );
|
||||||
cdebug_log(159,0) << "| next: " << nextFree << endl;
|
if (nextFree.intersect(termConstraints)) {
|
||||||
cdebug_tabw(159,-1);
|
axisHint = nextFree.getCenter();
|
||||||
return false;
|
} else {
|
||||||
|
cdebug_log(159,0) << "Neither previous free nor next free can be used." << endl;
|
||||||
|
cdebug_log(159,0) << "| previous:" << previousFree << endl;
|
||||||
|
cdebug_log(159,0) << "| next: " << nextFree << endl;
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1512,6 +1529,8 @@ namespace Katana {
|
||||||
_fsm.addAction( perpandiculars[i], SegmentAction::SelfRipupPerpandWithAxisHint, axisHint );
|
_fsm.addAction( perpandiculars[i], SegmentAction::SelfRipupPerpandWithAxisHint, axisHint );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//_fsm.addAction( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel3 );
|
||||||
|
|
||||||
_event->setMinimized();
|
_event->setMinimized();
|
||||||
|
|
||||||
cdebug_tabw(159,-1);
|
cdebug_tabw(159,-1);
|
||||||
|
@ -1536,12 +1555,11 @@ namespace Katana {
|
||||||
if ( not Manipulator(perpandicular,_fsm).canRipup()
|
if ( not Manipulator(perpandicular,_fsm).canRipup()
|
||||||
or (data->getState() >= DataNegociate::MaximumSlack) ) continue;
|
or (data->getState() >= DataNegociate::MaximumSlack) ) continue;
|
||||||
|
|
||||||
// Ugly: ExtensionCap usage.
|
|
||||||
if ( moveLeft ) {
|
if ( moveLeft ) {
|
||||||
if ( perpandicular->getTargetU()-Session::getExtensionCap(getLayer()) == _event->getAxisHistory() )
|
if ( perpandicular->getTargetAxis() == _event->getAxisHistory() )
|
||||||
_fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking );
|
_fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking );
|
||||||
} else {
|
} else {
|
||||||
if ( perpandicular->getSourceU()+Session::getExtensionCap(getLayer()) == _event->getAxisHistory() )
|
if ( perpandicular->getSourceAxis() == _event->getAxisHistory() )
|
||||||
_fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking );
|
_fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1560,6 +1578,7 @@ namespace Katana {
|
||||||
if (perpandicular->isFixed ()) continue;
|
if (perpandicular->isFixed ()) continue;
|
||||||
if (perpandicular->isGlobal()) continue;
|
if (perpandicular->isGlobal()) continue;
|
||||||
if (not data) continue;
|
if (not data) continue;
|
||||||
|
if (data->getState() >= DataNegociate::RepairFailed) continue;
|
||||||
|
|
||||||
if (RoutingEvent::getStage() == RoutingEvent::Repair) {
|
if (RoutingEvent::getStage() == RoutingEvent::Repair) {
|
||||||
data->setState( DataNegociate::Repair );
|
data->setState( DataNegociate::Repair );
|
||||||
|
|
|
@ -115,8 +115,9 @@ namespace {
|
||||||
|
|
||||||
void loadRoutingPads ( NegociateWindow* nw )
|
void loadRoutingPads ( NegociateWindow* nw )
|
||||||
{
|
{
|
||||||
AllianceFramework* af = AllianceFramework::get ();
|
AllianceFramework* af = AllianceFramework::get ();
|
||||||
RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge();
|
RoutingGauge* rg = nw->getKatanaEngine()->getConfiguration()->getRoutingGauge();
|
||||||
|
bool isVH = rg->isVH();
|
||||||
|
|
||||||
for( Net* net : nw->getCell()->getNets() ) {
|
for( Net* net : nw->getCell()->getNets() ) {
|
||||||
if (net->getType() == Net::Type::POWER ) continue;
|
if (net->getType() == Net::Type::POWER ) continue;
|
||||||
|
@ -126,9 +127,13 @@ namespace {
|
||||||
|
|
||||||
for( RoutingPad* rp : net->getRoutingPads() ) {
|
for( RoutingPad* rp : net->getRoutingPads() ) {
|
||||||
size_t depth = rg->getLayerDepth(rp->getLayer());
|
size_t depth = rg->getLayerDepth(rp->getLayer());
|
||||||
if (depth > 0) continue;
|
if (depth == 0) {
|
||||||
if (depth == 0)
|
|
||||||
TrackMarker::create( rp, 1 );
|
TrackMarker::create( rp, 1 );
|
||||||
|
//if (isVH) TrackMarker::create( rp, 2 );
|
||||||
|
}
|
||||||
|
if (depth == 1) {
|
||||||
|
TrackMarker::create( rp, 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,9 +516,6 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event->process( _eventQueue, _eventHistory, _eventLoop );
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (tty::enabled()) {
|
if (tty::enabled()) {
|
||||||
cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0')
|
cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0')
|
||||||
<< RoutingEvent::getProcesseds() << tty::reset
|
<< RoutingEvent::getProcesseds() << tty::reset
|
||||||
|
@ -530,6 +532,9 @@ namespace Katana {
|
||||||
cmess2.flush();
|
cmess2.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event->process( _eventQueue, _eventHistory, _eventLoop );
|
||||||
|
count++;
|
||||||
|
|
||||||
//if (count and not (count % 500)) {
|
//if (count and not (count % 500)) {
|
||||||
// _pack( count, false );
|
// _pack( count, false );
|
||||||
//}
|
//}
|
||||||
|
@ -580,7 +585,7 @@ namespace Katana {
|
||||||
event->process( _eventQueue, _eventHistory, _eventLoop );
|
event->process( _eventQueue, _eventHistory, _eventLoop );
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true );
|
if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
|
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
|
||||||
|
|
|
@ -383,49 +383,6 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void protectAlignedAccesses ( GCell* gcell )
|
|
||||||
{
|
|
||||||
DbU::Unit pitch3 = Session::getPitch( 2 );
|
|
||||||
|
|
||||||
multiset<AutoContactTerminal*,SortAcByXY> acTerminals;
|
|
||||||
for ( AutoContact* contact : gcell->getContacts() ) {
|
|
||||||
if (contact->isTerminal() and (Session::getViaDepth(contact->getLayer()) == 0) )
|
|
||||||
acTerminals.insert( dynamic_cast<AutoContactTerminal*>(contact) );
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoContactTerminal* south = NULL;
|
|
||||||
for ( AutoContactTerminal* north : acTerminals ) {
|
|
||||||
if (south) {
|
|
||||||
if (south->canDrag() and north->canDrag() and (south->getX() == north->getX())) {
|
|
||||||
//Interval constraints ( north->getCBYMax() - pitch3, gcell->getYMin() );
|
|
||||||
Interval constraints ( north->getCBYMin() - pitch3, gcell->getYMin() );
|
|
||||||
AutoSegment* terminal = south->getSegment();
|
|
||||||
AutoContact* opposite = terminal->getOppositeAnchor( south );
|
|
||||||
|
|
||||||
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
|
|
||||||
segment->mergeUserConstraints( constraints );
|
|
||||||
cerr << "Apply " << constraints << " to " << segment << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//constraints = Interval( south->getCBYMin() + pitch3, gcell->getYMax() );
|
|
||||||
constraints = Interval( south->getCBYMax() + pitch3, gcell->getYMax() );
|
|
||||||
terminal = north->getSegment();
|
|
||||||
opposite = terminal->getOppositeAnchor( north );
|
|
||||||
|
|
||||||
for ( AutoSegment* segment : AutoSegments_OnContact(terminal,opposite->base()) ) {
|
|
||||||
segment->mergeUserConstraints( constraints );
|
|
||||||
cerr << "Apply " << constraints << " to " << segment << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (south->getConstraintBox().getHeight() < pitch3*2) metal2protect( south );
|
|
||||||
//if (north->getConstraintBox().getHeight() < pitch3*2) metal2protect( north );
|
|
||||||
}
|
|
||||||
south = north;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // End of local namespace.
|
} // End of local namespace.
|
||||||
|
|
||||||
|
|
||||||
|
@ -452,8 +409,6 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( GCell* gcell : getGCells() ) protectAlignedAccesses( gcell );
|
|
||||||
|
|
||||||
//DebugSession::close();
|
//DebugSession::close();
|
||||||
|
|
||||||
Session::revalidate ();
|
Session::revalidate ();
|
||||||
|
|
|
@ -68,7 +68,14 @@ namespace Katana {
|
||||||
bool RoutingEvent::Compare::operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const
|
bool RoutingEvent::Compare::operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const
|
||||||
{
|
{
|
||||||
if (lhs == rhs) return false;
|
if (lhs == rhs) return false;
|
||||||
return RoutingEvent::Key::Compare()( lhs->getKey(), rhs->getKey() );
|
bool value = RoutingEvent::Key::Compare()( lhs->getKey(), rhs->getKey() );
|
||||||
|
// if ( (lhs->getSegment()->base()->getFlags() & AutoSegment::SegFixedAxis)
|
||||||
|
// or (lhs->getSegment()->base()->getFlags() & AutoSegment::SegFixedAxis)) {
|
||||||
|
// cerr << "Compare: lhs < rhs = " << value << endl;
|
||||||
|
// cerr << " lhs L:" << lhs->getEventLevel() << " " << lhs << endl;
|
||||||
|
// cerr << " rhs L:" << rhs->getEventLevel() << " " << rhs << endl;
|
||||||
|
// }
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +94,11 @@ namespace Katana {
|
||||||
// Process all M2 (terminal access) before any others.
|
// Process all M2 (terminal access) before any others.
|
||||||
//if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false;
|
//if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false;
|
||||||
//if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true;
|
//if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true;
|
||||||
|
|
||||||
|
// For VH gauge, process fixed axis first.
|
||||||
|
if ( (lhs._segFlags & AutoSegment::SegFixedAxis) and not (rhs._segFlags & AutoSegment::SegFixedAxis)) return false;
|
||||||
|
if (not (lhs._segFlags & AutoSegment::SegFixedAxis) and (rhs._segFlags & AutoSegment::SegFixedAxis)) return true;
|
||||||
|
|
||||||
if (lhs._layerDepth > rhs._layerDepth) return true;
|
if (lhs._layerDepth > rhs._layerDepth) return true;
|
||||||
if (lhs._layerDepth < rhs._layerDepth) return false;
|
if (lhs._layerDepth < rhs._layerDepth) return false;
|
||||||
|
|
||||||
|
@ -317,6 +329,11 @@ namespace Katana {
|
||||||
|
|
||||||
RoutingEvent* fork = NULL;
|
RoutingEvent* fork = NULL;
|
||||||
|
|
||||||
|
if (getState() == DataNegociate::RepairFailed) {
|
||||||
|
cdebug_log(159,0) << "Reschedule: cancelled (RepairFailed) -> " << fork << endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (getStage() != Repair) and isUnimplemented() ) {
|
if ( (getStage() != Repair) and isUnimplemented() ) {
|
||||||
cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) -> " << fork << endl;
|
cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) -> " << fork << endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -332,7 +349,8 @@ namespace Katana {
|
||||||
|
|
||||||
_segment->getDataNegociate()->setRoutingEvent( fork );
|
_segment->getDataNegociate()->setRoutingEvent( fork );
|
||||||
|
|
||||||
cdebug_log(159,0) << "Reschedule/Fork: -> " << fork << endl;
|
cdebug_log(159,0) << "Reschedule/Fork: -> "
|
||||||
|
<< eventLevel << ":" << fork << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fork->_eventLevel < eventLevel)
|
if (fork->_eventLevel < eventLevel)
|
||||||
|
@ -364,10 +382,8 @@ namespace Katana {
|
||||||
, RoutingEventLoop& loop
|
, RoutingEventLoop& loop
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
loop.update( _segment->getId() );
|
loop.update( _segment );
|
||||||
if (loop.isLooping()) {
|
if (loop.isLooping()) {
|
||||||
loop.erase( _segment->getId() );
|
|
||||||
setState( DataNegociate::Unimplemented );
|
|
||||||
|
|
||||||
#if LOOP_DEBUG
|
#if LOOP_DEBUG
|
||||||
if (loop.getMaxCount() > 500) {
|
if (loop.getMaxCount() > 500) {
|
||||||
|
@ -391,13 +407,18 @@ namespace Katana {
|
||||||
|
|
||||||
const vector<RoutingEventLoop::Element>& elements = loop.getElements();
|
const vector<RoutingEventLoop::Element>& elements = loop.getElements();
|
||||||
for ( size_t i=0 ; i<elements.size() ; ++i ) {
|
for ( size_t i=0 ; i<elements.size() ; ++i ) {
|
||||||
message << "\n" << setw(10) << elements[i]._count << "| id:" << elements[i]._id;
|
message << "\n" << setw(10) << elements[i]._count << "| " << elements[i]._segment;
|
||||||
}
|
}
|
||||||
cbug << message.str() << endl;
|
cerr << message.str() << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
loop.erase( _segment );
|
||||||
|
setState( DataNegociate::RepairFailed );
|
||||||
|
setDisabled( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugSession::open( _segment->getNet(), 155, 160 );
|
//DebugSession::open( _segment->getNet(), 155, 160 );
|
||||||
|
DebugSession::open( _segment->getNet(), 149, 160 );
|
||||||
|
|
||||||
cdebug_log(9000,0) << "Deter| Event "
|
cdebug_log(9000,0) << "Deter| Event "
|
||||||
<< getProcesseds()
|
<< getProcesseds()
|
||||||
|
@ -591,6 +612,7 @@ namespace Katana {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cdebug_log(159,0) << "Repair failed." << endl;
|
cdebug_log(159,0) << "Repair failed." << endl;
|
||||||
|
setState( DataNegociate::RepairFailed );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,10 @@ namespace Katana {
|
||||||
using std::stable_sort;
|
using std::stable_sort;
|
||||||
|
|
||||||
|
|
||||||
|
size_t RoutingEventLoop::Element::getId () const
|
||||||
|
{ return _segment->getId(); }
|
||||||
|
|
||||||
|
|
||||||
RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit )
|
RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit )
|
||||||
: _elements ()
|
: _elements ()
|
||||||
, _depth (depth)
|
, _depth (depth)
|
||||||
|
@ -37,37 +41,37 @@ namespace Katana {
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
void RoutingEventLoop::update ( size_t id )
|
void RoutingEventLoop::update ( TrackElement* segment )
|
||||||
{
|
{
|
||||||
vector<Element>::iterator ielement = _elements.begin();
|
vector<Element>::iterator ielement = _elements.begin();
|
||||||
for ( ; ielement != _elements.end() ; ++ielement ) {
|
for ( ; ielement != _elements.end() ; ++ielement ) {
|
||||||
if ( (*ielement)._id == id ) {
|
if ((*ielement).getId() == segment->getId()) {
|
||||||
// Increment an already present element.
|
// Increment an already present element.
|
||||||
(*ielement)._count += 1;
|
(*ielement)._count += 1;
|
||||||
(*ielement)._timestamp = RoutingEvent::getProcesseds();
|
(*ielement)._timestamp = RoutingEvent::getProcesseds();
|
||||||
_maxCount = std::max ( _maxCount, (*ielement)._count );
|
_maxCount = std::max ( _maxCount, (*ielement)._count );
|
||||||
|
|
||||||
if ( _maxCount > _countLimit ) _isLooping = true;
|
if (_maxCount > _countLimit) _isLooping = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Event was not found.
|
// The Event was not found.
|
||||||
if ( ielement == _elements.end() ) {
|
if (ielement == _elements.end()) {
|
||||||
if ( _elements.size() >= _depth ) _elements.pop_back ();
|
if (_elements.size() >= _depth) _elements.pop_back();
|
||||||
_elements.push_back ( Element(id,RoutingEvent::getProcesseds()) );
|
_elements.push_back( Element(segment,RoutingEvent::getProcesseds()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
stable_sort ( _elements.begin(), _elements.end(), CompareByTimestamp() );
|
stable_sort( _elements.begin(), _elements.end(), CompareByTimestamp() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RoutingEventLoop::erase ( size_t id )
|
void RoutingEventLoop::erase ( TrackElement* segment )
|
||||||
{
|
{
|
||||||
vector<Element>::iterator ielement = _elements.begin();
|
vector<Element>::iterator ielement = _elements.begin();
|
||||||
for ( ; ielement != _elements.end() ; ++ielement ) {
|
for ( ; ielement != _elements.end() ; ++ielement ) {
|
||||||
if ( (*ielement)._id == id ) {
|
if ((*ielement).getId() == segment->getId()) {
|
||||||
_elements.erase ( ielement );
|
_elements.erase( ielement );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,7 @@ namespace Katana {
|
||||||
_maxCount = 0;
|
_maxCount = 0;
|
||||||
ielement = _elements.begin();
|
ielement = _elements.begin();
|
||||||
for ( ; ielement != _elements.end() ; ++ielement ) {
|
for ( ; ielement != _elements.end() ; ++ielement ) {
|
||||||
_maxCount = std::max ( _maxCount, (*ielement)._count );
|
_maxCount = std::max( _maxCount, (*ielement)._count );
|
||||||
}
|
}
|
||||||
|
|
||||||
_isLooping = (_maxCount > _countLimit);
|
_isLooping = (_maxCount > _countLimit);
|
||||||
|
|
|
@ -125,7 +125,7 @@ namespace Katana {
|
||||||
if (plane->getDirection() == Flags::Horizontal) {
|
if (plane->getDirection() == Flags::Horizontal) {
|
||||||
plane->_tracks.push_back( HorizontalTrack::create( plane, index ) );
|
plane->_tracks.push_back( HorizontalTrack::create( plane, index ) );
|
||||||
// Ugly: Direct uses of CellGauge (middle tracks 4 & 5 for local use).
|
// Ugly: Direct uses of CellGauge (middle tracks 4 & 5 for local use).
|
||||||
if (depth == 1) {
|
if ( (depth == 1) and not Session::getRoutingGauge()->isVH() ) {
|
||||||
switch ( index%10 ) {
|
switch ( index%10 ) {
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
|
|
|
@ -445,20 +445,21 @@ namespace Katana {
|
||||||
SegmentFsm::SegmentFsm ( RoutingEvent* event1
|
SegmentFsm::SegmentFsm ( RoutingEvent* event1
|
||||||
, RoutingEventQueue& queue
|
, RoutingEventQueue& queue
|
||||||
, RoutingEventHistory& history )
|
, RoutingEventHistory& history )
|
||||||
: _event1 (event1)
|
: _event1 (event1)
|
||||||
, _event2 (NULL)
|
, _event2 (NULL)
|
||||||
, _queue (queue)
|
, _queue (queue)
|
||||||
, _history (history)
|
, _history (history)
|
||||||
, _state (0)
|
, _state (0)
|
||||||
, _data1 (NULL)
|
, _data1 (NULL)
|
||||||
, _data2 (NULL)
|
, _data2 (NULL)
|
||||||
, _constraint ()
|
, _constraint ()
|
||||||
, _optimal ()
|
, _optimal ()
|
||||||
, _costs ()
|
, _costs ()
|
||||||
, _actions ()
|
, _actions ()
|
||||||
, _fullBlocked(true)
|
, _fullBlocked (true)
|
||||||
, _sameAxis (false)
|
, _sameAxis (false)
|
||||||
, _useEvent2 (false)
|
, _useEvent2 (false)
|
||||||
|
, _minimizeDrag(false)
|
||||||
{
|
{
|
||||||
DataSymmetric* symData = NULL;
|
DataSymmetric* symData = NULL;
|
||||||
TrackElement* segment1 = _event1->getSegment();
|
TrackElement* segment1 = _event1->getSegment();
|
||||||
|
@ -1184,53 +1185,70 @@ namespace Katana {
|
||||||
|
|
||||||
switch (data->getState()) {
|
switch (data->getState()) {
|
||||||
case DataNegociate::RipupPerpandiculars:
|
case DataNegociate::RipupPerpandiculars:
|
||||||
nextState = DataNegociate::Minimize;
|
if (segment->isDrag() and getCost(0)->isInfinite()) {
|
||||||
success = manipulator.ripupPerpandiculars();
|
nextState = DataNegociate::Slacken;
|
||||||
|
success = manipulator.dragMinimize();
|
||||||
|
if (success) _minimizeDrag = true;
|
||||||
|
} else {
|
||||||
|
nextState = DataNegociate::Minimize;
|
||||||
|
success = manipulator.ripupPerpandiculars();
|
||||||
|
}
|
||||||
if (success) break;
|
if (success) break;
|
||||||
case DataNegociate::Minimize:
|
case DataNegociate::Minimize:
|
||||||
if (isFullBlocked() and not segment->isTerminal()) {
|
if (nextState == DataNegociate::Minimize) {
|
||||||
cdebug_log(159,0) << "Is Fully blocked." << endl;
|
if (isFullBlocked() and not segment->isTerminal()) {
|
||||||
nextState = DataNegociate::Unimplemented;
|
cdebug_log(159,0) << "Is Fully blocked." << endl;
|
||||||
break;
|
nextState = DataNegociate::Unimplemented;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nextState = DataNegociate::Dogleg;
|
||||||
|
success = manipulator.minimize();
|
||||||
|
if (success) break;
|
||||||
}
|
}
|
||||||
nextState = DataNegociate::Dogleg;
|
|
||||||
// if (segment->isDrag())
|
|
||||||
// success = manipulator.dragMinimize();
|
|
||||||
// else
|
|
||||||
success = manipulator.minimize();
|
|
||||||
if (success) break;
|
|
||||||
case DataNegociate::Dogleg:
|
case DataNegociate::Dogleg:
|
||||||
nextState = DataNegociate::Slacken;
|
if (nextState == DataNegociate::Dogleg) {
|
||||||
success = manipulator.makeDogleg();
|
nextState = DataNegociate::Slacken;
|
||||||
if (success) break;
|
success = manipulator.makeDogleg();
|
||||||
|
if (success) break;
|
||||||
|
}
|
||||||
case DataNegociate::Slacken:
|
case DataNegociate::Slacken:
|
||||||
nextState = DataNegociate::ConflictSolveByPlaceds;
|
if (nextState == DataNegociate::Slacken) {
|
||||||
success = manipulator.slacken();
|
nextState = DataNegociate::ConflictSolveByPlaceds;
|
||||||
if (success) break;
|
success = manipulator.slacken();
|
||||||
|
if (success) break;
|
||||||
|
}
|
||||||
case DataNegociate::ConflictSolveByHistory:
|
case DataNegociate::ConflictSolveByHistory:
|
||||||
case DataNegociate::ConflictSolveByPlaceds:
|
case DataNegociate::ConflictSolveByPlaceds:
|
||||||
nextState = DataNegociate::LocalVsGlobal;
|
if ( (nextState == DataNegociate::ConflictSolveByHistory)
|
||||||
success = conflictSolveByHistory();
|
or (nextState == DataNegociate::ConflictSolveByPlaceds) ) {
|
||||||
break;
|
nextState = DataNegociate::LocalVsGlobal;
|
||||||
|
success = conflictSolveByHistory();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DataNegociate::LocalVsGlobal:
|
case DataNegociate::LocalVsGlobal:
|
||||||
nextState = DataNegociate::MoveUp;
|
if (nextState == DataNegociate::LocalVsGlobal) {
|
||||||
success = solveTerminalVsGlobal();
|
nextState = DataNegociate::MoveUp;
|
||||||
if (success) break;
|
success = solveTerminalVsGlobal();
|
||||||
break;
|
if (success) break;
|
||||||
|
}
|
||||||
case DataNegociate::MoveUp:
|
case DataNegociate::MoveUp:
|
||||||
nextState = DataNegociate::MaximumSlack;
|
if (nextState == DataNegociate::LocalVsGlobal) {
|
||||||
success = manipulator.moveUp();
|
nextState = DataNegociate::MaximumSlack;
|
||||||
if (success) break;
|
success = manipulator.moveUp();
|
||||||
|
if (success) break;
|
||||||
|
}
|
||||||
case DataNegociate::MaximumSlack:
|
case DataNegociate::MaximumSlack:
|
||||||
if (segment->isStrap()) {
|
if (nextState == DataNegociate::MaximumSlack) {
|
||||||
if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) {
|
if (segment->isStrap()) {
|
||||||
nextState = DataNegociate::MaximumSlack;
|
if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) {
|
||||||
success = conflictSolveByPlaceds();
|
nextState = DataNegociate::MaximumSlack;
|
||||||
if (success) break;
|
success = conflictSolveByPlaceds();
|
||||||
|
if (success) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case DataNegociate::Unimplemented:
|
case DataNegociate::Unimplemented:
|
||||||
if (segment->isDrag()) cerr << "Slacken DRAG:" << segment << endl;
|
//if (segment->isDrag()) cerr << "Slacken DRAG:" << segment << endl;
|
||||||
nextState = DataNegociate::Unimplemented;
|
nextState = DataNegociate::Unimplemented;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1249,7 +1267,8 @@ namespace Katana {
|
||||||
|
|
||||||
if (not (flags&NoTransition)) {
|
if (not (flags&NoTransition)) {
|
||||||
data->setState( nextState );
|
data->setState( nextState );
|
||||||
cdebug_log(159,0) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl;
|
cdebug_log(159,0) << "Incrementing state (after): "
|
||||||
|
<< DataNegociate::getStateString(nextState,data->getStateCount()) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -1384,6 +1403,10 @@ namespace Katana {
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
actionFlags |= SegmentAction::ResetRipup;
|
actionFlags |= SegmentAction::ResetRipup;
|
||||||
|
if (isMinimizeDrag()) {
|
||||||
|
actionFlags &= ~SegmentAction::EventLevel5;
|
||||||
|
actionFlags |= SegmentAction::EventLevel3;
|
||||||
|
}
|
||||||
addAction( segment1, actionFlags );
|
addAction( segment1, actionFlags );
|
||||||
} else {
|
} else {
|
||||||
clearActions();
|
clearActions();
|
||||||
|
|
|
@ -181,6 +181,23 @@ namespace Katana {
|
||||||
{ return _getKatanaEngine()->getGCellUnder(Point(x,y)); };
|
{ return _getKatanaEngine()->getGCellUnder(Point(x,y)); };
|
||||||
|
|
||||||
|
|
||||||
|
Interval& Session::_toAxisInterval ( Interval& interval, size_t depth ) const
|
||||||
|
{
|
||||||
|
RoutingLayerGauge* rg = getLayerGauge(depth);
|
||||||
|
if (not rg) return interval;
|
||||||
|
|
||||||
|
Box ab = getKatanaEngine()->getCell()->getAbutmentBox();
|
||||||
|
DbU::Unit abMin = (rg->isHorizontal()) ? ab.getYMin() : ab.getXMin();
|
||||||
|
DbU::Unit abMax = (rg->isHorizontal()) ? ab.getYMax() : ab.getXMax() ;
|
||||||
|
|
||||||
|
DbU::Unit trackMin = rg->getTrackPosition( abMin, abMax, interval.getVMin(), Constant::Superior );
|
||||||
|
DbU::Unit trackMax = rg->getTrackPosition( abMin, abMax, interval.getVMax(), Constant::Inferior );
|
||||||
|
interval = Interval( trackMin, trackMax );
|
||||||
|
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Session::_doRemovalEvents ()
|
void Session::_doRemovalEvents ()
|
||||||
{
|
{
|
||||||
set<Track*> packTracks;
|
set<Track*> packTracks;
|
||||||
|
|
|
@ -308,6 +308,11 @@ namespace Katana {
|
||||||
if (_markers[mbegin]->getNet() != cost.getNet()) {
|
if (_markers[mbegin]->getNet() != cost.getNet()) {
|
||||||
cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl;
|
cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl;
|
||||||
cost.incTerminals( _markers[mbegin]->getWeight(this) );
|
cost.incTerminals( _markers[mbegin]->getWeight(this) );
|
||||||
|
|
||||||
|
if ( (_markers[mbegin]->getRefCount() == 1) and (interval.contains(_markers[mbegin]->getSpan())) ) {
|
||||||
|
cdebug_log(155,0) << " Total overlap of a one track terminal: infinite cost." << endl;
|
||||||
|
cost.setInfinite();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,8 +396,11 @@ namespace Katana {
|
||||||
if (_segments.empty()) return Interval(_min,_max);
|
if (_segments.empty()) return Interval(_min,_max);
|
||||||
|
|
||||||
getBeginIndex( position, begin, state );
|
getBeginIndex( position, begin, state );
|
||||||
if ( (state == InsideElement) and (_segments[begin]->getNet() != net) )
|
if ( (state == InsideElement) and (_segments[begin]->getNet() != net) ) {
|
||||||
|
cdebug_log(155,0) << "Track::getFreeInterval(): Inside other element @" << begin
|
||||||
|
<< " - " << _segments[begin] << endl;
|
||||||
return Interval();
|
return Interval();
|
||||||
|
}
|
||||||
|
|
||||||
end = begin;
|
end = begin;
|
||||||
return expandFreeInterval( begin, end, state, net );
|
return expandFreeInterval( begin, end, state, net );
|
||||||
|
@ -616,7 +624,6 @@ namespace Katana {
|
||||||
return free;
|
return free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Interval occupied = getOccupiedInterval( index );
|
Interval occupied = getOccupiedInterval( index );
|
||||||
cdebug_log(155,0) << "Previous occupied:" << occupied << endl;
|
cdebug_log(155,0) << "Previous occupied:" << occupied << endl;
|
||||||
Interval free = getFreeInterval( occupied.getVMin()-1, net );
|
Interval free = getFreeInterval( occupied.getVMin()-1, net );
|
||||||
|
@ -642,10 +649,10 @@ namespace Katana {
|
||||||
while ( --i != npos ) {
|
while ( --i != npos ) {
|
||||||
if (_segments[i]->getNet() != owner) break;
|
if (_segments[i]->getNet() != owner) break;
|
||||||
|
|
||||||
cdebug_log(155,0) << "| merge:" << _segments[i] << endl;
|
|
||||||
|
|
||||||
_segments[i]->getCanonical ( segmentInterval );
|
_segments[i]->getCanonical ( segmentInterval );
|
||||||
if (segmentInterval.getVMax() >= mergedInterval.getVMin()) {
|
if (segmentInterval.getVMax() >= mergedInterval.getVMin()) {
|
||||||
|
cdebug_log(155,0) << "| merge (prev):" << _segments[i] << endl;
|
||||||
|
|
||||||
mergedInterval.merge( segmentInterval );
|
mergedInterval.merge( segmentInterval );
|
||||||
begin = i;
|
begin = i;
|
||||||
}
|
}
|
||||||
|
@ -658,6 +665,8 @@ namespace Katana {
|
||||||
_segments[i]->getCanonical( segmentInterval );
|
_segments[i]->getCanonical( segmentInterval );
|
||||||
if (segmentInterval.getVMin() > mergedInterval.getVMax()) break;
|
if (segmentInterval.getVMin() > mergedInterval.getVMax()) break;
|
||||||
|
|
||||||
|
cdebug_log(155,0) << "| merge (next):" << _segments[i] << endl;
|
||||||
|
|
||||||
mergedInterval.merge( segmentInterval );
|
mergedInterval.merge( segmentInterval );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,9 @@ namespace Katana {
|
||||||
, _selectFlags (NoFlags)
|
, _selectFlags (NoFlags)
|
||||||
, _selectIndex (0)
|
, _selectIndex (0)
|
||||||
{
|
{
|
||||||
|
cdebug_log(159,1) << "TrackCost::TrackCost() - " << refSegment << endl;
|
||||||
|
cdebug_log(159,0) << " interval1: " << _interval1 << endl;
|
||||||
|
|
||||||
std::get<0>( _tracks[0] ) = refTrack;
|
std::get<0>( _tracks[0] ) = refTrack;
|
||||||
_segment1->addOverlapCost( *this );
|
_segment1->addOverlapCost( *this );
|
||||||
|
|
||||||
|
@ -68,6 +71,7 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
consolidate();
|
consolidate();
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ namespace Katana {
|
||||||
// Wrapped AutoSegment Functions.
|
// Wrapped AutoSegment Functions.
|
||||||
AutoSegment* TrackElement::base () const { return NULL; }
|
AutoSegment* TrackElement::base () const { return NULL; }
|
||||||
bool TrackElement::isFixed () const { return false; }
|
bool TrackElement::isFixed () const { return false; }
|
||||||
|
bool TrackElement::isFixedAxis () const { return false; }
|
||||||
bool TrackElement::isLocal () const { return true; }
|
bool TrackElement::isLocal () const { return true; }
|
||||||
bool TrackElement::isGlobal () const { return not isLocal(); }
|
bool TrackElement::isGlobal () const { return not isLocal(); }
|
||||||
bool TrackElement::isBipoint () const { return false; }
|
bool TrackElement::isBipoint () const { return false; }
|
||||||
|
@ -162,7 +163,7 @@ namespace Katana {
|
||||||
uint32_t TrackElement::getTrackCount () const { return 0; }
|
uint32_t TrackElement::getTrackCount () const { return 0; }
|
||||||
DbU::Unit TrackElement::getPitch () const { return 0; }
|
DbU::Unit TrackElement::getPitch () const { return 0; }
|
||||||
DbU::Unit TrackElement::getPPitch () const { return 0; }
|
DbU::Unit TrackElement::getPPitch () const { return 0; }
|
||||||
DbU::Unit TrackElement::getExtensionCap () const { return 0; }
|
DbU::Unit TrackElement::getExtensionCap ( Flags ) const { return 0; }
|
||||||
float TrackElement::getMaxUnderDensity ( Flags ) const { return 0.0; };
|
float TrackElement::getMaxUnderDensity ( Flags ) const { return 0.0; };
|
||||||
uint32_t TrackElement::getDoglegLevel () const { return 0; }
|
uint32_t TrackElement::getDoglegLevel () const { return 0; }
|
||||||
TrackElement* TrackElement::getParent () const { return NULL; }
|
TrackElement* TrackElement::getParent () const { return NULL; }
|
||||||
|
|
|
@ -144,6 +144,30 @@ namespace Katana {
|
||||||
size_t TrackFixedSegment::getTrackSpan () const { return 1; }
|
size_t TrackFixedSegment::getTrackSpan () const { return 1; }
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit TrackFixedSegment::getSourceAxis () const
|
||||||
|
{
|
||||||
|
const Horizontal* horizontal = dynamic_cast<const Horizontal*>( _segment );
|
||||||
|
if (horizontal) return horizontal->getSourceX();
|
||||||
|
|
||||||
|
const Vertical* vertical = dynamic_cast<const Vertical*>( _segment );
|
||||||
|
if (vertical) return vertical->getSourceY();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit TrackFixedSegment::getTargetAxis () const
|
||||||
|
{
|
||||||
|
const Horizontal* horizontal = dynamic_cast<const Horizontal*>( _segment );
|
||||||
|
if (horizontal) return horizontal->getTargetX();
|
||||||
|
|
||||||
|
const Vertical* vertical = dynamic_cast<const Vertical*>( _segment );
|
||||||
|
if (vertical) return vertical->getTargetY();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long TrackFixedSegment::getId () const
|
unsigned long TrackFixedSegment::getId () const
|
||||||
{
|
{
|
||||||
cerr << Error("::getId() called on %s.",_getString().c_str()) << endl;
|
cerr << Error("::getId() called on %s.",_getString().c_str()) << endl;
|
||||||
|
|
|
@ -81,9 +81,9 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rpDirection xor (uint64_t)rg->getLayerDirection(rg->getLayerDepth(pad->getLayer())) ) {
|
if ( rpDirection xor (uint64_t)rg->getLayerDirection(rg->getLayerDepth(pad->getLayer())) ) {
|
||||||
_weight = (uint32_t)(( pitch / (pitch+DbU::toLambda(trackSpan.getSize())) ) * 100.0) ;
|
_weight = (uint32_t)(( pitch / (pitch+trackSpan.getSize()) ) * 100.0) ;
|
||||||
} else {
|
} else {
|
||||||
_weight = (uint32_t)( (pitch + DbU::toLambda(trackSpan.getSize())) * 20.0 );
|
_weight = (uint32_t)( (pitch + trackSpan.getSize()) * 20.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Track* track = rp->getTrackByPosition ( trackSpan.getVMin() );
|
Track* track = rp->getTrackByPosition ( trackSpan.getVMin() );
|
||||||
|
|
|
@ -154,6 +154,7 @@ namespace Katana {
|
||||||
AutoSegment* TrackSegment::base () const { return _base; }
|
AutoSegment* TrackSegment::base () const { return _base; }
|
||||||
Segment* TrackSegment::getSegment () const { return _base->base(); }
|
Segment* TrackSegment::getSegment () const { return _base->base(); }
|
||||||
bool TrackSegment::isFixed () const { return _base->isFixed(); }
|
bool TrackSegment::isFixed () const { return _base->isFixed(); }
|
||||||
|
bool TrackSegment::isFixedAxis () const { return _base->isFixedAxis(); }
|
||||||
bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); }
|
bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); }
|
||||||
bool TrackSegment::isVertical () const { return _base->isVertical(); }
|
bool TrackSegment::isVertical () const { return _base->isVertical(); }
|
||||||
bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); }
|
bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); }
|
||||||
|
@ -181,7 +182,7 @@ namespace Katana {
|
||||||
const Layer* TrackSegment::getLayer () const { return _base->getLayer(); }
|
const Layer* TrackSegment::getLayer () const { return _base->getLayer(); }
|
||||||
DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); }
|
DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); }
|
||||||
DbU::Unit TrackSegment::getPPitch () const { return _ppitch; }
|
DbU::Unit TrackSegment::getPPitch () const { return _ppitch; }
|
||||||
DbU::Unit TrackSegment::getExtensionCap () const { return _base->getExtensionCap(); }
|
DbU::Unit TrackSegment::getExtensionCap ( Flags flags ) const { return _base->getExtensionCap(flags); }
|
||||||
DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); }
|
DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); }
|
||||||
unsigned long TrackSegment::getFreedomDegree () const { return _freedomDegree; }
|
unsigned long TrackSegment::getFreedomDegree () const { return _freedomDegree; }
|
||||||
float TrackSegment::getPriority () const { return _priority; }
|
float TrackSegment::getPriority () const { return _priority; }
|
||||||
|
@ -195,6 +196,24 @@ namespace Katana {
|
||||||
void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); }
|
void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); }
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit TrackSegment::getSourceAxis () const
|
||||||
|
{
|
||||||
|
DbU::Unit sourceAxis = 0;
|
||||||
|
DbU::Unit targetAxis = 0;
|
||||||
|
base()->getEndAxes( sourceAxis, targetAxis );
|
||||||
|
return sourceAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit TrackSegment::getTargetAxis () const
|
||||||
|
{
|
||||||
|
DbU::Unit sourceAxis = 0;
|
||||||
|
DbU::Unit targetAxis = 0;
|
||||||
|
base()->getEndAxes( sourceAxis, targetAxis );
|
||||||
|
return targetAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DataNegociate* TrackSegment::getDataNegociate ( Flags flags ) const
|
DataNegociate* TrackSegment::getDataNegociate ( Flags flags ) const
|
||||||
{
|
{
|
||||||
if (flags & Flags::DataSelf) return _data;
|
if (flags & Flags::DataSelf) return _data;
|
||||||
|
|
|
@ -52,4 +52,7 @@ namespace Katana {
|
||||||
|
|
||||||
} // Katana namespace.
|
} // Katana namespace.
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_PV_SUPPORT(Katana::Flags)
|
||||||
|
|
||||||
#endif // KATANA_CONSTANTS_H
|
#endif // KATANA_CONSTANTS_H
|
||||||
|
|
|
@ -49,17 +49,18 @@ namespace Katana {
|
||||||
|
|
||||||
class DataNegociate {
|
class DataNegociate {
|
||||||
public:
|
public:
|
||||||
enum SlackState { RipupPerpandiculars = 1
|
enum SlackState { RipupPerpandiculars = 1
|
||||||
, Minimize = 2
|
, Minimize = 2
|
||||||
, Dogleg = 3
|
, Dogleg = 3
|
||||||
, Slacken = 4
|
, Slacken = 4
|
||||||
, ConflictSolveByHistory = 5
|
, ConflictSolveByHistory = 5
|
||||||
, ConflictSolveByPlaceds = 6
|
, ConflictSolveByPlaceds = 6
|
||||||
, LocalVsGlobal = 7
|
, LocalVsGlobal = 7
|
||||||
, MoveUp = 8
|
, MoveUp = 8
|
||||||
, MaximumSlack = 9
|
, MaximumSlack = 9
|
||||||
, Unimplemented =10
|
, Unimplemented = 10
|
||||||
, Repair =11
|
, Repair = 11
|
||||||
|
, RepairFailed = 12
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
DataNegociate ( TrackElement* );
|
DataNegociate ( TrackElement* );
|
||||||
|
@ -89,6 +90,7 @@ namespace Katana {
|
||||||
inline void resetRipupCount ();
|
inline void resetRipupCount ();
|
||||||
inline void resetStateCount ();
|
inline void resetStateCount ();
|
||||||
void update ();
|
void update ();
|
||||||
|
static string getStateString ( uint32_t state, unsigned int stateCount );
|
||||||
static string getStateString ( DataNegociate* );
|
static string getStateString ( DataNegociate* );
|
||||||
Record* _getRecord () const;
|
Record* _getRecord () const;
|
||||||
string _getString () const;
|
string _getString () const;
|
||||||
|
@ -141,6 +143,18 @@ namespace Katana {
|
||||||
|
|
||||||
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
||||||
{
|
{
|
||||||
|
if ( (_state >= Repair) and (state < _state) ) {
|
||||||
|
std::cerr << "Revert DataNegociate state from Repair/RepairFailed to " << getStateString(state,_stateCount).c_str() << std::endl;
|
||||||
|
std::cerr << "On " << _getString() << std::endl;
|
||||||
|
|
||||||
|
std::cerr << *((char*)NULL) << std::endl;
|
||||||
|
|
||||||
|
throw Hurricane::Error( "Revert DataNegociate state from Repair/RepairFailed to %s."
|
||||||
|
" On %s"
|
||||||
|
, getStateString(state,_stateCount).c_str()
|
||||||
|
, _getString().c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
if ( (_state != state) or (flags & Flags::ResetCount) ) {
|
if ( (_state != state) or (flags & Flags::ResetCount) ) {
|
||||||
//std::cerr << "Changing state to:" << state << std::endl;
|
//std::cerr << "Changing state to:" << state << std::endl;
|
||||||
_state = state;
|
_state = state;
|
||||||
|
@ -155,4 +169,7 @@ namespace Katana {
|
||||||
|
|
||||||
} // Katana namespace.
|
} // Katana namespace.
|
||||||
|
|
||||||
|
|
||||||
|
INSPECTOR_P_SUPPORT(Katana::DataNegociate);
|
||||||
|
|
||||||
#endif // KATANA_DATA_NEGOCIATE_H
|
#endif // KATANA_DATA_NEGOCIATE_H
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//
|
//
|
||||||
// This file is part of the Coriolis Software.
|
// This file is part of the Coriolis Software.
|
||||||
// Copyright (c) UPMC 2008-2013, All Rights Reserved
|
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||||
//
|
//
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
// | C O R I O L I S |
|
// | C O R I O L I S |
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
// | Author : Jean-Paul CHAPUT |
|
// | Author : Jean-Paul CHAPUT |
|
||||||
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||||
// | =============================================================== |
|
// | =============================================================== |
|
||||||
// | C++ Header : "./katana/RoutingEventLoop.h" |
|
// | C++ Header : "./katana/RoutingEventLoop.h" |
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
namespace Katana {
|
namespace Katana {
|
||||||
|
|
||||||
|
class TrackElement;
|
||||||
class RoutingEvent;
|
class RoutingEvent;
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,11 +34,12 @@ namespace Katana {
|
||||||
public:
|
public:
|
||||||
class Element {
|
class Element {
|
||||||
public:
|
public:
|
||||||
inline Element ( size_t id=0, size_t timestamp=0 );
|
inline Element ( TrackElement* segment, size_t timestamp=0 );
|
||||||
|
size_t getId () const;
|
||||||
public:
|
public:
|
||||||
size_t _id;
|
TrackElement* _segment;
|
||||||
size_t _timestamp;
|
size_t _timestamp;
|
||||||
int _count;
|
int _count;
|
||||||
};
|
};
|
||||||
class CompareByTimestamp {
|
class CompareByTimestamp {
|
||||||
public:
|
public:
|
||||||
|
@ -48,8 +50,8 @@ namespace Katana {
|
||||||
inline bool isLooping () const;
|
inline bool isLooping () const;
|
||||||
inline int getMaxCount () const;
|
inline int getMaxCount () const;
|
||||||
inline const std::vector<Element>& getElements () const;
|
inline const std::vector<Element>& getElements () const;
|
||||||
void update ( size_t id );
|
void update ( TrackElement* );
|
||||||
void erase ( size_t id );
|
void erase ( TrackElement* );
|
||||||
private:
|
private:
|
||||||
std::vector<Element> _elements;
|
std::vector<Element> _elements;
|
||||||
size_t _depth;
|
size_t _depth;
|
||||||
|
@ -59,8 +61,8 @@ namespace Katana {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline RoutingEventLoop::Element::Element ( size_t id, size_t timestamp )
|
inline RoutingEventLoop::Element::Element ( TrackElement* segment, size_t timestamp )
|
||||||
: _id(id), _timestamp(timestamp), _count(1)
|
: _segment(segment), _timestamp(timestamp), _count(1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace Katana {
|
||||||
~SegmentFsm ();
|
~SegmentFsm ();
|
||||||
inline bool isFullBlocked () const;
|
inline bool isFullBlocked () const;
|
||||||
inline bool isSymmetric () const;
|
inline bool isSymmetric () const;
|
||||||
|
inline bool isMinimizeDrag () const;
|
||||||
inline RoutingEvent* getEvent () const;
|
inline RoutingEvent* getEvent () const;
|
||||||
inline RoutingEvent* getEvent1 () const;
|
inline RoutingEvent* getEvent1 () const;
|
||||||
inline RoutingEvent* getEvent2 () const;
|
inline RoutingEvent* getEvent2 () const;
|
||||||
|
@ -187,40 +188,42 @@ namespace Katana {
|
||||||
bool _fullBlocked;
|
bool _fullBlocked;
|
||||||
bool _sameAxis;
|
bool _sameAxis;
|
||||||
bool _useEvent2;
|
bool _useEvent2;
|
||||||
|
bool _minimizeDrag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; }
|
inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; }
|
||||||
inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); }
|
inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; }
|
||||||
inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; }
|
inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); }
|
||||||
inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; }
|
inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; }
|
||||||
inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; }
|
inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; }
|
||||||
inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; }
|
inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; }
|
||||||
inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; }
|
inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; }
|
||||||
inline uint32_t SegmentFsm::getState () const { return _state; }
|
inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; }
|
||||||
inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); }
|
inline uint32_t SegmentFsm::getState () const { return _state; }
|
||||||
inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; }
|
inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); }
|
||||||
inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; }
|
inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; }
|
||||||
inline DataNegociate* SegmentFsm::getData1 () { return _data1; }
|
inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; }
|
||||||
inline DataNegociate* SegmentFsm::getData2 () { return _data2; }
|
inline DataNegociate* SegmentFsm::getData1 () { return _data1; }
|
||||||
inline Interval& SegmentFsm::getConstraint () { return _constraint; }
|
inline DataNegociate* SegmentFsm::getData2 () { return _data2; }
|
||||||
inline Interval& SegmentFsm::getOptimal () { return _optimal; }
|
inline Interval& SegmentFsm::getConstraint () { return _constraint; }
|
||||||
inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; }
|
inline Interval& SegmentFsm::getOptimal () { return _optimal; }
|
||||||
inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; }
|
inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; }
|
||||||
inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); }
|
inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; }
|
||||||
inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); }
|
inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); }
|
||||||
inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); }
|
inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); }
|
||||||
inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); }
|
inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); }
|
||||||
inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); }
|
inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); }
|
||||||
inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); }
|
inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); }
|
||||||
inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); }
|
inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); }
|
||||||
inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); }
|
inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); }
|
||||||
inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); }
|
inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); }
|
||||||
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
|
inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); }
|
||||||
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; }
|
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
|
||||||
inline void SegmentFsm::clearActions () { _actions.clear(); }
|
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; }
|
||||||
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; }
|
inline void SegmentFsm::clearActions () { _actions.clear(); }
|
||||||
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; }
|
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; }
|
||||||
|
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; }
|
||||||
|
|
||||||
|
|
||||||
} // Katana namespace.
|
} // Katana namespace.
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace Katana {
|
||||||
using Hurricane::Contact;
|
using Hurricane::Contact;
|
||||||
using Hurricane::Segment;
|
using Hurricane::Segment;
|
||||||
using Hurricane::DbU;
|
using Hurricane::DbU;
|
||||||
|
using Hurricane::Interval;
|
||||||
using Anabatic::AutoContact;
|
using Anabatic::AutoContact;
|
||||||
using Anabatic::AutoSegment;
|
using Anabatic::AutoSegment;
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ namespace Katana {
|
||||||
inline static uint32_t getRipupCost ();
|
inline static uint32_t getRipupCost ();
|
||||||
inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit );
|
inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit );
|
||||||
static void setInterrupt ( bool );
|
static void setInterrupt ( bool );
|
||||||
|
inline static Interval& toAxisInterval ( Interval&, size_t depth );
|
||||||
inline static void addInsertEvent ( TrackMarker* , Track* );
|
inline static void addInsertEvent ( TrackMarker* , Track* );
|
||||||
inline static void addInsertEvent ( TrackElement* , Track* );
|
inline static void addInsertEvent ( TrackElement* , Track* );
|
||||||
inline static void addRemoveEvent ( TrackElement* );
|
inline static void addRemoveEvent ( TrackElement* );
|
||||||
|
@ -90,6 +92,7 @@ namespace Katana {
|
||||||
Net* _getBlockageNet ();
|
Net* _getBlockageNet ();
|
||||||
uint32_t _getRipupCost ();
|
uint32_t _getRipupCost ();
|
||||||
Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit );
|
Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit );
|
||||||
|
Interval& _toAxisInterval ( Interval&, size_t depth ) const;
|
||||||
void _doLockEvents ();
|
void _doLockEvents ();
|
||||||
void _doRemovalEvents ();
|
void _doRemovalEvents ();
|
||||||
virtual size_t _revalidate ();
|
virtual size_t _revalidate ();
|
||||||
|
@ -164,6 +167,9 @@ namespace Katana {
|
||||||
inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y )
|
inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y )
|
||||||
{ return get("getGCellUnder()")->_getGCellUnder(x,y); }
|
{ return get("getGCellUnder()")->_getGCellUnder(x,y); }
|
||||||
|
|
||||||
|
inline Interval& Session::toAxisInterval ( Interval& interval, size_t depth )
|
||||||
|
{ return get("getGCellUnder()")->_toAxisInterval(interval,depth); }
|
||||||
|
|
||||||
inline void Session::addInsertEvent ( TrackMarker* marker, Track* track )
|
inline void Session::addInsertEvent ( TrackMarker* marker, Track* track )
|
||||||
{ get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); }
|
{ get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); }
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace Katana {
|
||||||
virtual Segment* getSegment () const = 0;
|
virtual Segment* getSegment () const = 0;
|
||||||
// Wrapped AutoSegment Functions (when applicable).
|
// Wrapped AutoSegment Functions (when applicable).
|
||||||
virtual bool isFixed () const;
|
virtual bool isFixed () const;
|
||||||
|
virtual bool isFixedAxis () const;
|
||||||
virtual bool isHorizontal () const = 0;
|
virtual bool isHorizontal () const = 0;
|
||||||
virtual bool isVertical () const = 0;
|
virtual bool isVertical () const = 0;
|
||||||
virtual bool isWide () const;
|
virtual bool isWide () const;
|
||||||
|
@ -151,11 +152,13 @@ namespace Katana {
|
||||||
inline Box getBoundingBox () const;
|
inline Box getBoundingBox () const;
|
||||||
virtual TrackElement* getNext () const;
|
virtual TrackElement* getNext () const;
|
||||||
virtual TrackElement* getPrevious () const;
|
virtual TrackElement* getPrevious () const;
|
||||||
virtual DbU::Unit getExtensionCap () const;
|
virtual DbU::Unit getExtensionCap ( Flags ) const;
|
||||||
virtual DbU::Unit getAxis () const = 0;
|
virtual DbU::Unit getAxis () const = 0;
|
||||||
inline DbU::Unit getSymmetricAxis ( DbU::Unit ) const;
|
inline DbU::Unit getSymmetricAxis ( DbU::Unit ) const;
|
||||||
inline DbU::Unit getSourceU () const;
|
inline DbU::Unit getSourceU () const;
|
||||||
inline DbU::Unit getTargetU () const;
|
inline DbU::Unit getTargetU () const;
|
||||||
|
virtual DbU::Unit getSourceAxis () const = 0;
|
||||||
|
virtual DbU::Unit getTargetAxis () const = 0;
|
||||||
inline DbU::Unit getLength () const;
|
inline DbU::Unit getLength () const;
|
||||||
inline Interval getCanonicalInterval () const;
|
inline Interval getCanonicalInterval () const;
|
||||||
virtual Interval getFreeInterval () const;
|
virtual Interval getFreeInterval () const;
|
||||||
|
|
|
@ -55,6 +55,8 @@ namespace Katana {
|
||||||
virtual TrackElement* getNext () const;
|
virtual TrackElement* getNext () const;
|
||||||
virtual TrackElement* getPrevious () const;
|
virtual TrackElement* getPrevious () const;
|
||||||
virtual DbU::Unit getAxis () const;
|
virtual DbU::Unit getAxis () const;
|
||||||
|
inline DbU::Unit getSourceAxis () const;
|
||||||
|
virtual DbU::Unit getTargetAxis () const;
|
||||||
virtual Interval getFreeInterval () const;
|
virtual Interval getFreeInterval () const;
|
||||||
virtual void addOverlapCost ( TrackCost& ) const;
|
virtual void addOverlapCost ( TrackCost& ) const;
|
||||||
virtual float getPriority () const;
|
virtual float getPriority () const;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
//
|
//
|
||||||
// This file is part of the Coriolis Software.
|
// This file is part of the Coriolis Software.
|
||||||
// Copyright (c) UPMC 2008-2013, All Rights Reserved
|
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||||
//
|
//
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
// | C O R I O L I S |
|
// | C O R I O L I S |
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
// | Author : Jean-Paul CHAPUT |
|
// | Author : Jean-Paul CHAPUT |
|
||||||
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||||
// | =============================================================== |
|
// | =============================================================== |
|
||||||
// | C++ Header : "./katana/TrackMarker.h" |
|
// | C++ Header : "./katana/TrackMarker.h" |
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ namespace Katana {
|
||||||
|
|
||||||
using Hurricane::Record;
|
using Hurricane::Record;
|
||||||
using Hurricane::DbU;
|
using Hurricane::DbU;
|
||||||
|
using Hurricane::Interval;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
using Hurricane::Net;
|
using Hurricane::Net;
|
||||||
|
|
||||||
|
@ -47,8 +48,10 @@ namespace Katana {
|
||||||
void destroy ();
|
void destroy ();
|
||||||
public:
|
public:
|
||||||
Net* getNet () const;
|
Net* getNet () const;
|
||||||
|
inline uint32_t getRefCount () const;
|
||||||
inline DbU::Unit getSourceU () const;
|
inline DbU::Unit getSourceU () const;
|
||||||
inline DbU::Unit getTargetU () const;
|
inline DbU::Unit getTargetU () const;
|
||||||
|
inline Interval getSpan () const;
|
||||||
inline Track* getTrack () const;
|
inline Track* getTrack () const;
|
||||||
inline uint32_t getWeight ( const Track* ) const;
|
inline uint32_t getWeight ( const Track* ) const;
|
||||||
inline void setTrack ( Track* );
|
inline void setTrack ( Track* );
|
||||||
|
@ -85,11 +88,13 @@ namespace Katana {
|
||||||
|
|
||||||
|
|
||||||
// Inline Functions.
|
// Inline Functions.
|
||||||
inline DbU::Unit TrackMarker::getSourceU () const { return _sourcePosition; }
|
inline uint32_t TrackMarker::getRefCount () const { return _refcount; }
|
||||||
inline DbU::Unit TrackMarker::getTargetU () const { return _targetPosition; }
|
inline DbU::Unit TrackMarker::getSourceU () const { return _sourcePosition; }
|
||||||
inline Track* TrackMarker::getTrack () const { return _track; }
|
inline DbU::Unit TrackMarker::getTargetU () const { return _targetPosition; }
|
||||||
inline uint32_t TrackMarker::getWeight ( const Track* track ) const { return _weight; }
|
inline Interval TrackMarker::getSpan () const { return Interval(_sourcePosition,_targetPosition); }
|
||||||
inline void TrackMarker::setTrack ( Track* track ) { _track = track; }
|
inline Track* TrackMarker::getTrack () const { return _track; }
|
||||||
|
inline uint32_t TrackMarker::getWeight ( const Track* track ) const { return _weight; }
|
||||||
|
inline void TrackMarker::setTrack ( Track* track ) { _track = track; }
|
||||||
|
|
||||||
inline bool TrackMarker::Compare::operator() ( const TrackMarker* lhs, const TrackMarker* rhs ) const
|
inline bool TrackMarker::Compare::operator() ( const TrackMarker* lhs, const TrackMarker* rhs ) const
|
||||||
{ return markerLess ( lhs->getSourceU(), rhs->getSourceU() ); }
|
{ return markerLess ( lhs->getSourceU(), rhs->getSourceU() ); }
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace Katana {
|
||||||
virtual AutoSegment* base () const;
|
virtual AutoSegment* base () const;
|
||||||
virtual Segment* getSegment () const;
|
virtual Segment* getSegment () const;
|
||||||
virtual bool isFixed () const;
|
virtual bool isFixed () const;
|
||||||
|
virtual bool isFixedAxis () const;
|
||||||
virtual bool isHorizontal () const;
|
virtual bool isHorizontal () const;
|
||||||
virtual bool isVertical () const;
|
virtual bool isVertical () const;
|
||||||
virtual bool isLocal () const;
|
virtual bool isLocal () const;
|
||||||
|
@ -85,11 +86,11 @@ namespace Katana {
|
||||||
virtual bool canDogleg ();
|
virtual bool canDogleg ();
|
||||||
virtual bool canDogleg ( Interval );
|
virtual bool canDogleg ( Interval );
|
||||||
virtual bool canDogleg ( Anabatic::GCell*, Flags flags=0 );
|
virtual bool canDogleg ( Anabatic::GCell*, Flags flags=0 );
|
||||||
virtual bool canPivotUp ( float reserve, Flags flags ) const;
|
virtual bool canPivotUp ( float reserve, Flags ) const;
|
||||||
virtual bool canPivotDown ( float reserve, Flags flags ) const;
|
virtual bool canPivotDown ( float reserve, Flags ) const;
|
||||||
virtual bool canMoveUp ( float reserve, Flags flags ) const;
|
virtual bool canMoveUp ( float reserve, Flags ) const;
|
||||||
virtual bool canSlacken () const;
|
virtual bool canSlacken () const;
|
||||||
virtual float getMaxUnderDensity ( Flags flags ) const;
|
virtual float getMaxUnderDensity ( Flags ) const;
|
||||||
virtual unsigned long getId () const;
|
virtual unsigned long getId () const;
|
||||||
virtual Flags getDirection () const;
|
virtual Flags getDirection () const;
|
||||||
virtual Net* getNet () const;
|
virtual Net* getNet () const;
|
||||||
|
@ -97,7 +98,7 @@ namespace Katana {
|
||||||
virtual const Layer* getLayer () const;
|
virtual const Layer* getLayer () const;
|
||||||
virtual DbU::Unit getPitch () const;
|
virtual DbU::Unit getPitch () const;
|
||||||
virtual DbU::Unit getPPitch () const;
|
virtual DbU::Unit getPPitch () const;
|
||||||
virtual DbU::Unit getExtensionCap () const;
|
virtual DbU::Unit getExtensionCap ( Flags ) const;
|
||||||
virtual unsigned long getFreedomDegree () const;
|
virtual unsigned long getFreedomDegree () const;
|
||||||
virtual float getPriority () const;
|
virtual float getPriority () const;
|
||||||
virtual uint32_t getDoglegLevel () const;
|
virtual uint32_t getDoglegLevel () const;
|
||||||
|
@ -105,6 +106,8 @@ namespace Katana {
|
||||||
virtual TrackElement* getPrevious () const;
|
virtual TrackElement* getPrevious () const;
|
||||||
virtual TrackElement* getParent () const;
|
virtual TrackElement* getParent () const;
|
||||||
virtual DbU::Unit getAxis () const;
|
virtual DbU::Unit getAxis () const;
|
||||||
|
virtual DbU::Unit getSourceAxis () const;
|
||||||
|
virtual DbU::Unit getTargetAxis () const;
|
||||||
virtual Interval getFreeInterval () const;
|
virtual Interval getFreeInterval () const;
|
||||||
virtual Interval getSourceConstraints () const;
|
virtual Interval getSourceConstraints () const;
|
||||||
virtual Interval getTargetConstraints () const;
|
virtual Interval getTargetConstraints () const;
|
||||||
|
@ -137,10 +140,10 @@ namespace Katana {
|
||||||
virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel );
|
virtual TrackElement* makeDogleg ( Anabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel );
|
||||||
virtual TrackElement* makeDogleg ( Interval, Flags& flags );
|
virtual TrackElement* makeDogleg ( Interval, Flags& flags );
|
||||||
virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel );
|
virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel );
|
||||||
virtual bool moveAside ( Flags flags );
|
virtual bool moveAside ( Flags );
|
||||||
virtual bool slacken ( Flags flags=Flags::NoFlags );
|
virtual bool slacken ( Flags flags=Flags::NoFlags );
|
||||||
virtual bool moveUp ( Flags flags );
|
virtual bool moveUp ( Flags );
|
||||||
virtual bool moveDown ( Flags flags );
|
virtual bool moveDown ( Flags );
|
||||||
#if THIS_IS_DISABLED
|
#if THIS_IS_DISABLED
|
||||||
virtual void desalignate ();
|
virtual void desalignate ();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue