ISPD05 loading speed issues. IO PAD support for LEF importation.
* New: In Hurricane::IntrusiveMap, introduce IntrusiveMapConst which allow to search with a "const Key&" instead of a "Key", sparing the copy construction of the Key. * Change: In Hurricane::Cell::NetMap, use the new kind of map with "const Name&" key access. This speeds up the Cell::getNet() method by suppressing one copy construction of a Name, which are costly after all... Should review the whole code to use "const Name&" everywhere it is possible. * Change: In Hurricane::Entity & Hurricane::DBo, displace the unique identifier from Entity to DBo (move up to the base class).This to allow us to build deterministic map of DBo requireds in UpdateSession (which is built upon a SharedProperty). WARNING: This break the JSON database exportation support, do not use it until fixed/rewritten. * Change: In Hurricane::Layer, add an attribute to know if a layer is associated to a blockage. Modificate accordingly PyLayer and BasicLayer. * Change: In Hurricane::SharedProperty, the set of owners (DBo*) is now stored in a std::set sorted on the objects Ids, instead of a simple vector. The linera search time through the std::vector was starting to show (ISPD05 bigblue1). * Bug: In Isobar::PyInstance, make full contructor signature (5 arguments) conform to the C++ one. It was only accepting the four first and forcing the placement status to be FIXED. * Bug: In CRL/etc/symbolic/ispd05/kite.conf, update for the new configuration requirements where all distance must be converted into DbU in the file itself (use "helpers.l()", "helpers.m()"). Apply to the cell & routing gauges. * Bug: In CRL/etc/symbolic/ispd05/technology.conf, update for the new configuration. "helpers.initTechno()" *must* by called first thing in this file in order for the Technology to be created. * New: In CRL::AllianceFramework, add matchCellGauge() & matchCellgaugeByHeight() * New: In CRL::CellGauge, add a flag to distinguish gauges meant for IO Pads and an "isPad()" predicate. * Change: In CRL::Ispd05Bookshelf, flush the UpdateSession stack every 1000 elements additions. Maybe not necessary now the the UpdateSession property relies on a std::set instead of a std::vector. * New: In CRL::LefImport, support for SITE and match/create the appropriate CellGauge on the fly. Specific support for MACROS that are flagged PAD. Add a dedicated post-treatment for PAD connectors, extend them toward the boundary of the nearest abutment box side. Tested only on AMS 350nm c35b4 for now. This part is most likely to be tweaked for every kind of real foundry pad that we may encounter... * Change: In EtesianEngine::findYSpin(), use the C++ "for" construct to loop over Collections. * Change: In Unicorn/cgt.py, register the Python/C++ tutorial support by default.
This commit is contained in:
parent
bbcf14eb5a
commit
f6c840fd59
|
@ -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();
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# -*- Mode:Python; explicit-buffer-name: "analog.conf<cmos>" -*-
|
||||
|
||||
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' )
|
||||
)
|
|
@ -1,6 +1,7 @@
|
|||
# -*- Mode:Python; explicit-buffer-name: "kite.conf<cmos>" -*-
|
||||
# -*- Mode:Python; explicit-buffer-name: "kite.conf<ispd05>" -*-
|
||||
|
||||
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))
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- Mode:Python; explicit-buffer-name: "technology.conf<ispd05>" -*-
|
||||
|
||||
import helpers
|
||||
from helpers.Technology import initTechno
|
||||
from Hurricane import DbU
|
||||
|
||||
# Provides standard settings for:
|
||||
|
@ -9,168 +10,33 @@ from Hurricane import DbU
|
|||
# - <compositeLayersTable>
|
||||
# - <symbolicLayersTable>
|
||||
|
||||
|
||||
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 <layersExtensionsTable>:
|
||||
# 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 = \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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<int64_t>( stack, "_pitch" );
|
||||
DbU::Unit sliceHeight = get<int64_t>( stack, "_sliceHeight" );
|
||||
DbU::Unit sliceStep = get<int64_t>( stack, "_sliceStep" );
|
||||
unsigned long flags = get<int64_t>( stack, "_flags" );
|
||||
|
||||
if (stack.issetFlags(JsonWriter::TechnoMode)) {
|
||||
if (af) {
|
||||
|
@ -172,6 +177,7 @@ namespace CRL {
|
|||
, sliceHeight
|
||||
, sliceStep
|
||||
);
|
||||
cg->setFlags( flags );
|
||||
af->addCellGauge( cg );
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -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="" );
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -154,6 +154,7 @@ namespace CRL {
|
|||
AllianceFramework* af = AllianceFramework::get();
|
||||
pitch = af->getCellGauge()->getPitch();
|
||||
|
||||
size_t count = 0;
|
||||
UpdateSession::open ();
|
||||
|
||||
unique_ptr<Bookshelf::Circuit> 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 );
|
||||
|
||||
|
|
|
@ -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 <site>. 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<Segment*>& segments = element.second;
|
||||
vector<Segment*> ongrids;
|
||||
|
||||
if (segments.empty()) continue;
|
||||
|
||||
Net* net = segments[0]->getNet();
|
||||
|
||||
for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
||||
Box bb = segments[i]->getBoundingBox();
|
||||
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<DbU::Unit> 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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<Instance*>((*ioccurrence).getEntity());
|
||||
Instance* instance = static_cast<Instance*>(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<Instance*>((*ioccurrence).getEntity());
|
||||
Instance* instance = static_cast<Instance*>(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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<unsigned int>::max()) {
|
||||
throw Error( "DBo::DBo(): Identifier counter has reached type limit (%d bits)."
|
||||
, std::numeric_limits<unsigned int>::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 "<id:" + getString(_id) + " " + _getTypeName() + ">";
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <limits>
|
||||
#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<unsigned int>::max()) {
|
||||
throw Error( "Entity::Entity(): Identifier counter has reached type limit (%d bits)."
|
||||
, std::numeric_limits<unsigned int>::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) );
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -265,15 +265,15 @@ class Cell : public Entity {
|
|||
|
||||
};
|
||||
|
||||
public: class NetMap : public IntrusiveMap<Name, Net> {
|
||||
// **************************************************
|
||||
public: class NetMap : public IntrusiveMapConst<Name, Net> {
|
||||
// *********************************************************
|
||||
|
||||
public: typedef IntrusiveMap<Name, Net> Inherit;
|
||||
public: typedef IntrusiveMapConst<Name, Net> 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;
|
||||
|
||||
|
|
|
@ -45,43 +45,70 @@ namespace Hurricane {
|
|||
|
||||
class DBo {
|
||||
public:
|
||||
virtual void destroy ();
|
||||
inline set<Property*>& _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<Property*> _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<Property*>& _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<Property*> _propertySet;
|
||||
public:
|
||||
struct CompareById : public std::binary_function<const DBo*,const DBo*,bool> {
|
||||
inline bool operator() ( const DBo* lhs, const DBo* rhs ) const;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline set<Property*>& 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); }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
|
@ -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<const Entity*,const Entity*,bool> {
|
||||
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".
|
||||
|
||||
|
|
|
@ -507,6 +507,487 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::Intru
|
|||
w->endArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
// ****************************************************************************************************
|
||||
// IntrusiveMapConst declaration
|
||||
// ****************************************************************************************************
|
||||
|
||||
template<class Key, class Element> class IntrusiveMapConst {
|
||||
// ********************************************************
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
class Elements : public Collection<Element*> {
|
||||
// *****************************************
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
public: typedef Collection<Element*> Inherit;
|
||||
|
||||
public: class Locator : public Hurricane::Locator<Element*> {
|
||||
// ********************************************************
|
||||
|
||||
// Types
|
||||
// *****
|
||||
|
||||
public: typedef Hurricane::Locator<Element*> 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<Element*>* 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<Element*>* getClone() const
|
||||
// ***************************************************
|
||||
{
|
||||
return new Elements(*this);
|
||||
};
|
||||
|
||||
public: virtual Hurricane::Locator<Element*>* 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<Element*>(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<class Key, class Element>
|
||||
inline GenericCollection<Element*> getCollection(const IntrusiveMapConst<Key,Element>& intrusiveMap)
|
||||
// ********************************************************************************************
|
||||
{
|
||||
return intrusiveMap.getElements();
|
||||
}
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
template<typename Key, typename Element>
|
||||
inline std::string getString ( Hurricane::IntrusiveMapConst<Key,Element>* intrusiveMap )
|
||||
{ return intrusiveMap->_getString(); }
|
||||
|
||||
template<typename Key, typename Element>
|
||||
inline std::string getString ( const Hurricane::IntrusiveMapConst<Key,Element>* intrusiveMap )
|
||||
{ return intrusiveMap->_getString(); }
|
||||
|
||||
template<typename Key, typename Element>
|
||||
inline Hurricane::Record* getRecord ( Hurricane::IntrusiveMapConst<Key,Element>* intrusiveMap )
|
||||
{ return intrusiveMap->_getRecord(); }
|
||||
|
||||
template<typename Key, typename Element>
|
||||
inline Hurricane::Record* getRecord ( const Hurricane::IntrusiveMapConst<Key,Element>* intrusiveMap )
|
||||
{ return intrusiveMap->_getRecord(); }
|
||||
|
||||
|
||||
template<typename Key, typename Element>
|
||||
inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::IntrusiveMapConst<Key,Element>* intrusiveMap )
|
||||
{
|
||||
w->key( key );
|
||||
w->startArray();
|
||||
for ( Element* element : intrusiveMap->getElements() ) jsonWrite( w, element );
|
||||
w->endArray();
|
||||
}
|
||||
#endif // HURRICANE_INTRUSIVE_MAP
|
||||
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -396,8 +396,8 @@ namespace Hurricane {
|
|||
unsigned int _count;
|
||||
};
|
||||
public:
|
||||
typedef vector<DBo*> DBoSet;
|
||||
typedef map<string,Orphaned> OrphanedMap;
|
||||
typedef set<DBo*,DBo::CompareById> DBoSet;
|
||||
typedef map<string,Orphaned> OrphanedMap;
|
||||
public:
|
||||
static const OrphanedMap& getOrphaneds ();
|
||||
static SharedProperty* getOrphaned ( const string& );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue