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:
parent
18405599e8
commit
8f0a8e5a3a
|
@ -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) );
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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<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,11 +178,16 @@ 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 );
|
||||
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 );
|
||||
|
@ -164,17 +195,17 @@ namespace Anabatic {
|
|||
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() ));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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." }
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -176,6 +176,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if (NetRoutingExtension::isManualDetailRoute(net)) continue;
|
||||
if (NetRoutingExtension::isManualGlobalRoute(net)) continue;
|
||||
|
||||
if (netType == Net::Type::POWER) {
|
||||
|
|
|
@ -282,6 +282,7 @@ namespace {
|
|||
}
|
||||
|
||||
if (NetRoutingExtension::isManualGlobalRoute(net)) continue;
|
||||
if (NetRoutingExtension::isManualDetailRoute(net)) continue;
|
||||
|
||||
if (netType == Net::Type::POWER) {
|
||||
if (_vddiPadNetName.isEmpty()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue