DRC correct on Arlet6505 / TSMC C180.
Integrate new features and bug fixes so the Arlet 6502 benchs successfully passes real DRC with reference industrial tools. Short summary: * Manage minimum area for VIAs in Katana::Tracks. * Allow different wire width for wires perpandicular to the prefered routing direction. * StackedVIAs used in the clock tree no longer assume an uniform routing grid (same offset & pitch all the way up). * Some hard-coded patches in PowerRails for FlexLib. * New: In CRL/symbolic/cmos/kite.py & cmos45/kite.py, update the RoutingLayerGauges by adding the new PWireWidth parameter. Always zero in case of symbolic layout (too fine tuning). * New: In CRL::RoutingGauge, add accessor to PWireWidth parameter. Modify the clone method. * New: In CRL::RoutingLayerGauge, add new parameter "PWireWidth" to give the width of a wire when it not drawn in the prefered routing direction. If it is set to zero, the normal width is used. * New: In CRL::PyRoutingGauge, export the updated constructor interface. It is *not* backward compatible, one must add the PWireWidth parameter in the various kite.py configuration files (in etc/). * Change: In AnabaticEngine::_gutAnabatic(), disable the minimum area detection mechanism, replaced by a more complete one in Katana::Track. Left commented out for now, but will be removed in the future. * Change: In Anabatic::AutoContact::updateLayer(), now systematically calls setLayerAndWidth() to potentially resize the VIAs. This is needed in real mode as VIAs are *not* macro-generated but have their real final size. * Change: In Anabatic::AutoContact::setLayerAndWidth(), select the width and height of the contact using the gauge wire width *and* perpandicular *wire width*. * Change: In Anabatic::AutoSegment::_initialize(), the "VIA to same cap" to PWireWidth/2, this will be the size of the VIA in the non-preferred direction at the end cap (non-square in real mode). * Change: In Anabatic::AutoSegment::getExtensionCap(), makes different cases for symbolic and real. Use raw length in real, add half the wire width in symbolic. Add a flag to get the extension cap *only*, not increased of half the minimal spacing. * Change: In Anabatic::AutoSegment::bloatStackedStrap(), enhanced, but finally unused... * New: In Anabatic::AutoSegment::create(), use the PWireWidth when the segment is not in the preferred routing direction (and of minimal width). * New: In Anabatic::Configuration, add new getPWirewidth(), DPHorizontalWidth() and DPVerticalWidth() accessors. * Change: In AnabaticEngine::setupPreRouteds(), skip components in in "cut" material. We are only interested in objects containing some metal (happens in real mode when VIAs cuts are really there). * New: In Katana::PowerRailsPlanes::Rail::doLayout(), add an hard-coded patch that artificially enlarge the *wide wire* so the spacing for wide wire is enforced. For now, two pitches on each side for "FlexLib" gauge. * New: In Katana::Track, add support to find and correct small wire chunks so they respect the minimum area rules. Two helper functions: * ::hasSameLayerTurn(), to find if a a TrackElement as non-zero length perpandicular is same layer connected to it. * ::toFoundryGrid(), to ensure that all coordinates will be on the foundry grid (may move in a more shared location). * ::expandToMinArea(), try to expand, *in the routing direction* the too small wire so it respect the minimal area. Check for the free space in the track. Track::minExpandArea() go through all the TrackElements in the track to look for too small ones and correct them. * Change: In Katana::RoutingPlane, add an accessor to get the tracks. * New: In KatanaEngine::finalizeLayout(), add a post-treatment to find for minimal area violations. * Change: In cumulus/plugins.block.configuration.GaugeConf, add a routingBb attribute that will serve as a common reference to all the functions calculation track positions. We must not have two different reference for the core and the corona. The reference is always the corona when we working on a complete chip. * New: In cumulus/plugins.block.configuration.GaugeConf.getTrack(), Simplified and more reliable way of getting tracks positions. Use the routingBb. * New: In cumulus/plugins.block.configuration.GaugeConf.rpAccess(), Make use of getTrack() to get every metal strap on the right X/Y position. * New: In cumulus/plugins.block.configuration.GaugeConf.expandMinArea(), As those wires are left alone by the router, it is our responsability to abide by the minimal area rule here. Hence the code duplication from the router (bad). Mainly wires made for the clock tree, I mean. * Bug: In cumulus/plugins.chip.configuration.ChipConf.setupICore(), the core instance must be placed on the GCell grid, defined by the slice height (X *and* Y). * Bug: In cumulus/plugins.chip.corona.Builder(), forgot to use bigvia for the corners of the inner ring. * Bug: In cumulus/plugins.chip.pads.corona._createCoreWire(), hard-coded patch for LibreSOCIO, the power/ground connectors toward the core are too wide and can create DRC errors when put side by side. Shrink them by the minimal distance.
This commit is contained in:
parent
ba43b02e87
commit
29b57e86e5
|
@ -412,7 +412,7 @@ namespace Anabatic {
|
|||
for ( auto isegment : _autoSegmentLut ) {
|
||||
if (isegment.second->isFixed()) ++fixedSegments;
|
||||
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
|
||||
//if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
|
||||
}
|
||||
|
||||
cmess1 << " o Driving Hurricane data-base." << endl;
|
||||
|
|
|
@ -205,10 +205,11 @@ namespace Anabatic {
|
|||
size_t maxDepth = 0;
|
||||
|
||||
getDepthSpan( minDepth, maxDepth );
|
||||
if (minDepth == maxDepth)
|
||||
setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
|
||||
else
|
||||
setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
|
||||
setLayerAndWidth( maxDepth-minDepth, minDepth );
|
||||
// if (minDepth == maxDepth)
|
||||
// setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
|
||||
// else
|
||||
// setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -576,8 +577,13 @@ namespace Anabatic {
|
|||
|
||||
if (delta == 0) {
|
||||
setLayer( Session::getRoutingLayer(depth) );
|
||||
setSizes( Session::getWireWidth (depth)
|
||||
if (Session::getDirection(depth) & Flags::Horizontal) {
|
||||
setSizes( Session::getPWireWidth(depth)
|
||||
, Session::getWireWidth (depth) );
|
||||
} else {
|
||||
setSizes( Session::getWireWidth (depth)
|
||||
, Session::getPWireWidth(depth) );
|
||||
}
|
||||
} else {
|
||||
setLayer( Session::getContactLayer(depth) );
|
||||
setSizes( Session::getViaWidth (depth)
|
||||
|
|
|
@ -441,7 +441,7 @@ namespace Anabatic {
|
|||
//cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||
// << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
|
||||
|
||||
*viaToSameCap = Session::getWireWidth(depth)/2;
|
||||
*viaToSameCap = Session::getPWireWidth(depth)/2;
|
||||
|
||||
// Bottom metal of the VIA going *up*.
|
||||
const Layer* viaLayer = dynamic_cast<const ViaLayer*>( Session::getContactLayer(depth) );
|
||||
|
@ -726,9 +726,10 @@ namespace Anabatic {
|
|||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(145,0) << "getExtensionCap(): flags:" << getFlags()
|
||||
cdebug_log(150,0) << "getExtensionCap(): flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " " << (getFlags() & SegSourceBottom)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
@ -738,8 +739,9 @@ namespace Anabatic {
|
|||
else cap = getViaToSameCap (depth);
|
||||
}
|
||||
|
||||
if (cap < getWidth()/2) cap = getWidth()/2;
|
||||
return cap + getLayer()->getMinimalSpacing()/2;;
|
||||
if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2;
|
||||
if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2;
|
||||
return cap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2088,17 +2090,49 @@ namespace Anabatic {
|
|||
|
||||
bool AutoSegment::bloatStackedStrap ()
|
||||
{
|
||||
if (getLength() or isReduced()) return false;
|
||||
if ( ((_flags & (SegSourceBottom|SegTargetTop)) != (SegSourceBottom|SegTargetTop))
|
||||
and ((_flags & (SegTargetBottom|SegSourceTop)) != (SegTargetBottom|SegSourceTop)) ) return false;
|
||||
|
||||
DebugSession::open( getNet(), 145, 150 );
|
||||
cdebug_log(149,1) << "AutoSegment::bloatStackedStrap() " << this << endl;
|
||||
double minArea = getLayer()->getMinimalArea();
|
||||
if (minArea == 0.0) return false;
|
||||
if (minArea == 0.0) {
|
||||
cdebug_log(149,-1) << "False, NO minimal area." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
|
||||
DbU::Unit minLength
|
||||
= DbU::fromPhysical( minArea / DbU::toPhysical( getWidth(), DbU::UnitPower::Micro )
|
||||
, DbU::UnitPower::Micro );
|
||||
cdebug_log(149,0) << "Min length: " << DbU::getValueString(minLength) << " ." << endl;
|
||||
|
||||
if ((getSpanLength() >= minLength) or isReduced()) {
|
||||
cdebug_log(149,-1) << "False, has length or is reduced." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
if (isDrag()) {
|
||||
for ( AutoSegment* perpandicular : getPerpandiculars() ) {
|
||||
if (perpandicular->getSpanLength() > minLength) {
|
||||
cdebug_log(149,-1) << "False (drag), has length or PP has length." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ((_flags & (SegSourceBottom|SegTargetTop)) != (SegSourceBottom|SegTargetTop))
|
||||
and ((_flags & (SegTargetBottom|SegSourceTop)) != (SegTargetBottom|SegSourceTop)) ) {
|
||||
cdebug_log(149,-1) << "False, not part of a stacked VIA." << endl;
|
||||
DebugSession::close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DbU::Unit side = DbU::fromPhysical( std::sqrt(minArea) , DbU::UnitPower::Micro );
|
||||
setWidth( side );
|
||||
setDuSource( -side/2 );
|
||||
setDuTarget( side/2 );
|
||||
|
||||
cdebug_log(149,-1) << "True, add area." << endl;
|
||||
DebugSession::close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2587,9 +2621,10 @@ namespace Anabatic {
|
|||
segment->_postCreate();
|
||||
} else if (vertical) {
|
||||
if (vertical->getLayer() != verticalLayer) {
|
||||
if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) )
|
||||
if (Session::getAnabatic()->getConfiguration()->isGMetal(vertical->getLayer()) ) {
|
||||
vertical->setLayer( verticalLayer );
|
||||
vertical->setWidth( verticalWidth );
|
||||
}
|
||||
} else {
|
||||
if (vertical->getWidth() != verticalWidth) {
|
||||
cerr << Warning("Segment %s has non-default width %s."
|
||||
|
@ -2630,14 +2665,16 @@ namespace Anabatic {
|
|||
|
||||
if (dir & Flags::UseNonPref) {
|
||||
if (dir & Flags::Vertical) {
|
||||
cdebug_log(149,0) << "Make vertical in non-preferred direction." << endl;
|
||||
vLayer = hLayer;
|
||||
vWidth = hWidth;
|
||||
vWidth = Session::getDPHorizontalWidth();
|
||||
cdebug_log(149,0) << "Make vertical in non-preferred direction (ppW:"
|
||||
<< DbU::getValueString(vWidth).c_str() << ")." << endl;
|
||||
}
|
||||
if (dir & Flags::Horizontal) {
|
||||
cdebug_log(149,0) << "Make horizontal in non-preferred direction." << endl;
|
||||
hLayer = vLayer;
|
||||
hWidth = vWidth;
|
||||
hWidth = Session::getDPVerticalWidth();
|
||||
cdebug_log(149,0) << "Make horizontal in non-preferred direction (ppW:"
|
||||
<< DbU::getValueString(hWidth).c_str() << ")." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2645,12 +2682,14 @@ namespace Anabatic {
|
|||
DbU::Unit horizontalWidth = hWidth;
|
||||
const Layer* verticalLayer = vLayer;
|
||||
DbU::Unit verticalWidth = vWidth;
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
|
||||
if (wPitch > 1) {
|
||||
horizontalWidth = (wPitch-1) * Session::getDHorizontalPitch() + hWidth;
|
||||
verticalWidth = (wPitch-1) * Session::getDVerticalPitch () + vWidth;
|
||||
}
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
if (depth != RoutingGauge::nlayerdepth) {
|
||||
horizontalLayer = verticalLayer = Session::getRoutingLayer( depth );
|
||||
|
@ -2659,9 +2698,23 @@ namespace Anabatic {
|
|||
horizontalWidth = verticalWidth = (wPitch-1) * Session::getPitch (depth)
|
||||
+ Session::getWireWidth(depth);
|
||||
} else {
|
||||
horizontalWidth = verticalWidth = Session::getWireWidth( depth );
|
||||
if (dir & Flags::Horizontal) {
|
||||
horizontalWidth = Session::getWireWidth ( depth );
|
||||
verticalWidth = Session::getPWireWidth( depth );
|
||||
} else {
|
||||
verticalWidth = Session::getWireWidth ( depth );
|
||||
horizontalWidth = Session::getPWireWidth( depth );
|
||||
}
|
||||
cdebug_log(149,0) << "hW:" << DbU::getValueString(horizontalWidth).c_str()
|
||||
<< "vW:" << DbU::getValueString( verticalWidth).c_str()
|
||||
<< endl;
|
||||
if (dir & Flags::UseNonPref) {
|
||||
cdebug_log(149,0) << "swap H/W width." << endl;
|
||||
std::swap( horizontalWidth, verticalWidth );
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_log(149,0) << "verticalWidth:" << DbU::getValueString(verticalWidth).c_str() << endl;
|
||||
|
||||
AutoSegment* segment;
|
||||
AutoContact* reference = source;
|
||||
|
|
|
@ -288,6 +288,10 @@ namespace Anabatic {
|
|||
{ return getWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const
|
||||
{ return getPWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
Flags Configuration::getDirection ( const Layer* layer ) const
|
||||
{ return getDirection( getLayerDepth(layer) ); }
|
||||
|
||||
|
@ -339,6 +343,9 @@ namespace Anabatic {
|
|||
{ return _rg->getLayerWireWidth(depth); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( size_t depth ) const
|
||||
{ return _rg->getLayerPWireWidth(depth); }
|
||||
|
||||
DbU::Unit Configuration::getExtensionCap ( size_t depth ) const
|
||||
{ return _extensionCaps[depth]; }
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||
const BaseFlags Flags::UseNonPref = (1L << 34);
|
||||
const BaseFlags Flags::Force = (1L << 35);
|
||||
const BaseFlags Flags::LayerCapOnly = (1L << 36);
|
||||
|
||||
|
||||
Flags::~Flags ()
|
||||
|
|
|
@ -100,12 +100,16 @@ namespace Anabatic {
|
|||
continue;
|
||||
|
||||
if ( not Session::isGaugeLayer(component->getLayer())
|
||||
and not Session::isGLayer (component->getLayer()))
|
||||
and not Session::isGLayer (component->getLayer())) {
|
||||
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( component->getLayer() );
|
||||
if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut))
|
||||
continue;
|
||||
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) {
|
||||
|
|
|
@ -171,6 +171,7 @@ namespace Anabatic {
|
|||
inline DbU::Unit getWidth () const;
|
||||
inline DbU::Unit getContactWidth () const;
|
||||
inline DbU::Unit getLength () const;
|
||||
inline DbU::Unit getSpanLength () const;
|
||||
inline DbU::Unit getSourcePosition () const;
|
||||
inline DbU::Unit getTargetPosition () const;
|
||||
inline DbU::Unit getSourceX () const;
|
||||
|
@ -574,6 +575,10 @@ namespace Anabatic {
|
|||
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||
|
||||
inline DbU::Unit AutoSegment::getSpanLength () const
|
||||
{ return getLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly )
|
||||
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly );
|
||||
}
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
|
|
|
@ -80,11 +80,13 @@ namespace Anabatic {
|
|||
inline size_t getDVerticalDepth () const;
|
||||
inline const Layer* getDVerticalLayer () const;
|
||||
inline DbU::Unit getDVerticalWidth () const;
|
||||
inline DbU::Unit getDPVerticalWidth () const;
|
||||
inline DbU::Unit getDVerticalPitch () const;
|
||||
inline DbU::Unit getDVerticalOffset () const;
|
||||
inline size_t getDHorizontalDepth () const;
|
||||
inline const Layer* getDHorizontalLayer () const;
|
||||
inline DbU::Unit getDHorizontalWidth () const;
|
||||
inline DbU::Unit getDPHorizontalWidth () const;
|
||||
inline DbU::Unit getDHorizontalPitch () const;
|
||||
inline DbU::Unit getDHorizontalOffset () const;
|
||||
inline size_t getDContactDepth () const;
|
||||
|
@ -104,11 +106,13 @@ namespace Anabatic {
|
|||
DbU::Unit getPitch ( size_t depth, Flags flags ) const;
|
||||
DbU::Unit getOffset ( size_t depth ) const;
|
||||
DbU::Unit getWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getPWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getExtensionCap ( size_t depth ) const;
|
||||
Flags getDirection ( size_t depth ) const;
|
||||
DbU::Unit getPitch ( const Layer*, Flags flags ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getExtensionCap ( const Layer* ) const;
|
||||
Flags getDirection ( const Layer* ) const;
|
||||
float getSaturateRatio () const;
|
||||
|
@ -169,11 +173,13 @@ namespace Anabatic {
|
|||
inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; }
|
||||
inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPVerticalWidth () const { return getPWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDVerticalOffset () const { return getOffset ( getDVerticalDepth() ); }
|
||||
inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; }
|
||||
inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPHorizontalWidth () const { return getPWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalOffset () const { return getOffset ( getDHorizontalDepth() ); }
|
||||
inline size_t Configuration::getDContactDepth () const { return _ddepthc; }
|
||||
|
|
|
@ -102,6 +102,7 @@ namespace Anabatic {
|
|||
static const BaseFlags NorthPath ;
|
||||
static const BaseFlags UseNonPref ;
|
||||
static const BaseFlags Force ;
|
||||
static const BaseFlags LayerCapOnly ;
|
||||
public:
|
||||
inline Flags ( uint64_t flags = NoFlags );
|
||||
inline Flags ( const Hurricane::BaseFlags& );
|
||||
|
|
|
@ -97,11 +97,13 @@ namespace Anabatic {
|
|||
static inline size_t getDVerticalDepth ();
|
||||
static inline const Layer* getDVerticalLayer ();
|
||||
static inline DbU::Unit getDVerticalWidth ();
|
||||
static inline DbU::Unit getDPVerticalWidth ();
|
||||
static inline DbU::Unit getDVerticalPitch ();
|
||||
static inline DbU::Unit getDVerticalOffset ();
|
||||
static inline size_t getDHorizontalDepth ();
|
||||
static inline const Layer* getDHorizontalLayer ();
|
||||
static inline DbU::Unit getDHorizontalWidth ();
|
||||
static inline DbU::Unit getDPHorizontalWidth ();
|
||||
static inline DbU::Unit getDHorizontalPitch ();
|
||||
static inline DbU::Unit getDHorizontalOffset ();
|
||||
static inline size_t getDContactDepth ();
|
||||
|
@ -123,6 +125,7 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getPitch ( size_t depth, Flags flags );
|
||||
static inline DbU::Unit getOffset ( size_t depth );
|
||||
static inline DbU::Unit getWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getPWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getViaWidth ( size_t depth );
|
||||
static inline Flags getDirection ( const Layer* );
|
||||
static inline DbU::Unit getPitch ( const Layer*, Flags flags );
|
||||
|
@ -239,11 +242,13 @@ namespace Anabatic {
|
|||
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
|
||||
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
|
||||
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDPVerticalWidth () { return getConfiguration()->getDPVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
|
||||
inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); }
|
||||
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
|
||||
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
|
||||
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDPHorizontalWidth () { return getConfiguration()->getDPHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
|
||||
inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); }
|
||||
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
|
||||
|
@ -263,6 +268,7 @@ namespace Anabatic {
|
|||
inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); }
|
||||
inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
|
||||
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }
|
||||
inline DbU::Unit Session::getPWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerPWireWidth(depth); }
|
||||
inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); }
|
||||
inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); }
|
||||
inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); }
|
||||
|
|
|
@ -88,6 +88,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA12).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -100,6 +101,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -112,6 +114,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA34).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -124,6 +127,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -136,6 +140,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -152,6 +157,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA12).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
@ -164,6 +170,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(5) # track pitch.
|
||||
, l(2) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(1) # VIA side (that is VIA23).
|
||||
, l(4) # obstacle dW.
|
||||
) )
|
||||
|
|
|
@ -91,6 +91,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -103,6 +104,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -115,6 +117,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA34).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -127,6 +130,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -139,6 +143,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -151,6 +156,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL6') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -166,6 +172,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -178,6 +185,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -190,6 +198,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA34).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -202,6 +211,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(15) # track pitch.
|
||||
, l(6) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(4) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -214,6 +224,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(15) # track pitch.
|
||||
, l(6) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(4) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -226,6 +237,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL6') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(15) # track pitch.
|
||||
, l(6) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(4) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -242,6 +254,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -254,6 +267,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -266,6 +280,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(8) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA12).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -278,6 +293,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(2) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
@ -294,6 +310,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(3) # VIA side (that is VIA12).
|
||||
, l(7) # obstacle dW.
|
||||
) )
|
||||
|
@ -306,6 +323,7 @@ rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # meta
|
|||
, l(0) # track offset from AB.
|
||||
, l(10) # track pitch.
|
||||
, l(3) # wire width.
|
||||
, 0 # perpandicular wire width.
|
||||
, l(3) # VIA side (that is VIA23).
|
||||
, l(8) # obstacle dW.
|
||||
) )
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace CRL {
|
|||
, _isSymbolic (gauge._isSymbolic)
|
||||
{
|
||||
// Make a deep copy of the map.
|
||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ )
|
||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
|
||||
addLayerGauge ( RoutingLayerGauge::create
|
||||
( gauge._layerGauges[i]->getLayer()
|
||||
, gauge._layerGauges[i]->getDirection()
|
||||
|
@ -82,10 +82,12 @@ namespace CRL {
|
|||
, gauge._layerGauges[i]->getOffset()
|
||||
, gauge._layerGauges[i]->getPitch()
|
||||
, gauge._layerGauges[i]->getWireWidth()
|
||||
, gauge._layerGauges[i]->getPWireWidth()
|
||||
, gauge._layerGauges[i]->getViaWidth()
|
||||
, gauge._layerGauges[i]->getObstacleDw() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RoutingGauge* RoutingGauge::create ( const char* name )
|
||||
|
@ -228,6 +230,13 @@ namespace CRL {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit RoutingGauge::getPWireWidth ( const Layer* layer ) const
|
||||
{
|
||||
size_t depth = getLayerDepth( layer );
|
||||
return (depth != nlayerdepth) ? _layerGauges[depth]->getPWireWidth() : 0;
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit RoutingGauge::getViaWidth ( const Layer* layer ) const
|
||||
{
|
||||
size_t depth = getLayerDepth( layer );
|
||||
|
|
|
@ -106,6 +106,7 @@ namespace CRL {
|
|||
, DbU::Unit offset
|
||||
, DbU::Unit pitch
|
||||
, DbU::Unit wireWidth
|
||||
, DbU::Unit pwireWidth
|
||||
, DbU::Unit viaWidth
|
||||
, DbU::Unit obsDw )
|
||||
: _layer (layer)
|
||||
|
@ -117,6 +118,7 @@ namespace CRL {
|
|||
, _offset (offset)
|
||||
, _pitch (pitch)
|
||||
, _wireWidth (wireWidth)
|
||||
, _pwireWidth (pwireWidth)
|
||||
, _viaWidth (viaWidth)
|
||||
, _obstacleDw (obsDw)
|
||||
{ }
|
||||
|
@ -130,6 +132,7 @@ namespace CRL {
|
|||
, DbU::Unit offset
|
||||
, DbU::Unit pitch
|
||||
, DbU::Unit wireWidth
|
||||
, DbU::Unit pwireWidth
|
||||
, DbU::Unit viaWidth
|
||||
, DbU::Unit obsDw )
|
||||
{
|
||||
|
@ -149,6 +152,7 @@ namespace CRL {
|
|||
, offset
|
||||
, pitch
|
||||
, wireWidth
|
||||
, pwireWidth
|
||||
, viaWidth
|
||||
, obsDw );
|
||||
|
||||
|
@ -327,6 +331,7 @@ namespace CRL {
|
|||
jsonWrite( w, "_offset" , _offset );
|
||||
jsonWrite( w, "_pitch" , _pitch );
|
||||
jsonWrite( w, "_wireWidth" , _wireWidth );
|
||||
jsonWrite( w, "_pwireWidth" , _pwireWidth );
|
||||
jsonWrite( w, "_viaWidth" , _viaWidth );
|
||||
jsonWrite( w, "_obstacleDw" , _obstacleDw );
|
||||
w->endObject();
|
||||
|
@ -381,6 +386,7 @@ namespace CRL {
|
|||
DbU::Unit offset = get<int64_t> ( stack, "_offset" );
|
||||
DbU::Unit pitch = get<int64_t> ( stack, "_pitch" );
|
||||
DbU::Unit wireWidth = get<int64_t> ( stack, "_wireWidth" );
|
||||
DbU::Unit pwireWidth = get<int64_t> ( stack, "_pwireWidth" );
|
||||
DbU::Unit viaWidth = get<int64_t> ( stack, "_viaWidth" );
|
||||
DbU::Unit obstacleDw = get<int64_t> ( stack, "_obstacleDw" );
|
||||
|
||||
|
@ -400,6 +406,7 @@ namespace CRL {
|
|||
, offset
|
||||
, pitch
|
||||
, wireWidth
|
||||
, pwireWidth
|
||||
, viaWidth
|
||||
, obstacleDw
|
||||
);
|
||||
|
|
|
@ -76,6 +76,7 @@ namespace CRL {
|
|||
DbU::Unit getPitch ( const Layer* ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getViaWidth ( const Layer* ) const;
|
||||
RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
|
||||
inline unsigned int getLayerDirection ( size_t depth ) const;
|
||||
|
@ -83,6 +84,7 @@ namespace CRL {
|
|||
inline DbU::Unit getLayerPitch ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerOffset ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerPWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getViaWidth ( size_t depth ) const;
|
||||
const Layer* getRoutingLayer ( size_t depth ) const;
|
||||
Layer* getContactLayer ( size_t depth ) const;
|
||||
|
@ -129,6 +131,7 @@ namespace CRL {
|
|||
inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); }
|
||||
inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); }
|
||||
inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); }
|
||||
inline DbU::Unit RoutingGauge::getLayerPWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getPWireWidth(); }
|
||||
inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); }
|
||||
inline void RoutingGauge::setSymbolic ( bool state ) { _isSymbolic=state; }
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace CRL {
|
|||
, DbU::Unit offset
|
||||
, DbU::Unit pitch
|
||||
, DbU::Unit wireWidth
|
||||
, DbU::Unit pwireWidth
|
||||
, DbU::Unit viaWidth
|
||||
, DbU::Unit obsDw );
|
||||
virtual void destroy ();
|
||||
|
@ -102,6 +103,7 @@ namespace CRL {
|
|||
inline DbU::Unit getPitch () const;
|
||||
inline DbU::Unit getHalfPitch () const;
|
||||
inline DbU::Unit getWireWidth () const;
|
||||
inline DbU::Unit getPWireWidth () const;
|
||||
inline DbU::Unit getHalfWireWidth () const;
|
||||
inline DbU::Unit getViaWidth () const;
|
||||
inline DbU::Unit getHalfViaWidth () const;
|
||||
|
@ -111,6 +113,7 @@ namespace CRL {
|
|||
long getTrackIndex ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
|
||||
inline DbU::Unit getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const;
|
||||
DbU::Unit getTrackPosition ( DbU::Unit start, long index ) const;
|
||||
inline void setPWireWidth ( DbU::Unit );
|
||||
// Hurricane Managment.
|
||||
void toJson ( JsonWriter* ) const;
|
||||
virtual string _getTypeName () const;
|
||||
|
@ -128,6 +131,7 @@ namespace CRL {
|
|||
DbU::Unit _offset;
|
||||
DbU::Unit _pitch;
|
||||
DbU::Unit _wireWidth;
|
||||
DbU::Unit _pwireWidth;
|
||||
DbU::Unit _viaWidth;
|
||||
DbU::Unit _obstacleDw;
|
||||
|
||||
|
@ -140,11 +144,13 @@ namespace CRL {
|
|||
, DbU::Unit offset
|
||||
, DbU::Unit pitch
|
||||
, DbU::Unit wireWidth
|
||||
, DbU::Unit pwireWidth
|
||||
, DbU::Unit viaWidth
|
||||
, DbU::Unit obsDw );
|
||||
RoutingLayerGauge ( const RoutingLayerGauge& ) = delete;
|
||||
virtual ~RoutingLayerGauge ();
|
||||
virtual void _preDestroy();
|
||||
RoutingLayerGauge& operator= ( const RoutingLayerGauge& );
|
||||
RoutingLayerGauge& operator= ( const RoutingLayerGauge& ) = delete;
|
||||
|
||||
// Friends.
|
||||
friend class RoutingGauge;
|
||||
|
@ -178,12 +184,14 @@ namespace CRL {
|
|||
inline DbU::Unit RoutingLayerGauge::getPitch () const { return _pitch; }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfPitch () const { return _pitch>>1; }
|
||||
inline DbU::Unit RoutingLayerGauge::getWireWidth () const { return _wireWidth; }
|
||||
inline DbU::Unit RoutingLayerGauge::getPWireWidth () const { return (_pwireWidth) ? _pwireWidth : _wireWidth; }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfWireWidth () const { return _wireWidth>>1; }
|
||||
inline DbU::Unit RoutingLayerGauge::getViaWidth () const { return _viaWidth; }
|
||||
inline DbU::Unit RoutingLayerGauge::getHalfViaWidth () const { return _viaWidth>>1; }
|
||||
inline DbU::Unit RoutingLayerGauge::getObstacleDw () const { return _obstacleDw; }
|
||||
inline DbU::Unit RoutingLayerGauge::getTrackPosition ( DbU::Unit start, DbU::Unit stop, DbU::Unit position, unsigned mode ) const
|
||||
{ return getTrackPosition( start, getTrackIndex(start,stop,position,mode) ); }
|
||||
inline void RoutingLayerGauge::setPWireWidth ( DbU::Unit pwidth ) { _pwireWidth = pwidth; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -252,6 +252,30 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PyRoutingGauge_getPWireWidth ( PyRoutingGauge* self, PyObject* args )
|
||||
{
|
||||
cdebug_log(30,0) << "PyRoutingGauge_getPWireWidth()" << endl;
|
||||
|
||||
DbU::Unit wireWidth = 0;
|
||||
HTRY
|
||||
METHOD_HEAD("RoutingGauge.getPWireWidth()")
|
||||
PyObject* pyLayer = NULL;
|
||||
|
||||
if (PyArg_ParseTuple( args, "O:RoutingGauge.getPWireWidth", &pyLayer)) {
|
||||
if ( not PyObject_IsInstance(pyLayer,(PyObject*)&PyTypeLayer) ) {
|
||||
PyErr_SetString ( ConstructorError, "Bad type for layer argument of RoutingGauge.getPWireWidth()." );
|
||||
return NULL;
|
||||
}
|
||||
wireWidth = rg->getPWireWidth( PYLAYER_O(pyLayer) );
|
||||
} else {
|
||||
PyErr_SetString ( ConstructorError, "Bad parameters given to RoutingGauge.getPWireWidth()." );
|
||||
return NULL;
|
||||
}
|
||||
HCATCH
|
||||
return Py_BuildValue("I",wireWidth);
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyRoutingGauge_getViaWidth ( PyRoutingGauge* self, PyObject* args )
|
||||
{
|
||||
cdebug_log(30,0) << "PyRoutingGauge_getViaWidth()" << endl;
|
||||
|
|
|
@ -77,11 +77,12 @@ extern "C" {
|
|||
PyObject* pyOffset = NULL;
|
||||
PyObject* pyPitch = NULL;
|
||||
PyObject* pyWireWidth = NULL;
|
||||
PyObject* pyPWireWidth = NULL;
|
||||
PyObject* pyViaWidth = NULL;
|
||||
PyObject* pyObsDw = NULL;
|
||||
|
||||
if (PyArg_ParseTuple( args
|
||||
, "OIIIdOOOOO:RoutingLayerGauge.create"
|
||||
, "OIIIdOOOOOO:RoutingLayerGauge.create"
|
||||
, &pyLayer
|
||||
, &direction
|
||||
, &type
|
||||
|
@ -90,6 +91,7 @@ extern "C" {
|
|||
, &pyOffset
|
||||
, &pyPitch
|
||||
, &pyWireWidth
|
||||
, &pyPWireWidth
|
||||
, &pyViaWidth
|
||||
, &pyObsDw
|
||||
)) {
|
||||
|
@ -120,6 +122,7 @@ extern "C" {
|
|||
, PyAny_AsLong(pyOffset)
|
||||
, PyAny_AsLong(pyPitch)
|
||||
, PyAny_AsLong(pyWireWidth)
|
||||
, PyAny_AsLong(pyPWireWidth)
|
||||
, PyAny_AsLong(pyViaWidth)
|
||||
, PyAny_AsLong(pyObsDw)
|
||||
);
|
||||
|
@ -265,10 +268,12 @@ extern "C" {
|
|||
DirectGetLongAttribute (PyRoutingLayerGauge_getPitch ,getPitch ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getHalfPitch ,getHalfPitch ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getWireWidth ,getWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getPWireWidth ,getPWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getHalfWireWidth,getHalfWireWidth,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getViaWidth ,getViaWidth ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getHalfViaWidth ,getHalfViaWidth ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectGetLongAttribute (PyRoutingLayerGauge_getObstacleDw ,getObstacleDw ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
DirectSetLongAttribute (PyRoutingLayerGauge_setPWireWidth ,setPWireWidth ,PyRoutingLayerGauge,RoutingLayerGauge)
|
||||
|
||||
|
||||
// Standart Destroy (Attribute).
|
||||
|
@ -297,6 +302,8 @@ extern "C" {
|
|||
, "Returns the half track pitch (center to center)." }
|
||||
, { "getWireWidth" , (PyCFunction)PyRoutingLayerGauge_getWireWidth , METH_NOARGS
|
||||
, "Returns the wire width." }
|
||||
, { "getPWireWidth" , (PyCFunction)PyRoutingLayerGauge_getPWireWidth , METH_NOARGS
|
||||
, "Returns the perpandicular wire width (same layer)." }
|
||||
, { "getHalfWireWidth" , (PyCFunction)PyRoutingLayerGauge_getHalfWireWidth, METH_NOARGS
|
||||
, "Returns the half wire width." }
|
||||
, { "getViaWidth" , (PyCFunction)PyRoutingLayerGauge_getViaWidth , METH_NOARGS
|
||||
|
@ -311,6 +318,8 @@ extern "C" {
|
|||
, "Returns the index of track at the given position (with rounding)." }
|
||||
, { "getTrackPosition" , (PyCFunction)PyRoutingLayerGauge_getTrackPosition, METH_VARARGS
|
||||
, "Compute the position of track number <depth>." }
|
||||
, { "setPWireWidth" , (PyCFunction)PyRoutingLayerGauge_setPWireWidth , METH_VARARGS
|
||||
, "Sets the perpandicular wire width (same layer)." }
|
||||
//, { "destroy" , (PyCFunction)PyRoutingLayerGauge_destroy , METH_VARARGS
|
||||
// , "Destroy the associated hurricane object. The python object remains." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
|
|
|
@ -70,9 +70,14 @@ class BigVia ( object ):
|
|||
global rg
|
||||
if rg is None: rg = CRL.AllianceFramework.get().getRoutingGauge()
|
||||
for depth in range(self.bottomDepth,self.topDepth+1):
|
||||
print( 'Create plate @{} {} {}'.format(DbU.getValueString(self.x)
|
||||
,DbU.getValueString(self.y)
|
||||
,rg.getRoutingLayer(depth)) )
|
||||
minArea = rg.getRoutingLayer( depth ).getMinimalArea()
|
||||
minLength = DbU.fromPhysical( minArea / DbU.toPhysical( self.width, DbU.UnitPowerMicro )
|
||||
, DbU.UnitPowerMicro )
|
||||
#minLength = toFoundryGrid( minLength, DbU.SnapModeSuperior )
|
||||
plateArea = DbU.toPhysical( self.width , DbU.UnitPowerMicro ) \
|
||||
* DbU.toPhysical( self.height, DbU.UnitPowerMicro )
|
||||
if plateArea < minArea:
|
||||
print( WarningMessage( 'BigVia::doLayout(): Area too small for {}'.format(self.net) ))
|
||||
self.plates[ depth ] = Contact.create( self.net
|
||||
, rg.getRoutingLayer(depth)
|
||||
, self.x , self.y
|
||||
|
@ -115,9 +120,6 @@ class BigVia ( object ):
|
|||
x = cutArea.getXMin()
|
||||
self.vias[ depth ].append( [] )
|
||||
while x <= cutArea.getXMax():
|
||||
print( 'Create cut @{} {} {}'.format(DbU.getValueString(x)
|
||||
,DbU.getValueString(y)
|
||||
,cutLayer) )
|
||||
cut = Contact.create( self.net, cutLayer, x, y, cutSide, cutSide )
|
||||
self.vias[ depth ][ -1 ].append( cut )
|
||||
x += cutSide + cutSpacing
|
||||
|
|
|
@ -376,6 +376,8 @@ class Block ( object ):
|
|||
trace( 550, '\tCORE AB is {}\n'.format(self.conf.cell.getAbutmentBox()) )
|
||||
if self.conf.isCoreBlock:
|
||||
self.conf.setupICore()
|
||||
else:
|
||||
self.conf.setRoutingBb( self.conf.cell.getAbutmentBox() )
|
||||
|
||||
def addClockTrees ( self ):
|
||||
"""Create the trunk of all the clock trees (recursive H-Tree)."""
|
||||
|
|
|
@ -97,11 +97,13 @@ class ClockTree ( object ):
|
|||
if qt.isLeaf():
|
||||
trace( 550, '-' )
|
||||
return False
|
||||
|
||||
gaugeConf = self.spares.conf
|
||||
bufferConf = self.spares.conf.bufferConf
|
||||
ckNet = qt.bOutputPlug.getNet()
|
||||
self.subNets.append( ckNet )
|
||||
hLeafDepth = gaugeConf.horizontalDepth
|
||||
if gaugeConf.horizontalDepth > 2 and (gaugeConf.horizontalDepth > gaugeConf.verticalDepth):
|
||||
hLeafDepth = gaugeConf.horizontalDepth - 2
|
||||
leftSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 )
|
||||
rightSourceContact = gaugeConf.rpAccessByPlugName( qt.buffer , bufferConf.output, ckNet , GaugeConf.HAccess|GaugeConf.OffsetBottom1 )
|
||||
blContact = gaugeConf.rpAccessByPlugName( qt.bl.buffer, bufferConf.input , ckNet )
|
||||
|
@ -110,14 +112,17 @@ class ClockTree ( object ):
|
|||
trContact = gaugeConf.rpAccessByPlugName( qt.tr.buffer, bufferConf.input , ckNet )
|
||||
leftContact = gaugeConf.createContact( ckNet, blContact.getX(), leftSourceContact.getY(), 0 )
|
||||
rightContact = gaugeConf.createContact( ckNet, brContact.getX(), rightSourceContact.getY(), 0 )
|
||||
leftSourceX = gaugeConf.getNearestVerticalTrack ( qt.root.area, leftSourceContact.getX(), 0 )
|
||||
leftSourceY = gaugeConf.getNearestHorizontalTrack( qt.root.area, leftSourceContact.getY(), 0 )
|
||||
rightSourceX = gaugeConf.getNearestVerticalTrack ( qt.root.area, rightSourceContact.getX(), 0 )
|
||||
rightSourceY = gaugeConf.getNearestHorizontalTrack( qt.root.area, rightSourceContact.getY(), 0 )
|
||||
leftX = gaugeConf.getNearestVerticalTrack ( qt.root.area, leftContact.getX(), 0 )
|
||||
rightX = gaugeConf.getNearestVerticalTrack ( qt.root.area, rightContact.getX(), 0 )
|
||||
tlY = gaugeConf.getNearestHorizontalTrack( qt.root.area, tlContact.getY(), 0 )
|
||||
blY = gaugeConf.getNearestHorizontalTrack( qt.root.area, blContact.getY(), 0 )
|
||||
leftSourceX = gaugeConf.getNearestVerticalTrack ( leftSourceContact.getX(), 0 )
|
||||
leftSourceY = gaugeConf.getNearestHorizontalTrack( leftSourceContact.getY(), 0 )
|
||||
rightSourceX = gaugeConf.getNearestVerticalTrack ( rightSourceContact.getX(), 0 )
|
||||
rightSourceY = gaugeConf.getNearestHorizontalTrack( rightSourceContact.getY(), 0 )
|
||||
leftX = gaugeConf.getNearestVerticalTrack ( leftContact.getX(), 0 )
|
||||
rightX = gaugeConf.getNearestVerticalTrack ( rightContact.getX(), 0 )
|
||||
tlY = gaugeConf.getTrack( tlContact.getY(), hLeafDepth, 0 )
|
||||
blY = gaugeConf.getTrack( blContact.getY(), hLeafDepth, 0 )
|
||||
#tlY = gaugeConf.getNearestHorizontalTrack( tlContact.getY(), 0 )
|
||||
#blY = gaugeConf.getNearestHorizontalTrack( blContact.getY(), 0 )
|
||||
trace( 550, '\tblY:{}\n'.format( DbU.getValueString(blY) ))
|
||||
gaugeConf.setStackPosition( leftSourceContact, leftSourceX, leftSourceY )
|
||||
gaugeConf.setStackPosition( rightSourceContact, rightSourceX, rightSourceY )
|
||||
gaugeConf.setStackPosition( tlContact, leftX, tlY )
|
||||
|
|
|
@ -59,6 +59,12 @@ def findCellOutput ( cell, callerName, parameterId ):
|
|||
, ' please check that the Nets directions are set.' ] )
|
||||
|
||||
|
||||
def toFoundryGrid ( u, mode ):
|
||||
"""Snap the DbU ``u`` to the foundry grid, according to ``mode``."""
|
||||
oneGrid = DbU.fromGrid( 1.0 )
|
||||
return DbU.getOnCustomGrid( u, oneGrid, mode )
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Class : "configuration.GaugeConf".
|
||||
|
||||
|
@ -87,6 +93,7 @@ class GaugeConf ( object ):
|
|||
self._plugToRp = { }
|
||||
self._rpToAccess = { }
|
||||
self._loadRoutingGauge()
|
||||
self._routingBb = Box()
|
||||
return
|
||||
|
||||
@property
|
||||
|
@ -122,8 +129,15 @@ class GaugeConf ( object ):
|
|||
@property
|
||||
def vDeepRG ( self ): return self._routingGauge.getLayerGauge( self.verticalDeepDepth )
|
||||
|
||||
@property
|
||||
def routingBb ( self ): return self._routingBb
|
||||
|
||||
def getPitch ( self, layer ): return self._routingGauge.getPitch( layer )
|
||||
|
||||
def setRoutingBb ( self, bb ):
|
||||
trace( 550, '\tGaugeConf.setRoutingBb(): {}\n'.format(bb) )
|
||||
self._routingBb = bb
|
||||
|
||||
def _loadRoutingGauge ( self ):
|
||||
trace( 550, ',+', '\tGaugeConf._loadRoutingGauge()\n' )
|
||||
gaugeName = Cfg.getParamString('anabatic.routingGauge').asString()
|
||||
|
@ -206,25 +220,34 @@ class GaugeConf ( object ):
|
|||
, self._routingGauge.getLayerGauge(depth).getViaWidth()
|
||||
)
|
||||
|
||||
def getNearestHorizontalTrack ( self, bb, y, flags ):
|
||||
def getTrack ( self, u, depth, offset ):
|
||||
"""
|
||||
Returns the y/x axis position of the H/V track nearest to ``u`` (y/x)
|
||||
with an offset of ``offset`` tracks applied.
|
||||
"""
|
||||
trace( 550, '\tGaugeConf.getTrack(): u={}, depth={}, offset={}' \
|
||||
.format( DbU.getValueString(u), depth, offset ))
|
||||
rg = self._routingGauge.getLayerGauge( depth )
|
||||
if rg.getDirection() == RoutingLayerGauge.Horizontal:
|
||||
bbMin = self.routingBb.getYMin()
|
||||
bbMax = self.routingBb.getYMax()
|
||||
else:
|
||||
bbMin = self.routingBb.getXMin()
|
||||
bbMax = self.routingBb.getXMax()
|
||||
index = rg.getTrackIndex( bbMin, bbMax, u, RoutingLayerGauge.Nearest )
|
||||
utrack = rg.getTrackPosition( bbMin, index )
|
||||
trace( 550, ' -> utrack={}\n'.format( DbU.getValueString(utrack) ))
|
||||
return utrack + offset*rg.getPitch()
|
||||
|
||||
def getNearestHorizontalTrack ( self, y, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth
|
||||
else: depth = self.horizontalDepth
|
||||
return self.getTrack( y, depth, 0 )
|
||||
|
||||
index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getYMin()
|
||||
, bb.getYMax()
|
||||
, y
|
||||
, RoutingLayerGauge.Nearest )
|
||||
return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getYMin(), index )
|
||||
|
||||
def getNearestVerticalTrack ( self, bb, x, flags ):
|
||||
def getNearestVerticalTrack ( self, x, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self.verticalDeepDepth
|
||||
else: depth = self.verticalDepth
|
||||
|
||||
index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getXMin()
|
||||
, bb.getXMax()
|
||||
, x
|
||||
, RoutingLayerGauge.Nearest )
|
||||
return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getXMin(), index )
|
||||
return self.getTrack( x, depth, 0 )
|
||||
|
||||
def createHorizontal ( self, source, target, y, flags ):
|
||||
if flags & GaugeConf.DeepDepth: depth = self.horizontalDeepDepth
|
||||
|
@ -274,16 +297,26 @@ class GaugeConf ( object ):
|
|||
hdepth = self.horizontalDepth
|
||||
vdepth = self.verticalDepth
|
||||
|
||||
hpitch = self._routingGauge.getLayerGauge(hdepth).getPitch()
|
||||
hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset()
|
||||
#hpitch = self._routingGauge.getLayerGauge(hdepth).getPitch()
|
||||
#hoffset = self._routingGauge.getLayerGauge(hdepth).getOffset()
|
||||
#contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 )
|
||||
#midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \
|
||||
# + self._cellGauge.getSliceHeight() / 2
|
||||
#midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch)
|
||||
#dy = midSliceY - contact1.getY()
|
||||
#
|
||||
#if flags & GaugeConf.OffsetBottom1: dy += hpitch
|
||||
#if flags & GaugeConf.OffsetTop1: dy -= hpitch
|
||||
#contact1.setDy( dy )
|
||||
|
||||
yoffset = 0
|
||||
if flags & GaugeConf.OffsetBottom1: yoffset = 1
|
||||
if flags & GaugeConf.OffsetTop1: yoffset = -1
|
||||
contact1 = Contact.create( rp, self._routingGauge.getContactLayer(0), 0, 0 )
|
||||
midSliceY = contact1.getY() - (contact1.getY() % self._cellGauge.getSliceHeight()) \
|
||||
+ self._cellGauge.getSliceHeight() / 2
|
||||
midTrackY = midSliceY - ((midSliceY - hoffset) % hpitch)
|
||||
dy = midSliceY - contact1.getY()
|
||||
|
||||
if flags & GaugeConf.OffsetBottom1: dy += hpitch
|
||||
if flags & GaugeConf.OffsetTop1: dy -= hpitch
|
||||
ytrack = self.getTrack( contact1.getY(), self.horizontalDeepDepth, yoffset )
|
||||
dy = ytrack - contact1.getY()
|
||||
contact1.setDy( dy )
|
||||
|
||||
trace( 550, contact1 )
|
||||
|
@ -293,13 +326,20 @@ class GaugeConf ( object ):
|
|||
trace( 550, '\tstopDepth:%d\n' % stopDepth )
|
||||
|
||||
for depth in range(1,stopDepth):
|
||||
rg = self._routingGauge.getLayerGauge(depth)
|
||||
xoffset = 0
|
||||
if flags & GaugeConf.OffsetRight1 and depth == 1:
|
||||
xoffset = self._routingGauge.getLayerGauge(depth+1).getPitch()
|
||||
xoffset = 1
|
||||
if rg.getDirection() == RoutingLayerGauge.Horizontal:
|
||||
xtrack = self.getTrack( contact1.getX(), depth+1, xoffset )
|
||||
ytrack = self.getTrack( contact1.getY(), depth , 0 )
|
||||
else:
|
||||
xtrack = self.getTrack( contact1.getX(), depth , xoffset )
|
||||
ytrack = self.getTrack( contact1.getY(), depth+1, 0 )
|
||||
contact2 = Contact.create( rp.getNet()
|
||||
, self._routingGauge.getContactLayer(depth)
|
||||
, contact1.getX() + xoffset
|
||||
, contact1.getY()
|
||||
, xtrack
|
||||
, ytrack
|
||||
, self._routingGauge.getLayerGauge(depth).getViaWidth()
|
||||
, self._routingGauge.getLayerGauge(depth).getViaWidth()
|
||||
)
|
||||
|
@ -307,17 +347,17 @@ class GaugeConf ( object ):
|
|||
if self._routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal:
|
||||
segment = Horizontal.create( contact1
|
||||
, contact2
|
||||
, self._routingGauge.getRoutingLayer(depth)
|
||||
, rg.getLayer()
|
||||
, contact1.getY()
|
||||
, self._routingGauge.getLayerGauge(depth).getWireWidth()
|
||||
, rg.getWireWidth()
|
||||
)
|
||||
trace( 550, segment )
|
||||
else:
|
||||
segment = Vertical.create( contact1
|
||||
, contact2
|
||||
, self._routingGauge.getRoutingLayer(depth)
|
||||
, rg.getLayer()
|
||||
, contact1.getX()
|
||||
, self._routingGauge.getLayerGauge(depth).getWireWidth()
|
||||
, rg.getWireWidth()
|
||||
)
|
||||
trace( 550, segment )
|
||||
contact1 = contact2
|
||||
|
@ -385,8 +425,55 @@ class GaugeConf ( object ):
|
|||
elif isinstance(segment,Vertical):
|
||||
segment.setX( x )
|
||||
segment.getOppositeAnchor( topContact ).setX( x )
|
||||
self.expandMinArea( topContact )
|
||||
return
|
||||
|
||||
def expandMinArea ( self, topContact ):
|
||||
segments = []
|
||||
contacts = [ topContact ]
|
||||
i = 0
|
||||
while i < len(contacts):
|
||||
for component in contacts[i].getSlaveComponents():
|
||||
if not isinstance(component,Horizontal) and not isinstance(component,Vertical):
|
||||
continue
|
||||
if component not in segments:
|
||||
segments.append( component )
|
||||
if component.getSource() not in contacts:
|
||||
contacts.append( component.getSource() )
|
||||
if component.getTarget() not in contacts:
|
||||
contacts.append( component.getTarget() )
|
||||
i += 1
|
||||
for segment in segments:
|
||||
layer = segment.getLayer()
|
||||
wireWidth = segment.getWidth()
|
||||
depth = self._routingGauge.getLayerDepth( layer )
|
||||
minArea = self._routingGauge.getRoutingLayer( depth ).getMinimalArea()
|
||||
extension = 0
|
||||
if minArea:
|
||||
minLength = DbU.fromPhysical( minArea / DbU.toPhysical( wireWidth, DbU.UnitPowerMicro )
|
||||
, DbU.UnitPowerMicro )
|
||||
minLength = toFoundryGrid( minLength, DbU.SnapModeSuperior );
|
||||
if isinstance(segment,Horizontal):
|
||||
uMin = segment.getSource().getX()
|
||||
uMax = segment.getTarget().getX()
|
||||
segLength = abs( uMax - uMin )
|
||||
if segLength < minLength:
|
||||
extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior )
|
||||
if uMin > uMax:
|
||||
extension = - extension
|
||||
segment.setDxSource( -extension )
|
||||
segment.setDxTarget( extension )
|
||||
if isinstance(segment,Vertical):
|
||||
uMin = segment.getSource().getY()
|
||||
uMax = segment.getTarget().getY()
|
||||
segLength = abs( uMax - uMin )
|
||||
if segLength < minLength:
|
||||
extension = toFoundryGrid( (minLength - segLength)/2, DbU.SnapModeSuperior )
|
||||
if uMin > uMax:
|
||||
extension = - extension
|
||||
segment.setDySource( -extension )
|
||||
segment.setDyTarget( extension )
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# Class : "IoPadConf".
|
||||
|
@ -1004,8 +1091,8 @@ class BlockConf ( GaugeConf ):
|
|||
@property
|
||||
def coreAb ( self ):
|
||||
if not hasattr(self,'coreSize'): return Box()
|
||||
trace( 550, '\tcoreAb:[{} {}]\n'.format( DbU.getValueString(self.coreSize[0])
|
||||
, DbU.getValueString(self.coreSize[1]) ))
|
||||
#trace( 550, '\tcoreAb:[{} {}]\n'.format( DbU.getValueString(self.coreSize[0])
|
||||
# , DbU.getValueString(self.coreSize[1]) ))
|
||||
return Box( 0, 0, self.coreSize[0], self.coreSize[1] )
|
||||
|
||||
@property
|
||||
|
|
|
@ -105,7 +105,10 @@ class Chip ( Block ):
|
|||
self.conf.core.setAbutmentBox( self.conf.coreAb )
|
||||
x = (coronaAb.getWidth () - self.conf.coreAb.getWidth ()) / 2
|
||||
y = (coronaAb.getHeight() - self.conf.coreAb.getHeight()) / 2
|
||||
trace( 550, '\tCore X, {} '.format(DbU.getValueString(x)) )
|
||||
x = x - (x % self.conf.sliceHeight)
|
||||
trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.conf.sliceHeight)
|
||||
, DbU.getValueString(x)) )
|
||||
y = y - (y % self.conf.sliceHeight)
|
||||
self.conf.icore.setTransformation ( Transformation(x,y,Transformation.Orientation.ID) )
|
||||
self.conf.icore.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||
|
|
|
@ -190,8 +190,11 @@ class ChipConf ( BlockConf ):
|
|||
self.core.setAbutmentBox( Box( 0, 0, ab.getWidth(), ab.getHeight() ) )
|
||||
trace( 550, '\tCORE ab:{}\n'.format(self.coreAb) )
|
||||
coreX = (self.coronaAb.getWidth () - self.coreAb.getWidth ()) / 2
|
||||
trace( 550, '\tCore X, {} '.format(DbU.getValueString(coreX)) )
|
||||
coreX = coreX - (coreX % self.sliceHeight)
|
||||
trace( 550, ' adjusted on {}, {}\n'.format( DbU.getValueString(self.sliceHeight)
|
||||
, DbU.getValueString(coreX)) )
|
||||
coreY = (self.coronaAb.getHeight() - self.coreAb.getHeight()) / 2
|
||||
coreX = coreX - (coreX % self.sliceStep)
|
||||
coreY = coreY - (coreY % self.sliceHeight)
|
||||
self.icore.setTransformation( Transformation( coreX, coreY, Transformation.Orientation.ID ) )
|
||||
self.icore.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||
|
@ -668,6 +671,7 @@ class ChipConf ( BlockConf ):
|
|||
, self.toSymbolic( self.ioPadHeight + ab.getYMin(), Superior )
|
||||
, Transformation.Orientation.ID ) )
|
||||
self.icorona.setPlacementStatus( Instance.PlacementStatus.FIXED )
|
||||
self.setRoutingBb( self.corona.getAbutmentBox() )
|
||||
|
||||
def setupCore ( self, gapX1, gapY1, gapX2, gapY2 ):
|
||||
trace( 550, ',+', '\tChipConf.setupCore()\n' )
|
||||
|
|
|
@ -115,6 +115,7 @@ class HorizontalRail ( Rail ):
|
|||
|
||||
def connect ( self, contact ):
|
||||
trace( 550, ',+', '\tTry to connect to: {}\n'.format(self) )
|
||||
trace( 550, '\tContact {}\n'.format(contact) )
|
||||
contactBb = contact.getBoundingBox()
|
||||
if contactBb.getXMin() < self.side.innerBb.getXMin() \
|
||||
or contactBb.getXMax() > self.side.innerBb.getXMax():
|
||||
|
@ -167,8 +168,8 @@ class HorizontalRail ( Rail ):
|
|||
def doLayout ( self ):
|
||||
trace( 550, ',+', '\tHorizontalRail.doLayout() order:{} @{}\n' \
|
||||
.format( self.order,DbU.getValueString(self.axis )))
|
||||
railVias = [ self.side.corner0(self.order)
|
||||
, self.side.corner1(self.order) ]
|
||||
railVias = [ self.side.corner0(self.order).getPlate( self.side.getHLayer() )
|
||||
, self.side.corner1(self.order).getPlate( self.side.getHLayer() ) ]
|
||||
for via in self.vias.values():
|
||||
if via[1].getNet() != via[2].getNet(): continue
|
||||
via[1].mergeDepth( self.side.getLayerDepth(self.side.getVLayer()) )
|
||||
|
@ -206,8 +207,8 @@ class VerticalRail ( Rail ):
|
|||
, DbU.getValueString(self.axis) )
|
||||
|
||||
def doLayout ( self ):
|
||||
railVias = [ self.side.corner0(self.order)
|
||||
, self.side.corner1(self.order) ]
|
||||
railVias = [ self.side.corner0(self.order).getPlate( self.side.getVLayer() )
|
||||
, self.side.corner1(self.order).getPlate( self.side.getVLayer() ) ]
|
||||
for via in self.vias.values():
|
||||
if via[1].getNet() != via[2].getNet(): continue
|
||||
via[1].doLayout()
|
||||
|
@ -465,8 +466,6 @@ class VerticalSide ( Side ):
|
|||
if via[1].getNet() != via[2].getNet(): continue
|
||||
spans.merge( via[1].y - via[1].height/2, via[1].y + via[1].height/2 )
|
||||
routingGauge = self.corona.routingGauge
|
||||
print( self.getOuterRail(0) )
|
||||
print( self.getOuterRail(0).vias.values() )
|
||||
for depth in range(self.getOuterRail(0).vias.values()[0][1].bottomDepth
|
||||
,self.getOuterRail(0).vias.values()[0][1].topDepth ):
|
||||
blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer()
|
||||
|
@ -645,33 +644,21 @@ class Builder ( object ):
|
|||
trBox.merge( xTR, yTR )
|
||||
self.routingGauge.getContactLayer(contactDepth)
|
||||
self.corners[SouthWest].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xBL, yBL
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
BigVia( net, contactDepth, xBL, yBL, self.hRailWidth, self.vRailWidth ) )
|
||||
self.corners[SouthWest][-1].mergeDepth( contactDepth+1 )
|
||||
self.corners[SouthWest][-1].doLayout()
|
||||
self.corners[NorthWest].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xBL, yTR
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
BigVia( net, contactDepth, xBL, yTR, self.hRailWidth, self.vRailWidth ) )
|
||||
self.corners[NorthWest][-1].mergeDepth( contactDepth+1 )
|
||||
self.corners[NorthWest][-1].doLayout()
|
||||
self.corners[SouthEast].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xTR, yBL
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
BigVia( net, contactDepth, xTR, yBL, self.hRailWidth, self.vRailWidth ) )
|
||||
self.corners[SouthEast][-1].mergeDepth( contactDepth+1 )
|
||||
self.corners[SouthEast][-1].doLayout()
|
||||
self.corners[NorthEast].append(
|
||||
Contact.create( net
|
||||
, self.routingGauge.getContactLayer(contactDepth)
|
||||
, xTR, yTR
|
||||
, self.hRailWidth
|
||||
, self.vRailWidth
|
||||
) )
|
||||
BigVia( net, contactDepth, xTR, yTR, self.hRailWidth, self.vRailWidth ) )
|
||||
self.corners[NorthEast][-1].mergeDepth( contactDepth+1 )
|
||||
self.corners[NorthEast][-1].doLayout()
|
||||
self.southSide.doLayout()
|
||||
self.northSide.doLayout()
|
||||
self.westSide .doLayout()
|
||||
|
|
|
@ -946,6 +946,12 @@ class Corona ( object ):
|
|||
bb = component.getBoundingBox()
|
||||
padInstance.getTransformation().applyOn( bb )
|
||||
trace( 550, '\t| External:{} bb:{}\n'.format(component,bb) )
|
||||
if self.conf.chipConf.ioPadGauge == 'LibreSOCIO':
|
||||
if chipIntNet.isPower() or chipIntNet.isGround():
|
||||
if side.type == North or side.type == South:
|
||||
bb.inflate( -DbU.fromPhysical( 0.6, DbU.UnitPowerMicro ), 0 )
|
||||
else:
|
||||
bb.inflate( 0, -DbU.fromPhysical( 0.6, DbU.UnitPowerMicro ) )
|
||||
if bb.intersect(innerBb):
|
||||
trace( 550, '\t| Accepted.\n' )
|
||||
lg = rg.getLayerGauge( component.getLayer() )
|
||||
|
|
|
@ -225,6 +225,7 @@ class Builder ( object ):
|
|||
return
|
||||
with UpdateSession():
|
||||
bufferRp = self.conf.rpAccessByOccurrence( Occurrence(htPlugs[0], Path()), ck, 0 )
|
||||
self.conf.expandMinArea( bufferRp )
|
||||
blockAb = self.block.getAbutmentBox()
|
||||
self.path.getTransformation().applyOn( blockAb )
|
||||
layerGauge = self.conf.routingGauge.getLayerGauge(self.conf.verticalDepth)
|
||||
|
|
|
@ -806,6 +806,14 @@ namespace Katana {
|
|||
|
||||
cdebug_tabw(155,1);
|
||||
|
||||
openSession();
|
||||
for ( RoutingPlane* plane : _routingPlanes ) {
|
||||
for ( Track* track : plane->getTracks() ) {
|
||||
track->expandMinArea();
|
||||
}
|
||||
}
|
||||
Session::close();
|
||||
|
||||
setState( Anabatic::EngineDriving );
|
||||
_gutKatana();
|
||||
|
||||
|
|
|
@ -504,7 +504,8 @@ namespace {
|
|||
//DbU::Unit delta = plane->getLayerGauge()->getPitch()
|
||||
// - plane->getLayerGauge()->getHalfWireWidth()
|
||||
// - DbU::fromLambda(0.1);
|
||||
DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1);
|
||||
//DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1);
|
||||
DbU::Unit delta = 0;
|
||||
DbU::Unit extension = layer->getExtentionCap();
|
||||
//DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2;
|
||||
//DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth();
|
||||
|
@ -515,6 +516,12 @@ namespace {
|
|||
DbU::Unit axisMin = 0;
|
||||
DbU::Unit axisMax = 0;
|
||||
|
||||
if (AllianceFramework::get()->getCellGauge()->getName() == Name("FlexLib")) {
|
||||
if (_width >= DbU::fromPhysical( 10.0, DbU::UnitPower::Micro )) {
|
||||
delta = 2 * plane->getLayerGauge()->getPitch();
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_log(159,0) << " delta:" << DbU::getValueString(delta)
|
||||
<< " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch())
|
||||
<< " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth())
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "anabatic/AutoContact.h"
|
||||
#include "katana/RoutingPlane.h"
|
||||
#include "katana/Track.h"
|
||||
#include "katana/TrackMarker.h"
|
||||
|
@ -31,6 +33,7 @@
|
|||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::DebugSession;
|
||||
using namespace CRL;
|
||||
using namespace Katana;
|
||||
|
||||
|
@ -44,6 +47,81 @@ namespace {
|
|||
// { return (*(v.begin()+i))->getSourceU(); }
|
||||
|
||||
|
||||
bool hasSameLayerTurn ( const Layer* layer, TrackElement* segment, Flags flags )
|
||||
{
|
||||
if (not segment or not segment->base()) return false;
|
||||
AutoContact* contact = (flags & Flags::Source) ? segment->base()->getAutoSource()
|
||||
: segment->base()->getAutoTarget() ;
|
||||
if (contact->getLayer() != layer) return false;
|
||||
if (not contact->isTurn()) return false;
|
||||
AutoSegment* pp = contact->getPerpandicular( segment->base() );
|
||||
return contact->getPerpandicular(segment->base())->getLength();
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit toFoundryGrid ( DbU::Unit u, DbU::SnapMode mode )
|
||||
{
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1.0 );
|
||||
return DbU::getOnCustomGrid( u, oneGrid, mode );
|
||||
}
|
||||
|
||||
|
||||
void expandToMinArea ( TrackElement* minSegment
|
||||
, TrackElement* maxSegment
|
||||
, const Interval& segSpan
|
||||
, DbU::Unit minFree
|
||||
, DbU::Unit maxFree )
|
||||
{
|
||||
DebugSession::open( minSegment->getNet(), 150, 160 );
|
||||
cdebug_log(155,1) << "Track::expandMinArea() for:" << endl;
|
||||
cdebug_log(155,0) << "minSegment:" << minSegment << endl;
|
||||
cdebug_log(155,0) << "maxSegment:" << maxSegment << endl;
|
||||
|
||||
const Layer* layer = minSegment->getLayer();
|
||||
double minArea = layer->getMinimalArea();
|
||||
DbU::Unit minSpacing = layer->getMinimalSpacing();
|
||||
DbU::Unit minLength
|
||||
= DbU::fromPhysical( minArea / DbU::toPhysical( minSegment->getWidth(), DbU::UnitPower::Micro )
|
||||
, DbU::UnitPower::Micro );
|
||||
minLength = toFoundryGrid( minLength, DbU::Superior );
|
||||
DbU::Unit segLength = segSpan.getSize() - minSpacing;
|
||||
cdebug_log(155,0) << "minSpacing:" << DbU::getValueString(minSpacing) << endl;
|
||||
cdebug_log(155,0) << " minLength:" << DbU::getValueString(minLength) << endl;
|
||||
cdebug_log(155,0) << " segLenght:" << DbU::getValueString(segLength) << endl;
|
||||
|
||||
DbU::Unit sourceECap = minSegment->base()->getExtensionCap( Flags::Source|Flags::LayerCapOnly );
|
||||
DbU::Unit targetECap = maxSegment->base()->getExtensionCap( Flags::Target|Flags::LayerCapOnly );
|
||||
cdebug_log(155,0) << "sourceECap:" << DbU::getValueString(sourceECap) << endl;
|
||||
cdebug_log(155,0) << "targetECap:" << DbU::getValueString(targetECap) << endl;
|
||||
|
||||
if (segLength < minLength) {
|
||||
DbU::Unit marginLeft = segSpan.getVMin() - minFree;
|
||||
DbU::Unit marginRight = maxFree - segSpan.getVMax();
|
||||
DbU::Unit expandLeft = toFoundryGrid( (minLength - segLength)/2 + sourceECap, DbU::Inferior );
|
||||
DbU::Unit expandRight = toFoundryGrid( (minLength - segLength)/2 + targetECap, DbU::Superior );
|
||||
if ((marginLeft >= expandLeft) and (marginRight >= expandRight)) {
|
||||
minSegment->base()->setDuSource( minSegment->base()->getDuSource() - expandLeft );
|
||||
maxSegment->base()->setDuTarget( maxSegment->base()->getDuTarget() + expandRight );
|
||||
} else {
|
||||
if (marginLeft + marginRight >= expandLeft + expandRight) {
|
||||
DbU::Unit shiftLeft = 0;
|
||||
if (marginLeft >= expandLeft + expandRight)
|
||||
shiftLeft = - expandRight;
|
||||
else
|
||||
shiftLeft = - marginLeft + expandLeft;
|
||||
minSegment->base()->setDuSource( minSegment->base()->getDuSource() - expandLeft + shiftLeft );
|
||||
maxSegment->base()->setDuTarget( maxSegment->base()->getDuTarget() + expandRight + shiftLeft );
|
||||
} else {
|
||||
cerr << Error( "::expandToMinArea(): Cannot expand %s."
|
||||
, getString(minSegment).c_str() ) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(155,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
|
@ -54,6 +132,7 @@ namespace Katana {
|
|||
using std::sort;
|
||||
using Hurricane::dbo_ptr;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Layer;
|
||||
|
@ -786,6 +865,58 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void Track::expandMinArea ()
|
||||
{
|
||||
if (_segments.empty()) return;
|
||||
|
||||
double minArea = getLayer()->getMinimalArea();
|
||||
if (minArea == 0.0) return;
|
||||
|
||||
DbU::Unit prevSpanMin = getMin();
|
||||
TrackElement* minSegment = NULL;
|
||||
TrackElement* maxSegment = NULL;
|
||||
Interval span;
|
||||
bool hasTurn = false;
|
||||
for ( size_t j=0 ; j<_segments.size() ; ) {
|
||||
if (not _segments[j]->base() or not (_segments[j]->getDirection() & getDirection())) {
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (not minSegment) {
|
||||
minSegment = _segments[j];
|
||||
maxSegment = _segments[j];
|
||||
if (not span.isEmpty()) prevSpanMin = span.getVMax();
|
||||
span.makeEmpty();
|
||||
span = _segments[j]->getCanonicalInterval();
|
||||
hasTurn = hasSameLayerTurn( getLayer(), _segments[j], Flags::Source )
|
||||
or hasSameLayerTurn( getLayer(), _segments[j], Flags::Target );
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (_segments[j]->getNet() == minSegment->getNet())
|
||||
and (span.getVMax() >= _segments[j]->getSourceU()) ) {
|
||||
if (_segments[j]->getTargetU() > span.getVMax()) {
|
||||
maxSegment = _segments[j];
|
||||
span.merge( _segments[j]->getTargetU() );
|
||||
hasTurn = hasTurn or hasSameLayerTurn( getLayer(), _segments[j], Flags::Target );
|
||||
}
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (not hasTurn and minSegment->base())
|
||||
expandToMinArea( minSegment, maxSegment, span, prevSpanMin, _segments[j]->getSourceU() );
|
||||
|
||||
minSegment = NULL;
|
||||
}
|
||||
|
||||
if (not hasTurn and minSegment and minSegment->base())
|
||||
expandToMinArea( minSegment, maxSegment, span, prevSpanMin, getMax() );
|
||||
}
|
||||
|
||||
|
||||
string Track::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " "
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_ROUTING_PLANE_H
|
||||
#define KATANA_ROUTING_PLANE_H
|
||||
|
||||
#pragma once
|
||||
#include "crlcore/RoutingLayerGauge.h"
|
||||
#include "katana/Track.h"
|
||||
|
||||
|
@ -49,6 +47,7 @@ namespace Katana {
|
|||
RoutingPlane* getBottom () const;
|
||||
inline const Layer* getLayer () const;
|
||||
inline const Layer* getBlockageLayer () const;
|
||||
inline const vector<Track*> getTracks () const;
|
||||
inline size_t getTracksSize () const;
|
||||
inline size_t computeTracksSize () const;
|
||||
inline DbU::Unit getTrackPosition ( size_t index ) const;
|
||||
|
@ -101,6 +100,7 @@ namespace Katana {
|
|||
inline DbU::Unit RoutingPlane::getTrackMax () const { return _trackMax; }
|
||||
inline const Layer* RoutingPlane::getLayer () const { return getLayerGauge()->getLayer(); }
|
||||
inline const Layer* RoutingPlane::getBlockageLayer () const { return getLayerGauge()->getBlockageLayer(); }
|
||||
inline const vector<Track*> RoutingPlane::getTracks () const { return _tracks; }
|
||||
inline size_t RoutingPlane::getTracksSize () const { return _tracks.size(); }
|
||||
inline string RoutingPlane::_getTypeName () const { return "RoutingPlane"; }
|
||||
|
||||
|
@ -121,6 +121,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::RoutingPlane);
|
||||
|
||||
|
||||
#endif // KATANA_ROUTING_PLANE_H
|
||||
|
|
|
@ -14,14 +14,11 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_TRACK_H
|
||||
#define KATANA_TRACK_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/Point.h"
|
||||
namespace Hurricane {
|
||||
class Layer;
|
||||
}
|
||||
|
||||
#include "katana/TrackCost.h"
|
||||
#include "katana/TrackElement.h"
|
||||
|
||||
|
@ -102,6 +99,7 @@ namespace Katana {
|
|||
DbU::Unit getSourcePosition ( size_t index ) const;
|
||||
bool check ( uint32_t& overlaps, const char* message=NULL ) const;
|
||||
uint32_t checkOverlap ( uint32_t& overlaps ) const;
|
||||
void expandMinArea ();
|
||||
inline void setLocalAssigned ( bool );
|
||||
void invalidate ();
|
||||
void insert ( TrackElement* );
|
||||
|
@ -231,5 +229,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::Track);
|
||||
|
||||
#endif // KATANA_TRACK_H
|
||||
|
|
Loading…
Reference in New Issue