Added support for loading user defined global routing in Anabatic.

* New: In Hurricane::NetRoutingProperty, add and change the meaning
    of the following flags:
      - ManualGlobalRoute : now means that a global routing *trunk*
        is present, made of "gmetalh", "gmetalv" & "gcontact".
      - Manualdetailroute : added, get the former meaning of
        ManualGlobalRoute, that is, the detailed routing is
	already present for this net, but can be changed by the
	detailed router. Implies that it respect the Terminal,
	HTee & VTee structuration.
* New: Add Anabatic::Diskstra::loadFixedGlobal(), to account
    a manually global net into the edges capacities.
* New: In Anabatic::Edges::ripup(), exclude manually global routed
    segments from the ripup. Change the segment sorting function
    so that thoses segments are put in head of list (considered
    as "smaller").
* Change: In AnabaticEngine::setupPreRouteds(), now detect manual
    global routed and manual detail routed signals, and tag them
    accordingly.
* New: In AnabaticEngine::Configuration & Session, add proxies
    for the global routing layers ("gmetalh", "gmetalv", "gcontact").
* New: In Anabatic::Constants, add flags for global fixed and
    detail routed nets.
* Change: In KatanaEngine::updateEstimateDensity(), now use int64_t
    for flute coordinates.
* New: Add CRL::RoutingGauge::hasLayer(), to know if a layer is
    managed by the gauge (comparison by mask).
This commit is contained in:
Jean-Paul Chaput 2020-09-30 11:55:39 +02:00
parent 18405599e8
commit 8f0a8e5a3a
24 changed files with 326 additions and 64 deletions

View File

@ -1144,7 +1144,8 @@ namespace Anabatic {
//AutoSegment::setShortNetMode( true );
++shortNets;
}
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
if ( NetRoutingExtension::isManualGlobalRoute(net)
or NetRoutingExtension::isAutomaticGlobalRoute(net)) {
DebugSession::open( net, 145, 150 );
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );

View File

@ -93,6 +93,14 @@ namespace Anabatic {
mergeNativeMax( gcell->getConstraintYMax() );
}
}
if (getId() == 1518590) {
cerr << "AutoHorizontal::_postCreate(): " << this << endl;
cerr << "| Source contact:" << source << endl;
cerr << "| Source GCell: " << getGCell() << endl;
cerr << "| Target contact:" << target << endl;
cerr << "| Target GCell: " << target->getGCell() << endl;
}
}

View File

