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

View File

@ -14,6 +14,7 @@
// +-----------------------------------------------------------------+
#include <cmath>
#include "hurricane/DebugSession.h"
#include "hurricane/Warning.h"
#include "hurricane/Bug.h"
@ -2000,7 +2001,7 @@ namespace Anabatic {
bool AutoSegment::reduceDoglegLayer ()
{
if (not isReduced()) return true;
if (not isReduced()) return false;
DebugSession::open( getNet(), 149, 160 );
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
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 isTargetTerminal () const;
inline bool isLayerChange () const;
inline bool isStackedStrap () const;
inline bool isSpinTop () const;
inline bool isSpinBottom () const;
inline bool isSpinTopOrBottom () const;
@ -325,6 +326,7 @@ namespace Anabatic {
bool moveUp ( Flags flags=Flags::NoFlags );
bool moveDown ( Flags flags=Flags::NoFlags );
bool reduceDoglegLayer ();
bool bloatStackedStrap ();
bool reduce ();
bool raise ();
// Canonical Modifiers.
@ -559,7 +561,6 @@ namespace Anabatic {
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
inline void AutoSegment::setLayer ( size_t depth )
{
RoutingLayerGauge* layerGauge = Session::getLayerGauge( depth );
@ -570,7 +571,6 @@ namespace Anabatic {
_flags|=SegInvalidatedLayer;
}
inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }

View File

@ -58,6 +58,7 @@ namespace Hurricane {
, _nextOfTechnologyLayerMap(NULL)
, _symbolic(false)
, _blockage(false)
, _minimalArea(0.0)
{
if ( !_technology )
throw Error ( "Can't create " + _TName("Layer") + " : null technology" );
@ -138,6 +139,10 @@ namespace Hurricane {
{ return 0; }
double Layer::getMinimalArea () const
{ return _minimalArea; }
bool Layer::contains ( const Layer* layer ) const
{
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 )
{
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 getTopEnclosure ( uint32_t flags ) const;
virtual DbU::Unit getBottomEnclosure ( uint32_t flags ) const;
virtual double getMinimalArea () const;
// Predicates
inline bool above ( 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 setExtentionCap ( const BasicLayer* layer, DbU::Unit );
virtual void setExtentionWidth ( const BasicLayer* layer, DbU::Unit );
virtual void setMinimalArea ( double );
// Hurricane Managment.
virtual void _toJson ( JsonWriter* ) const;
virtual string _getString () const;
@ -126,6 +128,7 @@ namespace Hurricane {
Layer* _nextOfTechnologyLayerMap;
bool _symbolic;
bool _blockage;
double _minimalArea;
protected:
// Internal: Constructors & Destructors.

View File

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