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:
Jean-Paul Chaput 2020-11-23 23:07:15 +01:00
parent ba43b02e87
commit 29b57e86e5
32 changed files with 581 additions and 171 deletions

View File

@ -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;

View File

@ -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)
, 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)

View File

@ -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()) )
vertical->setLayer( verticalLayer );
vertical->setWidth( verticalWidth );
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;

View File

@ -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]; }

View File

@ -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 ()

View File

@ -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) {

View File

@ -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 )
{

View File

@ -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; }

View File

@ -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& );

View File

@ -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) ); }

View File

@ -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.
) )

View File

@ -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.
) )

View File

@ -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,9 +82,11 @@ 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() )
);
}
}
@ -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 );

View File

@ -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,8 +386,9 @@ 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" );
DbU::Unit obstacleDw = get<int64_t> ( stack, "_obstacleDw" );
Constant::Direction direction;
Constant::LayerGaugeType type;
@ -400,6 +406,7 @@ namespace CRL {
, offset
, pitch
, wireWidth
, pwireWidth
, viaWidth
, obstacleDw
);

View File

@ -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; }

View File

@ -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; }
// -------------------------------------------------------------------

View File

@ -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;

View File

@ -74,14 +74,15 @@ extern "C" {
int type;
int depth;
double density;
PyObject* pyOffset = NULL;
PyObject* pyPitch = NULL;
PyObject* pyWireWidth = NULL;
PyObject* pyViaWidth = NULL;
PyObject* pyObsDw = NULL;
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 */

View File

@ -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

View File

@ -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)."""

View File

@ -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 )

View File

@ -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
index = self._routingGauge.getLayerGauge(depth).getTrackIndex( bb.getYMin()
, bb.getYMax()
, y
, RoutingLayerGauge.Nearest )
return self._routingGauge.getLayerGauge(depth).getTrackPosition( bb.getYMin(), index )
return self.getTrack( y, depth, 0 )
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
@ -273,17 +296,27 @@ class GaugeConf ( object ):
else:
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

View File

@ -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 )

View File

@ -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' )

View File

@ -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()

View File

@ -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() )

View File

@ -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)

View File

@ -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();

View File

@ -383,11 +383,11 @@ namespace {
void merge ( const Box&, Net* );
void doLayout ();
private:
const Layer* _layer;
RoutingPlane* _routingPlane;
RailsMap _horizontalRails;
RailsMap _verticalRails;
Flags _powerDirection;
const Layer* _layer;
RoutingPlane* _routingPlane;
RailsMap _horizontalRails;
RailsMap _verticalRails;
Flags _powerDirection;
};
public:
@ -404,7 +404,7 @@ namespace {
void merge ( const Box&, Net* );
void doLayout ();
private:
KatanaEngine* _katana;
KatanaEngine* _katana;
GlobalNetTable _globalNets;
PlanesMap _planes;
Plane* _activePlane;
@ -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())

View File

@ -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() + " "

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef KATANA_ROUTING_PLANE_H
#define KATANA_ROUTING_PLANE_H
#pragma once
#include "crlcore/RoutingLayerGauge.h"
#include "katana/Track.h"
@ -33,31 +31,32 @@ namespace Katana {
class RoutingPlane {
public:
static RoutingPlane* create ( KatanaEngine*, size_t depth );
void destroy ();
inline bool isHorizontal () const;
inline bool isVertical () const;
inline KatanaEngine* getKatanaEngine () const;
inline RoutingLayerGauge* getLayerGauge () const;
inline Flags getDirection () const;
inline size_t getDepth () const;
inline DbU::Unit getAxisMin () const;
inline DbU::Unit getAxisMax () const;
inline DbU::Unit getTrackMin () const;
inline DbU::Unit getTrackMax () const;
RoutingPlane* getTop () const;
RoutingPlane* getBottom () const;
inline const Layer* getLayer () const;
inline const Layer* getBlockageLayer () const;
inline size_t getTracksSize () const;
inline size_t computeTracksSize () const;
inline DbU::Unit getTrackPosition ( size_t index ) const;
Track* getTrackByIndex ( size_t index ) const;
Track* getTrackByPosition ( DbU::Unit axis, uint32_t mode=Constant::Nearest ) const;
bool _check ( uint32_t& overlaps ) const;
Record* _getRecord () const;
string _getString () const;
inline string _getTypeName () const;
static RoutingPlane* create ( KatanaEngine*, size_t depth );
void destroy ();
inline bool isHorizontal () const;
inline bool isVertical () const;
inline KatanaEngine* getKatanaEngine () const;
inline RoutingLayerGauge* getLayerGauge () const;
inline Flags getDirection () const;
inline size_t getDepth () const;
inline DbU::Unit getAxisMin () const;
inline DbU::Unit getAxisMax () const;
inline DbU::Unit getTrackMin () const;
inline DbU::Unit getTrackMax () const;
RoutingPlane* getTop () const;
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;
Track* getTrackByIndex ( size_t index ) const;
Track* getTrackByPosition ( DbU::Unit axis, uint32_t mode=Constant::Nearest ) const;
bool _check ( uint32_t& overlaps ) const;
Record* _getRecord () const;
string _getString () const;
inline string _getTypeName () const;
protected:
// Sub-Class: TrackCompare.
@ -91,18 +90,19 @@ namespace Katana {
inline bool RoutingPlane::TrackCompare::operator() ( Track* lhs, Track* rhs )
{ return lhs->getAxis() > rhs->getAxis(); };
inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; }
inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; }
inline Flags RoutingPlane::getDirection () const { return _flags & Flags::DirectionMask; }
inline size_t RoutingPlane::getDepth () const { return _depth; }
inline DbU::Unit RoutingPlane::getAxisMin () const { return _axisMin; }
inline DbU::Unit RoutingPlane::getAxisMax () const { return _axisMax; }
inline DbU::Unit RoutingPlane::getTrackMin () const { return _trackMin; }
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 size_t RoutingPlane::getTracksSize () const { return _tracks.size(); }
inline string RoutingPlane::_getTypeName () const { return "RoutingPlane"; }
inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; }
inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; }
inline Flags RoutingPlane::getDirection () const { return _flags & Flags::DirectionMask; }
inline size_t RoutingPlane::getDepth () const { return _depth; }
inline DbU::Unit RoutingPlane::getAxisMin () const { return _axisMin; }
inline DbU::Unit RoutingPlane::getAxisMax () const { return _axisMax; }
inline DbU::Unit RoutingPlane::getTrackMin () const { return _trackMin; }
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"; }
inline size_t RoutingPlane::computeTracksSize () const
{ return _layerGauge->getTrackNumber(_axisMin,_axisMax); }
@ -121,6 +121,3 @@ namespace Katana {
INSPECTOR_P_SUPPORT(Katana::RoutingPlane);
#endif // KATANA_ROUTING_PLANE_H

View File

@ -14,16 +14,13 @@
// +-----------------------------------------------------------------+
#ifndef KATANA_TRACK_H
#define KATANA_TRACK_H
#include "hurricane/Point.h"
#pragma once
#include "hurricane/Point.h"
namespace Hurricane {
class Layer;
}
#include "katana/TrackCost.h"
#include "katana/TrackElement.h"
#include "katana/TrackCost.h"
#include "katana/TrackElement.h"
namespace Katana {
@ -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