Update the channel routing feature to integrate with the OTC P&R.
* Update: In CRL/node600/phenitec/kite.py, update the routing gauge to the new format. So now we can use again SxLib-2M (channel routing SxLib for two metal technologies). * Change: In CRL::BlifParser, if a master cell is not found in the AllianceFramework, then try in the Blif supplied libraries. This is used to load the zero, one and tie cells. Add a Blif::getCell() static function to look into the Blif supplied libraries. * Change: In CRL::LefImport, sometimes there can be discrepencies between the LEF ROUTING layers and the Coriolis routing gauge. Now ignore routing layers that are *not* presents in the Coriolis gauge. * Change: In AnabaticEngine, moved routingMode attribute from KatanaEngine, as some setup operations needs it. * Change: In AutoSegment::canReduce(), allow fixed segments to be reduced if they are "jumpers" (turn+turn and top+top or bot+bot). This case arise on the edge of routing channels for fixed wires to connect terminals. * Change: In AutoSegment::getTopologicalinfos(), compute differently the (leftBound,rightBound) interval when in channel mode. In over-the-cell mode, this interval is the one of the whole GCells under the wire. In channel mode, for fixed wires (that is, verticals connecteds to cells) this interval is reduced to half the GCell height, on the connected side of said channel. This allows Manipulator::_insertToTrack() to issue disantangling requests (push left/push right) for fixed segments that are face to face in the channel. * Change: In Anabatic::Configuration CTOR, allow the cellGauge to have a different name from the routingGauge. Now if the cell gauge that should match the routing gauge is not found, fallback to the name set in "anabatic.cellGauge" parameter. Case occur when we try to match with CORE sites from LEF files. * Change: In Etesian::Configuration CTOR, same change as in the Anabatic configuration. * Change: In Anabatic::GCell::updateDensity(), never set the GoStraight flag in channel mode. This flag makes sense when there is at least 4 routing layers (so we have 2 contiguous free of blockages). * Bug: In Anabatic::Session::_getNearestGridpoint(), sometimes the nearest on grid point is outside the constraint box. Now force the point to remains inside constraints even if offgrid. * Change: In Katana::DataNegociate::update(), perpandiculars that are either reduced or in non-preferred routing direction should not trigger a bug message. * Change: In KatanaEngine::_check(), do not check for fixed, horizontal non-prefs AutoSegments in channel mode (avoid false bug display). * Bug: In Manipulator::_forceToTrack(), slighty shrink (-1) the interval to free. The intersection function of intervals returns true when the two intervals *exactly* touches (1.vMax == 2.vMin). But in this specific case, they are not *overlapping* and no action should be taken... * Bug: In Manipulator::_insertInTrack(), do not reject the track when we are overlapping a fixed vertical segment in channel mode. (Hmm, maybe already corrected by the previous one). * Change: In Katana::NegociateOverlapCost(), in channel mode, do not put two overlaping vertical fixed segments into infinite cost. This happens when two cell connected verticals are face to face in a channel. We want them negociated the track (by shrinking their length) instead of excluding it right away. * Change: In NegociateWindow::createTrackSegment(), in channel mode, do not attempt to create a track segment over a fixed and reduced AutoSegment. Do not attempt to put a non-preferred AutoSegment on a Track either. * Bug: In RoutingEvent::revalidate(), the number of availables tracks was badly computed when in the pure constraint case, when there was only one it was reporting zero. * Change: In TrackElements::TrackElements_Perpandicular::Locator, do not issue a bug when an non-pref or reduced AutoSegment do not have an associated TrackElement. * Change: In TrackSegmentCost::update(), do not issue a bug when a perpandicular is reduded or non-pref and do not have a TrackElement.
This commit is contained in:
parent
9594476ab6
commit
a6f61c1044
|
@ -376,6 +376,7 @@ namespace Anabatic {
|
|||
, _viewer (NULL)
|
||||
, _flags (Flags::DestroyBaseContact)
|
||||
, _stamp (-1)
|
||||
, _routingMode (DigitalMode)
|
||||
, _densityMode (MaxDensity)
|
||||
, _autoSegmentLut ()
|
||||
, _autoContactLut ()
|
||||
|
|
|
@ -503,6 +503,9 @@ namespace Anabatic {
|
|||
AutoContact* opposite = _segment->getOppositeAnchor(this);
|
||||
AutoSegment* perpandicular = opposite->getPerpandicular( _segment );
|
||||
if (perpandicular) {
|
||||
cdebug_log(145,0) << "Draging V interval ["
|
||||
<< DbU::getValueString(getCBYMin()) << " "
|
||||
<< DbU::getValueString(getCBYMax()) << "]" << endl;
|
||||
DbU::Unit y = perpandicular->getAxis();
|
||||
y = std::min( y, getCBYMax() );
|
||||
y = std::max( y, getCBYMin() );
|
||||
|
|
|
@ -466,8 +466,10 @@ namespace Anabatic {
|
|||
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;
|
||||
// cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||
// << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
|
||||
// cerr << " minimalSpacing: "
|
||||
// << DbU::getValueString( Session::getLayerGauge(depth)->getLayer()->getMinimalSpacing() ) << endl;
|
||||
|
||||
*viaToSameCap = Session::getPWireWidth(depth)/2;
|
||||
|
||||
|
@ -492,12 +494,12 @@ namespace Anabatic {
|
|||
*minimalLength += twoGrid - modulo;
|
||||
}
|
||||
|
||||
//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;
|
||||
// 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*,4>( {{ viaToTopCap
|
||||
, viaToBottomCap
|
||||
|
@ -1794,14 +1796,21 @@ namespace Anabatic {
|
|||
DbU::Unit length = getAnchoredLength();
|
||||
if (isGlobal() and (length > getPPitch())) return false;
|
||||
|
||||
if (isDrag() or isFixed()) return false;
|
||||
if (isDrag()) return false;
|
||||
if (not isSpinTopOrBottom()) return false;
|
||||
if ((getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
||||
if (isFixed()) {
|
||||
if (isSpinTopOrBottom() and source->isTurn() and target->isTurn())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
|
||||
cdebug_log(159,0) << " source:" << source->isHTee() << "+" << source->isVTee() << endl;
|
||||
cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl;
|
||||
|
||||
|
@ -3214,6 +3223,9 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << "getTopologicalInfos() - " << seed << endl;
|
||||
|
||||
bool isSourceBoundToChannel = false;
|
||||
bool isTargetBoundToChannel = false;
|
||||
|
||||
leftBound = DbU::Max;
|
||||
rightBound = DbU::Min;
|
||||
|
||||
|
@ -3271,10 +3283,19 @@ namespace Anabatic {
|
|||
Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact)
|
||||
? Flags::Source : Flags::Target;
|
||||
perpandiculars.push_back( make_tuple( currentSegment, perpandFlags ));
|
||||
if (Session::getAnabatic()->isChannelMode()) {
|
||||
if (currentSegment->isNonPref() and currentSegment->isFixed()) {
|
||||
if (perpandFlags & Flags::Source) isSourceBoundToChannel = true;
|
||||
else isTargetBoundToChannel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isSourceBoundToChannel) rightBound -= (leftBound + rightBound)/2;
|
||||
if (isTargetBoundToChannel) leftBound += (leftBound + rightBound)/2;
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,17 +97,22 @@ namespace Anabatic {
|
|||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
|
||||
if (cg == NULL) {
|
||||
if (not cg)
|
||||
cg = AllianceFramework::get()->getCellGauge( gaugeName );
|
||||
if (cg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." );
|
||||
if (not cg) {
|
||||
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
|
||||
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
|
||||
}
|
||||
if (not cg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
if (rg == NULL) {
|
||||
if (not rg)
|
||||
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
|
||||
if (rg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
|
||||
}
|
||||
if (not rg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
_cg = cg->getClone();
|
||||
_rg = rg->getClone();
|
||||
|
||||
|
|
|
@ -1551,20 +1551,24 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
// Add the blockages.
|
||||
int contiguousNonSaturated = 0;
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (not i) continue;
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||
continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
|
||||
contiguousNonSaturated = 0;
|
||||
else
|
||||
contiguousNonSaturated++;
|
||||
}
|
||||
if (contiguousNonSaturated < 2) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
if (isStdCellRow() or isChannelRow()) {
|
||||
flags().reset( Flags::GoStraight );
|
||||
} else {
|
||||
int contiguousNonSaturated = 0;
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (not i) continue;
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||
continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
|
||||
contiguousNonSaturated = 0;
|
||||
else
|
||||
contiguousNonSaturated++;
|
||||
}
|
||||
if (contiguousNonSaturated < 2) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the number of non pass-through tracks.
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace Anabatic {
|
|||
contact2 ->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref );
|
||||
fixed ->setFlags( AutoSegment::SegFixed );
|
||||
dogleg->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
|
|
|
@ -412,6 +412,9 @@ namespace Anabatic {
|
|||
if (y < constraint.getYMin()) y += lg->getPitch();
|
||||
if (y > constraint.getYMax()) y -= lg->getPitch();
|
||||
|
||||
y = std::max( y, constraint.getYMin() );
|
||||
y = std::min( y, constraint.getYMax() );
|
||||
|
||||
return Point(x,y);
|
||||
}
|
||||
|
||||
|
@ -420,6 +423,10 @@ namespace Anabatic {
|
|||
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
|
||||
|
||||
|
||||
bool Session::isChannelMode ()
|
||||
{ return get("isChannelMode()")->_anabatic->isChannelMode(); }
|
||||
|
||||
|
||||
float Session::getSaturateRatio ()
|
||||
{ return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); }
|
||||
|
||||
|
|
|
@ -191,20 +191,27 @@ namespace Anabatic {
|
|||
|
||||
class AnabaticEngine : public ToolEngine {
|
||||
public:
|
||||
enum DensityMode { AverageHVDensity=1 // Average between all densities.
|
||||
, AverageHDensity =2 // Average between all H densities.
|
||||
, AverageVDensity =3 // Average between all V densities.
|
||||
, MaxHVDensity =4 // Maximum between average H and average V.
|
||||
, MaxVDensity =5 // Maximum of V densities.
|
||||
, MaxHDensity =6 // Maximum of H densities.
|
||||
, MaxDensity =7 // Maximum of H & V densities.
|
||||
};
|
||||
static const uint32_t DigitalMode = (1 << 0);
|
||||
static const uint32_t AnalogMode = (1 << 1);
|
||||
static const uint32_t MixedMode = (1 << 2);
|
||||
static const uint32_t ChannelMode = (1 << 3);
|
||||
static const uint32_t AverageHVDensity = 1; // Average between all densities.
|
||||
static const uint32_t AverageHDensity = 2; // Average between all H densities.
|
||||
static const uint32_t AverageVDensity = 3; // Average between all V densities.
|
||||
static const uint32_t MaxHVDensity = 4; // Maximum between average H and average V.
|
||||
static const uint32_t MaxVDensity = 5; // Maximum of V densities.
|
||||
static const uint32_t MaxHDensity = 6; // Maximum of H densities.
|
||||
static const uint32_t MaxDensity = 7; // Maximum of H & V densities.
|
||||
public:
|
||||
typedef ToolEngine Super;
|
||||
public:
|
||||
static AnabaticEngine* create ( Cell* );
|
||||
static AnabaticEngine* get ( const Cell* );
|
||||
inline bool isCanonizeDisabled () const;
|
||||
inline bool isDigitalMode () const;
|
||||
inline bool isAnalogMode () const;
|
||||
inline bool isMixedMode () const;
|
||||
inline bool isChannelMode () const;
|
||||
static const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual Configuration* getConfiguration ();
|
||||
|
@ -269,6 +276,8 @@ namespace Anabatic {
|
|||
void invalidateRoutingPads ();
|
||||
void updateDensity ();
|
||||
size_t checkGCellDensities ();
|
||||
inline void setRoutingMode ( uint32_t );
|
||||
inline void resetRoutingMode ( uint32_t );
|
||||
inline void setGlobalThreshold ( DbU::Unit );
|
||||
inline void setSaturateRatio ( float );
|
||||
inline void setSaturateRp ( size_t );
|
||||
|
@ -350,6 +359,7 @@ namespace Anabatic {
|
|||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
uint32_t _routingMode;
|
||||
uint64_t _densityMode;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
|
@ -359,6 +369,12 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
|
||||
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
|
||||
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
|
||||
inline bool AnabaticEngine::isChannelMode () const { return (_routingMode & ChannelMode); };
|
||||
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
|
||||
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
|
||||
inline EngineState AnabaticEngine::getState () const { return _state; }
|
||||
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
|
||||
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace Anabatic {
|
|||
static inline bool doDestroyBaseSegment ();
|
||||
static inline bool doDestroyTool ();
|
||||
static bool isInDemoMode ();
|
||||
static bool isChannelMode ();
|
||||
static bool doWarnGCellOverload ();
|
||||
static Session* get ( const char* message=NULL );
|
||||
static inline Technology* getTechnology ();
|
||||
|
|
|
@ -85,6 +85,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -97,6 +98,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -109,6 +111,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA34).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -121,6 +124,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(15) # track pitch.
|
||||
, l(6) # wire width.
|
||||
, l(6) # perpandicular wire width.
|
||||
, l(4) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -137,6 +141,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -149,6 +154,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -161,6 +167,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA34).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -177,6 +184,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(3) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -189,6 +197,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, l(3) # perpandicular wire width.
|
||||
, l(3) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
|
|
@ -24,7 +24,7 @@ from Hurricane import Technology
|
|||
|
||||
tech = DataBase.getDB().getTechnology()
|
||||
if tech:
|
||||
print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'format(tech.getName()) ))
|
||||
print( WarningMessage( 'cmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
|
||||
else:
|
||||
tech = Technology.create( DataBase.getDB(), 'phenitec06' )
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ namespace CRL {
|
|||
, _technology (DataBase::getDB()->getTechnology())
|
||||
, _isSymbolic (true)
|
||||
, _isSuperPitched(true)
|
||||
, _usableLayers (0)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -72,6 +73,7 @@ namespace CRL {
|
|||
, _technology (gauge._technology)
|
||||
, _isSymbolic (gauge._isSymbolic)
|
||||
, _isSuperPitched(gauge._isSuperPitched)
|
||||
, _usableLayers (0)
|
||||
{
|
||||
// Make a deep copy of the map.
|
||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
|
||||
|
@ -312,6 +314,8 @@ namespace CRL {
|
|||
if (fabsf(roundf(r) - r) > 0.00001f)
|
||||
_isSuperPitched = false;
|
||||
}
|
||||
|
||||
if (layerGauge->getType() == Constant::LayerGaugeType::Default) ++_usableLayers;
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,12 +358,14 @@ namespace CRL {
|
|||
|
||||
Record* RoutingGauge::_getRecord ( Record* record ) const
|
||||
{
|
||||
if ( record == NULL )
|
||||
if (not record)
|
||||
record = new Record ( getString(this) );
|
||||
|
||||
record->add ( getSlot("_name" , _name ) );
|
||||
record->add ( getSlot("_gauges" ,&_layerGauges) );
|
||||
record->add ( getSlot("_isSymbolic", _isSymbolic ) );
|
||||
record->add( getSlot("_name" , _name ));
|
||||
record->add( getSlot("_gauges" ,&_layerGauges ));
|
||||
record->add( getSlot("_isSymbolic" , _isSymbolic ));
|
||||
record->add( getSlot("_isSuperPitched", _isSuperPitched ));
|
||||
record->add( getSlot("_usableLayers" , _usableLayers ));
|
||||
return ( record );
|
||||
}
|
||||
|
||||
|
|
|
@ -377,10 +377,12 @@ namespace {
|
|||
static string zeroName = Cfg::getParamString("etesian.cell.zero","zero_x0")->asString();
|
||||
static string oneName = Cfg::getParamString("etesian.cell.one" , "one_x0")->asString();
|
||||
|
||||
_zeroCell = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign );
|
||||
_oneCell = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign );
|
||||
_groundName = Cfg::getParamString("crlcore.groundName","vss")->asString();
|
||||
_powerName = Cfg::getParamString("crlcore.powerName" ,"vdd")->asString();
|
||||
_zeroCell = framework->getCell( zeroName, Catalog::State::Views|Catalog::State::Foreign );
|
||||
_oneCell = framework->getCell( oneName, Catalog::State::Views|Catalog::State::Foreign );
|
||||
_groundName = Cfg::getParamString("crlcore.groundName","vss")->asString();
|
||||
_powerName = Cfg::getParamString("crlcore.powerName" ,"vdd")->asString();
|
||||
if (not _zeroCell) _zeroCell = Blif::getCell( zeroName );
|
||||
if (not _oneCell) _oneCell = Blif::getCell( oneName );
|
||||
|
||||
if (_zeroCell) {
|
||||
for ( Net* net : _zeroCell->getNets() ) {
|
||||
|
@ -818,6 +820,17 @@ namespace CRL {
|
|||
{ if (library) _libraries.push_back( library ); }
|
||||
|
||||
|
||||
Cell* Blif::getCell ( string name )
|
||||
{
|
||||
Cell* cell = nullptr;
|
||||
for ( Library* library : getLibraries() ) {
|
||||
cell = library->getCell( name );
|
||||
if (cell) return cell;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Cell* Blif::load ( string cellPath, bool enforceVhdl )
|
||||
{
|
||||
using namespace std;
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace CRL {
|
|||
static Cell* load ( std::string netlist, bool enforceVhdl=true );
|
||||
static void add ( Library* );
|
||||
static inline const std::vector<Library*>& getLibraries ();
|
||||
static Cell* getCell ( std::string );
|
||||
private:
|
||||
static std::vector<Library*> _libraries;
|
||||
};
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace CRL {
|
|||
inline const Name getName () const;
|
||||
inline Technology* getTechnology () const;
|
||||
inline size_t getDepth () const;
|
||||
inline size_t getUsableLayers () const;
|
||||
inline DbU::Unit getHorizontalPitch () const;
|
||||
inline DbU::Unit getVerticalPitch () const;
|
||||
RoutingLayerGauge* getHorizontalGauge () const;
|
||||
|
@ -109,6 +110,7 @@ namespace CRL {
|
|||
Technology* _technology;
|
||||
bool _isSymbolic;
|
||||
bool _isSuperPitched;
|
||||
size_t _usableLayers;
|
||||
|
||||
// Internal - Constructors & Destructors.
|
||||
RoutingGauge ( const char* name );
|
||||
|
@ -121,13 +123,14 @@ namespace CRL {
|
|||
|
||||
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
|
||||
inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; }
|
||||
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
|
||||
inline bool RoutingGauge::isTwoMetals () const { return (_usableLayers < 3); }
|
||||
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::hasPowerSupply () const { return (getPowerSupplyGauge() != NULL); }
|
||||
inline const Name RoutingGauge::getName () const { return _name; }
|
||||
inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
|
||||
inline Technology* RoutingGauge::getTechnology () const { return _technology; }
|
||||
inline size_t RoutingGauge::getUsableLayers () const { return _usableLayers; }
|
||||
inline DbU::Unit RoutingGauge::getHorizontalPitch () const { return getHorizontalGauge()->getPitch(); }
|
||||
inline DbU::Unit RoutingGauge::getVerticalPitch () const { return getVerticalGauge ()->getPitch(); }
|
||||
inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); }
|
||||
|
|
|
@ -104,6 +104,8 @@ namespace {
|
|||
inline void incNthMetal ();
|
||||
inline int getNthCut () const;
|
||||
inline void incNthCut ();
|
||||
inline int getNthRouting () const;
|
||||
inline void incNthRouting ();
|
||||
inline RoutingGauge* getRoutingGauge () const;
|
||||
inline void addPinSegment ( string name, Segment* );
|
||||
inline void clearPinSegments ();
|
||||
|
@ -130,6 +132,7 @@ namespace {
|
|||
vector<string> _errors;
|
||||
int _nthMetal;
|
||||
int _nthCut;
|
||||
int _nthRouting;
|
||||
RoutingGauge* _routingGauge;
|
||||
CellGauge* _cellGauge;
|
||||
DbU::Unit _minTerminalWidth;
|
||||
|
@ -154,6 +157,8 @@ namespace {
|
|||
inline void LefParser::incNthMetal () { ++_nthMetal; }
|
||||
inline int LefParser::getNthCut () const { return _nthCut; }
|
||||
inline void LefParser::incNthCut () { ++_nthCut; }
|
||||
inline int LefParser::getNthRouting () const { return _nthRouting; }
|
||||
inline void LefParser::incNthRouting () { ++_nthRouting; }
|
||||
inline RoutingGauge* LefParser::getRoutingGauge () const { return _routingGauge; }
|
||||
inline CellGauge* LefParser::getCellGauge () const { return _cellGauge; }
|
||||
inline void LefParser::setCoreSite ( DbU::Unit x, DbU::Unit y ) { _coreSiteX=x; _coreSiteY=y; }
|
||||
|
@ -210,6 +215,7 @@ namespace {
|
|||
, _errors ()
|
||||
, _nthMetal (0)
|
||||
, _nthCut (0)
|
||||
, _nthRouting (0)
|
||||
, _routingGauge (NULL)
|
||||
, _cellGauge (NULL)
|
||||
, _minTerminalWidth(DbU::fromPhysical(Cfg::getParamDouble("lefImport.minTerminalWidth",0.0)->asDouble(),DbU::UnitPower::Micro))
|
||||
|
@ -305,9 +311,9 @@ namespace {
|
|||
|
||||
cerr << " - \"" << lefLayer->name() << "\" map to \"" << basicLayer->getName() << "\"" << endl;
|
||||
|
||||
RoutingLayerGauge* gauge = parser->getRoutingGauge()->getLayerGauge( parser->getNthMetal() );
|
||||
RoutingLayerGauge* gauge = parser->getRoutingGauge()->getLayerGauge( parser->getNthRouting() );
|
||||
|
||||
if (gauge) {
|
||||
if (gauge and (layer == gauge->getLayer())) {
|
||||
if (lefLayer->hasPitch()) {
|
||||
double lefPitch = lefLayer->pitch();
|
||||
double crlPitch = DbU::toPhysical(gauge->getPitch(),DbU::Micro);
|
||||
|
@ -336,6 +342,7 @@ namespace {
|
|||
cerr << Warning( "LefParser::_layerCbk(): CRL Routing direction discrepency for \"%s\", LEF is VERTICAL."
|
||||
, getString( basicLayer->getName() ).c_str() ) << endl;
|
||||
}
|
||||
parser->incNthRouting();
|
||||
} else {
|
||||
cerr << Warning( "LefParser::_layerCbk(): No CRL routing gauge defined for \"%s\"."
|
||||
, getString( basicLayer->getName() ).c_str()
|
||||
|
|
|
@ -73,18 +73,21 @@ namespace Etesian {
|
|||
, _antennaDiodeMaxWL( Cfg::getParamInt ("etesian.antennaDiodeMaxWL" ,0 )->asInt() )
|
||||
{
|
||||
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
|
||||
if (cg == NULL) {
|
||||
if (not cg)
|
||||
cg = AllianceFramework::get()->getCellGauge( gaugeName );
|
||||
if (cg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge \"%s\"."
|
||||
, gaugeName.c_str() );
|
||||
if (not cg) {
|
||||
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
|
||||
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
|
||||
}
|
||||
if (not cg)
|
||||
throw Error( "EtesianEngine::Configuration(): Unable to find cell gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
if (rg == NULL) {
|
||||
if (not rg)
|
||||
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
|
||||
if (rg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
|
||||
}
|
||||
if (not rg)
|
||||
throw Error( "EtesianEngine::Configuration(): Unable to find routing gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
_rg = rg->getClone();
|
||||
_cg = cg->getClone();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "anabatic/Edge.h"
|
||||
|
@ -37,6 +38,7 @@ namespace Katana {
|
|||
using Hurricane::Breakpoint;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::SubTypeCollection;
|
||||
using Hurricane::UpdateSession;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Instance;
|
||||
|
@ -104,8 +106,14 @@ namespace Katana {
|
|||
throw Error( "Row::createChannel(): NULL southWest GCell." );
|
||||
if (_occurrences.empty())
|
||||
throw Error( "Row::createChannel(): No instances in row." );
|
||||
if (southWest->getXMin() != (*_occurrences.begin()).first)
|
||||
throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs." );
|
||||
if (southWest->getXMin() != (*_occurrences.begin()).first) {
|
||||
UpdateSession::close();
|
||||
throw Error( "Row::createChannel(): South-west GCell XMin and Row X min differs.\n"
|
||||
" * southWest=%s\n"
|
||||
" * first=%s\n"
|
||||
, getString(southWest).c_str()
|
||||
, DbU::getValueString((*_occurrences.begin()).first).c_str() );
|
||||
}
|
||||
if (southWest->getYMin() != _y)
|
||||
throw Error( "Row::createChannel(): South-west GCell YMIn and Row Y min differs (%s vs. %s)."
|
||||
, DbU::getValueString(southWest->getYMin()).c_str()
|
||||
|
@ -198,6 +206,7 @@ namespace Katana {
|
|||
// _channelHeight = std::max( _channelHeight, east->getRealOccupancy() );
|
||||
gcell = gcell->getEast();
|
||||
}
|
||||
_channelHeight += 2;
|
||||
|
||||
return _channelHeight;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ namespace Katana {
|
|||
vector<AutoSegment*> collapseds;
|
||||
vector< tuple<AutoSegment*,Anabatic::Flags> > perpandiculars;
|
||||
map<DbU::Unit,int> attractorSpins;
|
||||
size_t reducedPerpands = 0;
|
||||
|
||||
_reduceRanges[0].makeEmpty();
|
||||
_reduceRanges[1].makeEmpty();
|
||||
|
@ -125,12 +126,16 @@ namespace Katana {
|
|||
perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() );
|
||||
}
|
||||
if (not perpandicular) {
|
||||
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
|
||||
//, getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
, getString(basePerpand->getCanonical(interval)).c_str()
|
||||
//, getString((void*)basePerpand->base()).c_str()
|
||||
, getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
if (not (Session::isChannelMode()
|
||||
and (basePerpand->isReduced() or basePerpand->isNonPref())))
|
||||
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
|
||||
//, getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
, getString(basePerpand->getCanonical(interval)).c_str()
|
||||
//, getString((void*)basePerpand->base()).c_str()
|
||||
, getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
else
|
||||
++reducedPerpands;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -266,7 +271,7 @@ namespace Katana {
|
|||
|
||||
cdebug_tabw(159,-1);
|
||||
}
|
||||
if ( not _trackSegment->isTerminal() and (_perpandiculars.size() < 2) )
|
||||
if ( not _trackSegment->isTerminal() and (_perpandiculars.size()+reducedPerpands < 2) )
|
||||
cerr << Bug( "Less than two perpandiculars on %s.", getString(_trackSegment).c_str() ) << endl;
|
||||
|
||||
map<DbU::Unit,int>::iterator iattractor = attractorSpins.begin();
|
||||
|
|
|
@ -685,7 +685,8 @@ namespace Katana {
|
|||
addMeasure<uint32_t>( "H-ovE", hoverflow, 12 );
|
||||
addMeasure<uint32_t>( "V-ovE", voverflow, 12 );
|
||||
|
||||
_buildBloatProfile();
|
||||
if (not Session::isChannelMode())
|
||||
_buildBloatProfile();
|
||||
|
||||
if (flags & Flags::ShowFailedNets ) selectNets ( this, nets );
|
||||
if (flags & Flags::ShowFailedGSegments ) selectSegments ( this, segments );
|
||||
|
|
|
@ -195,7 +195,6 @@ namespace Katana {
|
|||
, _minimumWL (0.0)
|
||||
, _shortDoglegs ()
|
||||
, _symmetrics ()
|
||||
, _mode (DigitalMode)
|
||||
, _stage (StageNegociate)
|
||||
, _successState (0)
|
||||
{
|
||||
|
@ -241,7 +240,7 @@ namespace Katana {
|
|||
{
|
||||
cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl;
|
||||
|
||||
_mode |= DigitalMode;
|
||||
setRoutingMode( DigitalMode );
|
||||
|
||||
Super::chipPrep();
|
||||
|
||||
|
@ -270,8 +269,8 @@ namespace Katana {
|
|||
{
|
||||
cdebug_log(155,1) << "KatanaEngine::_initDataBase()" << endl;
|
||||
|
||||
_mode &= ~DigitalMode;
|
||||
_mode |= AnalogMode;
|
||||
resetRoutingMode( DigitalMode );
|
||||
setRoutingMode( AnalogMode );
|
||||
|
||||
Super::chipPrep();
|
||||
|
||||
|
@ -286,11 +285,11 @@ namespace Katana {
|
|||
{
|
||||
cdebug_log(155,1) << "KatanaEngine::setupChannelMode()" << endl;
|
||||
|
||||
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
|
||||
size_t maxDepth = rg->getDepth();
|
||||
if (maxDepth < 3) {
|
||||
_mode |= ChannelMode;
|
||||
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
|
||||
if (rg->isTwoMetals()) {
|
||||
setRoutingMode( ChannelMode );
|
||||
|
||||
size_t maxDepth = rg->getDepth();
|
||||
if (maxDepth < 2) {
|
||||
throw Error( "KatanaEngine::setupChannelMode(): Layer gauge %s must contains at least two layers (%u)."
|
||||
, getString(rg->getName()).c_str(), maxDepth );
|
||||
|
@ -554,10 +553,10 @@ namespace Katana {
|
|||
}
|
||||
}
|
||||
|
||||
if (Session::getConfiguration()->isTwoMetals()) {
|
||||
if (Session::isChannelMode()) {
|
||||
for ( GCell* gcell : getGCells() ) {
|
||||
if (not gcell->isStdCellRow()) continue;
|
||||
|
||||
|
||||
set<DbU::Unit> terminalsX;
|
||||
for ( Component* component : getCell()->getComponentsUnder(gcell->getBoundingBox()) ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
|
||||
|
@ -574,7 +573,7 @@ namespace Katana {
|
|||
edge = gcell->getSouthEdge();
|
||||
if (edge) {
|
||||
capacity = edge->getCapacity();
|
||||
if (terminalsX.size() < capacity) capacity = terminalsX.size();
|
||||
if (terminalsX.size()/2 < capacity) capacity = terminalsX.size()/2;
|
||||
edge->reserveCapacity( capacity );
|
||||
}
|
||||
}
|
||||
|
@ -849,9 +848,15 @@ namespace Katana {
|
|||
AutoSegment* autoSegment = anbtSession->lookup( segment );
|
||||
if (not autoSegment) continue;
|
||||
if (not autoSegment->isCanonical()) continue;
|
||||
if (autoSegment->isReduced()) continue;
|
||||
|
||||
TrackElement* trackSegment = Session::lookup( segment );
|
||||
if (not trackSegment) {
|
||||
if ( isChannelMode()
|
||||
and autoSegment->isFixed()
|
||||
and autoSegment->isHorizontal()
|
||||
and autoSegment->isNonPref())
|
||||
continue;
|
||||
coherency = false;
|
||||
cerr << Bug( "%p %s without Track Segment"
|
||||
, autoSegment
|
||||
|
|
|
@ -722,8 +722,10 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "No intersection with: " << segment2->getCanonicalInterval() << endl;
|
||||
continue;
|
||||
}
|
||||
if ( segment2->isBlockage() or segment2->isFixed() ) {
|
||||
cdebug_log(159,0) << "Ovelap is blockage or fixed." << endl;
|
||||
if ( segment2->isBlockage()
|
||||
or (segment2->isFixed()
|
||||
and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelMode()))) {
|
||||
cdebug_log(159,0) << "Overlap is blockage or fixed." << endl;
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -890,6 +892,7 @@ namespace Katana {
|
|||
set<TrackElement*> canonicals;
|
||||
bool success = true;
|
||||
|
||||
toFree.inflate( -1 );
|
||||
cdebug_log(159,1) << "Manipulator::_forceToTrack(size_t) - " << toFree << endl;
|
||||
|
||||
for ( size_t i=begin ; success and (i < end) ; ++i ) {
|
||||
|
@ -898,7 +901,15 @@ namespace Katana {
|
|||
cdebug_log(159,0) << "* Looking // " << segment2 << endl;
|
||||
|
||||
if (segment2->getNet() == ownerNet) continue;
|
||||
if (not toFree.intersect(segment2->getCanonicalInterval())) continue;
|
||||
Interval segCanon = segment2->getCanonicalInterval();
|
||||
if (not toFree.intersect(segment2->getCanonicalInterval()))
|
||||
continue;
|
||||
cdebug_log(159,0) << "toFree = " << toFree
|
||||
<< " [" << toFree.getVMin()
|
||||
<< " " << toFree.getVMax() << "]" << endl;
|
||||
cdebug_log(159,0) << "segCanon = " << segCanon
|
||||
<< " [" << segCanon.getVMin()
|
||||
<< " " << segCanon.getVMax() << "]" << endl;
|
||||
if (segment2->isFixed()) {
|
||||
success = false;
|
||||
continue;
|
||||
|
|
|
@ -60,7 +60,9 @@ namespace {
|
|||
|
||||
if (not intersect.intersect(cost.getInterval())) return;
|
||||
|
||||
if (segment->isBlockage() or segment->isFixed()) {
|
||||
if ( segment->isBlockage()
|
||||
or (segment->isFixed()
|
||||
and not (segment->isVertical() and Session::getKatanaEngine()->isChannelMode()))) {
|
||||
cdebug_log(159,0) << "Infinite cost from: " << segment << endl;
|
||||
cost.setInfinite ();
|
||||
cost.setOverlap ();
|
||||
|
@ -329,13 +331,25 @@ namespace Katana {
|
|||
// Special case: fixed AutoSegments must not interfere with blockages.
|
||||
// Ugly: uses of getExtensionCap().
|
||||
if (autoSegment->isFixed()) {
|
||||
if (Session::isChannelMode() and autoSegment->isReduced()) {
|
||||
cdebug_log(159,0) << "* Fixed segment is reduced, ignore " << autoSegment << endl;
|
||||
cdebug_tabw(159,-1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t begin;
|
||||
size_t end;
|
||||
Interval fixedSpan;
|
||||
Interval blockageSpan;
|
||||
|
||||
if (Session::isChannelMode() and autoSegment->isNonPref()) {
|
||||
cdebug_log(159,0) << "Fixed in non-preferred direction, do not attempt to set on track." << endl;
|
||||
cdebug_tabw(159,-1);
|
||||
DebugSession::close();
|
||||
return NULL;
|
||||
}
|
||||
if (not refTrack) {
|
||||
string message = "NULL refTrack for " + getString(autoSegment);
|
||||
string message = "NULL refTrack for " + getString(autoSegment) + " brace for crashing!";
|
||||
Breakpoint::stop( 0, message );
|
||||
}
|
||||
|
||||
|
|
|
@ -99,9 +99,10 @@ namespace {
|
|||
|
||||
if (CatalogExtension::isPad(masterNet->getCell())) {
|
||||
if ( rp->getNet()->isPower()
|
||||
or (rp->getNet()->getName() == padNetName) )
|
||||
or (rp->getNet()->getName() == padNetName) ) {
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vector<Segment*> segments;
|
||||
|
|
|
@ -747,16 +747,22 @@ namespace Katana {
|
|||
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer());
|
||||
Track* track = plane->getTrackByPosition(_constraints.getVMin());
|
||||
|
||||
if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack();
|
||||
for ( ; track && (track->getAxis() <= _constraints.getVMax())
|
||||
; track = track->getNextTrack(), _tracksNb++ );
|
||||
if ( track and (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack();
|
||||
cdebug_log(159,0) << "| Nearest " << track << endl;
|
||||
while ( track and (track->getAxis() <= _constraints.getVMax()) ) {
|
||||
_tracksNb++;
|
||||
track = track->getNextTrack();
|
||||
cdebug_log(159,0) << "| Next " << track << endl;
|
||||
}
|
||||
}
|
||||
cdebug_log(159,0) << "| _tracksNb " << _tracksNb << endl;
|
||||
if (not _tracksNb) {
|
||||
cdebug_log(159,0) << "| Pure constraints are too tight." << endl;
|
||||
if (_segment->base())
|
||||
_overConstrained = _segment->base()->getAutoSource()->isTerminal()
|
||||
and _segment->base()->getAutoTarget()->isTerminal();
|
||||
}
|
||||
cdebug_log(159,0) << "| _tracksNb " << _tracksNb << endl;
|
||||
|
||||
_segment->computePriority();
|
||||
|
||||
|
|
|
@ -45,8 +45,12 @@ namespace Katana {
|
|||
Interval bounds;
|
||||
if ( _locator.isValid() ) {
|
||||
_element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if ( !_element ) {
|
||||
cerr << Bug("Canonical segment without TrackElement.") << endl;
|
||||
if (not _element) {
|
||||
AutoSegment* segment = _locator.getElement()->getCanonical(bounds);
|
||||
if (Session::isChannelMode()
|
||||
and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed()))
|
||||
cerr << Bug( "Canonical segment without TrackElement on %s."
|
||||
, getString(segment).c_str()) << endl;
|
||||
progress ();
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +71,12 @@ namespace Katana {
|
|||
|
||||
if ( _locator.isValid() ) {
|
||||
_element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if ( !_element ) {
|
||||
cerr << Bug("Canonical segment without TrackElement.") << endl;
|
||||
if (not _element ) {
|
||||
AutoSegment* segment = _locator.getElement()->getCanonical(bounds);
|
||||
if (Session::isChannelMode()
|
||||
and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed()))
|
||||
cerr << Bug( "Canonical segment without TrackElement on %s."
|
||||
, getString(segment).c_str() ) << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,12 +105,14 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( not perpandicular ) {
|
||||
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)"
|
||||
,getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
,getString(basePerpand->getCanonical(interval)).c_str()
|
||||
,getString((void*)basePerpand->base()).c_str()
|
||||
,getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
if (Session::isChannelMode()
|
||||
and not (basePerpand->isReduced() or basePerpand->isNonPref()))
|
||||
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)"
|
||||
,getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
,getString(basePerpand->getCanonical(interval)).c_str()
|
||||
,getString((void*)basePerpand->base()).c_str()
|
||||
,getString(basePerpand).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
interval.inflate ( DbU::lambda(-1.5) );
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_BLOCK_H
|
||||
#define KATANA_BLOCK_H
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
@ -113,5 +111,3 @@ namespace Katana {
|
|||
|
||||
INSPECTOR_P_SUPPORT(Katana::Row);
|
||||
INSPECTOR_P_SUPPORT(Katana::Block);
|
||||
|
||||
#endif // KATANA_BLOCK_H
|
||||
|
|
|
@ -55,10 +55,6 @@ namespace Katana {
|
|||
|
||||
class KatanaEngine : public AnabaticEngine {
|
||||
public:
|
||||
static const uint32_t DigitalMode = (1 << 0);
|
||||
static const uint32_t AnalogMode = (1 << 1);
|
||||
static const uint32_t MixedMode = (1 << 2);
|
||||
static const uint32_t ChannelMode = (1 << 3);
|
||||
static const uint32_t GlobalRoutingSuccess = (1 << 0);
|
||||
static const uint32_t DetailedRoutingSuccess = (1 << 1);
|
||||
public:
|
||||
|
@ -68,10 +64,6 @@ namespace Katana {
|
|||
static KatanaEngine* create ( Cell* );
|
||||
static KatanaEngine* get ( const Cell* );
|
||||
public:
|
||||
inline bool isDigitalMode () const;
|
||||
inline bool isAnalogMode () const;
|
||||
inline bool isMixedMode () const;
|
||||
inline bool isChannelMode () const;
|
||||
inline bool isGlobalRoutingSuccess () const;
|
||||
inline bool isDetailedRoutingSuccess () const;
|
||||
inline bool useClockTree () const;
|
||||
|
@ -172,7 +164,6 @@ namespace Katana {
|
|||
double _minimumWL;
|
||||
TrackElementPairing _shortDoglegs;
|
||||
DataSymmetricMap _symmetrics;
|
||||
uint32_t _mode;
|
||||
uint32_t _stage;
|
||||
mutable uint32_t _successState;
|
||||
protected:
|
||||
|
@ -188,10 +179,6 @@ namespace Katana {
|
|||
|
||||
|
||||
// Inline Functions.
|
||||
inline bool KatanaEngine::isDigitalMode () const { return (_mode & DigitalMode); };
|
||||
inline bool KatanaEngine::isAnalogMode () const { return (_mode & AnalogMode); };
|
||||
inline bool KatanaEngine::isMixedMode () const { return (_mode & MixedMode); };
|
||||
inline bool KatanaEngine::isChannelMode () const { return (_mode & ChannelMode); };
|
||||
inline bool KatanaEngine::isGlobalRoutingSuccess () const { return (_successState & GlobalRoutingSuccess); }
|
||||
inline bool KatanaEngine::isDetailedRoutingSuccess() const { return (_successState & DetailedRoutingSuccess); }
|
||||
inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); }
|
||||
|
|
Loading…
Reference in New Issue