Manage minimum area for VIAs in the P&R.

* New: In Hurricane::Layer, add support for a minimal area (given in
    microns). Exported in the Python interface.
* New: In Anabatic::AutoSegment::bloatStackedStrap(), method to
    enlarge too small vertically stacked VIAs. For now just create
    a square ensuring the minimal area. Potentially cause DRC error in
    some cases so needs to be refined.
* New: In Anabatic::_gutAnabatic(), check for too little stacked VIAs
    and display a report.
This commit is contained in:
Jean-Paul Chaput 2020-11-16 00:55:49 +01:00
parent b91fbbbda2
commit f5ee37d2e6
6 changed files with 49 additions and 10 deletions

View File

@ -408,17 +408,20 @@ namespace Anabatic {
size_t fixedSegments = 0; size_t fixedSegments = 0;
size_t sameLayerDoglegs = 0; size_t sameLayerDoglegs = 0;
size_t bloatedStraps = 0;
for ( auto isegment : _autoSegmentLut ) { for ( auto isegment : _autoSegmentLut ) {
if (isegment.second->isFixed()) ++fixedSegments; if (isegment.second->isFixed()) ++fixedSegments;
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs; if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
} }
cmess1 << " o Driving Hurricane data-base." << endl; cmess1 << " o Driving Hurricane data-base." << endl;
cmess1 << Dots::asSizet(" - Active AutoSegments",AutoSegment::getAllocateds()-fixedSegments) << endl; cmess1 << Dots::asSizet(" - Active AutoSegments" ,AutoSegment::getAllocateds()-fixedSegments) << endl;
cmess1 << Dots::asSizet(" - Active AutoContacts",AutoContact::getAllocateds()-fixedSegments*2) << endl; cmess1 << Dots::asSizet(" - Active AutoContacts" ,AutoContact::getAllocateds()-fixedSegments*2) << endl;
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl; cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl; cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl; cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
cmess1 << Dots::asSizet(" - Bloated straps (< minArea)",bloatedStraps ) << endl;
//for ( Net* net : _cell->getNets() ) _saveNet( net ); //for ( Net* net : _cell->getNets() ) _saveNet( net );

View File

@ -14,6 +14,7 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include <cmath>
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
@ -2000,7 +2001,7 @@ namespace Anabatic {
bool AutoSegment::reduceDoglegLayer () bool AutoSegment::reduceDoglegLayer ()
{ {
if (not isReduced()) return true; if (not isReduced()) return false;
DebugSession::open( getNet(), 149, 160 ); DebugSession::open( getNet(), 149, 160 );
cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl; cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl;
@ -2085,6 +2086,23 @@ 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;
double minArea = getLayer()->getMinimalArea();
if (minArea == 0.0) return false;
DbU::Unit side = DbU::fromPhysical( std::sqrt(minArea) , DbU::UnitPower::Micro );
setWidth( side );
setDuSource( -side/2 );
setDuTarget( side/2 );
return true;
}
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags ) bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags )
{ {

View File

@ -205,6 +205,7 @@ namespace Anabatic {
inline bool isSourceTerminal () const; inline bool isSourceTerminal () const;
inline bool isTargetTerminal () const; inline bool isTargetTerminal () const;
inline bool isLayerChange () const; inline bool isLayerChange () const;
inline bool isStackedStrap () const;
inline bool isSpinTop () const; inline bool isSpinTop () const;
inline bool isSpinBottom () const; inline bool isSpinBottom () const;
inline bool isSpinTopOrBottom () const; inline bool isSpinTopOrBottom () const;
@ -325,6 +326,7 @@ namespace Anabatic {
bool moveUp ( Flags flags=Flags::NoFlags ); bool moveUp ( Flags flags=Flags::NoFlags );
bool moveDown ( Flags flags=Flags::NoFlags ); bool moveDown ( Flags flags=Flags::NoFlags );
bool reduceDoglegLayer (); bool reduceDoglegLayer ();
bool bloatStackedStrap ();
bool reduce (); bool reduce ();
bool raise (); bool raise ();
// Canonical Modifiers. // Canonical Modifiers.
@ -559,7 +561,6 @@ namespace Anabatic {
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } //inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
inline void AutoSegment::setLayer ( size_t depth ) inline void AutoSegment::setLayer ( size_t depth )
{ {
RoutingLayerGauge* layerGauge = Session::getLayerGauge( depth ); RoutingLayerGauge* layerGauge = Session::getLayerGauge( depth );
@ -570,7 +571,6 @@ namespace Anabatic {
_flags|=SegInvalidatedLayer; _flags|=SegInvalidatedLayer;
} }
inline DbU::Unit AutoSegment::getContactWidth () const inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } { return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }

View File

@ -58,6 +58,7 @@ namespace Hurricane {
, _nextOfTechnologyLayerMap(NULL) , _nextOfTechnologyLayerMap(NULL)
, _symbolic(false) , _symbolic(false)
, _blockage(false) , _blockage(false)
, _minimalArea(0.0)
{ {
if ( !_technology ) if ( !_technology )
throw Error ( "Can't create " + _TName("Layer") + " : null technology" ); throw Error ( "Can't create " + _TName("Layer") + " : null technology" );
@ -138,6 +139,10 @@ namespace Hurricane {
{ return 0; } { return 0; }
double Layer::getMinimalArea () const
{ return _minimalArea; }
bool Layer::contains ( const Layer* layer ) const bool Layer::contains ( const Layer* layer ) const
{ {
return ( layer && ((_mask & layer->getMask()) == layer->getMask()) ); return ( layer && ((_mask & layer->getMask()) == layer->getMask()) );
@ -184,6 +189,10 @@ namespace Hurricane {
} }
void Layer::setMinimalArea ( double area )
{ _minimalArea = area; }
void Layer::setEnclosure ( const BasicLayer*, DbU::Unit, uint32_t ) void Layer::setEnclosure ( const BasicLayer*, DbU::Unit, uint32_t )
{ {
cerr << "[WARNING] Layer::setEnclosure() musn't be called on " cerr << "[WARNING] Layer::setEnclosure() musn't be called on "

View File

@ -88,6 +88,7 @@ namespace Hurricane {
virtual DbU::Unit getExtentionWidth ( const BasicLayer* layer ) const; virtual DbU::Unit getExtentionWidth ( const BasicLayer* layer ) const;
virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const; virtual DbU::Unit getTopEnclosure ( uint32_t flags ) const;
virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const; virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const;
virtual double getMinimalArea () const;
// Predicates // Predicates
inline bool above ( const Layer* layer ) const; inline bool above ( const Layer* layer ) const;
inline bool below ( const Layer* layer ) const; inline bool below ( const Layer* layer ) const;
@ -104,6 +105,7 @@ namespace Hurricane {
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags ); virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags );
virtual void setExtentionCap ( const BasicLayer* layer, DbU::Unit ); virtual void setExtentionCap ( const BasicLayer* layer, DbU::Unit );
virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit ); virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit );
virtual void setMinimalArea ( double );
// Hurricane Managment. // Hurricane Managment.
virtual void _toJson ( JsonWriter* ) const; virtual void _toJson ( JsonWriter* ) const;
virtual string _getString () const; virtual string _getString () const;
@ -126,6 +128,7 @@ namespace Hurricane {
Layer* _nextOfTechnologyLayerMap; Layer* _nextOfTechnologyLayerMap;
bool _symbolic; bool _symbolic;
bool _blockage; bool _blockage;
double _minimalArea;
protected: protected:
// Internal: Constructors & Destructors. // Internal: Constructors & Destructors.

View File

@ -374,14 +374,16 @@ extern "C" {
accessorDbuFromUInt ( getBottomEnclosure,PyLayer,Layer) accessorDbuFromUInt ( getBottomEnclosure,PyLayer,Layer)
DirectGetLongAttribute (PyLayer_getMinimalSize ,getMinimalSize ,PyLayer,Layer) DirectGetLongAttribute (PyLayer_getMinimalSize ,getMinimalSize ,PyLayer,Layer)
DirectGetLongAttribute (PyLayer_getMinimalSpacing,getMinimalSpacing ,PyLayer,Layer) DirectGetLongAttribute (PyLayer_getMinimalSpacing,getMinimalSpacing ,PyLayer,Layer)
DirectGetDoubleAttribute (PyLayer_getMinimalArea ,getMinimalArea ,PyLayer,Layer)
SetNameMethod(Layer, layer) SetNameMethod(Layer, layer)
updatorFromDbu (setMinimalSize ,PyLayer,Layer) updatorFromDbu (setMinimalSize ,PyLayer,Layer)
updatorFromDbu (setMinimalSpacing,PyLayer,Layer) updatorFromDbu (setMinimalSpacing,PyLayer,Layer)
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer) DirectSetBoolAttribute (PyLayer_setSymbolic ,setSymbolic ,PyLayer,Layer)
DirectSetBoolAttribute (PyLayer_setBlockage,setBlockage,PyLayer,Layer) DirectSetBoolAttribute (PyLayer_setBlockage ,setBlockage ,PyLayer,Layer)
DirectSetDoubleAttribute(PyLayer_setMinimalArea,setMinimalArea,PyLayer,Layer)
// Standart destroy (Attribute). // Standart destroy (Attribute).
DBoDestroyAttribute(PyLayer_destroy, PyLayer) DBoDestroyAttribute(PyLayer_destroy, PyLayer)
@ -398,6 +400,8 @@ extern "C" {
, "Returns the extract mask of the layer (for GDSII)." } , "Returns the extract mask of the layer (for GDSII)." }
, { "getMinimalSize" , (PyCFunction)PyLayer_getMinimalSize , METH_NOARGS , { "getMinimalSize" , (PyCFunction)PyLayer_getMinimalSize , METH_NOARGS
, "Returns the minimum width allowed for the layer." } , "Returns the minimum width allowed for the layer." }
, { "getMinimalArea" , (PyCFunction)PyLayer_getMinimalArea , METH_NOARGS
, "Returns the minimum area allowed for the layer." }
, { "getMinimalSpacing" , (PyCFunction)PyLayer_getMinimalSpacing , METH_NOARGS , { "getMinimalSpacing" , (PyCFunction)PyLayer_getMinimalSpacing , METH_NOARGS
, "Returns the spacing allowed for the layer (edge to edge)." } , "Returns the spacing allowed for the layer (edge to edge)." }
, { "getBasicLayers" , (PyCFunction)PyLayer_getBasicLayers , METH_NOARGS , { "getBasicLayers" , (PyCFunction)PyLayer_getBasicLayers , METH_NOARGS
@ -458,6 +462,8 @@ extern "C" {
, "Sets the extention cap for the given BasiLayer sub-component." } , "Sets the extention cap for the given BasiLayer sub-component." }
, { "setExtentionWidth" , (PyCFunction)PyLayer_setExtentionWidth , METH_VARARGS , { "setExtentionWidth" , (PyCFunction)PyLayer_setExtentionWidth , METH_VARARGS
, "Sets the extention width for the given BasiLayer sub-component." } , "Sets the extention width for the given BasiLayer sub-component." }
, { "setMinimalArea" , (PyCFunction)PyLayer_setMinimalArea , METH_VARARGS
, "Sets the minimum area allowed for the layer." }
, { "destroy" , (PyCFunction)PyLayer_destroy , METH_NOARGS , { "destroy" , (PyCFunction)PyLayer_destroy , METH_NOARGS
, "Destroy associated hurricane object The python object remains." } , "Destroy associated hurricane object The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */