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:
Jean-Paul Chaput 2019-04-22 12:16:16 +02:00
parent bbcf14eb5a
commit f6c840fd59
32 changed files with 1122 additions and 457 deletions

View File

@ -92,11 +92,14 @@ namespace Anabatic {
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge(); if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (cg == NULL)
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." );
if (rg == NULL) { if (rg == NULL) {
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
if (rg == NULL) 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(); _cg = cg->getClone();
_rg = rg->getClone(); _rg = rg->getClone();

View File

@ -46,6 +46,7 @@ parametersTable = \
, ("katana.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("katana.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
, ("katana.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("katana.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
, ("katana.longGlobalRipupLimit" ,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 ) # ( METAL_PIN, xy_common_pitch, slice_height, slice_step )
cellGaugesTable = {} 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))

View File

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

View File

@ -1,6 +1,7 @@
# -*- Mode:Python; explicit-buffer-name: "kite.conf<cmos>" -*- # -*- Mode:Python; explicit-buffer-name: "kite.conf<ispd05>" -*-
import helpers import helpers
from helpers import l, u, n
# Contains the layout (shared by all technologies). # Contains the layout (shared by all technologies).
execfile( helpers.sysConfDir+'/common/kite.conf' ) execfile( helpers.sysConfDir+'/common/kite.conf' )
@ -21,8 +22,31 @@ parametersTable = \
, ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } ) , ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
, ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } ) , ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
, ("kite.longGlobalRipupLimit" ,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.edgeHScaling" ,TypeDouble ,1.0 )
, ("anabatic.globalIterations" ,TypeInt ,10 , { 'min':1, 'max':100 } ) , ("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 = {}
routingGaugesTable['sxlib'] = \ routingGaugesTable['sxlib'] = \
( ( 'METAL1', ( Gauge.Vertical , Gauge.PinOnly, 0, 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, 0, 5, 2, 1, 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, 0, 5, 2, 1, 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, 0, 5, 2, 1, 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, 0, 5, 2, 1, 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, 0, 5, 2, 1, 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, 0, 5, 2, 1, 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 ) # ( METAL_PIN, xy_common_pitch, slice_height, slice_step )
cellGaugesTable = {} cellGaugesTable = {}
cellGaugesTable['ispd05'] = ('metal2', 5.0, 60.0, 5.0) cellGaugesTable['ispd05'] = ('metal2', l(5.0), l(60.0), l(5.0))

View File

@ -1,6 +1,7 @@
# -*- Mode:Python; explicit-buffer-name: "technology.conf<ispd05>" -*- # -*- Mode:Python; explicit-buffer-name: "technology.conf<ispd05>" -*-
import helpers import helpers
from helpers.Technology import initTechno
from Hurricane import DbU from Hurricane import DbU
# Provides standard settings for: # Provides standard settings for:
@ -9,168 +10,33 @@ from Hurricane import DbU
# - <compositeLayersTable> # - <compositeLayersTable>
# - <symbolicLayersTable> # - <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' ) 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>: # Format of <layersExtensionsTable>:
# Each entry is a pair of (string, value). # Each entry is a pair of (string, value).
# * string: a synthetic way to designate the real or symbolic layer on # * string: a synthetic way to designate the real or symbolic layer on
# which it applies, an optional sub layer (BasicLayer) in case # which it applies, an optional sub layer (BasicLayer) in case
# where there is more than one, and the dimension name. # where there is more than one, and the dimension name.
# * value : the rule (dimension) value. If the main layer is symbolic it # * value : the rule (dimension) value.
# must be expressed in lambda, if it is for a real layers it # Values/dimensions must be given using one of the following conversion
# must be expressed in microns. # function:
# * l(value) : value expressed in lambda (symbolic).
# * u(value) : value is expressed in microns.
# * n(value) : value is expressed in nanometers.
layersExtensionsTable = \ layersExtensionsTable = symbolicLayersExtensionsTable
( ('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)
)
gdsLayersTable = \ gdsLayersTable = \

View File

@ -755,7 +755,38 @@ namespace CRL {
} }
_cellGauges [ gauge->getName() ] = gauge; _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;
} }

View File

@ -38,6 +38,7 @@ namespace CRL {
, _pitch (pitch) , _pitch (pitch)
, _sliceHeight (sliceHeight) , _sliceHeight (sliceHeight)
, _sliceStep (sliceStep) , _sliceStep (sliceStep)
, _flags (Flags::NoFlags)
{ } { }
@ -47,6 +48,7 @@ namespace CRL {
, _pitch (other._pitch) , _pitch (other._pitch)
, _sliceHeight (other._sliceHeight) , _sliceHeight (other._sliceHeight)
, _sliceStep (other._sliceStep) , _sliceStep (other._sliceStep)
, _flags (other._flags)
{ } { }
@ -100,11 +102,12 @@ namespace CRL {
Record* CellGauge::_getRecord () const Record* CellGauge::_getRecord () const
{ {
Record* record = new Record ( getString(this) ); Record* record = new Record ( getString(this) );
record->add( getSlot ( "Name" , &_name ) ); record->add( getSlot ( "_name" , &_name ) );
record->add( getSlot ( "PinLayerName" , &_pinLayerName ) ); record->add( getSlot ( "_pinLayerName" , &_pinLayerName ) );
record->add( DbU::getValueSlot( "pitch" , &_pitch ) ); record->add( DbU::getValueSlot( "_pitch" , &_pitch ) );
record->add( DbU::getValueSlot( "sliceHeight" , &_sliceHeight ) ); record->add( DbU::getValueSlot( "_sliceHeight" , &_sliceHeight ) );
record->add( DbU::getValueSlot( "sliceStep" , &_sliceStep ) ); record->add( DbU::getValueSlot( "_sliceStep" , &_sliceStep ) );
record->add( getSlot ( "_flags" , &_flags ) );
return ( record ); return ( record );
} }
@ -118,6 +121,7 @@ namespace CRL {
jsonWrite( w, "_pitch" , _pitch ); jsonWrite( w, "_pitch" , _pitch );
jsonWrite( w, "_sliceHeight" , _sliceHeight ); jsonWrite( w, "_sliceHeight" , _sliceHeight );
jsonWrite( w, "_sliceStep" , _sliceStep ); jsonWrite( w, "_sliceStep" , _sliceStep );
jsonWrite( w, "_flags" , _flags );
w->endObject(); w->endObject();
} }
@ -162,6 +166,7 @@ namespace CRL {
DbU::Unit pitch = get<int64_t>( stack, "_pitch" ); DbU::Unit pitch = get<int64_t>( stack, "_pitch" );
DbU::Unit sliceHeight = get<int64_t>( stack, "_sliceHeight" ); DbU::Unit sliceHeight = get<int64_t>( stack, "_sliceHeight" );
DbU::Unit sliceStep = get<int64_t>( stack, "_sliceStep" ); DbU::Unit sliceStep = get<int64_t>( stack, "_sliceStep" );
unsigned long flags = get<int64_t>( stack, "_flags" );
if (stack.issetFlags(JsonWriter::TechnoMode)) { if (stack.issetFlags(JsonWriter::TechnoMode)) {
if (af) { if (af) {
@ -172,6 +177,7 @@ namespace CRL {
, sliceHeight , sliceHeight
, sliceStep , sliceStep
); );
cg->setFlags( flags );
af->addCellGauge( cg ); af->addCellGauge( cg );
} }
} else { } else {

View File

@ -32,6 +32,7 @@ namespace CRL {
using Hurricane::BaseObserver; using Hurricane::BaseObserver;
using Hurricane::JsonObject; using Hurricane::JsonObject;
using Hurricane::JsonStack; using Hurricane::JsonStack;
using Hurricane::DbU;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::Net; using Hurricane::Net;
class RoutingGauge; class RoutingGauge;
@ -98,6 +99,8 @@ namespace CRL {
void saveLibrary ( AllianceLibrary* ); void saveLibrary ( AllianceLibrary* );
RoutingGauge* getRoutingGauge ( const Name& name="" ); RoutingGauge* getRoutingGauge ( const Name& name="" );
CellGauge* getCellGauge ( 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; inline const Name getDefaultCGPinLayerName () const;
// Modifiers. // Modifiers.
RoutingGauge* setRoutingGauge ( const Name& name="" ); RoutingGauge* setRoutingGauge ( const Name& name="" );

View File

@ -41,38 +41,40 @@ namespace CRL {
// Class : "CRL::CellGauge". // Class : "CRL::CellGauge".
class CellGauge { class CellGauge {
public: public:
// Constructors & Destructor. enum Flags { NoFlags = 0, Pad = ( 1<<0) };
public:
static CellGauge* create ( const char* name static CellGauge* create ( const char* name
, const char* pinLayerName , const char* pinLayerName
, const DbU::Unit pitch =0 , const DbU::Unit pitch =0
, const DbU::Unit sliceHeight =0 , const DbU::Unit sliceHeight =0
, const DbU::Unit sliceStep =0 ); , const DbU::Unit sliceStep =0 );
virtual void destroy (); virtual void destroy ();
// Accessors inline bool isPad () const;
inline const Name& getName () const; inline const Name& getName () const;
inline unsigned long getFlags () const;
inline const Name& getPinLayerName () const; inline const Name& getPinLayerName () const;
inline const DbU::Unit getPitch () const; inline const DbU::Unit getPitch () const;
inline const DbU::Unit getSliceHeight () const; inline const DbU::Unit getSliceHeight () const;
inline const DbU::Unit getSliceStep () const; inline const DbU::Unit getSliceStep () const;
CellGauge* getClone () 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; void toJson ( JsonWriter* ) const;
virtual string _getTypeName () const; virtual string _getTypeName () const;
virtual string _getString () const; virtual string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
protected: protected:
// Internal: Attributes.
Name _name; Name _name;
Name _pinLayerName; Name _pinLayerName;
DbU::Unit _pitch; DbU::Unit _pitch;
DbU::Unit _sliceHeight; DbU::Unit _sliceHeight;
DbU::Unit _sliceStep; DbU::Unit _sliceStep;
unsigned long _flags;
protected: protected:
// Internal: Constructors & Destructors.
CellGauge ( const char* name CellGauge ( const char* name
, const char* pinLayerName , const char* pinLayerName
, const DbU::Unit pitch , const DbU::Unit pitch
@ -91,11 +93,18 @@ namespace CRL {
// Inline Functions. // Inline Functions.
inline const Name& CellGauge::getName () const { return _name; } inline bool CellGauge::isPad () const { return _flags & Flags::Pad; }
inline const Name& CellGauge::getPinLayerName () const { return _pinLayerName; } inline const Name& CellGauge::getName () const { return _name; }
inline const DbU::Unit CellGauge::getPitch () const { return _pitch; } inline const Name& CellGauge::getPinLayerName () const { return _pinLayerName; }
inline const DbU::Unit CellGauge::getSliceHeight () const { return _sliceHeight; } inline const DbU::Unit CellGauge::getPitch () const { return _pitch; }
inline const DbU::Unit CellGauge::getSliceStep () const { return _sliceStep; } 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; }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -154,6 +154,7 @@ namespace CRL {
AllianceFramework* af = AllianceFramework::get(); AllianceFramework* af = AllianceFramework::get();
pitch = af->getCellGauge()->getPitch(); pitch = af->getCellGauge()->getPitch();
size_t count = 0;
UpdateSession::open (); UpdateSession::open ();
unique_ptr<Bookshelf::Circuit> circuit ( Bookshelf::Circuit::parse( benchmark unique_ptr<Bookshelf::Circuit> circuit ( Bookshelf::Circuit::parse( benchmark
@ -172,6 +173,11 @@ namespace CRL {
for ( auto net : circuit->getNets() ) { for ( auto net : circuit->getNets() ) {
dots.dot(); dots.dot();
Net::create ( cell, net->getName() ); Net::create ( cell, net->getName() );
if (++count % 1000) {
UpdateSession::close ();
UpdateSession::open ();
}
} }
dots.finish( Dots::Reset|Dots::FirstDot ); dots.finish( Dots::Reset|Dots::FirstDot );
@ -196,6 +202,11 @@ namespace CRL {
Net* masterNet = master->getNet( netName ); Net* masterNet = master->getNet( netName );
instance->getPlug( masterNet )->setNet( cell->getNet(netName) ); instance->getPlug( masterNet )->setNet( cell->getNet(netName) );
} }
if (++count % 1000) {
UpdateSession::close ();
UpdateSession::open ();
}
} }
dots.finish( Dots::Reset|Dots::FirstDot ); dots.finish( Dots::Reset|Dots::FirstDot );

View File

@ -84,6 +84,8 @@ namespace {
inline Library* getLibrary ( bool create=false ); inline Library* getLibrary ( bool create=false );
inline Cell* getCell () const; inline Cell* getCell () const;
inline void setCell ( Cell* ); inline void setCell ( Cell* );
inline CellGauge* getCellGauge () const;
inline void setCellGauge ( CellGauge* );
inline Net* getNet () const; inline Net* getNet () const;
inline void setNet ( Net* ); inline void setNet ( Net* );
static void setCoreSite ( DbU::Unit x, DbU::Unit y ); static void setCoreSite ( DbU::Unit x, DbU::Unit y );
@ -103,17 +105,18 @@ namespace {
inline int getNthCut () const; inline int getNthCut () const;
inline void incNthCut (); inline void incNthCut ();
inline RoutingGauge* getRoutingGauge () const; inline RoutingGauge* getRoutingGauge () const;
inline CellGauge* getCellGauge () const;
inline void addPinSegment ( string name, Segment* ); inline void addPinSegment ( string name, Segment* );
inline void clearPinSegments (); inline void clearPinSegments ();
private: private:
static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData ); static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData );
static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData ); static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData );
static int _siteCbk ( lefrCallbackType_e, lefiSite* , lefiUserData ); static int _siteCbk ( lefrCallbackType_e, lefiSite* , lefiUserData );
static int _obstructionCbk ( lefrCallbackType_e, lefiObstruction*, lefiUserData ); static int _obstructionCbk ( lefrCallbackType_e, lefiObstruction*, lefiUserData );
static int _macroCbk ( lefrCallbackType_e, lefiMacro* , lefiUserData ); static int _macroCbk ( lefrCallbackType_e, lefiMacro* , lefiUserData );
static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData ); static int _macroSiteCbk ( lefrCallbackType_e, const lefiMacroSite* , lefiUserData );
void _pinPostProcess (); static int _pinCbk ( lefrCallbackType_e, lefiPin* , lefiUserData );
void _pinStdPostProcess ();
void _pinPadPostProcess ();
private: private:
string _file; string _file;
string _libraryName; string _libraryName;
@ -141,6 +144,7 @@ namespace {
inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; } inline Library* LefParser::getLibrary ( bool create ) { if (not _library and create) createLibrary(); return _library; }
inline Cell* LefParser::getCell () const { return _cell; } inline Cell* LefParser::getCell () const { return _cell; }
inline void LefParser::setCell ( Cell* cell ) { _cell=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 Net* LefParser::getNet () const { return _net; }
inline void LefParser::setNet ( Net* net ) { _net=net; } inline void LefParser::setNet ( Net* net ) { _net=net; }
inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); } inline DbU::Unit LefParser::fromUnitsMicrons ( double d ) const { return DbU::fromPhysical(d,DbU::Micro); }
@ -219,6 +223,7 @@ namespace {
lefrSetSiteCbk ( _siteCbk ); lefrSetSiteCbk ( _siteCbk );
lefrSetObstructionCbk( _obstructionCbk ); lefrSetObstructionCbk( _obstructionCbk );
lefrSetMacroCbk ( _macroCbk ); lefrSetMacroCbk ( _macroCbk );
lefrSetMacroSiteCbk ( _macroSiteCbk );
lefrSetPinCbk ( _pinCbk ); lefrSetPinCbk ( _pinCbk );
} }
@ -341,27 +346,48 @@ namespace {
int LefParser::_siteCbk ( lefrCallbackType_e c, lefiSite* site, lefiUserData ud ) 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()) { if (site->hasClass()) {
string siteClass = site->siteClass(); string siteClass = site->siteClass();
boost::to_upper( siteClass ); boost::to_upper( siteClass );
if (siteClass == "CORE") { DbU::Unit lefSiteWidth = DbU::fromPhysical( site->sizeX(), DbU::Micro );
CellGauge* gauge = parser->getCellGauge(); DbU::Unit lefSiteHeight = DbU::fromPhysical( site->sizeY(), DbU::Micro );
DbU::Unit lefSliceStep = DbU::fromPhysical( site->sizeX(), DbU::Micro ); if (siteClass == "CORE") {
DbU::Unit lefSliceHeight = DbU::fromPhysical( site->sizeY(), DbU::Micro ); CellGauge* gauge = parser->getCellGauge();
DbU::Unit crlSliceStep = gauge->getSliceStep (); DbU::Unit crlSliceStep = gauge->getSliceStep ();
DbU::Unit crlSliceHeight = gauge->getSliceHeight(); DbU::Unit crlSliceHeight = gauge->getSliceHeight();
if (not parser->getCoreSiteX() if (not parser->getCoreSiteX()
or ((parser->getCoreSiteX() != crlSliceStep) and (parser->getCoreSiteY() != crlSliceHeight)) ) { 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; 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 ) 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(); string cellName = macro->name();
DbU::Unit width = 0; DbU::Unit width = 0;
@ -441,17 +470,47 @@ namespace {
cell->setAbutmentBox( Box( 0, 0, width, height ) ); 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(); parser->clearPinSegments();
cerr << " - " << cellName 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 ); parser->setCell( NULL );
return 0; 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 ) int LefParser::_pinCbk ( lefrCallbackType_e c, lefiPin* pin, lefiUserData ud )
{ {
LefParser* parser = (LefParser*)ud; LefParser* parser = (LefParser*)ud;
@ -519,6 +578,10 @@ namespace {
//cerr << " | " << segment << endl; //cerr << " | " << segment << endl;
continue; continue;
} }
if (geoms->itemType(igeom) == lefiGeomClassE) {
// Ignore CLASS <site>. Deduced from segments positions.
continue;
}
string geomTypeName; string geomTypeName;
switch ( geoms->itemType(igeom) ) { 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 Layer* metal1 = _routingGauge->getLayerGauge( (size_t)0 )->getLayer();
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
Box ab = _cell->getAbutmentBox(); Box ab = _cell->getAbutmentBox();
//cerr << " @ _pinPostProcess" << endl; //cerr << " @ _pinStdPostProcess" << endl;
for ( auto element : _pinSegments ) { for ( auto element : _pinSegments ) {
string pinName = element.first; string pinName = element.first;
@ -612,7 +675,7 @@ namespace {
} }
if (ongrids.empty()) { 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; , pinName.c_str() ) << endl;
for ( Segment* segment : segments ) { for ( Segment* segment : segments ) {
NetExternalComponents::setExternal( segment ); 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 LefParser::flushErrors ()
{ {
int code = (hasErrors()) ? 1 : 0; int code = (hasErrors()) ? 1 : 0;

View File

@ -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 ) static PyObject* PyAllianceFramework_loadLibraryCells ( PyAllianceFramework* self, PyObject* args )
{ {
cdebug_log(30,0) << "PyAllianceFramework_loadLibraryCells()" << endl; cdebug_log(30,0) << "PyAllianceFramework_loadLibraryCells()" << endl;
@ -505,6 +538,8 @@ extern "C" {
, "Add a new cell gauge." } , "Add a new cell gauge." }
, { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS , { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS
, "Get a cell gauge (whithout a name, return the default)." } , "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 , { "addRoutingGauge" , (PyCFunction)PyAllianceFramework_addRoutingGauge , METH_VARARGS
, "Add a new routing gauge." } , "Add a new routing gauge." }
, { "getRoutingGauge" , (PyCFunction)PyAllianceFramework_getRoutingGauge , METH_VARARGS , { "getRoutingGauge" , (PyCFunction)PyAllianceFramework_getRoutingGauge , METH_VARARGS

View File

@ -56,9 +56,11 @@ extern "C" {
// +=================================================================+ // +=================================================================+
DirectGetBoolAttribute(PyCellGauge_isPad ,isPad ,PyCellGauge,CellGauge)
DirectGetLongAttribute(PyCellGauge_getSliceHeight,getSliceHeight,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getSliceHeight,getSliceHeight,PyCellGauge,CellGauge)
DirectGetLongAttribute(PyCellGauge_getSliceStep ,getSliceStep ,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getSliceStep ,getSliceStep ,PyCellGauge,CellGauge)
DirectGetLongAttribute(PyCellGauge_getPitch ,getPitch ,PyCellGauge,CellGauge) DirectGetLongAttribute(PyCellGauge_getPitch ,getPitch ,PyCellGauge,CellGauge)
DirectGetNameAttribute(PyCellGauge_getName ,getName ,PyCellGauge,CellGauge)
static PyObject* PyCellGauge_create ( PyObject*, PyObject* args ) static PyObject* PyCellGauge_create ( PyObject*, PyObject* args )
@ -113,9 +115,11 @@ extern "C" {
PyMethodDef PyCellGauge_Methods[] = PyMethodDef PyCellGauge_Methods[] =
{ { "create" , (PyCFunction)PyCellGauge_create , METH_VARARGS|METH_STATIC { { "create" , (PyCFunction)PyCellGauge_create , METH_VARARGS|METH_STATIC
, "Create a new CellGauge." } , "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." } , { "getSliceHeight" , (PyCFunction)PyCellGauge_getSliceHeight, METH_NOARGS , "Return the slice height." }
, { "getSliceStep" , (PyCFunction)PyCellGauge_getSliceStep , METH_NOARGS , "Return the slice step." } , { "getSliceStep" , (PyCFunction)PyCellGauge_getSliceStep , METH_NOARGS , "Return the slice step." }
, { "getPitch" , (PyCFunction)PyCellGauge_getPitch , METH_NOARGS , "Return the smallest common pitch." } , { "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" , (PyCFunction)PyCellGauge_destroy , METH_VARARGS
// , "Destroy the associated hurricane object. The python object remains." } // , "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */

View File

@ -298,7 +298,6 @@ namespace {
namespace Etesian { namespace Etesian {
using Hurricane::ForEachIterator;
using Hurricane::DataBase; using Hurricane::DataBase;
using Hurricane::UpdateSession; using Hurricane::UpdateSession;
using Hurricane::Occurrence; using Hurricane::Occurrence;
@ -312,14 +311,14 @@ namespace Etesian {
Box topCellAb = getCell()->getAbutmentBox(); Box topCellAb = getCell()->getAbutmentBox();
if (not topCellAb.isEmpty()) { 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(); Cell* masterCell = instance->getMasterCell();
Box instanceAb = masterCell->getAbutmentBox(); Box instanceAb = masterCell->getAbutmentBox();
Transformation instanceTransf = instance->getTransformation(); Transformation instanceTransf = instance->getTransformation();
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); occurrence.getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb ); instanceTransf.applyOn( instanceAb );
if (not topCellAb.contains(instanceAb)) continue; if (not topCellAb.contains(instanceAb)) continue;
@ -371,9 +370,9 @@ namespace Etesian {
sliceHoles.setSpinSlice0( _yspinSlice0 ); 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(); Cell* masterCell = instance->getMasterCell();
if (CatalogExtension::isFeed(masterCell)) { if (CatalogExtension::isFeed(masterCell)) {
@ -384,7 +383,7 @@ namespace Etesian {
Box instanceAb = masterCell->getAbutmentBox(); Box instanceAb = masterCell->getAbutmentBox();
Transformation instanceTransf = instance->getTransformation(); Transformation instanceTransf = instance->getTransformation();
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); occurrence.getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb ); instanceTransf.applyOn( instanceAb );
if (not topCellAb.contains(instanceAb)) { if (not topCellAb.contains(instanceAb)) {

View File

@ -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(); return net->getName();
} }
unsigned Cell::NetMap::_getHashValue(Name name) const unsigned Cell::NetMap::_getHashValue(const Name& name) const
// ************************************************** // *********************************************************
{ {
unsigned long hash = 0; unsigned long hash = 0;
unsigned long sum4 = 0; unsigned long sum4 = 0;

View File

@ -30,6 +30,7 @@
#include "hurricane/Initializer.h" #include "hurricane/Initializer.h"
#include "hurricane/Timer.h"
#include "hurricane/DBo.h" #include "hurricane/DBo.h"
#include "hurricane/Entity.h" #include "hurricane/Entity.h"
#include "hurricane/Property.h" #include "hurricane/Property.h"
@ -44,8 +45,101 @@ namespace Hurricane {
// Class : "Hurricane::DBo". // 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 () 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 ) void DBo::put ( Property* property )
{ {
if ( !property ) if ( !property )
@ -181,14 +286,15 @@ namespace Hurricane {
string DBo::_getString () const string DBo::_getString () const
{ {
return "<" + _getTypeName() + ">"; return "<id:" + getString(_id) + " " + _getTypeName() + ">";
} }
Record* DBo::_getRecord () const Record* DBo::_getRecord () const
{ {
Record* record = new Record ( getString(this) ); Record* record = new Record ( getString(this) );
record->add ( getSlot("_propertySet", &_propertySet) ); record->add( getSlot("_id" , _id ) );
record->add( getSlot("_propertySet", &_propertySet) );
return record; return record;
} }

View File

@ -19,7 +19,6 @@
#include <limits> #include <limits>
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Timer.h"
#include "hurricane/Entity.h" #include "hurricane/Entity.h"
#include "hurricane/Quark.h" #include "hurricane/Quark.h"
#include "hurricane/Cell.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() Entity::Entity()
: Inherit() : 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() 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 void Entity::_toJson ( JsonWriter* writer ) const
{ {
Inherit::_toJson( writer ); Inherit::_toJson( writer );
@ -204,7 +101,6 @@ namespace Hurricane {
string Entity::_getString() const string Entity::_getString() const
{ {
string s = Inherit::_getString(); string s = Inherit::_getString();
s.insert( 1, "id:"+getString(_id)+" " );
return s; return s;
} }
@ -213,7 +109,6 @@ namespace Hurricane {
{ {
Record* record = Inherit::_getRecord(); Record* record = Inherit::_getRecord();
if (record) { if (record) {
record->add( getSlot("_id", _id) );
Occurrence occurrence = Occurrence(this); Occurrence occurrence = Occurrence(this);
if (occurrence.hasProperty()) if (occurrence.hasProperty())
record->add( getSlot("Occurrence", occurrence) ); record->add( getSlot("Occurrence", occurrence) );

View File

@ -182,19 +182,19 @@ Instance::Instance(Cell* cell, const Name& name, Cell* masterCell, const Transfo
_nextOfCellSlaveInstanceSet(NULL) _nextOfCellSlaveInstanceSet(NULL)
{ {
if (!_cell) 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()) 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)) 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) 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)) 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) Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, bool secureFlag)

View File

@ -56,6 +56,7 @@ namespace Hurricane {
, _minimalSpacing(minimalSpacing) , _minimalSpacing(minimalSpacing)
, _nextOfTechnologyLayerMap(NULL) , _nextOfTechnologyLayerMap(NULL)
, _symbolic(false) , _symbolic(false)
, _blockage(false)
{ {
if ( !_technology ) if ( !_technology )
throw Error ( "Can't create " + _TName("Layer") + " : null technology" ); throw Error ( "Can't create " + _TName("Layer") + " : null technology" );

View File

@ -226,10 +226,11 @@ namespace Hurricane {
void SharedProperty::_preDestroy () void SharedProperty::_preDestroy ()
{ {
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { for ( DBo* owner : _ownerSet ) owner->_onDestroyed( this );
_ownerSet[i]->_onDestroyed(this); // for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) {
_ownerSet[i] = NULL; // _ownerSet[i]->_onDestroyed(this);
} // _ownerSet[i] = NULL;
// }
_ownerSet.clear(); _ownerSet.clear();
// while (!_ownerSet.empty()) { // while (!_ownerSet.empty()) {
@ -244,36 +245,24 @@ namespace Hurricane {
void SharedProperty::_erase ( DBo* owner ) void SharedProperty::_erase ( DBo* owner )
{ {
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { auto iowner = _ownerSet.find( owner );
if (_ownerSet[i] == owner) { if (iowner != _ownerSet.end()) {
std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] ); _ownerSet.erase( iowner );
_ownerSet.pop_back();
}
} }
} }
void SharedProperty::onCapturedBy ( DBo* owner ) void SharedProperty::onCapturedBy ( DBo* owner )
{ {
for ( DBo* dbo : _ownerSet ) { if (_ownerSet.find(owner) != _ownerSet.end()) return;
if (dbo == owner) return; _ownerSet.insert(owner);
}
_ownerSet.push_back( owner );
//_ownerSet.insert(owner);
} }
void SharedProperty::onReleasedBy ( DBo* owner ) void SharedProperty::onReleasedBy ( DBo* owner )
{ {
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { auto iowner = _ownerSet.find( owner );
if (_ownerSet[i] == owner) { if (iowner != _ownerSet.end()) _ownerSet.erase( owner );
std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] );
_ownerSet.pop_back();
}
}
//_ownerSet.erase(owner);
if (_ownerSet.empty()) onNotOwned(); if (_ownerSet.empty()) onNotOwned();
} }

View File

@ -140,7 +140,7 @@ namespace Hurricane {
inline unsigned BasicLayer::getGds2Layer () const { return _gds2Layer; } inline unsigned BasicLayer::getGds2Layer () const { return _gds2Layer; }
inline unsigned BasicLayer::getGds2Datatype () const { return _gds2Datatype; } inline unsigned BasicLayer::getGds2Datatype () const { return _gds2Datatype; }
inline const Name& BasicLayer::getRealName () const { return _realName; } 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::setGds2Layer ( unsigned int number ) { _gds2Layer=number; }
inline void BasicLayer::setGds2Datatype ( unsigned int number ) { _gds2Datatype=number; } inline void BasicLayer::setGds2Datatype ( unsigned int number ) { _gds2Datatype=number; }
inline void BasicLayer::setRealName ( const char* realName) { _realName = realName; } inline void BasicLayer::setRealName ( const char* realName) { _realName = realName; }

View File

@ -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: NetMap();
public: virtual Name _getKey(Net* net) const; public: virtual const Name& _getKey(Net* net) const;
public: virtual unsigned _getHashValue(Name name) const; public: virtual unsigned _getHashValue(const Name& name) const;
public: virtual Net* _getNextElement(Net* net) const; public: virtual Net* _getNextElement(Net* net) const;
public: virtual void _setNextElement(Net* net, Net* nextNet) const; public: virtual void _setNextElement(Net* net, Net* nextNet) const;

View File

@ -45,43 +45,70 @@ namespace Hurricane {
class DBo { class DBo {
public: public:
virtual void destroy (); enum DBoFlags { ForcedIdMode = (1<<0)
inline set<Property*>& _getPropertySet (); , NextIdSet = (1<<1)
void _onDestroyed ( Property* property ); };
Property* getProperty ( const Name& ) const; public:
Properties getProperties () const; static void setMemoryLimit ( unsigned int );
inline bool hasProperty () const; static void setIdCounterLimit ( unsigned int );
void put ( Property* ); static unsigned int getIdCounter ();
void remove ( Property* ); unsigned int getNextId ();
void removeProperty ( const Name& ); static void setNextId ( unsigned int );
void clearProperties (); static bool inForcedIdMode ();
virtual string _getTypeName () const; static void enableForcedIdMode ();
virtual string _getString () const; static void disableForcedIdMode ();
virtual Record* _getRecord () const; static void useIdCounter2 ();
virtual void _toJson ( JsonWriter* ) const; public:
virtual void _toJsonCollections ( JsonWriter* ) const; virtual void destroy ();
virtual void _toJsonSignature ( JsonWriter* ) const; inline set<Property*>& _getPropertySet ();
void toJson ( JsonWriter* ) const; void _onDestroyed ( Property* property );
void toJsonSignature ( JsonWriter* ) const; inline unsigned int getId () const;
Property* getProperty ( const Name& ) const;
private: Properties getProperties () const;
mutable set<Property*> _propertySet; 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: protected:
DBo (); DBo ();
virtual ~DBo (); virtual ~DBo ();
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
private: private:
DBo ( const DBo& ); DBo ( const DBo& );
DBo& operator= ( 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 Functions.
inline set<Property*>& DBo::_getPropertySet () { return _propertySet; } inline set<Property*>& DBo::_getPropertySet () { return _propertySet; }
inline bool DBo::hasProperty () const { return !_propertySet.empty(); } 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); }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -40,24 +40,8 @@ namespace Hurricane {
public: public:
typedef DBo Inherit; typedef DBo Inherit;
public: 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 Cell* getCell () const = 0;
virtual Box getBoundingBox () const = 0; virtual Box getBoundingBox () const = 0;
void setId ( unsigned int );
virtual void _toJson ( JsonWriter* ) const; virtual void _toJson ( JsonWriter* ) const;
virtual string _getString () const; virtual string _getString () const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
@ -66,26 +50,9 @@ namespace Hurricane {
Entity (); Entity ();
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); 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". // Class : "Hurricane::JsonEntity".

View File

@ -507,6 +507,487 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::Intru
w->endArray(); 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 #endif // HURRICANE_INTRUSIVE_MAP

View File

@ -93,9 +93,11 @@ namespace Hurricane {
bool contains ( const Layer* layer ) const; bool contains ( const Layer* layer ) const;
bool intersect ( const Layer* layer ) const; bool intersect ( const Layer* layer ) const;
inline bool isSymbolic () const; inline bool isSymbolic () const;
inline bool isBlockage () const;
// Updators // Updators
void setName ( const Name& name ); void setName ( const Name& name );
inline void setSymbolic ( bool ); inline void setSymbolic ( bool );
inline void setBlockage ( bool );
void setMinimalSize ( const DbU::Unit& minimalSize ); void setMinimalSize ( const DbU::Unit& minimalSize );
void setMinimalSpacing ( const DbU::Unit& minimalSpacing ); void setMinimalSpacing ( const DbU::Unit& minimalSpacing );
virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags ); virtual void setEnclosure ( const BasicLayer* layer, DbU::Unit, uint32_t flags );
@ -122,6 +124,7 @@ namespace Hurricane {
DbU::Unit _minimalSpacing; DbU::Unit _minimalSpacing;
Layer* _nextOfTechnologyLayerMap; Layer* _nextOfTechnologyLayerMap;
bool _symbolic; bool _symbolic;
bool _blockage;
protected: protected:
// Internal: Constructors & Destructors. // Internal: Constructors & Destructors.
@ -143,6 +146,7 @@ namespace Hurricane {
// Inline Functions. // Inline Functions.
inline bool Layer::isSymbolic () const { return _symbolic; } 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::above ( const Layer* layer ) const { return _mask > layer->getMask(); }
inline bool Layer::below ( 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; } 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::getMinimalSize () const { return _minimalSize; }
inline const DbU::Unit& Layer::getMinimalSpacing () const { return _minimalSpacing; } inline const DbU::Unit& Layer::getMinimalSpacing () const { return _minimalSpacing; }
inline void Layer::setSymbolic ( bool state ) { _symbolic = state; } inline void Layer::setSymbolic ( bool state ) { _symbolic = state; }
inline void Layer::setBlockage ( bool state ) { _blockage = state; }
inline Layer* Layer::_getNextOfTechnologyLayerMap () const { return _nextOfTechnologyLayerMap; } inline Layer* Layer::_getNextOfTechnologyLayerMap () const { return _nextOfTechnologyLayerMap; }
inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; } inline void Layer::_setMask ( const Mask& mask ) { _mask = mask; }
inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; } inline void Layer::_setExtractMask ( const Mask& extractMask ) { _extractMask = extractMask; }

View File

@ -396,8 +396,8 @@ namespace Hurricane {
unsigned int _count; unsigned int _count;
}; };
public: public:
typedef vector<DBo*> DBoSet; typedef set<DBo*,DBo::CompareById> DBoSet;
typedef map<string,Orphaned> OrphanedMap; typedef map<string,Orphaned> OrphanedMap;
public: public:
static const OrphanedMap& getOrphaneds (); static const OrphanedMap& getOrphaneds ();
static SharedProperty* getOrphaned ( const string& ); static SharedProperty* getOrphaned ( const string& );

View File

@ -51,7 +51,7 @@ extern "C" {
#if defined(__PYTHON_MODULE__) #if defined(__PYTHON_MODULE__)
static Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* object ) extern Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* object )
{ {
switch ( PyAny_AsLong(object) ) { switch ( PyAny_AsLong(object) ) {
case Instance::PlacementStatus::UNPLACED : return ( Instance::PlacementStatus(Instance::PlacementStatus::UNPLACED) ); case Instance::PlacementStatus::UNPLACED : return ( Instance::PlacementStatus(Instance::PlacementStatus::UNPLACED) );
@ -80,35 +80,37 @@ extern "C" {
PyObject* arg1 = NULL; PyObject* arg1 = NULL;
PyObject* arg2 = NULL; PyObject* arg2 = NULL;
PyObject* arg3 = NULL; PyObject* arg3 = NULL;
PyObject* arg4 = NULL;
HTRY HTRY
__cs.init( "Instance.create" ); __cs.init( "Instance.create" );
if (not PyArg_ParseTuple(args,"O&O&O&|O&:Instance.create" if (not PyArg_ParseTuple(args,"O&O&O&|O&O&:Instance.create"
,Converter,&arg0 ,Converter,&arg0
,Converter,&arg1 ,Converter,&arg1
,Converter,&arg2 ,Converter,&arg2
,Converter,&arg3 ,Converter,&arg3
)) { ,Converter,&arg4
PyErr_SetString( ConstructorError, "Instance.create(): Invalid number of parameters." ); )) {
return NULL; PyErr_SetString( ConstructorError, "Instance.create(): Invalid number of parameters." );
} return NULL;
}
if (__cs.getObjectIds() == ":ent:string:ent") { if (__cs.getObjectIds() == ":ent:string:ent") {
instance = Instance::create( PYCELL_O(arg0) instance = Instance::create( PYCELL_O(arg0)
, Name(PyString_AsString(arg1)) , Name(PyString_AsString(arg1))
, PYCELL_O(arg2) , PYCELL_O(arg2)
); );
} else if (__cs.getObjectIds() == ":ent:string:ent:transfo") { } else if (__cs.getObjectIds() == ":ent:string:ent:transfo:int") {
instance = Instance::create( PYCELL_O(arg0) instance = Instance::create( PYCELL_O(arg0)
, Name(PyString_AsString(arg1)) , Name(PyString_AsString(arg1))
, PYCELL_O(arg2) , PYCELL_O(arg2)
, *PYTRANSFORMATION_O(arg3) , *PYTRANSFORMATION_O(arg3)
, Instance::PlacementStatus::PLACED , PyInt_AsPlacementStatus(arg4)
); );
} else { } else {
PyErr_SetString( ConstructorError, "Instance.create(): Bad type of parameter(s)." ); PyErr_SetString( ConstructorError, "Instance.create(): Bad type of parameter(s)." );
return NULL; return NULL;
} }
HCATCH HCATCH
return PyInstance_Link( instance ); return PyInstance_Link( instance );

View File

@ -313,6 +313,7 @@ extern "C" {
predicateFromLayer ( contains ,PyLayer,Layer) predicateFromLayer ( contains ,PyLayer,Layer)
predicateFromLayer ( intersect ,PyLayer,Layer) predicateFromLayer ( intersect ,PyLayer,Layer)
predicateFromVoid ( isSymbolic ,PyLayer,Layer) predicateFromVoid ( isSymbolic ,PyLayer,Layer)
predicateFromVoid ( isBlockage ,PyLayer,Layer)
accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionCap ,PyLayer,Layer)
accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer) accessorDbuFromOptBasicLayer( getExtentionWidth,PyLayer,Layer)
accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer) accessorCollectionFromVoid ( getBasicLayers ,PyLayer,Layer,BasicLayer)
@ -335,6 +336,7 @@ extern "C" {
updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionCap ,PyLayer,Layer)
updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer) updatorFromBasicLayerDbu(setExtentionWidth,PyLayer,Layer)
DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer) DirectSetBoolAttribute (PyLayer_setSymbolic,setSymbolic,PyLayer,Layer)
DirectSetBoolAttribute (PyLayer_setBlockage,setBlockage,PyLayer,Layer)
// Standart destroy (Attribute). // Standart destroy (Attribute).
DBoDestroyAttribute(PyLayer_destroy, PyLayer) DBoDestroyAttribute(PyLayer_destroy, PyLayer)
@ -387,10 +389,14 @@ extern "C" {
, "Tells if the layer share some BasicLayer with the one passed as argument." } , "Tells if the layer share some BasicLayer with the one passed as argument." }
, { "isSymbolic" , (PyCFunction)PyLayer_isSymbolic , METH_NOARGS , { "isSymbolic" , (PyCFunction)PyLayer_isSymbolic , METH_NOARGS
, "Tells if the layer is the symbolic one for this BasicLayer." } , "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 , { "setName" , (PyCFunction)PyLayer_setName , METH_VARARGS
, "Allows to change the layer name." } , "Allows to change the layer name." }
, { "setSymbolic" , (PyCFunction)PyLayer_setSymbolic , METH_VARARGS , { "setSymbolic" , (PyCFunction)PyLayer_setSymbolic , METH_VARARGS
, "Sets the layer as the symbolic one." } , "Sets the layer as the symbolic one." }
, { "setBlockage" , (PyCFunction)PyLayer_setBlockage , METH_VARARGS
, "Sets the layer as blockage." }
, { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS , { "setMinimalSize" , (PyCFunction)PyLayer_setMinimalSize , METH_VARARGS
, "Sets the layer minimal size (width)." } , "Sets the layer minimal size (width)." }
, { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS , { "setMinimalSpacing" , (PyCFunction)PyLayer_setMinimalSpacing , METH_VARARGS

View File

@ -103,6 +103,17 @@ extern "C" {
} }
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. #endif // Shared Library Code Part.
} // extern "C". } // extern "C".

View File

@ -37,12 +37,13 @@ namespace Isobar {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.ccp". // Functions & Types exported to "PyHurricane.ccp".
extern PyTypeObject PyTypePlacementStatus; extern PyTypeObject PyTypePlacementStatus;
extern PyMethodDef PyPlacementStatus_Methods[]; extern PyMethodDef PyPlacementStatus_Methods[];
extern PyObject* PyPlacementStatus_Link ( Hurricane::Instance::PlacementStatus* ); extern PyObject* PyPlacementStatus_Link ( Hurricane::Instance::PlacementStatus* );
extern void PyPlacementStatus_LinkPyType (); extern void PyPlacementStatus_LinkPyType ();
extern void PyPlacementStatus_postModuleInit (); extern void PyPlacementStatus_postModuleInit ();
extern Hurricane::Instance::PlacementStatus PyInt_AsPlacementStatus ( PyObject* );
#define IsPyPlacementStatus(v) ( (v)->ob_type == &PyTypePlacementStatus ) #define IsPyPlacementStatus(v) ( (v)->ob_type == &PyTypePlacementStatus )

View File

@ -16,6 +16,7 @@ try:
import Katabatic import Katabatic
import Kite import Kite
import Bora import Bora
import Tutorial
import Unicorn import Unicorn
except ImportError, e: except ImportError, e:
serror = str(e) serror = str(e)
@ -190,6 +191,7 @@ if __name__ == '__main__':
unicorn.registerTool (Kite.GraphicKiteEngine.grab()) unicorn.registerTool (Kite.GraphicKiteEngine.grab())
unicorn.registerTool (Katana.GraphicKatanaEngine.grab()) unicorn.registerTool (Katana.GraphicKatanaEngine.grab())
unicorn.registerTool (Bora.GraphicBoraEngine.grab()) unicorn.registerTool (Bora.GraphicBoraEngine.grab())
unicorn.registerTool (Tutorial.GraphicTutorialEngine.grab())
#unicorn.setAnonNetSelectable(False) #unicorn.setAnonNetSelectable(False)
unicorn.setLayerVisible ("grid" , False); unicorn.setLayerVisible ("grid" , False);
unicorn.setLayerVisible ("text.instance" , False); unicorn.setLayerVisible ("text.instance" , False);