diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index e2305d03..4ea94084 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -92,11 +92,14 @@ namespace Anabatic { GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); if (cg == NULL) cg = AllianceFramework::get()->getCellGauge(); + if (cg == NULL) + throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." ); + if (rg == NULL) { string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); if (rg == NULL) - throw Error( "Anabatic::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); + throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); } _cg = cg->getClone(); _rg = rg->getClone(); diff --git a/crlcore/etc/symbolic/cmos/kite.conf b/crlcore/etc/symbolic/cmos/kite.conf index b8897670..b020336e 100644 --- a/crlcore/etc/symbolic/cmos/kite.conf +++ b/crlcore/etc/symbolic/cmos/kite.conf @@ -46,6 +46,7 @@ parametersTable = \ , ("katana.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("katana.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("katana.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ('chip.padCoreSide' ,TypeString ,'South' ) ) @@ -76,4 +77,5 @@ routingGaugesTable['sxlib-2M'] = \ # ( METAL_PIN, xy_common_pitch, slice_height, slice_step ) cellGaugesTable = {} -cellGaugesTable['sxlib'] = ('metal2', l(5.0), l(50.0), l(5.0)) +cellGaugesTable['sxlib'] = ('metal2', l(5.0), l( 50.0), l( 5.0)) +cellGaugesTable['pxlib'] = ('metal2', l(5.0), l(400.0), l(200.0)) diff --git a/crlcore/etc/symbolic/ispd05/analog.conf b/crlcore/etc/symbolic/ispd05/analog.conf new file mode 100644 index 00000000..4d4cf6a2 --- /dev/null +++ b/crlcore/etc/symbolic/ispd05/analog.conf @@ -0,0 +1,10 @@ +# -*- Mode:Python; explicit-buffer-name: "analog.conf" -*- + +import helpers + + +parametersTable = \ + ( ('analog.techno' , TypeString, 'Analog_technology_is_disabled', + { 'flags':Cfg.Parameter.Flags.NeedRestart|Cfg.Parameter.Flags.MustExist } ) + , ('analog.devices', TypeString, helpers.technoDir+'/devices.conf' ) + ) diff --git a/crlcore/etc/symbolic/ispd05/kite.conf b/crlcore/etc/symbolic/ispd05/kite.conf index 1844876a..359c336d 100644 --- a/crlcore/etc/symbolic/ispd05/kite.conf +++ b/crlcore/etc/symbolic/ispd05/kite.conf @@ -1,6 +1,7 @@ -# -*- Mode:Python; explicit-buffer-name: "kite.conf" -*- +# -*- Mode:Python; explicit-buffer-name: "kite.conf" -*- import helpers +from helpers import l, u, n # Contains the layout (shared by all technologies). execfile( helpers.sysConfDir+'/common/kite.conf' ) @@ -21,8 +22,31 @@ parametersTable = \ , ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + # Anabatic & Katana parameters are temporarily hosted here. + , ('anabatic.routingGauge' ,TypeString , 'sxlib' ) + , ("anabatic.globalLengthThreshold" ,TypeInt ,1450 ) + , ("anabatic.saturateRatio" ,TypePercentage,80 ) + , ("anabatic.saturateRp" ,TypeInt ,8 ) + , ('anabatic.topRoutingLayer' ,TypeString , 'METAL5') + , ("anabatic.edgeLength" ,TypeInt ,24 ) + , ("anabatic.edgeWidth" ,TypeInt ,4 ) + , ("anabatic.edgeCostH" ,TypeDouble ,19.0 ) + , ("anabatic.edgeCostK" ,TypeDouble ,-60.0 ) , ("anabatic.edgeHScaling" ,TypeDouble ,1.0 ) , ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) + , ("anabatic.gcell.displayMode" ,TypeEnumerate ,1 + , { 'values':( ("Boundary" , 1) + , ("Density" , 2) ) } + ) + , ("katana.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } ) + , ("katana.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } ) + , ("katana.eventsLimit" ,TypeInt ,4000002 ) + , ("katana.ripupCost" ,TypeInt ,3 , { 'min':0 } ) + , ("katana.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } ) + , ("katana.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) + , ("katana.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ("katana.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) + , ('chip.padCoreSide' ,TypeString ,'South' ) ) @@ -33,13 +57,13 @@ parametersTable = \ routingGaugesTable = {} routingGaugesTable['sxlib'] = \ - ( ( 'METAL1', ( Gauge.Vertical , Gauge.PinOnly, 0, 0.0, 0, 5, 2, 1, 4 ) ) - , ( 'METAL2', ( Gauge.Horizontal, Gauge.Default, 1, 7.0, 0, 5, 2, 1, 4 ) ) - , ( 'METAL3', ( Gauge.Vertical , Gauge.Default, 2, 0.0, 0, 5, 2, 1, 4 ) ) - , ( 'METAL4', ( Gauge.Horizontal, Gauge.Default, 3, 0.0, 0, 5, 2, 1, 4 ) ) - , ( 'METAL5', ( Gauge.Vertical , Gauge.Default, 4, 0.0, 0, 5, 2, 1, 4 ) ) - #, ( 'METAL6', ( Gauge.Horizontal, Gauge.Default, 5, 0.0, 0, 5, 2, 1, 4 ) ) - #, ( 'METAL7', ( Gauge.Vertical , Gauge.Default, 6, 0.0, 0, 5, 2, 1, 4 ) ) + ( ( 'METAL1', ( Gauge.Vertical , Gauge.PinOnly, 0, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) + , ( 'METAL2', ( Gauge.Horizontal, Gauge.Default, 1, 7.0, l(0), l(5), l(2), l(1), l(4) ) ) + , ( 'METAL3', ( Gauge.Vertical , Gauge.Default, 2, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) + , ( 'METAL4', ( Gauge.Horizontal, Gauge.Default, 3, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) + , ( 'METAL5', ( Gauge.Vertical , Gauge.Default, 4, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) + #, ( 'METAL6', ( Gauge.Horizontal, Gauge.Default, 5, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) + #, ( 'METAL7', ( Gauge.Vertical , Gauge.Default, 6, 0.0, l(0), l(5), l(2), l(1), l(4) ) ) ) @@ -48,5 +72,5 @@ routingGaugesTable['sxlib'] = \ # ( METAL_PIN, xy_common_pitch, slice_height, slice_step ) cellGaugesTable = {} -cellGaugesTable['ispd05'] = ('metal2', 5.0, 60.0, 5.0) +cellGaugesTable['ispd05'] = ('metal2', l(5.0), l(60.0), l(5.0)) diff --git a/crlcore/etc/symbolic/ispd05/technology.conf b/crlcore/etc/symbolic/ispd05/technology.conf index 0f81fb0b..990cad34 100644 --- a/crlcore/etc/symbolic/ispd05/technology.conf +++ b/crlcore/etc/symbolic/ispd05/technology.conf @@ -1,6 +1,7 @@ # -*- Mode:Python; explicit-buffer-name: "technology.conf" -*- import helpers +from helpers.Technology import initTechno from Hurricane import DbU # Provides standard settings for: @@ -9,168 +10,33 @@ from Hurricane import DbU # - # - + +initTechno( { 'name' : 'IPSD05/symbolic' + , 'precision' : 2 + , 'gridValue' : 0.005 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 24 + , 'symbolicGridStep' : 1.0 + , 'polygonStep' : 24.0 + } ) + + execfile( helpers.sysConfDir+'/common/technology.conf' ) -technoConfig = { 'name' : 'ISPD05/symbolic' - , 'precision' : 2 - , 'gridValue' : 0.005 - , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda' : 24 - , 'symbolicGridStep' : 1.0 - , 'polygonStep' : 24.0 - } - - # Format of : # Each entry is a pair of (string, value). # * string: a synthetic way to designate the real or symbolic layer on # which it applies, an optional sub layer (BasicLayer) in case # where there is more than one, and the dimension name. -# * value : the rule (dimension) value. If the main layer is symbolic it -# must be expressed in lambda, if it is for a real layers it -# must be expressed in microns. +# * value : the rule (dimension) value. +# Values/dimensions must be given using one of the following conversion +# function: +# * l(value) : value expressed in lambda (symbolic). +# * u(value) : value is expressed in microns. +# * n(value) : value is expressed in nanometers. -layersExtensionsTable = \ - ( ('NWELL.nWell.extention.cap' , 0.0) - , ('PWELL.pWell.extention.cap' , 0.0) - - , ('NTIE.minimum.width' , 3.0) - , ('NTIE.nWell.extention.cap' , 1.5) - , ('NTIE.nWell.extention.width' , 0.5) - , ('NTIE.nImplant.extention.cap' , 1.0) - , ('NTIE.nImplant.extention.width' , 0.5) - , ('NTIE.active.extention.cap' , 0.5) - , ('NTIE.active.extention.width' , 0.0) - - , ('PTIE.minimum.width' , 3.0) - , ('PTIE.pWell.extention.cap' , 1.5) - , ('PTIE.pWell.extention.width' , 0.5) - , ('PTIE.pImplant.extention.cap' , 1.0) - , ('PTIE.pImplant.extention.width' , 0.5) - , ('PTIE.active.extention.cap' , 0.5) - , ('PTIE.active.extention.width' , 0.0) - - , ('NDIF.minimum.width' , 3.0) - , ('NDIF.nImplant.extention.cap' , 1.0) - , ('NDIF.nImplant.extention.width' , 0.5) - , ('NDIF.active.extention.cap' , 0.5) - , ('NDIF.active.extention.width' , 0.0) - - , ('PDIF.minimum.width' , 3.0) - , ('PDIF.pImplant.extention.cap' , 1.0) - , ('PDIF.pImplant.extention.width' , 0.5) - , ('PDIF.active.extention.cap' , 0.5) - , ('PDIF.active.extention.width' , 0.0) - - , ('GATE.minimum.width' , 1.0) - , ('GATE.poly.extention.cap' , 1.5) - - , ('NTRANS.minimum.width' , 1.0) - , ('NTRANS.nImplant.extention.cap' , -1.0) - , ('NTRANS.nImplant.extention.width' , 2.5) - , ('NTRANS.active.extention.cap' , -1.5) - , ('NTRANS.active.extention.width' , 2.0) - - , ('PTRANS.minimum.width' , 1.0) - , ('PTRANS.nWell.extention.cap' , -1.0) - , ('PTRANS.nWell.extention.width' , 4.5) - , ('PTRANS.pImplant.extention.cap' , -1.0) - , ('PTRANS.pImplant.extention.width' , 4.0) - , ('PTRANS.active.extention.cap' , -1.5) - , ('PTRANS.active.extention.width' , 3.0) - - , ('POLY.minimum.width' , 1.0) - , ('POLY.poly.extention.cap' , 0.5) - , ('POLY2.minimum.width' , 1.0) - , ('POLY2.poly.extention.cap' , 0.5) - - # Routing Layers (symbolic). - , ('METAL1.minimum.width' , 1.0) - , ('METAL1.metal1.extention.cap' , 0.5) - , ('METAL2.minimum.width' , 1.0) - , ('METAL2.metal2.extention.cap' , 1.0) - , ('METAL3.minimum.width' , 1.0) - , ('METAL3.metal3.extention.cap' , 1.0) - , ('METAL4.minimum.width' , 1.0) - , ('METAL4.metal4.extention.cap' , 1.0) - , ('METAL5.minimum.width' , 2.0) - , ('METAL5.metal5.extention.cap' , 1.0) - , ('METAL6.minimum.width' , 2.0) - , ('METAL6.metal6.extention.cap' , 1.0) - , ('METAL7.minimum.width' , 2.0) - , ('METAL7.metal6.extention.cap' , 1.0) - , ('METAL8.minimum.width' , 2.0) - , ('METAL8.metal6.extention.cap' , 1.0) - - # Contacts (i.e. Active <--> Metal) (symbolic). - , ('CONT_BODY_N.minimum.side' , 1.0) - , ('CONT_BODY_N.nWell.enclosure' , 1.5) - , ('CONT_BODY_N.nImplant.enclosure' , 1.5) - , ('CONT_BODY_N.active.enclosure' , 1.0) - , ('CONT_BODY_N.metal1.enclosure' , 0.5) - - , ('CONT_BODY_P.minimum.side' , 1.0) - , ('CONT_BODY_P.pWell.enclosure' , 1.5) - , ('CONT_BODY_P.pImplant.enclosure' , 1.5) - , ('CONT_BODY_P.active.enclosure' , 1.0) - , ('CONT_BODY_P.metal1.enclosure' , 0.5) - - , ('CONT_DIF_N.minimum.side' , 1.0) - , ('CONT_DIF_N.nImplant.enclosure' , 1.0) - , ('CONT_DIF_N.active.enclosure' , 0.5) - , ('CONT_DIF_N.metal1.enclosure' , 0.5) - - , ('CONT_DIF_P.minimum.side' , 1.0) - , ('CONT_DIF_P.pImplant.enclosure' , 1.0) - , ('CONT_DIF_P.active.enclosure' , 0.5) - , ('CONT_DIF_P.metal1.enclosure' , 0.5) - - , ('CONT_POLY.minimum.width' , 1.0) - , ('CONT_POLY.poly.enclosure' , 0.5) - , ('CONT_POLY.metal1.enclosure' , 0.5) - - # VIAs (i.e. Metal <--> Metal) (symbolic). - , ('VIA12.minimum.side' , 1.0) - , ('VIA12.metal1.enclosure' , 0.5) - , ('VIA12.metal2.enclosure' , 0.5) - , ('VIA23.minimum.side' , 1.0) - , ('VIA23.metal2.enclosure' , 0.5) - , ('VIA23.metal3.enclosure' , 0.5) - , ('VIA34.minimum.side' , 1.0) - , ('VIA34.metal3.enclosure' , 0.5) - , ('VIA34.metal4.enclosure' , 0.5) - , ('VIA45.minimum.side' , 1.0) - , ('VIA45.metal4.enclosure' , 0.5) - , ('VIA45.metal5.enclosure' , 0.5) - , ('VIA56.minimum.side' , 1.0) - , ('VIA56.metal5.enclosure' , 0.5) - , ('VIA56.metal6.enclosure' , 0.5) - , ('VIA67.minimum.side' , 1.0) - , ('VIA67.metal6.enclosure' , 0.5) - , ('VIA67.metal7.enclosure' , 0.5) - , ('VIA78.minimum.side' , 1.0) - , ('VIA78.metal7.enclosure' , 0.5) - , ('VIA78.metal8.enclosure' , 0.5) - - # Blockages (symbolic). - , ('BLOCKAGE1.minimum.width' , 1.0) - , ('BLOCKAGE1.blockage1.extention.cap' , 0.5) - , ('BLOCKAGE2.minimum.width' , 2.0) - , ('BLOCKAGE2.blockage2.extention.cap' , 0.5) - , ('BLOCKAGE3.minimum.width' , 2.0) - , ('BLOCKAGE3.blockage3.extention.cap' , 0.5) - , ('BLOCKAGE4.minimum.width' , 2.0) - , ('BLOCKAGE4.blockage4.extention.cap' , 0.5) - , ('BLOCKAGE5.minimum.width' , 2.0) - , ('BLOCKAGE5.blockage5.extention.cap' , 1.0) - , ('BLOCKAGE6.minimum.width' , 2.0) - , ('BLOCKAGE6.blockage6.extention.cap' , 1.0) - , ('BLOCKAGE7.minimum.width' , 2.0) - , ('BLOCKAGE7.blockage6.extention.cap' , 1.0) - , ('BLOCKAGE8.minimum.width' , 2.0) - , ('BLOCKAGE8.blockage6.extention.cap' , 1.0) - ) +layersExtensionsTable = symbolicLayersExtensionsTable gdsLayersTable = \ diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index d7d66dd1..52c6b5f2 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -755,7 +755,38 @@ namespace CRL { } _cellGauges [ gauge->getName() ] = gauge; - _defaultCellGauge = gauge; + if (not _defaultCellGauge) _defaultCellGauge = gauge; + } + + + CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const + { + for ( const auto item : _cellGauges ) { + CellGauge* cg = item.second; + DbU::Unit hcount = width / cg->getSliceStep (); + DbU::Unit hremains = width % cg->getSliceStep (); + DbU::Unit vcount = height / cg->getSliceHeight(); + DbU::Unit vremains = height % cg->getSliceHeight(); + + if ( (hcount) and (not hremains) and (vcount == 1) and (not vremains) ) + return cg; + } + + return NULL; + } + + + CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const + { + for ( const auto item : _cellGauges ) { + CellGauge* cg = item.second; + DbU::Unit vcount = height / cg->getSliceHeight(); + DbU::Unit vremains = height % cg->getSliceHeight(); + + if ( (vcount == 1) and (not vremains) ) return cg; + } + + return NULL; } diff --git a/crlcore/src/ccore/CellGauge.cpp b/crlcore/src/ccore/CellGauge.cpp index c00e65c5..69509561 100644 --- a/crlcore/src/ccore/CellGauge.cpp +++ b/crlcore/src/ccore/CellGauge.cpp @@ -38,6 +38,7 @@ namespace CRL { , _pitch (pitch) , _sliceHeight (sliceHeight) , _sliceStep (sliceStep) + , _flags (Flags::NoFlags) { } @@ -47,6 +48,7 @@ namespace CRL { , _pitch (other._pitch) , _sliceHeight (other._sliceHeight) , _sliceStep (other._sliceStep) + , _flags (other._flags) { } @@ -100,11 +102,12 @@ namespace CRL { Record* CellGauge::_getRecord () const { Record* record = new Record ( getString(this) ); - record->add( getSlot ( "Name" , &_name ) ); - record->add( getSlot ( "PinLayerName" , &_pinLayerName ) ); - record->add( DbU::getValueSlot( "pitch" , &_pitch ) ); - record->add( DbU::getValueSlot( "sliceHeight" , &_sliceHeight ) ); - record->add( DbU::getValueSlot( "sliceStep" , &_sliceStep ) ); + record->add( getSlot ( "_name" , &_name ) ); + record->add( getSlot ( "_pinLayerName" , &_pinLayerName ) ); + record->add( DbU::getValueSlot( "_pitch" , &_pitch ) ); + record->add( DbU::getValueSlot( "_sliceHeight" , &_sliceHeight ) ); + record->add( DbU::getValueSlot( "_sliceStep" , &_sliceStep ) ); + record->add( getSlot ( "_flags" , &_flags ) ); return ( record ); } @@ -118,6 +121,7 @@ namespace CRL { jsonWrite( w, "_pitch" , _pitch ); jsonWrite( w, "_sliceHeight" , _sliceHeight ); jsonWrite( w, "_sliceStep" , _sliceStep ); + jsonWrite( w, "_flags" , _flags ); w->endObject(); } @@ -162,6 +166,7 @@ namespace CRL { DbU::Unit pitch = get( stack, "_pitch" ); DbU::Unit sliceHeight = get( stack, "_sliceHeight" ); DbU::Unit sliceStep = get( stack, "_sliceStep" ); + unsigned long flags = get( stack, "_flags" ); if (stack.issetFlags(JsonWriter::TechnoMode)) { if (af) { @@ -172,6 +177,7 @@ namespace CRL { , sliceHeight , sliceStep ); + cg->setFlags( flags ); af->addCellGauge( cg ); } } else { diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h index f17f1904..3e46ce96 100644 --- a/crlcore/src/ccore/crlcore/AllianceFramework.h +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -32,6 +32,7 @@ namespace CRL { using Hurricane::BaseObserver; using Hurricane::JsonObject; using Hurricane::JsonStack; + using Hurricane::DbU; using Hurricane::Cell; using Hurricane::Net; class RoutingGauge; @@ -98,6 +99,8 @@ namespace CRL { void saveLibrary ( AllianceLibrary* ); RoutingGauge* getRoutingGauge ( const Name& name="" ); CellGauge* getCellGauge ( const Name& name="" ); + CellGauge* matchCellGauge ( DbU::Unit width, DbU::Unit height ) const; + CellGauge* matchCellGaugeByHeight ( DbU::Unit height ) const; inline const Name getDefaultCGPinLayerName () const; // Modifiers. RoutingGauge* setRoutingGauge ( const Name& name="" ); diff --git a/crlcore/src/ccore/crlcore/CellGauge.h b/crlcore/src/ccore/crlcore/CellGauge.h index fc5ee456..dc0803b6 100644 --- a/crlcore/src/ccore/crlcore/CellGauge.h +++ b/crlcore/src/ccore/crlcore/CellGauge.h @@ -41,38 +41,40 @@ namespace CRL { // Class : "CRL::CellGauge". class CellGauge { - public: - // Constructors & Destructor. + enum Flags { NoFlags = 0, Pad = ( 1<<0) }; + public: static CellGauge* create ( const char* name , const char* pinLayerName , const DbU::Unit pitch =0 , const DbU::Unit sliceHeight =0 , const DbU::Unit sliceStep =0 ); virtual void destroy (); - // Accessors + inline bool isPad () const; inline const Name& getName () const; + inline unsigned long getFlags () const; inline const Name& getPinLayerName () const; inline const DbU::Unit getPitch () const; inline const DbU::Unit getSliceHeight () const; inline const DbU::Unit getSliceStep () const; CellGauge* getClone () const; - // Hurricane management. + inline void setFlags ( unsigned long flags ); + inline void resetFlags ( unsigned long flags ); + inline void setPitch ( DbU::Unit ); + inline void setSliceHeight ( DbU::Unit ); + inline void setSliceStep ( DbU::Unit ); void toJson ( JsonWriter* ) const; virtual string _getTypeName () const; virtual string _getString () const; virtual Record* _getRecord () const; - protected: - // Internal: Attributes. Name _name; Name _pinLayerName; DbU::Unit _pitch; DbU::Unit _sliceHeight; DbU::Unit _sliceStep; - + unsigned long _flags; protected: - // Internal: Constructors & Destructors. CellGauge ( const char* name , const char* pinLayerName , const DbU::Unit pitch @@ -91,11 +93,18 @@ namespace CRL { // Inline Functions. - inline const Name& CellGauge::getName () const { return _name; } - inline const Name& CellGauge::getPinLayerName () const { return _pinLayerName; } - inline const DbU::Unit CellGauge::getPitch () const { return _pitch; } - inline const DbU::Unit CellGauge::getSliceHeight () const { return _sliceHeight; } - inline const DbU::Unit CellGauge::getSliceStep () const { return _sliceStep; } + inline bool CellGauge::isPad () const { return _flags & Flags::Pad; } + inline const Name& CellGauge::getName () const { return _name; } + inline const Name& CellGauge::getPinLayerName () const { return _pinLayerName; } + inline const DbU::Unit CellGauge::getPitch () const { return _pitch; } + inline const DbU::Unit CellGauge::getSliceHeight () const { return _sliceHeight; } + inline const DbU::Unit CellGauge::getSliceStep () const { return _sliceStep; } + inline unsigned long CellGauge::getFlags () const { return _flags; } + inline void CellGauge::setFlags ( unsigned long flags ) { _flags |= flags; } + inline void CellGauge::resetFlags ( unsigned long flags ) { _flags &= ~flags; } + inline void CellGauge::setPitch ( DbU::Unit pitch ) { _pitch = pitch; } + inline void CellGauge::setSliceHeight ( DbU::Unit height ) { _sliceHeight = height; } + inline void CellGauge::setSliceStep ( DbU::Unit step ) { _sliceStep = step; } // ------------------------------------------------------------------- diff --git a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp index 82f039b9..214fe60f 100644 --- a/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp +++ b/crlcore/src/ccore/ispd05/Ispd05Bookshelf.cpp @@ -154,6 +154,7 @@ namespace CRL { AllianceFramework* af = AllianceFramework::get(); pitch = af->getCellGauge()->getPitch(); + size_t count = 0; UpdateSession::open (); unique_ptr circuit ( Bookshelf::Circuit::parse( benchmark @@ -172,6 +173,11 @@ namespace CRL { for ( auto net : circuit->getNets() ) { dots.dot(); Net::create ( cell, net->getName() ); + + if (++count % 1000) { + UpdateSession::close (); + UpdateSession::open (); + } } dots.finish( Dots::Reset|Dots::FirstDot ); @@ -196,6 +202,11 @@ namespace CRL { Net* masterNet = master->getNet( netName ); instance->getPlug( masterNet )->setNet( cell->getNet(netName) ); } + + if (++count % 1000) { + UpdateSession::close (); + UpdateSession::open (); + } } dots.finish( Dots::Reset|Dots::FirstDot ); diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index ea96367e..81bdc09a 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -84,6 +84,8 @@ namespace { inline Library* getLibrary ( bool create=false ); inline Cell* getCell () const; inline void setCell ( Cell* ); + inline CellGauge* getCellGauge () const; + inline void setCellGauge ( CellGauge* ); inline Net* getNet () const; inline void setNet ( Net* ); static void setCoreSite ( DbU::Unit x, DbU::Unit y ); @@ -103,17 +105,18 @@ namespace { inline int getNthCut () const; inline void incNthCut (); inline RoutingGauge* getRoutingGauge () const; - inline CellGauge* getCellGauge () const; inline void addPinSegment ( string name, Segment* ); inline void clearPinSegments (); private: - static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData ); - static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData ); - static int _siteCbk ( lefrCallbackType_e, lefiSite* , lefiUserData ); - static int _obstructionCbk ( lefrCallbackType_e, lefiObstruction*, lefiUserData ); - static int _macroCbk ( lefrCallbackType_e, lefiMacro* , lefiUserData ); - static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData ); - void _pinPostProcess (); + static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData ); + static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData ); + static int _siteCbk ( lefrCallbackType_e, lefiSite* , lefiUserData ); + static int _obstructionCbk ( lefrCallbackType_e, lefiObstruction*, lefiUserData ); + static int _macroCbk ( lefrCallbackType_e, lefiMacro* , lefiUserData ); + static int _macroSiteCbk ( lefrCallbackType_e, const lefiMacroSite* , lefiUserData ); + static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData ); + void _pinStdPostProcess (); + void _pinPadPostProcess (); private: string _file; string _libraryName; @@ -141,6 +144,7 @@ namespace { inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; } inline Cell* LefParser::getCell () const { return _cell; } inline void LefParser::setCell ( Cell* cell ) { _cell=cell; } + inline void LefParser::setCellGauge ( CellGauge* gauge ) { _cellGauge=gauge; } inline Net* LefParser::getNet () const { return _net; } inline void LefParser::setNet ( Net* net ) { _net=net; } inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); } @@ -219,6 +223,7 @@ namespace { lefrSetSiteCbk ( _siteCbk ); lefrSetObstructionCbk( _obstructionCbk ); lefrSetMacroCbk ( _macroCbk ); + lefrSetMacroSiteCbk ( _macroSiteCbk ); lefrSetPinCbk ( _pinCbk ); } @@ -341,27 +346,48 @@ namespace { int LefParser::_siteCbk ( lefrCallbackType_e c, lefiSite* site, lefiUserData ud ) { - LefParser* parser = (LefParser*)ud; + LefParser* parser = (LefParser*)ud; + AllianceFramework* af = AllianceFramework::get(); if (site->hasClass()) { string siteClass = site->siteClass(); boost::to_upper( siteClass ); - if (siteClass == "CORE") { - CellGauge* gauge = parser->getCellGauge(); + DbU::Unit lefSiteWidth = DbU::fromPhysical( site->sizeX(), DbU::Micro ); + DbU::Unit lefSiteHeight = DbU::fromPhysical( site->sizeY(), DbU::Micro ); - DbU::Unit lefSliceStep = DbU::fromPhysical( site->sizeX(), DbU::Micro ); - DbU::Unit lefSliceHeight = DbU::fromPhysical( site->sizeY(), DbU::Micro ); - DbU::Unit crlSliceStep = gauge->getSliceStep (); - DbU::Unit crlSliceHeight = gauge->getSliceHeight(); + if (siteClass == "CORE") { + CellGauge* gauge = parser->getCellGauge(); + DbU::Unit crlSliceStep = gauge->getSliceStep (); + DbU::Unit crlSliceHeight = gauge->getSliceHeight(); if (not parser->getCoreSiteX() or ((parser->getCoreSiteX() != crlSliceStep) and (parser->getCoreSiteY() != crlSliceHeight)) ) { - parser->setCoreSite( lefSliceStep, lefSliceHeight ); + parser->setCoreSite( lefSiteWidth, lefSiteHeight ); - if ( (crlSliceStep == lefSliceStep) and (crlSliceHeight == lefSliceHeight) ) + if ( (crlSliceStep == lefSiteWidth) and (crlSliceHeight == lefSiteHeight) ) cerr << " - Site \"" << site->name() << "\" of class CORE match the Coriolis Cell gauge." << endl; } + } else if (siteClass == "PAD") { + string name = string("LEF.") + site->name(); + CellGauge* cg = af->getCellGauge( name ); + + if (cg) { + if ( (cg->getSliceStep() != lefSiteWidth) or (cg->getSliceHeight() != lefSiteHeight)) { + cerr << " - Site \"" << site->name() << "\" of class PAD has mismatched redefinition OVERWRITING." << endl; + cerr << " width: " << DbU::getValueString(cg->getSliceStep ()) << " vs. " << DbU::getValueString(lefSiteWidth) + << " height: " << DbU::getValueString(cg->getSliceHeight()) << " vs. " << DbU::getValueString(lefSiteHeight) + << endl; + //cg->setPitch ( lefSiteWidth ); + cg->setSliceStep ( lefSiteWidth ); + cg->setSliceHeight( lefSiteHeight ); + } + cg->setFlags( CellGauge::Flags::Pad ); + } else { + cg = CellGauge::create( name.c_str(), "unknown", lefSiteWidth, lefSiteHeight, lefSiteWidth ); + cg->setFlags( CellGauge::Flags::Pad ); + af->addCellGauge( cg ); + } } } @@ -421,7 +447,10 @@ namespace { int LefParser::_macroCbk ( lefrCallbackType_e c, lefiMacro* macro, lefiUserData ud ) { - LefParser* parser = (LefParser*)ud; + AllianceFramework* af = AllianceFramework::get(); + LefParser* parser = (LefParser*)ud; + + parser->setCellGauge( NULL ); string cellName = macro->name(); DbU::Unit width = 0; @@ -441,17 +470,47 @@ namespace { cell->setAbutmentBox( Box( 0, 0, width, height ) ); } - parser->_pinPostProcess(); + bool isPad = false; + string gaugeName = "Unknown SITE"; + if (macro->hasSiteName()) { + gaugeName = string("LEF.") + macro->siteName(); + CellGauge* cg = af->getCellGauge( gaugeName ); + if (cg) { + isPad = cg->isPad(); + if (cg->getSliceHeight() != height) { + cerr << Warning( "LefParser::_macroCbk(): Cell height %s do not match CellGauge/SITE \"%s\" of %s." + , DbU::getValueString(height).c_str() + , getString(cg->getName()).c_str() + , DbU::getValueString(cg->getSliceHeight()).c_str() + ) << endl; + } + parser->setCellGauge( cg ); + } else { + cerr << Warning( "LefParser::_macroCbk(): No CellGauge associated to SITE \"%s\"." + , macro->siteName() ) << endl; + } + } + + if (not isPad) parser->_pinStdPostProcess(); + else parser->_pinPadPostProcess(); parser->clearPinSegments(); cerr << " - " << cellName - << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) << endl; + << " " << DbU::getValueString(width) << " " << DbU::getValueString(height) + << " " << gaugeName; + if (isPad) cerr << " (PAD)"; + cerr << endl; + parser->setCell( NULL ); return 0; } + int LefParser::_macroSiteCbk ( lefrCallbackType_e c, const lefiMacroSite* site, lefiUserData ud ) + { return 0; } + + int LefParser::_pinCbk ( lefrCallbackType_e c, lefiPin* pin, lefiUserData ud ) { LefParser* parser = (LefParser*)ud; @@ -519,6 +578,10 @@ namespace { //cerr << " | " << segment << endl; continue; } + if (geoms->itemType(igeom) == lefiGeomClassE) { + // Ignore CLASS . Deduced from segments positions. + continue; + } string geomTypeName; switch ( geoms->itemType(igeom) ) { @@ -550,13 +613,13 @@ namespace { } - void LefParser::_pinPostProcess () + void LefParser::_pinStdPostProcess () { const Layer* metal1 = _routingGauge->getLayerGauge( (size_t)0 )->getLayer(); const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); Box ab = _cell->getAbutmentBox(); - //cerr << " @ _pinPostProcess" << endl; + //cerr << " @ _pinStdPostProcess" << endl; for ( auto element : _pinSegments ) { string pinName = element.first; @@ -612,7 +675,7 @@ namespace { } if (ongrids.empty()) { - cerr << Warning( "LefParser::_pinPostProcess(): Pin \"%s\" has no terminal ongrid." + cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid." , pinName.c_str() ) << endl; for ( Segment* segment : segments ) { NetExternalComponents::setExternal( segment ); @@ -626,6 +689,112 @@ namespace { } + void LefParser::_pinPadPostProcess () + { + Box ab = getCell()->getAbutmentBox(); + bool isCornerPad = (_cellGauge) and (_cellGauge->getSliceHeight() == _cellGauge->getSliceStep()); + + for ( auto element : _pinSegments ) { + string pinName = element.first; + vector& segments = element.second; + vector ongrids; + + if (segments.empty()) continue; + + Net* net = segments[0]->getNet(); + + for ( size_t i=0 ; igetBoundingBox(); + Interval hspan = Interval( bb.getXMin(), bb.getXMax() ); + Interval vspan = Interval( bb.getYMin(), bb.getYMax() ); + Segment* capSegment = NULL; + + if (segments[i]->getLayer()->isBlockage()) continue; + + if (net->isSupply()) { + if (hspan.contains(ab.getXMin())) { + capSegment = Horizontal::create( net + , segments[i]->getLayer() + , vspan.getCenter() + , vspan.getSize() + , ab.getXMin() + , hspan.getVMax() + ); + } else if (hspan.contains(ab.getXMax())) { + capSegment = Horizontal::create( net + , segments[i]->getLayer() + , vspan.getCenter() + , vspan.getSize() + , hspan.getVMin() + , ab.getXMax() + ); + } + } + + if (not capSegment) { + vector distanceToSide; + distanceToSide.push_back( std::abs(bb.getXMin() - ab.getXMin()) ); // West. + distanceToSide.push_back( std::abs(ab.getXMax() - bb.getXMax()) ); // East. + distanceToSide.push_back( std::abs(bb.getYMin() - ab.getYMin()) ); // South. + distanceToSide.push_back( std::abs(ab.getYMax() - bb.getYMax()) ); // North. + + size_t closestSide = ((isCornerPad) ? 0 : 2); + for ( size_t i=closestSide ; i < distanceToSide.size() ; ++i ) { + if (distanceToSide[i] < distanceToSide[closestSide]) + closestSide = i; + } + + switch ( closestSide ) { + default: + case 0: // West. + capSegment = Horizontal::create( net + , segments[i]->getLayer() + , vspan.getCenter() + , vspan.getSize() + , ab.getXMin() + , hspan.getVMax() + ); + break; + case 1: // East. + capSegment = Horizontal::create( net + , segments[i]->getLayer() + , vspan.getCenter() + , vspan.getSize() + , hspan.getVMin() + , ab.getXMax() + ); + break; + case 2: // South. + capSegment = Vertical::create( net + , segments[i]->getLayer() + , hspan.getCenter() + , hspan.getSize() + , ab.getYMin() + , vspan.getVMax() + ); + break; + case 3: // North. + capSegment = Vertical::create( net + , segments[i]->getLayer() + , hspan.getCenter() + , hspan.getSize() + , vspan.getVMin() + , ab.getYMax() + ); + break; + } + } + + if (capSegment) { + NetExternalComponents::setExternal( capSegment ); + segments[i]->destroy(); + segments[i] = NULL; + } + } + } + } + + int LefParser::flushErrors () { int code = (hasErrors()) ? 1 : 0; diff --git a/crlcore/src/pyCRL/PyAllianceFramework.cpp b/crlcore/src/pyCRL/PyAllianceFramework.cpp index b15acf5c..5831f1b1 100644 --- a/crlcore/src/pyCRL/PyAllianceFramework.cpp +++ b/crlcore/src/pyCRL/PyAllianceFramework.cpp @@ -440,6 +440,39 @@ extern "C" { } + static PyObject* PyAllianceFramework_matchCellGauge ( PyAllianceFramework* self, PyObject* args ) + { + cdebug_log(30,0) << "PyAllianceFramework_matchCellGauge()" << endl; + + CellGauge* cg = NULL; + HTRY + METHOD_HEAD( "AllianceFramework.matchCellGauge()" ) + + PyObject* arg0; + PyObject* arg1; + __cs.init( "AllianceFramework.matchCellGauge" ); + if (not PyArg_ParseTuple( args + , "O&O&|O&:AllianceFramework.matchCellGauge" + , Converter, &arg0 + , Converter, &arg1 + )) { + PyErr_SetString( ConstructorError, "Invalid number of parameters for AllianceFramework.matchCellGauge()." ); + return NULL; + } + + if (__cs.getObjectIds() == ":int:int") { + cg = af->matchCellGauge( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); + } else { + PyErr_SetString( ConstructorError, "Bad parameter type for AllianceFramework.matchCelGauge()." ); + return NULL; + } + HCATCH + + if (cg == NULL) Py_RETURN_NONE; + return PyCellGauge_Link(cg); + } + + static PyObject* PyAllianceFramework_loadLibraryCells ( PyAllianceFramework* self, PyObject* args ) { cdebug_log(30,0) << "PyAllianceFramework_loadLibraryCells()" << endl; @@ -505,6 +538,8 @@ extern "C" { , "Add a new cell gauge." } , { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS , "Get a cell gauge (whithout a name, return the default)." } + , { "matchCellGauge" , (PyCFunction)PyAllianceFramework_matchCellGauge , METH_VARARGS + , "Find the first CellGauge comptible with width and height." } , { "addRoutingGauge" , (PyCFunction)PyAllianceFramework_addRoutingGauge , METH_VARARGS , "Add a new routing gauge." } , { "getRoutingGauge" , (PyCFunction)PyAllianceFramework_getRoutingGauge , METH_VARARGS diff --git a/crlcore/src/pyCRL/PyCellGauge.cpp b/crlcore/src/pyCRL/PyCellGauge.cpp index 85dfadd4..84eadbe2 100644 --- a/crlcore/src/pyCRL/PyCellGauge.cpp +++ b/crlcore/src/pyCRL/PyCellGauge.cpp @@ -56,9 +56,11 @@ extern "C" { // +=================================================================+ + DirectGetBoolAttribute(PyCellGauge_isPad ,isPad ,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getSliceHeight,getSliceHeight,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getSliceStep ,getSliceStep ,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getPitch ,getPitch ,PyCellGauge,CellGauge) + DirectGetNameAttribute(PyCellGauge_getName ,getName ,PyCellGauge,CellGauge) static PyObject* PyCellGauge_create ( PyObject*, PyObject* args ) @@ -113,9 +115,11 @@ extern "C" { PyMethodDef PyCellGauge_Methods[] = { { "create" , (PyCFunction)PyCellGauge_create , METH_VARARGS|METH_STATIC , "Create a new CellGauge." } + , { "isPad" , (PyCFunction)PyCellGauge_isPad , METH_NOARGS , "Is the gauge for the IO pads." } , { "getSliceHeight" , (PyCFunction)PyCellGauge_getSliceHeight, METH_NOARGS , "Return the slice height." } , { "getSliceStep" , (PyCFunction)PyCellGauge_getSliceStep , METH_NOARGS , "Return the slice step." } , { "getPitch" , (PyCFunction)PyCellGauge_getPitch , METH_NOARGS , "Return the smallest common pitch." } + , { "getName" , (PyCFunction)PyCellGauge_getName , METH_NOARGS , "Return the gauge name." } //, { "destroy" , (PyCFunction)PyCellGauge_destroy , METH_VARARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/etesian/src/AddFeeds.cpp b/etesian/src/AddFeeds.cpp index 0b34b057..40c91cd6 100644 --- a/etesian/src/AddFeeds.cpp +++ b/etesian/src/AddFeeds.cpp @@ -298,7 +298,6 @@ namespace { namespace Etesian { - using Hurricane::ForEachIterator; using Hurricane::DataBase; using Hurricane::UpdateSession; using Hurricane::Occurrence; @@ -312,14 +311,14 @@ namespace Etesian { Box topCellAb = getCell()->getAbutmentBox(); if (not topCellAb.isEmpty()) { - forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) { - Instance* instance = static_cast((*ioccurrence).getEntity()); + Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); Box instanceAb = masterCell->getAbutmentBox(); Transformation instanceTransf = instance->getTransformation(); - (*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); + occurrence.getPath().getTransformation().applyOn( instanceTransf ); instanceTransf.applyOn( instanceAb ); if (not topCellAb.contains(instanceAb)) continue; @@ -371,9 +370,9 @@ namespace Etesian { sliceHoles.setSpinSlice0( _yspinSlice0 ); - forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) { - Instance* instance = static_cast((*ioccurrence).getEntity()); + Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); if (CatalogExtension::isFeed(masterCell)) { @@ -384,7 +383,7 @@ namespace Etesian { Box instanceAb = masterCell->getAbutmentBox(); Transformation instanceTransf = instance->getTransformation(); - (*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); + occurrence.getPath().getTransformation().applyOn( instanceTransf ); instanceTransf.applyOn( instanceAb ); if (not topCellAb.contains(instanceAb)) { diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 9549ced1..ecd577c9 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -1575,14 +1575,14 @@ Cell::NetMap::NetMap() { } -Name Cell::NetMap::_getKey(Net* net) const +const Name& Cell::NetMap::_getKey(Net* net) const // *************************************** { return net->getName(); } -unsigned Cell::NetMap::_getHashValue(Name name) const -// ************************************************** +unsigned Cell::NetMap::_getHashValue(const Name& name) const +// ********************************************************* { unsigned long hash = 0; unsigned long sum4 = 0; diff --git a/hurricane/src/hurricane/DBo.cpp b/hurricane/src/hurricane/DBo.cpp index 7393df2d..382828a9 100644 --- a/hurricane/src/hurricane/DBo.cpp +++ b/hurricane/src/hurricane/DBo.cpp @@ -30,6 +30,7 @@ #include "hurricane/Initializer.h" +#include "hurricane/Timer.h" #include "hurricane/DBo.h" #include "hurricane/Entity.h" #include "hurricane/Property.h" @@ -44,8 +45,101 @@ namespace Hurricane { // Class : "Hurricane::DBo". - DBo::DBo (): _propertySet() - { } + unsigned int DBo::_memoryLimit = 0; + unsigned long DBo::_flags = 0; + unsigned int DBo::_nextId = 0; + unsigned int DBo::_idCounterLimit = 0; + unsigned int DBo::_idCounter = 1; + + + void DBo::setIdCounterLimit ( unsigned int limit ) + { _idCounterLimit = limit; } + + + void DBo::setMemoryLimit ( unsigned int limit ) + { _memoryLimit = limit; } + + + unsigned int DBo::getIdCounter () + { return _idCounter; } + + + bool DBo::inForcedIdMode () + { return _flags & ForcedIdMode; } + + + void DBo::enableForcedIdMode () + { + if (_flags & ForcedIdMode) return; + if (_idCounter != 1) { + throw Error( "DBo::enableForcedIdMode(): DataBase must be reset before forcind ids." ); + } + _flags |= ForcedIdMode; + } + + + void DBo::disableForcedIdMode () + { + if (not (_flags & ForcedIdMode)) return; + _flags &= ~ForcedIdMode; + } + + + void DBo::setNextId ( unsigned int nid ) + { + if (not (_flags & ForcedIdMode)) { + cerr << Error("DBo::setNextId(): Not in forced id mode, ignored.") << endl; + return; + } + _nextId = nid; + if (nid > _idCounter) _idCounter = nid; + _flags |= NextIdSet; + } + + + unsigned int DBo::getNextId () + { + if (_flags & ForcedIdMode) { + if (_flags & NextIdSet) { + _flags &= ~NextIdSet; + cdebug_log(18,0) << demangle(typeid(*this).name()) + << "::getNextId(): Consuming the preset id:" << _nextId << endl; + return _nextId; + } else { + throw Error("DBo::getNextId(): Next id is not set, while in forced id mode."); + } + } + + return ++_idCounter; + } + + + + DBo::DBo () + : _id (getNextId()) + , _propertySet() + { + if (_idCounterLimit and (_id > _idCounterLimit)) { + throw Error( "DBo::DBo(): Identifier counter has reached user's limit (%d)." + , _idCounterLimit ); + } + if (_idCounter == std::numeric_limits::max()) { + throw Error( "DBo::DBo(): Identifier counter has reached type limit (%d bits)." + , std::numeric_limits::digits ); + } + + size_t memorySize = Timer::getMemorySize(); + if (_memoryLimit and ((memorySize >> 20) > _memoryLimit)) { + throw Error( "DBo::DBo(): Program has reached maximum allowed limit of %dMb." + , _memoryLimit ); + } + + // if (_id % 10000 == 0) { + // cerr << "Reached id:" << _id << " " << Timer::getStringMemory(memorySize) << endl; + // } + // if (_id == 75060) + // cerr << "DBo::DBo() " << this << endl; + } DBo::~DBo () @@ -91,6 +185,17 @@ namespace Hurricane { } + void DBo::setId ( unsigned int id ) + { + if (_flags & ForcedIdMode) { + _id = id; + if (_id > _idCounter) _idCounter = _id; + } else { + throw Error("DBo::setId(): Attempt to set id while not in forced id mode."); + } + } + + void DBo::put ( Property* property ) { if ( !property ) @@ -181,14 +286,15 @@ namespace Hurricane { string DBo::_getString () const { - return "<" + _getTypeName() + ">"; + return ""; } Record* DBo::_getRecord () const { Record* record = new Record ( getString(this) ); - record->add ( getSlot("_propertySet", &_propertySet) ); + record->add( getSlot("_id" , _id ) ); + record->add( getSlot("_propertySet", &_propertySet) ); return record; } diff --git a/hurricane/src/hurricane/Entity.cpp b/hurricane/src/hurricane/Entity.cpp index c18e7f8f..f8c1a5d8 100644 --- a/hurricane/src/hurricane/Entity.cpp +++ b/hurricane/src/hurricane/Entity.cpp @@ -19,7 +19,6 @@ #include #include "hurricane/Error.h" -#include "hurricane/Timer.h" #include "hurricane/Entity.h" #include "hurricane/Quark.h" #include "hurricane/Cell.h" @@ -34,100 +33,9 @@ namespace Hurricane { // **************************************************************************************************** - unsigned int Entity::_memoryLimit = 0; - unsigned long Entity::_flags = 0; - unsigned int Entity::_nextId = 0; - unsigned int Entity::_idCounterLimit = 0; - unsigned int Entity::_idCounter = 1; - - - void Entity::setIdCounterLimit ( unsigned int limit ) - { _idCounterLimit = limit; } - - - void Entity::setMemoryLimit ( unsigned int limit ) - { _memoryLimit = limit; } - - - unsigned int Entity::getIdCounter () - { return _idCounter; } - - - bool Entity::inForcedIdMode () - { return _flags & ForcedIdMode; } - - - void Entity::enableForcedIdMode () - { - if (_flags & ForcedIdMode) return; - if (_idCounter != 1) { - throw Error( "Entity::enableForcedIdMode(): DataBase must be reset before forcind ids." ); - } - _flags |= ForcedIdMode; - } - - - void Entity::disableForcedIdMode () - { - if (not (_flags & ForcedIdMode)) return; - _flags &= ~ForcedIdMode; - } - - - void Entity::setNextId ( unsigned int nid ) - { - if (not (_flags & ForcedIdMode)) { - cerr << Error("Entity::setNextId(): Not in forced id mode, ignored.") << endl; - return; - } - _nextId = nid; - if (nid > _idCounter) _idCounter = nid; - _flags |= NextIdSet; - } - - - unsigned int Entity::getNextId () - { - if (_flags & ForcedIdMode) { - if (_flags & NextIdSet) { - _flags &= ~NextIdSet; - cdebug_log(18,0) << demangle(typeid(*this).name()) - << "::getNextId(): Consuming the preset id:" << _nextId << endl; - return _nextId; - } else { - throw Error("Entity::getNextId(): Next id is not set, while in forced id mode."); - } - } - - return ++_idCounter; - } - - Entity::Entity() : Inherit() - , _id (getNextId()) - { - if (_idCounterLimit and (_id > _idCounterLimit)) { - throw Error( "Entity::Entity(): Identifier counter has reached user's limit (%d)." - , _idCounterLimit ); - } - if (_idCounter == std::numeric_limits::max()) { - throw Error( "Entity::Entity(): Identifier counter has reached type limit (%d bits)." - , std::numeric_limits::digits ); - } - - size_t memorySize = Timer::getMemorySize(); - if (_memoryLimit and ((memorySize >> 20) > _memoryLimit)) { - throw Error( "Entity::Entity(): Program has reached maximum allowed limit of %dMb." - , _memoryLimit ); - } - - // if (_id % 10000 == 0) { - // cerr << "Reached id:" << _id << " " << Timer::getStringMemory(memorySize) << endl; - // } - // if (_id == 75060) - // cerr << "Entity::Entity() " << this << endl; - } + { } void Entity::_postCreate() @@ -182,17 +90,6 @@ namespace Hurricane { } - void Entity::setId ( unsigned int id ) - { - if (_flags & ForcedIdMode) { - _id = id; - if (_id > _idCounter) _idCounter = _id; - } else { - throw Error("Entity::setId(): Attempt to set id while not in forced id mode."); - } - } - - void Entity::_toJson ( JsonWriter* writer ) const { Inherit::_toJson( writer ); @@ -204,7 +101,6 @@ namespace Hurricane { string Entity::_getString() const { string s = Inherit::_getString(); - s.insert( 1, "id:"+getString(_id)+" " ); return s; } @@ -213,7 +109,6 @@ namespace Hurricane { { Record* record = Inherit::_getRecord(); if (record) { - record->add( getSlot("_id", _id) ); Occurrence occurrence = Occurrence(this); if (occurrence.hasProperty()) record->add( getSlot("Occurrence", occurrence) ); diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index 2f88d3f3..37f5cbb4 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -182,19 +182,19 @@ Instance::Instance(Cell* cell, const Name& name, Cell* masterCell, const Transfo _nextOfCellSlaveInstanceSet(NULL) { if (!_cell) - throw Error("Can't create " + _TName("Instance") + " : null cell"); + throw Error("Instance::Instance(): Can't create " + _TName("Instance") + ", NULL cell"); if (name.isEmpty()) - throw Error("Can't create " + _TName("Instance") + " : empty name"); + throw Error("Instance::Instance(): Can't create " + _TName("Instance") + ", empty name"); if (_cell->getInstance(_name)) - throw Error("Can't create " + _TName("Instance") + " " + getString(_name) + " : already exists"); + throw Error("Instance::Instance(): Can't create " + _TName("Instance") + " " + getString(_name) + ", already exists"); if (!_masterCell) - throw Error("Can't create " + _TName("Instance") + " : null master cell"); + throw Error("Instance::Instance(): Can't create " + _TName("Instance") + ", NULL master cell"); if (secureFlag && _cell->isCalledBy(_masterCell)) - throw Error("Can't create " + _TName("Instance") + " : cyclic construction"); + throw Error("Instance::Instance(): Can't create " + _TName("Instance") + ", cyclic construction"); } Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, bool secureFlag) diff --git a/hurricane/src/hurricane/Layer.cpp b/hurricane/src/hurricane/Layer.cpp index 2bb977e1..bc51373d 100644 --- a/hurricane/src/hurricane/Layer.cpp +++ b/hurricane/src/hurricane/Layer.cpp @@ -56,6 +56,7 @@ namespace Hurricane { , _minimalSpacing(minimalSpacing) , _nextOfTechnologyLayerMap(NULL) , _symbolic(false) + , _blockage(false) { if ( !_technology ) throw Error ( "Can't create " + _TName("Layer") + " : null technology" ); diff --git a/hurricane/src/hurricane/Property.cpp b/hurricane/src/hurricane/Property.cpp index f3a5d17f..a2ad9f02 100644 --- a/hurricane/src/hurricane/Property.cpp +++ b/hurricane/src/hurricane/Property.cpp @@ -226,10 +226,11 @@ namespace Hurricane { void SharedProperty::_preDestroy () { - for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { - _ownerSet[i]->_onDestroyed(this); - _ownerSet[i] = NULL; - } + for ( DBo* owner : _ownerSet ) owner->_onDestroyed( this ); + // for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { + // _ownerSet[i]->_onDestroyed(this); + // _ownerSet[i] = NULL; + // } _ownerSet.clear(); // while (!_ownerSet.empty()) { @@ -244,36 +245,24 @@ namespace Hurricane { void SharedProperty::_erase ( DBo* owner ) { - for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { - if (_ownerSet[i] == owner) { - std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] ); - _ownerSet.pop_back(); - } + auto iowner = _ownerSet.find( owner ); + if (iowner != _ownerSet.end()) { + _ownerSet.erase( iowner ); } } void SharedProperty::onCapturedBy ( DBo* owner ) { - for ( DBo* dbo : _ownerSet ) { - if (dbo == owner) return; - } - _ownerSet.push_back( owner ); - - //_ownerSet.insert(owner); + if (_ownerSet.find(owner) != _ownerSet.end()) return; + _ownerSet.insert(owner); } void SharedProperty::onReleasedBy ( DBo* owner ) { - for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { - if (_ownerSet[i] == owner) { - std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] ); - _ownerSet.pop_back(); - } - } - //_ownerSet.erase(owner); - + auto iowner = _ownerSet.find( owner ); + if (iowner != _ownerSet.end()) _ownerSet.erase( owner ); if (_ownerSet.empty()) onNotOwned(); } diff --git a/hurricane/src/hurricane/hurricane/BasicLayer.h b/hurricane/src/hurricane/hurricane/BasicLayer.h index 4e34943c..d3c475f5 100644 --- a/hurricane/src/hurricane/hurricane/BasicLayer.h +++ b/hurricane/src/hurricane/hurricane/BasicLayer.h @@ -140,7 +140,7 @@ namespace Hurricane { inline unsigned BasicLayer::getGds2Layer () const { return _gds2Layer; } inline unsigned BasicLayer::getGds2Datatype () const { return _gds2Datatype; } inline const Name& BasicLayer::getRealName () const { return _realName; } - inline void BasicLayer::setBlockageLayer ( BasicLayer* layer) { _blockageLayer = layer; } + inline void BasicLayer::setBlockageLayer ( BasicLayer* layer) { _blockageLayer = layer; layer->setBlockage(true); } inline void BasicLayer::setGds2Layer ( unsigned int number ) { _gds2Layer=number; } inline void BasicLayer::setGds2Datatype ( unsigned int number ) { _gds2Datatype=number; } inline void BasicLayer::setRealName ( const char* realName) { _realName = realName; } diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index fbad248b..7aecbe10 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -265,15 +265,15 @@ class Cell : public Entity { }; - public: class NetMap : public IntrusiveMap { - // ************************************************** + public: class NetMap : public IntrusiveMapConst { + // ********************************************************* - public: typedef IntrusiveMap Inherit; + public: typedef IntrusiveMapConst Inherit; public: NetMap(); - public: virtual Name _getKey(Net* net) const; - public: virtual unsigned _getHashValue(Name name) const; + public: virtual const Name& _getKey(Net* net) const; + public: virtual unsigned _getHashValue(const Name& name) const; public: virtual Net* _getNextElement(Net* net) const; public: virtual void _setNextElement(Net* net, Net* nextNet) const; diff --git a/hurricane/src/hurricane/hurricane/DBo.h b/hurricane/src/hurricane/hurricane/DBo.h index 0d12dd70..4a4096d4 100644 --- a/hurricane/src/hurricane/hurricane/DBo.h +++ b/hurricane/src/hurricane/hurricane/DBo.h @@ -45,43 +45,70 @@ namespace Hurricane { class DBo { public: - virtual void destroy (); - inline set& _getPropertySet (); - void _onDestroyed ( Property* property ); - Property* getProperty ( const Name& ) const; - Properties getProperties () const; - inline bool hasProperty () const; - void put ( Property* ); - void remove ( Property* ); - void removeProperty ( const Name& ); - void clearProperties (); - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - virtual void _toJson ( JsonWriter* ) const; - virtual void _toJsonCollections ( JsonWriter* ) const; - virtual void _toJsonSignature ( JsonWriter* ) const; - void toJson ( JsonWriter* ) const; - void toJsonSignature ( JsonWriter* ) const; - - private: - mutable set _propertySet; - + enum DBoFlags { ForcedIdMode = (1<<0) + , NextIdSet = (1<<1) + }; + public: + static void setMemoryLimit ( unsigned int ); + static void setIdCounterLimit ( unsigned int ); + static unsigned int getIdCounter (); + unsigned int getNextId (); + static void setNextId ( unsigned int ); + static bool inForcedIdMode (); + static void enableForcedIdMode (); + static void disableForcedIdMode (); + static void useIdCounter2 (); + public: + virtual void destroy (); + inline set& _getPropertySet (); + void _onDestroyed ( Property* property ); + inline unsigned int getId () const; + Property* getProperty ( const Name& ) const; + Properties getProperties () const; + inline bool hasProperty () const; + void setId ( unsigned int ); + void put ( Property* ); + void remove ( Property* ); + void removeProperty ( const Name& ); + void clearProperties (); + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + virtual void _toJson ( JsonWriter* ) const; + virtual void _toJsonCollections ( JsonWriter* ) const; + virtual void _toJsonSignature ( JsonWriter* ) const; + void toJson ( JsonWriter* ) const; + void toJsonSignature ( JsonWriter* ) const; protected: - DBo (); - virtual ~DBo (); - virtual void _postCreate (); - virtual void _preDestroy (); - - private: - DBo ( const DBo& ); - DBo& operator= ( const DBo& ); + DBo (); + virtual ~DBo (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + DBo ( const DBo& ); + DBo& operator= ( const DBo& ); + private: + static unsigned int _memoryLimit; + static unsigned long _flags; + static unsigned int _nextId; + static unsigned int _idCounter; + static unsigned int _idCounterLimit; + unsigned int _id; + mutable set _propertySet; + public: + struct CompareById : public std::binary_function { + inline bool operator() ( const DBo* lhs, const DBo* rhs ) const; + }; }; // Inline Functions. inline set& DBo::_getPropertySet () { return _propertySet; } inline bool DBo::hasProperty () const { return !_propertySet.empty(); } + inline unsigned int DBo::getId () const { return _id; } + + inline bool DBo::CompareById::operator() ( const DBo* lhs, const DBo* rhs ) const + { return ((lhs)?lhs->getId():0) < ((rhs)?rhs->getId():0); } // ------------------------------------------------------------------- diff --git a/hurricane/src/hurricane/hurricane/Entity.h b/hurricane/src/hurricane/hurricane/Entity.h index ae8ef382..02e206ed 100644 --- a/hurricane/src/hurricane/hurricane/Entity.h +++ b/hurricane/src/hurricane/hurricane/Entity.h @@ -39,25 +39,9 @@ namespace Hurricane { { public: typedef DBo Inherit; - public: - enum EntityFlags { ForcedIdMode = (1<<0) - , NextIdSet = (1<<1) - }; - public: - static void setMemoryLimit ( unsigned int ); - static void setIdCounterLimit ( unsigned int ); - static unsigned int getIdCounter (); - unsigned int getNextId (); - static void setNextId ( unsigned int ); - static bool inForcedIdMode (); - static void enableForcedIdMode (); - static void disableForcedIdMode (); - static void useIdCounter2 (); public: - inline unsigned int getId () const; virtual Cell* getCell () const = 0; virtual Box getBoundingBox () const = 0; - void setId ( unsigned int ); virtual void _toJson ( JsonWriter* ) const; virtual string _getString () const; virtual Record* _getRecord () const; @@ -66,26 +50,9 @@ namespace Hurricane { Entity (); virtual void _postCreate (); virtual void _preDestroy (); - private: - static unsigned int _memoryLimit; - static unsigned long _flags; - static unsigned int _nextId; - static unsigned int _idCounter; - static unsigned int _idCounterLimit; - unsigned int _id; - - public: - struct CompareById : public std::binary_function { - inline bool operator() ( const Entity* lhs, const Entity* rhs ) const; - }; }; - inline unsigned int Entity::getId () const { return _id; } - inline bool Entity::CompareById::operator() ( const Entity* lhs, const Entity* rhs ) const - { return ((lhs)?lhs->getId():0) < ((rhs)?rhs->getId():0); } - - // ------------------------------------------------------------------- // Class : "Hurricane::JsonEntity". diff --git a/hurricane/src/hurricane/hurricane/IntrusiveMap.h b/hurricane/src/hurricane/hurricane/IntrusiveMap.h index 31c84223..7ca44572 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveMap.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveMap.h @@ -507,6 +507,487 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::Intru w->endArray(); } + + + +namespace Hurricane { + +// **************************************************************************************************** +// IntrusiveMapConst declaration +// **************************************************************************************************** + +template class IntrusiveMapConst { +// ******************************************************** + +// Types +// ***** + + class Elements : public Collection { + // ***************************************** + + // Types + // ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ******************************************************** + + // Types + // ***** + + public: typedef Hurricane::Locator Inherit; + + // Attributes + // ********** + + private: const IntrusiveMapConst* _map; + private: unsigned _index; + private: Element* _element; + + // Constructors + // ************ + + public: Locator(const IntrusiveMapConst* map = NULL) + // ******************************************** + : Inherit(), + _map(map), + _index(0), + _element(NULL) + { + if (_map) { + unsigned length = _map->_getLength(); + do { + _element = _map->_getArray()[_index++]; + } while (!_element && (_index < length)); + } + }; + + public: Locator(const Locator& locator) + // ************************************ + : Inherit(), + _map(locator._map), + _index(locator._index), + _element(locator._element) + { + }; + + // Operators + // ********* + + public: Locator& operator=(const Locator& locator) + // *********************************************** + { + _map = locator._map; + _index = locator._index; + _element = locator._element; + return *this; + }; + + // Accessors + // ********* + + public: virtual Element* getElement() const + // **************************************** + { + return _element; + }; + + public: virtual Hurricane::Locator* getClone() const + // *********************************************************** + { + return new Locator(*this); + }; + + // Predicates + // ********** + + public: virtual bool isValid() const + // ********************************* + { + return (_element != NULL); + }; + + // Updators + // ******** + + public: virtual void progress() + // **************************** + { + if (_element) { + cdebug_log(0,0) << "IntrusiveMapConst::progress() from:" + << " -> " << tsetw(4) << _index + << " + " << _map->_getHashValue(_map->_getKey(_element)) + << "/" << _map->_getKey(_element) << ":" << _element << endl; + + _element = _map->_getNextElement(_element); + if (!_element) { + unsigned length = _map->_getLength(); + if (_index < length) { + do { + cdebug_log(0,0) << "next bucket: " << _index+1 << endl; + _element = _map->_getArray()[_index++]; + } while (!_element && (_index < length)); + } + + if (_element) + cdebug_log(0,0) << "IntrusiveMapConst::progress() to:" + << " -> " << tsetw(4) << _index + << " + " << _map->_getHashValue(_map->_getKey(_element)) + << "/" << _map->_getKey(_element) << ":" << _element << endl; + } + } + }; + + // Others + // ****** + + public: virtual string _getString() const + // ************************************** + { + string s = "<" + _TName("IntrusiveMapConst::Elements::Locator"); + if (_map) s += " " + getString(_map); + s += ">"; + return s; + }; + + }; + + // Attributes + // ********** + + private: const IntrusiveMapConst* _map; + + // Constructors + // ************ + + public: Elements(const IntrusiveMapConst* map = NULL) + // ********************************************* + : Inherit(), + _map(map) + { + }; + + public: Elements(const Elements& elements) + // *************************************** + : Inherit(), + _map(elements._map) + { + }; + + // Operators + // ********* + + public: Elements& operator=(const Elements& elements) + // ************************************************** + { + _map = elements._map; + return *this; + }; + + // Accessors + // ********* + + public: virtual Collection* getClone() const + // *************************************************** + { + return new Elements(*this); + }; + + public: virtual Hurricane::Locator* getLocator() const + // ************************************************************* + { + return new Locator(_map); + }; + + // Others + // ****** + + public: virtual string _getString() const + // ************************************** + { + string s = "<" + _TName("IntrusiveMapConst::Elements"); + if (_map) s += " " + getString(_map); + s += ">"; + return s; + }; + + }; + +// Attributes +// ********** + + private: unsigned _size; + private: unsigned _length; + private: Element** _array; + +// Constructors +// ************ + + public: IntrusiveMapConst() + // ******************* + : _size(0), + _length(1), + _array(new Element*[1]) + { + _array[0] = NULL; + }; + + private: IntrusiveMapConst(const IntrusiveMapConst& map); // not implemented to forbid copy + +// Destructor +// ********** + + public: virtual ~IntrusiveMapConst() + // **************************** + { + for (unsigned index = 0; index < _length; index++) { + Element* element = _array[index]; + while (element) { + _array[index] = _getNextElement(element); + _setNextElement(element, NULL); + element = _array[index]; + } + _array[index] = NULL; + } + delete[] _array; + }; + +// Operators +// ********* + + private: IntrusiveMapConst& operator=(const IntrusiveMapConst& map); // not implemented to forbid assignment + +// Accessors +// ********* + + public: Element* getElement(const Key& key) const + // ********************************************** + { + unsigned index = (_getHashValue(key) / 8) % _length; + Element* element = _array[index]; + while (element && (_getKey(element) != key)) element = _getNextElement(element); + return element; + }; + + public: Elements getElements() const + // ********************************* + { + return Elements(this); + }; + +// Predicates +// ********** + + public: bool isEmpty() const + // ************************* + { + return (_size == 0); + }; + +// Overridables +// ************ + + public: virtual const Key& _getKey(Element* element) const = 0; + + public: virtual unsigned _getHashValue(const Key& key) const = 0; + + // public: virtual Element* _getNextElement(Element* element) const = 0; // AD + public: virtual Element* _getNextElement(Element* element) const + // ************************************************************* + { + throw Error(_TName("IntrusiveMapConst") + "::_getNextElement(...) : should be overrided"); + return NULL; + }; + + // public: virtual void _setNextElement(Element* element, Element* nextElement) const = 0; // AD + public: virtual void _setNextElement(Element* element, Element* nextElement) const + // ******************************************************************************* + { + throw Error(_TName("IntrusiveMapConst") + "::_setNextElement(...) : should be overrided"); + }; + +// Others +// ****** + + public: string _getTypeName() const + // ******************************** + { + return _TName("IntrusiveMapConst"); + } + + public: string _getString() const + // ****************************** + { + if (isEmpty()) + return "<" + _getTypeName() + " empty>"; + else + return "<" + _getTypeName() + " " + getString(_size) + ">"; + }; + + public: Record* _getRecord() const + // ************************* + { + Record* record = NULL; + if (!isEmpty()) { + record = new Record(getString(this)); + unsigned n = 1; + for (unsigned index = 0; index < _length; index++) { + n = 1; + Element* element = _array[index]; + while (element) { + record->add(getSlot(getString(index) + ":" + getString(n++), element)); + element = _getNextElement(element); + } + } + } + return record; + }; + + public: unsigned _getSize() const + // ****************************** + { + return _size; + }; + + public: unsigned _getLength() const + // ******************************** + { + return _length; + }; + + public: Element** _getArray() const + // ******************************** + { + return _array; + }; + + public: bool _contains(Element* element) const + // ******************************************* + { + unsigned index = (_getHashValue(_getKey(element)) / 8) % _length; + Element* currentElement = _array[index]; + while (currentElement && (currentElement != element)) + currentElement = _getNextElement(currentElement); + return (currentElement != NULL); + }; + + public: void _insert(Element* element) + // *********************************** + { + if (!_contains(element)) { + unsigned index = (_getHashValue(_getKey(element)) / 8) % _length; + _setNextElement(element, _array[index]); + _array[index] = element; + _size++; + _resize(); + } + }; + + public: void _remove(Element* element) + // *********************************** + { + if (_contains(element)) { + unsigned index = (_getHashValue(_getKey(element)) / 8) % _length; + Element* currentElement = _array[index]; + if (currentElement) { + if (currentElement == element) { + _array[index] = _getNextElement(element); + _setNextElement(element, NULL); + _size--; + } + else { + while (_getNextElement(currentElement) && (_getNextElement(currentElement) != element)) + currentElement = _getNextElement(currentElement); + if (currentElement && (_getNextElement(currentElement) == element)) { + _setNextElement(currentElement, _getNextElement(element)); + _setNextElement(element, NULL); + _size--; + } + } + } + } + }; + + public: void _resize() + // ******************* + { + unsigned newLength = _length; + double ratio = (double)_size / (double)_length; + if (ratio < 3.0) newLength = max(_size / 8, (unsigned)1); + else if (ratio > 10.0) newLength = min(_size / 5, (unsigned)512); + + if (newLength != _length) { + cdebug_log(0,0) << "IntrusiveMapConst::_resize() " << _length << " -> " << newLength << endl; + + unsigned oldLength = _length; + Element** oldArray = _array; + _length = newLength; + _array = new Element* [_length]; + memset( _array, 0, _length * sizeof(Element*) ); + + for ( unsigned index = 0; index < oldLength; ++index ) { + Element* element = oldArray[index]; + if (not element) + cdebug_log(0,0) << "| entry:" << tsetw(4) << index << " empty" << endl; + + while ( element ) { + Element* nextElement = _getNextElement(element); + unsigned newIndex = (_getHashValue(_getKey(element)) / 8) % _length; + _setNextElement(element, _array[newIndex]); + _array[ newIndex ] = element; + + cdebug_log(0,0) << "| entry:" << tsetw(4) << index + << " -> " << tsetw(4) << newIndex + << " + " << _getHashValue(_getKey(element)) + << "/" << _getKey(element) << ":" << element << endl; + + element = nextElement; + } + } + delete [] oldArray; + } + }; + +}; + + + template + inline GenericCollection getCollection(const IntrusiveMapConst& intrusiveMap) + // ******************************************************************************************** + { + return intrusiveMap.getElements(); + } + + +} // End of Hurricane namespace. + + +template +inline std::string getString ( Hurricane::IntrusiveMapConst* intrusiveMap ) + { return intrusiveMap->_getString(); } + +template +inline std::string getString ( const Hurricane::IntrusiveMapConst* intrusiveMap ) + { return intrusiveMap->_getString(); } + +template +inline Hurricane::Record* getRecord ( Hurricane::IntrusiveMapConst* intrusiveMap ) + { return intrusiveMap->_getRecord(); } + +template +inline Hurricane::Record* getRecord ( const Hurricane::IntrusiveMapConst* intrusiveMap ) + { return intrusiveMap->_getRecord(); } + + +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::IntrusiveMapConst* intrusiveMap ) +{ + w->key( key ); + w->startArray(); + for ( Element* element : intrusiveMap->getElements() ) jsonWrite( w, element ); + w->endArray(); +} #endif // HURRICANE_INTRUSIVE_MAP diff --git a/hurricane/src/hurricane/hurricane/Layer.h b/hurricane/src/hurricane/hurricane/Layer.h index ab3358e5..bbc873af 100644 --- a/hurricane/src/hurricane/hurricane/Layer.h +++ b/hurricane/src/hurricane/hurricane/Layer.h @@ -93,9 +93,11 @@ namespace Hurricane { bool contains ( const Layer* layer ) const; bool intersect ( const Layer* layer ) const; inline bool isSymbolic () const; + inline bool isBlockage () const; // Updators void setName ( const Name& name ); inline void setSymbolic ( bool ); + inline void setBlockage ( bool ); void setMinimalSize ( const DbU::Unit& minimalSize ); void setMinimalSpacing ( const DbU::Unit& minimalSpacing ); virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags ); @@ -122,6 +124,7 @@ namespace Hurricane { DbU::Unit _minimalSpacing; Layer* _nextOfTechnologyLayerMap; bool _symbolic; + bool _blockage; protected: // Internal: Constructors & Destructors. @@ -143,6 +146,7 @@ namespace Hurricane { // Inline Functions. inline bool Layer::isSymbolic () const { return _symbolic; } + inline bool Layer::isBlockage () const { return _blockage; } inline bool Layer::above ( const Layer* layer ) const { return _mask > layer->getMask(); } inline bool Layer::below ( const Layer* layer ) const { return _mask < layer->getMask(); } inline Technology* Layer::getTechnology () const { return _technology; } @@ -152,6 +156,7 @@ namespace Hurricane { inline const DbU::Unit& Layer::getMinimalSize () const { return _minimalSize; } inline const DbU::Unit& Layer::getMinimalSpacing () const { return _minimalSpacing; } inline void Layer::setSymbolic ( bool state ) { _symbolic = state; } + inline void Layer::setBlockage ( bool state ) { _blockage = state; } inline Layer* Layer::_getNextOfTechnologyLayerMap () const { return _nextOfTechnologyLayerMap; } inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; } inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; } diff --git a/hurricane/src/hurricane/hurricane/Property.h b/hurricane/src/hurricane/hurricane/Property.h index 3672db72..51fa4861 100644 --- a/hurricane/src/hurricane/hurricane/Property.h +++ b/hurricane/src/hurricane/hurricane/Property.h @@ -396,8 +396,8 @@ namespace Hurricane { unsigned int _count; }; public: - typedef vector DBoSet; - typedef map OrphanedMap; + typedef set DBoSet; + typedef map OrphanedMap; public: static const OrphanedMap& getOrphaneds (); static SharedProperty* getOrphaned ( const string& ); diff --git a/hurricane/src/isobar/PyInstance.cpp b/hurricane/src/isobar/PyInstance.cpp index c552a6d5..84016b1e 100644 --- a/hurricane/src/isobar/PyInstance.cpp +++ b/hurricane/src/isobar/PyInstance.cpp @@ -51,7 +51,7 @@ extern "C" { #if defined(__PYTHON_MODULE__) - static Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* object ) + extern Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* object ) { switch ( PyAny_AsLong(object) ) { case Instance::PlacementStatus::UNPLACED : return ( Instance::PlacementStatus(Instance::PlacementStatus::UNPLACED) ); @@ -80,35 +80,37 @@ extern "C" { PyObject* arg1 = NULL; PyObject* arg2 = NULL; PyObject* arg3 = NULL; + PyObject* arg4 = NULL; HTRY - __cs.init( "Instance.create" ); - if (not PyArg_ParseTuple(args,"O&O&O&|O&:Instance.create" - ,Converter,&arg0 - ,Converter,&arg1 - ,Converter,&arg2 - ,Converter,&arg3 - )) { - PyErr_SetString( ConstructorError, "Instance.create(): Invalid number of parameters." ); + __cs.init( "Instance.create" ); + if (not PyArg_ParseTuple(args,"O&O&O&|O&O&:Instance.create" + ,Converter,&arg0 + ,Converter,&arg1 + ,Converter,&arg2 + ,Converter,&arg3 + ,Converter,&arg4 + )) { + PyErr_SetString( ConstructorError, "Instance.create(): Invalid number of parameters." ); + return NULL; + } + + if (__cs.getObjectIds() == ":ent:string:ent") { + instance = Instance::create( PYCELL_O(arg0) + , Name(PyString_AsString(arg1)) + , PYCELL_O(arg2) + ); + } else if (__cs.getObjectIds() == ":ent:string:ent:transfo:int") { + instance = Instance::create( PYCELL_O(arg0) + , Name(PyString_AsString(arg1)) + , PYCELL_O(arg2) + , *PYTRANSFORMATION_O(arg3) + , PyInt_AsPlacementStatus(arg4) + ); + } else { + PyErr_SetString( ConstructorError, "Instance.create(): Bad type of parameter(s)." ); return NULL; - } - - if (__cs.getObjectIds() == ":ent:string:ent") { - instance = Instance::create( PYCELL_O(arg0) - , Name(PyString_AsString(arg1)) - , PYCELL_O(arg2) - ); - } else if (__cs.getObjectIds() == ":ent:string:ent:transfo") { - instance = Instance::create( PYCELL_O(arg0) - , Name(PyString_AsString(arg1)) - , PYCELL_O(arg2) - , *PYTRANSFORMATION_O(arg3) - , Instance::PlacementStatus::PLACED - ); - } else { - PyErr_SetString( ConstructorError, "Instance.create(): Bad type of parameter(s)." ); - return NULL; - } + } HCATCH return PyInstance_Link( instance ); diff --git a/hurricane/src/isobar/PyLayer.cpp b/hurricane/src/isobar/PyLayer.cpp index c264b837..7d34d57d 100644 --- a/hurricane/src/isobar/PyLayer.cpp +++ b/hurricane/src/isobar/PyLayer.cpp @@ -313,6 +313,7 @@ extern "C" { predicateFromLayer ( contains ,PyLayer,Layer) predicateFromLayer ( intersect ,PyLayer,Layer) predicateFromVoid ( isSymbolic ,PyLayer,Layer) + predicateFromVoid ( isBlockage ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer) accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer) @@ -335,6 +336,7 @@ extern "C" { updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer) DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer) + DirectSetBoolAttribute (PyLayer_setBlockage,setBlockage,PyLayer,Layer) // Standart destroy (Attribute). DBoDestroyAttribute(PyLayer_destroy, PyLayer) @@ -387,10 +389,14 @@ extern "C" { , "Tells if the layer share some BasicLayer with the one passed as argument." } , { "isSymbolic" , (PyCFunction)PyLayer_isSymbolic , METH_NOARGS , "Tells if the layer is the symbolic one for this BasicLayer." } + , { "isBlockage" , (PyCFunction)PyLayer_isBlockage , METH_NOARGS + , "Tells if the layer represent blockage." } , { "setName" , (PyCFunction)PyLayer_setName , METH_VARARGS , "Allows to change the layer name." } , { "setSymbolic" , (PyCFunction)PyLayer_setSymbolic , METH_VARARGS , "Sets the layer as the symbolic one." } + , { "setBlockage" , (PyCFunction)PyLayer_setBlockage , METH_VARARGS + , "Sets the layer as blockage." } , { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS , "Sets the layer minimal size (width)." } , { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS diff --git a/hurricane/src/isobar/PyPlacementStatus.cpp b/hurricane/src/isobar/PyPlacementStatus.cpp index 4239936f..b7c57e1d 100644 --- a/hurricane/src/isobar/PyPlacementStatus.cpp +++ b/hurricane/src/isobar/PyPlacementStatus.cpp @@ -101,6 +101,17 @@ extern "C" { LoadObjectConstant(PyTypePlacementStatus.tp_dict,Instance::PlacementStatus::PLACED ,"PLACED"); LoadObjectConstant(PyTypePlacementStatus.tp_dict,Instance::PlacementStatus::FIXED ,"FIXED"); } + + + extern Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* object ) { + switch ( PyAny_AsLong(object) ) { + case Instance::PlacementStatus::UNPLACED : return Instance::PlacementStatus::UNPLACED; + case Instance::PlacementStatus::PLACED : return Instance::PlacementStatus::PLACED; + case Instance::PlacementStatus::FIXED : return Instance::PlacementStatus::FIXED; + } + + return Instance::PlacementStatus::UNPLACED; + } #endif // Shared Library Code Part. diff --git a/hurricane/src/isobar/hurricane/isobar/PyPlacementStatus.h b/hurricane/src/isobar/hurricane/isobar/PyPlacementStatus.h index 9d16fbc0..a0d89996 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyPlacementStatus.h +++ b/hurricane/src/isobar/hurricane/isobar/PyPlacementStatus.h @@ -37,12 +37,13 @@ namespace Isobar { // ------------------------------------------------------------------- // Functions & Types exported to "PyHurricane.ccp". - extern PyTypeObject PyTypePlacementStatus; - extern PyMethodDef PyPlacementStatus_Methods[]; + extern PyTypeObject PyTypePlacementStatus; + extern PyMethodDef PyPlacementStatus_Methods[]; - extern PyObject* PyPlacementStatus_Link ( Hurricane::Instance::PlacementStatus* ); - extern void PyPlacementStatus_LinkPyType (); - extern void PyPlacementStatus_postModuleInit (); + extern PyObject* PyPlacementStatus_Link ( Hurricane::Instance::PlacementStatus* ); + extern void PyPlacementStatus_LinkPyType (); + extern void PyPlacementStatus_postModuleInit (); + extern Hurricane::Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* ); #define IsPyPlacementStatus(v) ( (v)->ob_type == &PyTypePlacementStatus ) diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index 70f4533e..9383a3a5 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -16,6 +16,7 @@ try: import Katabatic import Kite import Bora + import Tutorial import Unicorn except ImportError, e: serror = str(e) @@ -190,6 +191,7 @@ if __name__ == '__main__': unicorn.registerTool (Kite.GraphicKiteEngine.grab()) unicorn.registerTool (Katana.GraphicKatanaEngine.grab()) unicorn.registerTool (Bora.GraphicBoraEngine.grab()) + unicorn.registerTool (Tutorial.GraphicTutorialEngine.grab()) #unicorn.setAnonNetSelectable(False) unicorn.setLayerVisible ("grid" , False); unicorn.setLayerVisible ("text.instance" , False);