@ -54,9 +54,11 @@ namespace Anabatic {
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
// Flags for NetDatas objects states only.
const BaseFlags Flags::GlobalRouted = (1L << 5);
const BaseFlags Flags::GlobalFixed = (1L << 5);
const BaseFlags Flags::GlobalEstimated = (1L << 6);
const BaseFlags Flags::ExcludeRoute = (1L << 7);
const BaseFlags Flags::GlobalRouted = (1L << 7);
const BaseFlags Flags::DetailRouted = (1L << 8);
const BaseFlags Flags::ExcludeRoute = (1L << 9);
// Masks.
const BaseFlags Flags::WestSide = Horizontal|Target;
const BaseFlags Flags::EastSide = Horizontal|Source;

View File

@ -1478,6 +1478,48 @@ namespace Anabatic {
}
void Dijkstra::loadFixedGlobal ( Net* net )
{
NetData* netData = _anabatic->getNetData( net );
netData->setGlobalRouted( true );
netData->setGlobalFixed ( true );
for ( Component* component : net->getComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal) {
if (not Session::isGLayer(horizontal->getLayer())) {
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
) << endl;
continue;
}
GCell* begin = _anabatic->getGCellUnder( horizontal->getSource()->getPosition() );
GCell* end = _anabatic->getGCellUnder( horizontal->getTarget()->getPosition() );
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end) )
edge->add( horizontal );
}
Vertical* vertical = dynamic_cast<Vertical*>( component );
if (vertical) {
if (not Session::isGLayer(vertical->getLayer())) {
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
) << endl;
continue;
}
GCell* begin = _anabatic->getGCellUnder( vertical->getSource()->getPosition() );
GCell* end = _anabatic->getGCellUnder( vertical->getTarget()->getPosition() );
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end,Flags::NorthPath) )
edge->add( vertical );
}
}
}
void Dijkstra::load ( Net* net )
{
_cleanup();

View File

@ -29,16 +29,31 @@ namespace {
using namespace std;
using namespace Hurricane;
using Anabatic::NetData;
using Anabatic::AnabaticEngine;
class SortSegmentByLength {
public:
inline SortSegmentByLength ( AnabaticEngine* );
inline bool operator() ( const Segment*, const Segment* );
private:
AnabaticEngine* _anabatic;
};
inline SortSegmentByLength::SortSegmentByLength ( AnabaticEngine* anabatic )
: _anabatic(anabatic)
{ }
inline bool SortSegmentByLength::operator() ( const Segment* lhs, const Segment* rhs )
{
NetData* lhsNData = _anabatic->getNetData( lhs->getNet() );
NetData* rhsNData = _anabatic->getNetData( rhs->getNet() );
if (lhsNData->isGlobalFixed() and not rhsNData->isGlobalFixed()) return true;
if (rhsNData->isGlobalFixed() and not lhsNData->isGlobalFixed()) return false;
DbU::Unit delta = rhs->getLength() - lhs->getLength();
if (delta > 0) return true;
if (delta < 0) return false;
@ -358,12 +373,13 @@ namespace Anabatic {
AnabaticEngine* anabatic = getAnabatic();
size_t netCount = 0;
sort( _segments.begin(), _segments.end(), SortSegmentByLength() );
sort( _segments.begin(), _segments.end(), SortSegmentByLength(anabatic) );
if (Session::getRoutingGauge()->isTwoMetals()) {
for ( size_t i=0 ; i<_segments.size() ; ) {
if (not isEnding(_segments[i])) {
NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
if (netData->isGlobalFixed ()) break;
if (netData->isGlobalRouted()) ++netCount;
anabatic->ripup( _segments[i], Flags::Propagate );
continue;
@ -374,6 +390,7 @@ namespace Anabatic {
size_t truncate = (size_t)( (getCapacity()*2) / 3 );
while ( _segments.size() > truncate ) {
NetData* netData = anabatic->getNetData( _segments[truncate]->getNet() );
if (netData->isGlobalFixed ()) break;
if (netData->isGlobalRouted()) ++netCount;
anabatic->ripup( _segments[truncate], Flags::Propagate );
}

View File

@ -35,6 +35,7 @@ namespace Anabatic {
using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Pin;
using Hurricane::Plug;
using Hurricane::DeepNet;
using Hurricane::Cell;
using Hurricane::NetRoutingExtension;
@ -85,47 +86,69 @@ namespace Anabatic {
vector<Segment*> segments;
vector<Contact*> contacts;
bool isPreRouted = false;
bool isManualGlobalRouted = false;
bool isManualDetailRouted = false;
bool isFixed = false;
size_t rpCount = 0;
for( Component* component : net->getComponents() ) {
if (dynamic_cast<Pin*>(component)) continue;
if (dynamic_cast<Pin *>(component)) continue;
if (dynamic_cast<Plug*>(component)) continue;
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
continue;
if ( not Session::isGaugeLayer(component->getLayer())
and not Session::isGLayer (component->getLayer()))
throw Error( "AnabaticEngine::setupPreRouted(): A component of \"%s\" has a routing gauge umanaged layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
);
Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
if (horizontal) {
if ( not ab.contains(horizontal->getSourcePosition())
and not ab.contains(horizontal->getTargetPosition()) ) continue;
segments.push_back( horizontal );
isPreRouted = true;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualDetailRouted = true;
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
isFixed = true;
}
} else {
Vertical* vertical = dynamic_cast<Vertical*>(component);
if (vertical) {
if ( not ab.contains(vertical->getSourcePosition())
and not ab.contains(vertical->getTargetPosition()) ) continue;
isPreRouted = true;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualDetailRouted = true;
segments.push_back( vertical );
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
isFixed = true;
}
} else {
Contact* contact = dynamic_cast<Contact*>(component);
if (contact) {
if (not ab.contains(contact->getCenter())) continue;
isPreRouted = true;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualGlobalRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
or (contact->getLayer () == Session::getContactLayer(0)) )
isFixed = true;
}
} else {
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
if (rp) {
@ -142,7 +165,10 @@ namespace Anabatic {
}
}
if ((not isFixed and not isPreRouted) and net->isDeepNet()) {
if ( (not isFixed)
and (not isManualGlobalRouted)
and (not isManualDetailRouted)
and net->isDeepNet()) {
Net* rootNet = dynamic_cast<Net*>(
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
for( Component* component : rootNet->getComponents() ) {
@ -152,29 +178,34 @@ namespace Anabatic {
}
}
if (isFixed or isPreRouted or (rpCount < 2)) {
if (isFixed or isManualDetailRouted or isManualGlobalRouted or (rpCount < 2)) {
NetData* ndata = getNetData( net, Flags::Create );
NetRoutingState* state = ndata->getNetRoutingState();
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute );
if (isManualGlobalRouted) {
state->setFlags( NetRoutingState::ManualGlobalRoute );
ndata->setGlobalFixed( true );
}
if (isManualDetailRouted)
state->setFlags( NetRoutingState::ManualDetailRoute );
ndata->setGlobalRouted( true );
if (rpCount < 2)
state->setFlags ( NetRoutingState::Unconnected );
state->setFlags( NetRoutingState::Unconnected );
if (isFixed) {
if (rpCount > 1)
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
state->unsetFlags( NetRoutingState::ManualGlobalRoute|NetRoutingState::ManualDetailRoute );
state->setFlags ( NetRoutingState::Fixed );
} else {
} else if (isManualGlobalRouted) {
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
} else if (isManualDetailRouted) {
if (rpCount > 1) {
++toBeRouteds;
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
for ( auto icontact : contacts ) {
AutoContact::createFrom( icontact );
cmess2 << " - <" << net->getName() << "> is manually detail routed." << endl;
for ( auto contact : contacts ) {
AutoContact::createFrom( contact );
}
for ( auto segment : segments ) {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() ));
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() ));

View File

@ -14,20 +14,16 @@
// +-----------------------------------------------------------------+
#ifndef ANABATIC_ANABATIC_ENGINE_H
#define ANABATIC_ANABATIC_ENGINE_H
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <set>
#include "hurricane/NetRoutingProperty.h"
namespace Hurricane {
class Instance;
class CellViewer;
}
#include "crlcore/ToolEngine.h"
#include "anabatic/Configuration.h"
#include "anabatic/Matrix.h"
@ -107,6 +103,7 @@ namespace Anabatic {
NetData ( Net* );
inline bool isGlobalEstimated () const;
inline bool isGlobalRouted () const;
inline bool isGlobalFixed () const;
inline bool isMixedPreRoute () const;
inline bool isFixed () const;
inline bool isExcluded () const;
@ -120,6 +117,7 @@ namespace Anabatic {
inline void setSearchArea ( Box );
inline void setGlobalEstimated ( bool );
inline void setGlobalRouted ( bool );
inline void setGlobalFixed ( bool );
inline void setExcluded ( bool );
inline void setRpCount ( size_t );
private:
@ -138,6 +136,7 @@ namespace Anabatic {
inline bool NetData::isGlobalEstimated () const { return _flags & Flags::GlobalEstimated; }
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
inline bool NetData::isGlobalFixed () const { return _flags & Flags::GlobalFixed; }
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : false; }
inline bool NetData::isExcluded () const { return _flags & Flags::ExcludeRoute; }
@ -150,6 +149,7 @@ namespace Anabatic {
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
inline void NetData::setGlobalEstimated ( bool state ) { _flags.set(Flags::GlobalEstimated,state); }
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted ,state); }
inline void NetData::setGlobalFixed ( bool state ) { _flags.set(Flags::GlobalFixed ,state); }
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
@ -419,5 +419,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
#endif // ANABATIC_ANABATIC_ENGINE_H

View File

@ -64,6 +64,7 @@ namespace Anabatic {
virtual ~Configuration ();
virtual Configuration* clone () const;
// Methods.
inline bool isGLayer ( const Layer* ) const;
bool isGMetal ( const Layer* ) const;
bool isGContact ( const Layer* ) const;
bool isTwoMetals () const;
@ -160,6 +161,7 @@ namespace Anabatic {
};
inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); }
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); }

View File

@ -52,9 +52,11 @@ namespace Anabatic {
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
// Flags for NetDatas objects states only.
static const BaseFlags GlobalRouted ; // = (1 << 5);
static const BaseFlags GlobalFixed ; // = (1 << 5);
static const BaseFlags GlobalEstimated ; // = (1 << 6);
static const BaseFlags ExcludeRoute ; // = (1 << 7);
static const BaseFlags GlobalRouted ; // = (1 << 7);
static const BaseFlags DetailRouted ; // = (1 << 8);
static const BaseFlags ExcludeRoute ; // = (1 << 9);
// Masks.
static const BaseFlags WestSide ; // = Horizontal|Target;
static const BaseFlags EastSide ; // = Horizontal|Source;

View File

@ -517,6 +517,7 @@ namespace Anabatic {
inline DistanceT* setDistance ( DistanceT );
inline void setSearchAreaHalo ( DbU::Unit );
void load ( Net* net );
void loadFixedGlobal ( Net* net );
void run ( Mode mode=Mode::Standart );
inline const VertexSet& getSources () const;
private:

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef ANABATIC_EDGE_H
#define ANABATIC_EDGE_H
#pragma once
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Interval.h"
@ -168,5 +166,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::Edge);
#endif // ANABATIC_EDGE_H

View File

@ -109,6 +109,10 @@ namespace Anabatic {
static inline DbU::Unit getDContactWidth ();
static inline DbU::Unit getDContactPitch ();
static inline RoutingGauge* getRoutingGauge ();
static inline bool isGLayer ( const Layer* );
static inline bool isGMetal ( const Layer* );
static inline bool isGContact ( const Layer* );
static inline bool isGaugeLayer ( const Layer* );
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
static inline size_t getDepth ();
static inline size_t getViaDepth ( const Layer* layer );
@ -246,6 +250,10 @@ namespace Anabatic {
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
inline bool Session::isGLayer ( const Layer* layer ) { return getConfiguration()->isGLayer(layer); }
inline bool Session::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); }
inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); }
inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(layer); }
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }

View File

@ -120,6 +120,10 @@ namespace CRL {
}
bool RoutingGauge::hasLayer ( const Layer* layer ) const
{ return (getLayerGauge(layer) != NULL) or (getViaDepth(layer) != nlayerdepth); }
RoutingLayerGauge* RoutingGauge::getHorizontalGauge () const
{
RoutingLayerGauge* pinOnly = NULL;

View File

@ -58,6 +58,7 @@ namespace CRL {
inline bool isTwoMetals () const;
inline bool isHV () const;
inline bool isVH () const;
bool hasLayer ( const Layer* ) const;
// Accessors.
RoutingGauge* getClone () const;
inline const Name getName () const;

133
flute/src/3.1/PyFlute.cpp Normal file
View File

@ -0,0 +1,133 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2020-2020, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | F l u t e - Flute / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyFlute.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyPoint.h"
#include "crlcore/Utilities.h"
#include <sstream>
#include <stddef.h>
#include "flute.h"
namespace Flute {
using namespace Hurricane;
using namespace Isobar;
using namespace std;
using CRL::System;
#if !defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PyFlute" Shared Library Code Part |
// +=================================================================+
# else // PyFlute Shared Library Code Part.
// +=================================================================+
// | "PyFlute" Python Module Code Part |
// +=================================================================+
extern "C" {
static PyObject* PyFlute_readLUT ( PyObject* self, PyObject* )
{
HTRY
Flute::readLUT( System::getPath( "coriolis_top" ).toString() );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyFlute_flute ( PyObject* self, PyObject* args )
{
PyObject* treeTuple = NULL;
HTRY
PyObject* pyPoints = NULL;
if (PyArg_ParseTuple(args,"O:Flute.flute()",&pyPoints)) {
} else {
PyErr_SetString( ConstructorError, "Flute.flute(): Takes only one argument." );
return NULL;
}
if (not PyList_Check(pyPoints)) {
PyErr_SetString( ConstructorError, "Flute.flute(): Argument must be a list." );
return NULL;
}
size_t size = PyList_Size( pyPoints );
int accuracy = 3;
int64_t* xs = new int64_t [size];
int64_t* ys = new int64_t [size];
for ( size_t i=0 ; i<size ; ++i ) {
PyObject* pyPoint = PyList_GetItem( pyPoints, i );
if (not PyTuple_Check(pyPoint) or (PyTuple_Size(pyPoint) != 2)) {
ostringstream message;
message << "Flute.flute(): Item " << i << " of the list is *not* a 2 elements tuple.";
PyErr_SetString( Isobar::ConstructorError, message.str().c_str() );
return NULL;
}
xs[ i ] = (int64_t)PyInt_AsLong( PyTuple_GetItem( pyPoint, 0 ) );
ys[ i ] = (int64_t)PyInt_AsLong( PyTuple_GetItem( pyPoint, 1 ) );
}
Tree tree = flute( size, xs, ys, accuracy );
treeTuple = PyTuple_New( 2*tree.deg - 2 );
for ( size_t i=0 ; (int)i < 2*tree.deg - 2 ; ++i ) {
PyObject* flutePoint = PyTuple_New( 3 );
PyTuple_SetItem( flutePoint, 0, PyInt_FromLong( tree.branch[i].n) );
PyTuple_SetItem( flutePoint, 1, PyDbU_FromLong((DbU::Unit)tree.branch[i].x) );
PyTuple_SetItem( flutePoint, 2, PyDbU_FromLong((DbU::Unit)tree.branch[i].y) );
PyTuple_SetItem( treeTuple, i, flutePoint);
}
HCATCH
return treeTuple;
}
static PyMethodDef PyFlute_Methods[] =
{ { "flute" , PyFlute_flute , METH_VARARGS, "Call Flute on a set of points." }
, { "readLUT" , PyFlute_readLUT, METH_NOARGS , "Load POWV9.dat & POST9.dat." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
// ---------------------------------------------------------------
// Module Initialization : "initFlute ()"
DL_EXPORT(void) initFlute ()
{
cdebug_log(20,0) << "initFlute()" << endl;
PyObject* module = Py_InitModule( "Flute", PyFlute_Methods );
if (not module) {
cerr << "[ERROR]\n"
<< " Failed to initialize Flute module." << endl;
return;
}
cdebug_log(20,0) << "Flute.so loaded " << (void*)&typeid(string) << endl;
}
} // extern "C".
#endif // Python Module Code Part.
} // Isobar namespace.

View File

@ -43,6 +43,7 @@ namespace Hurricane {
s += (isFixed ()) ? 'f' : '-';
s += (isUnconnected ()) ? 'u' : '-';
s += (isManualGlobalRoute ()) ? 'm' : '-';
s += (isManualDetailRoute ()) ? 'd' : '-';
s += (isAutomaticGlobalRoute()) ? 'a' : '-';
s += (isSymmetric ()) ? 'S' : '-';
s += (isSymHorizontal ()) ? 'h' : '-';
@ -175,6 +176,7 @@ namespace Hurricane {
flags |= (sflags[1] == 'f') ? NetRoutingState::Fixed : 0;
flags |= (sflags[2] == 'u') ? NetRoutingState::Unconnected : 0;
flags |= (sflags[3] == 'm') ? NetRoutingState::ManualGlobalRoute : 0;
flags |= (sflags[3] == 'd') ? NetRoutingState::ManualDetailRoute : 0;
flags |= (sflags[4] == 'a') ? NetRoutingState::AutomaticGlobalRoute : 0;
flags |= (sflags[5] == 'S') ? NetRoutingState::Symmetric : 0;
flags |= (sflags[6] == 'h') ? NetRoutingState::Horizontal : 0;

View File

@ -42,20 +42,22 @@ namespace Hurricane {
, Fixed = (1<< 1)
, Unconnected = (1<< 2)
, ManualGlobalRoute = (1<< 3)
, AutomaticGlobalRoute = (1<< 4)
, MixedPreRoute = Fixed|ManualGlobalRoute
, Horizontal = (1<< 5)
, Vertical = (1<< 6)
, Symmetric = (1<< 7)
, SymmetricMaster = (1<< 8)
, Analog = (1<< 9)
, ShortNet = (1<<10)
, ManualDetailRoute = (1<< 4)
, AutomaticGlobalRoute = (1<< 5)
, MixedPreRoute = Fixed|ManualDetailRoute
, Horizontal = (1<< 6)
, Vertical = (1<< 7)
, Symmetric = (1<< 8)
, SymmetricMaster = (1<< 9)
, Analog = (1<<10)
, ShortNet = (1<<11)
};
public:
inline bool isExcluded () const;
inline bool isFixed () const;
inline bool isUnconnected () const;
inline bool isManualGlobalRoute () const;
inline bool isManualDetailRoute () const;
inline bool isAutomaticGlobalRoute () const;
inline bool isMixedPreRoute () const;
inline bool isSymmetric () const;
@ -98,6 +100,7 @@ namespace Hurricane {
inline bool NetRoutingState::isFixed () const { return _flags & Fixed; };
inline bool NetRoutingState::isUnconnected () const { return _flags & Unconnected; };
inline bool NetRoutingState::isManualGlobalRoute () const { return _flags & ManualGlobalRoute; };
inline bool NetRoutingState::isManualDetailRoute () const { return _flags & ManualDetailRoute; };
inline bool NetRoutingState::isAutomaticGlobalRoute () const { return _flags & AutomaticGlobalRoute; };
inline bool NetRoutingState::isMixedPreRoute () const { return _flags & MixedPreRoute; };
inline bool NetRoutingState::isSymmetric () const { return _flags & Symmetric; }
@ -173,6 +176,7 @@ namespace Hurricane {
static inline bool isUnconnected ( const Net* );
static inline bool isFixed ( const Net* );
static inline bool isManualGlobalRoute ( const Net* );
static inline bool isManualDetailRoute ( const Net* );
static inline bool isAutomaticGlobalRoute ( const Net* );
static inline bool isMixedPreRoute ( const Net* );
static inline bool isSymmetric ( const Net* );
@ -221,6 +225,13 @@ namespace Hurricane {
}
inline bool NetRoutingExtension::isManualDetailRoute ( const Net* net )
{
NetRoutingState* state = get( net );
return (state == NULL) ? false : state->isManualDetailRoute();
}
inline bool NetRoutingExtension::isAutomaticGlobalRoute ( const Net* net )
{
NetRoutingState* state = get( net );

View File

@ -121,6 +121,7 @@ extern "C" {
ExtensionGetBoolFunction(isFixed ,NetRoutingExtension)
ExtensionGetBoolFunction(isUnconnected ,NetRoutingExtension)
ExtensionGetBoolFunction(isManualGlobalRoute ,NetRoutingExtension)
ExtensionGetBoolFunction(isManualDetailRoute ,NetRoutingExtension)
ExtensionGetBoolFunction(isAutomaticGlobalRoute,NetRoutingExtension)
ExtensionGetBoolFunction(isMixedPreRoute ,NetRoutingExtension)
ExtensionGetBoolFunction(isSymmetric ,NetRoutingExtension)
@ -197,6 +198,7 @@ extern "C" {
{ { "isFixed" , (PyCFunction)PyNetRoutingExtension_isFixed , METH_NOARGS |METH_CLASS , "To be documented." }
, { "isUnconnected" , (PyCFunction)PyNetRoutingExtension_isUnconnected , METH_NOARGS |METH_CLASS , "To be documented." }
, { "isManualGlobalRoute" , (PyCFunction)PyNetRoutingExtension_isManualGlobalRoute , METH_NOARGS |METH_CLASS , "To be documented." }
, { "isManualDetailRoute" , (PyCFunction)PyNetRoutingExtension_isManualDetailRoute , METH_NOARGS |METH_CLASS , "To be documented." }
, { "isAutomaticGlobalRoute", (PyCFunction)PyNetRoutingExtension_isAutomaticGlobalRoute, METH_NOARGS |METH_CLASS , "To be documented." }
, { "isMixedPreRoute" , (PyCFunction)PyNetRoutingExtension_isMixedPreRoute , METH_NOARGS |METH_CLASS , "To be documented." }
, { "isSymmetric" , (PyCFunction)PyNetRoutingExtension_isSymmetric , METH_NOARGS |METH_CLASS , "To be documented." }

View File

@ -72,6 +72,7 @@ extern "C" {
DirectGetBoolAttribute(PyNetRoutingState_isFixed ,isFixed ,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isUnconnected ,isUnconnected ,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isManualGlobalRoute ,isManualGlobalRoute ,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isManualDetailRoute ,isManualDetailRoute ,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isAutomaticGlobalRoute,isAutomaticGlobalRoute,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isMixedPreRoute ,isMixedPreRoute ,PyNetRoutingState,NetRoutingState)
DirectGetBoolAttribute(PyNetRoutingState_isSymmetric ,isSymmetric ,PyNetRoutingState,NetRoutingState)
@ -97,6 +98,7 @@ extern "C" {
, { "isFixed" , (PyCFunction)PyNetRoutingState_isFixed , METH_NOARGS , "To be documented." }
, { "isUnconnected" , (PyCFunction)PyNetRoutingState_isUnconnected , METH_NOARGS , "To be documented." }
, { "isManualGlobalRoute" , (PyCFunction)PyNetRoutingState_isManualGlobalRoute , METH_NOARGS , "To be documented." }
, { "isManualDetailRoute" , (PyCFunction)PyNetRoutingState_isManualDetailRoute , METH_NOARGS , "To be documented." }
, { "isAutomaticGlobalRoute", (PyCFunction)PyNetRoutingState_isAutomaticGlobalRoute, METH_NOARGS , "To be documented." }
, { "isMixedPreRoute" , (PyCFunction)PyNetRoutingState_isMixedPreRoute , METH_NOARGS , "To be documented." }
, { "isSymmetric" , (PyCFunction)PyNetRoutingState_isSymmetric , METH_NOARGS , "To be documented." }
@ -145,6 +147,7 @@ extern "C" {
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::Fixed ,"Fixed" );
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::Unconnected ,"Unconnected" );
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::ManualGlobalRoute ,"ManualGlobalRoute" );
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::ManualDetailRoute ,"ManualDetailRoute" );
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::AutomaticGlobalRoute,"AutomaticGlobalRoute");
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::MixedPreRoute ,"MixedPreRoute" );
LoadObjectConstant(PyTypeNetRoutingState.tp_dict,NetRoutingState::Horizontal ,"Horizontal" );

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef PY_POINT_H
#define PY_POINT_H
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/Point.h"
@ -51,5 +49,3 @@ namespace Isobar {
} // extern "C".
} // Isobar namespace.
#endif // PY_POINT_H

View File

@ -176,6 +176,7 @@ namespace {
}
}
if (NetRoutingExtension::isManualDetailRoute(net)) continue;
if (NetRoutingExtension::isManualGlobalRoute(net)) continue;
if (netType == Net::Type::POWER) {

View File

@ -282,6 +282,7 @@ namespace {
}
if (NetRoutingExtension::isManualGlobalRoute(net)) continue;
if (NetRoutingExtension::isManualDetailRoute(net)) continue;
if (netType == Net::Type::POWER) {
if (_vddiPadNetName.isEmpty()) {

View File

@ -160,13 +160,13 @@ namespace Kite {
if (isFixed or isPreRouted or (rpCount < 2)) {
NetRoutingState* state = getRoutingState( net, Katabatic::KbCreate );
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute );
state->setFlags ( NetRoutingState::ManualDetailRoute );
if (rpCount < 2)
state->setFlags ( NetRoutingState::Unconnected );
if (isFixed) {
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
state->unsetFlags( NetRoutingState::ManualDetailRoute );
state->setFlags ( NetRoutingState::Fixed );
} else {
if (rpCount > 1) {

View File

@ -219,7 +219,7 @@ namespace Kite {
for ( Net* net : cell->getNets() ) {
if (net->isClock() or net->isSupply()) continue;
if (NetRoutingExtension::isManualGlobalRoute(net)) continue;
if (NetRoutingExtension::isManualDetailRoute(net)) continue;
// First pass: destroy the contacts
std::vector<Contact*> contacts;